AzerothCore 3.3.5a
OpenSource WoW Emulator
Loading...
Searching...
No Matches
WorldSessionMgr Class Reference

#include "WorldSessionMgr.h"

Public Types

typedef std::unordered_map< uint32, WorldSession * > SessionMap
 

Public Member Functions

 WorldSessionMgr ()
 
 ~WorldSessionMgr ()
 
WorldSession * FindSession (uint32 id) const
 Find a session by its id.
 
WorldSession * FindOfflineSession (uint32 id) const
 
WorldSession * FindOfflineSessionForCharacterGUID (ObjectGuid::LowType guidLow) const
 
void UpdateSessions (uint32 const diff)
 
bool KickSession (uint32 id)
 Remove a given session.
 
void KickAll ()
 Kick (and save) all players.
 
void KickAllLess (AccountTypes sec)
 Kick (and save) all players with security level less sec
 
void AddSession (WorldSession *session)
 
void AddQueuedPlayer (WorldSession *session)
 
bool RemoveQueuedPlayer (WorldSession *session)
 
int32 GetQueuePos (WorldSession *session)
 
bool HasRecentlyDisconnected (WorldSession *session)
 
SessionMap const & GetAllSessions () const
 
void UpdateMaxSessionCounters ()
 Get the number of current active sessions.
 
uint32 GetActiveAndQueuedSessionCount () const
 
uint32 GetActiveSessionCount () const
 
uint32 GetQueuedSessionCount () const
 
uint32 GetMaxQueuedSessionCount () const
 Get the maximum number of parallel sessions on the server since last reboot.
 
uint32 GetMaxActiveSessionCount () const
 
uint32 GetPlayerCount () const
 Get number of players.
 
uint32 GetMaxPlayerCount () const
 
void SetPlayerAmountLimit (uint32 limit)
 Active session server limit.
 
uint32 GetPlayerAmountLimit () const
 
void IncreasePlayerCount ()
 Increase/Decrease number of players.
 
void DecreasePlayerCount ()
 
void SendGlobalMessage (WorldPacket const *packet, WorldSession *self=nullptr, TeamId teamId=TEAM_NEUTRAL)
 Send a packet to all players (except self if mentioned)
 
void SendGlobalGMMessage (WorldPacket const *packet, WorldSession *self=nullptr, TeamId teamId=TEAM_NEUTRAL)
 Send a packet to all GMs (except self if mentioned)
 
void SendServerMessage (ServerMessageType messageID, std::string stringParam="", Player *player=nullptr)
 Send a server message to the user(s)
 
void DoForAllOnlinePlayers (std::function< void(Player *)> exec)
 

Static Public Member Functions

static WorldSessionMgr * Instance ()
 

Private Types

typedef std::unordered_map< uint32, time_t > DisconnectMap
 
typedef std::list< WorldSession * > Queue
 

Private Member Functions

void AddSession_ (WorldSession *session)
 

Private Attributes

LockedQueue< WorldSession * > _addSessQueue
 
SessionMap _sessions
 
SessionMap _offlineSessions
 
std::map< uint32, AccountPlayHistory > _accountsPlayHistory
 
DisconnectMap _disconnects
 
Queue _queuedPlayer
 
uint32 _playerLimit
 
uint32 _maxActiveSessionCount
 
uint32 _maxQueuedSessionCount
 
uint32 _playerCount
 
uint32 _maxPlayerCount
 
uint32 _stalePruneTimer
 

Detailed Description

Member Typedef Documentation

◆ DisconnectMap

typedef std::unordered_map<uint32, time_t> WorldSessionMgr::DisconnectMap
private

◆ Queue

typedef std::list<WorldSession*> WorldSessionMgr::Queue
private

◆ SessionMap

typedef std::unordered_map<uint32, WorldSession*> WorldSessionMgr::SessionMap

Constructor & Destructor Documentation

◆ WorldSessionMgr()

WorldSessionMgr::WorldSessionMgr ( )
35{
36 _playerLimit = 0;
39 _playerCount = 0;
42}
uint32 _playerLimit
Definition WorldSessionMgr.h:110
uint32 _maxActiveSessionCount
Definition WorldSessionMgr.h:111
uint32 _maxQueuedSessionCount
Definition WorldSessionMgr.h:112
uint32 _stalePruneTimer
Definition WorldSessionMgr.h:115
uint32 _playerCount
Definition WorldSessionMgr.h:113
uint32 _maxPlayerCount
Definition WorldSessionMgr.h:114

References _maxActiveSessionCount, _maxPlayerCount, _maxQueuedSessionCount, _playerCount, _playerLimit, and _stalePruneTimer.

◆ ~WorldSessionMgr()

WorldSessionMgr::~WorldSessionMgr ( )
  • Empty the kicked session set
45{
47 while (!_sessions.empty())
48 {
49 // not remove from queue, prevent loading new sessions
50 delete _sessions.begin()->second;
51 _sessions.erase(_sessions.begin());
52 }
53
54 while (!_offlineSessions.empty())
55 {
56 delete _offlineSessions.begin()->second;
58 }
59}
SessionMap _sessions
Definition WorldSessionMgr.h:100
SessionMap _offlineSessions
Definition WorldSessionMgr.h:101

References _offlineSessions, and _sessions.

Member Function Documentation

◆ AddQueuedPlayer()

void WorldSessionMgr::AddQueuedPlayer ( WorldSession *  session)
264{
265 session->SetInQueue(true);
266 _queuedPlayer.push_back(session);
267
268 // The 1st SMSG_AUTH_RESPONSE needs to contain other info too.
269 session->SendAuthResponse(AUTH_WAIT_QUEUE, false, GetQueuePos(session));
270}
@ AUTH_WAIT_QUEUE
Definition SharedDefines.h:3599
Queue _queuedPlayer
Definition WorldSessionMgr.h:108
int32 GetQueuePos(WorldSession *session)
Definition WorldSessionMgr.cpp:320
void SetInQueue(bool state)
Session in auth.queue currently.
Definition WorldSession.h:523
void SendAuthResponse(uint8 code, bool shortForm, uint32 queuePos=0)
Definition AuthHandler.cpp:23

References _queuedPlayer, AUTH_WAIT_QUEUE, GetQueuePos(), WorldSession::SendAuthResponse(), and WorldSession::SetInQueue().

Referenced by AddSession_().

◆ AddSession()

void WorldSessionMgr::AddSession ( WorldSession *  session)
259{
260 _addSessQueue.add(session);
261}
void add(T const &item)
Adds an item to the back of the queue.
Definition LockedQueue.h:52
LockedQueue< WorldSession * > _addSessQueue
Definition WorldSessionMgr.h:97

References _addSessQueue, and LockedQueue< T, StorageType >::add().

◆ AddSession_()

void WorldSessionMgr::AddSession_ ( WorldSession *  session)
private
332{
333 ASSERT(session);
334
335 // kick existing session with same account (if any)
336 // if character on old session is being loaded, then return
337 if (!KickSession(session->GetAccountId()))
338 {
339 session->KickPlayer("kick existing session with same account");
340 delete session; // session not added yet in session list, so not listed in queue
341 return;
342 }
343
344 SessionMap::const_iterator old = _sessions.find(session->GetAccountId());
345 if (old != _sessions.end())
346 {
347 WorldSession* oldSession = old->second;
348
349 if (!RemoveQueuedPlayer(oldSession) && sWorld->getIntConfig(CONFIG_INTERVAL_DISCONNECT_TOLERANCE))
350 _disconnects[session->GetAccountId()] = GameTime::GetGameTime().count();
351
352 // don't allow resetting consecutive play time on double login to same account
353 session->SetPreviousPlayedTime(old->second->GetConsecutivePlayTime(GameTime::GetGameTime()));
354
355 // pussywizard:
356 if (oldSession->HandleSocketClosed())
357 {
358 // there should be no offline session if current one is logged onto a character
359 SessionMap::iterator iter;
360 if ((iter = _offlineSessions.find(oldSession->GetAccountId())) != _offlineSessions.end())
361 {
362 WorldSession* tmp = iter->second;
363 _offlineSessions.erase(iter);
364 delete tmp;
365 }
366 oldSession->SetOfflineTime(GameTime::GetGameTime().count());
367 _offlineSessions[oldSession->GetAccountId()] = oldSession;
368 }
369 else
370 delete oldSession;
371 }
372 else
373 {
374 auto itr = _accountsPlayHistory.find(session->GetAccountId());
375 if (itr != _accountsPlayHistory.end())
376 {
377 // carry consecutive play time only if the offline gap was under the reset window
378 if ((GameTime::GetGameTime() - itr->second.logoutTime) < PLAY_TIME_LIMIT_FULL)
379 session->SetPreviousPlayedTime(itr->second.playedTime);
380
381 // entry consumed on login; erase so _accountsPlayHistory cannot grow unbounded
382 _accountsPlayHistory.erase(itr);
383 }
384 }
385
386 _sessions[session->GetAccountId()] = session;
387
389 uint32 pLimit = GetPlayerAmountLimit();
390
391 // don't count this session when checking player limit
392 --Sessions;
393
394 // Trial accounts do not get account-flag queue priority. RBAC_PERM_SKIP_QUEUE is still honored
395 // since it can be granted intentionally to specific accounts.
396 bool trialQueueRestricted = sWorld->getBoolConfig(CONFIG_TRIAL_RESTRICTION_QUEUE) && session->IsTrialAccount();
397 bool canSkipQueue = session->HasPermission(rbac::RBAC_PERM_SKIP_QUEUE) || (!trialQueueRestricted && session->CanSkipQueue());
398
399 if (pLimit > 0 && Sessions >= pLimit && !canSkipQueue && !HasRecentlyDisconnected(session))
400 {
401 AddQueuedPlayer(session);
403 return;
404 }
405
406 session->InitializeSession();
407
409}
std::uint32_t uint32
Definition Define.h:107
#define ASSERT
Definition Errors.h:68
@ CONFIG_TRIAL_RESTRICTION_QUEUE
Definition WorldConfig.h:515
@ CONFIG_INTERVAL_DISCONNECT_TOLERANCE
Definition WorldConfig.h:172
bool KickSession(uint32 id)
Remove a given session.
Definition WorldSessionMgr.cpp:219
void UpdateMaxSessionCounters()
Get the number of current active sessions.
Definition WorldSessionMgr.cpp:433
DisconnectMap _disconnects
Definition WorldSessionMgr.h:105
uint32 GetPlayerAmountLimit() const
Definition WorldSessionMgr.h:80
bool HasRecentlyDisconnected(WorldSession *session)
Definition WorldSessionMgr.cpp:411
std::map< uint32, AccountPlayHistory > _accountsPlayHistory
Definition WorldSessionMgr.h:102
uint32 GetActiveAndQueuedSessionCount() const
Definition WorldSessionMgr.h:69
void AddQueuedPlayer(WorldSession *session)
Definition WorldSessionMgr.cpp:263
bool RemoveQueuedPlayer(WorldSession *session)
Definition WorldSessionMgr.cpp:272
Player session in the World.
Definition WorldSession.h:430
void SetOfflineTime(uint32 time)
Definition WorldSession.h:1212
void SetPreviousPlayedTime(Seconds playedTime)
Definition WorldSession.h:531
bool HasPermission(uint32 permissionId)
Definition WorldSession.cpp:1691
bool HandleSocketClosed()
Definition WorldSession.cpp:627
uint32 GetAccountId() const
Definition WorldSession.h:502
bool IsTrialAccount() const
Definition WorldSession.cpp:225
void KickPlayer(bool setKicked=true)
Definition WorldSession.h:551
void InitializeSession()
Definition WorldSession.cpp:1564
bool CanSkipQueue() const
Definition WorldSession.h:491
constexpr Seconds PLAY_TIME_LIMIT_FULL
Definition WorldSession.h:310
#define sWorld
Definition World.h:337
Seconds GetGameTime()
Definition GameTime.cpp:39
@ RBAC_PERM_SKIP_QUEUE
Definition RBAC.h:53

References _accountsPlayHistory, _disconnects, _offlineSessions, _sessions, AddQueuedPlayer(), ASSERT, WorldSession::CanSkipQueue(), CONFIG_INTERVAL_DISCONNECT_TOLERANCE, CONFIG_TRIAL_RESTRICTION_QUEUE, WorldSession::GetAccountId(), GetActiveAndQueuedSessionCount(), GameTime::GetGameTime(), GetPlayerAmountLimit(), WorldSession::HandleSocketClosed(), WorldSession::HasPermission(), HasRecentlyDisconnected(), WorldSession::InitializeSession(), WorldSession::IsTrialAccount(), WorldSession::KickPlayer(), KickSession(), PLAY_TIME_LIMIT_FULL, rbac::RBAC_PERM_SKIP_QUEUE, RemoveQueuedPlayer(), WorldSession::SetOfflineTime(), WorldSession::SetPreviousPlayedTime(), sWorld, and UpdateMaxSessionCounters().

Referenced by UpdateSessions().

◆ DecreasePlayerCount()

void WorldSessionMgr::DecreasePlayerCount ( )
inline
88{ _playerCount--; }

References _playerCount.

◆ DoForAllOnlinePlayers()

void WorldSessionMgr::DoForAllOnlinePlayers ( std::function< void(Player *)>  exec)
489{
490 std::shared_lock lock(*HashMapHolder<Player>::GetLock());
491 for (auto const& it : ObjectAccessor::GetPlayers())
492 {
493 if (Player* player = it.second)
494 {
495 if (!player->IsInWorld())
496 {
497 continue;
498 }
499
500 exec(player);
501 }
502 }
503}
Definition ObjectAccessor.h:41
Definition Player.h:1086
Definition ObjectAccessor.h:61
HashMapHolder< Player >::MapType const & GetPlayers()
Definition ObjectAccessor.cpp:99

References ObjectAccessor::GetPlayers().

◆ FindOfflineSession()

WorldSession * WorldSessionMgr::FindOfflineSession ( uint32  id) const
73{
74 SessionMap::const_iterator itr = _offlineSessions.find(id);
75 if (itr != _offlineSessions.end())
76 return itr->second;
77 else
78 return nullptr;
79}

References _offlineSessions.

◆ FindOfflineSessionForCharacterGUID()

WorldSession * WorldSessionMgr::FindOfflineSessionForCharacterGUID ( ObjectGuid::LowType  guidLow) const
82{
83 if (_offlineSessions.empty())
84 return nullptr;
85
86 for (SessionMap::const_iterator itr = _offlineSessions.begin(); itr != _offlineSessions.end(); ++itr)
87 if (itr->second->GetGuidLow() == guidLow)
88 return itr->second;
89
90 return nullptr;
91}

References _offlineSessions.

◆ FindSession()

WorldSession * WorldSessionMgr::FindSession ( uint32  id) const

Find a session by its id.

63{
64 SessionMap::const_iterator itr = _sessions.find(id);
65
66 if (itr != _sessions.end())
67 return itr->second; // also can return nullptr for kicked session
68 else
69 return nullptr;
70}

References _sessions.

◆ GetActiveAndQueuedSessionCount()

uint32 WorldSessionMgr::GetActiveAndQueuedSessionCount ( ) const
inline
69{ return _sessions.size(); }

References _sessions.

Referenced by AddSession_().

◆ GetActiveSessionCount()

uint32 WorldSessionMgr::GetActiveSessionCount ( ) const
inline
70{ return _sessions.size() - _queuedPlayer.size(); }

References _queuedPlayer, and _sessions.

Referenced by RemoveQueuedPlayer().

◆ GetAllSessions()

SessionMap const & WorldSessionMgr::GetAllSessions ( ) const
inline
65{ return _sessions; }

References _sessions.

◆ GetMaxActiveSessionCount()

uint32 WorldSessionMgr::GetMaxActiveSessionCount ( ) const
inline

◆ GetMaxPlayerCount()

uint32 WorldSessionMgr::GetMaxPlayerCount ( ) const
inline
77{ return _maxPlayerCount; }

References _maxPlayerCount.

◆ GetMaxQueuedSessionCount()

uint32 WorldSessionMgr::GetMaxQueuedSessionCount ( ) const
inline

Get the maximum number of parallel sessions on the server since last reboot.

73{ return _maxQueuedSessionCount; }

References _maxQueuedSessionCount.

◆ GetPlayerAmountLimit()

uint32 WorldSessionMgr::GetPlayerAmountLimit ( ) const
inline
80{ return _playerLimit; }

References _playerLimit.

Referenced by AddSession_(), and RemoveQueuedPlayer().

◆ GetPlayerCount()

uint32 WorldSessionMgr::GetPlayerCount ( ) const
inline

Get number of players.

76{ return _playerCount; }

References _playerCount.

◆ GetQueuedSessionCount()

uint32 WorldSessionMgr::GetQueuedSessionCount ( ) const
inline
71{ return _queuedPlayer.size(); }

References _queuedPlayer.

◆ GetQueuePos()

int32 WorldSessionMgr::GetQueuePos ( WorldSession *  session)
321{
322 uint32 position = 1;
323
324 for (Queue::const_iterator iter = _queuedPlayer.begin(); iter != _queuedPlayer.end(); ++iter, ++position)
325 if ((*iter) == session)
326 return position;
327
328 return 0;
329}

References _queuedPlayer.

Referenced by AddQueuedPlayer().

◆ HasRecentlyDisconnected()

bool WorldSessionMgr::HasRecentlyDisconnected ( WorldSession *  session)
412{
413 if (!session)
414 return false;
415
416 if (uint32 tolerance = sWorld->getIntConfig(CONFIG_INTERVAL_DISCONNECT_TOLERANCE))
417 {
418 for (DisconnectMap::iterator i = _disconnects.begin(); i != _disconnects.end();)
419 {
420 if ((GameTime::GetGameTime().count() - i->second) < tolerance)
421 {
422 if (i->first == session->GetAccountId())
423 return true;
424 ++i;
425 }
426 else
427 _disconnects.erase(i++);
428 }
429 }
430 return false;
431}

References _disconnects, CONFIG_INTERVAL_DISCONNECT_TOLERANCE, WorldSession::GetAccountId(), GameTime::GetGameTime(), and sWorld.

Referenced by AddSession_().

◆ IncreasePlayerCount()

void WorldSessionMgr::IncreasePlayerCount ( )
inline

Increase/Decrease number of players.

84 {
87 }

References _maxPlayerCount, and _playerCount.

◆ Instance()

WorldSessionMgr * WorldSessionMgr::Instance ( )
static
29{
30 static WorldSessionMgr instance;
31 return &instance;
32}
Definition WorldSessionMgr.h:41

◆ KickAll()

void WorldSessionMgr::KickAll ( )

Kick (and save) all players.

237{
238 _queuedPlayer.clear(); // prevent send queue update packet and login queued sessions
239
240 // session not removed at kick and will removed in next update tick
241 for (SessionMap::const_iterator itr = _sessions.begin(); itr != _sessions.end(); ++itr)
242 itr->second->KickPlayer("KickAll sessions");
243
244 // pussywizard: kick offline sessions
245 for (SessionMap::const_iterator itr = _offlineSessions.begin(); itr != _offlineSessions.end(); ++itr)
246 itr->second->KickPlayer("KickAll offline sessions");
247}

References _offlineSessions, _queuedPlayer, and _sessions.

◆ KickAllLess()

void WorldSessionMgr::KickAllLess ( AccountTypes  sec)

Kick (and save) all players with security level less sec

251{
252 // session not removed at kick and will removed in next update tick
253 for (SessionMap::const_iterator itr = _sessions.begin(); itr != _sessions.end(); ++itr)
254 if (itr->second->GetSecurity() < sec)
255 itr->second->KickPlayer("KickAllLess");
256}

References _sessions.

◆ KickSession()

bool WorldSessionMgr::KickSession ( uint32  id)

Remove a given session.

  • Find the session, kick the user, but we can't delete session at this moment to prevent iterator invalidation
220{
222 SessionMap::const_iterator itr = _sessions.find(id);
223
224 if (itr != _sessions.end() && itr->second)
225 {
226 if (itr->second->PlayerLoading())
227 return false;
228
229 itr->second->KickPlayer("KickSession", false);
230 }
231
232 return true;
233}

References _sessions, and WorldSession::KickPlayer().

Referenced by AddSession_().

◆ RemoveQueuedPlayer()

bool WorldSessionMgr::RemoveQueuedPlayer ( WorldSession *  session)
273{
274 uint32 sessions = GetActiveSessionCount();
275
276 uint32 position = 1;
277 Queue::iterator iter = _queuedPlayer.begin();
278
279 // search to remove and count skipped positions
280 bool found = false;
281
282 for (; iter != _queuedPlayer.end(); ++iter, ++position)
283 {
284 if (*iter == session)
285 {
286 session->SetInQueue(false);
287 session->ResetTimeOutTime(false);
288 iter = _queuedPlayer.erase(iter);
289 found = true;
290 break;
291 }
292 }
293
294 // if session not queued then it was an active session
295 if (!found)
296 {
297 ASSERT(sessions > 0);
298 --sessions;
299 }
300
301 // accept first in queue
302 if ((!GetPlayerAmountLimit() || sessions < GetPlayerAmountLimit()) && !_queuedPlayer.empty())
303 {
304 WorldSession* pop_sess = _queuedPlayer.front();
305 pop_sess->InitializeSession();
306 _queuedPlayer.pop_front();
307
308 // update iter to point first queued socket or end() if queue is empty now
309 iter = _queuedPlayer.begin();
310 position = 1;
311 }
312
313 // update queue position from iter to end()
314 for (; iter != _queuedPlayer.end(); ++iter, ++position)
315 (*iter)->SendAuthWaitQueue(position);
316
317 return found;
318}
uint32 GetActiveSessionCount() const
Definition WorldSessionMgr.h:70
void ResetTimeOutTime(bool onlyActive)
Definition WorldSession.h:662

References _queuedPlayer, ASSERT, GetActiveSessionCount(), GetPlayerAmountLimit(), WorldSession::InitializeSession(), WorldSession::ResetTimeOutTime(), and WorldSession::SetInQueue().

Referenced by AddSession_(), and UpdateSessions().

◆ SendGlobalGMMessage()

void WorldSessionMgr::SendGlobalGMMessage ( WorldPacket const *  packet,
WorldSession *  self = nullptr,
TeamId  teamId = TEAM_NEUTRAL 
)

Send a packet to all GMs (except self if mentioned)

458{
459 SessionMap::iterator itr;
460 for (itr = _sessions.begin(); itr != _sessions.end(); ++itr)
461 {
462 if (itr->second &&
463 itr->second->GetPlayer() &&
464 itr->second->GetPlayer()->IsInWorld() &&
465 itr->second != self &&
467 (teamId == TEAM_NEUTRAL || itr->second->GetPlayer()->GetTeamId() == teamId))
468 {
469 itr->second->SendPacket(packet);
470 }
471 }
472}
@ TEAM_NEUTRAL
Definition SharedDefines.h:750
@ RBAC_PERM_RECEIVE_GLOBAL_GM_TEXTMESSAGE
Definition RBAC.h:95

References _sessions, WorldSession::HasPermission(), rbac::RBAC_PERM_RECEIVE_GLOBAL_GM_TEXTMESSAGE, and TEAM_NEUTRAL.

◆ SendGlobalMessage()

void WorldSessionMgr::SendGlobalMessage ( WorldPacket const *  packet,
WorldSession *  self = nullptr,
TeamId  teamId = TEAM_NEUTRAL 
)

Send a packet to all players (except self if mentioned)

441{
442 SessionMap::const_iterator itr;
443 for (itr = _sessions.begin(); itr != _sessions.end(); ++itr)
444 {
445 if (itr->second &&
446 itr->second->GetPlayer() &&
447 itr->second->GetPlayer()->IsInWorld() &&
448 itr->second != self &&
449 (teamId == TEAM_NEUTRAL || itr->second->GetPlayer()->GetTeamId() == teamId))
450 {
451 itr->second->SendPacket(packet);
452 }
453 }
454}

References _sessions, and TEAM_NEUTRAL.

Referenced by SendServerMessage().

◆ SendServerMessage()

void WorldSessionMgr::SendServerMessage ( ServerMessageType  messageID,
std::string  stringParam = "",
Player *  player = nullptr 
)

Send a server message to the user(s)

476{
478 chatServerMessage.MessageID = int32(messageID);
479 if (messageID <= SERVER_MSG_STRING)
480 chatServerMessage.StringParam = stringParam;
481
482 if (player)
483 player->SendDirectMessage(chatServerMessage.Write());
484 else
485 SendGlobalMessage(chatServerMessage.Write());
486}
std::int32_t int32
Definition Define.h:103
@ SERVER_MSG_STRING
Definition IWorld.h:58
void SendDirectMessage(WorldPacket const *data) const
Definition Player.cpp:5873
Definition ChatPackets.h:50
std::string StringParam
Definition ChatPackets.h:57
WorldPacket const * Write() override
Definition ChatPackets.cpp:33
int32 MessageID
Definition ChatPackets.h:56
void SendGlobalMessage(WorldPacket const *packet, WorldSession *self=nullptr, TeamId teamId=TEAM_NEUTRAL)
Send a packet to all players (except self if mentioned)
Definition WorldSessionMgr.cpp:440

References WorldPackets::Chat::ChatServerMessage::MessageID, Player::SendDirectMessage(), SendGlobalMessage(), SERVER_MSG_STRING, WorldPackets::Chat::ChatServerMessage::StringParam, and WorldPackets::Chat::ChatServerMessage::Write().

◆ SetPlayerAmountLimit()

void WorldSessionMgr::SetPlayerAmountLimit ( uint32  limit)
inline

Active session server limit.

79{ _playerLimit = limit; }

References _playerLimit.

◆ UpdateMaxSessionCounters()

void WorldSessionMgr::UpdateMaxSessionCounters ( )

Get the number of current active sessions.

References _maxActiveSessionCount, _maxQueuedSessionCount, _queuedPlayer, and _sessions.

Referenced by AddSession_().

◆ UpdateSessions()

void WorldSessionMgr::UpdateSessions ( uint32 const  diff)
  • Add new sessions
  • Then send an update signal to remaining ones
  • and remove not active sessions from the list
94{
95 _stalePruneTimer += diff;
97 {
99 Seconds const now = GameTime::GetGameTime();
100
101 // Drop play-history entries past the reset window so the map stays bounded even for
102 // accounts that disconnect and never reconnect (login only erases their own entry).
103 for (auto itr = _accountsPlayHistory.begin(); itr != _accountsPlayHistory.end();)
104 {
105 if ((now - itr->second.logoutTime) >= PLAY_TIME_LIMIT_FULL)
106 itr = _accountsPlayHistory.erase(itr);
107 else
108 ++itr;
109 }
110
111 // Drop disconnect entries past the tolerance window so the map stays bounded on realms that never
112 // reach PlayerLimit (HasRecentlyDisconnected only prunes _disconnects while the queue is active).
113 time_t const tolerance = sWorld->getIntConfig(CONFIG_INTERVAL_DISCONNECT_TOLERANCE);
114 for (auto itr = _disconnects.begin(); itr != _disconnects.end();)
115 {
116 if ((now.count() - itr->second) >= tolerance)
117 itr = _disconnects.erase(itr);
118 else
119 ++itr;
120 }
121 }
122
123 {
124 METRIC_DETAILED_NO_THRESHOLD_TIMER("world_update_time",
125 METRIC_TAG("type", "Add sessions"),
126 METRIC_TAG("parent_type", "Update sessions"));
127
129 WorldSession* sess = nullptr;
130 while (_addSessQueue.next(sess))
131 {
132 AddSession_(sess);
133 }
134 }
135
137 for (SessionMap::iterator itr = _sessions.begin(), next; itr != _sessions.end(); itr = next)
138 {
139 next = itr;
140 ++next;
141
143 WorldSession* pSession = itr->second;
144 WorldSessionFilter updater(pSession);
145
146 // pussywizard:
147 if (pSession->HandleSocketClosed())
148 {
149 Seconds const now = GameTime::GetGameTime();
150
151 if (pSession->IsAffectedByCAIS())
152 {
153 // a reconnect builds a fresh session and carries time from _accountsPlayHistory, so persist it
154 // here at socket-close time rather than during offline cleanup (which runs ~60s later)
156 history.playedTime = pSession->GetConsecutivePlayTime(now);
157 history.logoutTime = now;
158 }
159
160 if (!RemoveQueuedPlayer(pSession) && sWorld->getIntConfig(CONFIG_INTERVAL_DISCONNECT_TOLERANCE))
161 _disconnects[pSession->GetAccountId()] = now.count();
162 _sessions.erase(itr);
163 // there should be no offline session if current one is logged onto a character
164 SessionMap::iterator iter;
165 if ((iter = _offlineSessions.find(pSession->GetAccountId())) != _offlineSessions.end())
166 {
167 WorldSession* tmp = iter->second;
168 _offlineSessions.erase(iter);
169 delete tmp;
170 }
171 pSession->SetOfflineTime(now.count());
172 _offlineSessions[pSession->GetAccountId()] = pSession;
173 continue;
174 }
175
176 [[maybe_unused]] uint32 currentSessionId = itr->first;
177 METRIC_DETAILED_TIMER("world_update_sessions_time", METRIC_TAG("account_id", std::to_string(currentSessionId)));
178
179 if (!pSession->Update(diff, updater))
180 {
181 Seconds const now = GameTime::GetGameTime();
182
183 if (pSession->IsAffectedByCAIS())
184 {
186 history.playedTime = pSession->GetConsecutivePlayTime(now);
187 history.logoutTime = now;
188 }
189
190 if (!RemoveQueuedPlayer(pSession) && sWorld->getIntConfig(CONFIG_INTERVAL_DISCONNECT_TOLERANCE))
191 _disconnects[pSession->GetAccountId()] = now.count();
192 _sessions.erase(itr);
193 delete pSession;
194 }
195 }
196
197 // pussywizard:
198 if (_offlineSessions.empty())
199 return;
200 uint32 currTime = GameTime::GetGameTime().count();
201 for (SessionMap::iterator itr = _offlineSessions.begin(), next; itr != _offlineSessions.end(); itr = next)
202 {
203 next = itr;
204 ++next;
205 WorldSession* pSession = itr->second;
206 // A session with a logout already running leaves when that countdown ends, so closing the client early
207 // with EXIT NOW doesn't shorten it. A client crash (or sudden ALT+F4) waits out the full interval so a
208 // dropped connection can be reclaimed.
209 if (!pSession->GetPlayer() || pSession->IsKicked() || pSession->ShouldLogOut(currTime) ||
210 pSession->GetOfflineTime() + sWorld->getIntConfig(CONFIG_INTERVAL_DISCONNECT_TOLERANCE) < currTime)
211 {
212 _offlineSessions.erase(itr);
213 delete pSession;
214 }
215 }
216}
constexpr auto IN_MILLISECONDS
Definition Common.h:53
constexpr auto MINUTE
Definition Common.h:47
std::chrono::seconds Seconds
Seconds shorthand typedef.
Definition Duration.h:30
#define METRIC_DETAILED_TIMER(category,...)
Definition Metric.h:223
#define METRIC_DETAILED_NO_THRESHOLD_TIMER(category,...)
Definition Metric.h:224
#define METRIC_TAG(name, value)
Definition Metric.h:163
bool next(T &result)
Gets the next item in the queue and removes it.
Definition LockedQueue.h:77
Definition WorldSession.h:350
void AddSession_(WorldSession *session)
Definition WorldSessionMgr.cpp:331
bool Update(uint32 diff, PacketFilter &updater)
Update the WorldSession (triggered by World update)
Definition WorldSession.cpp:385
uint32 GetOfflineTime() const
Definition WorldSession.h:1213
Player * GetPlayer() const
Definition WorldSession.h:503
bool IsAffectedByCAIS() const
Definition WorldSession.cpp:240
Seconds GetConsecutivePlayTime(Seconds now) const
Definition WorldSession.h:529
bool ShouldLogOut(time_t currTime) const
Is logout cooldown expired?
Definition WorldSession.h:545
bool IsKicked() const
Definition WorldSession.h:1214
Definition WorldSessionMgr.h:35
Seconds logoutTime
Definition WorldSessionMgr.h:36
Seconds playedTime
Definition WorldSessionMgr.h:37

References _accountsPlayHistory, _addSessQueue, _disconnects, _offlineSessions, _sessions, _stalePruneTimer, AddSession_(), CONFIG_INTERVAL_DISCONNECT_TOLERANCE, WorldSession::GetAccountId(), WorldSession::GetConsecutivePlayTime(), GameTime::GetGameTime(), WorldSession::GetOfflineTime(), WorldSession::GetPlayer(), WorldSession::HandleSocketClosed(), IN_MILLISECONDS, WorldSession::IsAffectedByCAIS(), WorldSession::IsKicked(), AccountPlayHistory::logoutTime, METRIC_DETAILED_NO_THRESHOLD_TIMER, METRIC_DETAILED_TIMER, METRIC_TAG, MINUTE, LockedQueue< T, StorageType >::next(), PLAY_TIME_LIMIT_FULL, AccountPlayHistory::playedTime, RemoveQueuedPlayer(), WorldSession::SetOfflineTime(), WorldSession::ShouldLogOut(), sWorld, and WorldSession::Update().

Member Data Documentation

◆ _accountsPlayHistory

std::map<uint32 , AccountPlayHistory> WorldSessionMgr::_accountsPlayHistory
private

Referenced by AddSession_(), and UpdateSessions().

◆ _addSessQueue

LockedQueue<WorldSession*> WorldSessionMgr::_addSessQueue
private

Referenced by AddSession(), and UpdateSessions().

◆ _disconnects

DisconnectMap WorldSessionMgr::_disconnects
private

◆ _maxActiveSessionCount

uint32 WorldSessionMgr::_maxActiveSessionCount
private

◆ _maxPlayerCount

uint32 WorldSessionMgr::_maxPlayerCount
private

◆ _maxQueuedSessionCount

uint32 WorldSessionMgr::_maxQueuedSessionCount
private

◆ _offlineSessions

◆ _playerCount

uint32 WorldSessionMgr::_playerCount
private

◆ _playerLimit

uint32 WorldSessionMgr::_playerLimit
private

◆ _queuedPlayer

◆ _sessions

◆ _stalePruneTimer

uint32 WorldSessionMgr::_stalePruneTimer
private

Referenced by UpdateSessions(), and WorldSessionMgr().


The documentation for this class was generated from the following files: