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.
|
// 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)
|
public void SendMessage(string text, ChatSelectChannel channel)
|
||||||
{
|
{
|
||||||
var str = text.ToString();
|
var str = text.ToString();
|
||||||
|
|||||||
@@ -12,13 +12,16 @@ using Content.Shared.Database;
|
|||||||
using Content.Shared.Mind;
|
using Content.Shared.Mind;
|
||||||
using Content.Shared.Players.PlayTimeTracking;
|
using Content.Shared.Players.PlayTimeTracking;
|
||||||
using Prometheus;
|
using Prometheus;
|
||||||
|
using Robust.Server.GameObjects;
|
||||||
using Robust.Shared;
|
using Robust.Shared;
|
||||||
using Robust.Shared.Configuration;
|
using Robust.Shared.Configuration;
|
||||||
|
using Robust.Shared.Map;
|
||||||
using Robust.Shared.Network;
|
using Robust.Shared.Network;
|
||||||
using Robust.Shared.Player;
|
using Robust.Shared.Player;
|
||||||
using Robust.Shared.Prototypes;
|
using Robust.Shared.Prototypes;
|
||||||
using Robust.Shared.Reflection;
|
using Robust.Shared.Reflection;
|
||||||
using Robust.Shared.Timing;
|
using Robust.Shared.Timing;
|
||||||
|
using Robust.Shared.Utility;
|
||||||
|
|
||||||
namespace Content.Server.Administration.Logs;
|
namespace Content.Server.Administration.Logs;
|
||||||
|
|
||||||
@@ -338,7 +341,7 @@ public sealed partial class AdminLogManager : SharedAdminLogManager, IAdminLogMa
|
|||||||
Players = players,
|
Players = players,
|
||||||
};
|
};
|
||||||
|
|
||||||
DoAdminAlerts(players, message, impact);
|
DoAdminAlerts(players, message, impact, handler);
|
||||||
|
|
||||||
if (preRound)
|
if (preRound)
|
||||||
{
|
{
|
||||||
@@ -380,6 +383,34 @@ public sealed partial class AdminLogManager : SharedAdminLogManager, IAdminLogMa
|
|||||||
return players;
|
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)
|
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
|
// 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 adminLog = false;
|
||||||
var logMessage = message;
|
var logMessage = message;
|
||||||
|
var playerNetEnts = new List<(NetEntity, string)>();
|
||||||
|
|
||||||
foreach (var player in players)
|
foreach (var player in players)
|
||||||
{
|
{
|
||||||
@@ -419,6 +451,8 @@ public sealed partial class AdminLogManager : SharedAdminLogManager, IAdminLogMa
|
|||||||
("name", cachedInfo.CharacterName),
|
("name", cachedInfo.CharacterName),
|
||||||
("subtype", subtype));
|
("subtype", subtype));
|
||||||
}
|
}
|
||||||
|
if (cachedInfo != null && cachedInfo.NetEntity != null)
|
||||||
|
playerNetEnts.Add((cachedInfo.NetEntity.Value, cachedInfo.CharacterName));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (adminLog)
|
if (adminLog)
|
||||||
@@ -442,7 +476,73 @@ public sealed partial class AdminLogManager : SharedAdminLogManager, IAdminLogMa
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (adminLog)
|
if (adminLog)
|
||||||
|
{
|
||||||
_chat.SendAdminAlert(logMessage);
|
_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)
|
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)
|
public void SendAdminAlert(string message)
|
||||||
{
|
{
|
||||||
var clients = _adminManager.ActiveAdmins.Select(p => p.Channel);
|
|
||||||
|
|
||||||
var wrappedMessage = Loc.GetString("chat-manager-send-admin-announcement-wrap-message",
|
var wrappedMessage = Loc.GetString("chat-manager-send-admin-announcement-wrap-message",
|
||||||
("adminChannelName", Loc.GetString("chat-manager-admin-channel-name")), ("message", FormattedMessage.EscapeText(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)
|
public void SendAdminAlert(EntityUid player, string message)
|
||||||
{
|
{
|
||||||
var mindSystem = _entityManager.System<SharedMindSystem>();
|
var mindSystem = _entityManager.System<SharedMindSystem>();
|
||||||
|
|||||||
@@ -256,11 +256,14 @@ public sealed partial class ExplosionSystem : SharedExplosionSystem
|
|||||||
var logImpact = (alertMinExplosionIntensity > -1 && totalIntensity >= alertMinExplosionIntensity)
|
var logImpact = (alertMinExplosionIntensity > -1 && totalIntensity >= alertMinExplosionIntensity)
|
||||||
? LogImpact.Extreme
|
? LogImpact.Extreme
|
||||||
: LogImpact.High;
|
: LogImpact.High;
|
||||||
_adminLogger.Add(LogType.Explosion, logImpact,
|
if (posFound)
|
||||||
$"{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}");
|
_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>
|
/// <summary>
|
||||||
/// Queue an explosion, with a specified epicenter and set of starting tiles.
|
/// Queue an explosion, with a specified epicenter and set of starting tiles.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -3,6 +3,28 @@ namespace Content.Shared.Chat;
|
|||||||
public interface ISharedChatManager
|
public interface ISharedChatManager
|
||||||
{
|
{
|
||||||
void Initialize();
|
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);
|
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);
|
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-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-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-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