Fixed lobby close

This commit is contained in:
2026-02-10 19:10:17 +01:00
parent 4c53282bfa
commit de2684d4c1
2 changed files with 30 additions and 17 deletions

View File

@@ -467,7 +467,6 @@
const msg = JSON.parse(e.data); const msg = JSON.parse(e.data);
if (msg.type === "room_list") updateRoomList(msg.rooms); if (msg.type === "room_list") updateRoomList(msg.rooms);
if (msg.type === "init") { if (msg.type === "init") {
myRole = msg.role;
roomId = msg.roomId; roomId = msg.roomId;
document.getElementById("roomCode").innerText = roomId.toUpperCase(); document.getElementById("roomCode").innerText = roomId.toUpperCase();
window.history.replaceState({}, '', `?room=${roomId}`); window.history.replaceState({}, '', `?room=${roomId}`);

View File

@@ -199,54 +199,68 @@ wss.on("connection", (ws, req) => {
const room = rooms[roomId]; const room = rooms[roomId];
ws.roomId = roomId; ws.roomId = roomId;
ws.sessionId = sessionId; // Store on socket for easy lookup during close
let player = room.players.find(p => p.sessionId === sessionId); let player = room.players.find(p => p.sessionId === sessionId);
if (player) { if (player) {
// Reconnecting existing player
player.ws = ws; player.ws = ws;
} else if (room.players.length < 2) { } else if (room.players.length < 2) {
// New player joining: logic to pick the opposite role
let role; let role;
if (room.players.length === 1) { if (room.players.length === 1) {
// Pick the role that isn't taken role = (room.players[0].role === "wolf") ? "sheep" : "wolf";
const takenRole = room.players[0].role;
role = (takenRole === "wolf") ? "sheep" : "wolf";
} else { } else {
// First player in the room defaults to sheep
role = "sheep"; role = "sheep";
} }
player = { ws, role, sessionId, isBot: false };
player = { ws, role, sessionId };
room.players.push(player); room.players.push(player);
} }
// Inform the client of their assigned role
ws.send(JSON.stringify({ type: "init", role: player.role, roomId })); ws.send(JSON.stringify({ type: "init", role: player.role, roomId }));
broadcastRoomList(); broadcastRoomList();
broadcastState(roomId); broadcastState(roomId);
// If a bot is involved, update its state
if (room.players.some(p => p.isBot)) sendBotState(roomId); if (room.players.some(p => p.isBot)) sendBotState(roomId);
// --- HANDLE DISCONNECT ---
ws.on("close", () => {
const currentRoom = rooms[ws.roomId];
if (!currentRoom) return;
// Remove the player from the room array
currentRoom.players = currentRoom.players.filter(p => p.sessionId !== ws.sessionId);
// If the room is now empty (or only contains a bot), delete it
const humanRemaining = currentRoom.players.some(p => !p.isBot);
if (currentRoom.players.length === 0 || (!humanRemaining && currentRoom.players.some(p => p.isBot))) {
// If it was a bot room, close the bot socket before deleting
const bot = currentRoom.players.find(p => p.isBot);
if (bot && bot.socket) bot.socket.destroy();
delete rooms[ws.roomId];
} else {
// Room still has someone, notify them
broadcastState(ws.roomId);
}
broadcastRoomList();
});
ws.on("message", msg => { ws.on("message", msg => {
let data = JSON.parse(msg); let data = JSON.parse(msg);
const playerObj = room.players.find(p => p.sessionId === sessionId);
if (!playerObj) return;
if (data.type === "restart") { if (data.type === "restart") {
swapRoles(room); swapRoles(room);
room.game = { wolf: 5, sheep: [0, 1, 3], turn: "sheep", moveCount: 0, winner: null, lastMove: null }; room.game = { wolf: 5, sheep: [0, 1, 3], turn: "sheep", moveCount: 0, winner: null, lastMove: null };
// Critical: Re-sync roles for all human clients on restart
room.players.forEach(p => { room.players.forEach(p => {
if (p.ws && p.ws.readyState === WebSocket.OPEN) { if (p.ws && p.ws.readyState === WebSocket.OPEN) {
p.ws.send(JSON.stringify({ type: "init", role: p.role, roomId })); p.ws.send(JSON.stringify({ type: "init", role: p.role, roomId }));
} }
}); });
broadcastState(roomId); broadcastState(roomId);
if (room.players.some(p => p.isBot)) sendBotState(roomId); if (room.players.some(p => p.isBot)) sendBotState(roomId);
} else { } else {
handleMove(roomId, player.role, data); handleMove(roomId, playerObj.role, data);
} }
}); });
}); });