fix(platform): isolate game host leases

This commit is contained in:
2026-09-05 07:48:23 +08:00
parent 30547f6a54
commit 471e2e9479
5 changed files with 237 additions and 33 deletions
@@ -5,8 +5,9 @@ import type {
GameServerMessage,
PlatformToGameEvent,
} from '../contracts/index.ts';
import { Route } from '../../core/constants.ts';
const RESERVED_ROUTES = new Set(['platform', 'agent', 'room']);
const RESERVED_ROUTES = new Set<string>(Object.values(Route));
const GAME_SESSION_OPEN_FAULT_BRAND = Symbol.for(
'youle.framework.sdk.GameSessionOpenFault',
);
@@ -81,10 +82,7 @@ export function isGameSessionOpenFault(value: unknown): value is GameSessionOpen
export function assertGameEntry(entry: GameEntry): void {
assertNonEmptyText(entry.key, 'key');
assertGameId(entry.gameId);
assertNonEmptyText(entry.route, 'route');
if (RESERVED_ROUTES.has(entry.route)) {
throw new Error(`GameEntry reserved route: ${entry.route}`);
}
assertGameRoute(entry.route);
if (typeof entry.resolveSeatCount !== 'function') {
throw new Error('GameEntry resolveSeatCount must be a function');
}
@@ -103,6 +101,14 @@ export function assertGameEntry(entry: GameEntry): void {
}
}
/** The single GameEntry route admission check shared by runtime adapters. */
export function assertGameRoute(route: unknown): asserts route is string {
assertNonEmptyText(route, 'route');
if (RESERVED_ROUTES.has(route)) {
throw new Error(`GameEntry reserved route: ${route}`);
}
}
/** Owns one isolated game module for one room at a time. */
export class GameSessionHost {
private module: GameModule | undefined;