This commit is contained in:
2022-12-17 21:16:02 +04:00
parent 13044357a5
commit ab85578ccf
9 changed files with 565 additions and 558 deletions
+7 -1
View File
@@ -82,7 +82,13 @@ public class Application : INetworkListener
if (_contexts.Remove(connection.Id, out var context)) if (_contexts.Remove(connection.Id, out var context))
{ {
context.Room?.RemovePlayer(context.RoomPlayer); var room = context.Room;
if (room != null)
{
room.RemovePlayer(context.RoomPlayer);
_lobby.RemoveIfEmpty(room);
}
context.Dispose(); context.Dispose();
} }
} }
+3 -4
View File
@@ -20,16 +20,15 @@ public class EntityList
_entitiesMap.Add(entity.Id, entity); _entitiesMap.Add(entity.Id, entity);
} }
public Entity Remove(Entity entity) public bool Remove(Entity entity)
{ {
if (_entitiesMap.Remove(entity.Id, out var existEntity)) if (_entitiesMap.Remove(entity.Id, out var existEntity))
{ {
_staticEntitiesList.Remove(entity); _staticEntitiesList.Remove(entity);
_dynamicEntitiesList.Remove(entity); _dynamicEntitiesList.Remove(entity);
return existEntity; return true;
} }
return false;
return null;
} }
} }
+24 -27
View File
@@ -5,11 +5,11 @@ namespace Ragon.Core.Game;
public class Room: IAction public class Room: IAction
{ {
public string Id { get; } public string Id { get; private set; }
public RoomInformation Info { get; } public RoomInformation Info { get; private set; }
public RoomPlayer Owner { get; set; } public RoomPlayer Owner { get; private set; }
public RagonSerializer Writer { get; }
public Dictionary<ushort, RoomPlayer> Players { get; } public Dictionary<ushort, RoomPlayer> Players { get; private set; }
public List<RoomPlayer> WaitPlayersList { get; private set; } public List<RoomPlayer> WaitPlayersList { get; private set; }
public List<RoomPlayer> ReadyPlayersList { get; private set; } public List<RoomPlayer> ReadyPlayersList { get; private set; }
public List<RoomPlayer> PlayerList { get; private set; } public List<RoomPlayer> PlayerList { get; private set; }
@@ -19,10 +19,7 @@ public class Room: IAction
public List<Entity> StaticEntitiesList { get; private set; } public List<Entity> StaticEntitiesList { get; private set; }
public List<Entity> EntityList { get; private set; } public List<Entity> EntityList { get; private set; }
private HashSet<Entity> _entitiesDirtySet; private readonly HashSet<Entity> _entitiesDirtySet;
private RagonSerializer _writer;
public RagonSerializer Writer => _writer;
public Room(string roomId, RoomInformation info) public Room(string roomId, RoomInformation info)
{ {
@@ -40,7 +37,7 @@ public class Room: IAction
EntityList = new List<Entity>(); EntityList = new List<Entity>();
_entitiesDirtySet = new HashSet<Entity>(); _entitiesDirtySet = new HashSet<Entity>();
_writer = new RagonSerializer(512); Writer = new RagonSerializer(512);
} }
public void AttachEntity(RoomPlayer newOwner, Entity entity) public void AttachEntity(RoomPlayer newOwner, Entity entity)
@@ -75,16 +72,16 @@ public class Room: IAction
var entities = (ushort) _entitiesDirtySet.Count; var entities = (ushort) _entitiesDirtySet.Count;
if (entities > 0) if (entities > 0)
{ {
_writer.Clear(); Writer.Clear();
_writer.WriteOperation(RagonOperation.REPLICATE_ENTITY_STATE); Writer.WriteOperation(RagonOperation.REPLICATE_ENTITY_STATE);
_writer.WriteUShort(entities); Writer.WriteUShort(entities);
foreach (var entity in _entitiesDirtySet) foreach (var entity in _entitiesDirtySet)
entity.State.Write(_writer); entity.State.Write(Writer);
_entitiesDirtySet.Clear(); _entitiesDirtySet.Clear();
var sendData = _writer.ToArray(); var sendData = Writer.ToArray();
foreach (var roomPlayer in ReadyPlayersList) foreach (var roomPlayer in ReadyPlayersList)
roomPlayer.Connection.UnreliableChannel.Send(sendData); roomPlayer.Connection.UnreliableChannel.Send(sendData);
} }
@@ -108,19 +105,19 @@ public class Room: IAction
PlayerList.Remove(player); PlayerList.Remove(player);
{ {
_writer.Clear(); Writer.Clear();
_writer.WriteOperation(RagonOperation.PLAYER_LEAVED); Writer.WriteOperation(RagonOperation.PLAYER_LEAVED);
_writer.WriteString(player.Id); Writer.WriteString(player.Id);
var entitiesToDelete = player.Entities.DynamicList; var entitiesToDelete = player.Entities.DynamicList;
_writer.WriteUShort((ushort) entitiesToDelete.Count); Writer.WriteUShort((ushort) entitiesToDelete.Count);
foreach (var entity in entitiesToDelete) foreach (var entity in entitiesToDelete)
{ {
_writer.WriteUShort(entity.Id); Writer.WriteUShort(entity.Id);
EntityList.Remove(entity); EntityList.Remove(entity);
} }
var sendData = _writer.ToArray(); var sendData = Writer.ToArray();
Broadcast(sendData); Broadcast(sendData);
} }
@@ -132,20 +129,20 @@ public class Room: IAction
var entitiesToUpdate = roomPlayer.Entities.StaticList; var entitiesToUpdate = roomPlayer.Entities.StaticList;
_writer.Clear(); Writer.Clear();
_writer.WriteOperation(RagonOperation.OWNERSHIP_CHANGED); Writer.WriteOperation(RagonOperation.OWNERSHIP_CHANGED);
_writer.WriteString(Owner.Id); Writer.WriteString(Owner.Id);
_writer.WriteUShort((ushort) entitiesToUpdate.Count); Writer.WriteUShort((ushort) entitiesToUpdate.Count);
foreach (var entity in entitiesToUpdate) foreach (var entity in entitiesToUpdate)
{ {
_writer.WriteUShort(entity.Id); Writer.WriteUShort(entity.Id);
entity.SetOwner(nextOwner); entity.SetOwner(nextOwner);
nextOwner.Entities.Add(entity); nextOwner.Entities.Add(entity);
} }
var sendData = _writer.ToArray(); var sendData = Writer.ToArray();
Broadcast(sendData); Broadcast(sendData);
} }
} }
+3 -3
View File
@@ -2,9 +2,9 @@ namespace Ragon.Core.Game;
public class RoomInformation public class RoomInformation
{ {
public string Map { get; set; } public string Map { get; init; } = "none";
public int Min { get; set; } public int Min { get; init; }
public int Max { get; set; } public int Max { get; init; }
public override string ToString() public override string ToString()
{ {
+1 -1
View File
@@ -8,5 +8,5 @@ public interface ILobby
public bool FindRoomById(string roomId, [MaybeNullWhen(false)] out Room room); public bool FindRoomById(string roomId, [MaybeNullWhen(false)] out Room room);
public bool FindRoomByMap(string map, [MaybeNullWhen(false)] out Room room); public bool FindRoomByMap(string map, [MaybeNullWhen(false)] out Room room);
public void Persist(Room room); public void Persist(Room room);
public void Remove(Room room); public void RemoveIfEmpty(Room room);
} }
+7 -3
View File
@@ -47,11 +47,15 @@ public class LobbyInMemory : ILobby
_rooms.Add(room); _rooms.Add(room);
foreach (var r in _rooms) foreach (var r in _rooms)
_logger.Trace($"{r.Id} {r.Info}"); _logger.Trace($"Room: {r.Id} {r.Info} Players: {r.Players.Count}");
} }
public void Remove(Room room) public void RemoveIfEmpty(Room room)
{ {
_rooms.Remove(room); if (room.Players.Count == 0)
_rooms.Remove(room);
foreach (var r in _rooms)
_logger.Trace($"Room: {r.Id} {r.Info} Players: {r.Players.Count}");
} }
} }
+16 -15
View File
@@ -8,30 +8,31 @@ namespace Ragon.Server.ENet
{ {
public sealed class ENetServer: INetworkServer public sealed class ENetServer: INetworkServer
{ {
public ENetConnection[] Connections; private readonly Host _host;
private ILogger _logger = LogManager.GetCurrentClassLogger(); private readonly ILogger _logger = LogManager.GetCurrentClassLogger();
private INetworkListener _listener;
private ENetConnection[] _connections;
private uint _protocol; private uint _protocol;
private Host _host; private INetworkListener _listener;
private Event _event; private Event _event;
private NetworkConfiguration _configuration;
public ENetServer() public ENetServer()
{ {
_host = new Host(); _host = new Host();
_connections = Array.Empty<ENetConnection>();
} }
public void Start(INetworkListener listener, NetworkConfiguration configuration) public void Start(INetworkListener listener, NetworkConfiguration configuration)
{ {
Library.Initialize(); Library.Initialize();
_connections = new ENetConnection[configuration.LimitConnections];
_listener = listener; _listener = listener;
_protocol = configuration.Protocol; _protocol = configuration.Protocol;
Connections = new ENetConnection[configuration.LimitConnections];
var address = new Address { Port = (ushort) configuration.Port }; var address = new Address { Port = (ushort) configuration.Port };
_host.Create(address, Connections.Length, 2, 0, 0, 1024 * 1024); _host.Create(address, _connections.Length, 2, 0, 0, 1024 * 1024);
var protocolDecoded = RagonVersion.Parse(_protocol); var protocolDecoded = RagonVersion.Parse(_protocol);
_logger.Info($"Network listening on {configuration.Port}"); _logger.Info($"Network listening on {configuration.Port}");
@@ -60,34 +61,33 @@ namespace Ragon.Server.ENet
} }
case EventType.Connect: case EventType.Connect:
{ {
if (IsValidProtocol(_event.Data)) if (!IsValidProtocol(_event.Data))
{ {
_logger.Warn("Mismatched protocol, close connection"); _logger.Warn("Mismatched protocol, close connection");
break; break;
} }
var connection = new ENetConnection(_event.Peer); var connection = new ENetConnection(_event.Peer);
Connections[_event.Peer.ID] = connection; _connections[_event.Peer.ID] = connection;
_listener.OnConnected(connection); _listener.OnConnected(connection);
break; break;
} }
case EventType.Disconnect: case EventType.Disconnect:
{ {
var connection = Connections[_event.Peer.ID]; var connection = _connections[_event.Peer.ID];
_listener.OnDisconnected(connection); _listener.OnDisconnected(connection);
break; break;
} }
case EventType.Timeout: case EventType.Timeout:
{ {
var connection = Connections[_event.Peer.ID]; var connection = _connections[_event.Peer.ID];
_listener.OnTimeout(connection); _listener.OnTimeout(connection);
break; break;
} }
case EventType.Receive: case EventType.Receive:
{ {
var peerId = (ushort) _event.Peer.ID; var peerId = (ushort) _event.Peer.ID;
var connection = Connections[peerId]; var connection = _connections[peerId];
var dataRaw = new byte[_event.Packet.Length]; var dataRaw = new byte[_event.Packet.Length];
_event.Packet.CopyTo(dataRaw); _event.Packet.CopyTo(dataRaw);
@@ -109,7 +109,8 @@ namespace Ragon.Server.ENet
private bool IsValidProtocol(uint protocol) private bool IsValidProtocol(uint protocol)
{ {
return protocol == _configuration.Protocol; Console.WriteLine($"{protocol} {_protocol}");
return protocol == _protocol;
} }
} }
} }