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.1.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.1.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.1.0"; } internal static class ResolutionConfig { public static ConfigEntry CustomWidth; public static ConfigEntry CustomHeight; public static ConfigEntry ApplyOnLaunch; public static ConfigEntry ToggleGuiKey; private const string SavedWidthKey = "UltrawideResolutions_SavedWidth"; private const string SavedHeightKey = "UltrawideResolutions_SavedHeight"; private const string SavedFullScreenKey = "UltrawideResolutions_SavedFullScreen"; public static void Init(ConfigFile config) { CustomWidth = config.Bind("Custom", "Width", 0, "Custom resolution width. Set to 0 to disable custom resolution."); CustomHeight = config.Bind("Custom", "Height", 0, "Custom resolution height. Set to 0 to disable custom resolution."); ApplyOnLaunch = config.Bind("General", "ApplyOnLaunch", true, "Apply saved resolution automatically on game launch."); ToggleGuiKey = config.Bind("General", "ToggleGuiKey", (KeyCode)289, "Key to toggle the resolution picker overlay."); } public static int GetSavedWidth() { return PlayerPrefs.GetInt("UltrawideResolutions_SavedWidth", 0); } public static int GetSavedHeight() { return PlayerPrefs.GetInt("UltrawideResolutions_SavedHeight", 0); } public static int GetSavedFullScreen() { return PlayerPrefs.GetInt("UltrawideResolutions_SavedFullScreen", -1); } public static void SaveResolution(int width, int height, int fullScreen) { PlayerPrefs.SetInt("UltrawideResolutions_SavedWidth", width); PlayerPrefs.SetInt("UltrawideResolutions_SavedHeight", height); PlayerPrefs.SetInt("UltrawideResolutions_SavedFullScreen", fullScreen); PlayerPrefs.Save(); } } 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 list = new List(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 list = new List(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()); GUILayout.Label("Current: " + Screen.width + "x" + Screen.height, Array.Empty()); GUILayout.Space(4f); GUILayout.BeginHorizontal(Array.Empty()); 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())) { selectedFullScreen = i; } } GUILayout.EndHorizontal(); GUILayout.Space(4f); GUILayout.Label("-- Presets --", Array.Empty()); int num = 2; int num2 = 0; bool flag = false; for (int j = 0; j < cachedResolutions.Length; j++) { if (num2 == 0) { GUILayout.BeginHorizontal(Array.Empty()); 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())) { 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()); GUILayout.BeginHorizontal(Array.Empty()); 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()) && 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()); 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_006e: 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_0085: 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_003e: Expected I4, but got Unknown if (!ResolutionConfig.ApplyOnLaunch.Value) { return; } int savedWidth = ResolutionConfig.GetSavedWidth(); int savedHeight = ResolutionConfig.GetSavedHeight(); int num = ResolutionConfig.GetSavedFullScreen(); if (savedWidth > 0 && savedHeight > 0) { if (num < 0) { num = (int)Optionshandler.fullScreen; } Plugin.Log.LogInfo((object)$"Restoring saved resolution: {savedWidth}x{savedHeight} mode={num}"); ResolutionManager.ApplyResolution(savedWidth, savedHeight, num); Resolution resolution = default(Resolution); ((Resolution)(ref resolution)).width = savedWidth; ((Resolution)(ref resolution)).height = savedHeight; 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}"); } } }