allow player to claim win/draw for abandoned games

This commit is contained in:
Nathaniel Tampus
2023-03-25 19:18:01 +08:00
parent 10ed00ebc0
commit d469cdff56
4 changed files with 166 additions and 11 deletions

View File

@@ -18,11 +18,13 @@ export async function joinLobby(this: Socket, gameCode: string) {
}
if (game.white && game.white?.id === this.request.session.user.id) {
game.white.connected = true;
game.white.disconnectedOn = undefined;
if (game.white.name !== this.request.session.user.name) {
game.white.name = this.request.session.user.name;
}
} else if (game.black && game.black?.id === this.request.session.user.id) {
game.black.connected = true;
game.black.disconnectedOn = undefined;
if (game.black.name !== this.request.session.user.name) {
game.black.name = this.request.session.user.name;
}
@@ -50,7 +52,7 @@ export async function joinLobby(this: Socket, gameCode: string) {
export async function leaveLobby(this: Socket, reason?: DisconnectReason, code?: string) {
if (this.rooms.size >= 3 && !code) {
console.log(`[WARNING] leaveLobby: room size is ${this.rooms.size}, aborting...`);
console.log(`leaveLobby: room size is ${this.rooms.size}, aborting...`);
return;
}
const game = activeGames.find(
@@ -68,8 +70,10 @@ export async function leaveLobby(this: Socket, reason?: DisconnectReason, code?:
}
if (game.black && game.black?.id === this.request.session.user.id) {
game.black.connected = false;
game.black.disconnectedOn = Date.now();
} else if (game.white && game.white?.id === this.request.session.user.id) {
game.white.connected = false;
game.white.disconnectedOn = Date.now();
}
// count sockets
@@ -94,6 +98,54 @@ export async function leaveLobby(this: Socket, reason?: DisconnectReason, code?:
await this.leave(code || Array.from(this.rooms)[1]);
}
export async function claimAbandoned(this: Socket, type: "win" | "draw") {
const game = activeGames.find((g) => g.code === Array.from(this.rooms)[1]);
if (
!game ||
!game.pgn ||
!game.white ||
!game.black ||
(game.white.id !== this.request.session.user.id &&
game.black.id !== this.request.session.user.id)
) {
console.log(`claimAbandoned: Game not found or user is not a player.`);
return;
}
if (
(game.white &&
game.white.id === this.request.session.user.id &&
(game.black?.connected ||
Date.now() - (game.black?.disconnectedOn as number) < 50000)) ||
(game.black &&
game.black.id === this.request.session.user.id &&
(game.white?.connected || Date.now() - (game.white?.disconnectedOn as number) < 50000))
) {
console.log(
`claimAbandoned: Invalid claim by ${this.request.session.user.name}. Opponent is still connected or disconnected less than 50 seconds ago.`
);
return;
}
game.reason = "abandoned";
if (type === "draw") {
game.winner = "draw";
} else if (game.white && game.white?.id === this.request.session.user.id) {
game.winner = "white";
} else if (game.black && game.black?.id === this.request.session.user.id) {
game.winner = "black";
}
const gameOver = {
reason: game.reason,
winnerName: this.request.session.user.name,
winnerSide: game.winner === "draw" ? undefined : game.winner
};
io.to(game.code as string).emit("gameOver", gameOver);
}
export async function getLatestGame(this: Socket) {
const game = activeGames.find((g) => g.code === Array.from(this.rooms)[1]);
if (game) this.emit("receivedLatestGame", game);
@@ -101,7 +153,7 @@ export async function getLatestGame(this: Socket) {
export async function sendMove(this: Socket, m: { from: string; to: string; promotion?: string }) {
const game = activeGames.find((g) => g.code === Array.from(this.rooms)[1]);
if (!game) return;
if (!game || game.reason || game.winner) return;
const chess = new Chess();
if (game.pgn) {
chess.loadPgn(game.pgn);
@@ -139,6 +191,7 @@ export async function sendMove(this: Socket, m: { from: string; to: string; prom
} else {
game.winner = "draw";
}
game.reason = reason;
io.to(game.code as string).emit("gameOver", { reason, winnerName, winnerSide });
}
if (newMove) {
@@ -182,7 +235,7 @@ export async function joinAsPlayer(this: Socket) {
side: "black"
});
} else {
console.log("[WARNING] attempted to join a game with already 2 players");
console.log("joinAsPlayer: attempted to join a game with already 2 players");
}
io.to(game.code as string).emit("receivedLatestGame", game);
}