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 ShieldRestyler v1.0.1
ShieldRestyler.dll
Decompiled a month agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using ShieldRestyler.Data; using ShieldRestyler.Patches; using UnityEngine; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("ShieldRestyler")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("HP")] [assembly: AssemblyProduct("ShieldRestyler")] [assembly: AssemblyCopyright("Copyright © HP 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("4b016a14-be14-4ddd-b106-a3020d02e2e3")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8.1", FrameworkDisplayName = ".NET Framework 4.8.1")] [assembly: AssemblyVersion("1.0.0.0")] namespace ShieldRestyler { [BepInPlugin("YouDied.ShieldRestyler", "Shield Restyler", "1.0.1")] [BepInProcess("valheim.exe")] public class ShieldRestylerPlugin : BaseUnityPlugin { public const string PluginGUID = "YouDied.ShieldRestyler"; public const string PluginName = "Shield Restyler"; public const string PluginVersion = "1.0.1"; internal static ManualLogSource Log; public static ConfigEntry<KeyboardShortcut> OpenStylerKey; private readonly Harmony _harmony = new Harmony("YouDied.ShieldRestyler"); private void Awake() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; OpenStylerKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "OpenStylerKey", new KeyboardShortcut((KeyCode)96, Array.Empty<KeyCode>()), "Press while hovering a shield in the inventory grid to cycle its visual style."); _harmony.PatchAll(); InventoryGui_Patches.Apply(_harmony); ManualLogSource log = Log; KeyboardShortcut value = OpenStylerKey.Value; log.LogInfo((object)string.Format("{0} {1} loaded. Press [{2}] while hovering a shield to cycle styles.", "Shield Restyler", "1.0.1", ((KeyboardShortcut)(ref value)).MainKey)); } private void OnDestroy() { _harmony.UnpatchSelf(); } } } namespace ShieldRestyler.Patches { public static class InventoryGui_Patches { internal static ItemData LastHoveredShield; public static void Apply(Harmony harmony) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Expected O, but got Unknown BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; MethodInfo method = typeof(InventoryGui).GetMethod("Update", bindingAttr); if (method != null) { harmony.Patch((MethodBase)method, (HarmonyMethod)null, new HarmonyMethod(typeof(InventoryGui_Patches), "Update_Postfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); ShieldRestylerPlugin.Log.LogInfo((object)"[ShieldRestyler] Patched InventoryGui.Update"); } } private static void Update_Postfix() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) if (!InventoryGui.IsVisible()) { return; } KeyboardShortcut value = ShieldRestylerPlugin.OpenStylerKey.Value; KeyCode mainKey = ((KeyboardShortcut)(ref value)).MainKey; if (Input.GetKeyDown(mainKey) && LastHoveredShield != null) { string prefabName = GetPrefabName(LastHoveredShield); if (ShieldVariantDatabase.HasVariants(prefabName)) { List<string> variants = ShieldVariantDatabase.GetVariants(prefabName); int num = (LastHoveredShield.m_variant + 1) % variants.Count; LastHoveredShield.m_variant = num; string slotKey = StyleSaveData.MakeSlotKey(LastHoveredShield); StyleSaveData.SetChoice(slotKey, num); ShieldRestylerPlugin.Log.LogInfo((object)$"[ShieldRestyler] {LastHoveredShield.m_shared.m_name} → variant {num} ({variants[num]})"); } } } internal static string GetPrefabName(ItemData item) { if ((Object)(object)item.m_dropPrefab != (Object)null) { return ((Object)item.m_dropPrefab).name; } string text = item.m_shared.m_name.Replace("$item_", ""); string[] array = text.Split(new char[1] { '_' }); StringBuilder stringBuilder = new StringBuilder(); string[] array2 = array; foreach (string text2 in array2) { if (text2.Length > 0) { stringBuilder.Append(char.ToUpper(text2[0])).Append(text2.Substring(1)); } } return stringBuilder.ToString(); } } [HarmonyPatch(typeof(InventoryGrid), "UpdateGui")] public static class InventoryGrid_UpdateGui_Patch { private static FieldInfo _elementsField; private static PropertyInfo _positionProp; private static MethodInfo _getRectMethod; private static bool _ready; [HarmonyPostfix] private static void Postfix(InventoryGrid __instance) { //IL_01e6: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_034d: Unknown result type (might be due to invalid IL or missing references) //IL_0353: Invalid comparison between Unknown and I4 //IL_02a6: Unknown result type (might be due to invalid IL or missing references) //IL_02a7: Unknown result type (might be due to invalid IL or missing references) //IL_0301: Unknown result type (might be due to invalid IL or missing references) //IL_0306: Unknown result type (might be due to invalid IL or missing references) //IL_02d9: Unknown result type (might be due to invalid IL or missing references) //IL_02de: Unknown result type (might be due to invalid IL or missing references) //IL_030a: Unknown result type (might be due to invalid IL or missing references) //IL_0311: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Player.m_localPlayer == (Object)null || __instance.GetInventory() != ((Humanoid)Player.m_localPlayer).GetInventory() || !InventoryGui.IsVisible()) { return; } if (!_ready) { BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; _elementsField = typeof(InventoryGrid).GetField("m_elements", bindingFlags); if (_elementsField == null) { Log("m_elements field not found"); return; } if (!(_elementsField.GetValue(__instance) is IList { Count: not 0 } list)) { return; } Type type = list[0].GetType(); _positionProp = type.GetProperty("Position", bindingFlags | BindingFlags.GetProperty); if (_positionProp == null) { FieldInfo field = type.GetField("<Position>k__BackingField", bindingFlags); if (!(field != null)) { Log("Position property/field not found on element type"); return; } _elementsField = _elementsField; Log("Using backing field for Position on " + type.Name); } _getRectMethod = type.GetMethod("GetElementRectTransform", bindingFlags); if (_getRectMethod == null) { Log("GetElementRectTransform not found — falling back to m_button"); } _ready = true; Log("InventoryGrid fields resolved on type '" + type.Name + "'."); } if (!_ready || !(_elementsField.GetValue(__instance) is IList list2)) { return; } Inventory inventory = __instance.GetInventory(); Vector3 mousePosition = Input.mousePosition; ItemData val = null; BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; foreach (object item in list2) { RectTransform val2 = null; if (_getRectMethod != null) { object? obj = _getRectMethod.Invoke(item, null); val2 = (RectTransform)((obj is RectTransform) ? obj : null); } if ((Object)(object)val2 == (Object)null) { object? obj2 = item.GetType().GetField("m_button", bindingAttr)?.GetValue(item); Button val3 = (Button)((obj2 is Button) ? obj2 : null); val2 = ((val3 != null) ? ((Component)val3).GetComponent<RectTransform>() : null); } if ((Object)(object)val2 == (Object)null || !((Component)val2).gameObject.activeInHierarchy || !RectTransformUtility.RectangleContainsScreenPoint(val2, Vector2.op_Implicit(mousePosition))) { continue; } Vector2i val4; if (_positionProp != null) { val4 = (Vector2i)_positionProp.GetValue(item); } else { FieldInfo field2 = item.GetType().GetField("<Position>k__BackingField", bindingAttr); val4 = (Vector2i)field2.GetValue(item); } val = inventory.GetItemAt(val4.x, val4.y); break; } InventoryGui_Patches.LastHoveredShield = ((val != null && (int)val.m_shared.m_itemType == 5) ? val : null); } private static void Log(string msg) { ShieldRestylerPlugin.Log.LogInfo((object)("[ShieldRestyler] " + msg)); } } [HarmonyPatch(typeof(Player), "OnSpawned")] public static class Player_OnSpawned_Patch { [HarmonyPostfix] private static void Postfix(Player __instance) { //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Invalid comparison between Unknown and I4 if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer) { return; } Game instance = Game.instance; object obj; if (instance == null) { obj = null; } else { PlayerProfile playerProfile = instance.GetPlayerProfile(); obj = ((playerProfile != null) ? playerProfile.GetName() : null); } if (obj == null) { obj = "unknown"; } string characterName = (string)obj; StyleSaveData.LoadForCharacter(characterName); Inventory inventory = ((Humanoid)__instance).GetInventory(); if (inventory == null) { return; } foreach (ItemData allItem in inventory.GetAllItems()) { if ((int)allItem.m_shared.m_itemType == 5) { string prefabName = (((Object)(object)allItem.m_dropPrefab != (Object)null) ? ((Object)allItem.m_dropPrefab).name : ""); if (ShieldVariantDatabase.HasVariants(prefabName)) { allItem.m_variant = StyleSaveData.GetChoice(StyleSaveData.MakeSlotKey(allItem)); } } } } } } namespace ShieldRestyler.Data { public static class ShieldVariantDatabase { public static readonly Dictionary<string, List<string>> Variants = new Dictionary<string, List<string>> { { "ShieldWood", new List<string> { "Plain", "Iron Rivets", "Sun Cross", "Spirals" } }, { "ShieldWoodTower", new List<string> { "Plain", "Diamond", "Cross", "Banded" } }, { "ShieldBoneTower", new List<string> { "Ribbed", "Skull Face", "Spine Cross", "Jagged" } }, { "ShieldBronze", new List<string> { "Plain", "Concentric Rings", "Sun Boss", "Etched Rim" } }, { "ShieldBronzeBuckler", new List<string> { "Plain", "Punched", "Riveted", "Embossed" } }, { "ShieldIron", new List<string> { "Plain", "Banded", "Studded", "Engraved", "Worn" } }, { "ShieldIronTower", new List<string> { "Plain", "Flanged", "Cross Guard", "Spiked", "Runic" } }, { "ShieldIronBuckler", new List<string> { "Smooth", "Hammered", "Punched", "Etched" } }, { "ShieldSilver", new List<string> { "Plain", "Moon Crest", "Wolf Howl", "Frost Rune", "Dragon Fang", "Blizzard" } }, { "ShieldBlackmetal", new List<string> { "Plain", "Serpent Eye", "Fuling Glyph", "Death Mark", "Tar Splash", "Runed", "Warlord" } }, { "ShieldBlackmetalTower", new List<string> { "Plain", "Spiked", "Rune Wall", "Glyph Crest", "War Chief", "Obsidian" } }, { "ShieldCarapace", new List<string> { "Natural", "Polished", "Cracked", "Runed", "Seeker Glyph" } }, { "ShieldCarapaceBuckler", new List<string> { "Natural", "Polished", "Cracked", "Runed" } }, { "ShieldFlametal", new List<string> { "Ember", "Scorched", "Molten", "Ash Rune", "Cinder Crest", "Inferno" } }, { "ShieldFlametalTower", new List<string> { "Ember", "Scorched", "Molten", "Ash Rune", "Cinder Crest", "Inferno", "Volcanic" } }, { "ShieldGold", new List<string> { "Style 1", "Style 2", "Style 3", "Style 4", "Style 5" } }, { "ShieldGoldTower", new List<string> { "Style 1", "Style 2", "Style 3", "Style 4", "Style 5" } }, { "ShieldRoots", new List<string> { "Style 1", "Style 2", "Style 3" } } }; public static bool HasVariants(string prefabName) { return Variants.ContainsKey(prefabName); } public static List<string> GetVariants(string prefabName) { List<string> value; return Variants.TryGetValue(prefabName, out value) ? value : null; } } public static class StyleSaveData { private static readonly string SaveDir = Path.Combine(Paths.ConfigPath, "ShieldRestyler"); private static Dictionary<string, int> _choices = new Dictionary<string, int>(); private static string _currentCharacter = ""; private static ManualLogSource Log => ShieldRestylerPlugin.Log; public static int GetChoice(string slotKey) { int value; return _choices.TryGetValue(slotKey, out value) ? value : 0; } public static void SetChoice(string slotKey, int variant) { _choices[slotKey] = variant; SaveToDisk(); } public static void LoadForCharacter(string characterName) { _currentCharacter = characterName; _choices.Clear(); string savePath = GetSavePath(characterName); if (!File.Exists(savePath)) { return; } string[] array = File.ReadAllLines(savePath); foreach (string text in array) { if (!string.IsNullOrWhiteSpace(text)) { string[] array2 = text.Split(new char[1] { '=' }); if (array2.Length == 2 && int.TryParse(array2[1], out var result)) { _choices[array2[0]] = result; } } } Log.LogDebug((object)$"[StyleSaveData] Loaded {_choices.Count} choices for '{characterName}'."); } private static void SaveToDisk() { if (string.IsNullOrEmpty(_currentCharacter)) { return; } Directory.CreateDirectory(SaveDir); List<string> list = new List<string>(); foreach (KeyValuePair<string, int> choice in _choices) { list.Add($"{choice.Key}={choice.Value}"); } File.WriteAllLines(GetSavePath(_currentCharacter), list); } private static string GetSavePath(string characterName) { return Path.Combine(SaveDir, characterName + ".cfg"); } public static string MakeSlotKey(ItemData item) { string arg = (((Object)(object)item.m_dropPrefab != (Object)null) ? ((Object)item.m_dropPrefab).name : item.m_shared.m_name); return $"{arg}_{item.m_gridPos.x}_{item.m_gridPos.y}"; } } }