Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of UncappedAttackSpeed v2.0.4
plugins/UncapAttackSpeed.dll
Decompiled 5 months 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 System.Security; using System.Security.Permissions; using System.Threading.Tasks; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using Dolso; using EntityStates; using EntityStates.Commando.CommandoWeapon; using EntityStates.Huntress.HuntressWeapon; using EntityStates.Toolbot; using EntityStates.VoidSurvivor.Weapon; using HG.GeneralSerializer; using HG.Reflection; using Mono.Cecil.Cil; using MonoMod.Cil; using MonoMod.RuntimeDetour; using RiskOfOptions; using RiskOfOptions.OptionConfigs; using RiskOfOptions.Options; using RoR2; using RoR2.Orbs; using RoR2.Skills; using RoR2BepInExPack.Utilities; using TMPro; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.Networking; using UnityEngine.ResourceManagement.AsyncOperations; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: OptIn] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("UncapAttackSpeed")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+d6c99d9196968be3f0ba41bf42917e3abd212624")] [assembly: AssemblyProduct("UncapAttackSpeed")] [assembly: AssemblyTitle("UncapAttackSpeed")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] namespace Dolso { internal static class log { private static readonly ManualLogSource logger = Logger.CreateLogSource(Assembly.GetExecutingAssembly().GetName().Name); [Conditional("DEBUG")] 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)$"ILCursor failure, skipping: {data}\n{c}"); } internal static void LogErrorCaller(this ILCursor c, object data) { logger.LogError((object)$"ILCursor failed in {new StackFrame(1).GetMethod().Name}, skipping: {data}\n{c}"); } } internal static class HookManager { internal delegate bool ConfigEnabled<T>(T configValue); private class HookedConfig<T> { private readonly ConfigEnabled<T> enabled; private readonly IDetour detour; internal HookedConfig(ConfigEntry<T> configEntry, ConfigEnabled<T> enabled, IDetour detour) { this.enabled = enabled; this.detour = detour; if (configEntry != null) { configEntry.SettingChanged += ConfigChanged; ConfigChanged(configEntry, null); } else { detour.Apply(); } } private void ConfigChanged(object sender, EventArgs args) { if (enabled(((ConfigEntry<T>)sender).Value)) { if (!detour.IsApplied) { detour.Apply(); } } else if (detour.IsApplied) { detour.Undo(); } } } internal const BindingFlags allFlags = BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; private static readonly ConfigEnabled<bool> boolConfigEnabled = BoolEnabled; private static ILHookConfig ilHookConfig = new ILHookConfig { ManualApply = true }; private static HookConfig onHookConfig = new HookConfig { ManualApply = true }; internal static void Hook(Type typeFrom, string fromMethod, Manipulator ilHook) { Hook(GetMethod(typeFrom, fromMethod), ilHook); } internal static void Hook(Delegate fromMethod, Manipulator ilHook) { Hook(fromMethod.Method, ilHook); } internal static void Hook(MethodBase fromMethod, Manipulator ilHook) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) try { new ILHook(fromMethod, ilHook, ref ilHookConfig).Apply(); } catch (Exception e) { e.LogHookError(fromMethod, ((Delegate)(object)ilHook).Method); } } internal static void Hook(Type typeFrom, string fromMethod, Delegate onHook) { Hook(GetMethod(typeFrom, fromMethod), onHook.Method, onHook.Target); } internal static void Hook(Delegate fromMethod, Delegate onHook) { Hook(fromMethod.Method, onHook.Method, onHook.Target); } internal static void Hook(MethodBase fromMethod, Delegate onHook) { Hook(fromMethod, onHook.Method, onHook.Target); } internal static void Hook(MethodBase fromMethod, MethodInfo onHook, object target = null) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) try { new Hook(fromMethod, onHook, target, ref onHookConfig).Apply(); } catch (Exception e) { e.LogHookError(fromMethod, onHook); } } internal static void HookConfig(this ConfigEntry<bool> configEntry, Type typeFrom, string fromMethod, Delegate hook) { configEntry.HookConfig(boolConfigEnabled, GetMethod(typeFrom, fromMethod), hook.Method, hook.Target); } internal static void HookConfig(this ConfigEntry<bool> configEntry, MethodBase fromMethod, Delegate hook) { configEntry.HookConfig(boolConfigEnabled, fromMethod, hook.Method, hook.Target); } internal static void HookConfig(this ConfigEntry<bool> configEntry, MethodBase fromMethod, MethodInfo hook) { configEntry.HookConfig(boolConfigEnabled, fromMethod, hook); } internal static void HookConfig<T>(this ConfigEntry<T> configEntry, ConfigEnabled<T> enabled, Type typeFrom, string fromMethod, Delegate hook) { configEntry.HookConfig(enabled, GetMethod(typeFrom, fromMethod), hook.Method, hook.Target); } internal static void HookConfig<T>(this ConfigEntry<T> configEntry, ConfigEnabled<T> enabled, MethodBase fromMethod, Delegate hook) { configEntry.HookConfig(enabled, fromMethod, hook.Method, hook.Target); } internal static void HookConfig<T>(this ConfigEntry<T> configEntry, ConfigEnabled<T> enabled, MethodBase fromMethod, MethodInfo hook, object target = null) { try { new HookedConfig<T>(configEntry, enabled, ManualDetour(fromMethod, hook, target)); } catch (Exception e) { e.LogHookError(fromMethod, hook); } } internal static IDetour ManualDetour(Type typeFrom, string fromMethod, Delegate hook) { return ManualDetour(GetMethod(typeFrom, fromMethod), hook.Method, hook.Target); } internal static IDetour ManualDetour(MethodBase fromMethod, Delegate hook) { return ManualDetour(fromMethod, hook.Method, hook.Target); } internal static IDetour ManualDetour(MethodBase fromMethod, MethodInfo hook, object target = null) { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Expected O, but got Unknown //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Expected O, but got Unknown //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Expected O, but got Unknown try { ParameterInfo[] parameters = hook.GetParameters(); if (parameters.Length == 1 && parameters[0].ParameterType == typeof(ILContext)) { return (IDetour)new ILHook(fromMethod, (Manipulator)hook.CreateDelegate(typeof(Manipulator)), ref ilHookConfig); } return (IDetour)new Hook(fromMethod, hook, target, ref onHookConfig); } catch (Exception e) { e.LogHookError(fromMethod, hook); return null; } } internal static MethodInfo GetMethod(Type typeFrom, string methodName) { if (typeFrom == null || methodName == null) { log.error($"Null argument in GetMethod: type={typeFrom}, name={methodName}"); return null; } MethodInfo[] array = (from a in typeFrom.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) where a.Name == methodName select a).ToArray(); switch (array.Length) { case 1: return array[0]; case 0: log.error($"Failed to find method: {typeFrom}::{methodName}"); return null; default: { string text = $"{array.Length} ambiguous matches found for: {typeFrom}::{methodName}, may be incorrect"; MethodInfo[] array2 = array; for (int i = 0; i < array2.Length; i++) { text = text + "\n" + array2[i]; } log.warning(text); return array[0]; } } } internal static MethodInfo GetMethod(Type typeFrom, string methodName, params Type[] parameters) { if (typeFrom == null || methodName == null) { log.error($"Null argument in GetMethod: type={typeFrom}, name={methodName}"); return null; } MethodInfo? method = typeFrom.GetMethod(methodName, BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, parameters, null); if (method == null) { log.error($"Failed to find method: {typeFrom}::{methodName}_{parameters.Length}"); } return method; } internal static void SetPriority(string[] before_il = null, string[] before_on = null, string[] after_il = null, string[] after_on = null) { ilHookConfig.Before = before_il; onHookConfig.Before = before_on; ilHookConfig.After = after_il; onHookConfig.After = after_on; } internal static void LogHookError(this Exception e, MethodBase fromMethod, MethodInfo hook) { log.error((fromMethod == null) ? $"null from-method for hook: {hook.Name}\n{e}" : $"Failed to hook: {fromMethod.DeclaringType}::{fromMethod.Name} - {hook.Name}\n{e}"); } private static bool BoolEnabled(bool configValue) { return configValue; } } internal static class Utilities { internal struct AsyncHandle<T> : IDisposable { private AsyncOperationHandle<T> handle; public T result => handle.Result; public Task<T> task => handle.Task; internal AsyncHandle(AsyncOperationHandle<T> handle) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) this.handle = handle; } public TaskAwaiter<T> GetAwaiter() { return handle.Task.GetAwaiter(); } public void Dispose() { handle.Release(); } public static implicit operator AsyncOperationHandle<T>(AsyncHandle<T> handle) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return handle.handle; } } private static GameObject _prefabParent; internal static GameObject CreatePrefab(GameObject gameObject, string name = null) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown if (!Object.op_Implicit((Object)(object)_prefabParent)) { _prefabParent = new GameObject("DolsoPrefabs"); Object.DontDestroyOnLoad((Object)(object)_prefabParent); ((Object)_prefabParent).hideFlags = (HideFlags)61; _prefabParent.SetActive(false); } GameObject val = Object.Instantiate<GameObject>(gameObject, _prefabParent.transform); if (name != null) { ((Object)val).name = name; } return val; } internal static AsyncHandle<T> GetAddressableAsync<T>(string addressable) where T : Object { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return new AsyncHandle<T>(Addressables.LoadAssetAsync<T>((object)addressable)); } internal static AsyncHandle<GameObject> GetAddressableAsync(string addressable) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return new AsyncHandle<GameObject>(Addressables.LoadAssetAsync<GameObject>((object)addressable)); } internal static void DoAddressable<T>(string addressable, Action<T> callback, bool release = false) where T : Object { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) AsyncOperationHandle<T> handle = Addressables.LoadAssetAsync<T>((object)addressable); handle.Completed += delegate(AsyncOperationHandle<T> a) { callback(a.Result); if (release) { handle.Release(); } }; } internal static void DoAddressable(string addressable, Action<GameObject> callback, bool release = false) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) AsyncOperationHandle<GameObject> handle = Addressables.LoadAssetAsync<GameObject>((object)addressable); handle.Completed += delegate(AsyncOperationHandle<GameObject> a) { callback(a.Result); if (release) { handle.Release(); } }; } internal static void AddressableAddComp<TComp>(string addressable, Action<TComp> callback = null) where TComp : 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) { TComp obj = a.Result.AddComponent<TComp>(); callback?.Invoke(obj); }; } 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 ModifyStateConfig(this EntityStateConfiguration stateConfig, string fieldName, object newValue) { SerializedField[] serializedFields = stateConfig.serializedFieldsCollection.serializedFields; for (int i = 0; i < serializedFields.Length; i++) { if (serializedFields[i].fieldName == fieldName) { Object val = (Object)((newValue is Object) ? newValue : null); if (val != null) { serializedFields[i].fieldValue.objectValue = val; } else if (newValue != null && StringSerializer.CanSerializeType(newValue.GetType())) { serializedFields[i].fieldValue.stringValue = StringSerializer.Serialize(newValue.GetType(), newValue); } else { log.error("Invalid value for SerializedField: " + newValue); } return; } } log.error("Failed to find " + fieldName + " for " + ((Object)stateConfig).name); } internal static bool IsKeyDown(this KeyboardShortcut key, bool onlyJustPressed) { //IL_0015: 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_0033: Unknown result type (might be due to invalid IL or missing references) if (onlyJustPressed) { if (!Input.GetKeyDown(((KeyboardShortcut)(ref key)).MainKey)) { return false; } } else if (!Input.GetKey(((KeyboardShortcut)(ref key)).MainKey)) { return false; } foreach (KeyCode modifier in ((KeyboardShortcut)(ref key)).Modifiers) { if (!Input.GetKey(modifier)) { return false; } } return true; } } internal static class RiskofOptions { internal const string RooGuid = "com.rune580.riskofoptions"; internal static bool enabled => Chainloader.PluginInfos.ContainsKey("com.rune580.riskofoptions"); [MethodImpl(MethodImplOptions.NoInlining)] internal static void SetSprite(Sprite sprite) { ModSettingsManager.SetModIcon(sprite); } internal static void SetSpriteDefaultIcon() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) try { string fullName = new DirectoryInfo(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)).FullName; Texture2D val = new Texture2D(256, 256); if (ImageConversion.LoadImage(val, File.ReadAllBytes(Path.Combine(fullName, "icon.png")))) { ModSettingsManager.SetModIcon(Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f))); } else { log.error("Failed to load icon.png"); } } catch (Exception ex) { log.error("Failed to load icon.png\n" + ex); } } internal static void AddOption(ConfigEntryBase entry) { AddOption(entry, string.Empty, string.Empty); } [MethodImpl(MethodImplOptions.NoInlining)] internal static void AddOption(ConfigEntryBase entry, string categoryName = "", string name = "", bool restartRequired = false) { //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Expected O, but got Unknown //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Expected O, but got Unknown //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Expected O, but got Unknown //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Expected O, but got Unknown //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Expected O, but got Unknown //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Expected O, but got Unknown //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Expected O, but got Unknown //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Expected O, but got Unknown //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Expected O, but got Unknown //IL_00a5: 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_0095: Expected O, but got Unknown //IL_0090: Unknown result type (might be due to invalid IL or missing references) Type settingType = entry.SettingType; object obj; if (!(settingType == typeof(float))) { obj = ((!(settingType == typeof(string))) ? ((!(settingType == typeof(bool))) ? ((!(settingType == typeof(int))) ? ((!(settingType == typeof(Color))) ? ((!(settingType == typeof(KeyboardShortcut))) ? ((object)((!settingType.IsEnum) ? ((ChoiceOption)null) : new ChoiceOption(entry, new ChoiceConfig()))) : ((object)new KeyBindOption((ConfigEntry<KeyboardShortcut>)(object)entry, new KeyBindConfig()))) : ((object)new ColorOption((ConfigEntry<Color>)(object)entry, new ColorOptionConfig()))) : ((object)new IntFieldOption((ConfigEntry<int>)(object)entry, new IntFieldConfig()))) : ((object)new CheckBoxOption((ConfigEntry<bool>)(object)entry, new CheckBoxConfig()))) : ((object)new StringInputFieldOption((ConfigEntry<string>)(object)entry, new InputFieldConfig { submitOn = (SubmitEnum)6, lineType = (LineType)0 }))); } else if (entry.Description.AcceptableValues is AcceptableValueRange<float>) { obj = (object)new SliderOption((ConfigEntry<float>)(object)entry, new SliderConfig { min = ((AcceptableValueRange<float>)(object)entry.Description.AcceptableValues).MinValue, max = ((AcceptableValueRange<float>)(object)entry.Description.AcceptableValues).MaxValue, FormatString = "{0:f2}", description = entry.DescWithDefault("{0:f2}") }); } else { ConfigEntry<float> obj2 = (ConfigEntry<float>)(object)entry; FloatFieldConfig val = new FloatFieldConfig(); ((NumericFieldConfig<float>)val).FormatString = "{0:f2}"; ((BaseOptionConfig)val).description = entry.DescWithDefault("{0:f2}"); obj = (object)new FloatFieldOption(obj2, val); } BaseOption val2 = (BaseOption)obj; if (val2 == null) { return; } BaseOptionConfig config = val2.GetConfig(); config.category = categoryName; config.name = name; config.restartRequired = restartRequired; if (config.description == "") { config.description = entry.DescWithDefault(); } try { ModSettingsManager.AddOption(val2); } catch (Exception arg) { log.error($"AddOption {entry.Definition} failed\n{arg}"); } } [MethodImpl(MethodImplOptions.NoInlining)] internal static void AddOption(ConfigEntry<float> entry, float min, float max, string format = "{0:f2}", string categoryName = "") { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Expected O, but got Unknown ModSettingsManager.AddOption((BaseOption)new SliderOption(entry, new SliderConfig { min = min, max = max, FormatString = format, category = categoryName, description = ((ConfigEntryBase)(object)entry).DescWithDefault(format) })); } [MethodImpl(MethodImplOptions.NoInlining)] internal static void AddIntSlider(ConfigEntry<int> entry, int min, int max, string categoryName = "") { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown ModSettingsManager.AddOption((BaseOption)new IntSliderOption(entry, new IntSliderConfig { min = min, max = max, category = categoryName, description = ((ConfigEntryBase)(object)entry).DescWithDefault() })); } private static string DescWithDefault(this ConfigEntryBase entry, string format = "{0}") { return string.Format("{1}\n[Default: " + format + "]", entry.DefaultValue, entry.Description.Description); } } } namespace UncapAttackSpeed { internal class AttackFraction { internal static FixedConditionalWeakTable<BaseSkillInstanceData, AttackFraction> skillInstanceToAttackFraction = new FixedConditionalWeakTable<BaseSkillInstanceData, AttackFraction>(); public float attackFraction; public static AttackFraction Constructor(object _) { return new AttackFraction(); } } internal static class Commando { internal const float baseDuration = 0.1666f; private static bool interrupt; internal static void DoSetup() { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown HookManager.Hook(typeof(FirePistol2).GetMethod("FixedUpdate"), new Manipulator(IL_FirePistol2_FixedUpdate_ExtraAttacks)); HookManager.Hook((MethodBase)typeof(FirePistol2).GetMethod("GetMinimumInterruptPriority"), (Delegate)new Func<Func<FirePistol2, InterruptPriority>, FirePistol2, InterruptPriority>(On_FirePistol2_Priority_AfterDuration)); Utilities.DoAddressable<EntityStateConfiguration>("RoR2/Base/Commando/EntityStates.Commando.CommandoWeapon.FirePistol2.asset", (Action<EntityStateConfiguration>)delegate(EntityStateConfiguration a) { a.ModifyStateConfig("baseDuration", 0.1666f); }, release: false); } private static void IL_FirePistol2_FixedUpdate_ExtraAttacks(ILContext il) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il); if (!val.TryGotoNext(new Func<Instruction, bool>[3] { (Instruction a) => ILPatternMatchingExt.MatchLdarg(a, 0), (Instruction a) => ILPatternMatchingExt.MatchCallOrCallvirt<BaseSkillState>(a, "get_activatorSkillSlot"), (Instruction a) => ILPatternMatchingExt.MatchCallOrCallvirt<GenericSkill>(a, "get_stock") })) { val.LogErrorCaller("commando state transition"); return; } val.Emit(OpCodes.Ldarg_0); val.EmitDelegate<Func<FirePistol2, bool>>((Func<FirePistol2, bool>)delegate(FirePistol2 self) { if (((BaseSkillState)self).IsKeyDownAuthority()) { BaseSkillInstanceData skillInstanceData = ((BaseSkillState)self).activatorSkillSlot.skillInstanceData; InstanceData val2 = (InstanceData)(object)((skillInstanceData is InstanceData) ? skillInstanceData : null); if (val2 != null) { float num = ((EntityState)self).fixedAge - self.duration; while (num >= self.duration) { num -= self.duration; Main.extraAttacks = 1; val2.step++; if (val2.step >= 2) { val2.step = 0; } if (val2.step % 2 == 0) { ((EntityState)self).PlayAnimation("Gesture Additive, Left", FirePistol2.FirePistolLeftStateHash); self.FireBullet("MuzzleLeft"); } else { ((EntityState)self).PlayAnimation("Gesture Additive, Right", FirePistol2.FirePistolRightStateHash); self.FireBullet("MuzzleRight"); } Main.extraAttacks = 0; } interrupt = true; ((BaseSkillState)self).activatorSkillSlot.OnExecute(); interrupt = false; EntityState nextState = ((EntityState)self).outer.nextState; FirePistol2 val3 = (FirePistol2)(object)((nextState is FirePistol2) ? nextState : null); if (val3 != null) { ((EntityState)val3).fixedAge = num; } return true; } } return false; }); val.Emit(OpCodes.Brfalse, val.Next); val.Emit(OpCodes.Ret); } private static InterruptPriority On_FirePistol2_Priority_AfterDuration(Func<FirePistol2, InterruptPriority> orig, FirePistol2 self) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) if (!interrupt) { return orig(self); } return (InterruptPriority)0; } } internal static class Config { private static ConfigFile configFile; internal static ConfigEntry<bool> nailgunFinalBurst; internal static ConfigEntry<EffectsFlags> disableExtraEffects; internal static void DoConfig(ConfigFile bepConfigFile) { configFile = bepConfigFile; nailgunFinalBurst = configFile.Bind<bool>("", "Nailgun Final Burst", false, "If should force Nailgun to always fire its final burst exactly once."); disableExtraEffects = configFile.Bind<EffectsFlags>("", "Disable extra effects", EffectsFlags.None, "Effects chosen here will be hidden for extra attacks generated by this mod"); if (RiskofOptions.enabled) { DoRiskOfOptions(); } } internal static void DoRiskOfOptions() { RiskofOptions.SetSpriteDefaultIcon(); RiskofOptions.AddOption((ConfigEntryBase)(object)nailgunFinalBurst); RiskofOptions.AddOption((ConfigEntryBase)(object)disableExtraEffects); } [ConCommand(/*Could not decode attribute arguments.*/)] private static void ReloadConfig(ConCommandArgs args) { configFile.Reload(); Debug.Log((object)"UncapAttackSpeed config reloaded"); } } [Flags] internal enum EffectsFlags { None = 0, Tracers = 1, Impacts = 2 } internal static class Huntress { internal const float sbaseDuration = 0.5166f; internal const float fbaseDuration = 1.3333f; private static bool interrupt; internal static void DoSetup() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown HookManager.Hook(typeof(FireSeekingArrow), "FixedUpdate", new Manipulator(IL_FireSeekingArrow_FixedUpdate_Stuff)); HookManager.Hook(typeof(FireSeekingArrow), "GetMinimumInterruptPriority", (Delegate)new Func<Func<FireSeekingArrow, InterruptPriority>, FireSeekingArrow, InterruptPriority>(On_FireSeekingArrow_Priority_AfterDuration)); HookManager.Hook(typeof(FireSeekingArrow), "OnExit", (Delegate)new Action<Action<FireSeekingArrow>, FireSeekingArrow>(On_FireSeekingArrow_OnExit_Excess)); HookManager.Hook(typeof(HuntressArrowOrb), "GetOrbEffect", (Delegate)(Func<Func<HuntressArrowOrb, GameObject>, HuntressArrowOrb, GameObject>)((Func<HuntressArrowOrb, GameObject> orig, HuntressArrowOrb self) => (Main.extraAttacks == 0) ? orig(self) : null)); HookManager.Hook(typeof(HuntressFlurryArrowOrb), "GetOrbEffect", (Delegate)(Func<Func<HuntressFlurryArrowOrb, GameObject>, HuntressFlurryArrowOrb, GameObject>)((Func<HuntressFlurryArrowOrb, GameObject> orig, HuntressFlurryArrowOrb self) => (Main.extraAttacks == 0) ? orig(self) : null)); Utilities.DoAddressable<EntityStateConfiguration>("RoR2/Base/Huntress/EntityStates.Huntress.HuntressWeapon.FireSeekingArrow.asset", (Action<EntityStateConfiguration>)delegate(EntityStateConfiguration a) { a.ModifyStateConfig("baseDuration", 0.5166f); }, release: false); Utilities.DoAddressable<EntityStateConfiguration>("RoR2/Base/Huntress/EntityStates.Huntress.HuntressWeapon.FireFlurrySeekingArrow.asset", (Action<EntityStateConfiguration>)delegate(EntityStateConfiguration a) { a.ModifyStateConfig("baseDuration", 1.3333f); }, release: false); } private static void IL_FireSeekingArrow_FixedUpdate_Stuff(ILContext context) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_01f4: Unknown result type (might be due to invalid IL or missing references) //IL_0206: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(context); ILCursor[] array = default(ILCursor[]); if (val.TryGotoNext(new Func<Instruction, bool>[2] { (Instruction a) => ILPatternMatchingExt.MatchLdarg(a, 0), (Instruction a) => ILPatternMatchingExt.MatchLdfld(a, typeof(FireSeekingArrow), "animator") }) && val.TryFindNext(ref array, new Func<Instruction, bool>[1] { (Instruction a) => ILPatternMatchingExt.MatchCall(a, typeof(FireSeekingArrow), "FireOrbArrow") })) { val.Emit(OpCodes.Ldarg_0); val.EmitDelegate<Func<FireSeekingArrow, bool>>((Func<FireSeekingArrow, bool>)((FireSeekingArrow self) => ((EntityState)self).fixedAge >= self.duration / 2f)); ILCursor val2 = array[0]; if (val2.TryGotoPrev(new Func<Instruction, bool>[1] { (Instruction a) => ILPatternMatchingExt.MatchLdarg(a, 0) })) { val.Emit(OpCodes.Brtrue, (object)val2.MarkLabel()); if (val2.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1] { (Instruction a) => ILPatternMatchingExt.MatchCall(a, typeof(FireSeekingArrow), "FireOrbArrow") })) { val.Emit(OpCodes.Br, (object)val2.MarkLabel()); goto IL_015e; } } } log.error($"Failed to find IL FireSeekingArrow_FixedUpdate duration\n{val}"); goto IL_015e; IL_015e: if (val.TryGotoNext(new Func<Instruction, bool>[1] { (Instruction a) => ILPatternMatchingExt.MatchCallOrCallvirt(a, typeof(EntityStateMachine), "SetNextStateToMain") }) && val.TryGotoPrev(new Func<Instruction, bool>[1] { (Instruction a) => ILPatternMatchingExt.MatchLdarg(a, 0) })) { val.Emit(OpCodes.Ldarg_0); val.EmitDelegate<Func<FireSeekingArrow, bool>>((Func<FireSeekingArrow, bool>)delegate(FireSeekingArrow self) { if (!((EntityState)self).inputBank.skill1.down || !Object.op_Implicit((Object)(object)self.huntressTracker) || !Object.op_Implicit((Object)(object)self.huntressTracker.GetTrackingTarget())) { return false; } interrupt = true; ((EntityState)self).skillLocator.primary.OnExecute(); interrupt = false; return true; }); val.Emit(OpCodes.Brfalse, val.Next); val.Emit(OpCodes.Ret); } else { log.error($"Failed to find IL FireSeekingArrow_FixedUpdate nextState\n{val}"); } } private static void On_FireSeekingArrow_OnExit_Excess(Action<FireSeekingArrow> orig, FireSeekingArrow self) { orig(self); if (!NetworkServer.active) { return; } while (self.firedArrowCount < self.maxArrowCount) { FireExcess(self); } BaseSkillInstanceData skillInstanceData = ((EntityState)self).skillLocator.primary.skillInstanceData; if (skillInstanceData == null) { return; } AttackFraction value = AttackFraction.skillInstanceToAttackFraction.GetValue(skillInstanceData, (Func<BaseSkillInstanceData, AttackFraction>)AttackFraction.Constructor); float num; for (num = (((EntityState)self).fixedAge - self.duration) / self.duration + value.attackFraction; num >= 1f; num -= 1f) { for (int i = 0; i < self.maxArrowCount; i++) { self.firedArrowCount--; FireExcess(self); } } value.attackFraction = num; } private static void FireExcess(FireSeekingArrow self) { self.arrowReloadTimer = 0f; Main.extraAttacks = 1; self.FireOrbArrow(); Main.extraAttacks = 0; } private static InterruptPriority On_FireSeekingArrow_Priority_AfterDuration(Func<FireSeekingArrow, InterruptPriority> orig, FireSeekingArrow self) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) if (!interrupt) { return orig(self); } return (InterruptPriority)0; } } [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("dolso.uncapattackspeed", "UncapAttackSpeed", "2.0.4")] public class Main : BaseUnityPlugin { public static int extraAttacks; private void Awake() { Config.DoConfig(((BaseUnityPlugin)this).Config); Commando.DoSetup(); Nailgun.DoSetup(); VoidFiend.DoSetup(); Huntress.DoSetup(); Config.disableExtraEffects.HookConfig((EffectsFlags a) => a != EffectsFlags.None, typeof(BulletAttack), "FireSingle", new Action<Action<BulletAttack, FireSingleArgs>, BulletAttack, FireSingleArgs>(On_BulletAttack_FireSingle_RemoveTracer)); HookManager.Hook(typeof(BaseState), "AddRecoil", (Delegate)new Action<Action<BaseState, float, float, float, float>, BaseState, float, float, float, float>(On_BaseState_AddRecoil_RemoveRecoil)); } private static void On_BulletAttack_FireSingle_RemoveTracer(Action<BulletAttack, FireSingleArgs> orig, BulletAttack self, FireSingleArgs args) { //IL_0066: 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) if (extraAttacks > 0) { EffectsFlags value = Config.disableExtraEffects.Value; extraAttacks--; GameObject tracerEffectPrefab = self.tracerEffectPrefab; GameObject hitEffectPrefab = self.hitEffectPrefab; if ((value & EffectsFlags.Tracers) != 0) { self.tracerEffectPrefab = null; } if ((value & EffectsFlags.Impacts) != 0) { self.hitEffectPrefab = null; } orig(self, args); if ((value & EffectsFlags.Tracers) != 0) { self.tracerEffectPrefab = tracerEffectPrefab; } if ((value & EffectsFlags.Impacts) != 0) { self.hitEffectPrefab = hitEffectPrefab; } } else { orig(self, args); } } private static void On_BaseState_AddRecoil_RemoveRecoil(Action<BaseState, float, float, float, float> orig, BaseState self, float verticalMin, float verticalMax, float horizontalMin, float horizontalMax) { if (extraAttacks == 0) { orig(self, verticalMin, verticalMax, horizontalMin, horizontalMax); } } } internal static class Nailgun { private static List<FireNailgun> nailgunInstances = new List<FireNailgun>(); internal static void DoSetup() { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown HookManager.Hook(typeof(FireNailgun).GetMethod("FixedUpdate"), new Manipulator(IL_FireNailgun_FixedUpdate_ExtraAttacks)); HookManager.Hook((MethodBase)typeof(FireNailgun).GetMethod("OnExit"), (Delegate)new Action<Action<FireNailgun>, FireNailgun>(On_FireNailgun_OnExit_ForceBurst)); HookManager.Hook((MethodBase)typeof(FireNailgun).GetMethod("OnEnter"), (Delegate)new Action<Action<FireNailgun>, FireNailgun>(On_FireNailgun_OnEnter_Track)); } private static void IL_FireNailgun_FixedUpdate_ExtraAttacks(ILContext il) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_014e: 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) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il); int num2 = default(int); if (val.TryGotoNext(new Func<Instruction, bool>[1] { (Instruction a) => ILPatternMatchingExt.MatchCallOrCallvirt<BaseNailgunState>(a, "FireBullet") }) && val.TryGotoPrev((MoveType)2, new Func<Instruction, bool>[1] { (Instruction a) => ILPatternMatchingExt.MatchLdcI4(a, ref num2) })) { val.Emit(OpCodes.Ldarg, 0); val.EmitDelegate<Func<FireNailgun, int>>((Func<FireNailgun, int>)delegate(FireNailgun self) { int num = Mathf.FloorToInt(self.refireStopwatch / ((BaseNailgunState)self).duration); if (num > 0) { self.refireStopwatch -= (float)num * ((BaseNailgunState)self).duration; Main.extraAttacks = num; return num; } return 0; }); val.Emit(OpCodes.Add); if (val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1] { (Instruction a) => ILPatternMatchingExt.MatchCallOrCallvirt<BaseNailgunState>(a, "FireBullet") })) { val.Emit(OpCodes.Ldc_I4, 0); val.Emit(OpCodes.Stsfld, typeof(Main).GetField("extraAttacks")); } else { log.error($"Failed to find BaseNailgunState.FireBullet\n{val}"); } if (val.TryGotoNext(new Func<Instruction, bool>[1] { (Instruction a) => ILPatternMatchingExt.MatchCallOrCallvirt<EntityStateMachine>(a, "SetNextState") })) { val.Emit(OpCodes.Ldsfld, typeof(Nailgun).GetField("nailgunInstances", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)); val.Emit(OpCodes.Ldarg, 0); val.Emit<List<FireNailgun>>(OpCodes.Call, "Remove"); val.Emit(OpCodes.Pop); return; } } log.error($"Failed IL hook Nailgun\n{val}"); } private static void On_FireNailgun_OnEnter_Track(Action<FireNailgun> orig, FireNailgun self) { orig(self); nailgunInstances.Add(self); } private static void On_FireNailgun_OnExit_ForceBurst(Action<FireNailgun> orig, FireNailgun self) { //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) orig(self); if (!nailgunInstances.Contains(self)) { return; } nailgunInstances.Remove(self); if (Config.nailgunFinalBurst.Value) { Util.PlayAttackSpeedSound(NailgunSpinDown.spinDownSound, ((EntityState)self).gameObject, ((BaseState)self).attackSpeedStat); ((EntityState)self).characterBody.SetSpreadBloom(1f, false); Ray aimRay = ((BaseState)self).GetAimRay(); ((BaseNailgunState)self).FireBullet(((BaseState)self).GetAimRay(), NailgunFinalBurst.finalBurstBulletCount, BaseNailgunState.spreadPitchScale, BaseNailgunState.spreadYawScale); if (!((BaseToolbotPrimarySkillState)self).isInDualWield) { ((EntityState)self).PlayAnimation("Gesture, Additive", "FireGrenadeLauncher", "FireGrenadeLauncher.playbackRate", 0.45f / ((BaseState)self).attackSpeedStat, 0f); } else { BaseToolbotPrimarySkillStateMethods.PlayGenericFireAnim<FireNailgun>(self, ((EntityState)self).gameObject, ((EntityState)self).skillLocator, 0.45f / ((BaseState)self).attackSpeedStat); } Util.PlaySound(NailgunFinalBurst.burstSound, ((EntityState)self).gameObject); if (((EntityState)self).isAuthority) { float num = NailgunFinalBurst.selfForce * (((EntityState)self).characterMotor.isGrounded ? 0.5f : 1f) * ((EntityState)self).characterMotor.mass; ((EntityState)self).characterMotor.ApplyForce(((Ray)(ref aimRay)).direction * (0f - num), false, false); } Util.PlaySound(BaseNailgunState.fireSoundString, ((EntityState)self).gameObject); Util.PlaySound(BaseNailgunState.fireSoundString, ((EntityState)self).gameObject); Util.PlaySound(BaseNailgunState.fireSoundString, ((EntityState)self).gameObject); } } } internal static class VoidFiend { internal const float baseDuration = 7.5f; internal static void DoSetup() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown HookManager.Hook(typeof(FireCorruptHandBeam), "FixedUpdate", new Manipulator(IL_FireCorruptHandBeam_FixedUpdate_ExtraAttacks)); HookManager.Hook(typeof(FireCorruptHandBeam), "FireBullet", (Delegate)new Action<Action<FireCorruptHandBeam>, FireCorruptHandBeam>(On_FireCorruptHandBeam_FireBullet_RemoveEffects)); Utilities.DoAddressable<EntityStateConfiguration>("RoR2/DLC1/VoidSurvivor/EntityStates.VoidSurvivor.Weapon.FireCorruptHandBeam.asset", (Action<EntityStateConfiguration>)delegate(EntityStateConfiguration a) { a.ModifyStateConfig("tickRate", 7.5f); }, release: false); } private static void IL_FireCorruptHandBeam_FixedUpdate_ExtraAttacks(ILContext il) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il); float num = default(float); if (val.TryGotoNext(new Func<Instruction, bool>[3] { (Instruction a) => ILPatternMatchingExt.MatchLdarg(a, 0), (Instruction a) => ILPatternMatchingExt.MatchLdfld(a, typeof(FireCorruptHandBeam), "fireCountdown"), (Instruction a) => ILPatternMatchingExt.MatchLdcR4(a, ref num) })) { ILLabel val2 = val.MarkLabel(); if (val.TryGotoNext(new Func<Instruction, bool>[1] { (Instruction a) => ILPatternMatchingExt.MatchStfld(a, typeof(FireCorruptHandBeam), "fireCountdown") })) { val.Emit(OpCodes.Ldarg_0); val.Emit<FireCorruptHandBeam>(OpCodes.Ldfld, "fireCountdown"); val.Emit(OpCodes.Add); if (val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1] { (Instruction a) => ILPatternMatchingExt.MatchCallOrCallvirt(a, typeof(FireCorruptHandBeam), "FireBullet") })) { val.Emit(OpCodes.Br, (object)val2); return; } } } log.error($"Failed to find IL for IL_FireCorruptHandBeam_FixedUpdate_ExtraAttacks\n{val}"); } private static void On_FireCorruptHandBeam_FireBullet_RemoveEffects(Action<FireCorruptHandBeam> orig, FireCorruptHandBeam self) { if (self.fireCountdown <= 0f) { Main.extraAttacks = 1; orig(self); Main.extraAttacks = 0; } else { orig(self); } } } }