Decompiled source of FOVChanger v1.0.0

Mods/FOVChanger.dll

Decompiled 20 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BoneLib.BoneMenu;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using MelonLoader;
using MelonLoader.Preferences;
using Microsoft.CodeAnalysis;
using SpectatorFov;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: MelonInfo(typeof(Main), "SpectatorFOV", "1.1.0", "devmadman", null)]
[assembly: MelonGame("Stress Level Zero", "BONELAB")]
[assembly: MelonAdditionalDependencies(new string[] { "BoneLib" })]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("FOVChanger")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("FOVChanger")]
[assembly: AssemblyTitle("FOVChanger")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
namespace SpectatorFov
{
	public class Main : MelonMod
	{
		private const int VK_SHIFT = 16;

		private const int VK_PRIOR = 33;

		private const int VK_NEXT = 34;

		private const int VK_HOME = 36;

		private const float DefaultFov = 90f;

		private MelonPreferences_Category _cat;

		private MelonPreferences_Entry<bool> _enabled;

		private MelonPreferences_Entry<float> _fov;

		private MelonPreferences_Entry<float> _step;

		private MelonPreferences_Entry<bool> _hotkeys;

		private MelonPreferences_Entry<string> _nameFilter;

		private FloatElement _fovElement;

		private Camera[] _cams = (Camera[])(object)new Camera[0];

		private float _nextScan;

		private bool _pgUpHeld;

		private bool _pgDnHeld;

		private bool _homeHeld;

		[DllImport("user32.dll")]
		private static extern short GetAsyncKeyState(int vKey);

		public override void OnInitializeMelon()
		{
			_cat = MelonPreferences.CreateCategory("SpectatorFOV");
			_enabled = _cat.CreateEntry<bool>("Enabled", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_fov = _cat.CreateEntry<float>("SpectatorFOV", 110f, (string)null, "Desktop/spectator camera FOV (1-179)", false, false, (ValueValidator)null, (string)null);
			_step = _cat.CreateEntry<float>("Step", 5f, (string)null, "Degrees per hotkey press / menu click (Shift = x3 on hotkeys)", false, false, (ValueValidator)null, (string)null);
			_hotkeys = _cat.CreateEntry<bool>("HotkeysEnabled", true, (string)null, "PageUp/PageDown/Home on keyboard", false, false, (ValueValidator)null, (string)null);
			_nameFilter = _cat.CreateEntry<string>("CameraNameFilter", "", (string)null, "Only touch cameras whose name contains this text. Empty = auto-detect.", false, false, (ValueValidator)null, (string)null);
			BuildMenu();
			((MelonBase)this).LoggerInstance.Msg("SpectatorFOV loaded. Find it in BoneMenu > SpectatorFOV.");
		}

		private void BuildMenu()
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0200: Unknown result type (might be due to invalid IL or missing references)
			Page val = Page.Root.CreatePage("SpectatorFOV", Color.cyan, 0, true);
			val.CreateBool("Enabled", Color.green, _enabled.Value, (Action<bool>)delegate(bool v)
			{
				_enabled.Value = v;
				MelonPreferences.Save();
			});
			_fovElement = val.CreateFloat("FOV", Color.white, _fov.Value, _step.Value, 1f, 179f, (Action<float>)delegate(float v)
			{
				SetFov(v, updateMenu: false);
			});
			val.CreateFloat("Step Size", Color.yellow, _step.Value, 1f, 1f, 30f, (Action<float>)delegate(float v)
			{
				_step.Value = v;
				MelonPreferences.Save();
			});
			Page val2 = val.CreatePage("Presets", Color.magenta, 0, true);
			float[] array = new float[6] { 60f, 90f, 110f, 130f, 150f, 170f };
			foreach (float num2 in array)
			{
				float val3 = num2;
				val2.CreateFunction($"{val3:0}°", Color.white, (Action)delegate
				{
					SetFov(val3, updateMenu: true);
				});
			}
			val.CreateFunction("Reset FOV", Color.red, (Action)delegate
			{
				SetFov(90f, updateMenu: true);
			});
			val.CreateBool("Keyboard Hotkeys", Color.green, _hotkeys.Value, (Action<bool>)delegate(bool v)
			{
				_hotkeys.Value = v;
				MelonPreferences.Save();
			});
			Page val4 = val.CreatePage("Camera Targeting", Color.gray, 0, true);
			val4.CreateString("Name Filter", Color.white, _nameFilter.Value, (Action<string>)delegate(string v)
			{
				_nameFilter.Value = v ?? "";
				MelonPreferences.Save();
				_nextScan = 0f;
			});
			val4.CreateFunction("Clear Filter (auto-detect)", Color.yellow, (Action)delegate
			{
				_nameFilter.Value = "";
				MelonPreferences.Save();
				_nextScan = 0f;
				((MelonBase)this).LoggerInstance.Msg("Camera filter cleared.");
			});
			val4.CreateFunction("Rescan Cameras", Color.cyan, (Action)delegate
			{
				Rescan();
				((MelonBase)this).LoggerInstance.Msg($"Controlling {_cams.Length} camera(s).");
			});
			val4.CreateFunction("Log All Cameras To Console", Color.cyan, (Action)LogCameras);
		}

		public override void OnSceneWasInitialized(int buildIndex, string sceneName)
		{
			_nextScan = 0f;
		}

		public override void OnUpdate()
		{
			if (_hotkeys.Value)
			{
				float num = _step.Value * (Down(16) ? 3f : 1f);
				if (Edge(33, ref _pgUpHeld))
				{
					SetFov(_fov.Value + num, updateMenu: true);
				}
				if (Edge(34, ref _pgDnHeld))
				{
					SetFov(_fov.Value - num, updateMenu: true);
				}
				if (Edge(36, ref _homeHeld))
				{
					SetFov(90f, updateMenu: true);
				}
			}
		}

		public override void OnLateUpdate()
		{
			if (!_enabled.Value)
			{
				return;
			}
			if (Time.unscaledTime >= _nextScan)
			{
				_nextScan = Time.unscaledTime + 2f;
				Rescan();
			}
			float fieldOfView = Mathf.Clamp(_fov.Value, 1f, 179f);
			Camera[] cams = _cams;
			foreach (Camera val in cams)
			{
				if (!((Object)(object)val == (Object)null))
				{
					val.fieldOfView = fieldOfView;
				}
			}
		}

		private void SetFov(float value, bool updateMenu)
		{
			_fov.Value = Mathf.Clamp(value, 1f, 179f);
			MelonPreferences.Save();
			if (updateMenu && _fovElement != null)
			{
				try
				{
					_fovElement.Value = _fov.Value;
				}
				catch
				{
				}
			}
		}

		private void Rescan()
		{
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			Il2CppArrayBase<Camera> val = Object.FindObjectsOfType<Camera>();
			List<Camera> list = new List<Camera>();
			string value = _nameFilter.Value;
			foreach (Camera item in val)
			{
				if ((Object)(object)item == (Object)null)
				{
					continue;
				}
				if (!string.IsNullOrEmpty(value))
				{
					if (((Object)item).name.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0)
					{
						list.Add(item);
					}
				}
				else if ((int)item.stereoTargetEye == 0 && (Object)(object)item.targetTexture == (Object)null && ((Behaviour)item).enabled)
				{
					list.Add(item);
				}
			}
			_cams = list.ToArray();
		}

		private void LogCameras()
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			Rescan();
			((MelonBase)this).LoggerInstance.Msg("--- All cameras ---");
			foreach (Camera item in Object.FindObjectsOfType<Camera>())
			{
				((MelonBase)this).LoggerInstance.Msg($"{((Object)item).name} | stereo={item.stereoTargetEye} | rt={(Object)(object)item.targetTexture != (Object)null} | enabled={((Behaviour)item).enabled} | fov={item.fieldOfView}");
			}
			((MelonBase)this).LoggerInstance.Msg($"Currently controlling {_cams.Length} camera(s).");
		}

		private static bool Down(int vk)
		{
			return (GetAsyncKeyState(vk) & 0x8000) != 0;
		}

		private static bool Edge(int vk, ref bool held)
		{
			bool flag = Down(vk);
			bool result = flag && !held;
			held = flag;
			return result;
		}
	}
}