fix(Core/Server): Fix player login checks (#23073)

This commit is contained in:
Takenbacon
2025-09-30 03:16:07 -07:00
committed by GitHub
parent 05b57ecb74
commit a56d1f65aa
3 changed files with 39 additions and 37 deletions
+29 -29
View File
@@ -668,51 +668,46 @@ void WorldSession::HandleCharDeleteOpcode(WorldPacket& recvData)
void WorldSession::HandlePlayerLoginOpcode(WorldPacket& recvData) void WorldSession::HandlePlayerLoginOpcode(WorldPacket& recvData)
{ {
m_playerLoading = true; if (!sWorld->getBoolConfig(CONFIG_REALM_LOGIN_ENABLED))
{
SendCharLoginFailed(LoginFailureReason::NoWorld);
return;
}
if (PlayerLoading() || GetPlayer() != nullptr)
{
LOG_ERROR("network", "Player tried to login again, AccountId = {}", GetAccountId());
KickPlayer("WorldSession::HandlePlayerLoginOpcode Another client logging in");
return;
}
ObjectGuid playerGuid; ObjectGuid playerGuid;
recvData >> playerGuid; recvData >> playerGuid;
if (PlayerLoading() || GetPlayer() != nullptr || !playerGuid.IsPlayer()) if (!IsLegitCharacterForAccount(playerGuid))
{
// limit player interaction with the world
if (!sWorld->getBoolConfig(CONFIG_REALM_LOGIN_ENABLED))
{
WorldPacket data(SMSG_CHARACTER_LOGIN_FAILED, 1);
// see LoginFailureReason enum for more reasons
data << uint8(LoginFailureReason::NoWorld);
SendPacket(&data);
return;
}
}
if (!playerGuid.IsPlayer() || !IsLegitCharacterForAccount(playerGuid))
{ {
LOG_ERROR("network", "Account ({}) can't login with that character ({}).", GetAccountId(), playerGuid.ToString()); LOG_ERROR("network", "Account ({}) can't login with that character ({}).", GetAccountId(), playerGuid.ToString());
KickPlayer("Account can't login with this character"); KickPlayer("Account can't login with this character");
return; return;
} }
auto SendCharLogin = [&](ResponseCodes result)
{
WorldPacket data(SMSG_CHARACTER_LOGIN_FAILED, 1);
data << uint8(result);
SendPacket(&data);
};
// pussywizard: // pussywizard:
if (WorldSession* sess = sWorldSessionMgr->FindOfflineSessionForCharacterGUID(playerGuid.GetCounter())) if (WorldSession* sess = sWorldSessionMgr->FindOfflineSessionForCharacterGUID(playerGuid.GetCounter()))
{
if (sess->GetAccountId() != GetAccountId()) if (sess->GetAccountId() != GetAccountId())
{ {
SendCharLogin(CHAR_LOGIN_DUPLICATE_CHARACTER); SendCharLoginFailed(LoginFailureReason::DuplicateCharacter);
return; return;
} }
}
// pussywizard: // pussywizard:
if (WorldSession* sess = sWorldSessionMgr->FindOfflineSession(GetAccountId())) if (WorldSession* sess = sWorldSessionMgr->FindOfflineSession(GetAccountId()))
{ {
Player* p = sess->GetPlayer(); Player* p = sess->GetPlayer();
if (!p || sess->IsKicked()) if (!p || sess->IsKicked())
{ {
SendCharLogin(CHAR_LOGIN_DUPLICATE_CHARACTER); SendCharLoginFailed(LoginFailureReason::DuplicateCharacter);
return; return;
} }
@@ -723,7 +718,7 @@ void WorldSession::HandlePlayerLoginOpcode(WorldPacket& recvData)
// pussywizard: players stay ingame no matter what (prevent abuse), but allow to turn it off to stop crashing // pussywizard: players stay ingame no matter what (prevent abuse), but allow to turn it off to stop crashing
if (!sWorld->getBoolConfig(CONFIG_ENABLE_LOGIN_AFTER_DC)) if (!sWorld->getBoolConfig(CONFIG_ENABLE_LOGIN_AFTER_DC))
{ {
SendCharLogin(CHAR_LOGIN_DUPLICATE_CHARACTER); SendCharLoginFailed(LoginFailureReason::DuplicateCharacter);
return; return;
} }
@@ -765,7 +760,7 @@ void WorldSession::HandlePlayerLoginOpcode(WorldPacket& recvData)
} }
if (!p->FindMap() || !p->IsInWorld() || sess->IsKicked()) if (!p->FindMap() || !p->IsInWorld() || sess->IsKicked())
{ {
SendCharLogin(CHAR_LOGIN_DUPLICATE_CHARACTER); SendCharLoginFailed(LoginFailureReason::DuplicateCharacter);
return; return;
} }
@@ -781,11 +776,9 @@ void WorldSession::HandlePlayerLoginOpcode(WorldPacket& recvData)
std::shared_ptr<LoginQueryHolder> holder = std::make_shared<LoginQueryHolder>(GetAccountId(), playerGuid); std::shared_ptr<LoginQueryHolder> holder = std::make_shared<LoginQueryHolder>(GetAccountId(), playerGuid);
if (!holder->Initialize()) if (!holder->Initialize())
{
m_playerLoading = false;
return; return;
}
m_playerLoading = true;
AddQueryHolderCallback(CharacterDatabase.DelayQueryHolder(holder)).AfterComplete([this](SQLQueryHolderBase const& holder) AddQueryHolderCallback(CharacterDatabase.DelayQueryHolder(holder)).AfterComplete([this](SQLQueryHolderBase const& holder)
{ {
HandlePlayerLoginFromDB(static_cast<LoginQueryHolder const&>(holder)); HandlePlayerLoginFromDB(static_cast<LoginQueryHolder const&>(holder));
@@ -2575,6 +2568,13 @@ void WorldSession::SendCharDelete(ResponseCodes result)
SendPacket(&data); SendPacket(&data);
} }
void WorldSession::SendCharLoginFailed(LoginFailureReason reason)
{
WorldPacket data(SMSG_CHARACTER_LOGIN_FAILED, 1);
data << uint8(reason);
SendPacket(&data);
};
void WorldSession::SendCharRename(ResponseCodes result, CharacterRenameInfo const* renameInfo) void WorldSession::SendCharRename(ResponseCodes result, CharacterRenameInfo const* renameInfo)
{ {
WorldPacket data(SMSG_CHAR_RENAME, 1 + 8 + renameInfo->Name.size() + 1); WorldPacket data(SMSG_CHAR_RENAME, 1 + 8 + renameInfo->Name.size() + 1);
+1
View File
@@ -601,6 +601,7 @@ public: // opcodes handlers
void SendCharCreate(ResponseCodes result); void SendCharCreate(ResponseCodes result);
void SendCharDelete(ResponseCodes result); void SendCharDelete(ResponseCodes result);
void SendCharLoginFailed(LoginFailureReason reason);
void SendCharRename(ResponseCodes result, CharacterRenameInfo const* renameInfo); void SendCharRename(ResponseCodes result, CharacterRenameInfo const* renameInfo);
void SendCharCustomize(ResponseCodes result, CharacterCustomizeInfo const* customizeInfo); void SendCharCustomize(ResponseCodes result, CharacterCustomizeInfo const* customizeInfo);
void SendCharFactionChange(ResponseCodes result, CharacterFactionChangeInfo const* factionChangeInfo); void SendCharFactionChange(ResponseCodes result, CharacterFactionChangeInfo const* factionChangeInfo);
+9 -8
View File
@@ -4010,14 +4010,15 @@ enum ServerProcessTypes
// Login Failure Reasons // Login Failure Reasons
enum class LoginFailureReason : uint8 enum class LoginFailureReason : uint8
{ {
Failed = 0, Failed = 0, // Login failed
NoWorld = 1, NoWorld = 1, // World server down
DuplicateCharacter = 2, DuplicateCharacter = 2, // A character with that name already exists
NoInstances = 3, NoInstances = 3, // No instance servers are available
Disabled = 4, Disabled = 4, // Login for that race, class or character is currently disabled.
NoCharacter = 5, NoCharacter = 5, // Character not found
LockedForTransfer = 6, LockedForTransfer = 6, // You cannot log in until the character update process you recently initiated is complete.
LockedByBilling = 7 LockedByBilling = 7, // Character locked. Contact billing for more information
UsingRemote = 8, // You cannot log in while using World of Warcraft Remote.
}; };
namespace Acore::Impl namespace Acore::Impl