
diff --git a/bc.js b/bc.js index 5474738..72fffc8 100644 --- a/bc.js +++ b/bc.js @@ -1,42 +1,50 @@ // bc.js (или server.js - ваш основной файл сервера) -// КОД ОСТАЕТСЯ БЕЗ ИЗМЕНЕНИЙ ОТНОСИТЕЛЬНО ПРЕДЫДУЩЕЙ ВЕРСИИ, -// ГДЕ УЖЕ БЫЛА ДОБАВЛЕНА ПЕРЕДАЧА characterKey В GameManager - const express = require('express'); const http = require('http'); const socketIo = require('socket.io'); const path = require('path'); // Серверные модули -const GameManager = require('./server_modules/gameManager'); // GameManager будет изменен -const authController = require('./server_modules/auth'); +const GameManager = require('./server_modules/gameManager'); +const authController = require('./server_modules/auth'); // Ваш модуль аутентификации +// const GAME_CONFIG = require('./server_modules/config'); // Не используется напрямую здесь, но может быть полезен для отладки -const hostname = 'localhost'; +const hostname = 'localhost'; // или '0.0.0.0' для доступа извне const app = express(); const server = http.createServer(app); -const io = socketIo(server); +const io = socketIo(server, { + cors: { + origin: "*", // Разрешить все источники для простоты разработки. В продакшене укажите конкретный домен клиента. + methods: ["GET", "POST"] + } +}); const PORT = process.env.PORT || 3200; +// Статическое обслуживание файлов из папки 'public' app.use(express.static(path.join(__dirname, 'public'))); -const gameManager = new GameManager(io); // GameManager будет содержать новую логику +// Создание экземпляра GameManager +const gameManager = new GameManager(io); io.on('connection', (socket) => { - console.log('[Server] New client connected:', socket.id); + console.log(`[Server BC.JS] New client connected: ${socket.id}`); + // При подключении нового клиента, отправляем ему текущий список доступных PvP игр const availableGames = gameManager.getAvailablePvPGamesListForClient(); socket.emit('availablePvPGamesList', availableGames); + // Обработчик запроса на обновление списка PvP игр socket.on('requestPvPGameList', () => { const currentAvailableGames = gameManager.getAvailablePvPGamesListForClient(); socket.emit('availablePvPGamesList', currentAvailableGames); }); + // --- Аутентификация --- socket.on('register', async (data) => { console.log(`[Server BC.JS] Received 'register' event from ${socket.id} with username: ${data?.username}`); if (!data || typeof data.username !== 'string' || typeof data.password !== 'string') { - socket.emit('registerResponse', { success: false, message: 'Некорректные данные запроса.' }); + socket.emit('registerResponse', { success: false, message: 'Некорректные данные запроса для регистрации.' }); return; } const result = await authController.registerUser(data.username, data.password); @@ -46,12 +54,13 @@ io.on('connection', (socket) => { socket.on('login', async (data) => { console.log(`[Server BC.JS] Received 'login' event from ${socket.id} with username: ${data?.username}`); if (!data || typeof data.username !== 'string' || typeof data.password !== 'string') { - socket.emit('loginResponse', { success: false, message: 'Некорректные данные запроса.' }); + socket.emit('loginResponse', { success: false, message: 'Некорректные данные запроса для входа.' }); return; } const result = await authController.loginUser(data.username, data.password); if (result.success) { - socket.userData = { userId: result.userId, username: result.username }; // Сохраняем userId + // Сохраняем данные пользователя в объекте сокета для последующего использования + socket.userData = { userId: result.userId, username: result.username }; console.log(`[Server BC.JS] User ${result.username} (ID: ${result.userId}) associated with socket ${socket.id}. Welcome!`); } socket.emit('loginResponse', result); @@ -61,21 +70,24 @@ io.on('connection', (socket) => { const username = socket.userData?.username || socket.id; console.log(`[Server BC.JS] Received 'logout' event from ${username}.`); if (socket.userData) { - gameManager.handleDisconnect(socket.id); // Обработает выход из игр - delete socket.userData; + // При выходе пользователя, обрабатываем его возможное участие в играх + gameManager.handleDisconnect(socket.id, socket.userData.userId); // Используем userId для более точной обработки + delete socket.userData; // Удаляем данные пользователя из сокета console.log(`[Server BC.JS] User data cleared for ${username}.`); } + // Можно отправить подтверждение выхода, если нужно + // socket.emit('logoutResponse', { success: true, message: 'Вы успешно вышли.' }); }); + // --- Управление Играми --- socket.on('createGame', (data) => { if (!socket.userData) { socket.emit('gameError', { message: "Ошибка: Вы не авторизованы для создания игры." }); return; } - const mode = data?.mode || 'ai'; - const characterKey = (data?.characterKey === 'almagest') ? 'almagest' : 'elena'; + const mode = data?.mode || 'ai'; // 'ai' или 'pvp' + const characterKey = (data?.characterKey === 'almagest') ? 'almagest' : 'elena'; // По умолчанию Елена console.log(`[Server BC.JS] User ${socket.userData.username} (socket: ${socket.id}) requests createGame. Mode: ${mode}, Character: ${characterKey}`); - // Передаем socket.userData.userId в GameManager, если он нужен для идентификации пользователя между сессиями gameManager.createGame(socket, mode, characterKey, socket.userData.userId); }); @@ -86,7 +98,6 @@ io.on('connection', (socket) => { } console.log(`[Server BC.JS] User ${socket.userData.username} (socket: ${socket.id}) requests joinGame for ID: ${data?.gameId}`); if (data && typeof data.gameId === 'string') { - // Передаем socket.userData.userId gameManager.joinGame(socket, data.gameId, socket.userData.userId); } else { socket.emit('gameError', { message: 'Ошибка присоединения: неверный формат ID игры.' }); @@ -100,38 +111,56 @@ io.on('connection', (socket) => { } const characterKey = (data?.characterKey === 'almagest') ? 'almagest' : 'elena'; console.log(`[Server BC.JS] User ${socket.userData.username} (socket: ${socket.id}) requests findRandomGame. Preferred Character: ${characterKey}`); - // Передаем socket.userData.userId gameManager.findAndJoinRandomPvPGame(socket, characterKey, socket.userData.userId); }); + // --- Игровые Действия --- socket.on('playerAction', (data) => { - if (!socket.userData) return; + if (!socket.userData) { + // Если пользователь не авторизован, но пытается совершить действие (маловероятно при правильной логике клиента) + socket.emit('gameError', { message: "Ошибка: Вы не авторизованы для совершения этого действия." }); + return; + } + // GameManager сам проверит, принадлежит ли этот сокет к активной игре gameManager.handlePlayerAction(socket.id, data); }); - socket.on('requestRestart', (data) => { - if (!socket.userData) { - socket.emit('gameError', { message: "Ошибка: Вы не авторизованы для запроса рестарта." }); - return; - } - console.log(`[Server BC.JS] User ${socket.userData.username} (socket: ${socket.id}) requests restart for game ID: ${data?.gameId}`); - if (data && typeof data.gameId === 'string') { - gameManager.requestRestart(socket.id, data.gameId); - } else { - socket.emit('gameError', { message: 'Ошибка рестарта: неверный формат ID игры.' }); - } - }); + // Обработчик 'requestRestart' удален, так как эта функциональность заменена на "возврат в меню" + // --- Отключение Клиента --- socket.on('disconnect', (reason) => { const username = socket.userData?.username || socket.id; - console.log(`[Server] Client ${username} disconnected. Reason: ${reason}. Socket ID: ${socket.id}`); + console.log(`[Server BC.JS] Client ${username} disconnected. Reason: ${reason}. Socket ID: ${socket.id}`); // Передаем userId, если он есть, для более точной обработки в GameManager + // (например, для удаления его ожидающих игр или корректного завершения активной игры) const userId = socket.userData?.userId; gameManager.handleDisconnect(socket.id, userId); - // socket.userData автоматически очистится для этого объекта socket + // socket.userData автоматически очистится для этого объекта socket при его удалении из io.sockets }); + + // Для отладки: вывод списка активных игр каждые N секунд + // setInterval(() => { + // console.log("--- Active Games ---"); + // const activeGames = gameManager.getActiveGamesList(); + // if (activeGames.length > 0) { + // activeGames.forEach(game => { + // console.log(`ID: ${game.id}, Mode: ${game.mode}, Players: ${game.playerCount}, GameOver: ${game.isGameOver}, P1: ${game.playerSlot}, P2: ${game.opponentSlot}, Owner: ${game.ownerUserId}, Pending: ${game.pending}`); + // }); + // } else { + // console.log("No active games."); + // } + // console.log("--- Pending PvP Games IDs ---"); + // console.log(gameManager.pendingPvPGames.map(id => id.substring(0,8))); + // console.log("--- User to Pending Game Map ---"); + // console.log(gameManager.userToPendingGame); + // console.log("---------------------"); + // }, 30000); // Каждые 30 секунд }); server.listen(PORT, hostname, () => { - console.log(`Server listening on http://${hostname}:${PORT}`); + console.log(`==== Medieval Clash Server ====`); + console.log(` Listening on http://${hostname}:${PORT}`); + console.log(` Public files served from: ${path.join(__dirname, 'public')}`); + console.log(` Waiting for connections...`); + console.log(`===============================`); }); \ No newline at end of file diff --git a/public/index.html b/public/index.html index d39f2f9..51d02a5 100644 --- a/public/index.html +++ b/public/index.html @@ -9,196 +9,6 @@ -
@@ -233,7 +43,7 @@ -