rooms
This commit is contained in:
118
src/rooms.ts
118
src/rooms.ts
@@ -0,0 +1,118 @@
|
|||||||
|
export interface RoomSettings {
|
||||||
|
teamMode: boolean;
|
||||||
|
numTeams: number;
|
||||||
|
teamNames: string[];
|
||||||
|
allowRebuzz: boolean;
|
||||||
|
buzzerLockout: boolean;
|
||||||
|
showOrder: boolean;
|
||||||
|
pointsCorrect: number;
|
||||||
|
pointsIncorrect: number;
|
||||||
|
pointsNeg: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Player {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
teamIndex: number | null;
|
||||||
|
score: number;
|
||||||
|
ws: ServerWebSocket<unknown> | null;
|
||||||
|
isConnected: boolean;
|
||||||
|
joinedAt: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface BuzzerState {
|
||||||
|
roundOpen: boolean;
|
||||||
|
active: boolean;
|
||||||
|
buzzOrder: string[];
|
||||||
|
buzzTimes: Map<string, number>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Room {
|
||||||
|
id: string;
|
||||||
|
moderatorSecret: string;
|
||||||
|
modWs: ServerWebSocket<unknown> | null;
|
||||||
|
settings: RoomSettings;
|
||||||
|
players: Map<string, Player>;
|
||||||
|
buzzerState: BuzzerState;
|
||||||
|
locked: boolean;
|
||||||
|
createdAt: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
import type { ServerWebSocket } from "bun";
|
||||||
|
|
||||||
|
export const rooms = new Map<string, Room>();
|
||||||
|
export const wsToPlayer = new Map<ServerWebSocket<unknown>, { roomId: string; playerId: string }>();
|
||||||
|
|
||||||
|
export function generateId(len = 8): string {
|
||||||
|
const chars = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789";
|
||||||
|
let out = "";
|
||||||
|
for (let i = 0; i < len; i++) out += chars[Math.floor(Math.random() * chars.length)];
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function defaultSettings(): RoomSettings {
|
||||||
|
return {
|
||||||
|
teamMode: false,
|
||||||
|
numTeams: 2,
|
||||||
|
teamNames: ["ALPHA", "BETA", "GAMMA", "DELTA", "EPSILON", "ZETA", "ETA", "THETA"],
|
||||||
|
allowRebuzz: false,
|
||||||
|
buzzerLockout: true,
|
||||||
|
showOrder: true,
|
||||||
|
pointsCorrect: 100,
|
||||||
|
pointsIncorrect: 0,
|
||||||
|
pointsNeg: false,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function freshBuzzerState(): BuzzerState {
|
||||||
|
return { roundOpen: false, active: false, buzzOrder: [], buzzTimes: new Map() };
|
||||||
|
}
|
||||||
|
|
||||||
|
export function sanitize(str: unknown, maxLen = 32): string {
|
||||||
|
return String(str ?? "")
|
||||||
|
.trim()
|
||||||
|
.replace(/[<>"'`]/g, "")
|
||||||
|
.slice(0, maxLen);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getPublicRoom(room: Room) {
|
||||||
|
return {
|
||||||
|
id: room.id,
|
||||||
|
settings: room.settings,
|
||||||
|
locked: room.locked,
|
||||||
|
modOnline: room.modWs !== null,
|
||||||
|
buzzerState: {
|
||||||
|
roundOpen: room.buzzerState.roundOpen,
|
||||||
|
active: room.buzzerState.active,
|
||||||
|
buzzOrder: room.buzzerState.buzzOrder,
|
||||||
|
},
|
||||||
|
players: Array.from(room.players.values()).map((p) => ({
|
||||||
|
id: p.id,
|
||||||
|
name: p.name,
|
||||||
|
teamIndex: p.teamIndex,
|
||||||
|
score: p.score,
|
||||||
|
isConnected: p.isConnected,
|
||||||
|
})),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function broadcastToRoom(
|
||||||
|
room: Room,
|
||||||
|
msg: object,
|
||||||
|
exclude?: ServerWebSocket<unknown>
|
||||||
|
) {
|
||||||
|
const data = JSON.stringify(msg);
|
||||||
|
for (const p of room.players.values()) {
|
||||||
|
if (p.ws && p.isConnected && p.ws !== exclude) {
|
||||||
|
try { p.ws.send(data); } catch {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (room.modWs && room.modWs !== exclude) {
|
||||||
|
try { room.modWs.send(data); } catch {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function sendToMod(room: Room, msg: object) {
|
||||||
|
if (!room.modWs) return;
|
||||||
|
try { room.modWs.send(JSON.stringify(msg)); } catch {}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user