using 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);
}
}
}
}