Core/Chat: Apply chat flood control to addon messages as well

(cherry picked from commit 5384fc194f9061bbac314abb66a9bac88aaaf760)
This commit is contained in:
stoneharry authored and Ovahlord committed 2025-06-17 17:43:49 +02:00
1 parent 6daba28efe
commit 1c38edaae4
8 files changed
+79 -26

No files matched your search

+25 -18
View File
@@ -146,9 +146,6 @@ uint64 const MAX_MONEY_AMOUNT = 9999999999ULL;
Player::Player(WorldSession* session): Unit(true)
{
m_speakTime = 0;
m_speakCount = 0;
m_objectType |= TYPEMASK_PLAYER;
m_objectTypeId = TYPEID_PLAYER;
@@ -19903,39 +19900,49 @@ void Player::outDebugValues() const
/*** FLOOD FILTER SYSTEM ***/
/*********************************************************/
void Player::UpdateSpeakTime()
void Player::UpdateSpeakTime(ChatFloodThrottle::Index index)
{
// ignore chat spam protection for GMs in any mode
if (GetSession()->HasPermission(rbac::RBAC_PERM_SKIP_CHECK_CHAT_SPAM))
return;
time_t current = GameTime::GetGameTime();
if (m_speakTime > current)
uint32 limit;
uint32 delay;
switch (index)
{
uint32 max_count = sWorld->getIntConfig(CONFIG_CHATFLOOD_MESSAGE_COUNT);
if (!max_count)
case ChatFloodThrottle::REGULAR:
limit = sWorld->getIntConfig(CONFIG_CHATFLOOD_MESSAGE_COUNT);
delay = sWorld->getIntConfig(CONFIG_CHATFLOOD_MESSAGE_DELAY);
break;
case ChatFloodThrottle::ADDON:
limit = sWorld->getIntConfig(CONFIG_CHATFLOOD_ADDON_MESSAGE_COUNT);
delay = sWorld->getIntConfig(CONFIG_CHATFLOOD_ADDON_MESSAGE_DELAY);
break;
default:
return;
}
time_t current = GameTime::GetGameTime();
if (m_chatFloodData[index].Time > current)
{
if (!limit)
return;
++m_speakCount;
if (m_speakCount >= max_count)
++m_chatFloodData[index].Count;
if (m_chatFloodData[index].Count >= limit)
{
// prevent overwrite mute time, if message send just before mutes set, for example.
time_t new_mute = current + sWorld->getIntConfig(CONFIG_CHATFLOOD_MUTE_TIME);
if (GetSession()->m_muteTime < new_mute)
GetSession()->m_muteTime = new_mute;
m_speakCount = 0;
m_chatFloodData[index].Count = 0;
}
}
else
m_speakCount = 1;
m_chatFloodData[index].Count = 1;
m_speakTime = current + sWorld->getIntConfig(CONFIG_CHATFLOOD_MESSAGE_DELAY);
}
bool Player::CanSpeak() const
{
return GetSession()->m_muteTime <= time (nullptr);
m_chatFloodData[index].Time = current + delay;
}
/*********************************************************/
+15 -5
View File
@@ -2108,9 +2108,20 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
/*** FLOOD FILTER SYSTEM ***/
/*********************************************************/
void UpdateSpeakTime();
bool CanSpeak() const;
void ChangeSpeakTime(int utime);
struct ChatFloodThrottle
{
enum Index
{
REGULAR = 0,
ADDON = 1,
MAX
};
time_t Time = 0;
uint32 Count = 0;
};
void UpdateSpeakTime(ChatFloodThrottle::Index index);
/*********************************************************/
/*** VARIOUS SYSTEMS ***/
@@ -2502,8 +2513,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
uint32 m_team;
uint32 m_nextSave;
time_t m_speakTime;
uint32 m_speakCount;
std::array<ChatFloodThrottle, ChatFloodThrottle::MAX> m_chatFloodData;
Difficulty m_dungeonDifficulty;
Difficulty m_raidDifficulty;
Difficulty m_raidMapDifficulty;
+13 -2
View File
@@ -212,13 +212,16 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
lang = ModLangAuras.front()->GetMiscValue();
}
if (!sender->CanSpeak())
if (!CanSpeak())
{
std::string timeStr = secsToTimeString(m_muteTime - GameTime::GetGameTime());
SendNotification(GetTrinityString(LANG_WAIT_BEFORE_SPEAKING), timeStr.c_str());
recvData.rfinish(); // Prevent warnings
return;
}
if (type != CHAT_MSG_AFK && type != CHAT_MSG_DND)
sender->UpdateSpeakTime(Player::ChatFloodThrottle::REGULAR);
}
}
else
@@ -651,6 +654,14 @@ void WorldSession::HandleAddonMessagechatOpcode(WorldPacket& recvData)
return;
}
if (!CanSpeak())
{
recvData.rfinish();
return;
}
sender->UpdateSpeakTime(Player::ChatFloodThrottle::ADDON);
switch (type)
{
case CHAT_MSG_BATTLEGROUND:
@@ -727,7 +738,7 @@ void WorldSession::HandleSendTextEmoteOpcode(WorldPackets::Chat::SendTextEmote&
if (!GetPlayer()->IsAlive())
return;
if (!GetPlayer()->CanSpeak())
if (!CanSpeak())
{
std::string timeStr = secsToTimeString(m_muteTime - GameTime::GetGameTime());
SendNotification(GetTrinityString(LANG_WAIT_BEFORE_SPEAKING), timeStr.c_str());
+5
View File
@@ -748,6 +748,11 @@ void WorldSession::SendNotification(uint32 string_id, ...)
}
}
bool WorldSession::CanSpeak() const
{
return m_muteTime <= GameTime::GetGameTime();
}
char const* WorldSession::GetTrinityString(uint32 entry) const
{
return sObjectMgr->GetTrinityString(entry, GetSessionDbLocaleIndex());
+1
View File
@@ -628,6 +628,7 @@ class TC_GAME_API WorldSession
void DoLootRelease(ObjectGuid lguid);
// Account mute time
bool CanSpeak() const;
time_t m_muteTime;
// Locales
+2
View File
@@ -1187,6 +1187,8 @@ void World::LoadConfigSettings(bool reload)
m_int_configs[CONFIG_CHATFLOOD_MESSAGE_COUNT] = sConfigMgr->GetIntDefault("ChatFlood.MessageCount", 10);
m_int_configs[CONFIG_CHATFLOOD_MESSAGE_DELAY] = sConfigMgr->GetIntDefault("ChatFlood.MessageDelay", 1);
m_int_configs[CONFIG_CHATFLOOD_ADDON_MESSAGE_COUNT] = sConfigMgr->GetIntDefault("ChatFlood.AddonMessageCount", 100);
m_int_configs[CONFIG_CHATFLOOD_ADDON_MESSAGE_DELAY] = sConfigMgr->GetIntDefault("ChatFlood.AddonMessageDelay", 1);
m_int_configs[CONFIG_CHATFLOOD_MUTE_TIME] = sConfigMgr->GetIntDefault("ChatFlood.MuteTime", 10);
m_bool_configs[CONFIG_EVENT_ANNOUNCE] = sConfigMgr->GetBoolDefault("Event.Announce", false);
+2
View File
@@ -295,6 +295,8 @@ enum WorldIntConfigs : uint8
CONFIG_EXPANSION,
CONFIG_CHATFLOOD_MESSAGE_COUNT,
CONFIG_CHATFLOOD_MESSAGE_DELAY,
CONFIG_CHATFLOOD_ADDON_MESSAGE_COUNT,
CONFIG_CHATFLOOD_ADDON_MESSAGE_DELAY,
CONFIG_CHATFLOOD_MUTE_TIME,
CONFIG_CREATURE_FAMILY_ASSISTANCE_DELAY,
CONFIG_CREATURE_FAMILY_FLEE_DELAY,
+16 -1
View File
@@ -1931,9 +1931,24 @@ ChatFlood.MessageCount = 10
ChatFlood.MessageDelay = 1
#
# ChatFlood.AddonMessageCount
# Description: Chat flood protection, number of addon messages before player gets muted.
# Default: 100 - (Enabled)
# 0 - (Disabled)
ChatFlood.AddonMessageCount = 100
#
# ChatFlood.AddonMessageDelay
# Description: Time (in seconds) between addon messages to be counted into ChatFlood.AddonMessageCount.
# Default: 1
ChatFlood.AddonMessageDelay = 1
#
# ChatFlood.MuteTime
# Description: Time (in seconds) characters get muted for violating ChatFlood.MessageCount.
# Description: Time (in seconds) characters get muted for violating ChatFlood.MessageCount / ChatFlood.AddonMessageCount.
# Default: 10
ChatFlood.MuteTime = 10