Files
RobustToolbox/Robust.Server/GameObjects/EntitySystems/ServerMetaDataSystem.cs
2023-11-11 12:50:21 +11:00

80 lines
2.6 KiB
C#

using Robust.Server.GameStates;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Player;
namespace Robust.Server.GameObjects;
public sealed class ServerMetaDataSystem : MetaDataSystem
{
[Dependency] private readonly PvsSystem _pvsSystem = default!;
private EntityQuery<MetaDataComponent> _mQuery;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<MetaDataComponent, PlayerAttachedEvent>(OnActorPlayerAttach);
EntityManager.ComponentAdded += OnComponentAdded;
EntityManager.ComponentRemoved += OnComponentRemoved;
_mQuery = GetEntityQuery<MetaDataComponent>();
}
public override void Shutdown()
{
base.Shutdown();
EntityManager.ComponentAdded -= OnComponentAdded;
EntityManager.ComponentRemoved -= OnComponentRemoved;
}
/// <summary>
/// If a session-specific component gets added, make sure the meta-data flag is set.
/// </summary>
private void OnComponentAdded(AddedComponentEventArgs obj)
{
var comp = obj.BaseArgs.Component;
if (comp.NetSyncEnabled && (comp.SessionSpecific || comp.SendOnlyToOwner))
MetaData(obj.BaseArgs.Owner).Flags |= MetaDataFlags.SessionSpecific;
}
/// <summary>
/// If a session-specific component gets removed, this will update the meta-data flag.
/// </summary>
private void OnComponentRemoved(RemovedComponentEventArgs obj)
{
var removed = obj.BaseArgs.Component;
if (obj.Terminating || !removed.NetSyncEnabled || (!removed.SessionSpecific && !removed.SendOnlyToOwner))
return;
foreach (var comp in obj.Meta.NetComponents.Values)
{
if (comp.LifeStage >= ComponentLifeStage.Removing)
continue;
if (comp.NetSyncEnabled && (comp.SessionSpecific || comp.SendOnlyToOwner))
return; // keep the flag
}
// remove the flag
obj.Meta.Flags &= ~MetaDataFlags.SessionSpecific;
}
/// <summary>
/// If a new player gets attached to an entity, this will ensure that the player receives session-restricted
/// component states by dirtying any restricted components.
/// </summary>
private void OnActorPlayerAttach(EntityUid uid, MetaDataComponent meta, PlayerAttachedEvent args)
{
if ((meta.Flags & MetaDataFlags.SessionSpecific) == 0)
return;
foreach (var (_, comp) in meta.NetComponents)
{
if (comp.SessionSpecific || comp.SendOnlyToOwner)
Dirty(uid, comp);
}
}
}