Compare commits
2
Commits
1b3536452c
...
c50741e49c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c50741e49c | ||
|
|
dfcca1be82 |
No files matched your search
@@ -392,7 +392,8 @@ export class ServerManager {
|
||||
maybeConfigure(matchId) {
|
||||
const match = this.service.getMatch(matchId);
|
||||
const row = this.row(matchId);
|
||||
if (match.status === 'server_setup' && row?.status === 'ready') {
|
||||
// Auch im laufenden Match: nach einem Neustart des Servers die aktuelle Map samt Passwort wieder laden
|
||||
if (['server_setup', 'live'].includes(match.status) && row?.status === 'ready') {
|
||||
this.configure(matchId).catch((err) => this.logger.error(err));
|
||||
}
|
||||
}
|
||||
@@ -467,7 +468,7 @@ export class ServerManager {
|
||||
await this.provision(matchId);
|
||||
return;
|
||||
}
|
||||
if (row.status === 'config_failed' || (row.status === 'ready' && match.status === 'server_setup')) {
|
||||
if (row.status === 'config_failed' || (row.status === 'ready' && ['server_setup', 'live'].includes(match.status))) {
|
||||
this.service.log(matchId, 'server', 'Organisator wiederholt die Konfiguration');
|
||||
this.configure(matchId).catch((err) => this.logger.error(err));
|
||||
return;
|
||||
@@ -591,11 +592,12 @@ export class ServerManager {
|
||||
continue;
|
||||
}
|
||||
const webActive = this.service.presence(row.match_id).size > 0;
|
||||
let lastUse = match.last_activity_at;
|
||||
// Ein (neu) gestarteter Server zählt als Nutzung, sonst stoppt ein Neustart nach langer Pause sofort wieder
|
||||
let lastUse = Math.max(match.last_activity_at, row.started_at ?? 0);
|
||||
if (row.status === 'configured' && row.player_count !== null) {
|
||||
// Echter Server mit bekannter Spielerzahl: entscheidend ist, ob jemand auf dem Server ist.
|
||||
if (row.player_count > 0) continue;
|
||||
lastUse = Math.max(row.configured_at ?? 0, row.last_player_seen_at ?? 0);
|
||||
lastUse = Math.max(row.configured_at ?? 0, row.last_player_seen_at ?? 0, row.started_at ?? 0);
|
||||
} else if (webActive) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -477,3 +477,34 @@ test('Spieler verlassen die Lobby, Captain geht über', async () => {
|
||||
await close();
|
||||
}
|
||||
});
|
||||
test('Neustart im laufenden Match: Map wird wieder geladen, Server läuft die volle Frist', async () => {
|
||||
const { app, call, close } = await setup({ idleTimeoutMinutes: 30 });
|
||||
try {
|
||||
const { id, org, tokens } = await readyWingmanMatch(call, 'bo1');
|
||||
await call('POST', `/matches/${id}/veto/start`, { token: org });
|
||||
await playVeto(call, id, { A: tokens.a1, B: tokens.b1 });
|
||||
await app.manager.poll();
|
||||
await waitFor(() => app.service.getMatch(id).status === 'live', { label: 'live' });
|
||||
|
||||
// Lange nichts los, dann stoppt der Server
|
||||
const hourAgo = Date.now() - 60 * 60_000;
|
||||
app.db.prepare('UPDATE matches SET last_activity_at = ? WHERE id = ?').run(hourAgo, id);
|
||||
await call('POST', `/matches/${id}/server/stop`, { token: org });
|
||||
await waitFor(() => app.service.serverRow(id).status === 'stopped', { label: 'gestoppt' });
|
||||
|
||||
// Neustart durch den Organisator: Server fährt hoch und lädt die Map wieder (Match ist weiter "live")
|
||||
const res = await call('POST', `/matches/${id}/server/retry`, { token: org });
|
||||
assert.equal(res.status, 200, JSON.stringify(res.body));
|
||||
await waitFor(async () => { await app.manager.poll(); return app.service.serverRow(id).status === 'configured'; }, { label: 'neu konfiguriert' });
|
||||
assert.equal(app.service.getMatch(id).status, 'live');
|
||||
|
||||
// Die Abschaltung darf den frisch gestarteten Server nicht sofort wieder stoppen
|
||||
await app.manager.reap();
|
||||
assert.equal(app.service.serverRow(id).status, 'configured');
|
||||
// Nach Ablauf der Frist ab dem Neustart dagegen schon
|
||||
await app.manager.reap(Date.now() + 31 * 60_000);
|
||||
assert.equal(app.service.serverRow(id).status, 'stopped');
|
||||
} finally {
|
||||
await close();
|
||||
}
|
||||
});
|
||||
Reference in new issue
Block a user