API/Client-Server/js/LocalServerManager.js

225 lines
8.4 KiB
JavaScript

/**
* 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');