Decompiled source of ThirdPersonF5 v0.1.0

ThirdPersonF5.dll

Decompiled 3 hours ago
using System;
using System.Diagnostics;
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 GameNetcodeStuff;
using HarmonyLib;
using LethalCompanyInputUtils.Api;
using Microsoft.CodeAnalysis;
using ModMenu;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("ThirdPersonF5")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.1.0.0")]
[assembly: AssemblyInformationalVersion("0.1.0+5d5e622c2887424482de7152a26a0b3696813702")]
[assembly: AssemblyProduct("ThirdPersonF5")]
[assembly: AssemblyTitle("ThirdPersonF5")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace ThirdPersonF5
{
	internal static class MenuHooks
	{
		internal const string ModMenuGuid = "daniel.lethalcompany.modmenu";

		[MethodImpl(MethodImplOptions.NoInlining)]
		internal static void Register()
		{
			MenuApi.Toggle("Third Person", "Third person", (Func<bool>)(() => Plugin.Active), (Func<bool, string>)((bool on) => (on == Plugin.Active) ? null : Plugin.Toggle()), false, false, (Func<string>)(() => (!((Object)(object)Plugin.LocalPlayer == (Object)null)) ? null : "not in a game"), "or press F5");
		}
	}
	[BepInPlugin("daniel.lethalcompany.thirdpersonf5", "ThirdPersonF5", "0.1.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		internal static ManualLogSource Log;

		internal static ConfigEntry<float> Distance;

		internal static ConfigEntry<float> Height;

		internal static ConfigEntry<float> Side;

		internal static ConfigEntry<string> ToggleKey;

		internal static bool Active;

		internal static bool InputUtilsLoaded;

		private static FieldInfo controllerField;

		internal static PlayerControllerB LocalPlayer
		{
			get
			{
				if (!((Object)(object)GameNetworkManager.Instance != (Object)null))
				{
					return null;
				}
				return GameNetworkManager.Instance.localPlayerController;
			}
		}

		private void Awake()
		{
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Expected O, but got Unknown
			//IL_00da: 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_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			Distance = ((BaseUnityPlugin)this).Config.Bind<float>("Camera", "Distance", 3f, "Metres behind the player's eyes.");
			Height = ((BaseUnityPlugin)this).Config.Bind<float>("Camera", "Height", 0.3f, "Metres above the player's eyes.");
			Side = ((BaseUnityPlugin)this).Config.Bind<float>("Camera", "Side", 0f, "Metres to the right (over-the-shoulder if not 0).");
			ToggleKey = ((BaseUnityPlugin)this).Config.Bind<string>("Keys", "Toggle key", "<Keyboard>/f5", "Third person on/off. Used when LethalCompany InputUtils isn't installed (with it, rebind in Settings > Controls).");
			InputUtilsLoaded = Chainloader.PluginInfos.ContainsKey("com.rune580.LethalCompanyInputUtils");
			Keys.Init();
			if (Chainloader.PluginInfos.ContainsKey("daniel.lethalcompany.modmenu"))
			{
				MenuHooks.Register();
			}
			GameObject val = new GameObject("ThirdPersonF5");
			Object.DontDestroyOnLoad((Object)val);
			((Object)val).hideFlags = (HideFlags)61;
			val.AddComponent<EarlyRestore>();
			val.AddComponent<LatePullBack>();
			PatchModelReplacement(new Harmony("daniel.lethalcompany.thirdpersonf5"));
			Log.LogInfo((object)("ThirdPersonF5 0.1.0 loaded: press " + ToggleKey.Value + " for third person (InputUtils " + (InputUtilsLoaded ? "found" : "not found") + ")"));
		}

		internal static string Toggle()
		{
			PlayerControllerB localPlayer = LocalPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				return null;
			}
			Active = !Active;
			Log.LogInfo((object)("Third person " + (Active ? "on" : "off")));
			if (!Active)
			{
				EarlyRestore.RestoreBody(localPlayer);
			}
			if (!Active)
			{
				return "third person off";
			}
			return "third person on";
		}

		private static void PatchModelReplacement(Harmony h)
		{
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Expected O, but got Unknown
			Type type = AccessTools.TypeByName("ModelReplacement.ViewStateManager");
			MethodInfo methodInfo = ((type == null) ? null : AccessTools.Method(type, "GetViewState", (Type[])null, (Type[])null));
			controllerField = ((type == null) ? null : AccessTools.Field(type, "controller"));
			if (methodInfo == null || controllerField == null)
			{
				Log.LogInfo((object)"ModelReplacementAPI not found: vanilla bodies only");
			}
			else
			{
				h.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(Plugin), "GetViewStatePostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
		}

		private static void GetViewStatePostfix(object __instance, ref object __result)
		{
			if (Active && Convert.ToInt32(__result) == 2)
			{
				object? value = controllerField.GetValue(__instance);
				PlayerControllerB val = (PlayerControllerB)((value is PlayerControllerB) ? value : null);
				if (val != null && (Object)(object)val == (Object)(object)LocalPlayer)
				{
					__result = Enum.ToObject(__result.GetType(), 1);
				}
			}
		}

		internal static bool CanUse(PlayerControllerB p)
		{
			if ((Object)(object)p != (Object)null && p.isPlayerControlled && !p.isPlayerDead && !p.inTerminalMenu && !p.isTypingChat && !p.performingEmote && (Object)(object)p.gameplayCamera != (Object)null)
			{
				if (!((Object)(object)p.quickMenuManager == (Object)null))
				{
					return !p.quickMenuManager.isMenuOpen;
				}
				return true;
			}
			return false;
		}
	}
	internal static class Keys
	{
		private static InputAction _toggle;

		internal static void Init()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			if (Plugin.InputUtilsLoaded)
			{
				_toggle = FromInputUtils();
			}
			if (_toggle == null)
			{
				_toggle = InputActionSetupExtensions.AddAction(new InputActionMap("ThirdPersonF5"), "ThirdPersonF5.Toggle", (InputActionType)1, Plugin.ToggleKey.Value, (string)null, (string)null, (string)null, (string)null);
				_toggle.Enable();
			}
			_toggle.performed += delegate
			{
				PlayerControllerB localPlayer = Plugin.LocalPlayer;
				if ((Object)(object)localPlayer != (Object)null && !localPlayer.isTypingChat && !localPlayer.inTerminalMenu)
				{
					Plugin.Toggle();
				}
			};
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static InputAction FromInputUtils()
		{
			return ThirdPersonInputs.Instance.Toggle;
		}
	}
	internal class ThirdPersonInputs : LcInputActions
	{
		internal static readonly ThirdPersonInputs Instance = new ThirdPersonInputs();

		[InputAction("<Keyboard>/f5", Name = "Third person")]
		public InputAction Toggle { get; set; }
	}
	[DefaultExecutionOrder(-10000)]
	public class EarlyRestore : MonoBehaviour
	{
		internal static Transform movedCam;

		internal static Vector3 savedLocalPos;

		internal static int savedMask;

		internal static Renderer bodyShown;

		internal static ShadowCastingMode savedShadow;

		internal static bool armsHidden;

		private void Update()
		{
			Restore();
		}

		internal static void Restore()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)movedCam == (Object)null))
			{
				movedCam.localPosition = savedLocalPos;
				Camera component = ((Component)movedCam).GetComponent<Camera>();
				if (Object.op_Implicit((Object)(object)component))
				{
					component.cullingMask = savedMask;
				}
				movedCam = null;
			}
		}

		internal static void RestoreBody(PlayerControllerB p)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)bodyShown != (Object)null)
			{
				bodyShown.shadowCastingMode = savedShadow;
				bodyShown = null;
			}
			if (armsHidden && (Object)(object)p != (Object)null && (Object)(object)p.thisPlayerModelArms != (Object)null)
			{
				((Renderer)p.thisPlayerModelArms).enabled = true;
			}
			armsHidden = false;
		}
	}
	[DefaultExecutionOrder(10000)]
	public class LatePullBack : MonoBehaviour
	{
		private const int PlayerModelLayer = 23;

		private void LateUpdate()
		{
			//IL_0037: 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_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: 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_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: 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_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: 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_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: 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_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			PlayerControllerB localPlayer = Plugin.LocalPlayer;
			if (!Plugin.Active || !Plugin.CanUse(localPlayer))
			{
				if ((Object)(object)localPlayer != (Object)null)
				{
					EarlyRestore.RestoreBody(localPlayer);
				}
				return;
			}
			Transform transform = ((Component)localPlayer.gameplayCamera).transform;
			EarlyRestore.Restore();
			Vector3 position = transform.position;
			Vector3 val = position - transform.forward * Plugin.Distance.Value + Vector3.up * Plugin.Height.Value + transform.right * Plugin.Side.Value;
			Vector3 val2 = val - position;
			float magnitude = ((Vector3)(ref val2)).magnitude;
			int num = (((Object)(object)StartOfRound.Instance != (Object)null) ? StartOfRound.Instance.collidersAndRoomMaskAndDefault : (-1));
			RaycastHit val3 = default(RaycastHit);
			if (magnitude > 0.001f && Physics.SphereCast(position, 0.2f, val2 / magnitude, ref val3, magnitude, num, (QueryTriggerInteraction)1))
			{
				val = position + val2 / magnitude * Mathf.Max(((RaycastHit)(ref val3)).distance - 0.05f, 0.1f);
			}
			EarlyRestore.movedCam = transform;
			EarlyRestore.savedLocalPos = transform.localPosition;
			Camera gameplayCamera = localPlayer.gameplayCamera;
			EarlyRestore.savedMask = gameplayCamera.cullingMask;
			transform.position = val;
			gameplayCamera.cullingMask |= 0x800000;
			SkinnedMeshRenderer thisPlayerModel = localPlayer.thisPlayerModel;
			if ((Object)(object)thisPlayerModel != (Object)null && ((Renderer)thisPlayerModel).enabled && (Object)(object)EarlyRestore.bodyShown == (Object)null)
			{
				EarlyRestore.bodyShown = (Renderer)(object)thisPlayerModel;
				EarlyRestore.savedShadow = ((Renderer)thisPlayerModel).shadowCastingMode;
				((Renderer)thisPlayerModel).shadowCastingMode = (ShadowCastingMode)1;
			}
			if ((Object)(object)localPlayer.thisPlayerModelArms != (Object)null && ((Renderer)localPlayer.thisPlayerModelArms).enabled)
			{
				((Renderer)localPlayer.thisPlayerModelArms).enabled = false;
				EarlyRestore.armsHidden = true;
			}
		}
	}
}