Handle disconnects, add restart flow and UI fixes
Server: Make DisconnectedPlayer async, await hub notifications, add logging, and delay scheduled deletion (2s). Harden ScheduleGameDeletion with try/catch and only destroy/send GameDestroyed when game is not running or has no players. Client: Add restart-game flow — expose restartGame on OnlineGame, propagate event from GameEndedMenu (adds local restarted state and disables button), and hook restart handling + player disconnect on unmount in OnlineMode. Also conditionally show bot switch in GameCreationMenu and include replayGameCode in GameEnded interface. Remove automatic reconnect on SignalR connection. Overall: Improves robustness around player disconnects and adds a UI/logic path for restarting games.
This commit is contained in:
@@ -131,27 +131,28 @@ public class GameManager(IGameRepository gameRepository, IHubContext<GameHubSock
|
||||
}
|
||||
}
|
||||
|
||||
public Task DisconnectedPlayer(string playerConnectionId)
|
||||
public async Task DisconnectedPlayer(string playerConnectionId)
|
||||
{
|
||||
var game = gameRepository.GetOneByConnectionId(playerConnectionId);
|
||||
if (game == null || game.State == GameState.Ended)
|
||||
return Task.CompletedTask;
|
||||
return;
|
||||
|
||||
var player = game.GetPlayerByConnectionId(playerConnectionId);
|
||||
if (player == null)
|
||||
return Task.CompletedTask;
|
||||
return;
|
||||
|
||||
game.RemovePlayer(playerConnectionId);
|
||||
game.EndGame();
|
||||
hubContext.Clients.Group(game.Id).SendAsync("GameEnded", new
|
||||
|
||||
Console.WriteLine("Play has Disconnected");
|
||||
|
||||
await hubContext.Clients.Group(game.Id).SendAsync("GameEnded", new
|
||||
{
|
||||
Method = "PlayerDisconnected",
|
||||
Player = player
|
||||
});
|
||||
|
||||
ScheduleGameDeletion(game.Id, TimeSpan.FromSeconds(0));
|
||||
|
||||
return Task.CompletedTask;
|
||||
ScheduleGameDeletion(game.Id, TimeSpan.FromSeconds(2));
|
||||
}
|
||||
|
||||
private static int[][] ConvertField(int[,]? field)
|
||||
@@ -180,14 +181,25 @@ public class GameManager(IGameRepository gameRepository, IHubContext<GameHubSock
|
||||
{
|
||||
_ = Task.Run(async () =>
|
||||
{
|
||||
await Task.Delay(delay);
|
||||
|
||||
var g = gameRepository.GetOne(gameId);
|
||||
if (g != null && g.State != GameState.Running)
|
||||
try
|
||||
{
|
||||
gameRepository.Destroy(gameId);
|
||||
await Task.Delay(delay);
|
||||
|
||||
await hubContext.Clients.Group(gameId).SendAsync("GameDestroyed");
|
||||
var g = gameRepository.GetOne(gameId);
|
||||
if (g == null)
|
||||
return;
|
||||
|
||||
if (g.State != GameState.Running || g.Players.Count == 0)
|
||||
{
|
||||
gameRepository.Destroy(gameId);
|
||||
await hubContext.Clients.Group(gameId).SendAsync("GameDestroyed");
|
||||
}
|
||||
|
||||
Console.WriteLine($"Scheduled deletion of game {gameId} executed. {gameRepository.GetAll().Count}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Error deleting game {gameId}: {ex}");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user