pong-game/PongGame/Hubs/PongRoom.cs

65 lines
2.2 KiB
C#

using Microsoft.AspNetCore.SignalR;
namespace PongGame.Hubs;
public class PongRoom {
public string ID { get; }
private readonly ILogger Logger;
public PongRoom(string id, ILogger logger) {
ID = id;
Logger = logger;
}
public PongPlayer? Player1 { get; private set; }
public PongPlayer? Player2 { get; private set; }
public GameState State { get; private set; } = GameState.WaitingForPlayers;
public void Join(PongPlayer player) {
// TODO: synchronize this
if (Player1 is null) {
Player1 = player;
Logger.LogInformation($"[{ID}] {player} joined pong room as player 1!");
} else if (Player2 is null) {
Player2 = player;
Logger.LogInformation($"[{ID}] {player} joined pong room as player 2!");
} else
throw new HubException($"Lobby [{ID}] is already full!");
_ = Task.Run(PlayersChanged);
player.ConnectedRoom = this;
}
public void Leave(PongPlayer player) {
if (Player1 == player) {
Player1 = null;
Logger.LogInformation($"[{ID}] Player 1 {player} left pong room!");
} else if (Player2 == player) {
Player2 = null;
Logger.LogInformation($"[{ID}] Player 2 {player} left pong room!");
}
player.ConnectedRoom = null;
_ = Task.Run(PlayersChanged);
}
private Task PlayersChanged() {
if (Player1 is PongPlayer player1 && Player2 is PongPlayer player2) {
ResumeGame(player1, player2);
} else if (Player1 is null && Player2 is null) {
CloseRoom();
} else
PauseGame();
return Task.CompletedTask;
}
private void ResumeGame(PongPlayer player1, PongPlayer player2) {
Logger.LogInformation($"[{ID}] Pong game started: {player1} vs. {player2}");
State = GameState.InProgress;
player1.Client.GameStateChanged(State);
player2.Client.GameStateChanged(State);
}
private void PauseGame() => State = GameState.WaitingForPlayers;
private void CloseRoom() => State = GameState.Finished;
public override string ToString() => $"[{ID}]";
}