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