Try to reconnect before showing a communication error

This commit is contained in:
Andrio Celos 2023-11-21 22:49:24 +11:00
parent 46d5aed44c
commit 97a459c748
4 changed files with 42 additions and 16 deletions

View File

@ -340,6 +340,9 @@ class Board {
resize(grid?: Space[][]) {
if (grid) this.grid = grid;
if (this.cells.length == this.grid.length && this.cells[0].length == this.grid[0].length)
return; // Reconnected and board size did not change.
clearChildren(this.table);
this.cells.splice(0);
this.highlightedCells.splice(0);
@ -422,7 +425,6 @@ class Board {
}
refresh() {
this.clearHighlight();
this.clearInkAnimations();
for (let x = 0; x < this.grid.length; x++) {
for (let y = 0; y < this.grid[x].length; y++) {

View File

@ -23,7 +23,8 @@ let currentGame: {
/** The user's player data, or null if they are spectating. */
me: PlayerData | null,
/** The WebSocket used for receiving game events, or null if not yet connected. */
webSocket: WebSocket | null
webSocket: WebSocket | null,
reconnecting?: boolean
} | null = null;
let enterGameTimeout: number | null = null;

View File

@ -122,6 +122,7 @@ function initSpectator() {
spectatorRow.hidden = false;
flipButton.hidden = false;
gameButtonsContainer.hidden = false;
board.autoHighlight = false;
showPage('game');
}
@ -795,13 +796,12 @@ function populateShowDeck(deck: Deck) {
/** Handles an update to the player's hand and/or deck during a game. */
function updateHandAndDeck(playerData: PlayerData) {
handButtons.clear();
const hand = playerData.hand!;
populateShowDeck(playerData.deck!);
for (const button of showDeckButtons) {
const li = button.buttonElement.parentElement!;
if (playerData.hand!.find(c => c.number == button.card.number))
if (hand.find(c => c.number == button.card.number))
li.className = 'inHand';
else if (playerData.cardsUsed.includes(button.card.number))
li.className = 'used';
@ -810,7 +810,20 @@ function updateHandAndDeck(playerData: PlayerData) {
}
if (!currentGame?.me) return;
currentGame.me.hand = playerData.hand!.map(Card.fromJson);
if (handButtons.entries.length == 4 && hand.length == 4) {
let handIsSame = true;
for (let i = 0; i < 4; i++) {
if ((<CardButton> handButtons.entries[i].button).card.number != hand[i].number) {
handIsSame = false;
break;
}
}
if (handIsSame) return; // The player's hand has not changed after reconnecting to the game.
}
currentGame.me.hand = hand.map(Card.fromJson);
handButtons.clear();
board.autoHighlight = false;
for (let i = 0; i < currentGame.me.hand.length; i++) {
const card = currentGame.me.hand[i];
const button = new CardButton(card);

View File

@ -113,7 +113,10 @@ function onGameSettingsChange() {
function onGameStateChange(game: any, playerData: PlayerData | null) {
if (currentGame == null)
throw new Error('currentGame is null');
clearPlayContainers();
const isSameTurnReconnect = currentGame.game.state == GameState.Ongoing && currentGame.game.turnNumber == turnNumberLabel.turnNumber;
if (!isSameTurnReconnect) clearPlayContainers();
currentGame.game.state = game.state;
if (game.board) {
@ -122,9 +125,10 @@ function onGameStateChange(game: any, playerData: PlayerData | null) {
else gamePage.classList.remove('boardFlipped');
board.resize(game.board);
board.startSpaces = game.startSpaces;
board.refresh();
if (!isSameTurnReconnect) board.refresh();
}
loadPlayers(game.players);
if (currentGame.game.state != GameState.Ongoing || currentGame.game.turnNumber != turnNumberLabel.turnNumber)
loadPlayers(game.players);
gamePage.dataset.myPlayerIndex = playerData ? playerData.playerIndex.toString() : '';
gamePage.dataset.uiBaseColourIsSpecialColour = (userConfig.colourLock
? (playerData?.playerIndex ?? 0) != 1
@ -162,7 +166,6 @@ function onGameStateChange(game: any, playerData: PlayerData | null) {
case GameState.Ongoing:
case GameState.GameEnded:
case GameState.SetEnded:
board.autoHighlight = false;
redrawModal.hidden = true;
if (playerData) {
updateHandAndDeck(playerData);
@ -183,15 +186,17 @@ function onGameStateChange(game: any, playerData: PlayerData | null) {
timeLabel.paused = false;
break;
case GameState.Ongoing:
for (let i = 0; i < currentGame.game.players.length; i++)
showWaiting(i);
if (currentGame.me) setConfirmLeavingGame();
turnNumberLabel.turnNumber = game.turnNumber;
board.autoHighlight = true;
canPlay = currentGame.me != null && !currentGame.game.players[currentGame.me.playerIndex].isReady;
timeLabel.faded = !canPlay;
timeLabel.paused = false;
resetPlayControls();
if (!isSameTurnReconnect) {
for (let i = 0; i < currentGame.game.players.length; i++)
showWaiting(i);
resetPlayControls();
}
break;
case GameState.GameEnded:
case GameState.SetEnded:
@ -268,7 +273,8 @@ function setupWebSocket(gameID: string) {
goalWinCount: payload.data.goalWinCount,
},
me: payload.playerData,
webSocket: webSocket
webSocket: webSocket,
reconnecting: false
};
updateColours();
@ -419,8 +425,12 @@ function setupWebSocket(gameID: string) {
webSocket.addEventListener('close', webSocket_close);
}
function webSocket_close() {
communicationError();
function webSocket_close(e: CloseEvent) {
if (currentGame == null || currentGame.reconnecting || (e.code != 1005 && e.code != 1006))
communicationError();
else
// Try to automatically reconnect.
setupWebSocket(currentGame.id);
}
function setConfirmLeavingGame() {