using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; using System.IO.Compression; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using System.Threading; using System.Timers; using APIManager; using AzuEPI; using AzuEPI.Core.Input; using AzuEPI.Core.InventoryHandlers; using AzuEPI.Core.Slots; using AzuEPI.Core.Text; using AzuEPI.Core.Utilities.Extensions; using AzuEPI.EPI; using AzuEPI.Game.Compatibility; using AzuEPI.Game.Compatibility.AdvBackpacks; using AzuEPI.Game.Loadout; using AzuEPI.Game.Panels; using AzuEPI.Game.Panels.Stats; using AzuEPI.Game.Panels.Vanity; using AzuEPI.Game.Patches; using AzuEPI.Game.PlayerPreview; using AzuEPI.Game.Slots; using AzuEPI.Game.Slots.QAB; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using BepInEx.Preloader; using BepInEx.Preloader.Patching; using HarmonyLib; using JetBrains.Annotations; using LocalizationManager; using Microsoft.CodeAnalysis; using Mono.Cecil; using Mono.Cecil.Cil; using Mono.Collections.Generic; using ServerSync; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.UI; using YamlDotNet.Core; using YamlDotNet.Core.Events; using YamlDotNet.Core.ObjectPool; using YamlDotNet.Core.Tokens; using YamlDotNet.Helpers; using YamlDotNet.Serialization; using YamlDotNet.Serialization.BufferedDeserialization; using YamlDotNet.Serialization.BufferedDeserialization.TypeDiscriminators; using YamlDotNet.Serialization.Callbacks; using YamlDotNet.Serialization.Converters; using YamlDotNet.Serialization.EventEmitters; using YamlDotNet.Serialization.NamingConventions; using YamlDotNet.Serialization.NodeDeserializers; using YamlDotNet.Serialization.NodeTypeResolvers; using YamlDotNet.Serialization.ObjectFactories; using YamlDotNet.Serialization.ObjectGraphTraversalStrategies; using YamlDotNet.Serialization.ObjectGraphVisitors; using YamlDotNet.Serialization.Schemas; using YamlDotNet.Serialization.TypeInspectors; using YamlDotNet.Serialization.TypeResolvers; using YamlDotNet.Serialization.Utilities; using YamlDotNet.Serialization.ValueDeserializers; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("AzuExtendedPlayerInventory")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("Azumatt")] [assembly: AssemblyProduct("AzuExtendedPlayerInventory")] [assembly: AssemblyCopyright("Copyright © 2021")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("4358610B-F3F4-4843-B7AF-98B7BC60DCDE")] [assembly: AssemblyFileVersion("2.4.2")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("2.4.2.0")] [module: UnverifiableCode] [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; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class ExtensionMarkerAttribute : Attribute { public ExtensionMarkerAttribute(string name) { } } } public static class ToggleExtensions { [SpecialName] public sealed class $4F220943ABCF1C1726BA9F32F1C84BFA { [SpecialName] public static class $B886148B8B9A8A91C986883EF65534E9 { } [ExtensionMarker("$B886148B8B9A8A91C986883EF65534E9")] public bool isOn() { throw null; } [ExtensionMarker("$B886148B8B9A8A91C986883EF65534E9")] public bool isOff() { throw null; } } public static bool isOn(this AzuExtendedPlayerInventoryPlugin.Toggle toggle) { return toggle == AzuExtendedPlayerInventoryPlugin.Toggle.On; } public static bool isOff(this AzuExtendedPlayerInventoryPlugin.Toggle toggle) { return toggle == AzuExtendedPlayerInventoryPlugin.Toggle.Off; } } namespace AzuExtendedPlayerInventory { [PublicAPI] public class API { public delegate void SlotAddedHandler(string slotName); public delegate void SlotRemovedHandler(string slotName); private static readonly Dictionary _slotAddedMap = new Dictionary(); private static readonly Dictionary _slotRemovedMap = new Dictionary(); private static readonly Dictionary, Action> _hudAwakeMap = new Dictionary, Action>(); private static readonly Dictionary, Action> _hudAwakeCompleteMap = new Dictionary, Action>(); private static readonly Dictionary, Action> _hudUpdateMap = new Dictionary, Action>(); private static readonly Dictionary, Action> _hudUpdateCompleteMap = new Dictionary, Action>(); public static event SlotAddedHandler? SlotAdded { add { if (value == null || _slotAddedMap.ContainsKey(value)) { return; } AzuEPI.API.SlotAddedHandler value2 = delegate(string s) { try { value(s); } catch { } }; _slotAddedMap[value] = value2; AzuEPI.API.SlotAdded += value2; } remove { if (value != null && _slotAddedMap.TryGetValue(value, out AzuEPI.API.SlotAddedHandler value2)) { AzuEPI.API.SlotAdded -= value2; _slotAddedMap.Remove(value); } } } public static event SlotRemovedHandler? SlotRemoved { add { if (value == null || _slotRemovedMap.ContainsKey(value)) { return; } AzuEPI.API.SlotRemovedHandler value2 = delegate(string s) { try { value(s); } catch { } }; _slotRemovedMap[value] = value2; AzuEPI.API.SlotRemoved += value2; } remove { if (value != null && _slotRemovedMap.TryGetValue(value, out AzuEPI.API.SlotRemovedHandler value2)) { AzuEPI.API.SlotRemoved -= value2; _slotRemovedMap.Remove(value); } } } public static event Action? OnHudAwake { add { AddHudEvent(value, _hudAwakeMap, delegate(Action h) { AzuEPI.API.OnHudAwake += h; }); } remove { RemoveHudEvent(value, _hudAwakeMap, delegate(Action h) { AzuEPI.API.OnHudAwake -= h; }); } } public static event Action? OnHudAwakeComplete { add { AddHudEvent(value, _hudAwakeCompleteMap, delegate(Action h) { AzuEPI.API.OnHudAwakeComplete += h; }); } remove { RemoveHudEvent(value, _hudAwakeCompleteMap, delegate(Action h) { AzuEPI.API.OnHudAwakeComplete -= h; }); } } public static event Action? OnHudUpdate { add { AddHudEvent(value, _hudUpdateMap, delegate(Action h) { AzuEPI.API.OnHudUpdate += h; }); } remove { RemoveHudEvent(value, _hudUpdateMap, delegate(Action h) { AzuEPI.API.OnHudUpdate -= h; }); } } public static event Action? OnHudUpdateComplete { add { AddHudEvent(value, _hudUpdateCompleteMap, delegate(Action h) { AzuEPI.API.OnHudUpdateComplete += h; }); } remove { RemoveHudEvent(value, _hudUpdateCompleteMap, delegate(Action h) { AzuEPI.API.OnHudUpdateComplete -= h; }); } } private static void AddHudEvent(Action? handler, Dictionary, Action> map, Action> subscribe) { if (handler == null || map.ContainsKey(handler)) { return; } Action action = delegate(Hud h) { try { handler(h); } catch { } }; map[handler] = action; subscribe(action); } private static void RemoveHudEvent(Action? handler, Dictionary, Action> map, Action> unsubscribe) { if (handler != null && map.TryGetValue(handler, out Action value)) { unsubscribe(value); map.Remove(handler); } } public static bool IsLoaded() { return AzuEPI.API.IsLoaded(); } public static bool AddSlot(string slotName, Func getItem, Func isValid, int index = -1) { if (Localization.m_instance == null || Localization.m_instance.Localize(slotName).Contains("[")) { Localizer.OnLocalizationComplete += delegate { AzuEPI.API.AddSlot(slotName, getItem, isValid, index); }; } else { AzuEPI.API.AddSlot(slotName, getItem, isValid, index); } return true; } public static bool RemoveSlot(string slotName) { return AzuEPI.API.RemoveSlot(slotName); } public static SlotInfo GetSlots() { AzuEPI.SlotInfo slots = AzuEPI.API.GetSlots(); return new SlotInfo { SlotNames = (slots.SlotNames ?? Array.Empty()), SlotPositions = (slots.SlotPositions ?? Array.Empty()), GetItemFuncs = (slots.GetItemFuncs ?? Array.Empty>()), IsValidFuncs = (slots.IsValidFuncs ?? Array.Empty>()) }; } public static SlotInfo GetQuickSlots() { AzuEPI.SlotInfo quickSlots = AzuEPI.API.GetQuickSlots(); return new SlotInfo { SlotNames = (quickSlots.SlotNames ?? Array.Empty()), SlotPositions = (quickSlots.SlotPositions ?? Array.Empty()), GetItemFuncs = (quickSlots.GetItemFuncs ?? Array.Empty>()), IsValidFuncs = (quickSlots.IsValidFuncs ?? Array.Empty>()) }; } public static List GetQuickSlotsItems() { return AzuEPI.API.GetQuickSlotsItems(); } public static int GetAddedRows(int width) { return AzuEPI.API.GetAddedRows(width); } public static void HudAwake(Hud h) { SafeInvoke(delegate { AzuEPI.API.HudAwake(h); }); } public static void HudAwakeComplete(Hud h) { SafeInvoke(delegate { AzuEPI.API.HudAwakeComplete(h); }); } public static void HudUpdate(Hud h) { SafeInvoke(delegate { AzuEPI.API.HudUpdate(h); }); } public static void HudUpdateComplete(Hud h) { SafeInvoke(delegate { AzuEPI.API.HudUpdateComplete(h); }); } private static void SafeInvoke(Action a) { try { a(); } catch { } } } [PublicAPI] public class SlotInfo { public string[] SlotNames { get; set; } = Array.Empty(); public Vector2[] SlotPositions { get; set; } = Array.Empty(); public Func?[] GetItemFuncs { get; set; } = Array.Empty>(); public Func?[] IsValidFuncs { get; set; } = Array.Empty>(); } } namespace APIManager { public static class Patcher { private class MonoAssemblyResolver : IAssemblyResolver, IDisposable { public AssemblyDefinition Resolve(AssemblyNameReference name) { return AssemblyDefinition.ReadAssembly(AppDomain.CurrentDomain.Load(name.FullName).Location); } public AssemblyDefinition Resolve(AssemblyNameReference name, ReaderParameters parameters) { return Resolve(name); } public void Dispose() { } } private class AssemblyLoadInterceptor { private static string? assemblyPath; private static MethodInfo TargetMethod() { return AccessTools.DeclaredMethod(typeof(Assembly), "Load", new Type[1] { typeof(byte[]) }, (Type[])null); } private static bool Prefix(ref byte[] __0, ref Assembly? __result) { //IL_001d: 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_0032: Expected O, but got Unknown //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Expected O, but got Unknown //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Expected O, but got Unknown //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Expected O, but got Unknown //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Expected O, but got Unknown //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Expected O, but got Unknown //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_0201: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Expected O, but got Unknown //IL_0222: Unknown result type (might be due to invalid IL or missing references) //IL_0260: Unknown result type (might be due to invalid IL or missing references) assemblyPath = null; if (modifyNextLoad) { modifyNextLoad = false; try { AssemblyDefinition val = AssemblyDefinition.ReadAssembly((Stream)new MemoryStream(__0), new ReaderParameters { AssemblyResolver = (IAssemblyResolver)(object)new MonoAssemblyResolver() }); try { ((Dictionary)typeof(EnvVars).Assembly.GetType("BepInEx.Preloader.RuntimeFixes.UnityPatches").GetProperty("AssemblyLocations").GetValue(null))[val.FullName] = currentAssemblyPath; FixupModuleReferences(val.MainModule); TypeDefinition val2 = val.MainModule.GetType("APIManager", "PatchedAttribute"); if (val2 == null) { val2 = new TypeDefinition("APIManager", "PatchedAttribute", (TypeAttributes)3) { BaseType = val.MainModule.ImportReference(typeof(Attribute)) }; MethodDefinition val3 = new MethodDefinition(".ctor", (MethodAttributes)6278, val.MainModule.TypeSystem.Void); ((MethodReference)val3).Parameters.Add(new ParameterDefinition(val.MainModule.TypeSystem.String)); ((MethodReference)val3).Parameters.Add(new ParameterDefinition(val.MainModule.TypeSystem.String)); val3.Body.Instructions.Add(Instruction.Create(OpCodes.Ret)); val2.Methods.Add(val3); val.MainModule.Types.Add(val2); CustomAttribute val4 = new CustomAttribute((MethodReference)(object)val3); val4.ConstructorArguments.Add(new CustomAttributeArgument(val.MainModule.TypeSystem.String, (object)"")); val4.ConstructorArguments.Add(new CustomAttributeArgument(val.MainModule.TypeSystem.String, (object)val.MainModule.Mvid.ToString())); val.CustomAttributes.Add(val4); } CustomAttribute val5 = new CustomAttribute((MethodReference)(object)((IEnumerable)val2.Methods).First((MethodDefinition m) => ((MemberReference)m).Name == ".ctor")); val5.ConstructorArguments.Add(new CustomAttributeArgument(val.MainModule.TypeSystem.String, (object)modGUID)); val5.ConstructorArguments.Add(new CustomAttributeArgument(val.MainModule.TypeSystem.String, (object)patchingAssembly.ManifestModule.ModuleVersionId.ToString())); val.CustomAttributes.Add(val5); using MemoryStream memoryStream = new MemoryStream(); val.Write((Stream)memoryStream); __0 = memoryStream.ToArray(); string dumpedAssembliesPath = Patcher.dumpedAssembliesPath; char directorySeparatorChar = Path.DirectorySeparatorChar; string path = dumpedAssembliesPath + directorySeparatorChar + ((AssemblyNameReference)val.Name).Name + ".dll"; Directory.CreateDirectory(Patcher.dumpedAssembliesPath); File.WriteAllBytes(path, __0); assemblyPath = path; __result = null; return false; } finally { ((IDisposable)val)?.Dispose(); } } catch (BadImageFormatException) { } catch (Exception ex2) { Debug.LogError((object)("Failed patching ... " + ex2)); } } return true; } private static void Postfix(ref Assembly? __result) { if (assemblyPath != null && __result == null) { __result = Assembly.LoadFrom(assemblyPath); assemblyPath = null; } } } private static PluginInfo? lastPluginInfo; private static bool modifyNextLoad = false; private static string modGUID = null; private static HashSet redirectedNamespaces = null; private static readonly Assembly patchingAssembly = Assembly.GetExecutingAssembly(); private static string currentAssemblyPath = null; private static readonly string dumpedAssembliesPath = (string)AccessTools.DeclaredField(typeof(AssemblyPatcher), "DumpedAssembliesPath").GetValue(null); private static void GrabPluginInfo(PluginInfo __instance) { lastPluginInfo = __instance; } [HarmonyPriority(700)] private static void CheckAssemblyLoadFile(string __0) { PluginInfo? obj = lastPluginInfo; if (__0 == ((obj != null) ? obj.Location : null) && lastPluginInfo.Dependencies.Any((BepInDependency d) => d.DependencyGUID == modGUID)) { modifyNextLoad = true; currentAssemblyPath = __0; } lastPluginInfo = null; } [HarmonyPriority(500)] private static bool InterceptAssemblyLoadFile(string __0, ref Assembly? __result) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Expected O, but got Unknown //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) if (modifyNextLoad && (object)__result == null) { string text = dumpedAssembliesPath; char directorySeparatorChar = Path.DirectorySeparatorChar; string text2 = text + directorySeparatorChar + Path.GetFileName(__0); if (File.Exists(text2)) { AssemblyDefinition val = AssemblyDefinition.ReadAssembly(text2, new ReaderParameters { AssemblyResolver = (IAssemblyResolver)(object)new MonoAssemblyResolver() }); try { bool flag = false; Enumerator enumerator = val.CustomAttributes.GetEnumerator(); try { while (enumerator.MoveNext()) { CustomAttribute current = enumerator.Current; TypeReference declaringType = ((MemberReference)current.Constructor).DeclaringType; if (declaringType.Namespace == "APIManager" && ((MemberReference)declaringType).Name == "PatchedAttribute") { CustomAttributeArgument val2 = current.ConstructorArguments[0]; if ((string)((CustomAttributeArgument)(ref val2)).Value == modGUID) { val2 = current.ConstructorArguments[1]; flag = (string)((CustomAttributeArgument)(ref val2)).Value == patchingAssembly.ManifestModule.ModuleVersionId.ToString(); break; } } } } finally { ((IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose(); } if (flag) { return true; } } finally { ((IDisposable)val)?.Dispose(); } } __result = Assembly.Load(File.ReadAllBytes(__0)); return false; } return true; } [HarmonyPriority(499)] private static bool ReplaceAssemblyLoadWithCache(ref string __0, ref Assembly? __result) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Expected O, but got Unknown //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Expected O, but got Unknown //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) if (modifyNextLoad && (object)__result == null && !__0.StartsWith(dumpedAssembliesPath)) { string text = dumpedAssembliesPath; char directorySeparatorChar = Path.DirectorySeparatorChar; string text2 = text + directorySeparatorChar + Path.GetFileName(__0); AssemblyDefinition val = AssemblyDefinition.ReadAssembly(text2, new ReaderParameters { AssemblyResolver = (IAssemblyResolver)(object)new MonoAssemblyResolver() }); AssemblyDefinition val2 = AssemblyDefinition.ReadAssembly(__0, new ReaderParameters { AssemblyResolver = (IAssemblyResolver)(object)new MonoAssemblyResolver() }); Enumerator enumerator = val.CustomAttributes.GetEnumerator(); try { while (enumerator.MoveNext()) { CustomAttribute current = enumerator.Current; TypeReference declaringType = ((MemberReference)current.Constructor).DeclaringType; if (declaringType.Namespace == "APIManager" && ((MemberReference)declaringType).Name == "PatchedAttribute") { CustomAttributeArgument val3 = current.ConstructorArguments[0]; string text3 = (string)((CustomAttributeArgument)(ref val3)).Value; bool num; if (!(text3 == "")) { num = !Chainloader.PluginInfos.ContainsKey(text3); } else { val3 = current.ConstructorArguments[1]; num = (string)((CustomAttributeArgument)(ref val3)).Value != val2.MainModule.Mvid.ToString(); } if (num) { val2.Dispose(); val.Dispose(); __result = Assembly.Load(File.ReadAllBytes(__0)); return false; } } } } finally { ((IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose(); } ((Dictionary)typeof(EnvVars).Assembly.GetType("BepInEx.Preloader.RuntimeFixes.UnityPatches").GetProperty("AssemblyLocations").GetValue(null))[val.FullName] = __0; val2.Dispose(); val.Dispose(); __0 = text2; } modifyNextLoad = false; return true; } private static void FixupModuleReferences(ModuleDefinition module) { foreach (TypeDefinition type3 in module.GetTypes()) { if ((object)patchingAssembly.GetType(((MemberReference)type3).FullName) == null) { Dispatch(type3); } } static bool AreSame(TypeReference a, TypeReference b) { return (bool)typeof(MetadataResolver).Assembly.GetType("Mono.Cecil.MetadataResolver").GetMethod("AreSame", BindingFlags.Static | BindingFlags.NonPublic, null, new Type[2] { typeof(TypeReference), typeof(TypeReference) }, null).Invoke(null, new object[2] { a, b }); } void Dispatch(TypeDefinition type) { if (type.BaseType != null && (object)type.BaseType.Scope == module && redirectedNamespaces.Contains(baseDeclaringType(type.BaseType).Namespace)) { Type type2 = patchingAssembly.GetType(((MemberReference)type.BaseType).FullName); if ((object)type2 != null) { type.BaseType = module.ImportReference(type2); } } DispatchGenericParameters((IGenericParameterProvider)(object)type, ((MemberReference)type).FullName); DispatchInterfaces(type, ((MemberReference)type).FullName); DispatchAttributes((ICustomAttributeProvider)(object)type, ((MemberReference)type).FullName); DispatchFields(type, ((MemberReference)type).FullName); DispatchProperties(type, ((MemberReference)type).FullName); DispatchEvents(type, ((MemberReference)type).FullName); DispatchMethods(type); } void DispatchAttributes(ICustomAttributeProvider provider, string referencingEntityName) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) if (!provider.HasCustomAttributes) { return; } Enumerator enumerator2 = provider.CustomAttributes.GetEnumerator(); try { while (enumerator2.MoveNext()) { CustomAttribute current2 = enumerator2.Current; MethodReference val = importMethodReference(current2.Constructor); if (val != null) { current2.Constructor = val; } else { VisitMethod(current2.Constructor, referencingEntityName); } for (int i = 0; i < current2.ConstructorArguments.Count; i++) { CustomAttributeArgument val2 = current2.ConstructorArguments[i]; current2.ConstructorArguments[i] = new CustomAttributeArgument(VisitType(((CustomAttributeArgument)(ref val2)).Type, referencingEntityName), ((CustomAttributeArgument)(ref val2)).Value); } CustomAttributeArgument argument; for (int j = 0; j < current2.Properties.Count; j++) { CustomAttributeNamedArgument val3 = current2.Properties[j]; Collection properties = current2.Properties; int num = j; string name = ((CustomAttributeNamedArgument)(ref val3)).Name; argument = ((CustomAttributeNamedArgument)(ref val3)).Argument; TypeReference? obj = VisitType(((CustomAttributeArgument)(ref argument)).Type, referencingEntityName); argument = ((CustomAttributeNamedArgument)(ref val3)).Argument; properties[num] = new CustomAttributeNamedArgument(name, new CustomAttributeArgument(obj, ((CustomAttributeArgument)(ref argument)).Value)); } for (int k = 0; k < current2.Fields.Count; k++) { CustomAttributeNamedArgument val4 = current2.Fields[k]; Collection fields = current2.Fields; int num2 = k; string name2 = ((CustomAttributeNamedArgument)(ref val4)).Name; argument = ((CustomAttributeNamedArgument)(ref val4)).Argument; TypeReference? obj2 = VisitType(((CustomAttributeArgument)(ref argument)).Type, referencingEntityName); argument = ((CustomAttributeNamedArgument)(ref val4)).Argument; fields[num2] = new CustomAttributeNamedArgument(name2, new CustomAttributeArgument(obj2, ((CustomAttributeArgument)(ref argument)).Value)); } } } finally { ((IDisposable)enumerator2/*cast due to .constrained prefix*/).Dispose(); } } void DispatchEvents(TypeDefinition type, string referencingEntityName) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) Enumerator enumerator2 = type.Events.GetEnumerator(); try { while (enumerator2.MoveNext()) { EventDefinition current2 = enumerator2.Current; ((EventReference)current2).EventType = VisitType(((EventReference)current2).EventType, referencingEntityName); DispatchAttributes((ICustomAttributeProvider)(object)current2, referencingEntityName); } } finally { ((IDisposable)enumerator2/*cast due to .constrained prefix*/).Dispose(); } } void DispatchFields(TypeDefinition type, string referencingEntityName) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) Enumerator enumerator2 = type.Fields.GetEnumerator(); try { while (enumerator2.MoveNext()) { FieldDefinition current2 = enumerator2.Current; ((FieldReference)current2).FieldType = VisitType(((FieldReference)current2).FieldType, referencingEntityName); DispatchAttributes((ICustomAttributeProvider)(object)current2, referencingEntityName); } } finally { ((IDisposable)enumerator2/*cast due to .constrained prefix*/).Dispose(); } } void DispatchGenericArguments(IGenericInstance genericInstance, string referencingEntityName) { for (int i = 0; i < genericInstance.GenericArguments.Count; i++) { genericInstance.GenericArguments[i] = VisitType(genericInstance.GenericArguments[i], referencingEntityName); } } void DispatchGenericParameters(IGenericParameterProvider provider, string referencingEntityName) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) Enumerator enumerator2 = provider.GenericParameters.GetEnumerator(); try { while (enumerator2.MoveNext()) { GenericParameter current2 = enumerator2.Current; DispatchAttributes((ICustomAttributeProvider)(object)current2, referencingEntityName); for (int i = 0; i < current2.Constraints.Count; i++) { current2.Constraints[i] = VisitType(current2.Constraints[i], referencingEntityName); } } } finally { ((IDisposable)enumerator2/*cast due to .constrained prefix*/).Dispose(); } } void DispatchInterfaces(TypeDefinition type, string referencingEntityName) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) Enumerator enumerator2 = type.Interfaces.GetEnumerator(); try { while (enumerator2.MoveNext()) { InterfaceImplementation current2 = enumerator2.Current; current2.InterfaceType = VisitType(current2.InterfaceType, referencingEntityName); } } finally { ((IDisposable)enumerator2/*cast due to .constrained prefix*/).Dispose(); } } void DispatchMethod(MethodDefinition method) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) ((MethodReference)method).ReturnType = VisitType(((MethodReference)method).ReturnType, ((MemberReference)method).FullName); DispatchAttributes((ICustomAttributeProvider)(object)((MethodReference)method).MethodReturnType, ((MemberReference)method).FullName); DispatchGenericParameters((IGenericParameterProvider)(object)method, ((MemberReference)method).FullName); Enumerator enumerator2 = ((MethodReference)method).Parameters.GetEnumerator(); try { while (enumerator2.MoveNext()) { ParameterDefinition current2 = enumerator2.Current; ((ParameterReference)current2).ParameterType = VisitType(((ParameterReference)current2).ParameterType, ((MemberReference)method).FullName); DispatchAttributes((ICustomAttributeProvider)(object)current2, ((MemberReference)method).FullName); } } finally { ((IDisposable)enumerator2/*cast due to .constrained prefix*/).Dispose(); } for (int i = 0; i < method.Overrides.Count; i++) { MethodReference val = importMethodReference(method.Overrides[i]); if (val != null) { method.Overrides[i] = val; } else { VisitMethod(method.Overrides[i], ((MemberReference)method).FullName); } } if (method.HasBody) { DispatchMethodBody(method.Body); } } void DispatchMethodBody(MethodBody body) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) Enumerator enumerator2 = body.Variables.GetEnumerator(); try { while (enumerator2.MoveNext()) { VariableDefinition current2 = enumerator2.Current; ((VariableReference)current2).VariableType = VisitType(((VariableReference)current2).VariableType, ((MemberReference)body.Method).FullName); } } finally { ((IDisposable)enumerator2/*cast due to .constrained prefix*/).Dispose(); } Enumerator enumerator3 = body.Instructions.GetEnumerator(); try { while (enumerator3.MoveNext()) { Instruction current3 = enumerator3.Current; object operand = current3.Operand; FieldReference val = (FieldReference)((operand is FieldReference) ? operand : null); if (val == null) { MethodReference val2 = (MethodReference)((operand is MethodReference) ? operand : null); if (val2 == null) { TypeReference val3 = (TypeReference)((operand is TypeReference) ? operand : null); if (val3 != null) { current3.Operand = VisitType(val3, ((MemberReference)body.Method).FullName); } } else { MethodReference val4 = importMethodReference(val2); if (val4 != null) { current3.Operand = val4; } else { VisitMethod(val2, ((MemberReference)body.Method).FullName); } } } else { FieldReference val5 = importFieldReference(val); if (val5 != null) { current3.Operand = val5; } else { VisitField(val, ((MemberReference)body.Method).FullName); } } } } finally { ((IDisposable)enumerator3/*cast due to .constrained prefix*/).Dispose(); } } void DispatchMethods(TypeDefinition type) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) Enumerator enumerator2 = type.Methods.GetEnumerator(); try { while (enumerator2.MoveNext()) { MethodDefinition current2 = enumerator2.Current; DispatchMethod(current2); } } finally { ((IDisposable)enumerator2/*cast due to .constrained prefix*/).Dispose(); } } void DispatchProperties(TypeDefinition type, string referencingEntityName) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) Enumerator enumerator2 = type.Properties.GetEnumerator(); try { while (enumerator2.MoveNext()) { PropertyDefinition current2 = enumerator2.Current; ((PropertyReference)current2).PropertyType = VisitType(((PropertyReference)current2).PropertyType, referencingEntityName); DispatchAttributes((ICustomAttributeProvider)(object)current2, referencingEntityName); } } finally { ((IDisposable)enumerator2/*cast due to .constrained prefix*/).Dispose(); } } TypeReference FixupType(TypeReference type) { if ((object)type.Scope == module && redirectedNamespaces.Contains(baseDeclaringType(type).Namespace)) { if (type.IsNested) { return FixupType(((MemberReference)type).DeclaringType); } Type type2 = patchingAssembly.GetType(((MemberReference)type).FullName); if ((object)type2 != null) { return module.ImportReference(type2); } } return type; } void VisitField(FieldReference? field, string referencingEntityName) { if (field != null) { field.FieldType = VisitType(field.FieldType, referencingEntityName); if (!(field is FieldDefinition)) { ((MemberReference)field).DeclaringType = VisitType(((MemberReference)field).DeclaringType, referencingEntityName); } } } void VisitMethod(MethodReference? method, string referencingEntityName) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) if (method != null) { GenericInstanceMethod val = (GenericInstanceMethod)(object)((method is GenericInstanceMethod) ? method : null); if (val != null) { DispatchGenericArguments((IGenericInstance)(object)val, referencingEntityName); } method.ReturnType = VisitType(method.ReturnType, referencingEntityName); Enumerator enumerator2 = method.Parameters.GetEnumerator(); try { while (enumerator2.MoveNext()) { ParameterDefinition current2 = enumerator2.Current; ((ParameterReference)current2).ParameterType = VisitType(((ParameterReference)current2).ParameterType, referencingEntityName); } } finally { ((IDisposable)enumerator2/*cast due to .constrained prefix*/).Dispose(); } if (!(method is MethodSpecification)) { ((MemberReference)method).DeclaringType = VisitType(((MemberReference)method).DeclaringType, referencingEntityName); } } } TypeReference? VisitType(TypeReference? type, string referencingEntityName) { if (type == null) { return type; } if (type.GetElementType().IsGenericParameter) { return type; } GenericInstanceType val = (GenericInstanceType)(object)((type is GenericInstanceType) ? type : null); if (val != null) { DispatchGenericArguments((IGenericInstance)(object)val, referencingEntityName); } return FixupType(type); } static TypeReference baseDeclaringType(TypeReference type) { while (((MemberReference)type).DeclaringType != null) { type = ((MemberReference)type).DeclaringType; } return type; } FieldReference? importFieldReference(FieldReference field) { if ((object)((MemberReference)field).DeclaringType.Scope == module && redirectedNamespaces.Contains(baseDeclaringType(((MemberReference)field).DeclaringType).Namespace)) { FieldInfo fieldInfo = patchingAssembly.GetType(((MemberReference)((MemberReference)field).DeclaringType).FullName)?.GetField(((MemberReference)field).Name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if ((object)fieldInfo != null) { return module.ImportReference(fieldInfo); } } return null; } MethodReference? importMethodReference(MethodReference method) { //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Expected O, but got Unknown if ((object)((MemberReference)method).DeclaringType.Scope == module && redirectedNamespaces.Contains(baseDeclaringType(((MemberReference)method).DeclaringType).Namespace)) { if (((MemberReference)method).Name == ".cctor") { ConstructorInfo[] array = patchingAssembly.GetType(((MemberReference)((MemberReference)method).DeclaringType).FullName)?.GetConstructors(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (array != null && array.Length == 1) { return module.ImportReference((MethodBase)array[0]); } } else if (((MemberReference)method).Name == ".ctor") { ConstructorInfo constructorInfo = patchingAssembly.GetType(((MemberReference)((MemberReference)method).DeclaringType).FullName)?.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault(CompareMethods); if ((object)constructorInfo != null) { return module.ImportReference((MethodBase)constructorInfo); } } else { MethodInfo methodInfo = patchingAssembly.GetType(((MemberReference)((MemberReference)method).DeclaringType).FullName)?.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault(delegate(MethodInfo m) { if (m.Name != ((MemberReference)method).Name) { return false; } return (((MemberReference)method.ReturnType).ContainsGenericParameter == m.ReturnType.IsGenericParameter || AreSame(method.ReturnType, module.ImportReference(m.ReturnType))) && CompareMethods(m); }); if ((object)methodInfo != null) { MethodReference val = module.ImportReference((MethodBase)methodInfo); MethodReference obj = method; GenericInstanceMethod val2 = (GenericInstanceMethod)(object)((obj is GenericInstanceMethod) ? obj : null); if (val2 != null) { GenericInstanceMethod val3 = new GenericInstanceMethod(val); for (int num = 0; num < val2.GenericArguments.Count; num++) { val2.GenericArguments[num] = VisitType(val2.GenericArguments[num], ((MemberReference)method).FullName); val3.GenericArguments.Add(val2.GenericArguments[num]); } val = (MethodReference)(object)val3; } return val; } } } return null; bool CompareMethods(MethodBase m) { ParameterInfo[] parameters = m.GetParameters(); if (method.IsGenericInstance != m.IsGenericMethodDefinition || parameters.Length != 0 != method.HasParameters) { return false; } if (method.HasParameters) { if (method.Parameters.Count != parameters.Length) { return false; } for (int i = 0; i < method.Parameters.Count; i++) { if (parameters[i].ParameterType.IsGenericParameter ? (!((ParameterReference)method.Parameters[i]).ParameterType.IsGenericParameter) : (!AreSame(((ParameterReference)method.Parameters[i]).ParameterType, module.ImportReference(parameters[i].ParameterType)))) { return false; } } } return true; } } } public static bool PreventHarmonyInteropFixLoad(Assembly? __0) { return __0 == null; } public static void Patch(IEnumerable? extraNamespaces = null) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Expected O, but got Unknown //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Expected O, but got Unknown //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Expected O, but got Unknown //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Expected O, but got Unknown //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Expected O, but got Unknown //IL_022a: Unknown result type (might be due to invalid IL or missing references) //IL_0230: Expected O, but got Unknown Harmony val = new Harmony("org.bepinex.plugins.APIManager"); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(PluginInfo), "ToString", (Type[])null, (Type[])null), new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Patcher), "GrabPluginInfo", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Assembly), "LoadFile", new Type[1] { typeof(string) }, (Type[])null), new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Patcher), "InterceptAssemblyLoadFile", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Assembly), "LoadFile", new Type[1] { typeof(string) }, (Type[])null), new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Patcher), "CheckAssemblyLoadFile", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Assembly), "LoadFile", new Type[1] { typeof(string) }, (Type[])null), new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Patcher), "ReplaceAssemblyLoadWithCache", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); new PatchClassProcessor(val, typeof(AssemblyLoadInterceptor), true).Patch(); Type type = typeof(AssemblyPatcher).Assembly.GetType("BepInEx.Preloader.RuntimeFixes.HarmonyInteropFix"); if ((object)type != null) { val.Patch((MethodBase)AccessTools.DeclaredMethod(type, "OnAssemblyLoad", (Type[])null, (Type[])null), new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Patcher), "PreventHarmonyInteropFixLoad", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } IEnumerable source; try { source = patchingAssembly.DefinedTypes.ToList(); } catch (ReflectionTypeLoadException ex) { source = from t in ex.Types where t != null select t.GetTypeInfo(); } BaseUnityPlugin val2 = (BaseUnityPlugin)Chainloader.ManagerObject.GetComponent((Type)source.First((TypeInfo t) => t.IsClass && typeof(BaseUnityPlugin).IsAssignableFrom(t))); HashSet hashSet = new HashSet(); foreach (string item in extraNamespaces ?? Array.Empty()) { hashSet.Add(item); } hashSet.Add(((object)val2).GetType().Namespace); redirectedNamespaces = hashSet; modGUID = val2.Info.Metadata.GUID; } } } namespace LocalizationManager { [PublicAPI] public class Localizer { private static readonly Dictionary>> PlaceholderProcessors; private static readonly Dictionary> loadedTexts; private static readonly ConditionalWeakTable localizationLanguage; private static readonly List> localizationObjects; private static BaseUnityPlugin? _plugin; private static readonly List fileExtensions; private static BaseUnityPlugin plugin { get { //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Expected O, but got Unknown if (_plugin == null) { IEnumerable source; try { source = Assembly.GetExecutingAssembly().DefinedTypes.ToList(); } catch (ReflectionTypeLoadException ex) { source = from t in ex.Types where t != null select t.GetTypeInfo(); } _plugin = (BaseUnityPlugin)Chainloader.ManagerObject.GetComponent((Type)source.First((TypeInfo t) => t.IsClass && typeof(BaseUnityPlugin).IsAssignableFrom(t))); } return _plugin; } } public static event Action? OnLocalizationComplete; private static void UpdatePlaceholderText(Localization localization, string key) { localizationLanguage.TryGetValue(localization, out string value); string text = loadedTexts[value][key]; if (PlaceholderProcessors.TryGetValue(key, out Dictionary> value2)) { text = value2.Aggregate(text, (string current, KeyValuePair> kv) => current.Replace("{" + kv.Key + "}", kv.Value())); } localization.AddWord(key, text); } public static void AddPlaceholder(string key, string placeholder, ConfigEntry config, Func? convertConfigValue = null) where T : notnull { if (convertConfigValue == null) { convertConfigValue = (T val) => val.ToString(); } if (!PlaceholderProcessors.ContainsKey(key)) { PlaceholderProcessors[key] = new Dictionary>(); } config.SettingChanged += delegate { UpdatePlaceholder(); }; if (loadedTexts.ContainsKey(Localization.instance.GetSelectedLanguage())) { UpdatePlaceholder(); } void UpdatePlaceholder() { PlaceholderProcessors[key][placeholder] = () => convertConfigValue(config.Value); UpdatePlaceholderText(Localization.instance, key); } } public static void AddText(string key, string text) { List> list = new List>(); foreach (WeakReference localizationObject in localizationObjects) { if (localizationObject.TryGetTarget(out var target)) { Dictionary dictionary = loadedTexts[localizationLanguage.GetOrCreateValue(target)]; if (!target.m_translations.ContainsKey(key)) { dictionary[key] = text; target.AddWord(key, text); } } else { list.Add(localizationObject); } } foreach (WeakReference item in list) { localizationObjects.Remove(item); } } public static void Load() { _ = plugin; } public static void LoadLocalizationLater(Localization __instance) { LoadLocalization(Localization.instance, __instance.GetSelectedLanguage()); } public static void SafeCallLocalizeComplete() { Localizer.OnLocalizationComplete?.Invoke(); } private static void LoadLocalization(Localization __instance, string language) { if (!localizationLanguage.Remove(__instance)) { localizationObjects.Add(new WeakReference(__instance)); } localizationLanguage.Add(__instance, language); Dictionary dictionary = new Dictionary(); foreach (string item in from f in Directory.GetFiles(Path.GetDirectoryName(Paths.PluginPath), plugin.Info.Metadata.Name + ".*", SearchOption.AllDirectories) where fileExtensions.IndexOf(Path.GetExtension(f)) >= 0 select f) { string text = Path.GetFileNameWithoutExtension(item).Split(new char[1] { '.' })[1]; if (dictionary.ContainsKey(text)) { Debug.LogWarning((object)("Duplicate key " + text + " found for " + plugin.Info.Metadata.Name + ". The duplicate file found at " + item + " will be skipped.")); } else { dictionary[text] = item; } } byte[] array = LoadTranslationFromAssembly("English"); if (array == null) { throw new Exception("Found no English localizations in mod " + plugin.Info.Metadata.Name + ". Expected an embedded resource translations/English.json or translations/English.yml."); } Dictionary dictionary2 = new DeserializerBuilder().IgnoreFields().Build().Deserialize>(Encoding.UTF8.GetString(array)); if (dictionary2 == null) { throw new Exception("Localization for mod " + plugin.Info.Metadata.Name + " failed: Localization file was empty."); } string text2 = null; if (language != "English") { if (dictionary.TryGetValue(language, out var value)) { text2 = File.ReadAllText(value); } else { byte[] array2 = LoadTranslationFromAssembly(language); if (array2 != null) { text2 = Encoding.UTF8.GetString(array2); } } } if (text2 == null && dictionary.TryGetValue("English", out var value2)) { text2 = File.ReadAllText(value2); } if (text2 != null) { foreach (KeyValuePair item2 in new DeserializerBuilder().IgnoreFields().Build().Deserialize>(text2) ?? new Dictionary()) { dictionary2[item2.Key] = item2.Value; } } loadedTexts[language] = dictionary2; foreach (KeyValuePair item3 in dictionary2) { UpdatePlaceholderText(__instance, item3.Key); } } static Localizer() { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Expected O, but got Unknown //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Expected O, but got Unknown //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Expected O, but got Unknown PlaceholderProcessors = new Dictionary>>(); loadedTexts = new Dictionary>(); localizationLanguage = new ConditionalWeakTable(); localizationObjects = new List>(); fileExtensions = new List(2) { ".json", ".yml" }; Harmony val = new Harmony("org.bepinex.helpers.LocalizationManager"); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Localization), "SetupLanguage", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Localizer), "LoadLocalization", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(FejdStartup), "SetupGui", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Localizer), "LoadLocalizationLater", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(FejdStartup), "Start", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Localizer), "SafeCallLocalizeComplete", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } private static byte[]? LoadTranslationFromAssembly(string language) { foreach (string fileExtension in fileExtensions) { byte[] array = ReadEmbeddedFileBytes("translations." + language + fileExtension); if (array != null) { return array; } } return null; } public static byte[]? ReadEmbeddedFileBytes(string resourceFileName, Assembly? containingAssembly = null) { using MemoryStream memoryStream = new MemoryStream(); if ((object)containingAssembly == null) { containingAssembly = Assembly.GetCallingAssembly(); } string text = containingAssembly.GetManifestResourceNames().FirstOrDefault((string str) => str.EndsWith(resourceFileName, StringComparison.Ordinal)); if (text != null) { containingAssembly.GetManifestResourceStream(text)?.CopyTo(memoryStream); } return (memoryStream.Length == 0L) ? null : memoryStream.ToArray(); } } } namespace ItemDataManager { [PublicAPI] public abstract class ItemData { internal static WeakReference constructingInfo = null; internal WeakReference? info; private static readonly FieldInfo parameterInfoClassImpl = AccessTools.DeclaredField(typeof(ParameterInfo), "ClassImpl"); private static Dictionary> serializedFields = new Dictionary>(); public string CustomDataKey { get; internal set; } protected virtual bool AllowStackingIdenticalValues { get; set; } public string Value { get { if (!Item.m_customData.TryGetValue(CustomDataKey, out var value)) { return ""; } return value; } set { Item.m_customData[CustomDataKey] = value; } } public string Key { get; internal set; } public bool IsCloned => Info.isCloned.Contains(CustomDataKey); public bool IsAlive { get { ItemInfo target; return (info ?? constructingInfo).TryGetTarget(out target); } } public ItemData Item => Info.ItemData; public ItemInfo Info { get { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown if (!(info ?? constructingInfo).TryGetTarget(out ItemInfo target)) { return new ItemInfo(new ItemData()); } return target; } } public virtual void FirstLoad() { } public virtual void Load() { //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Expected O, but got Unknown Dictionary dictionary = fetchSerializedFields(); if (dictionary == null || dictionary.Count <= 0 || Value == "") { return; } List list = new List(); string[] array = Value.Split(new char[1] { '|' }); for (int i = 0; i < array.Length; i++) { string[] array2 = array[i].Split(new char[1] { ':' }); if (array2.Length == 2 && dictionary.TryGetValue(array2[0], out var value)) { ZPackage val = new ZPackage(array2[1]); ParameterInfo parameterInfo = (ParameterInfo)FormatterServices.GetUninitializedObject(typeof(ParameterInfo)); parameterInfoClassImpl.SetValue(parameterInfo, value.FieldType); list.Clear(); ZRpc.Deserialize(new ParameterInfo[2] { null, parameterInfo }, val, ref list); if (list.Count > 0) { value.SetValue(this, list[0]); } } } } public virtual void Save() { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Expected O, but got Unknown Dictionary dictionary = fetchSerializedFields(); if (dictionary == null || dictionary.Count <= 0) { return; } StringBuilder stringBuilder = new StringBuilder(); foreach (FieldInfo value in dictionary.Values) { ZPackage val = new ZPackage(); ZRpc.Serialize(new object[1] { value.GetValue(this) }, ref val); stringBuilder.Append(value.Name); stringBuilder.Append(':'); stringBuilder.Append(val.GetBase64()); stringBuilder.Append('|'); } int length = stringBuilder.Length - 1; stringBuilder.Length = length; Value = stringBuilder.ToString(); } public virtual void Unload() { } public virtual void Upgraded() { } public virtual string? TryStack(ItemData? data) { if (!AllowStackingIdenticalValues || !(data?.Value == Value)) { return null; } return Value; } private Dictionary fetchSerializedFields() { Type type = GetType(); if (serializedFields.TryGetValue(type, out Dictionary value)) { return value; } return serializedFields[type] = (from f in type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) where f.GetCustomAttributes(typeof(SerializeField), inherit: true).Length != 0 select f).ToDictionary((FieldInfo f) => f.Name, (FieldInfo f) => f); } } public sealed class StringItemData : ItemData { } [PublicAPI] public class ItemInfo : IEnumerable, IEnumerable { public static HashSet ForceLoadTypes; internal static string? _modGuid; private static Dictionary> typeInheritorsCache; private static HashSet knownTypes; private Dictionary data = new Dictionary(); private WeakReference? selfReference; internal HashSet isCloned = new HashSet(); private static ItemData? awakeningItem; private static Assembly primaryAssembly; private static Dictionary assemblyNameCache; private static Dictionary classKeyCache; private HashSet fetchedClassKeys = new HashSet(); private static MethodInfo removeMethod; private static ItemData? checkingForStackableItemData; private static Dictionary? newValuesOnStackable; private static ItemData? currentlyUpgradingItem; internal static string modGuid => _modGuid ?? (_modGuid = ((Func)delegate { //IL_0091: Unknown result type (might be due to invalid IL or missing references) IEnumerable source; try { source = Assembly.GetExecutingAssembly().DefinedTypes.ToList(); } catch (ReflectionTypeLoadException ex) { source = from t in ex.Types where t != null select t.GetTypeInfo(); } return ((BaseUnityPlugin)Chainloader.ManagerObject.GetComponent((Type)source.First((TypeInfo t) => t.IsClass && typeof(BaseUnityPlugin).IsAssignableFrom(t)))).Info.Metadata.GUID; })()); public string Mod => modGuid; public ItemData ItemData { get; private set; } public string? this[string key] { get { return Get(key)?.Value; } set { GetOrCreate(key).Value = value ?? ""; } } internal static void addTypeToInheritorsCache(Type type, string typeKey) { if (!knownTypes.Contains(typeKey)) { knownTypes.Add(typeKey); Type type2 = type; while ((object)type2 != null) { AddInterfaces(type2); type2 = type2.BaseType; } } void AddInterfaces(Type baseType) { if (!typeInheritorsCache.TryGetValue(baseType, out HashSet value)) { HashSet hashSet = (typeInheritorsCache[baseType] = new HashSet()); value = hashSet; } value.Add(type); Type[] interfaces = baseType.GetInterfaces(); for (int i = 0; i < interfaces.Length; i++) { AddInterfaces(interfaces[i]); } } } private static string cachedAssemblyName(Assembly assembly) { if (assemblyNameCache.TryGetValue(assembly, out string value)) { return value; } return assemblyNameCache[assembly] = assembly.GetName().Name; } internal static string classKey(Type type, string key) { if (!classKeyCache.TryGetValue(type, out string value)) { value = type.FullName + ((type.Assembly != primaryAssembly) ? ("," + cachedAssemblyName(type.Assembly)) : ""); addTypeToInheritorsCache(type, value); } if (key == "") { return value; } return value + "#" + key; } internal static string dataKey(string key) { return modGuid + "#" + key; } internal ItemInfo(ItemData itemData) { ItemData = itemData; string text = dataKey(""); foreach (string item in ItemData.m_customData.Keys.ToList()) { if (!item.StartsWith(text)) { continue; } string[] array = item.Substring(text.Length).Split(new char[1] { '#' }, 2); if (!knownTypes.Contains(array[0])) { Type type = Type.GetType(array[0]); if ((object)type != null && typeof(ItemData).IsAssignableFrom(type)) { addTypeToInheritorsCache(type, array[0]); } } } } public T GetOrCreate(string key = "") where T : ItemData, new() { return Add(key) ?? Get(key); } public T? Add(string key = "") where T : ItemData, new() { string text = classKey(typeof(T), key); if (fetchedClassKeys.Contains(text) && data.ContainsKey(text)) { return null; } string text2 = dataKey(text); if (ItemData.m_customData.ContainsKey(text2) || (awakeningItem != ItemData && data.ContainsKey(text))) { return null; } ItemData.m_customData[text2] = ""; ItemDataManager.ItemData.constructingInfo = selfReference ?? (selfReference = new WeakReference(this)); T val = new T { info = selfReference, Key = key, CustomDataKey = text2 }; data[text] = val; val.Value = ""; val.FirstLoad(); return val; } public T? Get(string key = "") where T : class { if (!typeInheritorsCache.TryGetValue(typeof(T), out HashSet value)) { if (!typeof(ItemData).IsAssignableFrom(typeof(T)) || typeof(T) == typeof(ItemData)) { throw new Exception("Trying to get value from ItemDataManager for class not inheriting from ItemData"); } return null; } foreach (Type item in value) { string text = classKey(item, key); if (data.TryGetValue(text, out ItemData value2)) { return (T)(object)value2; } if (!fetchedClassKeys.Contains(text) && awakeningItem != ItemData) { string text2 = dataKey(text); fetchedClassKeys.Add(text); if (ItemData.m_customData.ContainsKey(text2)) { return (T)(object)constructDataObj(text2, text); } } } return null; } public Dictionary GetAll() where T : ItemData { LoadAll(); return data.Values.Where((ItemData o) => o is T).ToDictionary((ItemData o) => o.Key, (ItemData o) => (T)o); } public bool Remove(string key = "") { return Remove(key); } public bool Remove(string key = "") where T : ItemData { string key2 = classKey(typeof(T), key); string key3 = dataKey(key2); if (ItemData.m_customData.Remove(key3)) { if (data.TryGetValue(key2, out ItemData value)) { value.Unload(); data.Remove(key2); } return true; } return false; } public bool Remove(T itemData) where T : ItemData { if (typeof(T) == itemData.GetType()) { return Remove(itemData.Key); } return (bool)removeMethod.MakeGenericMethod(itemData.GetType()).Invoke(this, new object[1] { itemData.Key }); } private ItemData? constructDataObj(string fullkey, string key) { string[] array = key.Split(new char[1] { '#' }, 2); Type type = Type.GetType(array[0]); if ((object)type == null || !typeof(ItemData).IsAssignableFrom(type)) { return null; } ItemDataManager.ItemData.constructingInfo = selfReference ?? (selfReference = new WeakReference(this)); ItemData itemData = (ItemData)Activator.CreateInstance(type); data[key] = itemData; itemData.info = selfReference; itemData.Key = ((array.Length > 1) ? array[1] : ""); itemData.CustomDataKey = fullkey; itemData.Load(); return itemData; } public void Save() { foreach (ItemData value in data.Values) { value.Save(); } } public void LoadAll() { if (awakeningItem == ItemData) { return; } string text = dataKey(""); foreach (string item in ItemData.m_customData.Keys.ToList()) { if (item.StartsWith(text)) { string key = item.Substring(text.Length); if (!data.ContainsKey(key)) { constructDataObj(item, key); } } } } public IEnumerator GetEnumerator() { LoadAll(); return data.Values.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } private static void SavePrefix(ItemData __instance) { SaveItem(__instance); } private static void SaveInventoryPrefix(Inventory __instance) { foreach (ItemData item in __instance.m_inventory) { SaveItem(item); } } private static void SaveItem(ItemData item) { if (ItemExtensions.itemInfo.TryGetValue(item, out ItemInfo value)) { value.Save(); } } public Dictionary? IsStackableWithOtherInfo(ItemInfo? info) { LoadAll(); Dictionary dictionary = new Dictionary(); if (info != null) { info.LoadAll(); foreach (string item in new HashSet(info.data.Keys.Intersect(data.Keys))) { string text = data[item].TryStack(info.data[item]); if (text == null) { return null; } dictionary[item] = text; } foreach (KeyValuePair datum in info.data) { if (!dictionary.ContainsKey(datum.Key)) { string text2 = info.data[datum.Key].TryStack(null); if (text2 == null) { return null; } dictionary[datum.Key] = text2; } } } foreach (KeyValuePair datum2 in data) { if (!dictionary.ContainsKey(datum2.Key)) { string text3 = data[datum2.Key].TryStack(null); if (text3 == null) { return null; } dictionary[datum2.Key] = text3; } } return dictionary.ToDictionary((KeyValuePair kv) => dataKey(kv.Key), (KeyValuePair kv) => kv.Value); } private static void RegisterForceLoadedTypesAddItem(ItemData? __result) { awakeningItem = null; if (__result != null) { RegisterForceLoadedTypes(__result); } } private static void RegisterForceLoadedTypes(ItemData itemData) { foreach (Type forceLoadType in ForceLoadTypes) { string key = classKey(forceLoadType, ""); string text = dataKey(key); if (itemData.m_customData.ContainsKey(text)) { ItemInfo itemInfo = itemData.Data(); if (!itemInfo.data.ContainsKey(key)) { itemInfo.constructDataObj(text, key); } } } } private static void ItemDropAwake(ItemDrop __instance) { GameObject dropPrefab = __instance.m_itemData.m_dropPrefab; if (dropPrefab == null || !ItemExtensions.itemInfo.TryGetValue(dropPrefab.GetComponent().m_itemData, out ItemInfo value)) { return; } ItemInfo itemInfo = __instance.m_itemData.Data(); HashSet hashSet = new HashSet(); foreach (string item in value.data.Values.Select((ItemData i) => i.CustomDataKey)) { hashSet.Add(item); } itemInfo.isCloned = hashSet; } private static void ItemDropAwakeDelayed(ItemDrop __instance) { if (!ZNetView.m_forceDisableInit) { RegisterForceLoadedTypes(__instance.m_itemData); } } private static void ItemDataClonePrefix(ItemData __instance, ItemData __result) { SaveItem(__instance); } private static void ItemDataClonePostfix(ItemData __instance, ItemData __result) { if (!ItemExtensions.itemInfo.TryGetValue(__instance, out ItemInfo value)) { return; } ItemInfo itemInfo = __result.Data(); HashSet hashSet = new HashSet(); foreach (string item in value.data.Values.Select((ItemData i) => i.CustomDataKey)) { hashSet.Add(item); } itemInfo.isCloned = hashSet; } private static void ItemDataClonePostfixDelayed(ItemData __result) { RegisterForceLoadedTypes(__result); } private static void RegisterForceLoadedTypesOnPlayerLoaded(Player __instance) { foreach (Food food in __instance.m_foods) { GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(food.m_name); if (itemPrefab.GetComponent().m_itemData == food.m_item) { food.m_item = food.m_item.Clone(); food.m_item.m_dropPrefab = itemPrefab; } RegisterForceLoadedTypes(food.m_item); } } private static void SaveCheckingForStackableItemData(ItemData item) { if (item == awakeningItem) { awakeningItem = null; } checkingForStackableItemData = item; } private static void ResetCheckingForStackableItemData() { checkingForStackableItemData = null; } private static IEnumerable CheckStackableInFindFreeStackMethods(IEnumerable instructionsEnumerable) { CodeInstruction[] instructions = instructionsEnumerable.ToArray(); Label target = (Label)instructions.First((CodeInstruction val) => val.opcode == OpCodes.Br || val.opcode == OpCodes.Br_S).operand; CodeInstruction targetedInstr = instructions.First((CodeInstruction val) => val.labels.Contains(target)); Label? label = default(Label?); CodeInstruction lastBranch = instructions.Reverse().First((CodeInstruction val) => CodeInstructionExtensions.Branches(val, ref label) && targetedInstr.labels.Contains(label.Value)); CodeInstruction loadingInstruction = null; int i = 0; while (i < instructions.Length) { yield return instructions[i]; if (loadingInstruction == null && instructions[i].opcode == OpCodes.Call && ((MethodInfo)instructions[i].operand).Name == "get_Current") { loadingInstruction = instructions[i + 1].Clone(); loadingInstruction.opcode = new Dictionary { { OpCodes.Stloc_0, OpCodes.Ldloc_0 }, { OpCodes.Stloc_1, OpCodes.Ldloc_1 }, { OpCodes.Stloc_2, OpCodes.Ldloc_2 }, { OpCodes.Stloc_3, OpCodes.Ldloc_3 }, { OpCodes.Stloc_S, OpCodes.Ldloc_S } }[loadingInstruction.opcode]; } if (instructions[i] == lastBranch) { yield return loadingInstruction; yield return new CodeInstruction(OpCodes.Ldsfld, (object)AccessTools.DeclaredField(typeof(ItemInfo), "checkingForStackableItemData")); yield return new CodeInstruction(OpCodes.Call, (object)AccessTools.DeclaredMethod(typeof(ItemInfo), "CheckItemDataIsStackableFindFree", (Type[])null, (Type[])null)); yield return new CodeInstruction(OpCodes.Brfalse, (object)target); } int num = i + 1; i = num; } } private static bool CheckItemDataIsStackableFindFree(ItemData item, ItemData? target) { if (target == null) { return true; } Dictionary dictionary = IsStackable(item, target); if (dictionary != null) { newValuesOnStackable = dictionary; return true; } return false; } private static void ResetNewValuesOnStackable() { newValuesOnStackable = null; } private static void ApplyNewValuesOnStackable(ItemData? __result) { if (__result == null || newValuesOnStackable == null) { return; } foreach (KeyValuePair item in newValuesOnStackable) { __result.m_customData[item.Key] = item.Value; } } private static Dictionary? IsStackable(ItemData a, ItemData b) { ItemInfo itemInfo = a.Data(); if (itemInfo != null) { return itemInfo.IsStackableWithOtherInfo(b.Data()); } ItemInfo itemInfo2 = b.Data(); if (itemInfo2 != null) { return itemInfo2.IsStackableWithOtherInfo(null); } return new Dictionary(); } private static bool CheckItemDataStackableAddItem(Inventory __instance, ItemData item, int x, int y, ref Dictionary? __state, ref bool __result) { ItemData itemAt = __instance.GetItemAt(x, y); if (itemAt != null) { Dictionary dictionary = IsStackable(item, itemAt); if (dictionary == null) { __result = false; return false; } __state = dictionary; } return true; } private static void ApplyCustomItemDataStackableAddItem(Inventory __instance, int x, int y, Dictionary? __state, bool __result) { if (!__result || __state == null) { return; } foreach (KeyValuePair item in __state) { __instance.GetItemAt(x, y).m_customData[item.Key] = item.Value; } } private static void ApplyCustomItemDataStackableAutoStack(ItemDrop item, Dictionary customData) { item.m_itemData.m_customData = customData; } private static Dictionary? IsStackableItemDrop(ItemDrop drop, ItemData item) { return IsStackable(drop.m_itemData, item); } private static IEnumerable HandleAutostackableItems(IEnumerable instructionList, ILGenerator ilg) { //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Expected O, but got Unknown //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Expected O, but got Unknown //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Expected O, but got Unknown //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Expected O, but got Unknown //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Expected O, but got Unknown //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Expected O, but got Unknown //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Expected O, but got Unknown //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Expected O, but got Unknown //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Expected O, but got Unknown //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: Expected O, but got Unknown //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Expected O, but got Unknown List list = instructionList.ToList(); FieldInfo fieldInfo = AccessTools.DeclaredField(typeof(ItemData), "m_stack"); FieldInfo fieldInfo2 = AccessTools.DeclaredField(typeof(ItemDrop), "m_itemData"); Label? label = default(Label?); for (int i = 0; i < list.Count; i++) { if (!CodeInstructionExtensions.StoresField(list[i], fieldInfo)) { continue; } for (int num = i; num > 0; num--) { if (CodeInstructionExtensions.Branches(list[num], ref label)) { for (int num2 = num; num2 > 0; num2--) { if (CodeInstructionExtensions.LoadsField(list[num2], fieldInfo2, false)) { LocalBuilder localBuilder = ilg.DeclareLocal(typeof(Dictionary)); LocalBuilder localBuilder2 = ilg.DeclareLocal(typeof(ItemData)); list.Insert(i + 1, new CodeInstruction(OpCodes.Call, (object)AccessTools.DeclaredMethod(typeof(ItemInfo), "ApplyCustomItemDataStackableAutoStack", (Type[])null, (Type[])null))); list.Insert(i + 1, new CodeInstruction(OpCodes.Ldloc, (object)localBuilder.LocalIndex)); list.Insert(i + 1, new CodeInstruction(OpCodes.Ldarg_0, (object)null)); list.Insert(num + 1, new CodeInstruction(OpCodes.Brfalse, (object)label)); list.Insert(num + 1, new CodeInstruction(OpCodes.Stloc, (object)localBuilder.LocalIndex)); list.Insert(num + 1, new CodeInstruction(OpCodes.Dup, (object)localBuilder.LocalIndex)); list.Insert(num + 1, new CodeInstruction(OpCodes.Call, (object)AccessTools.DeclaredMethod(typeof(ItemInfo), "IsStackableItemDrop", (Type[])null, (Type[])null))); list.Insert(num + 1, new CodeInstruction(OpCodes.Ldloc, (object)localBuilder2.LocalIndex)); list.Insert(num + 1, new CodeInstruction(OpCodes.Ldarg_0, (object)null)); list.Insert(num2 + 1, new CodeInstruction(OpCodes.Stloc, (object)localBuilder2.LocalIndex)); list.Insert(num2 + 1, new CodeInstruction(OpCodes.Dup, (object)null)); return list; } } } } } throw new Exception("Found no stack store in a branch"); } private static IEnumerable TransferCustomItemDataOnUpgrade(IEnumerable instructions, ILGenerator ilg) { MethodInfo itemDeleter = AccessTools.DeclaredMethod(typeof(Inventory), "RemoveItem", new Type[1] { typeof(ItemData) }, (Type[])null); foreach (CodeInstruction instruction in instructions) { if (instruction.opcode == OpCodes.Callvirt && CodeInstructionExtensions.OperandIs(instruction, (MemberInfo)itemDeleter)) { yield return new CodeInstruction(OpCodes.Dup, (object)null); yield return new CodeInstruction(OpCodes.Stsfld, (object)AccessTools.DeclaredField(typeof(ItemInfo), "currentlyUpgradingItem")); } yield return instruction; } } private static void ResetCurrentlyUpgradingItem() { currentlyUpgradingItem = null; } private static void CopyCustomDataFromUpgradedItem(ItemDrop item) { if (currentlyUpgradingItem != null) { item.m_itemData.m_customData = currentlyUpgradingItem.m_customData; ItemInfo itemInfo = currentlyUpgradingItem.Data(); ItemExtensions.itemInfo.Remove(currentlyUpgradingItem); ItemExtensions.itemInfo.Add(item.m_itemData, itemInfo); item.m_itemData.m_quality = currentlyUpgradingItem.m_quality + 1; item.m_itemData.m_variant = currentlyUpgradingItem.m_variant; itemInfo.ItemData = item.m_itemData; itemInfo.LoadAll(); foreach (ItemData value in itemInfo.data.Values) { value.Upgraded(); } currentlyUpgradingItem = null; awakeningItem = null; return; } GameObject dropPrefab = item.m_itemData.m_dropPrefab; if (dropPrefab == null || item.m_itemData.m_customData.Count != 0) { return; } ZNetView component = ((Component)item).GetComponent(); ZDO val = ((Object.op_Implicit((Object)(object)component) && component.IsValid()) ? component.GetZDO() : null); if (val != null && val.GetInt(ZDOVars.s_dataCount, -1) != -1) { return; } item.m_itemData.m_customData = new Dictionary(dropPrefab.GetComponent().m_itemData.m_customData); if (val == null) { return; } int num = 0; val.Set(ZDOVars.s_dataCount, item.m_itemData.m_customData.Count, false); foreach (KeyValuePair customDatum in item.m_itemData.m_customData) { val.Set($"data_{num}", customDatum.Key); val.Set($"data__{++num}", customDatum.Value); } } private static IEnumerable ImportCustomDataOnUpgrade(IEnumerable instructionList) { List list = instructionList.ToList(); foreach (CodeInstruction instruction in list) { yield return instruction; if (instruction.opcode == OpCodes.Stfld && CodeInstructionExtensions.OperandIs(instruction, (MemberInfo)AccessTools.DeclaredField(typeof(ItemData), "m_dropPrefab"))) { yield return new CodeInstruction(OpCodes.Ldarg_0, (object)null); yield return new CodeInstruction(OpCodes.Call, (object)AccessTools.DeclaredMethod(typeof(ItemInfo), "CopyCustomDataFromUpgradedItem", (Type[])null, (Type[])null)); } } } private static void TrackAwakeningItem(ItemDrop __instance) { if (ZNetView.m_forceDisableInit) { awakeningItem = __instance.m_itemData; } } static ItemInfo() { //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Expected O, but got Unknown //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Expected O, but got Unknown //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Expected O, but got Unknown //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Expected O, but got Unknown //IL_01d0: Expected O, but got Unknown //IL_021d: Unknown result type (might be due to invalid IL or missing references) //IL_0234: Unknown result type (might be due to invalid IL or missing references) //IL_023f: Expected O, but got Unknown //IL_023f: Expected O, but got Unknown //IL_027f: Unknown result type (might be due to invalid IL or missing references) //IL_0296: Unknown result type (might be due to invalid IL or missing references) //IL_02a1: Expected O, but got Unknown //IL_02a1: Expected O, but got Unknown //IL_02ee: Unknown result type (might be due to invalid IL or missing references) //IL_0305: Unknown result type (might be due to invalid IL or missing references) //IL_0310: Expected O, but got Unknown //IL_0310: Expected O, but got Unknown //IL_0340: Unknown result type (might be due to invalid IL or missing references) //IL_034c: Expected O, but got Unknown //IL_037a: Unknown result type (might be due to invalid IL or missing references) //IL_0381: Expected O, but got Unknown //IL_0397: Unknown result type (might be due to invalid IL or missing references) //IL_03b2: Unknown result type (might be due to invalid IL or missing references) //IL_03c0: Expected O, but got Unknown //IL_03c0: Expected O, but got Unknown //IL_03f0: Unknown result type (might be due to invalid IL or missing references) //IL_03fc: Expected O, but got Unknown //IL_042c: Unknown result type (might be due to invalid IL or missing references) //IL_0447: Unknown result type (might be due to invalid IL or missing references) //IL_0452: Expected O, but got Unknown //IL_0452: Expected O, but got Unknown //IL_04a3: Unknown result type (might be due to invalid IL or missing references) //IL_04b0: Expected O, but got Unknown //IL_0503: Unknown result type (might be due to invalid IL or missing references) //IL_0510: Expected O, but got Unknown //IL_05bc: Unknown result type (might be due to invalid IL or missing references) //IL_05c9: Expected O, but got Unknown //IL_05f7: Unknown result type (might be due to invalid IL or missing references) //IL_0622: Unknown result type (might be due to invalid IL or missing references) //IL_0629: Expected O, but got Unknown //IL_064f: Unknown result type (might be due to invalid IL or missing references) //IL_065d: Expected O, but got Unknown //IL_065d: Expected O, but got Unknown //IL_069c: Unknown result type (might be due to invalid IL or missing references) //IL_06a9: Expected O, but got Unknown //IL_06d7: Unknown result type (might be due to invalid IL or missing references) //IL_0702: Unknown result type (might be due to invalid IL or missing references) //IL_070f: Expected O, but got Unknown //IL_070f: Expected O, but got Unknown //IL_074e: Unknown result type (might be due to invalid IL or missing references) //IL_075b: Expected O, but got Unknown ForceLoadTypes = new HashSet(); typeInheritorsCache = new Dictionary>(); knownTypes = new HashSet(); awakeningItem = null; primaryAssembly = Assembly.GetExecutingAssembly(); assemblyNameCache = new Dictionary(); classKeyCache = new Dictionary(); removeMethod = typeof(ItemInfo).GetMethods().Single((MethodInfo m) => m.Name == "Remove" && m.IsGenericMethod && m.GetParameters()[0].ParameterType == typeof(string)); Harmony val = new Harmony("org.bepinex.helpers.ItemDataManager"); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Inventory), "Save", (Type[])null, (Type[])null), new HarmonyMethod(AccessTools.DeclaredMethod(typeof(ItemInfo), "SaveInventoryPrefix", (Type[])null, (Type[])null), 800, (string[])null, (string[])null, (bool?)null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); foreach (MethodInfo item in from m in typeof(ItemData).GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) where m.Name == "SaveToZDO" select m) { val.Patch((MethodBase)item, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(ItemInfo), "SavePrefix", (Type[])null, (Type[])null), 800, (string[])null, (string[])null, (bool?)null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Inventory), "AddItem", new Type[4] { typeof(ItemData), typeof(int), typeof(int), typeof(int) }, (Type[])null), new HarmonyMethod(AccessTools.DeclaredMethod(typeof(ItemInfo), "CheckItemDataStackableAddItem", (Type[])null, (Type[])null)), new HarmonyMethod(AccessTools.DeclaredMethod(typeof(ItemInfo), "ApplyCustomItemDataStackableAddItem", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Inventory), "CanAddItem", new Type[2] { typeof(ItemData), typeof(int) }, (Type[])null), new HarmonyMethod(AccessTools.DeclaredMethod(typeof(ItemInfo), "SaveCheckingForStackableItemData", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(typeof(ItemInfo), "ResetCheckingForStackableItemData", (Type[])null), (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Inventory), "AddItem", new Type[1] { typeof(ItemData) }, (Type[])null), new HarmonyMethod(AccessTools.DeclaredMethod(typeof(ItemInfo), "SaveCheckingForStackableItemData", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(typeof(ItemInfo), "ResetCheckingForStackableItemData", (Type[])null), (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Inventory), "AddItem", new Type[2] { typeof(ItemData), typeof(Vector2i) }, (Type[])null), new HarmonyMethod(AccessTools.DeclaredMethod(typeof(ItemInfo), "SaveCheckingForStackableItemData", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(typeof(ItemInfo), "ResetCheckingForStackableItemData", (Type[])null), (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Inventory), "FindFreeStackSpace", (Type[])null, (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(ItemInfo), "CheckStackableInFindFreeStackMethods", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null); MethodInfo methodInfo = AccessTools.DeclaredMethod(typeof(Inventory), "FindFreeStackItem", (Type[])null, (Type[])null); HarmonyMethod val2 = new HarmonyMethod(AccessTools.DeclaredMethod(typeof(ItemInfo), "CheckStackableInFindFreeStackMethods", (Type[])null, (Type[])null)); val.Patch((MethodBase)methodInfo, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(ItemInfo), "ResetNewValuesOnStackable", (Type[])null, (Type[])null)), new HarmonyMethod(AccessTools.DeclaredMethod(typeof(ItemInfo), "ApplyNewValuesOnStackable", (Type[])null, (Type[])null)), val2, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(ItemDrop), "AutoStackItems", (Type[])null, (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(ItemInfo), "HandleAutostackableItems", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(InventoryGui), "DoCrafting", (Type[])null, (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(ItemInfo), "TransferCustomItemDataOnUpgrade", (Type[])null, (Type[])null)), new HarmonyMethod(AccessTools.DeclaredMethod(typeof(ItemInfo), "ResetCurrentlyUpgradingItem", (Type[])null, (Type[])null)), (HarmonyMethod)null); foreach (MethodInfo item2 in from m in typeof(ItemData).GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) where m.Name == "LoadFromZDO" select m) { val.Patch((MethodBase)item2, (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(ItemInfo), "RegisterForceLoadedTypes", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Player), "Load", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(ItemInfo), "RegisterForceLoadedTypesOnPlayerLoaded", (Type[])null, (Type[])null), 700, (string[])null, (string[])null, (bool?)null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Inventory), "AddItem", new Type[8] { typeof(string), typeof(int), typeof(int), typeof(int), typeof(long), typeof(string), typeof(Vector2i), typeof(bool) }, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(ItemInfo), "RegisterForceLoadedTypesAddItem", (Type[])null, (Type[])null), 800, (string[])null, (string[])null, (bool?)null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); MethodInfo methodInfo2 = AccessTools.DeclaredMethod(typeof(ItemDrop), "Awake", (Type[])null, (Type[])null); HarmonyMethod val3 = new HarmonyMethod(AccessTools.DeclaredMethod(typeof(ItemInfo), "TrackAwakeningItem", (Type[])null, (Type[])null)); val2 = new HarmonyMethod(AccessTools.DeclaredMethod(typeof(ItemInfo), "ImportCustomDataOnUpgrade", (Type[])null, (Type[])null), 800, (string[])null, (string[])null, (bool?)null); val.Patch((MethodBase)methodInfo2, val3, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(ItemInfo), "ItemDropAwake", (Type[])null, (Type[])null), 800, (string[])null, (string[])null, (bool?)null), val2, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(ItemDrop), "Awake", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(ItemInfo), "ItemDropAwakeDelayed", (Type[])null, (Type[])null), 799, (string[])null, (string[])null, (bool?)null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(ItemData), "Clone", (Type[])null, (Type[])null), new HarmonyMethod(AccessTools.DeclaredMethod(typeof(ItemInfo), "ItemDataClonePrefix", (Type[])null, (Type[])null)), new HarmonyMethod(AccessTools.DeclaredMethod(typeof(ItemInfo), "ItemDataClonePostfix", (Type[])null, (Type[])null), 500, (string[])null, (string[])null, (bool?)null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(ItemData), "Clone", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(ItemInfo), "ItemDataClonePostfixDelayed", (Type[])null, (Type[])null), 499, (string[])null, (string[])null, (bool?)null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } [PublicAPI] public class ForeignItemInfo : IEnumerable, IEnumerable { private readonly object foreignItemInfo; public string Mod => ((string)foreignItemInfo.GetType().GetProperty("Mod")?.GetValue(foreignItemInfo)) ?? ""; public ItemData ItemData { get; private set; } public string? this[string key] { get { object obj = foreignItemInfo.GetType().InvokeMember("Item", BindingFlags.Instance | BindingFlags.Public | BindingFlags.GetProperty, null, foreignItemInfo, new object[1] { key }); if (obj != null) { return (string)obj.GetType().GetProperty("Value")?.GetValue(obj); } return null; } set { foreignItemInfo.GetType().GetMethod("set_Item", BindingFlags.Instance | BindingFlags.Public)?.Invoke(foreignItemInfo, new object[2] { key, value }); } } internal ForeignItemInfo(ItemData itemData, object foreignItemInfo) { ItemData = itemData; this.foreignItemInfo = foreignItemInfo; } public T GetOrCreate(string key = "") where T : class, new() { return Add(key) ?? Get(key); } private object? call(string name, object?[] values, Type?[] args, Type? generic = null) { MethodInfo[] methods = foreignItemInfo.GetType().GetMethods(); foreach (MethodInfo methodInfo in methods) { if (methodInfo.Name == name && (from p in methodInfo.GetParameters() select (!p.ParameterType.IsGenericParameter) ? p.ParameterType : null).SequenceEqual(args) && (object)generic != null == methodInfo.IsGenericMethod) { MethodInfo methodInfo2 = methodInfo; if ((object)generic != null) { methodInfo2 = methodInfo2.MakeGenericMethod(generic); } return methodInfo2.Invoke(foreignItemInfo, values); } } return null; } public T? Add(string key = "") where T : class, new() { return call("Add", new object[1] { key }, new Type[1] { typeof(string) }, typeof(T)) as T; } public T? Get(string key = "") where T : class { return call("Get", new object[1] { key }, new Type[1] { typeof(string) }, typeof(T)) as T; } public Dictionary GetAll() where T : class { return ((call("GetAll", Array.Empty(), Array.Empty(), typeof(T)) as T) as Dictionary) ?? new Dictionary(); } public bool Remove(string key = "") { return call("Add", new object[1] { key }, new Type[1] { typeof(string) }) as bool? == true; } public bool Remove(string key = "") where T : class { return call("Remove", new object[1] { key }, new Type[1] { typeof(string) }, typeof(T)) as bool? == true; } public bool Remove(T itemData) where T : class { return call("Remove", new object[1] { itemData }, new Type[1], typeof(T)) as bool? == true; } public void Save() { call("Save", Array.Empty(), Array.Empty()); } public void LoadAll() { call("LoadAll", Array.Empty(), Array.Empty()); } public IEnumerator GetEnumerator() { return (IEnumerator)((call("GetEnumerator", Array.Empty(), Array.Empty()) as IEnumerator) ?? ((object)new List().GetEnumerator())); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } [PublicAPI] public static class ItemExtensions { [SpecialName] public sealed class $89A7D4A522B437A8B95320B2CAC6531E { [SpecialName] public static class $091BBA0B72542A51B2CEA87B8CA8E7DC { } [ExtensionMarker("$091BBA0B72542A51B2CEA87B8CA8E7DC")] public ItemInfo Data() { throw null; } [ExtensionMarker("$091BBA0B72542A51B2CEA87B8CA8E7DC")] public ForeignItemInfo? Data(string mod) { throw null; } } private const string className = "ItemDataManager.ItemExtensions"; internal static readonly ConditionalWeakTable itemInfo = new ConditionalWeakTable(); private static readonly ConditionalWeakTable> foreignItemInfo = new ConditionalWeakTable>(); public static ItemInfo Data(this ItemData item) { if (itemInfo.TryGetValue(item, out ItemInfo value)) { return value; } itemInfo.Add(item, value = new ItemInfo(item)); return value; } public static ForeignItemInfo? Data(this ItemData item, string mod) { Dictionary orCreateValue = ItemExtensions.foreignItemInfo.GetOrCreateValue(item); if (orCreateValue.TryGetValue(mod, out var value)) { return value; } if (!Chainloader.PluginInfos.TryGetValue(mod, out var value2)) { return null; } object obj = ((object)value2.Instance).GetType().Assembly.GetType("ItemDataManager.ItemExtensions")?.GetMethod("Data", BindingFlags.Static | BindingFlags.Public, null, new Type[1] { typeof(ItemData) }, Array.Empty())?.Invoke(null, new object[1] { item }); if (obj != null) { return orCreateValue[mod] = new ForeignItemInfo(item, obj); } Debug.LogWarning((object)("Mod " + mod + " has an ItemDataManager.ItemExtensions class, but no Data(ItemDrop.ItemData) method could be called on it.")); return orCreateValue[mod] = null; } } } namespace AzuEPI { [BepInPlugin("Azumatt.AzuExtendedPlayerInventory", "AzuExtendedPlayerInventory", "2.4.2")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInIncompatibility("shudnal.ExtraSlots")] [BepInIncompatibility("shudnal.ExtraSlotsCustomSlots")] [BepInIncompatibility("aedenthorn.ExtendedPlayerInventory")] [BepInIncompatibility("com.bruce.valheim.comfyquickslots")] [BepInIncompatibility("randyknapp.mods.equipmentandquickslots")] [BepInIncompatibility("moreslots")] [BepInIncompatibility("randyknapp.mods.auga")] [BepInIncompatibility("toombe.EquipMultipleUtilityItemsUpdate")] [BepInIncompatibility("aedenthorn.EquipMultipleUtilityItems")] public class AzuExtendedPlayerInventoryPlugin : BaseUnityPlugin { public enum Toggle { On = 1, Off = 0 } private class ConfigurationManagerAttributes { [UsedImplicitly] public bool? Browsable; [UsedImplicitly] public string? Category; [UsedImplicitly] public Action? CustomDrawer; [UsedImplicitly] public int? Order; } private class AcceptableShortcuts : AcceptableValueBase { public AcceptableShortcuts() : base(typeof(KeyboardShortcut)) { } public override object Clamp(object value) { return value; } public override bool IsValid(object value) { return true; } public override string ToDescriptionString() { return "# Acceptable values: " + string.Join(", ", UnityInput.Current.SupportedKeyCodes); } } internal const string ModName = "AzuExtendedPlayerInventory"; internal const string ModVersion = "2.4.2"; internal const string Author = "Azumatt"; internal const string ModGUID = "Azumatt.AzuExtendedPlayerInventory"; private static readonly string ConfigFileName; private static readonly string ConfigFileFullPath; internal static string ConnectionError; public static readonly ManualLogSource AzuExtendedPlayerInventoryLogger; private static readonly ConfigSync ConfigSync; internal static AzuExtendedPlayerInventoryPlugin context; internal static bool WbInstalled; internal readonly Harmony _harmony = new Harmony("Azumatt.AzuExtendedPlayerInventory"); private FileSystemWatcher _cfgWatcher; private System.Timers.Timer _debounce; public static readonly int FakeType; private int _configOrder = 100; private static ConfigEntry _serverConfigLocked; public static ConfigEntry AutoEquip; public static ConfigEntry WishboneSlot; public static ConfigEntry WispLightSlot; public static ConfigEntry RemovedEquipmentSlots; public static ConfigEntry UserAddedSlots; public static ConfigEntry EPISlotsAddArmor; public static ConfigEntry UtilityEPIAddArmor; public static ConfigEntry AddEquipmentRow; public static ConfigEntry DisplayEquipmentRowSeparate; public static ConfigEntry QuickSlotsAmount; public static ConfigEntry ShowQuickSlots; public static ConfigEntry MakeDropAllButton; public static ConfigEntry DropAllButtonPosition; public static ConfigEntry SelectedPlayerStats; public static ConfigEntry SelectedLiveStats; public static ConfigEntry ExtraRows; public static ConfigEntry HelmetText; public static ConfigEntry ChestText; public static ConfigEntry LegsText; public static ConfigEntry BackText; public static ConfigEntry TrinketText; public static ConfigEntry UtilityText; public static ConfigEntry QuickAccessScale; public static ConfigEntry QuickslotDragKeys; public static ConfigEntry ModKeyTwo; public static ConfigEntry[] Hotkeys; public static ConfigEntry[] HotkeyTexts; public static ConfigEntry QuickAccessLocation; public static ConfigEntry QuickSlotsPerRow; public static ConfigEntry AlwaysShowQuickSlotsInUI; public static ConfigEntry UIAnchor; public static ConfigEntry LocalScale; public static ConfigEntry VanityOption; public static ConfigEntry LoadoutOption; public static ConfigEntry OldLayout; public static ConfigEntry VanityToggleGamepadKey; public static ConfigEntry LoadoutToggleGamepadKey; public static ConfigEntry StatsToggleGamepadKey; private static string _newSlotName; private static string _newSlotPrefabs; private static Vector2 _slotsScrollPosition; private static Vector2 _prefabScrollPosition; private static bool _showPrefabList; private int NextOrder => _configOrder--; static AzuExtendedPlayerInventoryPlugin() { //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) ConfigFileName = "Azumatt.AzuExtendedPlayerInventory.cfg"; string configPath = Paths.ConfigPath; char directorySeparatorChar = Path.DirectorySeparatorChar; ConfigFileFullPath = configPath + directorySeparatorChar + ConfigFileName; ConnectionError = ""; AzuExtendedPlayerInventoryLogger = Logger.CreateLogSource("AzuExtendedPlayerInventory"); ConfigSync = new ConfigSync("Azumatt.AzuExtendedPlayerInventory") { DisplayName = "AzuExtendedPlayerInventory", CurrentVersion = "2.4.2", MinimumRequiredVersion = "2.4.2" }; context = null; FakeType = StringExtensionMethods.GetStableHashCode("AzuEPIFakeType"); _serverConfigLocked = null; AutoEquip = null; WishboneSlot = null; WispLightSlot = null; RemovedEquipmentSlots = null; UserAddedSlots = null; EPISlotsAddArmor = null; UtilityEPIAddArmor = null; AddEquipmentRow = null; DisplayEquipmentRowSeparate = null; QuickSlotsAmount = null; ShowQuickSlots = null; MakeDropAllButton = null; DropAllButtonPosition = null; SelectedPlayerStats = null; SelectedLiveStats = null; ExtraRows = null; HelmetText = null; ChestText = null; LegsText = null; BackText = null; TrinketText = null; UtilityText = null; QuickAccessScale = null; QuickslotDragKeys = null; ModKeyTwo = null; Hotkeys = null; HotkeyTexts = null; QuickAccessLocation = null; QuickSlotsPerRow = null; AlwaysShowQuickSlotsInUI = null; UIAnchor = null; LocalScale = null; VanityOption = null; LoadoutOption = null; OldLayout = null; VanityToggleGamepadKey = null; LoadoutToggleGamepadKey = null; StatsToggleGamepadKey = null; _newSlotName = ""; _newSlotPrefabs = ""; _slotsScrollPosition = Vector2.zero; _prefabScrollPosition = Vector2.zero; _showPrefabList = false; AppDomain.CurrentDomain.AssemblyResolve += (object s, ResolveEventArgs e) => (!(new AssemblyName(e.Name).Name == "AzuExtendedPlayerInventory")) ? null : typeof(AzuExtendedPlayerInventoryPlugin).Assembly; } private unsafe void Awake() { //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Expected O, but got Unknown //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Expected O, but got Unknown //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Expected O, but got Unknown //IL_0262: Unknown result type (might be due to invalid IL or missing references) //IL_0273: Expected O, but got Unknown //IL_02b5: Unknown result type (might be due to invalid IL or missing references) //IL_02c6: Expected O, but got Unknown //IL_030c: Unknown result type (might be due to invalid IL or missing references) //IL_031d: Expected O, but got Unknown //IL_047c: Unknown result type (might be due to invalid IL or missing references) //IL_048d: Expected O, but got Unknown //IL_0516: Unknown result type (might be due to invalid IL or missing references) //IL_0527: Expected O, but got Unknown //IL_0651: Unknown result type (might be due to invalid IL or missing references) //IL_068a: Unknown result type (might be due to invalid IL or missing references) //IL_075e: Unknown result type (might be due to invalid IL or missing references) Localizer.Load(); Patcher.Patch(new <>z__ReadOnlyArray(new string[2] { "AzuExtendedPlayerInventory", "AzuExtendedPlayerInventory.EPI.Patches" })); context = this; ResetConfigOrder(); _serverConfigLocked = config("1 - Server & Sync", "Lock Configuration", Toggle.On, "When enabled, only server admins can modify configuration settings. All players will use the server's settings.", NextOrder); ConfigSync.AddLockingConfigEntry(_serverConfigLocked); ResetConfigOrder(); ExtraRows = config("2 - Inventory", "Extra Inventory Rows", 0, new ConfigDescription("Add extra rows to your inventory (0-5).", (AcceptableValueBase)(object)new AcceptableValueRange(0, 5), Array.Empty()), NextOrder); AddEquipmentRow = config("2 - Inventory", "Enable Equipment Row", Toggle.On, "Adds a dedicated row for equipped items and quick slots. IMPORTANT: Turn OFF if using Randy Knapp's Equipment and Quick Slots mod to avoid conflicts.", NextOrder); DisplayEquipmentRowSeparate = config("2 - Inventory", "Display Equipment in Separate Panel", Toggle.On, "Shows equipped items and quick slots in their own dedicated panel instead of inline. IMPORTANT: Turn OFF if using Randy Knapp's Equipment and Quick Slots mod.", NextOrder); AutoEquip = config("2 - Inventory", "Auto-Equip Items", Toggle.On, "Automatically equip items when picked up, moved from containers, or recovered from tombstones. Disable if you prefer manual equipping.", NextOrder); ResetConfigOrder(); QuickSlotsAmount = config("3 - Quick Slots", "Number of Quick Slots", 3, new ConfigDescription("How many quick slots to add (0-8). Quick slots let you hotkey items for instant access. Default is 3.", (AcceptableValueBase)(object)new AcceptableValueRange(0, 8), Array.Empty()), NextOrder); ShowQuickSlots = config("3 - Quick Slots", "Show Quick Slots on HUD", Toggle.On, "Display the quick slots bar on your screen during gameplay. Turn off to hide the bar while keeping the slots functional.", NextOrder); AlwaysShowQuickSlotsInUI = config("3 - Quick Slots", "Always Show All Slots", Toggle.On, "Display all available quick slots on the HUD. When disabled, only shows slots up to the highest occupied one.", NextOrder); QuickSlotsPerRow = config("3 - Quick Slots", "Slots Per Row", 8, new ConfigDescription("How many quick slots to show per row. Set to your total slots for horizontal layout, or use lower values (3-4) for vertical stacking.", (AcceptableValueBase)(object)new AcceptableValueRange(1, 8), Array.Empty()), NextOrder, synchronizedSetting: false); ResetConfigOrder(); WishboneSlot = config("4 - Special Equipment Slots", "Enable Wishbone Slot", Toggle.On, "Adds a dedicated equipment slot specifically for the Wishbone. When equipped here, the Wishbone's detection works without occupying utility slots.", NextOrder); WispLightSlot = config("4 - Special Equipment Slots", "Enable Demister Slot", Toggle.On, "Adds a dedicated equipment slot specifically for the Demister/Wisplight. Keeps the mist clear without using utility slots.", NextOrder); ResetConfigOrder(); config("4.5 - Equipment Slot Management", "Slot Manager (UI)", "", new ConfigDescription("If you are using the Configuration Manager, this will be a custom drawer. Use this for easier slot management with buttons and prefab browser.\nIf you aren't, edit the configs below directly", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { CustomDrawer = EquipmentSlotsConfigDrawer, Order = NextOrder } }), NextOrder); RemovedEquipmentSlots = config("4.5 - Equipment Slot Management", "Removed Equipment Slots", "", new ConfigDescription("Comma or semicolon-separated list of equipment slot names to remove from the game.\nWARNING: Removing slots will unequip items in those slots!\nExample: Head, Utility, Trinket\nBuilt-in slots: Head, Chest, Legs, Back, Utility, Trinket, Wishbone, Demister", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = NextOrder, Browsable = false } }), NextOrder); UserAddedSlots = config("4.5 - Equipment Slot Management", "Custom Equipment Slots", "", new ConfigDescription("Add custom equipment slots. Format: SlotName:PrefabName1,PrefabName2;SlotName2:Prefab3\nSemicolon separates different slots. Colon separates slot name from prefabs. Comma separates multiple prefabs for one slot.\nExample: Ring:RingIron,RingGold;Quiver:QuiverBone,QuiverLeather", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = NextOrder, Browsable = false } }), NextOrder); EPISlotsAddArmor = config("4.5 - Equipment Slot Management", "Slots Use Armor", Toggle.On, "If On, the armor on items in the custom slots is applied to the player. If off, the armor is not calculated, which is better for vanilla balance, but not expected. Default is set to On for this reason", NextOrder); UtilityEPIAddArmor = config("4.5 - Equipment Slot Management", "Utility Slots Use Armor", Toggle.Off, "If On & Slots Use Armor config is on, the armor on utility items in the custom slots is applied to the player. If off, the armor is not calculated, which is better for vanilla balance. Default is off for this reason.", NextOrder); ResetConfigOrder(); OldLayout = config("5 - UI Features", "Use Legacy Layout", Toggle.Off, "Reverts to the old inventory layout from previous versions. Only enable if you prefer the classic style or have compatibility issues.", NextOrder); VanityOption = config("5 - UI Features", "Show Vanity Button", Toggle.On, "Shows the vanity button (\ud83d\udc54) in the inventory. Use this to customize your character's appearance with cosmetic overrides.", NextOrder); LoadoutOption = config("5 - UI Features", "Show Loadout Button", Toggle.On, "Shows the loadout button (\ud83c\udfaf) in the inventory. Use this to save and quickly swap between different equipment sets.", NextOrder); string value = string.Join(",", from PlayerStatType stat in Enum.GetValues(typeof(PlayerStatType)) where (int)stat != 105 select ((object)(*(PlayerStatType*)(&stat))/*cast due to .constrained prefix*/).ToString()); SelectedPlayerStats = config("5 - UI Features", "Player Stats to Display", value, new ConfigDescription("Choose which character stats to display in the stats panel (\ud83d\udccb button). Use the config manager UI to select/deselect stats.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { CustomDrawer = StatsConfigDrawer } }), NextOrder, synchronizedSetting: false); string value2 = string.Join(",", from LiveStatType stat in Enum.GetValues(typeof(LiveStatType)) select stat.ToString()); SelectedLiveStats = config("5 - UI Features", "Live Stats to Display", value2, new ConfigDescription("Choose which live character stats to display in the stats panel (\ud83d\udccb button). These include health, damage modifiers, resistances, etc. Use the config manager UI to select/deselect stats.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { CustomDrawer = LiveStatsConfigDrawer } }), NextOrder, synchronizedSetting: false); ResetConfigOrder(); HelmetText = config("6 - Equipment Slot Labels", "Head Slot Label", "", "Customize the display text for the helmet/head equipment slot. Use a localization key (starts with $) to use translations, or set custom text.", NextOrder, synchronizedSetting: false); ChestText = config("6 - Equipment Slot Labels", "Chest Slot Label", "", "Customize the display text for the chest armor equipment slot. Use a localization key (starts with $) to use translations, or set custom text.", NextOrder, synchronizedSetting: false); LegsText = config("6 - Equipment Slot Labels", "Legs Slot Label", "", "Customize the display text for the leg armor equipment slot. Use a localization key (starts with $) to use translations, or set custom text.", NextOrder, synchronizedSetting: false); BackText = config("6 - Equipment Slot Labels", "Back Slot Label", "", "Customize the display text for the cape/back equipment slot. Use a localization key (starts with $) to use translations, or set custom text.", NextOrder, synchronizedSetting: false); UtilityText = config("6 - Equipment Slot Labels", "Utility Slot Label", "", "Customize the display text for the utility equipment slot. Use a localization key (starts with $) to use translations, or set custom text.", NextOrder, synchronizedSetting: false); TrinketText = config("6 - Equipment Slot Labels", "Trinket Slot Label", "", "Customize the display text for the trinket equipment slot. Use a localization key (starts with $) to use translations, or set custom text.", NextOrder, synchronizedSetting: false); ResetConfigOrder(); QuickAccessScale = config("7 - Quick Slots Customization", "HUD Size", 1f, "Scale/size multiplier for the quick slots bar on your HUD. 1.0 = default size, 0.5 = half size, 2.0 = double size.", NextOrder, synchronizedSetting: false); QuickAccessLocation = config("7 - Quick Slots Customization", "HUD Position", Vector2.one, "Screen position of the quick slots bar. Use the drag keys (default: CTRL+LeftClick) to reposition, or set to (9999, 9999) for automatic positioning.", NextOrder, synchronizedSetting: false); QuickslotDragKeys = config("7 - Quick Slots Customization", "Drag to Reposition Keys", new KeyboardShortcut((KeyCode)323, (KeyCode[])(object)new KeyCode[1] { (KeyCode)306 }), "Key combination to drag and reposition the quick slots bar on screen. Default: Hold CTRL and drag with left mouse button.", NextOrder, synchronizedSetting: false); ResetConfigOrder(); VanityToggleGamepadKey = config("8.5 - Panel Toggle Keys (Gamepad)", "Vanity Panel Toggle Key", (KeyCode)338, "Gamepad button to toggle the Vanity panel. Default: Left Stick Press (JoyLStick).", NextOrder, synchronizedSetting: false); LoadoutToggleGamepadKey = config("8.5 - Panel Toggle Keys (Gamepad)", "Loadout Panel Toggle Key", (KeyCode)339, "Gamepad button to toggle the Loadout panel. Default: Right Stick Press (JoyRStick).", NextOrder, synchronizedSetting: false); StatsToggleGamepadKey = config("8.5 - Panel Toggle Keys (Gamepad)", "Stats Panel Toggle Key", (KeyCode)333, "Gamepad button to toggle the Stats panel. Default: Y (JoyButtonY).", NextOrder, synchronizedSetting: false); ResetConfigOrder(); MakeDropAllButton = config("9 - Additional Features", "Enable Drop All Button", Toggle.Off, "Adds a 'Drop All' button to your inventory for quickly dropping all items. USE WITH CAUTION!", NextOrder, synchronizedSetting: false); DropAllButtonPosition = config("9 - Additional Features", "Drop All Button Position", new Vector2(880f, 10f), "Position of the Drop All button in the inventory window (X, Y coordinates).", NextOrder, synchronizedSetting: false); Initializers.InitSlotsAndKeys(); Initializers.SetupEventHandlers(); _harmony.PatchAll(); InitializeConfigWatcher(); if (WishboneSlot.Value.isOn() && !IsSlotMarkedForRemoval("$item_wishbone")) { API.AddSlot("$item_wishbone", "Wishbone", 5); } if (WispLightSlot.Value.isOn() && !IsSlotMarkedForRemoval("$item_demister")) { API.AddSlot("$item_demister", "Demister", WishboneSlot.Value.isOn() ? 6 : 5); } int index = ExtendedPlayerInventory.slots.Count - QuickSlotsAmount.Value; API.UpdateSlots(index, 1); ExtendedPlayerInventory.slots.Insert(index, new Model.EquipmentSlot { Name = TrinketText.Value, OriginalName = "$azu_epi_trinket", IsQuickSlot = false, Get = (Player player) => ((Humanoid)player).m_trinketItem, Valid = (ItemData item) => item != null && (int)item.m_shared.m_itemType == 24 }); SlotHelpers.ResizeSlots(); SlotBackupManager.InitializeBuiltInSlotBackups(); ApplySlotChanges(); Localization.OnLanguageChange = (Action)Delegate.Combine(Localization.OnLanguageChange, new Action(API.RelocalizeSlots)); Localizer.OnLocalizationComplete += API.RelocalizeSlots; } internal void FullRebuild() { try { InventoryGuiPatches.UpdateInventory_Patch.RebuildQuickslots(); SlotHelpers.ResizeSlots(); } catch (Exception ex) { AzuExtendedPlayerInventoryLogger.LogError((object)("Error during FullRebuild (slot rebuild): " + ex.Message + "\n" + ex.StackTrace)); } if ((Object)(object)Player.m_localPlayer == (Object)null || (Object)(object)InventoryGui.instance == (Object)null) { AzuExtendedPlayerInventoryLogger.LogDebug((object)"FullRebuild skipped GUI phase - player or inventory not initialized"); return; } try { Layout.UpdateInventorySize(); InventoryHealth.FixHiddenItems(); SlotHelpers.UpdateEquipmentBackgroundAnchors(); UIBuilder.RebuildUI(); QuickAccessBar.ForceRefresh(); API.RelocalizeSlots(); } catch (Exception ex2) { AzuExtendedPlayerInventoryLogger.LogError((object)("Error during FullRebuild (GUI phase): " + ex2.Message + "\n" + ex2.StackTrace)); } } internal static void RefreshPanelButtonBindings() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)VanityPanelController.VanityButtonGo != (Object)null) { PanelUtilities.UpdateButtonBinding(VanityPanelController.VanityButtonGo, VanityToggleGamepadKey.Value); } if ((Object)(object)PersonalLoadoutGui.LoadoutsToggleButton != (Object)null) { PanelUtilities.UpdateButtonBinding(PersonalLoadoutGui.LoadoutsToggleButton, LoadoutToggleGamepadKey.Value); } if ((Object)(object)StatsPanelController.StatsButtonGo != (Object)null) { PanelUtilities.UpdateButtonBinding(StatsPanelController.StatsButtonGo, StatsToggleGamepadKey.Value); } } private void Start() { EAQ.CheckRandy(); WeightBase.CheckWeightBase(); Localizer.OnLocalizationComplete += delegate { AdvBackpacksCompat.Init(); JudesEquipmentCompat.Init(); Hunter_LegacyCompat.Init(); WizardryCompat.Init(); EpicLootCompat.Init(); JewelcraftingCompat.Init(); }; ArmoireCompat.CheckForArmoire(); ZenUICompat.DisableEquipmentSlots(); ValheimPlusCompat.Initialize(); } private void OnDestroy() { if (_cfgWatcher != null) { _cfgWatcher.EnableRaisingEvents = false; _cfgWatcher.Dispose(); } if (_debounce != null) { _debounce.Stop(); _debounce.Dispose(); } try { Localization.OnLanguageChange = (Action)Delegate.Remove(Localization.OnLanguageChange, new Action(API.RelocalizeSlots)); Localizer.OnLocalizationComplete -= API.RelocalizeSlots; } catch { } JewelcraftingCompat.Cleanup(); try { if (QuickSlotsAmount != null) { ClearSettingChangedEvent(QuickSlotsAmount); } if (ExtraRows != null) { ClearSettingChangedEvent(ExtraRows); } if (AddEquipmentRow != null) { ClearSettingChangedEvent(AddEquipmentRow); } if (DisplayEquipmentRowSeparate != null) { ClearSettingChangedEvent(DisplayEquipmentRowSeparate); } if (ShowQuickSlots != null) { ClearSettingChangedEvent(ShowQuickSlots); } if (SelectedPlayerStats != null) { ClearSettingChangedEvent(SelectedPlayerStats); } if (QuickSlotsPerRow != null) { ClearSettingChangedEvent(QuickSlotsPerRow); } if (RemovedEquipmentSlots != null) { ClearSettingChangedEvent(RemovedEquipmentSlots); } if (UserAddedSlots != null) { ClearSettingChangedEvent(UserAddedSlots); } if (WishboneSlot != null) { ClearSettingChangedEvent(WishboneSlot); } if (WispLightSlot != null) { ClearSettingChangedEvent(WispLightSlot); } if (VanityOption != null) { ClearSettingChangedEvent(VanityOption); } if (LoadoutOption != null) { ClearSettingChangedEvent(LoadoutOption); } if (VanityToggleGamepadKey != null) { ClearSettingChangedEvent(VanityToggleGamepadKey); } if (LoadoutToggleGamepadKey != null) { ClearSettingChangedEvent(LoadoutToggleGamepadKey); } if (StatsToggleGamepadKey != null) { ClearSettingChangedEvent(StatsToggleGamepadKey); } if (OldLayout != null) { ClearSettingChangedEvent(OldLayout); } if (HotkeyTexts != null) { ConfigEntry[] hotkeyTexts = HotkeyTexts; foreach (ConfigEntry val in hotkeyTexts) { if (val != null) { ClearSettingChangedEvent(val); } } } } catch (Exception ex) { AzuExtendedPlayerInventoryLogger.LogWarning((object)("Error during event cleanup: " + ex.Message)); } ((BaseUnityPlugin)this).Config.Save(); } private static void ClearSettingChangedEvent(ConfigEntry configEntry) { FieldInfo field = typeof(ConfigEntry).GetField("SettingChanged", BindingFlags.Instance | BindingFlags.Public); if (field != null) { field.SetValue(configEntry, null); } } private void InitializeConfigWatcher() { _debounce = new System.Timers.Timer(150.0) { AutoReset = false }; _debounce.Elapsed += delegate { ReadConfigValues(null, null); }; _cfgWatcher = new FileSystemWatcher(Paths.ConfigPath, ConfigFileName) { NotifyFilter = (NotifyFilters.FileName | NotifyFilters.Size | NotifyFilters.LastWrite), IncludeSubdirectories = false, SynchronizingObject = ThreadingHelper.SynchronizingObject, EnableRaisingEvents = true }; _cfgWatcher.Changed += delegate { _debounce?.Start(); }; _cfgWatcher.Created += delegate { _debounce?.Start(); }; _cfgWatcher.Renamed += delegate { _debounce?.Start(); }; } private void ReadConfigValues(object sender, FileSystemEventArgs e) { if (!File.Exists(ConfigFileFullPath)) { return; } try { AzuExtendedPlayerInventoryLogger.LogDebug((object)"ReadConfigValues called"); ((BaseUnityPlugin)this).Config.Reload(); } catch (Exception arg) { AzuExtendedPlayerInventoryLogger.LogError((object)("There was an issue loading your " + ConfigFileName)); AzuExtendedPlayerInventoryLogger.LogError((object)$"Please check your config entries for spelling and format!{Environment.NewLine}{arg}"); } } private void ResetConfigOrder(int order = 100) { _configOrder = order; } internal ConfigEntry config(string group, string name, T value, ConfigDescription description, bool synchronizedSetting = true) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown ConfigDescription val = new ConfigDescription(description.Description + (synchronizedSetting ? " [Synced with Server]" : " [Not Synced with Server]"), description.AcceptableValues, description.Tags); ConfigEntry val2 = ((BaseUnityPlugin)this).Config.Bind(group, name, value, val); ConfigSync.AddConfigEntry(val2).SynchronizedConfig = synchronizedSetting; return val2; } internal ConfigEntry config(string group, string name, T value, string description, bool synchronizedSetting = true) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown return config(group, name, value, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty()), synchronizedSetting); } internal ConfigEntry config(string group, string name, T value, ConfigDescription description, int order, bool synchronizedSetting = true) { //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Expected O, but got Unknown ConfigurationManagerAttributes configurationManagerAttributes = new ConfigurationManagerAttributes { Order = order }; object[] array = ((description.Tags.Length != 0) ? description.Tags.Append(configurationManagerAttributes).ToArray() : new object[1] { configurationManagerAttributes }); ConfigDescription val = new ConfigDescription(description.Description + (synchronizedSetting ? " [Synced with Server]" : " [Not Synced with Server]"), description.AcceptableValues, array); ConfigEntry val2 = ((BaseUnityPlugin)this).Config.Bind(group, name, value, val); ConfigSync.AddConfigEntry(val2).SynchronizedConfig = synchronizedSetting; return val2; } internal ConfigEntry config(string group, string name, T value, string description, int order, bool synchronizedSetting = true) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Expected O, but got Unknown return config(group, name, value, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty()), order, synchronizedSetting); } private unsafe static void StatsConfigDrawer(ConfigEntryBase entry) { //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) PlayerStatType[] source = (PlayerStatType[])Enum.GetValues(typeof(PlayerStatType)); source = source.Where((PlayerStatType x) => (int)x != 105).ToArray(); List list = ParseStatsList(SelectedPlayerStats.Value); GUILayout.Space(5f); GUILayout.BeginVertical(GUI.skin.box, Array.Empty()); GUILayout.Space(5f); GUILayout.BeginHorizontal(Array.Empty()); if (GUILayout.Button("Select All", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(false) })) { SelectedPlayerStats.Value = string.Join(",", source.Select((PlayerStatType s) => ((object)(*(PlayerStatType*)(&s))/*cast due to .constrained prefix*/).ToString())); } if (GUILayout.Button("Clear All", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(false) })) { SelectedPlayerStats.Value = ""; } GUILayout.EndHorizontal(); int num = 3; int num2 = Mathf.CeilToInt((float)source.Length / (float)num); GUILayout.BeginHorizontal(Array.Empty()); for (int num3 = 0; num3 < num; num3++) { GUILayout.BeginVertical(Array.Empty()); int num4 = num3 * num2; int num5 = Math.Min(num4 + num2, source.Length); for (int num6 = num4; num6 < num5 && num6 < source.Length; num6++) { PlayerStatType item = source[num6]; bool flag = list.Contains(item); bool flag2 = GUILayout.Toggle(flag, ((object)(*(PlayerStatType*)(&item))/*cast due to .constrained prefix*/).ToString(), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(false) }); if (flag2 != flag) { if (flag2) { list.Add(item); } else { list.Remove(item); } SelectedPlayerStats.Value = string.Join(",", list.Select((PlayerStatType s) => ((object)(*(PlayerStatType*)(&s))/*cast due to .constrained prefix*/).ToString())); } } GUILayout.EndVertical(); } GUILayout.EndHorizontal(); GUILayout.EndVertical(); } public static List ParseStatsList(string statsString) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) List list = new List(); if (string.IsNullOrWhiteSpace(statsString)) { return list; } string[] array = statsString.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries); for (int i = 0; i < array.Length; i++) { if (Enum.TryParse(array[i].Trim(), out PlayerStatType result)) { list.Add(result); } } return list; } private static void LiveStatsConfigDrawer(ConfigEntryBase entry) { LiveStatType[] array = (LiveStatType[])Enum.GetValues(typeof(LiveStatType)); List list = ParseLiveStatsList(SelectedLiveStats.Value); GUILayout.Space(5f); GUILayout.BeginVertical(GUI.skin.box, Array.Empty()); GUILayout.Space(5f); GUILayout.BeginHorizontal(Array.Empty()); if (GUILayout.Button("Select All", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(false) })) { SelectedLiveStats.Value = string.Join(",", array.Select((LiveStatType s) => s.ToString())); } if (GUILayout.Button("Clear All", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(false) })) { SelectedLiveStats.Value = ""; } GUILayout.EndHorizontal(); int num = 3; int num2 = Mathf.CeilToInt((float)array.Length / (float)num); GUILayout.BeginHorizontal(Array.Empty()); for (int num3 = 0; num3 < num; num3++) { GUILayout.BeginVertical(Array.Empty()); int num4 = num3 * num2; int num5 = Math.Min(num4 + num2, array.Length); for (int num6 = num4; num6 < num5 && num6 < array.Length; num6++) { LiveStatType liveStatType = array[num6]; bool flag = list.Contains(liveStatType); bool flag2 = GUILayout.Toggle(flag, FormatLiveStatName(liveStatType), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(false) }); if (flag2 != flag) { if (flag2) { list.Add(liveStatType); } else { list.Remove(liveStatType); } SelectedLiveStats.Value = string.Join(",", list.Select((LiveStatType s) => s.ToString())); } } GUILayout.EndVertical(); } GUILayout.EndHorizontal(); GUILayout.EndVertical(); } public static List ParseLiveStatsList(string statsString) { List list = new List(); if (string.IsNullOrWhiteSpace(statsString)) { return list; } string[] array = statsString.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries); for (int i = 0; i < array.Length; i++) { if (Enum.TryParse(array[i].Trim(), out var result)) { list.Add(result); } } return list; } private static string FormatLiveStatName(LiveStatType stat) { return Regex.Replace(stat.ToString(), "([a-z])([A-Z])", "$1 $2"); } private static void EquipmentSlotsConfigDrawer(ConfigEntryBase entry) { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Expected O, but got Unknown //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_0379: Unknown result type (might be due to invalid IL or missing references) //IL_037e: Unknown result type (might be due to invalid IL or missing references) //IL_0385: Unknown result type (might be due to invalid IL or missing references) //IL_0396: Expected O, but got Unknown //IL_046f: Unknown result type (might be due to invalid IL or missing references) //IL_0474: Unknown result type (might be due to invalid IL or missing references) //IL_047c: Unknown result type (might be due to invalid IL or missing references) //IL_048d: Expected O, but got Unknown //IL_04b0: Unknown result type (might be due to invalid IL or missing references) //IL_04b5: Unknown result type (might be due to invalid IL or missing references) //IL_04c6: Expected O, but got Unknown //IL_04c6: Unknown result type (might be due to invalid IL or missing references) //IL_04e8: Unknown result type (might be due to invalid IL or missing references) //IL_04ed: Unknown result type (might be due to invalid IL or missing references) //IL_024c: Unknown result type (might be due to invalid IL or missing references) //IL_08a6: Unknown result type (might be due to invalid IL or missing references) //IL_08ab: Unknown result type (might be due to invalid IL or missing references) //IL_08b2: Unknown result type (might be due to invalid IL or missing references) //IL_08c3: Expected O, but got Unknown //IL_08dc: Unknown result type (might be due to invalid IL or missing references) //IL_08e1: Unknown result type (might be due to invalid IL or missing references) //IL_08f3: Expected O, but got Unknown //IL_0902: Unknown result type (might be due to invalid IL or missing references) //IL_0907: Unknown result type (might be due to invalid IL or missing references) //IL_0919: Expected O, but got Unknown //IL_0928: Unknown result type (might be due to invalid IL or missing references) //IL_092d: Unknown result type (might be due to invalid IL or missing references) //IL_093f: Expected O, but got Unknown //IL_094e: Unknown result type (might be due to invalid IL or missing references) //IL_0953: Unknown result type (might be due to invalid IL or missing references) //IL_0965: Expected O, but got Unknown //IL_096f: Unknown result type (might be due to invalid IL or missing references) //IL_0974: Unknown result type (might be due to invalid IL or missing references) //IL_0985: Unknown result type (might be due to invalid IL or missing references) //IL_06e4: Unknown result type (might be due to invalid IL or missing references) //IL_06e9: Unknown result type (might be due to invalid IL or missing references) //IL_06f0: Unknown result type (might be due to invalid IL or missing references) //IL_0701: Expected O, but got Unknown //IL_071a: Unknown result type (might be due to invalid IL or missing references) //IL_071f: Unknown result type (might be due to invalid IL or missing references) //IL_0727: Unknown result type (might be due to invalid IL or missing references) //IL_072e: Unknown result type (might be due to invalid IL or missing references) //IL_073f: Expected O, but got Unknown //IL_028a: Unknown result type (might be due to invalid IL or missing references) //IL_028f: Unknown result type (might be due to invalid IL or missing references) //IL_0297: Unknown result type (might be due to invalid IL or missing references) //IL_02b2: Expected O, but got Unknown //IL_09e6: Unknown result type (might be due to invalid IL or missing references) //IL_0319: Unknown result type (might be due to invalid IL or missing references) //IL_031e: Unknown result type (might be due to invalid IL or missing references) //IL_033a: Expected O, but got Unknown //IL_02ca: Unknown result type (might be due to invalid IL or missing references) //IL_02cf: Unknown result type (might be due to invalid IL or missing references) //IL_02d7: 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_02df: Unknown result type (might be due to invalid IL or missing references) //IL_02e4: Unknown result type (might be due to invalid IL or missing references) //IL_02e5: Unknown result type (might be due to invalid IL or missing references) //IL_02f4: Expected O, but got Unknown //IL_0308: Expected O, but got Unknown //IL_07a6: Unknown result type (might be due to invalid IL or missing references) //IL_07ab: Unknown result type (might be due to invalid IL or missing references) //IL_07bc: Expected O, but got Unknown //IL_07d4: Unknown result type (might be due to invalid IL or missing references) //IL_07d9: Unknown result type (might be due to invalid IL or missing references) //IL_07e1: Unknown result type (might be due to invalid IL or missing references) //IL_07e2: Unknown result type (might be due to invalid IL or missing references) //IL_07e7: Unknown result type (might be due to invalid IL or missing references) //IL_07f7: Unknown result type (might be due to invalid IL or missing references) //IL_0806: Expected O, but got Unknown //IL_0810: Expected O, but got Unknown //IL_0854: Unknown result type (might be due to invalid IL or missing references) //IL_0859: Unknown result type (might be due to invalid IL or missing references) //IL_0861: Unknown result type (might be due to invalid IL or missing references) //IL_0868: Unknown result type (might be due to invalid IL or missing references) //IL_0879: Expected O, but got Unknown List allCurrentSlots = GetAllCurrentSlots(); List list = ParseSlotList(RemovedEquipmentSlots.Value); List builtInSlotNames = GetBuiltInSlotNames(); List userAddedSlotNames = GetUserAddedSlotNames(); GUILayout.Space(5f); GUILayout.BeginVertical(GUI.skin.box, Array.Empty()); GUILayout.Label("REMOVE EQUIPMENT SLOTS", new GUIStyle(GUI.skin.label) { fontStyle = (FontStyle)1, alignment = (TextAnchor)4 }, Array.Empty()); GUILayout.Space(5f); GUILayout.Label("Click to remove slots (WARNING: unequips items!):", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }); GUILayout.Space(5f); _slotsScrollPosition = GUILayout.BeginScrollView(_slotsScrollPosition, GUI.skin.box, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(200f) }); foreach (string slot in allCurrentSlots) { bool flag = list.Contains(slot); bool flag2 = builtInSlotNames.Contains(slot); bool flag3 = userAddedSlotNames.Contains(slot); GUILayout.BeginHorizontal(Array.Empty()); Color backgroundColor = GUI.backgroundColor; if (flag) { GUI.backgroundColor = Color.red; } if (GUILayout.Button(flag ? "✓ Removed" : "Remove", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(100f) })) { if (flag) { list.Remove(slot); RemovedEquipmentSlots.Value = string.Join(", ", from s in list.Distinct() orderby s select s); } else if (flag3) { List list2 = ParseUserAddedSlots(); list2.RemoveAll((string s) => s.StartsWith(slot.Trim() + ":")); UserAddedSlots.Value = string.Join(";", list2.Distinct()); } else { if (!list.Contains(slot)) { list.Add(slot); } RemovedEquipmentSlots.Value = string.Join(", ", from s in list.Distinct() orderby s select s); } } GUI.backgroundColor = backgroundColor; GUILayout.Label(slot ?? "", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(false) }); if (flag2) { GUILayout.Label("(Built-in)", new GUIStyle(GUI.skin.label) { fontSize = 10, fontStyle = (FontStyle)2 }, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(false) }); } else if (flag3) { GUILayout.Label("(Your Custom)", new GUIStyle(GUI.skin.label) { fontSize = 10, fontStyle = (FontStyle)2, normal = new GUIStyleState { textColor = Color.cyan } }, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(false) }); } else { GUILayout.Label("(API/Mod)", new GUIStyle(GUI.skin.label) { fontSize = 10 }, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(false) }); } GUILayout.EndHorizontal(); } GUILayout.EndScrollView(); GUILayout.Space(15f); GUILayout.Label("ADD CUSTOM EQUIPMENT SLOTS", new GUIStyle(GUI.skin.label) { fontStyle = (FontStyle)1, alignment = (TextAnchor)4 }, Array.Empty()); GUILayout.Space(5f); GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label("Slot Name:", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(80f) }); _newSlotName = GUILayout.TextField(_newSlotName, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label("Prefab Names:", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(80f) }); _newSlotPrefabs = GUILayout.TextField(_newSlotPrefabs, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }); if (GUILayout.Button("?", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(25f) })) { _showPrefabList = !_showPrefabList; } GUILayout.EndHorizontal(); GUILayout.Label("(Comma-separated list of item prefab names, e.g., 'HelmetBronze,HelmetIron')", new GUIStyle(GUI.skin.label) { fontSize = 10, fontStyle = (FontStyle)2 }, Array.Empty()); if (_showPrefabList) { GUILayout.Space(5f); GUILayout.Label("Available Item Prefabs:", new GUIStyle(GUI.skin.label) { fontStyle = (FontStyle)1 }, Array.Empty()); _prefabScrollPosition = GUILayout.BeginScrollView(_prefabScrollPosition, GUI.skin.box, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(150f) }); foreach (string availableItemPrefab in GetAvailableItemPrefabs()) { if (GUILayout.Button(availableItemPrefab, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(false) })) { if (string.IsNullOrEmpty(_newSlotPrefabs)) { _newSlotPrefabs = availableItemPrefab; } else if (!_newSlotPrefabs.Contains(availableItemPrefab)) { _newSlotPrefabs = _newSlotPrefabs + ", " + availableItemPrefab; } } } GUILayout.EndScrollView(); } GUILayout.Space(5f); if (GUILayout.Button("Add Slot", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(30f) }) && !string.IsNullOrWhiteSpace(_newSlotName) && !string.IsNullOrWhiteSpace(_newSlotPrefabs)) { string trimmedSlotName = _newSlotName.Trim(); string item = trimmedSlotName + ":" + _newSlotPrefabs.Trim(); List list3 = ParseUserAddedSlots(); if (list.Contains(trimmedSlotName)) { list.Remove(trimmedSlotName); RemovedEquipmentSlots.Value = string.Join(", ", from s in list.Distinct() orderby s select s); } list3.RemoveAll((string s) => s.StartsWith(trimmedSlotName + ":")); list3.Add(item); UserAddedSlots.Value = string.Join(";", list3.Distinct()); _newSlotName = ""; _newSlotPrefabs = ""; } List list4 = ParseUserAddedSlots(); if (list4.Count > 0) { GUILayout.Space(10f); GUILayout.Label($"YOUR CUSTOM SLOTS ({list4.Count})", new GUIStyle(GUI.skin.label) { fontStyle = (FontStyle)1, alignment = (TextAnchor)4 }, Array.Empty()); GUILayout.Space(3f); GUILayout.Label("Valid item prefabs for each custom slot:", new GUIStyle(GUI.skin.label) { fontSize = 10, fontStyle = (FontStyle)2, alignment = (TextAnchor)4 }, Array.Empty()); GUILayout.Space(5f); foreach (string item2 in list4) { string[] array = item2.Split(new char[1] { ':' }); if (array.Length == 2) { GUILayout.BeginVertical(GUI.skin.box, Array.Empty()); GUILayout.Label("• " + array[0], new GUIStyle(GUI.skin.label) { fontStyle = (FontStyle)1 }, Array.Empty()); GUILayout.Label(" Accepts: " + array[1], new GUIStyle(GUI.skin.label) { fontSize = 10, normal = new GUIStyleState { textColor = new Color(0.7f, 0.7f, 0.7f) } }, Array.Empty()); GUILayout.EndVertical(); GUILayout.Space(2f); } } GUILayout.Space(3f); GUILayout.Label("(Use 'Remove Equipment Slots' section above to remove slots)", new GUIStyle(GUI.skin.label) { fontSize = 9, fontStyle = (FontStyle)2, alignment = (TextAnchor)4 }, Array.Empty()); } GUILayout.Space(15f); GUILayout.BeginVertical(GUI.skin.box, Array.Empty()); GUILayout.Label("RESET TO DEFAULTS", new GUIStyle(GUI.skin.label) { fontStyle = (FontStyle)1, alignment = (TextAnchor)4 }, Array.Empty()); GUILayout.Space(5f); GUILayout.Label("This will:", new GUIStyle(GUI.skin.label) { fontSize = 10 }, Array.Empty()); GUILayout.Label(" • Remove all your custom slots", new GUIStyle(GUI.skin.label) { fontSize = 10 }, Array.Empty()); GUILayout.Label(" • Restore all hidden built-in slots", new GUIStyle(GUI.skin.label) { fontSize = 10 }, Array.Empty()); GUILayout.Label(" • Keep API/Mod-added slots (from other mods)", new GUIStyle(GUI.skin.label) { fontSize = 10 }, Array.Empty()); GUILayout.Space(5f); Color backgroundColor2 = GUI.backgroundColor; GUI.backgroundColor = new Color(1f, 0.5f, 0.5f); if (GUILayout.Button("Reset to Defaults", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(30f) })) { UserAddedSlots.Value = ""; RemovedEquipmentSlots.Value = ""; _newSlotName = ""; _newSlotPrefabs = ""; _showPrefabList = false; } GUI.backgroundColor = backgroundColor2; GUILayout.EndVertical(); GUILayout.Space(5f); GUILayout.EndVertical(); } private static List GetAllCurrentSlots() { List list = new List(); try { foreach (Model.Slot slot in ExtendedPlayerInventory.slots) { if (slot != null && !slot.IsQuickSlot && slot is Model.EquipmentSlot equipmentSlot) { string text = equipmentSlot.OriginalName ?? equipmentSlot.Name; if (!string.IsNullOrEmpty(text)) { list.Add(text); } } } } catch (Exception ex) { AzuExtendedPlayerInventoryLogger.LogWarning((object)("Error getting current slots: " + ex.Message)); } return list.Distinct().ToList(); } public static List GetBuiltInSlotNames() { return new List(8) { "$azu_epi_helmet", "$azu_epi_chest", "$azu_epi_legs", "$azu_epi_shoulder", "$azu_epi_utility", "$item_wishbone", "$item_demister", "$azu_epi_trinket" }; } private static List GetUserAddedSlotNames() { return (from s in ParseUserAddedSlots() select s.Split(new char[1] { ':' })[0].Trim() into name where !string.IsNullOrEmpty(name) select name).ToList(); } private static List GetAvailableItemPrefabs() { List list = new List(); try { if ((Object)(object)ObjectDB.instance != (Object)null && ObjectDB.instance.m_items != null) { foreach (GameObject item in ObjectDB.instance.m_items) { if ((Object)(object)item != (Object)null) { list.Add(((Object)item).name); } } } } catch (Exception ex) { AzuExtendedPlayerInventoryLogger.LogWarning((object)("Error getting item prefabs: " + ex.Message)); } return list.OrderBy((string p) => p).ToList(); } private static List ParseSlotList(string slotsString) { List list = new List(); if (string.IsNullOrWhiteSpace(slotsString)) { return list; } string[] array = slotsString.Split(new char[2] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries); for (int i = 0; i < array.Length; i++) { string text = array[i].Trim(); if (!string.IsNullOrEmpty(text)) { list.Add(text); } } return list; } private static List ParseUserAddedSlots() { List list = new List(); if (string.IsNullOrWhiteSpace(UserAddedSlots?.Value)) { return list; } string[] array = UserAddedSlots.Value.Split(new char[1] { ';' }, StringSplitOptions.RemoveEmptyEntries); for (int i = 0; i < array.Length; i++) { string text = array[i].Trim(); if (!string.IsNullOrEmpty(text)) { list.Add(text); } } return list; } internal static bool IsSlotMarkedForRemoval(string slotName) { if (string.IsNullOrWhiteSpace(RemovedEquipmentSlots?.Value)) { return false; } List list = ParseSlotList(RemovedEquipmentSlots.Value); if (list.Contains(slotName)) { return true; } if (Localization.m_instance == null) { return false; } if (slotName.StartsWith("$")) { string item = Localization.m_instance.Localize(slotName); if (list.Contains(item)) { return true; } } else { string text = "$item_" + slotName.ToLower(); if (list.Contains(text) || list.Contains(Localization.m_instance.Localize(text))) { return true; } } return false; } internal static void ApplySlotChanges() { try { List list = ParseSlotList(RemovedEquipmentSlots?.Value ?? ""); HashSet hashSet = new HashSet(); foreach (string backupKey in SlotBackupManager.GetBackupKeys()) { if (SlotBackupManager._userConfigSlotNames.Contains(backupKey)) { continue; } bool flag = list.Contains(backupKey); if (!flag && Localization.m_instance != null) { if (backupKey.StartsWith("$")) { string item = Localization.m_instance.Localize(backupKey); flag = list.Contains(item); } else { string text = "$item_" + backupKey.ToLower(); flag = list.Contains(text) || list.Contains(Localization.m_instance.Localize(text)); } } if (!flag) { Model.Slot slot = ExtendedPlayerInventory.slots.FirstOrDefault((Model.Slot s) => (s is Model.EquipmentSlot equipmentSlot && equipmentSlot.OriginalName == backupKey) || s?.Name == backupKey); if (slot != null && list.Contains(slot.Name)) { flag = true; } } if (flag) { hashSet.Add(backupKey); } else if (SlotBackupManager.RestoreSlotFromBackup(backupKey)) { AzuExtendedPlayerInventoryLogger.LogInfo((object)("Restored slot '" + backupKey + "' from backup")); } } foreach (string item2 in hashSet) { if (API.RemoveSlot(item2)) { AzuExtendedPlayerInventoryLogger.LogInfo((object)("Removed slot: " + item2)); } } foreach (string item3 in list) { if (hashSet.Contains(item3)) { continue; } bool flag2 = API.RemoveSlot(item3); if (!flag2 && Localization.m_instance != null) { if (item3.StartsWith("$")) { string text2 = Localization.m_instance.Localize(item3); if (text2 != item3) { flag2 = API.RemoveSlot(text2); } } else { flag2 = API.RemoveSlot("$item_" + item3.ToLower()); } } if (flag2) { AzuExtendedPlayerInventoryLogger.LogInfo((object)("Removed slot: " + item3)); } } List list2 = ParseUserAddedSlots(); HashSet hashSet2 = new HashSet(); foreach (string item4 in list2) { string[] array = item4.Split(new char[1] { ':' }); if (array.Length == 2) { hashSet2.Add(array[0].Trim()); } } foreach (string item5 in SlotBackupManager._userConfigSlotNames.ToList()) { if (!hashSet2.Contains(item5) && API.RemoveSlot(item5)) { AzuExtendedPlayerInventoryLogger.LogInfo((object)("Removed user slot '" + item5 + "' (no longer in config)")); } } SlotBackupManager._userConfigSlotNames.Clear(); SlotBackupManager._userConfigSlotNames.UnionWith(hashSet2); foreach (string item6 in list2) { string[] array2 = item6.Split(new char[1] { ':' }); if (array2.Length != 2) { continue; } string text3 = array2[0].Trim(); string[] array3 = (from p in array2[1].Split(new char[1] { ',' }) select p.Trim() into p where !string.IsNullOrEmpty(p) select p).ToArray(); if (string.IsNullOrEmpty(text3) || array3.Length == 0) { continue; } int index; if (IsSlotMarkedForRemoval(text3)) { AzuExtendedPlayerInventoryLogger.LogWarning((object)("User slot '" + text3 + "' is in both add and remove lists - skipping addition (remove takes precedence)")); } else if (!API.TryGetSlotIndexByName(text3, out index, allowLocalized: false)) { if (array3.Length == 1) { API.AddSlot(text3, array3[0]); } else { API.AddSlot(text3, array3); } AzuExtendedPlayerInventoryLogger.LogInfo((object)("Added user slot: " + text3 + " with prefabs: " + string.Join(", ", array3))); } else { AzuExtendedPlayerInventoryLogger.LogDebug((object)("User slot '" + text3 + "' already exists, skipping addition")); } } } catch (Exception ex) { AzuExtendedPlayerInventoryLogger.LogError((object)("Error applying slot changes: " + ex.Message)); } } } [PublicAPI] public class API { public delegate void SlotAddedHandler(string slotName); public delegate void SlotRemovedHandler(string slotName); internal static HashSet CustomSlots { get; } = new HashSet(); public static event Action? OnHudAwake; public static event Action? OnHudAwakeComplete; public static event Action? OnHudUpdate; public static event Action? OnHudUpdateComplete; public static event Action? OnBeforeQuickSlotsAdded; public static event Action? OnQuickSlotsAdded; public static event SlotAddedHandler? SlotAdded; public static event SlotRemovedHandler? SlotRemoved; public static event Action? OnRegisterVisualPrefab; public static bool IsLoaded() { return true; } public static ItemType GetFakeItemType() { return (ItemType)AzuExtendedPlayerInventoryPlugin.FakeType; } public static bool AddSlot(string slotName, Func getItem, Func isValid, int index = -1) { if (string.IsNullOrWhiteSpace(slotName) || (getItem == null && isValid == null)) { return false; } AzuExtendedPlayerInventoryPlugin.AzuExtendedPlayerInventoryLogger.LogDebug((object)("API.AddSlot called, asking to add slot " + slotName)); if (AzuExtendedPlayerInventoryPlugin.IsSlotMarkedForRemoval(slotName)) { return false; } AzuExtendedPlayerInventoryPlugin.AzuExtendedPlayerInventoryLogger.LogDebug((object)("API.AddSlot proceeding to add slot " + slotName)); int num = ExtendedPlayerInventory.slots.FindIndex((Model.Slot? s) => s != null && (s.Name == slotName || (Localization.m_instance != null && s.Name == Localization.m_instance.Localize(slotName)))); if (num >= 0 && ExtendedPlayerInventory.slots[num] is Model.EquipmentSlot slot) { ComposeOntoSlot(slot, isValid, getItem); AzuExtendedPlayerInventoryPlugin.AzuExtendedPlayerInventoryLogger.LogDebug((object)("Extended slot " + slotName)); return true; } Model.EquipmentSlot equipmentSlot = new Model.EquipmentSlot { Name = ((slotName.StartsWith("$") && Localization.m_instance != null) ? Localization.m_instance.Localize(slotName) : slotName), OriginalName = slotName, Get = getItem, Valid = isValid, IsAPIAdded = true }; if (index < 0 || index > ExtendedPlayerInventory.slots.Count - AzuExtendedPlayerInventoryPlugin.QuickSlotsAmount.Value) { index = ExtendedPlayerInventory.slots.Count - AzuExtendedPlayerInventoryPlugin.QuickSlotsAmount.Value; } UpdateSlots(index, 1); ExtendedPlayerInventory.slots.Insert(index, equipmentSlot); CustomSlots.Add(equipmentSlot); SlotBackupManager.BackupSlot(equipmentSlot); SlotHelpers.ResizeSlots(); SlotHelpers.UpdateEquipmentBackgroundAnchors(); AzuExtendedPlayerInventoryPlugin.AzuExtendedPlayerInventoryLogger.LogDebug((object)("Added slot " + slotName + ", localized as '" + equipmentSlot.Name + "'")); API.SlotAdded?.Invoke(slotName); return true; } public static bool AddSlot(string slotName, string prefabName, int index = -1) { if (string.IsNullOrWhiteSpace(slotName) || string.IsNullOrWhiteSpace(prefabName)) { return false; } bool flag = AddSlot(slotName, Get, IsValid, index); if (flag) { RegisterVisualsForSlot(slotName, prefabName); } return flag; ItemData? Get(Player p) { if (p == null) { return null; } Inventory inventory = ((Humanoid)p).GetInventory(); if (inventory == null) { return null; } return inventory.GetEquippedItems()?.FirstOrDefault((Func)((ItemData i) => i != null && Object.op_Implicit((Object)(object)i.m_dropPrefab) && ((Object)i.m_dropPrefab).name == prefabName)); } bool IsValid(ItemData item) { if (item != null && Object.op_Implicit((Object)(object)item.m_dropPrefab)) { return ((Object)item.m_dropPrefab).name == prefabName; } return false; } } public static bool AddSlot(string slotName, IEnumerable prefabNames, int index = -1) { if (string.IsNullOrWhiteSpace(slotName) || prefabNames == null) { return false; } HashSet set = new HashSet(prefabNames.Where((string n) => !string.IsNullOrWhiteSpace(n)), StringComparer.Ordinal); if (set.Count == 0) { return false; } bool num = AddSlot(slotName, Get, IsValid, index); if (num) { RegisterVisualsForSlot(slotName, set.ToArray()); } return num; ItemData? Get(Player p) { if (p == null) { return null; } Inventory inventory = ((Humanoid)p).GetInventory(); if (inventory == null) { return null; } return inventory.GetEquippedItems()?.FirstOrDefault((Func)((ItemData i) => i != null && Object.op_Implicit((Object)(object)i.m_dropPrefab) && set.Contains(((Object)i.m_dropPrefab).name))); } bool IsValid(ItemData item) { if (item != null && Object.op_Implicit((Object)(object)item.m_dropPrefab)) { return set.Contains(((Object)item.m_dropPrefab).name); } return false; } } public static bool AddSlot(string slotName, Func isValid, int index = -1, IEnumerable? prefabNamesForVisuals = null) { if (string.IsNullOrWhiteSpace(slotName) || isValid == null) { return false; } bool num = AddSlot(slotName, AutoGet, isValid, index); if (num && prefabNamesForVisuals != null) { RegisterVisualsForSlot(slotName, prefabNamesForVisuals.ToArray()); } return num; ItemData? AutoGet(Player p) { if (p == null) { return null; } Inventory inventory = ((Humanoid)p).GetInventory(); if (inventory == null) { return null; } return inventory.GetEquippedItems()?.FirstOrDefault((Func)((ItemData i) => i != null && isValid(i))); } } public static bool AddQuickSlot(string slotName, bool showName = false, int index = -1) { if (string.IsNullOrWhiteSpace(slotName)) { return false; } int num = ExtendedPlayerInventory.slots.FindIndex((Model.Slot? s) => s?.Name == slotName); if (num >= 0 && ExtendedPlayerInventory.slots[num] is Model.EquipmentSlot) { return true; } Model.EquipmentSlot item = new Model.EquipmentSlot { Name = ((!showName) ? "" : ((slotName.StartsWith("$") && Localization.m_instance != null) ? Localization.m_instance.Localize(slotName) : slotName)), Valid = (ItemData val) => true, IsAPIAdded = true, IsQuickSlot = true }; if (index < 0 || index > ExtendedPlayerInventory.slots.Count - AzuExtendedPlayerInventoryPlugin.QuickSlotsAmount.Value) { index = ExtendedPlayerInventory.slots.Count - AzuExtendedPlayerInventoryPlugin.QuickSlotsAmount.Value; } UpdateSlots(index, 1); ExtendedPlayerInventory.slots.Insert(index, item); CustomSlots.Add(item); SlotHelpers.ResizeSlots(); SlotHelpers.UpdateEquipmentBackgroundAnchors(); AzuExtendedPlayerInventoryPlugin.AzuExtendedPlayerInventoryLogger.LogDebug((object)("Added slot " + slotName)); API.SlotAdded?.Invoke(slotName); return true; } public static bool RemoveSlot(string slotName) { //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) int num = ExtendedPlayerInventory.slots.FindIndex((Model.Slot? s) => s.Name == slotName || (s is Model.EquipmentSlot equipmentSlot2 && equipmentSlot2.OriginalName == slotName)); if (num >= 0 && ExtendedPlayerInventory.slots[num] is Model.EquipmentSlot equipmentSlot) { if (Object.op_Implicit((Object)(object)Player.m_localPlayer)) { ItemData val = equipmentSlot.Get?.Invoke(Player.m_localPlayer); if (val != null) { ((Humanoid)Player.m_localPlayer).UnequipItem(val, true); } } if (Object.op_Implicit((Object)(object)Player.m_localPlayer)) { Inventory inventory = ((Humanoid)Player.m_localPlayer).GetInventory(); Vector2i val2 = inventory.EpiIndexToGridPos(num); ItemData itemAt = inventory.GetItemAt(val2.x, val2.y); if (itemAt != null) { inventory.RemoveItem(itemAt); Vector2i val3 = inventory.FindEmptyQuickAware(topFirst: true); if (val3.x >= 0 && val3.y >= 0) { itemAt.m_gridPos = val3; inventory.AddItem(itemAt); AzuExtendedPlayerInventoryPlugin.AzuExtendedPlayerInventoryLogger.LogInfo((object)$"Relocated {Localization.m_instance.Localize(itemAt.m_shared.m_name)} from removed slot to ({val3.x}, {val3.y})"); } else { AzuExtendedPlayerInventoryPlugin.AzuExtendedPlayerInventoryLogger.LogWarning((object)("No room for " + Localization.m_instance.Localize(itemAt.m_shared.m_name) + " after slot removal, dropping item.")); ((Humanoid)Player.m_localPlayer).DropItem(inventory, itemAt, itemAt.m_stack); } } } UpdateSlots(num, -1); ExtendedPlayerInventory.slots.RemoveAt(num); SlotHelpers.ResizeSlots(); SlotHelpers.UpdateEquipmentBackgroundAnchors(); InventoryHealth.FixHiddenItems(); API.SlotRemoved?.Invoke(slotName); return true; } return false; } public static SlotInfo GetSlots() { return BuildSlotInfo((Model.Slot _) => true); } public static SlotInfo GetQuickSlots() { return BuildSlotInfo((Model.Slot s) => s.IsQuickSlot); } public static SlotInfo GetEquipmentSlots() { return BuildSlotInfo((Model.Slot s) => !s.IsQuickSlot && s.EquipmentSlot != null); } private static SlotInfo BuildSlotInfo(Func filter) { Model.Slot[] source = ExtendedPlayerInventory.slots.Where((Model.Slot s) => s != null && filter(s)).ToArray(); return new SlotInfo { SlotNames = source.Select((Model.Slot s) => s.Name).ToArray(), OriginalSlotNames = source.Select((Model.Slot s) => s.OriginalName).ToArray(), SlotPositions = source.Select((Model.Slot s) => s.Position).ToArray(), GetItemFuncs = source.Select((Model.Slot s) => s.EquipmentSlot?.Get).ToArray(), IsValidFuncs = source.Select((Model.Slot s) => s.EquipmentSlot?.Valid).ToArray() }; } public static List GetQuickSlotsItems() { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) List list = new List(); if ((Object)(object)Player.m_localPlayer == (Object)null) { return list; } Inventory inventory = ((Humanoid)Player.m_localPlayer).GetInventory(); inventory.GetWidth(); Layout.GetBaseSlotIndex(inventory); foreach (SlotSnapshot quickSlotSnapshot in GetQuickSlotSnapshots(inventory)) { ItemData itemAt = inventory.GetItemAt(quickSlotSnapshot.GridPos.x, quickSlotSnapshot.GridPos.y); if (itemAt != null) { list.Add(itemAt); } } return list; } public static int GetAddedRows(int width) { return Mathf.CeilToInt((float)ExtendedPlayerInventory.slots.Count / (float)width); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int GetFullHeight(int width) { return 4 + AzuExtendedPlayerInventoryPlugin.ExtraRows.Value + (AzuExtendedPlayerInventoryPlugin.AddEquipmentRow.Value.isOn() ? GetAddedRows(width) : 0); } public static void RegisterVisualPrefabs(string slotName, params (string prefabName, string visualName)[] pairs) { for (int i = 0; i < pairs.Length; i++) { var (text, visualName) = pairs[i]; if (!string.IsNullOrWhiteSpace(text)) { CustomEquipVisuals.Register(text); CustomEquipVisuals.RegisterForSlot(text, slotName, visualName); try { API.OnRegisterVisualPrefab?.Invoke(text); } catch { } } } } public static int GetSlotCount() { return ExtendedPlayerInventory.slots.Count; } public static bool TryGetSlotIndexByName(string slotName, out int index, bool allowLocalized = true) { index = -1; if (string.IsNullOrWhiteSpace(slotName)) { return false; } List slots = ExtendedPlayerInventory.slots; for (int i = 0; i < slots.Count; i++) { Model.Slot slot = slots[i]; if (slot != null && (string.Equals(slot.OriginalName, slotName, StringComparison.Ordinal) || (allowLocalized && string.Equals(slot.Name, slotName, StringComparison.Ordinal)))) { index = i; return true; } } return false; } public static bool TryGetSlotDescriptor(int index, out SlotDescriptor desc) { //IL_0079: Unknown result type (might be due to invalid IL or missing references) desc = default(SlotDescriptor); List slots = ExtendedPlayerInventory.slots; if ((uint)index >= (uint)slots.Count) { return false; } Model.Slot slot = slots[index]; if (slot == null) { return false; } bool isEquipmentSlot = slot is Model.EquipmentSlot && !slot.IsQuickSlot; bool isQuickSlot = slot?.IsQuickSlot ?? false; bool isCustom = IsCustomSlot(slot as Model.EquipmentSlot); desc = new SlotDescriptor(index, slot.Name ?? string.Empty, slot.OriginalName ?? string.Empty, isQuickSlot, isEquipmentSlot, isCustom, slot.Position); return true; } public static int GetSlotGridLinearIndex(Inventory inv, int slotIndex) { if (inv == null) { return -1; } int slotCount = GetSlotCount(); if ((uint)slotIndex >= (uint)slotCount) { return -1; } return Layout.GetBaseSlotIndex(inv) + slotIndex; } public static Vector2i GetSlotGridPos(Inventory inv, int slotIndex) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) int slotGridLinearIndex = GetSlotGridLinearIndex(inv, slotIndex); if (slotGridLinearIndex < 0) { return new Vector2i(-1, -1); } int width = inv.GetWidth(); return new Vector2i(slotGridLinearIndex % width, slotGridLinearIndex / width); } public static bool TryGetSlotIndexAtGridPos(Inventory inv, Vector2i gridPos, out int slotIndex) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) slotIndex = -1; if (inv == null) { return false; } int width = inv.GetWidth(); int num = Layout.NormalRows(inv); if (gridPos.y < num) { return false; } int num2 = gridPos.y * width + gridPos.x; int num3 = num * width; int num4 = num2 - num3; int slotCount = GetSlotCount(); if ((uint)num4 >= (uint)slotCount) { return false; } slotIndex = num4; return true; } public static bool IsEquipmentCell(Inventory inv, int x, int y, out int slotIndex) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) if (!TryGetSlotIndexAtGridPos(inv, new Vector2i(x, y), out slotIndex)) { return false; } if (TryGetSlotDescriptor(slotIndex, out var desc)) { return desc.IsEquipmentSlot; } return false; } public static bool IsQuickCell(Inventory inv, int x, int y, out int slotIndex) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) if (!TryGetSlotIndexAtGridPos(inv, new Vector2i(x, y), out slotIndex)) { return false; } if (TryGetSlotDescriptor(slotIndex, out var desc)) { return desc.IsQuickSlot; } return false; } public static bool TryGetSlotSnapshot(Inventory inv, int slotIndex, out SlotSnapshot snapshot) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) snapshot = default(SlotSnapshot); if (inv == null) { return false; } if (!TryGetSlotDescriptor(slotIndex, out var desc)) { return false; } bool occupied = ExtendedPlayerInventory.slots[slotIndex]?.Occupied ?? false; Vector2i slotGridPos = GetSlotGridPos(inv, slotIndex); int slotGridLinearIndex = GetSlotGridLinearIndex(inv, slotIndex); snapshot = new SlotSnapshot(desc, occupied, slotGridPos, slotGridLinearIndex); return true; } public static IEnumerable EnumerateSlots() { int count = GetSlotCount(); int i = 0; while (i < count) { if (TryGetSlotDescriptor(i, out var desc)) { yield return desc; } int num = i + 1; i = num; } } public static IEnumerable GetAllSlotSnapshots(Inventory inv) { int count = GetSlotCount(); int i = 0; while (i < count) { if (TryGetSlotSnapshot(inv, i, out var snapshot)) { yield return snapshot; } int num = i + 1; i = num; } } public static IEnumerable GetQuickSlotSnapshots(Inventory inv) { foreach (SlotSnapshot allSlotSnapshot in GetAllSlotSnapshots(inv)) { if (allSlotSnapshot.Descriptor.IsQuickSlot) { yield return allSlotSnapshot; } } } public static IEnumerable GetEquipmentSlotSnapshots(Inventory inv) { foreach (SlotSnapshot allSlotSnapshot in GetAllSlotSnapshots(inv)) { if (allSlotSnapshot.Descriptor.IsEquipmentSlot) { yield return allSlotSnapshot; } } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool TryGetSlotIndexByItem(Player player, ItemData item, out int slotIndex) { //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) slotIndex = -1; if (!Object.op_Implicit((Object)(object)player) || item == null) { return false; } int slotCount = GetSlotCount(); for (int i = 0; i < slotCount; i++) { if (TryGetSlotDescriptor(i, out var desc) && desc.IsEquipmentSlot && TryGetEquippedItem(i, out ItemData item2) && item2 == item) { slotIndex = i; return true; } } Inventory inventory = ((Humanoid)player).GetInventory(); if (inventory == null) { return false; } foreach (SlotSnapshot quickSlotSnapshot in GetQuickSlotSnapshots(inventory)) { if (inventory.GetItemAt(quickSlotSnapshot.GridPos.x, quickSlotSnapshot.GridPos.y) == item) { slotIndex = quickSlotSnapshot.Descriptor.Index; return true; } } return false; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool TryGetSlotIndexByItem(ItemData item, out int slotIndex) { return TryGetSlotIndexByItem(Player.m_localPlayer, item, out slotIndex); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool TryGetSlotDescriptorByItem(Player player, ItemData item, out SlotDescriptor desc) { desc = default(SlotDescriptor); if (!TryGetSlotIndexByItem(player, item, out var slotIndex)) { return false; } return TryGetSlotDescriptor(slotIndex, out desc); } public static bool SlotValidates(int slotIndex, ItemData item) { List slots = ExtendedPlayerInventory.slots; if ((uint)slotIndex >= (uint)slots.Count) { return false; } if (slots[slotIndex] is Model.EquipmentSlot equipmentSlot) { if (equipmentSlot.Valid == null) { return false; } try { return equipmentSlot.Valid(item); } catch { return false; } } Model.Slot slot = slots[slotIndex]; if (slot != null && slot.IsQuickSlot) { return true; } return false; } public static bool TryGetEquippedItem(int slotIndex, out ItemData? item) { item = null; if ((Object)(object)Player.m_localPlayer == (Object)null) { return false; } List slots = ExtendedPlayerInventory.slots; if ((uint)slotIndex >= (uint)slots.Count) { return false; } if (slots[slotIndex] is Model.EquipmentSlot equipmentSlot) { try { item = equipmentSlot.Get?.Invoke(Player.m_localPlayer); return item != null; } catch { item = null; return false; } } return false; } public static bool TryGetSlotDescriptorByName(string slotName, out SlotDescriptor desc, bool allowLocalized = true) { desc = default(SlotDescriptor); if (!TryGetSlotIndexByName(slotName, out var index, allowLocalized)) { return false; } return TryGetSlotDescriptor(index, out desc); } private static void RegisterVisualsForSlot(string slotName, params string[] prefabNames) { if (string.IsNullOrWhiteSpace(slotName) || prefabNames == null) { return; } foreach (string item in prefabNames.Where((string s) => !string.IsNullOrWhiteSpace(s))) { CustomEquipVisuals.Register(item); CustomEquipVisuals.RegisterForSlot(item, slotName); try { API.OnRegisterVisualPrefab?.Invoke(item); } catch { } } } private static void ComposeOntoSlot(Model.EquipmentSlot slot, Func isValid, Func getItem) { Func originalValid = slot.Valid; Func originalGet = slot.Get; slot.Valid = delegate(ItemData item) { try { Func func = originalValid; if (func != null && func(item)) { return true; } } catch { } try { return isValid(item); } catch { return false; } }; slot.Get = delegate(Player player) { try { ItemData val = originalGet?.Invoke(player); if (val != null) { return val; } } catch { } try { return getItem(player); } catch { return (ItemData?)null; } }; } internal static bool IsCustomSlot(Model.EquipmentSlot? slot) { return CustomSlots.Contains(slot); } public static bool IsCustomSlot(SlotDescriptor d) { return d.IsCustom; } public static bool IsQuickSlot(SlotDescriptor d) { return d.IsQuickSlot; } public static bool IsEquipmentSlot(SlotDescriptor d) { return d.IsEquipmentSlot; } public static void HudAwake(Hud __instance) { API.OnHudAwake?.Invoke(__instance); } public static void HudAwakeComplete(Hud __instance) { API.OnHudAwakeComplete?.Invoke(__instance); } public static void HudUpdate(Hud __instance) { API.OnHudUpdate?.Invoke(__instance); } public static void HudUpdateComplete(Hud __instance) { API.OnHudUpdateComplete?.Invoke(__instance); } public static void BeforeQuickSlotsAdded() { API.OnBeforeQuickSlotsAdded?.Invoke(); } public static void QuickSlotsAdded() { API.OnQuickSlotsAdded?.Invoke(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static bool TryGetModelSlot(int slotIndex, out Model.Slot? slot) { slot = null; List slots = ExtendedPlayerInventory.slots; if ((uint)slotIndex >= (uint)slots.Count) { return false; } slot = slots[slotIndex]; return slot != null; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static bool TryGetEquipmentModelSlot(int slotIndex, out Model.EquipmentSlot? equipmentSlot) { equipmentSlot = null; if (!TryGetModelSlot(slotIndex, out Model.Slot slot)) { return false; } equipmentSlot = slot as Model.EquipmentSlot; return equipmentSlot != null; } internal static bool TryGetModelSlotByName(string slotName, out Model.Slot? slot, bool allowLocalized = true) { slot = null; if (!TryGetSlotIndexByName(slotName, out var index, allowLocalized)) { return false; } return TryGetModelSlot(index, out slot); } internal static bool TryGetModelSlotByItem(Player player, ItemData item, out Model.Slot? slot) { slot = null; if (!TryGetSlotIndexByItem(player, item, out var slotIndex)) { return false; } return TryGetModelSlot(slotIndex, out slot); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static bool TryGetModelSlotByItem(ItemData item, out Model.Slot? slot) { return TryGetModelSlotByItem(Player.m_localPlayer, item, out slot); } internal static bool TryGetModelSlotAtGridPos(Inventory inv, Vector2i gridPos, out Model.Slot? slot) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) slot = null; if (!TryGetSlotIndexAtGridPos(inv, gridPos, out var slotIndex)) { return false; } return TryGetModelSlot(slotIndex, out slot); } internal static Model.Slot?[] GetModelSlotsSnapshot() { return ExtendedPlayerInventory.slots.ToArray(); } internal static IEnumerable EnumerateModelSlots() { List slots = ExtendedPlayerInventory.slots; int i = 0; while (i < slots.Count) { yield return slots[i]; int num = i + 1; i = num; } } internal static void UpdateSlots(int index, int shift) { //IL_0068: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)Player.m_localPlayer)) { return; } Inventory inventory = ((Humanoid)Player.m_localPlayer).m_inventory; int width = inventory.GetWidth(); int num = 4 + AzuExtendedPlayerInventoryPlugin.ExtraRows.Value; foreach (ItemData item in inventory.m_inventory) { if ((item.m_gridPos.y - num) * width + item.m_gridPos.x >= index) { _ = item.m_gridPos; item.m_gridPos.x += shift; if (item.m_gridPos.x < 0) { item.m_gridPos.x = width - 1; item.m_gridPos.y--; } if (item.m_gridPos.x >= width) { item.m_gridPos.x = 0; item.m_gridPos.y++; } } } inventory.m_height = num + Mathf.CeilToInt((float)(ExtendedPlayerInventory.slots.Count + shift) / (float)width); } internal static void RelocalizeSlots() { if (Localization.m_instance == null) { return; } List builtInSlotNames = AzuExtendedPlayerInventoryPlugin.GetBuiltInSlotNames(); foreach (Model.Slot slot in ExtendedPlayerInventory.slots) { if (slot == null || string.IsNullOrWhiteSpace(slot.OriginalName) || !slot.OriginalName.StartsWith("$", StringComparison.Ordinal)) { continue; } bool flag = builtInSlotNames.Contains(slot.OriginalName); string text = Localization.m_instance.Localize(slot.OriginalName); if (slot.Name == text && !flag) { continue; } if (flag) { switch (slot.OriginalName) { case "$azu_epi_helmet": slot.Name = (string.IsNullOrWhiteSpace(AzuExtendedPlayerInventoryPlugin.HelmetText.Value) ? text : (AzuExtendedPlayerInventoryPlugin.HelmetText.Value.StartsWith("$", StringComparison.Ordinal) ? Localization.m_instance.Localize(AzuExtendedPlayerInventoryPlugin.HelmetText.Value) : AzuExtendedPlayerInventoryPlugin.HelmetText.Value)); break; case "$azu_epi_chest": slot.Name = (string.IsNullOrWhiteSpace(AzuExtendedPlayerInventoryPlugin.ChestText.Value) ? text : (AzuExtendedPlayerInventoryPlugin.ChestText.Value.StartsWith("$", StringComparison.Ordinal) ? Localization.m_instance.Localize(AzuExtendedPlayerInventoryPlugin.ChestText.Value) : AzuExtendedPlayerInventoryPlugin.ChestText.Value)); break; case "$azu_epi_legs": slot.Name = (string.IsNullOrWhiteSpace(AzuExtendedPlayerInventoryPlugin.LegsText.Value) ? text : (AzuExtendedPlayerInventoryPlugin.LegsText.Value.StartsWith("$", StringComparison.Ordinal) ? Localization.m_instance.Localize(AzuExtendedPlayerInventoryPlugin.LegsText.Value) : AzuExtendedPlayerInventoryPlugin.LegsText.Value)); break; case "$azu_epi_shoulder": slot.Name = (string.IsNullOrWhiteSpace(AzuExtendedPlayerInventoryPlugin.BackText.Value) ? text : (AzuExtendedPlayerInventoryPlugin.BackText.Value.StartsWith("$", StringComparison.Ordinal) ? Localization.m_instance.Localize(AzuExtendedPlayerInventoryPlugin.BackText.Value) : AzuExtendedPlayerInventoryPlugin.BackText.Value)); break; case "$azu_epi_utility": slot.Name = (string.IsNullOrWhiteSpace(AzuExtendedPlayerInventoryPlugin.UtilityText.Value) ? text : (AzuExtendedPlayerInventoryPlugin.UtilityText.Value.StartsWith("$", StringComparison.Ordinal) ? Localization.m_instance.Localize(AzuExtendedPlayerInventoryPlugin.UtilityText.Value) : AzuExtendedPlayerInventoryPlugin.UtilityText.Value)); break; case "$azu_epi_trinket": slot.Name = (string.IsNullOrWhiteSpace(AzuExtendedPlayerInventoryPlugin.TrinketText.Value) ? text : (AzuExtendedPlayerInventoryPlugin.TrinketText.Value.StartsWith("$", StringComparison.Ordinal) ? Localization.m_instance.Localize(AzuExtendedPlayerInventoryPlugin.TrinketText.Value) : AzuExtendedPlayerInventoryPlugin.TrinketText.Value)); break; default: slot.Name = text; break; } AzuExtendedPlayerInventoryPlugin.AzuExtendedPlayerInventoryLogger.LogDebug((object)("Relocalizing slot '" + slot.Name + "' to '" + text + "' from key '" + slot.OriginalName + "'")); } else { AzuExtendedPlayerInventoryPlugin.AzuExtendedPlayerInventoryLogger.LogDebug((object)("Relocalizing slot '" + slot.Name + "' to '" + text + "' from key '" + slot.OriginalName + "'")); slot.Name = text; } } } } [PublicAPI] public class SlotInfo { public string[] SlotNames { get; set; } = Array.Empty(); public string[] OriginalSlotNames { get; set; } = Array.Empty(); public Vector2[] SlotPositions { get; set; } = Array.Empty(); public Func?[] GetItemFuncs { get; set; } = Array.Empty>(); public Func?[] IsValidFuncs { get; set; } = Array.Empty>(); } [PublicAPI] public struct SlotDescriptor { public int Index { get; } public string Name { get; } public string OriginalName { get; } public bool IsQuickSlot { get; } public bool IsEquipmentSlot { get; } public bool IsCustom { get; } public Vector2 UiPosition { get; } public SlotDescriptor(int index, string name, string originalName, bool isQuickSlot, bool isEquipmentSlot, bool isCustom, Vector2 uiPosition) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) Index = index; Name = name ?? string.Empty; OriginalName = originalName ?? string.Empty; IsQuickSlot = isQuickSlot; IsEquipmentSlot = isEquipmentSlot; IsCustom = isCustom; UiPosition = uiPosition; } } [PublicAPI] public struct SlotSnapshot { public SlotDescriptor Descriptor { get; } public bool Occupied { get; } public Vector2i GridPos { get; } public int LinearGridIndex { get; } public SlotSnapshot(SlotDescriptor descriptor, bool occupied, Vector2i gridPos, int linearGridIndex) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) Descriptor = descriptor; Occupied = occupied; GridPos = gridPos; LinearGridIndex = linearGridIndex; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool Validates(ItemData item) { return API.SlotValidates(Descriptor.Index, item); } } } namespace AzuEPI.Game.Slots { internal static class SlotBackupManager { private class SlotBackup { public Model.EquipmentSlot Slot { get; set; } public int OriginalIndex { get; set; } } internal static readonly HashSet _userConfigSlotNames = new HashSet(); private static readonly Dictionary _slotBackups = new Dictionary(); internal static void InitializeBuiltInSlotBackups() { foreach (Model.Slot slot in ExtendedPlayerInventory.slots) { if (slot is Model.EquipmentSlot { IsQuickSlot: false } equipmentSlot) { BackupSlot(equipmentSlot); } } } public static void BackupSlot(Model.EquipmentSlot slot) { string text = (string.IsNullOrWhiteSpace(slot.OriginalName) ? slot.Name : slot.OriginalName); if (!_slotBackups.ContainsKey(text)) { int num = ExtendedPlayerInventory.slots.FindIndex((Model.Slot? s) => s == slot); _slotBackups[text] = new SlotBackup { OriginalIndex = num, Slot = new Model.EquipmentSlot { Name = slot.Name, OriginalName = slot.OriginalName, Get = slot.Get, Valid = slot.Valid, IsAPIAdded = slot.IsAPIAdded, IsQuickSlot = slot.IsQuickSlot } }; AzuExtendedPlayerInventoryPlugin.AzuExtendedPlayerInventoryLogger.LogDebug((object)$"Created backup for slot '{text}' at index {num}"); } } public static bool RestoreSlotFromBackup(string slotKey) { if (!_slotBackups.TryGetValue(slotKey, out SlotBackup value)) { AzuExtendedPlayerInventoryPlugin.AzuExtendedPlayerInventoryLogger.LogDebug((object)("No backup found for slot '" + slotKey + "'")); return false; } Model.EquipmentSlot slot = value.Slot; if (API.TryGetSlotIndexByName(slot.Name, out var index, allowLocalized: false) || (!string.IsNullOrWhiteSpace(slot.OriginalName) && API.TryGetSlotIndexByName(slot.OriginalName, out index, allowLocalized: false))) { AzuExtendedPlayerInventoryPlugin.AzuExtendedPlayerInventoryLogger.LogDebug((object)("Slot '" + slotKey + "' already exists, skipping restore")); return false; } AzuExtendedPlayerInventoryPlugin.AzuExtendedPlayerInventoryLogger.LogInfo((object)$"Restoring slot '{slotKey}' from backup to index {value.OriginalIndex}"); Model.EquipmentSlot equipmentSlot = RecreateSlotWithDelegates(slot); int val = ExtendedPlayerInventory.slots.Count - AzuExtendedPlayerInventoryPlugin.QuickSlotsAmount.Value; int index2 = Math.Max(0, Math.Min(value.OriginalIndex, val)); API.UpdateSlots(index2, 1); ExtendedPlayerInventory.slots.Insert(index2, equipmentSlot); if (equipmentSlot.IsAPIAdded) { API.CustomSlots.Add(equipmentSlot); } SlotHelpers.ResizeSlots(); SlotHelpers.UpdateEquipmentBackgroundAnchors(); return true; } public static IEnumerable GetBackupKeys() { return _slotBackups.Keys.ToList(); } private static Model.EquipmentSlot RecreateSlotWithDelegates(Model.EquipmentSlot slotData) { return new Model.EquipmentSlot { Name = slotData.Name, OriginalName = slotData.OriginalName, IsAPIAdded = slotData.IsAPIAdded, IsQuickSlot = slotData.IsQuickSlot, Get = slotData.Get, Valid = slotData.Valid }; } } } namespace AzuEPI.Game.Slots.QAB { public class HudPatches { [HarmonyPatch(typeof(Hud), "Awake")] private static class HudAwakePatch { private static void Postfix(Hud __instance) { //IL_0065: Unknown result type (might be due to invalid IL or missing references) if (AzuExtendedPlayerInventoryPlugin.AddEquipmentRow.Value.isOff()) { return; } API.HudAwake(__instance); Transform val = __instance.m_rootObject.transform.Find("HotKeyBar"); if (Object.op_Implicit((Object)(object)val)) { RectTransform val2 = default(RectTransform); ((Component)val).TryGetComponent(ref val2); if (Object.op_Implicit((Object)(object)val2)) { RectTransform obj = Object.Instantiate(val2, __instance.m_rootObject.transform, true); ((Object)obj).name = "AzuEPI_QuickAccessBar"; ((Transform)obj).localPosition = Vector3.zero; ((Transform)obj).SetSiblingIndex(((Transform)val2).GetSiblingIndex() + 1); } } API.HudAwakeComplete(__instance); } } [HarmonyPatch(typeof(Hud), "Update")] private static class HudUpdatePatch { private static Transform _cachedHudrootTransform; private static Transform _cachedQuickAccessBarTransform; private static RectTransform _cachedQuickAccessBarRect; private static void Postfix(Hud __instance) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_021d: Unknown result type (might be due to invalid IL or missing references) //IL_021e: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: 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_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Unknown result type (might be due to invalid IL or missing references) if (AzuExtendedPlayerInventoryPlugin.AddEquipmentRow.Value.isOff() || (Object)(object)Player.m_localPlayer == (Object)null) { return; } API.HudUpdate(__instance); float largeGuiScale = GuiScaler.m_largeGuiScale; Vector3 mousePosition = Input.mousePosition; QuickAccessBar.SetElementPositions(); if (ExtendedPlayerInventory.lastMousePos == Vector3.zero) { ExtendedPlayerInventory.lastMousePos = mousePosition; } if ((Object)(object)_cachedHudrootTransform == (Object)null) { _cachedHudrootTransform = ((Component)Hud.instance).transform.Find("hudroot"); } if ((Object)(object)_cachedQuickAccessBarTransform == (Object)null) { _cachedQuickAccessBarTransform = _cachedHudrootTransform.Find("AzuEPI_QuickAccessBar"); } if ((Object)(object)_cachedQuickAccessBarRect == (Object)null && (Object)(object)_cachedQuickAccessBarTransform != (Object)null) { _cachedQuickAccessBarRect = ((Component)_cachedQuickAccessBarTransform).GetComponent(); } if (InventoryGui.IsVisible()) { return; } KeyboardShortcut value = AzuExtendedPlayerInventoryPlugin.QuickslotDragKeys.Value; if (((KeyboardShortcut)(ref value)).IsPressed() && (Object)(object)_cachedQuickAccessBarTransform != (Object)null) { RectTransform cachedQuickAccessBarRect = _cachedQuickAccessBarRect; Vector2 anchoredPosition = cachedQuickAccessBarRect.anchoredPosition; Vector2 sizeDelta = cachedQuickAccessBarRect.sizeDelta; float value2 = AzuExtendedPlayerInventoryPlugin.QuickAccessScale.Value; Rect val = default(Rect); ((Rect)(ref val))..ctor(anchoredPosition.x * largeGuiScale, anchoredPosition.y * largeGuiScale + (float)Screen.height - sizeDelta.y * largeGuiScale * value2, (float)((double)(sizeDelta.x * largeGuiScale * value2) * 0.375), sizeDelta.y * largeGuiScale * value2); bool flag = ((Rect)(ref val)).Contains(ExtendedPlayerInventory.lastMousePos); if (flag) { string currentlyDragging = ExtendedPlayerInventory.currentlyDragging; bool flag2 = (((currentlyDragging != null && currentlyDragging.Length == 0) || currentlyDragging == "AzuEPI_QuickAccessBar") ? true : false); flag = flag2; } if (flag) { float num = (mousePosition.x - ExtendedPlayerInventory.lastMousePos.x) / largeGuiScale; float num2 = (mousePosition.y - ExtendedPlayerInventory.lastMousePos.y) / largeGuiScale; AzuExtendedPlayerInventoryPlugin.QuickAccessLocation.Value = new Vector2(AzuExtendedPlayerInventoryPlugin.QuickAccessLocation.Value.x + num, AzuExtendedPlayerInventoryPlugin.QuickAccessLocation.Value.y + num2); ExtendedPlayerInventory.currentlyDragging = "AzuEPI_QuickAccessBar"; } else { ExtendedPlayerInventory.currentlyDragging = ""; } } else { ExtendedPlayerInventory.currentlyDragging = ""; } ExtendedPlayerInventory.lastMousePos = mousePosition; API.HudUpdateComplete(__instance); } } [HarmonyPatch(typeof(MessageHud), "Awake")] private static class LowerTopLeftMessageMessageHudAwakePatch { private static void Postfix(MessageHud __instance) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) RectTransform val = default(RectTransform); if (((Component)__instance.m_messageText.transform.parent).TryGetComponent(ref val)) { RectTransform obj = val; obj.anchoredPosition += new Vector2(0f, -75f); } } } } [HarmonyPatch] internal static class SettingsMenuClosedRecentlyPatchs { [HarmonyPatch(typeof(Settings), "OnDestroy")] [HarmonyPatch(typeof(Settings), "OnOk")] [HarmonyPatch(typeof(Settings), "OnBack")] private static void Postfix(Settings __instance) { QuickAccessBar.SettingsMenuClosedRecently = true; } } [HarmonyPatch(typeof(HotkeyBar), "UpdateIcons")] internal static class QuickAccessBar { internal static bool SettingsMenuClosedRecently; [HarmonyPriority(0)] internal static bool Prefix(HotkeyBar __instance, Player player) { //IL_01f1: Unknown result type (might be due to invalid IL or missing references) //IL_01f6: Unknown result type (might be due to invalid IL or missing references) //IL_020f: Expected O, but got Unknown //IL_0255: Unknown result type (might be due to invalid IL or missing references) //IL_02a0: Unknown result type (might be due to invalid IL or missing references) //IL_02a5: Unknown result type (might be due to invalid IL or missing references) //IL_0530: Unknown result type (might be due to invalid IL or missing references) //IL_0529: Unknown result type (might be due to invalid IL or missing references) if (((Object)__instance).name != "AzuEPI_QuickAccessBar") { return true; } if (AzuExtendedPlayerInventoryPlugin.ShowQuickSlots.Value.isOff()) { ClearElements(__instance); return false; } if (!Object.op_Implicit((Object)(object)player) || ((Character)player).IsDead()) { ClearElements(__instance); } else { if (SettingsMenuClosedRecently) { ClearElements(__instance); SettingsMenuClosedRecently = false; } __instance.m_items.Clear(); Inventory inventory = ((Humanoid)player).GetInventory(); int width = inventory.GetWidth(); int num = (inventory.GetHeight() - API.GetAddedRows(width)) * width + ExtendedPlayerInventory.slots.Count - AzuExtendedPlayerInventoryPlugin.QuickSlotsAmount.Value; for (int i = 0; i < AzuExtendedPlayerInventoryPlugin.QuickSlotsAmount.Value; i++) { int num2 = num + i; ItemData itemAt = inventory.GetItemAt(num2 % width, num2 / width); if (itemAt != null) { __instance.m_items.Add(itemAt); } } __instance.m_items.Sort((ItemData x, ItemData y) => (x.m_gridPos.x + x.m_gridPos.y * width).CompareTo(y.m_gridPos.x + y.m_gridPos.y * width)); int num3 = 0; if (AzuExtendedPlayerInventoryPlugin.AlwaysShowQuickSlotsInUI.Value.isOn()) { num3 = AzuExtendedPlayerInventoryPlugin.QuickSlotsAmount.Value; } else { for (int num4 = 0; num4 < __instance.m_items.Count; num4++) { int num5 = __instance.m_items[num4].m_gridPos.x + __instance.m_items[num4].m_gridPos.y * width - num + 1; if (num5 > num3) { num3 = num5; } } } if (__instance.m_elements.Count != num3) { foreach (ElementData element in __instance.m_elements) { Object.Destroy((Object)(object)element.m_go); } __instance.m_elements.Clear(); for (int num6 = 0; num6 < num3; num6++) { ElementData val = new ElementData { m_go = Object.Instantiate(__instance.m_elementPrefab, ((Component)__instance).transform) }; int num7 = Mathf.Max(1, AzuExtendedPlayerInventoryPlugin.QuickSlotsPerRow.Value); int num8 = num6 % num7; int num9 = num6 / num7; val.m_go.transform.localPosition = new Vector3((float)num8 * __instance.m_elementSpace, (float)(-num9) * __instance.m_elementSpace, 0f); if (num6 < AzuExtendedPlayerInventoryPlugin.HotkeyTexts.Length && num6 < AzuExtendedPlayerInventoryPlugin.Hotkeys.Length) { SlotText.Set(Utility.IsNullOrWhiteSpace(AzuExtendedPlayerInventoryPlugin.HotkeyTexts[num6].Value) ? ((object)AzuExtendedPlayerInventoryPlugin.Hotkeys[num6].Value/*cast due to .constrained prefix*/).ToString() : AzuExtendedPlayerInventoryPlugin.HotkeyTexts[num6].Value, val.m_go.transform); } val.m_icon = ((Component)((Component)val.m_go.transform).transform.Find("icon")).GetComponent(); val.m_durability = ((Component)val.m_go.transform.Find("durability")).GetComponent(); val.m_amount = ((Component)val.m_go.transform.Find("amount")).GetComponent(); val.m_equiped = ((Component)val.m_go.transform.Find("equiped")).gameObject; val.m_queued = ((Component)val.m_go.transform.Find("queued")).gameObject; val.m_selection = ((Component)val.m_go.transform.Find("selected")).gameObject; __instance.m_elements.Add(val); } } foreach (ElementData element2 in __instance.m_elements) { element2.m_used = false; } bool flag = ZInput.IsGamepadActive(); foreach (ItemData item in __instance.m_items) { int num10 = item.m_gridPos.x + item.m_gridPos.y * width - num; if (num10 < 0 || num10 >= __instance.m_elements.Count) { continue; } ElementData val2 = __instance.m_elements[num10]; val2.m_used = true; ((Component)val2.m_icon).gameObject.SetActive(true); val2.m_icon.sprite = item.GetIcon(); bool flag2 = item.m_shared.m_useDurability && (double)item.m_durability < (double)item.GetMaxDurability(); ((Component)val2.m_durability).gameObject.SetActive(flag2); if (item.m_shared.m_useDurability && flag2) { if ((double)item.m_durability <= 0.0) { val2.m_durability.SetValue(1f); val2.m_durability.SetColor((Color)(((double)Mathf.Sin(Time.time * 10f) > 0.0) ? Color.red : new Color(0f, 0f, 0f, 0f))); } else { val2.m_durability.SetValue(item.GetDurabilityPercentage()); val2.m_durability.ResetColor(); } } val2.m_equiped.SetActive(item.m_equipped); val2.m_queued.SetActive(false); InventoryGridQueuedFillPatch.UpdateFillOverlay(val2.m_queued, null, player, item); if (item.m_shared.m_maxStackSize > 1) { ((Component)val2.m_amount).gameObject.SetActive(true); if (val2.m_stackText != item.m_stack) { val2.m_amount.text = (AzuExtendedPlayerInventoryPlugin.WbInstalled ? Formatting.FormatNumberSimpleNoDecimal(item.m_stack) : $"{item.m_stack} / {item.m_shared.m_maxStackSize}"); val2.m_stackText = item.m_stack; } } else { ((Component)val2.m_amount).gameObject.SetActive(false); } } for (int num11 = 0; num11 < __instance.m_elements.Count; num11++) { ElementData val3 = __instance.m_elements[num11]; val3.m_selection.SetActive(flag && num11 == __instance.m_selected); if (!val3.m_used) { ((Component)val3.m_icon).gameObject.SetActive(false); ((Component)val3.m_durability).gameObject.SetActive(false); val3.m_equiped.SetActive(false); val3.m_queued.SetActive(false); InventoryGridQueuedFillPatch.UpdateFillOverlay(val3.m_queued, null, player, null); ((Component)val3.m_amount).gameObject.SetActive(false); } } } return false; } private static void ClearElements(HotkeyBar __instance, bool destroy = true) { foreach (ElementData element in __instance.m_elements) { if (destroy) { Object.Destroy((Object)(object)element.m_go); continue; } ((Component)element.m_icon).gameObject.SetActive(false); ((Component)element.m_durability).gameObject.SetActive(false); element.m_equiped.SetActive(false); element.m_queued.SetActive(false); ((Component)element.m_amount).gameObject.SetActive(false); } if (destroy) { InventoryGridQueuedFillPatch.ClearCache(); } __instance.m_elements.Clear(); } public static void ForceRefresh() { if (!((Object)(object)Hud.instance == (Object)null)) { Transform obj = ((Component)Hud.instance).transform.Find("hudroot"); object obj2; if (obj == null) { obj2 = null; } else { Transform obj3 = obj.Find("AzuEPI_QuickAccessBar"); obj2 = ((obj3 != null) ? ((Component)obj3).GetComponent() : null); } HotkeyBar val = (HotkeyBar)obj2; if ((Object)(object)val != (Object)null) { ClearElements(val); } } } public static void SetElementPositions() { //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) Transform val = ((Component)Hud.instance).transform.Find("hudroot"); Transform obj = val.Find("AzuEPI_QuickAccessBar"); if ((Object)(object)((obj != null) ? ((Component)obj).GetComponent() : null) != (Object)null) { RectTransform component = ((Component)Hud.instance.m_healthPanel).GetComponent(); if (AzuExtendedPlayerInventoryPlugin.QuickAccessLocation.Value == Vector2.one) { AzuExtendedPlayerInventoryPlugin.QuickAccessLocation.Value = new Vector2(component.anchoredPosition.x - 2.5f, component.anchoredPosition.y - 380.87f); } ((Component)val.Find("AzuEPI_QuickAccessBar")).GetComponent().anchoredPosition = AzuExtendedPlayerInventoryPlugin.QuickAccessLocation.Value; ((Transform)((Component)val.Find("AzuEPI_QuickAccessBar")).GetComponent()).localScale = new Vector3(AzuExtendedPlayerInventoryPlugin.QuickAccessScale.Value, AzuExtendedPlayerInventoryPlugin.QuickAccessScale.Value, 1f); } } } public static class HotkeyBarController { [HarmonyPatch(typeof(Hud), "Update")] public static class Hud_Update_Patch { public static void Postfix(Hud __instance) { Player localPlayer = Player.m_localPlayer; if (ExtendedPlayerInventory.HotkeyBars == null) { try { ExtendedPlayerInventory.HotkeyBars = ((Component)((Component)__instance).transform.parent).GetComponentsInChildren().ToList(); } catch { AzuExtendedPlayerInventoryPlugin.AzuExtendedPlayerInventoryLogger.LogError((object)("Failed to get hotkey bars from Hud. The parent transform may have changed. " + ((Object)((Component)__instance).transform.parent).name)); return; } } if ((Object)(object)localPlayer != (Object)null) { if (IsValidHotkeyBarIndex()) { HotkeyBar val = ExtendedPlayerInventory.HotkeyBars[ExtendedPlayerInventory.SelectedHotkeyBarIndex]; if (val.m_elements == null || val.m_elements.Count == 0) { DeselectHotkeyBar(); UpdateInitialHotkeyBarInput(); } else { UpdateHotkeyBarInput(val); } } else { UpdateInitialHotkeyBarInput(); } } bool flag = Time.frameCount % 2 == 0; foreach (HotkeyBar hotkeyBar in ExtendedPlayerInventory.HotkeyBars) { if ((Object)(object)hotkeyBar != (Object)null && hotkeyBar.m_elements != null) { ValidateHotkeyBarSelection(hotkeyBar); if (flag) { hotkeyBar.UpdateIcons(localPlayer); } } } } private static bool IsValidHotkeyBarIndex() { if (ExtendedPlayerInventory.SelectedHotkeyBarIndex >= 0) { return ExtendedPlayerInventory.SelectedHotkeyBarIndex < ExtendedPlayerInventory.HotkeyBars.Count; } return false; } private static void UpdateInitialHotkeyBarInput() { if (!ZInput.GetButtonDown("JoyDPadLeft") && !ZInput.GetButtonDown("JoyDPadRight")) { return; } for (int i = 0; i < ExtendedPlayerInventory.HotkeyBars.Count; i++) { if (ExtendedPlayerInventory.HotkeyBars[i].m_elements != null && ExtendedPlayerInventory.HotkeyBars[i].m_elements.Count > 0) { SelectHotkeyBar(i, fromRight: false); break; } } } public static void UpdateHotkeyBarInput(HotkeyBar hotkeyBar) { Player localPlayer = Player.m_localPlayer; if (hotkeyBar.m_selected >= 0 && (Object)(object)localPlayer != (Object)null && !InventoryGui.IsVisible() && !Menu.IsVisible() && !GameCamera.InFreeFly() && !Minimap.IsOpen() && !Hud.IsPieceSelectionVisible() && !StoreGui.IsVisible() && !Console.IsVisible() && !Chat.instance.HasFocus() && !PlayerCustomizaton.IsBarberGuiVisible() && !Hud.InRadial() && (Object)(object)localPlayer != (Object)null) { if (ZInput.GetButtonDown("JoyDPadLeft")) { if (hotkeyBar.m_selected == 0) { if (AzuExtendedPlayerInventoryPlugin.ShowQuickSlots.Value.isOn()) { GotoHotkeyBar(ExtendedPlayerInventory.SelectedHotkeyBarIndex - 1, fromRight: true); } else if (hotkeyBar.m_elements.Count > 1) { hotkeyBar.m_selected = hotkeyBar.m_elements.Count - 1; } } else { hotkeyBar.m_selected--; } } else if (ZInput.GetButtonDown("JoyDPadRight")) { if (hotkeyBar.m_selected == hotkeyBar.m_elements.Count - 1) { if (AzuExtendedPlayerInventoryPlugin.ShowQuickSlots.Value.isOn()) { GotoHotkeyBar(ExtendedPlayerInventory.SelectedHotkeyBarIndex + 1, fromRight: false); } else if (hotkeyBar.m_elements.Count > 1) { hotkeyBar.m_selected = 0; } } else { hotkeyBar.m_selected++; } } if (ZInput.GetButtonDown("JoyDPadUp") || ZInput.GetButtonDown("JoyHotbarUse")) { if (((Object)hotkeyBar).name == "AzuEPI_QuickAccessBar" && AzuExtendedPlayerInventoryPlugin.ShowQuickSlots.Value.isOn()) { Inventory inventory = ((Humanoid)localPlayer).m_inventory; int width = inventory.GetWidth(); int num = (inventory.GetHeight() - API.GetAddedRows(width)) * width + ExtendedPlayerInventory.slots.Count - AzuExtendedPlayerInventoryPlugin.QuickSlotsAmount.Value + hotkeyBar.m_selected; ItemData itemAt = inventory.GetItemAt(num % width, num / width); if (itemAt != null) { ((Humanoid)localPlayer).UseItem((Inventory)null, itemAt, false); } } else if (ZInput.GetButtonDown("JoyHotbarUse") && !ZInput.GetButton("JoyAltKeys")) { localPlayer.UseHotbarItem(hotkeyBar.m_selected + 1); } } } ValidateHotkeyBarSelection(hotkeyBar); } private static void ValidateHotkeyBarSelection(HotkeyBar hotkeyBar) { if (hotkeyBar.m_elements != null && hotkeyBar.m_selected > hotkeyBar.m_elements.Count - 1) { hotkeyBar.m_selected = Mathf.Max(0, hotkeyBar.m_elements.Count - 1); } } public static void GotoHotkeyBar(int newIndex, bool fromRight) { if (ExtendedPlayerInventory.HotkeyBars.Count == 0) { return; } int num = ((!fromRight) ? 1 : (-1)); for (int i = 0; i < ExtendedPlayerInventory.HotkeyBars.Count; i++) { if (newIndex < 0) { newIndex = ExtendedPlayerInventory.HotkeyBars.Count - 1; } else if (newIndex >= ExtendedPlayerInventory.HotkeyBars.Count) { newIndex = 0; } if (ExtendedPlayerInventory.HotkeyBars[newIndex].m_elements != null && ExtendedPlayerInventory.HotkeyBars[newIndex].m_elements.Count > 0) { SelectHotkeyBar(newIndex, fromRight); break; } newIndex += num; } } public static void SelectHotkeyBar(int index, bool fromRight) { if (index < 0 || index >= ExtendedPlayerInventory.HotkeyBars.Count) { return; } ExtendedPlayerInventory.SelectedHotkeyBarIndex = index; for (int i = 0; i < ExtendedPlayerInventory.HotkeyBars.Count; i++) { HotkeyBar val = ExtendedPlayerInventory.HotkeyBars[i]; if (i == index) { int num = val.m_elements?.Count ?? 0; val.m_selected = (fromRight ? Mathf.Max(0, num - 1) : 0); } else { val.m_selected = -1; } } } public static void DeselectHotkeyBar() { ExtendedPlayerInventory.SelectedHotkeyBarIndex = -1; foreach (HotkeyBar hotkeyBar in ExtendedPlayerInventory.HotkeyBars) { hotkeyBar.m_selected = -1; } } } [HarmonyPatch(typeof(Hud), "OnDestroy")] public static class Hud_OnDestroy_Patch { public static void Postfix(Hud __instance) { ExtendedPlayerInventory.HotkeyBars = null; ExtendedPlayerInventory.SelectedHotkeyBarIndex = -1; } } } [HarmonyPatch(typeof(HotkeyBar), "Update")] public static class HotkeyBar_Update_Patch { public static bool Prefix(HotkeyBar __instance) { return false; } } } namespace AzuEPI.Game.PlayerPreview { public class PlayerRotationController : MonoBehaviour, IDragHandler, IEventSystemHandler, IEndDragHandler, IScrollHandler { internal bool dragging; private Vector3 lastMousePosition; public float pitch; public float yaw; internal float zoom = -3f; public static PlayerRotationController instance; private void Awake() { instance = this; } public void OnDrag(PointerEventData eventData) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: 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_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) Rect rect = AzuEPICharacterPanel.instance.render.rect; if (((Rect)(ref rect)).Contains(Vector2.op_Implicit(((Component)this).transform.InverseTransformPoint(ZInput.mousePosition)))) { if (!dragging) { lastMousePosition = Input.mousePosition; dragging = true; } pitch = Mathf.Clamp(pitch + (lastMousePosition - Input.mousePosition).y, -80f, 80f); yaw -= (lastMousePosition - Input.mousePosition).x; ((Component)AzuEPICharacterPanel.instance.cam).transform.rotation = Quaternion.AngleAxis(yaw, Vector3.up) * Quaternion.AngleAxis(pitch, Vector3.right); ((Component)AzuEPICharacterPanel.instance.cam).transform.eulerAngles = new Vector3(((Component)AzuEPICharacterPanel.instance.cam).transform.eulerAngles.x, ((Component)AzuEPICharacterPanel.instance.cam).transform.eulerAngles.y, 0f); ((Component)AzuEPICharacterPanel.instance.cam).transform.position = AzuEPICharacterPanel.instance.basePosition + ((Component)AzuEPICharacterPanel.instance.cam).transform.forward * zoom; lastMousePosition = Input.mousePosition; } } public void OnEndDrag(PointerEventData eventData) { dragging = false; } public void OnScroll(PointerEventData eventData) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: 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_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) Rect rect = AzuEPICharacterPanel.instance.render.rect; if (((Rect)(ref rect)).Contains(Vector2.op_Implicit(((Component)this).transform.InverseTransformPoint(ZInput.mousePosition)))) { float axis = Input.GetAxis("Mouse ScrollWheel"); if (axis != 0f) { zoom = Mathf.Clamp(zoom + axis * GameCamera.instance.m_zoomSens, -10f, -1f); ((Component)AzuEPICharacterPanel.instance.cam).transform.position = AzuEPICharacterPanel.instance.basePosition + ((Component)AzuEPICharacterPanel.instance.cam).transform.forward * zoom; } } } } [HarmonyPatch(typeof(InventoryGui), "Hide")] internal static class InventoryGuiHidePatch { private static void Postfix(InventoryGui __instance) { //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) PlayerRotationController.instance.pitch = 0f; PlayerRotationController.instance.yaw = 0f; PlayerRotationController.instance.zoom = -3f; PlayerRotationController.instance.dragging = false; if (Object.op_Implicit((Object)(object)AzuEPICharacterPanel.instance.cam)) { ((Component)AzuEPICharacterPanel.instance.cam).transform.rotation = Quaternion.Euler(0f, 0f, 0f); ((Component)AzuEPICharacterPanel.instance.cam).transform.position = AzuEPICharacterPanel.instance.basePosition + ((Component)AzuEPICharacterPanel.instance.cam).transform.forward * PlayerRotationController.instance.zoom; } } } [HarmonyPatch(typeof(InventoryGui), "Awake")] internal static class InitializePlayerPreviewInventoryGuiAwakePatch { [HarmonyPriority(0)] private static void Postfix(InventoryGui __instance) { PlayerPreviewManager.InitializePlayerPreview(); } } [HarmonyPatch(typeof(InventoryGui), "Show")] internal static class ShowPlayerPreviewInventoryGuiShowPatch { [HarmonyPriority(0)] private static void Postfix(InventoryGui __instance) { PlayerPreviewManager.ShowPlayerPreview(); } } [HarmonyPatch(typeof(InventoryGui), "OnDestroy")] internal static class InventoryGuiOnDestroyPatch { private static void Prefix(InventoryGui __instance) { PlayerPreviewManager.DestroyPlayerPreview_All(); } } [HarmonyPatch(typeof(Humanoid), "SetupAnimationState")] internal static class UpdatePlayerPreviewVisuals { private static void Postfix(Humanoid __instance) { if (!((Object)(object)Player.m_localPlayer == (Object)null) && ((Character)__instance).IsPlayer() && (Object)(object)__instance == (Object)(object)Player.m_localPlayer && (Object)(object)AzuEPICharacterPanel.playerPreview != (Object)null) { PlayerPreviewManager.UpdatePlayerPreview(__instance); } } } [HarmonyPatch(typeof(InventoryGui), "Hide")] internal static class HidePlayerPreviewAndPanels { [HarmonyPriority(0)] private static void Postfix(InventoryGui __instance) { if (Object.op_Implicit((Object)(object)AzuEPICharacterPanel.playerPreview)) { AzuEPICharacterPanel.playerPreview.SetActive(false); } if (Object.op_Implicit((Object)(object)AzuEPICharacterPanel.instance?.cam)) { ((Behaviour)AzuEPICharacterPanel.instance.cam).enabled = false; } if (PersonalLoadoutGui.IsVisible()) { PersonalLoadoutGui.Hide(); } if (StatsPanelController.IsVisible()) { StatsPanelController.Hide(); } if (VanityPanelController.IsVisible()) { VanityPanelController.SetVisible(visible: false); } PanelUtilities.HideCraftingElements(hide: false); } } [HarmonyPatch(typeof(VisEquipment), "UpdateEquipmentVisuals")] internal static class PreviewInstantRefresh_VisEquipmentPatch { private static void Postfix(VisEquipment __instance) { if (Object.op_Implicit((Object)(object)Player.m_localPlayer) && !((Object)(object)__instance != (Object)(object)((Humanoid)Player.m_localPlayer).m_visEquipment) && !((Object)(object)AzuEPICharacterPanel.playerPreviewComp == (Object)null) && VECloneSync.MirrorFrom(Player.m_localPlayer, AzuEPICharacterPanel.playerPreviewComp)) { PreviewLayerFix.ForceUILayer(((Humanoid)AzuEPICharacterPanel.playerPreviewComp).m_visEquipment); Camera val = AzuEPICharacterPanel.instance?.cam; if (Object.op_Implicit((Object)(object)val)) { val.Render(); } } } } [HarmonyPatch(typeof(Humanoid), "EquipItem")] internal static class PreviewInstantRefresh_EquipItem { private static void Postfix() { PlayerPreviewManager.TryRefresh(); } } [HarmonyPatch(typeof(Humanoid), "UnequipItem")] internal static class PreviewInstantRefresh_UnequipItem { private static void Postfix() { PlayerPreviewManager.TryRefresh(); } } public class AzuEPICharacterPanel : MonoBehaviour, TextReceiver { public static AzuEPICharacterPanel instance; public RectTransform render; public RawImage renderRawImage; public Camera cam; public RenderTexture renderTexture; public readonly Vector3 basePosition = new Vector3(0f, -1000f, 1f); public static GameObject playerPreview; public static Player playerPreviewComp; public static TMP_Dropdown LoadoutDropdown; private void Awake() { instance = this; } public string GetText() { return string.Empty; } public void SetText(string text) { if (string.IsNullOrEmpty(text)) { MessageHud.instance.ShowMessage((MessageType)2, "Invalid loadout name.", 0, (Sprite)null, false); } else if (PersonalLoadoutGui.SaveLoadout(text)) { List availableLoadouts = PersonalLoadoutGui.GetAvailableLoadouts(); LoadoutDropdown.value = availableLoadouts.Count; MessageHud.instance.ShowMessage((MessageType)2, "New loadout '" + text + "' created.", 0, (Sprite)null, false); } else { MessageHud.instance.ShowMessage((MessageType)2, "Failed to create loadout '" + text + "'.", 0, (Sprite)null, false); } } } internal static class VECloneSync { private static int _lastStamp; public static void ResetStamp() { _lastStamp = 0; } public static bool MirrorFrom(Player srcPlayer, Player dstPreview) { //IL_03f9: Unknown result type (might be due to invalid IL or missing references) //IL_0405: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)srcPlayer) || !Object.op_Implicit((Object)(object)dstPreview)) { return false; } VisEquipment visEquipment = ((Humanoid)srcPlayer).m_visEquipment; VisEquipment visEquipment2 = ((Humanoid)dstPreview).m_visEquipment; int num = 0; int num2 = 0; int num3 = 0; int num4 = 0; int num5 = visEquipment.m_shoulderItemVariant; int num6 = visEquipment.m_leftItemVariant; int num7 = visEquipment.m_leftBackItemVariant; ZDO val = (Object.op_Implicit((Object)(object)visEquipment.m_nview) ? visEquipment.m_nview.GetZDO() : null); int num8; int num9; int num10; int num11; int num12; int num13; int num14; int num15; if (val != null) { num8 = val.GetInt(ZDOVars.s_leftItem, 0); num9 = val.GetInt(ZDOVars.s_rightItem, 0); num10 = val.GetInt(ZDOVars.s_chestItem, 0); num11 = val.GetInt(ZDOVars.s_legItem, 0); num12 = val.GetInt(ZDOVars.s_helmetItem, 0); num13 = val.GetInt(ZDOVars.s_shoulderItem, 0); num14 = val.GetInt(ZDOVars.s_utilityItem, 0); num15 = val.GetInt(ZDOVars.s_trinketItem, 0); num = val.GetInt(ZDOVars.s_beardItem, 0); num2 = val.GetInt(ZDOVars.s_hairItem, 0); num3 = val.GetInt(ZDOVars.s_leftBackItem, 0); num4 = val.GetInt(ZDOVars.s_rightBackItem, 0); num5 = val.GetInt(ZDOVars.s_shoulderItemVariant, 0); num6 = val.GetInt(ZDOVars.s_leftItemVariant, 0); num7 = val.GetInt(ZDOVars.s_leftBackItemVariant, 0); } else { num8 = ((!string.IsNullOrEmpty(visEquipment.m_leftItem)) ? StringExtensionMethods.GetStableHashCode(visEquipment.m_leftItem) : 0); num9 = ((!string.IsNullOrEmpty(visEquipment.m_rightItem)) ? StringExtensionMethods.GetStableHashCode(visEquipment.m_rightItem) : 0); num10 = ((!string.IsNullOrEmpty(visEquipment.m_chestItem)) ? StringExtensionMethods.GetStableHashCode(visEquipment.m_chestItem) : 0); num11 = ((!string.IsNullOrEmpty(visEquipment.m_legItem)) ? StringExtensionMethods.GetStableHashCode(visEquipment.m_legItem) : 0); num12 = ((!string.IsNullOrEmpty(visEquipment.m_helmetItem)) ? StringExtensionMethods.GetStableHashCode(visEquipment.m_helmetItem) : 0); num13 = ((!string.IsNullOrEmpty(visEquipment.m_shoulderItem)) ? StringExtensionMethods.GetStableHashCode(visEquipment.m_shoulderItem) : 0); num14 = ((!string.IsNullOrEmpty(visEquipment.m_utilityItem)) ? StringExtensionMethods.GetStableHashCode(visEquipment.m_utilityItem) : 0); num15 = ((!string.IsNullOrEmpty(visEquipment.m_trinketItem)) ? StringExtensionMethods.GetStableHashCode(visEquipment.m_trinketItem) : 0); num = ((!string.IsNullOrEmpty(visEquipment.m_beardItem)) ? StringExtensionMethods.GetStableHashCode(visEquipment.m_beardItem) : 0); num2 = ((!string.IsNullOrEmpty(visEquipment.m_hairItem)) ? StringExtensionMethods.GetStableHashCode(visEquipment.m_hairItem) : 0); num3 = ((!string.IsNullOrEmpty(visEquipment.m_leftBackItem)) ? StringExtensionMethods.GetStableHashCode(visEquipment.m_leftBackItem) : 0); num4 = ((!string.IsNullOrEmpty(visEquipment.m_rightBackItem)) ? StringExtensionMethods.GetStableHashCode(visEquipment.m_rightBackItem) : 0); } int num16 = CombineHash(visEquipment.m_modelIndex, ((object)Unsafe.As(ref visEquipment.m_skinColor)/*cast due to .constrained prefix*/).GetHashCode(), ((object)Unsafe.As(ref visEquipment.m_hairColor)/*cast due to .constrained prefix*/).GetHashCode(), num8, num6, num9, num10, num11, num12, num13, num5, num14, num15, num, num2, num3, num4, num7); if (num16 == _lastStamp) { return false; } _lastStamp = num16; visEquipment2.SetRightItem(visEquipment.m_rightItem); visEquipment2.SetLeftItem(visEquipment.m_leftItem, visEquipment.m_leftItemVariant); visEquipment2.SetChestItem(visEquipment.m_chestItem); visEquipment2.SetLegItem(visEquipment.m_legItem); visEquipment2.SetHelmetItem(visEquipment.m_helmetItem); visEquipment2.SetShoulderItem(visEquipment.m_shoulderItem, visEquipment.m_shoulderItemVariant); visEquipment2.SetUtilityItem(visEquipment.m_utilityItem); visEquipment2.SetTrinketItem(visEquipment.m_trinketItem); visEquipment2.SetLeftBackItem(visEquipment.m_leftBackItem, visEquipment.m_leftBackItemVariant); visEquipment2.SetRightBackItem(visEquipment.m_rightBackItem); visEquipment2.SetBeardItem(visEquipment.m_beardItem); visEquipment2.SetHairItem(visEquipment.m_hairItem); visEquipment2.SetModel(visEquipment.m_modelIndex); visEquipment2.SetSkinColor(visEquipment.m_skinColor); visEquipment2.SetHairColor(visEquipment.m_hairColor); try { visEquipment2.UpdateVisuals(); PreviewLayerFix.ForceUILayer(visEquipment2); } catch { } ((Behaviour)visEquipment2).enabled = false; return true; } internal static int CombineHash(params int[] hashes) { int num = 17; foreach (int num2 in hashes) { num = num * 31 + num2; } return num; } } internal static class PreviewLayerFix { public static void ForceUILayer(VisEquipment ve) { int ui = LayerMask.NameToLayer("UI"); Set(ve.m_leftItemInstance); Set(ve.m_rightItemInstance); Set(ve.m_helmetItemInstance); Set(ve.m_beardItemInstance); Set(ve.m_hairItemInstance); Set(ve.m_leftBackItemInstance); Set(ve.m_rightBackItemInstance); SetList(ve.m_chestItemInstances); SetList(ve.m_legItemInstances); SetList(ve.m_shoulderItemInstances); SetList(ve.m_utilityItemInstances); SetList(ve.m_trinketItemInstances); void Set(GameObject go) { if (Object.op_Implicit((Object)(object)go)) { go.SetLayerForEntireHierarchy(ui); } } void SetList(List list) { if (list == null) { return; } foreach (GameObject item in list) { Set(item); } } } } public class PlayerPreviewManager { public static PlayerPreviewManager Instance { get; private set; } public AzuEPICharacterPanel CharacterPanel { get; set; } private PlayerPreviewManager() { } public static void Initialize() { if (Instance == null) { Instance = new PlayerPreviewManager(); } Instance.CharacterPanel = AzuEPICharacterPanel.instance; } public void UpdateRenderTexture() { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Expected O, but got Unknown if (!((Object)(object)CharacterPanel == (Object)null) && !((Object)(object)CharacterPanel.render == (Object)null)) { int num = Mathf.Max(2, Mathf.RoundToInt(CharacterPanel.render.sizeDelta.x)); int num2 = Mathf.Max(2, Mathf.RoundToInt(CharacterPanel.render.sizeDelta.y)); if ((Object)(object)CharacterPanel.renderTexture != (Object)null && (((Texture)CharacterPanel.renderTexture).width != num || ((Texture)CharacterPanel.renderTexture).height != num2)) { CharacterPanel.renderTexture.Release(); Object.Destroy((Object)(object)CharacterPanel.renderTexture); CharacterPanel.renderTexture = null; } if ((Object)(object)CharacterPanel.renderTexture == (Object)null) { CharacterPanel.renderTexture = new RenderTexture(num, num2, 16, (RenderTextureFormat)0); CharacterPanel.renderTexture.Create(); } CharacterPanel.cam.targetTexture = CharacterPanel.renderTexture; CharacterPanel.renderRawImage.texture = (Texture)(object)CharacterPanel.renderTexture; CharacterPanel.cam.Render(); } } internal static GameObject CreatePlayerPreview() { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) GameObject prefab = ZNetScene.instance.GetPrefab("Player"); ZNetView.m_forceDisableInit = true; GameObject clone = Object.Instantiate(prefab); Player component = clone.GetComponent(); Player.s_players.Remove(component); clone.SetActive(false); clone.transform.SetPositionAndRotation(AzuEPICharacterPanel.instance.basePosition - Vector3.up, Quaternion.identity); DisableBehaviour(); DisableBehaviour(); DisableBehaviour(); DisableBehaviour(); DisableBehaviour(); DisableBehaviour(); DisableBehaviour(); DisableBehaviour(); DisableBehaviour(); DisableBehaviour(); DisableBehaviour("Visual"); ZNetView.m_forceDisableInit = false; Rigidbody component2 = clone.GetComponent(); if (Object.op_Implicit((Object)(object)component2)) { component2.isKinematic = true; } clone.transform.rotation = Quaternion.LookRotation(-Vector3.forward, Vector3.up); clone.SetLayerForEntireHierarchy(LayerMask.NameToLayer("UI")); AzuEPICharacterPanel.playerPreview = clone; AzuEPICharacterPanel.playerPreviewComp = component; return clone; void DisableBehaviour(string child = "") where T : notnull, Behaviour { object obj2; if (!string.IsNullOrEmpty(child)) { Transform obj = clone.transform.Find(child); obj2 = ((obj != null) ? ((Component)obj).gameObject : null); } else { obj2 = clone; } GameObject val = (GameObject)obj2; if (!((Object)(object)val == (Object)null)) { T component3 = val.GetComponent(); if (Object.op_Implicit((Object)(object)component3)) { ((Behaviour)component3).enabled = false; } } } } internal static void InitializePlayerPreview() { if (Object.op_Implicit((Object)(object)ZNetScene.instance) && Object.op_Implicit((Object)(object)AzuEPICharacterPanel.instance)) { if (!Object.op_Implicit((Object)(object)AzuEPICharacterPanel.playerPreview)) { AzuEPICharacterPanel.playerPreview = CreatePlayerPreview(); } if (!Object.op_Implicit((Object)(object)AzuEPICharacterPanel.playerPreviewComp) && Object.op_Implicit((Object)(object)AzuEPICharacterPanel.playerPreview)) { AzuEPICharacterPanel.playerPreviewComp = AzuEPICharacterPanel.playerPreview.GetComponent(); } if ((Object)(object)AzuEPICharacterPanel.instance?.cam == (Object)null) { Initialize(); Instance.CreatePreviewCamera(); Instance.CreatePreviewLights(); Instance.UpdateRenderTexture(); } } } internal static void ShowPlayerPreview() { //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) VECloneSync.ResetStamp(); if (!Object.op_Implicit((Object)(object)AzuEPICharacterPanel.playerPreview) || !Object.op_Implicit((Object)(object)AzuEPICharacterPanel.playerPreviewComp)) { InitializePlayerPreview(); } Player localPlayer = Player.m_localPlayer; if (!Object.op_Implicit((Object)(object)localPlayer) || !Object.op_Implicit((Object)(object)AzuEPICharacterPanel.playerPreviewComp)) { return; } AzuEPICharacterPanel instance = AzuEPICharacterPanel.instance; if ((Object)(object)instance?.cam == (Object)null) { InitializePlayerPreview(); if ((Object)(object)instance?.cam == (Object)null) { return; } } AzuEPICharacterPanel.playerPreview.SetActive(true); ((Behaviour)instance.cam).enabled = true; Player playerPreviewComp = AzuEPICharacterPanel.playerPreviewComp; ((Humanoid)playerPreviewComp).m_visEquipment.SetHairItem(((Humanoid)localPlayer).m_hairItem); ((Humanoid)playerPreviewComp).m_visEquipment.SetHairColor(localPlayer.m_hairColor); ((Humanoid)playerPreviewComp).m_visEquipment.SetSkinColor(localPlayer.m_skinColor); ((Humanoid)playerPreviewComp).m_visEquipment.SetModel(((Humanoid)localPlayer).m_visEquipment.m_currentModelIndex); ((Humanoid)playerPreviewComp).m_visEquipment.m_isPlayer = true; ((Character)playerPreviewComp).m_animator.SetBool("wakeup", false); ((Character)playerPreviewComp).m_animator.Update(0f); VECloneSync.MirrorFrom(localPlayer, playerPreviewComp); ((Component)playerPreviewComp).transform.rotation = Quaternion.LookRotation(-Vector3.forward, Vector3.up); AzuEPICharacterPanel.playerPreview.gameObject.SetLayerForEntireHierarchy(LayerMask.NameToLayer("UI")); instance.cam.Render(); } [Obsolete("Split into InitializePlayerPreview (Awake) and ShowPlayerPreview (Show) for better performance")] internal static void CreatePlayerPreviewShow() { //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) VECloneSync.ResetStamp(); if (!Object.op_Implicit((Object)(object)AzuEPICharacterPanel.playerPreview)) { AzuEPICharacterPanel.playerPreview = CreatePlayerPreview(); } if (!Object.op_Implicit((Object)(object)AzuEPICharacterPanel.playerPreviewComp) && Object.op_Implicit((Object)(object)AzuEPICharacterPanel.playerPreview)) { AzuEPICharacterPanel.playerPreviewComp = AzuEPICharacterPanel.playerPreview.GetComponent(); } AzuEPICharacterPanel instance = AzuEPICharacterPanel.instance; if ((Object)(object)instance?.cam == (Object)null) { Initialize(); Instance.CreatePreviewCamera(); Instance.CreatePreviewLights(); Instance.UpdateRenderTexture(); } Player localPlayer = Player.m_localPlayer; if (Object.op_Implicit((Object)(object)localPlayer) && Object.op_Implicit((Object)(object)AzuEPICharacterPanel.playerPreviewComp)) { AzuEPICharacterPanel.playerPreview.SetActive(true); ((Behaviour)instance.cam).enabled = true; Player playerPreviewComp = AzuEPICharacterPanel.playerPreviewComp; ((Humanoid)playerPreviewComp).m_visEquipment.SetHairItem(((Humanoid)localPlayer).m_hairItem); ((Humanoid)playerPreviewComp).m_visEquipment.SetHairColor(localPlayer.m_hairColor); ((Humanoid)playerPreviewComp).m_visEquipment.SetSkinColor(localPlayer.m_skinColor); ((Humanoid)playerPreviewComp).m_visEquipment.SetModel(((Humanoid)localPlayer).m_visEquipment.m_currentModelIndex); ((Humanoid)playerPreviewComp).m_visEquipment.m_isPlayer = true; try { ((Humanoid)playerPreviewComp).m_visEquipment.UpdateVisuals(); PreviewLayerFix.ForceUILayer(((Humanoid)playerPreviewComp).m_visEquipment); } catch { } ((Character)playerPreviewComp).m_animator.SetBool("wakeup", false); SyncAnimationState((Humanoid)(object)localPlayer, playerPreviewComp); ((Character)playerPreviewComp).m_animator.Update(0f); VECloneSync.MirrorFrom(localPlayer, playerPreviewComp); UpdatePlayerPreview((Humanoid)(object)localPlayer); AzuEPICharacterPanel.playerPreview.gameObject.SetLayerForEntireHierarchy(LayerMask.NameToLayer("UI")); AzuEPICharacterPanel.playerPreview.transform.rotation = Quaternion.LookRotation(-Vector3.forward, Vector3.up); instance.cam.Render(); } } internal static void DestroyPlayerPreview_All() { if (Object.op_Implicit((Object)(object)AzuEPICharacterPanel.playerPreview)) { Object.Destroy((Object)(object)AzuEPICharacterPanel.playerPreview); } AzuEPICharacterPanel.playerPreview = null; AzuEPICharacterPanel.playerPreviewComp = null; AzuEPICharacterPanel instance = AzuEPICharacterPanel.instance; if (Object.op_Implicit((Object)(object)instance?.cam)) { Object.Destroy((Object)(object)((Component)instance.cam).gameObject); } if (Object.op_Implicit((Object)(object)instance?.renderTexture)) { instance.renderTexture.Release(); Object.Destroy((Object)(object)instance.renderTexture); instance.renderTexture = null; } } internal static void TryRefresh() { if (!Object.op_Implicit((Object)(object)Player.m_localPlayer) || (Object)(object)AzuEPICharacterPanel.playerPreviewComp == (Object)null) { return; } VECloneSync.MirrorFrom(Player.m_localPlayer, AzuEPICharacterPanel.playerPreviewComp); SyncAnimationState((Humanoid)(object)Player.m_localPlayer, AzuEPICharacterPanel.playerPreviewComp); PreviewLayerFix.ForceUILayer(((Humanoid)AzuEPICharacterPanel.playerPreviewComp).m_visEquipment); AzuEPICharacterPanel instance = AzuEPICharacterPanel.instance; if (instance != null) { Camera cam = instance.cam; if (cam != null) { cam.Render(); } } } internal static void UpdatePlayerPreview(Humanoid pHumanoid) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Expected O, but got Unknown Player playerPreviewComp = AzuEPICharacterPanel.playerPreviewComp; if (Object.op_Implicit((Object)(object)pHumanoid) && Object.op_Implicit((Object)(object)playerPreviewComp)) { ((Component)playerPreviewComp).transform.rotation = Quaternion.LookRotation(-Vector3.forward, Vector3.up); VECloneSync.MirrorFrom((Player)pHumanoid, playerPreviewComp); if (!AzuEPICharacterPanel.playerPreview.activeSelf) { AzuEPICharacterPanel.playerPreview.SetActive(true); } } } internal static void SyncAnimationState(Humanoid p, Player playerPreviewComp) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Expected I4, but got Unknown //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Invalid comparison between Unknown and I4 Animator animator = ((Character)p).m_animator; Animator animator2 = ((Character)playerPreviewComp).m_animator; AnimatorStateInfo currentAnimatorStateInfo = animator.GetCurrentAnimatorStateInfo(0); animator2.Play(((AnimatorStateInfo)(ref currentAnimatorStateInfo)).shortNameHash, 0, ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).normalizedTime); AnimatorControllerParameter[] parameters = animator.parameters; foreach (AnimatorControllerParameter val in parameters) { AnimatorControllerParameterType type = val.type; switch (type - 1) { case 3: animator2.SetBool(val.name, animator.GetBool(val.name)); continue; case 0: animator2.SetFloat(val.name, animator.GetFloat(val.name)); continue; case 2: animator2.SetInteger(val.name, animator.GetInteger(val.name)); continue; case 1: continue; } if ((int)type == 9 && animator.GetBool(val.name)) { animator2.SetTrigger(val.name); } } animator2.Update(0f); } internal void CreatePreviewCamera() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Player Inspector Camera"); val.transform.position = AzuEPICharacterPanel.instance.basePosition + Vector3.forward * -3f; CharacterPanel.cam = val.AddComponent(); CharacterPanel.cam.clearFlags = (CameraClearFlags)2; CharacterPanel.cam.backgroundColor = Color.clear; CharacterPanel.cam.cullingMask = 1 << LayerMask.NameToLayer("UI"); CharacterPanel.cam.renderingPath = (RenderingPath)(-1); CharacterPanel.cam.useOcclusionCulling = false; } internal void CreatePreviewLights() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: 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) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Item Inspector Light1"); val.transform.position = CharacterPanel.basePosition + new Vector3(1.5f, 0.5f, -2f); Light obj = val.AddComponent(); obj.type = (LightType)2; obj.intensity = 3.5f; obj.range = 3f; GameObject val2 = new GameObject("Item Inspector Light2"); val2.transform.position = CharacterPanel.basePosition + new Vector3(-1.5f, -0.5f, 1.5f); Light obj2 = val2.AddComponent(); obj2.type = (LightType)2; obj2.intensity = 2.5f; obj2.range = 3f; } } public class CustomEquipVisuals { internal sealed class State { public readonly VisEquipment Vis; public readonly Dictionary Equipped = new Dictionary(StringComparer.Ordinal); public State(VisEquipment vis) { Vis = vis; } public bool ForceSetEquipped(string prefabName, int hashFromZdo) { if (!Equipped.TryGetValue(prefabName, out EquippedEntry value)) { value = (Equipped[prefabName] = new EquippedEntry(prefabName)); } if (value.CurrentHash == hashFromZdo) { return false; } if (value.Instances.Count > 0) { foreach (GameObject instance in value.Instances) { if (Object.op_Implicit((Object)(object)instance)) { Object.Destroy((Object)(object)instance); } } value.Instances.Clear(); } value.CurrentHash = hashFromZdo; if (hashFromZdo != 0) { value.Instances = Vis.AttachArmor(hashFromZdo, -1); if ((prefabName == "BackpackBlackForest" || prefabName == "BackpackMountains") ? true : false) { BoneReorder.ReorderBones(Vis, hashFromZdo, value.Instances); } } return true; } public bool UpdateAllVisuals() { bool flag = false; ZNetView nview = Vis.m_nview; ZDO val = (Object.op_Implicit((Object)(object)nview) ? nview.GetZDO() : null); bool flag2 = Object.op_Implicit((Object)(object)nview) && nview.IsOwner(); foreach (string item in _registered) { bool flag3 = false; string text = ""; if (Equipped.TryGetValue(item, out EquippedEntry value) && value.Item != null) { flag3 = value.Item.m_equipped; text = value.DisplayName ?? ""; } else if (!flag2 && val != null) { flag3 = val.GetInt(ZdoKeyFor(item), 0) != 0; } if (!flag3) { if (flag2 && val != null) { val.Set(ZdoKeyFor(item), 0); } if (Equipped.TryGetValue(item, out EquippedEntry value2) && !string.IsNullOrEmpty(value2.DisplayName)) { value2.DisplayName = ""; } if (ForceSetEquipped(item, 0)) { flag = true; } continue; } int num = 0; if (val != null) { num = val.GetInt(ZdoKeyFor(item), 0); } if (num == 0) { num = StringExtensionMethods.GetStableHashCode((!string.IsNullOrEmpty(text)) ? text : item); if (flag2 && val != null) { val.Set(ZdoKeyFor(item), num); } } if (ForceSetEquipped(item, num)) { flag = true; } } if (flag) { Vis.UpdateLodgroup(); } return flag; } public void SetDisplayName(string prefabName, string name) { if (!Equipped.TryGetValue(prefabName, out EquippedEntry value)) { value = new EquippedEntry(prefabName); Equipped[prefabName] = value; } if (value.DisplayName == name) { return; } value.DisplayName = name; if (Object.op_Implicit((Object)(object)Vis.m_nview) && Vis.m_nview.IsOwner()) { ZDO zDO = Vis.m_nview.GetZDO(); if (zDO != null) { zDO.Set(ZdoKeyFor(prefabName), (!string.IsNullOrEmpty(name)) ? StringExtensionMethods.GetStableHashCode(name) : 0); } } } } internal sealed class EquippedEntry { public readonly string PrefabName; public ItemData Item; public string DisplayName = ""; public List Instances = new List(); public int CurrentHash; public EquippedEntry(string prefabName) { PrefabName = prefabName; } } [HarmonyPatch(typeof(Player), "Awake")] private static class PlayerAwake { [HarmonyPriority(800)] private static void Prefix(Player __instance) { VisEquipment component = ((Component)__instance).GetComponent(); if (Object.op_Implicit((Object)(object)component) && !_states.ContainsKey(component)) { _states[component] = new State(component); } } } [HarmonyPatch(typeof(VisEquipment), "OnEnable")] private static class VisOnEnable { private static void Postfix(VisEquipment __instance) { if (__instance.m_isPlayer && !_states.ContainsKey(__instance)) { _states[__instance] = new State(__instance); } } } [HarmonyPatch(typeof(VisEquipment), "OnDisable")] private static class VisOnDisable { private static void Postfix(VisEquipment __instance) { _states.Remove(__instance); } } [HarmonyPatch(typeof(Humanoid), "SetupVisEquipment")] private static class SetupVis { private static void Prefix(Humanoid __instance) { Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val == null) { return; } VisEquipment visEquipment = ((Humanoid)val).m_visEquipment; if (!Object.op_Implicit((Object)(object)visEquipment) || !_states.TryGetValue(visEquipment, out State value)) { return; } foreach (string item in _registered) { EquippedEntry value2; string name = (value.Equipped.TryGetValue(item, out value2) ? (value2.DisplayName ?? "") : ""); value.SetDisplayName(item, name); } } } [HarmonyPatch(typeof(VisEquipment), "UpdateEquipmentVisuals")] private static class VisUpdate { private static void Postfix(VisEquipment __instance) { if (__instance.m_isPlayer && _states.TryGetValue(__instance, out State value) && value.UpdateAllVisuals() && (Object)(object)__instance == (Object)(object)((Humanoid)(Player.m_localPlayer?)).m_visEquipment) { VECloneSync.ResetStamp(); } } } [HarmonyPatch(typeof(Humanoid), "GetSetCount")] private static class HumanoidGetSetCountPatch { private static void Postfix(Humanoid __instance, string setName, ref int __result) { Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val == null) { return; } VisEquipment visEquipment = ((Humanoid)val).m_visEquipment; if (!Object.op_Implicit((Object)(object)visEquipment) || !_states.TryGetValue(visEquipment, out State value)) { return; } int num = 0; foreach (EquippedEntry value2 in value.Equipped.Values) { ItemData item = value2.Item; if (item != null && item.m_shared.m_setName == setName) { num++; } } __result += num; } } [HarmonyPatch(typeof(Player), "GetBodyArmor")] private static class EPIAddArmor_GetBodyArmorPatch { private static void Postfix(Player __instance, ref float __result) { //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Invalid comparison between Unknown and I4 //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Invalid comparison between Unknown and I4 if (AzuExtendedPlayerInventoryPlugin.EPISlotsAddArmor.Value.isOff() || (Object)(object)__instance != (Object)(object)Player.m_localPlayer) { return; } VisEquipment visEquipment = ((Humanoid)__instance).m_visEquipment; if (!Object.op_Implicit((Object)(object)visEquipment) || !_states.TryGetValue(visEquipment, out State value)) { return; } float num = 0f; foreach (EquippedEntry value2 in value.Equipped.Values) { ItemData item = value2.Item; if (item != null && item.m_equipped && !AdvBackpacksCompat.IsAbBackpack(item) && ((int)item.m_shared.m_itemType != 18 || (AzuExtendedPlayerInventoryPlugin.UtilityEPIAddArmor.Value.isOn() && (int)item.m_shared.m_itemType == 18))) { num += item.GetArmor(); } } __result += num; } } [HarmonyPatch(typeof(Player), "GetEquipmentEitrRegenModifier")] private static class Player_GetEquipmentEitrRegenModifier_ExtraUtility { private static void Postfix(Player __instance, ref float __result) { if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer || AzuExtendedPlayerInventoryPlugin.EPISlotsAddArmor.Value.isOff()) { return; } VisEquipment visEquipment = ((Humanoid)__instance).m_visEquipment; if (!Object.op_Implicit((Object)(object)visEquipment) || !_states.TryGetValue(visEquipment, out State value)) { return; } float num = 0f; foreach (EquippedEntry value2 in value.Equipped.Values) { ItemData item = value2.Item; if (item != null && item.m_equipped && !AdvBackpacksCompat.IsAbBackpack(item)) { num += item.m_shared.m_eitrRegenModifier; } } __result += num; } } [HarmonyPatch(typeof(Player), "ApplyArmorDamageMods")] private static class EPISlotsAddArmorDamage_ApplyArmorDamageModsPatch { private static void Postfix(Player __instance, ref DamageModifiers mods) { if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer) { return; } VisEquipment visEquipment = ((Humanoid)__instance).m_visEquipment; if (!Object.op_Implicit((Object)(object)visEquipment) || !_states.TryGetValue(visEquipment, out State value)) { return; } foreach (EquippedEntry value2 in value.Equipped.Values) { ItemData item = value2.Item; if (item != null && item.m_equipped && !AdvBackpacksCompat.IsAbBackpack(item)) { ((DamageModifiers)(ref mods)).Apply(item.m_shared.m_damageModifiers); } } } } [HarmonyPatch(typeof(Player), "UpdateModifiers")] private static class Player_UpdateModifiers_ExtraUtility { private static void Postfix(Player __instance) { if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer || Player.s_equipmentModifierSourceFields == null) { return; } VisEquipment visEquipment = ((Humanoid)__instance).m_visEquipment; if (!Object.op_Implicit((Object)(object)visEquipment) || !_states.TryGetValue(visEquipment, out State value)) { return; } for (int i = 0; i < __instance.m_equipmentModifierValues.Length; i++) { foreach (EquippedEntry value2 in value.Equipped.Values) { ItemData item = value2.Item; if (item != null && item.m_equipped && !AdvBackpacksCompat.IsAbBackpack(item)) { __instance.m_equipmentModifierValues[i] += (float)Player.s_equipmentModifierSourceFields[i].GetValue(item.m_shared); } } } } } [HarmonyPatch(typeof(Humanoid), "UnequipAllItems")] private static class UnequipAll { private static void Prefix(Humanoid __instance) { Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val == null) { return; } VisEquipment visEquipment = ((Humanoid)val).m_visEquipment; if (!Object.op_Implicit((Object)(object)visEquipment) || !_states.TryGetValue(visEquipment, out State value)) { return; } foreach (EquippedEntry item in value.Equipped.Values.ToList()) { if (item.Item != null) { ((Humanoid)val).UnequipItem(item.Item, false); } } } } [HarmonyPatch(typeof(Humanoid), "UpdateEquipmentStatusEffects")] private static class InjectStatusEffects { private static void Collect(Humanoid humanoid, HashSet set) { Player val = (Player)(object)((humanoid is Player) ? humanoid : null); if (val == null) { return; } VisEquipment visEquipment = ((Humanoid)val).m_visEquipment; if (!Object.op_Implicit((Object)(object)visEquipment) || !_states.TryGetValue(visEquipment, out State value)) { return; } foreach (EquippedEntry value2 in value.Equipped.Values) { ItemData item = value2.Item; StatusEffect val2 = item?.m_shared?.m_equipStatusEffect; if (val2 != null) { set.Add(val2); } if (item != null && humanoid.HaveSetEffect(item)) { StatusEffect setStatusEffect = item.m_shared.m_setStatusEffect; if ((Object)(object)setStatusEffect != (Object)null) { set.Add(setStatusEffect); } } } } private static IEnumerable Transpiler(IEnumerable instrs) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Expected O, but got Unknown List list = instrs.ToList(); list.InsertRange(2, new <>z__ReadOnlyArray((CodeInstruction[])(object)new CodeInstruction[3] { new CodeInstruction(OpCodes.Ldarg_0, (object)null), new CodeInstruction(OpCodes.Ldloc_0, (object)null), new CodeInstruction(OpCodes.Call, (object)AccessTools.DeclaredMethod(typeof(InjectStatusEffects), "Collect", (Type[])null, (Type[])null)) })); return list; } } [HarmonyPatch(typeof(ItemData), "IsEquipable")] private static class IsEquipablePatch { private static void Postfix(ItemData __instance, ref bool __result) { if (!((Object)(object)__instance?.m_dropPrefab == (Object)null)) { string name = ((Object)__instance.m_dropPrefab).name; if (_registered.Contains(name) && HasActiveSlot(__instance)) { __result = true; } } } } [HarmonyPatch(typeof(Humanoid), "IsItemEquiped")] private static class IsItemEquipedPatch { private static void Postfix(Humanoid __instance, ItemData item, ref bool __result) { Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val == null || item == null || (Object)(object)item.m_dropPrefab == (Object)null) { return; } VisEquipment visEquipment = ((Humanoid)val).m_visEquipment; if (Object.op_Implicit((Object)(object)visEquipment) && _states.TryGetValue(visEquipment, out State value)) { string name = ((Object)item.m_dropPrefab).name; if (_registered.Contains(name) && value.Equipped.TryGetValue(name, out EquippedEntry value2) && value2.Item == item) { __result = true; } } } } [HarmonyPatch(typeof(Humanoid), "EquipItem")] internal static class HideTypeWhileEquipping { internal static bool IsVanillaEquipping; private static bool IsReserved(ItemType t) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Invalid comparison between Unknown and I4 //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Invalid comparison between Unknown and I4 //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Invalid comparison between Unknown and I4 //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Invalid comparison between Unknown and I4 //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Invalid comparison between Unknown and I4 if ((int)t <= 11) { if (t - 6 <= 1 || (int)t == 11) { goto IL_001e; } } else if (t - 17 <= 1 || (int)t == 24) { goto IL_001e; } return false; IL_001e: return true; } [HarmonyPrefix] [HarmonyPriority(800)] private static void Prefix(Humanoid __instance, ItemData item, ref ItemType? __state) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) if (!(__instance is Player) || (Object)(object)item?.m_dropPrefab == (Object)null) { return; } if (!IsManaged(item) && IsReserved(item.m_shared.m_itemType)) { IsVanillaEquipping = true; } if (IsManaged(item) && HasActiveSlot(item) && IsReserved(item.m_shared.m_itemType) && !__instance.IsItemEquiped(item)) { __state = item.m_shared.m_itemType; item.m_shared.m_itemType = API.GetFakeItemType(); if (Object.op_Implicit((Object)(object)__instance.m_visEquipment) && __instance.m_visEquipment.m_isPlayer) { item.m_shared.m_equipEffect.Create(((Component)__instance).transform.position + Vector3.up, ((Component)__instance).transform.rotation, (Transform)null, 1f, -1); } } } [HarmonyPostfix] [HarmonyPriority(0)] private static void Postfix(Humanoid __instance, ItemData item, bool triggerEquipEffects, ItemType? __state, ref bool __result) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) IsVanillaEquipping = false; Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val == null || !__state.HasValue) { return; } ItemType valueOrDefault = __state.GetValueOrDefault(); if (item == null || item.m_shared.m_itemType != API.GetFakeItemType()) { return; } item.m_shared.m_itemType = valueOrDefault; if (!((Humanoid)val).IsItemEquiped(item)) { __instance.SetupEquipment(); return; } VisEquipment visEquipment = ((Humanoid)val).m_visEquipment; if (!Object.op_Implicit((Object)(object)visEquipment) || !_states.TryGetValue(visEquipment, out State value)) { __instance.SetupEquipment(); return; } string slotOf = GetSlotOf(item); if (!string.IsNullOrEmpty(slotOf)) { foreach (KeyValuePair item3 in value.Equipped.ToList()) { EquippedEntry value2 = item3.Value; ItemData item2 = value2.Item; if (item2 != null && item2 != item && string.Equals(GetSlotOf(item2), slotOf, StringComparison.OrdinalIgnoreCase)) { ((Humanoid)val).UnequipItem(item2, triggerEquipEffects); value.ForceSetEquipped(item3.Key, 0); value2.Item = null; value2.DisplayName = ""; value.SetDisplayName(item3.Key, ""); } } } string name = ((Object)item.m_dropPrefab).name; if (_registered.Contains(name)) { value.ForceSetEquipped(name, StringExtensionMethods.GetStableHashCode(name)); } item.m_equipped = true; __result = true; __instance.SetupEquipment(); } } [HarmonyPatch(typeof(Humanoid), "EquipItem")] private static class EquipItemPatch { private static void OnEquip(Humanoid humanoid, ItemData item, bool trigger) { Player val = (Player)(object)((humanoid is Player) ? humanoid : null); if (val == null || (Object)(object)item?.m_dropPrefab == (Object)null) { return; } string name = ((Object)item.m_dropPrefab).name; if (!_registered.Contains(name)) { return; } VisEquipment visEquipment = ((Humanoid)val).m_visEquipment; if (Object.op_Implicit((Object)(object)visEquipment) && _states.TryGetValue(visEquipment, out State value)) { if (!value.Equipped.TryGetValue(name, out EquippedEntry value2)) { value2 = (value.Equipped[name] = new EquippedEntry(name)); } value2.Item = item; string text = name; if (_managed.TryGetValue(name, out (string, bool, string) value3) && !string.IsNullOrEmpty(value3.Item3)) { text = value3.Item3; } value2.DisplayName = text; value.SetDisplayName(name, text); } } private static IEnumerable Transpiler(IEnumerable instructionsEnumerable) { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Expected O, but got Unknown //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Expected O, but got Unknown //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Expected O, but got Unknown //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Expected O, but got Unknown List list = instructionsEnumerable.ToList(); MethodInfo isItemEquiped = AccessTools.DeclaredMethod(typeof(Humanoid), "IsItemEquiped", (Type[])null, (Type[])null); int num = list.FindLastIndex((CodeInstruction ci) => CodeInstructionExtensions.Calls(ci, isItemEquiped)); if (num <= 1) { return list; } CodeInstruction val = list[num - 2]; list.InsertRange(num - 2, new <>z__ReadOnlyArray((CodeInstruction[])(object)new CodeInstruction[4] { new CodeInstruction(OpCodes.Ldarg_0, (object)null) { labels = val.labels }, new CodeInstruction(OpCodes.Ldarg_1, (object)null), new CodeInstruction(OpCodes.Ldarg_2, (object)null), new CodeInstruction(OpCodes.Call, (object)AccessTools.DeclaredMethod(typeof(EquipItemPatch), "OnEquip", (Type[])null, (Type[])null)) })); val.labels = new List