mejorando leaderboard
This commit is contained in:
@@ -909,6 +909,7 @@ async function sendPlayersActionsUpdate(client?: Response) {
|
||||
const round = (entry as any)?.round;
|
||||
const gameVariant = (entry as any)?.gameVariant || (entry as any)?.variant;
|
||||
const role = (entry as any)?.role;
|
||||
const timestamp = (entry as any)?.timestamp;
|
||||
|
||||
if (!ACTION_EVENTS.includes(kind)) continue;
|
||||
if (!isActionMade(kind, role)) continue;
|
||||
@@ -919,7 +920,8 @@ async function sendPlayersActionsUpdate(client?: Response) {
|
||||
kind,
|
||||
round,
|
||||
gameVariant,
|
||||
roomId
|
||||
roomId,
|
||||
timestamp
|
||||
});
|
||||
}
|
||||
|
||||
@@ -947,7 +949,136 @@ async function sendPlayersActionsUpdate(client?: Response) {
|
||||
};
|
||||
}).filter((p: any) => p.total > 0 || p.name);
|
||||
|
||||
const payload = { players };
|
||||
// Build aggregated data across all players
|
||||
const aggregatedCounts: Record<string, number> = Object.fromEntries(ACTION_EVENTS.map(k => [k, 0])) as any;
|
||||
const aggregatedDetailedEvents: Array<{ kind: string; round?: number; gameVariant?: string; roomId?: string; playerUuid?: string; timestamp?: number }>[] = [] as any;
|
||||
|
||||
const roomsIndex: Record<string, { roomId: string; lastSeenIndex: number; lastEventAt?: number; messageCount: number }> = {};
|
||||
let idxCounter = 0;
|
||||
players.forEach((p: any) => {
|
||||
// Sum counts
|
||||
ACTION_EVENTS.forEach(k => {
|
||||
const c = Number(p?.counts?.[k] || 0);
|
||||
aggregatedCounts[k] = (aggregatedCounts[k] || 0) + c;
|
||||
});
|
||||
// Flatten detailed history and build rooms index
|
||||
(Array.isArray(p?.detailedHistory) ? p.detailedHistory : []).forEach((ev: any) => {
|
||||
const e = {
|
||||
kind: String(ev?.kind || ''),
|
||||
round: ev?.round != null ? Number(ev.round) : undefined,
|
||||
gameVariant: (ev?.gameVariant || ev?.variant) ? String(ev.gameVariant || ev.variant) : undefined,
|
||||
roomId: ev?.roomId ? String(ev.roomId) : undefined,
|
||||
playerUuid: p.uuid,
|
||||
timestamp: ev?.timestamp != null ? Number(ev.timestamp) : undefined
|
||||
};
|
||||
aggregatedDetailedEvents.push(e as any);
|
||||
const rid = e.roomId || '';
|
||||
if (rid) {
|
||||
if (!roomsIndex[rid]) {
|
||||
roomsIndex[rid] = { roomId: rid, lastSeenIndex: idxCounter, messageCount: 0 };
|
||||
}
|
||||
roomsIndex[rid].lastSeenIndex = idxCounter; // newer index wins
|
||||
roomsIndex[rid].messageCount += 1;
|
||||
if (e.timestamp) {
|
||||
roomsIndex[rid].lastEventAt = Math.max(roomsIndex[rid].lastEventAt || 0, e.timestamp);
|
||||
}
|
||||
idxCounter += 1;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Optionally include snapshot of active rooms similar to /dashboard-stream
|
||||
let activeRoomsPayload: any | undefined = undefined;
|
||||
try {
|
||||
const rooms = await matchMaker.query({});
|
||||
const activeRoomDetails: any[] = [];
|
||||
const activeCounts: Record<string, number> = Object.fromEntries(ACTION_EVENTS.map(k => [k, 0]));
|
||||
for (const room of rooms) {
|
||||
if (room.name === 'game') {
|
||||
try {
|
||||
const detailData: any = await matchMaker.remoteRoomCall(room.roomId, "getState");
|
||||
// Map systemMessages to detailed events
|
||||
const msgs = Array.isArray(detailData?.systemMessages) ? detailData.systemMessages : [];
|
||||
const systemMessages = msgs.map((m: any) => ({
|
||||
kind: String(m?.kind || ''),
|
||||
round: m?.round != null ? Number(m.round) : undefined,
|
||||
gameVariant: (m?.gameVariant || m?.variant) ? String(m.gameVariant || m.variant) : undefined,
|
||||
roomId: String(m?.roomId || room.roomId),
|
||||
timestamp: m?.timestamp != null ? Number(m.timestamp) : undefined
|
||||
}));
|
||||
// Count events present in ACTION_EVENTS
|
||||
systemMessages.forEach((m: any) => {
|
||||
if (ACTION_EVENTS.includes(m.kind)) {
|
||||
activeCounts[m.kind] = (activeCounts[m.kind] || 0) + 1;
|
||||
}
|
||||
});
|
||||
activeRoomDetails.push({
|
||||
roomId: room.roomId,
|
||||
name: room.name,
|
||||
metadata: {
|
||||
gameStatus: room.metadata?.gameStatus || 'unknown',
|
||||
currentVariant: room.metadata?.currentVariant || detailData?.variant || undefined,
|
||||
currentRound: room.metadata?.currentRound || detailData?.round || undefined
|
||||
},
|
||||
players: (Array.isArray(detailData?.players) ? detailData.players : []).map((p: any) => ({
|
||||
uuid: String(p?.uuid || p?.sessionId || ''),
|
||||
name: p?.name || null,
|
||||
color: p?.color || null
|
||||
})),
|
||||
systemMessages
|
||||
});
|
||||
} catch (error) {
|
||||
// Ignore errors per room to not break the stream
|
||||
}
|
||||
}
|
||||
}
|
||||
activeRoomsPayload = {
|
||||
rooms: activeRoomDetails,
|
||||
counts: activeCounts
|
||||
};
|
||||
} catch (e) {
|
||||
// If querying active rooms fails, omit activeRooms in payload
|
||||
activeRoomsPayload = undefined;
|
||||
}
|
||||
|
||||
// Build summary metrics
|
||||
const playersWithNames = players.filter((p: any) => !!p.name).length;
|
||||
let totalP1 = 0, cntP1 = 0;
|
||||
let totalP2 = 0, cntP2 = 0;
|
||||
players.forEach((p: any) => {
|
||||
(Array.isArray(p?.roomScoreHistory) ? p.roomScoreHistory : []).forEach((rs: any) => {
|
||||
(Array.isArray(rs?.scores) ? rs.scores : []).forEach((s: any) => {
|
||||
if (s?.role === 'P1') { totalP1 += Number(s.score || 0); cntP1 += 1; }
|
||||
else if (s?.role === 'P2') { totalP2 += Number(s.score || 0); cntP2 += 1; }
|
||||
});
|
||||
});
|
||||
});
|
||||
const avgP1 = cntP1 > 0 ? totalP1 / cntP1 : 0;
|
||||
const avgP2 = cntP2 > 0 ? totalP2 / cntP2 : 0;
|
||||
const overallCnt = cntP1 + cntP2;
|
||||
const overallAvg = overallCnt > 0 ? (totalP1 + totalP2) / overallCnt : 0;
|
||||
|
||||
const payload = {
|
||||
version: '1.0',
|
||||
timestamp: Date.now(),
|
||||
players,
|
||||
aggregated: {
|
||||
detailedEvents: aggregatedDetailedEvents,
|
||||
counts: aggregatedCounts,
|
||||
rooms: Object.values(roomsIndex)
|
||||
},
|
||||
activeRooms: activeRoomsPayload,
|
||||
summary: {
|
||||
totalPlayers: playersWithNames,
|
||||
playersWithShame: players.filter((p: any) => Number(p?.shameTokens || 0) > 0).length,
|
||||
playersWithoutShame: Math.max(0, playersWithNames - players.filter((p: any) => Number(p?.shameTokens || 0) > 0).length),
|
||||
averageScore: {
|
||||
p1: Number(avgP1.toFixed(2)),
|
||||
p2: Number(avgP2.toFixed(2)),
|
||||
overall: Number(overallAvg.toFixed(2))
|
||||
}
|
||||
}
|
||||
};
|
||||
const message = `data: ${JSON.stringify(payload)}\n\n`;
|
||||
if (client) {
|
||||
if (!(client as any).destroyed) client.write(message);
|
||||
|
||||
Reference in New Issue
Block a user