From 5f430f0510b00efd6cd88c60ea887a385769786d Mon Sep 17 00:00:00 2001 From: BlaMacfly <165155133+BlaMacfly@users.noreply.github.com> Date: Sat, 12 Sep 2026 01:02:48 +0200 Subject: [PATCH] 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. --- src/server/game/Groups/Group.cpp | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp index e32ccea..11ac833 100644 --- a/src/server/game/Groups/Group.cpp +++ b/src/server/game/Groups/Group.cpp @@ -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())