From df44e90fe6cb4abcaeae442beea7ecb42a2c97d1 Mon Sep 17 00:00:00 2001 From: Shauren Date: Wed, 15 Apr 2020 21:46:28 +0200 Subject: [PATCH] Core/Misc: Fixed char enum packet sometimes not showing newly created character when client latency is too low --- src/server/game/Handlers/CharacterHandler.cpp | 37 +++++++++++-------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index ee2da03a323..fcfc14a2d87 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -600,25 +600,26 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData) return; } - Player newChar(this); - newChar.GetMotionMaster()->Initialize(); - if (!newChar.Create(sObjectMgr->GetGenerator().Generate(), createInfo.get())) - + std::shared_ptr newChar(new Player(this), [](Player* ptr) + { + ptr->CleanupsBeforeDelete(); + delete ptr; + }); + newChar->GetMotionMaster()->Initialize(); + if (!newChar->Create(sObjectMgr->GetGenerator().Generate(), createInfo.get())) { // Player not create (race/class/etc problem?) - newChar.CleanupsBeforeDelete(); - SendCharCreate(CHAR_CREATE_ERROR); return; } if ((haveSameRace && skipCinematics == 1) || skipCinematics == 2) - newChar.setCinematic(1); // not show intro + newChar->setCinematic(1); // not show intro - newChar.SetAtLoginFlag(AT_LOGIN_FIRST); // First login + newChar->SetAtLoginFlag(AT_LOGIN_FIRST); // First login // Player created, save it now - newChar.SaveToDB(true); + newChar->SaveToDB(true); createInfo->CharCount += 1; LoginDatabaseTransaction trans = LoginDatabase.BeginTransaction(); @@ -636,13 +637,19 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData) LoginDatabase.CommitTransaction(trans); - SendCharCreate(CHAR_CREATE_SUCCESS); + AddTransactionCallback(LoginDatabase.AsyncCommitTransaction(trans)).AfterComplete([this, newChar = std::move(newChar)](bool success) + { + if (success) + { + TC_LOG_INFO("entities.player.character", "Account: %d (IP: %s) Create Character:[%s] (GUID: %u)", GetAccountId(), GetRemoteAddress().c_str(), newChar->GetName().c_str(), newChar->GetGUID().GetCounter()); + sScriptMgr->OnPlayerCreate(newChar.get()); + sCharacterCache->AddCharacterCacheEntry(newChar->GetGUID(), GetAccountId(), newChar->GetName(), newChar->GetByteValue(PLAYER_BYTES_3, PLAYER_BYTES_3_OFFSET_GENDER), newChar->getRace(), newChar->getClass(), newChar->getLevel()); - TC_LOG_INFO("entities.player.character", "Account: %d (IP: %s) Create Character:[%s] (GUID: %u)", GetAccountId(), GetRemoteAddress().c_str(), createInfo->Name.c_str(), newChar.GetGUID().GetCounter()); - sScriptMgr->OnPlayerCreate(&newChar); - sCharacterCache->AddCharacterCacheEntry(newChar.GetGUID(), GetAccountId(), newChar.GetName(), newChar.GetByteValue(PLAYER_BYTES_3, PLAYER_BYTES_3_OFFSET_GENDER), newChar.getRace(), newChar.getClass(), newChar.getLevel()); - - newChar.CleanupsBeforeDelete(); + SendCharCreate(CHAR_CREATE_SUCCESS); + } + else + SendCharCreate(CHAR_CREATE_ERROR); + }); }; if (allowTwoSideAccounts && !skipCinematics && createInfo->Class != CLASS_DEATH_KNIGHT)