Compare commits

...

2 Commits

Author SHA1 Message Date
edmand46 5f3b2d7ed8 - Added support entities on scene
- Improved performance
2022-07-13 07:56:44 +04:00
edmand46 773adeefb2 feat: added scheduler, minor fixes 2022-07-02 11:02:09 +04:00
16 changed files with 270 additions and 68 deletions
+1
View File
@@ -20,6 +20,7 @@ namespace Ragon.Common
PLAYER_LEAVED, PLAYER_LEAVED,
CREATE_ENTITY, CREATE_ENTITY,
CREATE_STATIC_ENTITY,
DESTROY_ENTITY, DESTROY_ENTITY,
SNAPSHOT, SNAPSHOT,
@@ -4,6 +4,7 @@ namespace Game.Source
{ {
public class SimplePlugin: PluginBase public class SimplePlugin: PluginBase
{ {
public override void OnStart() public override void OnStart()
{ {
// _logger.Info("Plugin started"); // _logger.Info("Plugin started");
+1
View File
@@ -4,6 +4,7 @@
"sendRate": 30, "sendRate": 30,
"port": 4444, "port": 4444,
"skipTimeout": 60, "skipTimeout": 60,
"reconnectTimeout": 300,
"maxConnections": 4095, "maxConnections": 4095,
"maxPlayersPerRoom": 20, "maxPlayersPerRoom": 20,
"maxRooms": 200 "maxRooms": 200
+1 -1
View File
@@ -195,7 +195,7 @@ namespace Stress
for (var i = 0; i < 80; i ++) for (var i = 0; i < 80; i ++)
{ {
var thread = new SimulationThread(); var thread = new SimulationThread();
thread.Start("127.0.0.1", 4444, 50); thread.Start("49.12.70.233", 4444, 50);
Thread.Sleep(300); Thread.Sleep(300);
} }
@@ -14,7 +14,7 @@ public class AuthorizationManager : IAuthorizationManager
private RagonSerializer _serializer; private RagonSerializer _serializer;
private readonly Dictionary<uint, Player> _playersByPeers; private readonly Dictionary<uint, Player> _playersByPeers;
private readonly Dictionary<string, Player> _playersByIds; private readonly Dictionary<string, Player> _playersByIds;
public AuthorizationManager(IAuthorizationProvider provider, IGameThread gameThread, Lobby lobby, RagonSerializer serializer) public AuthorizationManager(IAuthorizationProvider provider, IGameThread gameThread, Lobby lobby, RagonSerializer serializer)
{ {
_serializer = serializer; _serializer = serializer;
@@ -28,15 +28,10 @@ public class AuthorizationManager : IAuthorizationManager
public void OnAuthorization(uint peerId, string key, string name, byte protocol) public void OnAuthorization(uint peerId, string key, string name, byte protocol)
{ {
var dispatcher = _gameThread.ThreadDispatcher; var dispatcher = _gameThread.ThreadDispatcher;
_provider.OnAuthorizationRequest(key, name, protocol, Array.Empty<byte>(), _provider.OnAuthorizationRequest(key, name, protocol, Array.Empty<byte>(),
(playerId, playerName) => (playerId, playerName) => { dispatcher.Dispatch(() => Accepted(peerId, playerId, playerName)); },
{ (errorCode) => { dispatcher.Dispatch(() => Rejected(peerId, errorCode)); });
dispatcher.Dispatch(() => Accepted(peerId, playerId, playerName));
},
(errorCode) =>
{
dispatcher.Dispatch(() => Rejected(peerId, errorCode));
});
} }
public void Accepted(uint peerId, string playerId, string playerName) public void Accepted(uint peerId, string playerId, string playerName)
@@ -45,7 +40,7 @@ public class AuthorizationManager : IAuthorizationManager
_serializer.WriteOperation(RagonOperation.AUTHORIZED_SUCCESS); _serializer.WriteOperation(RagonOperation.AUTHORIZED_SUCCESS);
_serializer.WriteString(playerId); _serializer.WriteString(playerId);
_serializer.WriteString(playerName); _serializer.WriteString(playerName);
var player = new Player() var player = new Player()
{ {
Id = playerId, Id = playerId,
@@ -55,10 +50,10 @@ public class AuthorizationManager : IAuthorizationManager
Entities = new List<Entity>(), Entities = new List<Entity>(),
EntitiesIds = new List<int>(), EntitiesIds = new List<int>(),
}; };
_playersByIds.Add(playerId, player); _playersByIds.Add(playerId, player);
_playersByPeers.Add(peerId, player); _playersByPeers.Add(peerId, player);
var sendData = _serializer.ToArray(); var sendData = _serializer.ToArray();
_gameThread.Server.Send(peerId, sendData, DeliveryType.Reliable); _gameThread.Server.Send(peerId, sendData, DeliveryType.Reliable);
} }
@@ -84,10 +79,10 @@ public class AuthorizationManager : IAuthorizationManager
{ {
if (_playersByPeers.TryGetValue(peerId, out var player)) if (_playersByPeers.TryGetValue(peerId, out var player))
return player; return player;
return null; return null;
} }
public Player GetPlayer(string playerId) public Player GetPlayer(string playerId)
{ {
return _playersByIds[playerId]; return _playersByIds[playerId];
@@ -10,6 +10,7 @@ namespace Ragon.Core
public ushort SendRate; public ushort SendRate;
public ushort Port; public ushort Port;
public int SkipTimeout; public int SkipTimeout;
public int ReconnectTimeout;
public int MaxConnections; public int MaxConnections;
public int MaxPlayersPerRoom; public int MaxPlayersPerRoom;
public int MaxRooms; public int MaxRooms;
@@ -9,7 +9,7 @@ namespace Ragon.Core
public static class ConfigurationLoader public static class ConfigurationLoader
{ {
private static readonly Logger _logger = LogManager.GetCurrentClassLogger(); private static readonly Logger _logger = LogManager.GetCurrentClassLogger();
private static readonly string _serverVersion = "1.0.6-rc"; private static readonly string _serverVersion = "1.0.9-rc";
private static void CopyrightInfo() private static void CopyrightInfo()
{ {
+3 -1
View File
@@ -6,15 +6,17 @@ public class Entity
{ {
private static int _idGenerator = 0; private static int _idGenerator = 0;
public int EntityId { get; private set; } public int EntityId { get; private set; }
public int StaticId { get; private set; }
public uint OwnerId { get; private set; } public uint OwnerId { get; private set; }
public ushort EntityType { get; private set; } public ushort EntityType { get; private set; }
public RagonAuthority Authority { get; private set; } public RagonAuthority Authority { get; private set; }
public EntityState State { get; private set; } public EntityState State { get; private set; }
public EntityState Payload { get; private set; } public EntityState Payload { get; private set; }
public Entity(uint ownerId, ushort entityType, RagonAuthority stateAuthority, RagonAuthority eventAuthority) public Entity(uint ownerId, ushort entityType, int staticId, RagonAuthority stateAuthority, RagonAuthority eventAuthority)
{ {
OwnerId = ownerId; OwnerId = ownerId;
StaticId = staticId;
EntityType = entityType; EntityType = entityType;
EntityId = _idGenerator++; EntityId = _idGenerator++;
State = new EntityState(stateAuthority); State = new EntityState(stateAuthority);
+107 -37
View File
@@ -1,6 +1,5 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using NLog; using NLog;
using Ragon.Common; using Ragon.Common;
@@ -20,19 +19,21 @@ namespace Ragon.Core
private Dictionary<int, Entity> _entities = new(); private Dictionary<int, Entity> _entities = new();
private uint _owner; private uint _owner;
private readonly PluginBase _plugin; private readonly IScheduler _scheduler;
private readonly IGameThread _gameThread; private readonly IGameThread _gameThread;
private readonly PluginBase _plugin;
private readonly RagonSerializer _serializer = new(512); private readonly RagonSerializer _serializer = new(512);
// Cache // Cache
private uint[] _readyPlayers = Array.Empty<uint>(); private uint[] _readyPlayers = Array.Empty<uint>();
private uint[] _allPlayers = Array.Empty<uint>(); private uint[] _allPlayers = Array.Empty<uint>();
private Entity[] _entitiesAll = Array.Empty<Entity>(); private Entity[] _entitiesAll = Array.Empty<Entity>();
public GameRoom(IGameThread gameThread, PluginBase pluginBase, string map, int min, int max) public GameRoom(IGameThread gameThread, PluginBase pluginBase, string map, int min, int max)
{ {
_gameThread = gameThread; _gameThread = gameThread;
_plugin = pluginBase; _plugin = pluginBase;
_scheduler = new Scheduler();
Map = map; Map = map;
PlayersMin = min; PlayersMin = min;
@@ -48,7 +49,7 @@ namespace Ragon.Core
{ {
_owner = player.PeerId; _owner = player.PeerId;
} }
{ {
_serializer.Clear(); _serializer.Clear();
_serializer.WriteOperation(RagonOperation.PLAYER_JOINED); _serializer.WriteOperation(RagonOperation.PLAYER_JOINED);
@@ -59,10 +60,10 @@ namespace Ragon.Core
var sendData = _serializer.ToArray(); var sendData = _serializer.ToArray();
Broadcast(_readyPlayers, sendData, DeliveryType.Reliable); Broadcast(_readyPlayers, sendData, DeliveryType.Reliable);
} }
_players.Add(player.PeerId, player); _players.Add(player.PeerId, player);
_allPlayers = _players.Select(p => p.Key).ToArray(); _allPlayers = _players.Select(p => p.Key).ToArray();
{ {
_serializer.Clear(); _serializer.Clear();
_serializer.WriteOperation(RagonOperation.JOIN_SUCCESS); _serializer.WriteOperation(RagonOperation.JOIN_SUCCESS);
@@ -92,7 +93,7 @@ namespace Ragon.Core
{ {
_allPlayers = _players.Select(p => p.Key).ToArray(); _allPlayers = _players.Select(p => p.Key).ToArray();
_readyPlayers = _players.Where(p => p.Value.IsLoaded).Select(p => p.Key).ToArray(); _readyPlayers = _players.Where(p => p.Value.IsLoaded).Select(p => p.Key).ToArray();
var isOwnershipChange = player.PeerId == _owner; var isOwnershipChange = player.PeerId == _owner;
{ {
@@ -117,9 +118,9 @@ namespace Ragon.Core
{ {
var newRoomOwnerId = _allPlayers[0]; var newRoomOwnerId = _allPlayers[0];
var newRoomOwner = _players[newRoomOwnerId]; var newRoomOwner = _players[newRoomOwnerId];
_owner = newRoomOwnerId; _owner = newRoomOwnerId;
{ {
_plugin.OnOwnershipChanged(newRoomOwner); _plugin.OnOwnershipChanged(newRoomOwner);
@@ -140,10 +141,10 @@ namespace Ragon.Core
{ {
var operation = (RagonOperation) rawData[0]; var operation = (RagonOperation) rawData[0];
var payloadRawData = rawData.Slice(1, rawData.Length - 1); var payloadRawData = rawData.Slice(1, rawData.Length - 1);
_serializer.Clear(); _serializer.Clear();
_serializer.FromSpan(ref payloadRawData); _serializer.FromSpan(ref payloadRawData);
switch (operation) switch (operation)
{ {
case RagonOperation.REPLICATE_ENTITY_STATE: case RagonOperation.REPLICATE_ENTITY_STATE:
@@ -157,11 +158,13 @@ namespace Ragon.Core
var entityStateData = _serializer.ReadData(_serializer.Size); var entityStateData = _serializer.ReadData(_serializer.Size);
ent.State.Write(ref entityStateData); ent.State.Write(ref entityStateData);
} }
break; break;
} }
case RagonOperation.REPLICATE_ENTITY_EVENT: case RagonOperation.REPLICATE_ENTITY_EVENT:
{ {
var evntId = _serializer.ReadUShort(); var evntId = _serializer.ReadUShort();
var evntMode = _serializer.ReadByte();
var entityId = _serializer.ReadInt(); var entityId = _serializer.ReadInt();
if (!_entities.TryGetValue(entityId, out var ent)) if (!_entities.TryGetValue(entityId, out var ent))
@@ -173,7 +176,7 @@ namespace Ragon.Core
Span<byte> payloadRaw = stackalloc byte[_serializer.Size]; Span<byte> payloadRaw = stackalloc byte[_serializer.Size];
var payloadData = _serializer.ReadData(_serializer.Size); var payloadData = _serializer.ReadData(_serializer.Size);
payloadData.CopyTo(payloadRaw); payloadData.CopyTo(payloadRaw);
ReadOnlySpan<byte> payload = payloadRaw; ReadOnlySpan<byte> payload = payloadRaw;
if (_plugin.InternalHandle(peerId, entityId, evntId, ref payload)) if (_plugin.InternalHandle(peerId, entityId, evntId, ref payload))
return; return;
@@ -181,30 +184,76 @@ namespace Ragon.Core
_serializer.Clear(); _serializer.Clear();
_serializer.WriteOperation(RagonOperation.REPLICATE_ENTITY_EVENT); _serializer.WriteOperation(RagonOperation.REPLICATE_ENTITY_EVENT);
_serializer.WriteUShort(evntId); _serializer.WriteUShort(evntId);
_serializer.WriteUShort((ushort) peerId);
_serializer.WriteByte(evntMode);
_serializer.WriteInt(entityId); _serializer.WriteInt(entityId);
_serializer.WriteData(ref payload); _serializer.WriteData(ref payload);
var sendData = _serializer.ToArray(); var sendData = _serializer.ToArray();
Broadcast(_readyPlayers, sendData, DeliveryType.Reliable); Broadcast(_readyPlayers, sendData, DeliveryType.Reliable);
break; break;
} }
case RagonOperation.REPLICATE_EVENT: case RagonOperation.REPLICATE_EVENT:
{ {
var evntId = _serializer.ReadUShort(); var evntId = _serializer.ReadUShort();
var evntMode = _serializer.ReadByte();
Span<byte> payloadRaw = stackalloc byte[_serializer.Size]; Span<byte> payloadRaw = stackalloc byte[_serializer.Size];
var payloadData = _serializer.ReadData(_serializer.Size); var payloadData = _serializer.ReadData(_serializer.Size);
payloadData.CopyTo(payloadRaw); payloadData.CopyTo(payloadRaw);
ReadOnlySpan<byte> payload = payloadRaw; ReadOnlySpan<byte> payload = payloadRaw;
if (_plugin.InternalHandle(peerId, evntId, ref payload)) if (_plugin.InternalHandle(peerId, evntId, ref payload))
return; return;
_serializer.Clear(); _serializer.Clear();
_serializer.WriteOperation(RagonOperation.REPLICATE_EVENT); _serializer.WriteOperation(RagonOperation.REPLICATE_EVENT);
_serializer.WriteUShort((ushort) peerId);
_serializer.WriteByte(evntMode);
_serializer.WriteUShort(evntId); _serializer.WriteUShort(evntId);
_serializer.WriteData(ref payload); _serializer.WriteData(ref payload);
var sendData = _serializer.ToArray();
Broadcast(_readyPlayers, sendData, DeliveryType.Reliable);
break;
}
case RagonOperation.CREATE_STATIC_ENTITY:
{
var entityType = _serializer.ReadUShort();
var staticId = _serializer.ReadUShort();
var stateAuthority = (RagonAuthority) _serializer.ReadByte();
var eventAuthority = (RagonAuthority) _serializer.ReadByte();
var entity = new Entity(peerId, entityType, staticId, stateAuthority, eventAuthority);
{
var entityPayload = _serializer.ReadData(_serializer.Size);
entity.Payload.Write(ref entityPayload);
}
var player = _players[peerId];
player.Entities.Add(entity);
player.EntitiesIds.Add(entity.EntityId);
var ownerId = (ushort) peerId;
_entities.Add(entity.EntityId, entity);
_entitiesAll = _entities.Values.ToArray();
_plugin.OnEntityCreated(player, entity);
_serializer.Clear();
_serializer.WriteOperation(RagonOperation.CREATE_STATIC_ENTITY);
_serializer.WriteUShort(entityType);
_serializer.WriteUShort(staticId);
_serializer.WriteByte((byte) stateAuthority);
_serializer.WriteByte((byte) eventAuthority);
_serializer.WriteInt(entity.EntityId);
_serializer.WriteUShort(ownerId);
{
var entityPayload = entity.Payload.Read();
_serializer.WriteData(ref entityPayload);
}
var sendData = _serializer.ToArray(); var sendData = _serializer.ToArray();
Broadcast(_readyPlayers, sendData, DeliveryType.Reliable); Broadcast(_readyPlayers, sendData, DeliveryType.Reliable);
break; break;
@@ -214,8 +263,8 @@ namespace Ragon.Core
var entityType = _serializer.ReadUShort(); var entityType = _serializer.ReadUShort();
var stateAuthority = (RagonAuthority) _serializer.ReadByte(); var stateAuthority = (RagonAuthority) _serializer.ReadByte();
var eventAuthority = (RagonAuthority) _serializer.ReadByte(); var eventAuthority = (RagonAuthority) _serializer.ReadByte();
var entity = new Entity(peerId, entityType, stateAuthority, eventAuthority); var entity = new Entity(peerId, entityType, -1, stateAuthority, eventAuthority);
{ {
var entityPayload = _serializer.ReadData(_serializer.Size); var entityPayload = _serializer.ReadData(_serializer.Size);
entity.Payload.Write(ref entityPayload); entity.Payload.Write(ref entityPayload);
@@ -239,12 +288,12 @@ namespace Ragon.Core
_serializer.WriteByte((byte) eventAuthority); _serializer.WriteByte((byte) eventAuthority);
_serializer.WriteInt(entity.EntityId); _serializer.WriteInt(entity.EntityId);
_serializer.WriteUShort(ownerId); _serializer.WriteUShort(ownerId);
{ {
var entityPayload = entity.Payload.Read(); var entityPayload = entity.Payload.Read();
_serializer.WriteData(ref entityPayload); _serializer.WriteData(ref entityPayload);
} }
var sendData = _serializer.ToArray(); var sendData = _serializer.ToArray();
Broadcast(_readyPlayers, sendData, DeliveryType.Reliable); Broadcast(_readyPlayers, sendData, DeliveryType.Reliable);
break; break;
@@ -291,14 +340,36 @@ namespace Ragon.Core
_serializer.WriteUShort((ushort) playerPeerId); _serializer.WriteUShort((ushort) playerPeerId);
_serializer.WriteString(_players[playerPeerId].PlayerName); _serializer.WriteString(_players[playerPeerId].PlayerName);
} }
_serializer.WriteInt(_entitiesAll.Length); var dynamicCount = _entitiesAll.Where(e => e.StaticId == -1).ToArray();
foreach (var entity in _entitiesAll) _serializer.WriteInt(dynamicCount.Length);
foreach (var entity in dynamicCount)
{
if (entity.StaticId != -1) continue;
var payload = entity.Payload.Read();
var state = entity.State.Read();
_serializer.WriteInt(entity.EntityId);
_serializer.WriteByte((byte) entity.State.Authority);
_serializer.WriteByte((byte) entity.Authority);
_serializer.WriteUShort(entity.EntityType);
_serializer.WriteUShort((ushort) entity.OwnerId);
_serializer.WriteUShort((ushort) payload.Length);
_serializer.WriteData(ref payload);
_serializer.WriteUShort((ushort) state.Length);
_serializer.WriteData(ref state);
}
var staticCount = _entitiesAll.Where(e => e.StaticId != -1).ToArray();
_serializer.WriteInt(staticCount.Length);
foreach (var entity in staticCount)
{ {
var payload = entity.Payload.Read(); var payload = entity.Payload.Read();
var state = entity.State.Read(); var state = entity.State.Read();
_serializer.WriteInt(entity.EntityId); _serializer.WriteInt(entity.EntityId);
_serializer.WriteUShort((ushort) entity.StaticId);
_serializer.WriteByte((byte) entity.State.Authority); _serializer.WriteByte((byte) entity.State.Authority);
_serializer.WriteByte((byte) entity.Authority); _serializer.WriteByte((byte) entity.Authority);
_serializer.WriteUShort(entity.EntityType); _serializer.WriteUShort(entity.EntityType);
@@ -320,10 +391,10 @@ namespace Ragon.Core
} }
} }
} }
public void Tick(float deltaTime) public void Tick(float deltaTime)
{ {
_plugin.OnTick(deltaTime); _scheduler.Tick(deltaTime);
foreach (var entity in _entitiesAll) foreach (var entity in _entitiesAll)
{ {
@@ -351,6 +422,9 @@ namespace Ragon.Core
public void Stop() public void Stop()
{ {
foreach (var peerId in _allPlayers)
_gameThread.Server.Disconnect(peerId, 0);
_plugin.OnStop(); _plugin.OnStop();
_plugin.Detach(); _plugin.Detach();
} }
@@ -358,10 +432,12 @@ namespace Ragon.Core
public Player GetPlayerById(uint peerId) => _players[peerId]; public Player GetPlayerById(uint peerId) => _players[peerId];
public Entity GetEntityById(int entityId) => _entities[entityId]; public Entity GetEntityById(int entityId) => _entities[entityId];
public Player GetOwner() => _players[_owner]; public Player GetOwner() => _players[_owner];
public IDispatcher GetThreadDispatcher() => _gameThread.ThreadDispatcher; public IDispatcher GetThreadDispatcher() => _gameThread.ThreadDispatcher;
public IScheduler GetScheduler() => _scheduler;
public void Send(uint peerId, byte[] rawData, DeliveryType deliveryType = DeliveryType.Unreliable) public void Send(uint peerId, byte[] rawData, DeliveryType deliveryType = DeliveryType.Unreliable)
{ {
@@ -370,18 +446,12 @@ namespace Ragon.Core
public void Broadcast(uint[] peersIds, byte[] rawData, DeliveryType deliveryType = DeliveryType.Unreliable) public void Broadcast(uint[] peersIds, byte[] rawData, DeliveryType deliveryType = DeliveryType.Unreliable)
{ {
foreach (var peer in peersIds) _gameThread.Server.Broadcast(peersIds, rawData, deliveryType);
{
_gameThread.Server.Send(peer, rawData, deliveryType);
}
} }
public void Broadcast(byte[] rawData, DeliveryType deliveryType = DeliveryType.Unreliable) public void Broadcast(byte[] rawData, DeliveryType deliveryType = DeliveryType.Unreliable)
{ {
foreach (var peer in _allPlayers) _gameThread.Server.Broadcast(_allPlayers, rawData, deliveryType);
{
_gameThread.Server.Send(peer, rawData, deliveryType);
}
} }
} }
} }
+1
View File
@@ -12,6 +12,7 @@ public interface IGameRoom
public Entity GetEntityById(int entityId); public Entity GetEntityById(int entityId);
public Player GetOwner(); public Player GetOwner();
public IDispatcher GetThreadDispatcher(); public IDispatcher GetThreadDispatcher();
public IScheduler GetScheduler();
public void Send(uint peerId, byte[] rawData, DeliveryType deliveryType = DeliveryType.Unreliable); public void Send(uint peerId, byte[] rawData, DeliveryType deliveryType = DeliveryType.Unreliable);
public void Broadcast(uint[] peersIds, byte[] rawData, DeliveryType deliveryType = DeliveryType.Unreliable); public void Broadcast(uint[] peersIds, byte[] rawData, DeliveryType deliveryType = DeliveryType.Unreliable);
+10 -9
View File
@@ -8,14 +8,15 @@ public class Lobby : ILobby
{ {
private readonly RagonSerializer _serializer; private readonly RagonSerializer _serializer;
private readonly RoomManager _roomManager; private readonly RoomManager _roomManager;
private readonly AuthorizationManager _authorizationManager;
public AuthorizationManager AuthorizationManager { get; private set; } public AuthorizationManager AuthorizationManager => _authorizationManager;
public Lobby(IAuthorizationProvider provider, RoomManager manager, IGameThread gameThread) public Lobby(IAuthorizationProvider provider, RoomManager manager, IGameThread gameThread)
{ {
_roomManager = manager; _roomManager = manager;
_serializer = new RagonSerializer(); _serializer = new RagonSerializer();
AuthorizationManager = new AuthorizationManager(provider, gameThread, this, _serializer); _authorizationManager = new AuthorizationManager(provider, gameThread, this, _serializer);
} }
public void ProcessEvent(uint peerId, ReadOnlySpan<byte> data) public void ProcessEvent(uint peerId, ReadOnlySpan<byte> data)
@@ -33,30 +34,30 @@ public class Lobby : ILobby
var key = _serializer.ReadString(); var key = _serializer.ReadString();
var playerName = _serializer.ReadString(); var playerName = _serializer.ReadString();
var protocol = _serializer.ReadByte(); var protocol = _serializer.ReadByte();
AuthorizationManager.OnAuthorization(peerId, key, playerName, protocol); _authorizationManager.OnAuthorization(peerId, key, playerName, protocol);
break; break;
} }
case RagonOperation.JOIN_ROOM: case RagonOperation.JOIN_ROOM:
{ {
var roomId = _serializer.ReadString(); var roomId = _serializer.ReadString();
var player = AuthorizationManager.GetPlayer(peerId); var player = _authorizationManager.GetPlayer(peerId);
if (player != null) if (player != null)
_roomManager.Join(player, roomId, Array.Empty<byte>()); _roomManager.Join(player, roomId, Array.Empty<byte>());
break; break;
} }
case RagonOperation.JOIN_OR_CREATE_ROOM: case RagonOperation.JOIN_OR_CREATE_ROOM:
{ {
var min = _serializer.ReadUShort();
var max = _serializer.ReadUShort();
var map = _serializer.ReadString(); var map = _serializer.ReadString();
var min = _serializer.ReadInt(); var player = _authorizationManager.GetPlayer(peerId);
var max = _serializer.ReadInt();
var player = AuthorizationManager.GetPlayer(peerId);
if (player != null) if (player != null)
_roomManager.JoinOrCreate(player, map, min, max, Array.Empty<byte>()); _roomManager.JoinOrCreate(player, map, min, max, Array.Empty<byte>());
break; break;
} }
case RagonOperation.LEAVE_ROOM: case RagonOperation.LEAVE_ROOM:
{ {
var player = AuthorizationManager.GetPlayer(peerId); var player = _authorizationManager.GetPlayer(peerId);
if (player != null) if (player != null)
_roomManager.Left(player, Array.Empty<byte>()); _roomManager.Left(player, Array.Empty<byte>());
break; break;
@@ -66,6 +67,6 @@ public class Lobby : ILobby
public void OnDisconnected(uint peerId) public void OnDisconnected(uint peerId)
{ {
AuthorizationManager.Cleanup(peerId); _authorizationManager.Cleanup(peerId);
} }
} }
+1 -5
View File
@@ -264,11 +264,7 @@ namespace Ragon.Core
public virtual void OnStop() public virtual void OnStop()
{ {
} }
public virtual void OnTick(float deltaTime)
{
}
#endregion #endregion
} }
} }
+22
View File
@@ -43,6 +43,28 @@ namespace Ragon.Core
_logger.Info($"Network listening on {port}"); _logger.Info($"Network listening on {port}");
} }
public void Broadcast(uint[] peersIds, byte[] data, DeliveryType type)
{
var newPacket = new Packet();
var packetFlags = PacketFlags.Instant;
byte channel = 1;
if (type == DeliveryType.Reliable)
{
packetFlags = PacketFlags.Reliable;
channel = 0;
}
else if (type == DeliveryType.Unreliable)
{
channel = 1;
packetFlags = PacketFlags.None;
}
newPacket.Create(data, data.Length, packetFlags);
foreach (var peerId in peersIds)
_peers[peerId].Send(channel, ref newPacket);
}
public void Send(uint peerId, byte[] data, DeliveryType type) public void Send(uint peerId, byte[] data, DeliveryType type)
{ {
var newPacket = new Packet(); var newPacket = new Packet();
+1
View File
@@ -6,5 +6,6 @@ public interface ISocketServer
public void Process(); public void Process();
public void Stop(); public void Stop();
public void Send(uint peerId, byte[] data, DeliveryType type); public void Send(uint peerId, byte[] data, DeliveryType type);
public void Broadcast(uint[] peersIds, byte[] data, DeliveryType type);
public void Disconnect(uint peerId, uint errorCode); public void Disconnect(uint peerId, uint errorCode);
} }
+12
View File
@@ -0,0 +1,12 @@
using System;
namespace Ragon.Core;
public interface IScheduler
{
public SchedulerTask Schedule(Action<SchedulerTask> action, float interval, int count = 1);
public SchedulerTask ScheduleForever(Action<SchedulerTask> action, float interval);
public void StopSchedule(SchedulerTask schedulerTask);
public void Tick(float deltaTime);
}
+98
View File
@@ -0,0 +1,98 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
namespace Ragon.Core
{
public class Scheduler: IScheduler
{
List<SchedulerTask> _scheduledTasks;
public Scheduler(int defaultCapacity = 100)
{
_scheduledTasks = new List<SchedulerTask>(defaultCapacity);
}
public SchedulerTask Schedule(Action<SchedulerTask> action, float interval, int count = 1)
{
var newTask = new SchedulerTask(action, interval, count - 1);
_scheduledTasks.Add(newTask);
return newTask;
}
public SchedulerTask ScheduleForever(Action<SchedulerTask> action, float interval)
{
var newTask = new SchedulerTask(action, interval, -1);
_scheduledTasks.Add(newTask);
return newTask;
}
public void StopSchedule(SchedulerTask schedulerTask)
{
if (_scheduledTasks.Contains(schedulerTask))
_scheduledTasks.Remove(schedulerTask);
}
public void Tick(float deltaTime)
{
for (int i = _scheduledTasks.Count - 1; i >= 0; i--)
{
var scheduledTask = _scheduledTasks[i];
scheduledTask.Tick(deltaTime);
if (!scheduledTask.IsActive)
_scheduledTasks.Remove(scheduledTask);
}
}
public void Dispose()
{
_scheduledTasks.Clear();
}
}
public class SchedulerTask
{
private Action<SchedulerTask> _action;
private float _timer = 0;
private float _interval = 0;
private int _repeats = 0;
private bool _active;
public int Repeats => _repeats;
public bool IsActive => _active;
public SchedulerTask(Action<SchedulerTask> task, float interval, int repeatCount = 0)
{
_action = task;
_interval = interval;
_timer = 0;
_active = true;
_repeats = repeatCount;
}
public void Tick(float deltaTime)
{
_timer += deltaTime;
if (_timer >= _interval)
{
_action.Invoke(this);
if (_repeats == -1)
{
_timer = 0;
return;
}
if (_repeats > 0)
{
_timer = 0;
_repeats--;
return;
}
if (_repeats == 0)
_active = false;
}
}
}
}