24d1ae71d9
Co-authored-by: Cursor <cursoragent@cursor.com>
128 lines
3.8 KiB
JavaScript
128 lines
3.8 KiB
JavaScript
'use strict';
|
|
|
|
const path = require('path');
|
|
const { listReleaseAttachmentNames } = require('./github');
|
|
|
|
/** Legacy launcher.json rows — ignored when merging explicit files. */
|
|
const DEPRECATED_SOURCES = new Set(['patch-Z.MPQ', 'Wow-patched.exe']);
|
|
|
|
function filterExplicitFiles(files) {
|
|
if (!Array.isArray(files)) return [];
|
|
return files
|
|
.filter((e) => e && String(e.source || '').trim())
|
|
.filter((e) => !DEPRECATED_SOURCES.has(String(e.source).trim()))
|
|
.map((e) => ({
|
|
source: String(e.source).trim(),
|
|
dest: String(e.dest || '').trim(),
|
|
backup: e.backup !== false,
|
|
from_release: e.from_release !== false,
|
|
}))
|
|
.filter((e) => e.dest);
|
|
}
|
|
|
|
function manifestLooksUsable(m) {
|
|
return !!(m && m.files && typeof m.files === 'object' && Object.keys(m.files).length > 0);
|
|
}
|
|
|
|
/** Launcher / updater attachments — never copied into the WoW folder. */
|
|
function isExcludedFromGameSync(fileName) {
|
|
const n = String(fileName || '');
|
|
const lower = n.toLowerCase();
|
|
if (lower === 'patch-manifest.json') return true;
|
|
if (/^fractured-launcher/i.test(n)) return true;
|
|
if (/\.blockmap$/i.test(n)) return true;
|
|
if (/^latest.*\.ya?ml$/i.test(n) || lower === 'latest.yml') return true;
|
|
if (lower.includes('builder-debug')) return true;
|
|
if (/\.appimage$/i.test(n)) return true;
|
|
return false;
|
|
}
|
|
|
|
function mpqDestFromSource(source) {
|
|
const base = path.basename(String(source || ''));
|
|
return `Data/enUS/${base}`;
|
|
}
|
|
|
|
function destForReleaseSource(source, cfg) {
|
|
const base = path.basename(String(source || ''));
|
|
if (/\.mpq$/i.test(base)) return mpqDestFromSource(source);
|
|
if (/\.exe$/i.test(base)) return (cfg.launch && cfg.launch.exe) || 'Wow.exe';
|
|
return base;
|
|
}
|
|
|
|
/**
|
|
* Explicit `files` in config wins. Otherwise use patch-manifest keys if present,
|
|
* else discover attachments on the release (excluding launcher artifacts).
|
|
*/
|
|
async function buildResolvedReleaseFiles(cfg, manifestMaybeNull) {
|
|
const explicit = filterExplicitFiles(cfg.files);
|
|
if (explicit.length) return explicit;
|
|
|
|
const manifest = manifestMaybeNull;
|
|
if (manifestLooksUsable(manifest)) {
|
|
const keys = Object.keys(manifest.files).filter((k) => k && !isExcludedFromGameSync(k));
|
|
if (!keys.length) {
|
|
throw new Error('patch-manifest.json has no file entries — add files or attach assets to the release.');
|
|
}
|
|
return keys.map((source) => ({
|
|
source,
|
|
dest: destForReleaseSource(source, cfg),
|
|
backup: true,
|
|
from_release: true,
|
|
}));
|
|
}
|
|
|
|
const names = await listReleaseAttachmentNames(cfg);
|
|
const game = names.filter((n) => n && !isExcludedFromGameSync(n));
|
|
if (!game.length) {
|
|
throw new Error(
|
|
'No patch files on this release (after excluding launcher installers). ' +
|
|
'Attach MPQ/exe assets or ship patch-manifest.json listing filenames.'
|
|
);
|
|
}
|
|
|
|
const exes = game.filter((n) => /\.exe$/i.test(n));
|
|
const mpqs = game.filter((n) => /\.mpq$/i.test(n));
|
|
const rest = game.filter((n) => !/\.(exe|mpq)$/i.test(n));
|
|
|
|
if (exes.length > 1) {
|
|
throw new Error(
|
|
`Release has multiple .exe files (${exes.join(', ')}). ` +
|
|
'Remove extras or publish patch-manifest.json with the exact filenames to install.'
|
|
);
|
|
}
|
|
|
|
const out = [];
|
|
for (const n of mpqs) {
|
|
out.push({
|
|
source: n,
|
|
dest: mpqDestFromSource(n),
|
|
backup: true,
|
|
from_release: true,
|
|
});
|
|
}
|
|
if (exes.length === 1) {
|
|
out.push({
|
|
source: exes[0],
|
|
dest: (cfg.launch && cfg.launch.exe) || 'Wow.exe',
|
|
backup: true,
|
|
from_release: true,
|
|
});
|
|
}
|
|
for (const n of rest) {
|
|
out.push({
|
|
source: n,
|
|
dest: path.basename(n),
|
|
backup: true,
|
|
from_release: true,
|
|
});
|
|
}
|
|
return out;
|
|
}
|
|
|
|
module.exports = {
|
|
buildResolvedReleaseFiles,
|
|
filterExplicitFiles,
|
|
isExcludedFromGameSync,
|
|
DEPRECATED_SOURCES,
|
|
};
|