Files
Fractured/tools/fractured-launcher-electron/lib/auto-update.js
T

112 lines
3.4 KiB
JavaScript

'use strict';
const { dialog } = require('electron');
const { autoUpdater } = require('electron-updater');
/**
* @param {import('electron').App} app
* @param {() => import('electron').BrowserWindow | null} getMainWindow
* @param {{ updateFeedUrl?: string, githubOwner?: string, githubRepo?: string, token?: string }} opts
*/
function setupAutoUpdater(app, getMainWindow, opts = {}) {
if (!app.isPackaged) {
return {
checkNow: async () => ({ skipped: true, reason: 'development build' }),
};
}
autoUpdater.autoDownload = true;
autoUpdater.autoInstallOnAppQuit = true;
const token = String(opts.token || '').trim();
const envGeneric = String(process.env.LAUNCHER_UPDATE_URL || '').trim();
const configGeneric = String(opts.updateFeedUrl || '').trim();
const genericUrl = envGeneric || configGeneric;
const owner = String(opts.githubOwner || 'Dawnforger').trim();
const repo = String(opts.githubRepo || 'Fractured').trim();
if (genericUrl) {
const base = genericUrl.replace(/\/?$/, '/');
autoUpdater.setFeedURL({
provider: 'generic',
url: base,
});
if (token) {
autoUpdater.requestHeaders = {
...autoUpdater.requestHeaders,
Authorization: `Bearer ${token}`,
};
}
} else if (token && owner && repo) {
autoUpdater.setFeedURL({
provider: 'github',
owner,
repo,
private: true,
token,
});
}
const send = (msg) => {
const w = getMainWindow();
if (w && !w.isDestroyed()) {
w.webContents.send('launcher:progress', msg);
}
};
autoUpdater.on('checking-for-update', () => send('Checking for launcher updates…'));
autoUpdater.on('update-available', (info) => {
send(`Launcher update available: ${info.version}`);
});
autoUpdater.on('update-not-available', () => {});
autoUpdater.on('error', (err) => {
const m = (err && (err.message || String(err))) || '';
if (/404|releases\.atom|HttpError:\s*404/i.test(m)) {
send(
'Launcher update: could not read GitHub releases (404). ' +
'If the repo is private, set GITHUB_TOKEN (or your token_env) so the launcher can authenticate, ' +
'or set update_feed_url in launcher.json to a public HTTPS folder that contains latest.yml.'
);
return;
}
if (m && !/net::ERR|ENOTFOUND|ETIMEDOUT/i.test(m)) {
send(`Launcher update: ${m.slice(0, 400)}`);
}
});
autoUpdater.on('download-progress', (p) => {
const pct = Math.round(p.percent || 0);
send(`Launcher update download: ${pct}%`);
});
autoUpdater.on('update-downloaded', async (info) => {
const win = getMainWindow();
const r = await dialog.showMessageBox(win || undefined, {
type: 'info',
title: 'Launcher update',
message: `Version ${info.version} is ready to install.`,
detail: 'Restart the launcher now to finish. You can finish patching WoW after restart.',
buttons: ['Restart now', 'Later'],
defaultId: 0,
cancelId: 1,
noLink: true,
});
if (r.response === 0) {
autoUpdater.quitAndInstall(false, true);
}
});
const checkNow = async () => {
const r = await autoUpdater.checkForUpdates();
return { ok: true, updateInfo: r && r.updateInfo };
};
const tick = () => {
checkNow().catch(() => {});
};
setTimeout(tick, 5000);
setInterval(tick, 6 * 60 * 60 * 1000);
return { checkNow };
}
module.exports = { setupAutoUpdater };