pong-game/PongGame/Hubs/PongRoom.cs

81 lines
3.0 KiB
C#
Raw Normal View History

2022-11-03 12:29:35 +01:00
using Microsoft.AspNetCore.SignalR;
namespace PongGame.Hubs;
public class PongRoom {
public string ID { get; }
private readonly ILogger Logger;
private const string JOIN_LOG_TEMPLATE = "[{ID}] {Player} joined pong room as player {Number}!";
private const string LEAVE_LOG_TEMPLATE = "[{ID}] Player {Number} {Player} left pong room!";
private const string DIRECTION_LOG_TEMPLATE = "[{ID}] Player {Number} {player} moves paddle in direction: {direction}!";
2022-11-03 12:29:35 +01:00
public PongRoom(string id, ILogger logger) {
ID = id;
Logger = logger;
}
public PongPlayer? Player1 { get; private set; }
public PongPlayer? Player2 { get; private set; }
private PongGameState State = PongGameState.Initial;
2022-11-03 12:29:35 +01:00
public void Join(PongPlayer player) {
// TODO: synchronize this
if (Player1 is null) {
Player1 = player;
Logger.LogInformation(JOIN_LOG_TEMPLATE, ID, player, 1);
2022-11-03 12:29:35 +01:00
} else if (Player2 is null) {
Player2 = player;
Logger.LogInformation(JOIN_LOG_TEMPLATE, ID, player, 1);
2022-11-03 12:29:35 +01:00
} 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(LEAVE_LOG_TEMPLATE, ID, 1, player);
2022-11-03 12:29:35 +01:00
} else if (Player2 == player) {
Player2 = null;
Logger.LogInformation(LEAVE_LOG_TEMPLATE, ID, 2, player);
2022-11-03 12:29:35 +01:00
}
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}", ID, player1, player2);
State.Status = GameStatus.InProgress;
player1.Client.GameStateChanged(State.Status);
player2.Client.GameStateChanged(State.Status);
2022-11-03 12:29:35 +01:00
}
private void PauseGame() => State.Status = GameStatus.WaitingForPlayers;
private void CloseRoom() => State.Status = GameStatus.Finished;
2022-11-03 12:29:35 +01:00
public override string ToString() => $"[{ID}]";
public void MovePaddle(PongPlayer player, PongPaddleDirection direction) {
if (Player1 == player) {
State.P1Direction = direction;
Logger.LogInformation(DIRECTION_LOG_TEMPLATE, ID, 1, player, direction);
return;
} else if (Player2 == player) {
State.P2Direction = direction;
Logger.LogInformation(DIRECTION_LOG_TEMPLATE, ID, 2, player, direction);
return;
}
throw new InvalidOperationException("Player is not in this room, but moved! Assumably players room wasn't deleted.");
}
2022-11-03 12:29:35 +01:00
}