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 ItemDisplayFix v1.0.0
plugins/ItemDisplayFix.dll
Decompiled 12 hours agousing System; using System.Collections; using System.Collections.Generic; using System.Reflection; using System.Runtime.CompilerServices; using BepInEx; using BepInEx.Logging; using HarmonyLib; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: AssemblyVersion("0.0.0.0")] namespace ItemDisplayFix; [BepInPlugin("evreborns.itemdisplayfix", "ItemDisplayFix", "1.0.0")] public class ItemDisplayFixPlugin : BaseUnityPlugin { private static ManualLogSource log; private static readonly Dictionary<string, GameObject> prefabs = new Dictionary<string, GameObject>(StringComparer.OrdinalIgnoreCase); private static bool built; private static readonly string[] bodies = new string[18] { "CommandoBody", "HuntressBody", "Bandit2Body", "ToolbotBody", "EngiBody", "MageBody", "MercBody", "TreebotBody", "LoaderBody", "CrocoBody", "CaptainBody", "RailgunnerBody", "VoidSurvivorBody", "SeekerBody", "ChefBody", "FalseSonBody", "HereticBody", "ScavBody" }; private static Harmony harmony; private static HarmonyMethod prefixHM; private static HarmonyMethod postfixHM; private static readonly HashSet<Type> patched = new HashSet<Type>(); private void Awake() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Expected O, but got Unknown //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Expected O, but got Unknown //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Expected O, but got Unknown log = ((BaseUnityPlugin)this).Logger; harmony = new Harmony("evreborns.itemdisplayfix"); postfixHM = new HarmonyMethod(typeof(ItemDisplayFixPlugin).GetMethod("PopulatePostfix", BindingFlags.Static | BindingFlags.NonPublic)); prefixHM = new HarmonyMethod(typeof(ItemDisplayFixPlugin).GetMethod("PopulatePrefix", BindingFlags.Static | BindingFlags.NonPublic)); PatchAll(); } private static void PatchAll() { try { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { Type[] types; try { types = assembly.GetTypes(); } catch (ReflectionTypeLoadException ex) { types = ex.Types; } catch { continue; } Type[] array = types; foreach (Type type in array) { if (type == null || patched.Contains(type)) { continue; } FieldInfo fieldInfo = FindDictField(type); if (fieldInfo == null) { continue; } MethodInfo method = type.GetMethod("PopulateDisplays", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null); if (!(method == null)) { patched.Add(type); try { harmony.Patch((MethodBase)method, prefixHM, postfixHM, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); log.LogInfo((object)("Template ItemDisplays dipatch: " + type.FullName)); } catch (Exception ex2) { log.LogWarning((object)("Gagal patch " + type.FullName + ": " + ex2.Message)); } } } } } catch (Exception ex3) { log.LogError((object)ex3); } } private void Start() { PatchAll(); try { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { Type[] types; try { types = assembly.GetTypes(); } catch (ReflectionTypeLoadException ex) { types = ex.Types; } catch { continue; } Type[] array = types; foreach (Type type in array) { if (type == null) { continue; } FieldInfo fieldInfo = FindDictField(type); if (!(fieldInfo == null)) { IDictionary dictionary = null; try { dictionary = fieldInfo.GetValue(null) as IDictionary; } catch { } if (dictionary != null) { Fill(dictionary, type.FullName); } } } } } catch (Exception ex2) { ((BaseUnityPlugin)this).Logger.LogError((object)ex2); } } private static FieldInfo FindDictField(Type t) { FieldInfo fieldInfo = null; try { fieldInfo = t.GetField("itemDisplayPrefabs", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); } catch { } if (fieldInfo == null || !typeof(IDictionary).IsAssignableFrom(fieldInfo.FieldType)) { return null; } return fieldInfo; } private static void PopulatePrefix() { try { Build(); } catch (Exception ex) { if (log != null) { log.LogWarning((object)ex.Message); } } } private static void PopulatePostfix(MethodBase __originalMethod) { try { FieldInfo fieldInfo = FindDictField(__originalMethod.DeclaringType); IDictionary dictionary = ((fieldInfo != null) ? (fieldInfo.GetValue(null) as IDictionary) : null); if (dictionary != null) { Fill(dictionary, __originalMethod.DeclaringType.FullName); } } catch (Exception ex) { if (log != null) { log.LogWarning((object)ex.Message); } } } private static void Fill(IDictionary d, string owner) { Build(); int num = 0; foreach (KeyValuePair<string, GameObject> prefab in prefabs) { string key = prefab.Key.ToLowerInvariant(); if (!d.Contains(key)) { d[key] = prefab.Value; num++; } } if (num > 0 && log != null) { log.LogInfo((object)("Mengisi " + num + " model item untuk " + owner)); } } private static void Build() { if (built) { return; } built = true; Type type = AccessTools.TypeByName("RoR2.LegacyResourcesAPI"); MethodInfo methodInfo = null; int num = 0; if (type != null) { MethodInfo[] methods = type.GetMethods(BindingFlags.Static | BindingFlags.Public); foreach (MethodInfo methodInfo2 in methods) { if (methodInfo2.Name != "Load" || !methodInfo2.IsGenericMethodDefinition) { continue; } ParameterInfo[] parameters = methodInfo2.GetParameters(); if (parameters.Length != 0 && !(parameters[0].ParameterType != typeof(string)) && (parameters.Length == 1 || (parameters.Length == 2 && parameters[1].ParameterType == typeof(bool)))) { methodInfo = methodInfo2.MakeGenericMethod(typeof(GameObject)); num = parameters.Length; if (parameters.Length == 1) { break; } } } } Type type2 = AccessTools.TypeByName("UnityEngine.AddressableAssets.Addressables"); MethodInfo loadAsync = null; if (type2 != null) { MethodInfo[] methods2 = type2.GetMethods(BindingFlags.Static | BindingFlags.Public); foreach (MethodInfo methodInfo3 in methods2) { if (methodInfo3.Name == "LoadAssetAsync" && methodInfo3.IsGenericMethodDefinition) { ParameterInfo[] parameters2 = methodInfo3.GetParameters(); if (parameters2.Length == 1 && parameters2[0].ParameterType == typeof(object)) { loadAsync = methodInfo3.MakeGenericMethod(typeof(GameObject)); break; } } } } if (methodInfo == null) { log.LogError((object)"LegacyResourcesAPI.Load tidak ditemukan."); return; } int num2 = 0; string[] array = bodies; foreach (string text in array) { try { object[] parameters3 = ((num == 2) ? new object[2] { "Prefabs/CharacterBodies/" + text, false } : new object[1] { "Prefabs/CharacterBodies/" + text }); object? obj = methodInfo.Invoke(null, parameters3); GameObject val = (GameObject)((obj is GameObject) ? obj : null); if ((Object)(object)val == (Object)null) { continue; } Component component = val.GetComponent("ModelLocator"); if ((Object)(object)component == (Object)null) { continue; } object member = GetMember(component, "modelTransform"); Transform val2 = (Transform)((member is Transform) ? member : null); if ((Object)(object)val2 == (Object)null) { continue; } Component component2 = ((Component)val2).GetComponent("CharacterModel"); if (!((Object)(object)component2 == (Object)null)) { object member2 = GetMember(component2, "itemDisplayRuleSet"); Object val3 = (Object)((member2 is Object) ? member2 : null); if (!(val3 == (Object)null)) { num2 += ProcessIdrs(val3, loadAsync); } } } catch (Exception ex) { log.LogDebug((object)(text + ": " + ex.Message)); } } log.LogInfo((object)("ItemDisplayFix: " + prefabs.Count + " model item ditemukan, " + num2 + " aturan display diperbaiki.")); } private static int ProcessIdrs(Object idrs, MethodInfo loadAsync) { int num = 0; if (!(GetMember(idrs, "keyAssetRuleGroups") is Array array)) { return 0; } for (int i = 0; i < array.Length; i++) { object value = array.GetValue(i); object member = GetMember(value, "displayRuleGroup"); if (member == null || !(GetMember(member, "rules") is Array array2)) { continue; } for (int j = 0; j < array2.Length; j++) { object value2 = array2.GetValue(j); FieldInfo field = value2.GetType().GetField("followerPrefab"); if (field == null) { continue; } object? value3 = field.GetValue(value2); GameObject val = (GameObject)((value3 is GameObject) ? value3 : null); if ((Object)(object)val == (Object)null && loadAsync != null) { object obj = FindAddressKey(value2); if (obj != null) { try { object obj2 = loadAsync.Invoke(null, new object[1] { obj }); MethodInfo method = obj2.GetType().GetMethod("WaitForCompletion"); object? obj3 = method.Invoke(obj2, null); val = (GameObject)((obj3 is GameObject) ? obj3 : null); } catch { val = null; } if ((Object)(object)val != (Object)null) { field.SetValue(value2, val); array2.SetValue(value2, j); num++; } } } if ((Object)(object)val != (Object)null && !prefabs.ContainsKey(((Object)val).name)) { prefabs[((Object)val).name] = val; } } } return num; } private static object FindAddressKey(object rule) { FieldInfo[] fields = rule.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo in fields) { if (fieldInfo.FieldType == typeof(GameObject)) { continue; } object value = fieldInfo.GetValue(rule); if (value == null) { continue; } Type type = value.GetType(); bool flag = false; Type type2 = type; while (type2 != null) { if (type2.Name == "AssetReference") { flag = true; break; } type2 = type2.BaseType; } if (flag) { PropertyInfo property = type.GetProperty("RuntimeKey"); object obj = ((property != null) ? property.GetValue(value, null) : null); MethodInfo method = type.GetMethod("RuntimeKeyIsValid", Type.EmptyTypes); if ((!(method != null) || (bool)method.Invoke(value, null)) && obj != null && obj.ToString().Length > 0) { return obj; } } else if (fieldInfo.FieldType == typeof(string) && fieldInfo.Name.ToLowerInvariant().Contains("address")) { string text = value as string; if (!string.IsNullOrEmpty(text)) { return text; } } } return null; } private static object GetMember(object o, string name) { if (o == null) { return null; } Type type = o.GetType(); FieldInfo field = type.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { return field.GetValue(o); } PropertyInfo property = type.GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (!(property != null)) { return null; } return property.GetValue(o, null); } }