From b43c6210beaac4e2070901e37eb33c51b89c9b7f Mon Sep 17 00:00:00 2001 From: doomtube Date: Thu, 8 Jan 2026 23:28:04 -0500 Subject: [PATCH] fixes lol --- .../lib/components/ChessGameOverlay.svelte | 38 +++++++++++++++++++ nakama/go-modules/main.go | 18 +++++++++ 2 files changed, 56 insertions(+) diff --git a/frontend/src/lib/components/ChessGameOverlay.svelte b/frontend/src/lib/components/ChessGameOverlay.svelte index 67fa89c..d7ef70c 100644 --- a/frontend/src/lib/components/ChessGameOverlay.svelte +++ b/frontend/src/lib/components/ChessGameOverlay.svelte @@ -181,6 +181,11 @@ game = new Chess(convertChess960Fen(payload.fen)); } + // Restore move history if rejoining an in-progress game + if (payload.moveHistory && payload.moveHistory.length > 0) { + moveHistory = payload.moveHistory; + } + gamesOverlay.setMode('playing'); gamesOverlay.updateState({ positionId: payload.positionId, @@ -202,6 +207,11 @@ game = new Chess(convertChess960Fen(payload.fen)); } + // Restore move history for spectators + if (payload.moveHistory && payload.moveHistory.length > 0) { + moveHistory = payload.moveHistory; + } + gamesOverlay.setMode('spectating'); gamesOverlay.updateState({ positionId: payload.positionId, @@ -213,6 +223,32 @@ blackName: payload.blackName }); + updateBoardDisplay(); + } else if (payload.status === 'finished') { + // Rejoining a finished game + const session = nakama.getSession(); + myColor = payload.whiteId === session?.user_id ? 'w' : 'b'; + + if (Chess && payload.fen) { + game = new Chess(convertChess960Fen(payload.fen)); + } + + if (payload.moveHistory && payload.moveHistory.length > 0) { + moveHistory = payload.moveHistory; + } + + gamesOverlay.setMode('finished'); + gamesOverlay.updateState({ + positionId: payload.positionId, + fen: payload.fen, + whiteId: payload.whiteId, + blackId: payload.blackId, + whiteName: payload.whiteName, + blackName: payload.blackName, + result: payload.result, + gameOver: payload.gameOver + }); + updateBoardDisplay(); } } @@ -499,6 +535,8 @@ return myColor === 'b' ? 'You win!' : 'You lose'; } else if (result === 'timeout') { return reason || 'Match timed out'; + } else if (result === 'cancelled') { + return reason || 'Match cancelled'; } return `Draw${reason ? ` (${reason})` : ''}`; } diff --git a/nakama/go-modules/main.go b/nakama/go-modules/main.go index a244a46..7df31e5 100644 --- a/nakama/go-modules/main.go +++ b/nakama/go-modules/main.go @@ -720,6 +720,24 @@ func (m *ChessMatch) MatchSignal(ctx context.Context, logger runtime.Logger, db if data == "cancel" { logger.Info("Match cancelled via signal") s.PendingCancel = true + + // Broadcast cancellation to any connected clients + msg, _ := json.Marshal(map[string]interface{}{ + "result": "cancelled", + "reason": "Challenge cancelled by creator", + }) + dispatcher.BroadcastMessage(OpCodeGameOver, msg, nil, nil, true) + + // Update match label to cancelled status so it's not detected as active + label := MatchLabel{ + Game: "chess960", + Status: "cancelled", + White: s.WhiteName, + WhiteID: s.WhiteID, + PositionID: s.PositionID, + } + labelJSON, _ := json.Marshal(label) + dispatcher.MatchLabelUpdate(string(labelJSON)) } return s, ""