/** * Simple Local Server for Singleplayer Mode * A mock server that simulates server responses without requiring Node.js dependencies * This runs entirely in the browser/renderer context */ class SimpleLocalServer { constructor() { this.isRunning = false; this.port = 3004; this.connectedClients = new Map(); this.existingSaveData = null; // Check for existing save data on initialization this.loadExistingSaveData(); this.mockData = { servers: [{ id: 'local-server', name: 'Local Singleplayer', description: 'Your personal local server for singleplayer gaming', type: 'private', region: 'local', maxPlayers: 1, currentPlayers: 0, owner: 'Local Player', address: 'localhost', port: this.port, status: 'online', createdAt: new Date().toISOString(), ping: 0 }], user: { id: 'local-user', email: 'local@player.com', username: 'Local Player', token: 'local-token-' + Date.now(), createdAt: new Date().toISOString() } }; console.log('[SIMPLE LOCAL SERVER] SimpleLocalServer initialized'); console.log('[SIMPLE LOCAL SERVER] Existing save data found:', !!this.existingSaveData); } // Mock Socket.IO server for local mode createMockSocket() { console.log('[SIMPLE LOCAL SERVER] Creating mock Socket.IO connection'); const mockSocket = { connected: false, eventHandlers: {}, on: function(event, handler) { console.log(`[MOCKET SOCKET] Registering event handler for: ${event}`); if (!this.eventHandlers[event]) { this.eventHandlers[event] = []; } this.eventHandlers[event].push(handler); }, emit: function(event, data) { console.log(`[MOCKET SOCKET] Emitting event: ${event}`, data); }, connect: function() { console.log('[MOCKET SOCKET] Connecting...'); this.connected = true; // Simulate successful connection setTimeout(() => { if (this.eventHandlers['connect']) { this.eventHandlers['connect'].forEach(handler => handler()); } }, 100); }, disconnect: function() { console.log('[MOCKET SOCKET] Disconnecting...'); this.connected = false; if (this.eventHandlers['disconnect']) { this.eventHandlers['disconnect'].forEach(handler => handler()); } } }; // Auto-connect mockSocket.connect(); return mockSocket; } loadExistingSaveData() { try { const saveData = localStorage.getItem(`gso_save_slot_1`); if (saveData) { this.existingSaveData = JSON.parse(saveData); console.log('[SIMPLE LOCAL SERVER] Loaded existing save data:', { hasPlayerData: !!this.existingSaveData.player, playerLevel: this.existingSaveData.player?.stats?.level, lastSave: this.existingSaveData.lastSave, gameTime: this.existingSaveData.gameTime }); } else { console.log('[SIMPLE LOCAL SERVER] No existing save data found'); } } catch (error) { console.warn('[SIMPLE LOCAL SERVER] Error loading existing save data:', error); this.existingSaveData = null; } } applyExistingSaveDataToGame() { if (!this.existingSaveData || !window.game) { console.log('[SIMPLE LOCAL SERVER] No existing save data or game not available'); return false; } try { console.log('[SIMPLE LOCAL SERVER] Applying existing save data to game...'); // Apply save data to game systems if (this.existingSaveData.player && window.game.systems.player) { window.game.systems.player.load(this.existingSaveData.player); console.log('[SIMPLE LOCAL SERVER] Player data applied'); } if (this.existingSaveData.inventory && window.game.systems.inventory) { window.game.systems.inventory.load(this.existingSaveData.inventory); console.log('[SIMPLE LOCAL SERVER] Inventory data applied'); } if (this.existingSaveData.economy && window.game.systems.economy) { window.game.systems.economy.load(this.existingSaveData.economy); console.log('[SIMPLE LOCAL SERVER] Economy data applied'); } if (this.existingSaveData.idleSystem && window.game.systems.idleSystem) { window.game.systems.idleSystem.load(this.existingSaveData.idleSystem); console.log('[SIMPLE LOCAL SERVER] Idle system data applied'); } if (this.existingSaveData.dungeonSystem && window.game.systems.dungeonSystem) { window.game.systems.dungeonSystem.load(this.existingSaveData.dungeonSystem); console.log('[SIMPLE LOCAL SERVER] Dungeon system data applied'); } if (this.existingSaveData.skillSystem && window.game.systems.skillSystem) { window.game.systems.skillSystem.load(this.existingSaveData.skillSystem); console.log('[SIMPLE LOCAL SERVER] Skill system data applied'); } if (this.existingSaveData.baseSystem && window.game.systems.baseSystem) { window.game.systems.baseSystem.load(this.existingSaveData.baseSystem); console.log('[SIMPLE LOCAL SERVER] Base system data applied'); } if (this.existingSaveData.questSystem && window.game.systems.questSystem) { window.game.systems.questSystem.load(this.existingSaveData.questSystem); console.log('[SIMPLE LOCAL SERVER] Quest system data applied'); } if (this.existingSaveData.gameTime && window.game) { window.game.gameTime = this.existingSaveData.gameTime; console.log('[SIMPLE LOCAL SERVER] Game time applied:', this.existingSaveData.gameTime); } console.log('[SIMPLE LOCAL SERVER] All save data applied successfully'); return true; } catch (error) { console.error('[SIMPLE LOCAL SERVER] Error applying save data to game:', error); return false; } } async start(port = 3004) { if (this.isRunning) { console.log('[SIMPLE LOCAL SERVER] Server is already running on port', this.port); return { success: false, error: 'Server already running' }; } try { this.port = port; this.isRunning = true; // Update mock server data with actual port this.mockData.servers[0].port = port; console.log(`[SIMPLE LOCAL SERVER] Mock local server started on port ${port}`); return { success: true, port: port, url: `http://localhost:${port}` }; } catch (error) { console.error('[SIMPLE LOCAL SERVER] Failed to start server:', error); return { success: false, error: error.message }; } } async stop() { if (!this.isRunning) { console.log('[SIMPLE LOCAL SERVER] Server is not running'); return { success: false, error: 'Server is not running' }; } try { this.isRunning = false; this.connectedClients.clear(); console.log('[SIMPLE LOCAL SERVER] Mock local server stopped'); return { success: true }; } catch (error) { console.error('[SIMPLE LOCAL SERVER] Failed to stop server:', error); return { success: false, error: error.message }; } } getStatus() { return { isRunning: this.isRunning, port: this.port, connectedClients: this.connectedClients.size, uptime: this.isRunning ? 0 : 0 // Mock uptime }; } getUrl() { return this.isRunning ? `http://localhost:${this.port}` : null; } // Mock API methods that simulate server responses async mockRequest(method, url, data = null) { console.log(`[SIMPLE LOCAL SERVER] Mock ${method} ${url}`, data); // Simulate network delay await new Promise(resolve => setTimeout(resolve, 100)); try { if (url === '/health') { return { status: 200, ok: true, headers: { get: (name) => name === 'content-type' ? 'application/json' : null }, json: () => Promise.resolve({ status: 'OK', timestamp: new Date().toISOString(), uptime: 0, mode: 'local' }), text: () => Promise.resolve(JSON.stringify({ status: 'OK', timestamp: new Date().toISOString(), uptime: 0, mode: 'local' })) }; } if (url === '/api/ssc/version') { return { status: 200, ok: true, headers: { get: (name) => name === 'content-type' ? 'application/json' : null }, json: () => Promise.resolve({ version: '1.0.0', service: 'galaxystrikeonline-local-server', timestamp: new Date().toISOString(), mode: 'local' }), text: () => Promise.resolve(JSON.stringify({ version: '1.0.0', service: 'galaxystrikeonline-local-server', timestamp: new Date().toISOString(), mode: 'local' })) }; } if (url === '/api/auth/login' && method === 'POST') { return { status: 200, ok: true, headers: { get: (name) => name === 'content-type' ? 'application/json' : null }, json: () => Promise.resolve({ success: true, user: this.mockData.user, token: this.mockData.user.token, message: 'Logged in to local mode' }), text: () => Promise.resolve(JSON.stringify({ success: true, user: this.mockData.user, token: this.mockData.user.token, message: 'Logged in to local mode' })) }; } if (url === '/api/auth/register' && method === 'POST') { return { status: 201, ok: true, headers: { get: (name) => name === 'content-type' ? 'application/json' : null }, json: () => Promise.resolve({ success: true, user: this.mockData.user, token: this.mockData.user.token, message: 'Registered in local mode' }), text: () => Promise.resolve(JSON.stringify({ success: true, user: this.mockData.user, token: this.mockData.user.token, message: 'Registered in local mode' })) }; } if (url === '/api/servers') { return { status: 200, ok: true, headers: { get: (name) => name === 'content-type' ? 'application/json' : null }, json: () => Promise.resolve({ success: true, servers: this.mockData.servers }), text: () => Promise.resolve(JSON.stringify({ success: true, servers: this.mockData.servers })) }; } if (url.startsWith('/servers/') && url.endsWith('/join') && method === 'POST') { // Mock server join response const serverId = url.split('/')[2]; return { status: 200, ok: true, headers: { get: (name) => name === 'content-type' ? 'application/json' : null }, json: () => Promise.resolve({ success: true, server: { id: serverId, name: 'Local Singleplayer', address: 'localhost', port: this.port, gamePort: this.port + 1, maxPlayers: 1, currentPlayers: 1, status: 'online' }, message: 'Joined server successfully' }), text: () => Promise.resolve(JSON.stringify({ success: true, server: { id: serverId, name: 'Local Singleplayer', address: 'localhost', port: this.port, gamePort: this.port + 1, maxPlayers: 1, currentPlayers: 1, status: 'online' }, message: 'Joined server successfully' })) }; } if (url.startsWith('/api/game/player/') && method === 'GET') { // Return player data from existing save data or localStorage let saveData = this.existingSaveData; // If no existing save data, try localStorage if (!saveData) { try { const localStorageData = localStorage.getItem(`gso_save_slot_1`); if (localStorageData) { saveData = JSON.parse(localStorageData); } } catch (error) { console.warn('[SIMPLE LOCAL SERVER] Could not access localStorage:', error); } } if (saveData) { return { status: 200, ok: true, headers: { get: (name) => name === 'content-type' ? 'application/json' : null }, json: () => Promise.resolve({ success: true, player: saveData.player }), text: () => Promise.resolve(JSON.stringify({ success: true, player: saveData.player })) }; } else { return { status: 404, ok: false, headers: { get: (name) => name === 'content-type' ? 'application/json' : null }, json: () => Promise.resolve({ success: false, error: 'No save data found' }), text: () => Promise.resolve(JSON.stringify({ success: false, error: 'No save data found' })) }; } } if (url.startsWith('/api/game/player/') && method === 'POST') { // Save player data to localStorage try { let existingSaveData = '{}'; if (typeof localStorage !== 'undefined') { existingSaveData = localStorage.getItem(`gso_save_slot_1`) || '{}'; } const parsedExisting = JSON.parse(existingSaveData); parsedExisting.player = data; parsedExisting.lastSave = Date.now(); if (typeof localStorage !== 'undefined') { localStorage.setItem(`gso_save_slot_1`, JSON.stringify(parsedExisting)); } return { status: 200, ok: true, headers: { get: (name) => name === 'content-type' ? 'application/json' : null }, json: () => Promise.resolve({ success: true, message: 'Player data saved locally' }), text: () => Promise.resolve(JSON.stringify({ success: true, message: 'Player data saved locally' })) }; } catch (error) { return { status: 500, ok: false, headers: { get: (name) => name === 'content-type' ? 'application/json' : null }, json: () => Promise.resolve({ success: false, error: 'Failed to save player data' }), text: () => Promise.resolve(JSON.stringify({ success: false, error: 'Failed to save player data' })) }; } } // Default response for unknown endpoints return { status: 404, ok: false, headers: { get: (name) => name === 'content-type' ? 'application/json' : null }, json: () => Promise.resolve({ success: false, error: 'Endpoint not found' }), text: () => Promise.resolve(JSON.stringify({ success: false, error: 'Endpoint not found' })) }; } catch (error) { console.error('[SIMPLE LOCAL SERVER] Mock request error:', error); return { status: 500, ok: false, headers: { get: (name) => name === 'content-type' ? 'application/json' : null }, json: () => Promise.resolve({ success: false, error: 'Internal server error' }), text: () => Promise.resolve(JSON.stringify({ success: false, error: 'Internal server error' })) }; } } } // Export for use in browser environment if (typeof window !== 'undefined') { window.SimpleLocalServer = SimpleLocalServer; } console.log('[SIMPLE LOCAL SERVER] SimpleLocalServer loaded and exported to window');