Decompiled source of SebCore v1.1.1

BepInEx\plugins\SebCore\SebCore.dll

Decompiled 3 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("SebCore")]
[assembly: AssemblyProduct("SebCore")]
[assembly: AssemblyFileVersion("1.1.1")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.1.1.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace SebCore
{
	public static class CartridgeApps
	{
		public struct App
		{
			public string DisplayName;

			public string FileName;

			public string PluginGuid;

			public string ListenerName;

			public string ListenerData;

			public string WindowTypeName;
		}

		private static readonly object _lock;

		private static readonly List<App> _registeredApps;

		private static readonly HashSet<string> _registeredAppIds;

		public static readonly App Wheel;

		public static readonly App Ultrawide;

		public static readonly App Binds;

		public static readonly App Truck;

		static CartridgeApps()
		{
			_lock = new object();
			_registeredApps = new List<App>();
			_registeredAppIds = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
			Wheel = new App
			{
				DisplayName = "Wheel",
				FileName = "wheel",
				PluginGuid = "shibe.easydeliveryco.seblogiwheel",
				ListenerName = "G920Menu",
				ListenerData = "listener_G920Menu",
				WindowTypeName = "SebLogiWheel.WheelMenuWindow"
			};
			Ultrawide = new App
			{
				DisplayName = "Graphics",
				FileName = "wide",
				PluginGuid = "shibe.easydeliveryco.sebultrawide",
				ListenerName = "UltrawideMenu",
				ListenerData = "listener_UltrawideMenu",
				WindowTypeName = "SebUltrawide.UltrawideMenuWindow"
			};
			Binds = new App
			{
				DisplayName = "Binds",
				FileName = "binds",
				PluginGuid = "shibe.easydeliveryco.sebbinds",
				ListenerName = "SebBindsMenu",
				ListenerData = "listener_SebBindsMenu",
				WindowTypeName = "SebBinds.BindsMenuWindow"
			};
			Truck = new App
			{
				DisplayName = "Truck",
				FileName = "truck",
				PluginGuid = "shibe.easydeliveryco.sebtruck",
				ListenerName = "SebTruckMenu",
				ListenerData = "listener_SebTruckMenu",
				WindowTypeName = "SebTruck.TruckMenuWindow"
			};
			RegisterAppInternal(Binds);
			RegisterAppInternal(Truck);
			RegisterAppInternal(Ultrawide);
			RegisterAppInternal(Wheel);
		}

		public static App[] GetRegisteredAppsSnapshot()
		{
			lock (_lock)
			{
				return _registeredApps.ToArray();
			}
		}

		public static bool RegisterApp(App app, bool replaceIfExists = false)
		{
			if (!IsValidForRegistration(app, out var id))
			{
				return false;
			}
			lock (_lock)
			{
				if (_registeredAppIds.Contains(id))
				{
					if (!replaceIfExists)
					{
						return false;
					}
					for (int i = 0; i < _registeredApps.Count; i++)
					{
						if (string.Equals(_registeredApps[i].FileName, id, StringComparison.OrdinalIgnoreCase))
						{
							_registeredApps[i] = app;
							return true;
						}
					}
					return false;
				}
				_registeredApps.Add(app);
				_registeredAppIds.Add(id);
				return true;
			}
		}

		private static void RegisterAppInternal(App app)
		{
			if (!IsValidForRegistration(app, out var id))
			{
				return;
			}
			lock (_lock)
			{
				if (!_registeredAppIds.Contains(id))
				{
					_registeredApps.Add(app);
					_registeredAppIds.Add(id);
				}
			}
		}

		private static bool IsValidForRegistration(App app, out string id)
		{
			id = null;
			if (string.IsNullOrWhiteSpace(app.FileName))
			{
				return false;
			}
			if (string.IsNullOrWhiteSpace(app.DisplayName))
			{
				return false;
			}
			if (string.IsNullOrWhiteSpace(app.PluginGuid))
			{
				return false;
			}
			if (string.IsNullOrWhiteSpace(app.ListenerName))
			{
				return false;
			}
			if (string.IsNullOrWhiteSpace(app.ListenerData))
			{
				return false;
			}
			id = app.FileName.Trim();
			return id.Length != 0;
		}

		public static bool IsInstalled(App app)
		{
			if (string.IsNullOrWhiteSpace(app.PluginGuid))
			{
				return false;
			}
			return Chainloader.PluginInfos.ContainsKey(app.PluginGuid);
		}

		public static bool EnsureListener(DesktopDotExe desktop, App app)
		{
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)desktop == (Object)null)
			{
				return false;
			}
			if ((Object)(object)((Component)desktop).transform.Find(app.ListenerName) != (Object)null)
			{
				return true;
			}
			if (!Chainloader.PluginInfos.TryGetValue(app.PluginGuid, out var value) || value == null || (Object)(object)value.Instance == (Object)null)
			{
				Plugin.LogDebug("Cartridge not loaded: '" + app.PluginGuid + "'");
				return false;
			}
			Assembly assembly = ((object)value.Instance).GetType().Assembly;
			if (string.IsNullOrWhiteSpace(app.WindowTypeName))
			{
				Plugin.LogDebug("Missing window type name for '" + app.PluginGuid + "'");
				return false;
			}
			Type type = assembly.GetType(app.WindowTypeName, throwOnError: false);
			if (type == null)
			{
				if (string.Equals(app.WindowTypeName, "SebUltrawide.UltrawideMenuWindow", StringComparison.Ordinal))
				{
					type = assembly.GetType("EasyDeliveryCoUltrawide.UltrawideMenuWindow", throwOnError: false);
				}
				else if (string.Equals(app.WindowTypeName, "SebLogiWheel.WheelMenuWindow", StringComparison.Ordinal))
				{
					type = assembly.GetType("EasyLogiWheelSupport.WheelMenuWindow", throwOnError: false);
				}
			}
			if (type == null)
			{
				Plugin.LogDebug("Failed to resolve window type '" + app.WindowTypeName + "' for '" + app.PluginGuid + "' (asm=" + assembly.GetName().Name + ")");
				return false;
			}
			GameObject val = new GameObject(app.ListenerName);
			val.transform.SetParent(((Component)desktop).transform, false);
			val.AddComponent(type);
			return true;
		}

		public static bool TryOpen(DesktopDotExe desktop, MiniRenderer renderer, App app)
		{
			if (!EnsureListener(desktop, app))
			{
				return false;
			}
			return DesktopAppLauncher.TryOpenProgramListener(desktop, renderer, app.FileName, app.ListenerData);
		}
	}
	public abstract class CartridgeWindowBase : MonoBehaviour
	{
		protected UIUtil Util;

		protected WindowView View;

		protected float MouseYLock;

		protected virtual bool EnableMouseYLock => true;

		public virtual void FrameUpdate(WindowView view)
		{
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: 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)
			if (view == null)
			{
				return;
			}
			View = view;
			if (Util == null)
			{
				Util = new UIUtil();
			}
			Util.M = view.M;
			Util.R = view.R;
			Util.Nav = view.M.nav;
			Rect contentRect = GetContentRect(view);
			if (EnableMouseYLock)
			{
				if (((ScreenProgram)Util.M).mouseButtonUp)
				{
					MouseYLock = 0f;
				}
				if (MouseYLock > 0f)
				{
					((ScreenProgram)Util.M).mouse.y = MouseYLock;
				}
			}
			DrawWindow(contentRect);
		}

		public virtual void BackButtonPressed()
		{
			ReturnToSebCoreAndClose();
		}

		protected abstract void DrawWindow(Rect p);

		protected static Rect GetContentRect(WindowView view)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: 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_001d: 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)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			Rect result = default(Rect);
			((Rect)(ref result))..ctor(view.position * 8f, view.size * 8f);
			((Rect)(ref result)).position = ((Rect)(ref result)).position + new Vector2(8f, 8f);
			return result;
		}

		protected float GetNavY(Rect p)
		{
			return ((Rect)(ref p)).y + ((Rect)(ref p)).height - 18f;
		}

		protected void ReturnToSebCoreAndClose()
		{
			DesktopAppLauncher.TryOpenProgramListener(Util?.M, Util?.R, SebCoreMenuWindow.FileName, "listener_SebCoreMenu");
			WindowView view = View;
			if (view != null)
			{
				view.Kill();
			}
		}
	}
	public static class ConfigUtil
	{
		public static void CopyLegacyConfigIfNeeded(string oldGuid, string newGuid)
		{
			try
			{
				if (!string.IsNullOrWhiteSpace(oldGuid) && !string.IsNullOrWhiteSpace(newGuid) && !string.Equals(oldGuid, newGuid, StringComparison.OrdinalIgnoreCase))
				{
					string configPath = Paths.ConfigPath;
					string text = Path.Combine(configPath, oldGuid + ".cfg");
					string text2 = Path.Combine(configPath, newGuid + ".cfg");
					if (File.Exists(text) && !File.Exists(text2))
					{
						File.Copy(text, text2);
					}
				}
			}
			catch
			{
			}
		}
	}
	public static class DesktopAppLauncher
	{
		public static bool TryOpen(DesktopDotExe desktop, string fileName)
		{
			if ((Object)(object)desktop == (Object)null || desktop.files == null || string.IsNullOrWhiteSpace(fileName))
			{
				return false;
			}
			File val = null;
			foreach (File file in desktop.files)
			{
				if (file != null && string.Equals(file.name, fileName, StringComparison.OrdinalIgnoreCase))
				{
					val = file;
					break;
				}
			}
			if (val == null)
			{
				return false;
			}
			WindowView val2 = default(WindowView);
			val.Execute(ref val2);
			if (val2 == null)
			{
				return false;
			}
			FieldInfo fieldInfo = AccessTools.Field(typeof(DesktopDotExe), "windowViewer");
			if (fieldInfo == null)
			{
				return false;
			}
			fieldInfo.SetValue(desktop, val2);
			return true;
		}

		public static bool TryOpenProgramListener(DesktopDotExe desktop, string fileName, string listenerData)
		{
			return TryOpenProgramListener(desktop, null, fileName, listenerData);
		}

		public static bool TryOpenProgramListener(DesktopDotExe desktop, MiniRenderer renderer, string fileName, string listenerData)
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: 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_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: 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_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: 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)
			if ((Object)(object)desktop == (Object)null || string.IsNullOrWhiteSpace(fileName) || string.IsNullOrWhiteSpace(listenerData))
			{
				return false;
			}
			MiniRenderer val = (((Object)(object)((ScreenProgram)desktop).R != (Object)null) ? ((ScreenProgram)desktop).R : renderer);
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			WindowView val2 = default(WindowView);
			new File(val, desktop)
			{
				name = fileName,
				type = (FileType)1,
				data = listenerData,
				icon = 7,
				iconHover = 7,
				position = Vector2.zero,
				visible = false,
				cantFolder = true
			}.Execute(ref val2);
			if (val2 == null)
			{
				Plugin.LogDebug("Failed to open program listener: file='" + fileName + "' data='" + listenerData + "'");
				return false;
			}
			FieldInfo fieldInfo = AccessTools.Field(typeof(DesktopDotExe), "windowViewer");
			if (fieldInfo == null)
			{
				return false;
			}
			fieldInfo.SetValue(desktop, val2);
			return true;
		}
	}
	public static class ModGraphics
	{
		public static Func<float> OutputAspect;

		public static Action<Camera> FreeCamCamera;

		private static bool _patched;

		private static bool _full;

		private static bool _mirror;

		private static float _nextPoll;

		private static bool _viewDistanceBaseCaptured;

		private static float _baseShadowDistance;

		private static float _baseLodBias;

		private static int _baseMaximumLodLevel;

		private static Camera _pixelMainCamera;

		private static MeshRenderer _pixelScreenRenderer;

		private static RenderTexture _pixelDefaultRt;

		private static RenderTexture _pixelCustomRt;

		private static Camera _pixelRearCamera;

		private static MeshRenderer _pixelRearRenderer;

		private static RenderTexture _pixelDefaultRearRt;

		private static RenderTexture _pixelCustomRearRt;

		private static int _pixelLastMode = -1;

		private static int _pixelBaseW;

		private static int _pixelBaseH;

		private static int _pixelRearBaseW;

		private static int _pixelRearBaseH;

		private static bool _insideLookupInit;

		private static Type _ambianceType;

		private static FieldInfo _ambiancePlayerInsideField;

		private static Object _ambianceInstance;

		private static Type _mirrorModeType;

		private static FieldInfo _mirrorModeMirroredField;

		private static bool _mirrorModeLookupDone;

		internal const string PrefKeyFovLegacy = "UltrawideFovOverride";

		internal const string PrefKeyFovThirdPerson = "UltrawideFovOverride_ThirdPerson";

		internal const string PrefKeyFovFirstPerson = "UltrawideFovOverride_FirstPerson";

		internal const string PrefKeyPixelationMode = "UltrawidePixelationMode";

		internal const string PrefKeyPixelationModeVersion = "UltrawidePixelationModeVersion";

		internal const string PrefKeyViewDistanceMode = "UltrawideViewDistanceMode";

		internal const string PrefKeyViewDistanceModeVersion = "UltrawideViewDistanceModeVersion";

		internal const string PrefKeyGfxVsyncMode = "SebTweaks_Gfx_VSyncMode";

		internal const string PrefKeyGfxVsyncModeVersion = "SebTweaks_Gfx_VSyncModeVersion";

		internal const string PrefKeyMirrorQuality = "SebTruck_MirrorQuality";

		public static void Enable()
		{
			_full = true;
			EnsurePatched();
			ApplySaved();
		}

		public static void EnableMirrorQuality(bool enabled)
		{
			_mirror = enabled;
			EnsurePatched();
			RefreshPixelation();
		}

		public static void SetMirrorQuality(int quality)
		{
			ModPrefs.SetInt("SebTruck_MirrorQuality", Mathf.Clamp(quality, 0, 3));
			RefreshPixelation();
		}

		public static void SavePixelationMode(int mode)
		{
			ModPrefs.SetInt("UltrawidePixelationModeVersion", 2);
			ModPrefs.SetInt("UltrawidePixelationMode", Mathf.Clamp(mode, 0, 4));
			RefreshPixelation();
		}

		public static void SaveViewDistanceMode(int mode)
		{
			ModPrefs.SetInt("UltrawideViewDistanceModeVersion", 2);
			ModPrefs.SetInt("UltrawideViewDistanceMode", Mathf.Clamp(mode, 0, 3));
			RefreshViewDistance();
		}

		public static void SetVsyncMode(int mode)
		{
			ModPrefs.SetInt("SebTweaks_Gfx_VSyncModeVersion", 2);
			ModPrefs.SetInt("SebTweaks_Gfx_VSyncMode", Mathf.Clamp(mode, 0, 1));
			ApplyVsyncMode();
		}

		public static bool TryGetSavedFov(bool firstPerson, out float fov)
		{
			fov = ModPrefs.GetFloat(firstPerson ? "UltrawideFovOverride_FirstPerson" : "UltrawideFovOverride_ThirdPerson", -1f);
			if (fov >= 1f)
			{
				return true;
			}
			if (!firstPerson)
			{
				fov = ModPrefs.GetFloat("UltrawideFovOverride", -1f);
				if (fov >= 1f)
				{
					return true;
				}
			}
			fov = 0f;
			return false;
		}

		public static float GetSavedFovOrDefault(bool firstPerson, float fallback)
		{
			if (!TryGetSavedFov(firstPerson, out var fov))
			{
				return fallback;
			}
			return fov;
		}

		public static void SaveFovOverride(bool firstPerson, float fov)
		{
			ModPrefs.SetFloat(firstPerson ? "UltrawideFovOverride_FirstPerson" : "UltrawideFovOverride_ThirdPerson", fov);
			if (_full && IsFirstPersonViewActive() == firstPerson)
			{
				ApplyFovOverride(fov);
			}
		}

		public static void ResetDefaults()
		{
			ModPrefs.DeleteKey("UltrawideFovOverride_FirstPerson");
			ModPrefs.DeleteKey("UltrawideFovOverride_ThirdPerson");
			ModPrefs.DeleteKey("UltrawideFovOverride");
			SavePixelationMode(3);
			SaveViewDistanceMode(1);
			ModPrefs.DeleteKey("SebTweaks_Gfx_VSyncMode");
			ModPrefs.DeleteKey("SebTweaks_Gfx_VSyncModeVersion");
			ApplyVsyncMode();
			ModPrefs.Save();
		}

		public static void ApplySaved()
		{
			if (_full)
			{
				try
				{
					if (TryGetSavedFov(IsFirstPersonViewActive(), out var fov))
					{
						ApplyFovOverride(fov);
					}
				}
				catch
				{
				}
				RefreshViewDistance();
				ApplyVsyncMode();
			}
			RefreshPixelation();
		}

		private static void EnsurePatched()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			if (_patched)
			{
				return;
			}
			_patched = true;
			try
			{
				Harmony harmony = new Harmony("shibe.easydeliveryco.sebcore.graphics");
				Patch(harmony, "sCameraController", "Update", null, "SCameraController_Update_Postfix");
				Patch(harmony, "sCameraController", "LateUpdate", null, "SCameraController_LateUpdate_Postfix");
				Patch(harmony, "sHUD", "WorldToHUDPoint", "SHud_WorldToHUDPoint_Prefix");
				Patch(harmony, "sEasyRally", "Update", null, "RefreshPixelation");
				Patch(harmony, "sEasyCinema", "Update", null, "RefreshPixelation");
				Patch(harmony, "RaceManager", "StartRace", null, "RefreshPixelation");
				string[] array = new string[9] { "sFreeCam.Start", "sFreeCam.ToggleFreeCam", "ScreenSystem.Init", "ScreenSystem.DoTransition", "sTeleporter.Teleport", "PauseSystem.Start", "PauseSystem.SetResolution", "PauseSystem.SetFullscreen", "PauseSystem.TogglePaused" };
				for (int i = 0; i < array.Length; i++)
				{
					string[] array2 = array[i].Split(new char[1] { '.' });
					Patch(harmony, array2[0], array2[1], null, "ApplySaved");
				}
			}
			catch (Exception ex)
			{
				Plugin.LogDebug("Graphics patching failed: " + ex);
			}
		}

		private static void Patch(Harmony harmony, string typeName, string methodName, string prefix = null, string postfix = null)
		{
			HarmonyUtil.PatchByName(harmony, typeof(ModGraphics), typeName, methodName, prefix, postfix, Plugin.LogDebug);
		}

		private static void SCameraController_Update_Postfix(sCameraController __instance)
		{
			try
			{
				if (_full)
				{
					ApplyViewDistanceFarClip(__instance);
				}
				if (!(Time.unscaledTime < _nextPoll))
				{
					_nextPoll = Time.unscaledTime + 0.5f;
					if (_full)
					{
						ApplyVsyncMode();
					}
					RefreshPixelation();
				}
			}
			catch
			{
			}
		}

		private static void SCameraController_LateUpdate_Postfix(sCameraController __instance)
		{
			if (_full && !((Object)(object)__instance == (Object)null) && !((Object)(object)__instance.cam == (Object)null) && !IsPlayerInsideBuilding() && TryGetSavedFov(__instance.firstPerson && !__instance.fixedPerspective, out var fov))
			{
				__instance.cam.fieldOfView = fov;
			}
		}

		private static bool SHud_WorldToHUDPoint_Prefix(ref Vector2 __result, sHUD __instance, ref Vector3 worldPoint, ref MiniRenderer ___R)
		{
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: 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_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: 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_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			if (!_full)
			{
				return true;
			}
			try
			{
				if ((Object)(object)__instance == (Object)null || (Object)(object)___R == (Object)null || (Object)(object)__instance.navigation == (Object)null || (Object)(object)__instance.navigation.car == (Object)null || (Object)(object)__instance.navigation.car.carCamera == (Object)null)
				{
					return true;
				}
				Camera carCamera = __instance.navigation.car.carCamera;
				Transform transform = ((Component)carCamera).transform;
				if (Vector3.Dot(transform.forward, worldPoint - transform.position) < 0f)
				{
					__result = new Vector2(-100f, -100f);
					return false;
				}
				float num = carCamera.pixelWidth;
				float num2 = carCamera.pixelHeight;
				if (num <= 0.01f || num2 <= 0.01f || ___R.width <= 0 || ___R.height <= 0)
				{
					return true;
				}
				Vector3 val = carCamera.WorldToScreenPoint(worldPoint);
				val.y = num2 - val.y;
				val.x -= num * 0.5f;
				val.y -= num2 * 0.5f;
				__result = new Vector2(val.x * ((float)___R.width / num) + (float)___R.width * 0.5f, val.y * ((float)___R.height / num2) + (float)___R.height * 0.5f);
				if (IsMirrorModeMirrored())
				{
					__result.x = (float)___R.width - __result.x;
				}
				return false;
			}
			catch
			{
				return true;
			}
		}

		private static bool IsMirrorModeMirrored()
		{
			try
			{
				if (!_mirrorModeLookupDone)
				{
					_mirrorModeLookupDone = true;
					_mirrorModeType = AccessTools.TypeByName("MirrorMode");
					_mirrorModeMirroredField = ((_mirrorModeType != null) ? AccessTools.Field(_mirrorModeType, "mirrored") : null);
				}
				return _mirrorModeMirroredField != null && Convert.ToBoolean(_mirrorModeMirroredField.GetValue(null));
			}
			catch
			{
				return false;
			}
		}

		private static void ApplyVsyncMode()
		{
			if (!_full)
			{
				return;
			}
			try
			{
				QualitySettings.vSyncCount = ((GetVsyncMode() == 1) ? 1 : 0);
			}
			catch
			{
			}
		}

		private static bool IsFirstPersonViewActive()
		{
			sCameraController val = Object.FindFirstObjectByType<sCameraController>();
			if ((Object)(object)val != (Object)null && val.firstPerson)
			{
				return !val.fixedPerspective;
			}
			return false;
		}

		private static void ApplyFovOverride(float fov)
		{
			if (!IsPlayerInsideBuilding())
			{
				PauseSystem.FOV = fov;
				PauseSystem pauseSystem = PauseSystem.pauseSystem;
				Camera val = (((Object)(object)pauseSystem != (Object)null && (Object)(object)pauseSystem.mainCamera != (Object)null) ? pauseSystem.mainCamera : Camera.main);
				if ((Object)(object)val != (Object)null)
				{
					val.fieldOfView = fov;
				}
			}
		}

		private static bool IsPlayerInsideBuilding()
		{
			try
			{
				if (!_insideLookupInit)
				{
					_insideLookupInit = true;
					_ambianceType = AccessTools.TypeByName("sAmbiance");
					_ambiancePlayerInsideField = ((_ambianceType != null) ? AccessTools.Field(_ambianceType, "playerInside") : null);
				}
				if (_ambianceType == null || _ambiancePlayerInsideField == null)
				{
					return false;
				}
				if (_ambianceInstance == (Object)null)
				{
					_ambianceInstance = Object.FindFirstObjectByType(_ambianceType);
				}
				if (_ambianceInstance == (Object)null)
				{
					return false;
				}
				object? value = _ambiancePlayerInsideField.GetValue(_ambianceInstance);
				GameObject val = (GameObject)((value is GameObject) ? value : null);
				return (Object)(object)val != (Object)null && val.activeSelf;
			}
			catch
			{
				return false;
			}
		}

		private static void RefreshViewDistance()
		{
			if (!_full)
			{
				return;
			}
			try
			{
				if (!_viewDistanceBaseCaptured)
				{
					_baseShadowDistance = QualitySettings.shadowDistance;
					_baseLodBias = QualitySettings.lodBias;
					_baseMaximumLodLevel = QualitySettings.maximumLODLevel;
					_viewDistanceBaseCaptured = true;
				}
				ApplyViewDistanceQuality(GetViewDistanceMode());
			}
			catch
			{
			}
		}

		private static void ApplyViewDistanceQuality(int mode)
		{
			float shadowDistance;
			float lodBias;
			switch (mode)
			{
			case 0:
				shadowDistance = 150f;
				lodBias = 0.75f;
				break;
			case 2:
				shadowDistance = 1200f;
				lodBias = 3f;
				break;
			case 3:
				shadowDistance = 8000f;
				lodBias = 12f;
				break;
			default:
				QualitySettings.shadowDistance = _baseShadowDistance;
				QualitySettings.lodBias = _baseLodBias;
				QualitySettings.maximumLODLevel = _baseMaximumLodLevel;
				return;
			}
			QualitySettings.shadowDistance = shadowDistance;
			QualitySettings.lodBias = lodBias;
			QualitySettings.maximumLODLevel = 0;
		}

		private static void ApplyViewDistanceFarClip(sCameraController controller)
		{
			if (!((Object)(object)controller == (Object)null) && !((Object)(object)controller.cam == (Object)null))
			{
				float num;
				switch (GetViewDistanceMode())
				{
				default:
					return;
				case 0:
					num = 3000f;
					break;
				case 2:
					num = 25000f;
					break;
				case 3:
					num = 250000f;
					break;
				case 1:
					return;
				}
				if (num > controller.cam.nearClipPlane + 1f)
				{
					controller.cam.farClipPlane = num;
				}
			}
		}

		public static void RefreshPixelation()
		{
			if (!_full && !_mirror && (Object)(object)_pixelCustomRearRt == (Object)null)
			{
				return;
			}
			try
			{
				EnsurePixelationTargets();
				int num = (_full ? GetPixelationMode() : 3);
				if (_full)
				{
					ApplyPixelationMain(num);
				}
				ApplyPixelationRear(num);
				_pixelLastMode = num;
			}
			catch
			{
			}
		}

		private static void EnsurePixelationTargets()
		{
			if (_full)
			{
				EnsureMainPixelationTargets();
			}
			if ((Object)(object)_pixelRearCamera == (Object)null || (Object)(object)_pixelRearRenderer == (Object)null)
			{
				sCarController val = Object.FindFirstObjectByType<sCarController>();
				if ((Object)(object)val != (Object)null)
				{
					if ((Object)(object)_pixelRearRenderer == (Object)null)
					{
						Transform val2 = ((Component)val).transform.Find("carInt/InvertMirrored/RearViewMirror") ?? ((Component)val).transform.Find("carInt/RearViewMirror");
						if ((Object)(object)val2 != (Object)null)
						{
							_pixelRearRenderer = ((Component)val2).GetComponent<MeshRenderer>();
						}
					}
					if ((Object)(object)_pixelRearCamera == (Object)null)
					{
						Transform val3 = ((Component)val).transform.Find("RearViewCam");
						if ((Object)(object)val3 != (Object)null)
						{
							_pixelRearCamera = ((Component)val3).GetComponent<Camera>();
						}
					}
				}
			}
			if ((Object)(object)_pixelDefaultRearRt == (Object)null && (Object)(object)_pixelRearCamera != (Object)null && (Object)(object)_pixelRearCamera.targetTexture != (Object)null && (Object)(object)_pixelRearCamera.targetTexture != (Object)(object)_pixelCustomRearRt)
			{
				_pixelDefaultRearRt = _pixelRearCamera.targetTexture;
			}
			if ((Object)(object)_pixelDefaultRearRt == (Object)null && TryGetStableRenderTexture(((Object)(object)_pixelRearRenderer != (Object)null) ? ((Renderer)_pixelRearRenderer).material.mainTexture : null, _pixelCustomRearRt, out var rt))
			{
				_pixelDefaultRearRt = rt;
			}
			CaptureRearPixelationBaseDimensions();
		}

		private static void EnsureMainPixelationTargets()
		{
			Camera camera;
			bool num = TryGetActiveFreeCam(out camera);
			if (num && (Object)(object)camera != (Object)(object)_pixelMainCamera)
			{
				SwitchMainPixelCamera(camera);
			}
			if (num)
			{
				FreeCamCamera?.Invoke(camera);
			}
			if (!num && TryGetRaceCamera(out var camera2) && (Object)(object)camera2 != (Object)(object)_pixelMainCamera)
			{
				SwitchMainPixelCamera(camera2);
			}
			if (!num && TryGetGameplayCamera(out var camera3) && (Object)(object)camera3 != (Object)(object)_pixelMainCamera && IsInactiveCamera(_pixelMainCamera))
			{
				SwitchMainPixelCamera(camera3);
			}
			if ((Object)(object)_pixelMainCamera == (Object)null)
			{
				if (TryGetGameplayCamera(out var camera4))
				{
					_pixelMainCamera = camera4;
				}
				if ((Object)(object)_pixelMainCamera == (Object)null)
				{
					PauseSystem pauseSystem = PauseSystem.pauseSystem;
					_pixelMainCamera = (((Object)(object)pauseSystem != (Object)null) ? pauseSystem.mainCamera : null);
				}
				if ((Object)(object)_pixelMainCamera == (Object)null)
				{
					_pixelMainCamera = Camera.main;
				}
			}
			if ((Object)(object)_pixelScreenRenderer == (Object)null)
			{
				Type type = AccessTools.TypeByName("ScreenSystem");
				Component val = (Component)((type != null) ? /*isinst with value type is only supported in some contexts*/: null);
				if ((Object)(object)val != (Object)null)
				{
					Transform val2 = val.transform.Find("Camera Persp/ScreenPivot/Screen");
					if ((Object)(object)val2 != (Object)null)
					{
						_pixelScreenRenderer = ((Component)val2).GetComponent<MeshRenderer>();
					}
					if ((Object)(object)_pixelScreenRenderer == (Object)null)
					{
						MeshRenderer[] componentsInChildren = val.GetComponentsInChildren<MeshRenderer>(true);
						foreach (MeshRenderer val3 in componentsInChildren)
						{
							if ((Object)(object)val3 != (Object)null && string.Equals(((Object)val3).name, "Screen", StringComparison.OrdinalIgnoreCase))
							{
								_pixelScreenRenderer = val3;
								break;
							}
						}
					}
				}
			}
			if ((Object)(object)_pixelDefaultRt == (Object)null && (Object)(object)_pixelMainCamera != (Object)null && (Object)(object)_pixelMainCamera.targetTexture != (Object)null && (Object)(object)_pixelMainCamera.targetTexture != (Object)(object)_pixelCustomRt)
			{
				_pixelDefaultRt = _pixelMainCamera.targetTexture;
			}
			if ((Object)(object)_pixelDefaultRt == (Object)null && TryGetStableRenderTexture(((Object)(object)_pixelScreenRenderer != (Object)null) ? ((Renderer)_pixelScreenRenderer).material.mainTexture : null, _pixelCustomRt, out var rt))
			{
				_pixelDefaultRt = rt;
			}
			CaptureMainPixelationBaseDimensions();
		}

		private static bool TryGetActiveFreeCam(out Camera camera)
		{
			sFreeCam val = Object.FindFirstObjectByType<sFreeCam>();
			camera = (((Object)(object)val != (Object)null && val.freeCamEnabled) ? val.cam : null);
			return (Object)(object)camera != (Object)null;
		}

		private static bool TryGetGameplayCamera(out Camera camera)
		{
			sCameraController val = Object.FindFirstObjectByType<sCameraController>();
			camera = (((Object)(object)val != (Object)null) ? val.cam : null);
			return (Object)(object)camera != (Object)null;
		}

		private static bool IsInactiveCamera(Camera camera)
		{
			if (!((Object)(object)camera == (Object)null))
			{
				return !((Component)camera).gameObject.activeInHierarchy;
			}
			return true;
		}

		private static bool TryGetRaceCamera(out Camera camera)
		{
			camera = null;
			RaceManager val = Object.FindFirstObjectByType<RaceManager>();
			if ((Object)(object)val == (Object)null || val.players == null || val.players.Count == 0)
			{
				return false;
			}
			camera = val.players[0]?.cam;
			return (Object)(object)camera != (Object)null;
		}

		private static void SwitchMainPixelCamera(Camera camera)
		{
			if (!((Object)(object)camera == (Object)null))
			{
				RenderTexture pixelCustomRt = _pixelCustomRt;
				if ((Object)(object)_pixelMainCamera != (Object)null && (Object)(object)_pixelCustomRt != (Object)null && (Object)(object)_pixelMainCamera.targetTexture == (Object)(object)_pixelCustomRt && (Object)(object)_pixelDefaultRt != (Object)null)
				{
					_pixelMainCamera.targetTexture = _pixelDefaultRt;
					SetMainTexture(_pixelScreenRenderer, (Texture)(object)_pixelDefaultRt);
				}
				ReleaseCustomRt(ref _pixelCustomRt, _pixelDefaultRt);
				_pixelMainCamera = camera;
				if ((Object)(object)camera.targetTexture != (Object)null && (Object)(object)camera.targetTexture != (Object)(object)pixelCustomRt)
				{
					_pixelDefaultRt = camera.targetTexture;
				}
				_pixelLastMode = -1;
				CaptureMainPixelationBaseDimensions();
				Plugin.LogDebug($"Switched pixelation source camera to {((Object)camera).name} ({((Object)camera).GetInstanceID()}).");
			}
		}

		private static void CaptureMainPixelationBaseDimensions()
		{
			if ((_pixelBaseW <= 0 || _pixelBaseH <= 0) && !TryGetTextureSize(((Object)(object)_pixelScreenRenderer != (Object)null) ? ((Renderer)_pixelScreenRenderer).material.mainTexture : null, out _pixelBaseW, out _pixelBaseH))
			{
				if ((Object)(object)_pixelDefaultRt != (Object)null && (Object)(object)_pixelDefaultRt != (Object)(object)_pixelCustomRt)
				{
					_pixelBaseW = ((Texture)_pixelDefaultRt).width;
					_pixelBaseH = ((Texture)_pixelDefaultRt).height;
				}
				else
				{
					_pixelBaseW = 456;
					_pixelBaseH = 256;
				}
			}
		}

		private static void CaptureRearPixelationBaseDimensions()
		{
			if ((_pixelRearBaseW <= 0 || _pixelRearBaseH <= 0) && !TryGetTextureSize(((Object)(object)_pixelRearRenderer != (Object)null) ? ((Renderer)_pixelRearRenderer).material.mainTexture : null, out _pixelRearBaseW, out _pixelRearBaseH))
			{
				if ((Object)(object)_pixelDefaultRearRt != (Object)null && (Object)(object)_pixelDefaultRearRt != (Object)(object)_pixelCustomRearRt)
				{
					_pixelRearBaseW = ((Texture)_pixelDefaultRearRt).width;
					_pixelRearBaseH = ((Texture)_pixelDefaultRearRt).height;
				}
				else
				{
					_pixelRearBaseW = 110;
					_pixelRearBaseH = 32;
				}
			}
		}

		private static bool TryGetTextureSize(Texture texture, out int width, out int height)
		{
			width = 0;
			height = 0;
			if ((Object)(object)texture == (Object)null || (Object)(object)texture == (Object)(object)_pixelCustomRt || (Object)(object)texture == (Object)(object)_pixelCustomRearRt || texture.width <= 0 || texture.height <= 0)
			{
				return false;
			}
			width = texture.width;
			height = texture.height;
			return true;
		}

		private static bool TryGetStableRenderTexture(Texture texture, RenderTexture custom, out RenderTexture rt)
		{
			rt = (RenderTexture)(object)((texture is RenderTexture) ? texture : null);
			if ((Object)(object)rt != (Object)null && (Object)(object)rt != (Object)(object)custom && ((Texture)rt).width > 0)
			{
				return ((Texture)rt).height > 0;
			}
			return false;
		}

		private static void GetScaledTarget(int mode, int baseW, int baseH, int fullW, int fullH, out int targetW, out int targetH)
		{
			switch (mode)
			{
			case 0:
				targetW = fullW;
				targetH = fullH;
				break;
			case 1:
				targetW = Mathf.Min(fullW, Mathf.Max(1, Mathf.RoundToInt((float)baseW * 2.25f)));
				targetH = Mathf.Min(fullH, Mathf.Max(1, Mathf.RoundToInt((float)baseH * 2.25f)));
				break;
			case 2:
				targetW = Mathf.Min(fullW, Mathf.Max(1, Mathf.RoundToInt((float)baseW * 1.5f)));
				targetH = Mathf.Min(fullH, Mathf.Max(1, Mathf.RoundToInt((float)baseH * 1.5f)));
				break;
			case 4:
				targetW = Mathf.Max(1, Mathf.RoundToInt((float)baseW * 0.75f));
				targetH = Mathf.Max(1, Mathf.RoundToInt((float)baseH * 0.75f));
				break;
			default:
				targetW = baseW;
				targetH = baseH;
				break;
			}
		}

		private static void ApplyPixelationMain(int mode)
		{
			if ((Object)(object)_pixelMainCamera == (Object)null || (Object)(object)_pixelScreenRenderer == (Object)null || (Object)(object)_pixelDefaultRt == (Object)null)
			{
				return;
			}
			if (mode == 3)
			{
				ReleaseCustomRt(ref _pixelCustomRt, _pixelDefaultRt);
				_pixelMainCamera.targetTexture = _pixelDefaultRt;
				SetMainTexture(_pixelScreenRenderer, (Texture)(object)_pixelDefaultRt);
				return;
			}
			int baseW = ((_pixelBaseW > 0) ? _pixelBaseW : ((Texture)_pixelDefaultRt).width);
			int baseH = ((_pixelBaseH > 0) ? _pixelBaseH : ((Texture)_pixelDefaultRt).height);
			GetMaxRtSizeForCurrentPresentation(out var width, out var height);
			GetScaledTarget(mode, baseW, baseH, width, height, out var targetW, out var targetH);
			if ((Object)(object)_pixelCustomRt != (Object)null && ((Texture)_pixelCustomRt).width == targetW && ((Texture)_pixelCustomRt).height == targetH && _pixelLastMode == mode)
			{
				_pixelMainCamera.targetTexture = _pixelCustomRt;
				SetMainTexture(_pixelScreenRenderer, (Texture)(object)_pixelCustomRt);
			}
			else
			{
				_pixelCustomRt = CreateLike(_pixelCustomRt, _pixelDefaultRt, targetW, targetH);
				_pixelMainCamera.targetTexture = _pixelCustomRt;
				SetMainTexture(_pixelScreenRenderer, (Texture)(object)_pixelCustomRt);
			}
		}

		private static void ApplyPixelationRear(int mode)
		{
			if ((Object)(object)_pixelRearCamera == (Object)null || (Object)(object)_pixelRearRenderer == (Object)null || (Object)(object)_pixelDefaultRearRt == (Object)null)
			{
				return;
			}
			int num = (_mirror ? GetMirrorQuality() : 0);
			if (mode == 3 && num == 0)
			{
				ReleaseCustomRt(ref _pixelCustomRearRt, _pixelDefaultRearRt);
				_pixelRearCamera.targetTexture = _pixelDefaultRearRt;
				SetMainTexture(_pixelRearRenderer, (Texture)(object)_pixelDefaultRearRt);
				return;
			}
			int num2 = ((_pixelRearBaseW > 0) ? _pixelRearBaseW : ((Texture)_pixelDefaultRearRt).width);
			int num3 = ((_pixelRearBaseH > 0) ? _pixelRearBaseH : ((Texture)_pixelDefaultRearRt).height);
			int targetW;
			int targetH;
			if (num > 0)
			{
				targetW = num2 * (1 << num);
				targetH = num3 * (1 << num);
			}
			else
			{
				int fullSize = GetFullSize(_pixelRearCamera.pixelWidth, ((Texture)_pixelDefaultRearRt).width, GetScreenWidth());
				int fullSize2 = GetFullSize(_pixelRearCamera.pixelHeight, ((Texture)_pixelDefaultRearRt).height, GetScreenHeight());
				GetScaledTarget(mode, num2, num3, (mode == 0) ? Mathf.Min(fullSize, num2 * 4) : fullSize, (mode == 0) ? Mathf.Min(fullSize2, num3 * 4) : fullSize2, out targetW, out targetH);
			}
			if ((Object)(object)_pixelCustomRearRt != (Object)null && ((Texture)_pixelCustomRearRt).width == targetW && ((Texture)_pixelCustomRearRt).height == targetH && _pixelLastMode == mode)
			{
				_pixelRearCamera.targetTexture = _pixelCustomRearRt;
				SetMainTexture(_pixelRearRenderer, (Texture)(object)_pixelCustomRearRt);
			}
			else
			{
				_pixelCustomRearRt = CreateLike(_pixelCustomRearRt, _pixelDefaultRearRt, targetW, targetH);
				_pixelRearCamera.targetTexture = _pixelCustomRearRt;
				SetMainTexture(_pixelRearRenderer, (Texture)(object)_pixelCustomRearRt);
			}
		}

		private static int GetScreenWidth()
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			int width;
			if (Screen.width <= 0)
			{
				Resolution currentResolution = Screen.currentResolution;
				width = ((Resolution)(ref currentResolution)).width;
			}
			else
			{
				width = Screen.width;
			}
			return Mathf.Max(1, width);
		}

		private static int GetScreenHeight()
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			int height;
			if (Screen.height <= 0)
			{
				Resolution currentResolution = Screen.currentResolution;
				height = ((Resolution)(ref currentResolution)).height;
			}
			else
			{
				height = Screen.height;
			}
			return Mathf.Max(1, height);
		}

		private static int GetFullSize(int cameraPixels, int fallbackPixels, int screenPixels)
		{
			if (cameraPixels <= 0)
			{
				if (fallbackPixels <= 0)
				{
					return screenPixels;
				}
				return fallbackPixels;
			}
			return cameraPixels;
		}

		private static void GetMaxRtSizeForCurrentPresentation(out int width, out int height)
		{
			int screenWidth = GetScreenWidth();
			int screenHeight = GetScreenHeight();
			width = screenWidth;
			height = screenHeight;
			float num = ((OutputAspect != null) ? OutputAspect() : ((float)screenWidth / (float)screenHeight));
			if (!(num <= 0.01f))
			{
				if ((float)screenWidth / (float)screenHeight >= num)
				{
					width = Mathf.Max(1, Mathf.RoundToInt((float)height * num));
				}
				else
				{
					height = Mathf.Max(1, Mathf.RoundToInt((float)width / num));
				}
				width = Mathf.Clamp(width, 1, 16384);
				height = Mathf.Clamp(height, 1, 16384);
			}
		}

		private static void SetMainTexture(MeshRenderer renderer, Texture tex)
		{
			if (!((Object)(object)renderer == (Object)null) && !((Object)(object)tex == (Object)null))
			{
				Material material = ((Renderer)renderer).material;
				if ((Object)(object)material != (Object)null)
				{
					material.mainTexture = tex;
				}
			}
		}

		private static RenderTexture CreateLike(RenderTexture existing, RenderTexture like, int width, int height)
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Expected O, but got Unknown
			if ((Object)(object)like == (Object)null)
			{
				return existing;
			}
			if ((Object)(object)existing != (Object)null && ((Texture)existing).width == width && ((Texture)existing).height == height)
			{
				return existing;
			}
			if ((Object)(object)existing != (Object)null && (Object)(object)existing != (Object)(object)like)
			{
				existing.Release();
			}
			RenderTexture val = new RenderTexture(width, height, like.depth)
			{
				format = like.format,
				antiAliasing = like.antiAliasing,
				filterMode = ((Texture)like).filterMode
			};
			val.Create();
			return val;
		}

		private static void ReleaseCustomRt(ref RenderTexture custom, RenderTexture defaultRt)
		{
			if ((Object)(object)custom != (Object)null && (Object)(object)custom != (Object)(object)defaultRt)
			{
				custom.Release();
			}
			custom = null;
		}

		public static int GetPixelationMode()
		{
			int num = PlayerPrefs.GetInt("UltrawidePixelationMode", 3);
			if (PlayerPrefs.GetInt("UltrawidePixelationModeVersion", 1) < 2 && PlayerPrefs.HasKey("UltrawidePixelationMode"))
			{
				switch (num)
				{
				case 1:
					num = 2;
					break;
				case 2:
					num = 3;
					break;
				case 3:
					num = 4;
					break;
				}
				PlayerPrefs.SetInt("UltrawidePixelationModeVersion", 2);
				PlayerPrefs.SetInt("UltrawidePixelationMode", num);
			}
			return Mathf.Clamp(num, 0, 4);
		}

		public static int GetViewDistanceMode()
		{
			int num = PlayerPrefs.GetInt("UltrawideViewDistanceMode", 1);
			if (PlayerPrefs.GetInt("UltrawideViewDistanceModeVersion", 1) < 2 && PlayerPrefs.HasKey("UltrawideViewDistanceMode"))
			{
				num = num switch
				{
					1 => 0, 
					3 => 2, 
					4 => 3, 
					_ => 1, 
				};
				PlayerPrefs.SetInt("UltrawideViewDistanceModeVersion", 2);
				PlayerPrefs.SetInt("UltrawideViewDistanceMode", num);
			}
			return Mathf.Clamp(num, 0, 3);
		}

		public static int GetVsyncMode()
		{
			if (!PlayerPrefs.HasKey("SebTweaks_Gfx_VSyncMode"))
			{
				PlayerPrefs.SetInt("SebTweaks_Gfx_VSyncModeVersion", 2);
				PlayerPrefs.SetInt("SebTweaks_Gfx_VSyncMode", 1);
				return 1;
			}
			int num = PlayerPrefs.GetInt("SebTweaks_Gfx_VSyncMode", -1);
			if (PlayerPrefs.GetInt("SebTweaks_Gfx_VSyncModeVersion", 0) < 2)
			{
				int num2 = ((num != 2) ? 1 : 0);
				PlayerPrefs.SetInt("SebTweaks_Gfx_VSyncModeVersion", 2);
				PlayerPrefs.SetInt("SebTweaks_Gfx_VSyncMode", num2);
				return num2;
			}
			return (num == 1) ? 1 : 0;
		}

		public static int GetMirrorQuality()
		{
			return Mathf.Clamp(PlayerPrefs.GetInt("SebTruck_MirrorQuality", 0), 0, 3);
		}
	}
	public static class HarmonyUtil
	{
		public static void PatchByName(Harmony harmony, Type patchType, string typeName, string methodName, string prefix = null, string postfix = null, Action<string> logDebug = null)
		{
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			if (harmony == null || patchType == null)
			{
				return;
			}
			Type type = AccessTools.TypeByName(typeName);
			if (type == null)
			{
				logDebug?.Invoke("Type '" + typeName + "' not found for patch " + methodName + ".");
				return;
			}
			MethodInfo methodInfo;
			try
			{
				methodInfo = AccessTools.Method(type, methodName, (Type[])null, (Type[])null);
			}
			catch (AmbiguousMatchException)
			{
				methodInfo = ResolveAmbiguousMethod(type, methodName);
			}
			if (methodInfo == null)
			{
				logDebug?.Invoke("Method '" + typeName + "." + methodName + "' not found for patch.");
			}
			else
			{
				HarmonyMethod val = (string.IsNullOrWhiteSpace(prefix) ? ((HarmonyMethod)null) : new HarmonyMethod(patchType, prefix, (Type[])null));
				HarmonyMethod val2 = (string.IsNullOrWhiteSpace(postfix) ? ((HarmonyMethod)null) : new HarmonyMethod(patchType, postfix, (Type[])null));
				harmony.Patch((MethodBase)methodInfo, val, val2, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
		}

		private static MethodInfo ResolveAmbiguousMethod(Type type, string methodName)
		{
			MethodInfo result = null;
			int num = int.MaxValue;
			Type type2 = type;
			while (type2 != null)
			{
				MethodInfo[] methods = type2.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				foreach (MethodInfo methodInfo in methods)
				{
					if (string.Equals(methodInfo.Name, methodName, StringComparison.Ordinal))
					{
						int num2 = methodInfo.GetParameters().Length;
						if (num2 == 0)
						{
							return methodInfo;
						}
						if (num2 < num)
						{
							num = num2;
							result = methodInfo;
						}
					}
				}
				type2 = type2.BaseType;
			}
			return result;
		}
	}
	public static class ModPrefs
	{
		public static float GetFloat(string key, float fallback)
		{
			try
			{
				return PlayerPrefs.GetFloat(key, fallback);
			}
			catch
			{
				return fallback;
			}
		}

		public static void SetFloat(string key, float value)
		{
			try
			{
				PlayerPrefs.SetFloat(key, value);
			}
			catch
			{
			}
		}

		public static int GetInt(string key, int fallback)
		{
			try
			{
				return PlayerPrefs.GetInt(key, fallback);
			}
			catch
			{
				return fallback;
			}
		}

		public static void SetInt(string key, int value)
		{
			try
			{
				PlayerPrefs.SetInt(key, value);
			}
			catch
			{
			}
		}

		public static bool GetBool(string key, bool fallback)
		{
			return GetInt(key, fallback ? 1 : 0) != 0;
		}

		public static void SetBool(string key, bool value)
		{
			SetInt(key, value ? 1 : 0);
		}

		public static void DeleteKey(string key)
		{
			try
			{
				PlayerPrefs.DeleteKey(key);
			}
			catch
			{
			}
		}

		public static bool HasKey(string key)
		{
			try
			{
				return PlayerPrefs.HasKey(key);
			}
			catch
			{
				return false;
			}
		}

		public static void Save()
		{
			try
			{
				PlayerPrefs.Save();
			}
			catch
			{
			}
		}
	}
	internal static class ModPrefsResetter
	{
		internal sealed class Result
		{
			public int DeletedCount;

			public List<string> DeletedKeys = new List<string>();
		}

		internal static Result ClearAllKnownModPrefs()
		{
			Result result = new Result();
			foreach (KeyValuePair<string, PluginInfo> pluginInfo in Chainloader.PluginInfos)
			{
				if (pluginInfo.Key.StartsWith("shibe.easydeliveryco.", StringComparison.Ordinal))
				{
					PluginInfo value = pluginInfo.Value;
					if (value != null && !((Object)(object)value.Instance == (Object)null))
					{
						TryDeletePrefKeyConstantsFromAssembly(((object)value.Instance).GetType().Assembly, result);
					}
				}
			}
			for (int i = 0; i <= 1; i++)
			{
				for (int j = 0; j <= 512; j++)
				{
					TryDeleteKey("ELWS_Bind_" + i + "_" + j, result);
					TryDeleteKey("SebBinds_KB_Bind_" + i + "_" + j, result);
					TryDeleteKey("SebBinds_Wheel_Bind_" + i + "_" + j, result);
				}
			}
			for (int k = 0; k <= 512; k++)
			{
				TryDeleteKey("SebBinds_Axis_" + k, result);
				TryDeleteKey("SebBinds_KB_Axis_" + k, result);
				TryDeleteKey("SebBinds_Wheel_Axis_" + k, result);
			}
			TryDeleteLegacyBindNameKeys(result);
			ResetLoadedBindings();
			PlayerPrefs.Save();
			return result;
		}

		private static void TryDeletePrefKeyConstantsFromAssembly(Assembly asm, Result result)
		{
			if (asm == null)
			{
				return;
			}
			Type[] types;
			try
			{
				types = asm.GetTypes();
			}
			catch
			{
				return;
			}
			foreach (Type type in types)
			{
				if (type == null)
				{
					continue;
				}
				FieldInfo[] fields;
				try
				{
					fields = type.GetFields(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				}
				catch
				{
					continue;
				}
				FieldInfo[] array = fields;
				foreach (FieldInfo fieldInfo in array)
				{
					if (!(fieldInfo == null) && !(fieldInfo.FieldType != typeof(string)) && fieldInfo.IsLiteral && !fieldInfo.IsInitOnly && fieldInfo.Name != null && fieldInfo.Name.StartsWith("PrefKey", StringComparison.Ordinal))
					{
						string key;
						try
						{
							key = (string)fieldInfo.GetRawConstantValue();
						}
						catch
						{
							continue;
						}
						TryDeleteKey(key, result);
					}
				}
			}
		}

		private static void TryDeleteLegacyBindNameKeys(Result result)
		{
			if (!Chainloader.PluginInfos.TryGetValue("shibe.easydeliveryco.sebbinds", out var value) || value == null || (Object)(object)value.Instance == (Object)null)
			{
				return;
			}
			Type type = ((object)value.Instance).GetType().Assembly.GetType("SebBinds.BindAction", throwOnError: false);
			if (type == null || !type.IsEnum)
			{
				return;
			}
			string[] names;
			try
			{
				names = Enum.GetNames(type);
			}
			catch
			{
				return;
			}
			for (int i = 0; i <= 1; i++)
			{
				string text = ((i == 0) ? "Normal" : "Modified");
				for (int j = 0; j < names.Length; j++)
				{
					TryDeleteKey("ELWS_Bind_" + text + "_" + names[j], result);
					TryDeleteKey("SebBinds_KB_Bind_" + text + "_" + names[j], result);
					TryDeleteKey("SebBinds_Wheel_Bind_" + text + "_" + names[j], result);
				}
			}
		}

		private static void ResetLoadedBindings()
		{
			if (!Chainloader.PluginInfos.TryGetValue("shibe.easydeliveryco.sebbinds", out var value) || (Object)(object)((value != null) ? value.Instance : null) == (Object)null)
			{
				return;
			}
			Type type = ((object)value.Instance).GetType();
			MethodInfo method = type.GetMethod("ResetBindings", BindingFlags.Static | BindingFlags.Public);
			if (method != null)
			{
				method.Invoke(null, null);
				return;
			}
			string[] array = new string[2] { "SebBinds.BindingStore", "SebBinds.AxisBindingStore" };
			foreach (string name in array)
			{
				type.Assembly.GetType(name)?.GetMethod("ClearAll", BindingFlags.Static | BindingFlags.Public)?.Invoke(null, null);
			}
		}

		private static void TryDeleteKey(string key, Result result)
		{
			if (string.IsNullOrWhiteSpace(key))
			{
				return;
			}
			try
			{
				if (PlayerPrefs.HasKey(key))
				{
					PlayerPrefs.DeleteKey(key);
					result.DeletedCount++;
					if (result.DeletedKeys.Count < 64)
					{
						result.DeletedKeys.Add(key);
					}
				}
			}
			catch
			{
			}
		}
	}
	[BepInPlugin("shibe.easydeliveryco.sebcore", "SebCore", "1.1.1")]
	public class Plugin : BaseUnityPlugin
	{
		private static ManualLogSource _log;

		private static ConfigEntry<bool> _debugLogging;

		public const string PluginGuid = "shibe.easydeliveryco.sebcore";

		public const string PluginName = "SebCore";

		public const string PluginVersion = "1.1.1";

		internal static Plugin Instance;

		private static ConfigEntry<string> _desktopMenuIconX;

		private static ConfigEntry<string> _desktopMenuIconY;

		private static ConfigEntry<string> _desktopMenuIconName;

		private static ConfigEntry<bool> _clearModPrefs;

		internal static void LogDebug(string message)
		{
			if (_debugLogging != null && _debugLogging.Value)
			{
				ManualLogSource log = _log;
				if (log != null)
				{
					log.LogInfo((object)("[debug] " + message));
				}
			}
		}

		internal static string GetMenuIconName()
		{
			string text = ((_desktopMenuIconName != null) ? _desktopMenuIconName.Value : null);
			if (string.IsNullOrWhiteSpace(text))
			{
				return "mods";
			}
			string text2 = text.Trim();
			if (text2.Length != 0)
			{
				return text2;
			}
			return "mods";
		}

		private void Awake()
		{
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Expected O, but got Unknown
			_log = ((BaseUnityPlugin)this).Logger;
			_debugLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("Logging", "debug_logging", false, "Log extra debug information.");
			_desktopMenuIconX = ((BaseUnityPlugin)this).Config.Bind<string>("Menu", "sebcore_icon_x", "5.5", "Main Menu icon X position. Example: 5.5");
			_desktopMenuIconY = ((BaseUnityPlugin)this).Config.Bind<string>("Menu", "sebcore_icon_y", "3.25", "Main Menu icon Y position. Example: 3.25");
			_desktopMenuIconName = ((BaseUnityPlugin)this).Config.Bind<string>("Menu", "sebcore_icon_name", "mods", "Main Menu icon file name (default: mods). Change this if you want to keep a custom icon with the same name from being overwritten.");
			if (_clearModPrefs == null)
			{
				_clearModPrefs = ((BaseUnityPlugin)this).Config.Bind<bool>("Maintenance", "clear_mod_prefs", false, "If true, clears known mod PlayerPrefs at runtime, then flips back to false. Use to recover from bad bindings.");
			}
			new Harmony("shibe.easydeliveryco.sebcore").Patch((MethodBase)AccessTools.Method(typeof(DesktopDotExe), "Setup", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(Plugin), "DesktopDotExe_Setup_Postfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			TryClearModPrefsIfRequested();
		}

		private static float ParseDesktopIconFloat(string value, float fallback, string label)
		{
			if (string.IsNullOrWhiteSpace(value))
			{
				return fallback;
			}
			string s = value.Trim();
			if (float.TryParse(s, NumberStyles.Float, CultureInfo.InvariantCulture, out var result))
			{
				return result;
			}
			if (float.TryParse(s, out result))
			{
				return result;
			}
			LogDebug("Failed to parse " + label + "='" + value + "', using " + fallback.ToString("0.###", CultureInfo.InvariantCulture) + ".");
			return fallback;
		}

		private static void DesktopDotExe_Setup_Postfix(DesktopDotExe __instance)
		{
			//IL_0177: 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_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: 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_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Expected O, but got Unknown
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)__instance == (Object)null)
			{
				return;
			}
			bool visible = true;
			float num = ParseDesktopIconFloat((_desktopMenuIconX != null) ? _desktopMenuIconX.Value : null, 3f, "sebcore_icon_x");
			float num2 = ParseDesktopIconFloat((_desktopMenuIconY != null) ? _desktopMenuIconY.Value : null, 3.25f, "sebcore_icon_y");
			Vector2 position = default(Vector2);
			((Vector2)(ref position))..ctor(num, num2);
			string menuIconName = GetMenuIconName();
			File val = null;
			File val2 = null;
			foreach (File file in __instance.files)
			{
				if (file != null)
				{
					if (val == null && string.Equals(file.name, menuIconName, StringComparison.OrdinalIgnoreCase))
					{
						val = file;
					}
					if (val2 == null && !string.Equals(menuIconName, "seb", StringComparison.OrdinalIgnoreCase) && string.Equals(file.name, "seb", StringComparison.OrdinalIgnoreCase))
					{
						val2 = file;
					}
				}
			}
			if (val == null && val2 != null)
			{
				val2.name = menuIconName;
				val = val2;
				val2 = null;
			}
			if (val2 != null)
			{
				val2.visible = false;
			}
			if (val == null)
			{
				File item = new File(((ScreenProgram)__instance).R, __instance)
				{
					name = menuIconName,
					type = (FileType)1,
					data = "listener_SebCoreMenu",
					icon = 7,
					iconHover = 7,
					position = position,
					visible = visible,
					cantFolder = false
				};
				__instance.files.Add(item);
			}
			else
			{
				val.icon = 7;
				val.iconHover = 7;
				val.position = position;
				val.visible = visible;
				val.name = menuIconName;
			}
			Transform transform = ((Component)__instance).transform;
			if ((Object)(object)transform.Find("SebCoreMenu") == (Object)null)
			{
				GameObject val3 = new GameObject("SebCoreMenu");
				val3.transform.SetParent(transform, false);
				val3.AddComponent<SebCoreMenuWindow>();
			}
		}

		private void OnEnable()
		{
			Instance = this;
		}

		private void Start()
		{
			if (_clearModPrefs == null)
			{
				_clearModPrefs = ((BaseUnityPlugin)this).Config.Bind<bool>("Maintenance", "clear_mod_prefs", false, "If true, clears known mod PlayerPrefs at runtime, then flips back to false. Use to recover from bad bindings.");
			}
			TryClearModPrefsIfRequested();
		}

		private void Update()
		{
			TryClearModPrefsIfRequested();
		}

		internal static bool RequestClearModPrefs()
		{
			if ((Object)(object)Instance == (Object)null || ((BaseUnityPlugin)Instance).Config == null)
			{
				return false;
			}
			if (_clearModPrefs == null)
			{
				_clearModPrefs = ((BaseUnityPlugin)Instance).Config.Bind<bool>("Maintenance", "clear_mod_prefs", false, "If true, clears known mod PlayerPrefs at runtime, then flips back to false. Use to recover from bad bindings.");
			}
			_clearModPrefs.Value = true;
			((BaseUnityPlugin)Instance).Config.Save();
			return true;
		}

		private void TryClearModPrefsIfRequested()
		{
			if (_clearModPrefs != null && _clearModPrefs.Value)
			{
				ModPrefsResetter.Result result = ModPrefsResetter.ClearAllKnownModPrefs();
				((BaseUnityPlugin)this).Logger.LogInfo((object)("Cleared mod prefs (deleted " + result.DeletedCount + " keys)"));
				_clearModPrefs.Value = false;
				((BaseUnityPlugin)this).Config.Save();
			}
		}
	}
	public class SebCoreMenuWindow : MonoBehaviour
	{
		private enum MenuPage
		{
			Main,
			Settings
		}

		public const string DefaultFileName = "mods";

		public const string ListenerName = "SebCoreMenu";

		public const string ListenerData = "listener_SebCoreMenu";

		private float _mouseYLock;

		private UIUtil _util;

		private WindowView _view;

		private bool _resetPrefsConfirm;

		private int _cartridgePageIndex;

		private MenuPage _page;

		public static string FileName => Plugin.GetMenuIconName();

		public void FrameUpdate(WindowView view)
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: 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_00e4: Unknown result type (might be due to invalid IL or missing references)
			if (view != null)
			{
				_view = view;
				if (_util == null)
				{
					_util = new UIUtil();
				}
				_util.M = view.M;
				_util.R = view.R;
				_util.Nav = view.M.nav;
				Rect p = default(Rect);
				((Rect)(ref p))..ctor(view.position * 8f, view.size * 8f);
				((Rect)(ref p)).position = ((Rect)(ref p)).position + new Vector2(8f, 8f);
				if (((ScreenProgram)_util.M).mouseButtonUp)
				{
					_mouseYLock = 0f;
				}
				if (_mouseYLock > 0f)
				{
					((ScreenProgram)_util.M).mouse.y = _mouseYLock;
				}
				DrawMenu(p);
			}
		}

		public void BackButtonPressed()
		{
			if (_page == MenuPage.Settings)
			{
				_resetPrefsConfirm = false;
				_page = MenuPage.Main;
			}
			else
			{
				CloseWindow();
			}
		}

		private void CloseWindow()
		{
			_resetPrefsConfirm = false;
			_page = MenuPage.Main;
			_cartridgePageIndex = 0;
			WindowView view = _view;
			if (view != null)
			{
				view.Kill();
			}
		}

		private void DrawMenu(Rect p)
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			float num = ((Rect)(ref p)).x + ((Rect)(ref p)).width / 2f;
			float num2 = ((Rect)(ref p)).y + 10f;
			float num3 = 12f;
			float num4 = 4f;
			_util.Label("SebCore", num, num2);
			num2 += num3 + num4;
			if (_page == MenuPage.Settings)
			{
				DrawSettings(p, num, ref num2, num3, num4);
			}
			else
			{
				DrawMain(p, num, ref num2, num3, num4);
			}
		}

		private void DrawMain(Rect p, float cx, ref float y, float line, float sectionGap)
		{
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_033f: Unknown result type (might be due to invalid IL or missing references)
			DesktopDotExe m = _util.M;
			List<CartridgeApps.App> list = CartridgeApps.GetRegisteredAppsSnapshot().Where(CartridgeApps.IsInstalled).ToList();
			float num = 22f;
			bool flag = list.Count > 10;
			int num2 = ((!flag) ? 1 : ((list.Count + 10 - 1) / 10));
			if (_cartridgePageIndex < 0)
			{
				_cartridgePageIndex = 0;
			}
			if (_cartridgePageIndex > num2 - 1)
			{
				_cartridgePageIndex = num2 - 1;
			}
			int num3 = (flag ? (_cartridgePageIndex * 10) : 0);
			int num4 = (flag ? Mathf.Min(num3 + 10, list.Count) : list.Count);
			int num5 = num4 - num3;
			float num6 = 0f;
			if (num5 > 0)
			{
				_util.R.fontOptions.alignment = (Alignment)1;
				float num7 = 0f;
				for (int i = num3; i < num4; i++)
				{
					string text = LocalizationDictionary.Translate(list[i].DisplayName);
					float num8 = _util.R.fput(text, cx, -32f, 0f, 13f, 0f, -1);
					if (num8 > num7)
					{
						num7 = num8;
					}
				}
				num6 = Mathf.Clamp(num7 / 8f + 5f, 12f, 17f);
			}
			float num9 = ((num6 > 0f) ? ((num6 + 2f) * 4f) : 76f);
			float num10 = cx - num9;
			float num11 = cx + num9;
			if (list.Count == 0)
			{
				_util.Label("(no cartridges installed)", cx, y + 8f);
			}
			else
			{
				float num12 = y;
				for (int j = num3; j < num4; j++)
				{
					int num13 = j - num3;
					float centerX = ((num13 % 2 == 0) ? num10 : num11);
					if (_util.FancyButton(list[j].DisplayName, centerX, num12, num6))
					{
						if (!CartridgeApps.EnsureListener(m, list[j]))
						{
							Plugin.LogDebug("Launch failed: could not ensure listener for '" + list[j].FileName + "'");
						}
						else if (!DesktopAppLauncher.TryOpenProgramListener(m, _util.R, list[j].FileName, list[j].ListenerData))
						{
							Plugin.LogDebug("Launch failed: program listener open failed for '" + list[j].FileName + "'");
						}
					}
					if (num13 % 2 == 1)
					{
						num12 += num;
					}
				}
				if (num5 % 2 == 1)
				{
					num12 += num;
				}
			}
			float y2 = ((Rect)(ref p)).y + ((Rect)(ref p)).height - 18f - 12f;
			if (_util.SimpleButtonRaw("Settings", cx, y2))
			{
				_resetPrefsConfirm = false;
				_page = MenuPage.Settings;
				return;
			}
			UIUtil.NavigationAction navigationAction = _util.NavigationFooter(p, flag, 44f);
			if (navigationAction == UIUtil.NavigationAction.Previous && _cartridgePageIndex > 0)
			{
				_cartridgePageIndex--;
			}
			switch (navigationAction)
			{
			case UIUtil.NavigationAction.Back:
				CloseWindow();
				return;
			case UIUtil.NavigationAction.Next:
				if (_cartridgePageIndex < num2 - 1)
				{
					_cartridgePageIndex++;
				}
				break;
			}
			if (flag)
			{
				_util.PageIndicator(p, _cartridgePageIndex, num2);
			}
		}

		private void DrawSettings(Rect p, float cx, ref float y, float line, float sectionGap)
		{
			_util.Label("Settings", cx, y);
			y += line + sectionGap;
			float num = ((Rect)(ref p)).y + ((Rect)(ref p)).height - 18f;
			float y2 = num - 12f;
			float num2 = num - 24f;
			if (_resetPrefsConfirm)
			{
				_util.Label("Clear all mod prefs?", cx, num2 - 12f);
				if (_util.SimpleButtonRaw("Confirm", cx, num2))
				{
					Plugin.RequestClearModPrefs();
					_resetPrefsConfirm = false;
				}
				if (_util.SimpleButtonRaw("Cancel", cx, y2))
				{
					_resetPrefsConfirm = false;
				}
			}
			else if (_util.SimpleButtonRaw("Clear Mod Prefs", cx, num2))
			{
				_resetPrefsConfirm = true;
			}
			if (_util.SimpleButtonRaw("Back", cx, num))
			{
				_resetPrefsConfirm = false;
				_page = MenuPage.Main;
				return;
			}
			y += sectionGap;
			_util.Label("Installed Mods", cx, y);
			y += line;
			List<string> cartridgeLabels = GetCartridgeLabels();
			if (cartridgeLabels.Count == 0)
			{
				_util.Label("(none detected)", cx, y);
				return;
			}
			int num3 = 8;
			float num4 = y;
			for (int i = 0; i < cartridgeLabels.Count && i < num3; i++)
			{
				_util.Label(cartridgeLabels[i], cx, num4);
				num4 += line - 2f;
			}
		}

		private static List<string> GetCartridgeLabels()
		{
			try
			{
				return (from m in (from kvp in Chainloader.PluginInfos
						where kvp.Value != null && kvp.Value.Metadata != null
						select kvp.Value.Metadata into m
						where m.GUID != null && m.GUID.StartsWith("shibe.easydeliveryco.", StringComparison.OrdinalIgnoreCase)
						select m).OrderBy<BepInPlugin, string>((BepInPlugin m) => m.Name, StringComparer.OrdinalIgnoreCase)
					select m.Name + " v" + m.Version).ToList();
			}
			catch (Exception)
			{
				return new List<string>();
			}
		}
	}
	public class UIUtil
	{
		public enum NavigationAction
		{
			None,
			Previous,
			Back,
			Next
		}

		public DesktopDotExe M;

		public GamepadNavigation Nav;

		public MiniRenderer R;

		public NavigationAction NavigationFooter(Rect p, bool paging = true, float sideInset = 40f)
		{
			float y = ((Rect)(ref p)).y + ((Rect)(ref p)).height - 18f;
			bool flag = paging && SimpleButtonRaw("Prev", ((Rect)(ref p)).x + sideInset, y);
			bool flag2 = SimpleButtonRaw("Back", ((Rect)(ref p)).x + ((Rect)(ref p)).width / 2f, y);
			bool flag3 = paging && !flag2 && SimpleButtonRaw("Next", ((Rect)(ref p)).x + ((Rect)(ref p)).width - sideInset, y);
			if (!flag2)
			{
				if (!flag)
				{
					if (!flag3)
					{
						return NavigationAction.None;
					}
					return NavigationAction.Next;
				}
				return NavigationAction.Previous;
			}
			return NavigationAction.Back;
		}

		public void PageIndicator(Rect p, int index, int count)
		{
			Label(index + 1 + "/" + count, ((Rect)(ref p)).x + ((Rect)(ref p)).width - 18f, ((Rect)(ref p)).y + 10f);
		}

		public float? SliderRow(string name, float value, float min, float max, string display, float x, float valueX, float y, ref float mouseYLock)
		{
			ValueLabel(display, valueX, y);
			float? num = Slider(name, Mathf.InverseLerp(min, max, value), x, y, ref mouseYLock);
			if (!num.HasValue)
			{
				return null;
			}
			return Mathf.Lerp(min, max, num.Value);
		}

		public int? ChoiceSliderRow(string name, int value, int max, string display, float x, float valueX, float y, ref float mouseYLock)
		{
			float? num = SliderRow(name, value, 0f, max, display, x, valueX, y, ref mouseYLock);
			if (!num.HasValue)
			{
				return null;
			}
			return Mathf.Clamp(Mathf.RoundToInt(num.Value), 0, Mathf.Max(0, max));
		}

		public void Label(string name, float x, float y)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			name = LocalizationDictionary.Translate(name);
			R.fontOptions.alignment = (Alignment)1;
			R.fput(name, x, y, 0f, 13f, 0f, -1);
		}

		public void LabelOk(string name, float x, float y)
		{
			Label("+ " + name, x, y);
		}

		public void LabelErr(string name, float x, float y)
		{
			Label("! " + name, x, y);
		}

		public void ValueLabel(string value, float x, float y)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			R.fontOptions.alignment = (Alignment)2;
			R.fput(value, x, y, 0f, 13f, 0f, -1);
		}

		public bool Button(string name, float x, float y)
		{
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			name = LocalizationDictionary.Translate(name);
			if (M.MouseOver((int)x - 2, (int)y, name.Length * 8 + 4, 8))
			{
				((ScreenProgram)M).mouseIcon = 128;
				name = ">" + name;
				if (((ScreenProgram)M).mouseButton)
				{
					((ScreenProgram)M).mouseIcon = 160;
				}
				if (((ScreenProgram)M).mouseButtonUp)
				{
					return true;
				}
			}
			R.fontOptions.alignment = (Alignment)2;
			R.fput(name, x - 4f, y, 0f, 13f, 0f, -1);
			return false;
		}

		public bool SimpleButton(string name, float x, float y)
		{
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			name = LocalizationDictionary.Translate(name);
			if (M.MouseOver((int)x - 32, (int)y, 64, 8))
			{
				((ScreenProgram)M).mouseIcon = 128;
				x += 4f;
				name = ">" + name;
				if (((ScreenProgram)M).mouseButton)
				{
					((ScreenProgram)M).mouseIcon = 160;
				}
				if (((ScreenProgram)M).mouseButtonUp)
				{
					return true;
				}
			}
			R.fontOptions.alignment = (Alignment)1;
			R.fput(name, x, y, 0f, 13f, 0f, -1);
			return false;
		}

		public bool SimpleButtonRaw(string name, float x, float y)
		{
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			if (M.MouseOver((int)x - 32, (int)y, 64, 8))
			{
				((ScreenProgram)M).mouseIcon = 128;
				x += 4f;
				name = ">" + name;
				if (((ScreenProgram)M).mouseButton)
				{
					((ScreenProgram)M).mouseIcon = 160;
				}
				if (((ScreenProgram)M).mouseButtonUp)
				{
					return true;
				}
			}
			R.fontOptions.alignment = (Alignment)1;
			R.fput(name, x, y, 0f, 13f, 0f, -1);
			return false;
		}

		public bool FancyButton(string title, float centerX, float y, float fixedWidthTiles = 0f)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			title = LocalizationDictionary.Translate(title);
			R.fontOptions.alignment = (Alignment)1;
			float num = R.fput(title, centerX, -32f, 0f, 13f, 0f, -1);
			float num2 = ((fixedWidthTiles > 0f) ? fixedWidthTiles : (num / 8f + 1f));
			float num3 = (centerX - 4f) / 8f;
			float num4 = y / 8f;
			if (M.MouseOver((int)((num3 - num2 / 2f) * 8f + 4f), (int)(num4 * 8f), (int)((num2 + 1f) * 8f), 24))
			{
				((ScreenProgram)M).mouseIcon = 128;
				float num5 = num2;
				float num6 = num5 + 2f;
				if (((ScreenProgram)M).mouseButton)
				{
					((ScreenProgram)M).mouseIcon = 160;
					num2 = num5;
				}
				else
				{
					num2 = num6;
				}
				if (((ScreenProgram)M).mouseButtonUp)
				{
					return true;
				}
			}
			R.fput(title, num3 * 8f + 4f, num4 * 8f + 8f, 0f, 13f, 0f, -1);
			((ScreenProgram)M).drawBox(num3 - num2 / 2f, num4, num2, 2f);
			return false;
		}

		public bool? Toggle(string name, bool state, float x, float y)
		{
			return Toggle(name, state, x, y, enabled: true);
		}

		public bool? Toggle(string name, bool state, float x, float y, bool enabled)
		{
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			name = LocalizationDictionary.Translate(name);
			bool? result = null;
			string text = "[" + (state ? "on" : "off") + "]";
			R.put(text, x + 4f, y);
			if (enabled && M.MouseOver((int)x - 2, (int)y, text.Length * 8 + 4, 8))
			{
				((ScreenProgram)M).mouseIcon = 128;
				name = ">" + name;
				if (((ScreenProgram)M).mouseButton)
				{
					((ScreenProgram)M).mouseIcon = 160;
				}
				if (((ScreenProgram)M).mouseButtonUp)
				{
					result = !state;
				}
			}
			if (!enabled)
			{
				name = "(" + name + ")";
			}
			R.fontOptions.alignment = (Alignment)2;
			R.fput(name, x - 4f, y, 0f, 13f, 0f, -1);
			return result;
		}

		public bool CycleButtonRaw(string name, string value, float x, float y)
		{
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			string text = "[" + value + "]";
			R.put(text, x + 4f, y);
			if (M.MouseOver((int)x - 2, (int)y, text.Length * 8 + 4, 8))
			{
				((ScreenProgram)M).mouseIcon = 128;
				name = ">" + name;
				if (((ScreenProgram)M).mouseButton)
				{
					((ScreenProgram)M).mouseIcon = 160;
				}
				if (((ScreenProgram)M).mouseButtonUp)
				{
					return true;
				}
			}
			R.fontOptions.alignment = (Alignment)2;
			R.fput(name, x - 4f, y, 0f, 13f, 0f, -1);
			return false;
		}

		public bool CycleButton(string name, string value, float x, float y)
		{
			name = LocalizationDictionary.Translate(name);
			return CycleButtonRaw(name, value, x, y);
		}

		public float? Slider(string name, float value, float x, float y, ref float mouseYLock)
		{
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			name = LocalizationDictionary.Translate(name);
			float? result = null;
			int num = 10;
			for (int i = 0; i < num; i++)
			{
				R.spr(32f, 0f, x + 4f + (float)i * 8f, y, 8f, 8f);
			}
			float num2 = x + value * (float)num * 8f;
			R.spr(0f, 24f, num2, y, 8f, 8f);
			if (M.MouseOver((int)x - 8, (int)y, num * 8 + 16, 8))
			{
				((ScreenProgram)M).mouseIcon = 128;
				name = ">" + name;
				if (Nav != null && Nav.menuInput.x < 0f)
				{
					result = Mathf.Clamp01(value - Time.unscaledDeltaTime / 2f);
				}
				if (Nav != null && Nav.menuInput.x > 0f)
				{
					result = Mathf.Clamp01(value + Time.unscaledDeltaTime / 2f);
				}
				if (((ScreenProgram)M).mouseButton)
				{
					((ScreenProgram)M).mouseIcon = 160;
					value = Mathf.InverseLerp(x + 4f, x + 4f + (float)num * 8f, ((ScreenProgram)M).mouse.x);
					value = Mathf.Clamp01(value);
					result = value;
					if (mouseYLock == 0f)
					{
						mouseYLock = ((ScreenProgram)M).mouse.y;
					}
				}
			}
			R.fontOptions.alignment = (Alignment)2;
			R.fput(name, x - 4f, y, 0f, 13f, 0f, -1);
			return result;
		}
	}
}