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 Item Storage Categories v1.0.0
plugins/ChestLabels.dll
Decompiled 4 days 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.Versioning; using BepInEx; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("ChestLabels")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("ChestLabels")] [assembly: AssemblyTitle("ChestLabels")] [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 BenjSammy.ChestLabels { internal static class ChestIcon { private const string AssetName = "BENJSAMMYCHESTLABELS"; private static bool ready; private static bool failed; internal static bool IsReady() { //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: Unknown result type (might be due to invalid IL or missing references) //IL_01fd: Expected O, but got Unknown //IL_021d: Unknown result type (might be due to invalid IL or missing references) //IL_0222: Unknown result type (might be due to invalid IL or missing references) if (ready || failed || (Object)(object)ZNetScene.instance == (Object)null) { return ready; } ScriptableObject val = null; Material val2 = null; try { GameObject prefab = ZNetScene.instance.GetPrefab("piece_chest_wood"); Piece val3 = (((Object)(object)prefab == (Object)null) ? null : prefab.GetComponent<Piece>()); Sprite val4 = (Sprite)(((Object)(object)val3 == (Object)null) ? null : /*isinst with value type is only supported in some contexts*/); if ((Object)(object)val4 == (Object)null) { throw new InvalidOperationException("Wooden chest sprite is unavailable."); } Type type = RequireType("TMPro.TMP_SpriteAsset"); Type type2 = RequireType("TMPro.TMP_SpriteGlyph"); Type type3 = RequireType("TMPro.TMP_SpriteCharacter"); Type type4 = RequireType("TMPro.MaterialReferenceManager"); Type type5 = AccessTools.TypeByName("TMPro.TMP_TextParsingUtilities"); MethodInfo methodInfo = ((type5 == null) ? null : AccessTools.Method(type5, "GetHashCodeCaseInSensitive", new Type[1] { typeof(string) }, (Type[])null)); Type type6 = AccessTools.TypeByName("TMPro.TMP_TextUtilities"); MethodInfo methodInfo2 = ((type6 == null) ? null : AccessTools.Method(type6, "GetSimpleHashCode", new Type[1] { typeof(string) }, (Type[])null)); int num = (int)((methodInfo ?? methodInfo2)?.Invoke(null, new object[1] { "BENJSAMMYCHESTLABELS" }) ?? throw new InvalidOperationException("TMP asset hash API unavailable.")); Shader obj = Shader.Find("TextMeshPro/Sprite"); if ((Object)(object)obj == (Object)null) { throw new InvalidOperationException("TMP sprite shader unavailable."); } val = ScriptableObject.CreateInstance(type); ((Object)val).name = "BENJSAMMYCHESTLABELS"; PropertyInfo property = type.GetProperty("version", AccessTools.all); if (property?.GetSetMethod(nonPublic: true) != null) { property.SetValue(val, "1.1.0"); } else { Set(val, "m_Version", "1.1.0"); } val2 = new Material(obj) { mainTexture = (Texture)(object)val4.texture }; Set(val, "material", val2); Set(val, "spriteSheet", val4.texture); Rect textureRect = val4.textureRect; object obj2 = Activator.CreateInstance(type2); Set(obj2, "index", 0u); float num2 = 20f; float num3 = num2 * ((Rect)(ref textureRect)).width / ((Rect)(ref textureRect)).height; ConstructProperty(obj2, "metrics", num3, num2, 0f, 17f, num3 + 2f); ConstructProperty(obj2, "glyphRect", (int)((Rect)(ref textureRect)).x, (int)((Rect)(ref textureRect)).y, (int)((Rect)(ref textureRect)).width, (int)((Rect)(ref textureRect)).height); object obj3 = Activator.CreateInstance(type3, 57344u, val, obj2); Set(obj3, "name", "Chest"); AddEntry(val, "spriteGlyphTable", obj2); AddEntry(val, "spriteCharacterTable", obj3); AccessTools.Method(type, "UpdateLookupTables", Type.EmptyTypes, (Type[])null).Invoke(val, null); MethodInfo methodInfo3 = AccessTools.Method(type4, "AddSpriteAsset", new Type[2] { typeof(int), type }, (Type[])null); if (methodInfo3 == null) { throw new InvalidOperationException("TMP sprite registration API unavailable."); } methodInfo3.Invoke(null, new object[2] { num, val }); ready = true; } catch (Exception ex) { failed = true; if ((Object)(object)val != (Object)null) { Object.Destroy((Object)(object)val); } if ((Object)(object)val2 != (Object)null) { Object.Destroy((Object)(object)val2); } Logger.CreateLogSource("Item Storage Categories").LogWarning((object)("Chest icon unavailable, using text: " + ex.GetBaseException())); } return ready; } private static Type RequireType(string name) { return AccessTools.TypeByName(name) ?? throw new InvalidOperationException("Missing type " + name); } private static PropertyInfo Property(object target, string name) { return AccessTools.Property(target.GetType(), name) ?? throw new InvalidOperationException("Missing property " + name); } private static void Set(object target, string name, object value) { PropertyInfo property = target.GetType().GetProperty(name, AccessTools.all); if (property != null) { property.SetValue(target, value); } else { (AccessTools.Field(target.GetType(), name) ?? throw new MissingMemberException(name)).SetValue(target, value); } } private static void ConstructProperty(object target, string name, params object[] args) { PropertyInfo propertyInfo = Property(target, name); propertyInfo.SetValue(target, Activator.CreateInstance(propertyInfo.PropertyType, args)); } private static void AddEntry(object target, string name, object entry) { PropertyInfo propertyInfo = Property(target, name); IList list = (IList)propertyInfo.GetValue(target); if (list == null) { list = (IList)Activator.CreateInstance(propertyInfo.PropertyType); propertyInfo.SetValue(target, list); } list.Add(entry); } } [BepInPlugin("benjsammy.chestlabels", "Item Storage Categories by BenjSammy", "1.0.0")] public sealed class ChestLabels : BaseUnityPlugin { private const string Id = "benjsammy.chestlabels"; private static readonly Dictionary<string, string> Categories = new Dictionary<string, string>(StringComparer.Ordinal); private static readonly Dictionary<string, string> English = new Dictionary<string, string>(StringComparer.Ordinal) { ["Bois"] = "Wood", ["Pierre"] = "Stone", ["Combustibles"] = "Fuel", ["Décoration"] = "Decorations", ["Minerais"] = "Ores", ["Lingots"] = "Ingots", ["Pièces fabriquées"] = "Crafted Parts", ["Composants"] = "Components", ["Cuir et tissus"] = "Leather and Cloth", ["Moules et pièces"] = "Moulds and Casts", ["Magie"] = "Magic", ["Cuisine crue"] = "Raw Ingredients", ["Repas"] = "Meals", ["Fermentation"] = "Brewing", ["Potions"] = "Potions", ["Culture"] = "Farming", ["Pêche"] = "Fishing", ["Armes"] = "Weapons", ["Armures"] = "Armor", ["Boucliers"] = "Shields", ["Munitions"] = "Ammo", ["Outils"] = "Tools", ["Trophées"] = "Trophies", ["Trésors"] = "Treasures", ["Clés et quêtes"] = "Keys and Quests" }; private static FieldRef<ItemData, GameObject> dropPrefab; private static MethodInfo getLanguage; private static MethodInfo getLocalization; private static FieldInfo localizationField; private Harmony harmony; private const string CategoryStart = "<align=center><line-height=115%>"; private void Awake() { //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: Expected O, but got Unknown //IL_0214: Unknown result type (might be due to invalid IL or missing references) //IL_0219: Unknown result type (might be due to invalid IL or missing references) //IL_0228: Expected O, but got Unknown //IL_0269: Unknown result type (might be due to invalid IL or missing references) //IL_026e: Unknown result type (might be due to invalid IL or missing references) //IL_027d: Expected O, but got Unknown using (StreamReader streamReader = new StreamReader(typeof(ChestLabels).Assembly.GetManifestResourceStream("Categories.tsv"))) { string text; while ((text = streamReader.ReadLine()) != null) { string[] array = text.Split('\t'); if (array.Length != 2 || !English.ContainsKey(array[1])) { throw new InvalidDataException("Invalid chest category record."); } Categories.Add(array[0], array[1]); } } dropPrefab = AccessTools.FieldRefAccess<ItemData, GameObject>("m_dropPrefab"); Type type = AccessTools.TypeByName("Localization"); if (type != null) { getLanguage = AccessTools.Method(type, "GetSelectedLanguage", Type.EmptyTypes, (Type[])null); getLocalization = AccessTools.PropertyGetter(type, "instance"); localizationField = AccessTools.Field(type, "instance"); } MethodInfo methodInfo = AccessTools.Method(typeof(ItemData), "GetTooltip", new Type[6] { typeof(ItemData), typeof(int), typeof(bool), typeof(float), typeof(int), typeof(bool) }, (Type[])null) ?? AccessTools.Method(typeof(ItemData), "GetTooltip", new Type[5] { typeof(ItemData), typeof(int), typeof(bool), typeof(float), typeof(int) }, (Type[])null); MethodInfo methodInfo2 = AccessTools.Method(typeof(ItemData), "GetTooltip", new Type[1] { typeof(int) }, (Type[])null); harmony = new Harmony("benjsammy.chestlabels"); if (methodInfo2 != null && !methodInfo2.IsStatic && methodInfo2.ReturnType == typeof(string)) { harmony.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, new HarmonyMethod(typeof(ChestLabels), "AddInventoryCategory", (Type[])null) { priority = 0 }, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } if (methodInfo != null && methodInfo.IsStatic && methodInfo.ReturnType == typeof(string)) { harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(ChestLabels), "AddCategory", (Type[])null) { priority = 0 }, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } ((BaseUnityPlugin)this).Logger.LogInfo((object)$"Tooltip hooks: inventory={methodInfo2 != null}, shared={methodInfo != null}."); } private void OnDestroy() { Harmony obj = harmony; if (obj != null) { obj.UnpatchSelf(); } Categories.Clear(); } private static void AddInventoryCategory(ItemData __instance, ref string __result) { AddCategory(__instance, ref __result); } private static void AddCategory(ItemData __0, ref string __result) { if (__0 == null) { return; } string obj = __result; if (obj == null || !obj.StartsWith("<align=center><line-height=115%>", StringComparison.Ordinal)) { object obj2 = getLocalization?.Invoke(null, null) ?? localizationField?.GetValue(null); string text = ((getLanguage == null || (obj2 == null && !getLanguage.IsStatic)) ? null : (getLanguage.Invoke(obj2, null) as string)); bool flag = string.Equals(text, "French", StringComparison.OrdinalIgnoreCase) || string.Equals(text, "fr", StringComparison.OrdinalIgnoreCase) || string.Equals(text, "Français", StringComparison.OrdinalIgnoreCase) || (text?.StartsWith("fr-", StringComparison.OrdinalIgnoreCase) ?? false); GameObject val = dropPrefab.Invoke(__0); string text2 = (((Object)(object)val == (Object)null) ? "" : ((Object)val).name); if (text2.EndsWith("(Clone)", StringComparison.Ordinal)) { text2 = text2.Substring(0, text2.Length - "(Clone)".Length).TrimEnd(); } string value; bool flag2 = Categories.TryGetValue(text2, out value); string text3 = ((!flag) ? (flag2 ? English[value] : "Unknown") : (flag2 ? value : "Inconnue")); string text4 = (ChestIcon.IsReady() ? "<sprite=\"BENJSAMMYCHESTLABELS\" index=0> " : (flag ? "Coffre • " : "Chest • ")); __result = "<align=center><line-height=115%>" + text4 + "<color=#E6BC72>" + text3 + "</color>\n</line-height></align>" + __result; } } } }