Decompiled source of UnifiedAutoRepair v1.0.1

plugins/UnifiedAutoRepair/UnifiedAutoRepair.dll

Decompiled 19 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("0.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[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 UnifiedAutoRepair
{
	[BepInPlugin("com.xman0922.unifiedautorepair", "Unified Auto Repair", "1.0.1")]
	public sealed class Plugin : BaseUnityPlugin
	{
		public const string PluginGuid = "com.xman0922.unifiedautorepair";

		public const string PluginName = "Unified Auto Repair";

		public const string PluginVersion = "1.0.1";

		internal static ManualLogSource Log = null;

		private static ConfigEntry<bool> repairEnabled = null;

		private static readonly MethodInfo? HaveRepairableItems = AccessTools.Method(typeof(InventoryGui), "HaveRepairableItems", (Type[])null, (Type[])null);

		private static readonly MethodInfo? RepairOneItem = AccessTools.Method(typeof(InventoryGui), "RepairOneItem", (Type[])null, (Type[])null);

		private Harmony? harmony;

		private static int lastRunFrame = -1;

		private static bool IsKorean
		{
			get
			{
				Localization instance = Localization.instance;
				if (instance != null)
				{
					return string.Equals(instance.GetSelectedLanguage(), "Korean", StringComparison.OrdinalIgnoreCase);
				}
				return false;
			}
		}

		private void Awake()
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Expected O, but got Unknown
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			repairEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Automatic repair", "Enabled", true, "Repair every eligible equipped item when using a crafting station.");
			harmony = new Harmony("com.xman0922.unifiedautorepair");
			MethodInfo methodInfo = AccessTools.Method(typeof(CraftingStation), "Interact", (Type[])null, (Type[])null);
			MethodInfo methodInfo2 = AccessTools.Method(typeof(Player), "SetCraftingStation", (Type[])null, (Type[])null);
			if (methodInfo == null || HaveRepairableItems == null || RepairOneItem == null)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)"CraftingStation/InventoryGui repair methods were not found; automatic repair is inactive.");
				return;
			}
			harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(Plugin), "CraftingStationInteractPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			if (methodInfo2 != null)
			{
				harmony.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, new HarmonyMethod(typeof(Plugin), "SetCraftingStationPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Unified Auto Repair 1.0.1 loaded.");
		}

		private static void CraftingStationInteractPostfix(CraftingStation __instance, Humanoid user, bool repeat)
		{
			if (!repeat && !((Object)(object)user != (Object)(object)Player.m_localPlayer))
			{
				TryRepair(__instance, "interact");
			}
		}

		private static void SetCraftingStationPostfix(Player __instance, CraftingStation station)
		{
			if ((Object)(object)station != (Object)null && (Object)(object)__instance == (Object)(object)Player.m_localPlayer)
			{
				TryRepair(station, "station");
			}
		}

		private static void TryRepair(CraftingStation station, string trigger)
		{
			Player localPlayer = Player.m_localPlayer;
			InventoryGui instance = InventoryGui.instance;
			if (!repairEnabled.Value || (Object)(object)localPlayer == (Object)null || (Object)(object)instance == (Object)null)
			{
				return;
			}
			if ((Object)(object)localPlayer.GetCurrentCraftingStation() != (Object)(object)station)
			{
				Log.LogInfo((object)("Auto repair skipped at " + station.m_name + " (" + trigger + "): it is not the player's active station."));
			}
			else
			{
				if (lastRunFrame == Time.frameCount)
				{
					return;
				}
				lastRunFrame = Time.frameCount;
				int num = 0;
				bool flag = default(bool);
				while (true)
				{
					int num2;
					if (num < 256)
					{
						object obj = HaveRepairableItems.Invoke(instance, null);
						if (obj is bool)
						{
							flag = (bool)obj;
							num2 = 1;
						}
						else
						{
							num2 = 0;
						}
					}
					else
					{
						num2 = 0;
					}
					if (((uint)num2 & (flag ? 1u : 0u)) == 0)
					{
						break;
					}
					RepairOneItem.Invoke(instance, null);
					num++;
				}
				if (num > 0)
				{
					Log.LogInfo((object)$"Automatically repaired {num} item(s) at {station.m_name} (level {station.GetLevel(true)}).");
					((Character)localPlayer).Message((MessageType)2, IsKorean ? $"장비와 도구 {num}개 수리 완료" : $"Repaired {num} equipped item(s)", 0, (Sprite)null, false);
				}
				else
				{
					Diagnose(localPlayer, station);
				}
			}
		}

		private static void Diagnose(Player player, CraftingStation station)
		{
			List<ItemData> list = new List<ItemData>();
			((Humanoid)player).GetInventory().GetWornItems(list);
			if (list.Count == 0)
			{
				return;
			}
			int num = Mathf.Min(station.GetLevel(true), 4);
			bool flag = station.CheckUsable(player, false);
			Log.LogInfo((object)($"Auto repair at {station.m_name}: level {station.GetLevel(true)}, usable {flag}, " + $"canRepair {station.m_canRepair}, {list.Count} damaged item(s) but none repairable here."));
			foreach (ItemData item in list)
			{
				Recipe val = (((Object)(object)ObjectDB.instance != (Object)null) ? ObjectDB.instance.GetRecipe(item) : null);
				string text;
				if (!item.m_shared.m_canBeReparied)
				{
					text = "the item cannot be repaired";
				}
				else if ((Object)(object)val == (Object)null)
				{
					text = "no recipe";
				}
				else
				{
					string text2 = (((Object)(object)val.m_repairStation != (Object)null) ? val.m_repairStation.m_name : null);
					string text3 = (((Object)(object)val.m_craftingStation != (Object)null) ? val.m_craftingStation.m_name : null);
					text = ((text2 != station.m_name && text3 != station.m_name && item.m_worldLevel >= Game.m_worldLevel) ? ("repaired at " + (text2 ?? text3 ?? "(none)")) : ((num >= val.m_minStationLevel) ? (flag ? "unknown" : "station not usable here (roof or fire)") : $"needs station level {val.m_minStationLevel}, this one is {num}"));
				}
				Log.LogInfo((object)$"  {item.m_shared.m_name} {item.m_durability:0}/{item.GetMaxDurability():0}: {text}");
			}
		}

		private void OnDestroy()
		{
			Harmony? obj = harmony;
			if (obj != null)
			{
				obj.UnpatchSelf();
			}
		}
	}
}