123
This commit is contained in:
48
server.js
48
server.js
@ -27,7 +27,7 @@ function getCard(room, cardId) {
|
||||
return cardDb[cardId];
|
||||
}
|
||||
|
||||
const rooms = new Map(); // code -> { lobby, gameState, gameStarted, faction, turnTimerInterval, turnTimeLeft, turnTimerWarnFired }
|
||||
const rooms = new Map(); // code -> { lobby, gameState, gameStarted, faction, turnTimerInterval, turnTimeLeft, turnTimerWarnFired, spectators: [] }
|
||||
const TURN_SECONDS = 90;
|
||||
const TURN_WARN_AT = 15;
|
||||
|
||||
@ -433,6 +433,7 @@ function getRoomBySocket(socketId) {
|
||||
for (const room of rooms.values()) {
|
||||
if (room.lobby?.some((p) => p.id === socketId)) return room;
|
||||
if (room.gameState?.players?.some((p) => p.id === socketId)) return room;
|
||||
if (room.spectators?.some((s) => s.id === socketId)) return room;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@ -1835,6 +1836,7 @@ io.on('connection', (socket) => {
|
||||
turnTimerInterval: null,
|
||||
turnTimeLeft: TURN_SECONDS,
|
||||
turnTimerWarnFired: false,
|
||||
spectators: [],
|
||||
};
|
||||
rooms.set(code, room);
|
||||
socket.join(code);
|
||||
@ -1849,6 +1851,19 @@ io.on('connection', (socket) => {
|
||||
cleanupEmptyRooms();
|
||||
});
|
||||
|
||||
socket.on('getRoomsList', () => {
|
||||
const roomsList = Array.from(rooms.entries()).map(([code, room]) => ({
|
||||
code,
|
||||
playerCount: room.lobby?.length || 0,
|
||||
maxPlayers: MAX_PLAYERS,
|
||||
gameStarted: room.gameStarted || false,
|
||||
hasAI: room.aiMode || false,
|
||||
players: room.lobby?.map(p => p.name) || [],
|
||||
spectators: (room.spectators || []).length
|
||||
}));
|
||||
socket.emit('roomsList', roomsList);
|
||||
});
|
||||
|
||||
socket.on('joinRoom', (data) => {
|
||||
const { code, name } = data || {};
|
||||
if (!code) {
|
||||
@ -1860,10 +1875,18 @@ io.on('connection', (socket) => {
|
||||
socket.emit('error', 'Комната не найдена');
|
||||
return;
|
||||
}
|
||||
|
||||
if (room.gameStarted) {
|
||||
socket.emit('error', 'Игра уже началась');
|
||||
// Игра уже началась - подключаемся как наблюдатель
|
||||
if (!room.spectators) room.spectators = [];
|
||||
room.spectators.push({ id: socket.id, name: name || 'Наблюдатель' });
|
||||
socket.join(code);
|
||||
socket.emit('joinedAsSpectator', { code, gameState: room.gameState });
|
||||
broadcastGameState(room); // Отправляем текущее состояние игры
|
||||
return;
|
||||
}
|
||||
|
||||
// Игра не началась - подключаемся как игрок
|
||||
if (room.lobby.length >= MAX_PLAYERS) {
|
||||
socket.emit('error', 'Комната заполнена');
|
||||
return;
|
||||
@ -2070,15 +2093,34 @@ io.on('connection', (socket) => {
|
||||
const hostId = room.gameState.players[0].id;
|
||||
if (socket.id !== hostId) return;
|
||||
clearTurnTimer(room);
|
||||
// Сохраняем список игроков для новой игры
|
||||
room.lobby = room.gameState.players.map((p) => ({ id: p.id, name: p.name }));
|
||||
// Сохраняем настройки комнаты
|
||||
const savedFaction = room.faction;
|
||||
const savedAIMode = room.aiMode;
|
||||
room.gameState = null;
|
||||
room.gameStarted = false;
|
||||
io.to(room.code).emit('backToLobby');
|
||||
room.faction = savedFaction;
|
||||
room.aiMode = savedAIMode;
|
||||
// Очищаем наблюдателей
|
||||
if (room.spectators) room.spectators = [];
|
||||
io.to(room.code).emit('backToLobby', { lobby: room.lobby });
|
||||
});
|
||||
|
||||
socket.on('disconnect', () => {
|
||||
const room = getRoomBySocket(socket.id);
|
||||
if (!room) return;
|
||||
|
||||
// Проверяем, был ли это наблюдатель
|
||||
if (room.spectators) {
|
||||
const specIdx = room.spectators.findIndex(s => s.id === socket.id);
|
||||
if (specIdx >= 0) {
|
||||
room.spectators.splice(specIdx, 1);
|
||||
socket.leave(room.code);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!room.gameStarted) {
|
||||
room.lobby = room.lobby.filter((p) => p.id !== socket.id);
|
||||
socket.leave(room.code);
|
||||
|
||||
Reference in New Issue
Block a user