diff options
-rw-r--r-- | src/server/apps/worldserver/worldserver.conf.dist | 1 | ||||
-rw-r--r-- | src/server/game/Autobroadcast/AutobroadcastMgr.cpp | 142 | ||||
-rw-r--r-- | src/server/game/Autobroadcast/AutobroadcastMgr.h | 54 | ||||
-rw-r--r-- | src/server/game/World/IWorld.h | 2 | ||||
-rw-r--r-- | src/server/game/World/World.cpp | 103 | ||||
-rw-r--r-- | src/server/game/World/World.h | 8 | ||||
-rw-r--r-- | src/server/scripts/Commands/cs_reload.cpp | 3 | ||||
-rw-r--r-- | src/test/mocks/WorldMock.h | 2 |
8 files changed, 202 insertions, 113 deletions
diff --git a/src/server/apps/worldserver/worldserver.conf.dist b/src/server/apps/worldserver/worldserver.conf.dist index 02210dd417..d18bea3adb 100644 --- a/src/server/apps/worldserver/worldserver.conf.dist +++ b/src/server/apps/worldserver/worldserver.conf.dist @@ -3931,6 +3931,7 @@ Logger.module=4,Console Server #Logger.addon=4,Console Server #Logger.ahbot=4,Console Server #Logger.auctionHouse=4,Console Server +#Logger.autobroadcast=4, Console Server #Logger.bg.arena=4,Console Server #Logger.bg.battlefield=4,Console Server #Logger.bg.battleground=4,Console Server diff --git a/src/server/game/Autobroadcast/AutobroadcastMgr.cpp b/src/server/game/Autobroadcast/AutobroadcastMgr.cpp new file mode 100644 index 0000000000..1ed046685b --- /dev/null +++ b/src/server/game/Autobroadcast/AutobroadcastMgr.cpp @@ -0,0 +1,142 @@ +/* + * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by the + * Free Software Foundation; either version 3 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "AutobroadcastMgr.h" +#include "Config.h" +#include "Chat.h" +#include "Player.h" +#include "GridNotifiers.h" + +AutobroadcastMgr* AutobroadcastMgr::instance() +{ + static AutobroadcastMgr instance; + return &instance; +} + +void AutobroadcastMgr::LoadAutobroadcasts() +{ + uint32 oldMSTime = getMSTime(); + + _autobroadcasts.clear(); + _autobroadcastsWeights.clear(); + + uint32 realmId = sConfigMgr->GetOption<int32>("RealmID", 0); + LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_AUTOBROADCAST); + stmt->SetData(0, realmId); + PreparedQueryResult result = LoginDatabase.Query(stmt); + + if (!result) + { + LOG_WARN("autobroadcast", ">> Loaded 0 autobroadcasts definitions. DB table `autobroadcast` is empty for this realm!"); + LOG_INFO("autobroadcast", " "); + return; + } + + _announceType = static_cast<AnnounceType>(sWorld->getIntConfig(CONFIG_AUTOBROADCAST_CENTER)); + + if (_announceType < AnnounceType::World || _announceType > AnnounceType::Both) + { + LOG_ERROR("autobroadcast", "AutobroadcastMgr::LoadAutobroadcasts: Config option AutoBroadcast.Center set to not allowed value {}. Set to default value 0", (int8)_announceType); + _announceType = AnnounceType::World; + } + + uint32 count = 0; + + do + { + Field* fields = result->Fetch(); + uint8 id = fields[0].Get<uint8>(); + + _autobroadcasts[id] = fields[2].Get<std::string>(); + _autobroadcastsWeights[id] = fields[1].Get<uint8>(); + + ++count; + } while (result->NextRow()); + + LOG_INFO("autobroadcast", ">> Loaded {} Autobroadcast Definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime)); + LOG_INFO("autobroadcast", " "); +} + +void AutobroadcastMgr::SendAutobroadcasts() +{ + if (_autobroadcasts.empty()) + { + return; + } + + uint32 weight = 0; + AutobroadcastsWeightMap selectionWeights; + + std::string msg; + + for (AutobroadcastsWeightMap::const_iterator it = _autobroadcastsWeights.begin(); it != _autobroadcastsWeights.end(); ++it) + { + if (it->second) + { + weight += it->second; + selectionWeights[it->first] = it->second; + } + } + + if (weight) + { + uint32 selectedWeight = urand(0, weight - 1); + weight = 0; + for (AutobroadcastsWeightMap::const_iterator it = selectionWeights.begin(); it != selectionWeights.end(); ++it) + { + weight += it->second; + if (selectedWeight < weight) + { + msg = _autobroadcasts[it->first]; + break; + } + } + } + else + { + msg = _autobroadcasts[urand(0, _autobroadcasts.size())]; + } + + switch (_announceType) + { + case AnnounceType::World: + SendWorldAnnouncement(msg); + break; + case AnnounceType::Notification: + SendNotificationAnnouncement(msg); + break; + case AnnounceType::Both: + SendWorldAnnouncement(msg); + SendNotificationAnnouncement(msg); + default: + break; + } + + LOG_DEBUG("autobroadcast", "AutobroadcastMgr::SendAutobroadcasts: '{}'", msg); +} + +void AutobroadcastMgr::SendWorldAnnouncement(std::string_view msg) +{ + sWorld->SendWorldTextOptional(LANG_AUTO_BROADCAST, ANNOUNCER_FLAG_DISABLE_AUTOBROADCAST, msg.data()); +} + +void AutobroadcastMgr::SendNotificationAnnouncement(std::string_view msg) +{ + WorldPacket data(SMSG_NOTIFICATION, (msg.size() + 1)); + data << msg.data(); + sWorld->SendGlobalMessage(&data); +} diff --git a/src/server/game/Autobroadcast/AutobroadcastMgr.h b/src/server/game/Autobroadcast/AutobroadcastMgr.h new file mode 100644 index 0000000000..2a45d48dd1 --- /dev/null +++ b/src/server/game/Autobroadcast/AutobroadcastMgr.h @@ -0,0 +1,54 @@ +/* + * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by the + * Free Software Foundation; either version 3 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef _AUTOBROADCASTMGR_H_ +#define _AUTOBROADCASTMGR_H_ + +#include "Common.h" +#include <map> + +enum class AnnounceType : uint8 +{ + World = 0, + Notification = 1, + Both = 2, +}; + +class AC_GAME_API AutobroadcastMgr +{ +public: + static AutobroadcastMgr* instance(); + + void LoadAutobroadcasts(); + void SendAutobroadcasts(); + +private: + void SendWorldAnnouncement(std::string_view msg); + void SendNotificationAnnouncement(std::string_view msg); + + typedef std::map<uint8, std::string> AutobroadcastsMap; + typedef std::map<uint8, uint8> AutobroadcastsWeightMap; + + AutobroadcastsMap _autobroadcasts; + AutobroadcastsWeightMap _autobroadcastsWeights; + + AnnounceType _announceType; +}; + +#define sAutobroadcastMgr AutobroadcastMgr::instance() + +#endif // _AUTOBROADCASTMGR_H_ diff --git a/src/server/game/World/IWorld.h b/src/server/game/World/IWorld.h index 663b54f8f9..6e340c5150 100644 --- a/src/server/game/World/IWorld.h +++ b/src/server/game/World/IWorld.h @@ -520,7 +520,6 @@ public: [[nodiscard]] virtual WorldSession* FindOfflineSession(uint32 id) const = 0; [[nodiscard]] virtual WorldSession* FindOfflineSessionForCharacterGUID(ObjectGuid::LowType guidLow) const = 0; virtual void AddSession(WorldSession* s) = 0; - virtual void SendAutoBroadcast() = 0; virtual bool KickSession(uint32 id) = 0; virtual void UpdateMaxSessionCounters() = 0; [[nodiscard]] virtual const SessionMap& GetAllSessions() const = 0; @@ -596,7 +595,6 @@ public: [[nodiscard]] virtual LocaleConstant GetAvailableDbcLocale(LocaleConstant locale) const = 0; virtual void LoadDBVersion() = 0; [[nodiscard]] virtual char const* GetDBVersion() const = 0; - virtual void LoadAutobroadcasts() = 0; virtual void LoadMotd() = 0; virtual void UpdateAreaDependentAuras() = 0; [[nodiscard]] virtual uint32 GetCleaningFlags() const = 0; diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 6342d1057c..cbc2fb82db 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -26,6 +26,7 @@ #include "ArenaTeamMgr.h" #include "AsyncAuctionListing.h" #include "AuctionHouseMgr.h" +#include "AutobroadcastMgr.h" #include "BattlefieldMgr.h" #include "BattlegroundMgr.h" #include "CalendarMgr.h" @@ -1987,7 +1988,7 @@ void World::SetInitialWorldSettings() ///- Load AutoBroadCast LOG_INFO("server.loading", "Loading Autobroadcasts..."); - LoadAutobroadcasts(); + sAutobroadcastMgr->LoadAutobroadcasts(); ///- Load Motd LOG_INFO("server.loading", "Loading MotD..."); @@ -2221,42 +2222,6 @@ void World::DetectDBCLang() LOG_INFO("server.loading", " "); } -void World::LoadAutobroadcasts() -{ - uint32 oldMSTime = getMSTime(); - - _autobroadcasts.clear(); - _autobroadcastsWeights.clear(); - - uint32 realmId = sConfigMgr->GetOption<int32>("RealmID", 0); - LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_AUTOBROADCAST); - stmt->SetData(0, realmId); - PreparedQueryResult result = LoginDatabase.Query(stmt); - - if (!result) - { - LOG_WARN("server.loading", ">> Loaded 0 autobroadcasts definitions. DB table `autobroadcast` is empty for this realm!"); - LOG_INFO("server.loading", " "); - return; - } - - uint32 count = 0; - - do - { - Field* fields = result->Fetch(); - uint8 id = fields[0].Get<uint8>(); - - _autobroadcasts[id] = fields[2].Get<std::string>(); - _autobroadcastsWeights[id] = fields[1].Get<uint8>(); - - ++count; - } while (result->NextRow()); - - LOG_INFO("server.loading", ">> Loaded {} Autobroadcast Definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime)); - LOG_INFO("server.loading", " "); -} - void World::LoadMotd() { uint32 oldMSTime = getMSTime(); @@ -2449,7 +2414,7 @@ void World::Update(uint32 diff) { METRIC_TIMER("world_update_time", METRIC_TAG("type", "Send autobroadcast")); _timers[WUPDATE_AUTOBROADCAST].Reset(); - SendAutoBroadcast(); + sAutobroadcastMgr->SendAutobroadcasts(); } } @@ -3028,68 +2993,6 @@ void World::ProcessCliCommands() } } -void World::SendAutoBroadcast() -{ - if (_autobroadcasts.empty()) - return; - - uint32 weight = 0; - AutobroadcastsWeightMap selectionWeights; - - std::string msg; - - for (AutobroadcastsWeightMap::const_iterator it = _autobroadcastsWeights.begin(); it != _autobroadcastsWeights.end(); ++it) - { - if (it->second) - { - weight += it->second; - selectionWeights[it->first] = it->second; - } - } - - if (weight) - { - uint32 selectedWeight = urand(0, weight - 1); - weight = 0; - for (AutobroadcastsWeightMap::const_iterator it = selectionWeights.begin(); it != selectionWeights.end(); ++it) - { - weight += it->second; - if (selectedWeight < weight) - { - msg = _autobroadcasts[it->first]; - break; - } - } - } - else - msg = _autobroadcasts[urand(0, _autobroadcasts.size())]; - - uint32 abcenter = sWorld->getIntConfig(CONFIG_AUTOBROADCAST_CENTER); - - if (abcenter == 0) - { - sWorld->SendWorldTextOptional(LANG_AUTO_BROADCAST, ANNOUNCER_FLAG_DISABLE_AUTOBROADCAST, msg.c_str()); - } - - else if (abcenter == 1) - { - WorldPacket data(SMSG_NOTIFICATION, (msg.size() + 1)); - data << msg; - sWorld->SendGlobalMessage(&data); - } - - else if (abcenter == 2) - { - sWorld->SendWorldTextOptional(LANG_AUTO_BROADCAST, ANNOUNCER_FLAG_DISABLE_AUTOBROADCAST, msg.c_str()); - - WorldPacket data(SMSG_NOTIFICATION, (msg.size() + 1)); - data << msg; - sWorld->SendGlobalMessage(&data); - } - - LOG_DEBUG("server.worldserver", "AutoBroadcast: '{}'", msg); -} - void World::UpdateRealmCharCount(uint32 accountId) { CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_COUNT); diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h index 6b53fbf8af..bb1ec8b844 100644 --- a/src/server/game/World/World.h +++ b/src/server/game/World/World.h @@ -163,7 +163,6 @@ public: [[nodiscard]] WorldSession* FindOfflineSession(uint32 id) const override; [[nodiscard]] WorldSession* FindOfflineSessionForCharacterGUID(ObjectGuid::LowType guidLow) const override; void AddSession(WorldSession* s) override; - void SendAutoBroadcast() override; bool KickSession(uint32 id) override; /// Get the number of current active sessions void UpdateMaxSessionCounters() override; @@ -341,7 +340,6 @@ public: void LoadDBVersion() override; [[nodiscard]] char const* GetDBVersion() const override { return _dbVersion.c_str(); } - void LoadAutobroadcasts() override; void LoadMotd() override; void UpdateAreaDependentAuras() override; @@ -438,12 +436,6 @@ private: // used versions std::string _dbVersion; - typedef std::map<uint8, std::string> AutobroadcastsMap; - AutobroadcastsMap _autobroadcasts; - - typedef std::map<uint8, uint8> AutobroadcastsWeightMap; - AutobroadcastsWeightMap _autobroadcastsWeights; - void ProcessQueryCallbacks(); QueryCallbackProcessor _queryProcessor; diff --git a/src/server/scripts/Commands/cs_reload.cpp b/src/server/scripts/Commands/cs_reload.cpp index 5eefe3a817..a0d2fad318 100644 --- a/src/server/scripts/Commands/cs_reload.cpp +++ b/src/server/scripts/Commands/cs_reload.cpp @@ -24,6 +24,7 @@ EndScriptData */ #include "AchievementMgr.h" #include "AuctionHouseMgr.h" +#include "AutobroadcastMgr.h" #include "BattlegroundMgr.h" #include "Chat.h" #include "CreatureTextMgr.h" @@ -401,7 +402,7 @@ public: static bool HandleReloadAutobroadcastCommand(ChatHandler* handler) { LOG_INFO("server.loading", "Re-Loading Autobroadcasts..."); - sWorld->LoadAutobroadcasts(); + sAutobroadcastMgr->LoadAutobroadcasts(); handler->SendGlobalGMSysMessage("DB table `autobroadcast` reloaded."); return true; } diff --git a/src/test/mocks/WorldMock.h b/src/test/mocks/WorldMock.h index d4e0247f19..aa8e88d6f3 100644 --- a/src/test/mocks/WorldMock.h +++ b/src/test/mocks/WorldMock.h @@ -36,7 +36,6 @@ public: MOCK_METHOD(WorldSession*, FindOfflineSession, (uint32 id), (const)); MOCK_METHOD(WorldSession*, FindOfflineSessionForCharacterGUID, (ObjectGuid::LowType guidLow),(const)); MOCK_METHOD(void, AddSession, (WorldSession* s), ()); - MOCK_METHOD(void, SendAutoBroadcast, ()); MOCK_METHOD(bool, KickSession, (uint32 id), ()); MOCK_METHOD(void, UpdateMaxSessionCounters, ()); MOCK_METHOD(const SessionMap&, GetAllSessions, (), (const)); @@ -112,7 +111,6 @@ public: MOCK_METHOD(LocaleConstant, GetAvailableDbcLocale, (LocaleConstant locale), (const)); MOCK_METHOD(void, LoadDBVersion, ()); MOCK_METHOD(char const *, GetDBVersion, (), (const)); - MOCK_METHOD(void, LoadAutobroadcasts, ()); MOCK_METHOD(void, LoadMotd, ()); MOCK_METHOD(void, UpdateAreaDependentAuras, ()); MOCK_METHOD(uint32, GetCleaningFlags, (), (const)); |