diff --git a/src/server/game/AI/PlayerAI/BotFieldAI/BotFieldAI.cpp b/src/server/game/AI/PlayerAI/BotFieldAI/BotFieldAI.cpp index 22d5366..68f02e6 100644 --- a/src/server/game/AI/PlayerAI/BotFieldAI/BotFieldAI.cpp +++ b/src/server/game/AI/PlayerAI/BotFieldAI/BotFieldAI.cpp @@ -16,6 +16,7 @@ */ #include "BotFieldAI.h" +#include "Config.h" #include "MoveSplineInit.h" #include "BotBGAIMovement.h" #include "PlayerBotMgr.h" @@ -269,8 +270,12 @@ bool BotFieldAI::ProcessGroupInvite() return false; if (me->IsInWorld() && me->GetMap()->IsDungeon()) { - BotUtility::TryTeleportHome(this); - return true; + // pbotqa=1 : harnais QA, autorise les bots field a rester en instance + if (!sConfigMgr->GetIntDefault("pbotqa", 0)) + { + BotUtility::TryTeleportHome(this); + return true; + } } Group* pGroup = me->GetGroupInvite(); if (!pGroup) diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index e728b01..4764fac 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -870,14 +870,19 @@ void WorldSession::HandleContinuePlayerLogin() std::shared_ptr holder = std::make_shared(GetAccountId(), m_playerLoading); if (!holder->Initialize()) { + TC_LOG_ERROR("server.worldserver", "QA-BOTLOG2: holder Initialize KO compte %u", GetAccountId()); // QA-BOTLOG2 m_playerLoading.Clear(); return; } + if (IsBotSession()) + TC_LOG_ERROR("server.worldserver", "QA-BOTLOG2: holder pose compte %u", GetAccountId()); SendPacket(WorldPackets::Auth::ResumeComms(CONNECTION_TYPE_INSTANCE).Write()); AddQueryHolderCallback(CharacterDatabase.DelayQueryHolder(holder)).AfterComplete([this](SQLQueryHolderBase const& holder) { + if (IsBotSession()) + TC_LOG_ERROR("server.worldserver", "QA-BOTLOG2: callback holder compte %u", GetAccountId()); HandlePlayerLogin(dynamic_cast(holder)); }); } @@ -910,6 +915,7 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder const& holder) // "GetAccountId() == db stored account id" checked in LoadFromDB (prevent login not own character using cheating tools) if (!pCurrChar->LoadFromDB(playerGuid, holder)) { + TC_LOG_ERROR("server.worldserver", "QA-BOTLOG3: LoadFromDB KO pour %s compte %u", playerGuid.ToString().c_str(), GetAccountId()); // QA-BOTLOG3 SetPlayer(NULL); KickPlayer(); // disconnect client, player no set to session and it will not deleted or saved at kick delete pCurrChar; // delete it manually diff --git a/src/server/game/PlayerBot/PlayerBotMgr.cpp b/src/server/game/PlayerBot/PlayerBotMgr.cpp index 886110f..9736893 100644 --- a/src/server/game/PlayerBot/PlayerBotMgr.cpp +++ b/src/server/game/PlayerBot/PlayerBotMgr.cpp @@ -1722,9 +1722,15 @@ bool PlayerBotMgr::LoginBotByAccountIndex(uint32 account, uint32 index) #ifndef INCOMPLETE_BOT PlayerBotBaseInfo* botInfo = GetPlayerBotAccountInfo(account); if (!botInfo) + { + TC_LOG_ERROR("server.worldserver", "QA-BOTLOG: pas de botInfo pour compte %u", account); // QA-BOTLOG return false; + } if (index >= botInfo->characters.size()) + { + TC_LOG_ERROR("server.worldserver", "QA-BOTLOG: compte %u index %u >= %u persos", account, index, (uint32)botInfo->characters.size()); return false; + } for (auto itChar = botInfo->characters.begin(); itChar != botInfo->characters.end(); itChar++) @@ -1738,7 +1744,15 @@ bool PlayerBotMgr::LoginBotByAccountIndex(uint32 account, uint32 index) WorldSession* pWorldSession = sWorld->FindSession(account); PlayerBotSession* pSession = dynamic_cast(pWorldSession); if (!pSession || pSession->PlayerLoading() || pSession->HasSchedules() || pSession->GetPlayer()) + { + TC_LOG_ERROR("server.worldserver", "QA-BOTLOG: compte %u session=%d cast=%d loading=%d schedules=%d player=%d", + account, pWorldSession ? 1 : 0, pSession ? 1 : 0, + pSession ? (int)pSession->PlayerLoading() : -1, + pSession ? (int)pSession->HasSchedules() : -1, + (pSession && pSession->GetPlayer()) ? 1 : 0); return false; + } + TC_LOG_ERROR("server.worldserver", "QA-BOTLOG: schedule Online_GUID pousse pour guid %u", (uint32)charInfo.guid); BotGlobleSchedule schedule1(BotGlobleScheduleType::BGSType_Online_GUID, charInfo.guid); pSession->PushScheduleToQueue(schedule1); return true; diff --git a/src/server/game/Server/PlayerBotSession.cpp b/src/server/game/Server/PlayerBotSession.cpp index 4ea0435..2e906d7 100644 --- a/src/server/game/Server/PlayerBotSession.cpp +++ b/src/server/game/Server/PlayerBotSession.cpp @@ -163,6 +163,15 @@ void PlayerBotSession::ProcessNoWorld(uint32 diff) if (!player) return; + // Un client reel confirme le changement de monde par MSG_MOVE_WORLDPORT_ACK ; + // sans cette simulation, un bot en jeu vise par .tele reste bloque sur le semaphore. + if (player->IsBeingTeleportedFar()) + { + HandleMoveWorldportAck(); + m_NoWorldTick = 500; + return; + } + if (player->IsInWorld()) { m_NoWorldTick = 0; @@ -226,6 +235,7 @@ void PlayerBotSession::CastSchedule(uint32 diff) break; case BGSType_Online_GUID: result = ProcessOnlineByGUID(schedule); + TC_LOG_ERROR("server.worldserver", "QA-BOTLOG: ProcessOnlineByGUID resultat=%d", (int)result); // QA-BOTLOG break; case BGSType_Offline: result = ProcessOffline(schedule); diff --git a/src/server/scripts/BrokenIsles/Scenario/scenario_artifact_runner.cpp b/src/server/scripts/BrokenIsles/Scenario/scenario_artifact_runner.cpp index 6802c9c..7dbc1e4 100644 --- a/src/server/scripts/BrokenIsles/Scenario/scenario_artifact_runner.cpp +++ b/src/server/scripts/BrokenIsles/Scenario/scenario_artifact_runner.cpp @@ -99,6 +99,7 @@ struct scenario_artifact_runner : public InstanceScript { SetBossNumber(12); config = ArtifactRunner::GetConfig(instance->GetId()); + TC_LOG_ERROR("server.worldserver", "QA-RUNLOG: Initialize map %u config=%d", instance->GetId(), config ? 1 : 0); // QA-RUNLOG stage = 0; aliveCount = 0; introDone = false; @@ -109,6 +110,7 @@ struct scenario_artifact_runner : public InstanceScript InstanceScript::OnPlayerEnter(player); PhasingHandler::AddPhase(player, 169, true); + TC_LOG_ERROR("server.worldserver", "QA-RUNLOG: OnPlayerEnter map %u introDone=%d config=%d", instance->GetId(), (int)introDone, config ? 1 : 0); if (!introDone && config) { introDone = true; @@ -144,6 +146,7 @@ struct scenario_artifact_runner : public InstanceScript return; } + TC_LOG_ERROR("server.worldserver", "QA-RUNLOG: StartStage %u map %u", (uint32)newStage, instance->GetId()); stage = newStage; aliveCount = 0; stageEntries.clear(); @@ -162,11 +165,21 @@ struct scenario_artifact_runner : public InstanceScript } for (uint8 i = 0; i < s.count; ++i) { - float dx = (i % 3) * 6.0f - 6.0f; - float dy = (i / 3) * 6.0f - 3.0f; - Position pos = { s.x + dx + 12.0f, s.y + dy + 8.0f, s.z, s.o }; - if (TempSummon* summon = instance->SummonCreature(s.entry, pos)) + float dx = (i % 3) * 4.0f - 4.0f; + float dy = (i / 3) * 4.0f - 2.0f; + Position pos = { s.x + dx + 6.0f, s.y + dy + 4.0f, s.z, s.o }; + // cale le Z au sol : les ancres sont sures mais les offsets peuvent sortir des plateformes + float gz = instance->GetHeight(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ() + 8.0f, true, 60.0f); + if (gz > INVALID_HEIGHT && std::abs(gz - s.z) < 25.0f) + pos.m_positionZ = gz + 0.5f; + else + pos.Relocate(s.x, s.y, s.z); // repli : pile sur l ancre officielle + TempSummon* summon = instance->SummonCreature(s.entry, pos); + if (!summon) + TC_LOG_ERROR("server.worldserver", "QA-RUNLOG: summon KO entry %u map %u", s.entry, instance->GetId()); + if (summon) { + TC_LOG_ERROR("server.worldserver", "QA-RUNLOG: summon POS entry %u (%.1f, %.1f, %.1f)", s.entry, summon->GetPositionX(), summon->GetPositionY(), summon->GetPositionZ()); if (s.level) { summon->SetLevel(s.level);