refactor
This commit is contained in:
+1
-1
@@ -3,7 +3,7 @@
|
||||
<PropertyGroup>
|
||||
<LangVersion>10</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
<TargetFrameworks>net6.0;netstandard2.1</TargetFrameworks>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace Ragon.Core
|
||||
{
|
||||
private readonly Logger _logger = LogManager.GetCurrentClassLogger();
|
||||
private readonly GameThread _gameThread;
|
||||
private readonly ENetServer _netServer;
|
||||
|
||||
public Application(PluginFactory factory, Configuration configuration)
|
||||
{
|
||||
_gameThread = new GameThread(factory, configuration);
|
||||
|
||||
@@ -27,7 +27,7 @@ public class AuthorizationManager : IAuthorizationManager
|
||||
|
||||
public void OnAuthorization(uint peerId, string key, string name, byte protocol)
|
||||
{
|
||||
var dispatcher = _gameThread.Dispatcher;
|
||||
var dispatcher = _gameThread.ThreadDispatcher;
|
||||
_provider.OnAuthorizationRequest(key, name, protocol, Array.Empty<byte>(),
|
||||
(playerId, playerName) =>
|
||||
{
|
||||
@@ -77,9 +77,12 @@ public class AuthorizationManager : IAuthorizationManager
|
||||
_playersByIds.Remove(player.Id);
|
||||
}
|
||||
|
||||
public Player GetPlayer(uint peerId)
|
||||
public Player? GetPlayer(uint peerId)
|
||||
{
|
||||
return _playersByPeers[peerId];
|
||||
if (_playersByPeers.TryGetValue(peerId, out var player))
|
||||
return player;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public Player GetPlayer(string playerId)
|
||||
|
||||
@@ -2,17 +2,16 @@
|
||||
|
||||
namespace Ragon.Core
|
||||
{
|
||||
[Serializable]
|
||||
public struct Server
|
||||
{
|
||||
public ushort Port;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct Configuration
|
||||
{
|
||||
public string Key;
|
||||
public ushort TickRate;
|
||||
public Server Server;
|
||||
public int StatisticsInterval;
|
||||
public ushort SendRate;
|
||||
public ushort Port;
|
||||
public int SkipTimeout;
|
||||
public int MaxConnections;
|
||||
public int MaxPlayersPerRoom;
|
||||
public int MaxRooms;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
namespace Ragon.Core;
|
||||
|
||||
public interface Receiver<T>
|
||||
{
|
||||
public bool Receive(out T data);
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
namespace Ragon.Core;
|
||||
|
||||
public interface ISender<T>
|
||||
{
|
||||
public void Send(T data);
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Ragon.Core;
|
||||
|
||||
public class DispatcherTask
|
||||
{
|
||||
public Action Action;
|
||||
public Action Callback;
|
||||
|
||||
public void Execute()
|
||||
{
|
||||
Action?.Invoke();
|
||||
}
|
||||
}
|
||||
@@ -1,130 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
|
||||
namespace Ragon.Core.Core.Utils;
|
||||
|
||||
public class SynchronizedCache
|
||||
{
|
||||
private ReaderWriterLockSlim cacheLock = new ReaderWriterLockSlim();
|
||||
private Dictionary<int, string> innerCache = new Dictionary<int, string>();
|
||||
|
||||
public int Count
|
||||
{ get { return innerCache.Count; } }
|
||||
|
||||
public string Read(int key)
|
||||
{
|
||||
cacheLock.EnterReadLock();
|
||||
try
|
||||
{
|
||||
return innerCache[key];
|
||||
}
|
||||
finally
|
||||
{
|
||||
cacheLock.ExitReadLock();
|
||||
}
|
||||
}
|
||||
|
||||
public void Add(int key, string value)
|
||||
{
|
||||
cacheLock.EnterWriteLock();
|
||||
try
|
||||
{
|
||||
innerCache.Add(key, value);
|
||||
}
|
||||
finally
|
||||
{
|
||||
cacheLock.ExitWriteLock();
|
||||
}
|
||||
}
|
||||
|
||||
public bool AddWithTimeout(int key, string value, int timeout)
|
||||
{
|
||||
if (cacheLock.TryEnterWriteLock(timeout))
|
||||
{
|
||||
try
|
||||
{
|
||||
innerCache.Add(key, value);
|
||||
}
|
||||
finally
|
||||
{
|
||||
cacheLock.ExitWriteLock();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public AddOrUpdateStatus AddOrUpdate(int key, string value)
|
||||
{
|
||||
cacheLock.EnterUpgradeableReadLock();
|
||||
try
|
||||
{
|
||||
string result = null;
|
||||
if (innerCache.TryGetValue(key, out result))
|
||||
{
|
||||
if (result == value)
|
||||
{
|
||||
return AddOrUpdateStatus.Unchanged;
|
||||
}
|
||||
else
|
||||
{
|
||||
cacheLock.EnterWriteLock();
|
||||
try
|
||||
{
|
||||
innerCache[key] = value;
|
||||
}
|
||||
finally
|
||||
{
|
||||
cacheLock.ExitWriteLock();
|
||||
}
|
||||
return AddOrUpdateStatus.Updated;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cacheLock.EnterWriteLock();
|
||||
try
|
||||
{
|
||||
innerCache.Add(key, value);
|
||||
}
|
||||
finally
|
||||
{
|
||||
cacheLock.ExitWriteLock();
|
||||
}
|
||||
return AddOrUpdateStatus.Added;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
cacheLock.ExitUpgradeableReadLock();
|
||||
}
|
||||
}
|
||||
|
||||
public void Delete(int key)
|
||||
{
|
||||
cacheLock.EnterWriteLock();
|
||||
try
|
||||
{
|
||||
innerCache.Remove(key);
|
||||
}
|
||||
finally
|
||||
{
|
||||
cacheLock.ExitWriteLock();
|
||||
}
|
||||
}
|
||||
|
||||
public enum AddOrUpdateStatus
|
||||
{
|
||||
Added,
|
||||
Updated,
|
||||
Unchanged
|
||||
};
|
||||
|
||||
~SynchronizedCache()
|
||||
{
|
||||
if (cacheLock != null) cacheLock.Dispose();
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace Ragon.Core
|
||||
{
|
||||
public struct SocketEvent
|
||||
{
|
||||
public EventType Type;
|
||||
public DeliveryType Delivery;
|
||||
public byte[] Data;
|
||||
public uint PeerId;
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
namespace Ragon.Core
|
||||
{
|
||||
public enum EventType
|
||||
{
|
||||
CONNECTED,
|
||||
DISCONNECTED,
|
||||
TIMEOUT,
|
||||
DATA,
|
||||
}
|
||||
}
|
||||
@@ -19,7 +19,6 @@ namespace Ragon.Core
|
||||
private Dictionary<uint, Player> _players = new();
|
||||
private Dictionary<int, Entity> _entities = new();
|
||||
private uint _owner;
|
||||
private uint _ticks;
|
||||
|
||||
private readonly PluginBase _plugin;
|
||||
private readonly IGameThread _gameThread;
|
||||
@@ -40,7 +39,6 @@ namespace Ragon.Core
|
||||
PlayersMax = max;
|
||||
Id = Guid.NewGuid().ToString();
|
||||
|
||||
_logger.Info($"Room created with plugin: {_plugin.GetType().Name}");
|
||||
_plugin.Attach(this);
|
||||
}
|
||||
|
||||
@@ -119,7 +117,9 @@ namespace Ragon.Core
|
||||
{
|
||||
var newRoomOwnerId = _allPlayers[0];
|
||||
var newRoomOwner = _players[newRoomOwnerId];
|
||||
|
||||
|
||||
_owner = newRoomOwnerId;
|
||||
|
||||
{
|
||||
_plugin.OnOwnershipChanged(newRoomOwner);
|
||||
|
||||
@@ -323,8 +323,7 @@ namespace Ragon.Core
|
||||
|
||||
public void Tick(float deltaTime)
|
||||
{
|
||||
_ticks++;
|
||||
_plugin.OnTick(_ticks, deltaTime);
|
||||
_plugin.OnTick(deltaTime);
|
||||
|
||||
foreach (var entity in _entitiesAll)
|
||||
{
|
||||
@@ -347,15 +346,12 @@ namespace Ragon.Core
|
||||
|
||||
public void Start()
|
||||
{
|
||||
_logger.Info("Room started");
|
||||
_plugin.OnStart();
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
_logger.Info("Room stopped");
|
||||
_plugin.OnStop();
|
||||
|
||||
_plugin.Detach();
|
||||
}
|
||||
|
||||
@@ -365,6 +361,8 @@ namespace Ragon.Core
|
||||
|
||||
public Player GetOwner() => _players[_owner];
|
||||
|
||||
public IDispatcher GetThreadDispatcher() => _gameThread.ThreadDispatcher;
|
||||
|
||||
public void Send(uint peerId, byte[] rawData, DeliveryType deliveryType = DeliveryType.Unreliable)
|
||||
{
|
||||
_gameThread.Server.Send(peerId, rawData, deliveryType);
|
||||
|
||||
@@ -9,37 +9,37 @@ namespace Ragon.Core
|
||||
{
|
||||
public class GameThread : IGameThread, IHandler
|
||||
{
|
||||
private readonly Dictionary<uint, GameRoom> _socketByRooms;
|
||||
private readonly RoomManager _roomManager;
|
||||
private readonly ISocketServer _server;
|
||||
private readonly Thread _thread;
|
||||
private readonly Server _serverConfiguration;
|
||||
private readonly Stopwatch _gameLoopTimer;
|
||||
private readonly Lobby _lobby;
|
||||
private readonly ILogger _logger = LogManager.GetCurrentClassLogger();
|
||||
private readonly float _deltaTime = 0.0f;
|
||||
private readonly Stopwatch _packetsTimer;
|
||||
private int _packets = 0;
|
||||
|
||||
public IDispatcher Dispatcher { get; private set; }
|
||||
private readonly Stopwatch _statisticsTimer;
|
||||
private readonly Configuration _configuration;
|
||||
private readonly IDispatcherInternal _dispatcherInternal;
|
||||
|
||||
public IDispatcher ThreadDispatcher { get; private set; }
|
||||
public ISocketServer Server { get; private set; }
|
||||
|
||||
|
||||
public GameThread(PluginFactory factory, Configuration configuration)
|
||||
{
|
||||
_configuration = configuration;
|
||||
|
||||
var authorizationProvider = factory.CreateAuthorizationProvider(configuration);
|
||||
var dispatcher = new Dispatcher();
|
||||
_dispatcherInternal = dispatcher;
|
||||
|
||||
Dispatcher = new Dispatcher();
|
||||
ThreadDispatcher = dispatcher;
|
||||
Server = new ENetServer(this);
|
||||
|
||||
_serverConfiguration = configuration.Server;
|
||||
_deltaTime = 1000.0f / configuration.TickRate;
|
||||
|
||||
_deltaTime = 1000.0f / configuration.SendRate;
|
||||
|
||||
_roomManager = new RoomManager(factory, this);
|
||||
_lobby = new Lobby(authorizationProvider, _roomManager, this);
|
||||
|
||||
|
||||
_gameLoopTimer = new Stopwatch();
|
||||
_packetsTimer = new Stopwatch();
|
||||
_socketByRooms = new Dictionary<uint, GameRoom>();
|
||||
_statisticsTimer = new Stopwatch();
|
||||
|
||||
_thread = new Thread(Execute);
|
||||
_thread.Name = "Game Thread";
|
||||
@@ -48,19 +48,19 @@ namespace Ragon.Core
|
||||
|
||||
public void Start()
|
||||
{
|
||||
Server.Start(_serverConfiguration.Port);
|
||||
|
||||
Server.Start(_configuration.Port, _configuration.MaxConnections);
|
||||
|
||||
_gameLoopTimer.Start();
|
||||
_packetsTimer.Start();
|
||||
_statisticsTimer.Start();
|
||||
_thread.Start();
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
Server.Stop();
|
||||
|
||||
|
||||
_gameLoopTimer.Stop();
|
||||
_packetsTimer.Stop();
|
||||
_statisticsTimer.Stop();
|
||||
_thread.Interrupt();
|
||||
}
|
||||
|
||||
@@ -69,8 +69,9 @@ namespace Ragon.Core
|
||||
while (true)
|
||||
{
|
||||
Server.Process();
|
||||
Dispatcher.Process();
|
||||
|
||||
_dispatcherInternal.Process();
|
||||
|
||||
var elapsedMilliseconds = _gameLoopTimer.ElapsedMilliseconds;
|
||||
if (elapsedMilliseconds > _deltaTime)
|
||||
{
|
||||
@@ -79,47 +80,38 @@ namespace Ragon.Core
|
||||
continue;
|
||||
}
|
||||
|
||||
if (_packetsTimer.Elapsed.Seconds > 1)
|
||||
if (_statisticsTimer.Elapsed.Seconds > _configuration.StatisticsInterval && _roomManager.RoomsBySocket.Count > 0)
|
||||
{
|
||||
_logger.Trace($"Clients: {_socketByRooms.Keys.Count} Packets: {_packets} per sec");
|
||||
_packetsTimer.Restart();
|
||||
_packets = 0;
|
||||
_logger.Trace($"Rooms: {_roomManager.Rooms.Count} Clients: {_roomManager.RoomsBySocket.Count}");
|
||||
_statisticsTimer.Restart();
|
||||
}
|
||||
|
||||
Thread.Sleep(15);
|
||||
}
|
||||
}
|
||||
|
||||
public void Attach(uint peerId, GameRoom room)
|
||||
{
|
||||
_socketByRooms.Add(peerId, room);
|
||||
}
|
||||
|
||||
public void Detach(uint peerId)
|
||||
{
|
||||
_socketByRooms.Remove(peerId);
|
||||
}
|
||||
|
||||
public void OnEvent(Event evnt)
|
||||
{
|
||||
if (evnt.Type == ENet.EventType.Timeout || evnt.Type == ENet.EventType.Disconnect)
|
||||
if (evnt.Type == EventType.Timeout || evnt.Type == EventType.Disconnect)
|
||||
{
|
||||
if (_socketByRooms.Remove(evnt.Peer.ID, out var room))
|
||||
room.Leave(evnt.Peer.ID);
|
||||
var player = _lobby.AuthorizationManager.GetPlayer(evnt.Peer.ID);
|
||||
if (player != null)
|
||||
_roomManager.Left(player, Array.Empty<byte>());
|
||||
|
||||
_lobby.OnDisconnected(evnt.Peer.ID);
|
||||
}
|
||||
|
||||
if (evnt.Type == ENet.EventType.Receive)
|
||||
if (evnt.Type == EventType.Receive)
|
||||
{
|
||||
_packets += 1;
|
||||
try
|
||||
{
|
||||
var peerId = evnt.Peer.ID;
|
||||
var dataRaw = new byte[evnt.Packet.Length];
|
||||
evnt.Packet.CopyTo(dataRaw);
|
||||
|
||||
|
||||
var data = new ReadOnlySpan<byte>(dataRaw);
|
||||
if (_socketByRooms.TryGetValue(peerId, out var room))
|
||||
if (_roomManager.RoomsBySocket.TryGetValue(peerId, out var room))
|
||||
{
|
||||
room.ProcessEvent(peerId, data);
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ public interface IGameRoom
|
||||
public Player GetPlayerById(uint peerId);
|
||||
public Entity GetEntityById(int entityId);
|
||||
public Player GetOwner();
|
||||
public IDispatcher GetThreadDispatcher();
|
||||
|
||||
public void Send(uint peerId, byte[] rawData, DeliveryType deliveryType = DeliveryType.Unreliable);
|
||||
public void Broadcast(uint[] peersIds, byte[] rawData, DeliveryType deliveryType = DeliveryType.Unreliable);
|
||||
|
||||
@@ -4,8 +4,6 @@ namespace Ragon.Core;
|
||||
|
||||
public interface IGameThread
|
||||
{
|
||||
public void Attach(uint peerId, GameRoom room);
|
||||
public void Detach(uint peerId);
|
||||
public IDispatcher Dispatcher { get; }
|
||||
public IDispatcher ThreadDispatcher { get; }
|
||||
public ISocketServer Server { get; }
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace Ragon.Core;
|
||||
|
||||
public interface ILobby
|
||||
{
|
||||
|
||||
}
|
||||
@@ -1,19 +1,21 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Ragon.Common;
|
||||
|
||||
namespace Ragon.Core;
|
||||
|
||||
public class Lobby
|
||||
public class Lobby : ILobby
|
||||
{
|
||||
private readonly RagonSerializer _serializer;
|
||||
private readonly AuthorizationManager _authorizationManager;
|
||||
private readonly RoomManager _roomManager;
|
||||
|
||||
public AuthorizationManager AuthorizationManager { get; private set; }
|
||||
|
||||
public Lobby(IAuthorizationProvider provider, RoomManager manager, IGameThread gameThread)
|
||||
{
|
||||
_roomManager = manager;
|
||||
_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)
|
||||
@@ -31,14 +33,15 @@ public class Lobby
|
||||
var key = _serializer.ReadString();
|
||||
var playerName = _serializer.ReadString();
|
||||
var protocol = _serializer.ReadByte();
|
||||
_authorizationManager.OnAuthorization(peerId, key, playerName, protocol);
|
||||
AuthorizationManager.OnAuthorization(peerId, key, playerName, protocol);
|
||||
break;
|
||||
}
|
||||
case RagonOperation.JOIN_ROOM:
|
||||
{
|
||||
var roomId = _serializer.ReadString();
|
||||
var player = _authorizationManager.GetPlayer(peerId);
|
||||
_roomManager.Join(player, roomId, Array.Empty<byte>());
|
||||
var player = AuthorizationManager.GetPlayer(peerId);
|
||||
if (player != null)
|
||||
_roomManager.Join(player, roomId, Array.Empty<byte>());
|
||||
break;
|
||||
}
|
||||
case RagonOperation.JOIN_OR_CREATE_ROOM:
|
||||
@@ -46,14 +49,16 @@ public class Lobby
|
||||
var map = _serializer.ReadString();
|
||||
var min = _serializer.ReadInt();
|
||||
var max = _serializer.ReadInt();
|
||||
var player = _authorizationManager.GetPlayer(peerId);
|
||||
_roomManager.JoinOrCreate(player, map, min, max, Array.Empty<byte>());
|
||||
var player = AuthorizationManager.GetPlayer(peerId);
|
||||
if (player != null)
|
||||
_roomManager.JoinOrCreate(player, map, min, max, Array.Empty<byte>());
|
||||
break;
|
||||
}
|
||||
case RagonOperation.LEAVE_ROOM:
|
||||
{
|
||||
var player = _authorizationManager.GetPlayer(peerId);
|
||||
_roomManager.Left(player, Array.Empty<byte>());
|
||||
var player = AuthorizationManager.GetPlayer(peerId);
|
||||
if (player != null)
|
||||
_roomManager.Left(player, Array.Empty<byte>());
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -61,6 +66,6 @@ public class Lobby
|
||||
|
||||
public void OnDisconnected(uint peerId)
|
||||
{
|
||||
_authorizationManager.Cleanup(peerId);
|
||||
AuthorizationManager.Cleanup(peerId);
|
||||
}
|
||||
}
|
||||
@@ -18,12 +18,12 @@ namespace Ragon.Core
|
||||
private readonly BitBuffer _buffer = new();
|
||||
private readonly RagonSerializer _serializer = new();
|
||||
|
||||
protected IGameRoom GameRoom { get; private set; }
|
||||
protected ILogger _logger;
|
||||
protected IGameRoom GameRoom { get; private set; } = null!;
|
||||
protected ILogger Logger = null!;
|
||||
|
||||
public void Attach(GameRoom gameRoom)
|
||||
{
|
||||
_logger = LogManager.GetLogger($"Plugin<{GetType().Name}>");
|
||||
Logger = LogManager.GetLogger($"Plugin<{GetType().Name}>");
|
||||
|
||||
GameRoom = gameRoom;
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace Ragon.Core
|
||||
{
|
||||
if (_globalEvents.ContainsKey(evntCode))
|
||||
{
|
||||
_logger.Warn($"Event subscriber already added {evntCode}");
|
||||
Logger.Warn($"Event subscriber already added {evntCode}");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ namespace Ragon.Core
|
||||
{
|
||||
if (raw.Length == 0)
|
||||
{
|
||||
_logger.Warn($"Payload is empty for event {evntCode}");
|
||||
Logger.Warn($"Payload is empty for event {evntCode}");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ namespace Ragon.Core
|
||||
{
|
||||
if (_globalEvents.ContainsKey(evntCode))
|
||||
{
|
||||
_logger.Warn($"Event subscriber already added {evntCode}");
|
||||
Logger.Warn($"Event subscriber already added {evntCode}");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ namespace Ragon.Core
|
||||
{
|
||||
if (_entityEvents[entity.EntityId].ContainsKey(evntCode))
|
||||
{
|
||||
_logger.Warn($"Event subscriber already added {evntCode} for {entity.EntityId}");
|
||||
Logger.Warn($"Event subscriber already added {evntCode} for {entity.EntityId}");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@ namespace Ragon.Core
|
||||
{
|
||||
if (raw.Length == 0)
|
||||
{
|
||||
_logger.Warn($"Payload is empty for entity {ent.EntityId} event {evntCode}");
|
||||
Logger.Warn($"Payload is empty for entity {ent.EntityId} event {evntCode}");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ namespace Ragon.Core
|
||||
{
|
||||
if (raw.Length == 0)
|
||||
{
|
||||
_logger.Warn($"Payload is empty for entity {ent.EntityId} event {evntCode}");
|
||||
Logger.Warn($"Payload is empty for entity {ent.EntityId} event {evntCode}");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -125,7 +125,7 @@ namespace Ragon.Core
|
||||
{
|
||||
if (_entityEvents[entity.EntityId].ContainsKey(evntCode))
|
||||
{
|
||||
_logger.Warn($"Event subscriber already added {evntCode} for {entity.EntityId}");
|
||||
Logger.Warn($"Event subscriber already added {evntCode} for {entity.EntityId}");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -265,7 +265,7 @@ namespace Ragon.Core
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void OnTick(ulong ticks, float deltaTime)
|
||||
public virtual void OnTick(float deltaTime)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
@@ -12,14 +11,19 @@ public class RoomManager
|
||||
private readonly IGameThread _gameThread;
|
||||
private readonly PluginFactory _factory;
|
||||
private readonly Logger _logger = LogManager.GetCurrentClassLogger();
|
||||
private List<GameRoom> _rooms = new List<GameRoom>();
|
||||
private readonly List<GameRoom> _rooms = new List<GameRoom>();
|
||||
private readonly Dictionary<uint, GameRoom> _roomsBySocket;
|
||||
|
||||
public IReadOnlyDictionary<uint, GameRoom> RoomsBySocket => _roomsBySocket;
|
||||
public IReadOnlyList<GameRoom> Rooms => _rooms;
|
||||
|
||||
public RoomManager(PluginFactory factory, IGameThread gameThread)
|
||||
{
|
||||
_gameThread = gameThread;
|
||||
_factory = factory;
|
||||
}
|
||||
|
||||
_roomsBySocket = new Dictionary<uint, GameRoom>();
|
||||
}
|
||||
|
||||
public void Join(Player player, string roomId, byte[] payload)
|
||||
{
|
||||
if (_rooms.Count > 0)
|
||||
@@ -29,7 +33,7 @@ public class RoomManager
|
||||
if (existRoom.Id == roomId && existRoom.PlayersCount < existRoom.PlayersMax)
|
||||
{
|
||||
existRoom.Joined(player, payload);
|
||||
_gameThread.Attach(player.PeerId, existRoom);
|
||||
_roomsBySocket.Add(player.PeerId, existRoom);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -45,8 +49,7 @@ public class RoomManager
|
||||
if (existRoom.Map == map && existRoom.PlayersCount < existRoom.PlayersMax)
|
||||
{
|
||||
existRoom.Joined(player, payload);
|
||||
_gameThread.Attach(player.PeerId, existRoom);
|
||||
|
||||
_roomsBySocket.Add(player.PeerId, existRoom);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -56,17 +59,25 @@ public class RoomManager
|
||||
if (plugin == null)
|
||||
throw new NullReferenceException($"Plugin for map {map} is null");
|
||||
|
||||
var room = new GameRoom(_gameThread, plugin, map, min, max);
|
||||
var room = new GameRoom(_gameThread, plugin, map, min, max);
|
||||
room.Joined(player, payload);
|
||||
room.Start();
|
||||
|
||||
_gameThread.Attach(player.PeerId, room);
|
||||
_roomsBySocket.Add(player.PeerId, room);
|
||||
_rooms.Add(room);
|
||||
}
|
||||
|
||||
public void Left(Player player, byte[] payload)
|
||||
{
|
||||
|
||||
if (_roomsBySocket.Remove(player.PeerId, out var room))
|
||||
{
|
||||
room.Leave(player.PeerId);
|
||||
if (room.PlayersCount < room.PlayersMin)
|
||||
{
|
||||
room.Stop();
|
||||
_rooms.Remove(room);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Tick(float deltaTime)
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Threading;
|
||||
using DisruptorUnity3d;
|
||||
using ENet;
|
||||
using NLog;
|
||||
|
||||
@@ -33,14 +30,14 @@ namespace Ragon.Core
|
||||
_handler = handler;
|
||||
}
|
||||
|
||||
public void Start(ushort port)
|
||||
public void Start(ushort port, int connections)
|
||||
{
|
||||
_address = default;
|
||||
_address.Port = port;
|
||||
_peers = new Peer[2048];
|
||||
_peers = new Peer[connections];
|
||||
|
||||
_host = new Host();
|
||||
_host.Create(_address, 2048, 2, 0, 0, 1024 * 1024);
|
||||
_host.Create(_address, connections, 2, 0, 0, 1024 * 1024);
|
||||
|
||||
Status = Status.Listening;
|
||||
_logger.Info($"Network listening on {port}");
|
||||
@@ -87,27 +84,27 @@ namespace Ragon.Core
|
||||
|
||||
switch (_netEvent.Type)
|
||||
{
|
||||
case ENet.EventType.None:
|
||||
case EventType.None:
|
||||
Console.WriteLine("None event");
|
||||
break;
|
||||
|
||||
case ENet.EventType.Connect:
|
||||
case EventType.Connect:
|
||||
{
|
||||
_peers[_netEvent.Peer.ID] = _netEvent.Peer;
|
||||
_handler.OnEvent(_netEvent);
|
||||
break;
|
||||
}
|
||||
case ENet.EventType.Disconnect:
|
||||
case EventType.Disconnect:
|
||||
{
|
||||
_handler.OnEvent(_netEvent);
|
||||
break;
|
||||
}
|
||||
case ENet.EventType.Timeout:
|
||||
case EventType.Timeout:
|
||||
{
|
||||
_handler.OnEvent(_netEvent);
|
||||
break;
|
||||
}
|
||||
case ENet.EventType.Receive:
|
||||
case EventType.Receive:
|
||||
{
|
||||
_handler.OnEvent(_netEvent);
|
||||
_netEvent.Packet.Dispose();
|
||||
@@ -2,7 +2,7 @@ namespace Ragon.Core;
|
||||
|
||||
public interface ISocketServer
|
||||
{
|
||||
public void Start(ushort port);
|
||||
public void Start(ushort port, int connections);
|
||||
public void Process();
|
||||
public void Stop();
|
||||
public void Send(uint peerId, byte[] data, DeliveryType type);
|
||||
|
||||
@@ -3,19 +3,20 @@ using System.Collections.Generic;
|
||||
|
||||
namespace Ragon.Core;
|
||||
|
||||
public class Dispatcher: IDispatcher
|
||||
public class Dispatcher: IDispatcher, IDispatcherInternal
|
||||
{
|
||||
public Queue<DispatcherTask> _actions = new Queue<DispatcherTask>();
|
||||
public Queue<Action> _actions = new Queue<Action>();
|
||||
|
||||
public void Dispatch(Action action)
|
||||
{
|
||||
lock (_actions)
|
||||
_actions.Enqueue(new DispatcherTask() { Action = action });
|
||||
_actions.Enqueue(action);
|
||||
}
|
||||
|
||||
public void Process()
|
||||
{
|
||||
lock(_actions)
|
||||
while(_actions.TryDequeue(out var action))
|
||||
action.Execute();
|
||||
action?.Invoke();
|
||||
}
|
||||
}
|
||||
@@ -5,5 +5,4 @@ namespace Ragon.Core;
|
||||
public interface IDispatcher
|
||||
{
|
||||
public void Dispatch(Action action);
|
||||
public void Process();
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace Ragon.Core;
|
||||
|
||||
public interface IDispatcherInternal
|
||||
{
|
||||
public void Process();
|
||||
}
|
||||
Reference in New Issue
Block a user