Skip to content

Commit 77e6f2f

Browse files
committed
Make timing more lenient
1 parent 495cf4c commit 77e6f2f

File tree

1 file changed

+55
-24
lines changed

1 file changed

+55
-24
lines changed

cardgame.js

Lines changed: 55 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ function sanitizeHtml(str) {
2121
.replace(/>/g, '>');
2222
}
2323

24+
async function wait(ms) {
25+
return new Promise(resolve => setTimeout(resolve, ms));
26+
}
27+
2428
// Add card sanitization helper
2529
function sanitizeCard(card) {
2630
return {
@@ -47,7 +51,7 @@ app.use(sessionParser);
4751

4852
// In-memory storage (intentionally vulnerable)
4953
const users = new Map(); // username -> {password, cards}
50-
const activeConnections = new Map(); // username -> WebSocket
54+
const activeConnections = new Map(); // username -> Set<WebSocket>
5155

5256
// Card generation utilities
5357
function generateUniqueCard(username) {
@@ -85,16 +89,20 @@ function checkForDuplication(username) {
8589

8690
// Broadcast active players to all connected clients
8791
function broadcastActivePlayers() {
92+
// Get unique active players
8893
const activePlayers = Array.from(activeConnections.keys());
8994
const message = JSON.stringify({
9095
type: 'activePlayers',
9196
players: activePlayers.filter(player => isValidUsername(player))
9297
});
9398

94-
activeConnections.forEach(ws => {
95-
if (ws.readyState === WebSocket.OPEN) {
96-
ws.send(message);
97-
}
99+
// Send to all connections
100+
activeConnections.forEach((connections, username) => {
101+
connections.forEach(ws => {
102+
if (ws.readyState === WebSocket.OPEN) {
103+
ws.send(message);
104+
}
105+
});
98106
});
99107
}
100108

@@ -191,7 +199,13 @@ wss.on('connection', (ws, req) => {
191199
return;
192200
}
193201

194-
activeConnections.set(username, ws);
202+
// Create a Set for this user's connections if it doesn't exist
203+
if (!activeConnections.has(username)) {
204+
activeConnections.set(username, new Set());
205+
}
206+
207+
// Add this connection to the user's set of connections
208+
activeConnections.get(username).add(ws);
195209
broadcastActivePlayers();
196210

197211
ws.on('message', (message) => {
@@ -210,7 +224,15 @@ wss.on('connection', (ws, req) => {
210224
});
211225

212226
ws.on('close', () => {
213-
activeConnections.delete(username);
227+
// Remove this specific connection
228+
const userConnections = activeConnections.get(username);
229+
if (userConnections) {
230+
userConnections.delete(ws);
231+
// Only remove the user from activeConnections if they have no connections left
232+
if (userConnections.size === 0) {
233+
activeConnections.delete(username);
234+
}
235+
}
214236
broadcastActivePlayers();
215237
});
216238
});
@@ -231,39 +253,48 @@ async function handleGiftCards(username, data, ws) {
231253
}
232254

233255
// Simulate network delay
234-
await new Promise(resolve => setTimeout(resolve, 100));
256+
await wait(300);
235257

236258
const giftedCards = cardIds
237259
.map(cardId => fromUser.cards.find(card => card.id === cardId))
238260
.filter(card => card)
239261
.map(sanitizeCard);
240262

241263
// Simulate more network delay
242-
await new Promise(resolve => setTimeout(resolve, 100));
264+
await wait(300);
243265

244266
giftedCards.forEach(card => {
245267
fromUser.cards = fromUser.cards.filter(c => c.id !== card.id);
246268
});
247269

248270
toUserData.cards.push(...giftedCards);
249271

250-
const fromWs = activeConnections.get(username);
251-
const toWs = activeConnections.get(toUser);
252-
253-
if (fromWs && fromWs.readyState === WebSocket.OPEN) {
254-
fromWs.send(JSON.stringify({
255-
type: 'giftComplete',
256-
inventory: fromUser.cards.map(sanitizeCard)
257-
}));
272+
// Send updates to all connections for both users
273+
const fromConnections = activeConnections.get(username);
274+
const toConnections = activeConnections.get(toUser);
275+
276+
if (fromConnections) {
277+
fromConnections.forEach(conn => {
278+
if (conn.readyState === WebSocket.OPEN) {
279+
conn.send(JSON.stringify({
280+
type: 'giftComplete',
281+
inventory: fromUser.cards.map(sanitizeCard)
282+
}));
283+
}
284+
});
258285
}
259286

260-
if (toWs && toWs.readyState === WebSocket.OPEN) {
261-
toWs.send(JSON.stringify({
262-
type: 'giftReceived',
263-
from: sanitizeHtml(username),
264-
cards: giftedCards,
265-
inventory: toUserData.cards.map(sanitizeCard)
266-
}));
287+
if (toConnections) {
288+
toConnections.forEach(conn => {
289+
if (conn.readyState === WebSocket.OPEN) {
290+
conn.send(JSON.stringify({
291+
type: 'giftReceived',
292+
from: sanitizeHtml(username),
293+
cards: giftedCards,
294+
inventory: toUserData.cards.map(sanitizeCard)
295+
}));
296+
}
297+
});
267298
}
268299
}
269300

0 commit comments

Comments
 (0)