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