/** * Local Server Manager * Manages the local server for singleplayer mode within the Electron client */ class LocalServerManager { constructor() { this.localServer = null; this.isRunning = false; this.port = 3004; this.startupAttempts = 0; this.maxStartupAttempts = 3; console.log('[LOCAL SERVER MANAGER] LocalServerManager initialized'); } async initialize() { console.log('[LOCAL SERVER MANAGER] Initializing local server...'); try { // In Electron renderer context, use SimpleLocalServer which doesn't require Node.js modules if (typeof window !== 'undefined' && window.SimpleLocalServer) { this.localServer = new window.SimpleLocalServer(); console.log('[LOCAL SERVER MANAGER] SimpleLocalServer class loaded from window'); return true; } else if (typeof window !== 'undefined' && window.LocalServer) { // Fallback to original LocalServer if available this.localServer = new window.LocalServer(); console.log('[LOCAL SERVER MANAGER] LocalServer class loaded from window'); return true; } else { console.warn('[LOCAL SERVER MANAGER] No local server class available'); return false; } } catch (error) { console.error('[LOCAL SERVER MANAGER] Failed to initialize local server:', error); console.log('[LOCAL SERVER MANAGER] Please ensure SimpleLocalServer.js is loaded properly'); return false; } } async startServer() { if (this.isRunning) { console.log('[LOCAL SERVER MANAGER] Server is already running'); return { success: true, port: this.port }; } if (!this.localServer) { const initialized = await this.initialize(); if (!initialized) { return { success: false, error: 'Failed to initialize server' }; } } console.log(`[LOCAL SERVER MANAGER] Attempting to start server on port ${this.port}`); try { const result = await this.localServer.start(this.port); if (result.success) { this.isRunning = true; this.port = result.port; this.startupAttempts = 0; console.log(`[LOCAL SERVER MANAGER] Server started successfully on port ${this.port}`); console.log(`[LOCAL SERVER MANAGER] Server URL: ${result.url}`); // Update LiveMainMenu to use local server this.updateMainMenuForLocalMode(); return result; } else { console.error('[LOCAL SERVER MANAGER] Failed to start server:', result.error); this.startupAttempts++; // Try alternative ports if first attempt fails if (this.startupAttempts < this.maxStartupAttempts) { this.port = 3004 + this.startupAttempts; console.log(`[LOCAL SERVER MANAGER] Retrying with port ${this.port}`); return await this.startServer(); } return result; } } catch (error) { console.error('[LOCAL SERVER MANAGER] Exception starting server:', error); return { success: false, error: error.message }; } } async stopServer() { if (!this.isRunning || !this.localServer) { console.log('[LOCAL SERVER MANAGER] Server is not running'); return { success: true }; } console.log('[LOCAL SERVER MANAGER] Stopping local server...'); try { const result = await this.localServer.stop(); if (result.success) { this.isRunning = false; this.port = 3004; console.log('[LOCAL SERVER MANAGER] Server stopped successfully'); } else { console.error('[LOCAL SERVER MANAGER] Failed to stop server:', result.error); } return result; } catch (error) { console.error('[LOCAL SERVER MANAGER] Exception stopping server:', error); return { success: false, error: error.message }; } } getStatus() { if (!this.localServer) { return { isRunning: false, port: null, connectedClients: 0, uptime: 0 }; } const status = this.localServer.getStatus(); return { ...status, url: this.isRunning ? `http://localhost:${status.port}` : null }; } getServerUrl() { return this.isRunning ? `http://localhost:${this.port}` : null; } updateMainMenuForLocalMode() { // Update LiveMainMenu to use local server URLs if (window.liveMainMenu) { console.log('[LOCAL SERVER MANAGER] Updating LiveMainMenu for local mode'); window.liveMainMenu.apiBaseUrl = `http://localhost:${this.port}/api`; window.liveMainMenu.gameServerUrl = `http://localhost:${this.port}`; window.liveMainMenu.isLocalMode = true; console.log(`[LOCAL SERVER MANAGER] Updated API URL to: ${window.liveMainMenu.apiBaseUrl}`); console.log(`[LOCAL SERVER MANAGER] Updated Game Server URL to: ${window.liveMainMenu.gameServerUrl}`); // Also update GameInitializer URLs if (window.gameInitializer) { window.gameInitializer.updateServerUrls( `http://localhost:${this.port}/api`, `http://localhost:${this.port}` ); console.log('[LOCAL SERVER MANAGER] Updated GameInitializer URLs for local mode'); } else { console.warn('[LOCAL SERVER MANAGER] GameInitializer not available for URL update'); } } else { console.warn('[LOCAL SERVER MANAGER] LiveMainMenu not available for update'); } } // Auto-start server when in singleplayer mode async autoStartIfSingleplayer() { // Check if we should auto-start (no external server available) try { // Try to connect to external server first const response = await fetch('https://api.korvarix.com/health', { method: 'GET', timeout: 3000 }); if (response.ok) { console.log('[LOCAL SERVER MANAGER] External server available, not starting local server'); return { success: false, reason: 'External server available' }; } } catch (error) { console.log('[LOCAL SERVER MANAGER] External server not available, starting local server'); } // Start local server return await this.startServer(); } // Handle server errors and restart if needed handleServerError(error) { console.error('[LOCAL SERVER MANAGER] Server error:', error); // Try to restart server if it crashes if (this.isRunning) { console.log('[LOCAL SERVER MANAGER] Attempting to restart server...'); this.stopServer().then(() => { setTimeout(() => { this.startServer(); }, 2000); // Wait 2 seconds before restarting }); } } // Get local server info for UI display getServerInfo() { return { isRunning: this.isRunning, port: this.port, url: this.getServerUrl(), status: this.isRunning ? 'Online' : 'Offline', mode: 'Local Singleplayer', connectedClients: this.localServer ? this.localServer.connectedClients.size : 0, uptime: this.localServer ? this.localServer.uptime : 0 }; } } // Create global instance window.localServerManager = new LocalServerManager(); // Auto-export for module systems if (typeof module !== 'undefined' && module.exports) { module.exports = LocalServerManager; } console.log('[LOCAL SERVER MANAGER] LocalServerManager loaded and global instance created');