Decompiled source of BehindYou v1.0.0

Mods\BehindYou.dll

Decompiled 11 hours ago
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);
		}
	}
}