diff --git a/electron/main.js b/electron/main.js index ef27fe3..134c29e 100644 --- a/electron/main.js +++ b/electron/main.js @@ -1,4 +1,4 @@ -const { app, BrowserWindow, session, shell, desktopCapturer } = require('electron'); +const { app, BrowserWindow, session, shell, desktopCapturer, autoUpdater } = require('electron'); const path = require('path'); const { setupAdBlocker } = require('./ad-blocker'); @@ -11,6 +11,43 @@ try { 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'); + }); + + 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() { @@ -64,7 +101,10 @@ function createWindow() { }); } -app.whenReady().then(createWindow); +app.whenReady().then(() => { + createWindow(); + setupAutoUpdater(); +}); app.on('window-all-closed', () => { if (process.platform !== 'darwin') app.quit(); diff --git a/electron/preload.js b/electron/preload.js index 081d511..fedd04e 100644 --- a/electron/preload.js +++ b/electron/preload.js @@ -1,6 +1,9 @@ -const { contextBridge } = require('electron'); +const { contextBridge, ipcRenderer } = require('electron'); contextBridge.exposeInMainWorld('electronAPI', { isElectron: true, version: '1.5.0', + onUpdateAvailable: (callback) => ipcRenderer.on('update-available', callback), + onUpdateReady: (callback) => ipcRenderer.on('update-ready', callback), + installUpdate: () => ipcRenderer.send('install-update'), }); diff --git a/server/src/index.ts b/server/src/index.ts index e8f838a..9abcbae 100644 --- a/server/src/index.ts +++ b/server/src/index.ts @@ -1,5 +1,6 @@ import express from 'express'; import path from 'node:path'; +import { readFile } from 'node:fs/promises'; import http from 'node:http'; import { WebSocketServer } from 'ws'; import { Client } from 'discord.js'; @@ -154,6 +155,18 @@ async function boot(): Promise { } } + // Squirrel.Windows auto-update feed + app.get('/updates', async (_req, res) => { + try { + const releasesPath = path.join(DATA_DIR, 'downloads', 'RELEASES'); + const data = await readFile(releasesPath, 'utf-8'); + res.set('Content-Type', 'application/octet-stream'); + res.send(data); + } catch { + res.status(204).end(); + } + }); + // Serve download files (Electron installer etc.) const downloadsDir = path.join(DATA_DIR, 'downloads'); app.use('/downloads', express.static(downloadsDir));