This commit is contained in:
AI-scor 2026-11-10 19:28:14 +01:00 • committed by GitHub
commit 13883f7aff
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -302,10 +302,22 @@ Response::ResponseCode Server_ProtocolHandler::processRoomCommandContainer(const
return finalResponseCode; return finalResponseCode;
} }
Response::ResponseCode Server_ProtocolHandler::processGameCommandContainer(const CommandContainer &cont, namespace
ResponseContainer &rc)
{ {
static QList<GameCommand::GameCommandType> antifloodCommandsWhiteList = /**
* @brief Records one game command in the flood window and reports whether the window is over its limit.
* Bursty commands are not counted, so drawing ten cards one by one does not trip the limit.
*/
bool commandExceedsFloodLimit(const GameCommand &command,
QList<int> &commandCountOverTime,
int commandCountingInterval,
int maxCommandCountPerInterval)
{
if (commandCountingInterval <= 0) {
return false;
}
static const QList<GameCommand::GameCommandType> antifloodCommandsWhiteList =
QList<GameCommand::GameCommandType>() QList<GameCommand::GameCommandType>()
// draw/undo card draw (example: drawing 10 cards one by one from the deck) // draw/undo card draw (example: drawing 10 cards one by one from the deck)
<< GameCommand::DRAW_CARDS << GameCommand::DRAW_CARDS
@ -322,6 +334,26 @@ Response::ResponseCode Server_ProtocolHandler::processGameCommandContainer(const
// allows a user to sideboard without receiving flooding message // allows a user to sideboard without receiving flooding message
<< GameCommand::MOVE_CARD; << GameCommand::MOVE_CARD;
if (commandCountOverTime.isEmpty()) {
commandCountOverTime.prepend(0);
}
if (!antifloodCommandsWhiteList.contains(static_cast<GameCommand::GameCommandType>(getPbExtension(command)))) {
++commandCountOverTime[0];
}
int totalCount = 0;
for (int count : commandCountOverTime) {
totalCount += count;
}
return maxCommandCountPerInterval > 0 && totalCount > maxCommandCountPerInterval;
}
} // namespace
Response::ResponseCode Server_ProtocolHandler::processGameCommandContainer(const CommandContainer &cont,
ResponseContainer &rc)
{
if (authState == NotLoggedIn) { if (authState == NotLoggedIn) {
return Response::RespLoginNeeded; return Response::RespLoginNeeded;
} }
@ -367,23 +399,8 @@ Response::ResponseCode Server_ProtocolHandler::processGameCommandContainer(const
logDebugMessage(QString("game %1 player %2: ").arg(cont.game_id()).arg(playerId) + getSafeDebugString(sc)); logDebugMessage(QString("game %1 player %2: ").arg(cont.game_id()).arg(playerId) + getSafeDebugString(sc));
} }
if (commandCountingInterval > 0) { if (commandExceedsFloodLimit(sc, commandCountOverTime, commandCountingInterval, maxCommandCountPerInterval)) {
int totalCount = 0; return Response::RespChatFlood;
if (commandCountOverTime.isEmpty()) {
commandCountOverTime.prepend(0);
}
if (!antifloodCommandsWhiteList.contains((GameCommand::GameCommandType)getPbExtension(sc))) {
++commandCountOverTime[0];
}
for (int count : commandCountOverTime) {
totalCount += count;
}
if (maxCommandCountPerInterval > 0 && totalCount > maxCommandCountPerInterval) {
return Response::RespChatFlood;
}
} }
Response::ResponseCode resp = participant->processGameCommand(sc, rc, ges); Response::ResponseCode resp = participant->processGameCommand(sc, rc, ges);