Files
Cs2-Mapveto/server/src/mapPools.js
T
mregosar 7be0d85ab5 Map-Bilder und Seitenwahl mit Emblemen
Map-Bilder aus ghostcap-gaming/cs2-map-images lokal als WebP gespeichert
(npm run images lädt und verkleinert sie). Bilder in Veto-Kacheln,
Pool-Vorschau, Serie und Seitenwahl; CT/T-Embleme aus client/public/sides
mit Ersatzsymbol, falls die Dateien fehlen.
2026-10-25 17:23:55 +01:00

62 lines
2.1 KiB
JavaScript

import fs from 'node:fs';
import { BEST_OF, validateFlow } from './veto.js';
/**
* Lädt die Map-Pools und markiert jede Kombination aus Modus und Format als unterstützt oder nicht.
* Nur gültige Kombinationen können beim Erstellen eines Matches gewählt werden.
*/
export function loadMapPools(file) {
const raw = JSON.parse(fs.readFileSync(file, 'utf8'));
return buildMapPools(raw);
}
export function buildMapPools(raw) {
const pools = {};
for (const [mode, pool] of Object.entries(raw.pools ?? {})) {
const ids = new Set();
for (const map of pool.maps ?? []) {
if (!/^[a-z0-9_]+$/.test(map.id)) throw new Error(`Ungültige Map-ID "${map.id}" im Pool "${mode}"`);
if (ids.has(map.id)) throw new Error(`Map "${map.id}" ist im Pool "${mode}" doppelt`);
if (map.image !== undefined && !/^(https?:\/\/|\/)[^\s"'()<>]+$/.test(map.image)) {
throw new Error(`Bild für "${map.id}" im Pool "${mode}" muss eine http(s)-URL oder ein Pfad mit / sein`);
}
ids.add(map.id);
}
const formats = {};
for (const format of Object.keys(BEST_OF)) {
const flow = pool.flows?.[format];
if (!flow) {
formats[format] = { supported: false, reason: 'Kein Veto-Ablauf für dieses Format hinterlegt' };
continue;
}
const errors = validateFlow(flow, pool.maps.length, format);
formats[format] = errors.length
? { supported: false, reason: errors.join('; ') }
: { supported: true, flow };
if (errors.length) console.warn(`[map-pools] ${mode}/${format} deaktiviert: ${errors.join('; ')}`);
}
pools[mode] = {
mode,
label: pool.label ?? mode,
teamSize: pool.teamSize,
gameType: pool.gameType,
gameMode: pool.gameMode,
maps: pool.maps,
formats,
};
}
return pools;
}
export function publicPools(pools) {
return Object.values(pools).map((p) => ({
mode: p.mode,
label: p.label,
teamSize: p.teamSize,
maps: p.maps,
formats: Object.fromEntries(
Object.entries(p.formats).map(([f, v]) => [f, { supported: v.supported, reason: v.reason ?? null, flow: v.flow ?? null }]),
),
}));
}