Merge remote-tracking branch 'upstream/stable' into ed-23-06-2025-upstream-sync
# Conflicts: # .github/workflows/check-trailing-whitespace.yml # Content.IntegrationTests/Tests/Access/AccessReaderTest.cs # Content.IntegrationTests/Tests/Chameleon/ChameleonJobLoadoutTest.cs # Content.IntegrationTests/Tests/GameRules/NukeOpsTest.cs # Content.IntegrationTests/Tests/PostMapInitTest.cs # Content.Server/Administration/Systems/AdminVerbSystem.Antags.cs # Content.Shared/Light/Components/SunShadowCycleComponent.cs # Resources/Prototypes/Damage/modifier_sets.yml # Resources/Prototypes/Maps/Pools/default.yml
This commit is contained in:
@@ -14,12 +14,17 @@ namespace Content.Client.UserInterface.Systems.Chat;
|
||||
/// </summary>
|
||||
public sealed partial class ChatUIController : IOnSystemChanged<CharacterInfoSystem>
|
||||
{
|
||||
[Dependency] private readonly ILocalizationManager _loc = default!;
|
||||
[UISystemDependency] private readonly CharacterInfoSystem _characterInfo = default!;
|
||||
|
||||
private static readonly Regex StartDoubleQuote = new("\"$");
|
||||
private static readonly Regex EndDoubleQuote = new("^\"|(?<=^@)\"");
|
||||
private static readonly Regex StartAtSign = new("^@");
|
||||
|
||||
/// <summary>
|
||||
/// The list of words to be highlighted in the chatbox.
|
||||
/// </summary>
|
||||
private List<string> _highlights = new();
|
||||
private readonly List<string> _highlights = new();
|
||||
|
||||
/// <summary>
|
||||
/// The string holding the hex color used to highlight words.
|
||||
@@ -42,7 +47,7 @@ public sealed partial class ChatUIController : IOnSystemChanged<CharacterInfoSys
|
||||
_config.OnValueChanged(CCVars.ChatHighlightsColor, (value) => { _highlightsColor = value; }, true);
|
||||
|
||||
// Load highlights if any were saved.
|
||||
string highlights = _config.GetCVar(CCVars.ChatHighlights);
|
||||
var highlights = _config.GetCVar(CCVars.ChatHighlights);
|
||||
|
||||
if (!string.IsNullOrEmpty(highlights))
|
||||
{
|
||||
@@ -84,12 +89,12 @@ public sealed partial class ChatUIController : IOnSystemChanged<CharacterInfoSys
|
||||
|
||||
// We first subdivide the highlights based on newlines to prevent replacing
|
||||
// a valid "\n" tag and adding it to the final regex.
|
||||
string[] splittedHighlights = newHighlights.Split('\n', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
|
||||
var splittedHighlights = newHighlights.Split('\n', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
|
||||
|
||||
for (int i = 0; i < splittedHighlights.Length; i++)
|
||||
for (var i = 0; i < splittedHighlights.Length; i++)
|
||||
{
|
||||
// Replace every "\" character with a "\\" to prevent "\n", "\0", etc...
|
||||
string keyword = splittedHighlights[i].Replace(@"\", @"\\");
|
||||
var keyword = splittedHighlights[i].Replace(@"\", @"\\");
|
||||
|
||||
// Escape the keyword to prevent special characters like "(" and ")" to be considered valid regex.
|
||||
keyword = Regex.Escape(keyword);
|
||||
@@ -102,17 +107,17 @@ public sealed partial class ChatUIController : IOnSystemChanged<CharacterInfoSys
|
||||
// that make sure the words to match are separated by spaces or punctuation.
|
||||
// NOTE: The reason why we don't use \b tags is that \b doesn't match reverse slash characters "\" so
|
||||
// a pre-sanitized (see 1.) string like "\[test]" wouldn't get picked up by the \b.
|
||||
if (keyword.Count(c => (c == '"')) > 0)
|
||||
if (keyword.Any(c => c == '"'))
|
||||
{
|
||||
// Matches the last double quote character.
|
||||
keyword = Regex.Replace(keyword, "\"$", "(?!\\w)");
|
||||
keyword = StartDoubleQuote.Replace(keyword, "(?!\\w)");
|
||||
// When matching for the first double quote character we also consider the possibility
|
||||
// of the double quote being preceded by a @ character.
|
||||
keyword = Regex.Replace(keyword, "^\"|(?<=^@)\"", "(?<!\\w)");
|
||||
keyword = EndDoubleQuote.Replace(keyword, "(?<!\\w)");
|
||||
}
|
||||
|
||||
// Make sure any name tagged as ours gets highlighted only when others say it.
|
||||
keyword = Regex.Replace(keyword, "^@", "(?<=(?<=/name.*)|(?<=,.*\"\".*))");
|
||||
keyword = StartAtSign.Replace(keyword, "(?<=(?<=/name.*)|(?<=,.*\"\".*))");
|
||||
|
||||
_highlights.Add(keyword);
|
||||
}
|
||||
@@ -132,7 +137,7 @@ public sealed partial class ChatUIController : IOnSystemChanged<CharacterInfoSys
|
||||
var (_, job, _, _, entityName) = data;
|
||||
|
||||
// Mark this entity's name as our character name for the "UpdateHighlights" function.
|
||||
string newHighlights = "@" + entityName;
|
||||
var newHighlights = "@" + entityName;
|
||||
|
||||
// Subdivide the character's name based on spaces or hyphens so that every word gets highlighted.
|
||||
if (newHighlights.Count(c => (c == ' ' || c == '-')) == 1)
|
||||
@@ -144,9 +149,9 @@ public sealed partial class ChatUIController : IOnSystemChanged<CharacterInfoSys
|
||||
newHighlights = newHighlights.Split('-')[0] + "\n@" + newHighlights.Split('-')[^1];
|
||||
|
||||
// Convert the job title to kebab-case and use it as a key for the loc file.
|
||||
string jobKey = job.Replace(' ', '-').ToLower();
|
||||
var jobKey = job.Replace(' ', '-').ToLower();
|
||||
|
||||
if (Loc.TryGetString($"highlights-{jobKey}", out var jobMatches))
|
||||
if (_loc.TryGetString($"highlights-{jobKey}", out var jobMatches))
|
||||
newHighlights += '\n' + jobMatches.Replace(", ", "\n");
|
||||
|
||||
UpdateHighlights(newHighlights);
|
||||
|
||||
@@ -19,8 +19,11 @@ namespace Content.Client.UserInterface.Systems.Chat.Widgets;
|
||||
[Virtual]
|
||||
public partial class ChatBox : UIWidget
|
||||
{
|
||||
[Dependency] private readonly IEntityManager _entManager = default!;
|
||||
[Dependency] private readonly ILogManager _log = default!;
|
||||
|
||||
private readonly ISawmill _sawmill;
|
||||
private readonly ChatUIController _controller;
|
||||
private readonly IEntityManager _entManager;
|
||||
|
||||
public bool Main { get; set; }
|
||||
|
||||
@@ -29,7 +32,7 @@ public partial class ChatBox : UIWidget
|
||||
public ChatBox()
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
_entManager = IoCManager.Resolve<IEntityManager>();
|
||||
_sawmill = _log.GetSawmill("chat");
|
||||
|
||||
ChatInput.Input.OnTextEntered += OnTextEntered;
|
||||
ChatInput.Input.OnKeyBindDown += OnInputKeyBindDown;
|
||||
@@ -52,7 +55,7 @@ public partial class ChatBox : UIWidget
|
||||
|
||||
private void OnMessageAdded(ChatMessage msg)
|
||||
{
|
||||
Logger.DebugS("chat", $"{msg.Channel}: {msg.Message}");
|
||||
_sawmill.Debug($"{msg.Channel}: {msg.Message}");
|
||||
if (!ChatInput.FilterButton.Popup.IsActive(msg.Channel))
|
||||
{
|
||||
return;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using Content.Client.Eui;
|
||||
using Content.Server.Ghost.Roles.Raffles;
|
||||
using Content.Shared.Eui;
|
||||
using Content.Shared.Ghost.Roles;
|
||||
using Content.Shared.Ghost.Roles.Raffles;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Client.Console;
|
||||
using Robust.Client.Player;
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using Content.Server.Ghost.Roles.Raffles;
|
||||
using System.Numerics;
|
||||
using Content.Shared.Ghost.Roles.Raffles;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
|
||||
@@ -225,6 +225,10 @@ public sealed class StorageUIController : UIController, IOnSystemChanged<Storage
|
||||
if (!IsDragging && EntityManager.System<HandsSystem>().GetActiveHandEntity() == null)
|
||||
return;
|
||||
|
||||
// Do not rotate items unless we are either dragging them or hovering over a storage window.
|
||||
if (DraggingGhost is null && UIManager.CurrentlyHovered is not StorageWindow)
|
||||
return;
|
||||
|
||||
//clamp it to a cardinal.
|
||||
DraggingRotation = (DraggingRotation + Math.PI / 2f).GetCardinalDir().ToAngle();
|
||||
if (DraggingGhost != null)
|
||||
|
||||
Reference in New Issue
Block a user