Decompiled source of CustomFov v1.0.0

Mods/CustomFov.dll

Decompiled a day 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 BoneLib;
using BoneLib.BoneMenu;
using CustomFov;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using MelonLoader;
using MelonLoader.Preferences;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(Main), "CustomFov", "1.0.0", "kamonkus", null)]
[assembly: MelonGame("Stress Level Zero", "BONELAB")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.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 CustomFov
{
	internal static class FovController
	{
		private static Camera _cam;

		private static float _gameFov = 90f;

		private static float _lastSet = -1f;

		private static float _nextSearch;

		private static float _nextProjCheck;

		private static bool _warnedNoCam;

		private static bool _projNoted;

		private static readonly string[] Keywords = new string[6] { "spectator", "mirror", "monitor", "desktop", "flat", "display" };

		public static void OnLevelLoaded()
		{
			_cam = null;
			_nextSearch = 0f;
		}

		private static List<Camera> Candidates()
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			List<Camera> list = new List<Camera>();
			Il2CppReferenceArray<Camera> allCameras = Camera.allCameras;
			for (int i = 0; i < ((Il2CppArrayBase<Camera>)(object)allCameras).Length; i++)
			{
				Camera val = ((Il2CppArrayBase<Camera>)(object)allCameras)[i];
				if (!((Object)(object)val == (Object)null) && ((Behaviour)val).enabled && ((Component)val).gameObject.activeInHierarchy && !((Object)(object)val.targetTexture != (Object)null) && (int)val.stereoTargetEye == 0)
				{
					list.Add(val);
				}
			}
			return list;
		}

		private static Camera PickCamera()
		{
			List<Camera> list = Candidates();
			if (list.Count == 0)
			{
				return null;
			}
			foreach (Camera item in list)
			{
				string text = ((Object)item).name.ToLowerInvariant();
				string[] keywords = Keywords;
				foreach (string value in keywords)
				{
					if (text.Contains(value))
					{
						return item;
					}
				}
			}
			Camera val = list[0];
			foreach (Camera item2 in list)
			{
				if (item2.depth > val.depth)
				{
					val = item2;
				}
			}
			return val;
		}

		private static void LogCameras()
		{
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Il2CppReferenceArray<Camera> allCameras = Camera.allCameras;
				for (int i = 0; i < ((Il2CppArrayBase<Camera>)(object)allCameras).Length; i++)
				{
					Camera val = ((Il2CppArrayBase<Camera>)(object)allCameras)[i];
					if (!((Object)(object)val == (Object)null))
					{
						MelonLogger.Msg("[CustomFov] camera: " + ((Object)val).name + " fov=" + val.fieldOfView.ToString("0.#") + " aspect=" + val.aspect.ToString("0.##") + " depth=" + val.depth + " stereo=" + ((object)val.stereoTargetEye/*cast due to .constrained prefix*/).ToString() + " texture=" + ((Object)(object)val.targetTexture != (Object)null) + " display=" + val.targetDisplay);
					}
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Warning("[CustomFov] could not list cameras: " + ex.Message);
			}
		}

		public static void Tick()
		{
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			float unscaledTime = Time.unscaledTime;
			if ((Object)(object)_cam == (Object)null || !((Behaviour)_cam).enabled || !((Component)_cam).gameObject.activeInHierarchy)
			{
				_cam = null;
				_lastSet = -1f;
				if (unscaledTime < _nextSearch)
				{
					return;
				}
				_nextSearch = unscaledTime + 1f;
				_cam = PickCamera();
				if ((Object)(object)_cam == (Object)null)
				{
					if (!_warnedNoCam)
					{
						_warnedNoCam = true;
						MelonLogger.Warning("[CustomFov] no monitor camera found yet.");
						LogCameras();
					}
					return;
				}
				_warnedNoCam = false;
				_gameFov = _cam.fieldOfView;
				MelonLogger.Msg("[CustomFov] using camera: " + ((Object)_cam).name + " (game FOV " + _gameFov.ToString("0.#") + ")");
				if (!Settings.Override.Value)
				{
					Settings.ShowFov(_gameFov);
				}
			}
			float fieldOfView = _cam.fieldOfView;
			if (_lastSet < 0f || !Mathf.Approximately(fieldOfView, _lastSet))
			{
				_gameFov = fieldOfView;
			}
			if (!Settings.Override.Value)
			{
				if (_lastSet >= 0f)
				{
					_cam.fieldOfView = _gameFov;
					_cam.ResetProjectionMatrix();
					_lastSet = -1f;
				}
				return;
			}
			float num = Mathf.Clamp(Settings.Fov.Value, 10f, 170f);
			if (!Mathf.Approximately(fieldOfView, num))
			{
				_cam.fieldOfView = num;
			}
			_lastSet = num;
			if (!(unscaledTime >= _nextProjCheck))
			{
				return;
			}
			_nextProjCheck = unscaledTime + 0.5f;
			float m = _cam.projectionMatrix.m11;
			if (Mathf.Abs(m) > 0.0001f && Mathf.Abs(2f * Mathf.Atan(1f / m) * 57.29578f - num) > 1f)
			{
				_cam.ResetProjectionMatrix();
				if (!_projNoted)
				{
					_projNoted = true;
					MelonLogger.Msg("[CustomFov] camera had a custom projection, it was reset to use the FOV.");
				}
			}
		}

		public static void ResetToGame()
		{
			Settings.Override.Value = false;
			Settings.Dirty();
			if ((Object)(object)_cam != (Object)null)
			{
				_cam.fieldOfView = _gameFov;
				_cam.ResetProjectionMatrix();
				_lastSet = -1f;
				Settings.ShowFov(_gameFov);
			}
		}
	}
	public class Main : MelonMod
	{
		private float _nextErrorLog;

		public override void OnInitializeMelon()
		{
			Settings.Init();
			Hooking.OnLevelLoaded += delegate
			{
				FovController.OnLevelLoaded();
			};
			Settings.BuildMenu();
			MelonLogger.Msg("CustomFov loaded. Open BoneMenu -> CustomFov.");
		}

		public override void OnLateUpdate()
		{
			try
			{
				FovController.Tick();
				Settings.Tick();
			}
			catch (Exception ex)
			{
				float realtimeSinceStartup = Time.realtimeSinceStartup;
				if (realtimeSinceStartup > _nextErrorLog)
				{
					_nextErrorLog = realtimeSinceStartup + 5f;
					MelonLogger.Error("[CustomFov] tick error: " + ex);
				}
			}
		}
	}
	public static class Settings
	{
		private static MelonPreferences_Category _cat;

		private static float _saveAt = -1f;

		private static bool _suppress;

		public static MelonPreferences_Entry<bool> Override;

		public static MelonPreferences_Entry<float> Fov;

		private static readonly float[] Steps = new float[2] { 1f, 10f };

		private static readonly FloatElement[] _rows = (FloatElement[])(object)new FloatElement[Steps.Length];

		public static void Init()
		{
			_cat = MelonPreferences.CreateCategory("CustomFov");
			Override = _cat.CreateEntry<bool>("OverrideFov", false, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			Fov = _cat.CreateEntry<float>("Fov", 90f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
		}

		public static void BuildMenu()
		{
			//IL_000a: 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_0091: Unknown result type (might be due to invalid IL or missing references)
			Page val = Page.Root.CreatePage("CustomFov", Color.cyan, 0, true);
			for (int i = 0; i < Steps.Length; i++)
			{
				_rows[i] = val.CreateFloat("FOV +/- " + (int)Steps[i], Color.white, Fov.Value, Steps[i], 10f, 170f, (Action<float>)OnFovChanged);
			}
			val.CreateFunction("Reset", Color.yellow, (Action)FovController.ResetToGame);
		}

		private static void OnFovChanged(float v)
		{
			if (!_suppress)
			{
				Fov.Value = v;
				Override.Value = true;
				ShowFov(v);
				Dirty();
			}
		}

		public static void ShowFov(float v)
		{
			bool suppress = _suppress;
			_suppress = true;
			try
			{
				for (int i = 0; i < _rows.Length; i++)
				{
					FloatElement val = _rows[i];
					if (val != null && !Mathf.Approximately(val.Value, v))
					{
						val.Value = v;
					}
				}
			}
			finally
			{
				_suppress = suppress;
			}
		}

		public static void Tick()
		{
			if (_saveAt > 0f && Time.realtimeSinceStartup >= _saveAt)
			{
				_saveAt = -1f;
				MelonPreferences.Save();
			}
		}

		public static void Dirty()
		{
			_saveAt = Time.realtimeSinceStartup + 1.5f;
		}
	}
}