Load character names from downloaded game assets

This commit is contained in:
Pandipipas
2026-03-03 16:15:11 +01:00
parent 584f872954
commit fc82c9215a
5 changed files with 96 additions and 251 deletions
+49
View File
@@ -6,6 +6,7 @@ import { nodecg } from './util/nodecg.js';
const GITHUB_OWNER = 'Pandipipas';
const GITHUB_REPO = 'scoreko-assets';
const GITHUB_API_BASE = `https://api.github.com/repos/${GITHUB_OWNER}/${GITHUB_REPO}/contents`;
const CHARACTER_NAMES_FILE = 'fighting-characters.json';
let cachedDefaultBranch: string | null = null;
@@ -122,6 +123,37 @@ const listInstalledGames = async () => {
return gameCatalog.filter((game) => installedSlugs.includes(game.slug)).map((game) => game.title);
};
const parseCharacterNames = (content: string, gameTitle: string) => {
const parsed = JSON.parse(content) as unknown;
const names = Array.isArray(parsed)
? parsed
: typeof parsed === 'object' && parsed !== null && Array.isArray((parsed as { characters?: unknown }).characters)
? (parsed as { characters: unknown[] }).characters
: null;
if (!names || names.some((name) => typeof name !== 'string')) {
throw new Error(`El archivo ${CHARACTER_NAMES_FILE} de ${gameTitle} no tiene un formato válido.`);
}
return names;
};
const listInstalledCharacterNamesByGame = async () => {
const charactersByGame = await Promise.all(gameCatalog.map(async (game) => {
const sourcePath = path.join(assetsRoot, game.slug, CHARACTER_NAMES_FILE);
try {
const fileContent = await readFile(sourcePath, 'utf8');
const names = parseCharacterNames(fileContent, game.title);
return [game.title, names] as const;
} catch {
return [game.title, []] as const;
}
}));
return Object.fromEntries(charactersByGame) as Record<string, string[]>;
};
const downloadGameAssets = async (gameTitle: string) => {
const game = gameCatalog.find((entry) => entry.title === gameTitle);
if (!game) {
@@ -136,6 +168,11 @@ const downloadGameAssets = async (gameTitle: string) => {
throw new Error(`No se encontraron archivos en ${repoFolderPath} dentro de scoreko-assets.`);
}
const hasCharacterNamesFile = files.some((file) => file.path === `${repoFolderPath}/${CHARACTER_NAMES_FILE}`);
if (!hasCharacterNamesFile) {
throw new Error(`No se encontró ${CHARACTER_NAMES_FILE} en ${repoFolderPath} dentro de scoreko-assets.`);
}
const totalBytes = files.reduce((acc, file) => acc + (file.size || 0), 0);
let downloadedBytes = 0;
@@ -199,6 +236,18 @@ nodecg.listenFor('scoreko-assets:listInstalled', async (_payload: unknown, ack)
}
});
nodecg.listenFor('scoreko-assets:listCharactersByGame', async (_payload: unknown, ack) => {
if (typeof ack !== 'function') {
return;
}
try {
ack(null, await listInstalledCharacterNamesByGame());
} catch (error) {
ack((error as Error).message);
}
});
nodecg.listenFor('scoreko-assets:downloadGame', async (payload: unknown, ack) => {
if (typeof ack !== 'function') {
return;