Update radio prefix parsing (#13777)
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user