Admin alerts now link players with tpto (#40472)
* Admin alerts now link players with tpto * Add coords * Slarti tweaks! * He saw my minor spelling mistake - its over...
This commit is contained in:
@@ -31,6 +31,11 @@ internal sealed class ChatManager : IChatManager
|
||||
// See server-side manager. This just exists for shared code.
|
||||
}
|
||||
|
||||
public void SendAdminAlertNoFormatOrEscape(string message)
|
||||
{
|
||||
// See server-side manager. This just exists for shared code.
|
||||
}
|
||||
|
||||
public void SendMessage(string text, ChatSelectChannel channel)
|
||||
{
|
||||
var str = text.ToString();
|
||||
|
||||
@@ -12,13 +12,16 @@ using Content.Shared.Database;
|
||||
using Content.Shared.Mind;
|
||||
using Content.Shared.Players.PlayTimeTracking;
|
||||
using Prometheus;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared;
|
||||
using Robust.Shared.Configuration;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Network;
|
||||
using Robust.Shared.Player;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Reflection;
|
||||
using Robust.Shared.Timing;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Server.Administration.Logs;
|
||||
|
||||
@@ -338,7 +341,7 @@ public sealed partial class AdminLogManager : SharedAdminLogManager, IAdminLogMa
|
||||
Players = players,
|
||||
};
|
||||
|
||||
DoAdminAlerts(players, message, impact);
|
||||
DoAdminAlerts(players, message, impact, handler);
|
||||
|
||||
if (preRound)
|
||||
{
|
||||
@@ -380,6 +383,34 @@ public sealed partial class AdminLogManager : SharedAdminLogManager, IAdminLogMa
|
||||
return players;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a list of coordinates from the <see cref="LogStringHandler"/>s values. Will transform all coordinate types
|
||||
/// to map coordinates!
|
||||
/// </summary>
|
||||
/// <returns>A list of map coordinates that were found in the value input, can return an empty list.</returns>
|
||||
private List<MapCoordinates> GetCoordinates(Dictionary<string, object?> values)
|
||||
{
|
||||
List<MapCoordinates> coordList = new();
|
||||
EntityManager.TrySystem(out TransformSystem? transform);
|
||||
|
||||
foreach (var value in values.Values)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case EntityCoordinates entCords:
|
||||
if (transform != null)
|
||||
coordList.Add(transform.ToMapCoordinates(entCords));
|
||||
continue;
|
||||
|
||||
case MapCoordinates mapCord:
|
||||
coordList.Add(mapCord);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return coordList;
|
||||
}
|
||||
|
||||
private void AddPlayer(List<AdminLogPlayer> players, Guid user, int logId)
|
||||
{
|
||||
// The majority of logs have a single player, or maybe two. Instead of allocating a List<AdminLogPlayer> and
|
||||
@@ -397,10 +428,11 @@ public sealed partial class AdminLogManager : SharedAdminLogManager, IAdminLogMa
|
||||
});
|
||||
}
|
||||
|
||||
private void DoAdminAlerts(List<AdminLogPlayer> players, string message, LogImpact impact)
|
||||
private void DoAdminAlerts(List<AdminLogPlayer> players, string message, LogImpact impact, LogStringHandler handler)
|
||||
{
|
||||
var adminLog = false;
|
||||
var logMessage = message;
|
||||
var playerNetEnts = new List<(NetEntity, string)>();
|
||||
|
||||
foreach (var player in players)
|
||||
{
|
||||
@@ -419,6 +451,8 @@ public sealed partial class AdminLogManager : SharedAdminLogManager, IAdminLogMa
|
||||
("name", cachedInfo.CharacterName),
|
||||
("subtype", subtype));
|
||||
}
|
||||
if (cachedInfo != null && cachedInfo.NetEntity != null)
|
||||
playerNetEnts.Add((cachedInfo.NetEntity.Value, cachedInfo.CharacterName));
|
||||
}
|
||||
|
||||
if (adminLog)
|
||||
@@ -442,7 +476,73 @@ public sealed partial class AdminLogManager : SharedAdminLogManager, IAdminLogMa
|
||||
}
|
||||
|
||||
if (adminLog)
|
||||
{
|
||||
_chat.SendAdminAlert(logMessage);
|
||||
|
||||
if (CreateTpLinks(playerNetEnts, out var tpLinks))
|
||||
_chat.SendAdminAlertNoFormatOrEscape(tpLinks);
|
||||
|
||||
var coords = GetCoordinates(handler.Values);
|
||||
|
||||
if (CreateCordLinks(coords, out var cordLinks))
|
||||
_chat.SendAdminAlertNoFormatOrEscape(cordLinks);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a list of tpto command links of the given players
|
||||
/// </summary>
|
||||
private bool CreateTpLinks(List<(NetEntity NetEnt, string CharacterName)> players, out string outString)
|
||||
{
|
||||
outString = string.Empty;
|
||||
|
||||
if (players.Count == 0)
|
||||
return false;
|
||||
|
||||
outString = Loc.GetString("admin-alert-tp-to-players-header");
|
||||
|
||||
for (var i = 0; i < players.Count; i++)
|
||||
{
|
||||
var player = players[i];
|
||||
outString += $"[cmdlink=\"{EscapeText(player.CharacterName)}\" command=\"tpto {player.NetEnt}\"/]";
|
||||
|
||||
if (i < players.Count - 1)
|
||||
outString += ", ";
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a list of toto command links for the given map coordinates.
|
||||
/// </summary>
|
||||
private bool CreateCordLinks(List<MapCoordinates> cords, out string outString)
|
||||
{
|
||||
outString = string.Empty;
|
||||
|
||||
if (cords.Count == 0)
|
||||
return false;
|
||||
|
||||
outString = Loc.GetString("admin-alert-tp-to-coords-header");
|
||||
|
||||
for (var i = 0; i < cords.Count; i++)
|
||||
{
|
||||
var cord = cords[i];
|
||||
outString += $"[cmdlink=\"{cord.ToString()}\" command=\"tp {cord.X} {cord.Y} {cord.MapId}\"/]";
|
||||
|
||||
if (i < cords.Count - 1)
|
||||
outString += ", ";
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Escape the given text to not allow breakouts of the cmdlink tags.
|
||||
/// </summary>
|
||||
private string EscapeText(string text)
|
||||
{
|
||||
return FormattedMessage.EscapeText(text).Replace("\"", "\\\"").Replace("'", "\\'");
|
||||
}
|
||||
|
||||
public async Task<List<SharedAdminLog>> All(LogFilter? filter = null, Func<List<SharedAdminLog>>? listProvider = null)
|
||||
|
||||
@@ -160,14 +160,20 @@ internal sealed partial class ChatManager : IChatManager
|
||||
|
||||
public void SendAdminAlert(string message)
|
||||
{
|
||||
var clients = _adminManager.ActiveAdmins.Select(p => p.Channel);
|
||||
|
||||
var wrappedMessage = Loc.GetString("chat-manager-send-admin-announcement-wrap-message",
|
||||
("adminChannelName", Loc.GetString("chat-manager-admin-channel-name")), ("message", FormattedMessage.EscapeText(message)));
|
||||
|
||||
ChatMessageToMany(ChatChannel.AdminAlert, message, wrappedMessage, default, false, true, clients);
|
||||
SendAdminAlertNoFormatOrEscape(wrappedMessage);
|
||||
}
|
||||
|
||||
public void SendAdminAlertNoFormatOrEscape(string message)
|
||||
{
|
||||
var clients = _adminManager.ActiveAdmins.Select(p => p.Channel);
|
||||
|
||||
ChatMessageToMany(ChatChannel.AdminAlert, message, message, default, false, true, clients);
|
||||
}
|
||||
|
||||
|
||||
public void SendAdminAlert(EntityUid player, string message)
|
||||
{
|
||||
var mindSystem = _entityManager.System<SharedMindSystem>();
|
||||
|
||||
@@ -256,11 +256,14 @@ public sealed partial class ExplosionSystem : SharedExplosionSystem
|
||||
var logImpact = (alertMinExplosionIntensity > -1 && totalIntensity >= alertMinExplosionIntensity)
|
||||
? LogImpact.Extreme
|
||||
: LogImpact.High;
|
||||
_adminLogger.Add(LogType.Explosion, logImpact,
|
||||
$"{ToPrettyString(user.Value):user} caused {ToPrettyString(uid):entity} to explode ({typeId}) at Pos:{(posFound ? $"{gridPos:coordinates}" : "[Grid or Map not found]")} with intensity {totalIntensity} slope {slope}");
|
||||
if (posFound)
|
||||
_adminLogger.Add(LogType.Explosion, logImpact, $"{ToPrettyString(user.Value):user} caused {ToPrettyString(uid):entity} to explode ({typeId}) at Pos:{gridPos:coordinates} with intensity {totalIntensity} slope {slope}");
|
||||
else
|
||||
_adminLogger.Add(LogType.Explosion, logImpact, $"{ToPrettyString(user.Value):user} caused {ToPrettyString(uid):entity} to explode ({typeId}) at Pos:[Grid or Map not found] with intensity {totalIntensity} slope {slope}");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Queue an explosion, with a specified epicenter and set of starting tiles.
|
||||
/// </summary>
|
||||
|
||||
@@ -3,6 +3,28 @@ namespace Content.Shared.Chat;
|
||||
public interface ISharedChatManager
|
||||
{
|
||||
void Initialize();
|
||||
|
||||
/// <summary>
|
||||
/// Send an admin alert to the admin chat channel.
|
||||
/// </summary>
|
||||
/// <param name="message">The message to send.</param>
|
||||
void SendAdminAlert(string message);
|
||||
|
||||
/// <summary>
|
||||
/// Send an admin alert to the admin chat channel specifically about the given player.
|
||||
/// Will include info extra like their antag status and name.
|
||||
/// </summary>
|
||||
/// <param name="player">The player that the message is about.</param>
|
||||
/// <param name="message">The message to send.</param>
|
||||
void SendAdminAlert(EntityUid player, string message);
|
||||
|
||||
/// <summary>
|
||||
/// This is a dangerous function! Only pass in property escaped text.
|
||||
/// See: <see cref="SendAdminAlert(string)"/>
|
||||
/// <br/><br/>
|
||||
/// Use this for things that need to be unformatted (like tpto links) but ensure that everything else
|
||||
/// is formated properly. If it's not, players could sneak in ban links or other nasty commands that the admins
|
||||
/// could clink on.
|
||||
/// </summary>
|
||||
void SendAdminAlertNoFormatOrEscape(string message);
|
||||
}
|
||||
|
||||
@@ -2,3 +2,5 @@
|
||||
admin-alert-ipintel-blocked = {$player} was rejected from joining due to their IP having a {TOSTRING($percent, "P2")} confidence of being a VPN/Datacenter.
|
||||
admin-alert-ipintel-warning = {$player} IP has a {TOSTRING($percent, "P2")} confidence of being a VPN/Datacenter. Please watch them.
|
||||
admin-alert-antag-label = {$message} [ANTAG: {$name}, {$subtype}]
|
||||
admin-alert-tp-to-players-header = Players:{" "}
|
||||
admin-alert-tp-to-coords-header = Coords:{" "}
|
||||
|
||||
Reference in New Issue
Block a user