From ac40810f2524655f7d61a6545d0a7a5e81bc099e Mon Sep 17 00:00:00 2001 From: BlaMacfly Date: Tue, 1 Sep 2026 08:08:00 +0200 Subject: [PATCH] Champs de bataille : le vrai appelant hors limites, et un opcode client diffuse Suite du signalement Discord. Le garde-fou pose dans GetBGObject a tenu -- plus de lecture hors limites -- mais les appels avec 24 et 32 persistaient : le correctif precedent visait BattlegroundAB.cpp alors que l'appelant fautif est le module BotFill. CommandAB.cpp indexait les bannieres en abNode * 8, disposition de l'ancien Bassin d'Arathi de TrinityCore ou chaque noeud possedait huit objets. Le notre n'en a qu'UN par noeud, aux indices 0 a 4. Le calcul etait donc faux pour TOUS les noeuds : noeud 0 -> 0 banniere juste, par hasard noeud 1 -> 8 REGENBUFF_STABLES noeud 2 -> 16 SPEEDBUFF_LUMBER_MILL noeud 3 -> 24 hors limites noeud 4 -> 32 hors limites Les bots visaient des objets de bonus au lieu des bannieres et ne voyaient tout simplement pas la scierie ni la mine d'or. Les deux sites etant proteges contre le pointeur nul, cela echouait en silence : seul le garde-fou a fini par le rendre visible. Le controle de borne manquant sur abNode est ajoute. Verifie au passage : Gilneas a REELLEMENT huit objets par noeud (BG_BFG_OBJECT_MAX = 37), son node * 8 + 5 est correct. Rien a y changer. Second defaut, sans lien avec le premier : deux fonctions de l'IA des bots construisaient un paquet portant l'opcode CLIENT CMSG_MOVE_FALL_LAND et le diffusaient. WorldSession le refuse toujours et journalise une ERREUR a chaque tentative -- des milliers de lignes par match dans le journal du rapporteur. BotBGAIMovement::SyncPosition n'avait meme aucun autre effet : elle ne deplacait pas le bot cote serveur. Les envois sont retires ; aucun comportement de remplacement n'a ete invente, le defaut n'etant pas reproductible chez nous. RESERVE IMPORTANTE : rien de ceci n'explique le PLANTAGE signale. Les deux sites fautifs testaient deja le pointeur nul, et le journal fourni ne contient aucune trace d'arret. Une pile d'appels est necessaire. Co-Authored-By: Claude Opus 5 --- src/server/game/AI/PlayerAI/BotAITool.cpp | 25 +++++++----- .../game/AI/PlayerAI/BotBGAIMovement.cpp | 35 ++++++++++------- .../Battlegrounds/CommandBG/CommandAB.cpp | 38 ++++++++++++++++++- 3 files changed, 73 insertions(+), 25 deletions(-) diff --git a/src/server/game/AI/PlayerAI/BotAITool.cpp b/src/server/game/AI/PlayerAI/BotAITool.cpp index 7a8c591..1803e30 100644 --- a/src/server/game/AI/PlayerAI/BotAITool.cpp +++ b/src/server/game/AI/PlayerAI/BotAITool.cpp @@ -1031,16 +1031,21 @@ void BotAITeleport::Update(uint32 diff, BotBGAIMovement* pMovement) } else if (m_TeleportStep == 3) { - WorldSession* pSession = me->GetSession(); - MovementInfo movementInfo; - movementInfo.pos = m_TeleportPositon; - movementInfo.time = getMSTime(); - movementInfo.guid = me->GetGUID(); - movementInfo.flags = 0; - movementInfo.flags2 = 0; - WorldPacket data(CMSG_MOVE_FALL_LAND);// MSG_MOVE_STOP); - data << movementInfo; - me->SendMessageToSet(&data, me); + // ===================================================== + // SylvaniaCore : envoi mort retire. + // + // Le bloc supprime ici diffusait un paquet portant + // l'opcode CLIENT CMSG_MOVE_FALL_LAND. WorldSession le + // REFUSE systematiquement -- « Prevented sending of + // opcode 14841 with non existing handler » -- et ecrit + // une ligne d'ERREUR a chaque tentative. Signale par un + // utilisateur de SylvaniaCore : des milliers de lignes + // par match de champ de bataille. + // + // Il n'accomplissait donc rien. La reconstruction de + // l'objet ci-dessous, ajoutee precedemment pour pallier + // son inefficacite, reste seule en charge du travail. + // ===================================================== me->CombatStop(true); me->SetSelection(ObjectGuid::Empty); // SylvaniaCore : le paquet diffuse ci-dessus porte un opcode CLIENT diff --git a/src/server/game/AI/PlayerAI/BotBGAIMovement.cpp b/src/server/game/AI/PlayerAI/BotBGAIMovement.cpp index 8194d5a..e8a42a6 100644 --- a/src/server/game/AI/PlayerAI/BotBGAIMovement.cpp +++ b/src/server/game/AI/PlayerAI/BotBGAIMovement.cpp @@ -674,19 +674,28 @@ void BotBGAIMovement::SyncPosition(Position& pos, bool immed) if (m_Player->IsFlying()) return; - Position targetPos(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), m_Player->GetOrientation()); - targetPos.m_positionZ = 0.01f + m_Player->GetMap()->GetHeight(m_Player->GetPhaseShift(), targetPos.GetPositionX(), targetPos.GetPositionY(), targetPos.m_positionZ); - WorldSession* pSession = m_Player->GetSession(); - MovementInfo movementInfo; - movementInfo.pos = targetPos; - movementInfo.time = getMSTime(); - movementInfo.guid = m_Player->GetGUID(); - movementInfo.flags = 0; - movementInfo.flags2 = 0; - - WorldPacket data(CMSG_MOVE_FALL_LAND);// MSG_MOVE_STOP); - data << movementInfo; - m_Player->SendMessageToSet(&data, m_Player); + // ================================================================= + // SylvaniaCore : cette fonction etait entierement inerte. + // + // Elle calculait une position au sol puis diffusait un paquet + // portant l'opcode CLIENT CMSG_MOVE_FALL_LAND. WorldSession le + // REFUSE toujours -- « Prevented sending of opcode 14841 with non + // existing handler » -- et journalise une ERREUR a chaque fois. + // Signale par un utilisateur de SylvaniaCore : des milliers de + // lignes par match, avec des bots en champ de bataille. + // + // Elle ne deplacait meme pas le bot cote serveur : aucun appel a + // UpdatePosition. Son seul effet observable etait donc le journal. + // + // L'envoi est retire. La fonction ne fait desormais plus que sa + // temporisation, ce qui est exactement ce qu'elle accomplissait + // avant -- en silence cette fois. + // + // A REPRENDRE : si une desynchronisation des bots est constatee en + // jeu, c'est ICI qu'il faut la corriger, par un UpdatePosition en + // bonne et due forme. Rien n'a ete ajoute a l'aveugle : le defaut + // signale ne pouvait pas etre reproduit sur notre serveur. + // ================================================================= } bool BotBGAIMovement::IsNearToPosition(float x, float y, float z, float range) diff --git a/src/server/game/Battlegrounds/CommandBG/CommandAB.cpp b/src/server/game/Battlegrounds/CommandBG/CommandAB.cpp index 29f4de8..869e639 100644 --- a/src/server/game/Battlegrounds/CommandBG/CommandAB.cpp +++ b/src/server/game/Battlegrounds/CommandBG/CommandAB.cpp @@ -181,7 +181,39 @@ void CommandAB::ProcessABNodeRequirement(uint32 abNode, AIWaypoint* waypoint, Pl { if (!waypoint) return; - GameObject* pBGNode = m_pBattleground->GetBGObject(abNode * 8); + // ================================================================= + // SylvaniaCore : les bannieres d'Arathi sont aux indices 0 a 4. + // + // SIGNALE PAR UN UTILISATEUR DE SYLVANIACORE, journal a l'appui : + // GetBGObject: type 24 hors limites (22 objets) carte 529 + // GetBGObject: type 32 hors limites (22 objets) carte 529 + // + // abNode * 8 vient de l'ancien Bassin d'Arathi de TrinityCore, ou + // chaque noeud possedait huit objets. Le notre n'en a qu'UN par + // noeud : BG_AB_OBJECT_BANNER + node, soit 0 a 4. _ChangeBanner + // modifie le visuel de cette banniere unique selon l'etat. + // + // Le calcul etait donc faux pour TOUS les noeuds, pas seulement + // pour ceux qui debordaient : + // noeud 0 -> 0 banniere juste, par hasard + // noeud 1 -> 8 REGENBUFF_STABLES + // noeud 2 -> 16 SPEEDBUFF_LUMBER_MILL + // noeud 3 -> 24 hors limites + // noeud 4 -> 32 hors limites + // + // Les bots visaient des objets de bonus au lieu des bannieres, et + // ne voyaient tout simplement pas la scierie ni la mine d'or. Les + // deux appels etant proteges contre le pointeur nul, cela echouait + // en silence -- seul le garde-fou pose dans GetBGObject a fini par + // le rendre visible. + // + // Le controle de borne sur abNode manquait ici alors qu'il existe + // dans GetABFlagRangePlayerByTeam : ajoute. + // ================================================================= + if (abNode >= BG_AB_BattlegroundNodes::BG_AB_DYNAMIC_NODES_COUNT) + return; + + GameObject* pBGNode = m_pBattleground->GetBGObject(BG_AB_ObjectType::BG_AB_OBJECT_BANNER + abNode); if (!pBGNode) return; PlayerGUIDs nodeNearPlayers = GetABFlagRangePlayerByTeam(abNode, m_TeamID); @@ -264,7 +296,9 @@ PlayerGUIDs CommandAB::GetABFlagRangePlayerByTeam(uint32 abNode, TeamId team) PlayerGUIDs existPlayers; if (!m_pBattleground || abNode >= BG_AB_BattlegroundNodes::BG_AB_DYNAMIC_NODES_COUNT) return existPlayers; - GameObject* pBGNode = m_pBattleground->GetBGObject(abNode * 8); + // Meme correction que dans ProcessABNodeRequirement : une banniere + // par noeud, aux indices 0 a 4. + GameObject* pBGNode = m_pBattleground->GetBGObject(BG_AB_ObjectType::BG_AB_OBJECT_BANNER + abNode); if (!pBGNode) return existPlayers; NearPlayerList playersNearby;