mirror of
https://github.com/space-wizards/RobustToolbox.git
synced 2026-02-15 03:30:53 +01:00
Remove Static Component NetIds (#1842)
* ComponentNames are not sent over the network when components are created. * Removed ComponentStates array from EntityState, now the state is stored directly inside the CompChange struct. * Remove the unnecessary NetID property from ComponentState. * Remove Component.NetworkSynchronizeExistence. * Change GetNetComponents to return both the component and the component NetId. * Remove public usages of the Component.NetID property. * Adds the NetIDAttribute that can be applied to components. * Removed Component.NetID. * Revert changes to GetComponentState and how prediction works. * Adds component netID automatic generation. * Modifies ClientConsoleHost so that commands can be called before Initialize(). * Completely remove static NetIds. * Renamed NetIDAttribute to NetworkedComponentAttribute. * Fixing unit tests.
This commit is contained in:
@@ -46,13 +46,15 @@ namespace Robust.Client
|
||||
IoCManager.Register<IClientMapManager, ClientMapManager>();
|
||||
IoCManager.Register<IEntityManager, ClientEntityManager>();
|
||||
IoCManager.Register<IEntityLookup, EntityLookup>();
|
||||
IoCManager.Register<IReflectionManager, ClientReflectionManager>();
|
||||
IoCManager.Register<IConsoleHost, ClientConsoleHost>();
|
||||
IoCManager.Register<IClientConsoleHost, ClientConsoleHost>();
|
||||
IoCManager.Register<IComponentFactory, ClientComponentFactory>();
|
||||
IoCManager.Register<ITileDefinitionManager, ClydeTileDefinitionManager>();
|
||||
IoCManager.Register<IClydeTileDefinitionManager, ClydeTileDefinitionManager>();
|
||||
IoCManager.Register<GameController, GameController>();
|
||||
IoCManager.Register<IGameController, GameController>();
|
||||
IoCManager.Register<IGameControllerInternal, GameController>();
|
||||
IoCManager.Register<IReflectionManager, ClientReflectionManager>();
|
||||
IoCManager.Register<IResourceManager, ResourceCache>();
|
||||
IoCManager.Register<IResourceManagerInternal, ResourceCache>();
|
||||
IoCManager.Register<IResourceCache, ResourceCache>();
|
||||
@@ -72,8 +74,6 @@ namespace Robust.Client
|
||||
IoCManager.Register<IDebugDrawingManager, DebugDrawingManager>();
|
||||
IoCManager.Register<ILightManager, LightManager>();
|
||||
IoCManager.Register<IDiscordRichPresence, DiscordRichPresence>();
|
||||
IoCManager.Register<IClientConsoleHost, ClientConsoleHost>();
|
||||
IoCManager.Register<IConsoleHost, ClientConsoleHost>();
|
||||
IoCManager.Register<IMidiManager, MidiManager>();
|
||||
IoCManager.Register<IAuthManager, AuthManager>();
|
||||
switch (mode)
|
||||
|
||||
@@ -49,7 +49,11 @@ namespace Robust.Client.Console
|
||||
NetManager.RegisterNetMessage<MsgConCmdAck>(HandleConCmdAck);
|
||||
NetManager.RegisterNetMessage<MsgConCmd>(ProcessCommand);
|
||||
|
||||
Reset();
|
||||
_requestedCommands = false;
|
||||
NetManager.Connected += OnNetworkConnected;
|
||||
|
||||
LoadConsoleCommands();
|
||||
SendServerCommandRequest();
|
||||
LogManager.RootSawmill.AddHandler(new DebugConsoleLogHandler(this));
|
||||
}
|
||||
|
||||
@@ -61,17 +65,6 @@ namespace Robust.Client.Console
|
||||
ExecuteCommand(null, text);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Reset()
|
||||
{
|
||||
AvailableCommands.Clear();
|
||||
_requestedCommands = false;
|
||||
NetManager.Connected += OnNetworkConnected;
|
||||
|
||||
LoadConsoleCommands();
|
||||
SendServerCommandRequest();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public event EventHandler<AddStringArgs>? AddString;
|
||||
|
||||
@@ -97,7 +90,7 @@ namespace Robust.Client.Console
|
||||
return;
|
||||
|
||||
// echo the command locally
|
||||
WriteError(null, "> " + command);
|
||||
WriteLine(null, "> " + command);
|
||||
|
||||
//Commands are processed locally and then sent to the server to be processed there again.
|
||||
var args = new List<string>();
|
||||
@@ -142,6 +135,9 @@ namespace Robust.Client.Console
|
||||
private void OutputText(string text, bool local, bool error)
|
||||
{
|
||||
AddString?.Invoke(this, new AddStringArgs(text, local, error));
|
||||
|
||||
var level = error ? LogLevel.Warning : LogLevel.Info;
|
||||
Logger.LogS(level, "CON", text);
|
||||
}
|
||||
|
||||
private void OnNetworkConnected(object? sender, NetChannelArgs netChannelArgs)
|
||||
|
||||
@@ -77,7 +77,7 @@ namespace Robust.Client.Console.Commands
|
||||
message.Append($"net ID: {registration.NetID}");
|
||||
}
|
||||
|
||||
message.Append($", NSE: {registration.NetworkSynchronizeExistence}, references:");
|
||||
message.Append($", References:");
|
||||
|
||||
shell.WriteLine(message.ToString());
|
||||
|
||||
|
||||
@@ -11,11 +11,6 @@ namespace Robust.Client.Console
|
||||
/// </summary>
|
||||
void Initialize();
|
||||
|
||||
/// <summary>
|
||||
/// Resets the console to a post-initialized state.
|
||||
/// </summary>
|
||||
void Reset();
|
||||
|
||||
event EventHandler<AddStringArgs> AddString;
|
||||
event EventHandler<AddFormattedMessageArgs> AddFormatted;
|
||||
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
using Robust.Shared.Console;
|
||||
using Robust.Shared.Containers;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Physics;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Reflection;
|
||||
|
||||
namespace Robust.Client.GameObjects
|
||||
{
|
||||
public class ClientComponentFactory : ComponentFactory
|
||||
internal class ClientComponentFactory : ComponentFactory
|
||||
{
|
||||
public ClientComponentFactory()
|
||||
public ClientComponentFactory(IDynamicTypeFactoryInternal typeFactory, IReflectionManager reflectionManager, IConsoleHost conHost)
|
||||
: base(typeFactory, reflectionManager, conHost)
|
||||
{
|
||||
// Required for the engine to work
|
||||
RegisterIgnore("KeyBindingInput");
|
||||
|
||||
@@ -109,13 +109,15 @@ namespace Robust.Client.GameObjects
|
||||
[Obsolete("Component Messages are deprecated, use Entity Events instead.")]
|
||||
public void SendComponentNetworkMessage(INetChannel? channel, IEntity entity, IComponent component, ComponentMessage message)
|
||||
{
|
||||
if (!component.NetID.HasValue)
|
||||
var netId = ComponentFactory.GetRegistration(component.GetType()).NetID;
|
||||
|
||||
if (!netId.HasValue)
|
||||
throw new ArgumentException($"Component {component.Name} does not have a NetID.", nameof(component));
|
||||
|
||||
var msg = _networkManager.CreateNetMessage<MsgEntity>();
|
||||
msg.Type = EntityMessageType.ComponentMessage;
|
||||
msg.EntityUid = entity.Uid;
|
||||
msg.NetId = component.NetID.Value;
|
||||
msg.NetId = netId.Value;
|
||||
msg.ComponentMessage = message;
|
||||
msg.SourceTick = _gameTiming.CurTick;
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ using Robust.Client.ResourceManagement;
|
||||
using Robust.Shared.Animations;
|
||||
using Robust.Shared.Configuration;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Log;
|
||||
using Robust.Shared.Map;
|
||||
@@ -17,12 +18,12 @@ namespace Robust.Client.GameObjects
|
||||
{
|
||||
[RegisterComponent]
|
||||
[ComponentReference(typeof(IPointLightComponent))]
|
||||
[NetworkedComponent()]
|
||||
public class PointLightComponent : Component, IPointLightComponent, ISerializationHooks
|
||||
{
|
||||
[Dependency] private readonly IResourceCache _resourceCache = default!;
|
||||
|
||||
public override string Name => "PointLight";
|
||||
public override uint? NetID => NetIDs.POINT_LIGHT;
|
||||
|
||||
internal bool TreeUpdateQueued { get; set; }
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.Input;
|
||||
using Robust.Client.Map;
|
||||
@@ -25,6 +26,7 @@ using Robust.Shared.Utility;
|
||||
namespace Robust.Client.GameStates
|
||||
{
|
||||
/// <inheritdoc />
|
||||
[UsedImplicitly]
|
||||
public class ClientGameStateManager : IClientGameStateManager
|
||||
{
|
||||
private GameStateProcessor _processor = default!;
|
||||
@@ -36,6 +38,8 @@ namespace Robust.Client.GameStates
|
||||
_pendingSystemMessages
|
||||
= new();
|
||||
|
||||
private uint _metaCompNetId;
|
||||
|
||||
[Dependency] private readonly IComponentFactory _compFactory = default!;
|
||||
[Dependency] private readonly IClientEntityManagerInternal _entities = default!;
|
||||
[Dependency] private readonly IEntityLookup _lookup = default!;
|
||||
@@ -99,6 +103,12 @@ namespace Robust.Client.GameStates
|
||||
Predicting = _config.GetCVar(CVars.NetPredict);
|
||||
PredictTickBias = _config.GetCVar(CVars.NetPredictTickBias);
|
||||
PredictLagBias = _config.GetCVar(CVars.NetPredictLagBias);
|
||||
|
||||
var metaId = _compFactory.GetRegistration(typeof(MetaDataComponent)).NetID;
|
||||
if (!metaId.HasValue)
|
||||
throw new InvalidOperationException("MetaDataComponent does not have a NetId.");
|
||||
|
||||
_metaCompNetId = metaId.Value;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -343,11 +353,11 @@ namespace Robust.Client.GameStates
|
||||
}
|
||||
|
||||
// TODO: handle component deletions/creations.
|
||||
foreach (var comp in _componentManager.GetNetComponents(entity.Uid))
|
||||
foreach (var (netId, comp) in _componentManager.GetNetComponents(entity.Uid))
|
||||
{
|
||||
DebugTools.AssertNotNull(comp.NetID);
|
||||
DebugTools.AssertNotNull(netId);
|
||||
|
||||
if (comp.LastModifiedTick < curTick || !last.TryGetValue(comp.NetID!.Value, out var compState))
|
||||
if (comp.LastModifiedTick < curTick || !last.TryGetValue(netId, out var compState))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -368,24 +378,22 @@ namespace Robust.Client.GameStates
|
||||
// so that we can later roll back to it (if necessary).
|
||||
var outputData = new Dictionary<EntityUid, Dictionary<uint, ComponentState>>();
|
||||
|
||||
Debug.Assert(_players.LocalPlayer != null, "_players.LocalPlayer != null");
|
||||
var player = _players.LocalPlayer.Session;
|
||||
|
||||
foreach (var createdEntity in createdEntities)
|
||||
{
|
||||
var compData = new Dictionary<uint, ComponentState>();
|
||||
outputData.Add(createdEntity, compData);
|
||||
|
||||
foreach (var component in _componentManager.GetNetComponents(createdEntity))
|
||||
foreach (var (netId, component) in _componentManager.GetNetComponents(createdEntity))
|
||||
{
|
||||
Debug.Assert(_players.LocalPlayer != null, "_players.LocalPlayer != null");
|
||||
|
||||
var player = _players.LocalPlayer.Session;
|
||||
var state = component.GetComponentState(player);
|
||||
|
||||
if (state.GetType() == typeof(ComponentState))
|
||||
{
|
||||
if(state.GetType() == typeof(ComponentState))
|
||||
continue;
|
||||
}
|
||||
|
||||
compData.Add(state.NetID, state);
|
||||
compData.Add(netId, state);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -432,8 +440,7 @@ namespace Robust.Client.GameStates
|
||||
}
|
||||
else //Unknown entities
|
||||
{
|
||||
var metaState = (MetaDataComponentState?) es.ComponentStates
|
||||
?.FirstOrDefault(c => c.NetID == NetIDs.META_DATA);
|
||||
var metaState = (MetaDataComponentState?) es.ComponentChanges?.FirstOrDefault(c => c.NetID == _metaCompNetId).State;
|
||||
if (metaState == null)
|
||||
{
|
||||
throw new InvalidOperationException($"Server sent new entity state for {es.Uid} without metadata component!");
|
||||
@@ -543,7 +550,7 @@ namespace Robust.Client.GameStates
|
||||
private void HandleEntityState(IComponentManager compMan, IEntity entity, EntityEventBus bus, EntityState? curState,
|
||||
EntityState? nextState)
|
||||
{
|
||||
var compStateWork = new Dictionary<uint, (ComponentState? curState, ComponentState? nextState)>();
|
||||
var compStateWork = new Dictionary<ushort, (ComponentState? curState, ComponentState? nextState)>();
|
||||
var entityUid = entity.Uid;
|
||||
|
||||
if (curState?.ComponentChanges != null)
|
||||
@@ -559,42 +566,46 @@ namespace Robust.Client.GameStates
|
||||
}
|
||||
else
|
||||
{
|
||||
//Right now we just assume every state from an unseen entity is added
|
||||
|
||||
if (compMan.HasComponent(entityUid, compChange.NetID))
|
||||
continue;
|
||||
|
||||
var newComp = (Component) _compFactory.GetComponent(compChange.ComponentName!);
|
||||
var newComp = (Component) _compFactory.GetComponent(compChange.NetID);
|
||||
newComp.Owner = entity;
|
||||
compMan.AddComponent(entity, newComp, true);
|
||||
|
||||
compStateWork[compChange.NetID] = (compChange.State, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (curState?.ComponentStates != null)
|
||||
if (curState?.ComponentChanges != null)
|
||||
{
|
||||
foreach (var compState in curState.ComponentStates)
|
||||
foreach (var compChange in curState.ComponentChanges)
|
||||
{
|
||||
compStateWork[compState.NetID] = (compState, null);
|
||||
compStateWork[compChange.NetID] = (compChange.State, null);
|
||||
}
|
||||
}
|
||||
|
||||
if (nextState?.ComponentStates != null)
|
||||
if (nextState?.ComponentChanges != null)
|
||||
{
|
||||
foreach (var compState in nextState.ComponentStates)
|
||||
foreach (var compState in nextState.ComponentChanges)
|
||||
{
|
||||
if (compStateWork.TryGetValue(compState.NetID, out var state))
|
||||
{
|
||||
compStateWork[compState.NetID] = (state.curState, compState);
|
||||
compStateWork[compState.NetID] = (state.curState, compState.State);
|
||||
}
|
||||
else
|
||||
{
|
||||
compStateWork[compState.NetID] = (null, compState);
|
||||
compStateWork[compState.NetID] = (null, compState.State);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var (netId, (cur, next)) in compStateWork)
|
||||
{
|
||||
if (compMan.TryGetComponent(entityUid, netId, out var component))
|
||||
if (compMan.TryGetComponent(entityUid, (ushort) netId, out var component))
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using Robust.Shared.GameObjects;
|
||||
@@ -195,14 +195,10 @@ namespace Robust.Client.GameStates
|
||||
{
|
||||
compData.Remove(change.NetID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (entityState.ComponentStates != null)
|
||||
{
|
||||
foreach (var compState in entityState.ComponentStates)
|
||||
{
|
||||
compData[compState.NetID] = compState;
|
||||
else if (change.State is not null)
|
||||
{
|
||||
compData[change.NetID] = change.State;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ namespace Robust.Client.GameStates
|
||||
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
||||
[Dependency] private readonly IClientNetManager _netManager = default!;
|
||||
[Dependency] private readonly IClientGameStateManager _gameStateManager = default!;
|
||||
[Dependency] private readonly IComponentFactory _componentFactory = default!;
|
||||
|
||||
private const int HistorySize = 60 * 3; // number of ticks to keep in history.
|
||||
private const int TargetPayloadBps = 56000 / 8; // Target Payload size in Bytes per second. A mind-numbing fifty-six thousand bits per second, who would ever need more?
|
||||
@@ -90,17 +91,14 @@ namespace Robust.Client.GameStates
|
||||
sb.Append($"\n Changes:");
|
||||
foreach (var compChange in entState.ComponentChanges)
|
||||
{
|
||||
var del = compChange.Deleted ? 'D' : 'C';
|
||||
sb.Append($"\n [{del}]{compChange.NetID}:{compChange.ComponentName}");
|
||||
}
|
||||
}
|
||||
var registration = _componentFactory.GetRegistration(compChange.NetID);
|
||||
var create = compChange.Created ? 'C' : '\0';
|
||||
var mod = !(compChange.Created || compChange.Created) ? 'M' : '\0';
|
||||
var del = compChange.Deleted ? 'D' : '\0';
|
||||
sb.Append($"\n [{create}{mod}{del}]{compChange.NetID}:{registration.Name}");
|
||||
|
||||
if (entState.ComponentStates is not null)
|
||||
{
|
||||
sb.Append($"\n States:");
|
||||
foreach (var compState in entState.ComponentStates)
|
||||
{
|
||||
sb.Append($"\n {compState.NetID}:{compState.GetType().Name}");
|
||||
if(compChange.State is not null)
|
||||
sb.Append($"\n STATE:{compChange.State.GetType().Name}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,12 +32,12 @@ namespace Robust.Client.Map
|
||||
//get shared euid of map comp entity
|
||||
foreach (var entityState in entityStates!)
|
||||
{
|
||||
if(entityState.ComponentStates is null)
|
||||
if(entityState.ComponentChanges is null)
|
||||
continue;
|
||||
|
||||
foreach (var compState in entityState.ComponentStates)
|
||||
foreach (var compChange in entityState.ComponentChanges)
|
||||
{
|
||||
if (compState is not MapComponentState mapCompState || mapCompState.MapId != mapId)
|
||||
if (compChange.State is not MapComponentState mapCompState || mapCompState.MapId != mapId)
|
||||
continue;
|
||||
|
||||
mapEuid = entityState.Uid;
|
||||
@@ -67,12 +67,12 @@ namespace Robust.Client.Map
|
||||
//get shared euid of map comp entity
|
||||
foreach (var entityState in entityStates!)
|
||||
{
|
||||
if(entityState.ComponentStates is null)
|
||||
if (entityState.ComponentChanges is null)
|
||||
continue;
|
||||
|
||||
foreach (var compState in entityState.ComponentStates)
|
||||
foreach (var compState in entityState.ComponentChanges)
|
||||
{
|
||||
if (compState is not MapGridComponentState gridCompState || gridCompState.GridIndex != gridId)
|
||||
if (compState.State is not MapGridComponentState gridCompState || gridCompState.GridIndex != gridId)
|
||||
continue;
|
||||
|
||||
gridEuid = entityState.Uid;
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace Robust.Client.UserInterface.Controls
|
||||
{
|
||||
public Label Label { get; }
|
||||
|
||||
public Button() : base()
|
||||
public Button()
|
||||
{
|
||||
AddStyleClass(StyleClassButton);
|
||||
Label = new Label
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace Robust.Client.UserInterface.Controls
|
||||
public Label Label { get; }
|
||||
public TextureRect TextureRect { get; }
|
||||
|
||||
public CheckBox() : base()
|
||||
public CheckBox()
|
||||
{
|
||||
ToggleMode = true;
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace Robust.Client.UserInterface.Controls
|
||||
public const string StylePseudoClassHover = "hover";
|
||||
public const string StylePseudoClassDisabled = "disabled";
|
||||
|
||||
public ContainerButton() : base()
|
||||
public ContainerButton()
|
||||
{
|
||||
DrawModeChanged();
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ namespace Robust.Client.UserInterface.Controls
|
||||
|
||||
public event EventHandler<ValueChangedEventArgs>? ValueChanged;
|
||||
|
||||
public SpinBox() : base()
|
||||
public SpinBox()
|
||||
{
|
||||
MouseFilter = MouseFilterMode.Pass;
|
||||
|
||||
|
||||
@@ -349,6 +349,16 @@ namespace Robust.Server
|
||||
_entityManager.Startup();
|
||||
IoCManager.Resolve<IEntityLookup>().Startup();
|
||||
_stateManager.Initialize();
|
||||
|
||||
// sometime after content init
|
||||
{
|
||||
var reg = _entityManager.ComponentFactory.GetRegistration<TransformComponent>();
|
||||
if (!reg.NetID.HasValue)
|
||||
throw new InvalidOperationException("TransformComponent does not have a NetId.");
|
||||
|
||||
_stateManager.SetTransformNetId(reg.NetID.Value);
|
||||
}
|
||||
|
||||
_scriptHost.Initialize();
|
||||
|
||||
_modLoader.BroadcastRunLevel(ModRunLevel.PostInit);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Players;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Players;
|
||||
@@ -10,6 +11,7 @@ namespace Robust.Server.GameObjects
|
||||
{
|
||||
[RegisterComponent]
|
||||
[ComponentReference(typeof(IPointLightComponent))]
|
||||
[NetworkedComponent()]
|
||||
public class PointLightComponent : Component, IPointLightComponent
|
||||
{
|
||||
[DataField("color")]
|
||||
@@ -22,7 +24,6 @@ namespace Robust.Server.GameObjects
|
||||
private Vector2 _offset = Vector2.Zero;
|
||||
|
||||
public override string Name => "PointLight";
|
||||
public override uint? NetID => NetIDs.POINT_LIGHT;
|
||||
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public Color Color
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
using Robust.Shared.Console;
|
||||
using Robust.Shared.Containers;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Reflection;
|
||||
|
||||
namespace Robust.Server.GameObjects
|
||||
{
|
||||
public class ServerComponentFactory : ComponentFactory
|
||||
internal class ServerComponentFactory : ComponentFactory
|
||||
{
|
||||
public ServerComponentFactory()
|
||||
public ServerComponentFactory(IDynamicTypeFactoryInternal typeFactory, IReflectionManager reflectionManager, IConsoleHost conHost)
|
||||
: base(typeFactory, reflectionManager, conHost)
|
||||
{
|
||||
RegisterIgnore("Input");
|
||||
RegisterIgnore("AnimationPlayer");
|
||||
|
||||
@@ -75,7 +75,7 @@ namespace Robust.Server.GameObjects
|
||||
// As such, we can reset the modified ticks to Zero,
|
||||
// which indicates "not different from client's own deserialization".
|
||||
// So the initial data for the component or even the creation doesn't have to be sent over the wire.
|
||||
foreach (var component in ComponentManager.GetNetComponents(entity.Uid))
|
||||
foreach (var (netId, component) in ComponentManager.GetNetComponents(entity.Uid))
|
||||
{
|
||||
// Make sure to ONLY get components that are defined in the prototype.
|
||||
// Others could be instantiated directly by AddComponent (e.g. ContainerManager).
|
||||
@@ -143,13 +143,15 @@ namespace Robust.Server.GameObjects
|
||||
if (_networkManager.IsClient)
|
||||
return;
|
||||
|
||||
if (!component.NetID.HasValue)
|
||||
var netId = ComponentFactory.GetRegistration(component.GetType()).NetID;
|
||||
|
||||
if (!netId.HasValue)
|
||||
throw new ArgumentException($"Component {component.Name} does not have a NetID.", nameof(component));
|
||||
|
||||
var msg = _networkManager.CreateNetMessage<MsgEntity>();
|
||||
msg.Type = EntityMessageType.ComponentMessage;
|
||||
msg.EntityUid = entity.Uid;
|
||||
msg.NetId = component.NetID.Value;
|
||||
msg.NetId = netId.Value;
|
||||
msg.ComponentMessage = message;
|
||||
msg.SourceTick = _gameTiming.CurTick;
|
||||
|
||||
|
||||
@@ -39,6 +39,8 @@ namespace Robust.Server.GameStates
|
||||
private readonly ObjectPool<HashSet<EntityUid>> _viewerEntsPool
|
||||
= new DefaultObjectPool<HashSet<EntityUid>>(new DefaultPooledObjectPolicy<HashSet<EntityUid>>(), MaxVisPoolSize);
|
||||
|
||||
private ushort _transformNetId = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Is view culling enabled, or will we send the whole map?
|
||||
/// </summary>
|
||||
@@ -58,6 +60,11 @@ namespace Robust.Server.GameStates
|
||||
_lookup = lookup;
|
||||
}
|
||||
|
||||
public void SetTransformNetId(ushort value)
|
||||
{
|
||||
_transformNetId = value;
|
||||
}
|
||||
|
||||
// Not thread safe
|
||||
public void EntityDeleted(EntityUid e)
|
||||
{
|
||||
@@ -204,17 +211,14 @@ namespace Robust.Server.GameStates
|
||||
var oldState = (TransformComponent.TransformComponentState) xform.GetComponentState(session);
|
||||
|
||||
entityStates.Add(new EntityState(entityUid,
|
||||
new ComponentChanged[]
|
||||
new[]
|
||||
{
|
||||
new(false, NetIDs.TRANSFORM, "Transform")
|
||||
},
|
||||
new ComponentState[]
|
||||
{
|
||||
new TransformComponent.TransformComponentState(Vector2NaN,
|
||||
oldState.Rotation,
|
||||
oldState.ParentID,
|
||||
oldState.NoLocalRotation,
|
||||
oldState.Anchored)
|
||||
ComponentChange.Changed(_transformNetId,
|
||||
new TransformComponent.TransformComponentState(Vector2NaN,
|
||||
oldState.Rotation,
|
||||
oldState.ParentID,
|
||||
oldState.NoLocalRotation,
|
||||
oldState.Anchored)),
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
@@ -17,5 +17,6 @@ namespace Robust.Server.GameStates
|
||||
|
||||
bool PvsEnabled { get; set; }
|
||||
float PvsRange { get; set; }
|
||||
void SetTransformNetId(ushort netId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Server.Map;
|
||||
using Robust.Server.Player;
|
||||
@@ -21,6 +22,7 @@ using Robust.Shared.Utility;
|
||||
namespace Robust.Server.GameStates
|
||||
{
|
||||
/// <inheritdoc cref="IServerGameStateManager"/>
|
||||
[UsedImplicitly]
|
||||
public class ServerGameStateManager : IServerGameStateManager, IPostInjectInit
|
||||
{
|
||||
// Mapping of net UID of clients -> last known acked state.
|
||||
@@ -53,6 +55,11 @@ namespace Robust.Server.GameStates
|
||||
set => _configurationManager.SetCVar(CVars.NetMaxUpdateRange, value);
|
||||
}
|
||||
|
||||
public void SetTransformNetId(ushort netId)
|
||||
{
|
||||
_entityView.SetTransformNetId(netId);
|
||||
}
|
||||
|
||||
public void PostInject()
|
||||
{
|
||||
_logger = Logger.GetSawmill("PVS");
|
||||
@@ -249,38 +256,44 @@ namespace Robust.Server.GameStates
|
||||
/// <returns>New entity State for the given entity.</returns>
|
||||
internal static EntityState GetEntityState(IComponentManager compMan, ICommonSession player, EntityUid entityUid, GameTick fromTick)
|
||||
{
|
||||
var compStates = new List<ComponentState>();
|
||||
var changed = new List<ComponentChanged>();
|
||||
var changed = new List<ComponentChange>();
|
||||
|
||||
foreach (var comp in compMan.GetNetComponents(entityUid))
|
||||
foreach (var (netId, component) in compMan.GetNetComponents(entityUid))
|
||||
{
|
||||
DebugTools.Assert(comp.Initialized);
|
||||
DebugTools.Assert(component.Initialized);
|
||||
|
||||
// NOTE: When LastModifiedTick or CreationTick are 0 it means that the relevant data is
|
||||
// "not different from entity creation".
|
||||
// i.e. when the client spawns the entity and loads the entity prototype,
|
||||
// the data it deserializes from the prototype SHOULD be equal
|
||||
// to what the component state / ComponentChanged would send.
|
||||
// to what the component state / ComponentChange would send.
|
||||
// As such, we can avoid sending this data in this case since the client "already has it".
|
||||
|
||||
if (comp.NetSyncEnabled && comp.LastModifiedTick != GameTick.Zero && comp.LastModifiedTick >= fromTick)
|
||||
compStates.Add(comp.GetComponentState(player));
|
||||
DebugTools.Assert(component.LastModifiedTick >= component.CreationTick);
|
||||
|
||||
if (comp.CreationTick != GameTick.Zero && comp.CreationTick >= fromTick && !comp.Deleted)
|
||||
if (component.CreationTick != GameTick.Zero && component.CreationTick >= fromTick && !component.Deleted)
|
||||
{
|
||||
ComponentState? state = null;
|
||||
if (component.NetSyncEnabled && component.LastModifiedTick != GameTick.Zero && component.LastModifiedTick >= fromTick)
|
||||
state = component.GetComponentState(player);
|
||||
|
||||
// Can't be null since it's returned by GetNetComponents
|
||||
// ReSharper disable once PossibleInvalidOperationException
|
||||
changed.Add(ComponentChanged.Added(comp.NetID!.Value, comp.Name));
|
||||
changed.Add(ComponentChange.Added(netId, state));
|
||||
}
|
||||
else if (comp.Deleted && comp.LastModifiedTick >= fromTick)
|
||||
else if (component.NetSyncEnabled && component.LastModifiedTick != GameTick.Zero && component.LastModifiedTick >= fromTick)
|
||||
{
|
||||
changed.Add(ComponentChange.Changed(netId, component.GetComponentState(player)));
|
||||
}
|
||||
else if (component.Deleted && component.LastModifiedTick >= fromTick)
|
||||
{
|
||||
// Can't be null since it's returned by GetNetComponents
|
||||
// ReSharper disable once PossibleInvalidOperationException
|
||||
changed.Add(ComponentChanged.Removed(comp.NetID!.Value));
|
||||
changed.Add(ComponentChange.Removed(netId));
|
||||
}
|
||||
}
|
||||
|
||||
return new EntityState(entityUid, changed.ToArray(), compStates.ToArray());
|
||||
return new EntityState(entityUid, changed.ToArray());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -409,7 +409,7 @@ namespace Robust.Server.Maps
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (var component in _componentManager.GetNetComponents(entity.Uid))
|
||||
foreach (var (netId, component) in _componentManager.GetNetComponents(entity.Uid))
|
||||
{
|
||||
var castComp = (Component) component;
|
||||
|
||||
|
||||
@@ -39,10 +39,11 @@ namespace Robust.Server
|
||||
IoCManager.Register<IBaseServerInternal, BaseServer>();
|
||||
IoCManager.Register<BaseServer, BaseServer>();
|
||||
IoCManager.Register<IGameTiming, GameTiming>();
|
||||
IoCManager.Register<IReflectionManager, ServerReflectionManager>();
|
||||
IoCManager.Register<IConsoleHost, ServerConsoleHost>();
|
||||
IoCManager.Register<IServerConsoleHost, ServerConsoleHost>();
|
||||
IoCManager.Register<IComponentFactory, ServerComponentFactory>();
|
||||
IoCManager.Register<IConGroupController, ConGroupController>();
|
||||
IoCManager.Register<IServerConsoleHost, ServerConsoleHost>();
|
||||
IoCManager.Register<IConsoleHost, ServerConsoleHost>();
|
||||
IoCManager.Register<IMapManager, ServerMapManager>();
|
||||
IoCManager.Register<IMapManagerInternal, ServerMapManager>();
|
||||
IoCManager.Register<IServerMapManager, ServerMapManager>();
|
||||
@@ -55,7 +56,6 @@ namespace Robust.Server
|
||||
IoCManager.Register<IPlayerManager, PlayerManager>();
|
||||
IoCManager.Register<ISharedPlayerManager, PlayerManager>();
|
||||
IoCManager.Register<IPrototypeManager, ServerPrototypeManager>();
|
||||
IoCManager.Register<IReflectionManager, ServerReflectionManager>();
|
||||
IoCManager.Register<IResourceManager, ResourceManager>();
|
||||
IoCManager.Register<IResourceManagerInternal, ResourceManager>();
|
||||
IoCManager.Register<IServerEntityManager, ServerEntityManager>();
|
||||
|
||||
@@ -4,6 +4,7 @@ using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Players;
|
||||
using Robust.Shared.Serialization;
|
||||
@@ -17,6 +18,7 @@ namespace Robust.Shared.Containers
|
||||
/// Holds data about a set of entity containers on this entity.
|
||||
/// </summary>
|
||||
[ComponentReference(typeof(IContainerManager))]
|
||||
[NetworkedComponent()]
|
||||
public class ContainerManagerComponent : Component, IContainerManager
|
||||
{
|
||||
[Dependency] private readonly IRobustSerializer _serializer = default!;
|
||||
@@ -29,9 +31,6 @@ namespace Robust.Shared.Containers
|
||||
/// <inheritdoc />
|
||||
public sealed override string Name => "ContainerContainer";
|
||||
|
||||
/// <inheritdoc />
|
||||
public sealed override uint? NetID => NetIDs.CONTAINER_MANAGER;
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void OnRemove()
|
||||
{
|
||||
@@ -281,7 +280,7 @@ namespace Robust.Shared.Containers
|
||||
{
|
||||
public List<ContainerData> ContainerSet;
|
||||
|
||||
public ContainerManagerComponentState(List<ContainerData> containers) : base(NetIDs.CONTAINER_MANAGER)
|
||||
public ContainerManagerComponentState(List<ContainerData> containers)
|
||||
{
|
||||
ContainerSet = containers;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Network;
|
||||
using Robust.Shared.Players;
|
||||
using Robust.Shared.Reflection;
|
||||
@@ -18,14 +19,6 @@ namespace Robust.Shared.GameObjects
|
||||
[ViewVariables]
|
||||
public abstract string Name { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
[ViewVariables]
|
||||
public virtual uint? NetID => null;
|
||||
|
||||
/// <inheritdoc />
|
||||
[ViewVariables]
|
||||
public virtual bool NetworkSynchronizeExistence => false;
|
||||
|
||||
/// <inheritdoc />
|
||||
[ViewVariables]
|
||||
[DataField("netsync")]
|
||||
@@ -249,14 +242,16 @@ namespace Robust.Shared.GameObjects
|
||||
[Obsolete("Component Messages are deprecated, use Entity Events instead.")]
|
||||
public virtual void HandleNetworkMessage(ComponentMessage message, INetChannel netChannel, ICommonSession? session = null) { }
|
||||
|
||||
private static readonly ComponentState DefaultComponentState = new();
|
||||
|
||||
/// <param name="player"></param>
|
||||
/// <inheritdoc />
|
||||
public virtual ComponentState GetComponentState(ICommonSession player)
|
||||
{
|
||||
if (NetID == null)
|
||||
throw new InvalidOperationException($"Cannot make state for component without Net ID: {GetType()}");
|
||||
if (!(Attribute.GetCustomAttribute(GetType(), typeof(NetworkedComponentAttribute)) is NetworkedComponentAttribute))
|
||||
throw new InvalidOperationException($"Calling base {nameof(GetComponentState)} without being networked.");
|
||||
|
||||
return new ComponentState(NetID.Value);
|
||||
return DefaultComponentState;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
@@ -3,31 +3,33 @@ using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using System.Runtime.Serialization;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.Console;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Log;
|
||||
using Robust.Shared.Reflection;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Robust.Shared.GameObjects
|
||||
{
|
||||
public class ComponentFactory : IComponentFactory
|
||||
internal class ComponentFactory : IComponentFactory
|
||||
{
|
||||
[Dependency] private readonly IDynamicTypeFactoryInternal _typeFactory = default!;
|
||||
[Dependency] private readonly IReflectionManager _reflectionManager = default!;
|
||||
private readonly IDynamicTypeFactoryInternal _typeFactory;
|
||||
private readonly IReflectionManager _reflectionManager;
|
||||
|
||||
private class ComponentRegistration : IComponentRegistration
|
||||
{
|
||||
public string Name { get; }
|
||||
public uint? NetID { get; }
|
||||
public bool NetworkSynchronizeExistence { get; }
|
||||
public ushort? NetID { get; set; }
|
||||
public Type Type { get; }
|
||||
internal readonly List<Type> References = new();
|
||||
IReadOnlyList<Type> IComponentRegistration.References => References;
|
||||
|
||||
public ComponentRegistration(string name, Type type, uint? netID, bool networkSynchronizeExistence)
|
||||
public ComponentRegistration(string name, Type type)
|
||||
{
|
||||
Name = name;
|
||||
NetID = netID;
|
||||
NetworkSynchronizeExistence = networkSynchronizeExistence;
|
||||
NetID = null;
|
||||
Type = type;
|
||||
References.Add(type);
|
||||
}
|
||||
@@ -52,7 +54,7 @@ namespace Robust.Shared.GameObjects
|
||||
/// <summary>
|
||||
/// Mapping of network ID to type.
|
||||
/// </summary>
|
||||
private readonly Dictionary<uint, ComponentRegistration> netIDs = new();
|
||||
private List<IComponentRegistration>? _networkedComponents;
|
||||
|
||||
/// <summary>
|
||||
/// Mapping of concrete component types to their registration.
|
||||
@@ -76,8 +78,34 @@ namespace Robust.Shared.GameObjects
|
||||
/// <inheritdoc />
|
||||
public IEnumerable<Type> AllRegisteredTypes => types.Keys;
|
||||
|
||||
/// <inheritdoc />
|
||||
public IReadOnlyList<IComponentRegistration>? NetworkedComponents => _networkedComponents;
|
||||
|
||||
private IEnumerable<ComponentRegistration> AllRegistrations => types.Values;
|
||||
|
||||
public ComponentFactory(IDynamicTypeFactoryInternal typeFactory, IReflectionManager reflectionManager, IConsoleHost conHost)
|
||||
{
|
||||
_typeFactory = typeFactory;
|
||||
_reflectionManager = reflectionManager;
|
||||
|
||||
conHost.RegisterCommand("dump_net_comps", "Prints the table of networked components.", "dump_net_comps", (shell, argStr, args) =>
|
||||
{
|
||||
if (_networkedComponents is null)
|
||||
{
|
||||
shell.WriteError("Registration still writeable, network ids have not been generated.");
|
||||
return;
|
||||
}
|
||||
|
||||
shell.WriteLine("Networked Component Registrations:");
|
||||
|
||||
for (int netId = 0; netId < _networkedComponents.Count; netId++)
|
||||
{
|
||||
var registration = _networkedComponents[netId];
|
||||
shell.WriteLine($" [{netId,4}] {registration.Name,-16} {registration.Type.Name}");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
[Obsolete("Use RegisterClass and Attributes instead of the Register/RegisterReference combo")]
|
||||
public void Register<T>(bool overwrite = false) where T : IComponent, new()
|
||||
{
|
||||
@@ -86,6 +114,9 @@ namespace Robust.Shared.GameObjects
|
||||
|
||||
private void Register(Type type, bool overwrite = false)
|
||||
{
|
||||
if (_networkedComponents is not null)
|
||||
throw new ComponentRegistrationLockException();
|
||||
|
||||
if (types.ContainsKey(type))
|
||||
{
|
||||
throw new InvalidOperationException($"Type is already registered: {type}");
|
||||
@@ -97,8 +128,6 @@ namespace Robust.Shared.GameObjects
|
||||
|
||||
var name = dummy.Name;
|
||||
var lowerCaseName = name.ToLowerInvariant();
|
||||
var netID = dummy.NetID;
|
||||
var netSyncExist = dummy.NetworkSynchronizeExistence;
|
||||
|
||||
if (IgnoredComponentNames.Contains(name))
|
||||
{
|
||||
@@ -128,24 +157,11 @@ namespace Robust.Shared.GameObjects
|
||||
}
|
||||
}
|
||||
|
||||
if (netID != null && netIDs.ContainsKey(netID.Value))
|
||||
{
|
||||
if (!overwrite)
|
||||
{
|
||||
throw new InvalidOperationException($"{name} has duplicate network ID {netID}, previous: {netIDs[netID.Value]}");
|
||||
}
|
||||
|
||||
RemoveComponent(netIDs[netID.Value].Name);
|
||||
}
|
||||
|
||||
var registration = new ComponentRegistration(name, type, netID, netSyncExist);
|
||||
var registration = new ComponentRegistration(name, type);
|
||||
names[name] = registration;
|
||||
_lowerCaseNames[lowerCaseName] = name;
|
||||
types[type] = registration;
|
||||
if (netID != null)
|
||||
{
|
||||
netIDs[netID.Value] = registration;
|
||||
}
|
||||
|
||||
ComponentAdded?.Invoke(registration);
|
||||
}
|
||||
|
||||
@@ -157,6 +173,9 @@ namespace Robust.Shared.GameObjects
|
||||
|
||||
private void RegisterReference(Type target, Type @interface)
|
||||
{
|
||||
if (_networkedComponents is not null)
|
||||
throw new ComponentRegistrationLockException();
|
||||
|
||||
if (!types.ContainsKey(target))
|
||||
{
|
||||
throw new InvalidOperationException($"Unregistered type: {target}");
|
||||
@@ -194,15 +213,14 @@ namespace Robust.Shared.GameObjects
|
||||
|
||||
private void RemoveComponent(string name)
|
||||
{
|
||||
if (_networkedComponents is not null)
|
||||
throw new ComponentRegistrationLockException();
|
||||
|
||||
var registration = names[name];
|
||||
|
||||
names.Remove(registration.Name);
|
||||
_lowerCaseNames.Remove(registration.Name.ToLowerInvariant());
|
||||
types.Remove(registration.Type);
|
||||
if (registration.NetID != null)
|
||||
{
|
||||
netIDs.Remove(registration.NetID.Value);
|
||||
}
|
||||
}
|
||||
|
||||
public ComponentAvailability GetComponentAvailability(string componentName, bool ignoreCase = false)
|
||||
@@ -253,7 +271,7 @@ namespace Robust.Shared.GameObjects
|
||||
return _typeFactory.CreateInstanceUnchecked<IComponent>(GetRegistration(componentName).Type);
|
||||
}
|
||||
|
||||
public IComponent GetComponent(uint netId)
|
||||
public IComponent GetComponent(ushort netId)
|
||||
{
|
||||
return _typeFactory.CreateInstanceUnchecked<IComponent>(GetRegistration(netId).Type);
|
||||
}
|
||||
@@ -275,11 +293,14 @@ namespace Robust.Shared.GameObjects
|
||||
}
|
||||
}
|
||||
|
||||
public IComponentRegistration GetRegistration(uint netID)
|
||||
public IComponentRegistration GetRegistration(ushort netID)
|
||||
{
|
||||
if (_networkedComponents is null)
|
||||
throw new ComponentRegistrationLockException();
|
||||
|
||||
try
|
||||
{
|
||||
return netIDs[netID];
|
||||
return _networkedComponents[netID];
|
||||
}
|
||||
catch (KeyNotFoundException)
|
||||
{
|
||||
@@ -343,9 +364,9 @@ namespace Robust.Shared.GameObjects
|
||||
return TryGetRegistration(typeof(T), out registration);
|
||||
}
|
||||
|
||||
public bool TryGetRegistration(uint netID, [NotNullWhen(true)] out IComponentRegistration? registration)
|
||||
public bool TryGetRegistration(ushort netID, [NotNullWhen(true)] out IComponentRegistration? registration)
|
||||
{
|
||||
if (netIDs.TryGetValue(netID, out var tempRegistration))
|
||||
if (_networkedComponents is not null && _networkedComponents.TryGetValue(netID, out var tempRegistration))
|
||||
{
|
||||
registration = tempRegistration;
|
||||
return true;
|
||||
@@ -406,15 +427,36 @@ namespace Robust.Shared.GameObjects
|
||||
return AllRegistrations.SelectMany(r => r.References).Distinct();
|
||||
}
|
||||
|
||||
public IEnumerable<uint> GetAllNetIds()
|
||||
/// <inheritdoc />
|
||||
public void GenerateNetIds()
|
||||
{
|
||||
foreach (var registration in AllRegistrations)
|
||||
// assumptions:
|
||||
// component names are guaranteed to be unique
|
||||
// component names are 1:1 with component concrete types
|
||||
|
||||
// a subset of component names are networked
|
||||
var networkedRegs = new List<IComponentRegistration>(names.Count);
|
||||
|
||||
foreach (var kvRegistration in names)
|
||||
{
|
||||
if (registration.NetID != null)
|
||||
var registration = kvRegistration.Value;
|
||||
if (Attribute.GetCustomAttribute(registration.Type, typeof(NetworkedComponentAttribute)) is NetworkedComponentAttribute)
|
||||
{
|
||||
yield return registration.NetID.Value;
|
||||
networkedRegs.Add(registration);
|
||||
}
|
||||
}
|
||||
|
||||
// The sorting implementation is unstable, but there are no duplicate names, so that isn't a problem.
|
||||
// Ordinal comparison is used so that the resulting order is always identical on every computer.
|
||||
networkedRegs.Sort((a, b) => string.Compare(a.Name, b.Name, StringComparison.Ordinal));
|
||||
|
||||
for (ushort i = 0; i < networkedRegs.Count; i++)
|
||||
{
|
||||
var registration = (ComponentRegistration) networkedRegs[i];
|
||||
registration.NetID = i;
|
||||
}
|
||||
|
||||
_networkedComponents = networkedRegs;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -434,4 +476,6 @@ namespace Robust.Shared.GameObjects
|
||||
SerializationInfo info,
|
||||
StreamingContext context) : base(info, context) { }
|
||||
}
|
||||
|
||||
public class ComponentRegistrationLockException : Exception { }
|
||||
}
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Internal.TypeSystem;
|
||||
using Robust.Shared.Exceptions;
|
||||
using Robust.Shared.Physics;
|
||||
using Robust.Shared.Serialization;
|
||||
@@ -28,7 +30,7 @@ namespace Robust.Shared.GameObjects
|
||||
private const int EntityCapacity = 1024;
|
||||
private const int NetComponentCapacity = 8;
|
||||
|
||||
private readonly Dictionary<EntityUid, Dictionary<uint, Component>> _netComponents
|
||||
private readonly Dictionary<EntityUid, Dictionary<ushort, Component>> _netComponents
|
||||
= new(EntityCapacity);
|
||||
|
||||
private readonly Dictionary<Type, Dictionary<EntityUid, Component>> _entTraitDict
|
||||
@@ -144,14 +146,14 @@ namespace Robust.Shared.GameObjects
|
||||
}
|
||||
|
||||
// add the component to the netId grid
|
||||
if (component.NetID != null)
|
||||
if (reg.NetID != null)
|
||||
{
|
||||
// the main comp grid keeps this in sync
|
||||
var netId = component.NetID.Value;
|
||||
var netId = reg.NetID.Value;
|
||||
|
||||
if (!_netComponents.TryGetValue(uid, out var netSet))
|
||||
{
|
||||
netSet = new Dictionary<uint, Component>(NetComponentCapacity);
|
||||
netSet = new Dictionary<ushort, Component>(NetComponentCapacity);
|
||||
_netComponents.Add(uid, netSet);
|
||||
}
|
||||
netSet.Add(netId, component);
|
||||
@@ -191,7 +193,7 @@ namespace Robust.Shared.GameObjects
|
||||
|
||||
/// <inheritdoc />
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void RemoveComponent(EntityUid uid, uint netId)
|
||||
public void RemoveComponent(EntityUid uid, ushort netId)
|
||||
{
|
||||
RemoveComponentDeferred((Component)GetComponent(uid, netId), uid, false);
|
||||
}
|
||||
@@ -335,13 +337,13 @@ namespace Robust.Shared.GameObjects
|
||||
}
|
||||
|
||||
// ReSharper disable once InvertIf
|
||||
if (component.NetID != null)
|
||||
if (reg.NetID != null)
|
||||
{
|
||||
var netSet = _netComponents[entityUid];
|
||||
if (netSet.Count == 1)
|
||||
_netComponents.Remove(entityUid);
|
||||
else
|
||||
netSet.Remove(component.NetID.Value);
|
||||
netSet.Remove(reg.NetID.Value);
|
||||
|
||||
component.Owner.Dirty();
|
||||
}
|
||||
@@ -367,7 +369,7 @@ namespace Robust.Shared.GameObjects
|
||||
|
||||
/// <inheritdoc />
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool HasComponent(EntityUid uid, uint netId)
|
||||
public bool HasComponent(EntityUid uid, ushort netId)
|
||||
{
|
||||
return _netComponents.TryGetValue(uid, out var netSet)
|
||||
&& netSet.ContainsKey(netId);
|
||||
@@ -397,7 +399,7 @@ namespace Robust.Shared.GameObjects
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IComponent GetComponent(EntityUid uid, uint netId)
|
||||
public IComponent GetComponent(EntityUid uid, ushort netId)
|
||||
{
|
||||
return _netComponents[uid][netId];
|
||||
}
|
||||
@@ -436,7 +438,7 @@ namespace Robust.Shared.GameObjects
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool TryGetComponent(EntityUid uid, uint netId, [MaybeNullWhen(false)] out IComponent component)
|
||||
public bool TryGetComponent(EntityUid uid, ushort netId, [MaybeNullWhen(false)] out IComponent component)
|
||||
{
|
||||
if (_netComponents.TryGetValue(uid, out var netSet)
|
||||
&& netSet.TryGetValue(netId, out var comp))
|
||||
@@ -474,9 +476,9 @@ namespace Robust.Shared.GameObjects
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IEnumerable<IComponent> GetNetComponents(EntityUid uid)
|
||||
public NetComponentEnumerable GetNetComponents(EntityUid uid)
|
||||
{
|
||||
return _netComponents[uid].Values;
|
||||
return new NetComponentEnumerable(_netComponents[uid]);
|
||||
}
|
||||
|
||||
#region Join Functions
|
||||
@@ -597,4 +599,30 @@ namespace Robust.Shared.GameObjects
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public readonly struct NetComponentEnumerable
|
||||
{
|
||||
private readonly Dictionary<ushort, Component> _dictionary;
|
||||
|
||||
public NetComponentEnumerable(Dictionary<ushort, Component> dictionary) => _dictionary = dictionary;
|
||||
public NetComponentEnumerator GetEnumerator() => new(_dictionary);
|
||||
}
|
||||
|
||||
public struct NetComponentEnumerator
|
||||
{
|
||||
// DO NOT MAKE THIS READONLY
|
||||
private Dictionary<ushort, Component>.Enumerator _dictEnum;
|
||||
|
||||
public NetComponentEnumerator(Dictionary<ushort, Component> dictionary) => _dictEnum = dictionary.GetEnumerator();
|
||||
public bool MoveNext() => _dictEnum.MoveNext();
|
||||
public (ushort netId, IComponent component) Current
|
||||
{
|
||||
get
|
||||
{
|
||||
var val = _dictEnum.Current;
|
||||
return (val.Key, val.Value);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +1,10 @@
|
||||
using Robust.Shared.Serialization;
|
||||
using System;
|
||||
using Robust.Shared.Analyzers;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Robust.Shared.GameObjects
|
||||
{
|
||||
[RequiresSerializable]
|
||||
[Serializable, NetSerializable]
|
||||
public class ComponentState
|
||||
{
|
||||
public uint NetID { get; }
|
||||
|
||||
public ComponentState(uint netID)
|
||||
{
|
||||
NetID = netID;
|
||||
}
|
||||
}
|
||||
public class ComponentState { }
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Robust.Shared.GameObjects
|
||||
@@ -11,10 +12,10 @@ namespace Robust.Shared.GameObjects
|
||||
/// The data works using a simple key/value system. It is recommended to use enum keys to prevent errors.
|
||||
/// Visualization works client side with overrides of the <c>AppearanceVisualizer</c> class.
|
||||
/// </summary>
|
||||
[NetworkedComponent()]
|
||||
public abstract class SharedAppearanceComponent : Component
|
||||
{
|
||||
public override string Name => "Appearance";
|
||||
public override uint? NetID => NetIDs.APPEARANCE;
|
||||
|
||||
public abstract void SetData(string key, object value);
|
||||
public abstract void SetData(Enum key, object value);
|
||||
@@ -30,7 +31,7 @@ namespace Robust.Shared.GameObjects
|
||||
{
|
||||
public readonly Dictionary<object, object> Data;
|
||||
|
||||
public AppearanceComponentState(Dictionary<object, object> data) : base(NetIDs.APPEARANCE)
|
||||
public AppearanceComponentState(Dictionary<object, object> data)
|
||||
{
|
||||
Data = data;
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace Robust.Shared.GameObjects
|
||||
{
|
||||
public Box2? LocalBounds { get; }
|
||||
|
||||
public ClickableComponentState(Box2? localBounds) : base(NetIDs.CLICKABLE)
|
||||
public ClickableComponentState(Box2? localBounds)
|
||||
{
|
||||
LocalBounds = localBounds;
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Robust.Shared.Containers;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Log;
|
||||
using Robust.Shared.Map;
|
||||
@@ -44,6 +45,7 @@ using Robust.Shared.ViewVariables;
|
||||
namespace Robust.Shared.GameObjects
|
||||
{
|
||||
[ComponentReference(typeof(IPhysBody))]
|
||||
[NetworkedComponent()]
|
||||
public sealed class PhysicsComponent : Component, IPhysBody, ISerializationHooks
|
||||
{
|
||||
[DataField("status", readOnly: true)]
|
||||
@@ -52,9 +54,6 @@ namespace Robust.Shared.GameObjects
|
||||
/// <inheritdoc />
|
||||
public override string Name => "Physics";
|
||||
|
||||
/// <inheritdoc />
|
||||
public override uint? NetID => NetIDs.PHYSICS;
|
||||
|
||||
/// <summary>
|
||||
/// Has this body been added to an island previously in this tick.
|
||||
/// </summary>
|
||||
|
||||
@@ -44,7 +44,6 @@ namespace Robust.Shared.GameObjects
|
||||
Vector2 linearVelocity,
|
||||
float angularVelocity,
|
||||
BodyType bodyType)
|
||||
: base(NetIDs.PHYSICS)
|
||||
{
|
||||
CanCollide = canCollide;
|
||||
SleepingAllowed = sleepingAllowed;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Physics;
|
||||
using Robust.Shared.Players;
|
||||
using Robust.Shared.Serialization;
|
||||
@@ -11,10 +12,10 @@ namespace Robust.Shared.GameObjects
|
||||
/// <summary>
|
||||
/// An optimisation component for stuff that should be set as collidable when it's awake and non-collidable when asleep.
|
||||
/// </summary>
|
||||
[NetworkedComponent()]
|
||||
public sealed class CollisionWakeComponent : Component
|
||||
{
|
||||
public override string Name => "CollisionWake";
|
||||
public override uint? NetID => NetIDs.COLLISION_WAKE;
|
||||
|
||||
[DataField("enabled")]
|
||||
private bool _enabled = true;
|
||||
@@ -64,7 +65,7 @@ namespace Robust.Shared.GameObjects
|
||||
{
|
||||
public bool Enabled { get; }
|
||||
|
||||
public CollisionWakeState(bool enabled) : base(NetIDs.COLLISION_WAKE)
|
||||
public CollisionWakeState(bool enabled)
|
||||
{
|
||||
Enabled = enabled;
|
||||
}
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
using System;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.ViewVariables;
|
||||
|
||||
namespace Robust.Shared.GameObjects
|
||||
{
|
||||
[NetworkedComponent()]
|
||||
public class SharedEyeComponent : Component
|
||||
{
|
||||
public override string Name => "Eye";
|
||||
public override uint? NetID => NetIDs.EYE;
|
||||
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public virtual bool DrawFov { get; set; }
|
||||
@@ -39,7 +40,7 @@ namespace Robust.Shared.GameObjects
|
||||
public Angle Rotation { get; }
|
||||
public uint VisibilityMask { get; }
|
||||
|
||||
public EyeComponentState(bool drawFov, Vector2 zoom, Vector2 offset, Angle rotation, uint visibilityMask) : base(NetIDs.EYE)
|
||||
public EyeComponentState(bool drawFov, Vector2 zoom, Vector2 offset, Angle rotation, uint visibilityMask)
|
||||
{
|
||||
DrawFov = drawFov;
|
||||
Zoom = zoom;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Prototypes;
|
||||
@@ -9,10 +10,10 @@ using Robust.Shared.ViewVariables;
|
||||
|
||||
namespace Robust.Shared.GameObjects
|
||||
{
|
||||
[NetworkedComponent()]
|
||||
public class OccluderComponent : Component
|
||||
{
|
||||
public sealed override string Name => "Occluder";
|
||||
public sealed override uint? NetID => NetIDs.OCCLUDER;
|
||||
|
||||
[DataField("enabled")]
|
||||
private bool _enabled = true;
|
||||
@@ -94,7 +95,7 @@ namespace Robust.Shared.GameObjects
|
||||
public bool Enabled { get; }
|
||||
public Box2 BoundingBox { get; }
|
||||
|
||||
public OccluderComponentState(bool enabled, Box2 boundingBox) : base(NetIDs.OCCLUDER)
|
||||
public OccluderComponentState(bool enabled, Box2 boundingBox)
|
||||
{
|
||||
Enabled = enabled;
|
||||
BoundingBox = boundingBox;
|
||||
|
||||
@@ -14,7 +14,6 @@ namespace Robust.Shared.GameObjects
|
||||
public readonly Vector2 Offset;
|
||||
|
||||
public PointLightComponentState(bool enabled, Color color, float radius, Vector2 offset)
|
||||
: base(NetIDs.POINT_LIGHT)
|
||||
{
|
||||
Enabled = enabled;
|
||||
Color = color;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Robust.Shared.Enums;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
using Robust.Shared.ViewVariables;
|
||||
|
||||
@@ -10,10 +11,10 @@ namespace Robust.Shared.GameObjects.Components.Localization
|
||||
/// Overrides grammar attributes specified in prototypes or localization files.
|
||||
/// </summary>
|
||||
[RegisterComponent]
|
||||
[NetworkedComponent()]
|
||||
public class GrammarComponent : Component
|
||||
{
|
||||
public override string Name => "Grammar";
|
||||
public override uint? NetID => NetIDs.GRAMMAR;
|
||||
|
||||
[ViewVariables]
|
||||
[DataField("attributes")]
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Players;
|
||||
using Robust.Shared.Serialization;
|
||||
@@ -18,6 +19,7 @@ namespace Robust.Shared.GameObjects
|
||||
|
||||
/// <inheritdoc cref="IMapComponent"/>
|
||||
[ComponentReference(typeof(IMapComponent))]
|
||||
[NetworkedComponent()]
|
||||
public class MapComponent : Component, IMapComponent
|
||||
{
|
||||
[ViewVariables(VVAccess.ReadOnly)]
|
||||
@@ -27,9 +29,6 @@ namespace Robust.Shared.GameObjects
|
||||
/// <inheritdoc />
|
||||
public override string Name => "Map";
|
||||
|
||||
/// <inheritdoc />
|
||||
public override uint? NetID => NetIDs.MAP_MAP;
|
||||
|
||||
/// <inheritdoc />
|
||||
public MapId WorldMap
|
||||
{
|
||||
@@ -73,7 +72,6 @@ namespace Robust.Shared.GameObjects
|
||||
public MapId MapId { get; }
|
||||
|
||||
public MapComponentState(MapId mapId)
|
||||
: base(NetIDs.MAP_MAP)
|
||||
{
|
||||
MapId = mapId;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Maths;
|
||||
@@ -25,6 +26,7 @@ namespace Robust.Shared.GameObjects
|
||||
|
||||
/// <inheritdoc cref="IMapGridComponent"/>
|
||||
[ComponentReference(typeof(IMapGridComponent))]
|
||||
[NetworkedComponent()]
|
||||
internal class MapGridComponent : Component, IMapGridComponent
|
||||
{
|
||||
[Dependency] private readonly IMapManager _mapManager = default!;
|
||||
@@ -36,9 +38,6 @@ namespace Robust.Shared.GameObjects
|
||||
/// <inheritdoc />
|
||||
public override string Name => "MapGrid";
|
||||
|
||||
/// <inheritdoc />
|
||||
public override uint? NetID => NetIDs.MAP_GRID;
|
||||
|
||||
/// <inheritdoc />
|
||||
public GridId GridIndex
|
||||
{
|
||||
@@ -145,7 +144,6 @@ namespace Robust.Shared.GameObjects
|
||||
/// </summary>
|
||||
/// <param name="gridIndex">Index of the grid this component is linked to.</param>
|
||||
public MapGridComponentState(GridId gridIndex)
|
||||
: base(NetIDs.MAP_GRID)
|
||||
{
|
||||
GridIndex = gridIndex;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Players;
|
||||
using Robust.Shared.Prototypes;
|
||||
@@ -35,7 +36,6 @@ namespace Robust.Shared.GameObjects
|
||||
/// <param name="description">The in-game description of this entity.</param>
|
||||
/// <param name="prototypeId">The prototype this entity was created from, if any.</param>
|
||||
public MetaDataComponentState(string? name, string? description, string? prototypeId)
|
||||
: base(NetIDs.META_DATA)
|
||||
{
|
||||
Name = name;
|
||||
Description = description;
|
||||
@@ -66,6 +66,7 @@ namespace Robust.Shared.GameObjects
|
||||
|
||||
/// <inheritdoc cref="IMetaDataComponent"/>
|
||||
[ComponentReference(typeof(IMetaDataComponent))]
|
||||
[NetworkedComponent()]
|
||||
internal class MetaDataComponent : Component, IMetaDataComponent
|
||||
{
|
||||
[Dependency] private readonly IPrototypeManager _prototypes = default!;
|
||||
@@ -79,9 +80,6 @@ namespace Robust.Shared.GameObjects
|
||||
/// <inheritdoc />
|
||||
public override string Name => "MetaData";
|
||||
|
||||
/// <inheritdoc />
|
||||
public override uint? NetID => NetIDs.META_DATA;
|
||||
|
||||
/// <inheritdoc />
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public string EntityName
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
namespace Robust.Shared.GameObjects
|
||||
{
|
||||
public static class NetIDs
|
||||
{
|
||||
public const uint MAP_MAP = 1;
|
||||
public const uint MAP_GRID = 2;
|
||||
public const uint META_DATA = 4;
|
||||
public const uint TRANSFORM = 5;
|
||||
public const uint SPRITE = 8;
|
||||
public const uint POINT_LIGHT = 10;
|
||||
public const uint PHYSICS = 12;
|
||||
public const uint CLICKABLE = 14;
|
||||
public const uint APPEARANCE = 22;
|
||||
public const uint USERINTERFACE = 24;
|
||||
public const uint CONTAINER_MANAGER = 25;
|
||||
public const uint OCCLUDER = 26;
|
||||
public const uint EYE = 28;
|
||||
public const uint GRAMMAR = 29;
|
||||
public const uint COLLISION_WAKE = 30;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
@@ -7,10 +8,10 @@ using Robust.Shared.Utility;
|
||||
|
||||
namespace Robust.Shared.GameObjects
|
||||
{
|
||||
[NetworkedComponent()]
|
||||
public abstract class SharedSpriteComponent : Component
|
||||
{
|
||||
public override string Name => "Sprite";
|
||||
public override uint? NetID => NetIDs.SPRITE;
|
||||
|
||||
public abstract bool Visible { get; set; }
|
||||
|
||||
@@ -42,7 +43,6 @@ namespace Robust.Shared.GameObjects
|
||||
string? baseRsiPath,
|
||||
List<PrototypeLayerData> layers,
|
||||
uint renderOrder)
|
||||
: base(NetIDs.SPRITE)
|
||||
{
|
||||
Visible = visible;
|
||||
DrawDepth = drawDepth;
|
||||
|
||||
@@ -4,6 +4,7 @@ using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using Robust.Shared.Animations;
|
||||
using Robust.Shared.Containers;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Maths;
|
||||
@@ -16,6 +17,7 @@ using Robust.Shared.ViewVariables;
|
||||
namespace Robust.Shared.GameObjects
|
||||
{
|
||||
[ComponentReference(typeof(ITransformComponent))]
|
||||
[NetworkedComponent()]
|
||||
internal class TransformComponent : Component, ITransformComponent, IComponentDebug
|
||||
{
|
||||
[DataField("parent")]
|
||||
@@ -54,9 +56,6 @@ namespace Robust.Shared.GameObjects
|
||||
/// <inheritdoc />
|
||||
public override string Name => "Transform";
|
||||
|
||||
/// <inheritdoc />
|
||||
public sealed override uint? NetID => NetIDs.TRANSFORM;
|
||||
|
||||
/// <inheritdoc />
|
||||
[ViewVariables]
|
||||
public MapId MapID { get; private set; }
|
||||
@@ -896,7 +895,6 @@ namespace Robust.Shared.GameObjects
|
||||
/// <param name="parentId">Current parent transform of this entity.</param>
|
||||
/// <param name="noLocalRotation"></param>
|
||||
public TransformComponentState(Vector2 localPosition, Angle rotation, EntityUid parentId, bool noLocalRotation, bool anchored)
|
||||
: base(NetIDs.TRANSFORM)
|
||||
{
|
||||
LocalPosition = localPosition;
|
||||
Rotation = rotation;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Reflection;
|
||||
using Robust.Shared.Serialization;
|
||||
@@ -6,10 +7,10 @@ using Robust.Shared.Serialization.Manager.Attributes;
|
||||
|
||||
namespace Robust.Shared.GameObjects
|
||||
{
|
||||
[NetworkedComponent()]
|
||||
public abstract class SharedUserInterfaceComponent : Component
|
||||
{
|
||||
public sealed override string Name => "UserInterface";
|
||||
public sealed override uint? NetID => NetIDs.USERINTERFACE;
|
||||
|
||||
[DataDefinition]
|
||||
public sealed class PrototypeData : ISerializationHooks
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace Robust.Shared.GameObjects
|
||||
|
||||
[IoC.Dependency] protected readonly IPrototypeManager PrototypeManager = default!;
|
||||
[IoC.Dependency] protected readonly IEntitySystemManager EntitySystemManager = default!;
|
||||
[IoC.Dependency] private readonly IComponentFactory ComponentFactory = default!;
|
||||
[IoC.Dependency] protected readonly IComponentFactory ComponentFactory = default!;
|
||||
[IoC.Dependency] private readonly IComponentManager _componentManager = default!;
|
||||
[IoC.Dependency] private readonly IMapManager _mapManager = default!;
|
||||
[IoC.Dependency] private readonly IGameTiming _gameTiming = default!;
|
||||
@@ -32,6 +32,8 @@ namespace Robust.Shared.GameObjects
|
||||
/// <inheritdoc />
|
||||
public GameTick CurrentTick => _gameTiming.CurTick;
|
||||
|
||||
IComponentFactory IEntityManager.ComponentFactory => ComponentFactory;
|
||||
|
||||
/// <inheritdoc />
|
||||
public IComponentManager ComponentManager => _componentManager;
|
||||
|
||||
@@ -479,7 +481,7 @@ namespace Robust.Shared.GameObjects
|
||||
var uid = netMsg.EntityUid;
|
||||
if (compMsg.Directed)
|
||||
{
|
||||
if (_componentManager.TryGetComponent(uid, netMsg.NetId, out var component))
|
||||
if (_componentManager.TryGetComponent(uid, (ushort) netMsg.NetId, out var component))
|
||||
component.HandleNetworkMessage(compMsg, compChannel, session);
|
||||
}
|
||||
else
|
||||
|
||||
@@ -7,61 +7,71 @@ namespace Robust.Shared.GameObjects
|
||||
public sealed class EntityState
|
||||
{
|
||||
public EntityUid Uid { get; }
|
||||
public ComponentChanged[]? ComponentChanges { get; }
|
||||
public ComponentState[]? ComponentStates { get; }
|
||||
|
||||
public bool Empty => ComponentChanges is null && ComponentStates is null;
|
||||
public ComponentChange[]? ComponentChanges { get; }
|
||||
|
||||
public EntityState(EntityUid uid, ComponentChanged[]? changedComponents, ComponentState[]? componentStates)
|
||||
public bool Empty => ComponentChanges is null;
|
||||
|
||||
public EntityState(EntityUid uid, ComponentChange[]? changedComponents)
|
||||
{
|
||||
Uid = uid;
|
||||
|
||||
// empty lists are 5 bytes each
|
||||
ComponentChanges = changedComponents == null || changedComponents.Length == 0 ? null : changedComponents;
|
||||
ComponentStates = componentStates == null || componentStates.Length == 0 ? null : componentStates;
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public readonly struct ComponentChanged
|
||||
public readonly struct ComponentChange
|
||||
{
|
||||
// 15ish bytes to create a component (strings are big), 5 bytes to remove one
|
||||
|
||||
/// <summary>
|
||||
/// Was the component added or removed from the entity.
|
||||
/// Was the component removed from the entity.
|
||||
/// </summary>
|
||||
public readonly bool Deleted;
|
||||
|
||||
/// <summary>
|
||||
/// The Network ID of the component to remove.
|
||||
/// Was the component added to the entity.
|
||||
/// </summary>
|
||||
public readonly uint NetID;
|
||||
public readonly bool Created;
|
||||
|
||||
/// <summary>
|
||||
/// The prototype name of the component to add.
|
||||
/// State data for the created/modified component, if any.
|
||||
/// </summary>
|
||||
public readonly string? ComponentName;
|
||||
public readonly ComponentState? State;
|
||||
|
||||
public ComponentChanged(bool deleted, uint netId, string? componentName)
|
||||
/// <summary>
|
||||
/// The Network ID of the component to remove.
|
||||
/// </summary>
|
||||
public readonly ushort NetID;
|
||||
|
||||
public ComponentChange(ushort netId, bool created, bool deleted, ComponentState? state)
|
||||
{
|
||||
Deleted = deleted;
|
||||
State = state;
|
||||
NetID = netId;
|
||||
ComponentName = componentName;
|
||||
Created = created;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{(Deleted ? "D" : "C")} {NetID} {ComponentName}";
|
||||
return $"{(Deleted ? "D" : "C")} {NetID} {State?.GetType().Name}";
|
||||
}
|
||||
|
||||
public static ComponentChanged Added(uint netId, string componentName)
|
||||
public static ComponentChange Added(ushort netId, ComponentState? state)
|
||||
{
|
||||
return new(false, netId, componentName);
|
||||
return new(netId, true, false, state);
|
||||
}
|
||||
|
||||
public static ComponentChanged Removed(uint netId)
|
||||
public static ComponentChange Changed(ushort netId, ComponentState state)
|
||||
{
|
||||
return new(true, netId, null);
|
||||
return new(netId, false, false, state);
|
||||
}
|
||||
|
||||
public static ComponentChange Removed(ushort netId)
|
||||
{
|
||||
return new(netId, false, true, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using System;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Network;
|
||||
using Robust.Shared.Players;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
namespace Robust.Shared.GameObjects
|
||||
@@ -13,16 +13,6 @@ namespace Robust.Shared.GameObjects
|
||||
/// </remarks>
|
||||
public interface IComponent
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the network ID for the component.
|
||||
/// The network ID is used to determine which component will receive the component state
|
||||
/// on the other side of the network.
|
||||
/// If this is <c>null</c>, the component is not replicated across the network.
|
||||
/// </summary>
|
||||
/// <seealso cref="NetworkSynchronizeExistence" />
|
||||
/// <seealso cref="IComponentRegistration.NetID" />
|
||||
uint? NetID { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Name that this component is represented with in prototypes.
|
||||
/// </summary>
|
||||
@@ -40,21 +30,11 @@ namespace Robust.Shared.GameObjects
|
||||
/// </summary>
|
||||
ComponentLifeStage LifeStage { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether the client should synchronize component additions and removals.
|
||||
/// If this is false and the component gets added or removed server side, the client will not do the same.
|
||||
/// If this is true and the server adds or removes the component, the client will do as such too.
|
||||
/// This flag has no effect if <see cref="NetID" /> is <c>null</c>.
|
||||
/// This is disabled by default, usually the client builds their instance from a prototype.
|
||||
/// </summary>
|
||||
/// <seealso cref="IComponentRegistration.NetworkSynchronizeExistence" />
|
||||
bool NetworkSynchronizeExistence { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether this component should be synchronized with clients when modified.
|
||||
/// If this is true, the server will synchronize all client instances with the data in this instance.
|
||||
/// If this is false, clients can modify the data in their instances without being overwritten by the server.
|
||||
/// This flag has no effect if <see cref="NetID" /> is <c>null</c>.
|
||||
/// This flag has no effect if <see cref="NetworkedComponentAttribute" /> is not defined on the component.
|
||||
/// This is enabled by default.
|
||||
/// </summary>
|
||||
bool NetSyncEnabled { get; }
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Robust.Shared.GameObjects
|
||||
@@ -58,6 +59,16 @@ namespace Robust.Shared.GameObjects
|
||||
/// </summary>
|
||||
IEnumerable<Type> AllRegisteredTypes { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The subset of all registered components that are networked, so that they can be
|
||||
/// referenced between the client and the server.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This will be null if the network Ids have not been generated yet.
|
||||
/// </remarks>
|
||||
/// <seealso cref="GenerateNetIds"/>
|
||||
IReadOnlyList<IComponentRegistration>? NetworkedComponents { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get whether a component is available right now.
|
||||
/// </summary>
|
||||
@@ -142,7 +153,7 @@ namespace Robust.Shared.GameObjects
|
||||
/// <exception cref="UnknownComponentException">
|
||||
/// Thrown if no component exists with the given id <see cref="netId"/>.
|
||||
/// </exception>
|
||||
IComponent GetComponent(uint netId);
|
||||
IComponent GetComponent(ushort netId);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the registration belonging to a component, throwing an exception if it does not exist.
|
||||
@@ -181,7 +192,7 @@ namespace Robust.Shared.GameObjects
|
||||
/// <exception cref="UnknownComponentException">
|
||||
/// Thrown if no component with id <see cref="netID"/> exists.
|
||||
/// </exception>
|
||||
IComponentRegistration GetRegistration(uint netID);
|
||||
IComponentRegistration GetRegistration(ushort netID);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the registration of a component, throwing an exception if
|
||||
@@ -225,7 +236,7 @@ namespace Robust.Shared.GameObjects
|
||||
/// <param name="netID">The network ID corresponding to the component.</param>
|
||||
/// <param name="registration">The registration if found, null otherwise.</param>
|
||||
/// <returns>true it found, false otherwise.</returns>
|
||||
bool TryGetRegistration(uint netID, [NotNullWhen(true)] out IComponentRegistration? registration);
|
||||
bool TryGetRegistration(ushort netID, [NotNullWhen(true)] out IComponentRegistration? registration);
|
||||
|
||||
/// <summary>
|
||||
/// Tries to get the registration of a component.
|
||||
@@ -241,8 +252,7 @@ namespace Robust.Shared.GameObjects
|
||||
void DoAutoRegistrations();
|
||||
|
||||
IEnumerable<Type> GetAllRefTypes();
|
||||
|
||||
IEnumerable<uint> GetAllNetIds();
|
||||
void GenerateNetIds();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -263,18 +273,8 @@ namespace Robust.Shared.GameObjects
|
||||
/// ID used to reference the component type across the network.
|
||||
/// If null, no network synchronization will be available for this component.
|
||||
/// </summary>
|
||||
/// <seealso cref="IComponent.NetID" />
|
||||
uint? NetID { get; }
|
||||
|
||||
/// <summary>
|
||||
/// True if the addition and removal of the component will be synchronized to clients.
|
||||
/// This means that if the server adds or removes the component outside of prototype-based creation,
|
||||
/// the client will update accordingly.
|
||||
/// If false the client will ignore missing components even when the net ID checks out and could be instantiated.
|
||||
/// and the client won't delete the component if no state was sent for it.
|
||||
/// </summary>
|
||||
/// <seealso cref="IComponent.NetworkSynchronizeExistence" />
|
||||
bool NetworkSynchronizeExistence { get; }
|
||||
/// <seealso cref="NetworkedComponentAttribute" />
|
||||
ushort? NetID { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The type that will be instantiated if this component is created.
|
||||
|
||||
@@ -72,7 +72,7 @@ namespace Robust.Shared.GameObjects
|
||||
/// </summary>
|
||||
/// <param name="uid">Entity UID to modify.</param>
|
||||
/// <param name="netID">Network ID of the component to remove.</param>
|
||||
void RemoveComponent(EntityUid uid, uint netID);
|
||||
void RemoveComponent(EntityUid uid, ushort netID);
|
||||
|
||||
/// <summary>
|
||||
/// Removes the specified component.
|
||||
@@ -118,7 +118,7 @@ namespace Robust.Shared.GameObjects
|
||||
/// <param name="uid">Entity UID to check.</param>
|
||||
/// <param name="netId">Network ID to check for.</param>
|
||||
/// <returns>True if the entity has a component with the given network ID, otherwise false.</returns>
|
||||
bool HasComponent(EntityUid uid, uint netId);
|
||||
bool HasComponent(EntityUid uid, ushort netId);
|
||||
|
||||
/// <summary>
|
||||
/// Returns the component of a specific type.
|
||||
@@ -143,7 +143,7 @@ namespace Robust.Shared.GameObjects
|
||||
/// <param name="uid">Entity UID to look on.</param>
|
||||
/// <param name="netId">Network ID of the component to retrieve.</param>
|
||||
/// <returns>The component with the specified network id.</returns>
|
||||
IComponent GetComponent(EntityUid uid, uint netId);
|
||||
IComponent GetComponent(EntityUid uid, ushort netId);
|
||||
|
||||
/// <summary>
|
||||
/// Returns the component of a specific type.
|
||||
@@ -171,7 +171,7 @@ namespace Robust.Shared.GameObjects
|
||||
/// <param name="netId">Component Network ID to check for.</param>
|
||||
/// <param name="component">Component with the specified network id.</param>
|
||||
/// <returns>If the component existed in the entity.</returns>
|
||||
bool TryGetComponent(EntityUid uid, uint netId, [NotNullWhen(true)] out IComponent? component);
|
||||
bool TryGetComponent(EntityUid uid, ushort netId, [NotNullWhen(true)] out IComponent? component);
|
||||
|
||||
/// <summary>
|
||||
/// Returns ALL component type instances on an entity. A single component instance
|
||||
@@ -195,7 +195,7 @@ namespace Robust.Shared.GameObjects
|
||||
/// </summary>
|
||||
/// <param name="uid">Entity UID to look on.</param>
|
||||
/// <returns>All components that have a network ID.</returns>
|
||||
IEnumerable<IComponent> GetNetComponents(EntityUid uid);
|
||||
NetComponentEnumerable GetNetComponents(EntityUid uid);
|
||||
|
||||
/// <summary>
|
||||
/// Returns ALL component instances of a specified type.
|
||||
|
||||
@@ -24,6 +24,7 @@ namespace Robust.Shared.GameObjects
|
||||
/// </summary>
|
||||
void FrameUpdate(float frameTime);
|
||||
|
||||
IComponentFactory ComponentFactory { get; }
|
||||
IComponentManager ComponentManager { get; }
|
||||
IEntitySystemManager EntitySysManager { get; }
|
||||
IEntityNetworkManager? EntityNetManager { get; }
|
||||
|
||||
10
Robust.Shared/GameStates/NetworkedComponentAttribute.cs
Normal file
10
Robust.Shared/GameStates/NetworkedComponentAttribute.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
using System;
|
||||
|
||||
namespace Robust.Shared.GameStates
|
||||
{
|
||||
/// <summary>
|
||||
/// This attribute marks a component as networked, so that it is replicated to clients.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
public class NetworkedComponentAttribute : Attribute { }
|
||||
}
|
||||
@@ -2,6 +2,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using JetBrains.Annotations;
|
||||
|
||||
namespace Robust.Shared.Utility
|
||||
{
|
||||
@@ -37,6 +38,18 @@ namespace Robust.Shared.Utility
|
||||
return dict;
|
||||
}
|
||||
|
||||
public static bool TryGetValue<T>(this IList<T> list, int index, out T value)
|
||||
{
|
||||
if (list.Count > index)
|
||||
{
|
||||
value = list[index];
|
||||
return true;
|
||||
}
|
||||
|
||||
value = default!;
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove an item from the list, replacing it with the one at the very end of the list.
|
||||
/// This means that the order will not be preserved, but it should be an O(1) operation.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
@@ -267,7 +267,6 @@ namespace Robust.UnitTesting.Server.GameObjects.Components
|
||||
var containerMan = entity.GetComponent<IContainerManager>();
|
||||
var state = (ContainerManagerComponent.ContainerManagerComponentState)containerMan.GetComponentState(new Mock<ICommonSession>().Object);
|
||||
|
||||
Assert.That(state.NetID, Is.EqualTo(containerMan.NetID));
|
||||
Assert.That(state.ContainerSet.Count, Is.EqualTo(1));
|
||||
Assert.That(state.ContainerSet[0].Id, Is.EqualTo("dummy"));
|
||||
Assert.That(state.ContainerSet[0].OccludesLight, Is.True);
|
||||
|
||||
@@ -62,6 +62,8 @@ namespace Robust.UnitTesting.Server.GameObjects.Components
|
||||
[OneTimeSetUp]
|
||||
public void Setup()
|
||||
{
|
||||
IoCManager.Resolve<IComponentFactory>().GenerateNetIds();
|
||||
|
||||
EntityManager = IoCManager.Resolve<IServerEntityManagerInternal>();
|
||||
MapManager = IoCManager.Resolve<IMapManager>();
|
||||
MapManager.CreateMap();
|
||||
|
||||
@@ -41,6 +41,7 @@ namespace Robust.UnitTesting.Server.GameObjects
|
||||
_componentFactory.RegisterClass<ThrowsInAddComponent>();
|
||||
_componentFactory.RegisterClass<ThrowsInInitializeComponent>();
|
||||
_componentFactory.RegisterClass<ThrowsInStartupComponent>();
|
||||
_componentFactory.GenerateNetIds();
|
||||
|
||||
EntityManager = IoCManager.Resolve<IServerEntityManager>();
|
||||
MapManager = IoCManager.Resolve<IMapManager>();
|
||||
|
||||
@@ -84,6 +84,7 @@ entities:
|
||||
{
|
||||
var compFactory = IoCManager.Resolve<IComponentFactory>();
|
||||
compFactory.RegisterClass<MapDeserializeTestComponent>();
|
||||
compFactory.GenerateNetIds();
|
||||
IoCManager.Resolve<ISerializationManager>().Initialize();
|
||||
|
||||
var resourceManager = IoCManager.Resolve<IResourceManagerInternal>();
|
||||
|
||||
@@ -10,6 +10,7 @@ using Robust.Server.Reflection;
|
||||
using Robust.Shared;
|
||||
using Robust.Shared.Asynchronous;
|
||||
using Robust.Shared.Configuration;
|
||||
using Robust.Shared.Console;
|
||||
using Robust.Shared.ContentPack;
|
||||
using Robust.Shared.Exceptions;
|
||||
using Robust.Shared.GameObjects;
|
||||
@@ -190,6 +191,7 @@ namespace Robust.UnitTesting.Server
|
||||
container.RegisterInstance<IGameTiming>(new Mock<IGameTiming>().Object); // TODO: get timing working similar to RobustIntegrationTest
|
||||
|
||||
//Tier 2: Simulation
|
||||
container.RegisterInstance<IConsoleHost>(new Mock<IConsoleHost>().Object); //Console is technically a frontend, we want to run headless
|
||||
container.Register<IEntityManager, EntityManager>();
|
||||
container.Register<IMapManager, MapManager>();
|
||||
container.Register<IEntityLookup, EntityLookup>();
|
||||
@@ -226,6 +228,8 @@ namespace Robust.UnitTesting.Server
|
||||
|
||||
_regDelegate?.Invoke(compFactory);
|
||||
|
||||
compFactory.GenerateNetIds();
|
||||
|
||||
var entityMan = container.Resolve<IEntityManager>();
|
||||
entityMan.Initialize();
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System.IO;
|
||||
using NUnit.Framework;
|
||||
using Robust.Shared.ContentPack;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
@@ -61,6 +62,9 @@ namespace Robust.UnitTesting.Shared.ContentPack
|
||||
[OneTimeSetUp]
|
||||
public void Setup()
|
||||
{
|
||||
var componentFactory = IoCManager.Resolve<IComponentFactory>();
|
||||
componentFactory.GenerateNetIds();
|
||||
|
||||
var stream = new MemoryStream(Data);
|
||||
var resourceManager = IoCManager.Resolve<IResourceManagerInternal>();
|
||||
resourceManager.MountStreamAt(stream, new ResourcePath("/a/b/c.dat"));
|
||||
|
||||
@@ -164,6 +164,7 @@ namespace Robust.UnitTesting.Shared.GameObjects
|
||||
componentFactory.RegisterClass<TestFiveComponent>();
|
||||
componentFactory.RegisterClass<TestSixComponent>();
|
||||
componentFactory.RegisterClass<TestSevenComponent>();
|
||||
componentFactory.GenerateNetIds();
|
||||
|
||||
IoCManager.Resolve<ISerializationManager>().Initialize();
|
||||
var prototypeManager = IoCManager.Resolve<IPrototypeManager>();
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.UnitTesting.Server;
|
||||
@@ -10,7 +11,6 @@ namespace Robust.UnitTesting.Shared.GameObjects
|
||||
[TestFixture, Parallelizable ,TestOf(typeof(ComponentManager))]
|
||||
public class ComponentManager_Tests
|
||||
{
|
||||
private const uint CompNetId = 3;
|
||||
private static readonly EntityCoordinates DefaultCoords = new(new EntityUid(1), Vector2.Zero);
|
||||
|
||||
[Test]
|
||||
@@ -98,13 +98,17 @@ namespace Robust.UnitTesting.Shared.GameObjects
|
||||
{
|
||||
// Arrange
|
||||
var sim = SimulationFactory();
|
||||
|
||||
var factory = sim.Resolve<IComponentFactory>();
|
||||
var netId = factory.GetRegistration<DummyComponent>().NetID!;
|
||||
|
||||
var entMan = sim.Resolve<IEntityManager>();
|
||||
var manager = sim.Resolve<IComponentManager>();
|
||||
var entity = entMan.SpawnEntity(null, DefaultCoords);
|
||||
entity.AddComponent<DummyComponent>();
|
||||
|
||||
// Act
|
||||
var result = manager.HasComponent(entity.Uid, CompNetId);
|
||||
var result = manager.HasComponent(entity.Uid, netId.Value);
|
||||
|
||||
// Assert
|
||||
Assert.That(result, Is.True);
|
||||
@@ -115,13 +119,17 @@ namespace Robust.UnitTesting.Shared.GameObjects
|
||||
{
|
||||
// Arrange
|
||||
var sim = SimulationFactory();
|
||||
|
||||
var factory = sim.Resolve<IComponentFactory>();
|
||||
var netId = factory.GetRegistration<DummyComponent>().NetID!;
|
||||
|
||||
var entMan = sim.Resolve<IEntityManager>();
|
||||
var manager = sim.Resolve<IComponentManager>();
|
||||
var entity = entMan.SpawnEntity(null, DefaultCoords);
|
||||
var component = entity.AddComponent<DummyComponent>();
|
||||
|
||||
// Act
|
||||
var result = manager.GetComponent(entity.Uid, CompNetId);
|
||||
var result = manager.GetComponent(entity.Uid, netId.Value);
|
||||
|
||||
// Assert
|
||||
Assert.That(result, Is.EqualTo(component));
|
||||
@@ -150,13 +158,17 @@ namespace Robust.UnitTesting.Shared.GameObjects
|
||||
{
|
||||
// Arrange
|
||||
var sim = SimulationFactory();
|
||||
|
||||
var factory = sim.Resolve<IComponentFactory>();
|
||||
var netId = factory.GetRegistration<DummyComponent>().NetID!;
|
||||
|
||||
var entMan = sim.Resolve<IEntityManager>();
|
||||
var manager = sim.Resolve<IComponentManager>();
|
||||
var entity = entMan.SpawnEntity(null, DefaultCoords);
|
||||
var component = entity.AddComponent<DummyComponent>();
|
||||
|
||||
// Act
|
||||
var result = manager.TryGetComponent(entity.Uid, CompNetId, out var comp);
|
||||
var result = manager.TryGetComponent(entity.Uid, netId.Value, out var comp);
|
||||
|
||||
// Assert
|
||||
Assert.That(result, Is.True);
|
||||
@@ -186,13 +198,17 @@ namespace Robust.UnitTesting.Shared.GameObjects
|
||||
{
|
||||
// Arrange
|
||||
var sim = SimulationFactory();
|
||||
|
||||
var factory = sim.Resolve<IComponentFactory>();
|
||||
var netId = factory.GetRegistration<DummyComponent>().NetID!;
|
||||
|
||||
var entMan = sim.Resolve<IEntityManager>();
|
||||
var manager = sim.Resolve<IComponentManager>();
|
||||
var entity = entMan.SpawnEntity(null, DefaultCoords);
|
||||
var component = entity.AddComponent<DummyComponent>();
|
||||
|
||||
// Act
|
||||
manager.RemoveComponent(entity.Uid, CompNetId);
|
||||
manager.RemoveComponent(entity.Uid, netId.Value);
|
||||
manager.CullRemovedComponents();
|
||||
|
||||
// Assert
|
||||
@@ -269,10 +285,10 @@ namespace Robust.UnitTesting.Shared.GameObjects
|
||||
return sim;
|
||||
}
|
||||
|
||||
[NetworkedComponent()]
|
||||
private class DummyComponent : Component, ICompType1, ICompType2
|
||||
{
|
||||
public override string Name => "Dummy";
|
||||
public override uint? NetID => CompNetId;
|
||||
}
|
||||
|
||||
private interface ICompType1 { }
|
||||
|
||||
@@ -60,11 +60,7 @@ namespace Robust.UnitTesting.Shared.GameObjects
|
||||
new EntityUid(512),
|
||||
new []
|
||||
{
|
||||
new ComponentChanged(false, NetIDs.MAP_GRID, nameof(MapGridComponent)),
|
||||
},
|
||||
new []
|
||||
{
|
||||
new MapGridComponentState(new GridId(0)),
|
||||
new ComponentChange(0, true, false, new MapGridComponentState(new GridId(0)))
|
||||
});
|
||||
|
||||
serializer.Serialize(stream, payload);
|
||||
|
||||
@@ -19,7 +19,6 @@ namespace Robust.UnitTesting.Shared.GameObjects.Systems
|
||||
|
||||
private class Subscriber : IEntityEventSubscriber { }
|
||||
|
||||
|
||||
private const string Prototypes = @"
|
||||
- type: entity
|
||||
name: anchoredEnt
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using NUnit.Framework;
|
||||
@@ -21,7 +21,9 @@ namespace Robust.UnitTesting.Shared.Localization
|
||||
public void Setup()
|
||||
{
|
||||
IoCManager.Resolve<ISerializationManager>().Initialize();
|
||||
IoCManager.Resolve<IComponentFactory>().RegisterClass<GrammarComponent>();
|
||||
var componentFactory = IoCManager.Resolve<IComponentFactory>();
|
||||
componentFactory.RegisterClass<GrammarComponent>();
|
||||
componentFactory.GenerateNetIds();
|
||||
|
||||
var res = IoCManager.Resolve<IResourceManagerInternal>();
|
||||
res.MountString("/Locale/en-US/a.ftl", FluentCode);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System.IO;
|
||||
using System.IO;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Robust.Server.GameObjects;
|
||||
@@ -44,6 +44,9 @@ namespace Robust.UnitTesting.Shared.Map
|
||||
var prototypeManager = IoCManager.Resolve<IPrototypeManager>();
|
||||
prototypeManager.LoadFromStream(new StringReader(PROTOTYPES));
|
||||
prototypeManager.Resync();
|
||||
|
||||
var factory = IoCManager.Resolve<IComponentFactory>();
|
||||
factory.GenerateNetIds();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -28,6 +28,12 @@ namespace Robust.UnitTesting.Shared.Map
|
||||
IoCManager.RegisterInstance<IEntitySystemManager>(mock.Object, true);
|
||||
}
|
||||
|
||||
[OneTimeSetUp]
|
||||
public void Setup()
|
||||
{
|
||||
IoCManager.Resolve<IComponentFactory>().GenerateNetIds();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetTileRefCoords()
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using NUnit.Framework;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
@@ -42,6 +42,7 @@ namespace Robust.UnitTesting.Shared.Prototypes
|
||||
_components = IoCManager.Resolve<IComponentFactory>();
|
||||
_components.RegisterClass<HotReloadTestComponentOne>();
|
||||
_components.RegisterClass<HotReloadTestComponentTwo>();
|
||||
_components.GenerateNetIds();
|
||||
|
||||
IoCManager.Resolve<ISerializationManager>().Initialize();
|
||||
_prototypes = (PrototypeManager) IoCManager.Resolve<IPrototypeManager>();
|
||||
|
||||
@@ -51,6 +51,7 @@ namespace Robust.UnitTesting.Shared.Serialization
|
||||
componentFactory.RegisterClass<BaseComponent>();
|
||||
componentFactory.RegisterClass<InheritorComponent>();
|
||||
componentFactory.RegisterClass<FinalComponent>();
|
||||
componentFactory.GenerateNetIds();
|
||||
|
||||
var serializationManager = IoCManager.Resolve<ISerializationManager>();
|
||||
serializationManager.Initialize();
|
||||
|
||||
Reference in New Issue
Block a user