const { app, BrowserWindow, session, shell, desktopCapturer, autoUpdater, dialog, ipcMain, Notification } = require('electron'); const path = require('path'); const fs = require('fs'); const os = require('os'); const { setupAdBlocker } = require('./ad-blocker'); // Handle Squirrel events (Windows installer) try { if (require('electron-squirrel-startup')) app.quit(); } catch { // electron-squirrel-startup not installed, skip } const HUB_URL = process.env.GAMING_HUB_URL || 'https://hub.daddelolymp.de'; // Auto-Updates laufen über HUB_URL — /downloads ist per Pangolin-Rule ohne Auth erreichbar const APP_VERSION = app.getVersion(); // Sync IPC: preload reads app version from package.json ipcMain.on('get-app-version', (event) => { event.returnValue = APP_VERSION; }); function setupAutoUpdater() { if (process.platform !== 'win32') return; // Squirrel.Windows appends /RELEASES to the feed URL. // /downloads ist per Pangolin-Rule ohne Auth erreichbar (Squirrel hat keine Browser-Session). const updateURL = `${HUB_URL}/downloads`; try { autoUpdater.setFeedURL({ url: updateURL }); } catch (e) { console.error('[AutoUpdater] setFeedURL failed:', e.message); return; } // State-Tracking: verhindert Doppelstarts und bewahrt Status let updateState = 'idle'; // idle | checking | downloading | ready autoUpdater.on('checking-for-update', () => { console.log('[AutoUpdater] Checking for updates...'); updateState = 'checking'; }); autoUpdater.on('update-available', () => { console.log('[AutoUpdater] Update available, downloading...'); updateState = 'downloading'; if (mainWindow) mainWindow.webContents.send('update-available'); }); autoUpdater.on('update-downloaded', (_event, releaseNotes, releaseName) => { console.log('[AutoUpdater] Update downloaded:', releaseName || 'new version'); updateState = 'ready'; if (mainWindow) mainWindow.webContents.send('update-ready'); }); autoUpdater.on('update-not-available', () => { console.log('[AutoUpdater] App is up to date.'); updateState = 'idle'; if (mainWindow) mainWindow.webContents.send('update-not-available'); }); autoUpdater.on('error', (err) => { console.error('[AutoUpdater] Error:', err.message); updateState = 'idle'; if (mainWindow) mainWindow.webContents.send('update-error', err.message); }); // Handle install-update request from renderer ipcMain.on('install-update', () => { autoUpdater.quitAndInstall(); }); // Manual check from renderer — gibt aktuellen Status zurück statt Doppelstart ipcMain.on('check-for-updates', () => { if (updateState === 'downloading') { if (mainWindow) mainWindow.webContents.send('update-available'); return; } if (updateState === 'ready') { if (mainWindow) mainWindow.webContents.send('update-ready'); return; } if (updateState === 'checking') { return; // bereits am Prüfen } try { autoUpdater.checkForUpdates(); } catch (e) { console.error('[AutoUpdater]', e.message); } }); // Sync-Abfrage: Frontend kann aktuellen Status beim Modal-Öffnen abfragen ipcMain.on('get-update-status', (event) => { event.returnValue = updateState; }); // Auto-Check nach 5 Sek, dann alle 30 Min (nur wenn idle) setTimeout(() => { if (updateState === 'idle') { try { autoUpdater.checkForUpdates(); } catch (e) { console.error('[AutoUpdater]', e.message); } } }, 5000); setInterval(() => { if (updateState === 'idle') { try { autoUpdater.checkForUpdates(); } catch (e) { console.error('[AutoUpdater]', e.message); } } }, 30 * 60 * 1000); } let mainWindow; function createWindow() { mainWindow = new BrowserWindow({ width: 1400, height: 900, minWidth: 900, minHeight: 600, title: 'Gaming Hub', icon: path.join(__dirname, 'assets', 'icon.png'), webPreferences: { preload: path.join(__dirname, 'preload.js'), contextIsolation: true, nodeIntegration: false, }, backgroundColor: '#1a1b1e', autoHideMenuBar: true, }); // Setup ad blocker BEFORE loading URL setupAdBlocker(session.defaultSession); // Enable screen capture (getDisplayMedia) in Electron — always show picker // IPC channel for picker result const PICKER_CHANNEL = 'screen-picker-result'; session.defaultSession.setDisplayMediaRequestHandler(async (_request, callback) => { const sources = await desktopCapturer.getSources({ types: ['screen', 'window'], thumbnailSize: { width: 320, height: 180 } }); if (sources.length === 0) { callback({}); return; } const sourceData = sources.map(s => ({ id: s.id, name: s.name, thumbnail: s.thumbnail.toDataURL(), })); // Write picker HTML to a temp file (data: URLs are blocked in Electron) const pickerHtml = `
${result.profileName}: ${result.gameCount} Spiele geladen.
${(result && result.error) || 'Unbekannter Fehler'}
GOG-Verbindung fehlgeschlagen.