using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BehindYou;
using BoneLib.BoneMenu;
using Il2CppSLZ.Marrow;
using Il2CppSLZ.Marrow.Combat;
using LabFusion.Data;
using LabFusion.Entities;
using LabFusion.Network;
using LabFusion.Player;
using MelonLoader;
using MelonLoader.Preferences;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(BehindYouMod), "BehindYou", "1.0.0", "you", null)]
[assembly: MelonGame("Stress Level Zero", "BONELAB")]
[assembly: MelonOptionalDependencies(new string[] { "LabFusion", "BoneLib" })]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("BehindYou")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("BehindYou")]
[assembly: AssemblyTitle("BehindYou")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace BehindYou;
public class BehindYouMod : MelonMod
{
internal static MelonPreferences_Category Category;
internal static MelonPreferences_Entry<bool> Enabled;
internal static MelonPreferences_Entry<float> DistanceBehind;
internal static MelonPreferences_Entry<float> CooldownSeconds;
internal static bool MenuBuilt;
private static bool _noBoneLib;
public override void OnInitializeMelon()
{
Category = MelonPreferences.CreateCategory("BehindYou");
Enabled = Category.CreateEntry<bool>("Enabled", true, "Teleport behind your attacker when hit", (string)null, false, false, (ValueValidator)null, (string)null);
DistanceBehind = Category.CreateEntry<float>("DistanceBehind", 1.25f, "Meters behind the attacker to appear", (string)null, false, false, (ValueValidator)null, (string)null);
CooldownSeconds = Category.CreateEntry<float>("CooldownSeconds", 0.75f, "Min seconds between teleports", (string)null, false, false, (ValueValidator)null, (string)null);
if (MelonBase.FindMelon("LabFusion", "Lakatrazz") != null)
{
HookFusion();
}
else
{
((MelonBase)this).LoggerInstance.Msg("LabFusion not found. BehindYou is idle until you join a Fusion lobby with it installed.");
}
((MelonEventBase<LemonAction<int, string>>)(object)MelonEvents.OnSceneWasLoaded).Subscribe((LemonAction<int, string>)OnSceneLoaded, 0, false);
}
private static void OnSceneLoaded(int buildIndex, string sceneName)
{
if (MenuBuilt || _noBoneLib)
{
return;
}
try
{
if (BoneMenuSetup.TryBuildMenu())
{
MenuBuilt = true;
}
}
catch (Exception ex)
{
_noBoneLib = true;
MelonLogger.Warning("BoneMenu unavailable, using config file only: " + ex.GetType().Name);
}
}
private static void HookFusion()
{
FusionCounterStep.Initialize();
}
}
internal static class BoneMenuSetup
{
public static bool TryBuildMenu()
{
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: 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_00a7: Unknown result type (might be due to invalid IL or missing references)
if (Page.Root == null)
{
return false;
}
Page obj = Page.Root.CreatePage("BehindYou", Color.red, 0, true);
obj.CreateBool("Enabled", Color.white, BehindYouMod.Enabled.Value, (Action<bool>)delegate(bool v)
{
BehindYouMod.Enabled.Value = v;
});
obj.CreateFloat("Distance Behind (m)", Color.white, BehindYouMod.DistanceBehind.Value, 0.25f, 0.5f, 3f, (Action<float>)delegate(float v)
{
BehindYouMod.DistanceBehind.Value = v;
});
obj.CreateFloat("Cooldown (s)", Color.white, BehindYouMod.CooldownSeconds.Value, 0.25f, 0f, 2f, (Action<float>)delegate(float v)
{
BehindYouMod.CooldownSeconds.Value = v;
});
MelonLogger.Msg("[BehindYou] BoneMenu page created.");
return true;
}
}
internal static class FusionCounterStep
{
private static float _lastTeleportTime = float.MinValue;
public static void Initialize()
{
LocalHealth.OnAttackedByPlayer += OnAttackedByPlayer;
MelonLogger.Msg("[BehindYou] Hooked Fusion damage events. You will now teleport behind anyone who hits you.");
}
private static void OnAttackedByPlayer(Attack attack, BodyPart bodyPart, PlayerID attackerId)
{
//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
//IL_0097: Unknown result type (might be due to invalid IL or missing references)
//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
//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)
//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
//IL_00f2: 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_00fc: Unknown result type (might be due to invalid IL or missing references)
NetworkPlayer val = default(NetworkPlayer);
if (!BehindYouMod.Enabled.Value || !NetworkInfo.HasServer || Time.time - _lastTeleportTime < BehindYouMod.CooldownSeconds.Value || !NetworkPlayerManager.TryGetPlayer(PlayerID.op_Implicit(attackerId), ref val) || val.NetworkEntity == null || val.NetworkEntity.IsOwner || !val.HasRig)
{
return;
}
RigManager rigManager = val.RigRefs.RigManager;
if (!((Object)(object)rigManager == (Object)null) && !((Object)(object)rigManager.physicsRig == (Object)null))
{
Vector3 val2 = (((Object)(object)val.RigRefs.Head != (Object)null) ? val.RigRefs.Head.forward : ((Component)rigManager).transform.forward);
val2.y = 0f;
if (!(((Vector3)(ref val2)).sqrMagnitude < 0.0001f))
{
val2 = ((Vector3)(ref val2)).normalized;
TeleportKeepingGrip(rigManager.physicsRig.feet.transform.position - val2 * BehindYouMod.DistanceBehind.Value, val2);
_lastTeleportTime = Time.time;
}
}
}
private static void TeleportKeepingGrip(Vector3 targetPos, Vector3 facing)
{
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_0104: Unknown result type (might be due to invalid IL or missing references)
//IL_0105: Unknown result type (might be due to invalid IL or missing references)
//IL_0099: Unknown result type (might be due to invalid IL or missing references)
//IL_009e: 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_0164: Unknown result type (might be due to invalid IL or missing references)
//IL_0169: Unknown result type (might be due to invalid IL or missing references)
//IL_016e: Unknown result type (might be due to invalid IL or missing references)
//IL_0173: Unknown result type (might be due to invalid IL or missing references)
//IL_0178: 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_0186: Unknown result type (might be due to invalid IL or missing references)
//IL_0192: Unknown result type (might be due to invalid IL or missing references)
RigManager rigManager = RigData.Refs.RigManager;
if ((Object)(object)rigManager == (Object)null || (Object)(object)rigManager.physicsRig == (Object)null)
{
LocalPlayer.TeleportToPosition(targetPos, facing);
return;
}
PhysicsRig physicsRig = rigManager.physicsRig;
Hand[] array = (Hand[])(object)new Hand[2] { physicsRig.leftHand, physicsRig.rightHand };
Vector3[] array2 = (Vector3[])(object)new Vector3[array.Length];
List<int> list = new List<int>();
List<Rigidbody> list2 = new List<Rigidbody>();
HashSet<int> hashSet = new HashSet<int>();
for (int i = 0; i < array.Length; i++)
{
Hand val = array[i];
if ((Object)(object)val == (Object)null || (Object)(object)val.rb == (Object)null)
{
continue;
}
array2[i] = val.rb.position;
if (!val.HasAttachedObject())
{
continue;
}
HandReciever attachedReceiver = val.AttachedReceiver;
if (!((Object)(object)attachedReceiver == (Object)null) && hashSet.Add(((Object)attachedReceiver).GetInstanceID()))
{
Rigidbody component = ((Component)attachedReceiver).GetComponent<Rigidbody>();
if ((Object)(object)component != (Object)null)
{
list.Add(i);
list2.Add(component);
}
}
}
LocalPlayer.TeleportToPosition(targetPos, facing);
try
{
for (int j = 0; j < list2.Count; j++)
{
Rigidbody val2 = list2[j];
Hand val3 = array[list[j]];
if (!((Object)(object)val2 == (Object)null) && !((Object)(object)val3 == (Object)null) && !((Object)(object)val3.rb == (Object)null))
{
Vector3 val4 = val3.rb.position - array2[list[j]];
val2.position += val4;
val2.velocity = Vector3.zero;
val2.angularVelocity = Vector3.zero;
}
}
}
catch (Exception ex)
{
MelonLogger.Warning("[BehindYou] Held-item carry skipped: " + ex.GetType().Name);
}
}
}