Decompiled source of Ultrawide Resolutions v1.0.0

plugins/UltrawideResolutions.dll

Decompiled 8 hours ago
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using UnityEngine;

[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace UltrawideResolutions
{
	[BepInPlugin("com.nicho.rounds.ultrawideresolutions", "Ultrawide Resolutions", "1.0.0")]
	[BepInProcess("Rounds.exe")]
	public class Plugin : BaseUnityPlugin
	{
		internal static Plugin Instance;

		internal static ConfigFile Cfg;

		internal static ManualLogSource Log;

		private void Awake()
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Expected O, but got Unknown
			Instance = this;
			Cfg = ((BaseUnityPlugin)this).Config;
			Log = ((BaseUnityPlugin)this).Logger;
			ResolutionConfig.Init(((BaseUnityPlugin)this).Config);
			Log.LogInfo((object)string.Format("{0} v{1} loaded", "Ultrawide Resolutions", "1.0.0"));
			Harmony val = new Harmony("com.nicho.rounds.ultrawideresolutions");
			val.PatchAll();
			Log.LogInfo((object)"Harmony patches applied");
		}

		private void Update()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			if (Input.GetKeyDown(ResolutionConfig.ToggleGuiKey.Value))
			{
				ResolutionGui.Visible = !ResolutionGui.Visible;
			}
		}

		private void OnGUI()
		{
			ResolutionGui.Draw();
		}
	}
	internal static class PluginInfo
	{
		public const string GUID = "com.nicho.rounds.ultrawideresolutions";

		public const string NAME = "Ultrawide Resolutions";

		public const string VERSION = "1.0.0";
	}
	internal static class ResolutionConfig
	{
		public static ConfigEntry<int> CustomWidth;

		public static ConfigEntry<int> CustomHeight;

		public static ConfigEntry<bool> ApplyOnLaunch;

		public static ConfigEntry<int> SavedWidth;

		public static ConfigEntry<int> SavedHeight;

		public static ConfigEntry<int> SavedFullScreen;

		public static ConfigEntry<KeyCode> ToggleGuiKey;

		public static void Init(ConfigFile config)
		{
			CustomWidth = config.Bind<int>("Custom", "Width", 0, "Custom resolution width. Set to 0 to disable custom resolution.");
			CustomHeight = config.Bind<int>("Custom", "Height", 0, "Custom resolution height. Set to 0 to disable custom resolution.");
			ApplyOnLaunch = config.Bind<bool>("General", "ApplyOnLaunch", true, "Apply saved resolution automatically on game launch.");
			SavedWidth = config.Bind<int>("General", "SavedWidth", 0, "Last used resolution width (auto-saved).");
			SavedHeight = config.Bind<int>("General", "SavedHeight", 0, "Last used resolution height (auto-saved).");
			SavedFullScreen = config.Bind<int>("General", "SavedFullScreen", -1, "Last used fullscreen mode (auto-saved). -1 = use game default.");
			ToggleGuiKey = config.Bind<KeyCode>("General", "ToggleGuiKey", (KeyCode)289, "Key to toggle the resolution picker overlay.");
		}

		public static void SaveResolution(int width, int height, int fullScreen)
		{
			SavedWidth.Value = width;
			SavedHeight.Value = height;
			SavedFullScreen.Value = fullScreen;
		}
	}
	internal static class ResolutionManager
	{
		private static readonly Resolution[] UltrawidePresets = (Resolution[])(object)new Resolution[9]
		{
			MakeRes(2560, 1080),
			MakeRes(2560, 1440),
			MakeRes(3440, 1440),
			MakeRes(3840, 1080),
			MakeRes(3840, 1600),
			MakeRes(3840, 2160),
			MakeRes(5120, 1440),
			MakeRes(5120, 2160),
			MakeRes(7680, 2160)
		};

		public static Resolution[] GetExtraResolutions()
		{
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			List<Resolution> list = new List<Resolution>(UltrawidePresets);
			int cw = ResolutionConfig.CustomWidth.Value;
			int ch = ResolutionConfig.CustomHeight.Value;
			if (cw > 0 && ch > 0 && !list.Any((Resolution r) => ((Resolution)(ref r)).width == cw && ((Resolution)(ref r)).height == ch))
			{
				list.Add(MakeRes(cw, ch));
			}
			return list.ToArray();
		}

		public static Resolution[] MergeResolutions(Resolution[] original)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: 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)
			List<Resolution> list = new List<Resolution>(original);
			Resolution[] extraResolutions = GetExtraResolutions();
			Resolution[] array = extraResolutions;
			for (int i = 0; i < array.Length; i++)
			{
				Resolution extra = array[i];
				if (!list.Any((Resolution r) => ((Resolution)(ref r)).width == ((Resolution)(ref extra)).width && ((Resolution)(ref r)).height == ((Resolution)(ref extra)).height))
				{
					list.Add(extra);
				}
			}
			list.Sort(delegate(Resolution a, Resolution b)
			{
				int num = ((Resolution)(ref a)).width.CompareTo(((Resolution)(ref b)).width);
				return (num == 0) ? ((Resolution)(ref a)).height.CompareTo(((Resolution)(ref b)).height) : num;
			});
			return list.ToArray();
		}

		public static void ApplyResolution(int width, int height, int fullScreenMode)
		{
			if (width > 0 && height > 0)
			{
				Screen.SetResolution(width, height, (FullScreenMode)fullScreenMode);
				ResolutionConfig.SaveResolution(width, height, fullScreenMode);
				if (Plugin.Instance != null)
				{
					Plugin.Log.LogInfo((object)$"Applied resolution: {width}x{height} (mode: {(object)(FullScreenMode)fullScreenMode})");
				}
			}
		}

		private static Resolution MakeRes(int w, int h)
		{
			//IL_0002: 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)
			Resolution result = default(Resolution);
			((Resolution)(ref result)).width = w;
			((Resolution)(ref result)).height = h;
			((Resolution)(ref result)).refreshRate = 60;
			return result;
		}
	}
	internal static class ResolutionGui
	{
		public static bool Visible = false;

		private static Rect windowRect = new Rect(20f, 20f, 300f, 400f);

		private static Vector2 scrollPos;

		private static string customW = "";

		private static string customH = "";

		private static bool initialized = false;

		private static int selectedFullScreen = 1;

		private static Resolution[] cachedResolutions;

		private static readonly string[] fullScreenLabels = new string[4] { "Fullscreen", "Windowed Fullscreen", "Maximized Window", "Windowed" };

		public static void Draw()
		{
			//IL_0056: 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_0082: 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: Expected O, but got Unknown
			if (Visible)
			{
				if (!initialized)
				{
					customW = Screen.width.ToString();
					customH = Screen.height.ToString();
					cachedResolutions = null;
					initialized = true;
				}
				windowRect = GUI.Window(94301, windowRect, new WindowFunction(DrawWindow), "Ultrawide Resolutions");
			}
		}

		private static void DrawWindow(int id)
		{
			//IL_013b: 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_0315: Unknown result type (might be due to invalid IL or missing references)
			//IL_034c: Unknown result type (might be due to invalid IL or missing references)
			if (cachedResolutions == null)
			{
				cachedResolutions = ResolutionManager.MergeResolutions(Screen.resolutions);
			}
			GUILayout.BeginVertical(Array.Empty<GUILayoutOption>());
			GUILayout.Label("Current: " + Screen.width + "x" + Screen.height, Array.Empty<GUILayoutOption>());
			GUILayout.Space(4f);
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label("Mode:", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(40f) });
			for (int i = 0; i < fullScreenLabels.Length; i++)
			{
				string text = ((i != selectedFullScreen) ? fullScreenLabels[i] : ("[" + fullScreenLabels[i] + "]"));
				if (GUILayout.Button(text, Array.Empty<GUILayoutOption>()))
				{
					selectedFullScreen = i;
				}
			}
			GUILayout.EndHorizontal();
			GUILayout.Space(4f);
			GUILayout.Label("-- Presets --", Array.Empty<GUILayoutOption>());
			int num = 2;
			int num2 = 0;
			bool flag = false;
			for (int j = 0; j < cachedResolutions.Length; j++)
			{
				if (num2 == 0)
				{
					GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
					flag = true;
				}
				Resolution val = cachedResolutions[j];
				string aspectLabel = GetAspectLabel(((Resolution)(ref val)).width, ((Resolution)(ref val)).height);
				string text2 = ((Resolution)(ref val)).width + "x" + ((Resolution)(ref val)).height;
				if (aspectLabel.Length > 0)
				{
					text2 = text2 + " (" + aspectLabel + ")";
				}
				if (GUILayout.Button(text2, Array.Empty<GUILayoutOption>()))
				{
					ResolutionManager.ApplyResolution(((Resolution)(ref val)).width, ((Resolution)(ref val)).height, selectedFullScreen);
					cachedResolutions = null;
				}
				num2++;
				if (num2 >= num)
				{
					GUILayout.EndHorizontal();
					flag = false;
					num2 = 0;
				}
			}
			if (flag)
			{
				GUILayout.EndHorizontal();
			}
			GUILayout.Space(8f);
			GUILayout.Label("-- Custom --", Array.Empty<GUILayoutOption>());
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label("W:", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(20f) });
			customW = GUILayout.TextField(customW, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(60f) });
			GUILayout.Label("H:", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(20f) });
			customH = GUILayout.TextField(customH, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(60f) });
			if (GUILayout.Button("Apply", Array.Empty<GUILayoutOption>()) && int.TryParse(customW, out var result) && int.TryParse(customH, out var result2) && result > 0 && result2 > 0)
			{
				ResolutionManager.ApplyResolution(result, result2, selectedFullScreen);
				cachedResolutions = null;
			}
			GUILayout.EndHorizontal();
			GUILayout.Space(4f);
			GUILayout.Label(string.Concat("Press ", ResolutionConfig.ToggleGuiKey.Value, " to close"), Array.Empty<GUILayoutOption>());
			GUILayout.EndVertical();
			GUI.DragWindow(new Rect(0f, 0f, 10000f, 20f));
		}

		private static string GetAspectLabel(int w, int h)
		{
			if (h <= 0)
			{
				return "";
			}
			float a = (float)w / (float)h;
			if (IsClose(a, 1.7777778f))
			{
				return "16:9";
			}
			if (IsClose(a, 1.6f))
			{
				return "16:10";
			}
			if (IsClose(a, 2.3333333f))
			{
				return "21:9";
			}
			if (IsClose(a, 2.3703704f))
			{
				return "21:9";
			}
			if (IsClose(a, 2.3888888f))
			{
				return "21:9";
			}
			if (IsClose(a, 3.5555556f))
			{
				return "32:9";
			}
			if (IsClose(a, 1.25f))
			{
				return "5:4";
			}
			if (IsClose(a, 1.3333334f))
			{
				return "4:3";
			}
			if (IsClose(a, 1.5f))
			{
				return "3:2";
			}
			return "";
		}

		private static bool IsClose(float a, float b)
		{
			return Math.Abs(a - b) < 0.05f;
		}
	}
}
namespace UltrawideResolutions.Patches
{
	[HarmonyPatch(typeof(MultiOptions), "GetBestResolutions")]
	internal static class GetBestResolutionsPatch
	{
		[HarmonyPostfix]
		private static void Postfix(ref Resolution[] __result)
		{
			__result = ResolutionManager.MergeResolutions(__result);
			Plugin.Log.LogDebug((object)$"Resolution list expanded to {__result.Length} entries");
		}
	}
	[HarmonyPatch(typeof(Optionshandler), "Start")]
	internal static class OptionshandlerStartPatch
	{
		[HarmonyPostfix]
		private static void Postfix()
		{
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: 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_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Expected I4, but got Unknown
			if (!ResolutionConfig.ApplyOnLaunch.Value)
			{
				return;
			}
			int value = ResolutionConfig.SavedWidth.Value;
			int value2 = ResolutionConfig.SavedHeight.Value;
			int num = ResolutionConfig.SavedFullScreen.Value;
			if (value > 0 && value2 > 0)
			{
				if (num < 0)
				{
					num = (int)Optionshandler.fullScreen;
				}
				Plugin.Log.LogInfo((object)$"Restoring saved resolution: {value}x{value2} mode={num}");
				ResolutionManager.ApplyResolution(value, value2, num);
				Resolution resolution = default(Resolution);
				((Resolution)(ref resolution)).width = value;
				((Resolution)(ref resolution)).height = value2;
				Optionshandler.resolution = resolution;
			}
		}
	}
	[HarmonyPatch(typeof(OptionsButton), "SetResolutionAndFullscreen")]
	internal static class SetResolutionAndFullscreenPatch
	{
		[HarmonyPostfix]
		private static void Postfix(Resolution resolution, FullScreenOption fullScreenOption)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Expected I4, but got Unknown
			ResolutionConfig.SaveResolution(((Resolution)(ref resolution)).width, ((Resolution)(ref resolution)).height, (int)fullScreenOption);
			Plugin.Log.LogDebug((object)$"Resolution changed via game UI: {((Resolution)(ref resolution)).width}x{((Resolution)(ref resolution)).height}");
		}
	}
}