feat(wip): room list support

This commit is contained in:
2024-04-13 16:17:31 +03:00
parent acedaef270
commit d82964526c
16 changed files with 215 additions and 54 deletions
@@ -80,6 +80,9 @@ public sealed class RoomCreateOperation : BaseOperation
var roomPlugin = _serverPlugin.CreateRoomPlugin(information);
var room = new RagonRoom(roomId, information, roomPlugin);
if (!roomPlugin.OnPlayerJoined(roomPlayer))
return;
roomPlayer.OnAttached(room);
context.Scheduler.Run(room);
@@ -53,6 +53,10 @@ public sealed class RoomJoinOrCreateOperation : BaseOperation
if (context.Lobby.FindRoomByScene(_roomParameters.Scene, out var existsRoom))
{
var player = new RagonRoomPlayer(context.Connection, lobbyPlayer.Id, lobbyPlayer.Name);
if (!existsRoom.Plugin.OnPlayerJoined(player))
return;
context.SetRoom(existsRoom, player);
_ragonWebHookPlugin.RoomJoined(context, existsRoom, player);
@@ -72,6 +76,9 @@ public sealed class RoomJoinOrCreateOperation : BaseOperation
var roomPlugin = _serverPlugin.CreateRoomPlugin(information);
var room = new RagonRoom(roomId, information, roomPlugin);
if (!roomPlugin.OnPlayerJoined(roomPlayer))
return;
_ragonWebHookPlugin.RoomCreated(context, room, roomPlayer);
context.Lobby.Persist(room);
@@ -21,6 +21,7 @@ namespace Ragon.Server.Lobby;
public interface IRagonLobby
{
public IReadOnlyList<IRagonRoom> Rooms { get; }
public bool FindRoomById(string roomId, [MaybeNullWhen(false)] out RagonRoom room);
public bool FindRoomByScene(string sceneName, [MaybeNullWhen(false)] out RagonRoom room);
public void Persist(RagonRoom room);
@@ -0,0 +1,33 @@
using Ragon.Protocol;
using Ragon.Server.Room;
namespace Ragon.Server.Lobby;
public class RagonLobbyDispatcher
{
private IRagonLobby _lobby;
public RagonLobbyDispatcher(IRagonLobby lobby)
{
_lobby = lobby;
}
public void Write(RagonBuffer writer)
{
writer.Clear();
writer.Write((byte)RagonOperation.ROOM_LIST_UPDATED);
var rooms = _lobby.Rooms;
writer.WriteUShort((ushort)rooms.Count);
for (int i = 0; i < rooms.Count; i++)
{
var room = rooms[i];
writer.WriteString(room.Id);
writer.WriteString(room.Scene);
writer.WriteUShort((ushort)room.PlayerMax);
writer.WriteUShort((ushort)room.PlayerMin);
writer.WriteUShort((ushort)room.PlayerCount);
}
}
}
@@ -25,6 +25,8 @@ public class LobbyInMemory : IRagonLobby
private readonly List<RagonRoom> _rooms = new();
private readonly Logger _logger = LogManager.GetCurrentClassLogger();
public IReadOnlyList<IRagonRoom> Rooms => _rooms.AsReadOnly();
public bool FindRoomById(string roomId, [MaybeNullWhen(false)] out RagonRoom room)
{
foreach (var existRagonRoom in _rooms)
+18 -2
View File
@@ -45,6 +45,7 @@ public class RagonServer : IRagonServer, INetworkListener
private readonly Dictionary<ushort, RagonContext> _contextsByConnection;
private readonly Dictionary<string, RagonContext> _contextsByPlayerId;
private readonly Stopwatch _timer;
private readonly RagonLobbyDispatcher _lobbySerializer;
private readonly long _tickRate = 0;
public RagonServer(
@@ -59,6 +60,7 @@ public class RagonServer : IRagonServer, INetworkListener
_contextsByConnection = new Dictionary<ushort, RagonContext>();
_contextsByPlayerId = new Dictionary<string, RagonContext>();
_lobby = new LobbyInMemory();
_lobbySerializer = new RagonLobbyDispatcher(_lobby);
_scheduler = new RagonScheduler();
_webhooks = new RagonWebHookPlugin(this, configuration);
_dedicatedThread = new Thread(Execute);
@@ -68,9 +70,11 @@ public class RagonServer : IRagonServer, INetworkListener
_writer = new RagonBuffer();
_tickRate = 1000 / _configuration.ServerTickRate;
_timer = new Stopwatch();
var contextObserver = new RagonContextObserver(_contextsByPlayerId);
_scheduler.Run(new RagonActionTimer(SendRoomList, 1.0f));
_serverPlugin.OnAttached(this);
_handlers = new BaseOperation[byte.MaxValue];
@@ -228,6 +232,18 @@ public class RagonServer : IRagonServer, INetworkListener
_server.Broadcast(sendData, NetworkChannel.UNRELIABLE);
}
public void SendRoomList()
{
_lobbySerializer.Write(_writer);
var sendData = _writer.ToArray();
foreach (var (_, value) in _contextsByPlayerId)
{
if (value.Room == null) // If only in lobby, then send room list data
value.Connection.Reliable.Send(sendData);
}
}
public BaseOperation ResolveHandler(RagonOperation operation)
{
return _handlers[(byte)operation];
+6
View File
@@ -21,6 +21,12 @@ namespace Ragon.Server.Room;
public interface IRagonRoom
{
public string Id { get; }
public string Scene { get; }
public int PlayerMin { get; }
public int PlayerMax { get; }
public int PlayerCount { get; }
RagonRoomPlayer GetPlayerByConnection(INetworkConnection connection);
RagonRoomPlayer GetPlayerById(string id);
IRagonEntity GetEntityById(ushort id);
@@ -0,0 +1,21 @@
using Ragon.Server.Time;
public class RagonActionTimer: IRagonAction
{
private Action _callback;
private float _timer;
private float _time;
public RagonActionTimer(Action callback, float timeInSeconds)
{
_callback = callback;
_time = timeInSeconds * 1000;
}
public void Tick(float dt)
{
_timer += dt;
if (_timer >= _time)
_callback?.Invoke();
}
}