-
Pick your color:
-
- {["orange", "red", "white", "blue"].map((c) => (
-
{
- if (!sendJsonMessage) return;
- sendJsonMessage({ type: "set", field: "color", value: c[0].toUpperCase() });
- }}
- >
-
-
- ))}
+ {/* If this is the local player and they haven't picked a color, show a picker */}
+ {player.local && player.color === "unassigned" && (
+
+
Pick your color:
+
+ {["orange", "red", "white", "blue"].map((c) => (
+
{
+ if (!sendJsonMessage) return;
+ sendJsonMessage({ type: "set", field: "color", value: c[0].toUpperCase() });
+ }}
+ >
+
+
+ ))}
+
-
- )}
- >
- ) : player.name && player.live && player.has_media === false ? (
-
- 💬 Chat Only
-
- ) : (
-
- )}
-
- ))}
+ )}
+ >
+ ) : player.name && player.live && player.has_media === false ? (
+
+ 💬 Chat Only
+
+ ) : (
+
+ )}
+
+ );
+ })}
diff --git a/server/routes/games.ts b/server/routes/games.ts
index ddabf0a..9b7b381 100755
--- a/server/routes/games.ts
+++ b/server/routes/games.ts
@@ -1222,13 +1222,13 @@ const setPlayerName = (game: Game, session: Session, name: string): string | und
message = `${name} has rejoined the lobby.`;
}
session.name = name;
- if (session.ws && game.id in audio && session.id in audio[game.id]) {
- webrtcPart(audio[game.id], session);
+ if (session.ws && game.id in audio && session.id in audio[game.id]!) {
+ webrtcPart(audio[game.id]!, session);
}
} else {
- message = `${session.name} has changed their name to ${name}.`;
+ message = `${session.name} hs changed their name to ${name}.`;
if (session.ws && game.id in audio) {
- webrtcPart(audio[game.id], session);
+ webrtcPart(audio[game.id]!, session);
}
}
}
@@ -1245,7 +1245,7 @@ const setPlayerName = (game: Game, session: Session, name: string): string | und
}
if (session.ws && session.hasAudio) {
- webrtcJoin(audio[game.id], session);
+ webrtcJoin(audio[game.id]!, session);
}
console.log(`${info}: ${message}`);
addChatMessage(game, null, message);
@@ -3726,7 +3726,7 @@ router.ws("/ws/:id", async (ws, req) => {
/* ignore logging errors */
}
if (!(gameId in audio)) {
- audio[gameId] = {}; /* List of peer sockets using session.id as index. */
+ audio[gameId] = {}; /* List of peer sockets using session.id as index. */
console.log(`${short}: Game ${gameId} - New Game Audio`);
} else {
console.log(`${short}: Game ${gameId} - Already has Audio`);
@@ -3822,7 +3822,7 @@ router.ws("/ws/:id", async (ws, req) => {
/* Cleanup any voice channels */
if (gameId in audio) {
try {
- webrtcPart(audio[gameId], session);
+ webrtcPart(audio[gameId]!, session);
} catch (e) {
console.warn(`${short}: Error during part():`, e);
}
@@ -3932,7 +3932,7 @@ router.ws("/ws/:id", async (ws, req) => {
// Clean up peer from audio registry before replacing WebSocket
if (gameId in audio) {
try {
- webrtcPart(audio[gameId], session);
+ webrtcPart(audio[gameId]!, session);
console.log(`${short}: Cleaned up peer ${session.name} from audio registry during reconnection`);
} catch (e) {
console.warn(`${short}: Error cleaning up peer during reconnection:`, e);
@@ -3968,11 +3968,11 @@ router.ws("/ws/:id", async (ws, req) => {
// Accept either legacy `config`, newer `data`, or flat payloads where
// the client sent fields at the top level (normalizeIncoming will
// populate `data` with the parsed object in that case).
- webrtcJoin(audio[gameId], session);
+ webrtcJoin(audio[gameId]!, session);
break;
case "part":
- webrtcPart(audio[gameId], session);
+ webrtcPart(audio[gameId]!, session);
break;
case "relayICECandidate":
diff --git a/server/routes/webrtc-signaling.ts b/server/routes/webrtc-signaling.ts
index ef72dbb..3fab2aa 100644
--- a/server/routes/webrtc-signaling.ts
+++ b/server/routes/webrtc-signaling.ts
@@ -10,7 +10,13 @@
import { Session } from "./games/types";
-export const audio: Record
= {};
+interface Peer {
+ ws: any;
+ name: string;
+}
+
+/* Map of session => peer_id => peer */
+export const audio: Record> = {};
// Default send helper used when caller doesn't provide a safeSend implementation.
const defaultSend = (targetOrSession: any, message: any): boolean => {
@@ -29,7 +35,7 @@ const defaultSend = (targetOrSession: any, message: any): boolean => {
}
};
-export const join = (peers: any, session: any): void => {
+export const join = (peers: Record, session: Session): void => {
const send = defaultSend;
const ws = session.ws;
@@ -45,18 +51,19 @@ export const join = (peers: any, session: any): void => {
console.log(`${session.short}: <- join - ${session.name}`);
+ const peer = peers[session.id];
// Use session.id as the canonical peer key
- if (session.id in peers) {
+ if (peer) {
console.log(`${session.short}:${session.id} - Already joined to Audio, updating WebSocket reference.`);
try {
- const prev = peers[session.id] && peers[session.id].ws;
+ const prev = peer.ws;
if (prev && prev._pingInterval) {
clearInterval(prev._pingInterval);
}
} catch (e) {
/* ignore */
}
- peers[session.id].ws = ws;
+ peer.ws = ws;
send(ws, {
type: "join_status",
@@ -72,7 +79,7 @@ export const join = (peers: any, session: any): void => {
type: "addPeer",
data: {
peer_id: peerId,
- peer_name: peers[peerId].name || peerId,
+ peer_name: peers[peerId]!.name,
should_create_offer: true,
},
});
@@ -82,7 +89,7 @@ export const join = (peers: any, session: any): void => {
for (const peerId in peers) {
if (peerId === session.id) continue;
- send(peers[peerId].ws, {
+ send(peers[peerId]!.ws, {
type: "addPeer",
data: {
peer_id: session.id,
@@ -97,7 +104,7 @@ export const join = (peers: any, session: any): void => {
for (let peerId in peers) {
// notify existing peers about the new client
- send(peers[peerId].ws, {
+ send(peers[peerId]!.ws, {
type: "addPeer",
data: {
peer_id: session.id,
@@ -111,7 +118,7 @@ export const join = (peers: any, session: any): void => {
type: "addPeer",
data: {
peer_id: peerId,
- peer_name: peers[peerId].name || peerId,
+ peer_name: peers[peerId]!.name || peerId,
should_create_offer: true,
},
});
@@ -130,7 +137,7 @@ export const join = (peers: any, session: any): void => {
});
};
-export const part = (peers: any, session: any): void => {
+export const part = (peers: Record, session: Session): void => {
const ws = session.ws;
const send = defaultSend;
@@ -151,7 +158,7 @@ export const part = (peers: any, session: any): void => {
delete peers[session.id];
for (let peerId in peers) {
- send(peers[peerId].ws, {
+ send(peers[peerId]!.ws, {
type: "removePeer",
data: {
peer_id: session.id,
@@ -162,7 +169,7 @@ export const part = (peers: any, session: any): void => {
type: "removePeer",
data: {
peer_id: peerId,
- peer_name: peers[peerId].name || peerId,
+ peer_name: peers[peerId]!.name || peerId,
},
});
}
@@ -195,8 +202,8 @@ export const handleRelayICECandidate = (gameId: string, cfg: any, session: Sessi
},
});
- if (peer_id in audio[gameId]) {
- const target = audio[gameId][peer_id] as any;
+ if (peer_id in audio[gameId]!) {
+ const target = audio[gameId]![peer_id] as any;
if (!target || !target.ws) {
console.warn(`${session.id}:${gameId} relayICECandidate - target ${peer_id} has no ws`);
} else if (!send(target.ws, message)) {
@@ -236,8 +243,8 @@ export const handleRelaySessionDescription = (gameId: string, cfg: any, session:
session_description,
},
});
- if (peer_id in audio[gameId]) {
- const target = audio[gameId][peer_id] as any;
+ if (peer_id in audio[gameId]!) {
+ const target = audio[gameId]![peer_id] as any;
if (!target || !target.ws) {
console.warn(`${session.id}:${gameId} relaySessionDescription - target ${peer_id} has no ws`);
} else if (!send(target.ws, message)) {