diff --git a/Ragon.Client/Sources/Entity/RagonEntity.cs b/Ragon.Client/Sources/Entity/RagonEntity.cs index 5268eb8..c0cfce5 100644 --- a/Ragon.Client/Sources/Entity/RagonEntity.cs +++ b/Ragon.Client/Sources/Entity/RagonEntity.cs @@ -19,8 +19,31 @@ using Ragon.Protocol; namespace Ragon.Client { - public sealed class RagonEntity: IDisposable + public sealed class RagonEntity : IDisposable { + private class EventSubscription : IDisposable + { + private List> _callbacks; + private List> _localCallbacks; + private Action _callback; + + public EventSubscription( + List> callbacks, + List> localCallbacks, + Action callback) + { + _callbacks = callbacks; + _localCallbacks = localCallbacks; + _callback = callback; + } + + public void Dispose() + { + _callbacks.Remove(_callback); + _localCallbacks.Remove(_callback); + } + } + private delegate void OnEventDelegate(RagonPlayer player, RagonBuffer serializer); private RagonClient _client; @@ -189,19 +212,18 @@ namespace Ragon.Client _client.Reliable.Send(sendData); } - public Action OnEvent(Action callback) where TEvent : IRagonEvent, new() + public IDisposable OnEvent(Action callback) where TEvent : IRagonEvent, new() { var t = new TEvent(); var eventCode = _client.Event.GetEventCode(t); - var action = (RagonPlayer player, IRagonEvent eventData) => callback.Invoke(player, (TEvent)eventData); - + if (!_listeners.TryGetValue(eventCode, out var callbacks)) { callbacks = new List>(); _listeners.Add(eventCode, callbacks); } - + if (!_localListeners.TryGetValue(eventCode, out var localCallbacks)) { localCallbacks = new List>(); @@ -222,19 +244,7 @@ namespace Ragon.Client }); } - return action; - } - - public void OffEvent(Action callback) where TEvent : IRagonEvent, new() - { - var t = new TEvent(); - var eventCode = _client.Event.GetEventCode(t); - - if (_listeners.TryGetValue(eventCode, out var callbacks)) - callbacks.Remove(callback); - - if (_localListeners.TryGetValue(eventCode, out var localCallbacks)) - localCallbacks.Remove(callback); + return new EventSubscription(callbacks, localCallbacks, action); } internal void Write(RagonBuffer buffer) diff --git a/Ragon.Server/Sources/Handler/RoomDataOperation.cs b/Ragon.Server/Sources/Handler/RoomDataOperation.cs index ac42d18..9d35986 100644 --- a/Ragon.Server/Sources/Handler/RoomDataOperation.cs +++ b/Ragon.Server/Sources/Handler/RoomDataOperation.cs @@ -30,21 +30,20 @@ public sealed class RoomDataOperation : BaseOperation { var player = context.RoomPlayer; var room = context.Room; - + var data = Reader.RawData; - - Writer.Clear(); - Writer.WriteOperation(RagonOperation.REPLICATE_RAW_DATA); - Writer.WriteUShort(player.Connection.Id); - - var playerData = Writer.ToArray(); - var payloadData = data; - var size = playerData.Length + payloadData.Length; + var dataSize = data.Length - 1; + var headerSize = 3; + var size = headerSize + dataSize; var sendData = new byte[size]; - - Array.Copy(playerData, 0, sendData, 0, playerData.Length); - Array.Copy(payloadData, 1, sendData, playerData.Length, payloadData.Length - 1); - + var peerId = player.Connection.Id; + + sendData[0] = (byte)RagonOperation.REPLICATE_RAW_DATA; + sendData[1] = (byte)peerId; + sendData[2] = (byte)(peerId >> 8); + + Array.Copy(data, 1, sendData, headerSize, dataSize); + room.Broadcast(sendData, channel); } } \ No newline at end of file