From 1bebe2ce65553c43ddb9b6cae7538d6856540956 Mon Sep 17 00:00:00 2001 From: Nb1X Date: Sat, 26 Sep 2026 21:08:58 +0200 Subject: [PATCH] added reload button --- src/RegionFileGenerator.cs | 122 +++++++++++++++++++++++++++++++++++++ src/RegionInstaller.cs | 109 +-------------------------------- src/ReloadButton.cs | 95 +++++++++++++++++++++++++++++ 3 files changed, 218 insertions(+), 108 deletions(-) create mode 100644 src/RegionFileGenerator.cs create mode 100644 src/ReloadButton.cs diff --git a/src/RegionFileGenerator.cs b/src/RegionFileGenerator.cs new file mode 100644 index 0000000..132c32e --- /dev/null +++ b/src/RegionFileGenerator.cs @@ -0,0 +1,122 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Text.Json; +using System.Text.Json.Nodes; +using UnityEngine; + +namespace RegionInstaller +{ + public static class RegionFileGenerator + { + public static void RegenerateRegionFile(string regionFilePath, ConfigData configData) + { + try + { + bool needsRewrite = true; + JsonNode? rootNode = null; + + if (File.Exists(regionFilePath) && new FileInfo(regionFilePath).Length > 0) + { + string content = File.ReadAllText(regionFilePath); + rootNode = JsonNode.Parse(content); + if (rootNode?["Regions"] is JsonArray existingRegions) + { + if (AreRegionsMatching(existingRegions, configData.Regions, configData.KeepInnerslothRegions)) + { + needsRewrite = false; + } + } + } + + if (needsRewrite) + { + if (File.Exists(regionFilePath)) + { + File.Delete(regionFilePath); + } + + Debug.Log("[RegionInstaller] Rewriting regionInfo.json..."); + rootNode = CreateEmptyRegionStructure(); + var regionsArray = rootNode["Regions"]!.AsArray(); + + foreach (var reg in configData.Regions) + { + if (!reg.IsValid) continue; + regionsArray.Add(BuildRegionNode(reg.Name, reg.FullUrl, reg.SelectedPort, reg.Dtls)); + } + + var options = new JsonSerializerOptions { WriteIndented = true }; + File.WriteAllText(regionFilePath, rootNode.ToJsonString(options)); + Debug.Log("Region file reloaded!"); + } + } + catch (Exception ex) + { + Debug.LogError($"[RegionInstaller] Error processing regionInfo.json: {ex.Message}"); + } + } + + private static bool AreRegionsMatching(JsonArray existingRegions, List parsedRegions, bool keepInnersloth) + { + var validCfgRegions = parsedRegions.FindAll(r => r.IsValid); + + int totalExpected = validCfgRegions.Count; + int totalExisting = 0; + + foreach (var node in existingRegions) + { + if (node == null) continue; + bool isOfficial = InnerslothRegions.IsOfficialInnersloth(node.ToJsonString()); + if (!isOfficial || keepInnersloth) + { + totalExisting++; + } + } + + if (totalExisting != totalExpected) return false; + + foreach (var reg in validCfgRegions) + { + bool found = false; + foreach (var node in existingRegions) + { + if (node != null && node.ToJsonString().Contains(reg.FullUrl, StringComparison.OrdinalIgnoreCase)) + { + found = true; + break; + } + } + if (!found) return false; + } + + return true; + } + + private static JsonNode CreateEmptyRegionStructure() => new JsonObject { ["CurrentRegionIdx"] = 0, ["Regions"] = new JsonArray() }; + + private static JsonNode BuildRegionNode(string name, string host, ushort port, bool dtls) + { + return new JsonObject + { + ["$type"] = "StaticHttpRegionInfo, Assembly-CSharp", + ["Name"] = name, + ["PingServer"] = host, + ["Servers"] = new JsonArray + { + new JsonObject + { + ["Name"] = "Http-1", + ["Ip"] = host, + ["Port"] = port, + ["UseDtls"] = dtls, + ["Players"] = 0, + ["ConnectionFailures"] = 0 + } + }, + ["TargetServer"] = null, + ["TranslateName"] = 1003 + }; + } + } +} \ No newline at end of file diff --git a/src/RegionInstaller.cs b/src/RegionInstaller.cs index e371ee0..2878cdc 100644 --- a/src/RegionInstaller.cs +++ b/src/RegionInstaller.cs @@ -1,8 +1,6 @@ using System; using System.Collections.Generic; using System.IO; -using System.Text.Json; -using System.Text.Json.Nodes; using BepInEx; using BepInEx.Unity.IL2CPP; using HarmonyLib; @@ -41,7 +39,7 @@ public override void Load() } string regionJsonPath = Path.Combine(Application.persistentDataPath, "regionInfo.json"); - ProcessAndCleanRegionJson(regionJsonPath, configData); + RegionFileGenerator.RegenerateRegionFile(regionJsonPath, configData); Harmony.PatchAll(); @@ -55,111 +53,6 @@ public override void Load() })); } - private void ProcessAndCleanRegionJson(string regionFilePath, ConfigData configData) - { - try - { - bool needsRewrite = true; - JsonNode? rootNode = null; - - if (File.Exists(regionFilePath) && new FileInfo(regionFilePath).Length > 0) - { - string content = File.ReadAllText(regionFilePath); - rootNode = JsonNode.Parse(content); - if (rootNode?["Regions"] is JsonArray existingRegions) - { - if (AreRegionsMatching(existingRegions, configData.Regions, configData.KeepInnerslothRegions)) - { - needsRewrite = false; - } - } - } - - if (needsRewrite) - { - Log.LogInfo("[RegionInstaller] Rewriting regionInfo.json..."); - rootNode = CreateEmptyRegionStructure(); - var regionsArray = rootNode["Regions"]!.AsArray(); - - foreach (var reg in configData.Regions) - { - if (!reg.IsValid) continue; - regionsArray.Add(BuildRegionNode(reg.Name, reg.FullUrl, reg.SelectedPort, reg.Dtls)); - } - - var options = new JsonSerializerOptions { WriteIndented = true }; - File.WriteAllText(regionFilePath, rootNode.ToJsonString(options)); - Log.LogInfo("[RegionInstaller] regionInfo.json successfully updated!"); - } - } - catch (Exception ex) - { - Log.LogError($"[RegionInstaller] Error processing regionInfo.json: {ex.Message}"); - } - } - - private bool AreRegionsMatching(JsonArray existingRegions, List parsedRegions, bool keepInnersloth) - { - var validCfgRegions = parsedRegions.FindAll(r => r.IsValid); - - int totalExpected = validCfgRegions.Count; - int totalExisting = 0; - - foreach (var node in existingRegions) - { - if (node == null) continue; - bool isOfficial = InnerslothRegions.IsOfficialInnersloth(node.ToJsonString()); - if (!isOfficial || keepInnersloth) - { - totalExisting++; - } - } - - if (totalExisting != totalExpected) return false; - - foreach (var reg in validCfgRegions) - { - bool found = false; - foreach (var node in existingRegions) - { - if (node != null && node.ToJsonString().Contains(reg.FullUrl, StringComparison.OrdinalIgnoreCase)) - { - found = true; - break; - } - } - if (!found) return false; - } - - return true; - } - - private static JsonNode CreateEmptyRegionStructure() => new JsonObject { ["CurrentRegionIdx"] = 0, ["Regions"] = new JsonArray() }; - - private static JsonNode BuildRegionNode(string name, string host, ushort port, bool dtls) - { - return new JsonObject - { - ["$type"] = "StaticHttpRegionInfo, Assembly-CSharp", - ["Name"] = name, - ["PingServer"] = host, - ["Servers"] = new JsonArray - { - new JsonObject - { - ["Name"] = "Http-1", - ["Ip"] = host, - ["Port"] = port, - ["UseDtls"] = dtls, - ["Players"] = 0, - ["ConnectionFailures"] = 0 - } - }, - ["TargetServer"] = null, - ["TranslateName"] = 1003 - }; - } - private void InjectRegions(List parsedRegions) { ServerManager serverMngr = DestroyableSingleton.Instance; diff --git a/src/ReloadButton.cs b/src/ReloadButton.cs new file mode 100644 index 0000000..694e265 --- /dev/null +++ b/src/ReloadButton.cs @@ -0,0 +1,95 @@ +using System; +using System.IO; +using HarmonyLib; +using TMPro; +using UnityEngine; +using Object = UnityEngine.Object; + +namespace RegionInstaller +{ + [HarmonyPatch(typeof(MainMenuManager), nameof(MainMenuManager.Start))] + public static class ReloadButtonPatch + { + private static PassiveButton refreshButton; + + public static void Postfix(MainMenuManager __instance) + { + if (__instance == null) return; + + if (refreshButton == null) + { + refreshButton = CreateOrangeRefreshButton(__instance); + } + } + + private static PassiveButton CreateOrangeRefreshButton(MainMenuManager menu) + { + var parent = menu.transform.Find("MainUI/AspectScaler/LeftPanel/Main Buttons"); + if (parent == null) return null; + + var button = Object.Instantiate(menu.quitButton, parent); + button.name = "RefreshRegionsButton"; + + button.transform.localPosition = new Vector3(2f, 4.05f, 1f); + button.transform.localScale = new Vector3(0.8f, 1f, 1f); + + var aspect = button.GetComponent(); + if (aspect != null) + { + aspect.enabled = false; + } + + button.OnClick = new(); + button.OnClick.AddListener((Action)(() => + { + ConfigData configData = ConfigFile.LoadOrCreate(RegionInstallerPlugin.ConfigPath); + + if (configData.GlitchedLobbiesRegion) + { + configData.KeepInnerslothRegions = true; + GlitchedLobbies.AddGlitchedLobbiesRegion(configData.Regions); + } + + if (configData.KeepInnerslothRegions) + { + InnerslothRegions.AddInnerslothRegions(configData.Regions); + } + + string regionJsonPath = Path.Combine(Application.persistentDataPath, "regionInfo.json"); + RegionFileGenerator.RegenerateRegionFile(regionJsonPath, configData); + + if (ServerManager.Instance != null) + { + ServerManager.Instance.LoadServers(); + } + + Object.FindObjectOfType()?.Start(); + if (Object.FindObjectOfType() is { } regionMenu) + { + regionMenu.OnDisable(); + regionMenu.OnEnable(); + } + })); + + var buttonText = button.transform.Find("FontPlacer/Text_TMP").GetComponent(); + + if (buttonText.TryGetComponent(out var translator)) + { + Object.Destroy(translator); + } + + buttonText.text = "Refresh"; + buttonText.fontSize = buttonText.fontSizeMax = buttonText.fontSizeMin = 3.5f; + buttonText.enableWordWrapping = false; + buttonText.horizontalAlignment = HorizontalAlignmentOptions.Center; + + var normalSprite = button.inactiveSprites.GetComponent(); + var hoverSprite = button.activeSprites.GetComponent(); + normalSprite.color = new Color32(255, 140, 0, byte.MaxValue); + hoverSprite.color = new Color32(255, 165, 50, byte.MaxValue); + + button.gameObject.SetActive(true); + return button; + } + } +} \ No newline at end of file