Add admin Erase verb, add checkbox to erase from the ban panel (#20985)

This commit is contained in:
DrSmugleaf
2023-10-14 02:02:56 -07:00
committed by GitHub
parent 3a2482420f
commit 5be0df32ad
22 changed files with 297 additions and 57 deletions

View File

@@ -2,22 +2,29 @@ using System.Collections.Immutable;
using System.Net;
using System.Net.Sockets;
using Content.Server.Administration.Managers;
using Content.Server.Administration.Systems;
using Content.Server.Chat.Managers;
using Content.Server.EUI;
using Content.Shared.Administration;
using Content.Shared.Database;
using Content.Shared.Eui;
using Robust.Server.Player;
using Robust.Shared.Network;
namespace Content.Server.Administration;
public sealed class BanPanelEui : BaseEui
public sealed class BanPanelEui : BaseEui, IPostInjectInit
{
[Dependency] private readonly IBanManager _banManager = default!;
[Dependency] private readonly IEntityManager _entities = default!;
[Dependency] private readonly ILogManager _log = default!;
[Dependency] private readonly IPlayerLocator _playerLocator = default!;
[Dependency] private readonly IPlayerManager _playerManager = default!;
[Dependency] private readonly IChatManager _chat = default!;
[Dependency] private readonly IAdminManager _admins = default!;
private ISawmill _sawmill = default!;
private NetUserId? PlayerId { get; set; }
private string PlayerName { get; set; } = string.Empty;
private IPAddress? LastAddress { get; set; }
@@ -41,7 +48,7 @@ public sealed class BanPanelEui : BaseEui
switch (msg)
{
case BanPanelEuiStateMsg.CreateBanRequest r:
BanPlayer(r.Player, r.IpAddress, r.UseLastIp, r.Hwid?.ToImmutableArray(), r.UseLastHwid, r.Minutes, r.Severity, r.Reason, r.Roles);
BanPlayer(r.Player, r.IpAddress, r.UseLastIp, r.Hwid?.ToImmutableArray(), r.UseLastHwid, r.Minutes, r.Severity, r.Reason, r.Roles, r.Erase);
break;
case BanPanelEuiStateMsg.GetPlayerInfoRequest r:
ChangePlayer(r.PlayerUsername);
@@ -49,11 +56,11 @@ public sealed class BanPanelEui : BaseEui
}
}
private async void BanPlayer(string? target, string? ipAddressString, bool useLastIp, ImmutableArray<byte>? hwid, bool useLastHwid, uint minutes, NoteSeverity severity, string reason, IReadOnlyCollection<string>? roles)
private async void BanPlayer(string? target, string? ipAddressString, bool useLastIp, ImmutableArray<byte>? hwid, bool useLastHwid, uint minutes, NoteSeverity severity, string reason, IReadOnlyCollection<string>? roles, bool erase)
{
if (!_admins.HasAdminFlag(Player, AdminFlags.Ban))
{
Logger.WarningS("admin.bans_eui", $"{Player.Name} ({Player.UserId}) tried to create a ban with no ban flag");
_sawmill.Warning($"{Player.Name} ({Player.UserId}) tried to create a ban with no ban flag");
return;
}
if (target == null && string.IsNullOrWhiteSpace(ipAddressString) && hwid == null)
@@ -120,7 +127,23 @@ public sealed class BanPanelEui : BaseEui
return;
}
if (erase &&
targetUid != null &&
_playerManager.TryGetSessionById(targetUid.Value, out var targetPlayer))
{
try
{
if (_entities.TrySystem(out AdminSystem? adminSystem))
adminSystem.Erase(targetPlayer);
}
catch (Exception e)
{
_sawmill.Error($"Error while erasing banned player:\n{e}");
}
}
_banManager.CreateServerBan(targetUid, target, Player.UserId, addressRange, targetHWid, minutes, severity, reason);
Close();
}
@@ -160,4 +183,9 @@ public sealed class BanPanelEui : BaseEui
StateDirty();
}
public void PostInject()
{
_sawmill = _log.GetSawmill("admin.bans_eui");
}
}

View File

@@ -1,17 +1,28 @@
using System.Linq;
using Content.Server.Administration.Managers;
using Content.Server.Chat.Managers;
using Content.Server.Forensics;
using Content.Server.GameTicking;
using Content.Server.Hands.Systems;
using Content.Server.IdentityManagement;
using Content.Server.Mind;
using Content.Server.Players.PlayTimeTracking;
using Content.Server.Popups;
using Content.Server.StationRecords.Systems;
using Content.Shared.Administration;
using Content.Shared.Administration.Events;
using Content.Shared.CCVar;
using Content.Shared.GameTicking;
using Content.Shared.Hands.Components;
using Content.Shared.IdentityManagement;
using Content.Shared.Inventory;
using Content.Shared.PDA;
using Content.Shared.Players.PlayTimeTracking;
using Content.Shared.Popups;
using Content.Shared.Roles;
using Content.Shared.Roles.Jobs;
using Content.Shared.StationRecords;
using Content.Shared.Throwing;
using Robust.Server.GameObjects;
using Robust.Server.Player;
using Robust.Shared.Configuration;
@@ -27,10 +38,17 @@ namespace Content.Server.Administration.Systems
[Dependency] private readonly IChatManager _chat = default!;
[Dependency] private readonly IConfigurationManager _config = default!;
[Dependency] private readonly IPlayerManager _playerManager = default!;
[Dependency] private readonly PlayTimeTrackingManager _playTime = default!;
[Dependency] private readonly HandsSystem _hands = default!;
[Dependency] private readonly SharedJobSystem _jobs = default!;
[Dependency] private readonly InventorySystem _inventory = default!;
[Dependency] private readonly MindSystem _minds = default!;
[Dependency] private readonly PopupSystem _popup = default!;
[Dependency] private readonly PhysicsSystem _physics = default!;
[Dependency] private readonly PlayTimeTrackingManager _playTime = default!;
[Dependency] private readonly SharedRoleSystem _role = default!;
[Dependency] private readonly GameTicker _gameTicker = default!;
[Dependency] private readonly StationRecordsSystem _stationRecords = default!;
[Dependency] private readonly TransformSystem _transform = default!;
private readonly Dictionary<NetUserId, PlayerInfo> _playerList = new();
@@ -299,5 +317,76 @@ namespace Content.Server.Administration.Systems
RaiseNetworkEvent(ev, admin);
}
}
/// <summary>
/// Erases a player from the round.
/// This removes them and any trace of them from the round, deleting their
/// chat messages and showing a popup to other players.
/// Their items are dropped on the ground.
/// </summary>
public void Erase(IPlayerSession player)
{
var entity = player.AttachedEntity;
_chat.DeleteMessagesBy(player);
if (entity != null && !TerminatingOrDeleted(entity.Value))
{
if (TryComp(entity.Value, out TransformComponent? transform))
{
var coordinates = _transform.GetMoverCoordinates(entity.Value, transform);
var name = Identity.Entity(entity.Value, EntityManager);
_popup.PopupCoordinates(Loc.GetString("admin-erase-popup", ("user", name)), coordinates, PopupType.LargeCaution);
}
foreach (var item in _inventory.GetHandOrInventoryEntities(entity.Value))
{
if (TryComp(item, out PdaComponent? pda) &&
TryComp(pda.ContainedId, out StationRecordKeyStorageComponent? keyStorage) &&
keyStorage.Key is { } key &&
_stationRecords.TryGetRecord(key.OriginStation, key, out GeneralStationRecord? record))
{
if (TryComp(entity, out DnaComponent? dna) &&
dna.DNA != record.DNA)
{
continue;
}
if (TryComp(entity, out FingerprintComponent? fingerPrint) &&
fingerPrint.Fingerprint != record.Fingerprint)
{
continue;
}
_stationRecords.RemoveRecord(key.OriginStation, key);
Del(item);
}
}
if (TryComp(entity.Value, out InventoryComponent? inventory) &&
_inventory.TryGetSlots(entity.Value, out var slots, inventory))
{
foreach (var slot in slots)
{
if (_inventory.TryUnequip(entity.Value, entity.Value, slot.Name, out var item, true, true))
{
_physics.ApplyAngularImpulse(item.Value, ThrowingSystem.ThrowAngularImpulse);
}
}
}
if (TryComp(entity.Value, out HandsComponent? hands))
{
foreach (var hand in _hands.EnumerateHands(entity.Value, hands))
{
_hands.TryDrop(entity.Value, hand, checkActionBlocker: false, doDropInteraction: false, handsComp: hands);
}
}
}
_minds.WipeMind(player);
QueueDel(entity);
_gameTicker.SpawnObserver(player);
}
}
}

View File

@@ -48,6 +48,7 @@ namespace Content.Server.Administration.Systems
[Dependency] private readonly IGameTiming _gameTiming = default!;
[Dependency] private readonly IMapManager _mapManager = default!;
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly AdminSystem _adminSystem = default!;
[Dependency] private readonly DisposalTubeSystem _disposalTubes = default!;
[Dependency] private readonly EuiManager _euiManager = default!;
[Dependency] private readonly GhostRoleSystem _ghostRoleSystem = default!;
@@ -140,6 +141,20 @@ namespace Content.Server.Administration.Systems
},
Impact = LogImpact.Medium,
});
// Erase
args.Verbs.Add(new Verb
{
Text = Loc.GetString("admin-verbs-erase"),
Category = VerbCategory.Admin,
Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/VerbIcons/delete_transparent.svg.192dpi.png")),
Act = () =>
{
_adminSystem.Erase(targetActor.PlayerSession);
},
Impact = LogImpact.Extreme,
ConfirmationPopup = true
});
}
// Admin Logs

View File

@@ -1,4 +1,5 @@
using System.Linq;
using System.Runtime.InteropServices;
using Content.Server.Administration.Logs;
using Content.Server.Administration.Managers;
using Content.Server.Administration.Systems;
@@ -50,9 +51,13 @@ namespace Content.Server.Chat.Managers
private bool _oocEnabled = true;
private bool _adminOocEnabled = true;
public Dictionary<IPlayerSession, int> SenderKeys { get; } = new();
public Dictionary<IPlayerSession, HashSet<NetEntity>> SenderEntities { get; } = new();
public void Initialize()
{
_netManager.RegisterNetMessage<MsgChatMessage>();
_netManager.RegisterNetMessage<MsgDeleteChatMessagesBy>();
_configurationManager.OnValueChanged(CCVars.OocEnabled, OnOocEnabledChanged, true);
_configurationManager.OnValueChanged(CCVars.AdminOocEnabled, OnAdminOocEnabledChanged, true);
@@ -74,6 +79,15 @@ namespace Content.Server.Chat.Managers
DispatchServerAnnouncement(Loc.GetString(val ? "chat-manager-admin-ooc-chat-enabled-message" : "chat-manager-admin-ooc-chat-disabled-message"));
}
public void DeleteMessagesBy(IPlayerSession player)
{
var key = SenderKeys.GetValueOrDefault(player);
var entities = SenderEntities.GetValueOrDefault(player) ?? new HashSet<NetEntity>();
var msg = new MsgDeleteChatMessagesBy { Key = key, Entities = entities };
_netManager.ServerSendToAll(msg);
}
#region Server Announcements
public void DispatchServerAnnouncement(string message, Color? colorOverride = null)
@@ -202,8 +216,12 @@ namespace Content.Server.Chat.Managers
wrappedMessage = Loc.GetString("chat-manager-send-ooc-patron-wrap-message", ("patronColor", patronColor),("playerName", player.Name), ("message", FormattedMessage.EscapeText(message)));
}
ref var key = ref CollectionsMarshal.GetValueRefOrAddDefault(SenderKeys, player, out var exists);
if (!exists)
key = SenderKeys.Count;
//TODO: player.Name color, this will need to change the structure of the MsgChatMessage
ChatMessageToAll(ChatChannel.OOC, message, wrappedMessage, EntityUid.Invalid, hideChat: false, recordReplay: true, colorOverride);
ChatMessageToAll(ChatChannel.OOC, message, wrappedMessage, EntityUid.Invalid, hideChat: false, recordReplay: true, colorOverride: colorOverride, senderKey: key);
_mommiLink.SendOOCMessage(player.Name, message);
_adminLogger.Add(LogType.Chat, LogImpact.Low, $"OOC from {player:Player}: {message}");
}
@@ -220,6 +238,11 @@ namespace Content.Server.Chat.Managers
var wrappedMessage = Loc.GetString("chat-manager-send-admin-chat-wrap-message",
("adminChannelName", Loc.GetString("chat-manager-admin-channel-name")),
("playerName", player.Name), ("message", FormattedMessage.EscapeText(message)));
ref var key = ref CollectionsMarshal.GetValueRefOrAddDefault(SenderKeys, player, out var exists);
if (!exists)
key = SenderKeys.Count;
foreach (var client in clients)
{
var isSource = client != player.ConnectedClient;
@@ -230,7 +253,7 @@ namespace Content.Server.Chat.Managers
false,
client,
audioPath: isSource ? _netConfigManager.GetClientCVar(client, CCVars.AdminChatSoundPath) : default,
audioVolume: isSource ? _netConfigManager.GetClientCVar(client, CCVars.AdminChatSoundVolume) : default);
audioVolume: isSource ? _netConfigManager.GetClientCVar(client, CCVars.AdminChatSoundVolume) : default, senderKey: key);
}
_adminLogger.Add(LogType.Chat, $"Admin chat from {player:Player}: {message}");
@@ -240,9 +263,9 @@ namespace Content.Server.Chat.Managers
#region Utility
public void ChatMessageToOne(ChatChannel channel, string message, string wrappedMessage, EntityUid source, bool hideChat, INetChannel client, Color? colorOverride = null, bool recordReplay = false, string? audioPath = null, float audioVolume = 0)
public void ChatMessageToOne(ChatChannel channel, string message, string wrappedMessage, EntityUid source, bool hideChat, INetChannel client, Color? colorOverride = null, bool recordReplay = false, string? audioPath = null, float audioVolume = 0, int? senderKey = null)
{
var msg = new ChatMessage(channel, message, wrappedMessage, _entityManager.GetNetEntity(source), hideChat, colorOverride, audioPath, audioVolume);
var msg = new ChatMessage(channel, message, wrappedMessage, _entityManager.GetNetEntity(source), senderKey, hideChat, colorOverride, audioPath, audioVolume);
_netManager.ServerSendMessage(new MsgChatMessage() { Message = msg }, client);
if (!recordReplay)
@@ -260,7 +283,7 @@ namespace Content.Server.Chat.Managers
public void ChatMessageToMany(ChatChannel channel, string message, string wrappedMessage, EntityUid source, bool hideChat, bool recordReplay, List<INetChannel> clients, Color? colorOverride = null, string? audioPath = null, float audioVolume = 0)
{
var msg = new ChatMessage(channel, message, wrappedMessage, _entityManager.GetNetEntity(source), hideChat, colorOverride, audioPath, audioVolume);
var msg = new ChatMessage(channel, message, wrappedMessage, _entityManager.GetNetEntity(source), null, hideChat, colorOverride, audioPath, audioVolume);
_netManager.ServerSendToMany(new MsgChatMessage() { Message = msg }, clients);
if (!recordReplay)
@@ -288,9 +311,9 @@ namespace Content.Server.Chat.Managers
ChatMessageToMany(channel, message, wrappedMessage, source, hideChat, recordReplay, clients, colorOverride, audioPath, audioVolume);
}
public void ChatMessageToAll(ChatChannel channel, string message, string wrappedMessage, EntityUid source, bool hideChat, bool recordReplay, Color? colorOverride = null, string? audioPath = null, float audioVolume = 0)
public void ChatMessageToAll(ChatChannel channel, string message, string wrappedMessage, EntityUid source, bool hideChat, bool recordReplay, Color? colorOverride = null, string? audioPath = null, float audioVolume = 0, int? senderKey = null)
{
var msg = new ChatMessage(channel, message, wrappedMessage, _entityManager.GetNetEntity(source), hideChat, colorOverride, audioPath, audioVolume);
var msg = new ChatMessage(channel, message, wrappedMessage, _entityManager.GetNetEntity(source), senderKey, hideChat, colorOverride, audioPath, audioVolume);
_netManager.ServerSendToAll(new MsgChatMessage() { Message = msg });
if (!recordReplay)

View File

@@ -8,6 +8,17 @@ namespace Content.Server.Chat.Managers
{
public interface IChatManager
{
/// <summary>
/// Keys identifying messages sent by a specific player, used when sending
/// <see cref="MsgChatMessage"/>
/// </summary>
Dictionary<IPlayerSession, int> SenderKeys { get; }
/// <summary>
/// Tracks which entities a player was attached to while sending messages.
/// </summary>
Dictionary<IPlayerSession, HashSet<NetEntity>> SenderEntities { get; }
void Initialize();
/// <summary>
@@ -27,15 +38,17 @@ namespace Content.Server.Chat.Managers
void SendAdminAlert(EntityUid player, string message);
void ChatMessageToOne(ChatChannel channel, string message, string wrappedMessage, EntityUid source, bool hideChat,
INetChannel client, Color? colorOverride = null, bool recordReplay = false, string? audioPath = null, float audioVolume = 0);
INetChannel client, Color? colorOverride = null, bool recordReplay = false, string? audioPath = null, float audioVolume = 0, int? senderKey = null);
void ChatMessageToMany(ChatChannel channel, string message, string wrappedMessage, EntityUid source, bool hideChat, bool recordReplay,
IEnumerable<INetChannel> clients, Color? colorOverride = null, string? audioPath = null, float audioVolume = 0);
void ChatMessageToManyFiltered(Filter filter, ChatChannel channel, string message, string wrappedMessage, EntityUid source, bool hideChat, bool recordReplay, Color? colorOverride, string? audioPath = null, float audioVolume = 0);
void ChatMessageToAll(ChatChannel channel, string message, string wrappedMessage, EntityUid source, bool hideChat, bool recordReplay, Color? colorOverride = null, string? audioPath = null, float audioVolume = 0);
void ChatMessageToAll(ChatChannel channel, string message, string wrappedMessage, EntityUid source, bool hideChat, bool recordReplay, Color? colorOverride = null, string? audioPath = null, float audioVolume = 0, int? senderKey = null);
bool MessageCharacterLimit(IPlayerSession player, string message);
void DeleteMessagesBy(IPlayerSession player);
}
}

View File

@@ -15,7 +15,6 @@ using Content.Shared.Database;
using Content.Shared.Ghost;
using Content.Shared.IdentityManagement;
using Content.Shared.Interaction;
using Content.Shared.Inventory;
using Content.Shared.Mobs.Systems;
using Content.Shared.Radio;
using Robust.Server.GameObjects;
@@ -33,6 +32,7 @@ using Robust.Shared.Utility;
namespace Content.Server.Chat.Systems;
// TODO refactor whatever active warzone this class and chatmanager have become
/// <summary>
/// ChatSystem is responsible for in-simulation chat handling, such as whispering, speaking, emoting, etc.
/// ChatSystem depends on ChatManager to actually send the messages.
@@ -191,6 +191,9 @@ public sealed partial class ChatSystem : SharedChatSystem
if (!CanSendInGame(message, shell, player))
return;
if (player != null)
_chatManager.SenderEntities.GetOrNew(player).Add(GetNetEntity(source));
if (desiredType == InGameICChatType.Speak && message.StartsWith(LocalPrefix))
{
// prevent radios and remove prefix.
@@ -484,7 +487,7 @@ public sealed partial class ChatSystem : SharedChatSystem
_chatManager.ChatMessageToOne(ChatChannel.Whisper, obfuscatedMessage, wrappedUnknownMessage, source, false, session.ConnectedClient);
}
_replay.RecordServerMessage(new ChatMessage(ChatChannel.Whisper, message, wrappedMessage, GetNetEntity(source), MessageRangeHideChatForReplay(range)));
_replay.RecordServerMessage(new ChatMessage(ChatChannel.Whisper, message, wrappedMessage, GetNetEntity(source), null, MessageRangeHideChatForReplay(range)));
var ev = new EntitySpokeEvent(source, message, channel, obfuscatedMessage);
RaiseLocalEvent(source, ev, true);
@@ -559,6 +562,8 @@ public sealed partial class ChatSystem : SharedChatSystem
("entityName", name),
("message", FormattedMessage.EscapeText(message)));
_chatManager.SenderEntities.GetOrNew(player).Add(GetNetEntity(source));
SendInVoiceRange(ChatChannel.LOOC, message, wrappedMessage, source, hideChat ? ChatTransmitRange.HideChat : ChatTransmitRange.Normal);
_adminLogger.Add(LogType.Chat, LogImpact.Low, $"LOOC from {player:Player}: {message}");
}
@@ -585,8 +590,9 @@ public sealed partial class ChatSystem : SharedChatSystem
_adminLogger.Add(LogType.Chat, LogImpact.Low, $"Dead chat from {player:Player}: {message}");
}
_chatManager.ChatMessageToMany(ChatChannel.Dead, message, wrappedMessage, source, hideChat, true, clients.ToList());
_chatManager.SenderEntities.GetOrNew(player).Add(GetNetEntity(source));
_chatManager.ChatMessageToMany(ChatChannel.Dead, message, wrappedMessage, source, hideChat, true, clients.ToList());
}
#endregion
@@ -651,7 +657,7 @@ public sealed partial class ChatSystem : SharedChatSystem
_chatManager.ChatMessageToOne(channel, message, wrappedMessage, source, entHideChat, session.ConnectedClient);
}
_replay.RecordServerMessage(new ChatMessage(channel, message, wrappedMessage, GetNetEntity(source), MessageRangeHideChatForReplay(range)));
_replay.RecordServerMessage(new ChatMessage(channel, message, wrappedMessage, GetNetEntity(source), null, MessageRangeHideChatForReplay(range)));
}
/// <summary>
@@ -893,4 +899,3 @@ public enum ChatTransmitRange : byte
/// Ghosts can't hear or see it at all. Regular players can if in-range.
NoGhosts
}

View File

@@ -37,6 +37,7 @@ public sealed class CrewManifestSystem : EntitySystem
{
SubscribeLocalEvent<AfterGeneralRecordCreatedEvent>(AfterGeneralRecordCreated);
SubscribeLocalEvent<RecordModifiedEvent>(OnRecordModified);
SubscribeLocalEvent<RecordRemovedEvent>(OnRecordRemoved);
SubscribeLocalEvent<CrewManifestViewerComponent, BoundUIClosedEvent>(OnBoundUiClose);
SubscribeLocalEvent<CrewManifestViewerComponent, CrewManifestOpenUiMessage>(OpenEuiFromBui);
SubscribeLocalEvent<RoundRestartCleanupEvent>(OnRoundRestart);
@@ -83,6 +84,12 @@ public sealed class CrewManifestSystem : EntitySystem
UpdateEuis(ev.Key.OriginStation);
}
private void OnRecordRemoved(RecordRemovedEvent ev)
{
BuildCrewManifest(ev.Key.OriginStation);
UpdateEuis(ev.Key.OriginStation);
}
private void OnBoundUiClose(EntityUid uid, CrewManifestViewerComponent component, BoundUIClosedEvent ev)
{
var owningStation = _stationSystem.GetOwningStation(uid);

View File

@@ -1,20 +1,18 @@
using Content.Server.Administration.Logs;
using Content.Server.Chat.Systems;
using Content.Server.Power.Components;
using Content.Server.Radio.Components;
using Content.Server.VoiceMask;
using Content.Server.Popups;
using Content.Shared.Chat;
using Content.Shared.Database;
using Content.Shared.Radio;
using Content.Shared.Radio.Components;
using Robust.Server.GameObjects;
using Robust.Shared.Map;
using Robust.Shared.Network;
using Robust.Shared.Random;
using Robust.Shared.Replays;
using Robust.Shared.Utility;
using Content.Shared.Popups;
using Robust.Shared.Map;
using Content.Shared.Radio.Components;
using Content.Server.Power.Components;
using Robust.Shared.Random;
namespace Content.Server.Radio.EntitySystems;
@@ -87,7 +85,8 @@ public sealed class RadioSystem : EntitySystem
ChatChannel.Radio,
message,
wrappedMessage,
NetEntity.Invalid);
NetEntity.Invalid,
null);
var chatMsg = new MsgChatMessage { Message = chat };
var ev = new RadioReceiveEvent(message, messageSource, channel, chatMsg);

View File

@@ -1,7 +1,7 @@
using System.Linq;
using Content.Server.Station.Systems;
using Content.Shared.StationRecords;
using Robust.Server.GameObjects;
using System.Linq;
namespace Content.Server.StationRecords.Systems;
@@ -18,6 +18,7 @@ public sealed class GeneralStationRecordConsoleSystem : EntitySystem
SubscribeLocalEvent<GeneralStationRecordConsoleComponent, GeneralStationRecordsFilterMsg>(OnFiltersChanged);
SubscribeLocalEvent<GeneralStationRecordConsoleComponent, RecordModifiedEvent>(UpdateUserInterface);
SubscribeLocalEvent<GeneralStationRecordConsoleComponent, AfterGeneralRecordCreatedEvent>(UpdateUserInterface);
SubscribeLocalEvent<GeneralStationRecordConsoleComponent, RecordRemovedEvent>(UpdateUserInterface);
}
private void UpdateUserInterface<T>(EntityUid uid, GeneralStationRecordConsoleComponent component, T ev)

View File

@@ -1,6 +1,6 @@
using System.Diagnostics.CodeAnalysis;
using Content.Server.GameTicking;
using Content.Server.Forensics;
using Content.Server.GameTicking;
using Content.Shared.Inventory;
using Content.Shared.PDA;
using Content.Shared.Preferences;
@@ -160,8 +160,13 @@ public sealed class StationRecordsSystem : SharedStationRecordsSystem
if (!Resolve(station, ref records))
return false;
RaiseLocalEvent(new RecordRemovedEvent(station, key));
return records.Records.RemoveAllRecords(key);
if (records.Records.RemoveAllRecords(key))
{
RaiseLocalEvent(new RecordRemovedEvent(station, key));
return true;
}
return false;
}
/// <summary>