Backend: Match-Lobbys, Map-Veto, Echtzeit und CS2-Serveradapter
Express + Socket.IO + SQLite. Veto-Engine mit konfigurierbaren Map-Pools und validierten Abläufen, rollenbasierte Berechtigungen, Server-Lebenszyklus mit Demo-, Docker- und Static-Pool-Adapter (RCON), automatisches Herunterfahren.
This commit is contained in:
commit
f08297dd0d
27 files changed
+6355
No files matched your search
@@ -0,0 +1,58 @@
|
||||
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`);
|
||||
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 }]),
|
||||
),
|
||||
}));
|
||||
}
|
||||
Reference in new issue
Block a user