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 <noreply@anthropic.com>
This commit is contained in:
BlaMacfly
2026-09-01 08:08:00 +02:00
parent 5c4c4b6d7a
commit ac40810f25
3 changed files with 73 additions and 25 deletions
+15 -10
View File
@@ -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
+22 -13
View File
@@ -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)
@@ -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;