From 0479a2198002afc8b02c6d2a84e873c981c79736 Mon Sep 17 00:00:00 2001 From: edmand45 Date: Sun, 9 Jul 2023 07:40:06 +0300 Subject: [PATCH] feat: added safe get entity by id --- Ragon.Client/Sources/Entity/RagonEntity.cs | 56 +++++++++++-------- Ragon.Client/Sources/RagonClient.cs | 41 ++++++++++---- Ragon.Client/Sources/RagonEntityCache.cs | 4 +- .../Sources/Handler/EntityCreateOperation.cs | 4 +- .../Sources/Handler/EntityEventOperation.cs | 13 ++--- 5 files changed, 72 insertions(+), 46 deletions(-) diff --git a/Ragon.Client/Sources/Entity/RagonEntity.cs b/Ragon.Client/Sources/Entity/RagonEntity.cs index 03621d2..b76db76 100644 --- a/Ragon.Client/Sources/Entity/RagonEntity.cs +++ b/Ragon.Client/Sources/Entity/RagonEntity.cs @@ -22,16 +22,17 @@ namespace Ragon.Client public sealed class RagonEntity { private delegate void OnEventDelegate(RagonPlayer player, RagonBuffer serializer); + private RagonClient _client; - + public ushort Id { get; private set; } public ushort Type { get; private set; } public bool Replication { get; private set; } - + public RagonAuthority Authority { get; private set; } public RagonPlayer Owner { get; private set; } public RagonEntityState State { get; private set; } - + public bool IsAttached { get; private set; } public bool HasAuthority { get; private set; } @@ -41,7 +42,7 @@ namespace Ragon.Client internal bool PropertiesChanged => _propertiesChanged; internal ushort SceneId => _sceneId; - + private ushort _sceneId; private bool _propertiesChanged; @@ -55,7 +56,7 @@ namespace Ragon.Client { State = new RagonEntityState(this); Type = type; - + _sceneId = sceneId; } @@ -67,17 +68,17 @@ namespace Ragon.Client IsAttached = true; Replication = true; HasAuthority = hasAuthority; - - _client = client; + + _client = client; _spawnPayload = payload; - + Attached?.Invoke(this); } internal void Detach(RagonPayload payload) { _destroyPayload = payload; - + Detached?.Invoke(); } @@ -91,6 +92,15 @@ namespace Ragon.Client return payload; } + + public void PreAttach(IRagonPayload payload) + { + var buffer = new RagonBuffer(); + payload.Serialize(buffer); + + _spawnPayload = new RagonPayload(); + _spawnPayload.Read(buffer); + } public T GetAttachPayload() where T : IRagonPayload, new() { @@ -110,7 +120,7 @@ namespace Ragon.Client RagonLog.Error("Entity not attached"); return; } - + var evntId = _client.Event.GetEventCode(evnt); var buffer = _client.Buffer; @@ -118,12 +128,12 @@ namespace Ragon.Client buffer.WriteOperation(RagonOperation.REPLICATE_ENTITY_EVENT); buffer.WriteUShort(Id); buffer.WriteUShort(evntId); - buffer.WriteByte((byte) replicationMode); - buffer.WriteByte((byte) RagonTarget.Player); + buffer.WriteByte((byte)replicationMode); + buffer.WriteByte((byte)RagonTarget.Player); buffer.WriteUShort(target.PeerId); evnt.Serialize(buffer); - + var sendData = buffer.ToArray(); _client.Reliable.Send(sendData); } @@ -139,7 +149,7 @@ namespace Ragon.Client RagonLog.Error("Entity not attached"); return; } - + if (target != RagonTarget.ExceptOwner) { if (replicationMode == RagonReplicationMode.Local) @@ -163,8 +173,8 @@ namespace Ragon.Client buffer.WriteOperation(RagonOperation.REPLICATE_ENTITY_EVENT); buffer.WriteUShort(Id); buffer.WriteUShort(evntId); - buffer.WriteByte((byte) replicationMode); - buffer.WriteByte((byte) target); + buffer.WriteByte((byte)replicationMode); + buffer.WriteByte((byte)target); evnt.Serialize(buffer); @@ -181,18 +191,18 @@ namespace Ragon.Client { _events.Remove(eventCode); _localEvents.Remove(eventCode); - + RagonLog.Warn($"Event already {eventCode} subscribed, removed old one!"); } - - _localEvents.Add(eventCode, (player, eventData) => { callback.Invoke(player, (TEvent) eventData); }); + + _localEvents.Add(eventCode, (player, eventData) => { callback.Invoke(player, (TEvent)eventData); }); _events.Add(eventCode, (player, serializer) => { t.Deserialize(serializer); callback.Invoke(player, t); }); } - + internal void Write(RagonBuffer buffer) { buffer.WriteUShort(Id); @@ -212,7 +222,7 @@ namespace Ragon.Client { if (_events.TryGetValue(eventCode, out var evnt)) evnt?.Invoke(caller, buffer); - else + else RagonLog.Warn($"Handler event on entity {Id} with eventCode {eventCode} not defined"); } @@ -224,10 +234,10 @@ namespace Ragon.Client public void OnOwnershipChanged(RagonPlayer player) { var prevOwner = Owner; - + Owner = player; HasAuthority = player.IsLocal; - + OwnershipChanged?.Invoke(prevOwner, player); } } diff --git a/Ragon.Client/Sources/RagonClient.cs b/Ragon.Client/Sources/RagonClient.cs index c7f4afb..25bb559 100644 --- a/Ragon.Client/Sources/RagonClient.cs +++ b/Ragon.Client/Sources/RagonClient.cs @@ -21,8 +21,8 @@ namespace Ragon.Client public sealed class RagonClient { private readonly INetworkConnection _connection; - private readonly IRagonEntityListener _entityListener; - private readonly IRagonSceneCollector _sceneCollector; + private IRagonEntityListener _entityListener; + private IRagonSceneCollector _sceneCollector; private Handler[] _handlers; private RagonBuffer _readBuffer; private RagonBuffer _writeBuffer; @@ -52,21 +52,15 @@ namespace Ragon.Client #region PUBLIC - public RagonClient( - INetworkConnection connection, - IRagonEntityListener entityListener, - IRagonSceneCollector sceneCollector, - int rate) + public RagonClient(INetworkConnection connection, int rate) { - _listenerList = new RagonListenerList(this); - _entityListener = entityListener; - _sceneCollector = sceneCollector; - _connection = connection; _connection.OnData += OnData; _connection.OnConnected += OnConnected; _connection.OnDisconnected += OnDisconnected; - + + _listenerList = new RagonListenerList(this); + _replicationRate = (1000.0f / rate) / 1000.0f; _replicationTime = 0; @@ -74,9 +68,32 @@ namespace Ragon.Client _stats = new NetworkStatistics(); _status = RagonStatus.DISCONNECTED; } + + + public void Configure(IRagonSceneCollector sceneCollector) + { + _sceneCollector = sceneCollector; + } + + public void Configure(IRagonEntityListener listener) + { + _entityListener = listener; + } public void Connect(string address, ushort port, string protocol) { + if (_sceneCollector == null) + { + RagonLog.Error("Scene collector is not defined!"); + return; + } + + if (_entityListener == null) + { + RagonLog.Error("Entity Listener is not defined!"); + return; + } + _writeBuffer = new RagonBuffer(); _readBuffer = new RagonBuffer(); _session = new RagonSession(this, _readBuffer); diff --git a/Ragon.Client/Sources/RagonEntityCache.cs b/Ragon.Client/Sources/RagonEntityCache.cs index 0563c50..34ac98c 100644 --- a/Ragon.Client/Sources/RagonEntityCache.cs +++ b/Ragon.Client/Sources/RagonEntityCache.cs @@ -45,9 +45,9 @@ public sealed class RagonEntityCache _playerCache = playerCache; } - public RagonEntity FindById(ushort id) + public bool TryGetEntity(ushort id, out RagonEntity entity) { - return _entityMap[id]; + return _entityMap.TryGetValue(id, out entity); } public void Create(RagonEntity entity, IRagonPayload? spawnPayload) diff --git a/Ragon.Server/Sources/Handler/EntityCreateOperation.cs b/Ragon.Server/Sources/Handler/EntityCreateOperation.cs index b3eff0d..c419d8c 100644 --- a/Ragon.Server/Sources/Handler/EntityCreateOperation.cs +++ b/Ragon.Server/Sources/Handler/EntityCreateOperation.cs @@ -54,8 +54,8 @@ public sealed class EntityCreateOperation : IRagonOperation if (reader.Capacity > 0) entity.Payload.Read(reader); - var roomPlugin = room.Plugin; - if (!roomPlugin.OnEntityCreate(player, entity)) + var plugin = room.Plugin; + if (!plugin.OnEntityCreate(player, entity)) return; entity.Attach(player); diff --git a/Ragon.Server/Sources/Handler/EntityEventOperation.cs b/Ragon.Server/Sources/Handler/EntityEventOperation.cs index 18192b8..069c9d3 100644 --- a/Ragon.Server/Sources/Handler/EntityEventOperation.cs +++ b/Ragon.Server/Sources/Handler/EntityEventOperation.cs @@ -40,20 +40,19 @@ public sealed class EntityEventOperation : IRagonOperation var eventMode = (RagonReplicationMode)reader.ReadByte(); var targetMode = (RagonTarget)reader.ReadByte(); var targetPlayerPeerId = (ushort)0; - + if (targetMode == RagonTarget.Player) targetPlayerPeerId = reader.ReadUShort(); - var ragonEvent = new RagonEvent(player, eventId); - ragonEvent.Read(reader); + var @event = new RagonEvent(player, eventId); + @event.Read(reader); - if (targetMode == RagonTarget.Player && - context.Room.Players.TryGetValue(targetPlayerPeerId, out var targetPlayer)) + if (targetMode == RagonTarget.Player && room.Players.TryGetValue(targetPlayerPeerId, out var targetPlayer)) { - ent.ReplicateEvent(player, ragonEvent, eventMode, targetPlayer); + ent.ReplicateEvent(player, @event, eventMode, targetPlayer); return; } - ent.ReplicateEvent(player, ragonEvent, eventMode, targetMode); + ent.ReplicateEvent(player, @event, eventMode, targetMode); } } \ No newline at end of file