using System.Net.WebSockets; using System.Text.Json; using System.Text.RegularExpressions; using MauMau_Server.Mau; namespace MauMau_Server.Websockets; public class Room { private readonly IRoomManager _roomManager; private readonly string _roomId; private readonly List _connections = new(); private ConnectionInstance _host; private readonly Chat _chat; private readonly Game _game = new(); public Room(IRoomManager roomManager, string roomId) { _roomManager = roomManager; _chat = new Chat(this); _roomId = roomId; } public async Task InstantiateConnection(WebSocket socket, string name) { var connection = AddConnection(socket, name); if (IsEmpty()) _host = connection; _game.AddPlayerToGame(connection); await HandleConnection(connection); } private async Task HandleConnection(ConnectionInstance connection) { BroadcastGameState(); var webSocketResponse = await WebsocketManager.ReceiveAsync(connection.Socket); while (!webSocketResponse.Result!.CloseStatus.HasValue) { var message = JsonSerializer.Deserialize(webSocketResponse.SlicedBuffer); switch (message.Type) { case "GAME": { var gameInput = JsonSerializer.Deserialize(message.Payload); _game.HandleAction(connection.ConnectionId, gameInput); break; } case "CHAT": { var cleanedMessage = StripHTML(message.Payload); if (string.IsNullOrWhiteSpace(cleanedMessage)) { cleanedMessage = "Mau!"; }; _chat.SendChatMessage(connection, cleanedMessage); break; } } BroadcastGameState(); webSocketResponse = await WebsocketManager.ReceiveAsync(connection.Socket); } WebsocketManager.CloseAsync(connection.Socket, webSocketResponse.Result); HandleDisconnect(connection.ConnectionId); } private ConnectionInstance AddConnection(WebSocket socket, string name) { var connectionId = Guid.NewGuid().ToString(); var connection = new ConnectionInstance(name, connectionId, socket); _connections.Add(connection); return connection; } private void RemoveConnection(string socketId) { _connections.RemoveAll(connection => connection.ConnectionId == socketId); } private void BroadcastGameState() { foreach (var connection in _connections) { var gameState = new GameState(_game, connection.ConnectionId); var message = new MessageDTO("GAME", JsonSerializer.Serialize(gameState)); WebsocketManager.SendAsync(connection.Socket, JsonSerializer.Serialize(message)); } } private void HandleDisconnect(string socketId) { RemoveConnection(socketId); _game.RemovePlayer(socketId); if (IsEmpty()) { _roomManager.RemoveRoom(_roomId); } else if (socketId == _host.ConnectionId) { _host = _connections.First(); } } public List GetWebsockets() { return _connections.Select(connection => connection.Socket).ToList(); } public bool IsEmpty() { return _connections.Count == 0; } private static string StripHTML(string input) { return Regex.Replace(input, "<.*?>", String.Empty); } }