/** * Game System - Manages game instances and real-time multiplayer logic */ const logger = require('../utils/logger'); class GameSystem { constructor() { this.gameInstances = new Map(); // serverId -> game instance this.playerConnections = new Map(); // socketId -> player data } async initializeGameSystems() { logger.info('Initializing Game Server systems...'); // Initialize any game systems needed this.initializeEconomySystem(); this.initializeDungeonSystem(); logger.info('Game Server systems initialized successfully'); } initializeEconomySystem() { // Economy system initialization for game server logger.info('Economy System initialized for Game Server'); } initializeDungeonSystem() { // Dungeon system initialization for game server logger.info('Dungeon System initialized for Game Server'); } createGameInstance(serverData) { const gameId = serverData.id; const gameInstance = { id: gameId, name: serverData.name, type: serverData.type, region: serverData.region, maxPlayers: serverData.maxPlayers, currentPlayers: 0, players: new Map(), // socketId -> player data gameState: { active: false, startTime: null, currentDungeon: null, enemies: new Map(), items: new Map(), environment: null }, createdAt: new Date(), lastActivity: new Date() }; this.gameInstances.set(gameId, gameInstance); logger.info(`Game instance created: ${gameId} - ${serverData.name}`); return gameInstance; } joinGameInstance(socket, serverId, playerData) { const gameInstance = this.gameInstances.get(serverId); if (!gameInstance) { logger.error(`Game instance not found: ${serverId}`); return false; } if (gameInstance.currentPlayers >= gameInstance.maxPlayers) { logger.warn(`Game instance full: ${serverId}`); return false; } // Add player to game instance gameInstance.players.set(socket.id, { socketId: socket.id, userId: playerData.userId, username: playerData.username, joinedAt: new Date(), isReady: false, ship: playerData.currentShip || null, stats: playerData.stats || { level: 1, health: 100 } }); // Track player connection this.playerConnections.set(socket.id, { gameId: serverId, socket: socket, data: playerData }); gameInstance.currentPlayers++; gameInstance.lastActivity = new Date(); // Join socket to game room socket.join(`game_${serverId}`); logger.info(`Player ${playerData.username} joined game instance ${serverId}`); return gameInstance; } leaveGameInstance(socket, serverId) { const gameInstance = this.gameInstances.get(serverId); if (!gameInstance) { logger.error(`Game instance not found: ${serverId}`); return false; } const player = gameInstance.players.get(socket.id); if (player) { gameInstance.players.delete(socket.id); gameInstance.currentPlayers--; gameInstance.lastActivity = new Date(); // Leave socket room socket.leave(`game_${serverId}`); // Remove player connection tracking this.playerConnections.delete(socket.id); logger.info(`Player ${player.username} left game instance ${serverId}`); // Clean up empty game instances if (gameInstance.currentPlayers === 0) { this.cleanupGameInstance(serverId); } return true; } return false; } cleanupGameInstance(serverId) { const gameInstance = this.gameInstances.get(serverId); if (gameInstance && gameInstance.currentPlayers === 0) { this.gameInstances.delete(serverId); logger.info(`Cleaned up empty game instance: ${serverId}`); } } getGameInstance(serverId) { return this.gameInstances.get(serverId); } getAllGameInstances() { return Array.from(this.gameInstances.values()).map(instance => ({ id: instance.id, name: instance.name, type: instance.type, region: instance.region, currentPlayers: instance.currentPlayers, maxPlayers: instance.maxPlayers, gameState: instance.gameState.active ? 'active' : 'waiting', createdAt: instance.createdAt })); } getPlayerConnection(socketId) { return this.playerConnections.get(socketId); } // Game action handlers handlePlayerAction(socket, actionType, actionData) { const connection = this.playerConnections.get(socket.id); if (!connection) { logger.warn(`No connection found for socket: ${socket.id}`); return false; } const gameInstance = this.gameInstances.get(connection.gameId); if (!gameInstance) { logger.warn(`No game instance found for player: ${socket.id}`); return false; } const player = gameInstance.players.get(socket.id); if (!player) { logger.warn(`Player not found in game instance: ${socket.id}`); return false; } // Handle different action types switch (actionType) { case 'move': return this.handlePlayerMove(gameInstance, player, actionData); case 'attack': return this.handlePlayerAttack(gameInstance, player, actionData); case 'interact': return this.handlePlayerInteract(gameInstance, player, actionData); case 'chat': return this.handlePlayerChat(gameInstance, player, actionData); default: logger.warn(`Unknown action type: ${actionType}`); return false; } } handlePlayerMove(gameInstance, player, moveData) { // Update player position player.position = moveData.position; gameInstance.lastActivity = new Date(); // Broadcast movement to other players in the game const socket = this.playerConnections.get(player.socketId)?.socket; if (socket) { socket.to(`game_${gameInstance.id}`).emit('playerMoved', { playerId: player.socketId, username: player.username, position: moveData.position }); } return true; } handlePlayerAttack(gameInstance, player, attackData) { // Handle combat logic logger.info(`Player ${player.username} attacked in game ${gameInstance.id}`); // Broadcast attack to other players const socket = this.playerConnections.get(player.socketId)?.socket; if (socket) { socket.to(`game_${gameInstance.id}`).emit('playerAttacked', { playerId: player.socketId, username: player.username, target: attackData.target, damage: attackData.damage }); } return true; } handlePlayerInteract(gameInstance, player, interactData) { // Handle interaction logic (picking up items, activating objects, etc.) logger.info(`Player ${player.username} interacted in game ${gameInstance.id}`); return true; } handlePlayerChat(gameInstance, player, chatData) { // Handle chat messages const message = { playerId: player.socketId, username: player.username, message: chatData.message, timestamp: new Date() }; // Broadcast chat to all players in the game const socket = this.playerConnections.get(player.socketId)?.socket; if (socket) { socket.to(`game_${gameInstance.id}`).emit('chatMessage', message); } return true; } } // Singleton instance let gameSystem = null; async function initializeGameSystems() { if (!gameSystem) { gameSystem = new GameSystem(); await gameSystem.initializeGameSystems(); } return gameSystem; } function getGameSystem() { return gameSystem; } module.exports = { GameSystem, initializeGameSystems, getGameSystem };