Decompiled source of Entity States Configurator v1.0.0

plugins/EntityStatesConfigurator.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using EntityStates;
using HG.Coroutines;
using HG.Reflection;
using Microsoft.CodeAnalysis;
using Mono.Cecil.Cil;
using MonoMod.Cil;
using MonoMod.RuntimeDetour;
using MonoMod.Utils;
using On.RoR2;
using RiskOfOptions;
using RiskOfOptions.Options;
using RoR2;
using RoR2.ContentManagement;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: OptIn]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("EntityStatesConfigurator")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("EntityStatesConfigurator")]
[assembly: AssemblyTitle("EntityStatesConfigurator")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace EntityStatesConfigurator
{
	[Serializable]
	[BepInPlugin("com.brynzananas.entitystatesconfigurator", "Entity States Configurator", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class EntityStatesConfiguratorPlugin : BaseUnityPlugin
	{
		private class DisplayClass<T>
		{
			public string name;

			private bool isFloat;

			public DisplayClass(ILContext iLContext, MethodInfo methodInfo, string name)
			{
				this.name = name;
				isFloat = typeof(T) == typeof(float);
				try
				{
					Handle<T>(iLContext, methodInfo);
				}
				catch
				{
				}
			}

			private void Handle<T>(ILContext iLContext, MethodInfo methodInfo)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0008: Expected O, but got Unknown
				//IL_009a: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a4: Expected O, but got Unknown
				//IL_009f: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a6: Expected O, but got Unknown
				ILCursor val = new ILCursor(iLContext);
				if (val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[2]
				{
					(Instruction x) => ILPatternMatchingExt.MatchCall<EntityState>(x, "get_characterBody"),
					(Instruction x) => ILPatternMatchingExt.MatchCallvirt<CharacterBody>(x, "get_" + name)
				}))
				{
					Type declaringType = methodInfo.DeclaringType;
					if (isFloat)
					{
						ConfigEntry<float> val2 = CreateConfig(declaringType, name, 1f, "", enableRiskOfOptions: true);
					}
					else
					{
						ConfigEntry<int> val3 = CreateConfig(declaringType, name, 1, "", enableRiskOfOptions: true);
					}
					try
					{
						ILHook val4 = new ILHook((MethodBase)methodInfo, new Manipulator(Handle2));
					}
					catch
					{
					}
				}
			}

			private void Handle2(ILContext iLContext)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0008: Expected O, but got Unknown
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				ILCursor val = new ILCursor(iLContext);
				while (val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[2]
				{
					(Instruction x) => ILPatternMatchingExt.MatchCall<EntityState>(x, "get_characterBody"),
					(Instruction x) => ILPatternMatchingExt.MatchCallvirt<CharacterBody>(x, "get_" + name)
				}))
				{
					val.Emit(OpCodes.Ldarg_0);
					if (isFloat)
					{
						val.EmitDelegate<Func<float, EntityState, float>>((Func<float, EntityState, float>)HandleFloat);
					}
					else
					{
						val.EmitDelegate<Func<int, EntityState, int>>((Func<int, EntityState, int>)HandleInt);
					}
				}
			}

			private float HandleFloat(float value, EntityState entityState)
			{
				Type type = ((object)entityState).GetType();
				if (debug)
				{
					Log.LogMessage((object)("Called " + value + " " + name + " from " + type.Namespace + type.Name));
				}
				if (keyValuePairs.TryGetValue(type, out var value2) && value2.TryGetValue(name, out var value3))
				{
					ConfigEntry<float> val = value3 as ConfigEntry<float>;
					value *= val.Value;
				}
				return value;
			}

			private int HandleInt(int value, EntityState entityState)
			{
				Type type = ((object)entityState).GetType();
				if (keyValuePairs.TryGetValue(type, out var value2) && value2.TryGetValue(name, out var value3))
				{
					ConfigEntry<int> val = value3 as ConfigEntry<int>;
					value *= val.Value;
				}
				return value;
			}
		}

		private class DisplayClassStat
		{
			public string name;

			public string name2;

			public DisplayClassStat(ILContext iLContext, MethodInfo methodInfo, string name, string name2)
			{
				this.name = name;
				this.name2 = name2;
				try
				{
					Handle(iLContext, methodInfo);
				}
				catch
				{
				}
			}

			private void Handle(ILContext iLContext, MethodInfo methodInfo)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0008: Expected O, but got Unknown
				//IL_0073: Unknown result type (might be due to invalid IL or missing references)
				//IL_007d: Expected O, but got Unknown
				//IL_0078: Unknown result type (might be due to invalid IL or missing references)
				//IL_007f: Expected O, but got Unknown
				ILCursor val = new ILCursor(iLContext);
				if (val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[2]
				{
					(Instruction x) => ILPatternMatchingExt.MatchLdarg(x, 0),
					(Instruction x) => ILPatternMatchingExt.MatchLdfld<BaseState>(x, name)
				}))
				{
					Type declaringType = methodInfo.DeclaringType;
					ConfigEntry<float> val2 = CreateConfig(declaringType, name2, 1f, "", enableRiskOfOptions: true);
					try
					{
						ILHook val3 = new ILHook((MethodBase)methodInfo, new Manipulator(Handle2));
					}
					catch
					{
					}
				}
			}

			private void Handle2(ILContext iLContext)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0008: Expected O, but got Unknown
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				ILCursor val = new ILCursor(iLContext);
				while (val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[2]
				{
					(Instruction x) => ILPatternMatchingExt.MatchLdarg(x, 0),
					(Instruction x) => ILPatternMatchingExt.MatchLdfld<BaseState>(x, name)
				}))
				{
					val.Emit(OpCodes.Ldarg_0);
					val.EmitDelegate<Func<float, EntityState, float>>((Func<float, EntityState, float>)Handle3);
				}
			}

			private float Handle3(float value, EntityState entityState)
			{
				Type type = ((object)entityState).GetType();
				if (debug)
				{
					Log.LogMessage((object)("Called " + value + " " + name + " from " + type.Namespace + type.Name));
				}
				if (keyValuePairs.TryGetValue(type, out var value2) && value2.TryGetValue(name, out var value3))
				{
					ConfigEntry<float> val = value3 as ConfigEntry<float>;
					value *= val.Value;
				}
				return value;
			}
		}

		[CompilerGenerated]
		private static class <>O
		{
			public static hook_SetState <0>__EntityStateMachine_SetState;
		}

		[CompilerGenerated]
		private sealed class <>c__DisplayClass25_0
		{
			public ParallelCoroutine loadCoroutine;

			public Stopwatch stopwatch;
		}

		[CompilerGenerated]
		private sealed class <Thread>d__26 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			private Type[] <>s__1;

			private int <>s__2;

			private Type <type2>5__3;

			private MethodInfo[] <methodInfos>5__4;

			private MethodInfo[] <>s__5;

			private int <>s__6;

			private MethodInfo <methodInfo>5__7;

			private DynamicMethodDefinition <dmd>5__8;

			private ILContext <il>5__9;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <Thread>d__26(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>s__1 = null;
				<type2>5__3 = null;
				<methodInfos>5__4 = null;
				<>s__5 = null;
				<methodInfo>5__7 = null;
				<dmd>5__8 = null;
				<il>5__9 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0112: Unknown result type (might be due to invalid IL or missing references)
				//IL_011c: Expected O, but got Unknown
				//IL_0128: Unknown result type (might be due to invalid IL or missing references)
				//IL_0132: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>s__1 = ContentManager.entityStateTypes;
					for (<>s__2 = 0; <>s__2 < <>s__1.Length; <>s__2++)
					{
						<type2>5__3 = <>s__1[<>s__2];
						<methodInfos>5__4 = <type2>5__3.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.GetProperty | BindingFlags.SetProperty);
						try
						{
							<>s__5 = <methodInfos>5__4;
							for (<>s__6 = 0; <>s__6 < <>s__5.Length; <>s__6++)
							{
								<methodInfo>5__7 = <>s__5[<>s__6];
								if (!<methodInfo>5__7.ContainsGenericParameters && !<methodInfo>5__7.IsGenericMethod && !<methodInfo>5__7.IsConstructedGenericMethod && !<methodInfo>5__7.IsGenericMethodDefinition && !methodInfos.Contains(<methodInfo>5__7))
								{
									methodInfos.Add(<methodInfo>5__7);
									if (<methodInfo>5__7.GetMethodBody() != null)
									{
										<dmd>5__8 = new DynamicMethodDefinition((MethodBase)<methodInfo>5__7);
										<il>5__9 = new ILContext(<dmd>5__8.Definition);
										new DisplayClass<float>(<il>5__9, <methodInfo>5__7, "maxHealth");
										new DisplayClass<float>(<il>5__9, <methodInfo>5__7, "maxBarrier");
										new DisplayClass<float>(<il>5__9, <methodInfo>5__7, "regen");
										new DisplayClass<float>(<il>5__9, <methodInfo>5__7, "maxShield");
										new DisplayClass<float>(<il>5__9, <methodInfo>5__7, "moveSpeed");
										new DisplayClassStat(<il>5__9, <methodInfo>5__7, "moveSpeedStat", "moveSpeed");
										new DisplayClass<float>(<il>5__9, <methodInfo>5__7, "acceleration");
										new DisplayClass<float>(<il>5__9, <methodInfo>5__7, "jumpPower");
										new DisplayClass<int>(<il>5__9, <methodInfo>5__7, "maxJumpCount");
										new DisplayClass<float>(<il>5__9, <methodInfo>5__7, "maxJumpHeight");
										new DisplayClass<float>(<il>5__9, <methodInfo>5__7, "damage");
										new DisplayClassStat(<il>5__9, <methodInfo>5__7, "damageStat", "damage");
										new DisplayClass<float>(<il>5__9, <methodInfo>5__7, "attackSpeed");
										new DisplayClassStat(<il>5__9, <methodInfo>5__7, "attackSpeedStat", "attackSpeed");
										new DisplayClass<float>(<il>5__9, <methodInfo>5__7, "crit");
										new DisplayClassStat(<il>5__9, <methodInfo>5__7, "critStat", "crit");
										new DisplayClass<float>(<il>5__9, <methodInfo>5__7, "critMultiplier");
										new DisplayClass<float>(<il>5__9, <methodInfo>5__7, "bleedChance");
										new DisplayClass<float>(<il>5__9, <methodInfo>5__7, "armor");
										new DisplayClass<float>(<il>5__9, <methodInfo>5__7, "critHeal");
										<dmd>5__8 = null;
										<il>5__9 = null;
										<methodInfo>5__7 = null;
									}
								}
							}
							<>s__5 = null;
						}
						catch
						{
						}
						<methodInfos>5__4 = null;
						<type2>5__3 = null;
					}
					<>s__1 = null;
					<>2__current = null;
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		public const string ModGuid = "com.brynzananas.entitystatesconfigurator";

		public const string ModName = "Entity States Configurator";

		public const string ModVer = "1.0.0";

		public static HashSet<MethodInfo> methodInfos = new HashSet<MethodInfo>();

		public static Dictionary<Type, string> names = new Dictionary<Type, string>();

		public static Dictionary<Type, Dictionary<string, ConfigEntryBase>> keyValuePairs = new Dictionary<Type, Dictionary<string, ConfigEntryBase>>();

		private static bool _debug;

		private static char[] forbiddenCharacters = new char[6] { '\n', '\t', '"', '\'', '[', ']' };

		public static ManualLogSource Log { get; private set; }

		public static ConfigFile configFile { get; private set; }

		public static bool riskOfOptionsEnabled { get; private set; }

		public static bool debug
		{
			get
			{
				return _debug;
			}
			set
			{
				//IL_0050: Unknown result type (might be due to invalid IL or missing references)
				//IL_0055: Unknown result type (might be due to invalid IL or missing references)
				//IL_005b: Expected O, but got Unknown
				//IL_002b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: Unknown result type (might be due to invalid IL or missing references)
				//IL_0036: Expected O, but got Unknown
				if (value == _debug)
				{
					return;
				}
				_debug = value;
				if (value)
				{
					object obj = <>O.<0>__EntityStateMachine_SetState;
					if (obj == null)
					{
						hook_SetState val = EntityStateMachine_SetState;
						<>O.<0>__EntityStateMachine_SetState = val;
						obj = (object)val;
					}
					EntityStateMachine.SetState += (hook_SetState)obj;
				}
				else
				{
					object obj2 = <>O.<0>__EntityStateMachine_SetState;
					if (obj2 == null)
					{
						hook_SetState val2 = EntityStateMachine_SetState;
						<>O.<0>__EntityStateMachine_SetState = val2;
						obj2 = (object)val2;
					}
					EntityStateMachine.SetState -= (hook_SetState)obj2;
				}
			}
		}

		private static void EntityStateMachine_SetState(orig_SetState orig, EntityStateMachine self, EntityState newState)
		{
			orig.Invoke(self, newState);
			Log.LogMessage((object)("Set state for " + ((object)self)?.ToString() + " to " + (object)newState));
		}

		[ConCommand(/*Could not decode attribute arguments.*/)]
		public static void CCDebug(ConCommandArgs args)
		{
			debug = ((ConCommandArgs)(ref args)).GetArgBool(0);
			if (debug)
			{
				Log.LogMessage((object)"Enabled debug");
			}
			else
			{
				Log.LogMessage((object)"Disabled debug");
			}
		}

		public void Awake()
		{
			Log = ((BaseUnityPlugin)this).Logger;
			configFile = ((BaseUnityPlugin)this).Config;
			riskOfOptionsEnabled = Chainloader.PluginInfos.ContainsKey("com.rune580.riskofoptions");
			RoR2Application.onLoadFinished = (Action)Delegate.Combine(RoR2Application.onLoadFinished, new Action(OnLoadFinished));
		}

		private void OnLoadFinished()
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			<>c__DisplayClass25_0 CS$<>8__locals0 = new <>c__DisplayClass25_0();
			configFile.SaveOnConfigSet = false;
			Log.LogMessage((object)"Begin configuring entity states");
			CS$<>8__locals0.stopwatch = Stopwatch.StartNew();
			CS$<>8__locals0.loadCoroutine = new ParallelCoroutine();
			CS$<>8__locals0.loadCoroutine.Add(Thread());
			((MonoBehaviour)RoR2Application.instance).StartCoroutine(runLoadCoroutine());
			[IteratorStateMachine(typeof(<>c__DisplayClass25_0.<<OnLoadFinished>g__runLoadCoroutine|0>d))]
			IEnumerator runLoadCoroutine()
			{
				//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
				return new <>c__DisplayClass25_0.<<OnLoadFinished>g__runLoadCoroutine|0>d(0)
				{
					<>4__this = CS$<>8__locals0
				};
			}
		}

		[IteratorStateMachine(typeof(<Thread>d__26))]
		private static IEnumerator Thread()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <Thread>d__26(0);
		}

		private static string HandleString(string @string, Type type)
		{
			if (Utility.IsNullOrWhiteSpace(@string))
			{
				return @string;
			}
			char[] array = forbiddenCharacters;
			foreach (char c in array)
			{
				while (@string.Contains(c))
				{
					@string = @string.Replace(c, ' ');
				}
			}
			@string.Trim();
			int j;
			for (j = 0; names.ContainsValue(@string + ((j == 0) ? "" : ((object)j))); j++)
			{
			}
			@string += ((j == 0) ? "" : ((object)j));
			names.Add(type, @string);
			return @string;
		}

		private static ConfigEntry<T> CreateConfig<T>(Type type, string key, T defaultValue, string description, bool enableRiskOfOptions)
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Expected O, but got Unknown
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Expected O, but got Unknown
			string text = (names.ContainsKey(type) ? names[type] : HandleString(type.Namespace + "." + type.Name, type));
			if (Utility.IsNullOrWhiteSpace(text))
			{
				return null;
			}
			ConfigDefinition val = new ConfigDefinition(text, key);
			if (keyValuePairs.TryGetValue(type, out var value) && value.TryGetValue(key, out var value2))
			{
				return value2 as ConfigEntry<T>;
			}
			ConfigDescription val2 = new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>());
			ConfigEntry<T> val3 = configFile.Bind<T>(val, defaultValue, val2);
			if (keyValuePairs.ContainsKey(type))
			{
				Dictionary<string, ConfigEntryBase> dictionary = keyValuePairs[type];
				dictionary.Add(key, (ConfigEntryBase)(object)val3);
			}
			else
			{
				Dictionary<string, ConfigEntryBase> dictionary2 = new Dictionary<string, ConfigEntryBase>();
				dictionary2.Add(key, (ConfigEntryBase)(object)val3);
				keyValuePairs.Add(type, dictionary2);
			}
			if (enableRiskOfOptions && riskOfOptionsEnabled)
			{
				ModCompatabilities.RiskOfOptionsCompatability.AddConfig<ConfigEntry<T>>(val3);
			}
			return val3;
		}
	}
	public static class ModCompatabilities
	{
		public static class RiskOfOptionsCompatability
		{
			public const string GUID = "com.rune580.riskofoptions";

			public static void AddConfig<T>(T config) where T : ConfigEntryBase
			{
				//IL_001f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0029: Expected O, but got Unknown
				//IL_0049: Unknown result type (might be due to invalid IL or missing references)
				//IL_0053: Expected O, but got Unknown
				//IL_0073: Unknown result type (might be due to invalid IL or missing references)
				//IL_007d: Expected O, but got Unknown
				//IL_009d: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a7: Expected O, but got Unknown
				if (config is ConfigEntry<float>)
				{
					ModSettingsManager.AddOption((BaseOption)new FloatFieldOption(config as ConfigEntry<float>));
				}
				if (config is ConfigEntry<bool>)
				{
					ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(config as ConfigEntry<bool>));
				}
				if (config is ConfigEntry<int>)
				{
					ModSettingsManager.AddOption((BaseOption)new IntFieldOption(config as ConfigEntry<int>));
				}
				if (config is ConfigEntry<string>)
				{
					ModSettingsManager.AddOption((BaseOption)new StringInputFieldOption(config as ConfigEntry<string>));
				}
			}
		}
	}
}