const { app, BrowserWindow, session, shell, desktopCapturer, autoUpdater, dialog, ipcMain } = require('electron'); const path = require('path'); 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'; function setupAutoUpdater() { if (process.platform !== 'win32') return; const updateURL = `${HUB_URL}/updates`; try { autoUpdater.setFeedURL({ url: updateURL }); } catch (e) { console.error('[AutoUpdater] setFeedURL failed:', e.message); return; } autoUpdater.on('update-available', () => { console.log('[AutoUpdater] Update available, downloading...'); }); autoUpdater.on('update-downloaded', (_event, releaseNotes, releaseName) => { console.log('[AutoUpdater] Update downloaded:', releaseName || 'new version'); if (mainWindow) mainWindow.webContents.send('update-ready'); }); // Handle install-update request from renderer ipcMain.on('install-update', () => { autoUpdater.quitAndInstall(); }); autoUpdater.on('update-not-available', () => { console.log('[AutoUpdater] App is up to date.'); }); autoUpdater.on('error', (err) => { console.error('[AutoUpdater] Error:', err.message); }); // Check for updates after 5 seconds, then every 30 minutes setTimeout(() => { try { autoUpdater.checkForUpdates(); } catch (e) { console.error('[AutoUpdater]', e.message); } }, 5000); setInterval(() => { 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 session.defaultSession.setDisplayMediaRequestHandler((_request, callback) => { desktopCapturer.getSources({ types: ['screen', 'window'] }).then((sources) => { callback({ video: sources[0], audio: 'loopback' }); }); }); // Custom User-Agent to identify Electron app const currentUA = mainWindow.webContents.getUserAgent(); mainWindow.webContents.setUserAgent(currentUA + ' GamingHubDesktop/1.5.0'); mainWindow.loadURL(HUB_URL); // Open external links in default browser mainWindow.webContents.setWindowOpenHandler(({ url }) => { if (!url.startsWith(HUB_URL)) { shell.openExternal(url); return { action: 'deny' }; } return { action: 'allow' }; }); // Handle navigation to external URLs mainWindow.webContents.on('will-navigate', (event, url) => { if (!url.startsWith(HUB_URL)) { event.preventDefault(); shell.openExternal(url); } }); // Track streaming status from renderer (synchronous — no async race) let isStreaming = false; ipcMain.on('streaming-status', (_event, active) => { isStreaming = active; }); // Warn before closing if a stream is active mainWindow.on('close', (event) => { if (!isStreaming) return; const result = dialog.showMessageBoxSync(mainWindow, { type: 'warning', buttons: ['Beenden', 'Abbrechen'], defaultId: 1, cancelId: 1, title: 'Stream laeuft noch!', message: 'Ein Stream ist noch aktiv.\nBeim Beenden wird der Stream gestoppt.', }); if (result !== 0) event.preventDefault(); }); } app.whenReady().then(() => { createWindow(); setupAutoUpdater(); }); app.on('window-all-closed', () => { if (process.platform !== 'darwin') app.quit(); }); app.on('activate', () => { if (BrowserWindow.getAllWindows().length === 0) createWindow(); });