diff options
Diffstat (limited to 'src/server/game/Handlers/CharacterHandler.cpp')
| -rw-r--r-- | src/server/game/Handlers/CharacterHandler.cpp | 91 |
1 files changed, 55 insertions, 36 deletions
diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index 2169cb5316..eeff0d3d64 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -1,14 +1,14 @@ /* * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along @@ -668,51 +668,46 @@ void WorldSession::HandleCharDeleteOpcode(WorldPacket& recvData) void WorldSession::HandlePlayerLoginOpcode(WorldPacket& recvData) { - m_playerLoading = true; - ObjectGuid playerGuid; - recvData >> playerGuid; + if (!sWorld->getBoolConfig(CONFIG_REALM_LOGIN_ENABLED)) + { + SendCharLoginFailed(LoginFailureReason::NoWorld); + return; + } - if (PlayerLoading() || GetPlayer() != nullptr || !playerGuid.IsPlayer()) + if (PlayerLoading() || GetPlayer() != nullptr) { - // 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; - } + LOG_ERROR("network", "Player tried to login again, AccountId = {}", GetAccountId()); + KickPlayer("WorldSession::HandlePlayerLoginOpcode Another client logging in"); + return; } - if (!playerGuid.IsPlayer() || !IsLegitCharacterForAccount(playerGuid)) + ObjectGuid playerGuid; + recvData >> playerGuid; + + if (!IsLegitCharacterForAccount(playerGuid)) { LOG_ERROR("network", "Account ({}) can't login with that character ({}).", GetAccountId(), playerGuid.ToString()); KickPlayer("Account can't login with this character"); return; } - auto SendCharLogin = [&](ResponseCodes result) - { - WorldPacket data(SMSG_CHARACTER_LOGIN_FAILED, 1); - data << uint8(result); - SendPacket(&data); - }; - // pussywizard: if (WorldSession* sess = sWorldSessionMgr->FindOfflineSessionForCharacterGUID(playerGuid.GetCounter())) + { if (sess->GetAccountId() != GetAccountId()) { - SendCharLogin(CHAR_LOGIN_DUPLICATE_CHARACTER); + SendCharLoginFailed(LoginFailureReason::DuplicateCharacter); return; } + } + // pussywizard: if (WorldSession* sess = sWorldSessionMgr->FindOfflineSession(GetAccountId())) { Player* p = sess->GetPlayer(); if (!p || sess->IsKicked()) { - SendCharLogin(CHAR_LOGIN_DUPLICATE_CHARACTER); + SendCharLoginFailed(LoginFailureReason::DuplicateCharacter); 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 if (!sWorld->getBoolConfig(CONFIG_ENABLE_LOGIN_AFTER_DC)) { - SendCharLogin(CHAR_LOGIN_DUPLICATE_CHARACTER); + SendCharLoginFailed(LoginFailureReason::DuplicateCharacter); return; } @@ -765,7 +760,7 @@ void WorldSession::HandlePlayerLoginOpcode(WorldPacket& recvData) } if (!p->FindMap() || !p->IsInWorld() || sess->IsKicked()) { - SendCharLogin(CHAR_LOGIN_DUPLICATE_CHARACTER); + SendCharLoginFailed(LoginFailureReason::DuplicateCharacter); return; } @@ -781,11 +776,9 @@ void WorldSession::HandlePlayerLoginOpcode(WorldPacket& recvData) std::shared_ptr<LoginQueryHolder> holder = std::make_shared<LoginQueryHolder>(GetAccountId(), playerGuid); if (!holder->Initialize()) - { - m_playerLoading = false; return; - } + m_playerLoading = true; AddQueryHolderCallback(CharacterDatabase.DelayQueryHolder(holder)).AfterComplete([this](SQLQueryHolderBase const& holder) { HandlePlayerLoginFromDB(static_cast<LoginQueryHolder const&>(holder)); @@ -957,7 +950,6 @@ void WorldSession::HandlePlayerLoginFromDB(LoginQueryHolder const& holder) pCurrChar->CastSpell(pCurrChar, 20584, true, 0); // auras SPELL_AURA_INCREASE_SPEED(+speed in wisp form), SPELL_AURA_INCREASE_SWIM_SPEED(+swim speed in wisp form), SPELL_AURA_TRANSFORM (to wisp form) pCurrChar->CastSpell(pCurrChar, 8326, true, 0); // auras SPELL_AURA_GHOST, SPELL_AURA_INCREASE_SPEED(why?), SPELL_AURA_INCREASE_SWIM_SPEED(why?) - pCurrChar->SetMovement(MOVE_WATER_WALK); } // Set FFA PvP for non GM in non-rest mode @@ -1171,15 +1163,23 @@ void WorldSession::HandlePlayerLoginToCharInWorld(Player* pCurrChar) SendPacket(&data); // Xinef: fix possible problem with flag UNIT_FLAG_STUNNED added during logout - if (!pCurrChar->HasUnitState(UNIT_STATE_STUNNED)) + if (pCurrChar->HasUnitState(UNIT_STATE_LOGOUT_TIMER)) + { + pCurrChar->SetRooted(false, true, true); pCurrChar->RemoveUnitFlag(UNIT_FLAG_STUNNED); + } + + if (pCurrChar->GetPendingFlightChange() <= pCurrChar->GetMapChangeOrderCounter()) + { + if (!pCurrChar->HasIncreaseMountedFlightSpeedAura() && !pCurrChar->HasFlyAura()) + pCurrChar->m_movementInfo.RemoveMovementFlag(MOVEMENTFLAG_CAN_FLY); + } pCurrChar->SendInitialPacketsBeforeAddToMap(); // necessary actions from AddPlayerToMap: pCurrChar->GetMap()->SendInitTransports(pCurrChar); pCurrChar->GetMap()->SendInitSelf(pCurrChar); - pCurrChar->GetMap()->SendZoneDynamicInfo(pCurrChar); // If we are logging into an existing player, simply clear visibility references // so player will receive a fresh list of new objects on the next vis update. @@ -1762,9 +1762,21 @@ void WorldSession::HandleEquipmentSetSave(WorldPacket& recvData) std::string name; recvData >> name; + if (name.length() > 16) // Client limitation + { + LOG_ERROR("entities.player.cheat", "Character GUID {} tried to create equipment set {} with too long a name!", _player->GetGUID().ToString(), setGuid); + return; + } + std::string iconName; recvData >> iconName; + if (iconName.length() > 100) // DB limitation + { + LOG_ERROR("entities.player.cheat", "Character GUID {} tried to create equipment set {} with too long an icon name!", _player->GetGUID().ToString(), setGuid); + return; + } + EquipmentSet eqSet; eqSet.Guid = setGuid; @@ -2576,6 +2588,13 @@ void WorldSession::SendCharDelete(ResponseCodes result) 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) { WorldPacket data(SMSG_CHAR_RENAME, 1 + 8 + renameInfo->Name.size() + 1); |
