Stage 17 round 5 — backend/correctness bug fixes
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 9s
CI / integration (pull_request) Failing after 12s
CI / ui (pull_request) Successful in 30s
CI / gate (pull_request) Failing after 1s
CI / deploy (pull_request) Has been skipped
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 9s
CI / integration (pull_request) Failing after 12s
CI / ui (pull_request) Successful in 30s
CI / gate (pull_request) Failing after 1s
CI / deploy (pull_request) Has been skipped
- Resign on the opponent's turn: engine ResignSeat(seat) resigns a specific seat (not just toMove); game.Resign bypasses the turn check and forfeits the actor's seat. - Quick-match cancel was a UI no-op (only stopped polling): add the full path (REST /lobby/cancel -> gateway lobby.cancel -> client) and clear the matchmaker's pending result on Cancel, so a cancelled search is dequeued (no 'already queued', no later robot-substituted game). NewGame dequeues on cancel and on abandon. - Lobby win/loss: result.ts ranked by score, so a 0-0 resignation read as a win. The winner now takes rank 1 and the viewer is placed from rank 2 — matching the game-detail screen. - Friend request to a robot: robots no longer block requests; the request stays pending and expires (friendRequestTTL), mirroring a human who ignores it. - Nudge cooldown: ErrNudgeTooSoon now maps to a distinct nudge_too_soon code with a correct message; the chat nudge button disables during the hourly cooldown; the nudge note reads 'Waiting for your move!' (button keeps the Nudge action label). Tests: engine/service off-turn resign, matchmaker cancel-clears-result, friend-to-robot inttest, result.ts 0-0 resignation, nudge_too_soon mapping.
This commit is contained in:
@@ -31,12 +31,22 @@
|
||||
poll = null;
|
||||
}
|
||||
}
|
||||
// cancelSearch leaves the auto-match pool on the backend too, so a cancelled quick-match
|
||||
// is actually dequeued — otherwise the account stays queued (blocking a re-queue) and the
|
||||
// reaper later substitutes a robot for a game the player abandoned (Stage 17 fix).
|
||||
function cancelSearch() {
|
||||
stop();
|
||||
searching = false;
|
||||
void gateway.lobbyCancel().catch(() => {});
|
||||
navigate('/');
|
||||
}
|
||||
|
||||
async function find(v: Variant) {
|
||||
searching = true;
|
||||
try {
|
||||
const r = await gateway.lobbyEnqueue(v);
|
||||
if (r.matched && r.game) {
|
||||
searching = false;
|
||||
navigate(`/game/${r.game.id}`);
|
||||
return;
|
||||
}
|
||||
@@ -45,6 +55,7 @@
|
||||
const p = await gateway.lobbyPoll();
|
||||
if (p.matched && p.game) {
|
||||
stop();
|
||||
searching = false;
|
||||
navigate(`/game/${p.game.id}`);
|
||||
}
|
||||
} catch (e) {
|
||||
@@ -103,7 +114,11 @@
|
||||
}
|
||||
}
|
||||
|
||||
onDestroy(stop);
|
||||
onDestroy(() => {
|
||||
stop();
|
||||
// Abandoned mid-search (navigated away without Cancel): dequeue so we don't linger.
|
||||
if (searching) void gateway.lobbyCancel().catch(() => {});
|
||||
});
|
||||
</script>
|
||||
|
||||
<Screen title={t('new.title')} back="/">
|
||||
@@ -112,7 +127,7 @@
|
||||
<div class="searching">
|
||||
<div class="spinner"></div>
|
||||
<p>{t('new.searching')}</p>
|
||||
<button class="cancel" onclick={() => { stop(); navigate('/'); }}>{t('common.cancel')}</button>
|
||||
<button class="cancel" onclick={cancelSearch}>{t('common.cancel')}</button>
|
||||
</div>
|
||||
{:else}
|
||||
{#if !guest}
|
||||
|
||||
Reference in New Issue
Block a user