Files
Ragon/Ragon/Sources/Rooms/RoomManager.cs
T
2022-04-30 08:20:17 +04:00

151 lines
3.7 KiB
C#

using System;
using System.Collections.Generic;
using System.Text;
using NLog;
using Ragon.Common.Protocol;
namespace Ragon.Core
{
public class RoomManager
{
private readonly Logger _logger = LogManager.GetCurrentClassLogger();
private List<Room> _rooms;
private Dictionary<uint, Room> _peersByRoom;
private PluginFactory _factory;
private AuthorizationManager _manager;
private RoomThread _roomThread;
public Action<(uint, Room)> OnJoined;
public Action<(uint, Room)> OnLeaved;
public RoomManager(RoomThread roomThread, PluginFactory factory)
{
_roomThread = roomThread;
_factory = factory;
_manager = _factory.CreateManager();
_rooms = new List<Room>();
_peersByRoom = new Dictionary<uint, Room>();
}
public void ProcessEvent(RagonOperation operation, uint peerId, byte[] payload)
{
switch (operation)
{
case RagonOperation.AUTHORIZE:
{
OnAuthorize(peerId, payload);
break;
}
case RagonOperation.JOIN_ROOM:
{
var room = Join(peerId, payload);
OnJoined?.Invoke((peerId, room));
break;
}
case RagonOperation.LEAVE_ROOM:
{
var room = Left(peerId, payload);
OnLeaved((peerId, room));
break;
}
}
}
public void OnAuthorize(uint peerId, byte[] payload)
{
if (_manager.OnAuthorize(peerId, payload))
{
Span<byte> data = stackalloc byte[2];
ProtocolHeader.WriteUShort((ushort) RagonOperation.AUTHORIZED_SUCCESS, ref data);
var bytes = data.ToArray();
_roomThread.WriteOutEvent(new Event()
{
Delivery = DeliveryType.Reliable,
Type = EventType.DATA,
Data = bytes,
PeerId = peerId,
});
}
else
{
Span<byte> data = stackalloc byte[2];
ProtocolHeader.WriteUShort((ushort) RagonOperation.AUTHORIZED_FAILED, ref data);
var bytes = data.ToArray();
_roomThread.WriteOutEvent(new Event()
{
Delivery = DeliveryType.Reliable,
Type = EventType.DATA,
Data = bytes,
PeerId = peerId,
});
_roomThread.WriteOutEvent(new Event()
{
Delivery = DeliveryType.Reliable,
Type = EventType.DISCONNECTED,
Data = Array.Empty<byte>(),
PeerId = peerId,
});
}
}
public Room Join(uint peerId, byte[] payload)
{
var map = Encoding.UTF8.GetString(payload);
if (_rooms.Count > 0)
{
var existsRoom = _rooms[0];
existsRoom.Joined(peerId, payload);
_peersByRoom.Add(peerId, existsRoom);
return existsRoom;
}
var plugin = _factory.CreatePlugin(map);
if (plugin == null)
throw new NullReferenceException($"Plugin for map {map} is null");
var room = new Room(_roomThread, plugin, map);
room.Joined(peerId, payload);
room.Start();
_peersByRoom.Add(peerId, room);
_rooms.Add(room);
return room;
}
public Room Left(uint peerId, byte[] payload)
{
_peersByRoom.Remove(peerId, out var room);
return room;
}
public void Disconnected(uint peerId)
{
_peersByRoom.Remove(peerId, out var room);
if (room != null)
{
room.Leave(peerId);
if (room.PlayersCount <= 0)
{
_rooms.Remove(room);
room.Stop();
room.Dispose();
}
}
}
public void Tick(float deltaTime)
{
foreach (Room room in _rooms)
room.Tick(deltaTime);
}
}
}