Removed the IEntityManager dependency out of EntityNetManager.

Removed the component message queue inside of EntityManager. There should be no time where messages are coming in before the EntityManager is initialized.
Removed the ability to send EntityEvents, you need to send either component or system messages.
This commit is contained in:
Acruid
2020-02-27 16:01:19 -08:00
parent 8f968760cb
commit d7e0edd1a3
9 changed files with 112 additions and 216 deletions

View File

@@ -7,30 +7,37 @@ using Robust.Shared.Network.Messages;
namespace Robust.Client.GameObjects
{
/// <summary>
/// The client implementation of the Entity Network Manager.
/// </summary>
public class ClientEntityNetworkManager : IEntityNetworkManager
{
#pragma warning disable 649
[Dependency] private readonly IClientNetManager _network;
[Dependency] private readonly IEntityManager _entityManager;
[Dependency] private readonly IClientNetManager _networkManager;
#pragma warning restore 649
/// <inheritdoc />
public event EventHandler<NetworkComponentMessage> ReceivedComponentMessage;
/// <inheritdoc />
public event EventHandler<EntitySystemMessage> ReceivedSystemMessage;
/// <inheritdoc />
public void SetupNetworking()
{
_network.RegisterNetMessage<MsgEntity>(MsgEntity.NAME, HandleEntityNetworkMessage);
_networkManager.RegisterNetMessage<MsgEntity>(MsgEntity.NAME, HandleEntityNetworkMessage);
}
/// <summary>
/// Sends a message to the relevant system(s) server side.
/// </summary>
/// <inheritdoc />
public void SendSystemNetworkMessage(EntitySystemMessage message)
{
var msg = _network.CreateNetMessage<MsgEntity>();
var msg = _networkManager.CreateNetMessage<MsgEntity>();
msg.Type = EntityMessageType.SystemMessage;
msg.SystemMessage = message;
_network.ClientSendMessage(msg);
_networkManager.ClientSendMessage(msg);
}
/// <inheritdoc />
public void SendSystemNetworkMessage(EntitySystemMessage message, INetChannel channel)
{
throw new NotSupportedException();
@@ -42,42 +49,24 @@ namespace Robust.Client.GameObjects
if (!component.NetID.HasValue)
throw new ArgumentException($"Component {component.Name} does not have a NetID.", nameof(component));
var msg = _network.CreateNetMessage<MsgEntity>();
var msg = _networkManager.CreateNetMessage<MsgEntity>();
msg.Type = EntityMessageType.ComponentMessage;
msg.EntityUid = entity.Uid;
msg.NetId = component.NetID.Value;
msg.ComponentMessage = message;
_network.ClientSendMessage(msg);
_networkManager.ClientSendMessage(msg);
}
/// <inheritdoc />
public void SendEntityNetworkMessage(IEntity entity, EntityEventArgs message)
{
var msg = _network.CreateNetMessage<MsgEntity>();
msg.Type = EntityMessageType.EntityMessage;
msg.EntityUid = entity.Uid;
msg.EntityMessage = message;
_network.ClientSendMessage(msg);
}
/// <summary>
/// Converts a raw NetIncomingMessage to an IncomingEntityMessage object
/// </summary>
/// <param name="message">raw network message</param>
/// <returns>An IncomingEntityMessage object</returns>
private void HandleEntityNetworkMessage(MsgEntity message)
{
switch (message.Type)
{
case EntityMessageType.ComponentMessage:
_entityManager.HandleEntityNetworkMessage(message);
return;
case EntityMessageType.EntityMessage:
ReceivedComponentMessage?.Invoke(this, new NetworkComponentMessage(message));
return;
case EntityMessageType.SystemMessage:
_entityManager.EventBus.RaiseEvent(EventSource.Network, message.SystemMessage);
ReceivedSystemMessage?.Invoke(this, message.SystemMessage);
return;
}
}

View File

@@ -7,37 +7,37 @@ using Robust.Shared.Network.Messages;
namespace Robust.Server.GameObjects
{
/// <summary>
/// The server implementation of the Entity Network Manager.
/// </summary>
public class ServerEntityNetworkManager : IEntityNetworkManager
{
#pragma warning disable 649
[Dependency] private readonly IServerNetManager _mNetManager;
[Dependency] private readonly IEntityManager _entityManager;
[Dependency] private readonly IServerNetManager _networkManager;
#pragma warning restore 649
#region IEntityNetworkManager Members
/// <inheritdoc />
public event EventHandler<NetworkComponentMessage> ReceivedComponentMessage;
/// <inheritdoc />
public event EventHandler<EntitySystemMessage> ReceivedSystemMessage;
/// <inheritdoc />
public void SetupNetworking()
{
_mNetManager.RegisterNetMessage<MsgEntity>(MsgEntity.NAME, HandleEntityNetworkMessage);
}
/// <inheritdoc />
public void SendEntityNetworkMessage(IEntity entity, EntityEventArgs message)
{
throw new NotImplementedException();
_networkManager.RegisterNetMessage<MsgEntity>(MsgEntity.NAME, HandleEntityNetworkMessage);
}
/// <inheritdoc />
public void SendComponentNetworkMessage(INetChannel channel, IEntity entity, IComponent component, ComponentMessage message)
{
if (_mNetManager.IsClient)
if (_networkManager.IsClient)
return;
if (!component.NetID.HasValue)
throw new ArgumentException($"Component {component.Name} does not have a NetID.", nameof(component));
var msg = _mNetManager.CreateNetMessage<MsgEntity>();
var msg = _networkManager.CreateNetMessage<MsgEntity>();
msg.Type = EntityMessageType.ComponentMessage;
msg.EntityUid = entity.Uid;
msg.NetId = component.NetID.Value;
@@ -45,63 +45,41 @@ namespace Robust.Server.GameObjects
//Send the message
if (channel == null)
{
_mNetManager.ServerSendToAll(msg);
}
_networkManager.ServerSendToAll(msg);
else
{
_mNetManager.ServerSendMessage(msg, channel);
}
_networkManager.ServerSendMessage(msg, channel);
}
#endregion IEntityNetworkManager Members
#region Sending
/// <summary>
/// Sends a message to the relevant system(s) on all clients.
/// </summary>
/// <inheritdoc />
public void SendSystemNetworkMessage(EntitySystemMessage message)
{
var newMsg = _mNetManager.CreateNetMessage<MsgEntity>();
var newMsg = _networkManager.CreateNetMessage<MsgEntity>();
newMsg.Type = EntityMessageType.SystemMessage;
newMsg.SystemMessage = message;
_mNetManager.ServerSendToAll(newMsg);
_networkManager.ServerSendToAll(newMsg);
}
/// <summary>
/// Sends a message to the relevant system(s) on the target client.
/// </summary>
/// <inheritdoc />
public void SendSystemNetworkMessage(EntitySystemMessage message, INetChannel targetConnection)
{
var newMsg = _mNetManager.CreateNetMessage<MsgEntity>();
var newMsg = _networkManager.CreateNetMessage<MsgEntity>();
newMsg.Type = EntityMessageType.SystemMessage;
newMsg.SystemMessage = message;
_mNetManager.ServerSendMessage(newMsg, targetConnection);
_networkManager.ServerSendMessage(newMsg, targetConnection);
}
#endregion Sending
/// <summary>
/// Handles an incoming entity message
/// </summary>
/// <param name="message"></param>
/// <returns></returns>
private void HandleEntityNetworkMessage(MsgEntity message)
{
switch (message.Type)
{
case EntityMessageType.ComponentMessage:
_entityManager.HandleEntityNetworkMessage(message);
return;
case EntityMessageType.EntityMessage:
ReceivedComponentMessage?.Invoke(this, new NetworkComponentMessage(message));
return;
case EntityMessageType.SystemMessage:
_entityManager.EventBus.RaiseEvent(EventSource.Network, message.SystemMessage);
ReceivedSystemMessage?.Invoke(this, message.SystemMessage);
return;
}
}

View File

@@ -14,13 +14,6 @@ namespace Robust.Shared.GameObjects
/// </summary>
public bool Remote { get; internal set; }
/// <summary>
/// If this is a remote message, should it be sent back to where it came from?
/// You want to set this to true if this message is mutable and is being sent over the network.
/// If this is not a remote message, this flag does nothing.
/// </summary>
public bool Reply { get; protected set; }
/// <summary>
/// If this is a remote message, will it only be sent to the corresponding component?
/// If this is not a remote message, this flag does nothing.

View File

@@ -11,7 +11,6 @@ using Robust.Shared.Interfaces.Timing;
using Robust.Shared.IoC;
using Robust.Shared.Map;
using Robust.Shared.Maths;
using Robust.Shared.Network.Messages;
using Robust.Shared.Physics;
using Robust.Shared.Prototypes;
using Robust.Shared.Timing;
@@ -52,8 +51,6 @@ namespace Robust.Shared.GameObjects
protected readonly List<IEntity> AllEntities = new List<IEntity>();
protected readonly Queue<IncomingEntityMessage> NetworkMessageBuffer = new Queue<IncomingEntityMessage>();
private readonly IEntityEventBus _eventBus = new EntityEventBus();
/// <inheritdoc />
@@ -64,6 +61,9 @@ namespace Robust.Shared.GameObjects
public virtual void Initialize()
{
EntityNetworkManager.SetupNetworking();
EntityNetworkManager.ReceivedComponentMessage += (sender, compMsg) => DispatchComponentMessage(compMsg);
EntityNetworkManager.ReceivedSystemMessage += (sender, systemMsg) => EventBus.RaiseEvent(EventSource.Network, systemMsg);
ComponentManager.Clear();
_componentManager.ComponentRemoved += (sender, args) => _eventBus.UnsubscribeEvents(args.Component);
}
@@ -82,7 +82,6 @@ namespace Robust.Shared.GameObjects
public virtual void Update(float frameTime)
{
ProcessMessageBuffer();
EntitySystemManager.Update(frameTime);
_eventBus.ProcessEventQueue();
CullDeletedEntities();
@@ -340,76 +339,16 @@ namespace Robust.Shared.GameObjects
#endregion Entity Management
#region message processing
/// <inheritdoc />
public void HandleEntityNetworkMessage(MsgEntity msg)
private void DispatchComponentMessage(NetworkComponentMessage netMsg)
{
var incomingEntity = new IncomingEntityMessage(msg);
if (!Started)
{
if (incomingEntity.Message.Type != EntityMessageType.Error)
NetworkMessageBuffer.Enqueue(incomingEntity);
return;
}
if (!Entities.TryGetValue(incomingEntity.Message.EntityUid, out _))
NetworkMessageBuffer.Enqueue(incomingEntity);
else
ProcessEntityMessage(incomingEntity.Message);
}
private void ProcessMessageBuffer()
{
if (!Started) return;
if (NetworkMessageBuffer.Count == 0) return;
var misses = new List<IncomingEntityMessage>();
while (NetworkMessageBuffer.Count != 0)
{
var incomingEntity = NetworkMessageBuffer.Dequeue();
if (!Entities.TryGetValue(incomingEntity.Message.EntityUid, out var entity))
{
incomingEntity.LastProcessingAttempt = DateTime.Now;
if ((incomingEntity.LastProcessingAttempt - incomingEntity.ReceivedTime).TotalSeconds >
incomingEntity.Expires)
misses.Add(incomingEntity);
}
else
{
ProcessEntityMessage(incomingEntity.Message);
}
}
foreach (var miss in misses)
{
NetworkMessageBuffer.Enqueue(miss);
}
}
private void ProcessEntityMessage(MsgEntity msgEntity)
{
switch (msgEntity.Type)
{
case EntityMessageType.ComponentMessage:
DispatchComponentMessage(msgEntity);
break;
}
}
private void DispatchComponentMessage(MsgEntity msgEntity)
{
var compMsg = msgEntity.ComponentMessage;
var compChannel = msgEntity.MsgChannel;
var compMsg = netMsg.Message;
var compChannel = netMsg.Channel;
compMsg.Remote = true;
var uid = msgEntity.EntityUid;
var uid = netMsg.EntityUid;
if (compMsg.Directed)
{
if (_componentManager.TryGetComponent(uid, msgEntity.NetId, out var component))
if (_componentManager.TryGetComponent(uid, netMsg.NetId, out var component))
component.HandleMessage(compMsg, compChannel);
}
else
@@ -421,8 +360,6 @@ namespace Robust.Shared.GameObjects
}
}
#endregion message processing
protected abstract EntityUid GenerateEntityUid();
#region Spatial Queries
@@ -652,7 +589,6 @@ namespace Robust.Shared.GameObjects
{
Error = 0,
ComponentMessage,
EntityMessage,
SystemMessage
}
}

View File

@@ -4,8 +4,21 @@ using Robust.Shared.Interfaces.Network;
namespace Robust.Shared.GameObjects
{
/// <summary>
/// Manages the sending and receiving of network messages between the server and client(s).
/// </summary>
public interface IEntityNetworkManager
{
/// <summary>
/// This event is raised when a component message comes in from the network.
/// </summary>
event EventHandler<NetworkComponentMessage> ReceivedComponentMessage;
/// <summary>
/// This event is raised when a component message comes in from the network.
/// </summary>
event EventHandler<EntitySystemMessage> ReceivedSystemMessage;
/// <summary>
/// Initializes networking for this manager. This should only be called once.
/// </summary>
@@ -25,13 +38,6 @@ namespace Robust.Shared.GameObjects
void SendComponentNetworkMessage(INetChannel channel, IEntity entity, IComponent component,
ComponentMessage message);
/// <summary>
/// Sends an arbitrary entity network message
/// </summary>
/// <param name="entity">The entity the message is going from(and to, on the other end)</param>
/// <param name="message">Message that should be sent.</param>
void SendEntityNetworkMessage(IEntity entity, EntityEventArgs message);
/// <summary>
/// Sends an Entity System Message to relevant System(s).
/// Client: Sends the message to the relevant server side System(s).

View File

@@ -1,21 +0,0 @@
using System;
using Robust.Shared.Network.Messages;
namespace Robust.Shared.GameObjects
{
public class IncomingEntityMessage
{
public MsgEntity Message { get; set; }
public ushort Expires { get; set; }
public DateTime LastProcessingAttempt { get; set; }
public DateTime ReceivedTime { get; set; }
public IncomingEntityMessage(MsgEntity message)
{
Message = message;
LastProcessingAttempt = DateTime.Now;
ReceivedTime = DateTime.Now;
Expires = 30;
}
}
}

View File

@@ -0,0 +1,50 @@
using Robust.Shared.Interfaces.Network;
using Robust.Shared.Network.Messages;
using Robust.Shared.Utility;
namespace Robust.Shared.GameObjects
{
#nullable enable
/// <summary>
/// A container that holds a component message and network info.
/// </summary>
public readonly struct NetworkComponentMessage
{
/// <summary>
/// Network channel this message came from.
/// </summary>
public readonly INetChannel Channel;
/// <summary>
/// Entity Uid this message is associated with.
/// </summary>
public readonly EntityUid EntityUid;
/// <summary>
/// If the Message is Directed, Component net Uid this message is being sent to.
/// </summary>
public readonly uint NetId;
/// <summary>
/// The message payload.
/// </summary>
public readonly ComponentMessage Message;
/// <summary>
/// Constructs a new instance of <see cref="NetworkComponentMessage"/>.
/// </summary>
/// <param name="netMsg">Raw network message containing the component message.</param>
public NetworkComponentMessage(MsgEntity netMsg)
{
DebugTools.Assert(netMsg.Type == EntityMessageType.ComponentMessage);
Channel = netMsg.MsgChannel;
EntityUid = netMsg.EntityUid;
NetId = netMsg.NetId;
Message = netMsg.ComponentMessage;
}
}
#nullable restore
}

View File

@@ -2,7 +2,6 @@
using Robust.Shared.GameObjects;
using Robust.Shared.Map;
using Robust.Shared.Maths;
using Robust.Shared.Network.Messages;
using Robust.Shared.Timing;
namespace Robust.Shared.Interfaces.GameObjects
@@ -106,16 +105,6 @@ namespace Robust.Shared.Interfaces.GameObjects
#endregion Entity Management
#region ComponentEvents
/// <summary>
/// Converts a raw NetIncomingMessage to an IncomingEntityMessage object
/// </summary>
/// <param name="message">raw network message</param>
/// <returns>An IncomingEntityMessage object</returns>
void HandleEntityNetworkMessage(MsgEntity message);
#endregion ComponentEvents
#region Spatial Queries
/// <summary>

View File

@@ -21,7 +21,6 @@ namespace Robust.Shared.Network.Messages
public EntityMessageType Type { get; set; }
public EntitySystemMessage SystemMessage { get; set; }
public EntityEventArgs EntityMessage { get; set; }
public ComponentMessage ComponentMessage { get; set; }
public EntityUid EntityUid { get; set; }
@@ -44,18 +43,7 @@ namespace Robust.Shared.Network.Messages
}
}
break;
case EntityMessageType.EntityMessage:
{
EntityUid = new EntityUid(buffer.ReadInt32());
var serializer = IoCManager.Resolve<IRobustSerializer>();
int messageLength = buffer.ReadInt32();
using (var stream = new MemoryStream(buffer.ReadBytes(messageLength)))
{
EntityMessage = serializer.Deserialize<EntityEventArgs>(stream);
}
}
break;
case EntityMessageType.ComponentMessage:
{
EntityUid = new EntityUid(buffer.ReadInt32());
@@ -89,19 +77,7 @@ namespace Robust.Shared.Network.Messages
}
}
break;
case EntityMessageType.EntityMessage:
{
buffer.Write((int)EntityUid);
var serializer = IoCManager.Resolve<IRobustSerializer>();
using (var stream = new MemoryStream())
{
serializer.Serialize(stream, EntityMessage);
buffer.Write((int)stream.Length);
buffer.Write(stream.ToArray());
}
}
break;
case EntityMessageType.ComponentMessage:
{
buffer.Write((int)EntityUid);