Update radio prefix parsing (#13777)

This commit is contained in:
Leon Friedrich
2023-02-19 06:27:56 +13:00
committed by GitHub
parent 63a0c76ecc
commit 75a559fa55
32 changed files with 659 additions and 606 deletions

View File

@@ -13,6 +13,7 @@ using Content.Shared.CCVar;
using Content.Shared.Chat;
using Content.Shared.Examine;
using Content.Shared.Input;
using Content.Shared.Radio;
using Robust.Client.Graphics;
using Robust.Client.Input;
using Robust.Client.Player;
@@ -45,30 +46,21 @@ public sealed class ChatUIController : UIController
[UISystemDependency] private readonly ExamineSystem? _examine = default;
[UISystemDependency] private readonly GhostSystem? _ghost = default;
[UISystemDependency] private readonly TypingIndicatorSystem? _typingIndicator = default;
[UISystemDependency] private readonly ChatSystem? _chatSys = default;
private ISawmill _sawmill = default!;
public const char AliasLocal = '.';
public const char AliasConsole = '/';
public const char AliasDead = '\\';
public const char AliasLOOC = '(';
public const char AliasOOC = '[';
public const char AliasEmotes = '@';
public const char AliasAdmin = ']';
public const char AliasRadio = ';';
public const char AliasWhisper = ',';
public static readonly Dictionary<char, ChatSelectChannel> PrefixToChannel = new()
{
{AliasLocal, ChatSelectChannel.Local},
{AliasWhisper, ChatSelectChannel.Whisper},
{AliasConsole, ChatSelectChannel.Console},
{AliasLOOC, ChatSelectChannel.LOOC},
{AliasOOC, ChatSelectChannel.OOC},
{AliasEmotes, ChatSelectChannel.Emotes},
{AliasAdmin, ChatSelectChannel.Admin},
{AliasRadio, ChatSelectChannel.Radio},
{AliasDead, ChatSelectChannel.Dead}
{SharedChatSystem.LocalPrefix, ChatSelectChannel.Local},
{SharedChatSystem.WhisperPrefix, ChatSelectChannel.Whisper},
{SharedChatSystem.ConsolePrefix, ChatSelectChannel.Console},
{SharedChatSystem.LOOCPrefix, ChatSelectChannel.LOOC},
{SharedChatSystem.OOCPrefix, ChatSelectChannel.OOC},
{SharedChatSystem.EmotesPrefix, ChatSelectChannel.Emotes},
{SharedChatSystem.AdminPrefix, ChatSelectChannel.Admin},
{SharedChatSystem.RadioCommonPrefix, ChatSelectChannel.Radio},
{SharedChatSystem.DeadPrefix, ChatSelectChannel.Dead}
};
public static readonly Dictionary<ChatSelectChannel, char> ChannelPrefixes =
@@ -369,11 +361,6 @@ public sealed class ChatUIController : UIController
}
}
public static string GetChannelSelectorName(ChatSelectChannel channelSelector)
{
return channelSelector.ToString();
}
private void UpdateChannelPermissions()
{
CanSendChannels = default;
@@ -592,50 +579,88 @@ public sealed class ChatUIController : UIController
return channel;
}
public (ChatSelectChannel channel, ReadOnlyMemory<char> text) SplitInputContents(string inputText)
private bool TryGetRadioChannel(string text, out RadioChannelPrototype? radioChannel)
{
var text = inputText.AsMemory().Trim();
if (text.Length == 0)
return default;
radioChannel = null;
return _player.LocalPlayer?.ControlledEntity is EntityUid { Valid: true } uid
&& _chatSys != null
&& _chatSys.TryProccessRadioMessage(uid, text, out _, out radioChannel, quiet: true);
}
var prefixChar = text.Span[0];
var channel = PrefixToChannel.GetValueOrDefault(prefixChar);
public void UpdateSelectedChannel(ChatBox box)
{
var (prefixChannel, _, radioChannel) = SplitInputContents(box.ChatInput.Input.Text);
if ((CanSendChannels & channel) != 0)
// Cut off prefix if it's valid and we can use the channel in question.
text = text[1..];
if (prefixChannel == ChatSelectChannel.None)
box.ChatInput.ChannelSelector.UpdateChannelSelectButton(box.SelectedChannel, null);
else
channel = 0;
box.ChatInput.ChannelSelector.UpdateChannelSelectButton(prefixChannel, radioChannel);
}
channel = MapLocalIfGhost(channel);
public (ChatSelectChannel chatChannel, string text, RadioChannelPrototype? radioChannel) SplitInputContents(string text)
{
text = text.Trim();
if (text.Length == 0)
return (ChatSelectChannel.None, text, null);
// Trim from start again to cut out any whitespace between the prefix and message, if any.
return (channel, text.TrimStart());
// We only cut off prefix only if it is not a radio or local channel, which both map to the same /say command
// because ????????
ChatSelectChannel chatChannel;
if (TryGetRadioChannel(text, out var radioChannel))
chatChannel = ChatSelectChannel.Radio;
else
chatChannel = PrefixToChannel.GetValueOrDefault(text[0]);
if ((CanSendChannels & chatChannel) == 0)
return (ChatSelectChannel.None, text, null);
if (chatChannel == ChatSelectChannel.Radio)
return (chatChannel, text, radioChannel);
if (chatChannel == ChatSelectChannel.Local)
{
if (_ghost?.IsGhost != true)
return (chatChannel, text, null);
else
chatChannel = ChatSelectChannel.Dead;
}
return (chatChannel, text[1..].TrimStart(), null);
}
public void SendMessage(ChatBox box, ChatSelectChannel channel)
{
_typingIndicator?.ClientSubmittedChatText();
if (!string.IsNullOrWhiteSpace(box.ChatInput.Input.Text))
var text = box.ChatInput.Input.Text;
box.ChatInput.Input.Clear();
box.ChatInput.Input.ReleaseKeyboardFocus();
UpdateSelectedChannel(box);
if (string.IsNullOrWhiteSpace(text))
return;
(var prefixChannel, text, var _) = SplitInputContents(text);
// Check if message is longer than the character limit
if (text.Length > MaxMessageLength)
{
var (prefixChannel, text) = SplitInputContents(box.ChatInput.Input.Text);
// Check if message is longer than the character limit
if (text.Length > MaxMessageLength)
{
var locWarning = Loc.GetString("chat-manager-max-message-length",
("maxMessageLength", MaxMessageLength));
box.AddLine(locWarning, Color.Orange);
return;
}
_manager.SendMessage(text, prefixChannel == 0 ? channel : prefixChannel);
var locWarning = Loc.GetString("chat-manager-max-message-length",
("maxMessageLength", MaxMessageLength));
box.AddLine(locWarning, Color.Orange);
return;
}
box.ChatInput.Input.Clear();
box.UpdateSelectedChannel();
box.ChatInput.Input.ReleaseKeyboardFocus();
if (prefixChannel != ChatSelectChannel.None)
channel = prefixChannel;
else if (channel == ChatSelectChannel.Radio)
{
// radio must have prefix as it goes through the say command.
text = $";{text}";
}
_manager.SendMessage(text, prefixChannel == 0 ? channel : prefixChannel);
}
private void OnChatMessage(MsgChatMessage message) => ProcessChatMessage(message.Message);
@@ -687,11 +712,6 @@ public sealed class ChatUIController : UIController
}
}
public char GetPrefixFromChannel(ChatSelectChannel channel)
{
return ChannelPrefixes.GetValueOrDefault(channel);
}
public void RegisterChat(ChatBox chat)
{
_chats.Add(chat);

View File

@@ -1,4 +1,4 @@
using Content.Shared.Chat;
using Content.Shared.Chat;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using Robust.Shared.Input;
@@ -64,12 +64,10 @@ public sealed class ChannelSelectorButton : Button
if (SelectedChannel == channel) return;
SelectedChannel = channel;
UpdateChannelSelectButton(channel);
OnChannelSelect?.Invoke(channel);
}
public string ChannelSelectorName(ChatSelectChannel channel)
public static string ChannelSelectorName(ChatSelectChannel channel)
{
return Loc.GetString($"hud-chatbox-select-channel-{channel}");
}
@@ -87,10 +85,10 @@ public sealed class ChannelSelectorButton : Button
};
}
public void UpdateChannelSelectButton(ChatSelectChannel channel)
public void UpdateChannelSelectButton(ChatSelectChannel channel, Shared.Radio.RadioChannelPrototype? radio)
{
Text = ChannelSelectorName(channel);
Modulate = ChannelSelectColor(channel);
Text = radio != null ? Loc.GetString(radio.Name) : ChannelSelectorName(channel);
Modulate = radio?.Color ?? ChannelSelectColor(channel);
}
private void OnSelectorButtonToggled(ButtonToggledEventArgs args)

View File

@@ -1,4 +1,4 @@
using Content.Client.Stylesheets;
using Content.Client.Stylesheets;
using Content.Shared.Chat;
using Robust.Client.UserInterface.Controls;
@@ -14,8 +14,12 @@ public sealed class ChannelSelectorItemButton : Button
{
Channel = selector;
AddStyleClass(StyleNano.StyleClassChatChannelSelectorButton);
Text = ChatUIController.GetChannelSelectorName(selector);
Text = ChannelSelectorButton.ChannelSelectorName(selector);
var prefix = ChatUIController.ChannelPrefixes[selector];
if (prefix != default) Text = Loc.GetString("hud-chatbox-select-name-prefixed", ("name", Text), ("prefix", prefix));
if (prefix != default)
Text = Loc.GetString("hud-chatbox-select-name-prefixed", ("name", Text), ("prefix", prefix));
}
}

View File

@@ -1,4 +1,4 @@
using Content.Shared.Chat;
using Content.Shared.Chat;
using Robust.Client.UserInterface.Controls;
using static Robust.Client.UserInterface.Controls.BaseButton;
@@ -56,65 +56,6 @@ public sealed class ChannelSelectorPopup : Popup
}
}
/*public ChatSelectChannel NextChannel()
{
var nextChannel = ChatUIController.GetNextChannelSelector(_activeSelector);
var index = 0;
while (_selectorStates[(int)nextChannel].IsHidden && index <= _selectorStates.Count)
{
nextChannel = ChatUIController.GetNextChannelSelector(nextChannel);
index++;
}
_activeSelector = nextChannel;
return nextChannel;
}
private void SetupChannels(ChatUIController.ChannelSelectorSetup[] selectorData)
{
_channelSelectorHBox.DisposeAllChildren(); //cleanup old toggles
_selectorStates.Clear();
foreach (var channelSelectorData in selectorData)
{
var newSelectorButton = new ChannelSelectorItemButton(channelSelectorData);
_selectorStates.Add(newSelectorButton);
if (!newSelectorButton.IsHidden)
{
_channelSelectorHBox.AddChild(newSelectorButton);
}
newSelectorButton.OnPressed += OnSelectorPressed;
}
}
private void OnSelectorPressed(BaseButton.ButtonEventArgs args)
{
if (_selectorButton == null) return;
_selectorButton.SelectedChannel = ((ChannelSelectorItemButton) args.Button).Channel;
}
public void HideChannels(params ChatChannel[] channels)
{
foreach (var channel in channels)
{
if (!ChatUIController.ChannelToSelector.TryGetValue(channel, out var selector)) continue;
var selectorbutton = _selectorStates[(int)selector];
if (!selectorbutton.IsHidden)
{
_channelSelectorHBox.RemoveChild(selectorbutton);
if (_activeSelector != selector) continue; // do nothing
if (_channelSelectorHBox.Children.First() is ChannelSelectorItemButton button)
{
_activeSelector = button.Channel;
}
else
{
_activeSelector = ChatSelectChannel.None;
}
}
}
}
*/
private bool IsPreferredAvailable()
{
var preferred = _chatUIController.MapLocalIfGhost(_chatUIController.GetPreferredChannel());

View File

@@ -1,4 +1,4 @@
using Content.Client.Chat;
using Content.Client.Chat;
using Content.Client.Chat.TypingIndicator;
using Content.Client.UserInterface.Systems.Chat.Controls;
using Content.Shared.Chat;
@@ -11,6 +11,7 @@ using Robust.Shared.Audio;
using Robust.Shared.Input;
using Robust.Shared.Player;
using Robust.Shared.Utility;
using TerraFX.Interop.Windows;
using static Robust.Client.UserInterface.Controls.LineEdit;
namespace Content.Client.UserInterface.Systems.Chat.Widgets;
@@ -68,7 +69,7 @@ public partial class ChatBox : UIWidget
private void OnChannelSelect(ChatSelectChannel channel)
{
UpdateSelectedChannel();
_controller.UpdateSelectedChannel(this);
}
public void Repopulate()
@@ -105,49 +106,13 @@ public partial class ChatBox : UIWidget
Contents.AddMessage(formatted);
}
public void UpdateSelectedChannel()
{
var (prefixChannel, _) = _controller.SplitInputContents(ChatInput.Input.Text);
var channel = prefixChannel == 0 ? SelectedChannel : prefixChannel;
ChatInput.ChannelSelector.UpdateChannelSelectButton(channel);
}
public void Focus(ChatSelectChannel? channel = null)
{
var input = ChatInput.Input;
var selectStart = Index.End;
if (channel != null)
{
channel = _controller.MapLocalIfGhost(channel.Value);
// Channel not selectable, just do NOTHING (not even focus).
if ((_controller.SelectableChannels & channel.Value) == 0)
return;
var (_, text) = _controller.SplitInputContents(input.Text);
var newPrefix = _controller.GetPrefixFromChannel(channel.Value);
DebugTools.Assert(newPrefix != default, "Focus channel must have prefix!");
if (channel == SelectedChannel)
{
// New selected channel is just the selected channel,
// just remove prefix (if any) and leave text unchanged.
input.Text = text.ToString();
selectStart = Index.Start;
}
else
{
// Change prefix to new focused channel prefix and leave text unchanged.
input.Text = string.Concat(newPrefix.ToString(), " ", text.Span);
selectStart = Index.FromStart(2);
}
ChatInput.ChannelSelector.Select(channel.Value);
}
input.IgnoreNext = true;
input.GrabKeyboardFocus();
@@ -205,7 +170,7 @@ public partial class ChatBox : UIWidget
private void OnTextChanged(LineEditEventArgs args)
{
// Update channel select button to correct channel if we have a prefix.
UpdateSelectedChannel();
_controller.UpdateSelectedChannel(this);
// Warn typing indicator about change
_controller.NotifyChatTextChange();