fix(multiplayer): terminate proposal offenders atomically

This commit is contained in:
Josh Creek
2026-09-03 00:09:07 +01:00
parent aa446cfbfe
commit f8af212e3f
6 changed files with 206 additions and 67 deletions
+2 -1
View File
@@ -182,7 +182,8 @@ func CooldownUntil(events []CooldownEvent, playlist Playlist, now time.Time) tim
cutoff := now.Add(-window)
filtered := make([]CooldownEvent, 0, len(events))
for _, event := range events {
if event.Playlist == playlist && !event.At.Before(cutoff) {
validKind := event.Kind == DeclinedResponse || event.Kind == TimedOutResponse
if event.Playlist == playlist && validKind && !event.At.Before(cutoff) && !event.At.After(now) {
filtered = append(filtered, event)
}
}
+14
View File
@@ -94,3 +94,17 @@ func TestRankedProposalAndCooldownEscalation(t *testing.T) {
t.Fatalf("ranked escalation cooldown = %v", got)
}
}
func TestCooldownIgnoresFutureForeignAndInvalidEvents(t *testing.T) {
now := time.Unix(10_000, 0)
events := []CooldownEvent{
{At: now.Add(-time.Minute), Playlist: Casual, Kind: DeclinedResponse},
{At: now.Add(time.Hour), Playlist: Ranked, Kind: TimedOutResponse},
{At: now, Playlist: Casual, Kind: TimedOutResponse},
{At: now, Playlist: Ranked, Kind: AcceptedResponse},
{At: now.Add(-31 * time.Minute), Playlist: Ranked, Kind: DeclinedResponse},
}
if got := CooldownUntil(events, Ranked, now); !got.IsZero() {
t.Fatalf("untrusted cooldown events produced %v, want zero", got)
}
}