Decompiled source of ItemStatistics v1.1.11
patchers/ItemStatisticsPatcher.dll
Decompiled 2 days 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; using Mono.Cecil.Cil; using Mono.Collections.Generic; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("ItemStatisticsPatcher")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.1.11.0")] [assembly: AssemblyInformationalVersion("1.1.11.0+501f7195a8c691d60d936bcfa7f346d8be7ea5d8")] [assembly: AssemblyProduct("ItemStatisticsPatcher")] [assembly: AssemblyTitle("ItemStatisticsPatcher")] [assembly: AssemblyVersion("1.1.11.0")] public static class Patcher { private static readonly ManualLogSource Log = Logger.CreateLogSource("ItemStatisticsPatcher"); public static IEnumerable<string> TargetDLLs { get; } = new string[1] { "RoR2.dll" }; public static void Patch(AssemblyDefinition assembly) { //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0063: 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 val2 = mainModule.ImportReference((TypeReference)(object)val.MainModule.GetType("ItemStatistics.ReverseTree")); GenericInstanceType val3 = new GenericInstanceType(mainModule.ImportReference(typeof(List<>))); val3.GenericArguments.Add(val2); TypeReference fieldType = mainModule.ImportReference((TypeReference)(object)val.MainModule.GetType("ItemStatistics.Index")); ModuleDefinition mainModule2 = AssemblyDefinition.ReadAssembly(Path.Combine(Paths.ManagedPath, "UnityEngine.CoreModule.dll")).MainModule; TypeReference fieldType2 = mainModule.ImportReference((TypeReference)(object)mainModule2.GetType("UnityEngine.GameObject")); AddField(mainModule.GetType("RoR2.DotController/DotStack"), val2, "dotStackTree"); AddField(mainModule.GetType("RoR2.DotController/PendingDamage"), (TypeReference)(object)val3, "pendingDotTreeList"); AddField(mainModule.GetType("RoR2.Orbs.GenericDamageOrb"), fieldType2, "inflictor"); AddField(mainModule.GetType("RoR2.Orbs.DevilOrb"), fieldType2, "inflictor"); AddField(mainModule.GetType("RoR2.Orbs.BounceOrb"), fieldType2, "inflictor"); AddField(mainModule.GetType("RoR2.Orbs.LunarDetonatorOrb"), fieldType2, "inflictor"); AddField(mainModule.GetType("RoR2.Orbs.HealOrb"), fieldType, "inflictor"); AddField(mainModule.GetType("EntityStates.FrozenState"), fieldType, "freezeInflictor"); AddField(mainModule.GetType("EntityStates.FrozenState"), (TypeReference)(object)mainModule.GetType("RoR2.CharacterMaster"), "freezeInflictorMaster"); TypeDefinition type = mainModule.GetType("EntityStates.BasicMeleeAttack"); AddOverrideMethod(mainModule, mainModule.GetType("EntityStates.Loader.SwingComboFist"), type, "AuthorityModifyOverlapAttack", (MethodAttributes)4); AddOverrideMethod(mainModule, mainModule.GetType("EntityStates.FalseSon.ClubSwing"), type, "AuthorityModifyOverlapAttack", (MethodAttributes)4); AddOverrideMethod(mainModule, mainModule.GetType("EntityStates.FalseSon.OverheadClubSwing"), type, "AuthorityModifyOverlapAttack", (MethodAttributes)4); } private static void AddOverrideMethod(ModuleDefinition module, TypeDefinition typeToAddTo, TypeDefinition baseType, string methodName, MethodAttributes attributes) { //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Expected O, but got Unknown //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Expected O, but got Unknown //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) if (((IEnumerable<MethodDefinition>)typeToAddTo.Methods).FirstOrDefault((Func<MethodDefinition, bool>)((MethodDefinition a) => ((MemberReference)a).Name == methodName)) != null) { Log.LogWarning((object)(((MemberReference)typeToAddTo).Name + "." + methodName + " already exists")); return; } MethodDefinition val = ((IEnumerable<MethodDefinition>)baseType.Methods).FirstOrDefault((Func<MethodDefinition, bool>)((MethodDefinition m) => ((MemberReference)m).Name == methodName)); if (val == null) { Log.LogError((object)("Failed to find " + ((MemberReference)baseType).Name + "." + methodName)); return; } MethodDefinition val2 = new MethodDefinition(methodName, (MethodAttributes)(attributes | 0x40 | 0x80), module.ImportReference(((MethodReference)val).ReturnType)); Enumerator<ParameterDefinition> enumerator = ((MethodReference)val).Parameters.GetEnumerator(); try { while (enumerator.MoveNext()) { ParameterDefinition current = enumerator.Current; ((MethodReference)val2).Parameters.Add(new ParameterDefinition(((ParameterReference)current).Name, current.Attributes, module.ImportReference(((ParameterReference)current).ParameterType))); } } finally { ((IDisposable)enumerator).Dispose(); } ILProcessor iLProcessor = val2.Body.GetILProcessor(); iLProcessor.Append(iLProcessor.Create(OpCodes.Ldarg_0)); for (int i = 1; i <= ((MethodReference)val).Parameters.Count; i++) { iLProcessor.Append(iLProcessor.Create(OpCodes.Ldarg, i)); } iLProcessor.Append(iLProcessor.Create(OpCodes.Call, module.ImportReference((MethodReference)(object)val))); iLProcessor.Append(iLProcessor.Create(OpCodes.Ret)); val2.Overrides.Add((MethodReference)(object)val); typeToAddTo.Methods.Add(val2); } private static void AddField(TypeDefinition target, TypeReference fieldType, string fieldName) { //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Expected O, but got Unknown if (target == null || fieldType == null) { Log.LogError((object)("Null types in AddField: " + fieldName)); return; } 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; } FieldDefinition val = new FieldDefinition(fieldName, (FieldAttributes)6, fieldType); target.Fields.Add(val); } }
plugins/ItemStatistics.dll
Decompiled 2 days ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Linq.Expressions; using System.Reflection; 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 BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using Dolso; using Dolso.RiskofOptions; using EntityStates; using EntityStates.Bandit2; using EntityStates.Bandit2.Weapon; using EntityStates.Captain.Weapon; using EntityStates.CaptainDefenseMatrixItem; using EntityStates.Chef; using EntityStates.Commando.CommandoWeapon; using EntityStates.Croco; using EntityStates.Engi.Mine; using EntityStates.Engi.SpiderMine; using EntityStates.FalseSon; using EntityStates.GlobalSkills.LunarDetonator; using EntityStates.GummyClone; using EntityStates.Headstompers; using EntityStates.Huntress.HuntressWeapon; using EntityStates.Huntress.Weapon; using EntityStates.Loader; using EntityStates.Mage; using EntityStates.Mage.Weapon; using EntityStates.Merc; using EntityStates.Merc.Weapon; using EntityStates.Railgunner.Weapon; using EntityStates.Seeker; using EntityStates.TeleporterHealNovaController; using EntityStates.Toolbot; using EntityStates.Treebot.TreebotFlower; using EntityStates.Treebot.Weapon; using EntityStates.VoidSurvivor.Weapon; using HG; using HG.GeneralSerializer; using HG.Reflection; using ItemStatistics; using ItemStatistics.Components; using ItemStatistics.Hooks; using ItemStatistics.Networking; using ItemStatistics.Trackers; using Magrider.Magrider; using Magrider.Magrider.SkillStates.Weapon; using Mono.Cecil; using Mono.Cecil.Cil; using MonoMod.Cil; using MonoMod.RuntimeDetour; 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+501f7195a8c691d60d936bcfa7f346d8be7ea5d8")] [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 debug(object data) { logger.LogDebug(data); } 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, [CallerMemberName] string callerName = "") { logger.LogError((object)string.Format($"ILCursor failure in {callerName}, skipping: {data}\n{c}")); } } internal static class HookManager { internal delegate bool ConfigEnabled<T>(ConfigEntry<T> configEntry); internal const BindingFlags allFlags = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; private static ILHookConfig ilHookConfig = new ILHookConfig { ManualApply = true }; private static HookConfig onHookConfig = new HookConfig { ManualApply = true }; private static readonly ConfigEnabled<bool> boolConfigEnabled = (ConfigEntry<bool> configEntry) => configEntry.Value; 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<T>(Expression<Action<T>> from, Manipulator ilHook) { HookInternal(((MethodCallExpression)from.Body).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<T>(Expression<Action<T>> from, Delegate onHook) { HookInternal(((MethodCallExpression)from.Body).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 onHook: {methodFrom.DeclaringType}.{methodFrom.Name} - {onHook.Name}\n{ex}"); } } internal static void HookConfig<T>(this ConfigEntry<T> configEntry, ConfigEnabled<T> enabled, Type typeFrom, string methodFrom, Manipulator ilHook) { configEntry.AddHookConfig(enabled, GetMethod(typeFrom, methodFrom), ilHook); } internal static void HookConfig<T>(this ConfigEntry<T> configEntry, ConfigEnabled<T> enabled, MethodBase methodFrom, Manipulator ilHook) { configEntry.AddHookConfig(enabled, methodFrom, ilHook); } internal static void HookConfig<T>(this ConfigEntry<T> configEntry, ConfigEnabled<T> enabled, Type typeFrom, string methodFrom, Delegate onHook) { configEntry.AddHookConfig(enabled, GetMethod(typeFrom, methodFrom), onHook.Method, onHook.Target); } internal static void HookConfig<T>(this ConfigEntry<T> configEntry, ConfigEnabled<T> enabled, MethodBase methodFrom, Delegate onHook) { configEntry.AddHookConfig(enabled, methodFrom, onHook.Method, onHook.Target); } internal static void HookConfig(this ConfigEntry<bool> configEntry, Type typeFrom, string methodFrom, Manipulator ilHook) { configEntry.AddHookConfig(boolConfigEnabled, GetMethod(typeFrom, methodFrom), ilHook); } internal static void HookConfig(this ConfigEntry<bool> configEntry, MethodBase methodFrom, Manipulator ilHook) { configEntry.AddHookConfig(boolConfigEnabled, methodFrom, ilHook); } internal static void HookConfig(this ConfigEntry<bool> configEntry, Type typeFrom, string methodFrom, Delegate onHook) { configEntry.AddHookConfig(boolConfigEnabled, GetMethod(typeFrom, methodFrom), onHook.Method, onHook.Target); } internal static void HookConfig(this ConfigEntry<bool> configEntry, MethodBase methodFrom, Delegate onHook) { configEntry.AddHookConfig(boolConfigEnabled, methodFrom, onHook.Method, onHook.Target); } private static void AddHookConfig<T>(this ConfigEntry<T> configEntry, ConfigEnabled<T> enabled, MethodBase methodFrom, Manipulator ilHook) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown if (methodFrom == null) { log.error("null MethodFrom for hook: " + ((Delegate)(object)ilHook).Method.Name); return; } try { configEntry.AddHookConfig(enabled, (IDetour)new ILHook(methodFrom, ilHook, ref ilHookConfig)); } catch (Exception ex) { log.error($"Failed to ilHook {methodFrom.DeclaringType}.{methodFrom.Name} - {((Delegate)(object)ilHook).Method.Name}\n{ex}"); } } private static void AddHookConfig<T>(this ConfigEntry<T> configEntry, ConfigEnabled<T> enabled, MethodBase methodFrom, MethodInfo onHook, object target) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown if (methodFrom == null) { log.error("null MethodFrom for hook: " + onHook.Name); return; } try { configEntry.AddHookConfig(enabled, (IDetour)new Hook(methodFrom, onHook, target, ref onHookConfig)); } catch (Exception ex) { log.error($"Failed to onHook {methodFrom.DeclaringType}.{methodFrom.Name} - {onHook.Name}\n{ex}"); } } private static void AddHookConfig<T>(this ConfigEntry<T> configEntry, ConfigEnabled<T> enabled, IDetour detour) { configEntry.SettingChanged += delegate(object sender, EventArgs args) { UpdateHook(detour, enabled(sender as ConfigEntry<T>)); }; if (enabled(configEntry)) { detour.Apply(); } } private static void UpdateHook(IDetour hook, bool enabled) { if (enabled) { if (!hook.IsApplied) { hook.Apply(); } } else if (hook.IsApplied) { hook.Undo(); } } internal static void PriorityFirst() { ilHookConfig.Before = new string[1] { "*" }; onHookConfig.Before = new string[1] { "*" }; } internal static void PriorityLast() { ilHookConfig.After = new string[1] { "*" }; onHookConfig.After = new string[1] { "*" }; } internal static void PriorityNormal() { ilHookConfig.Before = null; onHookConfig.Before = null; ilHookConfig.After = null; onHookConfig.After = null; } internal static IDetour ManualDetour(Type typeFrom, string methodFrom, Delegate onHook) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Expected O, but got Unknown try { return (IDetour)new Hook((MethodBase)GetMethod(typeFrom, methodFrom), onHook, ref onHookConfig); } catch (Exception ex) { log.error($"Failed to make onHook {typeFrom}.{methodFrom} - {onHook.Method.Name}\n{ex}"); } return null; } internal static MethodInfo GetMethod(Type typeFrom, string methodFrom) { if (typeFrom == null || methodFrom == null) { return null; } IEnumerable<MethodInfo> source = from predicate in typeFrom.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) where predicate.Name == methodFrom select predicate; if (source.Count() == 1) { return source.First(); } if (source.Count() == 0) { log.error($"Failed to find method: {typeFrom}.{methodFrom}"); } if (source.Count() > 1) { log.error($"{source.Count()} ambiguous matches found for: {typeFrom}.{methodFrom}"); } return null; } } internal static class Utilities { private static GameObject _prefabParent; internal static GameObject CreatePrefab(GameObject gameObject) { //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); } return Object.Instantiate<GameObject>(gameObject, _prefabParent.transform); } internal static GameObject CreatePrefab(GameObject gameObject, string name) { //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 obj = Object.Instantiate<GameObject>(gameObject, _prefabParent.transform); ((Object)obj).name = name; return obj; } 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 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 Obj GetAddressable<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).WaitForCompletion(); } internal static GameObject GetAddressable(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).WaitForCompletion(); } internal static void GetAddressable<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 GetAddressable(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 void SetStateConfigIndex(this EntityStateConfiguration stateConfig, string fieldName, string newValue) { ref SerializedField[] serializedFields = ref stateConfig.serializedFieldsCollection.serializedFields; for (int i = 0; i < serializedFields.Length; i++) { if (serializedFields[i].fieldName == fieldName) { serializedFields[i].fieldValue.stringValue = newValue; return; } } log.error("failed to find " + fieldName + " for " + ((Object)stateConfig).name); } internal static void SetStateConfigIndex(this EntityStateConfiguration stateConfig, string fieldName, Object newValue) { ref SerializedField[] serializedFields = ref stateConfig.serializedFieldsCollection.serializedFields; for (int i = 0; i < serializedFields.Length; i++) { if (serializedFields[i].fieldName == fieldName) { serializedFields[i].fieldValue.objectValue = 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; } internal static bool ContainsString(string source, string value) { return CultureInfo.InvariantCulture.CompareInfo.IndexOf(source, value, CompareOptions.IgnoreCase | CompareOptions.IgnoreSymbols) >= 0; } } } 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 AddBool(ConfigEntry<bool> 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 CheckBoxOption(entry, new CheckBoxConfig { description = ((ConfigEntryBase)(object)entry).DescWithDefault() })); } internal static void AddBool(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 AddBool(ConfigEntry<bool> entry, 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_001e: Expected O, but got Unknown //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(entry, new CheckBoxConfig { category = categoryName, description = ((ConfigEntryBase)(object)entry).DescWithDefault() })); } internal static void AddEnum<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 AddColor(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 AddKey(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 AddFloat(ConfigEntry<float> entry, float min, float max, 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: 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_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 ModSettingsManager.AddOption((BaseOption)new SliderOption(entry, new SliderConfig { min = min, max = max, formatString = format, description = ((ConfigEntryBase)(object)entry).DescWithDefault(format) })); } internal static void AddFloat(ConfigEntry<float> entry, string categoryName, float min, float max, 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: 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_001c: 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_0036: Expected O, but got Unknown //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_003b: 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 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_0026: Expected O, but got Unknown //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown FloatFieldConfig val = new FloatFieldConfig(); ((NumericFieldConfig<float>)val).Min = min; ((NumericFieldConfig<float>)val).Max = max; ((BaseOptionConfig)val).description = ((ConfigEntryBase)(object)entry).DescWithDefault(format); ModSettingsManager.AddOption((BaseOption)new FloatFieldOption(entry, val)); } internal static void AddInt(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) { //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 IntSliderOption(entry, new IntSliderConfig { min = min, max = max, description = ((ConfigEntryBase)(object)entry).DescWithDefault() })); } internal static void AddIntSlider(ConfigEntry<int> entry, string categoryName, int min, int max) { //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() })); } internal static void AddString(ConfigEntry<string> 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_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_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 StringInputFieldOption(entry, new InputFieldConfig { submitOn = (SubmitEnum)6, lineType = (LineType)0, description = ((ConfigEntryBase)(object)entry).DescWithDefault() })); } internal static void AddOption(ConfigEntry<bool> entry) { AddBool(entry); } internal static void AddOption(ConfigEntry<bool> entry, string categoryName, string name) { AddBool(entry, categoryName, name); } internal static void AddOption(ConfigEntry<bool> entry, string categoryName) { AddBool(entry, categoryName); } internal static void AddOption<T>(ConfigEntry<T> entry) where T : Enum { AddEnum<T>(entry); } internal static void AddOption(ConfigEntry<Color> entry) { AddColor(entry); } internal static void AddOption(ConfigEntry<KeyboardShortcut> entry) { AddKey(entry); } internal static void AddOption(ConfigEntry<int> entry) { AddInt(entry); } internal static void AddOption(ConfigEntry<string> entry) { AddString(entry); } 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 { public int index; public IndexType type; public Index(ItemIndex itemIndex) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected I4, but got Unknown index = (int)itemIndex; type = IndexType.Item; } public Index(EquipmentIndex equipIndex) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected I4, but got Unknown index = (int)equipIndex; type = IndexType.Equip; } public Index(SkillSlot slotIndex) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected I4, but got Unknown index = (int)slotIndex; type = IndexType.SkillSlot; } public Index(int itemIndex, byte indexType) { index = itemIndex; type = (IndexType)indexType; } public override string ToString() { //IL_0054: Unknown result type (might be due to invalid IL or missing references) switch (type) { 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 ((object)(SkillSlot)(ref val)).ToString(); } default: return "Invalid"; } } public static implicit operator Index(ItemIndex itemIndex) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return new Index(itemIndex); } 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 equipIndex) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return new Index(equipIndex); } 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 slotIndex) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return new Index(slotIndex); } public static explicit operator ItemIndex(Index index) { if (index.type != IndexType.Item) { throw new Exception("Index type is not Item"); } return (ItemIndex)index.index; } public static explicit operator EquipmentIndex(Index index) { if (index.type != IndexType.Equip) { throw new Exception("Index type is not Equip"); } return (EquipmentIndex)index.index; } public static explicit operator SkillSlot(Index index) { if (index.type != IndexType.SkillSlot) { throw new Exception("Index type is not SkillSlot"); } return (SkillSlot)(sbyte)index.index; } public override bool Equals(object obj) { if (obj is Index index && type == index.type) { return this.index == index.index; } return false; } public static bool operator ==(Index index, ItemIndex itemIndex) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Invalid comparison between I4 and Unknown if (index.type == IndexType.Item) { return index.index == (int)itemIndex; } return false; } public static bool operator !=(Index index, ItemIndex itemIndex) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Invalid comparison between I4 and Unknown if (index.type == IndexType.Item) { return index.index != (int)itemIndex; } return true; } public static bool operator ==(Index index, EquipmentIndex equipIndex) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Invalid comparison between I4 and Unknown if (index.type == IndexType.Equip) { return index.index == (int)equipIndex; } return false; } public static bool operator !=(Index index, EquipmentIndex equipIndex) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Invalid comparison between I4 and Unknown if (index.type == IndexType.Equip) { return index.index != (int)equipIndex; } return true; } public static bool operator ==(Index index, SkillSlot slotIndex) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Invalid comparison between I4 and Unknown if (index.type == IndexType.SkillSlot) { return index.index == (int)slotIndex; } return false; } public static bool operator !=(Index index, SkillSlot slotIndex) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Invalid comparison between I4 and Unknown if (index.type == IndexType.SkillSlot) { return index.index != (int)slotIndex; } return true; } } public enum IndexType : byte { None, Item, Equip, SkillSlot } [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("dolso.ItemStatistics", "ItemStatistics", "1.1.11")] public class ItemStatisticsPlugin : BaseUnityPlugin { public static Dictionary<Index, TrackedDef> itemToTracker; public static Action onCatalogLoaded; public static GameObject playerTooltip; public static GameObject missileLauncher; public static GameObject overloadingHeadhunter; public static GameObject fireTrailHeadhunter; public static int crocoDiseaseProjectileIndex; public static BodyIndex falseSonCharacterBodyIndex; private void Awake() { log.start(((BaseUnityPlugin)this).Logger); Config.DoConfig(((BaseUnityPlugin)this).Config); try { Utilities.AddressableAddComp<TrackedInventory>("RoR2/Base/Core/PlayerMaster.prefab"); 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.GetAddressable("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.GetAddressable("RoR2/Base/UI/ScoreboardStrip.prefab", delegate(GameObject scoreboardStrip) { ((Component)scoreboardStrip.GetComponentInChildren<EquipmentIcon>()).gameObject.AddComponent<IconBehaviour>().type = IndexType.Equip; scoreboardStrip.AddComponent<PlayerTooltip>(); }); PlayerTooltip.CreateTooltipPrefab(); Utilities.AddressableAddComp<ToolbotStance>("RoR2/Base/Toolbot/ToolbotBody.prefab"); } 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(); log.info($"Hooks completed in {stopwatch.Elapsed.TotalSeconds:f2}s"); onCatalogLoaded = (Action)Delegate.Combine(onCatalogLoaded, new Action(Mods.DoMods)); } [SystemInitializer(new Type[] { typeof(PickupCatalog), typeof(SurvivorCatalog), typeof(ProjectileCatalog) })] private static void Init() { //IL_0bba: Unknown result type (might be due to invalid IL or missing references) //IL_0bbf: Unknown result type (might be due to invalid IL or missing references) itemToTracker = new Dictionary<Index, TrackedDef> { { (SkillSlot)0, new TrackedDef(TrackedDef.Skill) }, { (SkillSlot)1, new TrackedDef(TrackedDef.Skill) }, { (SkillSlot)2, new TrackedDef(TrackedDef.Skill) }, { (SkillSlot)3, new TrackedDef(TrackedDef.Skill) }, { Items.Bear, new TrackedDef(TrackedDef.ArmorCount) }, { Items.BearVoid, new TrackedDef(TrackedDef.ArmorCount) }, { Items.Crowbar, new TrackedDef(TrackedDef.Damage) }, { Items.ExplodeOnDeathVoid, new TrackedDef(TrackedDef.Damage) }, { Items.NearbyDamageBonus, new TrackedDef(TrackedDef.Damage) }, { Items.FragileDamageBonus, new TrackedDef(TrackedDef.Damage) }, { Items.FragileDamageBonusConsumed, new TrackedDef(TrackedDef.Watch) }, { Items.PermanentDebuffOnHit, new TrackedDef(TrackedDef.Chance) }, { Items.BossDamageBonus, new TrackedDef(TrackedDef.Damage) }, { Items.CritGlasses, new TrackedDef(TrackedDef.Damage) }, { Items.CritDamage, new TrackedDef(TrackedDef.Damage) }, { Items.DeathMark, new TrackedDef(TrackedDef.Damage) }, { Items.CritGlassesVoid, new TrackedDef(TrackedDef.DamageChance) }, { Items.ExecuteLowHealthElite, new TrackedDef(TrackedDef.Damage, TrackedDef.portionTooltip) }, { Items.OutOfCombatArmor, new TrackedDef(TrackedDef.ArmorCount) }, { Items.SprintArmor, new TrackedDef(TrackedDef.Armor) }, { Items.ArmorPlate, new TrackedDef(TrackedDef.Armor) }, { Items.ParentEgg, new TrackedDef(TrackedDef.Heal) }, { Items.GoldOnHit, new TrackedDef(TrackedDef.Gold) }, { Items.GoldOnHurt, new TrackedDef(TrackedDef.Gold) }, { Items.Thorns, new TrackedDef(TrackedDef.Damage) }, { Items.Seed, new TrackedDef(TrackedDef.Heal) }, { Items.BleedOnHit, new TrackedDef(TrackedDef.DamageChance) }, { Items.BleedOnHitVoid, new TrackedDef(TrackedDef.DamageChance) }, { Items.SlowOnHitVoid, new TrackedDef(TrackedDef.Chance) }, { Items.Missile, new TrackedDef(TrackedDef.DamageChance) }, { Items.MissileVoid, new TrackedDef(TrackedDef.DamageChance) }, { Items.ChainLightning, new TrackedDef(TrackedDef.DamageChance) }, { Items.ChainLightningVoid, new TrackedDef(TrackedDef.DamageChance) }, { Items.BounceNearby, new TrackedDef(TrackedDef.DamageChance) }, { Items.StickyBomb, new TrackedDef(TrackedDef.DamageChance) }, { Items.IceRing, new TrackedDef(TrackedDef.Damage) }, { Items.FireRing, new TrackedDef(TrackedDef.Damage) }, { Items.ElementalRingVoid, new TrackedDef(TrackedDef.Damage) }, { Items.FireballsOnHit, new TrackedDef(TrackedDef.DamageChance) }, { Items.LightningStrikeOnHit, new TrackedDef(TrackedDef.DamageChance) }, { Items.HealOnCrit, new TrackedDef(TrackedDef.Heal) }, { Items.Behemoth, new TrackedDef(TrackedDef.Damage) }, { Items.IgniteOnKill, new TrackedDef(TrackedDef.DamageChance) }, { Items.ExplodeOnDeath, new TrackedDef(TrackedDef.DamageChance) }, { Items.Dagger, new TrackedDef(TrackedDef.Damage) }, { Items.Tooth, new TrackedDef(TrackedDef.Heal) }, { Items.Bandolier, new TrackedDef(TrackedDef.Chance) }, { Items.BonusGoldPackOnKill, new TrackedDef(TrackedDef.Gold) }, { Items.BleedOnHitAndExplode, new TrackedDef(TrackedDef.DamageChance, TrackedDef.hit_damageTooltip) }, { Items.Plant, new TrackedDef(TrackedDef.Heal) }, { Items.Mushroom, new TrackedDef(TrackedDef.Heal) }, { Items.MushroomVoid, new TrackedDef(TrackedDef.Heal) }, { Items.Medkit, new TrackedDef(TrackedDef.Heal) }, { Items.TPHealingNova, new TrackedDef(TrackedDef.Heal) }, { Items.HealingPotionConsumed, new TrackedDef(TrackedDef.Heal) }, { Items.ShockNearby, new TrackedDef(TrackedDef.Damage, TrackedDef.portionTooltip) }, { Items.PrimarySkillShuriken, new TrackedDef(TrackedDef.DamageChance, TrackedDef.hit_damageTooltip) }, { Items.StrengthenBurn, new TrackedDef(TrackedDef.Damage) }, { Items.LaserTurbine, new TrackedDef(TrackedDef.Damage) }, { Items.CaptainDefenseMatrix, new TrackedDef(TrackedDef.Count) }, { Items.Icicle, new TrackedDef(TrackedDef.Damage) }, { Items.NovaOnLowHealth, new TrackedDef(TrackedDef.Damage, TrackedDef.portionTooltip) }, { Items.ImmuneToDebuff, new TrackedDef(TrackedDef.Chance) }, { Items.NovaOnHeal, new TrackedDef(TrackedDef.Damage) }, { Items.SprintWisp, new TrackedDef(TrackedDef.Damage, TrackedDef.portionTooltip) }, { Items.RandomlyLunar, new TrackedDef(TrackedDef.Chance) }, { Items.Firework, new TrackedDef(TrackedDef.Damage) }, { Items.Phasing, new TrackedDef(TrackedDef.Count) }, { Items.FallBoots, new TrackedDef(TrackedDef.Damage, TrackedDef.portionTooltip) }, { Items.SiphonOnLowHealth, new TrackedDef(TrackedDef.Heal) }, { Items.LunarSun, new TrackedDef(TrackedDef.Damage, TrackedDef.portionTooltip) }, { Items.Infusion, new TrackedDef(TrackedDef.Count) }, { Items.HeadHunter, new TrackedDef(TrackedDef.Damage) }, { Items.RoboBallBuddy, new TrackedDef(TrackedDef.Damage) }, { Items.VoidMegaCrabItem, new TrackedDef(TrackedDef.Damage) }, { Items.BeetleGland, new TrackedDef(TrackedDef.Damage) }, { Items.DroneWeapons, new TrackedDef(TrackedDef.Damage) }, { Items.GhostOnKill, new TrackedDef(TrackedDef.Damage) }, { Items.MinorConstructOnKill, new TrackedDef(TrackedDef.Damage) }, { Items.Squid, new TrackedDef(TrackedDef.Damage) }, { Items.TitanGoldDuringTP, new TrackedDef(TrackedDef.Damage) }, { Items.LowerHealthHigherDamage, new TrackedDef(TrackedDef.Damage) }, { Items.NegateAttack, new TrackedDef(TrackedDef.DamageChance) }, { Items.ExtraShrineItem, new TrackedDef(TrackedDef.Chance) }, { Items.IncreasePrimaryDamage, new TrackedDef(TrackedDef.Damage) }, { Items.MeteorAttackOnHighDamage, new TrackedDef(TrackedDef.DamageChance) }, { Items.KnockBackHitEnemies, new TrackedDef(TrackedDef.Chance) }, { Items.StunAndPierce, new TrackedDef(TrackedDef.DamageChance) }, { Items.LowerPricedChests, new TrackedDef(TrackedDef.Count) }, { Items.LowerPricedChestsConsumed, new TrackedDef(TrackedDef.Count) }, { Items.ResetChests, new TrackedDef(TrackedDef.Chance) }, { Items.GoldOnStageStart, new TrackedDef(TrackedDef.Gold) }, { Items.TeleportOnLowHealth, new TrackedDef(TrackedDef.Count) }, { Equipment.Saw, new TrackedDef(TrackedDef.Damage, TrackedDef.portionTooltip) }, { Equipment.GoldGat, new TrackedDef(TrackedDef.Damage) }, { Equipment.BFG, new TrackedDef(TrackedDef.Damage) }, { Equipment.PassiveHealing, new TrackedDef(TrackedDef.Heal) }, { Equipment.CommandMissile, new TrackedDef(TrackedDef.Damage) }, { Equipment.Fruit, new TrackedDef(TrackedDef.Heal) }, { Equipment.DroneBackup, new TrackedDef(TrackedDef.Damage) }, { Equipment.Lightning, new TrackedDef(TrackedDef.Damage) }, { Equipment.Recycle, new TrackedDef(TrackedDef.Count, TrackedDef.recycledTooltip) }, { Equipment.LifestealOnHit, new TrackedDef(TrackedDef.Heal) }, { Equipment.Molotov, new TrackedDef(TrackedDef.Damage) }, { Equipment.VendingMachine, new TrackedDef(TrackedDef.Heal) }, { Equipment.GummyClone, new TrackedDef(TrackedDef.Damage) }, { Equipment.MultiShopCard, new TrackedDef(TrackedDef.Gold) }, { Equipment.GainArmor, new TrackedDef(TrackedDef.Armor) }, { Equipment.Meteor, new TrackedDef(TrackedDef.Damage) }, { Equipment.BurnNearby, new TrackedDef(TrackedDef.Damage) }, { Equipment.AffixRed, new TrackedDef(TrackedDef.Damage) }, { Equipment.AffixBlue, new TrackedDef(TrackedDef.Damage) }, { Equipment.AffixWhite, new TrackedDef(TrackedDef.Damage) } }; crocoDiseaseProjectileIndex = ProjectileCatalog.FindProjectileIndex("CrocoDiseaseProjectile"); falseSonCharacterBodyIndex = BodyCatalog.FindBodyIndex("FalseSonBody"); ModifyPrefabs(); onCatalogLoaded?.Invoke(); } private static void ModifyPrefabs() { 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); CommonAssets.daggerPrefab.AddComponent<ProcComponent>().index = Items.Dagger; CommonAssets.bleedOnHitAndExplodeBlastEffect.AddComponent<ProcComponent>().index = 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.GetAddressable("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.GetAddressable<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); missileLauncher = Utilities.CreatePrefab(CommonAssets.missilePrefab); missileLauncher.AddComponent<ProcComponent>().index = Equipment.CommandMissile; ((Object)missileLauncher).name = "MissileLauncherProjectile"; CommonAssets.missilePrefab = Utilities.CreatePrefab(CommonAssets.missilePrefab); CommonAssets.missilePrefab.AddComponent<ProcComponent>().index = Items.Missile; Utilities.GetAddressable("RoR2/Base/EliteLightning/LightningStake.prefab", delegate(GameObject blueorb) { overloadingHeadhunter = Utilities.CreatePrefab(blueorb); overloadingHeadhunter.AddComponent<ProcComponent>().index = Items.HeadHunter; blueorb.AddComponent<ProcComponent>().index = Equipment.AffixBlue; }); AddProcComponent("RoR2/Base/Common/FireTrail.prefab", Equipment.AffixRed); } 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; }; } } internal static class Mods { internal const string magriderGuid = "dolso.magrdier"; internal static void DoMods() { TryMod(LoadMagrider, "dolso.magrdier"); } private static void TryMod(Action DoMod, string modGuid) { if (Chainloader.PluginInfos.ContainsKey(modGuid)) { try { DoMod(); } catch (Exception arg) { log.error($"Failed to load mod {modGuid}\n{arg}"); } } } private static void LoadMagrider() { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected O, but got Unknown Blaster.projectilePrefab.AddComponent<ProcComponent>().index = (SkillSlot)0; Cannon.projectilePrefab.AddComponent<ProcComponent>().index = (SkillSlot)0; HookManager.Hook(typeof(MagriderCollision), "ApplyHit", new Manipulator(IL_MagriderCollision_ApplyHit_Inflictor)); } private static void IL_MagriderCollision_ApplyHit_Inflictor(ILContext context) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown ILCursor val = new ILCursor(context); val.AddInflictorToAttack<DamageInfo>((SkillSlot)2); if (val.TryGotoNext(new Func<Instruction, bool>[1] { (Instruction a) => ILPatternMatchingExt.MatchCallOrCallvirt(a, typeof(BlastAttack), "ClientReportDamage") })) { val.EmitDelegate<Action>((Action)delegate { NetworkHooks.inflictorIndex = (SkillSlot)2; }); int index = val.Index; val.Index = index + 1; val.EmitClearNetworkParameters(); } } } public class ReverseTree { public Index value; public ReverseTree parent; public ReverseTree(Index value, ReverseTree parent) { this.value = value; this.parent = parent; } public override string ToString() { string text = value.ToString(); for (ReverseTree reverseTree = parent; reverseTree != null; reverseTree = reverseTree.parent) { text += $" -> {reverseTree.value}"; } 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 struct 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 recycledTooltip = "ITEMSTATISTICS_TOOLTIPS_RECYCLED"; public static readonly string portionTooltip = "ITEMSTATISTICS_TOOLTIPS_DAMAGEPORTION"; public static readonly string count_chanceTooltip = "ITEMSTATISTICS_TOOLTIPS_COUNT_CHANCE"; public static readonly string chance_damageTooltip = "ITEMSTATISTICS_TOOLTIPS_CHANCE_DAMAGE"; public static readonly string reduction_countTooltip = "ITEMSTATISTICS_TOOLTIPS_REDUCTION_COUNT"; public static readonly string hit_damageTooltip = "ITEMSTATISTICS_TOOLTIPS_HIT_DAMAGE"; public static readonly string heal_countTooltip = "ITEMSTATISTICS_TOOLTIPS_HEAL_COUNT"; public static readonly string portion_healTooltip = "ITEMSTATISTICS_TOOLTIPS_PORTION_HEAL"; public static readonly string minion_portionTooltip = "ITEMSTATISTICS_TOOLTIPS_MINION_PORTION"; public static readonly Type ArmorCount = typeof(ArmorCountTracker); public static readonly Type Armor = typeof(ArmorTracker); public static readonly Type Chance = typeof(ChanceTracker); public static readonly Type Count = typeof(CountTracker); public static readonly Type DamageChance = typeof(DamageChanceTracker); public static readonly Type Watch = typeof(WatchTracker); public static readonly Type Skill = typeof(SkillTracker); public static readonly Type Damage = typeof(DamageTracker); public static readonly Type Gold = typeof(GoldTracker); public static readonly Type Heal = typeof(HealTracker); public Type trackedType; public string tooltipTokenOverride; public TrackedDef(Type trackedType) { tooltipTokenOverride = null; this.trackedType = trackedType; } public TrackedDef(Type trackedType, string tooltipTokenOverride) { this.tooltipTokenOverride = null; this.tooltipTokenOverride = tooltipTokenOverride; this.trackedType = trackedType; } public string GetTooltip(IItemTracker tracker, in Totals totals) { string[] tooltipArgs = tracker.GetTooltipArgs(in totals); if (tooltipTokenOverride != null) { string text = tooltipTokenOverride; object[] array = tooltipArgs; return Language.GetStringFormatted(text, array); } if (!(tracker is SkillTracker)) { if (!(tracker is WatchTracker)) { object[] array; if (!(tracker is DamageTracker)) { if (!(tracker is ArmorCountTracker)) { if (!(tracker is ArmorTracker)) { if (!(tracker is ChanceTracker)) { if (!(tracker is CountTracker)) { if (!(tracker is DamageChanceTracker)) { if (!(tracker is GoldTracker)) { if (tracker is HealTracker) { string text2 = healTooltip; array = tooltipArgs; return Language.GetStringFormatted(text2, array); } return (tooltipArgs == null) ? "" : string.Concat(tooltipArgs); } string text3 = goldTooltip; array = tooltipArgs; return Language.GetStringFormatted(text3, array); } string text4 = chance_damageTooltip; array = tooltipArgs; return Language.GetStringFormatted(text4, array); } string text5 = countTooltip; array = tooltipArgs; return Language.GetStringFormatted(text5, array); } string text6 = count_chanceTooltip; array = tooltipArgs; return Language.GetStringFormatted(text6, array); } string text7 = reductionTooltip; array = tooltipArgs; return Language.GetStringFormatted(text7, array); } string text8 = reduction_countTooltip; array = tooltipArgs; return Language.GetStringFormatted(text8, array); } string text9 = damageTooltip; array = tooltipArgs; return Language.GetStringFormatted(text9, array); } object result; if (tooltipArgs != null) { string text10 = damageTooltip; object[] array = tooltipArgs; result = Language.GetStringFormatted(text10, array); } else { result = ""; } return (string)result; } object result2; if (tooltipArgs != null) { string token = SkillTracker.GetToken(tooltipArgs); object[] array = tooltipArgs; result2 = Language.GetStringFormatted(token, array); } else { result2 = ""; } return (string)result2; } internal IItemTracker CreateTracker() { return (IItemTracker)Activator.CreateInstance(trackedType); } [SystemInitializer(new Type[] { })] private static void Init() { Language.english.SetStringsByTokens((IEnumerable<KeyValuePair<string, string>>)new KeyValuePair<string, string>[15] { new KeyValuePair<string, string>(damageTooltip, "Average damage increase: <style=cIsDamage>{0}</style>"), new KeyValuePair<string, string>(chanceTooltip, "Success rate: <style=cIsDamage>{0}</style>"), new KeyValuePair<string, string>(countTooltip, "Success count: <style=cIsDamage>{0}</style>"), new KeyValuePair<string, string>(healTooltip, "Heal portion: <style=cIsHealing>{0}</style>"), new KeyValuePair<string, string>(goldTooltip, "Average gold increase: <style=cIsDamage>{0}</style>"), new KeyValuePair<string, string>(reductionTooltip, "Average reduction: <style=cIsHealing>{0}</style>"), new KeyValuePair<string, string>(recycledTooltip, "Recycled: <style=cIsDamage>{0}</style>"), new KeyValuePair<string, string>(portionTooltip, "Damage portion: <style=cIsHealing>{1}</style>"), new KeyValuePair<string, string>(count_chanceTooltip, "Success count: <style=cIsDamage>{0}</style>\nSuccess rate: <style=cIsDamage>{1}</style>"), new KeyValuePair<string, string>(chance_damageTooltip, "Success rate: <style=cIsDamage>{0}</style>\nAverage damage increase: <style=cIsDamage>{1}</style>"), new KeyValuePair<string, string>(reduction_countTooltip, "Average reduction: <style=cIsHealing>{0}</style>\nSuccess count: <style=cIsDamage>{1}</style>"), new KeyValuePair<string, string>(hit_damageTooltip, "Hit rate: <style=cIsDamage>{0}</style>\nAverage damage increase: <style=cIsDamage>{1}</style>"), new KeyValuePair<string, string>(heal_countTooltip, "Heal portion: <style=cIsHealing>{0}</style>\nTotal healing: <style=cIsUtility>{1}</style>"), new KeyValuePair<string, string>(portion_healTooltip, "Damage portion: <style=cIsUtility>{1}</style>\nHeal portion: <style=cIsHealing>{0}</style>"), new KeyValuePair<string, string>(minion_portionTooltip, "Local minion portion: <style=cIsDamage>{0}</style>\nGlobal damage portion: <style=cIsHealing>{1}</style>") }); } } } namespace ItemStatistics.Trackers { public class ArmorCountTracker : IItemTracker, 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; } public string[] GetTooltipArgs(in Totals totals) { return new string[2] { TrackerStatics.ReductionToString(damageBlocked, totals.damageTaken - globalDamageTakenWhenSet), succedded.ToString() }; } public void Reset(in Totals totals) { attempted = 0u; succedded = 0u; damageBlocked = 0f; globalDamageTakenWhenSet = totals.damageTaken; } public void Serialize(out uint[] ints, out float[] floats) { ints = new uint[2] { attempted, succedded }; floats = new float[1] { damageBlocked }; } public void Deserialize(uint[] ints, float[] floats) { damageBlocked = floats[0]; attempted = ints[0]; succedded = ints[1]; } string[] IItemTracker.GetTooltipArgs(in Totals totals) { return GetTooltipArgs(in totals); } void IItemTracker.Reset(in Totals totals) { Reset(in totals); } } public class ArmorTracker : IItemTracker, 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; } public string[] GetTooltipArgs(in Totals totals) { return new string[1] { TrackerStatics.ReductionToString(damageBlocked, totals.damageTaken - globalDamageTakenWhenSet) }; } public void Reset(in Totals totals) { damageBlocked = 0f; globalDamageTakenWhenSet = totals.damageTaken; } public void Serialize(out uint[] ints, out float[] floats) { ints = null; floats = new float[1] { damageBlocked }; } public void Deserialize(uint[] ints, float[] floats) { damageBlocked = floats[0]; } string[] IItemTracker.GetTooltipArgs(in Totals totals) { return GetTooltipArgs(in totals); } void IItemTracker.Reset(in Totals totals) { Reset(in totals); } } public class ChanceTracker : IItemTracker, 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; } public string[] GetTooltipArgs(in Totals totals) { return new string[2] { succedded.ToString(), TrackerStatics.ChanceToString(attempted, succedded) }; } public void Reset(in Totals totals) { attempted = 0u; succedded = 0u; } public void Serialize(out uint[] ints, out float[] floats) { ints = new uint[2] { attempted, succedded }; floats = null; } public void Deserialize(uint[] ints, float[] floats) { attempted = ints[0]; succedded = ints[1]; } string[] IItemTracker.GetTooltipArgs(in Totals totals) { return GetTooltipArgs(in totals); } void IItemTracker.Reset(in Totals totals) { Reset(in totals); } } public class CountTracker : IItemTracker, IChanceTracker { private uint succedded; public int itemCount { get; set; } public bool dirtyBit { get; set; } public void Attempted() { log.error("Called Attempted on CountTracker"); } public void Succedded() { succedded++; dirtyBit = true; } public string[] GetTooltipArgs(in Totals totals) { return new string[1] { succedded.ToString() }; } public void Reset(in Totals totals) { succedded = 0u; } public void Serialize(out uint[] ints, out float[] floats) { ints = new uint[1] { succedded }; floats = null; } public void Deserialize(uint[] ints, float[] floats) { succedded = ints[0]; } string[] IItemTracker.GetTooltipArgs(in Totals totals) { return GetTooltipArgs(in totals); } void IItemTracker.Reset(in Totals totals) { Reset(in totals); } } public class DamageChanceTracker : IItemTracker, IChanceTracker, IDamageTracker { private float globalDamageWhenSet; private float itemDamage; 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; } public void AddItemDamage(float damage) { itemDamage += damage; dirtyBit = true; } public string[] GetTooltipArgs(in Totals totals) { return new string[2] { TrackerStatics.ChanceToString(attempted, succedded), TrackerStatics.IncreaseToString(itemDamage, totals.damageDealt - globalDamageWhenSet) }; } public void Reset(in Totals totals) { attempted = 0u; succedded = 0u; itemDamage = 0f; globalDamageWhenSet = totals.damageDealt; } public void Serialize(out uint[] ints, out float[] floats) { ints = new uint[2] { attempted, succedded }; floats = new float[1] { itemDamage }; } public void Deserialize(uint[] ints, float[] floats) { itemDamage = floats[0]; attempted = ints[0]; succedded = ints[1]; } string[] IItemTracker.GetTooltipArgs(in Totals totals) { return GetTooltipArgs(in totals); } void IItemTracker.Reset(in Totals totals) { Reset(in totals); } } public class DamageTracker : IItemTracker, IDamageTracker { internal float globalDamageWhenSet; internal float itemDamage; public int itemCount { get; set; } public bool dirtyBit { get; set; } public void AddItemDamage(float damage) { itemDamage += damage; dirtyBit = true; } public virtual string[] 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(out uint[] ints, out float[] floats) { ints = null; floats = new float[1] { itemDamage }; } public virtual void Deserialize(uint[] ints, float[] floats) { itemDamage = floats[0]; } } public class GoldTracker : IItemTracker { 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; } public string[] GetTooltipArgs(in Totals totals) { return new string[1] { TrackerStatics.IncreaseToString(itemEarned, (float)totals.goldEarned - globalEarnedWhenSet) }; } public void Reset(in Totals totals) { itemEarned = 0f; globalEarnedWhenSet = totals.goldEarned; } public void Serialize(out uint[] ints, out float[] floats) { ints = null; floats = new float[1] { itemEarned }; } public void Deserialize(uint[] ints, float[] floats) { itemEarned = floats[0]; } string[] IItemTracker.GetTooltipArgs(in Totals totals) { return GetTooltipArgs(in totals); } void IItemTracker.Reset(in Totals totals) { Reset(in totals); } } public class HealTracker : IItemTracker, 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; } public string[] GetTooltipArgs(in Totals totals) { return new string[2] { TrackerStatics.PortionToString(itemHealed, totals.healed - globalHealedWhenSet), itemHealed.ToString("0") }; } public void Reset(in Totals totals) { itemHealed = 0f; globalHealedWhenSet = totals.healed; } public void Serialize(out uint[] ints, out float[] floats) { ints = null; floats = new float[1] { itemHealed }; } public void Deserialize(uint[] ints, float[] floats) { itemHealed = floats[0]; } string[] IItemTracker.GetTooltipArgs(in Totals totals) { return GetTooltipArgs(in totals); } void IItemTracker.Reset(in Totals totals) { Reset(in totals); } } public interface IItemTracker { int itemCount { get; set; } bool dirtyBit { get; set; } string[] GetTooltipArgs(in Totals totals); void Reset(in Totals totals); void Serialize(out uint[] ints, out float[] floats); void Deserialize(uint[] ints, float[] floats); } public interface IChanceTracker { void Attempted(); void Succedded(); } public interface IDamageTracker { void AddItemDamage(float damage); } public interface IHealTracker { void AddHealing(float heal); } public interface IReductionTracker { void AddBlockedDamage(float blocked); } public class SkillTracker : IItemTracker, 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 AddItemDamage(float damage) { itemDamage += damage; dirtyBit = true; } public void AddHealing(float heal) { itemHealed += heal; dirtyBit = true; } public string[] GetTooltipArgs(in Totals totals) { bool flag = itemDamage != 0f; bool flag2 = itemHealed != 0f; if (flag && flag2) { return new string[2] { TrackerStatics.PortionToString(itemHealed, totals.healed - globalHealedWhenSet), TrackerStatics.PortionToString(itemDamage, totals.damageDealt - globalDamageWhenSet) }; } if (flag) { return new string[2] { null, TrackerStatics.PortionToString(itemDamage, totals.damageDealt - globalDamageWhenSet) }; } if (flag2) { return new string[2] { TrackerStatics.PortionToString(itemHealed, totals.healed - globalHealedWhenSet), null }; } return null; } public static string GetToken(string[] args) { bool flag = args[0] != null; bool flag2 = args[1] != null; if (flag2 && flag) { return TrackedDef.portion_healTooltip; } if (flag2) { return TrackedDef.portionTooltip; } if (flag) { return TrackedDef.healTooltip; } log.error("Null args for SkillTracker"); return TrackedDef.portion_healTooltip; } public void Reset(in Totals totals) { itemDamage = 0f; itemHealed = 0f; globalDamageWhenSet = totals.damageDealt; globalHealedWhenSet = totals.healed; } public virtual void Serialize(out uint[] ints, out float[] floats) { ints = null; floats = new float[2] { itemDamage, itemHealed }; } public virtual void Deserialize(uint[] ints, float[] floats) { itemDamage = floats[0]; itemHealed = floats[1]; } string[] IItemTracker.GetTooltipArgs(in Totals totals) { return GetTooltipArgs(in totals); } void IItemTracker.Reset(in Totals totals) { Reset(in totals); } } 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:f0}%"; } return $"{100f / (1f - localNum / totalNum) - 100f: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):f0}%"; } public static string PortionToString(float localNum, float totalNum) { if (totalNum == 0f) { return "NaN"; } return $"{100f * localNum / totalNum:f0}%"; } } public class WatchTracker : DamageTracker { private bool globalset; public void AddBrokenDamage(DamageTracker cleanWatchTracker) { AddItemDamage(cleanWatchTracker.itemDamage); if (!globalset) { globalDamageWhenSet = cleanWatchTracker.globalDamageWhenSet; globalset = true; } } public override void Reset(in Totals totals) { base.Reset(in totals); globalset = false; } public override void Serialize(out uint[] ints, out float[] floats) { ints = null; floats = new float[2] { itemDamage, globalDamageWhenSet }; } public override void Deserialize(uint[] ints, float[] floats) { itemDamage = floats[0]; globalDamageWhenSet = floats[1]; } } } namespace ItemStatistics.Networking { [Serializable] public struct DamageMessage { public Index inflictorIndex; public NetworkInstanceId victimId; public float damage; public bool crit; public GameObject attacker; public Vector3 position; public Vector3 force; public bool rejected; public uint procChainMask; public float procCoefficient; public ulong damageType; public DamageColorIndex damageColorIndex; public DotIndex dotIndex; public bool canRejectForce; public ProcChainMask GetProcChainMask() { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) ProcChainMask result = default(ProcChainMask); result.mask = procChainMask; return result; } public static explicit operator DamageInfo(DamageMessage message) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0011: 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_002f: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Expected O, but got Unknown return new DamageInfo { damage = message.damage, crit = message.crit, inflictor = ProcComponent.CreateInflictor(message.inflictorIndex, null), attacker = message.attacker, position = message.position, force = message.force, rejected = message.rejected, procChainMask = message.GetProcChainMask(), procCoefficient = message.procCoefficient, damageType = DamageTypeCombo.op_Implicit(message.damageType), damageColorIndex = message.damageColorIndex, dotIndex = message.dotIndex, canRejectForce = message.canRejectForce }; } public DamageMessage(DamageInfo damageInfo, Index inflictorIndex, HealthComponent victim) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) this.inflictorIndex = inflictorIndex; if (Object.op_Implicit((Object)(object)victim)) { victimId = ((NetworkBehaviour)victim).netId; } else { victimId = new NetworkInstanceId(0u); } damage = damageInfo.damage; crit = damageInfo.crit; attacker = damageInfo.attacker; position = damageInfo.position; force = damageInfo.force; rejected = damageInfo.rejected; procChainMask = damageInfo.procChainMask.mask; procCoefficient = damageInfo.procCoefficient; damageType = DamageTypeCombo.op_Implicit(damageInfo.damageType); damageColorIndex = damageInfo.damageColorIndex; dotIndex = damageInfo.dotIndex; canRejectForce = damageInfo.canRejectForce; } public DamageMessage(in BlastAttackDamageInfo blastAttack, Index inflictorIndex) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_001b: 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_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Invalid comparison between Unknown and I4 //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0083: 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_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0046: 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) this.inflictorIndex = inflictorIndex; if (Object.op_Implicit((Object)(object)blastAttack.hitHealthComponent)) { victimId = ((NetworkBehaviour)blastAttack.hitHealthComponent).netId; } else { victimId = new NetworkInstanceId(0u); } DamageTypeCombo val = blastAttack.damageType; if ((int)blastAttack.damageModifier == 2) { val |= DamageTypeCombo.op_Implicit((DamageType)16); } damage = blastAttack.damage; crit = blastAttack.crit; attacker = blastAttack.attacker; position = blastAttack.position; force = blastAttack.force; rejected = false; procChainMask = blastAttack.procChainMask.mask; procCoefficient = blastAttack.procCoefficient; damageType = DamageTypeCombo.op_Implicit(val); damageColorIndex = blastAttack.damageColorIndex; dotIndex = (DotIndex)(-1); canRejectForce = blastAttack.canRejectForce; } public DamageMessage(OverlapAttack overlapAttack, Index inflictorIndex) { //IL_000d: 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_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) this.inflictorIndex = inflictorIndex; victimId = default(NetworkInstanceId); damage = overlapAttack.damage; crit = overlapAttack.isCrit; attacker = overlapAttack.attacker; position = default(Vector3); force = overlapAttack.forceVector; rejected = false; procChainMask = overlapAttack.procChainMask.mask; procCoefficient = overlapAttack.procCoefficient; damageType = DamageTypeCombo.op_Implicit(overlapAttack.damageType); damageColorIndex = overlapAttack.damageColorIndex; dotIndex = (DotIndex)(-1); canRejectForce = true; } } 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.type != IndexType.None; } return false; } } internal static void Hook() { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Expected O, but got Unknown //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Expected O, but got Unknown HookManager.Hook(typeof(BlastAttack), "ClientReportDamage", (Delegate)new <>A{00000018}<BlastAttack_ClientReportDamage, BlastAttackDamageInfo>(On_BlastAttack_ClientReportDamage_NetworkMessage)); HookManager.Hook(typeof(BlastAttack), "HandleHits", new Manipulator(IL_BlastAttack_HandleHits_Inflictor)); HookManager.Hook(typeof(BulletAttack), "DefaultHitCallbackImplementation", new Manipulator(IL_BulletAttack_DefaultHitCallbackImplementation_NetworkMessage)); HookManager.Hook(typeof(OverlapAttack), "ProcessHits", new Manipulator(IL_OverlapAttack_ProcessHits_Inflictor)); HookManager.Hook(typeof(BasicMeleeAttack), "AuthorityFixedUpdate", (Delegate)new Action<Action<BaseState>, BaseState>(On_BasicMeleeAttack_AuthorityFixedUpdate_ClearModded)); } private static void On_BlastAttack_ClientReportDamage_NetworkMessage(BlastAttack_ClientReportDamage orig, in BlastAttackDamageInfo blastAttack) { if (!shouldClientSendMessage) { orig(in blastAttack); } else if (Object.op_Implicit((Object)(object)blastAttack.hitHealthComponent)) { TrackModdedUsers.localUser.CallCmdBlastAttack(new DamageMessage(in blastAttack, inflictorIndex)); } } private static void IL_BlastAttack_HandleHits_Inflictor(ILContext context) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown ILCursor val = new ILCursor(context); if (val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1] { (Instruction a) => ILPatternMatchingExt.MatchLdfld(a, typeof(BlastAttack), "inflictor") })) { val.EmitReplaceInflictor(); } else { val.LogErrorCaller("failed find", "IL_BlastAttack_HandleHits_Inflictor"); } } private static void IL_BulletAttack_DefaultHitCallbackImplementation_NetworkMessage(ILContext context) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Unknown result type (might be due to invalid IL or missing references) //IL_0218: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(context); int shouldHitIndex = 9; ILLabel val2 = default(ILLabel); int num = default(int); if (!val.TryGotoNext(new Func<Instruction, bool>[4] { (Instruction a) => ILPatternMatchingExt.MatchCallOrCallvirt(a, typeof(FriendlyFireManager), "ShouldDirectHitProceed"), (Instruction a) => ILPatternMatchingExt.MatchBr(a, ref val2), (Instruction a) => ILPatternMatchingExt.MatchLdcI4(a, ref num), (Instruction a) => ILPatternMatchingExt.MatchStloc(a, ref shouldHitIndex) })) { log.error($"Failed to find shouldHitIndex\n{val}"); } 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") })) { log.error($"Failed to find damageInfoIndex\n{val}"); } else { int index = val.Index; val.Index = index + 1; val.Emit(OpCodes.Dup); val.EmitDelegate<Action<DamageInfo>>((Action<DamageInfo>)delegate(DamageInfo damageInfo) { if (inflictorIndex.type != 0) { 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.