mirror of
https://github.com/jcreek/CosmicClash.git
synced 2026-09-12 22:12:08 +00:00
feat(multiplayer): enforce proposal decline cooldowns
This commit is contained in:
@@ -129,6 +129,46 @@ SET state = 'QUEUED', expires_at = $2, revision = revision + 1
|
||||
FROM proposal_participants pp
|
||||
WHERE pp.proposal_id = $1 AND q.ticket_id = pp.ticket_id AND q.player_id = pp.player_id AND q.state = 'PROPOSED'`
|
||||
|
||||
const ProposalCooldownEventsSQL = `SELECT kind, starts_at
|
||||
FROM penalties
|
||||
WHERE player_id = $1 AND playlist = $2
|
||||
AND kind IN ('PROPOSAL_DECLINED', 'PROPOSAL_TIMEOUT')
|
||||
AND starts_at >= $3
|
||||
ORDER BY starts_at`
|
||||
|
||||
const ProposalCooldownInsertSQL = `INSERT INTO penalties
|
||||
(penalty_id, player_id, playlist, kind, starts_at, ends_at)
|
||||
VALUES ($1, $2, $3, $4, $5, $6)
|
||||
ON CONFLICT (penalty_id) DO NOTHING`
|
||||
|
||||
func recordProposalDeclineCooldown(ctx context.Context, tx *sql.Tx, playerID string, playlist domain.Playlist, proposalID string, now time.Time) error {
|
||||
rows, err := tx.QueryContext(ctx, ProposalCooldownEventsSQL, playerID, string(playlist), now.Add(-30*time.Minute))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer rows.Close()
|
||||
events := make([]domain.CooldownEvent, 0)
|
||||
for rows.Next() {
|
||||
var kind string
|
||||
var at time.Time
|
||||
if err := rows.Scan(&kind, &at); err != nil {
|
||||
return err
|
||||
}
|
||||
response := domain.TimedOutResponse
|
||||
if kind == "PROPOSAL_DECLINED" {
|
||||
response = domain.DeclinedResponse
|
||||
}
|
||||
events = append(events, domain.CooldownEvent{At: at, Playlist: playlist, Kind: response})
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return err
|
||||
}
|
||||
events = append(events, domain.CooldownEvent{At: now, Playlist: playlist, Kind: domain.DeclinedResponse})
|
||||
until := domain.CooldownUntil(events, playlist, now)
|
||||
_, err = tx.ExecContext(ctx, ProposalCooldownInsertSQL, "proposal-decline:"+proposalID+":"+playerID, playerID, string(playlist), "PROPOSAL_DECLINED", now, until)
|
||||
return err
|
||||
}
|
||||
|
||||
const ProposalRevisionBumpSQL = `UPDATE proposals
|
||||
SET revision = revision + 1
|
||||
WHERE proposal_id = $1 AND state = 'OPEN'`
|
||||
@@ -286,6 +326,9 @@ func RespondToProposal(ctx context.Context, db *sql.DB, playerID, proposalID, id
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := recordProposalDeclineCooldown(ctx, tx, playerID, domain.Playlist(playlist), proposalID, now); err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = tx.ExecContext(ctx, ProposalDeclineRequeueSQL, proposalID, now.Add(domain.QueueExpiryWindow))
|
||||
}
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user