This commit is contained in:
2023-10-11 19:37:50 +03:00
parent 5d812d7acc
commit 6422db783a
33 changed files with 300 additions and 129 deletions
+1 -1
View File
@@ -12,7 +12,7 @@
<PropertyGroup Condition=" '$(Configuration)' == 'Release' "> <PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<DebugType>none</DebugType> <DebugType>none</DebugType>
<OutputPath>/Users/edmand46/RagonProjects/ragon-oss-examples/Assets/Ragon/Plugins/netstandard2.0/</OutputPath> <OutputPath>/Users/edmand46/RagonProjects/ragon-oss-becs/Assets/Ragon/Plugins</OutputPath>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' "> <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
+17 -9
View File
@@ -77,6 +77,11 @@ namespace Ragon.Client
Attached?.Invoke(this); Attached?.Invoke(this);
} }
internal void PrepareDetach()
{
IsAttached = false;
}
internal void Detach(RagonPayload payload) internal void Detach(RagonPayload payload)
{ {
_destroyPayload = payload; _destroyPayload = payload;
@@ -188,25 +193,26 @@ namespace Ragon.Client
{ {
var t = new TEvent(); var t = new TEvent();
var eventCode = _client.Event.GetEventCode(t); var eventCode = _client.Event.GetEventCode(t);
var callbacks = _listeners[eventCode];
var action = (RagonPlayer player, IRagonEvent eventData) => callback.Invoke(player, (TEvent)eventData); var action = (RagonPlayer player, IRagonEvent eventData) => callback.Invoke(player, (TEvent)eventData);
if (callbacks == null) if (!_listeners.TryGetValue(eventCode, out var callbacks))
{ {
callbacks = new List<Action<RagonPlayer, IRagonEvent>>(); callbacks = new List<Action<RagonPlayer, IRagonEvent>>();
_listeners.Add(eventCode, callbacks); _listeners.Add(eventCode, callbacks);
} }
var localCallbacks = _localListeners[eventCode]; if (!_localListeners.TryGetValue(eventCode, out var localCallbacks))
if (localCallbacks == null)
{ {
localCallbacks = new List<Action<RagonPlayer, IRagonEvent>>(); localCallbacks = new List<Action<RagonPlayer, IRagonEvent>>();
_localListeners.Add(eventCode, callbacks); _localListeners.Add(eventCode, localCallbacks);
} }
callbacks.Add(action); callbacks.Add(action);
localCallbacks.Add(action); localCallbacks.Add(action);
if (!_events.ContainsKey(eventCode))
{
_events.Add(eventCode, (player, serializer) => _events.Add(eventCode, (player, serializer) =>
{ {
t.Deserialize(serializer); t.Deserialize(serializer);
@@ -214,6 +220,7 @@ namespace Ragon.Client
foreach (var callbackListener in callbacks) foreach (var callbackListener in callbacks)
callbackListener.Invoke(player, t); callbackListener.Invoke(player, t);
}); });
}
return action; return action;
} }
@@ -222,11 +229,12 @@ namespace Ragon.Client
{ {
var t = new TEvent(); var t = new TEvent();
var eventCode = _client.Event.GetEventCode(t); var eventCode = _client.Event.GetEventCode(t);
var callbacks = _listeners[eventCode];
var localCallbacks = _localListeners[eventCode];
callbacks?.Remove(callback); if (_listeners.TryGetValue(eventCode, out var callbacks))
localCallbacks?.Remove(callback); callbacks.Remove(callback);
if (_localListeners.TryGetValue(eventCode, out var localCallbacks))
localCallbacks.Remove(callback);
} }
internal void Write(RagonBuffer buffer) internal void Write(RagonBuffer buffer)
@@ -24,6 +24,7 @@ internal class EntityCreateHandler : IHandler
private readonly RagonPlayerCache _playerCache; private readonly RagonPlayerCache _playerCache;
private readonly RagonEntityCache _entityCache; private readonly RagonEntityCache _entityCache;
private readonly IRagonEntityListener _entityListener; private readonly IRagonEntityListener _entityListener;
public EntityCreateHandler( public EntityCreateHandler(
RagonClient client, RagonClient client,
RagonPlayerCache playerCache, RagonPlayerCache playerCache,
@@ -1,11 +1,47 @@
/*
* Copyright 2023 Eduard Kargin <kargin.eduard@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using Ragon.Protocol; using Ragon.Protocol;
namespace Ragon.Client; namespace Ragon.Client;
public class RoomDataHandler: IHandler internal class RoomDataHandler: IHandler
{ {
private readonly RagonListenerList _listeners;
private readonly RagonPlayerCache _playerCache;
public RoomDataHandler(
RagonPlayerCache playerCache,
RagonListenerList listeners)
{
_playerCache = playerCache;
_listeners = listeners;
}
public void Handle(RagonBuffer reader) public void Handle(RagonBuffer reader)
{ {
var rawData = reader.RawData; var rawData = reader.RawData;
var peerId = (ushort)(rawData[1] + (rawData[2] << 8));
var player = _playerCache.GetPlayerByPeer(peerId);
var headerSize = 3;
var payload = new byte[rawData.Length - headerSize];
Array.Copy(rawData, headerSize, payload, 0, payload.Length);
_listeners.OnData(player, payload);
} }
} }
@@ -0,0 +1,22 @@
/*
* Copyright 2023 Eduard Kargin <kargin.eduard@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
namespace Ragon.Client;
public interface IRagonDataListener
{
public void OnData(RagonPlayer player, byte[] data);
}
+9 -3
View File
@@ -57,13 +57,13 @@ namespace Ragon.Client
public RagonClient(INetworkConnection connection, int rate) public RagonClient(INetworkConnection connection, int rate)
{ {
listeners = new RagonListenerList(this);
_connection = connection; _connection = connection;
_connection.OnData += OnData; _connection.OnData += OnData;
_connection.OnConnected += OnConnected; _connection.OnConnected += OnConnected;
_connection.OnDisconnected += OnDisconnected; _connection.OnDisconnected += OnDisconnected;
listeners = new RagonListenerList(this);
_replicationRate = (1000.0f / rate) / 1000.0f; _replicationRate = (1000.0f / rate) / 1000.0f;
_replicationTime = 0; _replicationTime = 0;
@@ -119,9 +119,10 @@ namespace Ragon.Client
_handlers[(byte)RagonOperation.REMOVE_ENTITY] = new EntityRemoveHandler(_entityCache); _handlers[(byte)RagonOperation.REMOVE_ENTITY] = new EntityRemoveHandler(_entityCache);
_handlers[(byte)RagonOperation.REPLICATE_ENTITY_STATE] = new StateEntityHandler(_entityCache); _handlers[(byte)RagonOperation.REPLICATE_ENTITY_STATE] = new StateEntityHandler(_entityCache);
_handlers[(byte)RagonOperation.REPLICATE_ENTITY_EVENT] = new EntityEventHandler(_playerCache, _entityCache); _handlers[(byte)RagonOperation.REPLICATE_ENTITY_EVENT] = new EntityEventHandler(_playerCache, _entityCache);
_handlers[(byte)RagonOperation.REPLICATE_ROOM_EVENT] = new RoomEventHandler(this, _playerCache);
_handlers[(byte)RagonOperation.SNAPSHOT] = new SnapshotHandler(this, listeners, _entityCache, _playerCache, _entityListener); _handlers[(byte)RagonOperation.SNAPSHOT] = new SnapshotHandler(this, listeners, _entityCache, _playerCache, _entityListener);
_handlers[(byte)RagonOperation.REPLICATE_RAW_DATA] = new RoomEventHandler(this, _playerCache);
_handlers[(byte)RagonOperation.TIMESTAMP_SYNCHRONIZATION] = new TimestampHandler(this); _handlers[(byte)RagonOperation.TIMESTAMP_SYNCHRONIZATION] = new TimestampHandler(this);
_handlers[(byte)RagonOperation.REPLICATE_RAW_DATA] = new RoomDataHandler(_playerCache, listeners);
var protocolRaw = RagonVersion.Parse(protocol); var protocolRaw = RagonVersion.Parse(protocol);
_connection.Connect(address, port, protocolRaw); _connection.Connect(address, port, protocolRaw);
@@ -157,9 +158,12 @@ namespace Ragon.Client
} }
public void Dispose() public void Dispose()
{
if (_status != RagonStatus.DISCONNECTED)
{ {
_status = RagonStatus.DISCONNECTED; _status = RagonStatus.DISCONNECTED;
_connection.Disconnect(); _connection.Disconnect();
}
_connection.Dispose(); _connection.Dispose();
} }
@@ -174,6 +178,7 @@ namespace Ragon.Client
public void AddListener(IRagonPlayerLeftListener listener) => listeners.Add(listener); public void AddListener(IRagonPlayerLeftListener listener) => listeners.Add(listener);
public void AddListener(IRagonSceneListener listener) => listeners.Add(listener); public void AddListener(IRagonSceneListener listener) => listeners.Add(listener);
public void AddListener(IRagonSceneRequestListener listener) => listeners.Add(listener); public void AddListener(IRagonSceneRequestListener listener) => listeners.Add(listener);
public void AddListener(IRagonDataListener listener) => listeners.Add(listener);
public void RemoveListener(IRagonListener listener) => listeners.Remove(listener); public void RemoveListener(IRagonListener listener) => listeners.Remove(listener);
public void RemoveListener(IRagonAuthorizationListener listener) => listeners.Remove(listener); public void RemoveListener(IRagonAuthorizationListener listener) => listeners.Remove(listener);
@@ -186,6 +191,7 @@ namespace Ragon.Client
public void RemoveListener(IRagonPlayerLeftListener listener) => listeners.Remove(listener); public void RemoveListener(IRagonPlayerLeftListener listener) => listeners.Remove(listener);
public void RemoveListener(IRagonSceneListener listener) => listeners.Remove(listener); public void RemoveListener(IRagonSceneListener listener) => listeners.Remove(listener);
public void RemoveListener(IRagonSceneRequestListener listener) => listeners.Remove(listener); public void RemoveListener(IRagonSceneRequestListener listener) => listeners.Remove(listener);
public void RemoveListener(IRagonDataListener listener) => listeners.Remove(listener);
#endregion #endregion
+2
View File
@@ -89,6 +89,8 @@ public sealed class RagonEntityCache
return; return;
} }
entity.PrepareDetach();
var buffer = _client.Buffer; var buffer = _client.Buffer;
buffer.Clear(); buffer.Clear();
+16 -1
View File
@@ -31,6 +31,7 @@ namespace Ragon.Client
private readonly List<IRagonOwnershipChangedListener> _ownershipChangedListeners = new(); private readonly List<IRagonOwnershipChangedListener> _ownershipChangedListeners = new();
private readonly List<IRagonPlayerJoinListener> _playerJoinListeners = new(); private readonly List<IRagonPlayerJoinListener> _playerJoinListeners = new();
private readonly List<IRagonPlayerLeftListener> _playerLeftListeners = new(); private readonly List<IRagonPlayerLeftListener> _playerLeftListeners = new();
private readonly List<IRagonDataListener> _dataListeners = new();
private readonly List<Action> _delayedActions = new(); private readonly List<Action> _delayedActions = new();
public RagonListenerList(RagonClient client) public RagonListenerList(RagonClient client)
@@ -75,6 +76,10 @@ namespace Ragon.Client
_delayedActions.Clear(); _delayedActions.Clear();
} }
public void Add(IRagonDataListener dataListener)
{
_dataListeners.Add(dataListener);
}
public void Add(IRagonAuthorizationListener listener) public void Add(IRagonAuthorizationListener listener)
{ {
@@ -126,6 +131,11 @@ namespace Ragon.Client
_playerLeftListeners.Add(listener); _playerLeftListeners.Add(listener);
} }
public void Remove(IRagonDataListener listener)
{
_delayedActions.Add(() => _dataListeners.Remove(listener));
}
public void Remove(IRagonSceneRequestListener listener) public void Remove(IRagonSceneRequestListener listener)
{ {
_delayedActions.Add(() => _sceneRequestListeners.Remove(listener)); _delayedActions.Add(() => _sceneRequestListeners.Remove(listener));
@@ -138,7 +148,6 @@ namespace Ragon.Client
public void Remove(IRagonConnectionListener listener) public void Remove(IRagonConnectionListener listener)
{ {
_delayedActions.Add(() => _connectionListeners.Remove(listener)); _delayedActions.Add(() => _connectionListeners.Remove(listener));
} }
@@ -248,5 +257,11 @@ namespace Ragon.Client
foreach (var listener in _connectionListeners) foreach (var listener in _connectionListeners)
listener.OnDisconnected(_client, disconnect); listener.OnDisconnected(_client, disconnect);
} }
public void OnData(RagonPlayer player, byte[] data)
{
foreach (var listener in _dataListeners)
listener.OnData(player, data);
}
} }
} }
+13 -9
View File
@@ -77,25 +77,26 @@ namespace Ragon.Client
{ {
var t = new TEvent(); var t = new TEvent();
var eventCode = _client.Event.GetEventCode(t); var eventCode = _client.Event.GetEventCode(t);
var callbacks = _listeners[eventCode];
var action = (RagonPlayer player, IRagonEvent eventData) => callback.Invoke(player, (TEvent)eventData); var action = (RagonPlayer player, IRagonEvent eventData) => callback.Invoke(player, (TEvent)eventData);
if (callbacks == null) if (!_listeners.TryGetValue(eventCode, out var callbacks))
{ {
callbacks = new List<Action<RagonPlayer, IRagonEvent>>(); callbacks = new List<Action<RagonPlayer, IRagonEvent>>();
_listeners.Add(eventCode, callbacks); _listeners.Add(eventCode, callbacks);
} }
var localCallbacks = _localListeners[eventCode]; if (!_localListeners.TryGetValue(eventCode, out var localCallbacks))
if (localCallbacks == null)
{ {
localCallbacks = new List<Action<RagonPlayer, IRagonEvent>>(); localCallbacks = new List<Action<RagonPlayer, IRagonEvent>>();
_localListeners.Add(eventCode, callbacks); _localListeners.Add(eventCode, localCallbacks);
} }
callbacks.Add(action); callbacks.Add(action);
localCallbacks.Add(action); localCallbacks.Add(action);
if (!_events.ContainsKey(eventCode))
{
_events.Add(eventCode, (player, serializer) => _events.Add(eventCode, (player, serializer) =>
{ {
t.Deserialize(serializer); t.Deserialize(serializer);
@@ -103,6 +104,7 @@ namespace Ragon.Client
foreach (var callbackListener in callbacks) foreach (var callbackListener in callbacks)
callbackListener.Invoke(player, t); callbackListener.Invoke(player, t);
}); });
}
return action; return action;
} }
@@ -111,11 +113,12 @@ namespace Ragon.Client
{ {
var t = new TEvent(); var t = new TEvent();
var eventCode = _client.Event.GetEventCode(t); var eventCode = _client.Event.GetEventCode(t);
var callbacks = _listeners[eventCode];
var localCallbacks = _localListeners[eventCode];
callbacks?.Remove(callback); if (_listeners.TryGetValue(eventCode, out var callbacks))
localCallbacks?.Remove(callback); callbacks.Remove(callback);
if (_localListeners.TryGetValue(eventCode, out var localCallbacks))
localCallbacks.Remove(callback);
} }
public void LoadScene(string sceneName) => _scene.Load(sceneName); public void LoadScene(string sceneName) => _scene.Load(sceneName);
@@ -123,6 +126,7 @@ namespace Ragon.Client
public void ReplicateEvent<TEvent>(TEvent evnt, RagonTarget target, RagonReplicationMode mode) where TEvent : IRagonEvent, new() => _scene.ReplicateEvent(evnt, target, mode); public void ReplicateEvent<TEvent>(TEvent evnt, RagonTarget target, RagonReplicationMode mode) where TEvent : IRagonEvent, new() => _scene.ReplicateEvent(evnt, target, mode);
public void ReplicateEvent<TEvent>(TEvent evnt, RagonPlayer target, RagonReplicationMode mode) where TEvent : IRagonEvent, new() => _scene.ReplicateEvent(evnt, target, mode); public void ReplicateEvent<TEvent>(TEvent evnt, RagonPlayer target, RagonReplicationMode mode) where TEvent : IRagonEvent, new() => _scene.ReplicateEvent(evnt, target, mode);
public void ReplicateData(byte[] data, bool reliable = false) => _scene.ReplicateData(data, reliable);
public void CreateEntity(RagonEntity entity) => CreateEntity(entity, null); public void CreateEntity(RagonEntity entity) => CreateEntity(entity, null);
public void CreateEntity(RagonEntity entity, RagonPayload payload) => _entityCache.Create(entity, payload); public void CreateEntity(RagonEntity entity, RagonPayload payload) => _entityCache.Create(entity, payload);
+12
View File
@@ -102,4 +102,16 @@ public class RagonScene
var sendData = buffer.ToArray(); var sendData = buffer.ToArray();
_client.Reliable.Send(sendData); _client.Reliable.Send(sendData);
} }
public void ReplicateData(byte[] data, bool reliable)
{
var sendData = new byte[data.Length + 1];
sendData[0] = (byte) RagonOperation.REPLICATE_RAW_DATA;
Array.Copy(data, 0, sendData, 1, data.Length);
if (reliable)
_client.Reliable.Send(sendData);
else
_client.Unreliable.Send(sendData);
}
} }
+4 -10
View File
@@ -118,20 +118,14 @@ namespace Ragon.Server.ENetServer
} }
} }
public void BroadcastReliable(byte[] data) public void Broadcast(byte[] data, NetworkChannel channel)
{ {
var packet = new Packet(); var packet = new Packet();
packet.Create(data, PacketFlags.Reliable); var flag = channel == NetworkChannel.RELIABLE? PacketFlags.Reliable: PacketFlags.None;
_host.Broadcast((byte)NetworkChannel.RELIABLE, ref packet); packet.Create(data, flag);
}
public void BroadcastUnreliable(byte[] data) _host.Broadcast((byte)channel, ref packet);
{
var packet = new Packet();
packet.Create(data, PacketFlags.None);
_host.Broadcast((byte)NetworkChannel.UNRELIABLE, ref packet);
} }
public void Stop() public void Stop()
@@ -84,9 +84,8 @@ public class WebSocketServer : INetworkServer
var result = await webSocket.ReceiveAsync(buffer, cancellationToken); var result = await webSocket.ReceiveAsync(buffer, cancellationToken);
if (result.Count > 0) if (result.Count > 0)
{ {
var channel = (RagonOperation) bytes[0] == RagonOperation.REPLICATE_RAW_DATA ? NetworkChannel.RAW : NetworkChannel.RELIABLE;
var payload = buffer.Slice(0, buffer.Length); var payload = buffer.Slice(0, buffer.Length);
_networkListener.OnData(connection, channel , payload.ToArray()); _networkListener.OnData(connection, NetworkChannel.RELIABLE, payload.ToArray());
} }
} }
catch (Exception ex) catch (Exception ex)
@@ -105,13 +104,7 @@ public class WebSocketServer : INetworkServer
Flush(); Flush();
} }
public void BroadcastUnreliable(byte[] data) public void Broadcast(byte[] data, NetworkChannel channel)
{
foreach (var activeConnection in _activeConnections)
activeConnection.Unreliable.Send(data);
}
public void BroadcastReliable(byte[] data)
{ {
foreach (var activeConnection in _activeConnections) foreach (var activeConnection in _activeConnections)
activeConnection.Reliable.Send(data); activeConnection.Reliable.Send(data);
@@ -16,6 +16,7 @@
using NLog; using NLog;
using Ragon.Protocol; using Ragon.Protocol;
using Ragon.Server.IO;
using Ragon.Server.Lobby; using Ragon.Server.Lobby;
using Ragon.Server.Plugin.Web; using Ragon.Server.Plugin.Web;
@@ -40,7 +41,7 @@ public sealed class AuthorizationOperation: BaseOperation
_writer = writer; _writer = writer;
} }
public override void Handle(RagonContext context) public override void Handle(RagonContext context, NetworkChannel channel)
{ {
if (context.ConnectionStatus == ConnectionStatus.Authorized) if (context.ConnectionStatus == ConnectionStatus.Authorized)
{ {
@@ -15,6 +15,7 @@
*/ */
using Ragon.Protocol; using Ragon.Protocol;
using Ragon.Server.IO;
namespace Ragon.Server.Handler; namespace Ragon.Server.Handler;
@@ -29,5 +30,5 @@ public abstract class BaseOperation
Writer = writer; Writer = writer;
} }
public abstract void Handle(RagonContext context); public abstract void Handle(RagonContext context, NetworkChannel channel);
} }
@@ -17,6 +17,7 @@
using NLog; using NLog;
using Ragon.Protocol; using Ragon.Protocol;
using Ragon.Server.Entity; using Ragon.Server.Entity;
using Ragon.Server.IO;
namespace Ragon.Server.Handler; namespace Ragon.Server.Handler;
@@ -28,7 +29,7 @@ public sealed class EntityCreateOperation : BaseOperation
{ {
} }
public override void Handle(RagonContext context) public override void Handle(RagonContext context, NetworkChannel channel)
{ {
var player = context.RoomPlayer; var player = context.RoomPlayer;
var room = context.Room; var room = context.Room;
@@ -17,6 +17,7 @@
using NLog; using NLog;
using Ragon.Protocol; using Ragon.Protocol;
using Ragon.Server.Event; using Ragon.Server.Event;
using Ragon.Server.IO;
namespace Ragon.Server.Handler; namespace Ragon.Server.Handler;
@@ -28,7 +29,7 @@ public sealed class EntityEventOperation : BaseOperation
{ {
} }
public override void Handle(RagonContext context) public override void Handle(RagonContext context, NetworkChannel channel)
{ {
var player = context.RoomPlayer; var player = context.RoomPlayer;
var room = context.Room; var room = context.Room;
@@ -1,5 +1,23 @@
/*
* Copyright 2023 Eduard Kargin <kargin.eduard@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using NLog; using NLog;
using Ragon.Protocol; using Ragon.Protocol;
using Ragon.Server.IO;
namespace Ragon.Server.Handler; namespace Ragon.Server.Handler;
@@ -11,7 +29,7 @@ public sealed class EntityOwnershipOperation : BaseOperation
{ {
} }
public override void Handle(RagonContext context) public override void Handle(RagonContext context, NetworkChannel channel)
{ {
var currentOwner = context.RoomPlayer; var currentOwner = context.RoomPlayer;
var room = context.Room; var room = context.Room;
@@ -17,6 +17,7 @@
using NLog; using NLog;
using Ragon.Protocol; using Ragon.Protocol;
using Ragon.Server.Entity; using Ragon.Server.Entity;
using Ragon.Server.IO;
namespace Ragon.Server.Handler; namespace Ragon.Server.Handler;
@@ -28,7 +29,7 @@ public sealed class EntityDestroyOperation: BaseOperation
{ {
} }
public override void Handle(RagonContext context) public override void Handle(RagonContext context, NetworkChannel channel)
{ {
var player = context.RoomPlayer; var player = context.RoomPlayer;
var room = context.Room; var room = context.Room;
@@ -16,6 +16,7 @@
using NLog; using NLog;
using Ragon.Protocol; using Ragon.Protocol;
using Ragon.Server.IO;
namespace Ragon.Server.Handler; namespace Ragon.Server.Handler;
@@ -27,7 +28,7 @@ public sealed class EntityStateOperation: BaseOperation
{ {
} }
public override void Handle(RagonContext context) public override void Handle(RagonContext context, NetworkChannel channel)
{ {
var room = context.Room; var room = context.Room;
var player = context.RoomPlayer; var player = context.RoomPlayer;
@@ -16,6 +16,7 @@
using NLog; using NLog;
using Ragon.Protocol; using Ragon.Protocol;
using Ragon.Server.IO;
using Ragon.Server.Lobby; using Ragon.Server.Lobby;
using Ragon.Server.Plugin; using Ragon.Server.Plugin;
using Ragon.Server.Plugin.Web; using Ragon.Server.Plugin.Web;
@@ -36,7 +37,7 @@ public sealed class RoomCreateOperation : BaseOperation
_ragonWebHookPlugin = ragonWebHook; _ragonWebHookPlugin = ragonWebHook;
} }
public override void Handle(RagonContext context) public override void Handle(RagonContext context, NetworkChannel channel)
{ {
if (context.ConnectionStatus == ConnectionStatus.Unauthorized) if (context.ConnectionStatus == ConnectionStatus.Unauthorized)
{ {
@@ -16,6 +16,7 @@
using NLog; using NLog;
using Ragon.Protocol; using Ragon.Protocol;
using Ragon.Server.IO;
namespace Ragon.Server.Handler; namespace Ragon.Server.Handler;
@@ -25,7 +26,7 @@ public sealed class RoomDataOperation : BaseOperation
{ {
} }
public override void Handle(RagonContext context) public override void Handle(RagonContext context, NetworkChannel channel)
{ {
var player = context.RoomPlayer; var player = context.RoomPlayer;
var room = context.Room; var room = context.Room;
@@ -42,8 +43,8 @@ public sealed class RoomDataOperation : BaseOperation
var sendData = new byte[size]; var sendData = new byte[size];
Array.Copy(playerData, 0, sendData, 0, playerData.Length); Array.Copy(playerData, 0, sendData, 0, playerData.Length);
Array.Copy(payloadData, 0, sendData, playerData.Length, payloadData.Length); Array.Copy(payloadData, 1, sendData, playerData.Length, payloadData.Length - 1);
room.Broadcast(sendData); room.Broadcast(sendData, channel);
} }
} }
@@ -1,5 +1,6 @@
using Ragon.Protocol; using Ragon.Protocol;
using Ragon.Server.Event; using Ragon.Server.Event;
using Ragon.Server.IO;
namespace Ragon.Server.Handler; namespace Ragon.Server.Handler;
@@ -9,7 +10,7 @@ public class RoomEventOperation : BaseOperation
{ {
} }
public override void Handle(RagonContext context) public override void Handle(RagonContext context, NetworkChannel channel)
{ {
var room = context.Room; var room = context.Room;
var player = context.RoomPlayer; var player = context.RoomPlayer;
@@ -16,7 +16,7 @@
using NLog; using NLog;
using Ragon.Protocol; using Ragon.Protocol;
using Ragon.Server.Plugin; using Ragon.Server.IO;
using Ragon.Server.Plugin.Web; using Ragon.Server.Plugin.Web;
using Ragon.Server.Room; using Ragon.Server.Room;
@@ -33,7 +33,7 @@ public sealed class RoomJoinOperation : BaseOperation
} }
public override void Handle(RagonContext context) public override void Handle(RagonContext context, NetworkChannel channel)
{ {
var roomId = Reader.ReadString(); var roomId = Reader.ReadString();
var lobbyPlayer = context.LobbyPlayer; var lobbyPlayer = context.LobbyPlayer;
@@ -16,6 +16,7 @@
using NLog; using NLog;
using Ragon.Protocol; using Ragon.Protocol;
using Ragon.Server.IO;
using Ragon.Server.Lobby; using Ragon.Server.Lobby;
using Ragon.Server.Plugin; using Ragon.Server.Plugin;
using Ragon.Server.Plugin.Web; using Ragon.Server.Plugin.Web;
@@ -36,7 +37,7 @@ public sealed class RoomJoinOrCreateOperation : BaseOperation
_ragonWebHookPlugin = plugin; _ragonWebHookPlugin = plugin;
} }
public override void Handle(RagonContext context) public override void Handle(RagonContext context, NetworkChannel channel)
{ {
if (context.ConnectionStatus == ConnectionStatus.Unauthorized) if (context.ConnectionStatus == ConnectionStatus.Unauthorized)
{ {
@@ -16,6 +16,7 @@
using NLog; using NLog;
using Ragon.Protocol; using Ragon.Protocol;
using Ragon.Server.IO;
using Ragon.Server.Plugin; using Ragon.Server.Plugin;
using Ragon.Server.Plugin.Web; using Ragon.Server.Plugin.Web;
@@ -31,7 +32,7 @@ public sealed class RoomLeaveOperation: BaseOperation
_webHook = plugin; _webHook = plugin;
} }
public override void Handle(RagonContext context) public override void Handle(RagonContext context, NetworkChannel channel)
{ {
var room = context.Room; var room = context.Room;
var roomPlayer = context.RoomPlayer; var roomPlayer = context.RoomPlayer;
@@ -1,6 +1,22 @@
/*
* Copyright 2023 Eduard Kargin <kargin.eduard@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using NLog; using NLog;
using Ragon.Protocol; using Ragon.Protocol;
using Ragon.Server.Entity; using Ragon.Server.IO;
namespace Ragon.Server.Handler; namespace Ragon.Server.Handler;
@@ -12,7 +28,7 @@ public sealed class RoomOwnershipOperation : BaseOperation
{ {
} }
public override void Handle(RagonContext context) public override void Handle(RagonContext context, NetworkChannel channel)
{ {
} }
@@ -14,9 +14,9 @@
* limitations under the License. * limitations under the License.
*/ */
using NLog; using NLog;
using Ragon.Protocol; using Ragon.Protocol;
using Ragon.Server.IO;
namespace Ragon.Server.Handler; namespace Ragon.Server.Handler;
@@ -26,7 +26,7 @@ public class SceneLoadOperation: BaseOperation
public SceneLoadOperation(RagonBuffer reader, RagonBuffer writer) : base(reader, writer) {} public SceneLoadOperation(RagonBuffer reader, RagonBuffer writer) : base(reader, writer) {}
public override void Handle(RagonContext context) public override void Handle(RagonContext context, NetworkChannel channel)
{ {
var roomOwner = context.Room.Owner; var roomOwner = context.Room.Owner;
var currentPlayer = context.RoomPlayer; var currentPlayer = context.RoomPlayer;
@@ -17,6 +17,7 @@
using NLog; using NLog;
using Ragon.Protocol; using Ragon.Protocol;
using Ragon.Server.Entity; using Ragon.Server.Entity;
using Ragon.Server.IO;
using Ragon.Server.Lobby; using Ragon.Server.Lobby;
using Ragon.Server.Room; using Ragon.Server.Room;
@@ -31,7 +32,7 @@ public sealed class SceneLoadedOperation : BaseOperation
} }
public override void Handle(RagonContext context) public override void Handle(RagonContext context, NetworkChannel channel)
{ {
if (context.ConnectionStatus == ConnectionStatus.Unauthorized) if (context.ConnectionStatus == ConnectionStatus.Unauthorized)
return; return;
@@ -1,4 +1,21 @@
/*
* Copyright 2023 Eduard Kargin <kargin.eduard@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using Ragon.Protocol; using Ragon.Protocol;
using Ragon.Server.IO;
namespace Ragon.Server.Handler; namespace Ragon.Server.Handler;
@@ -8,7 +25,7 @@ public class TimestampSyncOperation: BaseOperation
{ {
} }
public override void Handle(RagonContext context) public override void Handle(RagonContext context, NetworkChannel channel)
{ {
var timestamp0 = Reader.Read(32); var timestamp0 = Reader.Read(32);
var timestamp1 = Reader.Read(32); var timestamp1 = Reader.Read(32);
+1 -2
View File
@@ -21,7 +21,6 @@ public interface INetworkServer
public Executor Executor { get; } public Executor Executor { get; }
public void Stop(); public void Stop();
public void Update(); public void Update();
public void BroadcastUnreliable(byte[] data); public void Broadcast(byte[] data, NetworkChannel channel);
public void BroadcastReliable(byte[] data);
public void Start(INetworkListener listener, NetworkConfiguration configuration); public void Start(INetworkListener listener, NetworkConfiguration configuration);
} }
+17 -1
View File
@@ -1,8 +1,24 @@
/*
* Copyright 2023 Eduard Kargin <kargin.eduard@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
namespace Ragon.Server.IO; namespace Ragon.Server.IO;
public enum NetworkChannel public enum NetworkChannel
{ {
RELIABLE = 1, RELIABLE = 1,
UNRELIABLE = 2, UNRELIABLE = 2,
RAW = 3,
} }
+2 -2
View File
@@ -197,7 +197,7 @@ public class RagonServer : IRagonServer, INetworkListener
_reader.FromArray(data); _reader.FromArray(data);
var operation = _reader.ReadByte(); var operation = _reader.ReadByte();
_handlers[operation].Handle(context); _handlers[operation].Handle(context, channel);
} }
} }
catch (Exception ex) catch (Exception ex)
@@ -220,7 +220,7 @@ public class RagonServer : IRagonServer, INetworkListener
_writer.Write(value.Int1, 32); _writer.Write(value.Int1, 32);
var sendData = _writer.ToArray(); var sendData = _writer.ToArray();
_server.BroadcastUnreliable(sendData); _server.Broadcast(sendData, NetworkChannel.UNRELIABLE);
} }
public BaseOperation ResolveOperation(RagonOperation operation) public BaseOperation ResolveOperation(RagonOperation operation)