Decompiled source of BetterFreeCam v1.0.0

BepInEx/plugins/BetterFreeCam/BetterFreeCam.dll

Decompiled 3 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.SceneManagement;

[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("BetterFreeCam")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("BetterFreeCam")]
[assembly: AssemblyTitle("BetterFreeCam")]
[assembly: AssemblyVersion("1.0.0.0")]
[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 BetterFreeCam
{
	[BepInPlugin("com.github.LeonYewLey.BetterFreeCam", "BetterFreeCam", "1.0.0")]
	[DefaultExecutionOrder(10000)]
	public sealed class Plugin : BaseUnityPlugin
	{
		private static readonly string[] HudNames = new string[4] { "Canvas_HUD", "DisplayCanvas", "Canvas_Names", "Binocs" };

		private static readonly FieldInfo GodCamField = typeof(MainCameraMovement).GetField("isGodCam", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly MethodInfo ResetInputMethod = typeof(CharacterInput).GetMethod("ResetInput", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private readonly Dictionary<GameObject, bool> hudStates = new Dictionary<GameObject, bool>();

		private ConfigEntry<KeyCode> hotkey;

		private ConfigEntry<float> moveSpeed;

		private ConfigEntry<float> mouseSensitivity;

		private MainCameraMovement cameraMovement;

		private MainCamera camera;

		private Camera renderCamera;

		private CharacterInput characterInput;

		private bool cameraWasEnabled;

		private bool inputWasEnabled;

		private bool godCamWasEnabled;

		private bool cursorWasVisible;

		private CursorLockMode cursorWasLocked;

		private bool active;

		private bool hudVisible;

		private int activeSceneHandle;

		private float yaw;

		private float pitch;

		private float originalFov;

		private float fov;

		private void Awake()
		{
			hotkey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Controls", "FreeCamHotkey", (KeyCode)284, "Toggle FreeCam.");
			moveSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("FreeCam Settings", "MoveSpeed", 0.05f, "Movement per 1/60 second. 0.05 = 3 metres/second; Shift = 3x. No acceleration or deceleration.");
			mouseSensitivity = ((BaseUnityPlugin)this).Config.Bind<float>("FreeCam Settings", "MouseSensitivity", 0.05f, "Raw mouse sensitivity. 0.05 = 0.5 degrees per mouse-axis unit. No look inertia.");
			SceneManager.activeSceneChanged += SceneChanged;
			((BaseUnityPlugin)this).Logger.LogInfo((object)"BetterFreeCam 1.0.0 loaded. Native GodCam movement, shake and depth-of-field are bypassed while active.");
		}

		private static bool ValidScene()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			Scene activeScene = SceneManager.GetActiveScene();
			string name = ((Scene)(ref activeScene)).name;
			if (!(name == "Airport"))
			{
				return name.StartsWith("Level_");
			}
			return true;
		}

		private void Update()
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: 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 (active)
			{
				if (ValidScene())
				{
					Scene activeScene = SceneManager.GetActiveScene();
					if (!(((Scene)(ref activeScene)).handle != SceneHandle.op_Implicit(activeSceneHandle)) && Object.op_Implicit((Object)(object)cameraMovement) && Object.op_Implicit((Object)(object)camera))
					{
						goto IL_004e;
					}
				}
				DisableFreeCam();
			}
			goto IL_004e;
			IL_004e:
			if (Input.GetKeyDown(hotkey.Value))
			{
				if (active)
				{
					DisableFreeCam();
				}
				else if (ValidScene())
				{
					EnableFreeCam();
				}
			}
			if (!active)
			{
				return;
			}
			if (Input.GetKeyDown((KeyCode)27))
			{
				DisableFreeCam();
			}
			else
			{
				if (!Input.GetKeyDown((KeyCode)104))
				{
					return;
				}
				hudVisible = !hudVisible;
				foreach (KeyValuePair<GameObject, bool> hudState in hudStates)
				{
					if (Object.op_Implicit((Object)(object)hudState.Key))
					{
						hudState.Key.SetActive(hudVisible && hudState.Value);
					}
				}
			}
		}

		private void LateUpdate()
		{
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: 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_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: 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_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			if (active && Object.op_Implicit((Object)(object)cameraMovement) && Object.op_Implicit((Object)(object)camera) && (!Object.op_Implicit((Object)(object)GUIManager.instance) || !GUIManager.instance.windowBlockingInput))
			{
				Transform transform = ((Component)cameraMovement).transform;
				float num = Mathf.Max(0f, mouseSensitivity.Value) * 10f;
				yaw += Input.GetAxisRaw("Mouse X") * num;
				pitch = Mathf.Clamp(pitch - Input.GetAxisRaw("Mouse Y") * num, -89f, 89f);
				transform.rotation = Quaternion.Euler(pitch, yaw, 0f);
				Vector3 val = default(Vector3);
				((Vector3)(ref val))..ctor(Key((KeyCode)100) - Key((KeyCode)97), Key((KeyCode)32) - Key((KeyCode)306), Key((KeyCode)119) - Key((KeyCode)115));
				val = Vector3.ClampMagnitude(val, 1f);
				float num2 = Mathf.Max(0f, moveSpeed.Value) * 60f * (Input.GetKey((KeyCode)304) ? 3f : 1f);
				Vector3 val2 = transform.right * val.x + Vector3.up * val.y + transform.forward * val.z;
				transform.position += val2 * num2 * Mathf.Min(Time.unscaledDeltaTime, 0.05f);
				fov = Mathf.Clamp(fov - Input.mouseScrollDelta.y * 2f, 1f, 120f);
				if (Object.op_Implicit((Object)(object)renderCamera))
				{
					renderCamera.fieldOfView = fov;
				}
			}
		}

		private static float Key(KeyCode key)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			if (!Input.GetKey(key))
			{
				return 0f;
			}
			return 1f;
		}

		private void EnableFreeCam()
		{
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: 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_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			MainCamera instance = MainCamera.instance;
			MainCameraMovement val = (Object.op_Implicit((Object)(object)instance) ? ((Component)instance).GetComponent<MainCameraMovement>() : null);
			Camera val2 = (Object.op_Implicit((Object)(object)instance) ? ((Component)instance).GetComponent<Camera>() : null);
			if (!Object.op_Implicit((Object)(object)instance) || !Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val2) || GodCamField == null || ResetInputMethod == null)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)"FreeCam is not ready: the gameplay camera is unavailable. Try F3 after loading.");
				return;
			}
			camera = instance;
			renderCamera = val2;
			cameraMovement = val;
			cameraWasEnabled = ((Behaviour)cameraMovement).enabled;
			godCamWasEnabled = GodCamField != null && (bool)GodCamField.GetValue(cameraMovement);
			cursorWasVisible = Cursor.visible;
			cursorWasLocked = Cursor.lockState;
			characterInput = (Object.op_Implicit((Object)(object)Character.localCharacter) ? Character.localCharacter.input : null);
			if (Object.op_Implicit((Object)(object)characterInput))
			{
				inputWasEnabled = ((Behaviour)characterInput).enabled;
				ClearCharacterInput(characterInput);
				((Behaviour)characterInput).enabled = false;
			}
			((Behaviour)cameraMovement).enabled = false;
			GodCamField.SetValue(cameraMovement, true);
			Vector3 eulerAngles = ((Component)cameraMovement).transform.eulerAngles;
			yaw = eulerAngles.y;
			pitch = Mathf.Clamp(Mathf.DeltaAngle(0f, eulerAngles.x), -89f, 89f);
			originalFov = (fov = renderCamera.fieldOfView);
			Scene activeScene = SceneManager.GetActiveScene();
			activeSceneHandle = SceneHandle.op_Implicit(((Scene)(ref activeScene)).handle);
			hudStates.Clear();
			string[] hudNames = HudNames;
			for (int i = 0; i < hudNames.Length; i++)
			{
				GameObject val3 = GameObject.Find(hudNames[i]);
				if (Object.op_Implicit((Object)(object)val3) && !hudStates.ContainsKey(val3))
				{
					hudStates.Add(val3, val3.activeSelf);
					val3.SetActive(false);
				}
			}
			hudVisible = false;
			Cursor.visible = false;
			Cursor.lockState = (CursorLockMode)1;
			active = true;
			((BaseUnityPlugin)this).Logger.LogInfo((object)"FreeCam activated: direct camera input, no inertia. F3/ESC exits; H toggles HUD.");
		}

		private void DisableFreeCam()
		{
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			if (!active)
			{
				return;
			}
			active = false;
			if (Object.op_Implicit((Object)(object)cameraMovement))
			{
				if (GodCamField != null)
				{
					GodCamField.SetValue(cameraMovement, godCamWasEnabled);
				}
				((Behaviour)cameraMovement).enabled = cameraWasEnabled;
			}
			if (Object.op_Implicit((Object)(object)characterInput))
			{
				ClearCharacterInput(characterInput);
				((Behaviour)characterInput).enabled = inputWasEnabled;
			}
			if (Object.op_Implicit((Object)(object)renderCamera))
			{
				renderCamera.fieldOfView = originalFov;
			}
			foreach (KeyValuePair<GameObject, bool> hudState in hudStates)
			{
				if (Object.op_Implicit((Object)(object)hudState.Key))
				{
					hudState.Key.SetActive(hudState.Value);
				}
			}
			hudStates.Clear();
			Cursor.visible = cursorWasVisible;
			Cursor.lockState = cursorWasLocked;
			camera = null;
			renderCamera = null;
			cameraMovement = null;
			characterInput = null;
			((BaseUnityPlugin)this).Logger.LogInfo((object)"FreeCam deactivated; original camera and input states restored.");
		}

		private static void ClearCharacterInput(CharacterInput input)
		{
			ResetInputMethod.Invoke(input, null);
			input.scrollInput = 0f;
			input.scrollForwardWasPressed = (input.scrollBackwardWasPressed = false);
			input.scrollForwardIsPressed = (input.scrollBackwardIsPressed = false);
			input.selectSlotForwardWasPressed = (input.selectSlotBackwardWasPressed = false);
			input.unselectSlotWasPressed = (input.selectBackpackWasPressed = false);
			input.spectateLeftWasPressed = (input.spectateRightWasPressed = false);
			input.sprintToggleIsPressed = (input.pingWasPressed = (input.pauseWasPressed = false));
		}

		private void SceneChanged(Scene previous, Scene current)
		{
			DisableFreeCam();
		}

		private void OnDisable()
		{
			DisableFreeCam();
		}

		private void OnDestroy()
		{
			SceneManager.activeSceneChanged -= SceneChanged;
			DisableFreeCam();
		}
	}
}