feat(multiplayer): enforce proposal decline cooldowns

This commit is contained in:
Josh Creek
2026-09-01 19:30:45 +01:00
parent da92be73ef
commit 455055c67c
6 changed files with 68 additions and 0 deletions
+14
View File
@@ -35,6 +35,13 @@ RETURNING ticket_id, player_id, playlist, state, client_build, protocol_version,
WHERE ticket_id = $1 AND player_id = $2 AND revision = $3
AND state NOT IN ('COMPLETED', 'CANCELLED', 'EXPIRED', 'FAILED')
RETURNING ticket_id, player_id, playlist, state, client_build, protocol_version, enqueued_at, expires_at, revision, predicted_rtt`
QueueCooldownSelectSQL = `SELECT ends_at
FROM penalties
WHERE player_id = $1 AND playlist = $2
AND kind IN ('PROPOSAL_DECLINED', 'PROPOSAL_TIMEOUT')
AND ends_at > $3
ORDER BY ends_at DESC
LIMIT 1`
)
const QueueCandidateProjectionSQL = `SELECT ticket_id, player_id, playlist, client_build,
@@ -146,6 +153,13 @@ func CreateQueueTicket(ctx context.Context, db *sql.DB, ticketID, playerID, idem
ticket = queueTicketRecordToDomain(prior)
return nil
}
var cooldownEndsAt time.Time
if err := tx.QueryRowContext(ctx, QueueCooldownSelectSQL, playerID, string(spec.Playlist), now).Scan(&cooldownEndsAt); err != sql.ErrNoRows {
if err != nil {
return err
}
return fmt.Errorf("%w until %s", domain.ErrPlayerCooldown, cooldownEndsAt.UTC().Format(time.RFC3339))
}
predictedRTT, err := json.Marshal(candidate.PredictedRTT)
if err != nil {
return err