Fixed lobby close
This commit is contained in:
46
server.js
46
server.js
@@ -199,54 +199,68 @@ wss.on("connection", (ws, req) => {
|
||||
|
||||
const room = rooms[roomId];
|
||||
ws.roomId = roomId;
|
||||
ws.sessionId = sessionId; // Store on socket for easy lookup during close
|
||||
|
||||
let player = room.players.find(p => p.sessionId === sessionId);
|
||||
|
||||
if (player) {
|
||||
// Reconnecting existing player
|
||||
player.ws = ws;
|
||||
} else if (room.players.length < 2) {
|
||||
// New player joining: logic to pick the opposite role
|
||||
let role;
|
||||
if (room.players.length === 1) {
|
||||
// Pick the role that isn't taken
|
||||
const takenRole = room.players[0].role;
|
||||
role = (takenRole === "wolf") ? "sheep" : "wolf";
|
||||
role = (room.players[0].role === "wolf") ? "sheep" : "wolf";
|
||||
} else {
|
||||
// First player in the room defaults to sheep
|
||||
role = "sheep";
|
||||
}
|
||||
|
||||
player = { ws, role, sessionId };
|
||||
player = { ws, role, sessionId, isBot: false };
|
||||
room.players.push(player);
|
||||
}
|
||||
|
||||
// Inform the client of their assigned role
|
||||
ws.send(JSON.stringify({ type: "init", role: player.role, roomId }));
|
||||
|
||||
broadcastRoomList();
|
||||
broadcastState(roomId);
|
||||
|
||||
// If a bot is involved, update its state
|
||||
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 => {
|
||||
let data = JSON.parse(msg);
|
||||
const playerObj = room.players.find(p => p.sessionId === sessionId);
|
||||
if (!playerObj) return;
|
||||
|
||||
if (data.type === "restart") {
|
||||
swapRoles(room);
|
||||
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 => {
|
||||
if (p.ws && p.ws.readyState === WebSocket.OPEN) {
|
||||
p.ws.send(JSON.stringify({ type: "init", role: p.role, roomId }));
|
||||
}
|
||||
});
|
||||
|
||||
broadcastState(roomId);
|
||||
if (room.players.some(p => p.isBot)) sendBotState(roomId);
|
||||
} else {
|
||||
handleMove(roomId, player.role, data);
|
||||
handleMove(roomId, playerObj.role, data);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user