diff --git a/src/server/game/Cache/WhoListCacheMgr.cpp b/src/server/game/Cache/WhoListCacheMgr.cpp
new file mode 100644
index 000000000..bebd3e8c6
--- /dev/null
+++ b/src/server/game/Cache/WhoListCacheMgr.cpp
@@ -0,0 +1,63 @@
+/*
+ * 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 .
+ */
+
+#include "WhoListCacheMgr.h"
+#include "GuildMgr.h"
+#include "ObjectAccessor.h"
+#include "Player.h"
+#include "World.h"
+#include "WorldSession.h"
+
+WhoListCacheMgr* WhoListCacheMgr::instance()
+{
+ static WhoListCacheMgr instance;
+ return &instance;
+}
+
+void WhoListCacheMgr::Update()
+{
+ // clear current list
+ _whoListStorage.clear();
+ _whoListStorage.reserve(sWorld->GetPlayerCount() + 1);
+
+ for (auto const& [guid, player] : ObjectAccessor::GetPlayers())
+ {
+ if (!player->FindMap() || player->GetSession()->PlayerLoading())
+ continue;
+
+ std::string playerName = player->GetName();
+ std::wstring widePlayerName;
+
+ if (!Utf8toWStr(playerName, widePlayerName))
+ continue;
+
+ wstrToLower(widePlayerName);
+
+ std::string guildName = sGuildMgr->GetGuildNameById(player->GetGuildId());
+ std::wstring wideGuildName;
+
+ if (!Utf8toWStr(guildName, wideGuildName))
+ continue;
+
+ wstrToLower(wideGuildName);
+
+ _whoListStorage.emplace_back(player->GetGUID(), player->GetTeamId(), player->GetSession()->GetSecurity(), player->getLevel(),
+ player->getClass(), player->getRace(),
+ (player->IsSpectator() ? 4395 /*Dalaran*/ : player->GetZoneId()), player->getGender(), player->IsVisible(),
+ widePlayerName, wideGuildName, playerName, guildName);
+ }
+}
diff --git a/src/server/game/Cache/WhoListCacheMgr.h b/src/server/game/Cache/WhoListCacheMgr.h
new file mode 100644
index 000000000..ebeab820e
--- /dev/null
+++ b/src/server/game/Cache/WhoListCacheMgr.h
@@ -0,0 +1,98 @@
+/*
+ * 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 .
+ */
+
+#ifndef _WHO_LISTCACHE_H_
+#define _WHO_LISTCACHE_H_
+
+#include "Common.h"
+#include "SharedDefines.h"
+#include "ObjectGuid.h"
+
+class WhoListPlayerInfo
+{
+public:
+ WhoListPlayerInfo(ObjectGuid guid, TeamId team, AccountTypes security, uint8 level, uint8 clss, uint8 race, uint32 zoneid, uint8 gender, bool visible, std::wstring const& widePlayerName,
+ std::wstring const& wideGuildName, std::string const& playerName, std::string const& guildName) :
+ _guid(guid),
+ _team(team),
+ _security(security),
+ _level(level),
+ _class(clss),
+ _race(race),
+ _zoneid(zoneid),
+ _gender(gender),
+ _visible(visible),
+ _widePlayerName(widePlayerName),
+ _wideGuildName(wideGuildName),
+ _playerName(playerName),
+ _guildName(guildName) { }
+
+ ObjectGuid GetGuid() const { return _guid; }
+ TeamId GetTeamId() const { return _team; }
+ AccountTypes GetSecurity() const { return _security; }
+ uint8 GetLevel() const { return _level; }
+ uint8 GetClass() const { return _class; }
+ uint8 GetRace() const { return _race; }
+ uint32 GetZoneId() const { return _zoneid; }
+ uint8 GetGender() const { return _gender; }
+ bool IsVisible() const { return _visible; }
+ std::wstring const& GetWidePlayerName() const { return _widePlayerName; }
+ std::wstring const& GetWideGuildName() const { return _wideGuildName; }
+ std::string const& GetPlayerName() const { return _playerName; }
+ std::string const& GetGuildName() const { return _guildName; }
+
+private:
+ ObjectGuid _guid;
+ TeamId _team;
+ AccountTypes _security;
+ uint8 _level;
+ uint8 _class;
+ uint8 _race;
+ uint32 _zoneid;
+ uint8 _gender;
+ bool _visible;
+ std::wstring _widePlayerName;
+ std::wstring _wideGuildName;
+ std::string _playerName;
+ std::string _guildName;
+};
+
+using WhoListInfoVector = std::vector;
+
+class AC_GAME_API WhoListCacheMgr
+{
+ WhoListCacheMgr() = default;
+ ~WhoListCacheMgr() = default;
+
+ WhoListCacheMgr(WhoListCacheMgr const&) = delete;
+ WhoListCacheMgr(WhoListCacheMgr&&) = delete;
+
+ WhoListCacheMgr& operator= (WhoListCacheMgr const&) = delete;
+ WhoListCacheMgr& operator= (WhoListCacheMgr&&) = delete;
+public:
+ static WhoListCacheMgr* instance();
+
+ void Update();
+ WhoListInfoVector const& GetWhoList() const { return _whoListStorage; }
+
+protected:
+ WhoListInfoVector _whoListStorage;
+};
+
+#define sWhoListCacheMgr WhoListCacheMgr::instance()
+
+#endif
diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp
index 62c9eb705..b78632302 100644
--- a/src/server/game/Handlers/MiscHandler.cpp
+++ b/src/server/game/Handlers/MiscHandler.cpp
@@ -22,8 +22,8 @@
#include "Chat.h"
#include "Common.h"
#include "CreatureAI.h"
-#include "DatabaseEnv.h"
#include "DBCEnums.h"
+#include "DatabaseEnv.h"
#include "GameObjectAI.h"
#include "GossipDef.h"
#include "Group.h"
@@ -45,10 +45,11 @@
#include "Spell.h"
#include "UpdateData.h"
#include "Vehicle.h"
+#include "WhoListCacheMgr.h"
#include "World.h"
#include "WorldPacket.h"
#include "WorldSession.h"
-#include "zlib.h"
+#include
#ifdef ELUNA
#include "LuaEngine.h"
@@ -211,70 +212,67 @@ void WorldSession::HandleWhoOpcode(WorldPacket& recvData)
{
LOG_DEBUG("network", "WORLD: Recvd CMSG_WHO Message");
- time_t now = time(nullptr);
- if (now < timeWhoCommandAllowed)
- return;
- timeWhoCommandAllowed = now + 3;
+ uint32 matchCount = 0;
- uint32 matchcount = 0;
+ uint32 levelMin, levelMax, racemask, classmask, zonesCount, strCount;
+ std::array zoneids = {}; // 10 is client limit
+ std::string packetPlayerName, packetGuildName;
- uint32 level_min, level_max, racemask, classmask, zones_count, str_count;
- uint32 zoneids[10]; // 10 is client limit
- std::string player_name, guild_name;
+ recvData >> levelMin; // maximal player level, default 0
+ recvData >> levelMax; // minimal player level, default 100 (MAX_LEVEL)
+ recvData >> packetPlayerName; // player name, case sensitive...
- recvData >> level_min; // maximal player level, default 0
- recvData >> level_max; // minimal player level, default 100 (MAX_LEVEL)
- recvData >> player_name; // player name, case sensitive...
+ recvData >> packetGuildName; // guild name, case sensitive...
- recvData >> guild_name; // guild name, case sensitive...
+ recvData >> racemask; // race mask
+ recvData >> classmask; // class mask
+ recvData >> zonesCount; // zones count, client limit = 10 (2.0.10)
- recvData >> racemask; // race mask
- recvData >> classmask; // class mask
- recvData >> zones_count; // zones count, client limit = 10 (2.0.10)
-
- if (zones_count > 10)
+ if (zonesCount > 10)
return; // can't be received from real client or broken packet
- for (uint32 i = 0; i < zones_count; ++i)
+ for (uint32 i = 0; i < zonesCount; ++i)
{
uint32 temp;
- recvData >> temp; // zone id, 0 if zone is unknown...
+ recvData >> temp; // zone id, 0 if zone is unknown...
zoneids[i] = temp;
- LOG_DEBUG("network", "Zone %u: %u", i, zoneids[i]);
+ FMT_LOG_DEBUG("network.who", "Zone {}: {}", i, zoneids[i]);
}
- recvData >> str_count; // user entered strings count, client limit=4 (checked on 2.0.10)
+ recvData >> strCount; // user entered strings count, client limit=4 (checked on 2.0.10)
- if (str_count > 4)
+ if (strCount > 4)
return; // can't be received from real client or broken packet
- LOG_DEBUG("network", "Minlvl %u, maxlvl %u, name %s, guild %s, racemask %u, classmask %u, zones %u, strings %u", level_min, level_max, player_name.c_str(), guild_name.c_str(), racemask, classmask, zones_count, str_count);
+ FMT_LOG_DEBUG("network.who", "Minlvl {}, maxlvl {}, name {}, guild {}, racemask {}, classmask {}, zones {}, strings {}",
+ levelMin, levelMax, packetPlayerName, packetGuildName, racemask, classmask, zonesCount, strCount);
std::wstring str[4]; // 4 is client limit
- for (uint32 i = 0; i < str_count; ++i)
+ for (uint32 i = 0; i < strCount; ++i)
{
std::string temp;
- recvData >> temp; // user entered string, it used as universal search pattern(guild+player name)?
+ recvData >> temp; // user entered string, it used as universal search pattern(guild+player name)?
if (!Utf8toWStr(temp, str[i]))
continue;
wstrToLower(str[i]);
- LOG_DEBUG("network", "String %u: %s", i, temp.c_str());
+ FMT_LOG_DEBUG("network.who", "String {}: {}", i, temp);
}
- std::wstring wplayer_name;
- std::wstring wguild_name;
- if (!(Utf8toWStr(player_name, wplayer_name) && Utf8toWStr(guild_name, wguild_name)))
+ std::wstring wpacketPlayerName;
+ std::wstring wpacketGuildName;
+ if (!(Utf8toWStr(packetPlayerName, wpacketPlayerName) && Utf8toWStr(packetGuildName, wpacketGuildName)))
return;
- wstrToLower(wplayer_name);
- wstrToLower(wguild_name);
- // client send in case not set max level value 100 but Trinity supports 255 max level,
+ wstrToLower(wpacketPlayerName);
+ wstrToLower(wpacketGuildName);;
+
+ // client send in case not set max level value 100 but Acore supports 255 max level,
// update it to show GMs with characters after 100 level
- if (level_max >= MAX_LEVEL)
- level_max = STRONG_MAX_LEVEL;
+ if (levelMax >= MAX_LEVEL)
+ levelMax = STRONG_MAX_LEVEL;
uint32 team = _player->GetTeamId();
uint32 security = GetSecurity();
@@ -282,126 +280,138 @@ void WorldSession::HandleWhoOpcode(WorldPacket& recvData)
uint32 gmLevelInWhoList = sWorld->getIntConfig(CONFIG_GM_LEVEL_IN_WHO_LIST);
uint32 displaycount = 0;
- WorldPacket data(SMSG_WHO, 50); // guess size
- data << uint32(matchcount); // placeholder, count of players matching criteria
- data << uint32(displaycount); // placeholder, count of players displayed
+ WorldPacket data(SMSG_WHO, 50); // guess size
+ data << uint32(matchCount); // placeholder, count of players matching criteria
+ data << uint32(displaycount); // placeholder, count of players displayed
- std::shared_lock lock(*HashMapHolder::GetLock());
- HashMapHolder::MapType const& m = ObjectAccessor::GetPlayers();
- for (HashMapHolder::MapType::const_iterator itr = m.begin(); itr != m.end(); ++itr)
+ for (auto const& target : sWhoListCacheMgr->GetWhoList())
{
if (AccountMgr::IsPlayerAccount(security))
{
// player can see member of other team only if CONFIG_ALLOW_TWO_SIDE_WHO_LIST
- if (itr->second->GetTeamId() != team && !allowTwoSideWhoList)
+ if (target.GetTeamId() != team && !allowTwoSideWhoList)
+ {
continue;
+ }
// player can see MODERATOR, GAME MASTER, ADMINISTRATOR only if CONFIG_GM_IN_WHO_LIST
- if ((itr->second->GetSession()->GetSecurity() > AccountTypes(gmLevelInWhoList)))
+ if (target.GetSecurity() > AccountTypes(gmLevelInWhoList))
+ {
continue;
+ }
}
- //do not process players which are not in world
- if (!(itr->second->IsInWorld()))
- continue;
-
// check if target is globally visible for player
- if (!(itr->second->IsVisibleGloballyFor(_player)))
+ if ((_player->GetGUID() != target.GetGuid() && !target.IsVisible()) &&
+ (AccountMgr::IsPlayerAccount(_player->GetSession()->GetSecurity()) || target.GetSecurity() > _player->GetSession()->GetSecurity()))
+ {
continue;
+ }
// check if target's level is in level range
- uint8 lvl = itr->second->getLevel();
- if (lvl < level_min || lvl > level_max)
+ uint8 lvl = target.GetLevel();
+ if (lvl < levelMin || lvl > levelMax)
+ {
continue;
+ }
// check if class matches classmask
- uint32 class_ = itr->second->getClass();
+ uint8 class_ = target.GetClass();
if (!(classmask & (1 << class_)))
+ {
continue;
+ }
// check if race matches racemask
- uint32 race = itr->second->getRace();
+ uint32 race = target.GetRace();
if (!(racemask & (1 << race)))
- continue;
-
- uint32 pzoneid = itr->second->GetZoneId();
- uint8 gender = itr->second->getGender();
-
- bool z_show = true;
- for (uint32 i = 0; i < zones_count; ++i)
{
- if (zoneids[i] == pzoneid)
+ continue;
+ }
+
+ uint32 playerZoneId = target.GetZoneId();
+ uint8 gender = target.GetGender();
+
+ bool showZones = true;
+ for (uint32 i = 0; i < zonesCount; ++i)
+ {
+ if (zoneids[i] == playerZoneId)
{
- z_show = true;
+ showZones = true;
break;
}
- z_show = false;
+ showZones = false;
}
- if (!z_show)
- continue;
- std::string pname = itr->second->GetName();
- std::wstring wpname;
- if (!Utf8toWStr(pname, wpname))
+ if (!showZones)
+ {
continue;
- wstrToLower(wpname);
+ }
- if (!(wplayer_name.empty() || wpname.find(wplayer_name) != std::wstring::npos))
+ std::wstring const& wideplayername = target.GetWidePlayerName();
+ if (!(wpacketPlayerName.empty() || wideplayername.find(wpacketPlayerName) != std::wstring::npos))
+ {
continue;
+ }
- std::string gname = sGuildMgr->GetGuildNameById(itr->second->GetGuildId());
- std::wstring wgname;
- if (!Utf8toWStr(gname, wgname))
- continue;
- wstrToLower(wgname);
-
- if (!(wguild_name.empty() || wgname.find(wguild_name) != std::wstring::npos))
+ std::wstring const& wideguildname = target.GetWideGuildName();
+ if (!(wpacketGuildName.empty() || wideguildname.find(wpacketGuildName) != std::wstring::npos))
+ {
continue;
+ }
std::string aname;
- if (AreaTableEntry const* areaEntry = sAreaTableStore.LookupEntry(itr->second->GetZoneId()))
+ if (AreaTableEntry const* areaEntry = sAreaTableStore.LookupEntry(playerZoneId))
+ {
aname = areaEntry->area_name[GetSessionDbcLocale()];
+ }
bool s_show = true;
- for (uint32 i = 0; i < str_count; ++i)
+ for (uint32 i = 0; i < strCount; ++i)
{
if (!str[i].empty())
{
- if (wgname.find(str[i]) != std::wstring::npos ||
- wpname.find(str[i]) != std::wstring::npos ||
- Utf8FitTo(aname, str[i]))
+ if (wideguildname.find(str[i]) != std::wstring::npos ||
+ wideplayername.find(str[i]) != std::wstring::npos ||
+ Utf8FitTo(aname, str[i]))
{
s_show = true;
break;
}
+
s_show = false;
}
}
+
if (!s_show)
+ {
continue;
+ }
// 49 is maximum player count sent to client - can be overridden
// through config, but is unstable
- if ((matchcount++) >= sWorld->getIntConfig(CONFIG_MAX_WHO_LIST_RETURN))
+ if ((matchCount++) >= sWorld->getIntConfig(CONFIG_MAX_WHO_LIST_RETURN))
+ {
continue;
+ }
- data << pname; // player name
- data << gname; // guild name
+ data << target.GetPlayerName(); // player name
+ data << target.GetGuildName(); // guild name
data << uint32(lvl); // player level
data << uint32(class_); // player class
data << uint32(race); // player race
data << uint8(gender); // player gender
- data << uint32(pzoneid); // player zone id
+ data << uint32(playerZoneId); // player zone id
++displaycount;
}
data.put(0, displaycount); // insert right count, count displayed
- data.put(4, matchcount); // insert right count, count of matches
+ data.put(4, matchCount); // insert right count, count of matches
SendPacket(&data);
- // LOG_DEBUG("network", "WORLD: Send SMSG_WHO Message");
+ FMT_LOG_DEBUG("network", "WORLD: Send SMSG_WHO Message");
}
void WorldSession::HandleLogoutRequestOpcode(WorldPacket& /*recv_data*/)
diff --git a/src/server/game/Handlers/MovementHandler.cpp b/src/server/game/Handlers/MovementHandler.cpp
index eec83688c..0b66552ea 100644
--- a/src/server/game/Handlers/MovementHandler.cpp
+++ b/src/server/game/Handlers/MovementHandler.cpp
@@ -166,7 +166,6 @@ void WorldSession::HandleMoveWorldportAck()
_player->SetIsSpectator(false);
GetPlayer()->SetPendingSpectatorForBG(0);
- timeWhoCommandAllowed = time(nullptr) + sWorld->GetNextWhoListUpdateDelaySecs() + 1; // after exiting arena Subscribe will scan for a player and cached data says he is still in arena, so disallow until next update
if (uint32 inviteInstanceId = _player->GetPendingSpectatorInviteInstanceId())
{
diff --git a/src/server/game/Misc/WhoListCache.cpp b/src/server/game/Misc/WhoListCache.cpp
deleted file mode 100644
index 9680da250..000000000
--- a/src/server/game/Misc/WhoListCache.cpp
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * 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 .
- */
-
-#include "GuildMgr.h"
-#include "ObjectAccessor.h"
-#include "Player.h"
-#include "WhoListCache.h"
-#include "World.h"
-
-std::vector WhoListCacheMgr::m_whoOpcodeList;
-
-void WhoListCacheMgr::Update()
-{
- // clear current list
- m_whoOpcodeList.clear();
- m_whoOpcodeList.reserve(sWorld->GetPlayerCount() + 1);
-
- std::shared_lock lock(*HashMapHolder::GetLock());
- HashMapHolder::MapType const& m = ObjectAccessor::GetPlayers();
- for (HashMapHolder::MapType::const_iterator itr = m.begin(); itr != m.end(); ++itr)
- {
- if (!itr->second->FindMap() || itr->second->GetSession()->PlayerLoading())
- continue;
-
- if (itr->second->GetSession()->GetSecurity() > SEC_PLAYER)
- continue;
-
- std::string pname = itr->second->GetName();
- std::wstring wpname;
- if (!Utf8toWStr(pname, wpname))
- continue;
- wstrToLower(wpname);
-
- std::string gname = sGuildMgr->GetGuildNameById(itr->second->GetGuildId());
- std::wstring wgname;
- if (!Utf8toWStr(gname, wgname))
- continue;
- wstrToLower(wgname);
-
- std::string aname;
- if (AreaTableEntry const* areaEntry = sAreaTableStore.LookupEntry(itr->second->GetZoneId()))
- aname = areaEntry->area_name[sWorld->GetDefaultDbcLocale()];
-
- if (itr->second->IsSpectator())
- aname = "Dalaran";
-
- m_whoOpcodeList.push_back( WhoListPlayerInfo(itr->second->GetTeamId(), itr->second->GetSession()->GetSecurity(), itr->second->getLevel(), itr->second->getClass(), itr->second->getRace(), (itr->second->IsSpectator() ? 4395 /*Dalaran*/ : itr->second->GetZoneId()), itr->second->getGender(), wpname, wgname, aname, pname, gname) );
- }
-}
diff --git a/src/server/game/Misc/WhoListCache.h b/src/server/game/Misc/WhoListCache.h
deleted file mode 100644
index ddc54a8e7..000000000
--- a/src/server/game/Misc/WhoListCache.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * 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 .
- */
-
-#ifndef __WHOLISTCACHE_H
-#define __WHOLISTCACHE_H
-
-#include "Common.h"
-#include "SharedDefines.h"
-
-struct WhoListPlayerInfo
-{
- TeamId teamId;
- AccountTypes security;
- uint8 level;
- uint8 clas;
- uint8 race;
- uint32 zoneid;
- uint8 gender;
- std::wstring wpname;
- std::wstring wgname;
- std::string aname;
- std::string pname;
- std::string gname;
-
- WhoListPlayerInfo(TeamId teamId, AccountTypes security, uint8 level, uint8 clas, uint8 race, uint32 zoneid, uint8 gender, std::wstring wpname, std::wstring wgname, std::string aname, std::string pname, std::string gname) :
- teamId(teamId), security(security), level(level), clas(clas), race(race), zoneid(zoneid), gender(gender), wpname(wpname), wgname(wgname), aname(aname), pname(pname), gname(gname) {}
-};
-
-class WhoListCacheMgr
-{
-public:
- static void Update();
- static std::vector* GetWhoList() { return &m_whoOpcodeList; }
-
-protected:
- static std::vector m_whoOpcodeList;
-};
-
-#endif
diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp
index b048bbbd3..56b1dd208 100644
--- a/src/server/game/Server/WorldSession.cpp
+++ b/src/server/game/Server/WorldSession.cpp
@@ -132,7 +132,6 @@ WorldSession::WorldSession(uint32 id, std::string&& name, std::shared_ptr _recvQueue;
uint32 m_currentVendorEntry;
ObjectGuid m_currentBankerGUID;
- time_t timeWhoCommandAllowed;
uint32 _offlineTime;
bool _kicked;
bool _shouldSetOfflineInDB;
diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp
index a42bc627b..35f69e7ed 100644
--- a/src/server/game/World/World.cpp
+++ b/src/server/game/World/World.cpp
@@ -86,7 +86,7 @@
#include "WardenCheckMgr.h"
#include "WaypointMovementGenerator.h"
#include "WeatherMgr.h"
-#include "WhoListCache.h"
+#include "WhoListCacheMgr.h"
#include "WorldPacket.h"
#include "WorldSession.h"
#include
@@ -1990,6 +1990,8 @@ void World::SetInitialWorldSettings()
// our speed up
m_timers[WUPDATE_5_SECS].SetInterval(5 * IN_MILLISECONDS);
+ m_timers[WUPDATE_WHO_LIST].SetInterval(5 * IN_MILLISECONDS); // update who list cache every 5 seconds
+
mail_expire_check_timer = time(nullptr) + 6 * 3600;
///- Initilize static helper structures
@@ -2237,14 +2239,19 @@ void World::Update(uint32 diff)
// moved here from HandleCharEnumOpcode
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_EXPIRED_BANS);
CharacterDatabase.Execute(stmt);
-
- // copy players hashmapholder to avoid mutex
- WhoListCacheMgr::Update();
}
///- Update the game time and check for shutdown time
_UpdateGameTime();
+ ///- Update Who List Cache
+ if (m_timers[WUPDATE_WHO_LIST].Passed())
+ {
+ METRIC_TIMER("world_update_time", METRIC_TAG("type", "Update who list"));
+ m_timers[WUPDATE_WHO_LIST].Reset();
+ sWhoListCacheMgr->Update();
+ }
+
{
METRIC_TIMER("world_update_time", METRIC_TAG("type", "Check quest reset times"));
diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h
index 4aa5470bb..f6786f34d 100644
--- a/src/server/game/World/World.h
+++ b/src/server/game/World/World.h
@@ -69,6 +69,7 @@ enum WorldTimers
WUPDATE_MAILBOXQUEUE,
WUPDATE_PINGDB,
WUPDATE_5_SECS,
+ WUPDATE_WHO_LIST,
WUPDATE_COUNT
};