diff --git a/Patches/TextBoxPatch.cs b/Patches/TextBoxPatch.cs
index a2c74ff09..b076cf8d2 100644
--- a/Patches/TextBoxPatch.cs
+++ b/Patches/TextBoxPatch.cs
@@ -119,6 +119,9 @@ public static class TextBoxPatch
string input = __instance.outputText.text.Trim().Replace("\b", "");
+ bool startsWithCmd = input.StartsWith("/cmd ");
+ if (startsWithCmd) input = "/" + input[5..];
+
if (!input.StartsWith('/') || input.Length < 2)
{
Destroy();
@@ -132,7 +135,7 @@ public static class TextBoxPatch
var exactMatch = false;
bool english = TranslationController.Instance.currentLanguage.languageID == SupportedLangs.English;
- foreach ((string key, Command cmd) in Command.AllCommands)
+ foreach (Command cmd in Command.AllCommands.Values)
{
string[] commandForms = english ? [.. cmd.CommandForms.TakeWhile(x => x.All(char.IsAscii))] : cmd.CommandForms;
@@ -179,8 +182,9 @@ public static class TextBoxPatch
{
Destroy();
IsInvalidCommand = true;
- __instance.compoText.Color(Color.red);
- __instance.outputText.color = Color.red;
+ Color textColor = input is "/c" or "/cm" or "/cmd" ? Palette.Orange : Color.red;
+ __instance.compoText.Color(textColor);
+ __instance.outputText.color = textColor;
return;
}
@@ -226,7 +230,7 @@ public static class TextBoxPatch
}
string inputForm = input.TrimStart('/');
- string text = "/" + (exactMatch ? inputForm : command.CommandForms.TakeWhile(x => x.All(char.IsAscii) && x.StartsWith(inputForm)).MaxBy(x => x.Length));
+ string text = "/" + (startsWithCmd ? "cmd " : string.Empty) + (exactMatch ? inputForm : command.CommandForms.TakeWhile(x => x.All(char.IsAscii) && x.StartsWith(inputForm)).MaxBy(x => x.Length));
var info = $"{command.Description}";
if (!command.CanUseCommand(PlayerControl.LocalPlayer))
@@ -237,24 +241,25 @@ public static class TextBoxPatch
if (exactMatch && command.Arguments.Length > 0)
{
bool poll = command.CommandForms.Contains("poll");
- bool say = command.CommandForms.Contains("say");
int spaces = poll ? input.SkipWhile(x => x != '?').Count(x => x == ' ') + 1 : input.Count(x => x == ' ');
- if (say) spaces = Math.Min(spaces, 1);
var preText = $"{text} {command.Arguments}";
- if (!poll) text += " " + command.Arguments.Split(' ').Skip(spaces).Join(delimiter: " ");
+ if (!poll) text += " " + (spaces >= command.ArgsDescriptions.Length ? string.Empty : string.Join(' ', command.Arguments.Split(' ')[spaces..]));
- string[] args = preText.Split(' ')[1..];
+ string[] split = preText.Split(' ');
+ string[] args = split[(startsWithCmd && split.Length > 2 ? 2 : 1)..];
for (var i = 0; i < args.Length; i++)
{
- if (command.ArgsDescriptions.Length <= i) break;
+ int length = command.ArgsDescriptions.Length;
+ if (length <= i) break;
int skip = poll ? input.TakeWhile(x => x != '?').Count(x => x == ' ') - 1 : 0;
- string arg = say ? args[0] : poll ? i == 0 ? args[..++skip].Join(delimiter: " ") : args[spaces - 1 < i ? skip + i + spaces : skip + i] : args[spaces > i ? i : i + spaces];
+ Logger.Warn($"args.Length: {args.Length}, spaces: {spaces}, i: {i}, args: {string.Join('*', args)}", "debug");
+ string arg = poll ? i == 0 ? string.Join(' ', args[..++skip]) : args[spaces - 1 < i ? skip + i + spaces : skip + i] : spaces > length && i == length - 1 ? string.Join(' ', args[i..^length]) : args[spaces > i ? i : i + spaces];
string argName = command.Arguments.Split(' ')[i];
- bool current = spaces - 1 == i, invalid = IsInvalidArg(), valid = IsValidArg();
+ bool current = spaces - 1 == i || spaces > length && i == length - 1, invalid = IsInvalidArg(), valid = IsValidArg();
info += "\n" + (invalid, current, valid) switch
{
@@ -271,7 +276,7 @@ public static class TextBoxPatch
if (additionalInfo.Length == 0 && argName.Replace('[', '{').Replace(']', '}') is "{id}" or "{id1}" or "{id2}")
{
- Dictionary allIds = Main.AllPlayerControls.ToDictionary(x => x.PlayerId.ColoredPlayerName(), x => x.PlayerId);
+ Dictionary allIds = Main.AllPlayerControls.ToDictionary(x => x.PlayerId, x => x.PlayerId.ColoredPlayerName());
additionalInfo = $"{Translator.GetString("PlayerIdList").TrimEnd(' ')}\n{string.Join('\n', allIds.Select(x => $"{x.Key} \uffeb {x.Value}"))}";
OptionShower.CurrentPage = 0;
}
@@ -318,6 +323,8 @@ public static class TextBoxPatch
}
}
+ additionalInfo += startsWithCmd && AmongUsClient.Instance.AmHost ? $"\n\n<#00a5ff>ⓘ {Translator.GetString("HostMayOmitCmdPrefix")}" : string.Empty;
+
PlaceHolderText.text = text;
CommandInfoText.text = info;
AdditionalInfoText.text = additionalInfo;
diff --git a/Resources/Lang/en_US.json b/Resources/Lang/en_US.json
index 7244a46c2..c5634de61 100644
--- a/Resources/Lang/en_US.json
+++ b/Resources/Lang/en_US.json
@@ -10275,6 +10275,7 @@
"AutoGMRotationStatusText.NextGM": "Next",
"AutoGMRotationStatusText.GMPoll": "Player Vote (/gmpoll)",
"AutoGMRotationStatusText.CooldownTimer": "Jumping to the next game mode on the list in {0} seconds",
+ "HostMayOmitCmdPrefix": "'cmd' prefix\\ncan be omitted",
"SubmergedRoomName.128": "Research",
"SubmergedRoomName.129": "Observatory",
"SubmergedRoomName.130": "Upper Central",