Admin: Gameserver-Einstellungen, Docker-Hosts und Image-Update im Admin-Bereich
This commit is contained in:
1 parent
472bda31a9
commit
929134f2bc
10 files changed
+710
-12
No files matched your search
@@ -179,6 +179,78 @@ export class ServerManager {
|
||||
}));
|
||||
}
|
||||
|
||||
/** Server, die gerade laufen oder starten, mit dem Docker-Host aus ihrem Handle. */
|
||||
activeServers() {
|
||||
return this.db.prepare(`
|
||||
SELECT s.match_id, s.status, s.host, s.handle, m.mode
|
||||
FROM servers s JOIN matches m ON m.id = s.match_id
|
||||
WHERE s.status != 'stopped' AND s.handle IS NOT NULL
|
||||
`).all().map((r) => {
|
||||
let handle = null;
|
||||
try {
|
||||
handle = JSON.parse(r.handle);
|
||||
} catch {
|
||||
// kaputter Handle: Server zählt trotzdem als aktiv
|
||||
}
|
||||
return { ...r, handle, hostName: handle?.hostName ?? null };
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Übernimmt eine neue Liste von Docker-Hosts. Hosts mit laufenden Servern dürfen nicht wegfallen
|
||||
* und ihre Adresse nicht ändern, sonst verliert die App den Kontakt zu diesen Servern.
|
||||
*/
|
||||
setDockerHosts(hosts) {
|
||||
if (!this.adapter.setHosts) throw new HttpError(409, 'Nur mit dem Docker-Adapter möglich', 'unsupported');
|
||||
const before = new Map(this.adapter.hosts.map((h) => [h.name, h]));
|
||||
// Ohne Liste gilt der eine Host aus DOCKER_HOST/CS2_PUBLIC_HOST
|
||||
const nextList = hosts ?? [{ name: 'default', publicHost: this.config.docker.host, dockerHost: process.env.DOCKER_HOST || null }];
|
||||
for (const server of this.activeServers()) {
|
||||
const name = server.hostName ?? this.adapter.hosts[0]?.name;
|
||||
const old = before.get(name);
|
||||
const next = nextList.find((h) => h.name === name);
|
||||
if (!next) {
|
||||
throw new HttpError(409, `Auf ${name} läuft noch ein Server. Erst stoppen, dann den Host entfernen.`, 'host_busy');
|
||||
}
|
||||
if (old && (next.publicHost !== old.publicHost || (next.dockerHost ?? null) !== (old.dockerHost ?? null))) {
|
||||
throw new HttpError(409, `Auf ${name} läuft noch ein Server. Adresse und Docker-Ziel erst danach ändern.`, 'host_busy');
|
||||
}
|
||||
}
|
||||
this.adapter.setHosts(hosts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Schickt geänderte Match-Einstellungen an alle bereiten Server. Liefert, wie viele Server
|
||||
* aktualisiert wurden und welche nicht erreichbar waren.
|
||||
*/
|
||||
async applyLiveSettings(changed) {
|
||||
const keys = new Set(changed);
|
||||
const rows = this.activeServers().filter((r) => r.status === 'configured');
|
||||
if (!this.adapter.sendCommands || rows.length === 0) return { updated: 0, failed: [] };
|
||||
const m = this.config.match;
|
||||
const result = { updated: 0, failed: [] };
|
||||
for (const row of rows) {
|
||||
const wingman = row.mode === 'wingman';
|
||||
const commands = [];
|
||||
if (keys.has(wingman ? 'maxRoundsWingman' : 'maxRoundsCompetitive')) {
|
||||
commands.push(`mp_maxrounds ${wingman ? m.maxRoundsWingman : m.maxRoundsCompetitive}`);
|
||||
}
|
||||
if (keys.has('overtime')) commands.push(`mp_overtime_enable ${m.overtime ? 1 : 0}`);
|
||||
if (keys.has('tvDelaySeconds')) commands.push(`tv_delay ${m.tvDelaySeconds}`);
|
||||
if (keys.has('extraCommands')) commands.push(...m.extraCommands);
|
||||
if (commands.length === 0) continue;
|
||||
try {
|
||||
await this.adapter.sendCommands(row.handle, commands);
|
||||
result.updated += 1;
|
||||
this.service.log(row.match_id, 'server', `Einstellungen übernommen (Admin): ${commands.join('; ')}`);
|
||||
} catch (err) {
|
||||
result.failed.push(row.match_id);
|
||||
this.logger.warn?.(`Einstellungen für ${row.match_id} nicht übernommen: ${err.message}`);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/** Ports, die auf einem bestimmten Docker-Host belegt sind. */
|
||||
usedPortsOn(host) {
|
||||
const used = new Set();
|
||||
|
||||
Reference in new issue
Block a user