Decompiled source of FastRepairButton v1.0.0

BepInEx/plugins/FastRepairButton/FastRepairButton.dll

Decompiled 3 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using FastRepairButton.Localization;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Shared.BasePlugin;
using Shared.Localization;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("FastRepairButton")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0")]
[assembly: AssemblyProduct("FastRepairButton")]
[assembly: AssemblyTitle("FastRepairButton")]
[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;
		}
	}
}
internal static class PluginInfo
{
	public const string GUID = "com.rutabaga.fastrepairbutton";

	public const string NAME = "FastRepairButton";

	public const string VERSION = "1.0";
}
namespace FastRepairButton
{
	[BepInPlugin("com.rutabaga.fastrepairbutton", "FastRepairButton", "1.0")]
	public class FastRepairButton : AValheimModPlugin
	{
		protected override void Initialize()
		{
			Localization.OnLanguageChange = (Action)Delegate.Combine(Localization.OnLanguageChange, new Action(LocalizationUpdater.UpdateRepairButtonHoverText));
		}

		protected override void Cleanup()
		{
			Localization.OnLanguageChange = (Action)Delegate.Remove(Localization.OnLanguageChange, new Action(LocalizationUpdater.UpdateRepairButtonHoverText));
		}
	}
}
namespace FastRepairButton.Localization
{
	public static class LocalizationData
	{
		public const string REPAIR_BUTTON_HOVER_TEXT_KEY = "RepairAll";

		public const string REPAIR_COMPLETE_MESSAGE_TEXT_KEY = "RepairComplete";
	}
	public static class LocalizationUpdater
	{
		public static void UpdateRepairButtonHoverText()
		{
			string localizedText = LocalizationManager.GetLocalizedText("RepairAll");
			if ((Object)(object)InventoryGui.instance == (Object)null)
			{
				AValheimModPlugin.Log.LogWarning((object)"InventoryGui instance is null. Aborting setting fast repair text.");
				return;
			}
			UITooltip component = ((Component)InventoryGui.instance.m_repairButton).GetComponent<UITooltip>();
			if ((Object)(object)component == (Object)null)
			{
				AValheimModPlugin.Log.LogWarning((object)"Can't find UITooltip for Repair Button. Aborting setting fast repair text.");
			}
			else
			{
				component.m_text = localizedText;
			}
		}
	}
}
namespace FastRepairButton.Behaviours
{
	[HarmonyPatch(typeof(InventoryGui), "Awake")]
	public static class InventoryGuiPatch
	{
		[HarmonyPostfix]
		private static void Postfix()
		{
			LocalizationUpdater.UpdateRepairButtonHoverText();
		}
	}
	public static class RepairButtonPressedHandler
	{
		private static readonly MethodInfo _updateRepairMethod = AccessTools.Method(typeof(InventoryGui), "UpdateRepair", (Type[])null, (Type[])null);

		private static readonly MethodInfo _updateCraftingPanelMethod = AccessTools.Method(typeof(InventoryGui), "UpdateCraftingPanel", new Type[1] { typeof(bool) }, (Type[])null);

		private static readonly MethodInfo _setActiveGroupMethod = AccessTools.Method(typeof(InventoryGui), "SetActiveGroup", new Type[2]
		{
			typeof(UIGroupHandler),
			typeof(bool)
		}, (Type[])null);

		private static readonly MethodInfo _canRepairMethod = AccessTools.Method(typeof(InventoryGui), "CanRepair", new Type[1] { typeof(ItemData) }, (Type[])null);

		private static readonly FieldInfo _tempWornItemsField = AccessTools.Field(typeof(InventoryGui), "m_tempWornItems");

		public static bool HandleRepairButtonPressed(InventoryGui a_inventoryGui)
		{
			if (!ValidateReflectionDependencies(out var a_logMessage))
			{
				AValheimModPlugin.Log.LogError((object)(a_logMessage + "\nAborting repair all, fallback to vanilla behaviour."));
				return false;
			}
			_setActiveGroupMethod.Invoke(a_inventoryGui, new object[2]
			{
				a_inventoryGui.m_uiGroups[3],
				true
			});
			RepairAllItems(a_inventoryGui);
			_updateRepairMethod.Invoke(a_inventoryGui, null);
			_updateCraftingPanelMethod.Invoke(a_inventoryGui, new object[1] { false });
			return true;
		}

		private static void RepairAllItems(InventoryGui a_inventoryGui)
		{
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Player.m_localPlayer == (Object)null)
			{
				return;
			}
			CraftingStation currentCraftingStation = Player.m_localPlayer.GetCurrentCraftingStation();
			if (((Object)(object)currentCraftingStation == (Object)null && !Player.m_localPlayer.NoCostCheat()) || ((Object)(object)currentCraftingStation != (Object)null && !currentCraftingStation.CheckUsable(Player.m_localPlayer, false)))
			{
				return;
			}
			List<ItemData> list = (List<ItemData>)_tempWornItemsField.GetValue(a_inventoryGui);
			list.Clear();
			((Humanoid)Player.m_localPlayer).GetInventory().GetWornItems(list);
			bool flag = false;
			foreach (ItemData item in list)
			{
				if ((bool)_canRepairMethod.Invoke(a_inventoryGui, new object[1] { item }))
				{
					((Character)Player.m_localPlayer).RaiseSkill((SkillType)107, 1f - item.m_durability / item.GetMaxDurability());
					item.m_durability = item.GetMaxDurability();
					if ((Object)(object)currentCraftingStation != (Object)null)
					{
						currentCraftingStation.m_repairItemDoneEffects.Create(((Component)currentCraftingStation).transform.position, Quaternion.identity, (Transform)null, 1f, -1, default(ZDOID));
					}
					flag = true;
				}
			}
			if (flag)
			{
				((Character)Player.m_localPlayer).Message((MessageType)2, LocalizationManager.GetLocalizedText("RepairComplete"), 0, (Sprite)null, false);
			}
			else
			{
				((Character)Player.m_localPlayer).Message((MessageType)2, "No more item to repair", 0, (Sprite)null, false);
			}
		}

		private static bool ValidateReflectionDependencies(out string a_logMessage)
		{
			if (_setActiveGroupMethod == null)
			{
				a_logMessage = "InventoryGui.SetActiveGroup method not found.";
				return false;
			}
			if (_canRepairMethod == null)
			{
				a_logMessage = "InventoryGui.CanRepair method not found.";
				return false;
			}
			if (_tempWornItemsField == null)
			{
				a_logMessage = "InventoryGui.m_tempWornItems field not found.";
				return false;
			}
			if (_updateRepairMethod == null)
			{
				a_logMessage = "InventoryGui.UpdateRepair method not found.";
				return false;
			}
			if (_updateCraftingPanelMethod == null)
			{
				a_logMessage = "InventoryGui.UpdateCraftingPanel method not found.";
				return false;
			}
			a_logMessage = "";
			return true;
		}
	}
	[HarmonyPatch(typeof(InventoryGui), "OnRepairPressed")]
	public static class RepairButtonPressedPatch
	{
		[HarmonyPrefix]
		public static bool Prefix(InventoryGui __instance)
		{
			if ((Object)(object)__instance == (Object)null)
			{
				AValheimModPlugin.Log.LogError((object)"InventoryGui instance is null.\nAborting repair all, fallback to vanilla behaviour.");
				return true;
			}
			return !RepairButtonPressedHandler.HandleRepairButtonPressed(__instance);
		}
	}
}
namespace Shared.Localization
{
	internal static class LocalizationManager
	{
		private const string FALLBACK_LANGUAGE = "English";

		public const string ENGLISH_KEY = "English";

		public const string SWEDISH_KEY = "Swedish";

		public const string FRENCH_KEY = "French";

		public const string ITALIAN_KEY = "Italian";

		public const string GERMAN_KEY = "German";

		public const string SPANISH_KEY = "Spanish";

		public const string RUSSIAN_KEY = "Russian";

		public const string ROMANIAN_KEY = "Romanian";

		public const string BULGARIAN_KEY = "Bulgarian";

		public const string MACEDONIAN_KEY = "Macedonian";

		public const string FINNISH_KEY = "Finnish";

		public const string DANISH_KEY = "Danish";

		public const string NORWEGIAN_KEY = "Norwegian";

		public const string ICELANDIC_KEY = "Icelandic";

		public const string TURKISH_KEY = "Turkish";

		public const string LITHUANIAN_KEY = "Lithuanian";

		public const string CZECH_KEY = "Czech";

		public const string HUNGARIAN_KEY = "Hungarian";

		public const string SLOVAK_KEY = "Slovak";

		public const string POLISH_KEY = "Polish";

		public const string DUTCH_KEY = "Dutch";

		public const string PORTUGUESE_EUROPEAN_KEY = "Portuguese_European";

		public const string PORTUGUESE_BRAZILIAN_KEY = "Portuguese_Brazilian";

		public const string CHINESE_KEY = "Chinese";

		public const string CHINESE_TRAD_KEY = "Chinese_Trad";

		public const string JAPANESE_KEY = "Japanese";

		public const string KOREAN_KEY = "Korean";

		public const string HINDI_KEY = "Hindi";

		public const string THAI_KEY = "Thai";

		public const string ABENAKI_KEY = "Abenaki";

		public const string CROATIAN_KEY = "Croatian";

		public const string GEORGIAN_KEY = "Georgian";

		public const string GREEK_KEY = "Greek";

		public const string SERBIAN_KEY = "Serbian";

		public const string UKRAINIAN_KEY = "Ukrainian";

		public const string LATVIAN_KEY = "Latvian";

		private static readonly Dictionary<string, Dictionary<string, string>> _translations = new Dictionary<string, Dictionary<string, string>>();

		public static void Initialize()
		{
			LoadTranslations();
		}

		private static void LoadTranslations()
		{
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			string[] manifestResourceNames = executingAssembly.GetManifestResourceNames();
			foreach (string text in manifestResourceNames)
			{
				if (!text.Contains(".Localization.Translations.") || !text.EndsWith(".json"))
				{
					continue;
				}
				string text2 = ExtractLanguageFromPath(text);
				using Stream stream = executingAssembly.GetManifestResourceStream(text);
				if (stream == null)
				{
					AValheimModPlugin.Log.LogWarning((object)("Failed to load translations for language " + text2 + ". The resource " + text + " could not be found."));
					continue;
				}
				using StreamReader streamReader = new StreamReader(stream);
				Dictionary<string, string> dictionary = JsonConvert.DeserializeObject<Dictionary<string, string>>(streamReader.ReadToEnd());
				if (dictionary == null)
				{
					AValheimModPlugin.Log.LogWarning((object)("Failed to load translations for language " + text2 + ". The JSON file " + text + " is empty or invalid."));
				}
				else
				{
					_translations[text2] = dictionary;
				}
			}
		}

		private static string ExtractLanguageFromPath(string a_resourceName)
		{
			return a_resourceName.Split(new char[1] { '.' })[^2];
		}

		public static string GetLocalizedText(string a_key)
		{
			Localization instance = Localization.instance;
			if (instance == null)
			{
				AValheimModPlugin.Log.LogWarning((object)"Localization instance is null. Returning key as fallback.");
				return a_key;
			}
			string selectedLanguage = instance.GetSelectedLanguage();
			if (!_translations.TryGetValue(selectedLanguage, out var value))
			{
				AValheimModPlugin.Log.LogWarning((object)("Can't find given language " + selectedLanguage + ". Returning key as fallback."));
				return a_key;
			}
			if (value.TryGetValue(a_key, out var value2))
			{
				return value2;
			}
			if (value.TryGetValue("English", out var value3))
			{
				AValheimModPlugin.Log.LogWarning((object)("Can't find translation for key " + a_key + " in " + selectedLanguage + ". Returning English translation as fallback."));
				return value3;
			}
			AValheimModPlugin.Log.LogWarning((object)("Can't find translation for key " + a_key + " in " + selectedLanguage + " and English. Returning key as fallback."));
			return a_key;
		}
	}
}
namespace Shared.BasePlugin
{
	public abstract class AValheimModPlugin : BaseUnityPlugin
	{
		private Harmony _harmony;

		internal static ManualLogSource Log { get; private set; }

		protected abstract void Initialize();

		protected abstract void Cleanup();

		private void Awake()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			LocalizationManager.Initialize();
			Initialize();
			_harmony = new Harmony("com.rutabaga.fastrepairbutton");
			_harmony.PatchAll();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"FastRepairButton 1.0 loaded!");
		}

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