feat: require ranked match acceptance with configurable timeout

This commit is contained in:
2026-10-15 18:59:52 +09:00
parent 3540f392b0
commit c744e8c2a1
14 changed files with 388 additions and 74 deletions
+13 -2
View File
@@ -9,6 +9,15 @@ import { createGlobalSettingsStore } from '../src/server/global-settings.js';
import { createGameSessionStore } from '../src/server/game-session-store.js';
import { createRoomStore } from '../src/server/rooms.js';
import { createMatchEngine } from '../src/shared/match-engine.js';
import { isGlobalSettings } from '../src/shared/global-settings.js';
test('ranked acceptance timeout is a configurable positive duration', () => {
assert.equal(DEFAULT_GLOBAL_SETTINGS.rankedAcceptTimeoutMs, 10000);
assert.equal(isGlobalSettings({ ...DEFAULT_GLOBAL_SETTINGS, rankedAcceptTimeoutMs: 5000 }), true);
for (const rankedAcceptTimeoutMs of [0, -1, 60001, 1500.5]) {
assert.equal(isGlobalSettings({ ...DEFAULT_GLOBAL_SETTINGS, rankedAcceptTimeoutMs }), false);
}
});
test('browser caches settings, checks revision and retains valid settings through failures', async () => {
const memory = new Map<string, string>(), urls: string[] = [];
@@ -71,17 +80,19 @@ test('DB settings update without restart and friend matches share an immutable s
const c = await sessions.create(randomBytes(32).toString('base64url'));
const bot = await sessions.register(c, { requestId: 'bot', matchId: 'bot', mode: 'bot', expectedPreviousSeq: 0 });
assert.equal(bot.settings?.revision, 3); assert.equal(bot.settings?.finishCutsceneSpeed, 3);
await db.collection('global_settings').updateOne({ _id: 'global' as any }, { $unset: { matchingDelayMs: '', matchSuccessDelayMs: '', matchPreparationDelayMs: '' } });
await db.collection('global_settings').updateOne({ _id: 'global' as any }, { $unset: { matchingDelayMs: '', matchSuccessDelayMs: '', matchPreparationDelayMs: '', rankedAcceptTimeoutMs: '' } });
await store.initialize();
const migrated = await store.get();
assert.equal(migrated.matchingDelayMs, 1000); assert.equal(migrated.matchSuccessDelayMs, 1000);
assert.equal(migrated.matchPreparationDelayMs, 3000);
assert.equal(migrated.rankedAcceptTimeoutMs, 10000);
assert.equal(migrated.finishCutsceneSpeed, 3); assert.equal(migrated.turnDurationMs, 2000);
assert.ok(migrated.revision > 3);
await store.initialize(); assert.deepEqual(await store.get(), migrated);
const changed = await store.update({ ...migrated, matchingDelayMs: 4000, matchSuccessDelayMs: 2000, matchPreparationDelayMs: 5000 });
const changed = await store.update({ ...migrated, matchingDelayMs: 4000, matchSuccessDelayMs: 2000, matchPreparationDelayMs: 5000, rankedAcceptTimeoutMs: 7000 });
assert.equal(changed.matchingDelayMs, 4000); assert.equal(changed.matchSuccessDelayMs, 2000);
assert.equal((await store.get()).matchPreparationDelayMs, 5000);
assert.equal((await store.get()).rankedAcceptTimeoutMs, 7000);
await assert.rejects(store.update({ ...changed, matchPreparationDelayMs: -1 }), /INVALID_SETTINGS/);
await assert.rejects(store.update({ ...changed, matchingDelayMs: -1 }), /INVALID_SETTINGS/);
} finally { await app.close(); await db.dropDatabase(); await client.close(); }