mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-30 21:13:24 +00:00
Add getClientIDForGame for consistent client IDs per game session (#3108)
## Description: - Add getClientIDForGame function to Auth.ts that generates and stores a consistent clientID per gameID using sessionStorage - Update HostLobbyModal to use getClientIDForGame for lobby creation - Update Matchmaking to use getClientIDForGame when joining games - Update PublicLobby to use getClientIDForGame when joining lobbies This enables reconnection support by ensuring the same clientID is used when rejoining a game session. ## 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: w.o.n --------- Co-authored-by: Evan <evanpelle@gmail.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -2,12 +2,16 @@ import { decodeJwt } from "jose";
|
||||
import { z } from "zod";
|
||||
import { TokenPayload, TokenPayloadSchema } from "../core/ApiSchemas";
|
||||
import { base64urlToUuid } from "../core/Base64";
|
||||
import { ID } from "../core/Schemas";
|
||||
import { generateID } from "../core/Util";
|
||||
import { getApiBase, getAudience } from "./Api";
|
||||
import { generateCryptoRandomUUID } from "./Utils";
|
||||
|
||||
export type UserAuth = { jwt: string; claims: TokenPayload } | false;
|
||||
|
||||
const PERSISTENT_ID_KEY = "player_persistent_id";
|
||||
const CLIENT_ID_KEY = "client_join_id";
|
||||
const CLIENT_GAME_ID_KEY = "client_join_game_id";
|
||||
|
||||
let __jwt: string | null = null;
|
||||
|
||||
@@ -209,6 +213,22 @@ export function getPersistentID(): string {
|
||||
return base64urlToUuid(sub);
|
||||
}
|
||||
|
||||
export function getClientIDForGame(gameID: string): string {
|
||||
const storedGameID = sessionStorage.getItem(CLIENT_GAME_ID_KEY);
|
||||
const storedClientID = sessionStorage.getItem(CLIENT_ID_KEY);
|
||||
if (
|
||||
storedGameID === gameID &&
|
||||
storedClientID &&
|
||||
ID.safeParse(storedClientID).success
|
||||
) {
|
||||
return storedClientID;
|
||||
}
|
||||
const newID = generateID();
|
||||
sessionStorage.setItem(CLIENT_GAME_ID_KEY, gameID);
|
||||
sessionStorage.setItem(CLIENT_ID_KEY, newID);
|
||||
return newID;
|
||||
}
|
||||
|
||||
// WARNING: DO NOT EXPOSE THIS ID
|
||||
function getPersistentIDFromLocalStorage(): string {
|
||||
// Try to get existing localStorage
|
||||
|
||||
@@ -21,6 +21,7 @@ import {
|
||||
isValidGameID,
|
||||
} from "../core/Schemas";
|
||||
import { generateID } from "../core/Util";
|
||||
import { getClientIDForGame } from "./Auth";
|
||||
import "./components/baseComponents/Modal";
|
||||
import { BaseModal } from "./components/BaseModal";
|
||||
import "./components/CopyButton";
|
||||
@@ -635,9 +636,10 @@ export class HostLobbyModal extends BaseModal {
|
||||
}
|
||||
|
||||
protected onOpen(): void {
|
||||
this.lobbyCreatorClientID = generateID();
|
||||
this.lobbyId = generateID();
|
||||
this.lobbyCreatorClientID = getClientIDForGame(this.lobbyId);
|
||||
|
||||
createLobby(this.lobbyCreatorClientID)
|
||||
createLobby(this.lobbyCreatorClientID, this.lobbyId)
|
||||
.then(async (lobby) => {
|
||||
this.lobbyId = lobby.gameID;
|
||||
if (!isValidGameID(this.lobbyId)) {
|
||||
@@ -1080,12 +1082,14 @@ export class HostLobbyModal extends BaseModal {
|
||||
}
|
||||
}
|
||||
|
||||
async function createLobby(creatorClientID: string): Promise<GameInfo> {
|
||||
async function createLobby(
|
||||
creatorClientID: string,
|
||||
gameID: string,
|
||||
): Promise<GameInfo> {
|
||||
const config = await getServerConfigFromClient();
|
||||
try {
|
||||
const id = generateID();
|
||||
const response = await fetch(
|
||||
`/${config.workerPath(id)}/api/create_game/${id}?creatorClientID=${encodeURIComponent(creatorClientID)}`,
|
||||
`/${config.workerPath(gameID)}/api/create_game/${gameID}?creatorClientID=${encodeURIComponent(creatorClientID)}`,
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
|
||||
@@ -17,7 +17,6 @@ import {
|
||||
GameRecordSchema,
|
||||
LobbyInfoEvent,
|
||||
} from "../core/Schemas";
|
||||
import { generateID } from "../core/Util";
|
||||
import { getServerConfigFromClient } from "../core/configuration/ConfigLoader";
|
||||
import {
|
||||
GameMapSize,
|
||||
@@ -26,8 +25,8 @@ import {
|
||||
HumansVsNations,
|
||||
} from "../core/game/Game";
|
||||
import { getApiBase } from "./Api";
|
||||
import { getClientIDForGame } from "./Auth";
|
||||
import { crazyGamesSDK } from "./CrazyGamesSDK";
|
||||
import { JoinLobbyEvent } from "./Main";
|
||||
import { terrainMapFileLoader } from "./TerrainMapFileLoader";
|
||||
import { BaseModal } from "./components/BaseModal";
|
||||
import "./components/CopyButton";
|
||||
@@ -346,7 +345,7 @@ export class JoinLobbyModal extends BaseModal {
|
||||
|
||||
private startTrackingLobby(lobbyId: string, lobbyInfo?: GameInfo) {
|
||||
this.currentLobbyId = lobbyId;
|
||||
this.currentClientID = generateID();
|
||||
this.currentClientID = getClientIDForGame(lobbyId);
|
||||
this.gameConfig = null;
|
||||
this.players = [];
|
||||
this.playerCount = 0;
|
||||
|
||||
@@ -2,9 +2,8 @@ import { html, LitElement } from "lit";
|
||||
import { customElement, query, state } from "lit/decorators.js";
|
||||
import { UserMeResponse } from "../core/ApiSchemas";
|
||||
import { getServerConfigFromClient } from "../core/configuration/ConfigLoader";
|
||||
import { generateID } from "../core/Util";
|
||||
import { getUserMe, hasLinkedAccount } from "./Api";
|
||||
import { getPlayToken } from "./Auth";
|
||||
import { getClientIDForGame, getPlayToken } from "./Auth";
|
||||
import { BaseModal } from "./components/BaseModal";
|
||||
import "./components/Difficulties";
|
||||
import "./components/PatternButton";
|
||||
@@ -231,7 +230,7 @@ export class MatchmakingModal extends BaseModal {
|
||||
new CustomEvent("join-lobby", {
|
||||
detail: {
|
||||
gameID: this.gameID,
|
||||
clientID: generateID(),
|
||||
clientID: getClientIDForGame(this.gameID),
|
||||
} as JoinLobbyEvent,
|
||||
bubbles: true,
|
||||
composed: true,
|
||||
|
||||
Reference in New Issue
Block a user