Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of RepairTweaks v1.0.0
plugins/TXC.RepairTweaks.dll
Decompiled a week agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Jotunn.Entities; using Jotunn.Managers; using Jotunn.Utils; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8.1", FrameworkDisplayName = ".NET Framework 4.8.1")] [assembly: AssemblyCompany("TXC.RepairTweaks")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("TXC.RepairTweaks")] [assembly: AssemblyTitle("TXC.RepairTweaks")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace TXC.RepairTweaks { internal sealed class RepairInfoCommand : ConsoleCommand { public override string Name => "repairtweaks_info"; public override string Help => "TXC Repair Tweaks: station settings + whether each damaged item can be repaired at the current station"; public override void Run(string[] args) { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine("Stations: " + Stations.Describe()); stringBuilder.AppendLine($"Button: {Plugin.RepairButton.Value}, auto-repair: {Plugin.AutoRepair.Value}, cost: {Plugin.Cost.Value}"); Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null) { CraftingStation currentCraftingStation = localPlayer.GetCurrentCraftingStation(); StationMode? stationMode = (((Object)(object)currentCraftingStation != (Object)null) ? Stations.GetMode(currentCraftingStation) : ((StationMode?)null)); stringBuilder.AppendLine(((Object)(object)currentCraftingStation == (Object)null) ? "Current station: none" : (string.Format("Current station: {0} level {1}, mode {2}", Utils.GetPrefabName(((Component)currentCraftingStation).gameObject), currentCraftingStation.GetLevel(true), stationMode.HasValue ? stationMode.Value.ToString() : "vanilla (no setting)") + (localPlayer.NoCostCheat() ? " (no-cost cheat on)" : string.Empty))); foreach (ItemData item in from i in ((Humanoid)localPlayer).GetInventory().GetAllItems() where i.m_shared.m_useDurability && i.m_durability < i.GetMaxDurability() select i) { float num = 1f - item.m_durability / item.GetMaxDurability(); Dictionary<string, int> cost = Repairer.GetCost(item, num, localPlayer); string text = ((cost.Count == 0) ? "free" : string.Join(", ", cost.Select((KeyValuePair<string, int> c) => $"{c.Value} {c.Key}"))); Recipe recipe = Stations.GetRecipe(item); string text2 = (((Object)(object)recipe?.m_craftingStation != (Object)null) ? Utils.GetPrefabName(((Component)recipe.m_craftingStation).gameObject) : "none"); string text3 = (((Object)(object)currentCraftingStation == (Object)null || (Object)(object)InventoryGui.instance == (Object)null) ? "no station" : (Repairer.CanRepair(InventoryGui.instance, item) ? "repairable here" : "NOT repairable here")); stringBuilder.AppendLine($" {item.m_shared.m_name} {item.m_quality}* ({num:P0} damaged, crafted at {text2} level {recipe?.m_minStationLevel ?? 0}): {text3}, cost {text}"); } } string text4 = Localization.instance.Localize(stringBuilder.ToString()); string[] array = text4.TrimEnd(Array.Empty<char>()).Split(new char[1] { '\n' }); foreach (string text5 in array) { Console.instance.Print(text5.TrimEnd(new char[1] { '\r' })); } Plugin.Log.LogInfo((object)text4); } } public enum Toggle { Off, On } public enum ButtonMode { OneItem, All } public enum CostMode { Free, Materials, Coins } public enum StationMode { Vanilla, AssignedAnyLevel, All } [BepInPlugin("txc.repairtweaks", "TXC Repair Tweaks", "1.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] [SynchronizationMode(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { public const string PluginGuid = "txc.repairtweaks"; public const string PluginName = "TXC Repair Tweaks"; public const string PluginVersion = "1.0.0"; private const string RepairSection = "1 - Repair"; private const string CostSection = "2 - Repair Cost"; private const string StationsSection = "3 - Stations"; internal static ManualLogSource Log; internal static ConfigEntry<Toggle> AutoRepair; internal static ConfigEntry<ButtonMode> RepairButton; internal static ConfigEntry<CostMode> Cost; internal static ConfigEntry<float> MaterialPercent; internal static ConfigEntry<int> CoinsFullRepair; private Harmony _harmony; private void Awake() { //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; AutoRepair = ((BaseUnityPlugin)this).Config.Bind<Toggle>("1 - Repair", "AutoRepair", Toggle.Off, Admin("On = opening a crafting station repairs every damaged item that station can repair (and that the player can pay for), and the repair button is hidden. With TradersExtended, opening a trader that repairs does the same, at the trader's own price.")); RepairButton = ((BaseUnityPlugin)this).Config.Bind<ButtonMode>("1 - Repair", "ButtonMode", ButtonMode.OneItem, Admin("What the repair button does. OneItem = vanilla, one item per click. All = every repairable item at once. Also applies to the TradersExtended trader repair button. Crafting stations don't use it while AutoRepair is On (the button is hidden).")); Cost = ((BaseUnityPlugin)this).Config.Bind<CostMode>("2 - Repair Cost", "CostMode", CostMode.Free, Admin("Repair cost at crafting stations. Free = vanilla. Materials = a share of the item's crafting materials. Coins = coins. Costs scale with missing durability.")); MaterialPercent = ((BaseUnityPlugin)this).Config.Bind<float>("2 - Repair Cost", "MaterialPercent", 25f, Admin("Materials mode: % of the materials used to craft the item up to its current quality, for a fully broken item. Each material is rounded up.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f))); CoinsFullRepair = ((BaseUnityPlugin)this).Config.Bind<int>("2 - Repair Cost", "Coins", 50, Admin("Coins mode: coins for a fully broken item, rounded up.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100000))); Stations.Bind(((BaseUnityPlugin)this).Config, "3 - Stations"); _harmony = new Harmony("txc.repairtweaks"); _harmony.PatchAll(typeof(RepairPatches)); TradersExtendedRepair.TryPatch(_harmony); CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new RepairInfoCommand()); Log.LogInfo((object)"TXC Repair Tweaks 1.0.0 loaded."); } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } internal static ConfigDescription Admin(string description, AcceptableValueBase range = null) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown return new ConfigDescription(description, range, new object[1] { (object)new ConfigurationManagerAttributes { IsAdminOnly = true } }); } } internal static class RepairPatches { private static bool _canRepairErrorLogged; [HarmonyPatch(typeof(InventoryGui), "CanRepair")] [HarmonyPrefix] private static bool CanRepairPrefix(ItemData item, ref bool __result) { try { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || item == null || !item.m_shared.m_canBeReparied) { return true; } CraftingStation currentCraftingStation = localPlayer.GetCurrentCraftingStation(); StationMode? stationMode = (((Object)(object)currentCraftingStation != (Object)null) ? Stations.GetMode(currentCraftingStation) : ((StationMode?)null)); if (!stationMode.HasValue) { return true; } __result = Stations.Allows(stationMode.Value, item, currentCraftingStation); return false; } catch (Exception arg) { if (!_canRepairErrorLogged) { _canRepairErrorLogged = true; Plugin.Log.LogError((object)$"Repair check failed, using vanilla rules: {arg}"); } return true; } } [HarmonyPatch(typeof(InventoryGui), "RepairOneItem")] [HarmonyPrefix] private static bool RepairOneItemPrefix(InventoryGui __instance) { try { Repairer.Repair(__instance, Plugin.RepairButton.Value == ButtonMode.All, auto: false); return false; } catch (Exception arg) { Plugin.Log.LogError((object)$"Repair failed, falling back to vanilla: {arg}"); return true; } } [HarmonyPatch(typeof(CraftingStation), "Interact")] [HarmonyPostfix] private static void InteractPostfix(CraftingStation __instance, Humanoid user, bool repeat) { try { if (!repeat && Plugin.AutoRepair.Value != Toggle.Off && __instance.m_canRepair) { Player val = (Player)(object)((user is Player) ? user : null); if (!((Object)(object)val == (Object)null) && !((Object)(object)val != (Object)(object)Player.m_localPlayer) && !((Object)(object)val.GetCurrentCraftingStation() != (Object)(object)__instance) && InventoryGui.IsVisible()) { Repairer.Repair(InventoryGui.instance, all: true, auto: true); } } } catch (Exception arg) { Plugin.Log.LogError((object)$"Auto-repair failed: {arg}"); } } [HarmonyPatch(typeof(InventoryGui), "UpdateRepair")] [HarmonyPrefix] private static bool UpdateRepairPrefix(InventoryGui __instance) { if (Plugin.AutoRepair.Value == Toggle.Off) { return true; } if (((Component)__instance.m_repairButton).gameObject.activeSelf) { ((Component)__instance.m_repairButton).gameObject.SetActive(false); ((Component)__instance.m_repairPanel).gameObject.SetActive(false); ((Component)__instance.m_repairPanelSelection).gameObject.SetActive(false); } return false; } } internal static class Repairer { private const string CoinsName = "$item_coins"; internal static readonly Func<InventoryGui, ItemData, bool> CanRepair = AccessTools.MethodDelegate<Func<InventoryGui, ItemData, bool>>(AccessTools.Method(typeof(InventoryGui), "CanRepair", (Type[])null, (Type[])null), (object)null, true); internal static void Repair(InventoryGui gui, bool all, bool auto) { //IL_0288: Unknown result type (might be due to invalid IL or missing references) //IL_028d: Unknown result type (might be due to invalid IL or missing references) //IL_029b: Unknown result type (might be due to invalid IL or missing references) //IL_02a1: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return; } CraftingStation currentCraftingStation = localPlayer.GetCurrentCraftingStation(); if (((Object)(object)currentCraftingStation == (Object)null && !localPlayer.NoCostCheat()) || ((Object)(object)currentCraftingStation != (Object)null && !currentCraftingStation.CheckUsable(localPlayer, false))) { return; } Inventory inventory = ((Humanoid)localPlayer).GetInventory(); List<ItemData> list = new List<ItemData>(); inventory.GetWornItems(list); List<ItemData> list2 = list.Where((ItemData item) => CanRepair(gui, item)).ToList(); if (list2.Count == 0) { if (!auto) { ((Character)localPlayer).Message((MessageType)2, "No more item to repair", 0, (Sprite)null, false); } return; } Dictionary<string, int> dictionary = new Dictionary<string, int>(); List<ItemData> list3 = new List<ItemData>(); List<KeyValuePair<ItemData, Dictionary<string, int>>> list4 = new List<KeyValuePair<ItemData, Dictionary<string, int>>>(); foreach (ItemData item in list2) { float num = 1f - item.m_durability / item.GetMaxDurability(); Dictionary<string, int> cost = GetCost(item, num, localPlayer); if (!cost.All((KeyValuePair<string, int> c) => inventory.CountItems(c.Key, -1, false) >= c.Value)) { list4.Add(new KeyValuePair<ItemData, Dictionary<string, int>>(item, cost)); continue; } foreach (KeyValuePair<string, int> item2 in cost) { inventory.RemoveItem(item2.Key, item2.Value, -1, false); dictionary[item2.Key] = (dictionary.TryGetValue(item2.Key, out var value) ? value : 0) + item2.Value; } ((Character)localPlayer).RaiseSkill((SkillType)107, num); item.m_durability = item.GetMaxDurability(); list3.Add(item); if (all) { continue; } break; } if (list3.Count == 0) { KeyValuePair<ItemData, Dictionary<string, int>> keyValuePair = list4[0]; string text = ((list4.Count > 1) ? $"\n({list4.Count} items can't be paid for)" : string.Empty); ((Character)localPlayer).Message((MessageType)2, Localize("Can't repair " + keyValuePair.Key.m_shared.m_name + "\nNeeds: " + Describe(keyValuePair.Value) + text), 0, (Sprite)null, false); return; } if ((Object)(object)currentCraftingStation != (Object)null) { currentCraftingStation.m_repairItemDoneEffects.Create(((Component)currentCraftingStation).transform.position, Quaternion.identity, (Transform)null, 1f, -1, default(ZDOID)); } string text2 = ((list3.Count == 1) ? Localization.instance.Localize("$msg_repaired", new string[1] { list3[0].m_shared.m_name }) : string.Format("{0} {1} items", auto ? "Auto-repaired" : "Repaired", list3.Count)); if (dictionary.Count > 0) { text2 = text2 + "\nCost: " + Localize(Describe(dictionary)); } if (all && list4.Count > 0) { text2 += $"\n{list4.Count} item(s) not repaired: can't pay"; } ((Character)localPlayer).Message((MessageType)2, text2, 0, (Sprite)null, false); } internal static Dictionary<string, int> GetCost(ItemData item, float missing, Player player) { Dictionary<string, int> dictionary = new Dictionary<string, int>(); if (player.NoCostCheat() || missing <= 0f) { return dictionary; } switch (Plugin.Cost.Value) { case CostMode.Coins: { int num3 = Scale(Plugin.CoinsFullRepair.Value, missing); if (num3 > 0) { dictionary["$item_coins"] = num3; } break; } case CostMode.Materials: { float value = Plugin.MaterialPercent.Value; Recipe recipe = Stations.GetRecipe(item); if ((Object)(object)recipe == (Object)null || recipe.m_resources == null) { break; } Requirement[] resources = recipe.m_resources; foreach (Requirement val in resources) { if (!((Object)(object)val?.m_resItem == (Object)null)) { int num = 0; for (int j = 1; j <= item.m_quality; j++) { num += val.GetAmount(j); } int num2 = Scale((float)num * value / 100f, missing); if (num2 > 0) { string name = val.m_resItem.m_itemData.m_shared.m_name; dictionary[name] = (dictionary.TryGetValue(name, out var value2) ? value2 : 0) + num2; } } } break; } } return dictionary; } private static int Scale(float fullAmount, float missing) { return Mathf.Max(0, Mathf.CeilToInt(fullAmount * missing - 0.001f)); } private static string Describe(Dictionary<string, int> cost) { List<string> list = cost.Select((KeyValuePair<string, int> c) => $"{c.Value} {c.Key}").ToList(); List<string> list2 = new List<string>(); for (int num = 0; num < list.Count; num += 2) { list2.Add(string.Join(", ", list.Skip(num).Take(2))); } return string.Join(",\n", list2); } private static string Localize(string text) { return Localization.instance.Localize(text); } } internal static class Stations { private static readonly (string Key, string Prefab, string Label)[] Known = new(string, string, string)[5] { ("Workbench", "piece_workbench", "Workbench"), ("Forge", "forge", "Forge"), ("BlackForge", "blackforge", "Black forge"), ("GaldrTable", "piece_magetable", "Galdr table"), ("ArtisanTable", "piece_artisanstation", "Artisan table") }; private static readonly Dictionary<string, ConfigEntry<StationMode>> ModeByPrefab = new Dictionary<string, ConfigEntry<StationMode>>(); private static readonly Dictionary<string, Recipe> RecipeCache = new Dictionary<string, Recipe>(); private static ObjectDB _recipeCacheDb; private static int _recipeCacheCount; internal static void Bind(ConfigFile config, string section) { (string, string, string)[] known = Known; for (int i = 0; i < known.Length; i++) { var (text, key, text2) = known[i]; ModeByPrefab[key] = config.Bind<StationMode>(section, text, StationMode.Vanilla, Plugin.Admin("What the " + text2 + " repairs. Vanilla = vanilla rules (each item needs its station level). AssignedAnyLevel = the items it repairs in vanilla, at any " + text2 + " level. All = every repairable item, at any level.")); } } internal static StationMode? GetMode(CraftingStation station) { if (!ModeByPrefab.TryGetValue(Utils.GetPrefabName(((Component)station).gameObject), out var value)) { return null; } return value.Value; } internal static bool Allows(StationMode mode, ItemData item, CraftingStation station) { return mode switch { StationMode.All => true, StationMode.AssignedAnyLevel => VanillaAllows(item, station, ignoreLevel: true), _ => VanillaAllows(item, station, ignoreLevel: false), }; } internal static bool VanillaAllows(ItemData item, CraftingStation station, bool ignoreLevel) { Recipe recipe = GetRecipe(item); if ((Object)(object)recipe == (Object)null || ((Object)(object)recipe.m_craftingStation == (Object)null && (Object)(object)recipe.m_repairStation == (Object)null)) { return false; } if (((Object)(object)recipe.m_repairStation != (Object)null && recipe.m_repairStation.m_name == station.m_name) || ((Object)(object)recipe.m_craftingStation != (Object)null && recipe.m_craftingStation.m_name == station.m_name) || item.m_worldLevel < Game.m_worldLevel) { if (!ignoreLevel) { return Mathf.Min(station.GetLevel(true), 4) >= recipe.m_minStationLevel; } return true; } return false; } internal static Recipe GetRecipe(ItemData item) { ObjectDB instance = ObjectDB.instance; if ((Object)(object)instance == (Object)null) { return null; } if ((Object)(object)instance != (Object)(object)_recipeCacheDb || instance.m_recipes.Count != _recipeCacheCount) { RecipeCache.Clear(); _recipeCacheDb = instance; _recipeCacheCount = instance.m_recipes.Count; } string name = item.m_shared.m_name; if (!RecipeCache.TryGetValue(name, out var value)) { value = instance.GetRecipe(item); RecipeCache[name] = value; } return value; } internal static string Describe() { return string.Join(", ", Known.Select(((string Key, string Prefab, string Label) k) => $"{k.Label}: {ModeByPrefab[k.Prefab].Value}")); } } internal static class TradersExtendedRepair { internal const string TradersExtendedGuid = "shudnal.TradersExtended"; private static MethodInfo _repairOneItem; private static Func<StoreGui, ItemData> _getItemToRepair; private static Func<Trader, bool> _traderCanRepair; private static FieldInfo _repairPanelField; private static readonly FieldRef<StoreGui, Trader> StoreTrader = AccessTools.FieldRefAccess<StoreGui, Trader>("m_trader"); private static bool _looping; internal static void TryPatch(Harmony harmony) { //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Expected O, but got Unknown //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Expected O, but got Unknown //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Expected O, but got Unknown //IL_01f5: Expected O, but got Unknown if (Chainloader.PluginInfos.ContainsKey("shudnal.TradersExtended")) { Type type = AccessTools.TypeByName("TradersExtended.RepairPanel"); _repairOneItem = ((type == null) ? null : AccessTools.Method(type, "RepairOneItem", new Type[1] { typeof(StoreGui) }, (Type[])null)); MethodInfo methodInfo = ((type == null) ? null : AccessTools.Method(type, "GetItemToRepair", new Type[1] { typeof(StoreGui) }, (Type[])null)); MethodInfo methodInfo2 = ((type == null) ? null : AccessTools.Method(type, "TraderCanRepair", new Type[1] { typeof(Trader) }, (Type[])null)); MethodInfo methodInfo3 = ((type == null) ? null : AccessTools.Method(type, "Update", new Type[1] { typeof(StoreGui) }, (Type[])null)); _repairPanelField = ((type == null) ? null : AccessTools.Field(type, "repairPanel")); if (_repairOneItem == null || methodInfo == null || methodInfo2 == null || methodInfo3 == null || _repairPanelField == null) { Plugin.Log.LogWarning((object)"TradersExtended found, but its trader repair code has changed; ButtonMode/AutoRepair won't apply to trader repairs."); return; } _getItemToRepair = (Func<StoreGui, ItemData>)Delegate.CreateDelegate(typeof(Func<StoreGui, ItemData>), methodInfo); _traderCanRepair = (Func<Trader, bool>)Delegate.CreateDelegate(typeof(Func<Trader, bool>), methodInfo2); harmony.Patch((MethodBase)_repairOneItem, new HarmonyMethod(typeof(TradersExtendedRepair), "RepairOneItemPrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); harmony.Patch((MethodBase)methodInfo3, (HarmonyMethod)null, new HarmonyMethod(typeof(TradersExtendedRepair), "PanelUpdatePostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); harmony.Patch((MethodBase)AccessTools.Method(typeof(StoreGui), "Show", (Type[])null, (Type[])null), new HarmonyMethod(typeof(TradersExtendedRepair), "StoreShowPrefix", (Type[])null), new HarmonyMethod(typeof(TradersExtendedRepair), "StoreShowPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); Plugin.Log.LogInfo((object)"Patched TradersExtended trader repair (follows ButtonMode and AutoRepair)."); } } private static bool RepairOneItemPrefix(StoreGui storeGui) { if (_looping || Plugin.RepairButton.Value != ButtonMode.All) { return true; } RepairAll(storeGui, auto: false); return false; } private static void PanelUpdatePostfix() { if (Plugin.AutoRepair.Value != Toggle.Off) { object? value = _repairPanelField.GetValue(null); GameObject val = (GameObject)((value is GameObject) ? value : null); if ((Object)(object)val != (Object)null && val.activeSelf) { val.SetActive(false); } } } private static void StoreShowPrefix(StoreGui __instance, Trader trader, out bool __state) { __state = (Object)(object)StoreTrader.Invoke(__instance) == (Object)(object)trader && StoreGui.IsVisible(); } private static void StoreShowPostfix(StoreGui __instance, Trader trader, bool __state) { try { if (!__state && Plugin.AutoRepair.Value != Toggle.Off && !((Object)(object)trader == (Object)null) && _traderCanRepair(trader) && _getItemToRepair(__instance) != null) { RepairAll(__instance, auto: true); } } catch (Exception arg) { Plugin.Log.LogError((object)$"Trader auto-repair failed: {arg}"); } } private static void RepairAll(StoreGui storeGui, bool auto) { _looping = true; int num = 0; try { for (int i = 0; i < 1000; i++) { ItemData val = _getItemToRepair(storeGui); if (val != null || i <= 0) { _repairOneItem.Invoke(null, new object[1] { storeGui }); if (val != null && !(val.m_durability < val.GetMaxDurability())) { num++; continue; } break; } break; } } catch (Exception arg) { Plugin.Log.LogError((object)$"Trader repair-all failed: {arg}"); } finally { _looping = false; } if (num > 1 && (Object)(object)Player.m_localPlayer != (Object)null) { ((Character)Player.m_localPlayer).Message((MessageType)2, string.Format("{0} {1} items", auto ? "Auto-repaired" : "Repaired", num), 0, (Sprite)null, false); } } } }