From 34148499b71752a8a90ea45af08f8e5b92ac94f8 Mon Sep 17 00:00:00 2001 From: Atony <75191600+AtonyGit@users.noreply.github.com> Date: Tue, 25 Aug 2026 18:26:54 -0500 Subject: [PATCH] Fix up system registration for the most part --- .../English.xml => Locale/en_US.xml} | 0 .../SChinese.xml => Locale/zh_CN.xml} | 0 MiraAPI/Colors/CustomColor.cs | 6 +++--- MiraAPI/Colors/PaletteManager.cs | 5 +---- MiraAPI/GameModes/GameModeOption.cs | 9 +++++---- .../OptionTypes/ModdedEnumOption.cs | 9 +++++---- .../GameOptions/OptionTypes/ModdedOption.cs | 2 +- .../OptionTypes/ModdedStringOption.cs | 5 +++-- .../SettingTypes/LocalToggleSetting.cs | 2 +- .../Patches/Options/GameOptionsMenuPatch.cs | 4 ++-- .../Patches/Options/LobbyViewPanePatches.cs | 13 +++---------- .../Patches/Options/RoleSettingMenuPatches.cs | 10 ++-------- MiraAPI/Resources/Locale/en_US.xml | 10 +++++++--- MiraAPI/Roles/CustomRoleManager.cs | 7 ++++--- MiraAPI/Roles/ICustomRole.cs | 13 +++++++------ MiraAPI/Roles/RoleOptionsGroup.cs | 6 +++--- MiraAPI/Translation/MiraLocaleManager.cs | 19 ++++++++++++++++++- .../Translation/MiraLocalizationProvider.cs | 15 +++------------ 18 files changed, 68 insertions(+), 67 deletions(-) rename MiraAPI.Example/Resources/{Translations/English.xml => Locale/en_US.xml} (100%) rename MiraAPI.Example/Resources/{Translations/SChinese.xml => Locale/zh_CN.xml} (100%) diff --git a/MiraAPI.Example/Resources/Translations/English.xml b/MiraAPI.Example/Resources/Locale/en_US.xml similarity index 100% rename from MiraAPI.Example/Resources/Translations/English.xml rename to MiraAPI.Example/Resources/Locale/en_US.xml diff --git a/MiraAPI.Example/Resources/Translations/SChinese.xml b/MiraAPI.Example/Resources/Locale/zh_CN.xml similarity index 100% rename from MiraAPI.Example/Resources/Translations/SChinese.xml rename to MiraAPI.Example/Resources/Locale/zh_CN.xml diff --git a/MiraAPI/Colors/CustomColor.cs b/MiraAPI/Colors/CustomColor.cs index 89663d1..f1b5c49 100644 --- a/MiraAPI/Colors/CustomColor.cs +++ b/MiraAPI/Colors/CustomColor.cs @@ -1,5 +1,5 @@ -using MiraAPI.Utilities; -using Reactor.Localization.Utilities; +using MiraAPI.Translation; +using MiraAPI.Utilities; using UnityEngine; namespace MiraAPI.Colors; @@ -43,7 +43,7 @@ public sealed class CustomColor(StringNames name, Color32 mainColor, Color32 sha } /// - public CustomColor(string name, Color32 mainColor, Color32 shadowColor) : this(CustomStringName.CreateAndRegister(name), mainColor, shadowColor) + public CustomColor(string name, Color32 mainColor, Color32 shadowColor) : this(MiraLocaleManager.GetOrCreateLocaleString(name), mainColor, shadowColor) { } } diff --git a/MiraAPI/Colors/PaletteManager.cs b/MiraAPI/Colors/PaletteManager.cs index c8ae990..3d25b33 100644 --- a/MiraAPI/Colors/PaletteManager.cs +++ b/MiraAPI/Colors/PaletteManager.cs @@ -1,8 +1,6 @@ using System.Collections.Generic; using System.Linq; using HarmonyLib; -using MiraAPI.Translation; -using Reactor.Localization.Utilities; namespace MiraAPI.Colors; @@ -23,8 +21,7 @@ public static class PaletteManager var colors = CustomColors.Select(x => x.MainColor).ToArray(); var shadowColors = CustomColors.Select(x => x.ShadowColor).ToArray(); var stringNames = CustomColors.Select(x => - CustomStringName.CreateAndRegister(TranslationController.Instance.GetString(x.Name).Translate()) - ).ToArray(); + x.Name).ToArray(); Palette.PlayerColors = Palette.PlayerColors.ToArray().AddRangeToArray(colors); Palette.ShadowColors = Palette.ShadowColors.ToArray().AddRangeToArray(shadowColors); diff --git a/MiraAPI/GameModes/GameModeOption.cs b/MiraAPI/GameModes/GameModeOption.cs index 95acd9c..180103d 100644 --- a/MiraAPI/GameModes/GameModeOption.cs +++ b/MiraAPI/GameModes/GameModeOption.cs @@ -6,6 +6,7 @@ using MiraAPI.GameOptions; using MiraAPI.Networking; using MiraAPI.Patches.GameModes; using MiraAPI.Patches.Options; +using MiraAPI.Translation; using MiraAPI.Utilities; using MiraAPI.Utilities.Assets; using Reactor.Localization.Utilities; @@ -48,17 +49,17 @@ public static class GameModeOption internal static StringOption OptionBehaviour { get; set; } = null!; internal static int _lastValue; - internal static readonly StringNames GamemodeName = CustomStringName.CreateAndRegister("Gamemode"); - internal static readonly StringNames CustomName = CustomStringName.CreateAndRegister("Custom"); + internal static readonly StringNames GamemodeName = MiraLocaleManager.GetOrCreateLocaleString("Gamemode"); + internal static readonly StringNames CustomName = MiraLocaleManager.GetOrCreateLocaleString("Custom"); internal static readonly Dictionary Values = new() { - [0] = CustomStringName.CreateAndRegister("Classic"), + [0] = MiraLocaleManager.GetOrCreateLocaleString("Classic"), }; internal static void AddOption(AbstractGameMode mode) { if (!Values.ContainsKey(mode.ID)) - Values.Add(mode.ID, CustomStringName.CreateAndRegister(mode.ColoredName)); + Values.Add(mode.ID, MiraLocaleManager.GetOrCreateLocaleString(mode + ".colored")); } /*[HarmonyPatch(typeof(GameOptionsMenu), nameof(GameOptionsMenu.CreateSettings))] [HarmonyPostfix] diff --git a/MiraAPI/GameOptions/OptionTypes/ModdedEnumOption.cs b/MiraAPI/GameOptions/OptionTypes/ModdedEnumOption.cs index 30809bd..4e512af 100644 --- a/MiraAPI/GameOptions/OptionTypes/ModdedEnumOption.cs +++ b/MiraAPI/GameOptions/OptionTypes/ModdedEnumOption.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Text; using Il2CppInterop.Runtime.InteropTypes.Arrays; using MiraAPI.Networking; +using MiraAPI.Translation; using Reactor.Localization.Utilities; using UnityEngine; using Object = UnityEngine.Object; @@ -37,8 +38,8 @@ public class ModdedEnumOption : ModdedOption data.Title = StringName; data.Type = global::OptionTypes.String; data.Values = values is null ? - Enum.GetNames(enumType).Select(CustomStringName.CreateAndRegister).ToArray() - : [.. values.Select(CustomStringName.CreateAndRegister)]; + Enum.GetNames(enumType).Select(MiraLocaleManager.GetOrCreateLocaleString).ToArray() + : [.. values.Select(MiraLocaleManager.GetOrCreateLocaleString)]; data.Index = Value; } @@ -136,8 +137,8 @@ public class ModdedEnumOption : ModdedOption where T : Enum data.Title = StringName; data.Type = global::OptionTypes.String; data.Values = values is null ? - Enum.GetNames(typeof(T)).Select(CustomStringName.CreateAndRegister).ToArray() - : [.. values.Select(CustomStringName.CreateAndRegister)]; + Enum.GetNames(typeof(T)).Select(MiraLocaleManager.GetOrCreateLocaleString).ToArray() + : [.. values.Select(MiraLocaleManager.GetOrCreateLocaleString)]; data.Index = Convert.ToInt32(Value, NumberFormatInfo.InvariantInfo); } diff --git a/MiraAPI/GameOptions/OptionTypes/ModdedOption.cs b/MiraAPI/GameOptions/OptionTypes/ModdedOption.cs index 6178eff..5fa0ceb 100644 --- a/MiraAPI/GameOptions/OptionTypes/ModdedOption.cs +++ b/MiraAPI/GameOptions/OptionTypes/ModdedOption.cs @@ -82,7 +82,7 @@ public abstract class ModdedOption : IModdedOption Title = title.Translate(); DefaultValue = defaultValue; Value = defaultValue; - StringName = CustomStringName.CreateAndRegister(Title.Translate()); + StringName = MiraLocaleManager.GetOrCreateLocaleString(Title); Visible = () => true; IncludeInPreset = includeInPreset; } diff --git a/MiraAPI/GameOptions/OptionTypes/ModdedStringOption.cs b/MiraAPI/GameOptions/OptionTypes/ModdedStringOption.cs index 62d07cf..630a9ec 100644 --- a/MiraAPI/GameOptions/OptionTypes/ModdedStringOption.cs +++ b/MiraAPI/GameOptions/OptionTypes/ModdedStringOption.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Text; using Il2CppInterop.Runtime.InteropTypes.Arrays; using MiraAPI.Networking; +using MiraAPI.Translation; using Reactor.Localization.Utilities; using UnityEngine; using Object = UnityEngine.Object; @@ -56,7 +57,7 @@ public class ModdedStringOption : ModdedOption newVals.Insert(index, value); Values = newVals.ToArray(); var newStrVals = StringNameValues.ToList(); - newStrVals.Insert(index, CustomStringName.CreateAndRegister(value)); + newStrVals.Insert(index, MiraLocaleManager.GetOrCreateLocaleString(value)); StringNameValues = newStrVals.ToArray(); } @@ -108,7 +109,7 @@ public class ModdedStringOption : ModdedOption data.Title = StringName; data.Type = global::OptionTypes.String; - StringNameValues = values.Select(CustomStringName.CreateAndRegister).ToArray(); + StringNameValues = values.Select(MiraLocaleManager.GetOrCreateLocaleString).ToArray(); data.Values = StringNameValues; data.Index = GetIndex(Value, 3); diff --git a/MiraAPI/LocalSettings/SettingTypes/LocalToggleSetting.cs b/MiraAPI/LocalSettings/SettingTypes/LocalToggleSetting.cs index 3a1e507..3cb02e3 100644 --- a/MiraAPI/LocalSettings/SettingTypes/LocalToggleSetting.cs +++ b/MiraAPI/LocalSettings/SettingTypes/LocalToggleSetting.cs @@ -47,7 +47,7 @@ public class LocalToggleSetting : LocalSettingBase toggleObject.transform.localPosition = new Vector3(order == 1 ? -1.185f : 1.185f, 1.85f - offset, -7); } - toggleObject.BaseText = CustomStringName.CreateAndRegister(Name.Translate()); + toggleObject.BaseText = MiraLocaleManager.GetOrCreateLocaleString(Name); toggleObject.UpdateText(GetValue()); toggleObject.name = Name.Translate(); toggleObject.Background.color = GetValue() ? Tab!.TabAppearance.ToggleActiveColor : Tab!.TabAppearance.ToggleInactiveColor; diff --git a/MiraAPI/Patches/Options/GameOptionsMenuPatch.cs b/MiraAPI/Patches/Options/GameOptionsMenuPatch.cs index bfaf1c4..dec15b6 100644 --- a/MiraAPI/Patches/Options/GameOptionsMenuPatch.cs +++ b/MiraAPI/Patches/Options/GameOptionsMenuPatch.cs @@ -457,7 +457,7 @@ internal static class GameOptionsMenuPatch num -= 0.58f; - categoryHeaderMasked.SetHeader(CustomStringName.CreateAndRegister(group.GroupName), 20); + categoryHeaderMasked.SetHeader(MiraLocaleManager.GetOrCreateLocaleString(group.GroupName), 20); categoryHeaderMasked.Background.color = group.GroupColor; categoryHeaderMasked.Divider.color = group.GroupColor; categoryHeaderMasked.Title.color = group.GroupColor.Equals(MiraApiPlugin.DefaultHeaderColor) @@ -697,7 +697,7 @@ internal static class GameOptionsMenuPatch Quaternion.identity, container); - categoryHeaderMasked.SetHeader(CustomStringName.CreateAndRegister(group.GroupName.Translate()), 20); + categoryHeaderMasked.SetHeader(MiraLocaleManager.GetOrCreateLocaleString(group.GroupName), 20); categoryHeaderMasked.Background.color = group.GroupColor; categoryHeaderMasked.Divider.color = group.GroupColor; categoryHeaderMasked.Title.color = group.GroupColor.Equals(MiraApiPlugin.DefaultHeaderColor) diff --git a/MiraAPI/Patches/Options/LobbyViewPanePatches.cs b/MiraAPI/Patches/Options/LobbyViewPanePatches.cs index 6ee00cd..0a5acee 100644 --- a/MiraAPI/Patches/Options/LobbyViewPanePatches.cs +++ b/MiraAPI/Patches/Options/LobbyViewPanePatches.cs @@ -32,8 +32,7 @@ public static class LobbyViewPanePatches : Plugins[SelectedModIdx - 1]; private static PassiveButton? ModifiersTabButton { get; set; } - - private static StringNames ModifiersTabName { get; } = CustomStringName.CreateAndRegister("ModifiersTab"); + internal static StringNames ModifiersTabName { get; } = MiraLocaleManager.GetOrCreateLocaleString("ModifiersTab"); private static AbstractGameMode? GetCustomGamemode() { @@ -455,7 +454,7 @@ public static class LobbyViewPanePatches // sort the groups by priority var sortedRoleGroups = roleGroups .OrderBy(x => x.Key.Priority) - .ThenBy(x => x.Key.Name); + .ThenBy(x => x.Key.Name.Translate()); foreach (var grouping in sortedRoleGroups) { @@ -466,13 +465,7 @@ public static class LobbyViewPanePatches var group = grouping.Key; - var translatedName = group.Name.Translate(); - var name = translatedName switch - { - "Crewmate" => StringNames.CrewmateRolesHeader, - "Impostor" => StringNames.ImpostorRolesHeader, - _ => CustomStringName.CreateAndRegister(translatedName), - }; + var name = MiraLocaleManager.GetOrCreateLocaleString(group.Name); var categoryHeaderRoleVariant = Object.Instantiate(instance.categoryHeaderRoleOrigin, instance.settingsContainer, true); categoryHeaderRoleVariant.SetHeader(name, 61); diff --git a/MiraAPI/Patches/Options/RoleSettingMenuPatches.cs b/MiraAPI/Patches/Options/RoleSettingMenuPatches.cs index d08961e..ac444da 100644 --- a/MiraAPI/Patches/Options/RoleSettingMenuPatches.cs +++ b/MiraAPI/Patches/Options/RoleSettingMenuPatches.cs @@ -196,7 +196,7 @@ public static class RoleSettingMenuPatches // sort the groups by priority var sortedRoleGroups = roleGroups .OrderBy(x => x.Key.Priority) - .ThenBy(x => x.Key.Name); + .ThenBy(x => x.Key.Name.Translate()); var quotaThing = roleMenu.categoryHeaderEditRoleOrigin.transform.FindChild("QuotaHeader"); var usingNewQuota = false; @@ -215,13 +215,7 @@ public static class RoleSettingMenuPatches RoleGroupHidden.TryAdd(group, false); - var translatedName = group.Name.Translate(); - var name = translatedName switch - { - "Crewmate" => StringNames.CrewmateRolesHeader, - "Impostor" => StringNames.ImpostorRolesHeader, - _ => CustomStringName.CreateAndRegister(translatedName), - }; + var name = MiraLocaleManager.GetOrCreateLocaleString(group.Name); var categoryHeaderMasked = Object.Instantiate( template, diff --git a/MiraAPI/Resources/Locale/en_US.xml b/MiraAPI/Resources/Locale/en_US.xml index 7f3a2b0..5ee4b83 100644 --- a/MiraAPI/Resources/Locale/en_US.xml +++ b/MiraAPI/Resources/Locale/en_US.xml @@ -29,10 +29,14 @@ Outlive the timer or eliminate the crew. Save Roles Modifiers - Crewmate + Crewmate Crew - Impostor + Crewmate Roles + Impostor Imp - Neutral + Impostor Roles + Neutral Neut + Neutral Roles + Other diff --git a/MiraAPI/Roles/CustomRoleManager.cs b/MiraAPI/Roles/CustomRoleManager.cs index a54c439..0f4e839 100644 --- a/MiraAPI/Roles/CustomRoleManager.cs +++ b/MiraAPI/Roles/CustomRoleManager.cs @@ -132,9 +132,10 @@ public static class CustomRoleManager roleBehaviour.Role = (RoleTypes)roleId; roleBehaviour.TeamType = customRole.Team == ModdedRoleTeams.Custom ? RoleTeamTypes.Crewmate : (RoleTeamTypes)customRole.Team; roleBehaviour.NameColor = customRole.RoleColor; - roleBehaviour.StringName = CustomStringName.CreateAndRegister(customRole.RoleName.Translate()); - roleBehaviour.BlurbName = CustomStringName.CreateAndRegister(customRole.RoleDescription.Translate()); - roleBehaviour.BlurbNameLong = CustomStringName.CreateAndRegister(customRole.RoleLongDescription.Translate()); + roleBehaviour.StringName = MiraLocaleManager.GetOrCreateLocaleString(customRole.RoleName); + roleBehaviour.BlurbName = MiraLocaleManager.GetOrCreateLocaleString(customRole.RoleDescription); + roleBehaviour.BlurbNameMed = MiraLocaleManager.GetOrCreateLocaleString(customRole.RoleMedDescription); + roleBehaviour.BlurbNameLong = MiraLocaleManager.GetOrCreateLocaleString(customRole.RoleLongDescription); roleBehaviour.AffectedByLightAffectors = customRole.Configuration.AffectedByLightOnAirship; roleBehaviour.CanBeKilled = customRole.Configuration.CanGetKilled; roleBehaviour.CanUseKillButton = customRole.Configuration.UseVanillaKillButton; diff --git a/MiraAPI/Roles/ICustomRole.cs b/MiraAPI/Roles/ICustomRole.cs index 8e233b8..77d4ce8 100644 --- a/MiraAPI/Roles/ICustomRole.cs +++ b/MiraAPI/Roles/ICustomRole.cs @@ -1,4 +1,5 @@ using System; +using System.Globalization; using System.Text; using BepInEx.Configuration; using MiraAPI.GameOptions; @@ -17,7 +18,7 @@ public interface ICustomRole : IOptionable /// /// Gets the id part used to build the role's translation keys. /// - string IdPart => GetType().Name.ToLower(); + string IdPart => GetType().Name.ToLower(CultureInfo.InvariantCulture); /// /// Gets the name of the role. @@ -44,10 +45,10 @@ public interface ICustomRole : IOptionable /// string RoleFactionTitle => Team switch { - ModdedRoleTeams.Crewmate => TranslationController.Instance.GetString(StringNames.Crewmate), - ModdedRoleTeams.Impostor => TranslationController.Instance.GetString(StringNames.Impostor), - ModdedRoleTeams.Custom => "Neutral", - _ => "Other", + ModdedRoleTeams.Crewmate => MiraLocaleManager.Get("roleTeam.crewmate"), + ModdedRoleTeams.Impostor => MiraLocaleManager.Get("roleTeam.impostor"), + ModdedRoleTeams.Custom => MiraLocaleManager.Get("roleTeam.neutral"), + _ => MiraLocaleManager.Get("roleTeam.other"), }; /// @@ -78,7 +79,7 @@ public interface ICustomRole : IOptionable ModdedRoleTeams.Crewmate => RoleOptionsGroup.Crewmate, ModdedRoleTeams.Impostor => RoleOptionsGroup.Impostor, ModdedRoleTeams.Custom => RoleOptionsGroup.Neutral, - _ => new RoleOptionsGroup(RoleName.Translate(), RoleColor), + _ => new RoleOptionsGroup(RoleName, RoleColor), }; /// diff --git a/MiraAPI/Roles/RoleOptionsGroup.cs b/MiraAPI/Roles/RoleOptionsGroup.cs index 46b6067..a53ea95 100644 --- a/MiraAPI/Roles/RoleOptionsGroup.cs +++ b/MiraAPI/Roles/RoleOptionsGroup.cs @@ -13,15 +13,15 @@ public record struct RoleOptionsGroup(string Name, Color Color, int Priority = 0 /// /// Gets the default group for crewmates. /// - public static RoleOptionsGroup Crewmate { get; } = new("Crewmate", Palette.CrewmateBlue, -2); + public static RoleOptionsGroup Crewmate { get; } = new("roleTeam.crewmate.group", Palette.CrewmateBlue, -2); /// /// Gets the default group for impostors. /// - public static RoleOptionsGroup Impostor { get; } = new("Impostor", Palette.ImpostorRed, -1); + public static RoleOptionsGroup Impostor { get; } = new("roleTeam.impostor.group", Palette.ImpostorRed, -1); /// /// Gets the default group for neutral roles. /// - public static RoleOptionsGroup Neutral { get; } = new("Neutral Roles", Color.gray); + public static RoleOptionsGroup Neutral { get; } = new("roleTeam.neutral.group", Color.gray); } diff --git a/MiraAPI/Translation/MiraLocaleManager.cs b/MiraAPI/Translation/MiraLocaleManager.cs index ee6b1d8..9f9bfd7 100644 --- a/MiraAPI/Translation/MiraLocaleManager.cs +++ b/MiraAPI/Translation/MiraLocaleManager.cs @@ -4,6 +4,7 @@ using System.IO; using System.Linq; using System.Reflection; using System.Xml; +using Reactor.Localization.Utilities; using UnityEngine; namespace MiraAPI.Translation; @@ -12,7 +13,10 @@ public static class MiraLocaleManager { private const string LangDirectory = "mira_languages"; - private static readonly Dictionary>> Locale = []; + public static readonly Dictionary>> Locale = []; + + public static readonly Dictionary RegisteredStringNames = []; + internal static readonly Dictionary StringNamesLookup = []; public static Dictionary LangList { get; } = new() { @@ -177,6 +181,19 @@ public static class MiraLocaleManager return Path.Combine(Application.persistentDataPath, LangDirectory, modGuid); } + public static StringNames GetOrCreateLocaleString(string name) + { + if (RegisteredStringNames.TryGetValue(name, out var stringName)) + { + return stringName; + } + + var newString = CustomStringName.CreateAndRegister(name); + RegisteredStringNames.Add(name, newString); + StringNamesLookup.Add(newString, name); + return newString; + } + private static void LoadInternalStrings(Assembly assembly, string modGuid, string dir) { Directory.CreateDirectory(dir); diff --git a/MiraAPI/Translation/MiraLocalizationProvider.cs b/MiraAPI/Translation/MiraLocalizationProvider.cs index 20b80ed..7505855 100644 --- a/MiraAPI/Translation/MiraLocalizationProvider.cs +++ b/MiraAPI/Translation/MiraLocalizationProvider.cs @@ -13,19 +13,10 @@ public class MiraLocalizationProvider : LocalizationProvider public override bool TryGetText(StringNames stringName, out string? result) { - if (_reactorProvider != null && (int)stringName < 0 && _reactorProvider.TryGetText(stringName, out var reactorText)) + if (MiraLocaleManager.StringNamesLookup.TryGetValue(stringName, out var key)) { - if (reactorText.IsNullOrWhiteSpace()) - { - result = "STRMISS"; - return true; - } - var localeText = MiraLocaleManager.Get(reactorText!); - if (localeText != reactorText) - { - result = localeText; - return true; - } + result = MiraLocaleManager.Get(key); + return true; } result = null; return false;