diff --git a/sockets/arena_socket.js b/sockets/arena_socket.js index 3fce2bc..6ea99ec 100644 --- a/sockets/arena_socket.js +++ b/sockets/arena_socket.js @@ -359,32 +359,29 @@ function registerTeamModeHandlers(io, socket, mode) { }); } -/* ── Helper: Event direkt an beide Spieler eines Matches senden ── */ +/* ── Helper: Event an beide Spieler senden ── */ function emitToMatch(io, matchId, event, data) { + // Immer Room-Broadcast (zuverlässigste Methode) + io.to("arena_" + matchId).emit(event, data); + // Zusätzlich direkt an bekannte Socket-IDs falls vorhanden const room = io._arenaRooms?.get(matchId); if (room) { - // Direkt an bekannte Socket-IDs senden (kein Room-Broadcast → kein Duplikat) ["player1", "player2"].forEach((slot) => { if (room.sockets[slot]) { io.to(room.sockets[slot]).emit(event, data); } }); - } else { - // Fallback wenn room noch nicht gesetzt - io.to("arena_" + matchId).emit(event, data); } } function emitToOpponent(io, matchId, senderSlot, event, data) { - const room = io._arenaRooms?.get(matchId); const opponentSlot = senderSlot === "player1" ? "player2" : "player1"; + // Direkt an Gegner-Socket + const room = io._arenaRooms?.get(matchId); if (room?.sockets[opponentSlot]) { - // Direkt an Gegner-Socket (kein Duplikat beim Sender) io.to(room.sockets[opponentSlot]).emit(event, data); - } else { - // Fallback: Room-Broadcast - socket.to("arena_" + matchId).emit(event, data); } + // Kein Room-Broadcast hier (Sender würde eigene Karten nochmal empfangen) } /* ═══════════════════════════════════════════════════════════ diff --git a/views/1v1-battlefield.ejs b/views/1v1-battlefield.ejs index db8cc7c..9f00bb1 100644 --- a/views/1v1-battlefield.ejs +++ b/views/1v1-battlefield.ejs @@ -883,17 +883,17 @@ }); /* ── Server: Zugwechsel ──────────────────────────────── */ - let lastTurnChangeActive = null; + let lastTurnChangeTs = 0; socket.on("turn_change", (data) => { // Board synchronisieren falls mitgeliefert if (data.boardSync) applyBoardSync(data.boardSync); + // Duplikat-Schutz: gleiches Event innerhalb 1 Sekunde nur einmal verarbeiten + const now = Date.now(); + if (now - lastTurnChangeTs < 1000) return; + lastTurnChangeTs = now; + const nowMyTurn = data.activeSlot === mySlot; - - // Duplikat-Schutz: gleiche Zustandsänderung nicht doppelt anwenden - if (data.activeSlot === lastTurnChangeActive && nowMyTurn === isMyTurn) return; - lastTurnChangeActive = data.activeSlot; - console.log("[1v1] turn_change:", data.activeSlot, "| ich:", mySlot, "| meinZug:", nowMyTurn); setTurnState(nowMyTurn); });