Decompiled source of MotorAPI v1.0.1

plugins/MotorAPI.dll

Decompiled a month ago
using System;
using System.Diagnostics;
using System.Linq;
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 Dolso;
using EntityStates;
using EntityStates.GummyClone;
using EntityStates.Headstompers;
using JetBrains.Annotations;
using KinematicCharacterController;
using Mono.Cecil.Cil;
using MonoMod.Cil;
using MonoMod.RuntimeDetour;
using RoR2;
using RoR2.CameraModes;
using RoR2.UI;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.1.0")]
[module: UnverifiableCode]
namespace Dolso
{
	internal static class log
	{
		private static readonly ManualLogSource logger = Logger.CreateLogSource(Assembly.GetExecutingAssembly().GetName().Name);

		internal static void info(object data)
		{
			logger.LogInfo(data);
		}

		internal static void message(object data)
		{
			logger.LogMessage(data);
		}

		internal static void warning(object data)
		{
			logger.LogWarning(data);
		}

		internal static void error(object data)
		{
			logger.LogError(data);
		}

		internal static void fatal(object data)
		{
			logger.LogFatal(data);
		}

		internal static void LogError(this ILCursor c, object data)
		{
			logger.LogError((object)$"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;
				configEntry.SettingChanged += ConfigChanged;
				ConfigChanged(configEntry, null);
			}

			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[] beforeIL = null, string[] beforeOn = null, string[] afterIL = null, string[] afterOn = null)
		{
			ilHookConfig.Before = beforeIL;
			onHookConfig.Before = beforeOn;
			ilHookConfig.After = afterIL;
			onHookConfig.After = afterOn;
		}

		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;
		}
	}
	[MeansImplicitUse]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)]
	internal class HookAttribute : Attribute
	{
		protected readonly MethodInfo from;

		internal HookAttribute(Type typeFrom, string methodFrom)
		{
			from = HookManager.GetMethod(typeFrom, methodFrom);
		}

		internal HookAttribute(Type typeFrom, string methodFrom, params Type[] parameters)
		{
			from = HookManager.GetMethod(typeFrom, methodFrom, parameters);
		}

		internal HookAttribute()
		{
		}

		internal static void ScanAndApply()
		{
			ScanAndApply((from a in Assembly.GetExecutingAssembly().GetTypes()
				where a.GetCustomAttribute<HookAttribute>() != null
				select a).ToArray());
		}

		internal static void ScanAndApply(params Type[] types)
		{
			for (int i = 0; i < types.Length; i++)
			{
				MethodInfo[] methods = types[i].GetMethods(BindingFlags.Static | BindingFlags.NonPublic);
				foreach (MethodInfo methodInfo in methods)
				{
					foreach (HookAttribute customAttribute in methodInfo.GetCustomAttributes<HookAttribute>(inherit: false))
					{
						try
						{
							if (customAttribute.from == null && methodInfo.GetParameters().Length == 0)
							{
								methodInfo.Invoke(null, null);
							}
							else
							{
								customAttribute.Hook(methodInfo);
							}
						}
						catch (Exception e)
						{
							e.LogHookError(customAttribute.from, methodInfo);
						}
					}
				}
			}
		}

		protected virtual void Hook(MethodInfo member)
		{
			IDetour obj = HookManager.ManualDetour(from, member);
			if (obj != null)
			{
				obj.Apply();
			}
		}
	}
}
namespace MotorAPI
{
	[Hook]
	internal static class Hooks
	{
		static Hooks()
		{
			CharacterBody.onBodyAwakeGlobal += SetBodyFields;
			VehicleSeat.onPassengerExitGlobal += InheritVelocity_OnPassengerExitGlobal;
		}

		private static void SetBodyFields(CharacterBody self)
		{
			self.icamera = ((Component)self).GetComponent<ICameraModeProvider>();
			self.imotor = ((Component)self).GetComponent<IMotor>();
		}

		[Hook(typeof(CameraRigController), "set_cameraMode")]
		private static void ReplaceCamera_On_CameraRigController_set_cameraMode(Action<CameraRigController, CameraModeBase> orig, CameraRigController self, CameraModeBase value)
		{
			bool flag;
			if (value == CameraModePlayerBasic.playerBasic)
			{
				flag = false;
			}
			else
			{
				if (value != CameraModePlayerBasic.spectator)
				{
					orig(self, value);
					return;
				}
				flag = true;
			}
			if (Object.op_Implicit((Object)(object)self.nextTarget))
			{
				CharacterBody targetBody = default(CharacterBody);
				if ((Object)(object)self.nextTarget == (Object)(object)self.target)
				{
					targetBody = self.targetBody;
				}
				else
				{
					self.nextTarget.TryGetComponent<CharacterBody>(ref targetBody);
				}
				if (Object.op_Implicit((Object)(object)targetBody) && targetBody.icamera != null && !Object.op_Implicit((Object)(object)targetBody.currentVehicle))
				{
					orig(self, (CameraModeBase)(object)(flag ? targetBody.icamera.spectatorCameraMode : targetBody.icamera.playerCameraMode));
					return;
				}
			}
			orig(self, value);
		}

		[Hook(typeof(CameraRigController), "set_rawScreenShakeDisplacement")]
		private static void DisableScreenShake_On_CameraRigController_set_rawScreenShakeDisplacement(Action<CameraRigController, Vector3> orig, CameraRigController self, Vector3 value)
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			CharacterBody targetBody = self.targetBody;
			if (Object.op_Implicit((Object)(object)targetBody))
			{
				IMotor imotor = targetBody.imotor;
				if (imotor != null && imotor.motorParams.disableScreenShake)
				{
					orig(self, Vector3.zero);
					return;
				}
			}
			orig(self, value);
		}

		[Hook(typeof(FrozenState), "OnEnter")]
		private static void PreserveVelocityAndFixFreeze_IL_FrozenState_OnEnter(ILContext il)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
			ILCursor val = new ILCursor(il);
			VariableDefinition val2 = new VariableDefinition(val.Module.TypeSystem.Boolean);
			val.Body.Variables.Add(val2);
			val.Emit(OpCodes.Ldarg_0);
			val.Emit<EntityState>(OpCodes.Call, "get_characterBody");
			val.EmitMotorParamsBoolean("preventFreezeMomentumDeletion");
			val.Emit(OpCodes.Stloc, val2);
			ILLabel val4 = default(ILLabel);
			if (val.TryGotoNext(new Func<Instruction, bool>[1]
			{
				(Instruction a) => ILPatternMatchingExt.MatchLdfld<FrozenState>(a, "modelAnimator")
			}) && val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1]
			{
				(Instruction a) => ILPatternMatchingExt.MatchBrfalse(a, ref val4)
			}))
			{
				Instruction next = val.Next;
				val.Index -= 1;
				val.Emit(OpCodes.Brtrue, next);
				val.Emit(OpCodes.Ldloc, val2);
				val.Index += 1;
				ILLabel val3 = val.DefineLabel();
				val.Emit(OpCodes.Br, (object)val3);
				if (val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1]
				{
					(Instruction a) => ILPatternMatchingExt.MatchCallOrCallvirt<Behaviour>(a, "set_enabled")
				}))
				{
					val.MarkLabel(val3);
				}
				else
				{
					val.LogErrorCaller("freeze duration 2");
				}
			}
			else
			{
				val.LogErrorCaller("freeze duration");
			}
			ILLabel brfalse = null;
			if (val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[3]
			{
				(Instruction a) => ILPatternMatchingExt.MatchCallOrCallvirt<EntityState>(a, "get_rigidbody"),
				(Instruction a) => ILPatternMatchingExt.MatchCallOrCallvirt<Object>(a, "op_Implicit"),
				(Instruction a) => ILPatternMatchingExt.MatchBrfalse(a, ref brfalse)
			}))
			{
				val.Emit(OpCodes.Ldloc, val2);
				val.Emit(OpCodes.Brtrue, (object)brfalse);
			}
			else
			{
				val.LogErrorCaller("freeze rigidbody");
			}
		}

		[Hook(typeof(CrosshairManager), "UpdateCrosshair")]
		private static void RemoveSprintCrosshair_IL_CrosshairManager_UpdateCrosshair(ILContext il)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			ILCursor val = new ILCursor(il);
			if (val.TryGotoNext((MoveType)1, new Func<Instruction, bool>[1]
			{
				(Instruction a) => ILPatternMatchingExt.MatchLdsfld<CrosshairManager>(a, "_sprintingCrosshair")
			}))
			{
				ILLabel val2 = val.DefineLabel();
				val.Emit(OpCodes.Ldarg_1);
				val.EmitMotorParamsBoolean("disableSprintCrosshair");
				val.Emit(OpCodes.Brtrue, (object)val2);
				ILLabel val3 = default(ILLabel);
				if (val.TryGotoPrev((MoveType)2, new Func<Instruction, bool>[1]
				{
					(Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt<CharacterBody>(x, "get_isSprinting")
				}) && val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1]
				{
					(Instruction x) => ILPatternMatchingExt.MatchBrtrue(x, ref val3)
				}))
				{
					val.MarkLabel(val2);
				}
				else
				{
					val.LogErrorCaller("not sprint");
				}
			}
			else
			{
				val.LogErrorCaller("sprint crosshair");
			}
		}

		[Hook(typeof(TeleportHelper), "TeleportGameObject", new Type[]
		{
			typeof(GameObject),
			typeof(Vector3)
		})]
		private static void AddOffset_On_TeleportHelper_TeleportGameObject(Action<GameObject, Vector3> orig, GameObject gameObject, Vector3 newPosition)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			IMotor motor = default(IMotor);
			if (gameObject.TryGetComponent<IMotor>(ref motor))
			{
				newPosition.y += motor.motorParams.spawnYOffset;
				((IPhysMotor)motor).velocityAuthority = Vector3.zero;
			}
			orig(gameObject, newPosition);
		}

		[Hook(typeof(Util), "GetBodyPrefabFootOffset")]
		private static void AddSpawnOffset_IL_Util_BodyPrefabFootOffset(ILContext il)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Expected O, but got Unknown
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			ILCursor val = new ILCursor(il);
			if (val.TryGotoNext((MoveType)1, new Func<Instruction, bool>[1]
			{
				(Instruction a) => ILPatternMatchingExt.MatchLdcR4(a, 0f)
			}))
			{
				VariableDefinition val2 = new VariableDefinition(val.Module.ImportReference(typeof(IMotor)));
				val.Body.Variables.Add(val2);
				val.Emit(OpCodes.Ldarg_0);
				val.Emit(OpCodes.Ldloca, val2);
				val.Emit(OpCodes.Callvirt, (MethodBase)typeof(GameObject).GetMethods().First((MethodInfo a) => a.IsGenericMethod && a.Name == "TryGetComponent").MakeGenericMethod(typeof(IMotor)));
				val.Emit(OpCodes.Brfalse, val.Next);
				val.Emit(OpCodes.Ldloc, val2);
				val.Emit<IMotor>(OpCodes.Callvirt, "get_motorParams");
				val.Emit<MotorParams>(OpCodes.Ldfld, "spawnYOffset");
				val.Emit(OpCodes.Ret);
			}
			else
			{
				val.LogErrorCaller("");
			}
		}

		[Hook(typeof(GummyCloneSpawnState), "OnEnter")]
		private static void FixGooboNRE_On_GummyCloneSpawnState_OnEnter(Action<GummyCloneSpawnState> orig, GummyCloneSpawnState self)
		{
			orig(self);
			if (!Object.op_Implicit((Object)(object)self.characterModel) && Object.op_Implicit((Object)(object)((EntityState)self).modelLocator) && Object.op_Implicit((Object)(object)((EntityState)self).modelLocator.modelTransform))
			{
				self.characterModel = ((Component)((EntityState)self).modelLocator.modelTransform).GetComponent<CharacterModel>();
				CharacterModel characterModel = self.characterModel;
				int invisibilityCount = characterModel.invisibilityCount;
				characterModel.invisibilityCount = invisibilityCount + 1;
			}
		}

		[Hook(typeof(JumpVolume), "OnTriggerStay")]
		private static void JumpPad_On_JumpVolume_OnTriggerStay(Action<JumpVolume, Collider> orig, JumpVolume self, Collider other)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			IMotor motor = default(IMotor);
			if (!((Component)other).TryGetComponent<IMotor>(ref motor))
			{
				orig(self, other);
			}
			else if (motor.ShouldJumpPadActivate(self))
			{
				self.onJump.Invoke();
				Util.PlaySound(self.jumpSoundString, ((Component)self).gameObject);
				Vector3 val = ((IPhysMotor)motor).velocityAuthority + self.jumpVelocity;
				if (val.y < self.jumpVelocity.y)
				{
					val.y = self.jumpVelocity.y;
				}
				((IPhysMotor)motor).velocityAuthority = val;
			}
		}

		[Hook(typeof(HeadstompersFall), "FixedUpdateAuthority")]
		private static void Fall_On_HeadstompersFall_FixedUpdate(Action<HeadstompersFall> orig, HeadstompersFall self)
		{
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Expected O, but got Unknown
			//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: 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_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: 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)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)((BaseHeadstompersState)self).bodyMotor) || !Object.op_Implicit((Object)(object)((BaseHeadstompersState)self).body) || ((BaseHeadstompersState)self).body.imotor == null || ((BaseHeadstompersState)self).body.imotor.motorParams.headStompersBehaviour == HeadStompersBehaviour.VanillaBroken)
			{
				orig(self);
				return;
			}
			IMotor imotor = ((BaseHeadstompersState)self).body.imotor;
			self.stopwatch += Time.deltaTime;
			if (imotor.motorParams.headStompersBehaviour switch
			{
				HeadStompersBehaviour.OnCollision => imotor.isColliding, 
				HeadStompersBehaviour.WhenGrounded => imotor.isGrounded, 
				HeadStompersBehaviour.CollidingAndGrounded => imotor.isColliding && imotor.isGrounded, 
				_ => false, 
			})
			{
				self.DoStompExplosionAuthority();
				return;
			}
			if (self.stopwatch >= HeadstompersFall.maxFallDuration)
			{
				((EntityState)self).outer.SetNextState((EntityState)new HeadstompersCooldown());
				return;
			}
			Vector3 velocity = ((IPhysMotor)imotor).velocity;
			Vector3 val = default(Vector3);
			((Vector3)(ref val))..ctor(0f, (velocity.y > -0.15f * HeadstompersFall.maxFallSpeed) ? (-0.5f * HeadstompersFall.accelerationY * Time.deltaTime) : 0f, 0f);
			if (Object.op_Implicit((Object)(object)self.seekTransform) && !self.seekLost)
			{
				Vector3 val2 = self.seekTransform.position - ((BaseHeadstompersState)self).body.footPosition;
				Vector3 normalized = ((Vector3)(ref val2)).normalized;
				if (Vector3.Dot(Vector3.down, normalized) >= Mathf.Cos(HeadstompersFall.seekCone * (MathF.PI / 180f)))
				{
					if (velocity.y < 0f)
					{
						Vector3 val3 = (0f - velocity.y) * normalized;
						val.x = val3.x * 2f * Time.deltaTime;
						val.z = val3.z * 2f * Time.deltaTime;
					}
				}
				else
				{
					self.seekLost = true;
				}
			}
			PhysForceInfo val4 = new PhysForceInfo
			{
				force = val * ((IPhysMotor)imotor).mass
			};
			((IPhysMotor)imotor).ApplyForceImpulse(ref val4);
		}

		[Hook(typeof(HeadstompersFall), "DoStompExplosionAuthority")]
		private static void AddNullCheck_IL_HeadstompersFall_DoStompExplosionAuthority(ILContext il)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			ILCursor val = new ILCursor(il);
			if (val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[4]
			{
				(Instruction a) => ILPatternMatchingExt.MatchLdarg(a, 0),
				(Instruction a) => ILPatternMatchingExt.MatchLdfld<BaseHeadstompersState>(a, "bodyMotor"),
				(Instruction a) => ILPatternMatchingExt.MatchCallOrCallvirt<Vector3>(a, "get_zero"),
				(Instruction a) => ILPatternMatchingExt.MatchStfld<CharacterMotor>(a, "velocity")
			}))
			{
				Instruction next = val.Next;
				val.Index -= 4;
				val.Emit(OpCodes.Ldarg_0);
				val.Emit<BaseHeadstompersState>(OpCodes.Ldfld, "bodyMotor");
				val.Emit<Object>(OpCodes.Call, "op_Implicit");
				val.Emit(OpCodes.Brfalse, next);
			}
			else
			{
				val.LogErrorCaller("headstompers null check");
			}
		}

		[Hook(typeof(BaseHeadstompersState), "get_isGrounded")]
		private static bool IsGrounded_On_HeadstompersBase_isGrounded(Func<BaseHeadstompersState, bool> orig, BaseHeadstompersState self)
		{
			if (!Object.op_Implicit((Object)(object)self.bodyMotor) && Object.op_Implicit((Object)(object)self.body) && self.body.imotor != null)
			{
				return self.body.imotor.isGrounded;
			}
			return orig(self);
		}

		[Hook(typeof(JetpackController), "MyFixedUpdate")]
		private static void AllowDisablingFlight_IL_JetpackController_FixedUpdate(ILContext il)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			ILCursor val = new ILCursor(il);
			int num = default(int);
			if (val.TryGotoNext(new Func<Instruction, bool>[1]
			{
				(Instruction a) => ILPatternMatchingExt.MatchCallOrCallvirt(a, typeof(CharacterMotor), "get_isGrounded")
			}) && val.TryGotoNext(new Func<Instruction, bool>[1]
			{
				(Instruction a) => ILPatternMatchingExt.MatchStloc(a, ref num)
			}))
			{
				val.Emit(OpCodes.Ldarg_0);
				val.EmitDelegate<Func<bool, JetpackController, bool>>((Func<bool, JetpackController, bool>)delegate(bool continueHovering, JetpackController self)
				{
					if (!continueHovering)
					{
						return false;
					}
					IMotor imotor;
					return (!Object.op_Implicit((Object)(object)self.targetBody) || (imotor = self.targetBody.imotor) == null || imotor.motorParams.milkyChrysalisDuration == MilkyChrysalisDuration.VanillaBroken || (imotor.motorParams.milkyChrysalisDuration == MilkyChrysalisDuration.EquipDurationAndGrounded && !imotor.isGrounded)) ? true : false;
				});
			}
			else
			{
				val.LogErrorCaller("Milky Chrysalis disable");
			}
		}

		[Hook(typeof(CharacterBody), "RpcRequestShardInfoClient")]
		private static void FixAntlerShield_IL_CharacterBody_RpcRequestShardInfoClient(ILContext il)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			ILCursor val = new ILCursor(il);
			if (val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[2]
			{
				(Instruction a) => ILPatternMatchingExt.MatchCallOrCallvirt<CharacterBody>(a, "get_characterMotor"),
				(Instruction a) => ILPatternMatchingExt.MatchLdfld<CharacterMotor>(a, "velocity")
			}))
			{
				Instruction next = val.Next;
				val.Emit(OpCodes.Pop);
				val.Index -= 3;
				val.EmitDelegate<Func<CharacterBody, Vector3>>((Func<CharacterBody, Vector3>)MotorApiPlugin.GetVelocity);
				val.Emit(OpCodes.Br, next);
				val.Emit(OpCodes.Ldarg_0);
			}
			else
			{
				val.LogErrorCaller("no characterMotor");
			}
		}

		[Hook(typeof(VehicleSeat), "FixedUpdate")]
		private static void ImproveControls_On_VehicleSeat_FixedUpdate(Action<VehicleSeat> orig, VehicleSeat self)
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			orig(self);
			if (Object.op_Implicit((Object)(object)self.passengerInfo.body))
			{
				IMotor imotor = self.passengerInfo.body.imotor;
				if (imotor != null && imotor.motorParams.improveVehicleSeatHandling)
				{
					self.passengerInfo.body.transform.SetPositionAndRotation(((Component)self).transform.position, ((Component)self).transform.rotation);
				}
			}
		}

		private static void InheritVelocity_OnPassengerExitGlobal(VehicleSeat self, GameObject passenger)
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)self.rigidbody) && Object.op_Implicit((Object)(object)self.passengerInfo.body))
			{
				IMotor imotor = self.passengerInfo.body.imotor;
				if (imotor != null && imotor.motorParams.improveVehicleSeatHandling)
				{
					((IPhysMotor)self.passengerInfo.body.imotor).velocityAuthority = self.rigidbody.velocity;
				}
			}
		}

		private static void EmitMotorParamsBoolean(this ILCursor c, string fieldName)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			ILLabel val = c.DefineLabel();
			ILLabel val2 = c.DefineLabel();
			c.Emit<CharacterBody>(OpCodes.Ldfld, "imotor");
			c.Emit(OpCodes.Dup);
			c.Emit(OpCodes.Brtrue, (object)val);
			c.Emit(OpCodes.Pop);
			c.Emit(OpCodes.Ldc_I4_0);
			c.Emit(OpCodes.Br, (object)val2);
			c.MarkLabel(val);
			c.Emit<IMotor>(OpCodes.Callvirt, "get_motorParams");
			c.Emit<MotorParams>(OpCodes.Ldfld, fieldName);
			c.MarkLabel(val2);
		}
	}
	public interface ICameraModeProvider
	{
		CameraModePlayerBasic playerCameraMode { get; }

		CameraModePlayerBasic spectatorCameraMode { get; }
	}
	public interface IMotor : IPhysMotor, IDisplacementReceiver
	{
		bool isGrounded { get; }

		bool isColliding { get; }

		MotorParams motorParams { get; }

		bool ShouldJumpPadActivate(JumpVolume jumpPad);
	}
	[DisallowMultipleComponent]
	[RequireComponent(typeof(Rigidbody))]
	[AddComponentMenu("")]
	public class KccBodyMover : PhysicsMover
	{
		public static void OnAuthorityUpdated(GameObject gameObject, bool hasEffectiveAuthority)
		{
			KccBodyMover kccBodyMover = default(KccBodyMover);
			bool flag = gameObject.TryGetComponent<KccBodyMover>(ref kccBodyMover);
			if (!hasEffectiveAuthority)
			{
				if (!flag)
				{
					gameObject.AddComponent<KccBodyMover>();
				}
			}
			else if (flag)
			{
				Object.Destroy((Object)(object)kccBodyMover);
			}
		}

		private void Awake()
		{
			base.Rigidbody = ((Component)this).GetComponent<Rigidbody>();
		}

		private void OnEnable()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			((PhysicsMover)this).TransientPosition = base.Rigidbody.position;
			((PhysicsMover)this).TransientRotation = base.Rigidbody.rotation;
			base.LatestInterpolationPosition = base.Rigidbody.centerOfMass;
			base.Rigidbody.centerOfMass = Vector3.zero;
		}

		private void OnDisable()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			base.Rigidbody.centerOfMass = base.LatestInterpolationPosition;
		}

		private void OnValidate()
		{
			Debug.LogError((object)"KccBodyMover should not be used in the editor");
			Object.Destroy((Object)(object)this);
		}

		private void FixedUpdate()
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//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_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			if (!base.Rigidbody.isKinematic)
			{
				log.warning("KccBodyMover is on an authoritive dynamic body " + ((Object)((Component)this).gameObject).name);
			}
			Vector3 transientPosition = ((PhysicsMover)this).TransientPosition;
			Quaternion transientRotation = ((PhysicsMover)this).TransientRotation;
			((PhysicsMover)this).TransientPosition = base.Rigidbody.position;
			((PhysicsMover)this).TransientRotation = base.Rigidbody.rotation;
			((PhysicsMover)this).Velocity = (((PhysicsMover)this).TransientPosition - transientPosition) / Time.deltaTime;
			Quaternion val = ((PhysicsMover)this).TransientRotation * Quaternion.Inverse(transientRotation);
			((PhysicsMover)this).AngularVelocity = MathF.PI / 180f * ((Quaternion)(ref val)).eulerAngles / Time.deltaTime;
		}
	}
	[Serializable]
	public struct MotorParams
	{
		[Tooltip("Prevents velocity from being deleted when frozen, and fixes not freezing at all with no animator.")]
		public bool preventFreezeMomentumDeletion;

		[Tooltip("Blocks sprinting crosshair override.")]
		public bool disableSprintCrosshair;

		[Tooltip("Disables screen shake.")]
		public bool disableScreenShake;

		[Tooltip("Improves Volcanic Egg and Eccentric Vase handling.")]
		public bool improveVehicleSeatHandling;

		[Tooltip("Fixes Milky Chrysalis not leaving the post-duration hover state. Use ICharacterFlightParameterProvider and ICharacterGravityParameterProvider to implement flight.")]
		public MilkyChrysalisDuration milkyChrysalisDuration;

		[Tooltip("Fixes HeadStompers not accelerating.")]
		public HeadStompersBehaviour headStompersBehaviour;

		[Tooltip("Vertical offset for spawning and teleporting.")]
		public float spawnYOffset;

		public static MotorParams GetDefault()
		{
			MotorParams result = default(MotorParams);
			result.preventFreezeMomentumDeletion = true;
			result.disableSprintCrosshair = true;
			result.disableScreenShake = true;
			result.improveVehicleSeatHandling = true;
			result.milkyChrysalisDuration = MilkyChrysalisDuration.EquipDuration;
			result.headStompersBehaviour = HeadStompersBehaviour.OnCollision;
			result.spawnYOffset = 0f;
			return result;
		}
	}
	public enum MilkyChrysalisDuration : byte
	{
		VanillaBroken,
		EquipDuration,
		EquipDurationAndGrounded
	}
	public enum HeadStompersBehaviour : byte
	{
		VanillaBroken,
		OnCollision,
		WhenGrounded,
		CollidingAndGrounded
	}
	[BepInPlugin("dolso.MotorAPI", "MotorAPI", "1.0.1")]
	public class MotorApiPlugin : BaseUnityPlugin
	{
		public const string Guid = "dolso.MotorAPI";

		public const string Version = "1.0.1";

		public static IMotor GetIMotor(CharacterBody body)
		{
			return body.imotor;
		}

		public static ICameraModeProvider GetICameraModeProvider(CharacterBody body)
		{
			return body.icamera;
		}

		public static Vector3 GetVelocity(CharacterBody body)
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)body.characterMotor))
			{
				if (body.imotor == null)
				{
					if (!Object.op_Implicit((Object)(object)body.rigidbody))
					{
						return Vector3.zero;
					}
					return body.rigidbody.velocity;
				}
				return ((IPhysMotor)body.imotor).velocity;
			}
			return body.characterMotor.velocity;
		}

		private void Awake()
		{
			HookAttribute.ScanAndApply(typeof(Hooks));
		}

		private void Start()
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Expected O, but got Unknown
			if (Chainloader.PluginInfos.TryGetValue("pseudopulse.BetterDrones", out var value))
			{
				HookManager.Hook(((object)value.Instance).GetType().Assembly.GetType("BetterDrones.DroneTweaks.OrbitalMovement/OrbitController"), "Start", new Manipulator(BlockElfPhobia));
			}
		}

		private static void BlockElfPhobia(ILContext il)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			ILCursor val = new ILCursor(il);
			if (val.TryGotoNext((MoveType)1, new Func<Instruction, bool>[2]
			{
				(Instruction a) => ILPatternMatchingExt.MatchLdarg(a, 0),
				(Instruction a) => ILPatternMatchingExt.MatchCallOrCallvirt(a, (MethodBase)typeof(Component).GetMethod("GetComponent", Type.EmptyTypes).MakeGenericMethod(typeof(Rigidbody)))
			}))
			{
				val.Emit(OpCodes.Ret);
			}
			else
			{
				log.warning("Failed to find BetterDrones elfphobia");
			}
		}
	}
}

patchers/MotorAPI.Patcher.dll

Decompiled a month ago
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using Mono.Cecil;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace MotorAPI;

public static class Patcher
{
	public static IEnumerable<string> TargetDLLs => new string[1] { "RoR2.dll" };

	public static void Patch(AssemblyDefinition assembly)
	{
		//IL_0067: Unknown result type (might be due to invalid IL or missing references)
		//IL_0071: Expected O, but got Unknown
		//IL_008d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0097: Expected O, but got Unknown
		ModuleDefinition mainModule = assembly.MainModule;
		string[] files = Directory.GetFiles(Paths.PluginPath, "MotorAPI.dll", SearchOption.AllDirectories);
		if (files.Length == 0)
		{
			Logger.CreateLogSource("MotorAPI.Patcher").LogFatal((object)"Failed to find MotorAPI.dll");
			return;
		}
		ModuleDefinition mainModule2 = AssemblyDefinition.ReadAssembly(files[0]).MainModule;
		TypeDefinition type = mainModule.GetType("RoR2.CharacterBody");
		type.Fields.Add(new FieldDefinition("imotor", (FieldAttributes)6, mainModule.ImportReference((TypeReference)(object)mainModule2.GetType("MotorAPI.IMotor"))));
		type.Fields.Add(new FieldDefinition("icamera", (FieldAttributes)6, mainModule.ImportReference((TypeReference)(object)mainModule2.GetType("MotorAPI.ICameraModeProvider"))));
	}
}