improve game websockt (re)connection (#2584)

Previously, the connection and reconnection logic were identical in
Worker.ts, so clients would need to be re-authorized for cosmetics etc
even when reconnecting. Now, on reconnect, Worker.ts only does
authentication - verifying the jwt is valid.

This will allow clients to require a valid turnstile token when first
connecting, and not when reconnecting after a broken ws connection.

## Please complete the following:

- [x] I have added screenshots for all UI updates
- [x] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [x] I have added relevant tests to the test directory
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced

## Please put your Discord username so you can be contacted if a bug or
regression is found:

evan
This commit is contained in:
Evan
2025-12-08 14:07:07 -08:00
committed by GitHub
parent cb4cf091ff
commit 075c232d8a
7 changed files with 158 additions and 56 deletions
+16 -11
View File
@@ -79,9 +79,17 @@ export function joinLobby(
const transport = new Transport(lobbyConfig, eventBus);
let hasJoined = false;
const onconnect = () => {
console.log(`Joined game lobby ${lobbyConfig.gameID}`);
transport.joinGame(0);
if (hasJoined) {
console.log("rejoining game");
transport.rejoinGame(0);
} else {
hasJoined = true;
console.log(`Joining game lobby ${lobbyConfig.gameID}`);
transport.joinGame();
}
};
let terrainLoad: Promise<TerrainMapData> | null = null;
@@ -198,7 +206,6 @@ export class ClientGameRunner {
private isActive = false;
private turnsSeen = 0;
private hasJoined = false;
private lastMousePosition: { x: number; y: number } | null = null;
private lastMessageTime: number = 0;
@@ -322,13 +329,12 @@ export class ClientGameRunner {
const onconnect = () => {
console.log("Connected to game server!");
this.transport.joinGame(this.turnsSeen);
this.transport.rejoinGame(this.turnsSeen);
};
const onmessage = (message: ServerMessage) => {
this.lastMessageTime = Date.now();
if (message.type === "start") {
this.hasJoined = true;
console.log("starting game!");
console.log("starting game! in client game runner");
if (this.gameView.config().isRandomSpawn()) {
const goToPlayer = () => {
@@ -403,10 +409,6 @@ export class ClientGameRunner {
);
}
if (message.type === "turn") {
if (!this.hasJoined) {
this.transport.joinGame(0);
return;
}
// Track when we receive the turn to calculate delay
const now = Date.now();
if (this.lastTickReceiveTime > 0) {
@@ -425,7 +427,10 @@ export class ClientGameRunner {
}
}
};
this.transport.connect(onconnect, onmessage);
this.transport.updateCallback(onconnect, onmessage);
console.log("sending join game");
// Rejoin game from the start so we don't miss any turns.
this.transport.rejoinGame(0);
}
public stop() {