This commit is contained in:
2022-10-16 16:50:22 +04:00
parent ff712dc094
commit aaa0e4a317
3 changed files with 118 additions and 127 deletions
+5 -7
View File
@@ -17,7 +17,7 @@ namespace Ragon.Core
private readonly ILogger _logger = LogManager.GetCurrentClassLogger(); private readonly ILogger _logger = LogManager.GetCurrentClassLogger();
private readonly float _deltaTime = 0.0f; private readonly float _deltaTime = 0.0f;
private readonly Configuration _configuration; private readonly Configuration _configuration;
private RagonSerializer _serializer; private readonly RagonSerializer _serializer;
public ISocketServer SocketServer => _socketServer; public ISocketServer SocketServer => _socketServer;
public IDispatcher Dispatcher => _dispatcher; public IDispatcher Dispatcher => _dispatcher;
@@ -107,15 +107,13 @@ namespace Ragon.Core
var peerId = (ushort) evnt.Peer.ID; var peerId = (ushort) evnt.Peer.ID;
var dataRaw = new byte[evnt.Packet.Length]; var dataRaw = new byte[evnt.Packet.Length];
evnt.Packet.CopyTo(dataRaw); evnt.Packet.CopyTo(dataRaw);
_serializer.FromArray(dataRaw);
var data = new ReadOnlySpan<byte>(dataRaw); var operation = _serializer.ReadOperation();
var operation = (RagonOperation) data[0];
var payload = data.Slice(1, data.Length - 1);
if (_roomManager.RoomsBySocket.TryGetValue(peerId, out var room)) if (_roomManager.RoomsBySocket.TryGetValue(peerId, out var room))
room.ProcessEvent(peerId, operation, payload); room.ProcessEvent(peerId, operation, _serializer);
_lobby.ProcessEvent(peerId, operation, payload); _lobby.ProcessEvent(peerId, operation, _serializer);
} }
catch (Exception exception) catch (Exception exception)
{ {
+87 -91
View File
@@ -25,7 +25,6 @@ namespace Ragon.Core
private readonly ISocketServer _socketServer; private readonly ISocketServer _socketServer;
private readonly Application _application; private readonly Application _application;
private readonly PluginBase _plugin; private readonly PluginBase _plugin;
private readonly RagonSerializer _reader = new(512);
private readonly RagonSerializer _writer = new(512); private readonly RagonSerializer _writer = new(512);
// Cache // Cache
@@ -71,24 +70,24 @@ namespace Ragon.Core
_allPlayers = _players.Select(p => p.Key).ToArray(); _allPlayers = _players.Select(p => p.Key).ToArray();
{ {
_reader.Clear(); _writer.Clear();
_reader.WriteOperation(RagonOperation.JOIN_SUCCESS); _writer.WriteOperation(RagonOperation.JOIN_SUCCESS);
_reader.WriteString(Id); _writer.WriteString(Id);
_reader.WriteString(player.Id); _writer.WriteString(player.Id);
_reader.WriteString(GetOwner().Id); _writer.WriteString(GetOwner().Id);
_reader.WriteUShort((ushort) PlayersMin); _writer.WriteUShort((ushort) PlayersMin);
_reader.WriteUShort((ushort) PlayersMax); _writer.WriteUShort((ushort) PlayersMax);
var sendData = _reader.ToArray(); var sendData = _writer.ToArray();
Send(player.PeerId, sendData, DeliveryType.Reliable); Send(player.PeerId, sendData, DeliveryType.Reliable);
} }
{ {
_reader.Clear(); _writer.Clear();
_reader.WriteOperation(RagonOperation.LOAD_SCENE); _writer.WriteOperation(RagonOperation.LOAD_SCENE);
_reader.WriteString(Map); _writer.WriteString(Map);
var sendData = _reader.ToArray(); var sendData = _writer.ToArray();
Send(player.PeerId, sendData, DeliveryType.Reliable); Send(player.PeerId, sendData, DeliveryType.Reliable);
} }
} }
@@ -118,16 +117,13 @@ namespace Ragon.Core
} }
} }
public void ProcessEvent(ushort peerId, RagonOperation operation, ReadOnlySpan<byte> payloadRawData) public void ProcessEvent(ushort peerId, RagonOperation operation, RagonSerializer reader)
{ {
_reader.Clear();
_reader.FromSpan(ref payloadRawData);
switch (operation) switch (operation)
{ {
case RagonOperation.LOAD_SCENE: case RagonOperation.LOAD_SCENE:
{ {
var sceneName = _reader.ReadString(); var sceneName = reader.ReadString();
SendScene(sceneName); SendScene(sceneName);
break; break;
} }
@@ -136,19 +132,19 @@ namespace Ragon.Core
var player = _players[peerId]; var player = _players[peerId];
if (peerId == _owner) if (peerId == _owner)
{ {
var statics = _reader.ReadUShort(); var statics = reader.ReadUShort();
for (var staticIndex = 0; staticIndex < statics; staticIndex++) for (var staticIndex = 0; staticIndex < statics; staticIndex++)
{ {
var entityType = _reader.ReadUShort(); var entityType = reader.ReadUShort();
var entityAuthority = (RagonAuthority) _reader.ReadByte(); var entityAuthority = (RagonAuthority) reader.ReadByte();
var staticId = _reader.ReadUShort(); var staticId = reader.ReadUShort();
var propertiesCount = _reader.ReadUShort(); var propertiesCount = reader.ReadUShort();
var entity = new Entity(this, player.PeerId, entityType, staticId, entityAuthority); var entity = new Entity(this, player.PeerId, entityType, staticId, entityAuthority);
for (var propertyIndex = 0; propertyIndex < propertiesCount; propertyIndex++) for (var propertyIndex = 0; propertyIndex < propertiesCount; propertyIndex++)
{ {
var propertyType = _reader.ReadBool(); var propertyType = reader.ReadBool();
var propertySize = _reader.ReadUShort(); var propertySize = reader.ReadUShort();
entity.AddProperty(new EntityProperty(propertySize, propertyType)); entity.AddProperty(new EntityProperty(propertySize, propertyType));
} }
@@ -205,13 +201,13 @@ namespace Ragon.Core
} }
case RagonOperation.REPLICATE_ENTITY_STATE: case RagonOperation.REPLICATE_ENTITY_STATE:
{ {
var entitiesCount = _reader.ReadUShort(); var entitiesCount = reader.ReadUShort();
for (var entityIndex = 0; entityIndex < entitiesCount; entityIndex++) for (var entityIndex = 0; entityIndex < entitiesCount; entityIndex++)
{ {
var entityId = _reader.ReadUShort(); var entityId = reader.ReadUShort();
if (_entities.TryGetValue(entityId, out var entity)) if (_entities.TryGetValue(entityId, out var entity))
{ {
entity.HandleState(peerId, _reader); entity.HandleState(peerId, reader);
if (_entitiesDirtySet.Add(entity)) if (_entitiesDirtySet.Add(entity))
_entitiesDirty.Add(entity); _entitiesDirty.Add(entity);
@@ -227,13 +223,13 @@ namespace Ragon.Core
} }
case RagonOperation.REPLICATE_ENTITY_EVENT: case RagonOperation.REPLICATE_ENTITY_EVENT:
{ {
var eventId = _reader.ReadUShort(); var eventId = reader.ReadUShort();
var eventMode = (RagonReplicationMode) _reader.ReadByte(); var eventMode = (RagonReplicationMode) reader.ReadByte();
var targetMode = (RagonTarget) _reader.ReadByte(); var targetMode = (RagonTarget) reader.ReadByte();
var entityId = _reader.ReadUShort(); var entityId = reader.ReadUShort();
var payloadData = _reader.ReadData(_reader.Size); var payloadData = reader.ReadData(reader.Size);
Span<byte> payloadRaw = stackalloc byte[_reader.Size]; Span<byte> payloadRaw = stackalloc byte[reader.Size];
ReadOnlySpan<byte> payload = payloadRaw; ReadOnlySpan<byte> payload = payloadRaw;
payloadData.CopyTo(payloadRaw); payloadData.CopyTo(payloadRaw);
@@ -251,9 +247,9 @@ namespace Ragon.Core
} }
case RagonOperation.CREATE_ENTITY: case RagonOperation.CREATE_ENTITY:
{ {
var entityType = _reader.ReadUShort(); var entityType = reader.ReadUShort();
var eventAuthority = (RagonAuthority) _reader.ReadByte(); var eventAuthority = (RagonAuthority) reader.ReadByte();
var propertiesCount = _reader.ReadUShort(); var propertiesCount = reader.ReadUShort();
_logger.Trace($"[{peerId}] Create Entity {entityType}"); _logger.Trace($"[{peerId}] Create Entity {entityType}");
@@ -261,12 +257,12 @@ namespace Ragon.Core
var entity = new Entity(this, (ushort) player.PeerId, entityType, 0, eventAuthority); var entity = new Entity(this, (ushort) player.PeerId, entityType, 0, eventAuthority);
for (var i = 0; i < propertiesCount; i++) for (var i = 0; i < propertiesCount; i++)
{ {
var propertyType = _reader.ReadBool(); var propertyType = reader.ReadBool();
var propertySize = _reader.ReadUShort(); var propertySize = reader.ReadUShort();
entity.AddProperty(new EntityProperty(propertySize, propertyType)); entity.AddProperty(new EntityProperty(propertySize, propertyType));
} }
var entityPayload = _reader.ReadData(_reader.Size); var entityPayload = reader.ReadData(reader.Size);
entity.SetPayload(entityPayload.ToArray()); entity.SetPayload(entityPayload.ToArray());
if (_plugin.OnEntityCreated(player, entity)) if (_plugin.OnEntityCreated(player, entity))
@@ -280,14 +276,14 @@ namespace Ragon.Core
} }
case RagonOperation.DESTROY_ENTITY: case RagonOperation.DESTROY_ENTITY:
{ {
var entityId = _reader.ReadInt(); var entityId = reader.ReadInt();
if (_entities.TryGetValue(entityId, out var entity)) if (_entities.TryGetValue(entityId, out var entity))
{ {
if (entity.Authority == RagonAuthority.OwnerOnly && entity.OwnerId != peerId) if (entity.Authority == RagonAuthority.OwnerOnly && entity.OwnerId != peerId)
return; return;
var player = _players[peerId]; var player = _players[peerId];
var destroyPayload = _reader.ReadData(_reader.Size); var destroyPayload = reader.ReadData(reader.Size);
player.DetachEntity(entity); player.DetachEntity(entity);
DetachEntity(entity); DetachEntity(entity);
@@ -342,97 +338,97 @@ namespace Ragon.Core
{ {
var entitiesToUpdate = prev.Entities.Where(e => e.StaticId > 0).ToArray(); var entitiesToUpdate = prev.Entities.Where(e => e.StaticId > 0).ToArray();
_reader.Clear(); _writer.Clear();
_reader.WriteOperation(RagonOperation.OWNERSHIP_CHANGED); _writer.WriteOperation(RagonOperation.OWNERSHIP_CHANGED);
_reader.WriteString(next.Id); _writer.WriteString(next.Id);
_reader.WriteUShort((ushort) entitiesToUpdate.Length); _writer.WriteUShort((ushort) entitiesToUpdate.Length);
foreach (var entity in entitiesToUpdate) foreach (var entity in entitiesToUpdate)
{ {
_reader.WriteUShort(entity.EntityId); _writer.WriteUShort(entity.EntityId);
entity.SetOwner((ushort) next.PeerId); entity.SetOwner((ushort) next.PeerId);
} }
var sendData = _reader.ToArray(); var sendData = _writer.ToArray();
Broadcast(_readyPlayers, sendData); Broadcast(_readyPlayers, sendData);
} }
void SendJoined(Player player, uint excludePeerId) void SendJoined(Player player, uint excludePeerId)
{ {
_reader.Clear(); _writer.Clear();
_reader.WriteOperation(RagonOperation.PLAYER_JOINED); _writer.WriteOperation(RagonOperation.PLAYER_JOINED);
_reader.WriteUShort((ushort) player.PeerId); _writer.WriteUShort((ushort) player.PeerId);
_reader.WriteString(player.Id); _writer.WriteString(player.Id);
_reader.WriteString(player.PlayerName); _writer.WriteString(player.PlayerName);
var sendData = _reader.ToArray(); var sendData = _writer.ToArray();
var readyPlayersWithExcludedPeer = _readyPlayers.Where(p => p != excludePeerId).ToArray(); var readyPlayersWithExcludedPeer = _readyPlayers.Where(p => p != excludePeerId).ToArray();
Broadcast(readyPlayersWithExcludedPeer, sendData, DeliveryType.Reliable); Broadcast(readyPlayersWithExcludedPeer, sendData, DeliveryType.Reliable);
} }
void SendLeaved(Player player) void SendLeaved(Player player)
{ {
_reader.Clear(); _writer.Clear();
_reader.WriteOperation(RagonOperation.PLAYER_LEAVED); _writer.WriteOperation(RagonOperation.PLAYER_LEAVED);
_reader.WriteString(player.Id); _writer.WriteString(player.Id);
var entitiesToDelete = player.Entities.Where(e => e.StaticId == 0).ToArray(); var entitiesToDelete = player.Entities.Where(e => e.StaticId == 0).ToArray();
_reader.WriteUShort((ushort) entitiesToDelete.Length); _writer.WriteUShort((ushort) entitiesToDelete.Length);
foreach (var entity in entitiesToDelete) foreach (var entity in entitiesToDelete)
{ {
_reader.WriteUShort(entity.EntityId); _writer.WriteUShort(entity.EntityId);
_entities.Remove(entity.EntityId); _entities.Remove(entity.EntityId);
} }
var sendData = _reader.ToArray(); var sendData = _writer.ToArray();
Broadcast(_readyPlayers, sendData); Broadcast(_readyPlayers, sendData);
} }
void SendSnapshot(ushort peerId) void SendSnapshot(ushort peerId)
{ {
_reader.Clear(); _writer.Clear();
_reader.WriteOperation(RagonOperation.SNAPSHOT); _writer.WriteOperation(RagonOperation.SNAPSHOT);
_reader.WriteUShort((ushort) _readyPlayers.Length); _writer.WriteUShort((ushort) _readyPlayers.Length);
foreach (var playerPeerId in _readyPlayers) foreach (var playerPeerId in _readyPlayers)
{ {
_reader.WriteUShort(playerPeerId); _writer.WriteUShort(playerPeerId);
_reader.WriteString(_players[playerPeerId].Id); _writer.WriteString(_players[playerPeerId].Id);
_reader.WriteString(_players[playerPeerId].PlayerName); _writer.WriteString(_players[playerPeerId].PlayerName);
} }
var dynamicEntities = _entitiesAll.Where(e => e.StaticId == 0).ToArray(); var dynamicEntities = _entitiesAll.Where(e => e.StaticId == 0).ToArray();
var dynamicEntitiesCount = (ushort) dynamicEntities.Length; var dynamicEntitiesCount = (ushort) dynamicEntities.Length;
_reader.WriteUShort(dynamicEntitiesCount); _writer.WriteUShort(dynamicEntitiesCount);
foreach (var entity in dynamicEntities) foreach (var entity in dynamicEntities)
{ {
ReadOnlySpan<byte> payload = entity.Payload.AsSpan(); ReadOnlySpan<byte> payload = entity.Payload.AsSpan();
_reader.WriteUShort(entity.EntityType); _writer.WriteUShort(entity.EntityType);
_reader.WriteUShort(entity.EntityId); _writer.WriteUShort(entity.EntityId);
_reader.WriteUShort(entity.OwnerId); _writer.WriteUShort(entity.OwnerId);
_reader.WriteUShort((ushort) payload.Length); _writer.WriteUShort((ushort) payload.Length);
_reader.WriteData(ref payload); _writer.WriteData(ref payload);
entity.WriteSnapshot(_reader); entity.WriteSnapshot(_writer);
} }
var staticEntities = _entitiesAll.Where(e => e.StaticId != 0).ToArray(); var staticEntities = _entitiesAll.Where(e => e.StaticId != 0).ToArray();
var staticEntitiesCount = (ushort) staticEntities.Length; var staticEntitiesCount = (ushort) staticEntities.Length;
_reader.WriteUShort(staticEntitiesCount); _writer.WriteUShort(staticEntitiesCount);
foreach (var entity in staticEntities) foreach (var entity in staticEntities)
{ {
ReadOnlySpan<byte> payload = entity.Payload.AsSpan(); ReadOnlySpan<byte> payload = entity.Payload.AsSpan();
_reader.WriteUShort(entity.EntityType); _writer.WriteUShort(entity.EntityType);
_reader.WriteUShort(entity.EntityId); _writer.WriteUShort(entity.EntityId);
_reader.WriteUShort(entity.StaticId); _writer.WriteUShort(entity.StaticId);
_reader.WriteUShort(entity.OwnerId); _writer.WriteUShort(entity.OwnerId);
_reader.WriteUShort((ushort) payload.Length); _writer.WriteUShort((ushort) payload.Length);
_reader.WriteData(ref payload); _writer.WriteData(ref payload);
entity.WriteSnapshot(_reader); entity.WriteSnapshot(_writer);
} }
var sendData = _reader.ToArray(); var sendData = _writer.ToArray();
Send(peerId, sendData, DeliveryType.Reliable); Send(peerId, sendData, DeliveryType.Reliable);
} }
@@ -441,17 +437,17 @@ namespace Ragon.Core
var entities = (ushort) _entitiesDirty.Count; var entities = (ushort) _entitiesDirty.Count;
if (entities > 0) if (entities > 0)
{ {
_reader.Clear(); _writer.Clear();
_reader.WriteOperation(RagonOperation.REPLICATE_ENTITY_STATE); _writer.WriteOperation(RagonOperation.REPLICATE_ENTITY_STATE);
_reader.WriteUShort(entities); _writer.WriteUShort(entities);
foreach (var entity in _entitiesDirty) foreach (var entity in _entitiesDirty)
entity.WriteProperties(_reader); entity.WriteProperties(_writer);
_entitiesDirty.Clear(); _entitiesDirty.Clear();
_entitiesDirtySet.Clear(); _entitiesDirtySet.Clear();
var sendData = _reader.ToArray(); var sendData = _writer.ToArray();
Broadcast(_readyPlayers, sendData); Broadcast(_readyPlayers, sendData);
} }
} }
@@ -462,11 +458,11 @@ namespace Ragon.Core
_entitiesAll = Array.Empty<Entity>(); _entitiesAll = Array.Empty<Entity>();
_entities.Clear(); _entities.Clear();
_reader.Clear(); _writer.Clear();
_reader.WriteOperation(RagonOperation.LOAD_SCENE); _writer.WriteOperation(RagonOperation.LOAD_SCENE);
_reader.WriteString(sceneName); _writer.WriteString(sceneName);
var sendData = _reader.ToArray(); var sendData = _writer.ToArray();
Broadcast(_allPlayers, sendData, DeliveryType.Reliable); Broadcast(_allPlayers, sendData, DeliveryType.Reliable);
} }
+25 -28
View File
@@ -8,26 +8,23 @@ namespace Ragon.Core;
public class Lobby public class Lobby
{ {
private readonly ILogger _logger = LogManager.GetCurrentClassLogger(); private readonly ILogger _logger = LogManager.GetCurrentClassLogger();
private readonly RagonSerializer _serializer; private readonly Application _application;
private readonly RagonSerializer _writer;
private readonly RoomManager _roomManager; private readonly RoomManager _roomManager;
private readonly AuthorizationManager _authorizationManager; private readonly AuthorizationManager _authorizationManager;
private readonly Application _gameThread;
public AuthorizationManager AuthorizationManager => _authorizationManager; public AuthorizationManager AuthorizationManager => _authorizationManager;
public Lobby(IAuthorizationProvider provider, RoomManager manager, Application gameThread) public Lobby(IAuthorizationProvider provider, RoomManager manager, Application application)
{ {
_roomManager = manager; _roomManager = manager;
_gameThread = gameThread; _application = application;
_serializer = new RagonSerializer(); _writer = new RagonSerializer();
_authorizationManager = new AuthorizationManager(provider, gameThread, this, _serializer); _authorizationManager = new AuthorizationManager(provider, application, this, _writer);
} }
public void ProcessEvent(ushort peerId, RagonOperation op, ReadOnlySpan<byte> payload) public void ProcessEvent(ushort peerId, RagonOperation op, RagonSerializer reader)
{ {
_serializer.Clear();
_serializer.FromSpan(ref payload);
var player = _authorizationManager.GetPlayer(peerId); var player = _authorizationManager.GetPlayer(peerId);
if (op == RagonOperation.AUTHORIZE) if (op == RagonOperation.AUTHORIZE)
{ {
@@ -37,9 +34,9 @@ public class Lobby
return; return;
} }
var key = _serializer.ReadString(); var key = reader.ReadString();
var playerName = _serializer.ReadString(); var playerName = reader.ReadString();
var additionalData = _serializer.ReadData(_serializer.Size); var additionalData = reader.ReadData(reader.Size);
_authorizationManager.OnAuthorization(peerId, key, playerName, additionalData); _authorizationManager.OnAuthorization(peerId, key, playerName, additionalData);
return; return;
} }
@@ -54,15 +51,15 @@ public class Lobby
{ {
case RagonOperation.JOIN_ROOM: case RagonOperation.JOIN_ROOM:
{ {
var roomId = _serializer.ReadString(); var roomId = reader.ReadString();
var exists = _roomManager.Rooms.Any(r => r.Id == roomId); var exists = _roomManager.Rooms.Any(r => r.Id == roomId);
if (!exists) if (!exists)
{ {
_serializer.Clear(); _writer.Clear();
_serializer.WriteOperation(RagonOperation.JOIN_FAILED); _writer.WriteOperation(RagonOperation.JOIN_FAILED);
_serializer.WriteString($"Room with id {roomId} not exists"); _writer.WriteString($"Room with id {roomId} not exists");
var sendData = _serializer.ToArray(); var sendData = _writer.ToArray();
_gameThread.SocketServer.Send(peerId, sendData, DeliveryType.Reliable); _application.SocketServer.Send(peerId, sendData, DeliveryType.Reliable);
return; return;
} }
@@ -75,25 +72,25 @@ public class Lobby
case RagonOperation.CREATE_ROOM: case RagonOperation.CREATE_ROOM:
{ {
var roomId = Guid.NewGuid().ToString(); var roomId = Guid.NewGuid().ToString();
var custom = _serializer.ReadBool(); var custom = reader.ReadBool();
if (custom) if (custom)
{ {
roomId = _serializer.ReadString(); roomId = reader.ReadString();
var exists = _roomManager.Rooms.Any(r => r.Id == roomId); var exists = _roomManager.Rooms.Any(r => r.Id == roomId);
if (exists) if (exists)
{ {
_serializer.Clear(); _writer.Clear();
_serializer.WriteOperation(RagonOperation.JOIN_FAILED); _writer.WriteOperation(RagonOperation.JOIN_FAILED);
_serializer.WriteString($"Room with id {roomId} already exists"); _writer.WriteString($"Room with id {roomId} already exists");
var sendData = _serializer.ToArray(); var sendData = _writer.ToArray();
_gameThread.SocketServer.Send(peerId, sendData, DeliveryType.Reliable); _application.SocketServer.Send(peerId, sendData, DeliveryType.Reliable);
return; return;
} }
} }
var roomProperties = new RagonRoomParameters(); var roomProperties = new RagonRoomParameters();
roomProperties.Deserialize(_serializer); roomProperties.Deserialize(reader);
if (_roomManager.RoomsBySocket.ContainsKey(peerId)) if (_roomManager.RoomsBySocket.ContainsKey(peerId))
_roomManager.Left(player, Array.Empty<byte>()); _roomManager.Left(player, Array.Empty<byte>());
@@ -105,7 +102,7 @@ public class Lobby
{ {
var roomId = Guid.NewGuid().ToString(); var roomId = Guid.NewGuid().ToString();
var roomProperties = new RagonRoomParameters(); var roomProperties = new RagonRoomParameters();
roomProperties.Deserialize(_serializer); roomProperties.Deserialize(reader);
if (_roomManager.RoomsBySocket.ContainsKey(peerId)) if (_roomManager.RoomsBySocket.ContainsKey(peerId))
_roomManager.Left(player, Array.Empty<byte>()); _roomManager.Left(player, Array.Empty<byte>());