feat(games): allow admins to play against themselves
Some checks failed
Deploy to Production / test (push) Failing after 35s

Skip the duplicate-player check when the joining user has the admin
role, so admins can test games solo by joining their own room as both
players.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
syntaxbullet
2026-04-02 14:24:23 +02:00
parent 0dadc82f84
commit 87b66cd65d
3 changed files with 5 additions and 3 deletions

View File

@@ -33,7 +33,7 @@ export class RoomManager {
return { ok: true, roomId: id }; return { ok: true, roomId: id };
} }
joinRoom(roomId: string, playerId: string, as: "player" | "spectator"): JoinResult { joinRoom(roomId: string, playerId: string, as: "player" | "spectator", role?: string): JoinResult {
const room = this.rooms.get(roomId); const room = this.rooms.get(roomId);
if (!room) return { ok: false, error: "Room not found" }; if (!room) return { ok: false, error: "Room not found" };
@@ -46,7 +46,7 @@ export class RoomManager {
const plugin = gameRegistry.get(room.gameSlug)!; const plugin = gameRegistry.get(room.gameSlug)!;
if (room.players.length >= plugin.maxPlayers) return { ok: false, error: "Room is full" }; if (room.players.length >= plugin.maxPlayers) return { ok: false, error: "Room is full" };
if (room.players.includes(playerId)) return { ok: true, started: room.status === "playing" }; if (room.players.includes(playerId) && role !== "admin") return { ok: true, started: room.status === "playing" };
room.players.push(playerId); room.players.push(playerId);

View File

@@ -7,6 +7,7 @@ export const roomManager = new RoomManager();
interface WsContext { interface WsContext {
playerId: string; playerId: string;
username: string; username: string;
role: string;
send: (data: string) => void; send: (data: string) => void;
subscribe: (channel: string) => void; subscribe: (channel: string) => void;
unsubscribe: (channel: string) => void; unsubscribe: (channel: string) => void;
@@ -29,7 +30,7 @@ export function handleGameMessage(msg: GameWsClientMessage, ctx: WsContext): voi
} }
case "JOIN_ROOM": { case "JOIN_ROOM": {
const result = roomManager.joinRoom(msg.roomId, ctx.playerId, msg.as); const result = roomManager.joinRoom(msg.roomId, ctx.playerId, msg.as, ctx.role);
if (!result.ok) { if (!result.ok) {
ctx.send(JSON.stringify({ type: "ERROR", message: result.error })); ctx.send(JSON.stringify({ type: "ERROR", message: result.error }));
return; return;

View File

@@ -202,6 +202,7 @@ export async function createWebServer(config: WebServerConfig = {}): Promise<Web
handleGameMessage(parsed.data as any, { handleGameMessage(parsed.data as any, {
playerId: sessionData.discordId, playerId: sessionData.discordId,
username: sessionData.username, username: sessionData.username,
role: sessionData.role,
send: (data) => ws.send(data), send: (data) => ws.send(data),
subscribe: (channel) => ws.subscribe(channel), subscribe: (channel) => ws.subscribe(channel),
unsubscribe: (channel) => ws.unsubscribe(channel), unsubscribe: (channel) => ws.unsubscribe(channel),