From f6b2f3c69c49b000384af7e76e5c43a188259712 Mon Sep 17 00:00:00 2001 From: Nb1X Date: Sat, 22 Aug 2026 17:34:25 +0200 Subject: [PATCH] Corrected things and added KeepInnerslothRegions bool --- .github/workflows/build.yml | 10 ++ AUModdedRegions.cs | 332 +++++++++++++++++++++++++----------- INFO.md | 0 INSTALL.md | 34 ++++ build.ps1 | 8 + 5 files changed, 284 insertions(+), 100 deletions(-) create mode 100644 INFO.md create mode 100644 INSTALL.md create mode 100644 build.ps1 diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a039e47..226cb73 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -6,9 +6,19 @@ on: - nightly tags: - 'v*' + paths: + - '**/*.cs' + - '**/*.csproj' + - '**/*.yml' + - '**/*.yaml' pull_request: branches: - nightly + paths: + - '**/*.cs' + - '**/*.csproj' + - '**/*.yml' + - '**/*.yaml' workflow_dispatch: jobs: diff --git a/AUModdedRegions.cs b/AUModdedRegions.cs index 1700d13..68c6417 100644 --- a/AUModdedRegions.cs +++ b/AUModdedRegions.cs @@ -18,7 +18,7 @@ namespace AUModdedRegions { public const string Id = "com.nb1x.aumoddedregions"; public const string Name = "AUModdedRegions"; - public const string Version = "1.3.0"; + public const string Version = "1.1.0"; public static string ConfigPath => Path.Combine(Paths.ConfigPath, "CustomRegions.cfg"); public Harmony Harmony { get; } = new Harmony(Id); @@ -34,12 +34,18 @@ namespace AUModdedRegions public override void Load() { - Log.LogInfo($"[AUModdedRegions] Lancement de {Name} v{Version}..."); + Log.LogInfo($"[AUModdedRegions] Loading {Name} v{Version}..."); EnsureConfigFileExists(); - var parsedRegions = ParseConfigRegions(ConfigPath); - ProcessAndCleanRegionJson(parsedRegions); + var configData = ParseConfig(ConfigPath); + + if (configData.KeepInnerslothRegions) + { + AddInnerslothRegions(configData.Regions); + } + + ProcessAndCleanRegionJson(configData.Regions, configData.KeepInnerslothRegions); Harmony.PatchAll(); @@ -47,68 +53,99 @@ namespace AUModdedRegions { if (scene.name == "MainMenu") { - Log.LogInfo("[AUModdedRegions] Scène MainMenu détectée, injection des régions..."); - InjectRegions(parsedRegions); + Log.LogInfo("[AUModdedRegions] MainMenu scene detected, injecting regions..."); + InjectRegions(configData.Regions); } })); } + private static void AddInnerslothRegions(List regions) + { + bool hasEu = regions.Exists(r => r.Address.Equals("matchmaker-eu.among.us", StringComparison.OrdinalIgnoreCase)); + bool hasAs = regions.Exists(r => r.Address.Equals("matchmaker-as.among.us", StringComparison.OrdinalIgnoreCase)); + bool hasNa = regions.Exists(r => r.Address.Equals("matchmaker.among.us", StringComparison.OrdinalIgnoreCase)); + + int insertIndex = regions.FindIndex(r => string.Equals(r.Name, "Default", StringComparison.OrdinalIgnoreCase)); + if (insertIndex < 0) insertIndex = regions.Count; + + if (!hasEu) + { + regions.Insert(insertIndex, new ParsedRegion { Name = "Europe", Address = "matchmaker-eu.among.us", Https = true, Dtls = true, Port1 = 443, Port2 = 22023 }); + insertIndex++; + } + if (!hasAs) + { + regions.Insert(insertIndex, new ParsedRegion { Name = "Asia", Address = "matchmaker-as.among.us", Https = true, Dtls = true, Port1 = 443, Port2 = 22023 }); + insertIndex++; + } + if (!hasNa) + { + regions.Insert(insertIndex, new ParsedRegion { Name = "North America", Address = "matchmaker.among.us", Https = true, Dtls = true, Port1 = 443, Port2 = 22023 }); + } + } + private static void EnsureConfigFileExists() { - if (File.Exists(ConfigPath)) return; + if (File.Exists(ConfigPath)) + { + EnsureSettingExistsInConfig(ConfigPath); + return; + } - string defaultConfig = @"[Region 1] -Name = Niko_NA -Adress = au-us.niko233.top + string defaultConfig = @"KeepInnerslothRegions = false + +[Region 1] +Name = Skeld.net +Address = play.skeld.net Https = true Dtls = false Port = 443, 22023 [Region 2] -Name = Niko_EU -Adress = au-eu.niko233.top +Name = Niko_NA +Address = au-us.niko233.top Https = true Dtls = false Port = 443, 22023 [Region 3] -Name = Niko_AS -Adress = au-as.niko233.top +Name = Niko_EU +Address = au-eu.niko233.top Https = true Dtls = false Port = 443, 22023 [Region 4] -Name = Niko_CN -Adress = au-cn.niko233.top +Name = Niko_AS +Address = au-as.niko233.top Https = true Dtls = false Port = 443, 22023 [Region 5] Name = Modded NA -Adress = aumods.org +Address = aumods.org Https = true Dtls = false Port = 443, 22023 [Region 6] Name = Modded EU -Adress = au-eu.duikbo.at +Address = au-eu.duikbo.at Https = true Dtls = false Port = 443, 22023 [Region 7] Name = Modded AS -Adress = au-as.duikbo.at +Address = au-as.duikbo.at Https = true Dtls = false Port = 443, 22023 [Region 8] Name = Default -Adress = +Address = Https = Dtls = Port = 443, 22023 @@ -116,65 +153,150 @@ Port = 443, 22023 File.WriteAllText(ConfigPath, defaultConfig); } - private void ProcessAndCleanRegionJson(List parsedRegions) + private static void EnsureSettingExistsInConfig(string filePath) + { + var lines = File.ReadAllLines(filePath); + bool found = false; + + foreach (var line in lines) + { + if (line.Trim().StartsWith("KeepInnerslothRegions", StringComparison.OrdinalIgnoreCase)) + { + found = true; + break; + } + } + + if (!found) + { + var newLines = new List { "KeepInnerslothRegions = false" }; + newLines.AddRange(lines); + File.WriteAllLines(filePath, newLines); + } + } + + private void ProcessAndCleanRegionJson(List parsedRegions, bool keepInnersloth) { string regionFilePath = Path.Combine(Application.persistentDataPath, "regionInfo.json"); try { - JsonNode rootNode; + bool needsRewrite = false; + JsonNode? rootNode = null; - if (File.Exists(regionFilePath) && new FileInfo(regionFilePath).Length > 0) + if (!File.Exists(regionFilePath) || new FileInfo(regionFilePath).Length == 0) { - string content = File.ReadAllText(regionFilePath); - rootNode = JsonNode.Parse(content) ?? CreateEmptyRegionStructure(); + needsRewrite = true; } else { - rootNode = CreateEmptyRegionStructure(); - } - - JsonArray regionsArray = rootNode["Regions"]?.AsArray() ?? new JsonArray(); - - for (int i = regionsArray.Count - 1; i >= 0; i--) - { - string regionJson = regionsArray[i]?.ToJsonString() ?? ""; - if (IsOfficialInnersloth(regionJson)) + string content = File.ReadAllText(regionFilePath); + rootNode = JsonNode.Parse(content); + if (rootNode == null) { - regionsArray.RemoveAt(i); + needsRewrite = true; + } + else + { + JsonArray existingRegions = rootNode["Regions"]?.AsArray() ?? new JsonArray(); + if (!AreRegionsMatching(existingRegions, parsedRegions, keepInnersloth)) + { + needsRewrite = true; + } } } - foreach (var reg in parsedRegions) + if (needsRewrite) { - if (string.Equals(reg.Name, "Default", StringComparison.OrdinalIgnoreCase) && string.IsNullOrWhiteSpace(reg.Adress)) - continue; + Log.LogInfo("[AUModdedRegions] Differences detected in regionInfo.json (or file missing/empty). Rewriting completely..."); + rootNode = CreateEmptyRegionStructure(); + JsonArray regionsArray = rootNode["Regions"]?.AsArray() ?? new JsonArray(); - if (string.IsNullOrWhiteSpace(reg.Name) || string.IsNullOrWhiteSpace(reg.Adress)) - continue; - - string protocol = reg.Https ? "https://" : "http://"; - string host = $"{protocol}{reg.Adress}"; - - if (!HasRegion(regionsArray, host)) + foreach (var reg in parsedRegions) { + if (string.Equals(reg.Name, "Default", StringComparison.OrdinalIgnoreCase) && string.IsNullOrWhiteSpace(reg.Address)) + continue; + + if (string.IsNullOrWhiteSpace(reg.Name) || string.IsNullOrWhiteSpace(reg.Address)) + continue; + + string protocol = reg.Https ? "https://" : "http://"; + string host = $"{protocol}{reg.Address}"; + regionsArray.Add(BuildRegionNode(reg.Name, host, reg.Https ? reg.Port1 : reg.Port2, reg.Dtls)); } + rootNode["Regions"] = regionsArray; } - rootNode["Regions"] = regionsArray; + if (rootNode != null && rootNode["Regions"] is JsonArray currentRegionsArray) + { + if (!keepInnersloth) + { + for (int i = currentRegionsArray.Count - 1; i >= 0; i--) + { + string regionJson = currentRegionsArray[i]?.ToJsonString() ?? ""; + if (IsOfficialInnersloth(regionJson)) + { + currentRegionsArray.RemoveAt(i); + } + } + } + rootNode["Regions"] = currentRegionsArray; + } var options = new JsonSerializerOptions { WriteIndented = true }; File.WriteAllText(regionFilePath, rootNode.ToJsonString(options)); - Log.LogInfo("[AUModdedRegions] Fichier regionInfo.json nettoyé et mis à jour !"); + Log.LogInfo("[AUModdedRegions] regionInfo.json successfully verified and updated!"); } catch (Exception ex) { - Log.LogError($"[AUModdedRegions] Erreur lors du traitement du fichier regionInfo.json : {ex.Message}"); + Log.LogError($"[AUModdedRegions] Error while processing regionInfo.json: {ex.Message}"); } } + private bool AreRegionsMatching(JsonArray existingRegions, List parsedRegions, bool keepInnersloth) + { + var validCfgRegions = parsedRegions.FindAll(r => !(string.Equals(r.Name, "Default", StringComparison.OrdinalIgnoreCase) && string.IsNullOrWhiteSpace(r.Address)) && !string.IsNullOrWhiteSpace(r.Name)); + + int totalExpected = validCfgRegions.Count; + int totalExisting = 0; + + foreach (var node in existingRegions) + { + if (node != null) + { + bool isOfficial = IsOfficialInnersloth(node.ToJsonString()); + if (!isOfficial || keepInnersloth) + { + totalExisting++; + } + } + } + + if (totalExisting != totalExpected) return false; + + foreach (var reg in validCfgRegions) + { + string protocol = reg.Https ? "https://" : "http://"; + string host = $"{protocol}{reg.Address}"; + bool found = false; + + foreach (var node in existingRegions) + { + if (node != null && node.ToJsonString().Contains(host, StringComparison.OrdinalIgnoreCase)) + { + found = true; + break; + } + } + + if (!found) return false; + } + + return true; + } + private bool IsOfficialInnersloth(string json) { foreach (var domain in OfficialDomains) @@ -185,18 +307,6 @@ Port = 443, 22023 return false; } - private bool HasRegion(JsonArray regionsArray, string host) - { - foreach (var node in regionsArray) - { - if (node != null && node.ToJsonString().Contains(host, StringComparison.OrdinalIgnoreCase)) - { - return true; - } - } - return false; - } - private JsonNode CreateEmptyRegionStructure() { return new JsonObject @@ -237,15 +347,15 @@ Port = 443, 22023 foreach (var reg in parsedRegions) { - if (string.Equals(reg.Name, "Default", StringComparison.OrdinalIgnoreCase) && string.IsNullOrWhiteSpace(reg.Adress)) + if (string.Equals(reg.Name, "Default", StringComparison.OrdinalIgnoreCase) && string.IsNullOrWhiteSpace(reg.Address)) continue; - if (string.IsNullOrWhiteSpace(reg.Name) || string.IsNullOrWhiteSpace(reg.Adress)) + if (string.IsNullOrWhiteSpace(reg.Name) || string.IsNullOrWhiteSpace(reg.Address)) continue; ushort selectedPort = reg.Https ? reg.Port1 : reg.Port2; string protocol = reg.Https ? "https://" : "http://"; - string fullUrl = $"{protocol}{reg.Adress}"; + string fullUrl = $"{protocol}{reg.Address}"; var serverInfo = new ServerInfo("http-1", fullUrl, selectedPort, reg.Dtls); var serversArray = new Il2CppReferenceArray(new ServerInfo[] { serverInfo }); @@ -253,14 +363,14 @@ Port = 443, 22023 var regionInfo = new StaticHttpRegionInfo(reg.Name, (StringNames)1003, fullUrl, serversArray); serverMngr.AddOrUpdateRegion(regionInfo.Cast()); - Log.LogInfo($"[AUModdedRegions] Région '{reg.Name}' injectée en mémoire."); + Log.LogInfo($"[AUModdedRegions] Region '{reg.Name}' injected into memory."); } } - private static List ParseConfigRegions(string filePath) + private static ConfigData ParseConfig(string filePath) { - var result = new List(); - if (!File.Exists(filePath)) return result; + var configData = new ConfigData(); + if (!File.Exists(filePath)) return configData; ParsedRegion? current = null; @@ -268,55 +378,77 @@ Port = 443, 22023 { string trimmed = line.Trim(); + if (string.IsNullOrEmpty(trimmed) || trimmed.StartsWith("#")) continue; + if (trimmed.StartsWith("[") && trimmed.EndsWith("]")) { - if (current != null) result.Add(current); + if (current != null) configData.Regions.Add(current); current = new ParsedRegion(); continue; } - if (current == null || !trimmed.Contains('=')) continue; - - var parts = trimmed.Split(new[] { '=' }, 2); - string key = parts[0].Trim().ToLowerInvariant(); - string val = parts[1].Trim(); - - switch (key) + if (trimmed.Contains('=')) { - case "name": - current.Name = val; - break; - case "adress": - case "address": - current.Adress = val; - break; - case "https": - bool.TryParse(val, out bool https); - current.Https = https; - break; - case "dtls": - bool.TryParse(val, out bool dtls); - current.Dtls = dtls; - break; - case "port": - var ports = val.Split(','); - if (ports.Length > 0 && ushort.TryParse(ports[0].Trim(), out ushort p1)) - current.Port1 = p1; - if (ports.Length > 1 && ushort.TryParse(ports[1].Trim(), out ushort p2)) - current.Port2 = p2; - break; + var parts = trimmed.Split(new[] { '=' }, 2); + string key = parts[0].Trim().ToLowerInvariant(); + string val = parts[1].Trim(); + + if (current == null) + { + if (key == "keepinnerslothregions") + { + if (bool.TryParse(val, out bool keep)) + { + configData.KeepInnerslothRegions = keep; + } + } + } + else + { + switch (key) + { + case "name": + current.Name = val; + break; + case "address": + case "adress": + current.Address = val; + break; + case "https": + bool.TryParse(val, out bool https); + current.Https = https; + break; + case "dtls": + bool.TryParse(val, out bool dtls); + current.Dtls = dtls; + break; + case "port": + var ports = val.Split(','); + if (ports.Length > 0 && ushort.TryParse(ports[0].Trim(), out ushort p1)) + current.Port1 = p1; + if (ports.Length > 1 && ushort.TryParse(ports[1].Trim(), out ushort p2)) + current.Port2 = p2; + break; + } + } } } - if (current != null) result.Add(current); + if (current != null) configData.Regions.Add(current); - return result; + return configData; + } + + private class ConfigData + { + public bool KeepInnerslothRegions { get; set; } = false; + public List Regions { get; set; } = new List(); } private class ParsedRegion { public string Name { get; set; } = ""; - public string Adress { get; set; } = ""; + public string Address { get; set; } = ""; public bool Https { get; set; } = true; public bool Dtls { get; set; } = false; public ushort Port1 { get; set; } = 443; diff --git a/INFO.md b/INFO.md new file mode 100644 index 0000000..e69de29 diff --git a/INSTALL.md b/INSTALL.md new file mode 100644 index 0000000..6d790e0 --- /dev/null +++ b/INSTALL.md @@ -0,0 +1,34 @@ +# Install Instructions +To install AUModdedRegions, there are multiple methods. + +--- +**Easy install** + +1. Go to the [releases](https://github.com/BetterUsProject/AUModdedRegions/releases) of this project. +2. Download the latest .zip file for your game version (Steam, Epic Games...) +3. Open your Among Us folder and unzip the file you downloaded. +4. Now, launch Among Us to generate the config file. +5. AUModdedRegions is now installed! + +**Updating an existing install** + +> We're planning on adding a built-in updater to the plugin. + +1. Go to the [releases](https://github.com/BetterUsProject/AUModdedRegions/releases) of this project. +2. Download the latest .dll available. +3. Go to your Among Us folder and open BepInEx/plugins. +4. Delete the existing AUModdedRegions.dll file from the folder and replace it with the new one. +5. AUModdedRegions is now updated to the latest version! + +**Manual install** + +1. Go to the BepInEx [Bleeding Edge builds page](https://builds.bepinex.dev/projects/bepinex_be). +2. Scroll down until you see "Artifacts" and press on the latest artifact available. +3. Download the .zip for your game version: +- Steam/Itch.io: BepInEx-Unity.IL2CPP-win-x86-6.0.0-be.*...*+*...*.zip +- Epic Games/Windows Store: BepInEx-Unity.IL2CPP-win-x64-6.0.0-be.*...*+*...*.zip +4. Unzip the file in your Among Us folder. +5. Go to the [releases](https://github.com/BetterUsProject/AUModdedRegions/releases) of this project. +6. Download the latest .dll file available. +7. In your Among Us folder, put the .dll you downloaded in BepInEx/plugins. +8. AUModdedRegions is now installed! \ No newline at end of file diff --git a/build.ps1 b/build.ps1 new file mode 100644 index 0000000..ca47afc --- /dev/null +++ b/build.ps1 @@ -0,0 +1,8 @@ +Write-Host "Building project..." -ForegroundColor Cyan +dotnet build -c Release + +if ($LASTEXITCODE -eq 0) { + Write-Host "Build successful!" -ForegroundColor Green +} else { + Write-Host "Build failed!" -ForegroundColor Red +} \ No newline at end of file