Organisator kann im selben Browser selbst mitspielen
Ein Aufrufer darf Organisator- und Spieler-Zugang kombinieren (Authorization + X-Player-Token). Berechtigungen prüfen jetzt einzelne Merkmale statt einer Rangstufe. In der Lobby gibt es „Selbst mitspielen?“, Teamlinks funktionieren auch im Organisator-Browser. Online-Status wird direkt nach dem Beitritt aktualisiert. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
470b12f232
commit
4152f9c0a6
15 files changed
+248
-59
No files matched your search
+12
-6
@@ -17,12 +17,17 @@ export function attachRealtime(httpServer, { service, config }) {
|
||||
service.presence = (matchId) => new Set((presence.get(matchId) ?? new Map()).values());
|
||||
|
||||
const sendState = (socket) => {
|
||||
const { matchId, token } = socket.data;
|
||||
const { matchId, token, playerToken } = socket.data;
|
||||
try {
|
||||
const viewer = service.resolveViewer(matchId, token);
|
||||
const viewer = service.resolveViewer(matchId, [token, playerToken]);
|
||||
// Rolle kann sich geändert haben (z. B. beigetreten, entfernt) – Anwesenheit vor dem Snapshot nachziehen
|
||||
// und die anderen informieren, damit der Online-Status sofort stimmt.
|
||||
const map = presence.get(matchId);
|
||||
const key = viewer.playerId ?? `socket:${socket.id}`;
|
||||
const changed = map && map.get(socket.id) !== key;
|
||||
map?.set(socket.id, key);
|
||||
socket.emit('match:state', service.snapshot(matchId, viewer));
|
||||
// Rolle kann sich geändert haben (z. B. Spieler entfernt, neuer Captain) – Anwesenheit nachziehen.
|
||||
presence.get(matchId)?.set(socket.id, viewer.playerId ?? `socket:${socket.id}`);
|
||||
if (changed) broadcastMatch(matchId);
|
||||
} catch (err) {
|
||||
socket.emit('match:error', { error: err.message, code: err.code ?? 'error' });
|
||||
}
|
||||
@@ -56,10 +61,11 @@ export function attachRealtime(httpServer, { service, config }) {
|
||||
socket.emit('overview', { matches: service.listMatches() });
|
||||
});
|
||||
|
||||
socket.on('match:subscribe', ({ matchId, token } = {}) => {
|
||||
socket.on('match:subscribe', ({ matchId, token, playerToken } = {}) => {
|
||||
if (typeof matchId !== 'string') return;
|
||||
for (const room of socket.rooms) if (room.startsWith('match:')) leave(room.slice(6));
|
||||
socket.data = { matchId, token: typeof token === 'string' ? token : null };
|
||||
const str = (v) => (typeof v === 'string' ? v : null);
|
||||
socket.data = { matchId, token: str(token), playerToken: str(playerToken) };
|
||||
try {
|
||||
service.getMatch(matchId);
|
||||
} catch (err) {
|
||||
|
||||
Reference in new issue
Block a user