pong-game/PongGame/Hubs/PongLobbyCollection.cs

65 lines
1.9 KiB
C#

using System.Collections.Concurrent;
using Microsoft.AspNetCore.SignalR;
namespace PongGame.Hubs;
public class PongLobby {
private readonly HashSet<PongPlayer> connectedPlayers = new();
private readonly Dictionary<string, PongRoom> PongRooms = new();
public PongLobby(ILogger<PongLobby> logger)
=> Logger = logger;
public const int ROOM_ID_LENGTH = 4;
public PongPlayer CreatePlayer() {
var player = new PongPlayer();
lock (connectedPlayers)
connectedPlayers.Add(player);
return player;
}
public void RemovePlayer(PongPlayer player) {
if (player.ConnectedRoom is PongRoom room)
room.Leave(player);
lock (connectedPlayers)
_ = connectedPlayers.Remove(player);
}
public PongRoom CreateRoom(PongPlayer player) {
PongRoom room;
lock (PongRooms) {
room = new(GenerateRoomId(), Logger);
PongRooms.Add(room.ID, room);
}
room.Join(player);
return room;
}
public PongRoom JoinRoom(PongPlayer player, string roomId) {
PongRoom? room;
lock (PongRooms) {
room = PongRooms.GetValueOrDefault(roomId);
}
if (room is null) throw new HubException($"Room [{roomId}] not found!");
room.Join(player);
return room;
}
public void LeaveRoom(PongPlayer player) {
if (player.ConnectedRoom is PongRoom room)
room.Leave(player);
}
private readonly Random random = new();
private readonly ILogger<PongLobby> Logger;
private const string ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
private string GenerateRoomId() {
string id;
do {
id = string.Concat(Enumerable.Range(0, ROOM_ID_LENGTH).Select(_ => ALPHABET[random.Next(ALPHABET.Length)]));
} while (PongRooms.ContainsKey(id));
return id;
}
}