mirror of
https://github.com/Dingo-Shenanigans/ReSkate.git
synced 2026-10-23 05:45:53 +02:00
Chat's flood control refuses a line identical to the one before it within 15 s, which also caught /2 in a poll right after /2 in the last one. An answer to the running vote or poll is now exempt from that one rule, on the server and in the game; the pace still holds, and the vote still counts one answer per player. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
38 lines
1.5 KiB
C++
38 lines
1.5 KiB
C++
#pragma once
|
|
#include <algorithm>
|
|
#include <cstdint>
|
|
#include <string>
|
|
#include <string_view>
|
|
|
|
namespace dingosdk {
|
|
// Chat flood control, the same for the sender, the host, a dedicated server and every
|
|
// receiver: a few lines at once, then one every 1.5 s, and never the same line twice within
|
|
// 15 s. Receivers allow one line of slack for lines that arrive bunched up. An answer to the
|
|
// running vote or poll may repeat the line before it (`answer`): the same /2 is a new answer
|
|
// in the next poll, and the vote itself counts one answer per player. The pace still holds.
|
|
struct ChatRate {
|
|
static constexpr double burst = 4, interval_us = 1500000;
|
|
static constexpr std::uint64_t repeat_us = 15000000;
|
|
enum class Verdict { accepted, too_fast, repeated };
|
|
double tokens = burst;
|
|
std::uint64_t refilled{}, previous_at{};
|
|
std::string previous;
|
|
Verdict accept(std::uint64_t now, std::string_view text, double slack = 0, bool answer = false) {
|
|
const double limit = burst + slack;
|
|
if (!refilled || now < refilled) {
|
|
tokens = limit;
|
|
} else {
|
|
tokens = std::min(limit, tokens + static_cast<double>(now - refilled) / interval_us);
|
|
}
|
|
refilled = now;
|
|
if (!answer && !previous.empty() && text == previous && now >= previous_at && now - previous_at < repeat_us)
|
|
return Verdict::repeated;
|
|
if (tokens < 1) return Verdict::too_fast;
|
|
tokens -= 1;
|
|
previous.assign(text);
|
|
previous_at = now;
|
|
return Verdict::accepted;
|
|
}
|
|
};
|
|
} // namespace dingosdk
|