/** * Galaxy Strike Online - Main Entry Point * Initializes and starts the game */ console.log('[MAIN] main.js script loaded'); // Wait for DOM to be loaded document.addEventListener('DOMContentLoaded', async () => { const debugLogger = window.debugLogger; if (debugLogger) debugLogger.startStep('main.domContentLoaded', { timestamp: new Date().toISOString(), userAgent: navigator.userAgent, url: window.location.href }); const loadingIndicator = document.getElementById('loadingIndicator'); const loadingStatus = document.getElementById('loadingStatus'); if (debugLogger) debugLogger.logStep('DOM elements found', { loadingIndicator: !!loadingIndicator, loadingStatus: !!loadingStatus }); try { // Start debug logging if (window.debugLogger) { window.debugLogger.startStep('domLoad'); window.debugLogger.logStep('DOM loaded, starting initialization'); } // Show loading indicator if (loadingIndicator) loadingIndicator.classList.remove('hidden'); if (loadingStatus) { loadingStatus.textContent = 'Initializing application...'; loadingStatus.classList.remove('hidden'); } if (debugLogger) debugLogger.logStep('Loading indicator shown'); // Initialize title bar controls immediately (don't wait for DOMContentLoaded) console.log('[MAIN] Initializing title bar controls immediately'); if (debugLogger) debugLogger.logStep('Initializing title bar controls'); initializeTitleBar(); // Wait for DOM to be ready document.addEventListener('DOMContentLoaded', async () => { if (debugLogger) debugLogger.startStep('main.secondDOMContentLoaded', { timestamp: new Date().toISOString() }); window.debugLogger.startStep('domLoad'); window.debugLogger.logStep('DOM loaded, starting initialization'); // Auto-start local server for singleplayer mode (DISABLED to prevent auto-start after multiplayer disconnect) console.log('[MAIN] Skipping local server auto-start to prevent conflicts with multiplayer mode'); /* if (window.localServerManager) { try { const serverResult = await window.localServerManager.autoStartIfSingleplayer(); if (serverResult.success) { console.log('[MAIN] Local server started successfully:', serverResult); if (debugLogger) debugLogger.logStep('Local server auto-started', { port: serverResult.port, url: serverResult.url }); } else { console.log('[MAIN] Local server not started:', serverResult.reason || serverResult.error); if (debugLogger) debugLogger.logStep('Local server not started', { reason: serverResult.reason || serverResult.error }); } } catch (error) { console.error('[MAIN] Error starting local server:', error); if (debugLogger) debugLogger.errorEvent(error, 'Local server startup'); } } else { console.warn('[MAIN] LocalServerManager not available'); } */ // Title bar is already initialized, just log it console.log('[MAIN] DOM loaded - title bar should already be working'); if (debugLogger) debugLogger.logStep('DOM loaded - title bar should be working'); // Show main menu instead of directly loading game if (loadingStatus) { loadingStatus.textContent = 'Ready'; loadingStatus.classList.add('hidden'); } if (debugLogger) debugLogger.logStep('Loading status updated to Ready'); // Hide loading screen and show main menu const loadingScreen = document.getElementById('loadingScreen'); const mainMenu = document.getElementById('mainMenu'); if (loadingScreen) loadingScreen.classList.add('hidden'); if (mainMenu) mainMenu.classList.remove('hidden'); if (debugLogger) debugLogger.logStep('Loading screen hidden, main menu shown', { loadingScreenFound: !!loadingScreen, mainMenuFound: !!mainMenu, liveMainMenuReady: !!window.liveMainMenu }); // The LiveMainMenu will initialize itself and handle authentication console.log('[MAIN] Main menu displayed - LiveMainMenu will handle authentication and server browsing'); if (debugLogger) debugLogger.endStep('main.secondDOMContentLoaded', { success: true, mainMenuDisplayed: !!mainMenu }); }); if (debugLogger) debugLogger.endStep('main.domContentLoaded', { success: true, titleBarInitialized: true }); } catch (error) { console.error('Failed to initialize game:', error); if (debugLogger) debugLogger.errorEvent('main.domContentLoaded', error, { phase: 'initialization', timestamp: new Date().toISOString() }); if (window.debugLogger) { window.debugLogger.log('CRITICAL ERROR: Initialization failed', { error: error.message, stack: error.stack, timestamp: new Date().toISOString() }); } // Show error state if (loadingIndicator) loadingIndicator.classList.add('error'); if (loadingStatus) { loadingStatus.textContent = 'Failed to load application'; loadingStatus.classList.add('error'); } if (debugLogger) debugLogger.logStep('Error state displayed'); const logger = window.logger; if (logger) { await logger.errorEvent(error, 'Main.js Initialization'); } if (debugLogger) debugLogger.endStep('main.domContentLoaded', { success: false, error: error.message }); } }); // Initialize title bar controls function initializeTitleBar() { const debugLogger = window.debugLogger; if (debugLogger) debugLogger.startStep('main.initializeTitleBar', { timestamp: new Date().toISOString(), electronAPIAvailable: !!window.electronAPI }); console.log('[TITLE BAR] Starting title bar initialization'); // Wait for both electronAPI and DOM elements to be available const checkReady = () => { const hasElectronAPI = !!window.electronAPI; const hasMinimizeBtn = !!document.getElementById('minimizeBtn'); const hasCloseBtn = !!document.getElementById('closeBtn'); const hasFullscreenBtn = !!document.getElementById('fullscreenBtn'); const readyState = { hasElectronAPI, hasMinimizeBtn, hasCloseBtn, hasFullscreenBtn }; console.log(`[TITLE BAR] electronAPI: ${hasElectronAPI}, minimizeBtn: ${hasMinimizeBtn}, closeBtn: ${hasCloseBtn}, fullscreenBtn: ${hasFullscreenBtn}`); if (debugLogger) debugLogger.logStep('Title bar readiness check', readyState); if (hasElectronAPI && hasMinimizeBtn && hasCloseBtn && hasFullscreenBtn) { console.log('[TITLE BAR] All elements ready, setting up events'); if (debugLogger) debugLogger.logStep('All title bar elements ready, setting up events'); setupTitleBarEvents(); // Hide the "Initializing application..." text since title bar is now working const loadingStatus = document.getElementById('loadingStatus'); if (loadingStatus && loadingStatus.textContent === 'Initializing application...') { console.log('[TITLE BAR] Hiding initializing text'); loadingStatus.classList.add('hidden'); if (debugLogger) debugLogger.logStep('Hiding initializing text'); } if (debugLogger) debugLogger.endStep('main.initializeTitleBar', { success: true, allElementsReady: true }); } else { if (debugLogger) debugLogger.logStep('Not all elements ready, retrying in 50ms', { missingElements: Object.keys(readyState).filter(key => !readyState[key]) }); setTimeout(checkReady, 50); } }; checkReady(); } function setupTitleBarEvents() { const debugLogger = window.debugLogger; if (debugLogger) debugLogger.startStep('main.setupTitleBarEvents'); const minimizeBtn = document.getElementById('minimizeBtn'); const closeBtn = document.getElementById('closeBtn'); const fullscreenBtn = document.getElementById('fullscreenBtn'); console.log('[TITLE BAR] Setting up event listeners'); if (debugLogger) debugLogger.logStep('Title bar buttons found', { minimizeBtn: !!minimizeBtn, closeBtn: !!closeBtn, fullscreenBtn: !!fullscreenBtn }); let eventsSetup = 0; if (minimizeBtn) { console.log('[TITLE BAR] Adding minimize button listener'); if (debugLogger) debugLogger.logStep('Setting up minimize button listener'); minimizeBtn.addEventListener('click', (e) => { console.log('[TITLE BAR] Minimize button clicked'); if (debugLogger) debugLogger.log('Title bar minimize button clicked'); e.preventDefault(); e.stopPropagation(); if (window.electronAPI && window.electronAPI.minimize) { window.electronAPI.minimize(); if (debugLogger) debugLogger.logStep('Window minimized via electronAPI'); } else { console.error('[TITLE BAR] electronAPI not available when minimize clicked'); if (debugLogger) debugLogger.log('electronAPI not available for minimize'); } }); eventsSetup++; } else { console.error('[TITLE BAR] Minimize button not found during setup'); if (debugLogger) debugLogger.log('Minimize button not found'); } if (closeBtn) { console.log('[TITLE BAR] Adding close button listener'); if (debugLogger) debugLogger.logStep('Setting up close button listener'); closeBtn.addEventListener('click', (e) => { console.log('[TITLE BAR] Close button clicked'); if (debugLogger) debugLogger.log('Title bar close button clicked'); e.preventDefault(); // ... rest of the code remains the same ... e.stopPropagation(); if (window.electronAPI && window.electronAPI.closeWindow) { window.electronAPI.closeWindow(); if (debugLogger) debugLogger.logStep('Window closed via electronAPI'); } else { console.error('[TITLE BAR] electronAPI not available when close clicked'); if (debugLogger) debugLogger.log('electronAPI not available for close'); } }); eventsSetup++; } else { console.error('[TITLE BAR] Close button not found during setup'); if (debugLogger) debugLogger.log('Close button not found'); } if (fullscreenBtn) { console.log('[TITLE BAR] Adding fullscreen button listener'); if (debugLogger) debugLogger.logStep('Setting up fullscreen button listener'); fullscreenBtn.addEventListener('click', (e) => { console.log('[TITLE BAR] Fullscreen button clicked'); if (debugLogger) debugLogger.log('Title bar fullscreen button clicked'); e.preventDefault(); e.stopPropagation(); if (window.electronAPI && window.electronAPI.toggleFullscreen) { window.electronAPI.toggleFullscreen(); if (debugLogger) debugLogger.logStep('Fullscreen toggled via electronAPI'); // Toggle fullscreen class on body document.body.classList.toggle('fullscreen'); document.body.classList.toggle('fullscreen'); // Update icon const icon = fullscreenBtn.querySelector('i'); if (document.body.classList.contains('fullscreen')) { icon.className = 'fas fa-compress'; if (debugLogger) debugLogger.logStep('Fullscreen mode activated, icon changed to compress'); } else { icon.className = 'fas fa-expand'; if (debugLogger) debugLogger.logStep('Fullscreen mode deactivated, icon changed to expand'); } } else { console.error('[TITLE BAR] electronAPI not available when fullscreen clicked'); if (debugLogger) debugLogger.log('electronAPI not available for fullscreen'); } }); eventsSetup++; } else { console.error('[TITLE BAR] Fullscreen button not found during setup'); if (debugLogger) debugLogger.log('Fullscreen button not found'); } console.log('[TITLE BAR] Event listeners setup complete'); if (debugLogger) debugLogger.endStep('main.setupTitleBarEvents', { eventsSetup: eventsSetup, totalExpectedEvents: 3 }); } // Global utility functions for onclick handlers window.game = null; // Error handling window.addEventListener('error', (event) => { console.error('Game error:', event.error); if (window.game) { window.game.showNotification('An error occurred. Please refresh the page.', 'error', 5000); } }); // Shutdown handler for debug logging window.addEventListener('beforeunload', async () => { if (window.debugLogger) { try { await window.debugLogger.shutdown(); } catch (error) { console.error('[MAIN] Failed to shutdown debug logger:', error); } } }); // Performance monitoring if (window.performance && window.performance.memory) { setInterval(() => { if (window.game && window.game.isRunning) { const stats = window.game.getPerformanceStats(); if (stats.memory && stats.memory.used / stats.memory.limit > 0.8) { console.warn('High memory usage detected:', stats.memory); } } }, 30000); // Check every 30 seconds } // Global console functions function toggleConsole() { console.log('[DEBUG] toggleConsole called'); const consoleWindow = document.getElementById('consoleWindow'); const consoleInput = document.getElementById('consoleInput'); console.log('[DEBUG] consoleWindow element:', consoleWindow); console.log('[DEBUG] consoleInput element:', consoleInput); if (!consoleWindow) { console.error('[DEBUG] consoleWindow element not found!'); return; } if (consoleWindow.style.display === 'flex') { consoleWindow.style.display = 'none'; console.log('[DEBUG] Console hidden'); } else { consoleWindow.style.display = 'flex'; console.log('[DEBUG] Console shown'); if (consoleInput) { consoleInput.focus(); } } } function handleConsoleInput(event) { if (event.key === 'Enter') { const input = event.target; const command = input.value.trim(); if (command) { executeConsoleCommand(command); input.value = ''; } } } function executeConsoleCommand(command) { const output = document.getElementById('consoleOutput'); const commandLine = document.createElement('div'); commandLine.className = 'console-line'; commandLine.textContent = `> ${command}`; output.appendChild(commandLine); // Log command to file and browser console console.log(`[CONSOLE] Command: ${command}`); if (window.logger) { window.logger.playerAction('Console Command', { command: command }); } try { const result = processCommand(command); const resultLine = document.createElement('div'); resultLine.className = `console-line ${result.type || 'success'}`; // Convert line breaks to HTML for proper rendering resultLine.innerHTML = result.message.replace(/\n/g, '
'); output.appendChild(resultLine); // Log result to file and browser console const consoleMethod = result.type === 'error' ? console.error : result.type === 'info' ? console.info : console.log; consoleMethod(`[CONSOLE] Result (${result.type}): ${result.message.replace(/\n/g, ' ')}`); if (window.logger) { window.logger.playerAction('Console Result', { command: command, result: result.type, message: result.message }); } } catch (error) { const errorLine = document.createElement('div'); errorLine.className = 'console-line console-error'; errorLine.textContent = `Error: ${error.message}`; output.appendChild(errorLine); // Log error to file and browser console console.error(`[CONSOLE] Error: ${error.message}`); if (window.logger) { window.logger.errorEvent(error, 'Console Command', { command: command }); } } // Scroll to bottom output.scrollTop = output.scrollHeight; } function processCommand(command) { const parts = command.split(' '); const cmd = parts[0].toLowerCase(); const args = parts.slice(1); switch (cmd) { case 'help': return { type: 'info', message: `Available commands:\nhelp - Show this help message\nclear - Clear console output\ncoins - Add coins to player (e.g., "coins 1000")\ngems - Add gems to player (e.g., "gems 100")\nresearch - Add research points (e.g., "research 500")\ncraftingxp - Add crafting experience (e.g., "craftingxp 200")\ngiveitem - Add item to inventory (e.g., "giveitem iron_ore 10")\nhealth - Set current ship health (e.g., "health 150")\nlevel - Set current ship level (e.g., "level 5")\nunlock - Unlock a ship (e.g., "unlock heavy_fighter")\nstats - Show current player stats\nships - List all ships\ncurrent - Show current ship info` }; case 'clear': const output = document.getElementById('consoleOutput'); output.innerHTML = ''; return { type: 'success', message: 'Console cleared' }; case 'coins': if (args.length === 0) { return { type: 'error', message: 'Usage: coins ' }; } const amount = parseInt(args[0]); if (isNaN(amount)) { return { type: 'error', message: 'Invalid amount' }; } if (window.game && window.game.systems && window.game.systems.economy) { window.game.systems.economy.addCredits(amount, 'console'); window.game.systems.economy.updateUI(); return { type: 'success', message: `Added ${amount} credits` }; } return { type: 'error', message: 'Economy system not available' }; case 'gems': if (args.length === 0) { return { type: 'error', message: 'Usage: gems ' }; } const gemAmount = parseInt(args[0]); if (isNaN(gemAmount)) { return { type: 'error', message: 'Invalid amount' }; } if (window.game && window.game.systems && window.game.systems.economy) { window.game.systems.economy.addGems(gemAmount, 'console'); window.game.systems.economy.updateUI(); return { type: 'success', message: `Added ${gemAmount} gems` }; } return { type: 'error', message: 'Economy system not available' }; case 'research': if (args.length === 0) { return { type: 'error', message: 'Usage: research ' }; } const researchAmount = parseInt(args[0]); if (isNaN(researchAmount)) { return { type: 'error', message: 'Invalid amount' }; } if (window.game && window.game.systems && window.game.systems.player) { const currentSkillPoints = window.game.systems.player.stats.skillPoints || 0; window.game.systems.player.stats.skillPoints = currentSkillPoints + researchAmount; window.game.systems.player.updateUI(); // Also update skill system UI if (window.game.systems.skillSystem) { window.game.systems.skillSystem.updateUI(); } return { type: 'success', message: `Added ${researchAmount} skill points (Total: ${window.game.systems.player.stats.skillPoints})` }; } return { type: 'error', message: 'Player system not available' }; case 'craftingxp': if (args.length === 0) { return { type: 'error', message: 'Usage: craftingxp ' }; } const craftingXpAmount = parseInt(args[0]); if (isNaN(craftingXpAmount)) { return { type: 'error', message: 'Invalid amount' }; } if (window.game && window.game.systems && window.game.systems.skillSystem) { window.game.systems.skillSystem.awardCraftingExperience(craftingXpAmount); const currentLevel = window.game.systems.skillSystem.getSkillLevel('crafting'); const currentExp = window.game.systems.skillSystem.getSkillExperience('crafting'); return { type: 'success', message: `Added ${craftingXpAmount} crafting experience (Level: ${currentLevel}, XP: ${currentExp})` }; } return { type: 'error', message: 'Skill system not available' }; case 'giveitem': if (args.length < 2) { return { type: 'error', message: 'Usage: giveitem ' }; } const itemId = args[0]; const quantity = parseInt(args[1]); if (isNaN(quantity)) { return { type: 'error', message: 'Invalid quantity' }; } if (window.game && window.game.systems && window.game.systems.inventory) { window.game.systems.inventory.addItem(itemId, quantity); window.game.systems.ui.updateInventory(); return { type: 'success', message: `Added ${quantity}x ${itemId} to inventory` }; } return { type: 'error', message: 'Inventory system not available' }; case 'health': if (args.length === 0) { return { type: 'error', message: 'Usage: health ' }; } const healthAmount = parseInt(args[0]); if (isNaN(healthAmount)) { return { type: 'error', message: 'Invalid amount' }; } if (window.game && window.game.systems && window.game.systems.ship) { const currentShip = window.game.systems.ship.currentShip; if (currentShip) { currentShip.health = Math.min(healthAmount, currentShip.maxHealth); window.game.systems.ship.updateCurrentShipDisplay(); return { type: 'success', message: `Set ship health to ${currentShip.health}/${currentShip.maxHealth}` }; } } return { type: 'error', message: 'Ship system not available' }; case 'level': if (args.length === 0) { return { type: 'error', message: 'Usage: level ' }; } const levelAmount = parseInt(args[0]); if (isNaN(levelAmount)) { return { type: 'error', message: 'Invalid level' }; } if (window.game && window.game.systems && window.game.systems.player) { window.game.systems.player.stats.level = levelAmount; window.game.systems.player.updateTitle(); window.game.systems.player.updateUI(); return { type: 'success', message: `Set player level to ${levelAmount}` }; } return { type: 'error', message: 'Player system not available' }; case 'unlock': if (args.length === 0) { return { type: 'error', message: 'Usage: unlock ' }; } const shipId = args[0]; if (window.game && window.game.systems && window.game.systems.ship) { const ship = window.game.systems.ship.ships.find(s => s.id === shipId); if (ship) { ship.status = 'inactive'; window.game.systems.ship.renderShips(); return { type: 'success', message: `Unlocked ship: ${ship.name}` }; } else { return { type: 'error', message: `Ship not found: ${shipId}` }; } } return { type: 'error', message: 'Ship system not available' }; case 'stats': if (window.game && window.game.systems && window.game.systems.player && window.game.systems.economy) { const player = window.game.systems.player; const economy = window.game.systems.economy; return { type: 'info', message: `Player Stats:\nLevel: ${player.stats.level}\nExperience: ${player.stats.experience}/${player.stats.experienceToNext}\nCredits: ${economy.credits}\nGems: ${economy.gems}\nTotal Kills: ${player.stats.totalKills}\nDungeons Cleared: ${player.stats.dungeonsCleared}\nTitle: ${player.info.title}` }; } return { type: 'error', message: 'Player or Economy system not available' }; case 'ships': if (window.game && window.game.systems && window.game.systems.ship) { const ships = window.game.systems.ship.ships; const currentShip = window.game.systems.ship.currentShip; const shipList = ships.map(ship => `- ${ship.name} (${ship.id}) - Level ${ship.level} - ${ship.status} - ${ship.rarity}${currentShip.id === ship.id ? ' [CURRENT]' : ''}` ).join('\n'); return { type: 'info', message: `Available Ships:\n${shipList}` }; } return { type: 'error', message: 'Ship system not available' }; case 'current': if (window.game && window.game.systems && window.game.systems.ship) { const currentShip = window.game.systems.ship.currentShip; if (currentShip) { return { type: 'info', message: `Current Ship: - Name: ${currentShip.name} - Class: ${currentShip.class} - Level: ${currentShip.level} - Health: ${currentShip.health}/${currentShip.maxHealth} - Attack: ${currentShip.attack} - Defense: ${currentShip.defense} - Speed: ${currentShip.speed} - Rarity: ${currentShip.rarity}` }; } } return { type: 'error', message: 'Ship system not available' }; default: return { type: 'error', message: `Unknown command: ${cmd}. Type 'help' for available commands.` }; } } // Keyboard shortcut listener document.addEventListener('DOMContentLoaded', function() { console.log('[DEBUG] DOMContentLoaded event fired for keyboard shortcuts'); document.addEventListener('keydown', function(event) { // Log all key combinations for debugging if (event.ctrlKey || event.altKey || event.shiftKey) { console.log('[DEBUG] Key pressed:', { key: event.key, ctrlKey: event.ctrlKey, altKey: event.altKey, shiftKey: event.shiftKey, code: event.code }); } // Ctrl+Alt+Shift+C to toggle console if (event.ctrlKey && event.altKey && event.shiftKey && event.key === 'C') { console.log('[DEBUG] Ctrl+Alt+Shift+C detected!'); event.preventDefault(); // Check if toggleConsole function exists if (typeof toggleConsole === 'function') { console.log('[DEBUG] toggleConsole function exists, calling it'); toggleConsole(); } else { console.error('[DEBUG] toggleConsole function not found!'); } } // Escape to close console if (event.key === 'Escape') { const consoleWindow = document.getElementById('consoleWindow'); if (consoleWindow && consoleWindow.style.display === 'flex') { consoleWindow.style.display = 'none'; } } }); }); // Initialize console output with welcome message document.addEventListener('DOMContentLoaded', function() { const output = document.getElementById('consoleOutput'); if (output) { const welcomeLine = document.createElement('div'); welcomeLine.className = 'console-line console-info'; welcomeLine.textContent = 'Developer Console ready. Type "help" for available commands.'; output.appendChild(welcomeLine); } });