Decompiled source of ItemStatistics v1.1.15
patchers/ItemStatisticsPatcher.dll
Decompiled 2 weeks agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Logging; using Mono.Cecil; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyVersion("1.1.15.0")] public static class ItemStatisticsPatcher { private static ManualLogSource _log; private static ManualLogSource log { get { if (_log == null) { _log = Logger.CreateLogSource("ItemStatisticsPatcher"); } return _log; } } public static IEnumerable<string> TargetDLLs => new string[1] { "RoR2.dll" }; public static void Patch(AssemblyDefinition assembly) { //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Expected O, but got Unknown //IL_0229: Unknown result type (might be due to invalid IL or missing references) //IL_0230: Expected O, but got Unknown ModuleDefinition mainModule = assembly.MainModule; string[] files = Directory.GetFiles(Paths.PluginPath, "ItemStatistics.dll", SearchOption.AllDirectories); if (files.Length == 0) { log.LogFatal((object)"Failed to find ItemStatistics.dll"); return; } AssemblyDefinition val = AssemblyDefinition.ReadAssembly(files[0]); TypeReference fieldType = mainModule.ImportReference((TypeReference)(object)val.MainModule.GetType("ItemStatistics.Components.TrackedInventory")); TypeReference val2 = mainModule.ImportReference((TypeReference)(object)val.MainModule.GetType("ItemStatistics.ProcChain")); GenericInstanceType val3 = new GenericInstanceType(mainModule.ImportReference(typeof(List<>))); val3.GenericArguments.Add(val2); TypeReference fieldType2 = mainModule.ImportReference((TypeReference)(object)val.MainModule.GetType("ItemStatistics.Index")); ModuleDefinition mainModule2 = AssemblyDefinition.ReadAssembly(Path.Combine(Paths.ManagedPath, "UnityEngine.CoreModule.dll")).MainModule; TypeReference fieldType3 = mainModule.ImportReference((TypeReference)(object)mainModule2.GetType("UnityEngine.GameObject")); TypeReference val4 = mainModule.ImportReference((TypeReference)(object)mainModule2.GetType("UnityEngine.SerializeField")); AddField(mainModule.GetType("RoR2.CharacterMaster"), fieldType, "trackedInventory"); AddField(mainModule.GetType("RoR2.DotController/DotStack"), val2, "dotStackChain"); AddField(mainModule.GetType("RoR2.DotController/PendingDamage"), (TypeReference)(object)val3, "pendingDotChainList"); AddField(mainModule.GetType("RoR2.Orbs.GenericDamageOrb"), fieldType3, "inflictor"); AddField(mainModule.GetType("RoR2.Orbs.DevilOrb"), fieldType3, "inflictor"); AddField(mainModule.GetType("RoR2.Orbs.BounceOrb"), fieldType3, "inflictor"); AddField(mainModule.GetType("RoR2.Orbs.LunarDetonatorOrb"), fieldType3, "inflictor"); AddField(mainModule.GetType("RoR2.Orbs.HealOrb"), fieldType2, "inflictor"); AddField(mainModule.GetType("EntityStates.FrozenState"), fieldType2, "freezeInflictor"); AddField(mainModule.GetType("EntityStates.FrozenState"), (TypeReference)(object)mainModule.GetType("RoR2.CharacterMaster"), "freezeInflictorMaster"); FieldDefinition obj = AddField(mainModule.GetType("EntityStates.BasicMeleeAttack"), fieldType2, "meleeInflictorIndex"); CustomAttribute val5 = new CustomAttribute(mainModule.ImportReference((MethodReference)(object)((IEnumerable<MethodDefinition>)val4.Resolve().Methods).First((MethodDefinition a) => a.IsConstructor && !a.IsStatic))); obj.CustomAttributes.Add(val5); } private static FieldDefinition AddField(TypeDefinition target, TypeReference fieldType, string fieldName) { //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Expected O, but got Unknown if (target == null || fieldType == null) { log.LogError((object)("Null types in AddField: " + fieldName)); return null; } if (((IEnumerable<FieldDefinition>)target.Fields).FirstOrDefault((Func<FieldDefinition, bool>)((FieldDefinition a) => ((MemberReference)a).Name == fieldName)) != null) { log.LogWarning((object)(((MemberReference)target).Name + "." + fieldName + " already exists")); return null; } FieldDefinition val = new FieldDefinition(fieldName, (FieldAttributes)6, fieldType); target.Fields.Add(val); return val; } }
plugins/ItemStatistics.dll
Decompiled 2 weeks ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using Dolso; using Dolso.RiskofOptions; using EntityStates; using EntityStates.CaptainDefenseMatrixItem; using EntityStates.Chef; using EntityStates.Croco; using EntityStates.FalseSon; using EntityStates.GlobalSkills.LunarDetonator; using EntityStates.GummyClone; using EntityStates.Headstompers; using EntityStates.Loader; using EntityStates.Mage; using EntityStates.Mage.Weapon; using EntityStates.Railgunner.Weapon; using EntityStates.Seeker; using EntityStates.Toolbot; using HG; using HG.GeneralSerializer; using HG.Reflection; using ItemStatistics; using ItemStatistics.Components; using ItemStatistics.Hooks; using ItemStatistics.Networking; using ItemStatistics.Trackers; using Mono.Cecil; using Mono.Cecil.Cil; using MonoMod.Cil; using MonoMod.RuntimeDetour; using MonoMod.Utils; using Rewired.Integration.UnityUI; using RiskOfOptions; using RiskOfOptions.OptionConfigs; using RiskOfOptions.Options; using RoR2; using RoR2.Items; using RoR2.Networking; using RoR2.Orbs; using RoR2.Projectile; using RoR2.Skills; using RoR2.Stats; using RoR2.UI; using TMPro; using Unity; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.EventSystems; using UnityEngine.Networking; using UnityEngine.ResourceManagement.AsyncOperations; using UnityEngine.UI; [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: OptIn] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: AssemblyInformationalVersion("1.0.0+da3480dcae20f922586d0a62c3e4331984fc2069")] [assembly: AssemblyProduct("ItemStatistics")] [assembly: AssemblyTitle("ItemStatistics")] [assembly: AssemblyCompany("ItemStatistics")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] namespace Dolso { internal static class log { private static ManualLogSource logger; internal static void start(ManualLogSource logSource) { logger = logSource; } internal static void start(string name) { logger = Logger.CreateLogSource(name); } internal static void info(object data) { logger.LogInfo(data); } internal static void message(object data) { logger.LogMessage(data); } internal static void warning(object data) { logger.LogWarning(data); } internal static void error(object data) { logger.LogError(data); } internal static void fatal(object data) { logger.LogFatal(data); } internal static void LogError(this ILCursor c, object data) { logger.LogError((object)string.Format($"ILCursor failure, skipping: {data}\n{c}")); } internal static void LogErrorCaller(this ILCursor c, object data) { logger.LogError((object)string.Format($"ILCursor failure in {new StackFrame(1).GetMethod().Name}, skipping: {data}\n{c}")); } } internal static class HookManager { internal delegate bool ConfigEnabled<T>(ConfigEntry<T> configEntry); internal const BindingFlags allFlags = BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; private static readonly ConfigEnabled<bool> boolConfigEnabled = (ConfigEntry<bool> configEntry) => configEntry.Value; private static ILHookConfig ilHookConfig = new ILHookConfig { ManualApply = true }; private static HookConfig onHookConfig = new HookConfig { ManualApply = true }; internal static void Hook(Type typeFrom, string methodFrom, Manipulator ilHook) { HookInternal(GetMethod(typeFrom, methodFrom), ilHook); } internal static void Hook(MethodBase methodFrom, Manipulator ilHook) { HookInternal(methodFrom, ilHook); } internal static void Hook(Delegate from, Manipulator ilHook) { HookInternal(from.Method, ilHook); } internal static void Hook(Type typeFrom, string methodFrom, Delegate onHook) { HookInternal(GetMethod(typeFrom, methodFrom), onHook.Method, onHook.Target); } internal static void Hook(MethodBase methodFrom, MethodInfo onHook) { HookInternal(methodFrom, onHook, null); } internal static void Hook(MethodBase methodFrom, Delegate onHook) { HookInternal(methodFrom, onHook.Method, onHook.Target); } internal static void Hook(Delegate from, Delegate onHook) { HookInternal(from.Method, onHook.Method, onHook.Target); } internal static void Hook(Type typeFrom, string methodFrom, Delegate onHook, object instance) { HookInternal(GetMethod(typeFrom, methodFrom), onHook.Method, instance); } internal static void Hook(MethodBase methodFrom, MethodInfo onHook, object target) { HookInternal(methodFrom, onHook, target); } private static void HookInternal(MethodBase methodFrom, Manipulator ilHook) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) if (methodFrom == null) { log.error("null methodFrom for hook: " + ((Delegate)(object)ilHook).Method.Name); return; } try { new ILHook(methodFrom, ilHook, ref ilHookConfig).Apply(); } catch (Exception ex) { log.error($"Failed to apply ILHook: {methodFrom.DeclaringType}::{methodFrom.Name} - {((Delegate)(object)ilHook).Method.Name}\n{ex}"); } } private static void HookInternal(MethodBase methodFrom, MethodInfo onHook, object target) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) if (methodFrom == null) { log.error("null methodFrom for hook: " + onHook.Name); return; } try { new Hook(methodFrom, onHook, target, ref onHookConfig).Apply(); } catch (Exception ex) { log.error($"Failed to apply Hook: {methodFrom.DeclaringType}::{methodFrom.Name} - {onHook.Name}\n{ex}"); } } internal static void HookConfig(this ConfigEntry<bool> configEntry, Type typeFrom, string methodFrom, Manipulator ilHook) { configEntry.HookConfigInternal(boolConfigEnabled, GetMethod(typeFrom, methodFrom), (Delegate)(object)ilHook); } internal static void HookConfig(this ConfigEntry<bool> configEntry, MethodBase methodFrom, Manipulator ilHook) { configEntry.HookConfigInternal(boolConfigEnabled, methodFrom, (Delegate)(object)ilHook); } internal static void HookConfig(this ConfigEntry<bool> configEntry, Type typeFrom, string methodFrom, Delegate onHook) { configEntry.HookConfigInternal(boolConfigEnabled, GetMethod(typeFrom, methodFrom), onHook); } internal static void HookConfig(this ConfigEntry<bool> configEntry, MethodBase methodFrom, Delegate onHook) { configEntry.HookConfigInternal(boolConfigEnabled, methodFrom, onHook); } internal static void HookConfig<T>(this ConfigEntry<T> configEntry, ConfigEnabled<T> enabled, Type typeFrom, string methodFrom, Manipulator ilHook) { configEntry.HookConfigInternal(enabled, GetMethod(typeFrom, methodFrom), (Delegate)(object)ilHook); } internal static void HookConfig<T>(this ConfigEntry<T> configEntry, ConfigEnabled<T> enabled, MethodBase methodFrom, Manipulator ilHook) { configEntry.HookConfigInternal(enabled, methodFrom, (Delegate)(object)ilHook); } internal static void HookConfig<T>(this ConfigEntry<T> configEntry, ConfigEnabled<T> enabled, Type typeFrom, string methodFrom, Delegate onHook) { configEntry.HookConfigInternal(enabled, GetMethod(typeFrom, methodFrom), onHook); } internal static void HookConfig<T>(this ConfigEntry<T> configEntry, ConfigEnabled<T> enabled, MethodBase methodFrom, Delegate onHook) { configEntry.HookConfigInternal(enabled, methodFrom, onHook); } private static void HookConfigInternal<T>(this ConfigEntry<T> configEntry, ConfigEnabled<T> enabled, MethodBase methodFrom, Delegate hook) { try { IDetour detour = ManualDetour(methodFrom, hook); configEntry.SettingChanged += delegate(object sender, EventArgs _) { UpdateHook(detour, enabled(sender as ConfigEntry<T>)); }; if (enabled(configEntry)) { detour.Apply(); } } catch (Exception ex) { log.error($"Failed to do config hook {methodFrom.DeclaringType}::{methodFrom.Name} - {hook.Method.Name}\n{ex}"); } } private static void UpdateHook(IDetour hook, bool enabled) { if (enabled) { if (!hook.IsApplied) { hook.Apply(); } } else if (hook.IsApplied) { hook.Undo(); } } internal static IDetour ManualDetour(Type typeFrom, string methodFrom, Delegate hook) { return ManualDetour(GetMethod(typeFrom, methodFrom), hook); } internal static IDetour ManualDetour(MethodBase methodFrom, Delegate hook) { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Expected O, but got Unknown //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown if (methodFrom == null) { log.error("null methodFrom for detour: " + hook.Method.Name); } else { try { Manipulator val = (Manipulator)(object)((hook is Manipulator) ? hook : null); if (val != null) { return (IDetour)new ILHook(methodFrom, val, ref ilHookConfig); } return (IDetour)new Hook(methodFrom, hook, ref onHookConfig); } catch (Exception ex) { log.error($"Failed to create detour {methodFrom.DeclaringType}::{methodFrom} - {hook.Method.Name}\n{ex}"); } } return null; } internal static MethodInfo GetMethod(Type typeFrom, string methodName) { if (typeFrom == null || methodName == null) { log.error($"Null argument in GetMethod: type={typeFrom}, name={methodName}"); return null; } MethodInfo[] array = (from predicate in typeFrom.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) where predicate.Name == methodName select predicate).ToArray(); switch (array.Length) { case 1: return array[0]; case 0: log.error($"Failed to find method: {typeFrom}::{methodName}"); return null; default: { log.error($"{array.Length} ambiguous matches found for: {typeFrom}::{methodName}"); MethodInfo[] array2 = array; for (int i = 0; i < array2.Length; i++) { log.error(array2[i]); } return null; } } } internal static MethodInfo GetMethod(Type typeFrom, string methodName, params Type[] parameters) { if (typeFrom == null || methodName == null) { log.error($"Null argument in GetMethod: type={typeFrom}, name={methodName}"); return null; } MethodInfo? method = typeFrom.GetMethod(methodName, BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, parameters, null); if (method == null) { log.error($"Failed to find method: {typeFrom}::{methodName}_{parameters.Length}"); } return method; } internal static void SetPriority(string[] before = null, string[] after = null) { ilHookConfig.Before = before; onHookConfig.Before = before; ilHookConfig.After = after; onHookConfig.After = after; } internal static void CreateWrapper(MethodInfo targetMethod, Action prefix, Action suffix) { //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Expected O, but got Unknown //IL_00aa: 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_00da: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) try { if (targetMethod == null || targetMethod.IsGenericMethodDefinition || targetMethod.GetMethodBody()?.GetILAsByteArray() == null) { log.error("invalid target method " + targetMethod); return; } Type[] onHookParameters; Type type = CreateDelegateType(targetMethod, out onHookParameters); DynamicMethodDefinition val = new DynamicMethodDefinition("wrapper_" + targetMethod.DeclaringType.Name + "_" + targetMethod.Name, targetMethod.ReturnType ?? typeof(void), onHookParameters); ILProcessor iLProcessor = val.GetILProcessor(); if (prefix != null) { if (prefix.Target != null) { DynamicMethodHelper.EmitReference<object>(iLProcessor, prefix.Target); } Extensions.Emit(iLProcessor, OpCodes.Call, (MethodBase)prefix.Method); } for (int i = 0; i < onHookParameters.Length; i++) { iLProcessor.Emit(OpCodes.Ldarg, i); } Extensions.Emit(iLProcessor, OpCodes.Call, (MethodBase)type.GetMethod("Invoke")); if (suffix != null) { if (suffix.Target != null) { DynamicMethodHelper.EmitReference<object>(iLProcessor, suffix.Target); } Extensions.Emit(iLProcessor, OpCodes.Call, (MethodBase)suffix.Method); } iLProcessor.Emit(OpCodes.Ret); MethodInfo methodInfo = DetourHelper.Pin<MethodInfo>(val.Generate()); new Hook((MethodBase)targetMethod, methodInfo, (object)null, ref onHookConfig).Apply(); } catch (Exception arg) { log.error($"Failed to create wrapper for {targetMethod}\n{arg}"); } } private static Type CreateDelegateType(MethodInfo method, out Type[] onHookParameters) { ModuleBuilder moduleBuilder = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName($"DDTASM<{method.DeclaringType}{method.Name}>?{method.MethodHandle.Value}".Replace(".", "_")), AssemblyBuilderAccess.Run).DefineDynamicModule("DynamicDelegateModule"); ParameterInfo[] parameters = method.GetParameters(); Type[] array; if (!method.IsStatic) { array = new Type[parameters.Length + 1]; array[0] = Extensions.GetThisParamType((MethodBase)method); for (int i = 0; i < parameters.Length; i++) { array[i + 1] = parameters[i].ParameterType; } } else { array = new Type[parameters.Length]; for (int j = 0; j < parameters.Length; j++) { array[j] = parameters[j].ParameterType; } } TypeBuilder typeBuilder = moduleBuilder.DefineType($"<{method.DeclaringType.Name}{method.Name}>?{method.MethodHandle.Value}".Replace(".", "_"), TypeAttributes.Public | TypeAttributes.Sealed, typeof(MulticastDelegate)); typeBuilder.DefineConstructor(MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName, CallingConventions.Standard, new Type[2] { typeof(object), typeof(IntPtr) }).SetImplementationFlags(MethodImplAttributes.CodeTypeMask); typeBuilder.DefineMethod("Invoke", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig, method.ReturnType ?? typeof(void), array).SetImplementationFlags(MethodImplAttributes.CodeTypeMask); Type type = typeBuilder.CreateType(); onHookParameters = new Type[array.Length + 1]; onHookParameters[0] = type; for (int k = 0; k < array.Length; k++) { onHookParameters[k + 1] = array[k]; } return type; } } internal static class Utilities { private static GameObject _prefabParent; internal static GameObject CreatePrefab(GameObject gameObject, string name = null) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown if (!Object.op_Implicit((Object)(object)_prefabParent)) { _prefabParent = new GameObject("DolsoPrefabs"); Object.DontDestroyOnLoad((Object)(object)_prefabParent); ((Object)_prefabParent).hideFlags = (HideFlags)61; _prefabParent.SetActive(false); } GameObject val = Object.Instantiate<GameObject>(gameObject, _prefabParent.transform); if (name != null) { ((Object)val).name = name; } return val; } internal static MethodInfo MakeGenericMethod<T>(this Type type, string methodName, params Type[] parameters) { return type.GetMethod(methodName, parameters).MakeGenericMethod(typeof(T)); } internal static MethodInfo MakeGenericGetComponentG<T>() where T : Component { return typeof(GameObject).GetMethod("GetComponent", Type.EmptyTypes).MakeGenericMethod(typeof(T)); } internal static MethodInfo MakeGenericGetComponentC<T>() where T : Component { return typeof(Component).GetMethod("GetComponent", Type.EmptyTypes).MakeGenericMethod(typeof(T)); } internal static Task<Obj> GetAddressableAsync<Obj>(string addressable) where Obj : Object { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) return Addressables.LoadAssetAsync<Obj>((object)addressable).Task; } internal static Task<GameObject> GetAddressableAsync(string addressable) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) return Addressables.LoadAssetAsync<GameObject>((object)addressable).Task; } internal static void DoAddressable<Obj>(string addressable, Action<Obj> callback) where Obj : Object { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) AsyncOperationHandle<Obj> val = Addressables.LoadAssetAsync<Obj>((object)addressable); val.Completed += delegate(AsyncOperationHandle<Obj> a) { callback(a.Result); }; } internal static void DoAddressable(string addressable, Action<GameObject> callback) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) AsyncOperationHandle<GameObject> val = Addressables.LoadAssetAsync<GameObject>((object)addressable); val.Completed += delegate(AsyncOperationHandle<GameObject> a) { callback(a.Result); }; } internal static void AddressableAddComp<Comp>(string addressable) where Comp : Component { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) AsyncOperationHandle<GameObject> val = Addressables.LoadAssetAsync<GameObject>((object)addressable); val.Completed += delegate(AsyncOperationHandle<GameObject> a) { a.Result.AddComponent<Comp>(); }; } internal static void AddressableAddComp<Comp>(string addressable, Action<Comp> callback) where Comp : Component { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) AsyncOperationHandle<GameObject> val = Addressables.LoadAssetAsync<GameObject>((object)addressable); val.Completed += delegate(AsyncOperationHandle<GameObject> a) { callback(a.Result.AddComponent<Comp>()); }; } internal static void AddressableAddCompSingle<Comp>(string addressable) where Comp : Component { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) AsyncOperationHandle<GameObject> val = Addressables.LoadAssetAsync<GameObject>((object)addressable); val.Completed += delegate(AsyncOperationHandle<GameObject> a) { if (!Object.op_Implicit((Object)(object)a.Result.GetComponent<Comp>())) { a.Result.AddComponent<Comp>(); } }; } internal static AssetBundle LoadAssetBundle(string bundlePathName) { AssetBundle result = null; try { result = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), bundlePathName)); } catch (Exception ex) { log.error("Failed to load assetbundle\n" + ex); } return result; } internal static void ModifyStateConfig(string stateConfigAddress, string fieldName, object newValue) { Utilities.DoAddressable<EntityStateConfiguration>(stateConfigAddress, (Action<EntityStateConfiguration>)delegate(EntityStateConfiguration a) { a.ModifyStateConfig(fieldName, newValue); }); } internal static void ModifyStateConfig(this EntityStateConfiguration stateConfig, string fieldName, object newValue) { SerializedField[] serializedFields = stateConfig.serializedFieldsCollection.serializedFields; for (int i = 0; i < serializedFields.Length; i++) { if (serializedFields[i].fieldName == fieldName) { Object val = (Object)((newValue is Object) ? newValue : null); if (val != null) { serializedFields[i].fieldValue.objectValue = val; } else if (newValue is string stringValue) { serializedFields[i].fieldValue.stringValue = stringValue; } else { log.error("Invalid value for SerializedField: " + newValue); } return; } } log.error("Failed to find " + fieldName + " for " + ((Object)stateConfig).name); } internal static bool IsKeyDown(this ConfigEntry<KeyboardShortcut> key) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0009: 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_002e: Unknown result type (might be due to invalid IL or missing references) KeyboardShortcut value = key.Value; if (!Input.GetKey(((KeyboardShortcut)(ref value)).MainKey)) { return false; } value = key.Value; foreach (KeyCode modifier in ((KeyboardShortcut)(ref value)).Modifiers) { if (!Input.GetKey(modifier)) { return false; } } return true; } internal static bool IsKeyJustPressed(this ConfigEntry<KeyboardShortcut> key) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0009: 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_002e: Unknown result type (might be due to invalid IL or missing references) KeyboardShortcut value = key.Value; if (!Input.GetKeyDown(((KeyboardShortcut)(ref value)).MainKey)) { return false; } value = key.Value; foreach (KeyCode modifier in ((KeyboardShortcut)(ref value)).Modifiers) { if (!Input.GetKey(modifier)) { return false; } } return true; } } } namespace Dolso.RiskofOptions { internal static class RiskofOptions { internal const string rooGuid = "com.rune580.riskofoptions"; internal static bool enabled => Chainloader.PluginInfos.ContainsKey("com.rune580.riskofoptions"); internal static void SetSprite(Sprite sprite) { ModSettingsManager.SetModIcon(sprite); } internal static void SetSpriteDefaultIcon() { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Expected O, but got Unknown //IL_007e: 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) DirectoryInfo directoryInfo = new DirectoryInfo(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)); string path = ((!(directoryInfo.Name == "plugins")) ? directoryInfo.FullName : directoryInfo.Parent.FullName); try { Texture2D val = new Texture2D(256, 256); if (ImageConversion.LoadImage(val, File.ReadAllBytes(Path.Combine(path, "icon.png")))) { ModSettingsManager.SetModIcon(Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f))); } else { log.error("Failed to load icon.png"); } } catch (Exception ex) { log.error("Failed to load icon.png\n" + ex); } } internal static void AddOption(ConfigEntry<bool> entry) { AddOption(entry, "", ""); } internal static void AddOption(ConfigEntry<bool> entry, string categoryName = "", string name = "") { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000d: 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_0025: Expected O, but got Unknown //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(entry, new CheckBoxConfig { category = categoryName, name = name, description = ((ConfigEntryBase)(object)entry).DescWithDefault() })); } internal static void AddOption<T>(ConfigEntry<T> entry) where T : Enum { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown ModSettingsManager.AddOption((BaseOption)new ChoiceOption((ConfigEntryBase)(object)entry, new ChoiceConfig { description = ((ConfigEntryBase)(object)entry).DescWithDefault() })); } internal static void AddOption(ConfigEntry<Color> entry) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown ModSettingsManager.AddOption((BaseOption)new ColorOption(entry, new ColorOptionConfig { description = ((ConfigEntryBase)(object)entry).DescWithDefault() })); } internal static void AddOption(ConfigEntry<KeyboardShortcut> entry) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown ModSettingsManager.AddOption((BaseOption)new KeyBindOption(entry, new KeyBindConfig { description = ((ConfigEntryBase)(object)entry).DescWithDefault() })); } internal static void AddOption(ConfigEntry<float> entry, float min, float max, string format = "{0:f2}") { AddFloatSlider(entry, min, max, format); } internal static void AddOption(ConfigEntry<int> entry) { AddIntField(entry); } internal static void AddOption(ConfigEntry<string> entry) { AddString(entry); } internal static void AddString(ConfigEntry<string> entry, bool restartRequired = false, string categoryName = "") { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: 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_0014: 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_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown ModSettingsManager.AddOption((BaseOption)new StringInputFieldOption(entry, new InputFieldConfig { submitOn = (SubmitEnum)6, lineType = (LineType)0, category = categoryName, description = ((ConfigEntryBase)(object)entry).DescWithDefault(), restartRequired = restartRequired })); } internal static void AddFloatField(ConfigEntry<float> entry, float min = float.MinValue, float max = float.MaxValue, string format = "{0:f2}") { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Expected O, but got Unknown //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Expected O, but got Unknown //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Expected O, but got Unknown FloatFieldConfig val = new FloatFieldConfig(); ((NumericFieldConfig<float>)val).Min = min; ((NumericFieldConfig<float>)val).Max = max; ((NumericFieldConfig<float>)val).FormatString = format; ((BaseOptionConfig)val).description = ((ConfigEntryBase)(object)entry).DescWithDefault(format); ModSettingsManager.AddOption((BaseOption)new FloatFieldOption(entry, val)); } internal static void AddFloatSlider(ConfigEntry<float> entry, float min, float max, string format = "{0:f2}", string categoryName = "") { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000d: 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_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Expected O, but got Unknown ModSettingsManager.AddOption((BaseOption)new SliderOption(entry, new SliderConfig { min = min, max = max, FormatString = format, category = categoryName, description = ((ConfigEntryBase)(object)entry).DescWithDefault(format) })); } internal static void AddIntField(ConfigEntry<int> entry, int min = int.MinValue, int max = int.MaxValue) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Expected O, but got Unknown //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown IntFieldConfig val = new IntFieldConfig(); ((NumericFieldConfig<int>)val).Min = min; ((NumericFieldConfig<int>)val).Max = max; ((BaseOptionConfig)val).description = ((ConfigEntryBase)(object)entry).DescWithDefault(); ModSettingsManager.AddOption((BaseOption)new IntFieldOption(entry, val)); } internal static void AddIntSlider(ConfigEntry<int> entry, int min, int max, string categoryName = "") { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000d: 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_001b: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown ModSettingsManager.AddOption((BaseOption)new IntSliderOption(entry, new IntSliderConfig { min = min, max = max, category = categoryName, description = ((ConfigEntryBase)(object)entry).DescWithDefault() })); } private static string DescWithDefault(this ConfigEntryBase entry) { return $"{entry.Description.Description}\n[Default: {entry.DefaultValue}]"; } private static string DescWithDefault(this ConfigEntryBase entry, string format) { return string.Format("{1}\n[Default: " + format + "]", entry.DefaultValue, entry.Description.Description); } } } namespace ItemStatistics { internal static class Config { internal enum ResetMode { Never, WhenNotInInventory, EveryPickup } private static ConfigFile configFile; internal static ConfigEntry<ResetMode> resetOnStackChanged; internal static ConfigEntry<KeyboardShortcut> resetSpamKey; internal static void DoConfig(ConfigFile bepConfigFile) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) configFile = bepConfigFile; resetOnStackChanged = configFile.Bind<ResetMode>(string.Empty, "Reset on Stack Changed", ResetMode.Never, "When item stack changes, should its stats automatically be reset? Can right click on item to force a reset. Warning: having this enabled will cause stats to be reset during Mithrix's item steal phase"); resetSpamKey = configFile.Bind<KeyboardShortcut>(string.Empty, "Reset Spam Key", new KeyboardShortcut((KeyCode)306, Array.Empty<KeyCode>()), "Hold this key down to easily reset icons you hover over"); if (Chainloader.PluginInfos.ContainsKey("com.rune580.riskofoptions")) { DoRiskOfOptions(); } } internal static void DoRiskOfOptions() { RiskofOptions.SetSpriteDefaultIcon(); RiskofOptions.AddOption<ResetMode>(resetOnStackChanged); RiskofOptions.AddOption(resetSpamKey); } [ConCommand(/*Could not decode attribute arguments.*/)] private static void ReloadConfig(ConCommandArgs args) { configFile.Reload(); Debug.Log((object)"ItemStatistics config reloaded"); } } [Serializable] public struct Index : IEquatable<Index> { [SerializeField] private int _value; public readonly IndexType type => (IndexType)(_value >> 16); public readonly int index => (short)_value; public readonly bool isNotNone => _value != 0; public Index(ItemIndex index) { //IL_0001: 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_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Expected I4, but got Unknown _value = (index & 0xFFFF) + 65536; } public Index(EquipmentIndex index) { //IL_0001: 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_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Expected I4, but got Unknown _value = (index & 0xFFFF) + 131072; } public Index(SkillSlot index) { //IL_0001: 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_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Expected I4, but got Unknown _value = (index & 0xFFFF) + 196608; } public Index(BodyIndexType index) { _value = (int)((index & (BodyIndexType)65535) + 262144); } public Index(short type, short index) { _value = (type << 16) + (index & 0xFFFF); } public static implicit operator Index(ItemIndex index) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return new Index(index); } public static implicit operator Index(ItemDef itemDef) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return new Index(itemDef.itemIndex); } public static implicit operator Index(EquipmentIndex index) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return new Index(index); } public static implicit operator Index(EquipmentDef equipDef) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return new Index(equipDef.equipmentIndex); } public static implicit operator Index(SkillSlot index) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return new Index(index); } public static implicit operator Index(BodyIndexType index) { return new Index(index); } public static explicit operator ItemIndex(Index index) { if (index.type != IndexType.Item) { throw new InvalidCastException("Index type is not Item"); } return (ItemIndex)index.index; } public static explicit operator EquipmentIndex(Index index) { if (index.type != IndexType.Equip) { throw new InvalidCastException("Index type is not Equip"); } return (EquipmentIndex)index.index; } public static explicit operator SkillSlot(Index index) { if (index.type != IndexType.SkillSlot) { throw new InvalidCastException("Index type is not SkillSlot"); } return (SkillSlot)(sbyte)index.index; } public static explicit operator BodyIndexType(Index index) { if (index.type != IndexType.Body) { throw new InvalidCastException("Index type is not Body"); } return (BodyIndexType)index.index; } public static bool operator ==(Index a, Index b) { return a._value == b._value; } public static bool operator !=(Index a, Index b) { return a._value != b._value; } public override bool Equals(object obj) { if (obj is Index index) { return _value == index._value; } return false; } public bool Equals(Index index) { return _value == index._value; } public override int GetHashCode() { return _value; } public override string ToString() { //IL_0099: Unknown result type (might be due to invalid IL or missing references) switch (type) { case IndexType.None: return "None" + ((index == 0) ? "" : (", " + index)); case IndexType.Item: return Language.GetString(ItemCatalog.GetItemDef((ItemIndex)index).nameToken); case IndexType.Equip: return Language.GetString(EquipmentCatalog.GetEquipmentDef((EquipmentIndex)index).nameToken); case IndexType.SkillSlot: { SkillSlot val = (SkillSlot)(sbyte)index; return "Skill, " + ((object)(SkillSlot)(ref val)).ToString(); } case IndexType.Body: return "Body, " + (BodyIndexType)index; default: return $"Unknown Index {type}, {index}"; } } internal static void Serialize(NetworkWriter writer, Index value) { writer.WritePackedUInt32((uint)value._value); } internal static Index Deserialize(NetworkReader reader) { Index result = default(Index); result._value = (int)reader.ReadPackedUInt32(); return result; } private static string SerializeToString(object obj) { Index index = (Index)obj; return $"{((int)index.type).ToString()} {index.index.ToString(CultureInfo.InvariantCulture)}"; } private static object DeserializeFromString(string str) { string[] array = StringSerializer.SplitToComponents(str, typeof(Index), 2); return new Index(short.Parse(array[0], CultureInfo.InvariantCulture), short.Parse(array[1], CultureInfo.InvariantCulture)); } static Index() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown //IL_003d: Unknown result type (might be due to invalid IL or missing references) StringSerializer.serializationHandlers[typeof(Index)] = new SerializationHandler { serializer = new SerializerDelegate(SerializeToString), deserializer = new DeserializerDelegate(DeserializeFromString) }; } } public enum IndexType { None, Item, Equip, SkillSlot, Body } public enum BodyIndexType { Ignore, Regen, Barrier, MinionDamage } public static class ItemStatisticsAPI { public static void AddTrackerToPrefab(GameObject prefab, Index indexToCredit) { prefab.AddComponent<ProcComponent>().index = indexToCredit; } public static void AddMinionTrackerToPrefab(GameObject prefab, Index indexToCredit) { prefab.AddComponent<MinionComponent>().index = indexToCredit; } public static void AddTrackedIndex(Index indexToAdd, TrackedDef trackerType) { if (trackerType != null) { ItemStatisticsPlugin.indexToDef.Add(indexToAdd, trackerType); return; } Index index = indexToAdd; log.error(index.ToString() + " has a null tracker type"); } public static void WrapAttackWithIndex(MethodInfo yourAttackMethod, Index indexToCredit) { HookManager.CreateWrapper(yourAttackMethod, delegate { NetworkHooks.inflictorIndex = indexToCredit; }, AttackSuffix); } public static TrackedInventory GetTrackedInventory(CharacterMaster master, bool includeFromMinion) { return TrackedInventory.GetTrackedInventory(master, includeFromMinion); } public static bool TryGetTrackedInventory(CharacterMaster master, bool includeFromMinion, out TrackedInventory trackedInventory) { return TrackedInventory.TryGetTrackedInventory(master, includeFromMinion, out trackedInventory); } public static GameObject CreateNewInflictor(Index index, GameObject parentInflictor = null) { return ProcComponent.CreateInflictor(index, parentInflictor); } public static void AddChainToNextProjectileFromInflictor(GameObject parentInflictor) { ILExtensions.parentInflictorParameter = parentInflictor; } public static void TrackNextDot(GameObject parentInflictor) { DotTracking.dotChainParameter = ProcComponent.GetChainFromInflictor(parentInflictor); } public static void TrackNextDot(Index dotApplier, GameObject parentInflictor) { DotTracking.dotChainParameter = new ProcChain(dotApplier, ProcComponent.GetChainFromInflictor(parentInflictor)); } public static void CreditNextHeal(Index indexToCredit) { HCHeal.healIndex = indexToCredit; } public static void CreditDamage(TrackedInventory trackedInventory, Index index, float damage) { trackedInventory.AddDamage(index, damage); } public static void CreditGold(TrackedInventory trackedInventory, Index index, float gold) { trackedInventory.AddGold(index, gold); } public static void CreditProcAttempt(TrackedInventory trackedInventory, Index index) { trackedInventory.ProcAttempt(index); } public static void CreditProcSuccess(TrackedInventory trackedInventory, Index index) { trackedInventory.ProcSuccess(index); } private static void AttackSuffix() { NetworkHooks.inflictorIndex = default(Index); } } [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("dolso.ItemStatistics", "ItemStatistics", "1.1.15")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class ItemStatisticsPlugin : BaseUnityPlugin { public const string Version = "1.1.15"; public const string ModGuid = "dolso.ItemStatistics"; internal static readonly Dictionary<Index, TrackedDef> indexToDef = new Dictionary<Index, TrackedDef>(); internal static GameObject missileLauncher; internal static GameObject overloadingHeadhunter; internal static GameObject fireTrailHeadhunter; internal static int crocoDiseaseProjectileIndex; internal static BodyIndex falseSonCharacterBodyIndex; private void Awake() { log.start(((BaseUnityPlugin)this).Logger); Config.DoConfig(((BaseUnityPlugin)this).Config); try { Utilities.AddressableAddComp<IconBehaviour>("RoR2/Base/UI/ItemIcon.prefab", (Action<IconBehaviour>)delegate(IconBehaviour a) { a.type = IndexType.Item; }); Utilities.AddressableAddComp<IconBehaviour>("RoR2/Base/UI/ItemIconScoreboard_InGame.prefab", (Action<IconBehaviour>)delegate(IconBehaviour a) { a.type = IndexType.Item; }); Utilities.DoAddressable("RoR2/Base/Core/PlayerMaster.prefab", delegate(GameObject a) { a.GetComponent<CharacterMaster>().trackedInventory = a.AddComponent<TrackedInventory>(); }); Utilities.DoAddressable("RoR2/Base/UI/HUDSimple.prefab", delegate(GameObject hudsimple) { EquipmentIcon[] componentsInChildren = hudsimple.GetComponentsInChildren<EquipmentIcon>(); for (int i = 0; i < componentsInChildren.Length; i++) { ((Component)componentsInChildren[i]).gameObject.AddComponent<IconBehaviour>().type = IndexType.Equip; } SkillIcon[] componentsInChildren2 = hudsimple.GetComponentsInChildren<SkillIcon>(); for (int i = 0; i < componentsInChildren2.Length; i++) { ((Component)componentsInChildren2[i]).gameObject.AddComponent<IconBehaviour>().type = IndexType.SkillSlot; } }); Utilities.DoAddressable("RoR2/Base/UI/ScoreboardStrip.prefab", delegate(GameObject scoreboardStrip) { ((Component)scoreboardStrip.GetComponentInChildren<EquipmentIcon>()).gameObject.AddComponent<IconBehaviour>().type = IndexType.Equip; PlayerTooltip.CreateTooltipPrefab(scoreboardStrip); }); ToolbotStance.DoSetup(); } catch (Exception ex) { log.error("Failed to do addressables\n" + ex); } Stopwatch stopwatch = Stopwatch.StartNew(); GeneralHooks.Hook(); HCDamage.Hook(); HCHeal.Hook(); GEMHooks.Hook(); ItemHooks.Hook(); OrbHooks.Hook(); DotTracking.Hook(); EquipmentHooks.Hook(); SurvivorHooks.Hook(); NetworkHooks.Hook(); FreezeHooks.Hook(); Language.collectLanguageRootFolders += CollectLanguageRootFolders; log.info($"Hooks completed in {stopwatch.Elapsed.TotalSeconds:f2}s"); } [SystemInitializer(new Type[] { typeof(PickupCatalog), typeof(SurvivorCatalog), typeof(ProjectileCatalog) })] private static void Init() { //IL_0a31: Unknown result type (might be due to invalid IL or missing references) //IL_0a36: Unknown result type (might be due to invalid IL or missing references) Dictionary<Index, TrackedDef> dictionary = indexToDef; dictionary.Add((SkillSlot)0, TrackedDef.Skill); dictionary.Add((SkillSlot)1, TrackedDef.Skill); dictionary.Add((SkillSlot)2, TrackedDef.Skill); dictionary.Add((SkillSlot)3, TrackedDef.Skill); dictionary.Add(BodyIndexType.Regen, new TrackedDef(typeof(HealTracker), TrackedDef.regenPortionTooltip)); dictionary.Add(BodyIndexType.Barrier, new TrackedDef(typeof(ArmorTracker), TrackedDef.barrierBlockedTooltip)); dictionary.Add(BodyIndexType.MinionDamage, new TrackedDef(typeof(DamageTracker), TrackedDef.minionPortionTooltip)); dictionary.Add(Items.Bear, TrackedDef.ArmorCount); dictionary.Add(Items.BearVoid, TrackedDef.ArmorCount); dictionary.Add(Items.Crowbar, TrackedDef.Damage); dictionary.Add(Items.ExplodeOnDeathVoid, TrackedDef.Damage); dictionary.Add(Items.NearbyDamageBonus, TrackedDef.Damage); dictionary.Add(Items.FragileDamageBonus, TrackedDef.Damage); dictionary.Add(Items.FragileDamageBonusConsumed, TrackedDef.Watch); dictionary.Add(Items.PermanentDebuffOnHit, TrackedDef.Chance); dictionary.Add(Items.BossDamageBonus, TrackedDef.Damage); dictionary.Add(Items.CritGlasses, TrackedDef.Damage); dictionary.Add(Items.CritDamage, TrackedDef.Damage); dictionary.Add(Items.DeathMark, TrackedDef.Damage); dictionary.Add(Items.CritGlassesVoid, TrackedDef.DamageChance); dictionary.Add(Items.ExecuteLowHealthElite, TrackedDef.Damage); dictionary.Add(Items.OutOfCombatArmor, TrackedDef.ArmorCount); dictionary.Add(Items.SprintArmor, TrackedDef.Armor); dictionary.Add(Items.ArmorPlate, TrackedDef.Armor); dictionary.Add(Items.ParentEgg, TrackedDef.Heal); dictionary.Add(Items.GoldOnHit, TrackedDef.Gold); dictionary.Add(Items.GoldOnHurt, TrackedDef.Gold); dictionary.Add(Items.Thorns, TrackedDef.Damage); dictionary.Add(Items.Seed, TrackedDef.Heal); dictionary.Add(Items.BleedOnHit, TrackedDef.DamageChance); dictionary.Add(Items.BleedOnHitVoid, TrackedDef.DamageChance); dictionary.Add(Items.SlowOnHitVoid, TrackedDef.Chance); dictionary.Add(Items.Missile, TrackedDef.DamageChance); dictionary.Add(Items.MissileVoid, TrackedDef.DamageChance); dictionary.Add(Items.ChainLightning, TrackedDef.DamageChance); dictionary.Add(Items.ChainLightningVoid, TrackedDef.DamageChance); dictionary.Add(Items.BounceNearby, TrackedDef.DamageChance); dictionary.Add(Items.StickyBomb, TrackedDef.DamageChance); dictionary.Add(Items.IceRing, TrackedDef.Damage); dictionary.Add(Items.FireRing, TrackedDef.Damage); dictionary.Add(Items.ElementalRingVoid, TrackedDef.Damage); dictionary.Add(Items.FireballsOnHit, TrackedDef.DamageChance); dictionary.Add(Items.LightningStrikeOnHit, TrackedDef.DamageChance); dictionary.Add(Items.HealOnCrit, TrackedDef.Heal); dictionary.Add(Items.Behemoth, TrackedDef.Damage); dictionary.Add(Items.IgniteOnKill, TrackedDef.DamageChance); dictionary.Add(Items.ExplodeOnDeath, TrackedDef.DamageChance); dictionary.Add(Items.Dagger, TrackedDef.Damage); dictionary.Add(Items.Tooth, TrackedDef.Heal); dictionary.Add(Items.Bandolier, TrackedDef.Chance); dictionary.Add(Items.BonusGoldPackOnKill, TrackedDef.Gold); dictionary.Add(Items.BleedOnHitAndExplode, new TrackedDef(typeof(DamageChanceTracker), TrackedDef.hit_damageTooltip)); dictionary.Add(Items.BarrierOnKill, new TrackedDef(typeof(HealTracker), TrackedDef.barrierGainedTooltip)); dictionary.Add(Items.Plant, TrackedDef.Heal); dictionary.Add(Items.Mushroom, TrackedDef.Heal); dictionary.Add(Items.MushroomVoid, TrackedDef.Heal); dictionary.Add(Items.Medkit, TrackedDef.Heal); dictionary.Add(Items.TPHealingNova, TrackedDef.Heal); dictionary.Add(Items.HealingPotionConsumed, TrackedDef.Heal); dictionary.Add(Items.BarrierOnOverHeal, new TrackedDef(typeof(HealTracker), TrackedDef.barrierGainedTooltip)); dictionary.Add(Items.ShockNearby, TrackedDef.DamagePortion); dictionary.Add(Items.PrimarySkillShuriken, new TrackedDef(typeof(DamageChanceTracker), TrackedDef.hit_damageTooltip)); dictionary.Add(Items.StrengthenBurn, TrackedDef.Damage); dictionary.Add(Items.LaserTurbine, TrackedDef.Damage); dictionary.Add(Items.CaptainDefenseMatrix, TrackedDef.Count); dictionary.Add(Items.Icicle, TrackedDef.Damage); dictionary.Add(Items.NovaOnLowHealth, TrackedDef.DamagePortion); dictionary.Add(Items.ImmuneToDebuff, new TrackedDef(typeof(HealChanceTracker), TrackedDef.chance_barrierTooltip)); dictionary.Add(Items.NovaOnHeal, TrackedDef.Damage); dictionary.Add(Items.SprintWisp, TrackedDef.DamagePortion); dictionary.Add(Items.RandomlyLunar, TrackedDef.Chance); dictionary.Add(Items.Firework, TrackedDef.Damage); dictionary.Add(Items.Phasing, TrackedDef.Count); dictionary.Add(Items.FallBoots, TrackedDef.DamagePortion); dictionary.Add(Items.SiphonOnLowHealth, TrackedDef.Heal); dictionary.Add(Items.LunarSun, TrackedDef.DamagePortion); dictionary.Add(Items.Infusion, TrackedDef.Count); dictionary.Add(Items.HeadHunter, TrackedDef.Damage); dictionary.Add(Items.RoboBallBuddy, TrackedDef.Damage); dictionary.Add(Items.VoidMegaCrabItem, TrackedDef.Damage); dictionary.Add(Items.BeetleGland, TrackedDef.Damage); dictionary.Add(Items.DroneWeapons, TrackedDef.Damage); dictionary.Add(Items.GhostOnKill, TrackedDef.Damage); dictionary.Add(Items.MinorConstructOnKill, TrackedDef.Damage); dictionary.Add(Items.Squid, TrackedDef.Damage); dictionary.Add(Items.TitanGoldDuringTP, TrackedDef.Damage); dictionary.Add(Items.LowerHealthHigherDamage, TrackedDef.Damage); dictionary.Add(Items.NegateAttack, TrackedDef.DamageChance); dictionary.Add(Items.ExtraShrineItem, TrackedDef.Chance); dictionary.Add(Items.IncreasePrimaryDamage, TrackedDef.Damage); dictionary.Add(Items.MeteorAttackOnHighDamage, TrackedDef.DamageChance); dictionary.Add(Items.KnockBackHitEnemies, TrackedDef.Chance); dictionary.Add(Items.StunAndPierce, TrackedDef.DamageChance); dictionary.Add(Items.LowerPricedChests, TrackedDef.Count); dictionary.Add(Items.LowerPricedChestsConsumed, TrackedDef.Count); dictionary.Add(Items.ResetChests, TrackedDef.Chance); dictionary.Add(Items.GoldOnStageStart, TrackedDef.Gold); dictionary.Add(Items.TeleportOnLowHealth, TrackedDef.Count); dictionary.Add(Equipment.Saw, TrackedDef.DamagePortion); dictionary.Add(Equipment.GoldGat, TrackedDef.Damage); dictionary.Add(Equipment.BFG, TrackedDef.Damage); dictionary.Add(Equipment.PassiveHealing, TrackedDef.Heal); dictionary.Add(Equipment.CommandMissile, TrackedDef.Damage); dictionary.Add(Equipment.Fruit, TrackedDef.Heal); dictionary.Add(Equipment.DroneBackup, TrackedDef.Damage); dictionary.Add(Equipment.Lightning, TrackedDef.Damage); dictionary.Add(Equipment.Recycle, new TrackedDef(typeof(CountTracker), TrackedDef.recycledTooltip)); dictionary.Add(Equipment.LifestealOnHit, TrackedDef.Heal); dictionary.Add(Equipment.Molotov, TrackedDef.Damage); dictionary.Add(Equipment.VendingMachine, TrackedDef.Heal); dictionary.Add(Equipment.GummyClone, TrackedDef.Damage); dictionary.Add(Equipment.MultiShopCard, TrackedDef.Gold); dictionary.Add(Equipment.GainArmor, TrackedDef.Armor); dictionary.Add(Equipment.Meteor, TrackedDef.Damage); dictionary.Add(Equipment.BurnNearby, TrackedDef.Damage); dictionary.Add(Equipment.AffixRed, TrackedDef.Damage); dictionary.Add(Equipment.AffixBlue, TrackedDef.Damage); dictionary.Add(Equipment.AffixWhite, TrackedDef.Damage); crocoDiseaseProjectileIndex = ProjectileCatalog.FindProjectileIndex("CrocoDiseaseProjectile"); falseSonCharacterBodyIndex = BodyCatalog.FindBodyIndex("FalseSonBody"); ModifyPrefabs(); } private static void ModifyPrefabs() { //IL_078c: Unknown result type (might be due to invalid IL or missing references) //IL_0791: Unknown result type (might be due to invalid IL or missing references) AddProcComponent("RoR2/Base/StickyBomb/StickyBomb.prefab", Items.StickyBomb); AddProcComponent("RoR2/Base/ElementalRings/FireTornado.prefab", Items.FireRing); AddProcComponent("RoR2/DLC1/ElementalRingVoid/ElementalRingVoidBlackHole.prefab", Items.ElementalRingVoid); AddProcComponent("RoR2/Base/FireballsOnHit/FireMeatBall.prefab", Items.FireballsOnHit); AddProcComponent("RoR2/DLC1/PrimarySkillShuriken/ShurikenProjectile.prefab", Items.PrimarySkillShuriken); AddProcComponent("RoR2/Base/LaserTurbine/LaserTurbineController.prefab", Items.LaserTurbine); AddProcComponent("RoR2/Base/LaserTurbine/LaserTurbineBomb.prefab", Items.LaserTurbine); AddProcComponent("RoR2/Base/Icicle/IcicleAura.prefab", Items.Icicle); AddProcComponent("RoR2/Base/NovaOnLowHealth/VagrantNovaItemBodyAttachment.prefab", Items.NovaOnLowHealth); AddProcComponent("RoR2/Base/Firework/FireworkProjectile.prefab", Items.Firework); AddProcComponent("RoR2/DLC1/LunarSun/LunarSunProjectile.prefab", Items.LunarSun); AddProcComponent("RoR2/DLC2/Items/StunAndPierce/StunAndPierceBoomerang.prefab", Items.StunAndPierce); AddProcComponent("RoR2/Base/Dagger/DaggerProjectile.prefab", Items.Dagger); AddProcComponent("RoR2/Base/BleedOnHitAndExplode/BleedOnHitAndExplodeDelay.prefab", Items.BleedOnHitAndExplode); AddProcComponent("RoR2/Base/Mushroom/MushroomWard.prefab", Items.Mushroom); AddProcComponent("RoR2/Base/Plant/DeskplantWard.prefab", Items.Plant); AddMinionComponent("RoR2/Base/RoboBallBuddy/RoboBallGreenBuddyBody.prefab", Items.RoboBallBuddy); AddMinionComponent("RoR2/Base/RoboBallBuddy/RoboBallRedBuddyBody.prefab", Items.RoboBallBuddy); AddMinionComponent("RoR2/DLC1/VoidJailer/VoidJailerAllyBody.prefab", Items.VoidMegaCrabItem); AddMinionComponent("RoR2/Base/Nullifier/NullifierAllyBody.prefab", Items.VoidMegaCrabItem); AddMinionComponent("RoR2/DLC1/VoidMegaCrab/VoidMegaCrabAllyBody.prefab", Items.VoidMegaCrabItem); AddMinionComponent("RoR2/Base/BeetleGland/BeetleGuardAllyBody.prefab", Items.BeetleGland); AddMinionComponent("RoR2/Base/Squid/SquidTurretBody.prefab", Items.Squid); AddMinionComponent("RoR2/DLC1/MajorAndMinorConstruct/MinorConstructOnKillBody.prefab", Items.MinorConstructOnKill); AddMinionComponent("RoR2/Base/Titan/TitanGoldBody.prefab", Items.TitanGoldDuringTP); AddMinionComponent("RoR2/Base/Drones/BackupDroneBody.prefab", Equipment.DroneBackup); Utilities.AddressableAddComp<ProjectileBehaviour>("RoR2/Base/Nullifier/NullifierDeathBombProjectile.prefab", (Action<ProjectileBehaviour>)delegate(ProjectileBehaviour a) { a.projectile = ProjectileBehaviour.Projectile.Zoea; }); Utilities.AddressableAddComp<ProjectileBehaviour>("RoR2/DLC1/VoidJailer/VoidJailerDeathBombProjectile.prefab", (Action<ProjectileBehaviour>)delegate(ProjectileBehaviour a) { a.projectile = ProjectileBehaviour.Projectile.Zoea; }); Utilities.AddressableAddComp<ProjectileBehaviour>("RoR2/DLC1/VoidMegaCrab/VoidMegaCrabDeathBombProjectile.prefab", (Action<ProjectileBehaviour>)delegate(ProjectileBehaviour a) { a.projectile = ProjectileBehaviour.Projectile.ZoeaDeathBomblet; }); Utilities.AddressableAddComp<ProjectileBehaviour>("RoR2/DLC1/VoidMegaCrab/VoidMegaCrabDeathBombletsProjectile.prefab", (Action<ProjectileBehaviour>)delegate(ProjectileBehaviour a) { a.projectile = ProjectileBehaviour.Projectile.Zoea; }); AddProcComponent("RoR2/Base/Saw/Sawmerang.prefab", Equipment.Saw); AddProcComponent("RoR2/Base/GoldGat/GoldGatController.prefab", Equipment.GoldGat); AddProcComponent("RoR2/Base/BFG/BeamSphere.prefab", Equipment.BFG); AddProcComponent("RoR2/DLC1/Molotov/MolotovClusterProjectile.prefab", Equipment.Molotov); AddProcComponent("RoR2/DLC1/Molotov/MolotovSingleProjectile.prefab", Equipment.Molotov); AddProcComponent("RoR2/DLC1/Molotov/MolotovProjectileDotZone.prefab", Equipment.Molotov); AddProcComponent("RoR2/Base/Mage/MageFireboltBasic.prefab", (SkillSlot)0); AddProcComponent("RoR2/Base/Mage/MageLightningboltBasic.prefab", (SkillSlot)0); AddProcComponent("RoR2/Base/Mage/MageIceBombProjectile.prefab", (SkillSlot)1); AddProcComponent("RoR2/Base/Mage/MageLightningBombProjectile.prefab", (SkillSlot)1); AddProcComponent("RoR2/Base/Mage/MageIcewallPillarProjectile.prefab", (SkillSlot)2); AddProcComponent("RoR2/Base/Merc/EvisProjectile.prefab", (SkillSlot)3); AddProcComponent("RoR2/Base/Merc/EvisOverlapProjectile.prefab", (SkillSlot)3); AddProcComponent("RoR2/Base/Commando/FMJRamping.prefab", (SkillSlot)1); AddProcComponent("RoR2/Base/Commando/CommandoGrenadeProjectile.prefab", (SkillSlot)3); AddProcComponent("RoR2/Base/Captain/CaptainAirstrikeProjectile1.prefab", (SkillSlot)2); AddProcComponent("RoR2/Base/Captain/CaptainAirstrikeAltProjectile.prefab", (SkillSlot)2); AddProcComponent("RoR2/Base/Captain/CaptainSupplyDrop, Base.prefab", (SkillSlot)3); AddProcComponent("RoR2/Base/Captain/CaptainSupplyDrop, EquipmentRestock.prefab", (SkillSlot)3); AddProcComponent("RoR2/Base/Captain/CaptainSupplyDrop, Hacking.prefab", (SkillSlot)3); AddProcComponent("RoR2/Base/Captain/CaptainSupplyDrop, Healing.prefab", (SkillSlot)3); AddProcComponent("RoR2/Base/Captain/CaptainSupplyDrop, Shocking.prefab", (SkillSlot)3); AddProcComponent("RoR2/Base/Captain/CaptainTazer.prefab", (SkillSlot)1); AddProcComponent("RoR2/Base/Huntress/HuntressArrowRain.prefab", (SkillSlot)3); AddProcComponent("RoR2/Base/Loader/LoaderYankHook.prefab", (SkillSlot)1); AddProcComponent("RoR2/Base/Loader/LoaderZapCone.prefab", (SkillSlot)2); AddProcComponent("RoR2/Base/Loader/LoaderPylon.prefab", (SkillSlot)3); AddProcComponent("RoR2/Base/Engi/EngiGrenadeProjectile.prefab", (SkillSlot)0); AddProcComponent("RoR2/Base/Engi/EngiHarpoon.prefab", (SkillSlot)2); AddMinionComponent("RoR2/Base/Engi/EngiTurretBody.prefab", (SkillSlot)3); AddMinionComponent("RoR2/Base/Engi/EngiWalkerTurretBody.prefab", (SkillSlot)3); AddProcComponent("RoR2/Base/Croco/CrocoSpit.prefab", (SkillSlot)1); AddProcComponent("RoR2/Base/Croco/CrocoLeapAcid.prefab", (SkillSlot)2); AddProcComponent("RoR2/Base/Croco/CrocoDiseaseProjectile.prefab", (SkillSlot)3); AddProcComponent("RoR2/Base/Toolbot/ToolbotGrenadeLauncherProjectile.prefab", (SkillSlot)0); Utilities.DoAddressable("RoR2/Base/Toolbot/ToolbotGrenadeLauncherProjectile.prefab", delegate(GameObject a) { a.AddComponent<ProjectileBehaviour>().projectile = ProjectileBehaviour.Projectile.ScrapLauncher; }); AddProcComponent("RoR2/Base/Toolbot/CryoCanisterProjectile.prefab", (SkillSlot)1); AddProcComponent("RoR2/Base/Toolbot/CryoCanisterBombletsProjectile.prefab", (SkillSlot)1); AddProcComponent("RoR2/Base/Bandit2/Bandit2ShivProjectile.prefab", (SkillSlot)1); AddProcComponent("RoR2/DLC1/Railgunner/RailgunnerPistolProjectile.prefab", (SkillSlot)0); AddProcComponent("RoR2/Base/Treebot/SyringeProjectile.prefab", (SkillSlot)0); AddProcComponent("RoR2/Base/Treebot/SyringeProjectileHealing.prefab", (SkillSlot)0); AddProcComponent("RoR2/Base/Treebot/TreebotMortar2.prefab", (SkillSlot)1); AddProcComponent("RoR2/Base/Treebot/TreebotMortarRain.prefab", (SkillSlot)1); AddProcComponent("RoR2/Base/Treebot/TreebotFlowerSeed.prefab", (SkillSlot)3); AddProcComponent("RoR2/Base/Treebot/TreebotFruitSeedProjectile.prefab", (SkillSlot)3); Utilities.DoAddressable<GameObject>("RoR2/Base/Treebot/TreebotFruitPack.prefab", (Action<GameObject>)delegate(GameObject a) { ((Component)a.GetComponentInChildren<HealthPickup>()).gameObject.AddComponent<ProcComponent>().index = (SkillSlot)3; }); AddProcComponent("RoR2/DLC1/VoidSurvivor/VoidSurvivorMegaBlasterSmallProjectile.prefab", (SkillSlot)1); AddProcComponent("RoR2/DLC1/VoidSurvivor/VoidSurvivorMegaBlasterBigProjectile.prefab", (SkillSlot)1); AddProcComponent("RoR2/DLC1/VoidSurvivor/VoidSurvivorMegaBlasterBigProjectileCorrupted.prefab", (SkillSlot)1); AddProcComponent("RoR2/Base/LunarSkillReplacements/LunarNeedleProjectile.prefab", (SkillSlot)0); AddProcComponent("RoR2/Base/LunarSkillReplacements/LunarSecondaryProjectile.prefab", (SkillSlot)1); AddProcComponent("RoR2/DLC2/Seeker/SpiritPunchProjectile.prefab", (SkillSlot)0); AddProcComponent("RoR2/DLC2/Seeker/SpiritPunchFinisherProjectile.prefab", (SkillSlot)0); AddProcComponent("RoR2/DLC2/Seeker/SoulSpiralProjectile.prefab", (SkillSlot)1); AddProcComponent("RoR2/DLC2/Seeker/UnseenHandMovingProjectile.prefab", (SkillSlot)1); AddProcComponent("RoR2/DLC2/Seeker/SojournVehicle/SojournVehicle.prefab", (SkillSlot)2); AddProcComponent("RoR2/DLC2/FalseSon/LunarSpike.prefab", (SkillSlot)1); AddProcComponent("RoR2/DLC2/Chef/ChefCleaver.prefab", (SkillSlot)0); AddProcComponent("RoR2/DLC2/Chef/ChefDiceEnhanced.prefab", (SkillSlot)3); AddProcComponent("RoR2/DLC2/Chef/BoostedSearFireballProjectile.prefab", (SkillSlot)3); AddProcComponent("RoR2/DLC2/Chef/BoostedRolyPolyProjectile.prefab", (SkillSlot)3); AddProcComponent("RoR2/DLC2/Chef/ChefGlazeProjectile.prefab", (SkillSlot)3); Utilities.DoAddressable("RoR2/Base/Common/MissileProjectile.prefab", DoMissilePrefab); Utilities.DoAddressable("RoR2/Base/EliteLightning/LightningStake.prefab", DoOverloadingPrefab); Utilities.DoAddressable("RoR2/Base/Common/FireTrail.prefab", DoBlazingTrailPrefab); AddMeleeConfigIndexies(Addressables.LoadAssetsAsync<EntityStateConfiguration>((IEnumerable)new string[11] { "RoR2/Base/Bandit2/EntityStates.Bandit2.Weapon.SlashBlade.asset", "RoR2/Base/Croco/EntityStates.Croco.Bite.asset", "RoR2/Base/Croco/EntityStates.Croco.Slash.asset", "RoR2/DLC2/FalseSon/EntityStates.FalseSon.ClubSwing.asset", "RoR2/DLC2/FalseSon/EntityStates.FalseSon.ClubSwing2.asset", "RoR2/DLC2/FalseSon/EntityStates.FalseSon.OverheadClubSwing.asset", "RoR2/Base/Loader/EntityStates.Loader.SwingChargedFist.asset", "RoR2/Base/Loader/EntityStates.Loader.SwingComboFist.asset", "RoR2/Base/Loader/EntityStates.Loader.SwingZapFist.asset", "RoR2/Base/Merc/EntityStates.Merc.Assaulter2.asset", "RoR2/Base/Merc/EntityStates.Merc.Weapon.GroundLight2.asset" }, (Action<EntityStateConfiguration>)null, (MergeMode)1, false).WaitForCompletion()); } private static void AddMeleeConfigIndexies(IList<EntityStateConfiguration> list) { FieldInfo field = typeof(BasicMeleeAttack).GetField("meleeInflictorIndex"); foreach (EntityStateConfiguration item in list) { Index index = ((Object)item).name switch { "EntityStates.Bandit2.Weapon.SlashBlade" => (SkillSlot)1, "EntityStates.Croco.Bite" => (SkillSlot)1, "EntityStates.Croco.Slash" => (SkillSlot)0, "EntityStates.FalseSon.ClubSwing" => (SkillSlot)0, "EntityStates.FalseSon.ClubSwing2" => (SkillSlot)0, "EntityStates.FalseSon.OverheadClubSwing" => (SkillSlot)0, "EntityStates.Loader.SwingChargedFist" => (SkillSlot)2, "EntityStates.Loader.SwingComboFist" => (SkillSlot)0, "EntityStates.Loader.SwingZapFist" => (SkillSlot)2, "EntityStates.Merc.Assaulter2" => (SkillSlot)2, "EntityStates.Merc.Weapon.GroundLight2" => (SkillSlot)0, _ => default(Index), }; if (index.isNotNone) { ((SerializedValue)(ref ((SerializedFieldCollection)(ref item.serializedFieldsCollection)).GetOrCreateField("meleeInflictorIndex").fieldValue)).SetValue(field, (object)index); } else { log.error("Failed to add melee index to " + ((Object)item).name); } } } private static void AddProcComponent(string addressable, Index index) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) AsyncOperationHandle<GameObject> val = Addressables.LoadAssetAsync<GameObject>((object)addressable); val.Completed += delegate(AsyncOperationHandle<GameObject> a) { a.Result.AddComponent<ProcComponent>().index = index; }; } private static void AddMinionComponent(string addressable, Index index) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) AsyncOperationHandle<GameObject> val = Addressables.LoadAssetAsync<GameObject>((object)addressable); val.Completed += delegate(AsyncOperationHandle<GameObject> a) { a.Result.AddComponent<MinionComponent>().index = index; }; } private static void DoMissilePrefab(GameObject missilePrefab) { missileLauncher = Utilities.CreatePrefab(missilePrefab, "DisposableMissileProjectile"); missileLauncher.AddComponent<ProcComponent>().index = Equipment.CommandMissile; CommonAssets.missilePrefab = Utilities.CreatePrefab(missilePrefab, "ATGMissileProjectile"); CommonAssets.missilePrefab.AddComponent<ProcComponent>().index = Items.Missile; } private static void DoOverloadingPrefab(GameObject orbPrefab) { overloadingHeadhunter = Utilities.CreatePrefab(orbPrefab); overloadingHeadhunter.AddComponent<ProcComponent>().index = Items.HeadHunter; orbPrefab.AddComponent<ProcComponent>().index = Equipment.AffixBlue; } private static void DoBlazingTrailPrefab(GameObject trailPrefab) { fireTrailHeadhunter = Utilities.CreatePrefab(trailPrefab); fireTrailHeadhunter.AddComponent<ProcComponent>().index = Items.HeadHunter; trailPrefab.AddComponent<ProcComponent>().index = Equipment.AffixRed; } private void CollectLanguageRootFolders(List<string> list) { list.Add(Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "Language")); } } public class ProcChain { public Index value; public ProcChain parent; public ProcChain(Index value, ProcChain parent) { this.value = value; this.parent = parent; } public override string ToString() { string text = value.ToString(); for (ProcChain procChain = parent; procChain != null; procChain = procChain.parent) { string text2 = text; Index index = procChain.value; text = text2 + " -> " + index.ToString(); } return text; } } [Serializable] public struct Totals { public static float allDamageDealt; public float damageDealt; public float minionDamageDealt; public float damageTaken; public float healed; public uint goldEarned; } public class TrackedDef { public const string tooltipPrefix = "ITEMSTATISTICS_TOOLTIPS_"; public static readonly string damageTooltip = "ITEMSTATISTICS_TOOLTIPS_DAMAGE"; public static readonly string chanceTooltip = "ITEMSTATISTICS_TOOLTIPS_CHANCE"; public static readonly string countTooltip = "ITEMSTATISTICS_TOOLTIPS_COUNT"; public static readonly string healTooltip = "ITEMSTATISTICS_TOOLTIPS_HEAL"; public static readonly string goldTooltip = "ITEMSTATISTICS_TOOLTIPS_GOLD"; public static readonly string reductionTooltip = "ITEMSTATISTICS_TOOLTIPS_REDUCTION"; public static readonly string portionTooltip = "ITEMSTATISTICS_TOOLTIPS_DAMAGEPORTION"; public static readonly string recycledTooltip = "ITEMSTATISTICS_TOOLTIPS_RECYCLED"; public static readonly string barrierGainedTooltip = "ITEMSTATISTICS_TOOLTIPS_BARRIERGAINED"; public static readonly string globalPortionTooltip = "ITEMSTATISTICS_TOOLTIPS_GLOBALPORTION"; public static readonly string minionPortionTooltip = "ITEMSTATISTICS_TOOLTIPS_MINIONPORTION"; public static readonly string regenPortionTooltip = "ITEMSTATISTICS_TOOLTIPS_REGENPORTION"; public static readonly string barrierBlockedTooltip = "ITEMSTATISTICS_TOOLTIPS_BARRIERBLOCKED"; public static readonly string chance_barrierTooltip = "ITEMSTATISTICS_TOOLTIPS_CHANCE_BARRIER"; public static readonly string chance_healedTooltip = "ITEMSTATISTICS_TOOLTIPS_CHANCE_HEALED"; public static readonly string chance_damageTooltip = "ITEMSTATISTICS_TOOLTIPS_CHANCE_DAMAGE"; public static readonly string hit_damageTooltip = "ITEMSTATISTICS_TOOLTIPS_HIT_DAMAGE"; public static readonly string count_chanceTooltip = "ITEMSTATISTICS_TOOLTIPS_COUNT_CHANCE"; public static readonly string reduction_countTooltip = "ITEMSTATISTICS_TOOLTIPS_REDUCTION_COUNT"; public static readonly TrackedDef ArmorCount = new TrackedDef(typeof(ArmorCountTracker), reduction_countTooltip); public static readonly TrackedDef Armor = new TrackedDef(typeof(ArmorTracker), reductionTooltip); public static readonly TrackedDef Chance = new TrackedDef(typeof(ChanceTracker), count_chanceTooltip); public static readonly TrackedDef Count = new TrackedDef(typeof(CountTracker), countTooltip); public static readonly TrackedDef DamageChance = new TrackedDef(typeof(DamageChanceTracker), chance_damageTooltip); public static readonly TrackedDef DamagePortion = new TrackedDef(typeof(DamageTracker), portionTooltip); public static readonly TrackedDef Damage = new TrackedDef(typeof(DamageTracker), damageTooltip); public static readonly TrackedDef Gold = new TrackedDef(typeof(GoldTracker), goldTooltip); public static readonly TrackedDef Heal = new TrackedDef(typeof(HealTracker), healTooltip); public static readonly TrackedDef Watch = new TrackedDef(typeof(WatchTracker), damageTooltip); public static readonly TrackedDef Skill = new TrackedDef(typeof(SkillTracker), null); private readonly Type trackerType; private readonly string tooltipToken; public TrackedDef(Type trackerType, string tooltipToken) { if (typeof(ITracker).IsAssignableFrom(trackerType)) { this.trackerType = trackerType; this.tooltipToken = tooltipToken; } else { log.error(trackerType?.ToString() + " is not a valid tracker type"); } } public string GetTooltip(ITracker tracker, in Totals totals) { string[] tooltipArgs = tracker.GetTooltipArgs(in totals); if (tooltipArgs == null) { return ""; } if (tooltipToken == null) { return string.Concat(tooltipArgs); } string text = tooltipToken; object[] array = tooltipArgs; return Language.GetStringFormatted(text, array); } internal ITracker CreateTracker() { return (ITracker)Activator.CreateInstance(trackerType); } } } namespace ItemStatistics.Trackers { public class ArmorCountTracker : ITracker, IReductionTracker, IChanceTracker { private float globalDamageTakenWhenSet; private float damageBlocked; private uint attempted; private uint succedded; public int itemCount { get; set; } public bool dirtyBit { get; set; } public void Attempted() { log.warning("Called Attempted on ArmorChanceTracker"); } public void Succedded() { succedded++; dirtyBit = true; } public void AddBlockedDamage(float blocked) { damageBlocked += blocked; dirtyBit = true; } string[] ITracker.GetTooltipArgs(in Totals totals) { return new string[2] { TrackerStatics.ReductionToString(damageBlocked, totals.damageTaken - globalDamageTakenWhenSet), succedded.ToString() }; } void ITracker.Reset(in Totals totals) { attempted = 0u; succedded = 0u; damageBlocked = 0f; globalDamageTakenWhenSet = totals.damageTaken; } void ITracker.Serialize(SerializationBuffer data) { data.Add(attempted); data.Add(succedded); data.Add(damageBlocked); } void ITracker.Deserialize(SerializationBuffer data) { attempted = data.nextInt; succedded = data.nextInt; damageBlocked = data.nextFloat; } } public class ArmorTracker : ITracker, IReductionTracker { private float globalDamageTakenWhenSet; private float damageBlocked; public int itemCount { get; set; } public bool dirtyBit { get; set; } public void AddBlockedDamage(float blocked) { damageBlocked += blocked; dirtyBit = true; } string[] ITracker.GetTooltipArgs(in Totals totals) { return new string[2] { TrackerStatics.ReductionToString(damageBlocked, totals.damageTaken - globalDamageTakenWhenSet), TrackerStatics.PortionToString(damageBlocked, totals.damageTaken - globalDamageTakenWhenSet) }; } void ITracker.Reset(in Totals totals) { damageBlocked = 0f; globalDamageTakenWhenSet = totals.damageTaken; } void ITracker.Serialize(SerializationBuffer data) { data.Add(damageBlocked); } void ITracker.Deserialize(SerializationBuffer data) { damageBlocked = data.nextFloat; } } public class ChanceTracker : ITracker, IChanceTracker { private uint attempted; private uint succedded; public int itemCount { get; set; } public bool dirtyBit { get; set; } public void Attempted() { attempted++; dirtyBit = true; } public void Succedded() { succedded++; dirtyBit = true; } string[] ITracker.GetTooltipArgs(in Totals totals) { return new string[2] { succedded.ToString(), TrackerStatics.ChanceToString(attempted, succedded) }; } void ITracker.Reset(in Totals totals) { attempted = 0u; succedded = 0u; } void ITracker.Serialize(SerializationBuffer data) { data.Add(attempted); data.Add(succedded); } void ITracker.Deserialize(SerializationBuffer data) { attempted = data.nextInt; succedded = data.nextInt; } } public class CountTracker : ITracker, IChanceTracker { private uint succedded; public int itemCount { get; set; } public bool dirtyBit { get; set; } public void Attempted() { log.warning("Called Attempted on CountTracker"); } public void Succedded() { succedded++; dirtyBit = true; } string[] ITracker.GetTooltipArgs(in Totals totals) { return new string[1] { succedded.ToString() }; } void ITracker.Reset(in Totals totals) { succedded = 0u; } void ITracker.Serialize(SerializationBuffer data) { data.Add(succedded); } void ITracker.Deserialize(SerializationBuffer data) { succedded = data.nextInt; } } public class DamageChanceTracker : ITracker, IChanceTracker, IDamageTracker { private uint attempted; private uint succedded; private float globalDamageWhenSet; private float itemDamage; public int itemCount { get; set; } public bool dirtyBit { get; set; } public void Attempted() { attempted++; dirtyBit = true; } public void Succedded() { succedded++; dirtyBit = true; } public void AddDamage(float damage) { itemDamage += damage; dirtyBit = true; } string[] ITracker.GetTooltipArgs(in Totals totals) { return new string[2] { TrackerStatics.ChanceToString(attempted, succedded), TrackerStatics.IncreaseToString(itemDamage, totals.damageDealt - globalDamageWhenSet) }; } void ITracker.Reset(in Totals totals) { attempted = 0u; succedded = 0u; itemDamage = 0f; globalDamageWhenSet = totals.damageDealt; } void ITracker.Serialize(SerializationBuffer data) { data.Add(attempted); data.Add(succedded); data.Add(itemDamage); } void ITracker.Deserialize(SerializationBuffer data) { attempted = data.nextInt; succedded = data.nextInt; itemDamage = data.nextFloat; } } public class DamageTracker : ITracker, IDamageTracker { internal float globalDamageWhenSet; internal float itemDamage; public int itemCount { get; set; } public bool dirtyBit { get; set; } public void AddDamage(float damage) { itemDamage += damage; dirtyBit = true; } string[] ITracker.GetTooltipArgs(in Totals totals) { return new string[2] { TrackerStatics.IncreaseToString(itemDamage, totals.damageDealt - globalDamageWhenSet), TrackerStatics.PortionToString(itemDamage, totals.damageDealt - globalDamageWhenSet) }; } public virtual void Reset(in Totals totals) { itemDamage = 0f; globalDamageWhenSet = totals.damageDealt; } public virtual void Serialize(SerializationBuffer data) { data.Add(itemDamage); } public virtual void Deserialize(SerializationBuffer data) { itemDamage = data.nextFloat; } } public class GoldTracker : ITracker { private float globalEarnedWhenSet; private float itemEarned; public int itemCount { get; set; } public bool dirtyBit { get; set; } public void AddGold(float gold) { itemEarned += gold; dirtyBit = true; } string[] ITracker.GetTooltipArgs(in Totals totals) { return new string[1] { TrackerStatics.IncreaseToString(itemEarned, (float)totals.goldEarned - globalEarnedWhenSet) }; } void ITracker.Reset(in Totals totals) { itemEarned = 0f; globalEarnedWhenSet = totals.goldEarned; } void ITracker.Serialize(SerializationBuffer data) { data.Add(itemEarned); } void ITracker.Deserialize(SerializationBuffer data) { itemEarned = data.nextFloat; } } public class HealChanceTracker : ITracker, IChanceTracker, IHealTracker { private uint attempted; private uint succedded; private float itemHealed; private float globalHealedWhenSet; public int itemCount { get; set; } public bool dirtyBit { get; set; } public void Attempted() { attempted++; dirtyBit = true; } public void Succedded() { succedded++; dirtyBit = true; } public void AddHealing(float heal) { itemHealed += heal; dirtyBit = true; } string[] ITracker.GetTooltipArgs(in Totals totals) { return new string[3] { TrackerStatics.ChanceToString(attempted, succedded), TrackerStatics.PortionToString(itemHealed, totals.healed - globalHealedWhenSet), itemHealed.ToString("0") }; } void ITracker.Reset(in Totals totals) { attempted = 0u; succedded = 0u; itemHealed = 0f; globalHealedWhenSet = totals.healed; } void ITracker.Serialize(SerializationBuffer data) { data.Add(attempted); data.Add(succedded); data.Add(itemHealed); } void ITracker.Deserialize(SerializationBuffer data) { attempted = data.nextInt; succedded = data.nextInt; itemHealed = data.nextFloat; } } public class HealTracker : ITracker, IHealTracker { private float itemHealed; private float globalHealedWhenSet; public int itemCount { get; set; } public bool dirtyBit { get; set; } public void AddHealing(float heal) { itemHealed += heal; dirtyBit = true; } string[] ITracker.GetTooltipArgs(in Totals totals) { return new string[2] { TrackerStatics.PortionToString(itemHealed, totals.healed - globalHealedWhenSet), itemHealed.ToString("0") }; } void ITracker.Reset(in Totals totals) { itemHealed = 0f; globalHealedWhenSet = totals.healed; } void ITracker.Serialize(SerializationBuffer data) { data.Add(itemHealed); } void ITracker.Deserialize(SerializationBuffer data) { itemHealed = data.nextFloat; } } public interface IChanceTracker { void Attempted(); void Succedded(); } public interface IDamageTracker { void AddDamage(float damage); } public interface IHealTracker { void AddHealing(float heal); } public interface IReductionTracker { void AddBlockedDamage(float blocked); } public interface ITracker { int itemCount { get; set; } bool dirtyBit { get; set; } string[] GetTooltipArgs(in Totals totals); void Reset(in Totals totals); void Serialize(SerializationBuffer data); void Deserialize(SerializationBuffer data); } public class SkillTracker : ITracker, IDamageTracker, IHealTracker { private float itemDamage; private float itemHealed; private float globalDamageWhenSet; private float globalHealedWhenSet; public int itemCount { get; set; } public bool dirtyBit { get; set; } public void AddDamage(float damage) { itemDamage += damage; dirtyBit = true; } public void AddHealing(float heal) { itemHealed += heal; dirtyBit = true; } string[] ITracker.GetTooltipArgs(in Totals totals) { bool flag = itemDamage != 0f; bool flag2 = itemHealed != 0f; string text = null; if (flag) { text = Language.GetStringFormatted(TrackedDef.portionTooltip, new object[2] { null, TrackerStatics.PortionToString(itemDamage, totals.damageDealt - globalDamageWhenSet) }); } if (flag2) { if (flag) { text += "\n"; } text += Language.GetStringFormatted(TrackedDef.healTooltip, new object[2] { TrackerStatics.PortionToString(itemHealed, totals.healed - globalHealedWhenSet), null }); } if (text != null) { return new string[1] { text }; } return null; } void ITracker.Reset(in Totals totals) { itemDamage = 0f; itemHealed = 0f; globalDamageWhenSet = totals.damageDealt; globalHealedWhenSet = totals.healed; } void ITracker.Serialize(SerializationBuffer data) { data.Add(itemDamage); data.Add(itemHealed); } void ITracker.Deserialize(SerializationBuffer data) { itemDamage = data.nextFloat; itemHealed = data.nextFloat; } } public static class TrackerStatics { public static string IncreaseToString(float localNum, float totalNum) { if (totalNum == 0f) { return "NaN"; } if (localNum >= 0.999999f * totalNum) { return "Max"; } if (localNum < 0f) { return (100f * localNum / totalNum).ToString("f0") + "%"; } return (100f / (1f - localNum / totalNum) - 100f).ToString("f0") + "%"; } public static string ChanceToString(uint attempted, uint succedded) { if (attempted == 0) { return "NaN"; } float num = 100f * (float)succedded / (float)attempted; return num.ToString((num < 10f) ? "f1" : "f0") + "%"; } public static string ReductionToString(float localNum, float totalNum) { if (totalNum == 0f) { if (!(localNum > 0f)) { return "NaN"; } return "100%"; } if (localNum <= -0.999999f * totalNum) { return "Min"; } return (100f - 100f / (1f + localNum / totalNum)).ToString("f0") + "%"; } public static string PortionToString(float localNum, float totalNum) { if (totalNum == 0f) { return "NaN"; } return (100f * localNum / totalNum).ToString("f0") + "%"; } internal static void LogInvalid(Index index, ITracker tracker, string requiredTracker, [CallerMemberName] string caller = "") { log.error($"Invalid call '{caller}' on {index} ({tracker}). Has to be a {requiredTracker} tracker"); } } public class WatchTracker : DamageTracker { private bool globalset; public void AddBrokenDamage(DamageTracker notBrokenWatchTracker) { AddDamage(notBrokenWatchTracker.itemDamage); if (!globalset) { globalDamageWhenSet = notBrokenWatchTracker.globalDamageWhenSet; globalset = true; } } public override void Reset(in Totals totals) { base.Reset(in totals); globalset = false; } public override void Serialize(SerializationBuffer data) { base.Serialize(data); data.Add(globalDamageWhenSet); } public override void Deserialize(SerializationBuffer data) { base.Deserialize(data); globalDamageWhenSet = data.nextFloat; } } } namespace ItemStatistics.Networking { public struct DamageMessage { private Index inflictorIndex; internal DamageInfo damageInfo; public DamageMessage(DamageInfo damageInfo, Index inflictorIndex) { this.inflictorIndex = inflictorIndex; this.damageInfo = damageInfo; } public DamageMessage(in BlastAttackDamageInfo blastAttack, Index inflictorIndex) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0019: 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_0031: Unknown result type (might be due to invalid IL or missing references) //IL_003d: 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) //IL_0044: 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_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: 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_0061: 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_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0079: 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_0080: 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_0096: Expected O, but got Unknown //IL_009d: Unknown result type (might be due to invalid IL or missing references) this.inflictorIndex = inflictorIndex; damageInfo = new DamageInfo { attacker = blastAttack.attacker, inflictor = blastAttack.inflictor, damage = blastAttack.damage, crit = blastAttack.crit, force = blastAttack.force, procChainMask = blastAttack.procChainMask, procCoefficient = blastAttack.procCoefficient, damageType = blastAttack.damageType, damageColorIndex = blastAttack.damageColorIndex, position = blastAttack.position, canRejectForce = blastAttack.canRejectForce }; damageInfo.ModifyDamageInfo(blastAttack.damageModifier); } internal static void Serialize(NetworkWriter writer, DamageMessage value) { Index.Serialize(writer, value.inflictorIndex); NetworkExtensions.Write(writer, value.damageInfo); } internal static DamageMessage Deserialize(NetworkReader reader) { DamageMessage result = default(DamageMessage); result.inflictorIndex = Index.Deserialize(reader); result.damageInfo = NetworkExtensions.ReadDamageInfo(reader); result.damageInfo.inflictor = ProcComponent.CreateInflictor(result.inflictorIndex, null); return result; } } public static class NetworkHooks { private delegate void BlastAttack_ClientReportDamage(in BlastAttackDamageInfo blastAttack); public static Index inflictorIndex; public static bool shouldClientSendMessage { get { if (TrackModdedUsers.isModdedServer) { return inflictorIndex.isNotNone; } return false; } } internal static void Hook() { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Expected O, but got Unknown //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Expected O, but got Unknown //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Expected O, but got Unknown HookManager.Hook(MethodBase.GetMethodFromHandle((RuntimeMethodHandle)/*OpCode not supported: LdMemberToken*/), (Delegate)new <>A{00000018}<BlastAttack_ClientReportDamage, BlastAttackDamageInfo>(NetworkMessage_On_BlastAttack_ClientReportDamage)); HookManager.Hook(MethodBase.GetMethodFromHandle((RuntimeMethodHandle)/*OpCode not supported: LdMemberToken*/), new Manipulator(Inflictor_IL_BlastAttack_HandleHits)); HookManager.Hook(MethodBase.GetMethodFromHandle((RuntimeMethodHandle)/*OpCode not supported: LdMemberToken*/), new Manipulator(NetworkMessage_IL_BulletAttack_DefaultHitCallbackImplementation)); HookManager.Hook(MethodBase.GetMethodFromHandle((RuntimeMethodHandle)/*OpCode not supported: LdMemberToken*/), new Manipulator(Inflictor_IL_OverlapAttack_ProcessHits)); HookManager.Hook(MethodBase.GetMethodFromHandle((RuntimeMethodHandle)/*OpCode not supported: LdMemberToken*/), new Manipulator(SetInflictor_On_BasicMeleeAttack_AuthorityFireAttack)); } private static void NetworkMessage_On_BlastAttack_ClientReportDamage(BlastAttack_ClientReportDamage orig, in BlastAttackDamageInfo blastAttack) { if (!shouldClientSendMessage) { orig(in blastAttack); } else if (Object.op_Implicit((Object)(object)blastAttack.hitHealthComponent)) { TrackModdedUsers.localUser.CallCmdAttack(new DamageMessage(in blastAttack, inflictorIndex), ((Component)blastAttack.hitHealthComponent).gameObject, shouldHitProceed: true); } } private static void Inflictor_IL_BlastAttack_HandleHits(ILContext context) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0050: 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_007e: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(context); if (val.TryGotoNext(new Func<Instruction, bool>[1] { (Instruction a) => ILPatternMatchingExt.MatchCallOrCallvirt(a, typeof(BlastAttack), "PerformDamageServer") })) { val.Emit(OpCodes.Dup); val.Emit(OpCodes.Dup); val.Emit<BlastAttackDamageInfo>(OpCodes.Ldfld, "inflictor"); val.Emit(OpCodes.Call, (MethodBase)new Func<GameObject, GameObject>(ReplaceInflictor).Method); val.Emit<BlastAttackDamageInfo>(OpCodes.Stfld, "inflictor"); } else { val.LogErrorCaller("failed find"); } } private static void NetworkMessage_IL_BulletAttack_DefaultHitCallbackImplementation(ILContext context) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(context); int shouldHitIndex = 9; if (!val.TryGotoNext(new Func<Instruction, bool>[1] { (Instruction a) => ILPatternMatchingExt.MatchCallOrCallvirt(a, typeof(FriendlyFireManager), "ShouldDirectHitProceed") }) || !val.TryGotoNext(new Func<Instruction, bool>[1] { (Instruction a) => ILPatternMatchingExt.MatchStloc(a, ref shouldHitIndex) })) { val.LogErrorCaller("shouldHitIndex"); return; } int damageInfoIndex = 6; if (!val.TryGotoNext(new Func<Instruction, bool>[2] { (Instruction a) => ILPatternMatchingExt.MatchLdloc(a, ref damageInfoIndex), (Instruction a) => ILPatternMatchingExt.MatchCallOrCallvirt(a, typeof(HealthComponent), "TakeDamage") })) { val.LogErrorCaller("damageInfoIndex"); } else { int index = val.Index; val.Index = index + 1; val.Emit(OpCodes.Dup); val.EmitDelegate<Action<DamageInfo>>((Action<DamageInfo>)delegate(DamageInfo damageInfo) { if (inflictorIndex.isNotNone) { damageInfo.inflictor = ProcComponent.CreateInflictor(inflictorIndex, null); } }); } ILLabel branchSkip = null; if (val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[2] { (Instruction a) => ILPatternMatchingExt.MatchCallOrCallvirt(a, typeof(ClientScene), "get_ready"), (Instruction a) => ILPatternMatchingExt.MatchBrfalse(a, ref branchSkip) })) { Instruction next = val.Next; val.Emit(OpCodes.Call, (MethodBase)typeof(NetworkHooks).GetMethod("get_shouldClientSendMessage")); val.Emit(OpCodes.Brfalse, next); val.Emit(OpCodes.Ldarg, 1); val.Emit(OpCodes.Ldloc, damageInfoIndex); val.Emit(OpCodes.Ldloc, shouldHitIndex); val.EmitDelegate<<>A{00000001}<BulletHit, DamageInfo, bool>>((<>A{00000001}<BulletHit, DamageInfo, bool>)delegate(ref BulletHit hitInfo, DamageInfo damageInfo, bool shouldHit) { TrackModdedUsers.localUser.CallCmdAttack(new DamageMessage(damageInfo, inflictorIndex), Object.op_Implicit((Object)(object)hitInfo.hitHurtBox) ? ((Component)hitInfo.hitHurtBox.healthComponent).gameObject : null, shouldHit); }); val.Emit(OpCodes.Br, (object)branchSkip); } else { val.LogErrorCaller("Failed client IL"); } } private static void Inflictor_IL_OverlapAttack_ProcessHits(ILContext context) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0093: 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_00eb: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(context); if (val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1] { (Instruction a) => ILPatternMatchingExt.MatchLdfld(a, typeof(OverlapAttack), "inflictor") })) { val.Emit(OpCodes.Call, (MethodBase)new Func<GameObject, GameObject>(ReplaceInflictor).Method); } else { val.LogErrorCaller("inflictor"); } if (val.TryGotoNext(new Func<Instruction, bool>[1] { (Instruction a) => ILPatternMatchingExt.MatchLdsfld(a, typeof(PlatformSystems), "networkManager") })) { val.Emit(OpCodes.Call, (MethodBase)typeof(NetworkHooks).GetMethod("get_shouldClientSendMessage")); val.Emit(OpCodes.Brfalse, val.Next); val.EmitDelegate<Action>((Action)delegate { TrackModdedUsers.localUser.CallCmdOverlapAttack(new OverlapMessage(OverlapAttack.outgoingMessage, inflictorIndex)); }); val.Emit(OpCodes.Ret); } else { val.LogErrorCaller("Failed client IL"); } } private static void SetInflictor_On_BasicMeleeAttack_AuthorityFireAttack(ILContext context) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //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_0058: 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_00a8: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(context); if (val.TryGotoNext(new Func<Instruction, bool>[1] { (Instruction a) => ILPatternMatchingExt.MatchCallOrCallvirt(a, typeof(OverlapAttack), "Fire") })) { val.Emit(OpCodes.Ldarg_0); val.Emit<BasicMeleeAttack>(OpCodes.Ldfld, "meleeInflictorIndex"); val.Emit(OpCodes.Stsfld, typeof(NetworkHooks).GetField("inflictorIndex")); int index = val.Index; val.Index = index + 1; val.Emit(OpCodes.Ldsflda, typeof(NetworkHooks).GetField("inflictorIndex")); val.Emit(OpCodes.Initobj, typeof(Index)); } else { val.LogErrorCaller("inflictor"); } } private static GameObject ReplaceInflictor(GameObject inflictor) { if (inflictorIndex.isNotNone && (!Object.op_Implicit((Object)(object)inflictor) || !ProcComponent.inflictorToProc.ContainsKey(inflictor))) { return ProcComponent.CreateInflictor(inflictorIndex, null); } return inflictor; } } public struct OverlapMessage { private Index inflictorIndex; internal OverlapAttackMessage overlapAttack; public OverlapMessage(OverlapAttackMessage overlapAttack, Index inflictorIndex) { this.inflictorIndex = inflictorIndex; this.overlapAttack = overlapAttack; } internal static void Serialize(NetworkWriter writer, OverlapMessage value) { Index.Serialize(writer, value.inflictorIndex); ((MessageBase)value.overlapAttack).Serialize(writer); } internal static OverlapMessage Deserialize(NetworkReader reader) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown OverlapMessage result = default(OverlapMessage); result.inflictorIndex = Index.Deserialize(reader); result.overlapAttack = new OverlapAttackMessage(); ((MessageBase)result.overlapAttack).Deserialize(reader); result.overlapAttack.inflictor = ProcComponent.CreateInflictor(result.inflictorIndex, null); return result; } } public class SerializationBuffer : IEnumerable<Index>, IEnumerable { [StructLayout(LayoutKind.Explicit)] private struct IntFloat { [FieldOffset(0)] private float floatValue; [FieldOffset(0)] private uint intValue; internal static float IntToFloat(uint value) { IntFloat intFloat = default(IntFloat); intFloat.intValue = value; return intFloat.floatValue; } internal static uint FloatToInt(float value) { IntFloat intFloat = default(IntFloat); intFloat.floatValue = value; return intFloat.intValue; } } private static readonly SerializationBuffer staticBuffer = new SerializationBuffer(4u, 4u); private Index[] indexes; private uint[] bits; private uint indexSize; private uint bitsSize; private uint bitPos; public uint nextInt => bits[bitPos++]; public float nextFloat => IntFloat.IntToFloat(nextInt); public bool hasSomething => indexSize != 0; publ