Butin de groupe : une devise dans le butin d un boss tuait le worldserver

Signalement Discord : entrer dans la Prison violette fait planter le serveur.
Trois SIGSEGV cette nuit, pile identique : ASSERT_NOTNULL sur GetItemTemplate
dans Group::GroupLoot, appele depuis HandleLootOpcode.

Dans les tables de butin de ce core, un Item negatif designe une devise
(LootMgr.cpp:151). Loot::AddItem les range dans le meme tableau que les objets
mais sans modele d objet. Group::GroupLoot parcourait ce tableau et exigeait un
modele pour chaque entree : la premiere devise rencontree tuait le processus.
24 creatures sont concernees, dont cinq boss de l Assaut sur la Prison violette
(Blood-Princess Thal ena, Sael orn, Lord Malgath, Festerface, Taldath).

Les devises sont desormais ignorees par le tirage au sort, et un objet
introuvable est journalise puis saute au lieu de faire tomber le serveur.
This commit is contained in:
BlaMacfly
2026-09-12 01:02:48 +02:00
parent 01046fd22a
commit 5f430f0510
+20 -1
View File
@@ -1172,7 +1172,20 @@ void Group::GroupLoot(Loot* loot, WorldObject* lootedObject)
if (i->freeforall)
continue;
item = ASSERT_NOTNULL(sObjectMgr->GetItemTemplate(i->itemid));
// Les devises (Item negatif dans les tables de butin) occupent le meme tableau
// que les objets mais n'ont pas de modele d'objet. Les laisser arriver jusqu'a
// l'ASSERT tuait le worldserver des qu'un groupe ouvrait le butin d'un boss qui
// en lache -- ceux de la Prison violette, entre autres.
if (i->type != LOOT_ITEM_TYPE_ITEM)
continue;
item = sObjectMgr->GetItemTemplate(i->itemid);
if (!item)
{
TC_LOG_ERROR("sql.sql", "Group::GroupLoot: objet %u introuvable dans les donnees, ignore dans le butin de %s",
i->itemid, lootedObject->GetGUID().ToString().c_str());
continue;
}
//roll for over-threshold item if it's one-player loot
if (item->GetQuality() >= uint32(m_lootThreshold))
@@ -1247,7 +1260,13 @@ void Group::GroupLoot(Loot* loot, WorldObject* lootedObject)
if (!i->follow_loot_rules)
continue;
if (i->type != LOOT_ITEM_TYPE_ITEM)
continue;
item = sObjectMgr->GetItemTemplate(i->itemid);
if (!item)
continue;
Roll* r = new Roll(*i);
for (GroupReference* itr = GetFirstMember(); itr != NULL; itr = itr->next())