mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-02-02 02:23:49 +00:00
refactor(Core/World): Create WorldSessionMgr to split session logic out of World (#21400)
This commit is contained in:
@@ -48,8 +48,6 @@ private:
|
||||
CliCommandHolder& operator=(CliCommandHolder const& right) = delete;
|
||||
};
|
||||
|
||||
typedef std::unordered_map<uint32, WorldSession*> SessionMap;
|
||||
|
||||
// ServerMessages.dbc
|
||||
enum ServerMessageType
|
||||
{
|
||||
@@ -531,34 +529,11 @@ class IWorld
|
||||
{
|
||||
public:
|
||||
virtual ~IWorld() = default;
|
||||
[[nodiscard]] virtual WorldSession* FindSession(uint32 id) const = 0;
|
||||
[[nodiscard]] virtual WorldSession* FindOfflineSession(uint32 id) const = 0;
|
||||
[[nodiscard]] virtual WorldSession* FindOfflineSessionForCharacterGUID(ObjectGuid::LowType guidLow) const = 0;
|
||||
virtual void AddSession(WorldSession* s) = 0;
|
||||
virtual bool KickSession(uint32 id) = 0;
|
||||
virtual void UpdateMaxSessionCounters() = 0;
|
||||
[[nodiscard]] virtual const SessionMap& GetAllSessions() const = 0;
|
||||
[[nodiscard]] virtual uint32 GetActiveAndQueuedSessionCount() const = 0;
|
||||
[[nodiscard]] virtual uint32 GetActiveSessionCount() const = 0;
|
||||
[[nodiscard]] virtual uint32 GetQueuedSessionCount() const = 0;
|
||||
[[nodiscard]] virtual uint32 GetMaxQueuedSessionCount() const = 0;
|
||||
[[nodiscard]] virtual uint32 GetMaxActiveSessionCount() const = 0;
|
||||
[[nodiscard]] virtual uint32 GetPlayerCount() const = 0;
|
||||
[[nodiscard]] virtual uint32 GetMaxPlayerCount() const = 0;
|
||||
virtual void IncreasePlayerCount() = 0;
|
||||
virtual void DecreasePlayerCount() = 0;
|
||||
virtual Player* FindPlayerInZone(uint32 zone) = 0;
|
||||
[[nodiscard]] virtual bool IsClosed() const = 0;
|
||||
virtual void SetClosed(bool val) = 0;
|
||||
[[nodiscard]] virtual AccountTypes GetPlayerSecurityLimit() const = 0;
|
||||
virtual void SetPlayerSecurityLimit(AccountTypes sec) = 0;
|
||||
virtual void LoadDBAllowedSecurityLevel() = 0;
|
||||
virtual void SetPlayerAmountLimit(uint32 limit) = 0;
|
||||
[[nodiscard]] virtual uint32 GetPlayerAmountLimit() const = 0;
|
||||
virtual void AddQueuedPlayer(WorldSession*) = 0;
|
||||
virtual bool RemoveQueuedPlayer(WorldSession* session) = 0;
|
||||
virtual int32 GetQueuePos(WorldSession*) = 0;
|
||||
virtual bool HasRecentlyDisconnected(WorldSession*) = 0;
|
||||
[[nodiscard]] virtual bool getAllowMovement() const = 0;
|
||||
virtual void SetAllowMovement(bool allow) = 0;
|
||||
virtual void SetNewCharString(std::string const& str) = 0;
|
||||
@@ -571,18 +546,12 @@ public:
|
||||
[[nodiscard]] virtual uint16 GetConfigMaxSkillValue() const = 0;
|
||||
virtual void SetInitialWorldSettings() = 0;
|
||||
virtual void LoadConfigSettings(bool reload = false) = 0;
|
||||
virtual void SendGlobalMessage(WorldPacket const* packet, WorldSession* self = nullptr, TeamId teamId = TEAM_NEUTRAL) = 0;
|
||||
virtual void SendGlobalGMMessage(WorldPacket const* packet, WorldSession* self = nullptr, TeamId teamId = TEAM_NEUTRAL) = 0;
|
||||
virtual bool SendZoneMessage(uint32 zone, WorldPacket const* packet, WorldSession* self = nullptr, TeamId teamId = TEAM_NEUTRAL) = 0;
|
||||
virtual void SendZoneText(uint32 zone, std::string text, WorldSession* self = nullptr, TeamId teamId = TEAM_NEUTRAL) = 0;
|
||||
virtual void SendServerMessage(ServerMessageType messageID, std::string stringParam = "", Player* player = nullptr) = 0;
|
||||
[[nodiscard]] virtual bool IsShuttingDown() const = 0;
|
||||
[[nodiscard]] virtual uint32 GetShutDownTimeLeft() const = 0;
|
||||
virtual void ShutdownServ(uint32 time, uint32 options, uint8 exitcode, const std::string& reason = std::string()) = 0;
|
||||
virtual void ShutdownCancel() = 0;
|
||||
virtual void ShutdownMsg(bool show = false, Player* player = nullptr, const std::string& reason = std::string()) = 0;
|
||||
virtual void Update(uint32 diff) = 0;
|
||||
virtual void UpdateSessions(uint32 diff) = 0;
|
||||
virtual void setRate(Rates rate, float value) = 0;
|
||||
[[nodiscard]] virtual float getRate(Rates rate) const = 0;
|
||||
virtual void setBoolConfig(WorldBoolConfigs index, bool value) = 0;
|
||||
@@ -596,8 +565,6 @@ public:
|
||||
virtual void LoadWorldStates() = 0;
|
||||
[[nodiscard]] virtual bool IsPvPRealm() const = 0;
|
||||
[[nodiscard]] virtual bool IsFFAPvPRealm() const = 0;
|
||||
virtual void KickAll() = 0;
|
||||
virtual void KickAllLess(AccountTypes sec) = 0;
|
||||
virtual uint32 GetNextWhoListUpdateDelaySecs() = 0;
|
||||
virtual void ProcessCliCommands() = 0;
|
||||
virtual void QueueCliCommand(CliCommandHolder* commandHolder) = 0;
|
||||
@@ -613,7 +580,6 @@ public:
|
||||
[[nodiscard]] virtual std::string const& GetRealmName() const = 0;
|
||||
virtual void SetRealmName(std::string name) = 0;
|
||||
virtual void RemoveOldCorpses() = 0;
|
||||
virtual void DoForAllOnlinePlayers(std::function<void(Player*)> exec) = 0;
|
||||
};
|
||||
|
||||
#endif //AZEROTHCORE_IWORLD_H
|
||||
|
||||
@@ -92,6 +92,7 @@
|
||||
#include "WhoListCacheMgr.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "WorldSession.h"
|
||||
#include "WorldSessionMgr.h"
|
||||
#include "WorldState.h"
|
||||
#include <boost/asio/ip/address.hpp>
|
||||
#include <cmath>
|
||||
@@ -109,15 +110,10 @@ Realm realm;
|
||||
/// World constructor
|
||||
World::World()
|
||||
{
|
||||
_playerLimit = 0;
|
||||
_allowedSecurityLevel = SEC_PLAYER;
|
||||
_allowMovement = true;
|
||||
_shutdownMask = 0;
|
||||
_shutdownTimer = 0;
|
||||
_maxActiveSessionCount = 0;
|
||||
_maxQueuedSessionCount = 0;
|
||||
_playerCount = 0;
|
||||
_maxPlayerCount = 0;
|
||||
_nextDailyQuestReset = 0s;
|
||||
_nextWeeklyQuestReset = 0s;
|
||||
_nextMonthlyQuestReset = 0s;
|
||||
@@ -138,28 +134,12 @@ World::World()
|
||||
/// World destructor
|
||||
World::~World()
|
||||
{
|
||||
///- Empty the kicked session set
|
||||
while (!_sessions.empty())
|
||||
{
|
||||
// not remove from queue, prevent loading new sessions
|
||||
delete _sessions.begin()->second;
|
||||
_sessions.erase(_sessions.begin());
|
||||
}
|
||||
|
||||
while (!_offlineSessions.empty())
|
||||
{
|
||||
delete _offlineSessions.begin()->second;
|
||||
_offlineSessions.erase(_offlineSessions.begin());
|
||||
}
|
||||
|
||||
CliCommandHolder* command = nullptr;
|
||||
while (_cliCmdQueue.next(command))
|
||||
delete command;
|
||||
|
||||
VMAP::VMapFactory::clear();
|
||||
MMAP::MMapFactory::clear();
|
||||
|
||||
//TODO free addSessQueue
|
||||
}
|
||||
|
||||
std::unique_ptr<IWorld>& getWorldInstance()
|
||||
@@ -168,26 +148,6 @@ std::unique_ptr<IWorld>& getWorldInstance()
|
||||
return instance;
|
||||
}
|
||||
|
||||
/// Find a player in a specified zone
|
||||
Player* World::FindPlayerInZone(uint32 zone)
|
||||
{
|
||||
///- circle through active sessions and return the first player found in the zone
|
||||
SessionMap::const_iterator itr;
|
||||
for (itr = _sessions.begin(); itr != _sessions.end(); ++itr)
|
||||
{
|
||||
if (!itr->second)
|
||||
continue;
|
||||
|
||||
Player* player = itr->second->GetPlayer();
|
||||
if (!player)
|
||||
continue;
|
||||
|
||||
if (player->IsInWorld() && player->GetZoneId() == zone)
|
||||
return player;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool World::IsClosed() const
|
||||
{
|
||||
return _isClosed;
|
||||
@@ -201,211 +161,6 @@ void World::SetClosed(bool val)
|
||||
sScriptMgr->OnOpenStateChange(!val);
|
||||
}
|
||||
|
||||
/// Find a session by its id
|
||||
WorldSession* World::FindSession(uint32 id) const
|
||||
{
|
||||
SessionMap::const_iterator itr = _sessions.find(id);
|
||||
|
||||
if (itr != _sessions.end())
|
||||
return itr->second; // also can return nullptr for kicked session
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
WorldSession* World::FindOfflineSession(uint32 id) const
|
||||
{
|
||||
SessionMap::const_iterator itr = _offlineSessions.find(id);
|
||||
if (itr != _offlineSessions.end())
|
||||
return itr->second;
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
WorldSession* World::FindOfflineSessionForCharacterGUID(ObjectGuid::LowType guidLow) const
|
||||
{
|
||||
if (_offlineSessions.empty())
|
||||
return nullptr;
|
||||
|
||||
for (SessionMap::const_iterator itr = _offlineSessions.begin(); itr != _offlineSessions.end(); ++itr)
|
||||
if (itr->second->GetGuidLow() == guidLow)
|
||||
return itr->second;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/// Remove a given session
|
||||
bool World::KickSession(uint32 id)
|
||||
{
|
||||
///- Find the session, kick the user, but we can't delete session at this moment to prevent iterator invalidation
|
||||
SessionMap::const_iterator itr = _sessions.find(id);
|
||||
|
||||
if (itr != _sessions.end() && itr->second)
|
||||
{
|
||||
if (itr->second->PlayerLoading())
|
||||
return false;
|
||||
|
||||
itr->second->KickPlayer("KickSession", false);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void World::AddSession(WorldSession* s)
|
||||
{
|
||||
_addSessQueue.add(s);
|
||||
}
|
||||
|
||||
void World::AddSession_(WorldSession* s)
|
||||
{
|
||||
ASSERT (s);
|
||||
|
||||
// kick existing session with same account (if any)
|
||||
// if character on old session is being loaded, then return
|
||||
if (!KickSession(s->GetAccountId()))
|
||||
{
|
||||
s->KickPlayer("kick existing session with same account");
|
||||
delete s; // session not added yet in session list, so not listed in queue
|
||||
return;
|
||||
}
|
||||
|
||||
SessionMap::const_iterator old = _sessions.find(s->GetAccountId());
|
||||
if (old != _sessions.end())
|
||||
{
|
||||
WorldSession* oldSession = old->second;
|
||||
|
||||
if (!RemoveQueuedPlayer(oldSession) && getIntConfig(CONFIG_INTERVAL_DISCONNECT_TOLERANCE))
|
||||
_disconnects[s->GetAccountId()] = GameTime::GetGameTime().count();
|
||||
|
||||
// pussywizard:
|
||||
if (oldSession->HandleSocketClosed())
|
||||
{
|
||||
// there should be no offline session if current one is logged onto a character
|
||||
SessionMap::iterator iter;
|
||||
if ((iter = _offlineSessions.find(oldSession->GetAccountId())) != _offlineSessions.end())
|
||||
{
|
||||
WorldSession* tmp = iter->second;
|
||||
_offlineSessions.erase(iter);
|
||||
delete tmp;
|
||||
}
|
||||
oldSession->SetOfflineTime(GameTime::GetGameTime().count());
|
||||
_offlineSessions[oldSession->GetAccountId()] = oldSession;
|
||||
}
|
||||
else
|
||||
{
|
||||
delete oldSession;
|
||||
}
|
||||
}
|
||||
|
||||
_sessions[s->GetAccountId()] = s;
|
||||
|
||||
uint32 Sessions = GetActiveAndQueuedSessionCount();
|
||||
uint32 pLimit = GetPlayerAmountLimit();
|
||||
|
||||
// don't count this session when checking player limit
|
||||
--Sessions;
|
||||
|
||||
if (pLimit > 0 && Sessions >= pLimit && AccountMgr::IsPlayerAccount(s->GetSecurity()) && !s->CanSkipQueue() && !HasRecentlyDisconnected(s))
|
||||
{
|
||||
AddQueuedPlayer(s);
|
||||
UpdateMaxSessionCounters();
|
||||
return;
|
||||
}
|
||||
|
||||
s->InitializeSession();
|
||||
|
||||
UpdateMaxSessionCounters();
|
||||
}
|
||||
|
||||
bool World::HasRecentlyDisconnected(WorldSession* session)
|
||||
{
|
||||
if (!session)
|
||||
return false;
|
||||
|
||||
if (uint32 tolerance = getIntConfig(CONFIG_INTERVAL_DISCONNECT_TOLERANCE))
|
||||
{
|
||||
for (DisconnectMap::iterator i = _disconnects.begin(); i != _disconnects.end();)
|
||||
{
|
||||
if ((GameTime::GetGameTime().count() - i->second) < tolerance)
|
||||
{
|
||||
if (i->first == session->GetAccountId())
|
||||
return true;
|
||||
++i;
|
||||
}
|
||||
else
|
||||
_disconnects.erase(i++);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int32 World::GetQueuePos(WorldSession* sess)
|
||||
{
|
||||
uint32 position = 1;
|
||||
|
||||
for (Queue::const_iterator iter = _queuedPlayer.begin(); iter != _queuedPlayer.end(); ++iter, ++position)
|
||||
if ((*iter) == sess)
|
||||
return position;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void World::AddQueuedPlayer(WorldSession* sess)
|
||||
{
|
||||
sess->SetInQueue(true);
|
||||
_queuedPlayer.push_back(sess);
|
||||
|
||||
// The 1st SMSG_AUTH_RESPONSE needs to contain other info too.
|
||||
sess->SendAuthResponse(AUTH_WAIT_QUEUE, false, GetQueuePos(sess));
|
||||
}
|
||||
|
||||
bool World::RemoveQueuedPlayer(WorldSession* sess)
|
||||
{
|
||||
uint32 sessions = GetActiveSessionCount();
|
||||
|
||||
uint32 position = 1;
|
||||
Queue::iterator iter = _queuedPlayer.begin();
|
||||
|
||||
// search to remove and count skipped positions
|
||||
bool found = false;
|
||||
|
||||
for (; iter != _queuedPlayer.end(); ++iter, ++position)
|
||||
{
|
||||
if (*iter == sess)
|
||||
{
|
||||
sess->SetInQueue(false);
|
||||
sess->ResetTimeOutTime(false);
|
||||
iter = _queuedPlayer.erase(iter);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// if session not queued then it was an active session
|
||||
if (!found)
|
||||
{
|
||||
ASSERT(sessions > 0);
|
||||
--sessions;
|
||||
}
|
||||
|
||||
// accept first in queue
|
||||
if ((!GetPlayerAmountLimit() || sessions < GetPlayerAmountLimit()) && !_queuedPlayer.empty())
|
||||
{
|
||||
WorldSession* pop_sess = _queuedPlayer.front();
|
||||
pop_sess->InitializeSession();
|
||||
_queuedPlayer.pop_front();
|
||||
|
||||
// update iter to point first queued socket or end() if queue is empty now
|
||||
iter = _queuedPlayer.begin();
|
||||
position = 1;
|
||||
}
|
||||
|
||||
// update queue position from iter to end()
|
||||
for (; iter != _queuedPlayer.end(); ++iter, ++position)
|
||||
(*iter)->SendAuthWaitQueue(position);
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
/// Initialize config values
|
||||
void World::LoadConfigSettings(bool reload)
|
||||
{
|
||||
@@ -431,9 +186,7 @@ void World::LoadConfigSettings(bool reload)
|
||||
|
||||
///- Read the player limit and the Message of the day from the config file
|
||||
if (!reload)
|
||||
{
|
||||
SetPlayerAmountLimit(sConfigMgr->GetOption<int32>("PlayerLimit", 1000));
|
||||
}
|
||||
sWorldSessionMgr->SetPlayerAmountLimit(sConfigMgr->GetOption<int32>("PlayerLimit", 1000));
|
||||
|
||||
///- Read ticket system setting from the config file
|
||||
_bool_configs[CONFIG_ALLOW_TICKETS] = sConfigMgr->GetOption<bool>("AllowTickets", true);
|
||||
@@ -2293,9 +2046,9 @@ void World::Update(uint32 diff)
|
||||
sWorldUpdateTime.UpdateWithDiff(diff);
|
||||
|
||||
// Record update if recording set in log and diff is greater then minimum set in log
|
||||
sWorldUpdateTime.RecordUpdateTime(GameTime::GetGameTimeMS(), diff, GetActiveSessionCount());
|
||||
sWorldUpdateTime.RecordUpdateTime(GameTime::GetGameTimeMS(), diff, sWorldSessionMgr->GetActiveSessionCount());
|
||||
|
||||
DynamicVisibilityMgr::Update(GetActiveSessionCount());
|
||||
DynamicVisibilityMgr::Update(sWorldSessionMgr->GetActiveSessionCount());
|
||||
|
||||
///- Update the different timers
|
||||
for (int i = 0; i < WUPDATE_COUNT; ++i)
|
||||
@@ -2376,8 +2129,10 @@ void World::Update(uint32 diff)
|
||||
_mail_expire_check_timer = currentGameTime + 6h;
|
||||
}
|
||||
|
||||
METRIC_TIMER("world_update_time", METRIC_TAG("type", "Update sessions"));
|
||||
UpdateSessions(diff);
|
||||
{
|
||||
METRIC_TIMER("world_update_time", METRIC_TAG("type", "Update sessions"));
|
||||
sWorldSessionMgr->UpdateSessions(diff);
|
||||
}
|
||||
|
||||
/// <li> Handle weather updates when the timer has passed
|
||||
if (_timers[WUPDATE_WEATHERS].Passed())
|
||||
@@ -2463,7 +2218,7 @@ void World::Update(uint32 diff)
|
||||
|
||||
LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_UPTIME_PLAYERS);
|
||||
stmt->SetData(0, uint32(GameTime::GetUptime().count()));
|
||||
stmt->SetData(1, uint16(GetMaxPlayerCount()));
|
||||
stmt->SetData(1, uint16(sWorldSessionMgr->GetMaxPlayerCount()));
|
||||
stmt->SetData(2, realm.Id.Realm);
|
||||
stmt->SetData(3, uint32(GameTime::GetStartTime().count()));
|
||||
LoginDatabase.Execute(stmt);
|
||||
@@ -2535,41 +2290,6 @@ void World::ForceGameEventUpdate()
|
||||
_timers[WUPDATE_EVENTS].Reset();
|
||||
}
|
||||
|
||||
/// Send a packet to all players (except self if mentioned)
|
||||
void World::SendGlobalMessage(WorldPacket const* packet, WorldSession* self, TeamId teamId)
|
||||
{
|
||||
SessionMap::const_iterator itr;
|
||||
for (itr = _sessions.begin(); itr != _sessions.end(); ++itr)
|
||||
{
|
||||
if (itr->second &&
|
||||
itr->second->GetPlayer() &&
|
||||
itr->second->GetPlayer()->IsInWorld() &&
|
||||
itr->second != self &&
|
||||
(teamId == TEAM_NEUTRAL || itr->second->GetPlayer()->GetTeamId() == teamId))
|
||||
{
|
||||
itr->second->SendPacket(packet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Send a packet to all GMs (except self if mentioned)
|
||||
void World::SendGlobalGMMessage(WorldPacket const* packet, WorldSession* self, TeamId teamId)
|
||||
{
|
||||
SessionMap::iterator itr;
|
||||
for (itr = _sessions.begin(); itr != _sessions.end(); ++itr)
|
||||
{
|
||||
if (itr->second &&
|
||||
itr->second->GetPlayer() &&
|
||||
itr->second->GetPlayer()->IsInWorld() &&
|
||||
itr->second != self &&
|
||||
!AccountMgr::IsPlayerAccount(itr->second->GetSecurity()) &&
|
||||
(teamId == TEAM_NEUTRAL || itr->second->GetPlayer()->GetTeamId() == teamId))
|
||||
{
|
||||
itr->second->SendPacket(packet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace Acore
|
||||
{
|
||||
class WorldWorldTextBuilder
|
||||
@@ -2615,60 +2335,6 @@ namespace Acore
|
||||
};
|
||||
} // namespace Acore
|
||||
|
||||
/// Send a packet to all players (or players selected team) in the zone (except self if mentioned)
|
||||
bool World::SendZoneMessage(uint32 zone, WorldPacket const* packet, WorldSession* self, TeamId teamId)
|
||||
{
|
||||
bool foundPlayerToSend = false;
|
||||
SessionMap::const_iterator itr;
|
||||
|
||||
for (itr = _sessions.begin(); itr != _sessions.end(); ++itr)
|
||||
{
|
||||
if (itr->second &&
|
||||
itr->second->GetPlayer() &&
|
||||
itr->second->GetPlayer()->IsInWorld() &&
|
||||
itr->second->GetPlayer()->GetZoneId() == zone &&
|
||||
itr->second != self &&
|
||||
(teamId == TEAM_NEUTRAL || itr->second->GetPlayer()->GetTeamId() == teamId))
|
||||
{
|
||||
itr->second->SendPacket(packet);
|
||||
foundPlayerToSend = true;
|
||||
}
|
||||
}
|
||||
|
||||
return foundPlayerToSend;
|
||||
}
|
||||
|
||||
/// Send a System Message to all players in the zone (except self if mentioned)
|
||||
void World::SendZoneText(uint32 zone, std::string text, WorldSession* self, TeamId teamId)
|
||||
{
|
||||
WorldPacket data;
|
||||
ChatHandler::BuildChatPacket(data, CHAT_MSG_SYSTEM, LANG_UNIVERSAL, nullptr, nullptr, text.c_str());
|
||||
SendZoneMessage(zone, &data, self, teamId);
|
||||
}
|
||||
|
||||
/// Kick (and save) all players
|
||||
void World::KickAll()
|
||||
{
|
||||
_queuedPlayer.clear(); // prevent send queue update packet and login queued sessions
|
||||
|
||||
// session not removed at kick and will removed in next update tick
|
||||
for (SessionMap::const_iterator itr = _sessions.begin(); itr != _sessions.end(); ++itr)
|
||||
itr->second->KickPlayer("KickAll sessions");
|
||||
|
||||
// pussywizard: kick offline sessions
|
||||
for (SessionMap::const_iterator itr = _offlineSessions.begin(); itr != _offlineSessions.end(); ++itr)
|
||||
itr->second->KickPlayer("KickAll offline sessions");
|
||||
}
|
||||
|
||||
/// Kick (and save) all players with security level less `sec`
|
||||
void World::KickAllLess(AccountTypes sec)
|
||||
{
|
||||
// session not removed at kick and will removed in next update tick
|
||||
for (SessionMap::const_iterator itr = _sessions.begin(); itr != _sessions.end(); ++itr)
|
||||
if (itr->second->GetSecurity() < sec)
|
||||
itr->second->KickPlayer("KickAllLess");
|
||||
}
|
||||
|
||||
/// Update the game time
|
||||
void World::_UpdateGameTime()
|
||||
{
|
||||
@@ -2684,7 +2350,7 @@ void World::_UpdateGameTime()
|
||||
///- ... and it is overdue, stop the world (set m_stopEvent)
|
||||
if (_shutdownTimer <= elapsed.count())
|
||||
{
|
||||
if (!(_shutdownMask & SHUTDOWN_MASK_IDLE) || GetActiveAndQueuedSessionCount() == 0)
|
||||
if (!(_shutdownMask & SHUTDOWN_MASK_IDLE) || sWorldSessionMgr->GetActiveAndQueuedSessionCount() == 0)
|
||||
_stopEvent = true; // exist code already set
|
||||
else
|
||||
_shutdownTimer = 1; // minimum timer value to wait idle state
|
||||
@@ -2715,7 +2381,7 @@ void World::ShutdownServ(uint32 time, uint32 options, uint8 exitcode, std::strin
|
||||
///- If the shutdown time is 0, set m_stopEvent (except if shutdown is 'idle' with remaining sessions)
|
||||
if (time == 0)
|
||||
{
|
||||
if (!(options & SHUTDOWN_MASK_IDLE) || GetActiveAndQueuedSessionCount() == 0)
|
||||
if (!(options & SHUTDOWN_MASK_IDLE) || sWorldSessionMgr->GetActiveAndQueuedSessionCount() == 0)
|
||||
_stopEvent = true; // exist code already set
|
||||
else
|
||||
_shutdownTimer = 1; //So that the session count is re-evaluated at next world tick
|
||||
@@ -2767,7 +2433,7 @@ void World::ShutdownMsg(bool show, Player* player, std::string const& reason)
|
||||
str += " - " + _shutdownReason;
|
||||
|
||||
ServerMessageType msgid = (_shutdownMask & SHUTDOWN_MASK_RESTART) ? SERVER_MSG_RESTART_TIME : SERVER_MSG_SHUTDOWN_TIME;
|
||||
SendServerMessage(msgid, str, player);
|
||||
sWorldSessionMgr->SendServerMessage(msgid, str, player);
|
||||
LOG_WARN("server.worldserver", "Server {} in {}", (_shutdownMask & SHUTDOWN_MASK_RESTART ? "restarting" : "shutdown"), str);
|
||||
}
|
||||
}
|
||||
@@ -2784,100 +2450,13 @@ void World::ShutdownCancel()
|
||||
_shutdownMask = 0;
|
||||
_shutdownTimer = 0;
|
||||
_exitCode = SHUTDOWN_EXIT_CODE; // to default value
|
||||
SendServerMessage(msgid);
|
||||
sWorldSessionMgr->SendServerMessage(msgid);
|
||||
|
||||
LOG_DEBUG("server.worldserver", "Server {} cancelled.", (_shutdownMask & SHUTDOWN_MASK_RESTART ? "restart" : "shuttingdown"));
|
||||
|
||||
sScriptMgr->OnShutdownCancel();
|
||||
}
|
||||
|
||||
/// Send a server message to the user(s)
|
||||
void World::SendServerMessage(ServerMessageType messageID, std::string stringParam /*= ""*/, Player* player /*= nullptr*/)
|
||||
{
|
||||
WorldPackets::Chat::ChatServerMessage chatServerMessage;
|
||||
chatServerMessage.MessageID = int32(messageID);
|
||||
if (messageID <= SERVER_MSG_STRING)
|
||||
chatServerMessage.StringParam = stringParam;
|
||||
|
||||
if (player)
|
||||
player->SendDirectMessage(chatServerMessage.Write());
|
||||
else
|
||||
SendGlobalMessage(chatServerMessage.Write());
|
||||
}
|
||||
|
||||
void World::UpdateSessions(uint32 diff)
|
||||
{
|
||||
{
|
||||
METRIC_DETAILED_NO_THRESHOLD_TIMER("world_update_time",
|
||||
METRIC_TAG("type", "Add sessions"),
|
||||
METRIC_TAG("parent_type", "Update sessions"));
|
||||
|
||||
///- Add new sessions
|
||||
WorldSession* sess = nullptr;
|
||||
while (_addSessQueue.next(sess))
|
||||
{
|
||||
AddSession_(sess);
|
||||
}
|
||||
}
|
||||
|
||||
///- Then send an update signal to remaining ones
|
||||
for (SessionMap::iterator itr = _sessions.begin(), next; itr != _sessions.end(); itr = next)
|
||||
{
|
||||
next = itr;
|
||||
++next;
|
||||
|
||||
///- and remove not active sessions from the list
|
||||
WorldSession* pSession = itr->second;
|
||||
WorldSessionFilter updater(pSession);
|
||||
|
||||
// pussywizard:
|
||||
if (pSession->HandleSocketClosed())
|
||||
{
|
||||
if (!RemoveQueuedPlayer(pSession) && getIntConfig(CONFIG_INTERVAL_DISCONNECT_TOLERANCE))
|
||||
_disconnects[pSession->GetAccountId()] = GameTime::GetGameTime().count();
|
||||
_sessions.erase(itr);
|
||||
// there should be no offline session if current one is logged onto a character
|
||||
SessionMap::iterator iter;
|
||||
if ((iter = _offlineSessions.find(pSession->GetAccountId())) != _offlineSessions.end())
|
||||
{
|
||||
WorldSession* tmp = iter->second;
|
||||
_offlineSessions.erase(iter);
|
||||
delete tmp;
|
||||
}
|
||||
pSession->SetOfflineTime(GameTime::GetGameTime().count());
|
||||
_offlineSessions[pSession->GetAccountId()] = pSession;
|
||||
continue;
|
||||
}
|
||||
|
||||
[[maybe_unused]] uint32 currentSessionId = itr->first;
|
||||
METRIC_DETAILED_TIMER("world_update_sessions_time", METRIC_TAG("account_id", std::to_string(currentSessionId)));
|
||||
|
||||
if (!pSession->Update(diff, updater))
|
||||
{
|
||||
if (!RemoveQueuedPlayer(pSession) && getIntConfig(CONFIG_INTERVAL_DISCONNECT_TOLERANCE))
|
||||
_disconnects[pSession->GetAccountId()] = GameTime::GetGameTime().count();
|
||||
_sessions.erase(itr);
|
||||
delete pSession;
|
||||
}
|
||||
}
|
||||
|
||||
// pussywizard:
|
||||
if (_offlineSessions.empty())
|
||||
return;
|
||||
uint32 currTime = GameTime::GetGameTime().count();
|
||||
for (SessionMap::iterator itr = _offlineSessions.begin(), next; itr != _offlineSessions.end(); itr = next)
|
||||
{
|
||||
next = itr;
|
||||
++next;
|
||||
WorldSession* pSession = itr->second;
|
||||
if (!pSession->GetPlayer() || pSession->GetOfflineTime() + 60 < currTime || pSession->IsKicked())
|
||||
{
|
||||
_offlineSessions.erase(itr);
|
||||
delete pSession;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This handles the issued and queued CLI commands
|
||||
void World::ProcessCliCommands()
|
||||
{
|
||||
@@ -2995,7 +2574,8 @@ void World::ResetDailyQuests()
|
||||
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_QUEST_STATUS_DAILY);
|
||||
CharacterDatabase.Execute(stmt);
|
||||
|
||||
for (SessionMap::const_iterator itr = _sessions.begin(); itr != _sessions.end(); ++itr)
|
||||
WorldSessionMgr::SessionMap const& sessionMap = sWorldSessionMgr->GetAllSessions();
|
||||
for (WorldSessionMgr::SessionMap::const_iterator itr = sessionMap.begin(); itr != sessionMap.end(); ++itr)
|
||||
if (itr->second->GetPlayer())
|
||||
itr->second->GetPlayer()->ResetDailyQuestStatus();
|
||||
|
||||
@@ -3022,7 +2602,7 @@ void World::SetPlayerSecurityLimit(AccountTypes _sec)
|
||||
bool update = sec > _allowedSecurityLevel;
|
||||
_allowedSecurityLevel = sec;
|
||||
if (update)
|
||||
KickAllLess(_allowedSecurityLevel);
|
||||
sWorldSessionMgr->KickAllLess(_allowedSecurityLevel);
|
||||
}
|
||||
|
||||
void World::ResetWeeklyQuests()
|
||||
@@ -3030,7 +2610,8 @@ void World::ResetWeeklyQuests()
|
||||
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_QUEST_STATUS_WEEKLY);
|
||||
CharacterDatabase.Execute(stmt);
|
||||
|
||||
for (SessionMap::const_iterator itr = _sessions.begin(); itr != _sessions.end(); ++itr)
|
||||
WorldSessionMgr::SessionMap const& sessionMap = sWorldSessionMgr->GetAllSessions();
|
||||
for (WorldSessionMgr::SessionMap::const_iterator itr = sessionMap.begin(); itr != sessionMap.end(); ++itr)
|
||||
if (itr->second->GetPlayer())
|
||||
itr->second->GetPlayer()->ResetWeeklyQuestStatus();
|
||||
|
||||
@@ -3048,7 +2629,8 @@ void World::ResetMonthlyQuests()
|
||||
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_QUEST_STATUS_MONTHLY);
|
||||
CharacterDatabase.Execute(stmt);
|
||||
|
||||
for (SessionMap::const_iterator itr = _sessions.begin(); itr != _sessions.end(); ++itr)
|
||||
WorldSessionMgr::SessionMap const& sessionMap = sWorldSessionMgr->GetAllSessions();
|
||||
for (WorldSessionMgr::SessionMap::const_iterator itr = sessionMap.begin(); itr != sessionMap.end(); ++itr)
|
||||
if (itr->second->GetPlayer())
|
||||
itr->second->GetPlayer()->ResetMonthlyQuestStatus();
|
||||
|
||||
@@ -3062,7 +2644,8 @@ void World::ResetEventSeasonalQuests(uint16 event_id)
|
||||
stmt->SetData(0, event_id);
|
||||
CharacterDatabase.Execute(stmt);
|
||||
|
||||
for (SessionMap::const_iterator itr = _sessions.begin(); itr != _sessions.end(); ++itr)
|
||||
WorldSessionMgr::SessionMap const& sessionMap = sWorldSessionMgr->GetAllSessions();
|
||||
for (WorldSessionMgr::SessionMap::const_iterator itr = sessionMap.begin(); itr != sessionMap.end(); ++itr)
|
||||
if (itr->second->GetPlayer())
|
||||
itr->second->GetPlayer()->ResetSeasonalQuestStatus(event_id);
|
||||
}
|
||||
@@ -3074,7 +2657,8 @@ void World::ResetRandomBG()
|
||||
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_BATTLEGROUND_RANDOM);
|
||||
CharacterDatabase.Execute(stmt);
|
||||
|
||||
for (SessionMap::const_iterator itr = _sessions.begin(); itr != _sessions.end(); ++itr)
|
||||
WorldSessionMgr::SessionMap const& sessionMap = sWorldSessionMgr->GetAllSessions();
|
||||
for (WorldSessionMgr::SessionMap::const_iterator itr = sessionMap.begin(); itr != sessionMap.end(); ++itr)
|
||||
if (itr->second->GetPlayer())
|
||||
itr->second->GetPlayer()->SetRandomWinner(false);
|
||||
|
||||
@@ -3101,12 +2685,6 @@ void World::ResetGuildCap()
|
||||
sGuildMgr->ResetTimes();
|
||||
}
|
||||
|
||||
void World::UpdateMaxSessionCounters()
|
||||
{
|
||||
_maxActiveSessionCount = std::max(_maxActiveSessionCount, uint32(_sessions.size() - _queuedPlayer.size()));
|
||||
_maxQueuedSessionCount = std::max(_maxQueuedSessionCount, uint32(_queuedPlayer.size()));
|
||||
}
|
||||
|
||||
void World::LoadDBVersion()
|
||||
{
|
||||
QueryResult result = WorldDatabase.Query("SELECT db_version, cache_id FROM version LIMIT 1");
|
||||
@@ -3126,8 +2704,8 @@ void World::LoadDBVersion()
|
||||
|
||||
void World::UpdateAreaDependentAuras()
|
||||
{
|
||||
SessionMap::const_iterator itr;
|
||||
for (itr = _sessions.begin(); itr != _sessions.end(); ++itr)
|
||||
WorldSessionMgr::SessionMap const& sessionMap = sWorldSessionMgr->GetAllSessions();
|
||||
for (WorldSessionMgr::SessionMap::const_iterator itr = sessionMap.begin(); itr != sessionMap.end(); ++itr)
|
||||
if (itr->second && itr->second->GetPlayer() && itr->second->GetPlayer()->IsInWorld())
|
||||
{
|
||||
itr->second->GetPlayer()->UpdateAreaDependentAuras(itr->second->GetPlayer()->GetAreaId());
|
||||
@@ -3196,23 +2774,6 @@ void World::RemoveOldCorpses()
|
||||
_timers[WUPDATE_CORPSES].SetCurrent(_timers[WUPDATE_CORPSES].GetInterval());
|
||||
}
|
||||
|
||||
void World::DoForAllOnlinePlayers(std::function<void(Player*)> exec)
|
||||
{
|
||||
std::shared_lock lock(*HashMapHolder<Player>::GetLock());
|
||||
for (auto const& it : ObjectAccessor::GetPlayers())
|
||||
{
|
||||
if (Player* player = it.second)
|
||||
{
|
||||
if (!player->IsInWorld())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
exec(player);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool World::IsPvPRealm() const
|
||||
{
|
||||
return getIntConfig(CONFIG_GAME_TYPE) == REALM_TYPE_PVP || getIntConfig(CONFIG_GAME_TYPE) == REALM_TYPE_RPPVP || getIntConfig(CONFIG_GAME_TYPE) == REALM_TYPE_FFA_PVP;
|
||||
|
||||
@@ -155,34 +155,6 @@ public:
|
||||
|
||||
static uint32 m_worldLoopCounter;
|
||||
|
||||
[[nodiscard]] WorldSession* FindSession(uint32 id) const override;
|
||||
[[nodiscard]] WorldSession* FindOfflineSession(uint32 id) const override;
|
||||
[[nodiscard]] WorldSession* FindOfflineSessionForCharacterGUID(ObjectGuid::LowType guidLow) const override;
|
||||
void AddSession(WorldSession* s) override;
|
||||
bool KickSession(uint32 id) override;
|
||||
/// Get the number of current active sessions
|
||||
void UpdateMaxSessionCounters() override;
|
||||
[[nodiscard]] const SessionMap& GetAllSessions() const override { return _sessions; }
|
||||
[[nodiscard]] uint32 GetActiveAndQueuedSessionCount() const override { return _sessions.size(); }
|
||||
[[nodiscard]] uint32 GetActiveSessionCount() const override { return _sessions.size() - _queuedPlayer.size(); }
|
||||
[[nodiscard]] uint32 GetQueuedSessionCount() const override { return _queuedPlayer.size(); }
|
||||
/// Get the maximum number of parallel sessions on the server since last reboot
|
||||
[[nodiscard]] uint32 GetMaxQueuedSessionCount() const override { return _maxQueuedSessionCount; }
|
||||
[[nodiscard]] uint32 GetMaxActiveSessionCount() const override { return _maxActiveSessionCount; }
|
||||
/// Get number of players
|
||||
[[nodiscard]] inline uint32 GetPlayerCount() const override { return _playerCount; }
|
||||
[[nodiscard]] inline uint32 GetMaxPlayerCount() const override { return _maxPlayerCount; }
|
||||
|
||||
/// Increase/Decrease number of players
|
||||
inline void IncreasePlayerCount() override
|
||||
{
|
||||
_playerCount++;
|
||||
_maxPlayerCount = std::max(_maxPlayerCount, _playerCount);
|
||||
}
|
||||
inline void DecreasePlayerCount() override { _playerCount--; }
|
||||
|
||||
Player* FindPlayerInZone(uint32 zone) override;
|
||||
|
||||
/// Deny clients?
|
||||
[[nodiscard]] bool IsClosed() const override;
|
||||
|
||||
@@ -194,17 +166,6 @@ public:
|
||||
void SetPlayerSecurityLimit(AccountTypes sec) override;
|
||||
void LoadDBAllowedSecurityLevel() override;
|
||||
|
||||
/// Active session server limit
|
||||
void SetPlayerAmountLimit(uint32 limit) override { _playerLimit = limit; }
|
||||
[[nodiscard]] uint32 GetPlayerAmountLimit() const override { return _playerLimit; }
|
||||
|
||||
//player Queue
|
||||
typedef std::list<WorldSession*> Queue;
|
||||
void AddQueuedPlayer(WorldSession*) override;
|
||||
bool RemoveQueuedPlayer(WorldSession* session) override;
|
||||
int32 GetQueuePos(WorldSession*) override;
|
||||
bool HasRecentlyDisconnected(WorldSession*) override;
|
||||
|
||||
/// \todo Actions on m_allowMovement still to be implemented
|
||||
/// Is movement allowed?
|
||||
[[nodiscard]] bool getAllowMovement() const override { return _allowMovement; }
|
||||
@@ -236,12 +197,6 @@ public:
|
||||
void SetInitialWorldSettings() override;
|
||||
void LoadConfigSettings(bool reload = false) override;
|
||||
|
||||
void SendGlobalMessage(WorldPacket const* packet, WorldSession* self = nullptr, TeamId teamId = TEAM_NEUTRAL) override;
|
||||
void SendGlobalGMMessage(WorldPacket const* packet, WorldSession* self = nullptr, TeamId teamId = TEAM_NEUTRAL) override;
|
||||
bool SendZoneMessage(uint32 zone, WorldPacket const* packet, WorldSession* self = nullptr, TeamId teamId = TEAM_NEUTRAL) override;
|
||||
void SendZoneText(uint32 zone, std::string text, WorldSession* self = nullptr, TeamId teamId = TEAM_NEUTRAL) override;
|
||||
void SendServerMessage(ServerMessageType messageID, std::string stringParam = "", Player* player = nullptr) override;
|
||||
|
||||
/// Are we in the middle of a shutdown?
|
||||
[[nodiscard]] bool IsShuttingDown() const override { return _shutdownTimer > 0; }
|
||||
[[nodiscard]] uint32 GetShutDownTimeLeft() const override { return _shutdownTimer; }
|
||||
@@ -254,7 +209,6 @@ public:
|
||||
|
||||
void Update(uint32 diff) override;
|
||||
|
||||
void UpdateSessions(uint32 diff) override;
|
||||
/// Set a server rate (see #Rates)
|
||||
void setRate(Rates rate, float value) override { _rate_values[rate] = value; }
|
||||
/// Get a server rate (see #Rates)
|
||||
@@ -307,9 +261,6 @@ public:
|
||||
[[nodiscard]] bool IsPvPRealm() const override;
|
||||
[[nodiscard]] bool IsFFAPvPRealm() const override;
|
||||
|
||||
void KickAll() override;
|
||||
void KickAllLess(AccountTypes sec) override;
|
||||
|
||||
// for max speed access
|
||||
static float GetMaxVisibleDistanceOnContinents() { return _maxVisibleDistanceOnContinents; }
|
||||
static float GetMaxVisibleDistanceInInstances() { return _maxVisibleDistanceInInstances; }
|
||||
@@ -342,8 +293,6 @@ public:
|
||||
|
||||
void RemoveOldCorpses() override;
|
||||
|
||||
void DoForAllOnlinePlayers(std::function<void(Player*)> exec) override;
|
||||
|
||||
protected:
|
||||
void _UpdateGameTime();
|
||||
// callback for UpdateRealmCharacters
|
||||
@@ -375,15 +324,6 @@ private:
|
||||
IntervalTimer _timers[WUPDATE_COUNT];
|
||||
Seconds _mail_expire_check_timer;
|
||||
|
||||
SessionMap _sessions;
|
||||
SessionMap _offlineSessions;
|
||||
typedef std::unordered_map<uint32, time_t> DisconnectMap;
|
||||
DisconnectMap _disconnects;
|
||||
uint32 _maxActiveSessionCount;
|
||||
uint32 _maxQueuedSessionCount;
|
||||
uint32 _playerCount;
|
||||
uint32 _maxPlayerCount;
|
||||
|
||||
std::string _newCharString;
|
||||
|
||||
float _rate_values[MAX_RATES];
|
||||
@@ -392,7 +332,6 @@ private:
|
||||
float _float_configs[FLOAT_CONFIG_VALUE_COUNT];
|
||||
typedef std::map<uint32, uint64> WorldStatesMap;
|
||||
WorldStatesMap _worldstates;
|
||||
uint32 _playerLimit;
|
||||
AccountTypes _allowedSecurityLevel;
|
||||
LocaleConstant _defaultDbcLocale; // from config for one from loaded DBC locales
|
||||
uint32 _availableDbcLocaleMask; // by loaded DBC
|
||||
@@ -418,13 +357,6 @@ private:
|
||||
Seconds _nextCalendarOldEventsDeletionTime;
|
||||
Seconds _nextGuildReset;
|
||||
|
||||
//Player Queue
|
||||
Queue _queuedPlayer;
|
||||
|
||||
// sessions that are added async
|
||||
void AddSession_(WorldSession* s);
|
||||
LockedQueue<WorldSession*> _addSessQueue;
|
||||
|
||||
// used versions
|
||||
std::string _dbVersion;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user