diff --git a/apps/docker/docker-build-dev.sh b/apps/docker/docker-build-dev.sh index 830f5b2f4..ced35c437 100644 --- a/apps/docker/docker-build-dev.sh +++ b/apps/docker/docker-build-dev.sh @@ -2,8 +2,6 @@ CUR_PATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -IMPORT_DB=$1 - source "$CUR_PATH/docker-build-prod.sh" echo "Fixing EOL..." @@ -14,5 +12,3 @@ for file in "env/dist/etc/"* do dos2unix -n $file $file done - -[[ $IMPORT_DB != 0 ]] && bash acore.sh db-assembler import-all || true diff --git a/apps/docker/docker-cmd.ts b/apps/docker/docker-cmd.ts index 1511fe9dc..20e22f0f5 100644 --- a/apps/docker/docker-cmd.ts +++ b/apps/docker/docker-cmd.ts @@ -51,11 +51,11 @@ shellCommandFactory( shellCommandFactory( "build:compile", - "Run the compilation process only, without rebuilding all docker images and importing db", + "Run the compilation process only, without rebuilding all docker images", [ "docker-compose build --parallel ac-build", "docker image prune -f", - "docker-compose run --rm ac-build bash apps/docker/docker-build-dev.sh 0", + "docker-compose run --rm ac-build bash apps/docker/docker-build-dev.sh", ], env, ); @@ -77,13 +77,6 @@ shellCommandFactory( env, ); -shellCommandFactory( - "db-import", - "Create and upgrade the database with latest updates", - ["docker-compose run --rm ac-build bash acore.sh db-assembler import-all"], - env, -); - shellCommandFactory( "dev:up", "Start the dev server container in background", diff --git a/src/server/apps/worldserver/worldserver.conf.dist b/src/server/apps/worldserver/worldserver.conf.dist index a0a06f1c4..3e0775842 100644 --- a/src/server/apps/worldserver/worldserver.conf.dist +++ b/src/server/apps/worldserver/worldserver.conf.dist @@ -1880,9 +1880,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 diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 701cafe4e..a95aa49e0 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -153,9 +153,6 @@ Player::Player(WorldSession* session): Unit(true), m_mover(this) #pragma warning(default:4355) #endif - m_speakTime = 0; - m_speakCount = 0; - m_objectType |= TYPEMASK_PLAYER; m_objectTypeId = TYPEID_PLAYER; diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index a3974576d..9edc88db0 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -2256,9 +2256,21 @@ public: /*** FLOOD FILTER SYSTEM ***/ /*********************************************************/ - void UpdateSpeakTime(uint32 specialMessageLimit = 0); + struct ChatFloodThrottle + { + enum Index + { + REGULAR = 0, + ADDON = 1, + MAX + }; + + time_t Time = 0; + uint32 Count = 0; + }; + + void UpdateSpeakTime(ChatFloodThrottle::Index index); [[nodiscard]] bool CanSpeak() const; - void ChangeSpeakTime(int utime); /*********************************************************/ /*** VARIOUS SYSTEMS ***/ @@ -2697,8 +2709,7 @@ public: uint16 m_additionalSaveTimer; // pussywizard uint8 m_additionalSaveMask; // pussywizard uint16 m_hostileReferenceCheckTimer; // pussywizard - time_t m_speakTime; - uint32 m_speakCount; + std::array m_chatFloodData; Difficulty m_dungeonDifficulty; Difficulty m_raidDifficulty; Difficulty m_raidMapDifficulty; diff --git a/src/server/game/Entities/Player/PlayerMisc.cpp b/src/server/game/Entities/Player/PlayerMisc.cpp index c8a91f0b9..173b366f7 100644 --- a/src/server/game/Entities/Player/PlayerMisc.cpp +++ b/src/server/game/Entities/Player/PlayerMisc.cpp @@ -26,34 +26,44 @@ /*** FLOOD FILTER SYSTEM ***/ /*********************************************************/ -void Player::UpdateSpeakTime(uint32 specialMessageLimit) +void Player::UpdateSpeakTime(ChatFloodThrottle::Index index) { // ignore chat spam protection for GMs in any mode if (!AccountMgr::IsPlayerAccount(GetSession()->GetSecurity())) return; - time_t current = GameTime::GetGameTime().count(); - if (m_speakTime > current) + uint32 limit, delay; + switch (index) { - uint32 max_count = specialMessageLimit ? specialMessageLimit : sWorld->getIntConfig(CONFIG_CHATFLOOD_MESSAGE_COUNT); - if (!max_count) - return; - - ++m_speakCount; - if (m_speakCount >= max_count) + case ChatFloodThrottle::ADDON: + limit = sWorld->getIntConfig(CONFIG_CHATFLOOD_ADDON_MESSAGE_COUNT); + delay = sWorld->getIntConfig(CONFIG_CHATFLOOD_ADDON_MESSAGE_DELAY); + break; + case ChatFloodThrottle::REGULAR: + limit = sWorld->getIntConfig(CONFIG_CHATFLOOD_MESSAGE_COUNT); + delay = sWorld->getIntConfig(CONFIG_CHATFLOOD_MESSAGE_DELAY); + [[fallthrough]]; + default: + return; + } + time_t current = GameTime::GetGameTime().count(); + if (m_chatFloodData[index].Time > current) + { + ++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); + m_chatFloodData[index].Time = current + delay; } bool Player::CanSpeak() const diff --git a/src/server/game/Handlers/ChatHandler.cpp b/src/server/game/Handlers/ChatHandler.cpp index 48623c1bd..8f8dd4319 100644 --- a/src/server/game/Handlers/ChatHandler.cpp +++ b/src/server/game/Handlers/ChatHandler.cpp @@ -194,10 +194,8 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) return; } } - // LANG_ADDON should not be changed nor be affected by flood control else { - uint32 specialMessageLimit = 0; // send in universal language if player in .gmon mode (ignore spell effects) if (sender->IsGameMaster()) lang = LANG_UNIVERSAL; @@ -218,20 +216,12 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) // allow two side chat at group channel if two side group allowed if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP)) lang = LANG_UNIVERSAL; - - specialMessageLimit = 35; break; case CHAT_MSG_GUILD: case CHAT_MSG_OFFICER: // allow two side chat at guild channel if two side guild allowed if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD)) lang = LANG_UNIVERSAL; - - specialMessageLimit = 15; - break; - case CHAT_MSG_WHISPER: - if (sender->getLevel() >= 80) - specialMessageLimit = 15; break; } } @@ -242,7 +232,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) } if (type != CHAT_MSG_AFK && type != CHAT_MSG_DND) - sender->UpdateSpeakTime(specialMessageLimit); + sender->UpdateSpeakTime(lang == LANG_ADDON ? Player::ChatFloodThrottle::ADDON : Player::ChatFloodThrottle::REGULAR); } std::string to, channel, msg; @@ -344,6 +334,11 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) } } + else + { + ++_addonMessageReceiveCount; + } + sScriptMgr->OnBeforeSendChatMessage(_player, type, lang, msg); switch (type) @@ -737,7 +732,7 @@ void WorldSession::HandleTextEmoteOpcode(WorldPacket& recvData) if (!GetPlayer()->IsAlive()) return; - GetPlayer()->UpdateSpeakTime(); + GetPlayer()->UpdateSpeakTime(Player::ChatFloodThrottle::REGULAR); if (!GetPlayer()->CanSpeak()) { diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp index 647f9f865..4da60914f 100644 --- a/src/server/game/Server/WorldSession.cpp +++ b/src/server/game/Server/WorldSession.cpp @@ -130,6 +130,7 @@ WorldSession::WorldSession(uint32 id, std::string&& name, std::shared_ptr updater is of type MapSessionFilter { diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index 2699c193a..c1d92a2bb 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -1206,6 +1206,9 @@ private: // Packets cooldown time_t _calendarEventCreationCooldown; + // Addon Message count for Metric + std::atomic _addonMessageReceiveCount; + CircularBuffer> _timeSyncClockDeltaQueue; // first member: clockDelta. Second member: latency of the packet exchange that was used to compute that clockDelta. int64 _timeSyncClockDelta; void ComputeNewClockDelta(); diff --git a/src/server/game/World/IWorld.h b/src/server/game/World/IWorld.h index 52992b4ea..56a4d9355 100644 --- a/src/server/game/World/IWorld.h +++ b/src/server/game/World/IWorld.h @@ -267,6 +267,8 @@ enum WorldIntConfigs 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_EVENT_ANNOUNCE, CONFIG_CREATURE_FAMILY_ASSISTANCE_DELAY, diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index dbd56b23c..005e3422f 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1023,6 +1023,8 @@ void World::LoadConfigSettings(bool reload) m_int_configs[CONFIG_CHATFLOOD_MESSAGE_COUNT] = sConfigMgr->GetOption("ChatFlood.MessageCount", 10); m_int_configs[CONFIG_CHATFLOOD_MESSAGE_DELAY] = sConfigMgr->GetOption("ChatFlood.MessageDelay", 1); + m_int_configs[CONFIG_CHATFLOOD_ADDON_MESSAGE_COUNT] = sConfigMgr->GetOption("ChatFlood.AddonMessageCount", 100); + m_int_configs[CONFIG_CHATFLOOD_ADDON_MESSAGE_DELAY] = sConfigMgr->GetOption("ChatFlood.AddonMessageDelay", 1); m_int_configs[CONFIG_CHATFLOOD_MUTE_TIME] = sConfigMgr->GetOption("ChatFlood.MuteTime", 10); m_bool_configs[CONFIG_CHAT_MUTE_FIRST_LOGIN] = sConfigMgr->GetOption("Chat.MuteFirstLogin", false); m_int_configs[CONFIG_CHAT_TIME_MUTE_FIRST_LOGIN] = sConfigMgr->GetOption("Chat.MuteTimeFirstLogin", 120); diff --git a/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_ayamiss.cpp b/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_ayamiss.cpp index 41204a176..0b9744204 100644 --- a/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_ayamiss.cpp +++ b/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_ayamiss.cpp @@ -24,13 +24,13 @@ enum Spells { - SPELL_STINGER_SPRAY = 25749, - SPELL_POISON_STINGER = 25748, - SPELL_PARALYZE = 25725, - SPELL_FRENZY = 8269, - SPELL_LASH = 25852, - SPELL_FEED = 25721, - SPELL_THRASH = 3391, + SPELL_STINGER_SPRAY = 25749, + SPELL_POISON_STINGER = 25748, + SPELL_PARALYZE = 25725, + SPELL_FRENZY = 8269, + SPELL_LASH = 25852, + SPELL_FEED = 25721, + SPELL_THRASH = 3391, // Server-side spells SPELL_SUMMON_LARVA_A = 26538, @@ -53,26 +53,26 @@ enum Spells enum Misc { - MAX_SWARMER_COUNT = 28, - ACTION_SWARMER_SWARM = 1, + MAX_SWARMER_COUNT = 28, + ACTION_SWARMER_SWARM = 1, }; enum Emotes { - EMOTE_FRENZY = 0 + EMOTE_FRENZY = 0 }; enum Phases { - PHASE_AIR = 0, - PHASE_GROUND = 1 + PHASE_AIR = 0, + PHASE_GROUND = 1 }; enum Points { - POINT_AIR = 0, - POINT_GROUND = 2, - POINT_PARALYZE = 2 + POINT_AIR = 0, + POINT_GROUND = 2, + POINT_PARALYZE = 2 }; const Position AyamissAirPos = { -9689.292f, 1547.912f, 48.02729f, 0.0f }; @@ -177,6 +177,12 @@ struct boss_ayamiss : public BossAI } } + void JustDied(Unit* killer) override + { + me->GetMotionMaster()->MoveFall(); + BossAI::JustDied(killer); + } + void EnterEvadeMode(EvadeReason why) override { me->ClearUnitState(UNIT_STATE_ROOT); diff --git a/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_buru.cpp b/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_buru.cpp index 90744df9a..44a496a33 100644 --- a/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_buru.cpp +++ b/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_buru.cpp @@ -97,12 +97,10 @@ struct boss_buru : public BossAI ChaseNewVictim(); } - void JustDied(Unit* /*killer*/) override + void JustDied(Unit* killer) override { - if (InstanceScript* pInstance = me->GetInstanceScript()) - { - pInstance->DoRemoveAurasDueToSpellOnPlayers(SPELL_CREEPING_PLAGUE); - } + instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_CREEPING_PLAGUE); + BossAI::JustDied(killer); } void KilledUnit(Unit* victim) override