Some mods may be broken due to the recent Alloyed Collective update.
Decompiled source of MotorAPI v1.0.4
plugins/MotorAPI.dll
Decompiled 2 weeks agousing 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.4.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[] 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 { private readonly Type typeFrom; private readonly string methodFrom; private readonly Type[] parameters; protected MethodInfo from { get { if ((object)typeFrom != null) { if (parameters != null) { return HookManager.GetMethod(typeFrom, methodFrom, parameters); } return HookManager.GetMethod(typeFrom, methodFrom); } return null; } } internal HookAttribute(Type typeFrom, string methodFrom) { this.typeFrom = typeFrom; this.methodFrom = methodFrom; } internal HookAttribute(Type typeFrom, string methodFrom, params Type[] parameters) { this.typeFrom = typeFrom; this.methodFrom = methodFrom; this.parameters = 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)) { MethodInfo methodInfo2 = null; try { methodInfo2 = customAttribute.from; if (methodInfo2 == null && methodInfo.GetParameters().Length == 0) { methodInfo.Invoke(null, null); } else { customAttribute.Hook(methodInfo2, methodInfo); } } catch (Exception e) { e.LogHookError(methodInfo2, methodInfo); } } } } } protected virtual void Hook(MethodInfo from, 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 val = ((!((Object)(object)self.nextTarget == (Object)(object)self.target)) ? self.nextTarget.GetComponent<CharacterBody>() : self.targetBody); if (Object.op_Implicit((Object)(object)val) && val.icamera != null && !Object.op_Implicit((Object)(object)val.currentVehicle)) { orig(self, (CameraModeBase)(object)(flag ? val.icamera.spectatorCameraMode : val.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_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: 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_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) CharacterBody val = default(CharacterBody); if (!((Component)other).TryGetComponent<CharacterBody>(ref val) || val.imotor == null) { orig(self, other); } else if (val.imotor.ShouldJumpPadActivate(self)) { self.onJump.Invoke(val); Util.PlaySound(self.jumpSoundString, ((Component)self).gameObject); Vector3 val2 = ((IPhysMotor)val.imotor).velocityAuthority + self.jumpVelocity; if (val2.y < self.jumpVelocity.y) { val2.y = self.jumpVelocity.y; } ((IPhysMotor)val.imotor).velocityAuthority = val2; } } [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); if (gameObject.TryGetComponent<KccBodyMover>(ref kccBodyMover)) { if (hasEffectiveAuthority) { Object.Destroy((Object)(object)kccBodyMover); } } else if (!hasEffectiveAuthority) { gameObject.AddComponent<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.4")] public class MotorApiPlugin : BaseUnityPlugin { public const string Guid = "dolso.MotorAPI"; public const string Version = "1.0.4"; 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 2 weeks agousing 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")))); } }