diff --git a/src/Config.cs b/src/Config.cs index dee590b..d14ed02 100644 --- a/src/Config.cs +++ b/src/Config.cs @@ -47,9 +47,11 @@ public class Config Consts.Commands.DebugStat, Consts.Commands.ResetCharacter, Consts.Commands.Ping, + Consts.Commands.Chat, + Consts.Commands.Echo, }; - public List StartupCommands = new List { }; + public List StartupCommands = new List(); public Dictionary> CommandRenames = new(); @@ -494,6 +496,25 @@ public class MitigationSettings /// public bool KeepRestAlive = true; + /// + /// + /// Terraria will translate chat commands into command id. TShock + /// translate them back to keep the command working. + /// However, when the server and the client have different locale, + /// a enUS player send `/help` will be sent as `CommandId: Help` + /// and a deDE server will translate it back to `/hilfe`, thus the + /// command is broken. + /// + /// Cause some commands broken. + /// + /// This will try to change the translate target to enUS, so that + /// the command will be translated back to `/help`. A deDE player + /// may run `/help` (CommandId: Say, Content: /help) or + /// `/hilfe` (CommandId: Help), and both works. + /// + /// + public bool UseEnglishCommand = true; + [JsonConverter(typeof(StringEnumConverter))] public enum DisabledDamageAction { diff --git a/src/Mitigations.cs b/src/Mitigations.cs index 97d8988..b33da84 100644 --- a/src/Mitigations.cs +++ b/src/Mitigations.cs @@ -493,4 +493,23 @@ private void ILHook_Mitigation_KeepRestAlive(ILContext context) } } } + + private void Detour_Mitigation_I18nCommand(On.Terraria.Initializers.ChatInitializer.orig_Load orig) + { + // Pryaxis/TShock#2914 + Terraria.UI.Chat.ChatManager.Commands._localizedCommands.Clear(); + orig(); + if (this.config.Mitigation.Enabled && this.config.Mitigation.UseEnglishCommand) + { + var currentLanguage = Terraria.Localization.LanguageManager.Instance.ActiveCulture; + Terraria.Localization.LanguageManager.Instance.LoadLanguage(Terraria.Localization.GameCulture.FromCultureName(Terraria.Localization.GameCulture.CultureName.English)); + var items = Terraria.UI.Chat.ChatManager.Commands._localizedCommands.ToList(); + Terraria.UI.Chat.ChatManager.Commands._localizedCommands.Clear(); + foreach (var (key, value) in items) + { + Terraria.UI.Chat.ChatManager.Commands._localizedCommands[new Terraria.Localization.LocalizedText(key.Key, key.Value)] = value; + } + Terraria.Localization.LanguageManager.Instance.LoadLanguage(currentLanguage); + } + } } diff --git a/src/Plugin.cs b/src/Plugin.cs index b2dba76..95613eb 100644 --- a/src/Plugin.cs +++ b/src/Plugin.cs @@ -69,6 +69,11 @@ public Plugin(Main game) : base(game) typeof(TShockAPI.Commands) .GetMethod(nameof(TShockAPI.Commands.HandleCommand), _bfany)!, this.Detour_Command_Alternative); + this.Detour( + nameof(this.Detour_Mitigation_I18nCommand), + typeof(Terraria.Initializers.ChatInitializer) + .GetMethod(nameof(Terraria.Initializers.ChatInitializer.Load), _bfany)!, + this.Detour_Mitigation_I18nCommand); this.ILHook( nameof(this.ILHook_Mitigation_DisabledInvincible), Utils.TShockType("Bouncer") @@ -186,6 +191,7 @@ private void OnReload(ReloadEventArgs? e) { TShockAPI.Commands.HandleCommand(TShockAPI.TSPlayer.Server, command); } + Terraria.Initializers.ChatInitializer.Load(); } public override void Initialize()