Compare commits
7 Commits
v1.0.22-rc
...
v1.0.27-rc
| Author | SHA1 | Date | |
|---|---|---|---|
| 828112855f | |||
| 06ff76fe0b | |||
| c92b5a5bc4 | |||
| f83d3ea0c7 | |||
| 3564eb2adc | |||
| 3531432758 | |||
| 6bda468607 |
@@ -4,6 +4,7 @@ namespace Ragon.Common
|
|||||||
{
|
{
|
||||||
Owner,
|
Owner,
|
||||||
ExceptOwner,
|
ExceptOwner,
|
||||||
|
ExceptInvoker,
|
||||||
All,
|
All,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"key": "defaultkey",
|
"key": "defaultkey",
|
||||||
|
"socket": "udp",
|
||||||
"protocol": "1.0.0",
|
"protocol": "1.0.0",
|
||||||
"statisticsInterval": 5,
|
"statisticsInterval": 5,
|
||||||
"sendRate": 50,
|
"sendRate": 50,
|
||||||
|
|||||||
@@ -16,21 +16,33 @@ namespace Ragon.Core
|
|||||||
private readonly float _deltaTime = 0.0f;
|
private readonly float _deltaTime = 0.0f;
|
||||||
private readonly Configuration _configuration;
|
private readonly Configuration _configuration;
|
||||||
private readonly RagonSerializer _serializer;
|
private readonly RagonSerializer _serializer;
|
||||||
|
|
||||||
public ISocketServer SocketServer => _socketServer;
|
public ISocketServer SocketServer => _socketServer;
|
||||||
public Dispatcher Dispatcher => _dispatcher;
|
public Dispatcher Dispatcher => _dispatcher;
|
||||||
|
|
||||||
public Application(PluginFactory factory, Configuration configuration)
|
public Application(PluginFactory factory, Configuration configuration)
|
||||||
{
|
{
|
||||||
var authorizationProvider = factory.CreateAuthorizationProvider(configuration);
|
var authorizationProvider = factory.CreateAuthorizationProvider(configuration);
|
||||||
|
|
||||||
_configuration = configuration;
|
_configuration = configuration;
|
||||||
_serializer = new RagonSerializer();
|
_serializer = new RagonSerializer();
|
||||||
|
|
||||||
var dispatcher = new Dispatcher();
|
var dispatcher = new Dispatcher();
|
||||||
_dispatcher = dispatcher;
|
_dispatcher = dispatcher;
|
||||||
|
|
||||||
_socketServer = new ENetServer(this);
|
if (configuration.Socket == "udp")
|
||||||
|
{
|
||||||
|
_socketServer = new ENetServer(this);
|
||||||
|
}
|
||||||
|
else if (configuration.Socket == "websocket")
|
||||||
|
{
|
||||||
|
_socketServer = new WebSocketServer(this);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_logger.Error($"Unknown socket type {configuration.Socket}");
|
||||||
|
}
|
||||||
|
|
||||||
_deltaTime = 1000.0f / configuration.SendRate;
|
_deltaTime = 1000.0f / configuration.SendRate;
|
||||||
|
|
||||||
_roomManager = new RoomManager(factory, this);
|
_roomManager = new RoomManager(factory, this);
|
||||||
@@ -84,16 +96,16 @@ namespace Ragon.Core
|
|||||||
Thread.Sleep((int) _deltaTime);
|
Thread.Sleep((int) _deltaTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnConnected(ushort peerId)
|
public void OnConnected(ushort peerId)
|
||||||
{
|
{
|
||||||
_logger.Trace("Connected " + peerId);
|
// _logger.Trace("Connected " + peerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnDisconnected(ushort peerId)
|
public void OnDisconnected(ushort peerId)
|
||||||
{
|
{
|
||||||
_logger.Trace("Disconnected " + peerId);
|
// _logger.Trace("Disconnected " + peerId);
|
||||||
|
|
||||||
var player = _lobby.AuthorizationManager.GetPlayer(peerId);
|
var player = _lobby.AuthorizationManager.GetPlayer(peerId);
|
||||||
if (player != null)
|
if (player != null)
|
||||||
_roomManager.Left(player, Array.Empty<byte>());
|
_roomManager.Left(player, Array.Empty<byte>());
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ using Ragon.Common;
|
|||||||
|
|
||||||
namespace Ragon.Core;
|
namespace Ragon.Core;
|
||||||
|
|
||||||
public class AuthorizationManager
|
public class AuthorizationManager
|
||||||
{
|
{
|
||||||
private Logger _logger = LogManager.GetCurrentClassLogger();
|
private Logger _logger = LogManager.GetCurrentClassLogger();
|
||||||
private IApplicationHandler _provider;
|
private IApplicationHandler _provider;
|
||||||
@@ -29,12 +29,12 @@ public class AuthorizationManager
|
|||||||
{
|
{
|
||||||
if (_playersByPeers.ContainsKey(peerId))
|
if (_playersByPeers.ContainsKey(peerId))
|
||||||
{
|
{
|
||||||
_logger.Warn($"Connection already authorized {peerId}");
|
_logger.Warn($"Connection already authorized {peerId}");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var dispatcher = _gameThread.Dispatcher;
|
var dispatcher = _gameThread.Dispatcher;
|
||||||
|
|
||||||
_provider.OnAuthorizationRequest(key, name, additionalData.ToArray(),
|
_provider.OnAuthorizationRequest(key, name, additionalData.ToArray(),
|
||||||
(playerId, playerName) => { dispatcher.Dispatch(() => Accepted(peerId, playerId, playerName)); },
|
(playerId, playerName) => { dispatcher.Dispatch(() => Accepted(peerId, playerId, playerName)); },
|
||||||
(errorCode) => { dispatcher.Dispatch(() => Rejected(peerId, errorCode)); });
|
(errorCode) => { dispatcher.Dispatch(() => Rejected(peerId, errorCode)); });
|
||||||
@@ -42,6 +42,12 @@ public class AuthorizationManager
|
|||||||
|
|
||||||
public void Accepted(ushort peerId, string playerId, string playerName)
|
public void Accepted(ushort peerId, string playerId, string playerName)
|
||||||
{
|
{
|
||||||
|
if (_playersByPeers.ContainsKey(peerId))
|
||||||
|
{
|
||||||
|
_logger.Warn($"Connection already authorized {peerId}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
_serializer.Clear();
|
_serializer.Clear();
|
||||||
_serializer.WriteOperation(RagonOperation.AUTHORIZED_SUCCESS);
|
_serializer.WriteOperation(RagonOperation.AUTHORIZED_SUCCESS);
|
||||||
_serializer.WriteString(playerId);
|
_serializer.WriteString(playerId);
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ namespace Ragon.Core
|
|||||||
{
|
{
|
||||||
public string Key;
|
public string Key;
|
||||||
public string Protocol;
|
public string Protocol;
|
||||||
|
public string Socket;
|
||||||
public int StatisticsInterval;
|
public int StatisticsInterval;
|
||||||
public ushort SendRate;
|
public ushort SendRate;
|
||||||
public ushort Port;
|
public ushort Port;
|
||||||
@@ -18,9 +19,9 @@ namespace Ragon.Core
|
|||||||
public int MaxConnections;
|
public int MaxConnections;
|
||||||
public int MaxPlayersPerRoom;
|
public int MaxPlayersPerRoom;
|
||||||
public int MaxRooms;
|
public int MaxRooms;
|
||||||
|
|
||||||
private static readonly Logger _logger = LogManager.GetCurrentClassLogger();
|
private static readonly Logger _logger = LogManager.GetCurrentClassLogger();
|
||||||
private static readonly string _serverVersion = "1.0.22-rc";
|
private static readonly string _serverVersion = "1.0.27-rc";
|
||||||
|
|
||||||
private static void CopyrightInfo()
|
private static void CopyrightInfo()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ public class Entity
|
|||||||
serializer.WriteData(ref payload);
|
serializer.WriteData(ref payload);
|
||||||
|
|
||||||
var sendData = serializer.ToArray();
|
var sendData = serializer.ToArray();
|
||||||
Send(targetMode, sendData);
|
RouteEvent(peerId, targetMode, sendData);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ReadState(uint peerId, RagonSerializer serializer)
|
public void ReadState(uint peerId, RagonSerializer serializer)
|
||||||
@@ -197,6 +197,7 @@ public class Entity
|
|||||||
public void Destroy(ReadOnlySpan<byte> payload)
|
public void Destroy(ReadOnlySpan<byte> payload)
|
||||||
{
|
{
|
||||||
var serializer = _room.GetSharedSerializer();
|
var serializer = _room.GetSharedSerializer();
|
||||||
|
|
||||||
serializer.Clear();
|
serializer.Clear();
|
||||||
serializer.WriteOperation(RagonOperation.DESTROY_ENTITY);
|
serializer.WriteOperation(RagonOperation.DESTROY_ENTITY);
|
||||||
serializer.WriteInt(EntityId);
|
serializer.WriteInt(EntityId);
|
||||||
@@ -207,7 +208,7 @@ public class Entity
|
|||||||
_room.BroadcastToReady(sendData, DeliveryType.Reliable);
|
_room.BroadcastToReady(sendData, DeliveryType.Reliable);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Send(RagonTarget targetMode, byte[] sendData)
|
void RouteEvent(ushort peerId, RagonTarget targetMode, byte[] sendData)
|
||||||
{
|
{
|
||||||
switch (targetMode)
|
switch (targetMode)
|
||||||
{
|
{
|
||||||
@@ -221,6 +222,11 @@ public class Entity
|
|||||||
_room.BroadcastToReady(sendData, new [] { OwnerId }, DeliveryType.Reliable);
|
_room.BroadcastToReady(sendData, new [] { OwnerId }, DeliveryType.Reliable);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case RagonTarget.ExceptInvoker:
|
||||||
|
{
|
||||||
|
_room.BroadcastToReady(sendData, new[] {peerId}, DeliveryType.Reliable);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case RagonTarget.All:
|
case RagonTarget.All:
|
||||||
{
|
{
|
||||||
_room.BroadcastToReady(sendData, DeliveryType.Reliable);
|
_room.BroadcastToReady(sendData, DeliveryType.Reliable);
|
||||||
@@ -236,7 +242,7 @@ public class Entity
|
|||||||
var targetMode = (RagonTarget) reader.ReadByte();
|
var targetMode = (RagonTarget) reader.ReadByte();
|
||||||
var payloadData = reader.ReadData(reader.Size);
|
var payloadData = reader.ReadData(reader.Size);
|
||||||
|
|
||||||
Span<byte> payloadRaw = stackalloc byte[reader.Size];
|
Span<byte> payloadRaw = stackalloc byte[payloadData.Length];
|
||||||
ReadOnlySpan<byte> payload = payloadRaw;
|
ReadOnlySpan<byte> payload = payloadRaw;
|
||||||
payloadData.CopyTo(payloadRaw);
|
payloadData.CopyTo(payloadRaw);
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NLog;
|
using NLog;
|
||||||
using Ragon.Common;
|
using Ragon.Common;
|
||||||
@@ -129,7 +128,6 @@ namespace Ragon.Core
|
|||||||
var propertySize = reader.ReadUShort();
|
var propertySize = reader.ReadUShort();
|
||||||
entity.AddProperty(new EntityProperty(propertySize, propertyType));
|
entity.AddProperty(new EntityProperty(propertySize, propertyType));
|
||||||
}
|
}
|
||||||
|
|
||||||
player.AttachEntity(entity);
|
player.AttachEntity(entity);
|
||||||
AttachEntity(player, entity);
|
AttachEntity(player, entity);
|
||||||
}
|
}
|
||||||
@@ -218,9 +216,7 @@ namespace Ragon.Core
|
|||||||
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}");
|
|
||||||
|
|
||||||
var player = _players[peerId];
|
var player = _players[peerId];
|
||||||
var entity = new Entity(this, player.PeerId, entityType, 0, eventAuthority);
|
var entity = new Entity(this, player.PeerId, entityType, 0, eventAuthority);
|
||||||
for (var i = 0; i < propertiesCount; i++)
|
for (var i = 0; i < propertiesCount; i++)
|
||||||
@@ -246,7 +242,7 @@ namespace Ragon.Core
|
|||||||
{
|
{
|
||||||
var entityId = reader.ReadInt();
|
var entityId = reader.ReadInt();
|
||||||
if (_entities.TryGetValue(entityId, out var entity))
|
if (_entities.TryGetValue(entityId, out var entity))
|
||||||
{
|
{
|
||||||
var player = _players[peerId];
|
var player = _players[peerId];
|
||||||
var payload = reader.ReadData(reader.Size);
|
var payload = reader.ReadData(reader.Size);
|
||||||
DetachEntity(player, entity, payload);
|
DetachEntity(player, entity, payload);
|
||||||
@@ -306,12 +302,17 @@ namespace Ragon.Core
|
|||||||
_writer.WriteOperation(RagonOperation.OWNERSHIP_CHANGED);
|
_writer.WriteOperation(RagonOperation.OWNERSHIP_CHANGED);
|
||||||
_writer.WriteString(next.Id);
|
_writer.WriteString(next.Id);
|
||||||
_writer.WriteUShort((ushort) entitiesToUpdate.Length);
|
_writer.WriteUShort((ushort) entitiesToUpdate.Length);
|
||||||
|
|
||||||
foreach (var entity in entitiesToUpdate)
|
foreach (var entity in entitiesToUpdate)
|
||||||
{
|
{
|
||||||
_writer.WriteUShort(entity.EntityId);
|
_writer.WriteUShort(entity.EntityId);
|
||||||
entity.SetOwner((ushort) next.PeerId);
|
entity.SetOwner(next.PeerId);
|
||||||
|
|
||||||
|
next.Entities.Add(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
next.EntitiesIds = next.Entities.Select(e => e.EntityId).ToList();
|
||||||
|
|
||||||
BroadcastToReady(_writer, DeliveryType.Reliable);
|
BroadcastToReady(_writer, DeliveryType.Reliable);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -345,6 +346,7 @@ namespace Ragon.Core
|
|||||||
|
|
||||||
void BroadcastSnapshot(ushort[] peersIds)
|
void BroadcastSnapshot(ushort[] peersIds)
|
||||||
{
|
{
|
||||||
|
_logger.Trace("Snapshot");
|
||||||
_writer.Clear();
|
_writer.Clear();
|
||||||
_writer.WriteOperation(RagonOperation.SNAPSHOT);
|
_writer.WriteOperation(RagonOperation.SNAPSHOT);
|
||||||
_writer.WriteUShort((ushort) _readyPlayers.Length);
|
_writer.WriteUShort((ushort) _readyPlayers.Length);
|
||||||
@@ -367,7 +369,7 @@ namespace Ragon.Core
|
|||||||
_writer.WriteUShort(entity.OwnerId);
|
_writer.WriteUShort(entity.OwnerId);
|
||||||
_writer.WriteUShort((ushort) payload.Length);
|
_writer.WriteUShort((ushort) payload.Length);
|
||||||
_writer.WriteData(ref payload);
|
_writer.WriteData(ref payload);
|
||||||
|
|
||||||
entity.WriteSnapshot(_writer);
|
entity.WriteSnapshot(_writer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -384,7 +386,7 @@ namespace Ragon.Core
|
|||||||
_writer.WriteUShort(entity.OwnerId);
|
_writer.WriteUShort(entity.OwnerId);
|
||||||
_writer.WriteUShort((ushort) payload.Length);
|
_writer.WriteUShort((ushort) payload.Length);
|
||||||
_writer.WriteData(ref payload);
|
_writer.WriteData(ref payload);
|
||||||
|
|
||||||
entity.WriteSnapshot(_writer);
|
entity.WriteSnapshot(_writer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ public class RoomManager
|
|||||||
{
|
{
|
||||||
if (existRoom.Map == map && existRoom.PlayersCount < existRoom.PlayersMax)
|
if (existRoom.Map == map && existRoom.PlayersCount < existRoom.PlayersMax)
|
||||||
{
|
{
|
||||||
_logger.Trace($"Player ({player.PlayerName}|{player.Id}) joined to room with Id {roomId}");
|
_logger.Trace($"Player ({player.PlayerName}|{player.Id}) joined to room with Id {existRoom.Id}");
|
||||||
|
|
||||||
existRoom.AddPlayer(player, payload);
|
existRoom.AddPlayer(player, payload);
|
||||||
_roomsBySocket.Add(player.PeerId, existRoom);
|
_roomsBySocket.Add(player.PeerId, existRoom);
|
||||||
|
|||||||
@@ -75,7 +75,14 @@ public class WebSocketServer : ISocketServer
|
|||||||
{
|
{
|
||||||
if (_webSockets.TryGetValue(evnt.PeerId, out var ws) && ws.State == WebSocketState.Open)
|
if (_webSockets.TryGetValue(evnt.PeerId, out var ws) && ws.State == WebSocketState.Open)
|
||||||
{
|
{
|
||||||
await ws.SendAsync(evnt.Data, WebSocketMessageType.Binary, WebSocketMessageFlags.EndOfMessage, CancellationToken.None);
|
try
|
||||||
|
{
|
||||||
|
await ws.SendAsync(evnt.Data, WebSocketMessageType.Binary, WebSocketMessageFlags.EndOfMessage, CancellationToken.None);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.Error(ex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,8 +16,8 @@ Ragon is fully free, small and high perfomance room based game server with plugi
|
|||||||
- Simple matchmaking
|
- Simple matchmaking
|
||||||
- Room based architecture
|
- Room based architecture
|
||||||
- Сustomizable authorization
|
- Сustomizable authorization
|
||||||
- Сustomizable server-side logic via plugins with flexible API
|
- Сustomizable server-side logic via plugins with flexible API*(2)
|
||||||
- No CCU limitations*
|
- No CCU limitations*(1)
|
||||||
- No Room count limitations
|
- No Room count limitations
|
||||||
- Reliable UDP
|
- Reliable UDP
|
||||||
|
|
||||||
@@ -27,10 +27,11 @@ Ragon is fully free, small and high perfomance room based game server with plugi
|
|||||||
|
|
||||||
### Dependencies
|
### Dependencies
|
||||||
* ENet-Sharp [v2.4.8]
|
* ENet-Sharp [v2.4.8]
|
||||||
* NetStack [latest]
|
|
||||||
|
|
||||||
### License
|
### License
|
||||||
MIT
|
MIT
|
||||||
|
|
||||||
### Tips
|
### Tips
|
||||||
\* Limited to 4095 CCU by library ENet-Sharp
|
\* Limited to 4095 CCU by library ENet-Sharp (1)
|
||||||
|
|
||||||
|
\* Non finally (2)
|
||||||
|
|||||||
Reference in New Issue
Block a user