Rename fix (#31654)

* Localize RenameCommand and delegate most of the process to MetaDataSystem.SetEntityName()

* Make renaming rely on the EntityRenamedEvent. Fix issue where renaming would keep old Examine text

Requires engine change

* Fix localisation strings

* Make PDA search be based on a renamed entity's Uid instead of its old name

To do this the pda component now has an PdaOwner field which gets
assigned when it is given as a loadout to a player

* Fix bad merge???

huh

* Use AllEntityQuery
This commit is contained in:
nikthechampiongr
2024-09-15 01:55:03 +00:00
committed by GitHub
parent f81d18914d
commit ee434e397d
11 changed files with 95 additions and 79 deletions

View File

@@ -98,6 +98,7 @@ public sealed class AdminSystem : EntitySystem
SubscribeLocalEvent<RoleAddedEvent>(OnRoleEvent);
SubscribeLocalEvent<RoleRemovedEvent>(OnRoleEvent);
SubscribeLocalEvent<RoundRestartCleanupEvent>(OnRoundRestartCleanup);
SubscribeLocalEvent<ActorComponent, EntityRenamedEvent>(OnPlayerRenamed);
}
private void OnRoundRestartCleanup(RoundRestartCleanupEvent ev)
@@ -124,6 +125,11 @@ public sealed class AdminSystem : EntitySystem
}
}
private void OnPlayerRenamed(Entity<ActorComponent> ent, ref EntityRenamedEvent args)
{
UpdatePlayerList(ent.Comp.PlayerSession);
}
public void UpdatePlayerList(ICommonSession player)
{
_playerList[player.UserId] = GetPlayerInfo(player.Data, player);

View File

@@ -39,6 +39,7 @@ public sealed class IdentitySystem : SharedIdentitySystem
SubscribeLocalEvent<IdentityComponent, DidUnequipEvent>((uid, _, _) => QueueIdentityUpdate(uid));
SubscribeLocalEvent<IdentityComponent, DidUnequipHandEvent>((uid, _, _) => QueueIdentityUpdate(uid));
SubscribeLocalEvent<IdentityComponent, WearerMaskToggledEvent>((uid, _, _) => QueueIdentityUpdate(uid));
SubscribeLocalEvent<IdentityComponent, EntityRenamedEvent>((uid, _, _) => QueueIdentityUpdate(uid));
SubscribeLocalEvent<IdentityComponent, MapInitEvent>(OnMapInit);
}

View File

@@ -1,31 +1,22 @@
using System.Diagnostics.CodeAnalysis;
using Content.Server.Access.Systems;
using Content.Server.Administration;
using Content.Server.Administration.Systems;
using Content.Server.PDA;
using Content.Server.StationRecords.Systems;
using Content.Shared.Access.Components;
using Content.Shared.Administration;
using Content.Shared.Mind;
using Content.Shared.PDA;
using Content.Shared.StationRecords;
using Robust.Server.Player;
using Robust.Shared.Console;
using Robust.Shared.Player;
namespace Content.Server.Mind.Commands;
[AdminCommand(AdminFlags.VarEdit)]
public sealed class RenameCommand : IConsoleCommand
public sealed class RenameCommand : LocalizedEntityCommands
{
[Dependency] private readonly IEntityManager _entManager = default!;
[Dependency] private readonly IPlayerManager _playerManager = default!;
[Dependency] private readonly MetaDataSystem _metaSystem = default!;
public string Command => "rename";
public string Description => "Renames an entity and its cloner entries, ID cards, and PDAs.";
public string Help => "rename <Username|EntityUid> <New character name>";
public override string Command => "rename";
public void Execute(IConsoleShell shell, string argStr, string[] args)
public override void Execute(IConsoleShell shell, string argStr, string[] args)
{
if (args.Length != 2)
{
@@ -36,69 +27,14 @@ public sealed class RenameCommand : IConsoleCommand
var name = args[1];
if (name.Length > IdCardConsoleComponent.MaxFullNameLength)
{
shell.WriteLine("Name is too long.");
shell.WriteLine(Loc.GetString("cmd-rename-too-long"));
return;
}
if (!TryParseUid(args[0], shell, _entManager, out var entityUid))
return;
// Metadata
var metadata = _entManager.GetComponent<MetaDataComponent>(entityUid.Value);
var oldName = metadata.EntityName;
_entManager.System<MetaDataSystem>().SetEntityName(entityUid.Value, name, metadata);
var minds = _entManager.System<SharedMindSystem>();
if (minds.TryGetMind(entityUid.Value, out var mindId, out var mind))
{
// Mind
mind.CharacterName = name;
_entManager.Dirty(mindId, mind);
}
// Id Cards
if (_entManager.TrySystem<IdCardSystem>(out var idCardSystem))
{
if (idCardSystem.TryFindIdCard(entityUid.Value, out var idCard))
{
idCardSystem.TryChangeFullName(idCard, name, idCard);
// Records
// This is done here because ID cards are linked to station records
if (_entManager.TrySystem<StationRecordsSystem>(out var recordsSystem)
&& _entManager.TryGetComponent(idCard, out StationRecordKeyStorageComponent? keyStorage)
&& keyStorage.Key is {} key)
{
if (recordsSystem.TryGetRecord<GeneralStationRecord>(key, out var generalRecord))
{
generalRecord.Name = name;
}
recordsSystem.Synchronize(key);
}
}
}
// PDAs
if (_entManager.TrySystem<PdaSystem>(out var pdaSystem))
{
var query = _entManager.EntityQueryEnumerator<PdaComponent>();
while (query.MoveNext(out var uid, out var pda))
{
if (pda.OwnerName == oldName)
{
pdaSystem.SetOwner(uid, pda, name);
}
}
}
// Admin Overlay
if (_entManager.TrySystem<AdminSystem>(out var adminSystem)
&& _entManager.TryGetComponent<ActorComponent>(entityUid, out var actorComp))
{
adminSystem.UpdatePlayerList(actorComp.PlayerSession);
}
_metaSystem.SetEntityName(entityUid.Value, name);
}
private bool TryParseUid(string str, IConsoleShell shell,
@@ -114,9 +50,9 @@ public sealed class RenameCommand : IConsoleCommand
}
if (session == null)
shell.WriteError("Can't find username/uid: " + str);
shell.WriteError(Loc.GetString("cmd-rename-not-found", ("target", str)));
else
shell.WriteError(str + " does not have an entity.");
shell.WriteError(Loc.GetString("cmd-rename-no-entity", ("target", str)));
entityUid = EntityUid.Invalid;
return false;

View File

@@ -55,9 +55,23 @@ namespace Content.Server.PDA
SubscribeLocalEvent<PdaComponent, CartridgeLoaderNotificationSentEvent>(OnNotification);
SubscribeLocalEvent<StationRenamedEvent>(OnStationRenamed);
SubscribeLocalEvent<EntityRenamedEvent>(OnEntityRenamed);
SubscribeLocalEvent<AlertLevelChangedEvent>(OnAlertLevelChanged);
}
private void OnEntityRenamed(ref EntityRenamedEvent ev)
{
var query = EntityQueryEnumerator<PdaComponent>();
while (query.MoveNext(out var uid, out var comp))
{
if (comp.PdaOwner == ev.Uid)
{
SetOwner(uid, comp, ev.Uid, ev.NewName);
}
}
}
protected override void OnComponentInit(EntityUid uid, PdaComponent pda, ComponentInit args)
{
base.OnComponentInit(uid, pda, args);
@@ -94,9 +108,10 @@ namespace Content.Server.PDA
UpdatePdaUi(uid, pda);
}
public void SetOwner(EntityUid uid, PdaComponent pda, string ownerName)
public void SetOwner(EntityUid uid, PdaComponent pda, EntityUid owner, string ownerName)
{
pda.OwnerName = ownerName;
pda.PdaOwner = owner;
UpdatePdaUi(uid, pda);
}
@@ -112,7 +127,7 @@ namespace Content.Server.PDA
private void UpdateAllPdaUisOnStation()
{
var query = EntityQueryEnumerator<PdaComponent>();
var query = AllEntityQuery<PdaComponent>();
while (query.MoveNext(out var ent, out var comp))
{
UpdatePdaUi(ent, comp);

View File

@@ -246,7 +246,7 @@ public sealed class StationSpawningSystem : SharedStationSpawningSystem
_accessSystem.SetAccessToJob(cardId, jobPrototype, extendedAccess);
if (pdaComponent != null)
_pdaSystem.SetOwner(idUid.Value, pdaComponent, characterName);
_pdaSystem.SetOwner(idUid.Value, pdaComponent, entity, characterName);
}

View File

@@ -1,6 +1,9 @@
using System.Diagnostics.CodeAnalysis;
using System.IO;
using Content.Server.Access.Systems;
using Content.Server.Forensics;
using Content.Server.GameTicking;
using Content.Shared.Access.Components;
using Content.Shared.Inventory;
using Content.Shared.PDA;
using Content.Shared.Preferences;
@@ -35,12 +38,14 @@ public sealed class StationRecordsSystem : SharedStationRecordsSystem
[Dependency] private readonly InventorySystem _inventory = default!;
[Dependency] private readonly StationRecordKeyStorageSystem _keyStorage = default!;
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly IdCardSystem _idCard = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<PlayerSpawnCompleteEvent>(OnPlayerSpawn);
SubscribeLocalEvent<EntityRenamedEvent>(OnRename);
}
private void OnPlayerSpawn(PlayerSpawnCompleteEvent args)
@@ -51,6 +56,30 @@ public sealed class StationRecordsSystem : SharedStationRecordsSystem
CreateGeneralRecord(args.Station, args.Mob, args.Profile, args.JobId, stationRecords);
}
private void OnRename(ref EntityRenamedEvent ev)
{
// When a player gets renamed their card gets changed to match.
// Unfortunately this means that an event is called for it as well, and since TryFindIdCard will succeed if the
// given entity is a card and the card itself is the key the record will be mistakenly renamed to the card's name
// if we don't return early.
if (HasComp<IdCardComponent>(ev.Uid))
return;
if (_idCard.TryFindIdCard(ev.Uid, out var idCard))
{
if (TryComp(idCard, out StationRecordKeyStorageComponent? keyStorage)
&& keyStorage.Key is {} key)
{
if (TryGetRecord<GeneralStationRecord>(key, out var generalRecord))
{
generalRecord.Name = ev.NewName;
}
Synchronize(key);
}
}
}
private void CreateGeneralRecord(EntityUid station, EntityUid player, HumanoidCharacterProfile profile,
string? jobId, StationRecordsComponent records)
{

View File

@@ -25,6 +25,19 @@ public abstract class SharedIdCardSystem : EntitySystem
SubscribeLocalEvent<IdCardComponent, MapInitEvent>(OnMapInit);
SubscribeLocalEvent<TryGetIdentityShortInfoEvent>(OnTryGetIdentityShortInfo);
SubscribeLocalEvent<EntityRenamedEvent>(OnRename);
}
private void OnRename(ref EntityRenamedEvent ev)
{
// When a player gets renamed their id card is renamed as well to match.
// Unfortunately since TryFindIdCard will succeed if the entity is also a card this means that the card will
// keep renaming itself unless we return early.
if (HasComp<IdCardComponent>(ev.Uid))
return;
if (TryFindIdCard(ev.Uid, out var idCard))
TryChangeFullName(idCard, ev.NewName, idCard);
}
private void OnMapInit(EntityUid uid, IdCardComponent id, MapInitEvent args)

View File

@@ -39,6 +39,7 @@ public abstract class SharedMindSystem : EntitySystem
SubscribeLocalEvent<VisitingMindComponent, EntityTerminatingEvent>(OnVisitingTerminating);
SubscribeLocalEvent<RoundRestartCleanupEvent>(OnReset);
SubscribeLocalEvent<MindComponent, ComponentStartup>(OnMindStartup);
SubscribeLocalEvent<MindComponent, EntityRenamedEvent>(OnRenamed);
}
public override void Shutdown()
@@ -181,6 +182,12 @@ public abstract class SharedMindSystem : EntitySystem
args.Handled = true;
}
private void OnRenamed(Entity<MindComponent> ent, ref EntityRenamedEvent args)
{
ent.Comp.CharacterName = args.NewName;
Dirty(ent);
}
public EntityUid? GetMind(EntityUid uid, MindContainerComponent? mind = null)
{
if (!Resolve(uid, ref mind))

View File

@@ -5,7 +5,7 @@ using Content.Shared.NameModifier.Components;
namespace Content.Shared.NameModifier.EntitySystems;
/// <inheritdoc cref="NameModifierComponent"/>
public sealed partial class NameModifierSystem : EntitySystem
public sealed class NameModifierSystem : EntitySystem
{
[Dependency] private readonly MetaDataSystem _metaData = default!;
@@ -16,10 +16,10 @@ public sealed partial class NameModifierSystem : EntitySystem
SubscribeLocalEvent<NameModifierComponent, EntityRenamedEvent>(OnEntityRenamed);
}
private void OnEntityRenamed(Entity<NameModifierComponent> entity, ref EntityRenamedEvent args)
private void OnEntityRenamed(Entity<NameModifierComponent> ent, ref EntityRenamedEvent args)
{
SetBaseName((entity, entity.Comp), args.NewName);
RefreshNameModifiers((entity, entity.Comp));
SetBaseName(ent, args.NewName);
RefreshNameModifiers((ent.Owner, ent.Comp));
}
private void SetBaseName(Entity<NameModifierComponent> entity, string name)

View File

@@ -37,6 +37,10 @@ namespace Content.Shared.PDA
[ViewVariables] public bool FlashlightOn;
[ViewVariables(VVAccess.ReadWrite)] public string? OwnerName;
// The Entity that "owns" the PDA, usually a player's character.
// This is useful when we are doing stuff like renaming a player and want to find their PDA to change the name
// as well.
[ViewVariables(VVAccess.ReadWrite)] public EntityUid? PdaOwner;
[ViewVariables] public string? StationName;
[ViewVariables] public string? StationAlertLevel;
[ViewVariables] public Color StationAlertColor = Color.White;

View File

@@ -0,0 +1,5 @@
cmd-rename-desc = Renames an entity and its cloner entries, ID cards, and PDAs.
cmd-rename-help = rename <Username|EntityUid> <New character name>
cmd-rename-too-long = Name is too long.
cmd-rename-not-found = Can't find username/uid: {$target}
cmd-rename-no-entity = {$target} does not have an entity.