core: add clientless player session bootstrap
This commit is contained in:
1 parent
df55203a96
commit
fe96d310d6
5 files changed
+144
No files matched your search
@@ -754,6 +754,29 @@ void WorldSession::HandlePlayerLoginOpcode(WorldPackets::Character::PlayerLogin&
|
||||
SendConnectToInstance(WorldPackets::Auth::ConnectToSerial::WorldAttempt1);
|
||||
}
|
||||
|
||||
bool WorldSession::InitializeClientlessPlayer(ObjectGuid playerGuid)
|
||||
{
|
||||
if (!IsClientless())
|
||||
{
|
||||
TC_LOG_ERROR("server.worldserver",
|
||||
"WorldSession::InitializeClientlessPlayer rejected a non-clientless session for account %u.",
|
||||
GetAccountId());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!playerGuid || !_clientlessPendingPlayerGuid.IsEmpty() || PlayerLoading() || GetPlayer())
|
||||
{
|
||||
TC_LOG_ERROR("server.worldserver",
|
||||
"WorldSession::InitializeClientlessPlayer rejected invalid initialization state for account %u, character GUID %u.",
|
||||
GetAccountId(), uint32(playerGuid.GetCounter()));
|
||||
return false;
|
||||
}
|
||||
|
||||
_clientlessPendingPlayerGuid = playerGuid;
|
||||
InitializeSession();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WorldSession::BeginClientlessPlayerLogin(ObjectGuid playerGuid)
|
||||
{
|
||||
if (!IsClientless())
|
||||
|
||||
@@ -115,6 +115,7 @@ WorldSession::WorldSession(uint32 id, std::string&& name, std::shared_ptr<WorldS
|
||||
m_GUIDLow(0),
|
||||
_player(nullptr),
|
||||
_sessionMode(sessionMode),
|
||||
_clientlessPendingPlayerGuid(),
|
||||
_security(sec),
|
||||
_accountId(id),
|
||||
_accountName(std::move(name)),
|
||||
@@ -1280,6 +1281,17 @@ void WorldSession::InitializeSessionCallback(CharacterDatabaseQueryHolder const&
|
||||
}
|
||||
|
||||
SetInQueue(false);
|
||||
|
||||
if (IsClientless() && !_clientlessPendingPlayerGuid.IsEmpty())
|
||||
{
|
||||
ObjectGuid playerGuid = _clientlessPendingPlayerGuid;
|
||||
_clientlessPendingPlayerGuid.Clear();
|
||||
|
||||
if (!BeginClientlessPlayerLogin(playerGuid))
|
||||
TC_LOG_ERROR("server.worldserver",
|
||||
"WorldSession::InitializeSessionCallback failed to continue clientless login for account %u, character GUID %u.",
|
||||
GetAccountId(), uint32(playerGuid.GetCounter()));
|
||||
}
|
||||
}
|
||||
|
||||
rbac::RBACData* WorldSession::GetRBACData()
|
||||
|
||||
@@ -687,6 +687,10 @@ class TC_GAME_API WorldSession
|
||||
void HandleCharCreateOpcode(WorldPacket& recvPacket);
|
||||
void HandlePlayerLoginOpcode(WorldPackets::Character::PlayerLogin& packet);
|
||||
|
||||
// Initializes shared account/session state and then starts the normal
|
||||
// Player DB-load/login pipeline for a registered Clientless session.
|
||||
bool InitializeClientlessPlayer(ObjectGuid playerGuid);
|
||||
|
||||
// Starts the normal Player DB-load/login pipeline without relying on
|
||||
// client character-enumeration state or a network login opcode.
|
||||
// The WorldSession must already be a registered Clientless session
|
||||
@@ -1371,6 +1375,7 @@ class TC_GAME_API WorldSession
|
||||
ObjectGuid::LowType m_GUIDLow; // set logined or recently logout player (while m_playerRecentlyLogout set)
|
||||
Player* _player;
|
||||
WorldSessionMode _sessionMode;
|
||||
ObjectGuid _clientlessPendingPlayerGuid;
|
||||
std::shared_ptr<WorldSocket> m_Socket[2];
|
||||
std::string m_Address; // Current Remote Address
|
||||
// std::string m_LAddress; // Last Attempted Remote Adress - we can not set attempted ip for a non-existing session!
|
||||
|
||||
@@ -379,6 +379,109 @@ bool World::RemoveClientlessSession(uint32 characterGuid)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool World::CreateClientlessPlayerSession(uint32 accountId, uint32 characterGuid)
|
||||
{
|
||||
if (!accountId || !characterGuid)
|
||||
{
|
||||
TC_LOG_ERROR("server.worldserver",
|
||||
"World::CreateClientlessPlayerSession rejected account %u, character GUID %u.",
|
||||
accountId, characterGuid);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (FindClientlessSession(characterGuid))
|
||||
{
|
||||
TC_LOG_ERROR("server.worldserver",
|
||||
"World::CreateClientlessPlayerSession rejected duplicate character GUID %u.",
|
||||
characterGuid);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (FindSession(accountId))
|
||||
{
|
||||
TC_LOG_ERROR("server.worldserver",
|
||||
"World::CreateClientlessPlayerSession rejected account %u because a network session is active.",
|
||||
accountId);
|
||||
return false;
|
||||
}
|
||||
|
||||
QueryResult characterResult = CharacterDatabase.PQuery(
|
||||
"SELECT account FROM characters WHERE guid = %u", characterGuid);
|
||||
if (!characterResult)
|
||||
{
|
||||
TC_LOG_ERROR("server.worldserver",
|
||||
"World::CreateClientlessPlayerSession could not find character GUID %u.",
|
||||
characterGuid);
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32 characterAccountId = characterResult->Fetch()[0].GetUInt32();
|
||||
if (characterAccountId != accountId)
|
||||
{
|
||||
TC_LOG_ERROR("server.worldserver",
|
||||
"World::CreateClientlessPlayerSession rejected character GUID %u: character account %u does not match requested account %u.",
|
||||
characterGuid, characterAccountId, accountId);
|
||||
return false;
|
||||
}
|
||||
|
||||
QueryResult accountResult = LoginDatabase.PQuery(
|
||||
"SELECT username, expansion, mutetime, locale, recruiter FROM account WHERE id = %u",
|
||||
accountId);
|
||||
if (!accountResult)
|
||||
{
|
||||
TC_LOG_ERROR("server.worldserver",
|
||||
"World::CreateClientlessPlayerSession could not find account %u.",
|
||||
accountId);
|
||||
return false;
|
||||
}
|
||||
|
||||
Field* accountFields = accountResult->Fetch();
|
||||
std::string accountName = accountFields[0].GetString();
|
||||
uint8 expansion = accountFields[1].GetUInt8();
|
||||
time_t muteTime = time_t(accountFields[2].GetUInt64());
|
||||
LocaleConstant locale = LocaleConstant(accountFields[3].GetUInt8());
|
||||
uint32 recruiter = accountFields[4].GetUInt32();
|
||||
|
||||
if (locale >= TOTAL_LOCALES)
|
||||
locale = LOCALE_enUS;
|
||||
|
||||
QueryResult recruiterResult = LoginDatabase.PQuery(
|
||||
"SELECT 1 FROM account WHERE recruiter = %u LIMIT 1", accountId);
|
||||
bool isRecruiter = bool(recruiterResult);
|
||||
|
||||
AccountTypes security = AccountTypes(AccountMgr::GetSecurity(accountId, realm.Id.Realm));
|
||||
|
||||
WorldSession* session = new WorldSession(
|
||||
accountId,
|
||||
std::move(accountName),
|
||||
nullptr,
|
||||
security,
|
||||
expansion,
|
||||
muteTime,
|
||||
locale,
|
||||
recruiter,
|
||||
isRecruiter,
|
||||
WorldSession::WorldSessionMode::Clientless);
|
||||
|
||||
if (!AddClientlessSession(characterGuid, session))
|
||||
{
|
||||
delete session;
|
||||
return false;
|
||||
}
|
||||
|
||||
ObjectGuid playerGuid = ObjectGuid::Create<HighGuid::Player>(characterGuid);
|
||||
if (!session->InitializeClientlessPlayer(playerGuid))
|
||||
{
|
||||
RemoveClientlessSession(characterGuid);
|
||||
return false;
|
||||
}
|
||||
|
||||
TC_LOG_INFO("server.worldserver",
|
||||
"Created clientless player session for character GUID %u (account %u).",
|
||||
characterGuid, accountId);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool World::RemoveSession(uint32 id)
|
||||
{
|
||||
///- Find the session, kick the user, but we can't delete session at this moment to prevent iterator invalidation
|
||||
|
||||
@@ -612,6 +612,7 @@ class TC_GAME_API World
|
||||
WorldSession* FindClientlessSession(uint32 characterGuid) const;
|
||||
bool AddClientlessSession(uint32 characterGuid, WorldSession* session);
|
||||
bool RemoveClientlessSession(uint32 characterGuid);
|
||||
bool CreateClientlessPlayerSession(uint32 accountId, uint32 characterGuid);
|
||||
SessionMap const& GetAllClientlessSessions() const { return m_clientlessSessions; }
|
||||
uint32 GetClientlessSessionCount() const { return uint32(m_clientlessSessions.size()); }
|
||||
void AddInstanceSocket(std::weak_ptr<WorldSocket> sock, uint64 connectToKey);
|
||||
|
||||
Reference in new issue
Block a user