✨ http-commands
This commit is contained in:
@@ -0,0 +1,6 @@
|
|||||||
|
namespace Ragon.Relay;
|
||||||
|
|
||||||
|
public class KickPlayerCommand
|
||||||
|
{
|
||||||
|
public string Id;
|
||||||
|
}
|
||||||
@@ -6,7 +6,7 @@ using Ragon.Server.Room;
|
|||||||
|
|
||||||
namespace Ragon.Relay;
|
namespace Ragon.Relay;
|
||||||
|
|
||||||
public class RelayRoomPlugin: IRoomPlugin
|
public class RelayRoomPlugin: BaseRoomPlugin
|
||||||
{
|
{
|
||||||
public void Tick(float dt)
|
public void Tick(float dt)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,41 +1,24 @@
|
|||||||
using System.Net.Http;
|
using System;
|
||||||
using Ragon.Server;
|
using Newtonsoft.Json;
|
||||||
using Ragon.Server.Lobby;
|
|
||||||
using Ragon.Server.Plugin;
|
using Ragon.Server.Plugin;
|
||||||
using Ragon.Server.Room;
|
|
||||||
|
|
||||||
namespace Ragon.Relay;
|
namespace Ragon.Relay;
|
||||||
|
|
||||||
public class RelayServerPlugin: IServerPlugin
|
public class RelayServerPlugin: BaseServerPlugin
|
||||||
{
|
{
|
||||||
private HttpClient httpClient;
|
public override bool OnCommand(string command, string payload)
|
||||||
public IRoomPlugin CreateRoomPlugin(RoomInformation information)
|
|
||||||
{
|
{
|
||||||
return new RelayRoomPlugin();
|
Console.WriteLine(command);
|
||||||
|
if (command == "kick-player")
|
||||||
|
{
|
||||||
|
var commandPayload = JsonConvert.DeserializeObject<KickPlayerCommand>(payload);
|
||||||
|
var player = GetPlayerById(commandPayload.Id);
|
||||||
|
if (player != null)
|
||||||
|
player.Connection.Close();
|
||||||
|
else
|
||||||
|
Console.WriteLine($"Player not found with Id {commandPayload.Id}");
|
||||||
}
|
}
|
||||||
|
|
||||||
public RelayServerPlugin()
|
|
||||||
{
|
|
||||||
httpClient = new HttpClient();
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool OnRoomCreate(RagonLobbyPlayer player, RagonRoom room)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool OnRoomRemove(RagonLobbyPlayer player, RagonRoom room)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool OnRoomLeave(RagonRoomPlayer player, RagonRoom room)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool OnRoomJoin(RagonRoomPlayer player, RagonRoom room)
|
|
||||||
{
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4,6 +4,8 @@
|
|||||||
"serverTickRate": 30,
|
"serverTickRate": 30,
|
||||||
"gameProtocol": "1.0.0",
|
"gameProtocol": "1.0.0",
|
||||||
"port": 5000,
|
"port": 5000,
|
||||||
|
"httpPort": 5001,
|
||||||
|
"httpKey": "defaultkey",
|
||||||
"limitConnections": 4095,
|
"limitConnections": 4095,
|
||||||
"limitPlayersPerRoom": 20,
|
"limitPlayersPerRoom": 20,
|
||||||
"limitRooms": 200,
|
"limitRooms": 200,
|
||||||
|
|||||||
@@ -26,17 +26,19 @@ namespace Ragon.Server.Handler;
|
|||||||
public sealed class AuthorizationOperation: IRagonOperation
|
public sealed class AuthorizationOperation: IRagonOperation
|
||||||
{
|
{
|
||||||
private Logger _logger = LogManager.GetCurrentClassLogger();
|
private Logger _logger = LogManager.GetCurrentClassLogger();
|
||||||
private readonly WebHookPlugin _webHook;
|
private readonly RagonWebHookPlugin _ragonWebHook;
|
||||||
|
private readonly RagonContextObserver _contextObserver;
|
||||||
private readonly Configuration _configuration;
|
private readonly Configuration _configuration;
|
||||||
private readonly RagonBuffer _writer;
|
private readonly RagonBuffer _writer;
|
||||||
|
|
||||||
public AuthorizationOperation(
|
public AuthorizationOperation(RagonWebHookPlugin ragonWebHook,
|
||||||
WebHookPlugin webHook,
|
RagonContextObserver contextObserver,
|
||||||
RagonBuffer writer,
|
RagonBuffer writer,
|
||||||
Configuration configuration)
|
Configuration configuration)
|
||||||
{
|
{
|
||||||
_webHook = webHook;
|
_ragonWebHook = ragonWebHook;
|
||||||
_configuration = configuration;
|
_configuration = configuration;
|
||||||
|
_contextObserver = contextObserver;
|
||||||
_writer = writer;
|
_writer = writer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,10 +62,10 @@ public sealed class AuthorizationOperation: IRagonOperation
|
|||||||
|
|
||||||
if (key == _configuration.ServerKey)
|
if (key == _configuration.ServerKey)
|
||||||
{
|
{
|
||||||
if (_webHook.RequestAuthorization(context, name, payload))
|
if (_ragonWebHook.RequestAuthorization(context, name, payload))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var lobbyPlayer = new RagonLobbyPlayer(Guid.NewGuid().ToString(), name, payload);
|
var lobbyPlayer = new RagonLobbyPlayer(context.Connection, Guid.NewGuid().ToString(), name, payload);
|
||||||
context.SetPlayer(lobbyPlayer);
|
context.SetPlayer(lobbyPlayer);
|
||||||
|
|
||||||
Approve(context);
|
Approve(context);
|
||||||
@@ -78,6 +80,8 @@ public sealed class AuthorizationOperation: IRagonOperation
|
|||||||
{
|
{
|
||||||
context.ConnectionStatus = ConnectionStatus.Authorized;
|
context.ConnectionStatus = ConnectionStatus.Authorized;
|
||||||
|
|
||||||
|
_contextObserver.OnAuthorized(context);
|
||||||
|
|
||||||
var playerId = context.LobbyPlayer.Id;
|
var playerId = context.LobbyPlayer.Id;
|
||||||
var playerName = context.LobbyPlayer.Name;
|
var playerName = context.LobbyPlayer.Name;
|
||||||
var playerPayload = context.LobbyPlayer.Payload;
|
var playerPayload = context.LobbyPlayer.Payload;
|
||||||
|
|||||||
@@ -28,12 +28,12 @@ public sealed class RoomCreateOperation: IRagonOperation
|
|||||||
private readonly RagonRoomParameters _roomParameters = new();
|
private readonly RagonRoomParameters _roomParameters = new();
|
||||||
private readonly Logger _logger = LogManager.GetCurrentClassLogger();
|
private readonly Logger _logger = LogManager.GetCurrentClassLogger();
|
||||||
private readonly IServerPlugin _serverPlugin;
|
private readonly IServerPlugin _serverPlugin;
|
||||||
private readonly WebHookPlugin _webHookPlugin;
|
private readonly RagonWebHookPlugin _ragonWebHookPlugin;
|
||||||
|
|
||||||
public RoomCreateOperation(IServerPlugin serverPlugin, WebHookPlugin webHook)
|
public RoomCreateOperation(IServerPlugin serverPlugin, RagonWebHookPlugin ragonWebHook)
|
||||||
{
|
{
|
||||||
_serverPlugin = serverPlugin;
|
_serverPlugin = serverPlugin;
|
||||||
_webHookPlugin = webHook;
|
_ragonWebHookPlugin = ragonWebHook;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Handle(RagonContext context, RagonBuffer reader, RagonBuffer writer)
|
public void Handle(RagonContext context, RagonBuffer reader, RagonBuffer writer)
|
||||||
@@ -79,11 +79,13 @@ public sealed class RoomCreateOperation: IRagonOperation
|
|||||||
var roomPlugin = _serverPlugin.CreateRoomPlugin(information);
|
var roomPlugin = _serverPlugin.CreateRoomPlugin(information);
|
||||||
var room = new RagonRoom(roomId, information, roomPlugin);
|
var room = new RagonRoom(roomId, information, roomPlugin);
|
||||||
|
|
||||||
|
roomPlayer.OnAttached(room);
|
||||||
|
|
||||||
context.Scheduler.Run(room);
|
context.Scheduler.Run(room);
|
||||||
context.Lobby.Persist(room);
|
context.Lobby.Persist(room);
|
||||||
context.SetRoom(room, roomPlayer);
|
context.SetRoom(room, roomPlayer);
|
||||||
|
|
||||||
_webHookPlugin.RoomCreated(context, room);
|
_ragonWebHookPlugin.RoomCreated(context, room, roomPlayer);
|
||||||
|
|
||||||
_logger.Trace($"Player {context.Connection.Id}|{context.LobbyPlayer.Name} create room {room.Id} with map {information.Map}");
|
_logger.Trace($"Player {context.Connection.Id}|{context.LobbyPlayer.Name} create room {room.Id} with map {information.Map}");
|
||||||
|
|
||||||
|
|||||||
@@ -26,12 +26,12 @@ public sealed class RoomJoinOperation : IRagonOperation
|
|||||||
{
|
{
|
||||||
private readonly Logger _logger = LogManager.GetCurrentClassLogger();
|
private readonly Logger _logger = LogManager.GetCurrentClassLogger();
|
||||||
private readonly IServerPlugin _serverPlugin;
|
private readonly IServerPlugin _serverPlugin;
|
||||||
private readonly WebHookPlugin _webHookPlugin;
|
private readonly RagonWebHookPlugin _ragonWebHookPlugin;
|
||||||
|
|
||||||
public RoomJoinOperation(IServerPlugin serverPlugin, WebHookPlugin plugin)
|
public RoomJoinOperation(IServerPlugin serverPlugin, RagonWebHookPlugin plugin)
|
||||||
{
|
{
|
||||||
_serverPlugin = serverPlugin;
|
_serverPlugin = serverPlugin;
|
||||||
_webHookPlugin = plugin;
|
_ragonWebHookPlugin = plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Handle(RagonContext context, RagonBuffer reader, RagonBuffer writer)
|
public void Handle(RagonContext context, RagonBuffer reader, RagonBuffer writer)
|
||||||
@@ -53,7 +53,7 @@ public sealed class RoomJoinOperation : IRagonOperation
|
|||||||
if (!_serverPlugin.OnRoomJoin(player, existsRoom))
|
if (!_serverPlugin.OnRoomJoin(player, existsRoom))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_webHookPlugin.RoomJoined(context, existsRoom, player);
|
_ragonWebHookPlugin.RoomJoined(context, existsRoom, player);
|
||||||
|
|
||||||
JoinSuccess(context, existsRoom, writer);
|
JoinSuccess(context, existsRoom, writer);
|
||||||
|
|
||||||
|
|||||||
@@ -28,12 +28,12 @@ public sealed class RoomJoinOrCreateOperation : IRagonOperation
|
|||||||
private readonly RagonRoomParameters _roomParameters = new();
|
private readonly RagonRoomParameters _roomParameters = new();
|
||||||
private readonly Logger _logger = LogManager.GetCurrentClassLogger();
|
private readonly Logger _logger = LogManager.GetCurrentClassLogger();
|
||||||
private readonly IServerPlugin _serverPlugin;
|
private readonly IServerPlugin _serverPlugin;
|
||||||
private readonly WebHookPlugin _webHookPlugin;
|
private readonly RagonWebHookPlugin _ragonWebHookPlugin;
|
||||||
|
|
||||||
public RoomJoinOrCreateOperation(IServerPlugin serverPlugin, WebHookPlugin plugin)
|
public RoomJoinOrCreateOperation(IServerPlugin serverPlugin, RagonWebHookPlugin plugin)
|
||||||
{
|
{
|
||||||
_serverPlugin = serverPlugin;
|
_serverPlugin = serverPlugin;
|
||||||
_webHookPlugin = plugin;
|
_ragonWebHookPlugin = plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Handle(RagonContext context, RagonBuffer reader, RagonBuffer writer)
|
public void Handle(RagonContext context, RagonBuffer reader, RagonBuffer writer)
|
||||||
@@ -54,7 +54,7 @@ public sealed class RoomJoinOrCreateOperation : IRagonOperation
|
|||||||
var player = new RagonRoomPlayer(context.Connection, lobbyPlayer.Id, lobbyPlayer.Name);
|
var player = new RagonRoomPlayer(context.Connection, lobbyPlayer.Id, lobbyPlayer.Name);
|
||||||
context.SetRoom(existsRoom, player);
|
context.SetRoom(existsRoom, player);
|
||||||
|
|
||||||
_webHookPlugin.RoomJoined(context, existsRoom, player);
|
_ragonWebHookPlugin.RoomJoined(context, existsRoom, player);
|
||||||
|
|
||||||
JoinSuccess(player, existsRoom, writer);
|
JoinSuccess(player, existsRoom, writer);
|
||||||
}
|
}
|
||||||
@@ -71,7 +71,7 @@ public sealed class RoomJoinOrCreateOperation : IRagonOperation
|
|||||||
var roomPlugin = _serverPlugin.CreateRoomPlugin(information);
|
var roomPlugin = _serverPlugin.CreateRoomPlugin(information);
|
||||||
var room = new RagonRoom(roomId, information, roomPlugin);
|
var room = new RagonRoom(roomId, information, roomPlugin);
|
||||||
|
|
||||||
_webHookPlugin.RoomCreated(context, room);
|
_ragonWebHookPlugin.RoomCreated(context, room, roomPlayer);
|
||||||
|
|
||||||
context.Lobby.Persist(room);
|
context.Lobby.Persist(room);
|
||||||
context.Scheduler.Run(room);
|
context.Scheduler.Run(room);
|
||||||
|
|||||||
@@ -25,11 +25,11 @@ public sealed class RoomLeaveOperation: IRagonOperation
|
|||||||
{
|
{
|
||||||
private readonly Logger _logger = LogManager.GetCurrentClassLogger();
|
private readonly Logger _logger = LogManager.GetCurrentClassLogger();
|
||||||
private readonly IServerPlugin _serverPlugin;
|
private readonly IServerPlugin _serverPlugin;
|
||||||
private readonly WebHookPlugin _webHookPlugin;
|
private readonly RagonWebHookPlugin _ragonWebHookPlugin;
|
||||||
public RoomLeaveOperation(IServerPlugin serverPlugin, WebHookPlugin plugin)
|
public RoomLeaveOperation(IServerPlugin serverPlugin, RagonWebHookPlugin plugin)
|
||||||
{
|
{
|
||||||
_serverPlugin = serverPlugin;
|
_serverPlugin = serverPlugin;
|
||||||
_webHookPlugin = plugin;
|
_ragonWebHookPlugin = plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Handle(RagonContext context, RagonBuffer reader, RagonBuffer writer)
|
public void Handle(RagonContext context, RagonBuffer reader, RagonBuffer writer)
|
||||||
@@ -40,7 +40,7 @@ public sealed class RoomLeaveOperation: IRagonOperation
|
|||||||
if (room != null)
|
if (room != null)
|
||||||
{
|
{
|
||||||
_serverPlugin.OnRoomLeave(roomPlayer, room);
|
_serverPlugin.OnRoomLeave(roomPlayer, room);
|
||||||
_webHookPlugin.RoomLeaved(context, room, roomPlayer);
|
_ragonWebHookPlugin.RoomLeaved(context, room, roomPlayer);
|
||||||
context.Room?.DetachPlayer(roomPlayer);
|
context.Room?.DetachPlayer(roomPlayer);
|
||||||
_logger.Trace($"Player {context.Connection.Id}|{context.LobbyPlayer.Name} leaved from {room.Id}");
|
_logger.Trace($"Player {context.Connection.Id}|{context.LobbyPlayer.Name} leaved from {room.Id}");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,97 @@
|
|||||||
|
using NLog;
|
||||||
|
using System.Net;
|
||||||
|
using System.Text.Json;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using Ragon.Server.IO;
|
||||||
|
using Ragon.Server.Plugin;
|
||||||
|
|
||||||
|
namespace Ragon.Server.Http;
|
||||||
|
|
||||||
|
public class RagonHttpServer
|
||||||
|
{
|
||||||
|
private readonly ILogger _logger = LogManager.GetCurrentClassLogger();
|
||||||
|
private readonly IExecutor _executor;
|
||||||
|
private readonly IServerPlugin _serverPlugin;
|
||||||
|
private HttpListener _httpListener;
|
||||||
|
private CancellationTokenSource _cancellationTokenSource;
|
||||||
|
|
||||||
|
public RagonHttpServer(IExecutor executor, IServerPlugin serverPlugin)
|
||||||
|
{
|
||||||
|
_serverPlugin = serverPlugin;
|
||||||
|
_executor = executor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async void StartAccept(CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
while (!cancellationToken.IsCancellationRequested)
|
||||||
|
{
|
||||||
|
var context = await _httpListener.GetContextAsync();
|
||||||
|
|
||||||
|
if (context.Request.HttpMethod != "POST")
|
||||||
|
{
|
||||||
|
context.Response.StatusCode = 404;
|
||||||
|
context.Response.ContentLength64 = 0;
|
||||||
|
context.Response.Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
var request = context.Request;
|
||||||
|
var reader = new StreamReader(request.InputStream, request.ContentEncoding);
|
||||||
|
var rawJson = await reader.ReadToEndAsync();
|
||||||
|
var httpCommand = JsonDocument.Parse(rawJson);
|
||||||
|
if (httpCommand != null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var command = httpCommand.RootElement.GetProperty("command");
|
||||||
|
var payload = httpCommand.RootElement.GetProperty("payload");
|
||||||
|
|
||||||
|
if (_serverPlugin.OnCommand(command.GetString() ?? "none", payload.GetRawText()))
|
||||||
|
{
|
||||||
|
context.Response.StatusCode = 200;
|
||||||
|
context.Response.ContentLength64 = 0;
|
||||||
|
context.Response.Close();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
context.Response.StatusCode = 403;
|
||||||
|
context.Response.ContentLength64 = 0;
|
||||||
|
context.Response.Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.Error(ex);
|
||||||
|
|
||||||
|
context.Response.StatusCode = 505;
|
||||||
|
context.Response.ContentLength64 = 0;
|
||||||
|
context.Response.Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
context.Response.StatusCode = 403;
|
||||||
|
context.Response.ContentLength64 = 0;
|
||||||
|
context.Response.Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Start(Configuration configuration)
|
||||||
|
{
|
||||||
|
_cancellationTokenSource = new CancellationTokenSource();
|
||||||
|
_logger.Info($"Listen at http://0.0.0.0:{configuration.HttpPort}/");
|
||||||
|
|
||||||
|
_httpListener = new HttpListener();
|
||||||
|
_httpListener.Prefixes.Add($"http://127.0.0.1:{configuration.HttpPort}/");
|
||||||
|
_httpListener.Start();
|
||||||
|
|
||||||
|
_executor.Run(() => StartAccept(_cancellationTokenSource.Token), TaskCreationOptions.LongRunning);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Stop()
|
||||||
|
{
|
||||||
|
_cancellationTokenSource.Cancel();
|
||||||
|
_httpListener.Stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -18,21 +18,26 @@ using System.Threading.Channels;
|
|||||||
|
|
||||||
namespace Ragon.Server.IO;
|
namespace Ragon.Server.IO;
|
||||||
|
|
||||||
public class Executor: TaskScheduler, IExecutor
|
public class Executor : TaskScheduler, IExecutor
|
||||||
{
|
{
|
||||||
private ChannelReader<Task> _reader;
|
private readonly ChannelReader<Task> _reader;
|
||||||
private ChannelWriter<Task> _writer;
|
private readonly ChannelWriter<Task> _writer;
|
||||||
private Queue<Task> _pendingTasks;
|
private readonly Queue<Task> _pendingTasks;
|
||||||
private TaskFactory _taskFactory;
|
private readonly TaskFactory _taskFactory;
|
||||||
|
|
||||||
public Task Run(Action action)
|
public Task Run(Action action, TaskCreationOptions task = TaskCreationOptions.None)
|
||||||
{
|
{
|
||||||
return _taskFactory.StartNew(action);
|
return _taskFactory.StartNew(action, task);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Executor()
|
public Executor()
|
||||||
{
|
{
|
||||||
var channel = Channel.CreateUnbounded<Task>();
|
var channel = Channel.CreateUnbounded<Task>(new UnboundedChannelOptions()
|
||||||
|
{
|
||||||
|
SingleReader = true,
|
||||||
|
SingleWriter = true,
|
||||||
|
});
|
||||||
|
|
||||||
_reader = channel.Reader;
|
_reader = channel.Reader;
|
||||||
_writer = channel.Writer;
|
_writer = channel.Writer;
|
||||||
|
|
||||||
|
|||||||
@@ -18,5 +18,5 @@ namespace Ragon.Server.IO;
|
|||||||
|
|
||||||
public interface IExecutor
|
public interface IExecutor
|
||||||
{
|
{
|
||||||
public Task Run(Action action);
|
public Task Run(Action action, TaskCreationOptions task = TaskCreationOptions.None);
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
namespace Ragon.Server;
|
||||||
|
|
||||||
|
public class RagonContextObserver
|
||||||
|
{
|
||||||
|
private Dictionary<string, RagonContext> _contexts;
|
||||||
|
public RagonContextObserver(Dictionary<string, RagonContext> contexts)
|
||||||
|
{
|
||||||
|
_contexts = contexts;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnAuthorized(RagonContext context)
|
||||||
|
{
|
||||||
|
_contexts.Add(context.LobbyPlayer.Id, context);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
using Ragon.Server.IO;
|
||||||
|
|
||||||
|
namespace Ragon.Server;
|
||||||
|
|
||||||
|
public interface IRagonServer
|
||||||
|
{
|
||||||
|
RagonContext? ResolveContext(INetworkConnection connection);
|
||||||
|
RagonContext? ResolveContext(string id);
|
||||||
|
}
|
||||||
@@ -14,6 +14,8 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
using Ragon.Server.IO;
|
||||||
|
|
||||||
namespace Ragon.Server.Lobby;
|
namespace Ragon.Server.Lobby;
|
||||||
|
|
||||||
public enum ConnectionStatus
|
public enum ConnectionStatus
|
||||||
@@ -25,14 +27,16 @@ public enum ConnectionStatus
|
|||||||
|
|
||||||
public class RagonLobbyPlayer
|
public class RagonLobbyPlayer
|
||||||
{
|
{
|
||||||
|
public INetworkConnection Connection { get; }
|
||||||
public string Id { get; private set; }
|
public string Id { get; private set; }
|
||||||
public string Name { get; private set; }
|
public string Name { get; private set; }
|
||||||
public string Payload { get; private set; }
|
public string Payload { get; private set; }
|
||||||
|
|
||||||
public RagonLobbyPlayer(string id, string name, string payload)
|
public RagonLobbyPlayer(INetworkConnection connection, string id, string name, string payload)
|
||||||
{
|
{
|
||||||
Id = id;
|
Id = id;
|
||||||
Name = name;
|
Name = name;
|
||||||
Payload = payload;
|
Payload = payload;
|
||||||
|
Connection = connection;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
using Ragon.Server.Entity;
|
||||||
|
using Ragon.Server.IO;
|
||||||
|
using Ragon.Server.Lobby;
|
||||||
|
using Ragon.Server.Room;
|
||||||
|
using Ragon.Server.Time;
|
||||||
|
|
||||||
|
namespace Ragon.Server.Plugin;
|
||||||
|
|
||||||
|
public class BaseRoomPlugin: IRoomPlugin
|
||||||
|
{
|
||||||
|
private IRagonRoom _ragonRoom;
|
||||||
|
|
||||||
|
public RagonRoomPlayer GetPlayerById(string id)
|
||||||
|
{
|
||||||
|
var player = _ragonRoom.GetPlayerById(id);
|
||||||
|
return player;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RagonRoomPlayer GetPlayerByConnection(INetworkConnection connection)
|
||||||
|
{
|
||||||
|
var player = _ragonRoom.GetPlayerByConnection(connection);
|
||||||
|
return player;
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void OnAttached(IRagonRoom room)
|
||||||
|
{
|
||||||
|
_ragonRoom = room;
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void OnDetached()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#region VIRTUAL
|
||||||
|
|
||||||
|
public virtual void Tick(float dt)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual bool OnEntityCreate(RagonRoomPlayer creator, RagonEntity entity)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual bool OnEntityRemove(RagonRoomPlayer remover, RagonEntity entity)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
using Ragon.Server.IO;
|
||||||
|
using Ragon.Server.Lobby;
|
||||||
|
using Ragon.Server.Room;
|
||||||
|
|
||||||
|
namespace Ragon.Server.Plugin;
|
||||||
|
|
||||||
|
public class BaseServerPlugin: IServerPlugin
|
||||||
|
{
|
||||||
|
private IRagonServer _ragonServer;
|
||||||
|
|
||||||
|
public RagonLobbyPlayer? GetPlayerById(string id)
|
||||||
|
{
|
||||||
|
var context = _ragonServer.ResolveContext(id);
|
||||||
|
return context?.LobbyPlayer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RagonLobbyPlayer? GetPlayerByConnection(INetworkConnection connection)
|
||||||
|
{
|
||||||
|
var context = _ragonServer.ResolveContext(connection);
|
||||||
|
return context?.LobbyPlayer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnAttached(IRagonServer server)
|
||||||
|
{
|
||||||
|
_ragonServer = server;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnDetached()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual bool OnRoomCreate(RagonLobbyPlayer player, RagonRoom room)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual bool OnRoomRemove(RagonLobbyPlayer player, RagonRoom room)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual bool OnRoomLeave(RagonRoomPlayer player, RagonRoom room)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual bool OnRoomJoin(RagonRoomPlayer player, RagonRoom room)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual bool OnCommand(string command, string payload)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IRoomPlugin CreateRoomPlugin(RoomInformation information)
|
||||||
|
{
|
||||||
|
return new BaseRoomPlugin();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -22,7 +22,7 @@ namespace Ragon.Server.Plugin;
|
|||||||
public interface IRoomPlugin
|
public interface IRoomPlugin
|
||||||
{
|
{
|
||||||
void Tick(float dt);
|
void Tick(float dt);
|
||||||
void OnAttached();
|
void OnAttached(IRagonRoom room);
|
||||||
void OnDetached();
|
void OnDetached();
|
||||||
bool OnEntityCreate(RagonRoomPlayer creator, RagonEntity entity);
|
bool OnEntityCreate(RagonRoomPlayer creator, RagonEntity entity);
|
||||||
bool OnEntityRemove(RagonRoomPlayer remover, RagonEntity entity);
|
bool OnEntityRemove(RagonRoomPlayer remover, RagonEntity entity);
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
using Ragon.Server.Http;
|
||||||
using Ragon.Server.Lobby;
|
using Ragon.Server.Lobby;
|
||||||
using Ragon.Server.Room;
|
using Ragon.Server.Room;
|
||||||
|
|
||||||
@@ -21,10 +22,12 @@ namespace Ragon.Server.Plugin;
|
|||||||
|
|
||||||
public interface IServerPlugin
|
public interface IServerPlugin
|
||||||
{
|
{
|
||||||
|
void OnAttached(IRagonServer server);
|
||||||
|
void OnDetached();
|
||||||
bool OnRoomCreate(RagonLobbyPlayer player, RagonRoom room);
|
bool OnRoomCreate(RagonLobbyPlayer player, RagonRoom room);
|
||||||
bool OnRoomRemove(RagonLobbyPlayer player, RagonRoom room);
|
bool OnRoomRemove(RagonLobbyPlayer player, RagonRoom room);
|
||||||
bool OnRoomLeave(RagonRoomPlayer player, RagonRoom room);
|
bool OnRoomLeave(RagonRoomPlayer player, RagonRoom room);
|
||||||
bool OnRoomJoin(RagonRoomPlayer player, RagonRoom room);
|
bool OnRoomJoin(RagonRoomPlayer player, RagonRoom room);
|
||||||
|
bool OnCommand(string command, string payload);
|
||||||
IRoomPlugin CreateRoomPlugin(RoomInformation information);
|
IRoomPlugin CreateRoomPlugin(RoomInformation information);
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
using Ragon.Server.Room;
|
||||||
|
|
||||||
|
namespace Ragon.Server.Plugin.Web;
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public class PlayerDto
|
||||||
|
{
|
||||||
|
public string Id { get; set;}
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
public PlayerDto(RagonRoomPlayer ragonRoomPlayer)
|
||||||
|
{
|
||||||
|
Id = ragonRoomPlayer.Id;
|
||||||
|
Name = ragonRoomPlayer.Name;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
using Ragon.Server.Room;
|
||||||
|
|
||||||
|
namespace Ragon.Server.Plugin.Web;
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public class RoomDto
|
||||||
|
{
|
||||||
|
public string Id { get; set;}
|
||||||
|
public int PlayerMin { get; set; }
|
||||||
|
public int PlayerMax { get; set; }
|
||||||
|
public int PlayerCount { get; set; }
|
||||||
|
public PlayerDto[] Players { get; set; }
|
||||||
|
|
||||||
|
public RoomDto(RagonRoom room)
|
||||||
|
{
|
||||||
|
Id = room.Id;
|
||||||
|
PlayerMin = room.PlayerMin;
|
||||||
|
PlayerMax = room.PlayerMax;
|
||||||
|
PlayerCount = room.PlayerCount;
|
||||||
|
|
||||||
|
Players = room.PlayerList.Select(p => new PlayerDto(p)).ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
+15
-8
@@ -8,14 +8,14 @@ using Ragon.Server.Room;
|
|||||||
|
|
||||||
namespace Ragon.Server.Plugin.Web;
|
namespace Ragon.Server.Plugin.Web;
|
||||||
|
|
||||||
public class WebHookPlugin
|
public class RagonWebHookPlugin
|
||||||
{
|
{
|
||||||
private Dictionary<string, string> _webHooks;
|
private Dictionary<string, string> _webHooks;
|
||||||
|
|
||||||
private RagonServer _server;
|
private RagonServer _server;
|
||||||
private HttpClient _httpClient;
|
private HttpClient _httpClient;
|
||||||
|
|
||||||
public WebHookPlugin(RagonServer server, Configuration configuration)
|
public RagonWebHookPlugin(RagonServer server, Configuration configuration)
|
||||||
{
|
{
|
||||||
_webHooks = new Dictionary<string, string>(configuration.WebHooks);
|
_webHooks = new Dictionary<string, string>(configuration.WebHooks);
|
||||||
_httpClient = new HttpClient();
|
_httpClient = new HttpClient();
|
||||||
@@ -30,7 +30,7 @@ public class WebHookPlugin
|
|||||||
var executor = context.Executor;
|
var executor = context.Executor;
|
||||||
executor.Run(async () =>
|
executor.Run(async () =>
|
||||||
{
|
{
|
||||||
var authorizationOperation = (AuthorizationOperation) _server.Resolve(RagonOperation.AUTHORIZE);
|
var authorizationOperation = (AuthorizationOperation) _server.ResolveOperation(RagonOperation.AUTHORIZE);
|
||||||
var response = await _httpClient.PostAsync(new Uri(value), httpContent);
|
var response = await _httpClient.PostAsync(new Uri(value), httpContent);
|
||||||
if (response.StatusCode != HttpStatusCode.OK)
|
if (response.StatusCode != HttpStatusCode.OK)
|
||||||
{
|
{
|
||||||
@@ -42,7 +42,7 @@ public class WebHookPlugin
|
|||||||
var authorizationResponse = JsonConvert.DeserializeObject<AuthorizationResponse>(content);
|
var authorizationResponse = JsonConvert.DeserializeObject<AuthorizationResponse>(content);
|
||||||
if (authorizationResponse != null)
|
if (authorizationResponse != null)
|
||||||
{
|
{
|
||||||
var lobbyPlayer = new RagonLobbyPlayer(authorizationResponse.Id, authorizationResponse.Name, authorizationResponse.Payload);
|
var lobbyPlayer = new RagonLobbyPlayer(context.Connection, authorizationResponse.Id, authorizationResponse.Name, authorizationResponse.Payload);
|
||||||
|
|
||||||
context.SetPlayer(lobbyPlayer);
|
context.SetPlayer(lobbyPlayer);
|
||||||
authorizationOperation.Approve(context);
|
authorizationOperation.Approve(context);
|
||||||
@@ -58,12 +58,14 @@ public class WebHookPlugin
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RoomCreated(RagonContext context, RagonRoom room)
|
public void RoomCreated(RagonContext context, RagonRoom room, RagonRoomPlayer player)
|
||||||
{
|
{
|
||||||
if (_webHooks.TryGetValue("room-created", out var value) && !string.IsNullOrEmpty(value))
|
if (_webHooks.TryGetValue("room-created", out var value) && !string.IsNullOrEmpty(value))
|
||||||
{
|
{
|
||||||
var request = new RoomCreatedRequest()
|
var request = new RoomCreatedRequest()
|
||||||
{
|
{
|
||||||
|
Room = new RoomDto(room),
|
||||||
|
Player = new PlayerDto(player)
|
||||||
};
|
};
|
||||||
var content = JsonContent.Create(request);
|
var content = JsonContent.Create(request);
|
||||||
var executor = context.Executor;
|
var executor = context.Executor;
|
||||||
@@ -75,8 +77,9 @@ public class WebHookPlugin
|
|||||||
{
|
{
|
||||||
if (_webHooks.TryGetValue("room-removed", out var value) && !string.IsNullOrEmpty(value))
|
if (_webHooks.TryGetValue("room-removed", out var value) && !string.IsNullOrEmpty(value))
|
||||||
{
|
{
|
||||||
var request = new RoomCreatedRequest()
|
var request = new RoomRemovedRequest()
|
||||||
{
|
{
|
||||||
|
Room = new RoomDto(ragonRoom)
|
||||||
};
|
};
|
||||||
var content = JsonContent.Create(request);
|
var content = JsonContent.Create(request);
|
||||||
var executor = context.Executor;
|
var executor = context.Executor;
|
||||||
@@ -88,8 +91,10 @@ public class WebHookPlugin
|
|||||||
{
|
{
|
||||||
if (_webHooks.TryGetValue("room-joined", out var value) && !string.IsNullOrEmpty(value))
|
if (_webHooks.TryGetValue("room-joined", out var value) && !string.IsNullOrEmpty(value))
|
||||||
{
|
{
|
||||||
var request = new RoomCreatedRequest()
|
var request = new RoomJoinedRequest()
|
||||||
{
|
{
|
||||||
|
Room = new RoomDto(existsRoom),
|
||||||
|
Player = new PlayerDto(player)
|
||||||
};
|
};
|
||||||
var content = JsonContent.Create(request);
|
var content = JsonContent.Create(request);
|
||||||
var executor = context.Executor;
|
var executor = context.Executor;
|
||||||
@@ -101,8 +106,10 @@ public class WebHookPlugin
|
|||||||
{
|
{
|
||||||
if (_webHooks.TryGetValue("room-leaved", out var value) && !string.IsNullOrEmpty(value))
|
if (_webHooks.TryGetValue("room-leaved", out var value) && !string.IsNullOrEmpty(value))
|
||||||
{
|
{
|
||||||
var request = new RoomCreatedRequest()
|
var request = new RoomLeavedRequest()
|
||||||
{
|
{
|
||||||
|
Room = new RoomDto(room),
|
||||||
|
Player = new PlayerDto(roomPlayer)
|
||||||
};
|
};
|
||||||
var content = JsonContent.Create(request);
|
var content = JsonContent.Create(request);
|
||||||
var executor = context.Executor;
|
var executor = context.Executor;
|
||||||
@@ -1,7 +1,9 @@
|
|||||||
|
|
||||||
namespace Ragon.Server.Plugin.Web;
|
namespace Ragon.Server.Plugin.Web;
|
||||||
|
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public class RoomCreatedRequest
|
public class RoomCreatedRequest
|
||||||
{
|
{
|
||||||
|
public RoomDto Room { get; set; }
|
||||||
|
public PlayerDto Player { get; set; }
|
||||||
}
|
}
|
||||||
@@ -2,5 +2,6 @@ namespace Ragon.Server.Plugin.Web;
|
|||||||
|
|
||||||
public class RoomJoinedRequest
|
public class RoomJoinedRequest
|
||||||
{
|
{
|
||||||
|
public RoomDto Room { get; set; }
|
||||||
|
public PlayerDto Player { get; set; }
|
||||||
}
|
}
|
||||||
@@ -3,5 +3,6 @@ namespace Ragon.Server.Plugin.Web;
|
|||||||
[Serializable]
|
[Serializable]
|
||||||
public class RoomLeavedRequest
|
public class RoomLeavedRequest
|
||||||
{
|
{
|
||||||
|
public RoomDto Room { get; set; }
|
||||||
|
public PlayerDto Player { get; set; }
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,9 @@
|
|||||||
|
using Ragon.Server.Plugin.Web;
|
||||||
|
|
||||||
namespace Ragon.Server.Plugin.Web;
|
namespace Ragon.Server.Plugin.Web;
|
||||||
|
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public class RoomRemovedRequest
|
public class RoomRemovedRequest
|
||||||
{
|
{
|
||||||
|
public RoomDto Room { get; set; }
|
||||||
}
|
}
|
||||||
@@ -23,9 +23,8 @@ namespace Ragon.Server;
|
|||||||
|
|
||||||
public class RagonContext
|
public class RagonContext
|
||||||
{
|
{
|
||||||
public INetworkConnection Connection { get; }
|
|
||||||
public ConnectionStatus ConnectionStatus { get; set; }
|
public ConnectionStatus ConnectionStatus { get; set; }
|
||||||
|
public INetworkConnection Connection { get; }
|
||||||
public IExecutor Executor { get; private set; }
|
public IExecutor Executor { get; private set; }
|
||||||
|
|
||||||
public IRagonLobby Lobby { get; private set; }
|
public IRagonLobby Lobby { get; private set; }
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ using System.Diagnostics;
|
|||||||
using NLog;
|
using NLog;
|
||||||
using Ragon.Protocol;
|
using Ragon.Protocol;
|
||||||
using Ragon.Server.Handler;
|
using Ragon.Server.Handler;
|
||||||
|
using Ragon.Server.Http;
|
||||||
using Ragon.Server.IO;
|
using Ragon.Server.IO;
|
||||||
using Ragon.Server.Lobby;
|
using Ragon.Server.Lobby;
|
||||||
using Ragon.Server.Plugin;
|
using Ragon.Server.Plugin;
|
||||||
@@ -26,20 +27,23 @@ using Ragon.Server.Time;
|
|||||||
|
|
||||||
namespace Ragon.Server;
|
namespace Ragon.Server;
|
||||||
|
|
||||||
public class RagonServer : INetworkListener
|
public class RagonServer : IRagonServer, INetworkListener
|
||||||
{
|
{
|
||||||
private readonly Logger _logger = LogManager.GetCurrentClassLogger();
|
private readonly Logger _logger = LogManager.GetCurrentClassLogger();
|
||||||
private readonly INetworkServer _server;
|
private readonly INetworkServer _server;
|
||||||
|
private readonly IRagonOperation[] _handlers;
|
||||||
|
private readonly IRagonLobby _lobby;
|
||||||
|
private readonly IServerPlugin _serverPlugin;
|
||||||
private readonly Thread _dedicatedThread;
|
private readonly Thread _dedicatedThread;
|
||||||
private readonly Executor _executor;
|
private readonly Executor _executor;
|
||||||
private readonly WebHookPlugin _webhooks;
|
|
||||||
private readonly Configuration _configuration;
|
private readonly Configuration _configuration;
|
||||||
private readonly IRagonOperation[] _handlers;
|
private readonly RagonWebHookPlugin _webhooks;
|
||||||
|
private readonly RagonHttpServer _httpServer;
|
||||||
private readonly RagonBuffer _reader;
|
private readonly RagonBuffer _reader;
|
||||||
private readonly RagonBuffer _writer;
|
private readonly RagonBuffer _writer;
|
||||||
private readonly IRagonLobby _lobby;
|
|
||||||
private readonly RagonScheduler _scheduler;
|
private readonly RagonScheduler _scheduler;
|
||||||
private readonly Dictionary<ushort, RagonContext> _contexts;
|
private readonly Dictionary<ushort, RagonContext> _contextsByConnection;
|
||||||
|
private readonly Dictionary<string, RagonContext> _contextsByPlayerId;
|
||||||
private readonly Stopwatch _timer;
|
private readonly Stopwatch _timer;
|
||||||
private readonly long _tickRate = 0;
|
private readonly long _tickRate = 0;
|
||||||
|
|
||||||
@@ -51,20 +55,26 @@ public class RagonServer : INetworkListener
|
|||||||
_server = server;
|
_server = server;
|
||||||
_executor = _server.Executor;
|
_executor = _server.Executor;
|
||||||
_configuration = configuration;
|
_configuration = configuration;
|
||||||
_contexts = new Dictionary<ushort, RagonContext>();
|
_serverPlugin = plugin;
|
||||||
|
_contextsByConnection = new Dictionary<ushort, RagonContext>();
|
||||||
|
_contextsByPlayerId = new Dictionary<string, RagonContext>();
|
||||||
_lobby = new LobbyInMemory();
|
_lobby = new LobbyInMemory();
|
||||||
_scheduler = new RagonScheduler();
|
_scheduler = new RagonScheduler();
|
||||||
_webhooks = new WebHookPlugin(this, configuration);
|
_webhooks = new RagonWebHookPlugin(this, configuration);
|
||||||
_dedicatedThread = new Thread(Execute);
|
_dedicatedThread = new Thread(Execute);
|
||||||
_dedicatedThread.IsBackground = true;
|
_dedicatedThread.IsBackground = true;
|
||||||
|
_httpServer = new RagonHttpServer(_executor, plugin);
|
||||||
_reader = new RagonBuffer();
|
_reader = new RagonBuffer();
|
||||||
_writer = new RagonBuffer();
|
_writer = new RagonBuffer();
|
||||||
_tickRate = 1000 / _configuration.ServerTickRate;
|
_tickRate = 1000 / _configuration.ServerTickRate;
|
||||||
_timer = new Stopwatch();
|
_timer = new Stopwatch();
|
||||||
|
|
||||||
|
var contextObserver = new RagonContextObserver(_contextsByPlayerId);
|
||||||
|
|
||||||
|
_serverPlugin.OnAttached(this);
|
||||||
|
|
||||||
_handlers = new IRagonOperation[byte.MaxValue];
|
_handlers = new IRagonOperation[byte.MaxValue];
|
||||||
_handlers[(byte) RagonOperation.AUTHORIZE] = new AuthorizationOperation(_webhooks, _writer, configuration);
|
_handlers[(byte) RagonOperation.AUTHORIZE] = new AuthorizationOperation(_webhooks, contextObserver, _writer, configuration);
|
||||||
_handlers[(byte) RagonOperation.JOIN_OR_CREATE_ROOM] = new RoomJoinOrCreateOperation(plugin, _webhooks);
|
_handlers[(byte) RagonOperation.JOIN_OR_CREATE_ROOM] = new RoomJoinOrCreateOperation(plugin, _webhooks);
|
||||||
_handlers[(byte) RagonOperation.CREATE_ROOM] = new RoomCreateOperation(plugin, _webhooks);
|
_handlers[(byte) RagonOperation.CREATE_ROOM] = new RoomCreateOperation(plugin, _webhooks);
|
||||||
_handlers[(byte) RagonOperation.JOIN_ROOM] = new RoomJoinOperation(plugin, _webhooks);
|
_handlers[(byte) RagonOperation.JOIN_ROOM] = new RoomJoinOperation(plugin, _webhooks);
|
||||||
@@ -79,8 +89,6 @@ public class RagonServer : INetworkListener
|
|||||||
_logger.Trace($"Server Tick Rate: {_configuration.ServerTickRate}");
|
_logger.Trace($"Server Tick Rate: {_configuration.ServerTickRate}");
|
||||||
}
|
}
|
||||||
|
|
||||||
public IRagonOperation Resolve(RagonOperation operation) => _handlers[(byte)operation];
|
|
||||||
|
|
||||||
public void Execute()
|
public void Execute()
|
||||||
{
|
{
|
||||||
_timer.Start();
|
_timer.Start();
|
||||||
@@ -88,11 +96,11 @@ public class RagonServer : INetworkListener
|
|||||||
{
|
{
|
||||||
if (_timer.ElapsedMilliseconds > _tickRate)
|
if (_timer.ElapsedMilliseconds > _tickRate)
|
||||||
{
|
{
|
||||||
_executor.Update();
|
|
||||||
_scheduler.Update(_timer.ElapsedMilliseconds / 1000.0f);
|
_scheduler.Update(_timer.ElapsedMilliseconds / 1000.0f);
|
||||||
_timer.Restart();
|
_timer.Restart();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_executor.Update();
|
||||||
_server.Update();
|
_server.Update();
|
||||||
Thread.Sleep(1);
|
Thread.Sleep(1);
|
||||||
}
|
}
|
||||||
@@ -108,6 +116,7 @@ public class RagonServer : INetworkListener
|
|||||||
Port = _configuration.Port,
|
Port = _configuration.Port,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
_httpServer.Start(_configuration);
|
||||||
_server.Start(this, networkConfiguration);
|
_server.Start(this, networkConfiguration);
|
||||||
|
|
||||||
if (executeInDedicatedThread)
|
if (executeInDedicatedThread)
|
||||||
@@ -118,6 +127,7 @@ public class RagonServer : INetworkListener
|
|||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
|
_serverPlugin.OnDetached();
|
||||||
_server.Stop();
|
_server.Stop();
|
||||||
_dedicatedThread.Interrupt();
|
_dedicatedThread.Interrupt();
|
||||||
}
|
}
|
||||||
@@ -127,12 +137,12 @@ public class RagonServer : INetworkListener
|
|||||||
var context = new RagonContext(connection, _executor, _lobby, _scheduler);
|
var context = new RagonContext(connection, _executor, _lobby, _scheduler);
|
||||||
|
|
||||||
_logger.Trace($"Connected: {connection.Id}");
|
_logger.Trace($"Connected: {connection.Id}");
|
||||||
_contexts.Add(connection.Id, context);
|
_contextsByConnection.Add(connection.Id, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnDisconnected(INetworkConnection connection)
|
public void OnDisconnected(INetworkConnection connection)
|
||||||
{
|
{
|
||||||
if (_contexts.Remove(connection.Id, out var context))
|
if (_contextsByConnection.Remove(connection.Id, out var context))
|
||||||
{
|
{
|
||||||
var room = context.Room;
|
var room = context.Room;
|
||||||
if (room != null)
|
if (room != null)
|
||||||
@@ -152,7 +162,7 @@ public class RagonServer : INetworkListener
|
|||||||
|
|
||||||
public void OnTimeout(INetworkConnection connection)
|
public void OnTimeout(INetworkConnection connection)
|
||||||
{
|
{
|
||||||
if (_contexts.Remove(connection.Id, out var context))
|
if (_contextsByConnection.Remove(connection.Id, out var context))
|
||||||
{
|
{
|
||||||
var room = context.Room;
|
var room = context.Room;
|
||||||
if (room != null)
|
if (room != null)
|
||||||
@@ -173,7 +183,7 @@ public class RagonServer : INetworkListener
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (_contexts.TryGetValue(connection.Id, out var context))
|
if (_contextsByConnection.TryGetValue(connection.Id, out var context))
|
||||||
{
|
{
|
||||||
_writer.Clear();
|
_writer.Clear();
|
||||||
_reader.Clear();
|
_reader.Clear();
|
||||||
@@ -188,4 +198,7 @@ public class RagonServer : INetworkListener
|
|||||||
_logger.Error(ex);
|
_logger.Error(ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public IRagonOperation ResolveOperation(RagonOperation operation) => _handlers[(byte)operation];
|
||||||
|
public RagonContext? ResolveContext(INetworkConnection connection) => _contextsByConnection.TryGetValue(connection.Id, out var context) ? context : null;
|
||||||
|
public RagonContext? ResolveContext(string playerId) => _contextsByPlayerId.TryGetValue(playerId, out var context) ? context : null;
|
||||||
}
|
}
|
||||||
@@ -38,6 +38,8 @@ public struct Configuration
|
|||||||
public ushort ServerTickRate;
|
public ushort ServerTickRate;
|
||||||
public string GameProtocol;
|
public string GameProtocol;
|
||||||
public ushort Port;
|
public ushort Port;
|
||||||
|
public ushort HttpPort;
|
||||||
|
public string HttpKey;
|
||||||
public int LimitConnections;
|
public int LimitConnections;
|
||||||
public int LimitPlayersPerRoom;
|
public int LimitPlayersPerRoom;
|
||||||
public int LimitRooms;
|
public int LimitRooms;
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
using Ragon.Server.IO;
|
||||||
|
|
||||||
|
namespace Ragon.Server.Room;
|
||||||
|
|
||||||
|
public interface IRagonRoom
|
||||||
|
{
|
||||||
|
RagonRoomPlayer GetPlayerByConnection(INetworkConnection connection);
|
||||||
|
RagonRoomPlayer GetPlayerById(string id);
|
||||||
|
}
|
||||||
@@ -16,12 +16,13 @@
|
|||||||
|
|
||||||
using Ragon.Protocol;
|
using Ragon.Protocol;
|
||||||
using Ragon.Server.Entity;
|
using Ragon.Server.Entity;
|
||||||
|
using Ragon.Server.IO;
|
||||||
using Ragon.Server.Plugin;
|
using Ragon.Server.Plugin;
|
||||||
using Ragon.Server.Time;
|
using Ragon.Server.Time;
|
||||||
|
|
||||||
namespace Ragon.Server.Room;
|
namespace Ragon.Server.Room;
|
||||||
|
|
||||||
public class RagonRoom : IRagonAction
|
public class RagonRoom : IRagonRoom, IRagonAction
|
||||||
{
|
{
|
||||||
public string Id { get; private set; }
|
public string Id { get; private set; }
|
||||||
public string Map { get; private set; }
|
public string Map { get; private set; }
|
||||||
@@ -204,4 +205,7 @@ public class RagonRoom : IRagonAction
|
|||||||
foreach (var readyPlayer in ReadyPlayersList)
|
foreach (var readyPlayer in ReadyPlayersList)
|
||||||
readyPlayer.Connection.Reliable.Send(data);
|
readyPlayer.Connection.Reliable.Send(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public RagonRoomPlayer GetPlayerByConnection(INetworkConnection connection) => Players[connection.Id];
|
||||||
|
public RagonRoomPlayer GetPlayerById(string id) => PlayerList.First(p => p.Id == id);
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user