feat(games): allow admins to play against themselves
Some checks failed
Deploy to Production / test (push) Failing after 35s
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:
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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),
|
||||||
|
|||||||
Reference in New Issue
Block a user