Decompiled source of RealView v1.0.0

Mods/RealView.dll

Decompiled a day ago
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Threading;
using BoneLib;
using BoneLib.BoneMenu;
using BoneLib.Notifications;
using HarmonyLib;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSLZ.Bonelab.SaveData;
using Il2CppSLZ.Marrow;
using Il2CppSLZ.Marrow.SaveData;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using Il2CppSystem.Reflection;
using Il2CppTMPro;
using MelonLoader;
using MelonLoader.Logging;
using MelonLoader.Preferences;
using MelonLoader.Utils;
using Microsoft.CodeAnalysis;
using RealView;
using RealView.Core;
using RealView.Game;
using RealView.Native;
using RealView.Settings;
using RealView.UI;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
using UnityEngine.SceneManagement;
using UnityEngine.Scripting;
using UnityEngine.UI;
using UnityEngine.XR;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(RealViewMod), "RealView", "1.0.0", "Adam", null)]
[assembly: MelonGame("Stress Level Zero", "BONELAB")]
[assembly: MelonAdditionalDependencies(new string[] { "BoneLib" })]
[assembly: MelonColor(255, 79, 209, 255)]
[assembly: MelonAuthorColor(255, 255, 196, 0)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("RealView")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+fc175b1dea9c06d4da8564aa5a510f6095a039c6")]
[assembly: AssemblyProduct("RealView")]
[assembly: AssemblyTitle("RealView")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.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.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;
		}
	}
	[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 RealView
{
	internal sealed class Engine
	{
		private readonly Harmony _harmony;

		private bool _started;

		private bool _shutdown;

		private float _startupRetryAt;

		private int _startupFailures;

		private float _lastNotify = -100f;

		private bool _menuRetry;

		public readonly GraphicsController Graphics = new GraphicsController();

		public readonly SmoothController Smooth = new SmoothController();

		public readonly LookController Look = new LookController();

		public readonly PerfMonitor Perf = new PerfMonitor();

		public readonly Hud Hud = new Hud();

		private static float _menuHintAt = -100f;

		public static Engine Instance { get; private set; }

		public RealViewMenu Menu { get; private set; }

		public AutoGovernor Governor { get; private set; }

		public string LastAutoChange { get; private set; } = "";

		public bool Started => _started;

		public Engine(Harmony harmony)
		{
			_harmony = harmony;
			Instance = this;
		}

		public void Initialize()
		{
			Prefs.Init();
			Log.Msg($"RealView {"1.0.0"} loading. Mode {Prefs.Mode.Value}, smoothing {Prefs.Smoothing.Value}.");
			Hooking.OnMarrowGameStarted += TryStartup;
			Hooking.OnLevelLoading += delegate
			{
				Log.Soft("Level loading", OnLevelLoading);
			};
			Hooking.OnLevelLoaded += delegate
			{
				Log.Soft("Level loaded", OnLevelLoaded);
			};
			Hooking.OnSwitchAvatarPostfix += delegate
			{
				Log.Soft("Avatar", delegate
				{
					Graphics.OnAvatarChanged();
				});
			};
			ScriptGuard.Notify += Notify;
			Perf.WindowCompleted += OnWindow;
			Log.Try("Game hooks", PatchGame);
			Log.Try("Smoothing", delegate
			{
				Smooth.Capture();
				ApplySmoothing();
			});
		}

		public void BuildMenu()
		{
			if (Menu != null)
			{
				return;
			}
			if (Page.Root == null)
			{
				_menuRetry = true;
				return;
			}
			_menuRetry = false;
			Log.Try("Menu", delegate
			{
				Menu = new RealViewMenu(this);
				Menu.Build();
			});
		}

		private void TryStartup()
		{
			if (_started || _startupFailures >= 5)
			{
				return;
			}
			try
			{
				Startup();
			}
			catch (Exception ex)
			{
				_startupFailures++;
				if (_startupFailures == 1)
				{
					Log.Msg(ex.ToString());
				}
				if (_startupFailures < 5)
				{
					Log.Warn($"Startup failed ({ex.GetType().Name}: {ex.Message}); retrying.");
					_startupRetryAt = Clock.Now + 2f;
				}
				else
				{
					Log.Error("Graphics control could not start; smoothing and the other features still run.");
				}
			}
		}

		private void Startup()
		{
			if (_started)
			{
				return;
			}
			if (!Graphics.TryCapture())
			{
				_startupRetryAt = Clock.Now + 1f;
				return;
			}
			_started = true;
			if (!Prefs.CustomInitialized.Value)
			{
				Prefs.SetCustomProfile(Graphics.Original with
				{
					TextureSharpness = 0.35f,
					Anisotropic16x = true
				});
				Prefs.CustomInitialized.Value = true;
				Prefs.SaveSoon();
				Menu?.SyncAll();
			}
			Log.Soft("Graphics mode", delegate
			{
				ApplyGraphicsMode(announce: false);
			});
			Log.Soft("Look", Look.Apply);
			Log.Msg("RealView ready. " + Graphics.Describe());
		}

		public void ApplySmoothing()
		{
			Smooth.Apply();
			bool flag = Prefs.Smoothing.Value != SmoothLevel.Off;
			bool max = Prefs.Smoothing.Value == SmoothLevel.Max;
			LogShield.Apply(flag && Prefs.LogShield.Value, flag && Prefs.ScriptGuard.Value, Prefs.SwitchOffBroken.Value, max);
		}

		public void ApplyGraphicsMode(bool announce = true)
		{
			if (_started)
			{
				QualityMode value = Prefs.Mode.Value;
				if (!Graphics.Managing)
				{
					Graphics.RefreshOriginal();
				}
				Governor = null;
				switch (value)
				{
				case QualityMode.Off:
					Graphics.Release();
					break;
				case QualityMode.Auto:
					Governor = new AutoGovernor(GovernorConfigFromPrefs(), StartTier());
					ApplyTier(Governor.Tier);
					break;
				case QualityMode.Custom:
					Graphics.Apply(Prefs.CustomProfile());
					break;
				default:
					Graphics.Apply(TierTable.Compose(TierTable.TierFor(value), Prefs.CustomProfile(), lockResolution: false, lockFoveation: false));
					break;
				}
				Perf.MarkSettingChange();
				if (announce)
				{
					Notify("Quality: " + ModeLabel());
				}
			}
		}

		public void ApplyTier(int tier)
		{
			GraphicsProfile user = Prefs.CustomProfile();
			Graphics.Apply(TierTable.Compose(tier, user, Prefs.LockResolution.Value, Prefs.LockFoveation.Value));
			Perf.MarkSettingChange();
		}

		public void OnCustomChanged()
		{
			Prefs.SaveSoon();
			if (_started)
			{
				if (Prefs.Mode.Value == QualityMode.Custom)
				{
					Graphics.Apply(Prefs.CustomProfile());
				}
				else if (Prefs.Mode.Value == QualityMode.Auto && Governor != null)
				{
					ApplyTier(Governor.Tier);
				}
				else if (Prefs.Mode.Value != QualityMode.Off)
				{
					ApplyGraphicsMode(announce: false);
				}
			}
		}

		public void OnAutoSettingsChanged()
		{
			Prefs.SaveSoon();
			if (Prefs.Mode.Value == QualityMode.Auto)
			{
				ApplyGraphicsMode(announce: false);
			}
		}

		public void Update()
		{
			if (!_shutdown)
			{
				if (!_started && _startupRetryAt > 0f && Clock.Now >= _startupRetryAt)
				{
					_startupRetryAt = 0f;
					TryStartup();
				}
				if (_menuRetry)
				{
					BuildMenu();
				}
				bool loading = Smooth.Loading || Clock.Now - Smooth.LevelLoadedAt < 5f;
				float modMs = (LagFinder.Running ? ((float)LagFinder.Ledger.LastFrameMs) : 0f);
				Log.Soft("Perf", delegate
				{
					Perf.Update(loading, modMs);
				});
				LagFinder.EndFrame();
				Log.Soft("Lag Finder", LagFinder.Tick);
				LogShield.EndFrame();
				if (_started)
				{
					Log.Soft("Graphics", Graphics.Update);
				}
				Log.Soft("Smooth", delegate
				{
					Smooth.Update(QuietMoment());
				});
				Log.Soft("Script guard", ScriptGuard.ProcessQueue);
				Log.Soft("HUD", delegate
				{
					Hud.Update(HudText);
				});
				Menu?.Tick();
				Prefs.Tick();
			}
		}

		public void Shutdown()
		{
			if (!_shutdown)
			{
				_shutdown = true;
				if (Governor != null)
				{
					Prefs.LastAutoTier.Value = Governor.Tier;
				}
				Prefs.SaveNow();
				LagFinder.Stop();
				LogShield.Shutdown();
				Log.Soft("Shutdown", delegate
				{
					Smooth.RestoreAll();
				});
			}
		}

		public void Notify(string message)
		{
			if (Prefs.Notifications.Value && !(Clock.Now - _lastNotify < 1.5f))
			{
				_lastNotify = Clock.Now;
				Log.Soft("Notify", delegate
				{
					//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)
					//IL_000b: Unknown result type (might be due to invalid IL or missing references)
					//IL_0010: Unknown result type (might be due to invalid IL or missing references)
					//IL_0015: Unknown result type (might be due to invalid IL or missing references)
					//IL_001c: Unknown result type (might be due to invalid IL or missing references)
					//IL_0021: Unknown result type (might be due to invalid IL or missing references)
					//IL_0026: Unknown result type (might be due to invalid IL or missing references)
					//IL_002d: Unknown result type (might be due to invalid IL or missing references)
					//IL_0038: Unknown result type (might be due to invalid IL or missing references)
					//IL_003a: Unknown result type (might be due to invalid IL or missing references)
					//IL_0044: Expected O, but got Unknown
					Notifier.Send(new Notification
					{
						Title = NotificationText.op_Implicit("RealView"),
						Message = NotificationText.op_Implicit(message),
						ShowTitleOnPopup = true,
						PopupLength = 2.5f,
						Type = (NotificationType)0
					});
				});
			}
		}

		public string ModeLabel()
		{
			QualityMode value = Prefs.Mode.Value;
			if (value == QualityMode.Auto && Governor != null)
			{
				return "Auto (" + TierTable.Name(Governor.Tier) + (Governor.CpuLimited ? ", CPU-limited" : "") + ")";
			}
			return value.ToString();
		}

		public static string FpsColor(float fps, float target)
		{
			float num = ((target <= 0f) ? 1f : (fps / target));
			if (!(num >= 0.97f))
			{
				if (!(num >= 0.85f))
				{
					return "#FF6B6B";
				}
				return "#FFD34D";
			}
			return "#7CFF8A";
		}

		public string HudText()
		{
			float target = 1f / Perf.TargetInterval;
			float fps = Perf.Frames.AverageFps(1f);
			float fps2 = Perf.Frames.PercentileLowFps(1f, 10f);
			StringBuilder stringBuilder = new StringBuilder(256);
			stringBuilder.Append("<b>RealView</b>  <color=").Append(FpsColor(fps, target)).Append('>')
				.Append(fps.ToString("0"))
				.Append("</color> / ")
				.Append(target.ToString("0"))
				.Append(" fps");
			if (Prefs.HudInfo.Value == HudDetail.Minimal)
			{
				return stringBuilder.ToString();
			}
			stringBuilder.Append("\n1% low <color=").Append(FpsColor(fps2, target)).Append('>')
				.Append(fps2.ToString("0"))
				.Append("</color>  ·  ")
				.Append(Perf.Frames.AverageMs(1f).ToString("0.0"))
				.Append(" ms");
			if (Perf.GpuKnown)
			{
				stringBuilder.Append("  ·  GPU ").Append(Perf.GpuMs.ToString("0.0")).Append(" ms");
			}
			stringBuilder.Append('\n').Append(ModeLabel());
			float unscaledTime = Time.unscaledTime;
			float num = Perf.Stutters.PerMinute(unscaledTime, 60f);
			stringBuilder.Append("\nHitches/min ").Append(num.ToString("0"));
			if (unscaledTime - Perf.LastSpikeAt < 30f)
			{
				stringBuilder.Append("  ·  last: ").Append(StutterClassifier.Describe(Perf.LastCause));
			}
			if (LagFinder.Running)
			{
				ModLag modLag = LagFinder.Ledger.RankMods().FirstOrDefault();
				if (modLag != null)
				{
					stringBuilder.Append("\nTop mod: ").Append(modLag.Mod).Append(' ')
						.Append(modLag.RecentMs.ToString("0.00"))
						.Append(" ms");
				}
			}
			return stringBuilder.ToString();
		}

		private void OnLevelLoading()
		{
			Smooth.OnLevelLoading();
		}

		private void OnLevelLoaded()
		{
			if (!_started)
			{
				TryStartup();
			}
			Smooth.OnLevelLoaded();
			Graphics.OnLevelLoaded();
			Look.OnLevelLoaded();
		}

		private void OnWindow(float now, WindowSample sample)
		{
			if (Governor == null || Prefs.Mode.Value != QualityMode.Auto || !_started)
			{
				return;
			}
			GovernorDecision governorDecision = Governor.Update(now, sample);
			if (governorDecision.Changed)
			{
				ApplyTier(governorDecision.Tier);
				LastAutoChange = governorDecision.Reason;
				Prefs.LastAutoTier.Value = governorDecision.Tier;
				Prefs.SaveSoon();
				Log.Msg($"Auto: {governorDecision.Action} -> {TierTable.Name(governorDecision.Tier)} ({governorDecision.Reason}, missed {sample.MissRate:P0})");
				if (governorDecision.Action != GovernorAction.StepUp)
				{
					Notify(governorDecision.Reason);
				}
			}
		}

		private int StartTier()
		{
			int value = Prefs.LastAutoTier.Value;
			int val = Math.Max(0, Prefs.MinTier.Value);
			int val2 = Math.Min(TierTable.Count - 1, Prefs.MaxTier.Value);
			if (value >= 0)
			{
				return Math.Max(val, Math.Min(val2, value));
			}
			float num = (Graphics.Original ?? TierTable.Get(3)).EstimatedCost();
			int val3 = 3;
			float num2 = float.MaxValue;
			for (int i = 0; i < TierTable.Count; i++)
			{
				float num3 = Math.Abs(TierTable.Get(i).EstimatedCost() - num);
				if (num3 < num2)
				{
					num2 = num3;
					val3 = i;
				}
			}
			return Math.Max(val, Math.Min(val2, val3));
		}

		private GovernorConfig GovernorConfigFromPrefs()
		{
			GovernorConfig governorConfig = new GovernorConfig
			{
				MinTier = Math.Max(0, Math.Min(Prefs.MinTier.Value, TierTable.Count - 1)),
				MaxTier = Math.Max(0, Math.Min(Prefs.MaxTier.Value, TierTable.Count - 1)),
				WindowSeconds = Perf.WindowSeconds
			};
			if (governorConfig.MaxTier < governorConfig.MinTier)
			{
				governorConfig.MaxTier = governorConfig.MinTier;
			}
			switch (Prefs.AutoSpeed.Value)
			{
			case Aggressiveness.Gentle:
				governorConfig.DownMissRate = 0.12f;
				governorConfig.DownWindows = 3;
				governorConfig.UpStableSeconds = 30f;
				governorConfig.MinSecondsBetweenChanges = 8f;
				break;
			case Aggressiveness.Fast:
				governorConfig.DownMissRate = 0.05f;
				governorConfig.DownWindows = 1;
				governorConfig.UpStableSeconds = 12f;
				governorConfig.MinSecondsBetweenChanges = 3f;
				break;
			default:
				governorConfig.DownMissRate = 0.08f;
				governorConfig.DownWindows = 2;
				governorConfig.UpStableSeconds = 20f;
				governorConfig.MinSecondsBetweenChanges = 5f;
				break;
			}
			return governorConfig;
		}

		private static bool QuietMoment()
		{
			try
			{
				return TimeManager._isPaused;
			}
			catch
			{
				return false;
			}
		}

		private void PatchGame()
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Expected O, but got Unknown
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Expected O, but got Unknown
			HarmonyMethod hook = new HarmonyMethod(typeof(Engine).GetMethod("AfterGameApplied", BindingFlags.Static | BindingFlags.NonPublic));
			HarmonyMethod hook2 = new HarmonyMethod(typeof(Engine).GetMethod("AfterGameFoveation", BindingFlags.Static | BindingFlags.NonPublic));
			HarmonyMethod val = new HarmonyMethod(typeof(Engine).GetMethod("AfterGameMenuChange", BindingFlags.Static | BindingFlags.NonPublic));
			Type type = typeof(GraphicsManager);
			int count = 0;
			PatchAll(new string[5] { "RefreshQualitySettings", "SetQualityFromPreset", "CustomSet", "InitializeCustomSettings", "SetCurrentRenderer" }, hook);
			PatchAll(new string[2] { "SetFoveatedSettings", "CustomFoveatedSet" }, hook2);
			foreach (MethodInfo item in from x in type.GetMethods(BindingFlags.Static | BindingFlags.Public)
				where x.Name.StartsWith("Increase", StringComparison.Ordinal) || x.Name.StartsWith("Decrease", StringComparison.Ordinal)
				select x)
			{
				_harmony.Patch((MethodBase)item, (HarmonyMethod)null, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				count++;
			}
			Log.Msg($"Hooked {count} game graphics methods.");
			void PatchAll(string[] names, HarmonyMethod val2)
			{
				foreach (string name in names)
				{
					foreach (MethodInfo item2 in from x in type.GetMethods(BindingFlags.Static | BindingFlags.Public)
						where x.Name == name
						select x)
					{
						_harmony.Patch((MethodBase)item2, (HarmonyMethod)null, val2, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
						count++;
					}
				}
			}
		}

		private static void AfterGameApplied()
		{
			Instance?.Graphics.OnGameApplied();
		}

		private static void AfterGameFoveation()
		{
			Instance?.Graphics.OnGameFoveationApplied();
		}

		private static void AfterGameMenuChange()
		{
			Engine instance = Instance;
			if (instance != null && instance.Graphics.Managing)
			{
				instance.Graphics.OnGameMenuChanged();
				if (Clock.Now - _menuHintAt > 20f)
				{
					_menuHintAt = Clock.Now;
					instance.Notify("RealView is managing graphics. Set its Quality Mode to Off to use the game's menu.");
				}
			}
		}
	}
	public sealed class RealViewMod : MelonMod
	{
		public const string Version = "1.0.0";

		private Engine _engine;

		public override void OnInitializeMelon()
		{
			Log.Init(((MelonBase)this).LoggerInstance);
			_engine = new Engine(((MelonBase)this).HarmonyInstance);
			_engine.Initialize();
		}

		public override void OnLateInitializeMelon()
		{
			_engine?.BuildMenu();
		}

		public override void OnUpdate()
		{
			_engine?.Update();
		}

		public override void OnApplicationQuit()
		{
			_engine?.Shutdown();
		}

		public override void OnDeinitializeMelon()
		{
			_engine?.Shutdown();
		}
	}
}
namespace RealView.UI
{
	public enum MsaaOption
	{
		x1,
		x2,
		x4,
		x8
	}
	internal sealed class RealViewMenu
	{
		private static readonly Color Accent = new Color(0.31f, 0.82f, 1f);

		private static readonly Color Green = new Color(0.49f, 1f, 0.54f);

		private static readonly Color Yellow = new Color(1f, 0.83f, 0.3f);

		private static readonly Color Red = new Color(1f, 0.42f, 0.42f);

		private static readonly Color Purple = new Color(0.72f, 0.55f, 1f);

		private static readonly Color Orange = new Color(1f, 0.6f, 0.25f);

		private static readonly Color Gray = new Color(0.72f, 0.72f, 0.72f);

		private static readonly Color Teal = new Color(0.3f, 0.95f, 0.85f);

		private static readonly FieldInfo EnumIndexField = typeof(EnumElement).GetField("_index", BindingFlags.Instance | BindingFlags.NonPublic);

		private const int LagRows = 10;

		private const int SpamRows = 5;

		private const int BrokenRows = 5;

		private readonly Engine _e;

		private readonly HashSet<Page> _pages = new HashSet<Page>();

		private readonly List<Action> _syncers = new List<Action>();

		private float _nextRefresh;

		private Page _root;

		private FunctionElement _status;

		private FunctionElement _statFps;

		private FunctionElement _statLow;

		private FunctionElement _statFrame;

		private FunctionElement _statGpu;

		private FunctionElement _statTarget;

		private FunctionElement _statMode;

		private FunctionElement _statHitch;

		private FunctionElement _statCauses;

		private FunctionElement _statGc;

		private FunctionElement _statLogs;

		private FunctionElement _statDropped;

		private FunctionElement _autoTier;

		private FunctionElement _autoLast;

		private FunctionElement _smoothGc;

		private FunctionElement _lagState;

		private readonly List<FunctionElement> _lagRows = new List<FunctionElement>();

		private FunctionElement _shieldBlocked;

		private FunctionElement _shieldRate;

		private FunctionElement _guardState;

		private readonly List<FunctionElement> _brokenRows = new List<FunctionElement>();

		private readonly List<FunctionElement> _spamRows = new List<FunctionElement>();

		public RealViewMenu(Engine engine)
		{
			_e = engine;
		}

		public void Build()
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			_root = Page.Root.CreatePage("RealView", Accent, 0, true);
			Track(_root);
			Log.Soft("Menu logo", delegate
			{
				Texture2D val = LoadLogo();
				if ((Object)(object)val != (Object)null)
				{
					_root.Logo = val;
				}
			});
			_status = _root.CreateFunction("RealView starting…", Accent, (Action)delegate
			{
			});
			((Element)BindEnum<QualityMode>(_root, "Quality Mode", Green, Prefs.Mode, delegate
			{
				Prefs.SaveSoon();
				_e.ApplyGraphicsMode();
			})).SetTooltip("Auto holds your headset's frame rate. Off gives control back to the game.");
			((Element)BindEnum(_root, "Smoothing", Green, Prefs.Smoothing, delegate(SmoothLevel v)
			{
				OnSmoothingChanged();
				_e.Notify("Smoothing: " + v);
			})).SetTooltip("Stutter and lag fixes. Smooth is recommended; Max is strongest.");
			BindEnum<LookPreset>(_root, "Look", Orange, Prefs.Look, delegate
			{
				OnLookChanged();
			});
			BindEnum<HudMode>(_root, "Performance HUD", Teal, Prefs.Hud, delegate
			{
				OnSimpleChanged();
			});
			BuildStats();
			BuildAuto();
			BuildGraphics();
			BuildSmoothness();
			BuildLook();
			BuildLagFinder();
			BuildShield();
			BuildHud();
			BuildTools();
			Refresh();
		}

		public void Tick()
		{
			if (!(Clock.Now < _nextRefresh))
			{
				_nextRefresh = Clock.Now + 0.5f;
				Page currentPage = Menu.CurrentPage;
				if (currentPage != null && (_pages.Contains(currentPage) || (currentPage.Parent != null && _pages.Contains(currentPage.Parent))))
				{
					Log.Soft("Menu refresh", Refresh);
				}
			}
		}

		public void SyncAll()
		{
			foreach (Action syncer in _syncers)
			{
				try
				{
					syncer();
				}
				catch (Exception ex)
				{
					Log.WarnOnce("menu-sync", "Menu sync: " + ex.Message);
				}
			}
		}

		private void BuildStats()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			Page val = Sub("Live Stats", Color.white);
			_statFps = Label(val, Color.white);
			_statLow = Label(val, Color.white);
			_statFrame = Label(val, Gray);
			_statGpu = Label(val, Gray);
			_statTarget = Label(val, Gray);
			_statMode = Label(val, Accent);
			_statHitch = Label(val, Yellow);
			_statCauses = Label(val, Yellow);
			_statGc = Label(val, Gray);
			_statLogs = Label(val, Gray);
			_statDropped = Label(val, Gray);
			val.CreateFunction("Reset stats", Red, (Action)delegate
			{
				_e.Perf.Frames.Clear();
				_e.Perf.Stutters.Clear();
			});
		}

		private void BuildAuto()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: 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_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			Page val = Sub("Auto Tuner", Purple);
			_autoTier = Label(val, Purple);
			_autoLast = Label(val, Gray);
			((Element)BindEnum<TargetRate>(val, "Target FPS", Purple, Prefs.Target, delegate
			{
				_e.OnAutoSettingsChanged();
			})).SetTooltip("Headset = your headset's refresh rate.");
			((Element)BindEnum<Aggressiveness>(val, "Reaction", Purple, Prefs.AutoSpeed, delegate
			{
				_e.OnAutoSettingsChanged();
			})).SetTooltip("Gentle changes less often, Fast reacts sooner.");
			((Element)BindInt(val, "Lowest Tier", Purple, Prefs.MinTier, 1, 0, TierTable.Count - 1, _e.OnAutoSettingsChanged)).SetTooltip("0 Potato, 1 Performance, 2 Low, 3 Balanced, 4 Quality, 5 Ultra, 6 Extreme");
			((Element)BindInt(val, "Highest Tier", Purple, Prefs.MaxTier, 1, 0, TierTable.Count - 1, _e.OnAutoSettingsChanged)).SetTooltip("0 Potato, 1 Performance, 2 Low, 3 Balanced, 4 Quality, 5 Ultra, 6 Extreme");
			((Element)BindBool(val, "Lock Resolution", Purple, Prefs.LockResolution, _e.OnAutoSettingsChanged)).SetTooltip("Keep your Custom render scale and MSAA; Auto only changes effects (no resolution hitches).");
			BindBool(val, "Lock Foveation", Purple, Prefs.LockFoveation, _e.OnAutoSettingsChanged);
			val.CreateFunction("Forget Learned Tier", Red, (Action)delegate
			{
				Prefs.LastAutoTier.Value = -1;
				_e.OnAutoSettingsChanged();
				_e.Notify("Auto will re-learn from your settings.");
			});
		}

		private void BuildGraphics()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: 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_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0212: Unknown result type (might be due to invalid IL or missing references)
			//IL_023e: Unknown result type (might be due to invalid IL or missing references)
			//IL_027e: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_031f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0361: Unknown result type (might be due to invalid IL or missing references)
			Page val = Sub("Custom Graphics", Accent);
			((Element)val.CreateFunction("Used by Custom mode", Gray, (Action)delegate
			{
			})).SetTooltip("Auto also keeps these when Lock Resolution/Foveation is on.");
			((Element)BindInt(val, "Render Scale %", Accent, Prefs.RenderScale, 5, 50, 200, _e.OnCustomChanged)).SetTooltip("Above 100 = supersampling: sharper, heavier.");
			EnumElement msaa = val.CreateEnum("MSAA", Accent, (Enum)ToMsaa(Prefs.Msaa.Value), (Action<Enum>)delegate(Enum v)
			{
				Prefs.Msaa.Value = FromMsaa((MsaaOption)(object)v);
				_e.OnCustomChanged();
			});
			_syncers.Add(delegate
			{
				SetEnum(msaa, ToMsaa(Prefs.Msaa.Value));
			});
			BindEnum<Level>(val, "SMAA", Accent, Prefs.Smaa, delegate
			{
				_e.OnCustomChanged();
			});
			BindEnum<Level>(val, "Shadows", Accent, Prefs.Shadows, delegate
			{
				_e.OnCustomChanged();
			});
			BindInt(val, "Shadow Cascades", Accent, Prefs.ShadowCascades, 1, 1, 4, _e.OnCustomChanged);
			BindEnum<Level>(val, "Ambient Occlusion", Accent, Prefs.Hbao, delegate
			{
				_e.OnCustomChanged();
			});
			BindEnum<Level>(val, "Reflections", Accent, Prefs.Ssr, delegate
			{
				_e.OnCustomChanged();
			});
			BindEnum<Level>(val, "Volumetrics", Accent, Prefs.Volumetrics, delegate
			{
				_e.OnCustomChanged();
			});
			BindEnum<Level>(val, "Bloom", Accent, Prefs.Bloom, delegate
			{
				_e.OnCustomChanged();
			});
			BindInt(val, "Detail Distance %", Accent, Prefs.LodBias, 25, 50, 400, _e.OnCustomChanged);
			((Element)BindEnum<Foveation>(val, "Foveation", Accent, Prefs.FoveationLevel, delegate
			{
				_e.OnCustomChanged();
			})).SetTooltip("Full detail in the centre, less at the edges. Big FPS win on NVIDIA RTX.");
			((Element)BindFloat(val, "Texture Sharpness", Accent, Prefs.TextureSharpness, 0.05f, 0f, 1f, _e.OnCustomChanged)).SetTooltip("Crisper surfaces at a distance. 0.3-0.5 looks best in VR.");
			BindBool(val, "16x Anisotropic", Accent, Prefs.Anisotropic, _e.OnCustomChanged);
			val.CreateFunction("Copy My Game Settings", Yellow, (Action)delegate
			{
				if (!(_e.Graphics.RefreshOriginal() == null))
				{
					Prefs.SetCustomProfile(_e.Graphics.Original with
					{
						TextureSharpness = Prefs.TextureSharpness.Value,
						Anisotropic16x = Prefs.Anisotropic.Value
					});
					SyncAll();
					_e.OnCustomChanged();
					_e.Notify("Custom = your BONELAB settings");
				}
			});
			val.CreateFunction("Copy What's Active Now", Yellow, (Action)delegate
			{
				if (_e.Graphics.Applied == null)
				{
					_e.Notify("The game is in control (Quality Mode Off)");
				}
				else
				{
					Prefs.SetCustomProfile(_e.Graphics.Applied);
					SyncAll();
					_e.OnCustomChanged();
					_e.Notify("Custom = the active settings");
				}
			});
			for (int num = 1; num <= 3; num++)
			{
				int s = num;
				val.CreateFunction($"Save to Slot {s}", Green, (Action)delegate
				{
					Prefs.Slot(s).Value = Prefs.CustomProfile().Serialize();
					Prefs.SaveSoon();
					_e.Notify($"Saved Custom to slot {s}");
				});
				val.CreateFunction($"Load Slot {s}", Green, (Action)delegate
				{
					if (!GraphicsProfile.TryParse(Prefs.Slot(s).Value, out var profile))
					{
						_e.Notify($"Slot {s} is empty");
					}
					else
					{
						Prefs.SetCustomProfile(profile);
						SyncAll();
						_e.OnCustomChanged();
						_e.Notify($"Loaded slot {s}");
					}
				});
			}
		}

		private void BuildSmoothness()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			Page val = Sub("Smoothness", Green);
			_smoothGc = Label(val, Gray);
			BindEnum<SmoothLevel>(val, "Smoothing", Green, Prefs.Smoothing, delegate
			{
				OnSmoothingChanged();
			});
			Toggle(val, "CPU Priority Boost", Prefs.CpuBoost, "Higher priority, no Windows power throttling, 1 ms timer.");
			Toggle(val, "Smart Game GC", Prefs.SmartGc, "Smaller GC pauses; full collections moved to loading screens.");
			Toggle(val, "Low-Latency Mod GC", Prefs.ModGc, "Mods' .NET garbage collector avoids long pauses.");
			Toggle(val, "Smooth Streaming", Prefs.SmoothStreaming, "Spawning and texture uploads spread over frames; full speed while loading.");
			Toggle(val, "Clean Memory On Load", Prefs.CleanOnLoad, "Collect garbage during loading screens.");
			Toggle(val, "Log Spam Shield", Prefs.LogShield, "Repeated game log messages stop costing frame time.");
			Toggle(val, "Broken Script Guard", Prefs.ScriptGuard, "Finds scripts that throw an error every frame and silences their error spam.");
			Toggle(val, "Switch Off Broken Scripts", Prefs.SwitchOffBroken, "Off by default. Also switches the broken script off. Never touches your player rig or the game's systems.");
			((Element)val.CreateFunction("Clean Memory Now", Yellow, (Action)delegate
			{
				_e.Smooth.CleanMemory("request");
			})).SetTooltip("Causes a short pause: use it while standing still.");
		}

		private void BuildLook()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: 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)
			//IL_00d1: 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_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			Page page = Sub("Look & Color", Orange);
			BindEnum<LookPreset>(page, "Preset", Orange, Prefs.Look, delegate
			{
				OnLookChanged();
			});
			BindFloat(page, "Strength", Orange, Prefs.LookStrength, 0.1f, 0f, 1f, delegate
			{
				Prefs.SaveSoon();
				_e.Look.Apply();
			});
			BindFloat(page, "Exposure", Orange, Prefs.Exposure, 0.05f, -1f, 1f, SwitchLookToCustom);
			BindFloat(page, "Contrast", Orange, Prefs.Contrast, 2f, -50f, 50f, SwitchLookToCustom);
			BindFloat(page, "Saturation", Orange, Prefs.Saturation, 2f, -50f, 50f, SwitchLookToCustom);
			BindFloat(page, "Temperature", Orange, Prefs.Temperature, 2f, -50f, 50f, SwitchLookToCustom);
			BindFloat(page, "Tint", Orange, Prefs.Tint, 2f, -50f, 50f, SwitchLookToCustom);
			BindFloat(page, "Vignette", Orange, Prefs.Vignette, 0.02f, 0f, 0.5f, SwitchLookToCustom);
			((Element)BindEnum<Tonemapper>(page, "Tonemapper", Orange, Prefs.Tonemap, delegate
			{
				SwitchLookToCustom();
			})).SetTooltip("Keep the level's tonemapping, or force Neutral / ACES (filmic).");
		}

		private void BuildLagFinder()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: 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_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: 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_0120: Unknown result type (might be due to invalid IL or missing references)
			Page val = Sub("Lag Finder", Red);
			_lagState = Label(val, Gray);
			((Element)val.CreateFunction("Start", Green, (Action)delegate
			{
				int num2 = LagFinder.Start(Prefs.LagFinderDeep.Value);
				_e.Notify((num2 == 0) ? "Lag Finder: no mod update loops found" : $"Lag Finder timing {num2} mod callbacks");
			})).SetTooltip("Play normally for a minute, then check the list.");
			val.CreateFunction("Stop", Red, (Action)LagFinder.Stop);
			val.CreateFunction("Reset Numbers", Yellow, (Action)delegate
			{
				LagFinder.Ledger.Reset();
			});
			((Element)BindBool(val, "Deep Scan", Red, Prefs.LagFinderDeep, Prefs.SaveSoon)).SetTooltip("Also time mods' Harmony patches and their own scripts. Press Start again after changing.");
			val.CreateFunction("Save Report File", Yellow, (Action)delegate
			{
				string text = LagFinder.WriteReport(Path.Combine(MelonEnvironment.UserDataDirectory, "RealView"));
				Log.Msg("Lag report written to " + text);
				_e.Notify("Report saved in UserData/RealView");
			});
			for (int num = 0; num < 10; num++)
			{
				int index = num;
				_lagRows.Add(val.CreateFunction("", Color.white, (Action)delegate
				{
					ShowLagDetails(index);
				}));
			}
		}

		private void BuildShield()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: 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)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			Page val = Sub("Log Shield", Yellow);
			_shieldBlocked = Label(val, Yellow);
			_shieldRate = Label(val, Gray);
			_guardState = Label(val, Accent);
			for (int i = 0; i < 5; i++)
			{
				int index = i;
				_brokenRows.Add(val.CreateFunction("", Gray, (Action)delegate
				{
					ShowBrokenDetails(index);
				}));
			}
			val.CreateFunction("Turn Broken Scripts Back On", Green, (Action)delegate
			{
				int num2 = ScriptGuard.RestoreSwitchedOff();
				_e.Notify((num2 == 0) ? "No scripts are switched off" : $"Turned {num2} script(s) back on");
			});
			val.CreateFunction("Most repeated messages:", Gray, (Action)delegate
			{
			});
			for (int num = 0; num < 5; num++)
			{
				_spamRows.Add(Label(val, Gray));
			}
		}

		private void BuildHud()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			Page page = Sub("HUD", Teal);
			BindEnum<HudMode>(page, "Position", Teal, Prefs.Hud, delegate
			{
				OnSimpleChanged();
			});
			BindEnum<HudDetail>(page, "Detail", Teal, Prefs.HudInfo, delegate
			{
				OnSimpleChanged();
			});
			BindFloat(page, "Size", Teal, Prefs.HudScale, 0.1f, 0.5f, 2.5f, Prefs.SaveSoon);
		}

		private void BuildTools()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			Page val = Sub("Tools", Gray);
			BindBool(val, "Notifications", Gray, Prefs.Notifications, Prefs.SaveSoon);
			val.CreateFunction("Give Graphics Back To Game", Yellow, (Action)delegate
			{
				Prefs.Mode.Value = QualityMode.Off;
				SyncAll();
				Prefs.SaveSoon();
				_e.ApplyGraphicsMode();
			});
			val.CreateFunction("Write Diagnostics To Log", Gray, (Action)WriteDiagnostics);
			val.CreateFunction("Reset RealView Settings", Red, (Action)delegate
			{
				Menu.DisplayDialog("Reset RealView?", "All RealView settings go back to defaults.", (Texture2D)null, (Action)ResetAll, (Action)null);
			});
			val.CreateFunction("RealView 1.0.0 · Made By Adam", Accent, (Action)delegate
			{
			});
		}

		private void Refresh()
		{
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0585: Unknown result type (might be due to invalid IL or missing references)
			PerfMonitor perf = _e.Perf;
			float num = 1f / perf.TargetInterval;
			float num2 = perf.Frames.AverageFps(1f);
			float num3 = perf.Frames.PercentileLowFps(1f, 10f);
			float unscaledTime = Time.unscaledTime;
			((Element)_status).ElementName = (_e.Started ? $"{num2:0} FPS · {_e.ModeLabel()}" : "Waiting for the game…");
			((Element)_status).ElementColor = ColorFor(num2, num);
			Set(_statFps, $"FPS {num2:0.0} / {num:0}", ColorFor(num2, num));
			Set(_statLow, $"1% low {num3:0}", ColorFor(num3, num));
			Set(_statFrame, $"Frame {perf.Frames.AverageMs(1f):0.0} ms (budget {perf.TargetInterval * 1000f:0.0})");
			Set(_statGpu, perf.GpuKnown ? $"GPU {perf.GpuMs:0.0} ms" : "GPU time not reported by headset");
			Set(_statTarget, $"Refresh {perf.RefreshRate:0} Hz{(perf.RefreshFromHeadset ? "" : " (assumed)")}");
			Set(_statMode, _e.ModeLabel());
			Set(_statHitch, $"Hitches/min {perf.Stutters.PerMinute(unscaledTime, 60f):0}");
			IEnumerable<string> enumerable = from kv in (from kv in perf.Stutters.Count(unscaledTime, 60f)
					orderby kv.Value descending
					select kv).Take(3)
				select $"{StutterClassifier.Describe(kv.Key)} {kv.Value}";
			Set(_statCauses, "Causes: " + (enumerable.Any() ? string.Join(", ", enumerable) : "none"));
			Set(_statGc, $"GC: {_e.Smooth.GcStatus}, last {_e.Smooth.LastGcMs:0} ms");
			Set(_statLogs, $"Game logs {LogShield.LogsPerSecond:0.#}/s, {LogShield.Blocked:N0} blocked");
			Set(_statDropped, $"Dropped frames {perf.DroppedFrames:N0}");
			AutoGovernor governor = _e.Governor;
			Set(_autoTier, (governor == null) ? $"Auto is not the active mode ({Prefs.Mode.Value})" : $"Tier {governor.Tier}: {TierTable.Name(governor.Tier)}{(governor.CpuLimited ? " · CPU-limited" : "")}", Purple);
			Set(_autoLast, string.IsNullOrEmpty(_e.LastAutoChange) ? "No changes yet" : _e.LastAutoChange);
			Set(_smoothGc, "GC: " + _e.Smooth.GcStatus);
			RefreshLag();
			RefreshShield();
		}

		private void RefreshShield()
		{
			//IL_023e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0237: Unknown result type (might be due to invalid IL or missing references)
			Set(_shieldBlocked, $"Blocked {LogShield.Blocked:N0} of {LogShield.Seen:N0} log lines");
			Set(_shieldRate, $"Game logs now {LogShield.LogsPerSecond:0.#}/s{(LogShield.FilterFallback ? " (errors-only mode)" : "")}");
			IReadOnlyList<BrokenScript> scripts = ScriptGuard.Scripts;
			int switchedOffCount = ScriptGuard.SwitchedOffCount;
			Set(_guardState, (!ScriptGuard.Enabled) ? "Broken Script Guard is off" : ((scripts.Count == 0) ? "No broken scripts found" : $"Broken scripts: {scripts.Count} found, {switchedOffCount} switched off"));
			for (int i = 0; i < _brokenRows.Count; i++)
			{
				if (i >= scripts.Count)
				{
					Set(_brokenRows[i], "");
					continue;
				}
				BrokenScript brokenScript = scripts[i];
				string value = (brokenScript.SwitchedOff ? "off" : (brokenScript.Protected ? "kept (player/game)" : "silenced"));
				Set(_brokenRows[i], $"{Short(brokenScript.Script, 16)} · {Short(brokenScript.Object, 16)} · {value}", brokenScript.SwitchedOff ? Red : Yellow);
			}
			List<SpamEntry> list = LogShield.TopSpam(5);
			for (int j = 0; j < _spamRows.Count; j++)
			{
				Set(_spamRows[j], (j < list.Count) ? $"{list[j].Total:N0}× {Short(list[j].Key, 34)}" : "");
			}
		}

		private void RefreshLag()
		{
			//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_028b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			if (LagFinder.Active && !LagFinder.Running)
			{
				Set(_lagState, $"Preparing… {LagFinder.PendingCount} left");
				return;
			}
			if (!LagFinder.Running && LagFinder.Ledger.Frames == 0L)
			{
				Set(_lagState, "Press Start, then play for a minute");
				{
					foreach (FunctionElement lagRow in _lagRows)
					{
						Set(lagRow, "");
					}
					return;
				}
			}
			Set(_lagState, LagFinder.Running ? $"Running {LagFinder.Seconds:0} s · {LagFinder.PatchedCount} callbacks · mods {LagFinder.Ledger.LastFrameMs:0.00} ms" : "Stopped (last results below)");
			List<ModLag> list = LagFinder.Ledger.RankMods();
			float num = _e.Perf.TargetInterval * 1000f;
			for (int i = 0; i < _lagRows.Count; i++)
			{
				if (i >= list.Count)
				{
					Set(_lagRows[i], "");
					continue;
				}
				ModLag modLag = list[i];
				float num2 = ((num > 0f) ? ((float)(modLag.AverageMs / (double)num)) : 0f);
				Color value = ((num2 > 0.15f) ? Red : ((num2 > 0.05f) ? Yellow : Green));
				Set(_lagRows[i], $"{i + 1}. {Short(modLag.Mod, 18)} {modLag.AverageMs:0.00} ms · peak {modLag.PeakMs:0.0}", value);
			}
		}

		private void ShowLagDetails(int index)
		{
			List<ModLag> list = LagFinder.Ledger.RankMods();
			if (index >= list.Count)
			{
				return;
			}
			ModLag modLag = list[index];
			StringBuilder stringBuilder = new StringBuilder();
			StringBuilder stringBuilder2 = stringBuilder;
			StringBuilder stringBuilder3 = stringBuilder2;
			StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(38, 4, stringBuilder2);
			handler.AppendLiteral("Avg ");
			handler.AppendFormatted(modLag.AverageMs, "0.00");
			handler.AppendLiteral(" ms, peak ");
			handler.AppendFormatted(modLag.PeakMs, "0.0");
			handler.AppendLiteral(" ms, ");
			handler.AppendFormatted(modLag.AllocKbPerFrame, "0.0");
			handler.AppendLiteral(" KB/frame, logs ");
			handler.AppendFormatted(LagFinder.LogLinesPerSecond(modLag.Mod), "0.#");
			handler.AppendLiteral("/s\n");
			stringBuilder3.Append(ref handler);
			foreach (SiteLag item in LagFinder.Ledger.RankSites(modLag.Mod).Take(4))
			{
				stringBuilder2 = stringBuilder;
				StringBuilder stringBuilder4 = stringBuilder2;
				handler = new StringBuilder.AppendInterpolatedStringHandler(6, 2, stringBuilder2);
				handler.AppendFormatted(Short(item.Site, 40));
				handler.AppendLiteral(": ");
				handler.AppendFormatted(item.AverageMs, "0.00");
				handler.AppendLiteral(" ms\n");
				stringBuilder4.Append(ref handler);
			}
			Menu.DisplayDialog(modLag.Mod, stringBuilder.ToString().TrimEnd(), (Texture2D)null, (Action)null, (Action)null);
		}

		private void ShowBrokenDetails(int index)
		{
			IReadOnlyList<BrokenScript> scripts = ScriptGuard.Scripts;
			if (index < scripts.Count)
			{
				BrokenScript brokenScript = scripts[index];
				string value = (brokenScript.SwitchedOff ? "Switched off (Turn Broken Scripts Back On undoes this)." : (brokenScript.Protected ? "Left running: it belongs to your player or the game. Its errors are silenced." : "Left running; its errors are silenced. Turn on Switch Off Broken Scripts to disable it."));
				Menu.DisplayDialog(Short(brokenScript.Script, 28), $"On {Short(brokenScript.Object, 40)}\n{Short(brokenScript.Error, 90)}\n{brokenScript.Errors:N0}+ errors\n{value}", (Texture2D)null, (Action)null, (Action)null);
			}
		}

		private void OnSmoothingChanged()
		{
			Prefs.SaveSoon();
			SyncAll();
			_e.ApplySmoothing();
		}

		private void OnLookChanged()
		{
			Prefs.SaveSoon();
			SyncAll();
			_e.Look.Apply();
		}

		private void OnSimpleChanged()
		{
			Prefs.SaveSoon();
			SyncAll();
		}

		private void SwitchLookToCustom()
		{
			if (Prefs.Look.Value != LookPreset.Custom)
			{
				Prefs.Look.Value = LookPreset.Custom;
				SyncAll();
			}
			Prefs.SaveSoon();
			_e.Look.Apply();
		}

		private EnumElement BindEnum<T>(Page page, string name, Color color, MelonPreferences_Entry<T> entry, Action<T> changed) where T : struct, Enum
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			EnumElement element = page.CreateEnum(name, color, (Enum)entry.Value, (Action<Enum>)delegate(Enum v)
			{
				entry.Value = (T)v;
				changed?.Invoke((T)v);
			});
			_syncers.Add(delegate
			{
				SetEnum(element, entry.Value);
			});
			return element;
		}

		private IntElement BindInt(Page page, string name, Color color, MelonPreferences_Entry<int> entry, int step, int min, int max, Action changed)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			IntElement element = page.CreateInt(name, color, entry.Value, step, min, max, (Action<int>)delegate(int v)
			{
				entry.Value = v;
				changed?.Invoke();
			});
			_syncers.Add(delegate
			{
				if (element.Value != entry.Value)
				{
					element.Value = entry.Value;
				}
			});
			return element;
		}

		private FloatElement BindFloat(Page page, string name, Color color, MelonPreferences_Entry<float> entry, float step, float min, float max, Action changed)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			FloatElement element = page.CreateFloat(name, color, entry.Value, step, min, max, (Action<float>)delegate(float v)
			{
				entry.Value = v;
				changed?.Invoke();
			});
			_syncers.Add(delegate
			{
				if (Math.Abs(element.Value - entry.Value) > 0.0001f)
				{
					element.Value = entry.Value;
				}
			});
			return element;
		}

		private BoolElement BindBool(Page page, string name, Color color, MelonPreferences_Entry<bool> entry, Action changed)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			BoolElement element = page.CreateBool(name, color, entry.Value, (Action<bool>)delegate(bool v)
			{
				entry.Value = v;
				changed?.Invoke();
			});
			_syncers.Add(delegate
			{
				if (element.Value != entry.Value)
				{
					element.Value = entry.Value;
				}
			});
			return element;
		}

		private void Toggle(Page page, string name, MelonPreferences_Entry<bool> entry, string tooltip)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			((Element)BindBool(page, name, Green, entry, delegate
			{
				Prefs.SaveSoon();
				_e.ApplySmoothing();
			})).SetTooltip(tooltip);
		}

		private static void SetEnum(EnumElement element, Enum value)
		{
			if (element != null && value != null && !object.Equals(element.Value, value))
			{
				int num = Array.IndexOf(Enum.GetValues(value.GetType()), value);
				if (num >= 0)
				{
					EnumIndexField?.SetValue(element, num + 1);
				}
				element.Value = value;
			}
		}

		private Page Sub(string name, Color color)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			Page val = _root.CreatePage(name, color, 0, true);
			Track(val);
			return val;
		}

		private void Track(Page page)
		{
			_pages.Add(page);
		}

		private static FunctionElement Label(Page page, Color color)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return page.CreateFunction("…", color, (Action)delegate
			{
			});
		}

		private void WriteDiagnostics()
		{
			//IL_026d: Unknown result type (might be due to invalid IL or missing references)
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.AppendLine("RealView 1.0.0 diagnostics");
			StringBuilder stringBuilder2 = stringBuilder;
			StringBuilder stringBuilder3 = stringBuilder2;
			StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(24, 3, stringBuilder2);
			handler.AppendLiteral("Mode ");
			handler.AppendFormatted(_e.ModeLabel());
			handler.AppendLiteral(", smoothing ");
			handler.AppendFormatted(Prefs.Smoothing.Value);
			handler.AppendLiteral(", look ");
			handler.AppendFormatted(Prefs.Look.Value);
			stringBuilder3.AppendLine(ref handler);
			stringBuilder.AppendLine("Engine: " + _e.Graphics.Describe());
			stringBuilder.AppendLine("Applied: " + (_e.Graphics.Applied?.Serialize() ?? "game control"));
			stringBuilder.AppendLine("Game settings: " + (_e.Graphics.Original?.Serialize() ?? "not captured"));
			stringBuilder2 = stringBuilder;
			StringBuilder stringBuilder4 = stringBuilder2;
			handler = new StringBuilder.AppendInterpolatedStringHandler(28, 3, stringBuilder2);
			handler.AppendLiteral("Refresh ");
			handler.AppendFormatted(_e.Perf.RefreshRate, "0");
			handler.AppendLiteral(" Hz (headset ");
			handler.AppendFormatted(_e.Perf.RefreshFromHeadset);
			handler.AppendLiteral("), GPU ");
			handler.AppendFormatted(_e.Perf.GpuKnown ? (_e.Perf.GpuMs.ToString("0.0") + " ms") : "n/a");
			stringBuilder4.AppendLine(ref handler);
			stringBuilder2 = stringBuilder;
			StringBuilder stringBuilder5 = stringBuilder2;
			handler = new StringBuilder.AppendInterpolatedStringHandler(35, 3, stringBuilder2);
			handler.AppendLiteral("GC: ");
			handler.AppendFormatted(_e.Smooth.GcStatus);
			handler.AppendLiteral(", manual collections ");
			handler.AppendFormatted(_e.Smooth.ManualCollections);
			handler.AppendLiteral(", last ");
			handler.AppendFormatted(_e.Smooth.LastGcMs, "0");
			handler.AppendLiteral(" ms");
			stringBuilder5.AppendLine(ref handler);
			stringBuilder2 = stringBuilder;
			StringBuilder stringBuilder6 = stringBuilder2;
			handler = new StringBuilder.AppendInterpolatedStringHandler(47, 4, stringBuilder2);
			handler.AppendLiteral("Loading priority ");
			handler.AppendFormatted<ThreadPriority>(Application.backgroundLoadingPriority);
			handler.AppendLiteral(", upload ");
			handler.AppendFormatted(QualitySettings.asyncUploadTimeSlice);
			handler.AppendLiteral(" ms / ");
			handler.AppendFormatted(QualitySettings.asyncUploadBufferSize);
			handler.AppendLiteral(" MB, max delta ");
			handler.AppendFormatted(Time.maximumDeltaTime, "0.###");
			stringBuilder6.AppendLine(ref handler);
			stringBuilder2 = stringBuilder;
			StringBuilder stringBuilder7 = stringBuilder2;
			handler = new StringBuilder.AppendInterpolatedStringHandler(23, 3, stringBuilder2);
			handler.AppendLiteral("Log handler ");
			handler.AppendFormatted(LogShield.HandlerActive ? "active" : "not installed");
			handler.AppendLiteral(", blocked ");
			handler.AppendFormatted(LogShield.Blocked, "N0");
			handler.AppendLiteral("/");
			handler.AppendFormatted(LogShield.Seen, "N0");
			stringBuilder7.AppendLine(ref handler);
			stringBuilder2 = stringBuilder;
			StringBuilder stringBuilder8 = stringBuilder2;
			handler = new StringBuilder.AppendInterpolatedStringHandler(54, 3, stringBuilder2);
			handler.AppendLiteral("Broken scripts: ");
			handler.AppendFormatted(ScriptGuard.Scripts.Count);
			handler.AppendLiteral(" found, ");
			handler.AppendFormatted(ScriptGuard.SwitchedOffCount);
			handler.AppendLiteral(" switched off (switching off ");
			handler.AppendFormatted(Prefs.SwitchOffBroken.Value ? "on" : "off");
			handler.AppendLiteral(")");
			stringBuilder8.AppendLine(ref handler);
			foreach (BrokenScript script in ScriptGuard.Scripts)
			{
				stringBuilder2 = stringBuilder;
				StringBuilder stringBuilder9 = stringBuilder2;
				handler = new StringBuilder.AppendInterpolatedStringHandler(27, 6, stringBuilder2);
				handler.AppendLiteral("  ");
				handler.AppendFormatted(script.Script);
				handler.AppendLiteral(" on '");
				handler.AppendFormatted(script.Object);
				handler.AppendLiteral("' at ");
				handler.AppendFormatted(script.Site);
				handler.AppendLiteral(": ");
				handler.AppendFormatted(script.Errors, "N0");
				handler.AppendLiteral("+ errors, ");
				handler.AppendFormatted(script.SwitchedOff ? "switched off" : (script.Protected ? "protected" : "silenced"));
				handler.AppendLiteral(" (");
				handler.AppendFormatted(script.Error);
				handler.AppendLiteral(")");
				stringBuilder9.AppendLine(ref handler);
			}
			foreach (KeyValuePair<StutterCause, int> item in _e.Perf.Stutters.Count(Time.unscaledTime, 300f))
			{
				stringBuilder2 = stringBuilder;
				StringBuilder stringBuilder10 = stringBuilder2;
				handler = new StringBuilder.AppendInterpolatedStringHandler(20, 2, stringBuilder2);
				handler.AppendLiteral("  hitches (5 min) ");
				handler.AppendFormatted(StutterClassifier.Describe(item.Key));
				handler.AppendLiteral(": ");
				handler.AppendFormatted(item.Value);
				stringBuilder10.AppendLine(ref handler);
			}
			Log.Msg(stringBuilder.ToString());
			_e.Notify("Diagnostics written to the MelonLoader log");
		}

		private void ResetAll()
		{
			foreach (MelonPreferences_Entry entry in MelonPreferences.GetCategory("RealView").Entries)
			{
				entry.ResetToDefault();
			}
			if (_e.Graphics.RefreshOriginal() != null)
			{
				Prefs.SetCustomProfile(_e.Graphics.Original with
				{
					TextureSharpness = 0.35f,
					Anisotropic16x = true
				});
				Prefs.CustomInitialized.Value = true;
			}
			Prefs.SaveNow();
			SyncAll();
			_e.ApplySmoothing();
			_e.ApplyGraphicsMode();
			_e.Look.Apply();
			_e.Notify("RealView settings reset to defaults");
		}

		private static void Set(FunctionElement element, string text, Color? color = null)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			if (element != null)
			{
				if (((Element)element).ElementName != text)
				{
					((Element)element).ElementName = text;
				}
				if (color.HasValue && ((Element)element).ElementColor != color.Value)
				{
					((Element)element).ElementColor = color.Value;
				}
			}
		}

		private static Color ColorFor(float fps, float target)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			float num = ((target <= 0f) ? 1f : (fps / target));
			if (!(num >= 0.97f))
			{
				if (!(num >= 0.85f))
				{
					return Red;
				}
				return Yellow;
			}
			return Green;
		}

		private static string Short(string s, int max)
		{
			if (!string.IsNullOrEmpty(s) && s.Length > max)
			{
				return s.Substring(0, max - 1) + "…";
			}
			return s ?? "";
		}

		private static MsaaOption ToMsaa(int v)
		{
			if (v < 8)
			{
				if (v < 4)
				{
					if (v < 2)
					{
						return MsaaOption.x1;
					}
					return MsaaOption.x2;
				}
				return MsaaOption.x4;
			}
			return MsaaOption.x8;
		}

		private static int FromMsaa(MsaaOption o)
		{
			return o switch
			{
				MsaaOption.x2 => 2, 
				MsaaOption.x4 => 4, 
				MsaaOption.x8 => 8, 
				_ => 1, 
			};
		}

		private static Texture2D LoadLogo()
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			using Stream stream = typeof(RealViewMenu).Assembly.GetManifestResourceStream("RealView.icon.png");
			if (stream == null)
			{
				return null;
			}
			using MemoryStream memoryStream = new MemoryStream();
			stream.CopyTo(memoryStream);
			Texture2D val = new Texture2D(2, 2);
			if (!ImageConversion.LoadImage(val, Il2CppStructArray<byte>.op_Implicit(memoryStream.ToArray()), false))
			{
				return null;
			}
			((Object)val).hideFlags = (HideFlags)32;
			return val;
		}
	}
}
namespace RealView.Settings
{
	public enum SmoothLevel
	{
		Off,
		Smooth,
		Max
	}
	public enum TargetRate
	{
		Headset,
		Fps72,
		Fps80,
		Fps90,
		Fps120,
		Fps144
	}
	public enum Aggressiveness
	{
		Gentle,
		Normal,
		Fast
	}
	public enum LookPreset
	{
		GameDefault,
		Natural,
		Vivid,
		Cinematic,
		Warm,
		Cool,
		Custom
	}
	public enum Tonemapper
	{
		Keep,
		Neutral,
		ACES
	}
	public enum HudMode
	{
		Off,
		LeftWrist,
		RightWrist,
		View
	}
	public enum HudDetail
	{
		Minimal,
		Full
	}
	internal static class Prefs
	{
		private static MelonPreferences_Category _cat;

		private static float _saveAt = -1f;

		public static MelonPreferences_Entry<QualityMode> Mode;

		public static MelonPreferences_Entry<SmoothLevel> Smoothing;

		public static MelonPreferences_Entry<bool> Notifications;

		public static MelonPreferences_Entry<bool> CustomInitialized;

		public static MelonPreferences_Entry<int> RenderScale;

		public static MelonPreferences_Entry<int> Msaa;

		public static MelonPreferences_Entry<Level> Smaa;

		public static MelonPreferences_Entry<Level> Shadows;

		public static MelonPreferences_Entry<int> ShadowCascades;

		public static MelonPreferences_Entry<Level> Hbao;

		public static MelonPreferences_Entry<Level> Ssr;

		public static MelonPreferences_Entry<Level> Volumetrics;

		public static MelonPreferences_Entry<Level> Bloom;

		public static MelonPreferences_Entry<int> LodBias;

		public static MelonPreferences_Entry<Foveation> FoveationLevel;

		public static MelonPreferences_Entry<float> TextureSharpness;

		public static MelonPreferences_Entry<bool> Anisotropic;

		public static MelonPreferences_Entry<string> Slot1;

		public static MelonPreferences_Entry<string> Slot2;

		public static MelonPreferences_Entry<string> Slot3;

		public static MelonPreferences_Entry<TargetRate> Target;

		public static MelonPreferences_Entry<Aggressiveness> AutoSpeed;

		public static MelonPreferences_Entry<int> MinTier;

		public static MelonPreferences_Entry<int> MaxTier;

		public static MelonPreferences_Entry<bool> LockResolution;

		public static MelonPreferences_Entry<bool> LockFoveation;

		public static MelonPreferences_Entry<int> LastAutoTier;

		public static MelonPreferences_Entry<bool> CpuBoost;

		public static MelonPreferences_Entry<bool> SmartGc;

		public static MelonPreferences_Entry<bool> ModGc;

		public static MelonPreferences_Entry<bool> SmoothStreaming;

		public static MelonPreferences_Entry<bool> CleanOnLoad;

		public static MelonPreferences_Entry<bool> LogShield;

		public static MelonPreferences_Entry<bool> ScriptGuard;

		public static MelonPreferences_Entry<bool> SwitchOffBroken;

		public static MelonPreferences_Entry<LookPreset> Look;

		public static MelonPreferences_Entry<float> LookStrength;

		public static MelonPreferences_Entry<float> Exposure;

		public static MelonPreferences_Entry<float> Contrast;

		public static MelonPreferences_Entry<float> Saturation;

		public static MelonPreferences_Entry<float> Temperature;

		public static MelonPreferences_Entry<float> Tint;

		public static MelonPreferences_Entry<float> Vignette;

		public static MelonPreferences_Entry<Tonemapper> Tonemap;

		public static MelonPreferences_Entry<HudMode> Hud;

		public static MelonPreferences_Entry<HudDetail> HudInfo;

		public static MelonPreferences_Entry<float> HudScale;

		public static MelonPreferences_Entry<bool> LagFinderDeep;

		public static void Init()
		{
			_cat = MelonPreferences.CreateCategory("RealView", "RealView (Made By Adam)");
			Mode = E("Mode", QualityMode.Auto, "Off = the game's own settings. Auto = hold your headset's refresh rate. Performance/Balanced/Quality/Ultra/Extreme = fixed presets. Custom = the values below.");
			Smoothing = E("Smoothing", SmoothLevel.Smooth, "Stutter and lag fixes. Off / Smooth (recommended) / Max (strongest, trades a little load speed for smoothness).");
			Notifications = E("Notifications", value: true, "Show a small notification when the Auto tuner changes quality or a broken script is found.");
			CustomInitialized = E("CustomInitialized", value: false, "Internal: the Custom values below were copied from your game settings.");
			RenderScale = E("RenderScale", 100, "Custom: render scale in percent (50-200). Above 100 is supersampling (sharper, heavier).");
			Msaa = E("MSAA", 4, "Custom: MSAA samples (1, 2, 4, 8).");
			Smaa = E("SMAA", Level.Low, "Custom: post anti-aliasing quality.");
			Shadows = E("Shadows", Level.Medium, "Custom: shadow quality.");
			ShadowCascades = E("ShadowCascades", 2, "Custom: shadow cascades (1-4). More = sharper shadows further away, more CPU and GPU.");
			Hbao = E("AmbientOcclusion", Level.Low, "Custom: HBAO ambient occlusion (contact shadows).");
			Ssr = E("Reflections", Level.Off, "Custom: screen-space reflections.");
			Volumetrics = E("Volumetrics", Level.Low, "Custom: volumetric lighting and fog.");
			Bloom = E("Bloom", Level.Medium, "Custom: bloom glow.");
			LodBias = E("LODBias", 150, "Custom: level-of-detail distance in percent (50-400). Higher keeps full detail further away.");
			FoveationLevel = E("Foveation", Foveation.Wide, "Custom: foveated rendering. Off / Wide / Medium / Narrow (more savings, blurrier edges).");
			TextureSharpness = E("TextureSharpness", 0.35f, "Texture sharpness 0-1 (negative mip bias). Makes surfaces crisper at a distance.");
			Anisotropic = E("Anisotropic16x", value: true, "Force 16x anisotropic filtering: sharp floors and walls at angles, very cheap.");
			Slot1 = E("Slot1", "", "Saved custom profile 1.");
			Slot2 = E("Slot2", "", "Saved custom profile 2.");
			Slot3 = E("Slot3", "", "Saved custom profile 3.");
			Target = E("AutoTarget", TargetRate.Headset, "Frame rate the Auto tuner holds. Headset = your headset's refresh rate.");
			AutoSpeed = E("AutoSpeed", Aggressiveness.Normal, "How quickly Auto reacts. Gentle changes less often, Fast reacts sooner.");
			MinTier = E("AutoMinTier", 0, "Lowest tier Auto may use (0 Potato ... 6 Extreme).");
			MaxTier = E("AutoMaxTier", 5, "Highest tier Auto may use (0 Potato ... 6 Extreme).");
			LockResolution = E("AutoLockResolution", value: false, "Auto keeps your Custom render scale and MSAA (no resolution changes, so no reallocation hitch).");
			LockFoveation = E("AutoLockFoveation", value: false, "Auto keeps your Custom foveation setting.");
			LastAutoTier = E("AutoLastTier", -1, "Internal: the tier Auto settled on last session (it starts from here).");
			CpuBoost = E("CpuBoost", value: true, "Raise BONELAB's process priority, stop Windows power throttling it, and use a 1 ms timer.");
			SmartGc = E("SmartGC", value: true, "Tune the game's garbage collector so it pauses less, and move collections to loading screens and pauses.");
			ModGc = E("ModGC", value: true, "Low-latency garbage collection for mods (.NET side).");
			SmoothStreaming = E("SmoothStreaming", value: true, "Spread asset loading and texture uploads over frames during gameplay (fewer spawn hitches) and go full speed on loading screens.");
			CleanOnLoad = E("CleanMemoryOnLoad", value: true, "Clean memory during loading screens so gameplay starts with a clean heap.");
			LogShield = E("LogSpamShield", value: true, "Stop repeated game log messages and their stack traces from eating frame time.");
			ScriptGuard = E("BrokenScriptGuard", value: true, "Find scripts that throw an error every frame (for example a broken modded gun), report them and stop their error spam.");
			SwitchOffBroken = E("SwitchOffBrokenScripts", value: false, "Optional: also switch the broken script itself off. Never touches your player rig or the game's own systems. Log Shield page can turn them back on.");
			Look = E("Look", LookPreset.Natural, "Colour look: GameDefault / Natural / Vivid / Cinematic / Warm / Cool / Custom.");
			LookStrength = E("LookStrength", 1f, "Strength of the colour look (0-1).");
			Exposure = E("Exposure", 0f, "Custom look: exposure in stops (-1 to 1).");
			Contrast = E("Contrast", 10f, "Custom look: contrast (-50 to 50).");
			Saturation = E("Saturation", 5f, "Custom look: saturation (-50 to 50).");
			Temperature = E("Temperature", 0f, "Custom look: white balance temperature (-50 to 50).");
			Tint = E("Tint", 0f, "Custom look: white balance tint (-50 to 50).");
			Vignette = E("Vignette", 0f, "Custom look: vignette (0-0.5).");
			Tonemap = E("Tonemapper", Tonemapper.Keep, "Custom look: Keep the level's tonemapping, or force Neutral / ACES (filmic).");
			Hud = E("HUD", HudMode.Off, "Performance readout: Off / LeftWrist / RightWrist / View.");
			HudInfo = E("HUDDetail", HudDetail.Full, "HUD detail: Minimal (FPS only) or Full.");
			HudScale = E("HUDScale", 1f, "HUD size multiplier.");
			LagFinderDeep = E("LagFinderDeepMode", value: false, "Lag Finder also times mods' Harmony patches and their own MonoBehaviours, not just their update loops (more detail, a little more overhead while it runs).");
		}

		public static GraphicsProfile CustomProfile()
		{
			return new GraphicsProfile
			{
				RenderScalePercent = RenderScale.Value,
				Msaa = Msaa.Value,
				Smaa = Smaa.Value,
				Shadows = Shadows.Value,
				ShadowCascades = ShadowCascades.Value,
				Hbao = Hbao.Value,
				Ssr = Ssr.Value,
				Volumetrics = Volumetrics.Value,
				Bloom = Bloom.Value,
				LodBiasPercent = LodBias.Value,
				Foveation = FoveationLevel.Value,
				TextureSharpness = TextureSharpness.Value,
				Anisotropic16x = Anisotropic.Value
			}.Sanitized();
		}

		public static void SetCustomProfile(GraphicsProfile p)
		{
			p = p.Sanitized();
			RenderScale.Value = p.RenderScalePercent;
			Msaa.Value = p.Msaa;
			Smaa.Value = p.Smaa;
			Shadows.Value = p.Shadows;
			ShadowCascades.Value = p.ShadowCascades;
			Hbao.Value = p.Hbao;
			Ssr.Value = p.Ssr;
			Volumetrics.Value = p.Volumetrics;
			Bloom.Value = p.Bloom;
			LodBias.Value = p.LodBiasPercent;
			FoveationLevel.Value = p.Foveation;
			TextureSharpness.Value = p.TextureSharpness;
			Anisotropic.Value = p.Anisotropic16x;
			SaveSoon();
		}

		public static MelonPreferences_Entry<string> Slot(int index)
		{
			return (MelonPreferences_Entry<string>)(index switch
			{
				2 => Slot2, 
				1 => Slot1, 
				_ => Slot3, 
			});
		}

		public static void SaveSoon()
		{
			_saveAt = Clock.Now + 2f;
		}

		public static void Tick()
		{
			if (!(_saveAt < 0f) && !(Clock.Now < _saveAt))
			{
				_saveAt = -1f;
				MelonPreferences_Category cat = _cat;
				if (cat != null)
				{
					cat.SaveToFile(false);
				}
			}
		}

		public static void SaveNow()
		{
			_saveAt = -1f;
			MelonPreferences_Category cat = _cat;
			if (cat != null)
			{
				cat.SaveToFile(false);
			}
		}

		private static MelonPreferences_Entry<T> E<T>(string id, T value, string description)
		{
			return _cat.CreateEntry<T>(id, value, id, description, false, false, (ValueValidator)null, (string)null);
		}
	}
}
namespace RealView.Native
{
	internal static class Win32
	{
		private struct PowerThrottlingState
		{
			public uint Version;

			public uint ControlMask;

			public uint StateMask;
		}

		public const uint NormalPriority = 32u;

		public const uint AboveNormalPriority = 32768u;

		public const uint HighPriority = 128u;

		private const int ProcessPowerThrottling = 4;

		private const uint PowerThrottlingCurrentVersion = 1u;

		private const uint PowerThrottlingExecutionSpeed = 1u;

		private const uint PowerThrottlingIgnoreTimerResolution = 4u;

		[DllImport("kernel32.dll")]
		private static extern IntPtr GetCurrentProcess();

		[DllImport("kernel32.dll", SetLastError = true)]
		private static extern uint GetPriorityClass(IntPtr process);

		[DllImport("kernel32.dll", SetLastError = true)]
		private static extern bool SetPriorityClass(IntPtr process, uint priorityClass);

		[DllImport("kernel32.dll", SetLastError = true)]
		private static extern bool SetProcessInformation(IntPtr process, int infoClass, ref PowerThrottlingState info, int size);

		[DllImport("winmm.dll")]
		private static extern uint timeBeginPeriod(uint period);

		[DllImport("winmm.dll")]
		private static extern uint timeEndPeriod(uint period);

		public static uint GetPriority()
		{
			try
			{
				return GetPriorityClass(GetCurrentProcess());
			}
			catch
			{
				return 0u;
			}
		}

		public static bool SetPriority(uint priorityClass)
		{
			try
			{
				return SetPriorityClass(GetCurrentProcess(), priorityClass);
			}
			catch
			{
				return false;
			}
		}

		public static bool SetPowerThrottling(bool allowThrottling)
		{
			try
			{
				PowerThrottlingState info = new PowerThrottlingState
				{
					Version = 1u,
					ControlMask = ((!allowThrottling) ? 5u : 0u),
					StateMask = 0u
				};
				return SetProcessInformation(GetCurrentProcess(), 4, ref info, Marshal.SizeOf<PowerThrottlingState>());
			}
			catch
			{
				return false;
			}
		}

		public static bool BeginTimerPeriod()
		{
			try
			{
				return timeBeginPeriod(1u) == 0;
			}
			catch
			{
				return false;
			}
		}

		public static void EndTimerPeriod()
		{
			try
			{
				timeEndPeriod(1u);
			}
			catch
			{
			}
		}
	}
}
namespace RealView.Game
{
	internal static class Clock
	{
		private static readonly Stopwatch Watch = Stopwatch.StartNew();

		public static float Now => (float)Watch.Elapsed.TotalSeconds;
	}
	internal sealed class GraphicsController
	{
		private sealed class SavedValues
		{
			private GraphicsSettings _target;

			private GraphicsQuality _quality;

			private bool _adaptive;

			private bool _foveatedMenu;

			private int _textureRes;

			private int _renderScale;

			private int _msaa;

			private int _cascades;

			private int _lod;

			private int _fovOuter;

			private int _fovInner;

			private int _fovAniso;

			private SettingLevel _smaa;

			private SettingLevel _shadows;

			private SettingLevel _hbao;

			private SettingLevel _ssr;

			private SettingLevel _volumetrics;

			private SettingLevel _bloom;

			private FoveatedRenderingMode _foveationMode;

			private FoveatedPresets _foveation;

			public static SavedValues Read()
			{
				SavedValues v = null;
				Log.Soft("Read saved settings", delegate
				{
					//IL_0019: 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_003d: Unknown result type (might be due to invalid IL or missing references)
					//IL_0042: Unknown result type (might be due to invalid IL or missing references)
					//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
					//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
					//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
					//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
					//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
					//IL_00c6: 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_00d2: Unknown result type (might be due to invalid IL or missing references)
					//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
					//IL_00de: 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_00ea: Unknown result type (might be due to invalid IL or missing references)
					//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
					//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
					GraphicsSettings gameSettings = GameSettings;
					if (gameSettings != null)
					{
						v = new SavedValues
						{
							_target = gameSettings,
							_quality = gameSettings.GraphicsQuality,
							_adaptive = gameSettings.AdaptiveResolution,
							_textureRes = gameSettings.TextureResolution,
							_foveationMode = gameSettings.FoveatedRenderingModeSetting,
							_fovOuter = gameSettings.FoveatedOuterRadius,
							_fovInner = gameSettings.FoveatedInnerRatio,
							_fovAniso = gameSettings.FoveatedSamplingAnisotropy,
							_foveatedMenu = gameSettings.EnableFoveatedRenderingMenu,
							_renderScale = gameSettings.RenderScale,
							_msaa = gameSettings.MSAA,
							_cascades = gameSettings.ShadowCascade,
							_lod = gameSettings.LODBias,
							_smaa = gameSettings.SMAA,
							_shadows = gameSettings.Shadows,
							_hbao = gameSettings.HBAO,
							_ssr = gameSettings.SSR,
							_volumetrics = gameSettings.Volumetrics,
							_bloom = gameSettings.Bloom,
							_foveation = gameSettings.FoveatedPresetSetting
						};
					}
				});
				return v;
			}

			public void Restore()
			{
				Log.Soft("Protect saved settings", delegate
				{
					//IL_0074: Unknown result type (might be due to invalid IL or missing references)
					//IL_007a: 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_0094: Unknown result type (might be due to invalid IL or missing references)
					//IL_0083: Unknown result type (might be due to invalid IL or missing references)
					//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
					//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
					//IL_009d: Unknown result type (might be due to invalid IL or missing references)
					//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
					//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
					//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
					//IL_00dc: 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_00d1: Unknown result type (might be due to invalid IL or missing references)
					//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
					//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
					//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
					//IL_0110: Unknown result type (might be due to invalid IL or missing references)
					//IL_0116: Unknown result type (might be due to invalid IL or missing references)
					//IL_0105: Unknown result type (might be due to invalid IL or missing references)
					//IL_012a: Unknown result type (might be due to invalid IL or missing references)
					//IL_0130: Unknown result type (might be due to invalid IL or missing references)
					//IL_011f: Unknown result type (might be due to invalid IL or missing references)
					//IL_0139: Unknown result type (might be due to invalid IL or missing references)
					//IL_0178: 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_0187: Unknown result type (might be due to invalid IL or missing references)
					GraphicsSettings target = _target;
					if (target != null)
					{
						if (target.RenderScale != _renderScale)
						{
							target.RenderScale = _renderScale;
						}
						if (target.MSAA != _msaa)
						{
							target.MSAA = _msaa;
						}
						if (target.ShadowCascade != _cascades)
						{
							target.ShadowCascade = _cascades;
						}
						if (target.LODBias != _lod)
						{
							target.LODBias = _lod;
						}
						if (target.SMAA != _smaa)
						{
							target.SMAA = _smaa;
						}
						if (target.Shadows != _shadows)
						{
							target.Shadows = _shadows;
						}
						if (target.HBAO != _hbao)
						{
							target.HBAO = _hbao;
						}
						if (target.SSR != _ssr)
						{
							target.SSR = _ssr;
						}
						if (target.Volumetrics != _volumetrics)
						{
							target.Volumetrics = _volumetrics;
						}
						if (target.Bloom != _bloom)
						{
							target.Bloom = _bloom;
						}
						if (target.FoveatedPresetSetting != _foveation)
						{
							target.FoveatedPresetSetting = _foveation;
						}
						if (target.GraphicsQuality != _quality)
						{
							target.GraphicsQuality = _quality;
						}
						if (target.AdaptiveResolution != _adaptive)
						{
							target.AdaptiveResolution = _adaptive;
						}
						if (target.TextureResolution != _textureRes)
						{
							target.TextureResolution = _textureRes;
						}
						if (target.FoveatedRenderingModeSetting != _foveationMode)
						{
							target.FoveatedRenderingModeSetting = _foveationMode;
						}
						if (target.FoveatedOuterRadius != _fovOuter)
						{
							target.FoveatedOuterRadius = _fovOuter;
						}
						if (target.FoveatedInnerRatio != _fovInner)
						{
							target.FoveatedInnerRatio = _fovInner;
						}
						if (target.FoveatedSamplingAnisotropy != _fovAniso)
						{
							target.FoveatedSamplingAnisotropy = _fovAniso;
						}
						if (target.EnableFoveatedRenderingMenu != _foveatedMenu)
						{
							target.EnableFoveatedRenderingMenu = _foveatedMenu;
						}
					}
				});
			}
		}

		private const int TexturesPerFrame = 150;

		private const int MaxTrackedTextures = 50000;

		private static readonly string[] EffectFields = new string[5] { "Volumetrics", "Ssr", "Hbao", "Bloom", "Smaa" };

		private GraphicsProfile _applied;

		private bool _applying;

		private bool _pendingFull;

		private readonly HashSet<string> _pendingFields = new HashSet<string>();

		private float _nextReapplyAt;

		private int _gameApplyCount;

		private float _gameApplyWindow;

		private float _levelCheckAt = -1f;

		private (float scale, int msaa, int cascades, float lod, float eye) _fingerprint;

		private AnisotropicFiltering _originalAniso;

		private bool _anisoCaptured;

		private Il2CppReferenceArray<Object> _sweep;

		private int _sweepIndex;

		private float _sweepBias;

		private bool _sweepRestore;

		private readonly Dictionary<int, float> _originalBias = new Dictionary<int, float>();

		private readonly HashSet<int> _sweepSeen = new HashSet<int>();

		public GraphicsProfile Original { get; private set; }

		public GraphicsProfile Applied => _applied;

		public bool Managing => _applied != null;

		public bool Captured => Original != null;

		public static GraphicsSettings GameSettings
		{
			get
			{
				GraphicsSettings graphicsSettings = GraphicsManager.graphicsSettings;
				if (graphicsSettings != null)
				{
					return graphicsSettings;
				}
				Settings settings = DataManager.Settings;
				IGraphicsSettings obj = ((settings != null) ? settings.GraphicsSettings : null);
				if (obj == null)
				{
					return null;
				}
				return ((Il2CppObjectBase)obj).TryCast<GraphicsSettings>();
			}
		}

		public bool TryCapture()
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			if (Captured)
			{
				return true;
			}
			GraphicsProfile graphicsProfile = ReadGame();
			if (graphicsProfile == null)
			{
				return false;
			}
			Original = graphicsProfile;
			_originalAniso = QualitySettings.anisotropicFiltering;
			_anisoCaptured = true;
			Log.Msg("Captured game graphics: " + Original.Serialize());
			return true;
		}

		public GraphicsProfile RefreshOriginal()
		{
			GraphicsProfile graphicsProfile = ReadGame();
			if (graphicsProfile != null)
			{
				Original = graphicsProfile;
			}
			return Original;
		}

		public void Apply(GraphicsProfile profile)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			GraphicsProfile graphicsProfile = ReadGame();
			if (graphicsProfile != null)
			{
				Original = graphicsProfile;
			}
			if (!Managing)
			{
				_originalAniso = QualitySettings.anisotropicFiltering;
				_anisoCaptured = true;
				ClearPending();
				ApplyFrom(profile, null);
			}
			else
			{
				ApplyFrom(profile, TakeBasis(graphicsProfile));
			}
		}

		public void Release()
		{
			if (!Managing)
			{
				return;
			}
			_applied = null;
			ClearPending();
			_levelCheckAt = -1f;
			RefreshOriginal();
			_applying = true;
			SavedValues savedValues = SavedValues.Read();
			try
			{
				if (_anisoCaptured)
				{
					Set("Anisotropic", delegate
					{
						//IL_0001: Unknown result type (might be due to invalid IL or missing references)
						QualitySettings.anisotropicFiltering = _originalAniso;
						Texture.SetGlobalAnisotropicFilteringLimits(-1, -1);
					});
				}
				bool refreshed = false;
				Set("Restore", delegate
				{
					GraphicsManager.RefreshQualitySettings();
					refreshed = true;
				});
				if (!refreshed && Original != null)
				{
					ApplySettings(Original, null, includeTextures: false);
				}
				StartTextureSweep(0f);
			}
			finally
			{
				savedValues?.Restore();
				_applying = false;
			}
		}

		public void OnGameApplied()
		{
			if (!_applying && Managing)
			{
				_pendingFull = true;
				CountGameApply();
			}
		}

		public void OnGameFoveationApplied()
		{
			if (!_applying && Managing)
			{
				_pendingFields.Add("Foveation");
				CountGameApply();
			}
		}

		public void OnGameMenuChanged()
		{
			if (_applying || !Managing)
			{
				return;
			}
			GraphicsProfile graphicsProfile = ReadGame();
			if (graphicsProfile == null)
			{
				_pendingFull = true;
				return;
			}
			List<string> list = Original?.Diff(graphicsProfile);
			if (list != null && list.Count > 0)
			{
				foreach (string item in list)
				{
					_pendingFields.Add(item);
				}
			}
			else
			{
				_pendingFull = true;
			}
			Original = graphicsProfile;
		}

		public void OnLevelLoaded()
		{
			if (Managing)
			{
				_levelCheckAt = Time.unscaledTime + 0.25f;
			}
		}

		public void OnAvatarChanged()
		{
			if (Managing && _applied.TextureSharpness > 0f)
			{
				StartTextureSweep(_applied.TextureSharpness);
			}
		}

		public void Update()
		{
			if ((_pendingFull || _pendingFields.Count > 0) && Time.unscaledTime >= _nextReapplyAt)
			{
				_nextReapplyAt = Time.unscaledTime + 1f;
				if (Managing)
				{
					GraphicsProfile graphicsProfile = ReadGame();
					if (graphicsProfile != null)
					{
						Original = graphicsProfile;
					}
					ApplyFrom(_applied, TakeBasis(graphicsProfile), includeTextures: false);
				}
				else
				{
					ClearPending();
				}
			}
			if (_levelCheckAt > 0f && Time.unscaledTime >= _levelCheckAt)
			{
				_levelCheckAt = -1f;
				if (Managing)
				{
					LevelCheck();
				}
			}
			StepTextureSweep();
		}

		public string Describe()
		{
			string text = "";
			Log.Soft("Describe", delegate
			{
				//IL_0117: Unknown result type (might be due to invalid IL or missing references)
				UniversalRenderPipelineAsset customPipelineAsset = GraphicsManager.CustomPipelineAsset;
				text = $"URP render scale {(((Object)(object)customPipelineAsset != (Object)null) ? customPipelineAsset.renderScale : 0f):0.00}, MSAA {(((Object)(object)customPipelineAsset != (Object)null) ? customPipelineAsset.msaaSampleCount : 0)}, shadow distance {(((Object)(object)customPipelineAsset != (Object)null) ? customPipelineAsset.shadowDistance : 0f):0}, cascades {(((Object)(object)customPipelineAsset != (Object)null) ? customPipelineAsset.shadowCascadeCount : 0)}, eye scale {XRSettings.eyeTextureResolutionScale:0.00}, LOD bias {QualitySettings.lodBias:0.00}, aniso {QualitySettings.anisotropicFiltering}";
			});
			return text;
		}

		private void LevelCheck()
		{
			GraphicsProfile graphicsProfile = ReadGame();
			if (graphicsProfile == null)
			{
				return;
			}
			Original = graphicsProfile;
			if (!Fingerprint().Equals(_fingerprint))
			{
				_pendingFull = true;
			}
			else
			{
				string[] effectFields = EffectFields;
				foreach (string item in effectFields)
				{
					_pendingFields.Add(item);
				}
			}
			ApplyFrom(_applied, TakeBasis(graphicsProfile), includeTextures: false);
			if (_applied.TextureSharpness > 0f)
			{
				StartTextureSweep(_applied.TextureSharpness);
			}
		}

		private void CountGameApply()
		{
			float unscaledTime = Time.unscaledTime;
			if (unscaledTime - _gameApplyWindow > 10f)
			{
				_gameApplyWindow = unscaledTime;
				_gameApplyCount = 0;
			}
			if (++_gameApplyCount == 30)
			{
				Log.WarnOnce("gfx-storm", "The game re-applies its graphics settings very often; RealView follows at most once a second.");
			}
		}

		private void ClearPending()
		{
			_pendingFull = false;
			_pendingFields.Clear();
		}

		private GraphicsProfile TakeBasis(GraphicsProfile game)
		{
			if (_applied == null)
			{
				return null;
			}
			GraphicsProfile result = (_pendingFull ? ((game == null) ? null : game with
			{
				TextureSharpness = _applied.TextureSharpness,
				Anisotropic16x = !_applied.Anisotropic16x
			}) : ((_pendingFields.Count <= 0 || !(game != null)) ? _applied : WithGameFields(_applied, game, _pendingFields)));
			ClearPending();
			return result;
		}

		private static GraphicsProfile WithGameFields(GraphicsProfile b, GraphicsProfile game, IEnumerable<string> fields)
		{
			using IEnumerator<string> enumerator = fields.GetEnumerator();
			while (enumerator.MoveNext())
			{
				switch (enumerator.Current)
				{
				case "RenderScalePercent":
					b = b with
					{
						RenderScalePercent = game.RenderScalePercent
					};
					break;
				case "Msaa":
					b = b with
					{
						Msaa = game.Msaa
					};
					break;
				case "Smaa":
					b = b with
					{
						Smaa = game.Smaa
					};
					break;
				case "Shadows":
					b = b with
					{
						Shadows = game.Shadows
					};
					break;
				case "ShadowCascades":
					b = b with
					{
						ShadowCascades = game.ShadowCascades
					};
					break;
				case "Hbao":
					b = b with
					{
						Hbao = game.Hbao
					};
					break;
				case "Ssr":
					b = b with
					{
						Ssr = game.Ssr
					};
					break;
				case "Volumetrics":
					b = b with
					{
						Volumetrics = game.Volumetrics
					};
					break;
				case "Bloom":
					b = b with
					{
						Bloom = game.Bloom
					};
					break;
				case "LodBiasPercent":
					b = b with
					{
						LodBiasPercent = game.LodBiasPercent
					};
					break;
				case "Foveation":
					b = b with
					{
						Foveation = game.Foveation
					};
					break;
				}
			}
			return b;
		}

		private void ApplyFrom(GraphicsProfile profile, GraphicsProfile current, bool includeTextures = true)
		{
			if (profile == null || !Captured)
			{
				return;
			}
			profile = profile.Sanitized();
			if (current != null && current.Equals(profile))
			{
				_applied = profile;
				return;
			}
			_applying = true;
			SavedValues savedValues = SavedValues.Read();
			try
			{
				ApplySettings(profile, current, includeTextures);
				_applied = profile;
				Log.Soft("Fingerprint", delegate
				{
					_fingerprint = Fingerprint();
				});
			}
			finally
			{
				savedValues?.Restore();
				_applying = false;
			}
		}

		private void ApplySettings(GraphicsProfile p, GraphicsProfile current, bool includeTextures)
		{
			List<string> changed = ((current == null) ? null : p.Diff(current));
			if (Has("Volumetrics"))
			{
				Set("Volumetrics", delegate
				{
					//IL_000b: Unknown result type (might be due to invalid IL or missing references)
					GraphicsManager.SetVolumetricVariables(ToGame(p.Volumetrics));
				});
			}
			if (Has("Ssr"))
			{
				Set("Reflections", delegate
				{
					//IL_000b: Unknown result type (might be due to invalid IL or missing references)
					GraphicsManager.SetSSRVariables(ToGame(p.Ssr));
				});
			}
			if (Has("Hbao"))
			{
				Set("Ambient occlusion", delegate
				{
					//IL_000b: Unknown result type (might be due to invalid IL or missing references)
					GraphicsManager.SetHBAOVariables(ToGame(p.Hbao));
				});
			}
			if (Has("Bloom"))
			{
				Set("Bloom", delegate
				{
					//IL_000b: Unknown result type (might be due to invalid IL or missing references)
					GraphicsManager.SetBloomVariables(ToGame(p.Bloom));
				});
			}
			if (Has("Smaa"))
			{
				Set("SMAA", delegate
				{
					//IL_000b: Unknown result type (might be due to invalid IL or missing references)
					GraphicsManager.SetPostAAVariables(ToGame(p.Smaa));
				});
			}
			if (Has("Shadows"))
			{
				Set("Shadows", delegate
				{
					//IL_000b: Unknown result type (might be due to invalid IL or missing references)
					GraphicsManager.SetShadowVariables(ToGame(p.Shadows));
				});
			}
			if (Has("ShadowCascades"))
			{
				Set("Shadow cascades", delegate
				{
					GraphicsManager.SetShadowCascades(p.ShadowCascades);
				});
			}
			if (Has("LodBiasPercent"))
			{
				Set("LOD bias", delegate
				{
					GraphicsManager.SetLODBias(p.LodBiasPercent);
				});
			}
			if (Has("Foveation"))
			{
				Set("Foveation", delegate
				{
					//IL_000b: Unknown result type (might be due to invalid IL or missing references)
					GraphicsManager.SetFoveatedPreset(ToGame(p.Foveation));
				});
			}
			if (Has("Anisotropic16x"))
			{
				Set("Anisotropic", delegate
				{
					ApplyAniso(p.Anisotropic16x);
				});
			}
			if (Has("Msaa"))
			{
				Set("MSAA", delegate
				{
					GraphicsManager.SetMSAAVariables(p.Msaa);
				});
			}
			if (Has("RenderScalePercent"))
			{
				Set("Render scale", delegate
				{
					GraphicsManager.SetRenderscale(p.RenderScalePercent);
				});
			}
			if (includeTextures && Has("TextureSharpness"))
			{
				StartTextureSweep(p.TextureSharpness);
			}
			bool Has(string name)
			{
				if (changed != null)
				{
					return changed.Contains(name);
				}
				return true;
			}
		}

		private static GraphicsProfile ReadGame()
		{
			GraphicsProfile result = null;
			Log.Soft("Read game settings", delegate
			{
				//IL_002a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0034: Expected I4, but got Unknown
				//IL_0036: Unknown result type (might be due to invalid IL or missing references)
				//IL_0040: Expected I4, but got Unknown
				//IL_004e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0058: Expected I4, but got Unknown
				//IL_005a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0064: Expected I4, but got Unknown
				//IL_0066: Unknown result type (might be due to invalid IL or missing references)
				//IL_0070: Expected I4, but got Unknown
				//IL_0072: Unknown result type (might be due to invalid IL or missing references)
				//IL_007c: Expected I4, but got Unknown
				//IL_008a: Unknown result type (might be due to invalid IL or missing references)
				GraphicsSettings gameSettings = GameSettings;
				if (gameSettings != null)
				{
					result = new GraphicsProfile
					{
						RenderScalePercent = gameSettings.RenderScale,
						Msaa = gameSettings.MSAA,
						Smaa = (Level)gameSettings.SMAA,
						Shadows = (Level)gameSettings.Shadows,
						ShadowCascades = gameSettings.ShadowCascade,
						Hbao = (Level)gameSettings.HBAO,
						Ssr = (Level)gameSettings.SSR,
						Volumetrics = (Level)gameSettings.Volumetrics,
						Bloom = (Level)gameSettings.Bloom,
						LodBiasPercent = gameSettings.LODBias,
						Foveation = FromGame(gameSettings.FoveatedPresetSetting),
						TextureSharpness = 0f,
						Anisotropic16x = false
					}.Sanitized();
				}
			});
			return result;
		}

		private static (float, int, int, float, float) Fingerprint()
		{
			UniversalRenderPipelineAsset customPipelineAsset = GraphicsManager.CustomPipelineAsset;
			return (((Object)(object)customPipelineAsset != (Object)null) ? customPipelineAsset.renderScale : 0f, ((Object)(object)customPipelineAsset != (Object)null) ? customPipelineAsset.msaaSampleCount : 0, ((Object)(object)customPipelineAsset != (Object)null) ? customPipelineAsset.shadowCascadeCount : 0, QualitySettings.lodBias, XRSettings.eyeTextureResolutionScale);
		}

		private void ApplyAniso(bool on)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			if (on)
			{
				QualitySettings.anisotropicFiltering = (AnisotropicFiltering)2;
				Texture.SetGlobalAnisotropicFilteringLimits(16, 16);
			}
			else if (_anisoCaptured)
			{
				QualitySettings.anisotropicFiltering = _originalAniso;
				Texture.SetGlobalAnisotropicFilteringLimits(-1, -1);
			}
		}

		private void StartTextureSweep(float sharpness)
		{
			bool restore = sharpness <= 0f;
			if (restore && _originalBias.Count == 0)
			{
				_sweep = null;
				return;
			}
			Log.Soft("Texture sharpness", delegate
			{
				_sweep = Resources.FindObjectsOfTypeAll(Il2CppType.Of<Texture2D>());
				_sweepIndex = 0;
				_sweepRestore = restore;
				_sweepBias = 0f - Math.Min(1f, sharpness);
				_sweepSeen.Clear();
			});
		}

		private void StepTextureSweep()
		{
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Expected O, but got Unknown
			if (_sweep == null)
			{
				return;
			}
			try
			{
				for (int num = Math.Min(((Il2CppArrayBase<Object>)(object)_sweep).Length, _sweepIndex + 150); _sweepIndex < num; _sweepIndex++)
				{
					Object val = ((Il2CppArrayBase<Object>)(object)_sweep)[_sweepIndex];
					if (val == (Object)null)
					{
						continue;
					}
					int instanceID = val.GetInstanceID();
					Texture2D val2 = new Texture2D(((Il2CppObjectBase)val).Pointer);
					if (_sweepRestore)
					{
						if (_originalBias.TryGetValue(instanceID, out var value) && ((Texture)val2).mipMapBias != value)
						{
							((Texture)val2).mipMapBias = value;
						}
						continue;
					}
					_sweepSeen.Add(instanceID);
					if (((Texture)val2).mipmapCount <= 1)
					{
						continue;
					}
					float mipMapBias = ((Texture)val2).mipMapBias;
					if (Math.Abs(mipMapBias - _sweepBias) < 0.001f)
					{
						continue;
					}
					if (!_originalBias.ContainsKey(instanceID))
					{
						if (_originalBias.Count >= 50000)
						{
							continue;
						}
						_originalBias[instanceID] = mipMapBias;
					}
					((Texture)val2).mipMapBias = _sweepBias;
				}
				if (_sweepIndex < ((Il2CppArrayBase<Object>)(object)_sweep).Length)
				{
					return;
				}
				_sweep = null;
				if (_sweepRestore)
				{
					_originalBias.Clear();
					return;
				}
				List<int> list = null;
				foreach (int key in _originalBias.Keys)
				{
					if (!_sweepSeen.Contains(key))
					{
						(list ?? (list = new List<int>())).Add(key);
					}
				}
				if (list != null)
				{
					foreach (int item in list)
					{
						_originalBias.Remove(item);
					}
				}
				_sweepSeen.Clear();
			}
			catch (Exception ex)
			{
				_sweep = null;
				Log.WarnOnce("sweep", "Texture sharpness pass stopped: " + ex.Message);
			}
		}

		private static void Set(string what, Action action)
		{
			try
			{
				action();
			}
			catch (Exception ex)
			{
				Log.WarnOnce("gfx-" + what, $"Could not set {what}: {ex.GetType().Name}: {ex.Message}");
			}
		}

		private static SettingLevel ToGame(Level level)
		{
			return (SettingLevel)(sbyte)level;
		}

		private static FoveatedPresets ToGame(Foveation f)
		{
			return (FoveatedPresets)(f switch
			{
				Foveation.Wide => 1, 
				Foveation.Medium => 2, 
				Foveation.Narrow => 3, 
				_ => 0, 
			});
		}

		private static Foveation FromGame(FoveatedPresets p)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected I4, but got Unknown
			return (int)p switch
			{
				0 => Foveation.Off, 
				1 => Foveation.Wide, 
				3 => Foveation.Narrow, 
				_ => Foveation.Medium, 
			};
		}
	}
	internal sealed class Hud
	{
		private GameObject _go;

		private TextMeshPro _text;

		private TMP_FontAsset _font;

		private float _nextText;

		private Vector3 _smoothPos;

		private bool _hasPos;

		public void Update(Func<string> buildText)
		{
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing refe