mirror of
https://github.com/mangosfour/server.git
synced 2025-12-13 22:37:03 +00:00
[6858] Prevent cheating with ignore waiting in login queue.
Cheating preventing at reconect for queued session and sending unexpected packets to server. Removed unneeded after ACE related changes kicked sessions list.
This commit is contained in:
parent
874339ecee
commit
51546c7ab7
7 changed files with 56 additions and 47 deletions
|
|
@ -50,7 +50,8 @@ WaypointMovementGenerator<Creature>::LoadPath(Creature &c)
|
||||||
i_path = WaypointMgr.GetPath(c.GetDBTableGUIDLow());
|
i_path = WaypointMgr.GetPath(c.GetDBTableGUIDLow());
|
||||||
if(!i_path)
|
if(!i_path)
|
||||||
{
|
{
|
||||||
sLog.outErrorDb("WaypointMovementGenerator::LoadPath: creature %s(%d) doesn't have waypoint path", c.GetName(), c.GetDBTableGUIDLow());
|
sLog.outErrorDb("WaypointMovementGenerator::LoadPath: creature %s (Entry: %u GUID: %d) doesn't have waypoint path",
|
||||||
|
c.GetName(), c.GetEntry(), c.GetDBTableGUIDLow());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -112,10 +112,12 @@ World::World()
|
||||||
World::~World()
|
World::~World()
|
||||||
{
|
{
|
||||||
///- Empty the kicked session set
|
///- Empty the kicked session set
|
||||||
for (std::set<WorldSession*>::iterator itr = m_kicked_sessions.begin(); itr != m_kicked_sessions.end(); ++itr)
|
while (!m_sessions.empty())
|
||||||
delete *itr;
|
{
|
||||||
|
// not remove from queue, prevent loading new sessions
|
||||||
m_kicked_sessions.clear();
|
delete m_sessions.begin()->second;
|
||||||
|
m_sessions.erase(m_sessions.begin());
|
||||||
|
}
|
||||||
|
|
||||||
///- Empty the WeatherMap
|
///- Empty the WeatherMap
|
||||||
for (WeatherMap::iterator itr = m_weathers.begin(); itr != m_weathers.end(); ++itr)
|
for (WeatherMap::iterator itr = m_weathers.begin(); itr != m_weathers.end(); ++itr)
|
||||||
|
|
@ -195,17 +197,26 @@ World::AddSession_ (WorldSession* s)
|
||||||
if (!RemoveSession (s->GetAccountId ()))
|
if (!RemoveSession (s->GetAccountId ()))
|
||||||
{
|
{
|
||||||
s->KickPlayer ();
|
s->KickPlayer ();
|
||||||
m_kicked_sessions.insert (s);
|
delete s; // session not added yet in session list, so not listed in queue
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// decrease session counts only at not reconnection case
|
||||||
|
bool decrease_session = true;
|
||||||
|
|
||||||
// if session already exist, prepare to it deleting at next world update
|
// if session already exist, prepare to it deleting at next world update
|
||||||
// NOTE - KickPlayer() should be called on "old" in RemoveSession()
|
// NOTE - KickPlayer() should be called on "old" in RemoveSession()
|
||||||
{
|
{
|
||||||
SessionMap::const_iterator old = m_sessions.find(s->GetAccountId ());
|
SessionMap::const_iterator old = m_sessions.find(s->GetAccountId ());
|
||||||
|
|
||||||
if(old != m_sessions.end())
|
if(old != m_sessions.end())
|
||||||
m_kicked_sessions.insert (old->second);
|
{
|
||||||
|
// prevent decrease sessions count if session queued
|
||||||
|
if(RemoveQueuedPlayer(old->second))
|
||||||
|
decrease_session = false;
|
||||||
|
// not remove replaced session form queue if listed
|
||||||
|
delete old->second;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_sessions[s->GetAccountId ()] = s;
|
m_sessions[s->GetAccountId ()] = s;
|
||||||
|
|
@ -213,9 +224,11 @@ World::AddSession_ (WorldSession* s)
|
||||||
uint32 Sessions = GetActiveAndQueuedSessionCount ();
|
uint32 Sessions = GetActiveAndQueuedSessionCount ();
|
||||||
uint32 pLimit = GetPlayerAmountLimit ();
|
uint32 pLimit = GetPlayerAmountLimit ();
|
||||||
uint32 QueueSize = GetQueueSize (); //number of players in the queue
|
uint32 QueueSize = GetQueueSize (); //number of players in the queue
|
||||||
|
|
||||||
//so we don't count the user trying to
|
//so we don't count the user trying to
|
||||||
//login as a session and queue the socket that we are using
|
//login as a session and queue the socket that we are using
|
||||||
--Sessions;
|
if(decrease_session)
|
||||||
|
--Sessions;
|
||||||
|
|
||||||
if (pLimit > 0 && Sessions >= pLimit && s->GetSecurity () == SEC_PLAYER )
|
if (pLimit > 0 && Sessions >= pLimit && s->GetSecurity () == SEC_PLAYER )
|
||||||
{
|
{
|
||||||
|
|
@ -259,6 +272,7 @@ int32 World::GetQueuePos(WorldSession* sess)
|
||||||
|
|
||||||
void World::AddQueuedPlayer(WorldSession* sess)
|
void World::AddQueuedPlayer(WorldSession* sess)
|
||||||
{
|
{
|
||||||
|
sess->SetInQueue(true);
|
||||||
m_QueuedPlayer.push_back (sess);
|
m_QueuedPlayer.push_back (sess);
|
||||||
|
|
||||||
// The 1st SMSG_AUTH_RESPONSE needs to contain other info too.
|
// The 1st SMSG_AUTH_RESPONSE needs to contain other info too.
|
||||||
|
|
@ -274,7 +288,7 @@ void World::AddQueuedPlayer(WorldSession* sess)
|
||||||
//sess->SendAuthWaitQue (GetQueuePos (sess));
|
//sess->SendAuthWaitQue (GetQueuePos (sess));
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::RemoveQueuedPlayer(WorldSession* sess)
|
bool World::RemoveQueuedPlayer(WorldSession* sess)
|
||||||
{
|
{
|
||||||
// sessions count including queued to remove (if removed_session set)
|
// sessions count including queued to remove (if removed_session set)
|
||||||
uint32 sessions = GetActiveSessionCount();
|
uint32 sessions = GetActiveSessionCount();
|
||||||
|
|
@ -282,16 +296,16 @@ void World::RemoveQueuedPlayer(WorldSession* sess)
|
||||||
uint32 position = 1;
|
uint32 position = 1;
|
||||||
Queue::iterator iter = m_QueuedPlayer.begin();
|
Queue::iterator iter = m_QueuedPlayer.begin();
|
||||||
|
|
||||||
// if session not queued then we need decrease sessions count (Remove socked callet before session removing from session list)
|
|
||||||
bool decrease_session = true;
|
|
||||||
|
|
||||||
// search to remove and count skipped positions
|
// search to remove and count skipped positions
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
for(;iter != m_QueuedPlayer.end(); ++iter, ++position)
|
for(;iter != m_QueuedPlayer.end(); ++iter, ++position)
|
||||||
{
|
{
|
||||||
if(*iter==sess)
|
if(*iter==sess)
|
||||||
{
|
{
|
||||||
|
sess->SetInQueue(false);
|
||||||
iter = m_QueuedPlayer.erase(iter);
|
iter = m_QueuedPlayer.erase(iter);
|
||||||
decrease_session = false; // removing queued session
|
found = true; // removing queued session
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -299,15 +313,16 @@ void World::RemoveQueuedPlayer(WorldSession* sess)
|
||||||
// iter point to next socked after removed or end()
|
// iter point to next socked after removed or end()
|
||||||
// position store position of removed socket and then new position next socket after removed
|
// position store position of removed socket and then new position next socket after removed
|
||||||
|
|
||||||
// decrease for case session queued for removing
|
// if session not queued then we need decrease sessions count
|
||||||
if(decrease_session && sessions)
|
if(!found && sessions)
|
||||||
--sessions;
|
--sessions;
|
||||||
|
|
||||||
// accept first in queue
|
// accept first in queue
|
||||||
if( (!m_playerLimit || sessions < m_playerLimit) && !m_QueuedPlayer.empty() )
|
if( (!m_playerLimit || sessions < m_playerLimit) && !m_QueuedPlayer.empty() )
|
||||||
{
|
{
|
||||||
WorldSession * socket = m_QueuedPlayer.front();
|
WorldSession* pop_sess = m_QueuedPlayer.front();
|
||||||
socket->SendAuthWaitQue(0);
|
pop_sess->SetInQueue(false);
|
||||||
|
pop_sess->SendAuthWaitQue(0);
|
||||||
m_QueuedPlayer.pop_front();
|
m_QueuedPlayer.pop_front();
|
||||||
|
|
||||||
// update iter to point first queued socket or end() if queue is empty now
|
// update iter to point first queued socket or end() if queue is empty now
|
||||||
|
|
@ -319,6 +334,8 @@ void World::RemoveQueuedPlayer(WorldSession* sess)
|
||||||
// iter point to first not updated socket, position store new position
|
// iter point to first not updated socket, position store new position
|
||||||
for(; iter != m_QueuedPlayer.end(); ++iter, ++position)
|
for(; iter != m_QueuedPlayer.end(); ++iter, ++position)
|
||||||
(*iter)->SendAuthWaitQue(position);
|
(*iter)->SendAuthWaitQue(position);
|
||||||
|
|
||||||
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Find a Weather object by the given zoneid
|
/// Find a Weather object by the given zoneid
|
||||||
|
|
@ -2170,6 +2187,8 @@ void World::SendZoneText(uint32 zone, const char* text, WorldSession *self, uint
|
||||||
/// Kick (and save) all players
|
/// Kick (and save) all players
|
||||||
void World::KickAll()
|
void World::KickAll()
|
||||||
{
|
{
|
||||||
|
m_QueuedPlayer.clear(); // prevent send queue update packet and login queued sessions
|
||||||
|
|
||||||
// session not removed at kick and will removed in next update tick
|
// session not removed at kick and will removed in next update tick
|
||||||
for (SessionMap::iterator itr = m_sessions.begin(); itr != m_sessions.end(); ++itr)
|
for (SessionMap::iterator itr = m_sessions.begin(); itr != m_sessions.end(); ++itr)
|
||||||
itr->second->KickPlayer();
|
itr->second->KickPlayer();
|
||||||
|
|
@ -2184,18 +2203,6 @@ void World::KickAllLess(AccountTypes sec)
|
||||||
itr->second->KickPlayer();
|
itr->second->KickPlayer();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Kick all queued players
|
|
||||||
void World::KickAllQueued()
|
|
||||||
{
|
|
||||||
// session not removed at kick and will removed in next update tick
|
|
||||||
//TODO here
|
|
||||||
// for (Queue::iterator itr = m_QueuedPlayer.begin(); itr != m_QueuedPlayer.end(); ++itr)
|
|
||||||
// if(WorldSession* session = (*itr)->GetSession())
|
|
||||||
// session->KickPlayer();
|
|
||||||
|
|
||||||
m_QueuedPlayer.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Kick (and save) the designated player
|
/// Kick (and save) the designated player
|
||||||
bool World::KickPlayer(std::string playerName)
|
bool World::KickPlayer(std::string playerName)
|
||||||
{
|
{
|
||||||
|
|
@ -2426,20 +2433,13 @@ void World::SendServerMessage(uint32 type, const char *text, Player* player)
|
||||||
|
|
||||||
void World::UpdateSessions( time_t diff )
|
void World::UpdateSessions( time_t diff )
|
||||||
{
|
{
|
||||||
|
///- Add new sessions
|
||||||
while(!addSessQueue.empty())
|
while(!addSessQueue.empty())
|
||||||
{
|
{
|
||||||
WorldSession* sess = addSessQueue.next ();
|
WorldSession* sess = addSessQueue.next ();
|
||||||
AddSession_ (sess);
|
AddSession_ (sess);
|
||||||
}
|
}
|
||||||
|
|
||||||
///- Delete kicked sessions at add new session
|
|
||||||
for (std::set<WorldSession*>::iterator itr = m_kicked_sessions.begin(); itr != m_kicked_sessions.end(); ++itr)
|
|
||||||
{
|
|
||||||
RemoveQueuedPlayer (*itr);
|
|
||||||
delete *itr;
|
|
||||||
}
|
|
||||||
m_kicked_sessions.clear();
|
|
||||||
|
|
||||||
///- Then send an update signal to remaining ones
|
///- Then send an update signal to remaining ones
|
||||||
for (SessionMap::iterator itr = m_sessions.begin(), next; itr != m_sessions.end(); itr = next)
|
for (SessionMap::iterator itr = m_sessions.begin(), next; itr != m_sessions.end(); itr = next)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -350,7 +350,7 @@ class World
|
||||||
//player Queue
|
//player Queue
|
||||||
typedef std::list<WorldSession*> Queue;
|
typedef std::list<WorldSession*> Queue;
|
||||||
void AddQueuedPlayer(WorldSession*);
|
void AddQueuedPlayer(WorldSession*);
|
||||||
void RemoveQueuedPlayer(WorldSession*);
|
bool RemoveQueuedPlayer(WorldSession* session);
|
||||||
int32 GetQueuePos(WorldSession*);
|
int32 GetQueuePos(WorldSession*);
|
||||||
uint32 GetQueueSize() const { return m_QueuedPlayer.size(); }
|
uint32 GetQueueSize() const { return m_QueuedPlayer.size(); }
|
||||||
|
|
||||||
|
|
@ -433,7 +433,6 @@ class World
|
||||||
bool KickPlayer(std::string playerName);
|
bool KickPlayer(std::string playerName);
|
||||||
void KickAll();
|
void KickAll();
|
||||||
void KickAllLess(AccountTypes sec);
|
void KickAllLess(AccountTypes sec);
|
||||||
void KickAllQueued();
|
|
||||||
BanReturn BanAccount(BanMode mode, std::string nameOrIP, std::string duration, std::string reason, std::string author);
|
BanReturn BanAccount(BanMode mode, std::string nameOrIP, std::string duration, std::string reason, std::string author);
|
||||||
bool RemoveBanAccount(BanMode mode, std::string nameOrIP);
|
bool RemoveBanAccount(BanMode mode, std::string nameOrIP);
|
||||||
|
|
||||||
|
|
@ -491,7 +490,6 @@ class World
|
||||||
WeatherMap m_weathers;
|
WeatherMap m_weathers;
|
||||||
typedef UNORDERED_MAP<uint32, WorldSession*> SessionMap;
|
typedef UNORDERED_MAP<uint32, WorldSession*> SessionMap;
|
||||||
SessionMap m_sessions;
|
SessionMap m_sessions;
|
||||||
std::set<WorldSession*> m_kicked_sessions;
|
|
||||||
uint32 m_maxActiveSessionCount;
|
uint32 m_maxActiveSessionCount;
|
||||||
uint32 m_maxQueuedSessionCount;
|
uint32 m_maxQueuedSessionCount;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@ WorldSession::WorldSession(uint32 id, WorldSocket *sock, uint32 sec, uint8 expan
|
||||||
LookingForGroup_auto_join(false), LookingForGroup_auto_add(false), m_muteTime(mute_time),
|
LookingForGroup_auto_join(false), LookingForGroup_auto_add(false), m_muteTime(mute_time),
|
||||||
_player(NULL), m_Socket(sock),_security(sec), _accountId(id), m_expansion(expansion),
|
_player(NULL), m_Socket(sock),_security(sec), _accountId(id), m_expansion(expansion),
|
||||||
m_sessionDbcLocale(sWorld.GetAvailableDbcLocale(locale)), m_sessionDbLocaleIndex(objmgr.GetIndexForLocale(locale)),
|
m_sessionDbcLocale(sWorld.GetAvailableDbcLocale(locale)), m_sessionDbLocaleIndex(objmgr.GetIndexForLocale(locale)),
|
||||||
_logoutTime(0), m_playerLoading(false), m_playerLogout(false), m_playerRecentlyLogout(false), m_latency(0)
|
_logoutTime(0), m_inQueue(false), m_playerLoading(false), m_playerLogout(false), m_playerRecentlyLogout(false), m_latency(0)
|
||||||
{
|
{
|
||||||
if (sock)
|
if (sock)
|
||||||
{
|
{
|
||||||
|
|
@ -205,6 +205,13 @@ bool WorldSession::Update(uint32 /*diff*/)
|
||||||
(this->*opHandle.handler)(*packet);
|
(this->*opHandle.handler)(*packet);
|
||||||
break;
|
break;
|
||||||
case STATUS_AUTHED:
|
case STATUS_AUTHED:
|
||||||
|
// prevent cheating with skip queue wait
|
||||||
|
if(m_inQueue)
|
||||||
|
{
|
||||||
|
logUnexpectedOpcode(packet, "the player not pass queue yet");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
m_playerRecentlyLogout = false;
|
m_playerRecentlyLogout = false;
|
||||||
(this->*opHandle.handler)(*packet);
|
(this->*opHandle.handler)(*packet);
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -95,6 +95,9 @@ class MANGOS_DLL_SPEC WorldSession
|
||||||
void SetPlayer(Player *plr) { _player = plr; }
|
void SetPlayer(Player *plr) { _player = plr; }
|
||||||
uint8 Expansion() const { return m_expansion; }
|
uint8 Expansion() const { return m_expansion; }
|
||||||
|
|
||||||
|
/// Session in auth.queue currently
|
||||||
|
void SetInQueue(bool state) { m_inQueue = state; }
|
||||||
|
|
||||||
/// Is the user engaged in a log out process?
|
/// Is the user engaged in a log out process?
|
||||||
bool isLogingOut() const { return _logoutTime || m_playerLogout; }
|
bool isLogingOut() const { return _logoutTime || m_playerLogout; }
|
||||||
|
|
||||||
|
|
@ -635,6 +638,7 @@ class MANGOS_DLL_SPEC WorldSession
|
||||||
uint8 m_expansion;
|
uint8 m_expansion;
|
||||||
|
|
||||||
time_t _logoutTime;
|
time_t _logoutTime;
|
||||||
|
bool m_inQueue; // session wait in auth.queue
|
||||||
bool m_playerLoading; // code processed in LoginPlayer
|
bool m_playerLoading; // code processed in LoginPlayer
|
||||||
bool m_playerLogout; // code processed in LogoutPlayer
|
bool m_playerLogout; // code processed in LogoutPlayer
|
||||||
bool m_playerRecentlyLogout;
|
bool m_playerRecentlyLogout;
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,6 @@ void WorldRunnable::run()
|
||||||
prevSleepTime = 0;
|
prevSleepTime = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
sWorld.KickAllQueued(); // kick all queued players (and prevent its login at kick in game players)
|
|
||||||
sWorld.KickAll(); // save and kick all players
|
sWorld.KickAll(); // save and kick all players
|
||||||
sWorld.UpdateSessions( 1 ); // real players unload required UpdateSessions call
|
sWorld.UpdateSessions( 1 ); // real players unload required UpdateSessions call
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
#ifndef __REVISION_NR_H__
|
#ifndef __REVISION_NR_H__
|
||||||
#define __REVISION_NR_H__
|
#define __REVISION_NR_H__
|
||||||
#define REVISION_NR "6857"
|
#define REVISION_NR "6858"
|
||||||
#endif // __REVISION_NR_H__
|
#endif // __REVISION_NR_H__
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue