[7995] Check display id correctness for creature and gameobjects. Author: VladimirMangos

--HG--
branch : trunk
This commit is contained in:
megamage
2009-06-13 09:40:44 -05:00
parent ee9c12b480
commit 67a356767d
9 changed files with 82 additions and 56 deletions

View File

@@ -92,20 +92,20 @@ uint32 CreatureInfo::GetRandomValidModelId() const
uint32 c = 0;
uint32 modelIDs[4];
if (Modelid_A1) modelIDs[c++] = Modelid_A1;
if (Modelid_A2) modelIDs[c++] = Modelid_A2;
if (Modelid_H1) modelIDs[c++] = Modelid_H1;
if (Modelid_H2) modelIDs[c++] = Modelid_H2;
if (DisplayID_A) modelIDs[c++] = DisplayID_A;
if (DisplayID_A2) modelIDs[c++] = DisplayID_A2;
if (DisplayID_H) modelIDs[c++] = DisplayID_H;
if (DisplayID_H2) modelIDs[c++] = DisplayID_H2;
return ((c>0) ? modelIDs[urand(0,c-1)] : 0);
}
uint32 CreatureInfo::GetFirstValidModelId() const
{
if(Modelid_A1) return Modelid_A1;
if(Modelid_A2) return Modelid_A2;
if(Modelid_H1) return Modelid_H1;
if(Modelid_H2) return Modelid_H2;
if(DisplayID_A) return DisplayID_A;
if(DisplayID_A2) return DisplayID_A2;
if(DisplayID_H) return DisplayID_H;
if(DisplayID_H2) return DisplayID_H2;
return 0;
}
@@ -1272,8 +1272,8 @@ void Creature::SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask)
CreatureInfo const *cinfo = GetCreatureInfo();
if(cinfo)
{
if(displayId == cinfo->Modelid_A1 || displayId == cinfo->Modelid_A2 ||
displayId == cinfo->Modelid_H1 || displayId == cinfo->Modelid_H2) displayId = 0;
if(displayId == cinfo->DisplayID_A || displayId == cinfo->DisplayID_A2 ||
displayId == cinfo->DisplayID_H || displayId == cinfo->DisplayID_H2) displayId = 0;
}
// data->guid = guid don't must be update at save

View File

@@ -179,10 +179,10 @@ struct CreatureInfo
uint32 HeroicEntry;
uint32 unk1;
uint32 unk2;
uint32 Modelid_A1;
uint32 Modelid_A2;
uint32 Modelid_H1;
uint32 Modelid_H2;
uint32 DisplayID_A;
uint32 DisplayID_A2;
uint32 DisplayID_H;
uint32 DisplayID_H2;
char* Name;
char* SubName;
char* IconName;

View File

@@ -386,8 +386,8 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32
if (CreatureInfo const* ci = GetCreatureTemplateStore(action.morph.creatureId))
{
//use default display
if (ci->Modelid_A1)
m_creature->SetDisplayId(ci->Modelid_A1);
if (ci->DisplayID_A)
m_creature->SetDisplayId(ci->DisplayID_A);
}
}
//if no param1, then use value from param2 (modelId)

View File

@@ -69,7 +69,6 @@ DBCStorage <FactionEntry> sFactionStore(FactionEntryfmt);
DBCStorage <FactionTemplateEntry> sFactionTemplateStore(FactionTemplateEntryfmt);
DBCStorage <GameObjectDisplayInfoEntry> sGameObjectDisplayInfoStore(GameObjectDisplayInfofmt);
DBCStorage <GemPropertiesEntry> sGemPropertiesStore(GemPropertiesEntryfmt);
DBCStorage <GlyphPropertiesEntry> sGlyphPropertiesStore(GlyphPropertiesfmt);
DBCStorage <GlyphSlotEntry> sGlyphSlotStore(GlyphSlotfmt);

View File

@@ -861,8 +861,8 @@ struct FactionTemplateEntry
struct GameObjectDisplayInfoEntry
{
uint32 ID; //0
//char* mdx; //1
uint32 Displayid; // 0 m_ID
// char* filename; // 1
//uint32 unk1[10]; //2-11
float minX;
float minY;

View File

@@ -540,15 +540,15 @@ void Object::_BuildValuesUpdate(uint8 updatetype, ByteBuffer * data, UpdateMask
{
if(target->isGameMaster())
{
if(cinfo->Modelid_A1)
*data << cinfo->Modelid_A1;
if(cinfo->DisplayID_A)
*data << cinfo->DisplayID_A;
else
*data << 17519; // world invisible trigger's model
}
else
{
if(cinfo->Modelid_A2)
*data << cinfo->Modelid_A2;
if(cinfo->DisplayID_A2)
*data << cinfo->DisplayID_A2;
else
*data << 11686; // world invisible trigger's model
}

View File

@@ -614,28 +614,41 @@ void ObjectMgr::LoadCreatureTemplates()
if(!factionTemplate)
sLog.outErrorDb("Creature (Entry: %u) has non-existing faction_H template (%u)", cInfo->Entry, cInfo->faction_H);
// check model ids, supplying and sending non-existent ids to the client might crash them
if(cInfo->Modelid_A1 && !sCreatureModelStorage.LookupEntry<CreatureModelInfo>(cInfo->Modelid_A1))
// used later for scale
CreatureDisplayInfoEntry const* displayEntryA = cInfo->DisplayID_A ? sCreatureDisplayInfoStore.LookupEntry(cInfo->DisplayID_A) : NULL;
if(cInfo->DisplayID_A && !displayEntryA)
sLog.outErrorDb("Creature (Entry: %u) has non-existing DisplayID_A id (%u), can crash client", cInfo->Entry, cInfo->DisplayID_A);
if(cInfo->DisplayID_A2)
{
sLog.outErrorDb("Creature (Entry: %u) has non-existing Modelid_A1 (%u), setting it to 0", cInfo->Entry, cInfo->Modelid_A1);
const_cast<CreatureInfo*>(cInfo)->Modelid_A1 = 0;
if(CreatureDisplayInfoEntry const* displayEntry = sCreatureDisplayInfoStore.LookupEntry(cInfo->DisplayID_A2))
{
sLog.outErrorDb("Creature (Entry: %u) has non-existing DisplayID_A2 id (%u), can crash client", cInfo->Entry, cInfo->DisplayID_A2);
const_cast<CreatureInfo*>(cInfo)->DisplayID_A2 = 0;
}
}
if(cInfo->Modelid_A2 && !sCreatureModelStorage.LookupEntry<CreatureModelInfo>(cInfo->Modelid_A2))
// used later for scale
CreatureDisplayInfoEntry const* displayEntryH = cInfo->DisplayID_H ? sCreatureDisplayInfoStore.LookupEntry(cInfo->DisplayID_H) : NULL;
if(cInfo->DisplayID_H && !displayEntryH)
sLog.outErrorDb("Creature (Entry: %u) has non-existing DisplayID_H id (%u), can crash client", cInfo->Entry, cInfo->DisplayID_H);
if(cInfo->DisplayID_H2)
{
sLog.outErrorDb("Creature (Entry: %u) has non-existing Modelid_A2 (%u), setting it to 0", cInfo->Entry, cInfo->Modelid_A2);
const_cast<CreatureInfo*>(cInfo)->Modelid_A2 = 0;
}
if(cInfo->Modelid_H1 && !sCreatureModelStorage.LookupEntry<CreatureModelInfo>(cInfo->Modelid_H1))
{
sLog.outErrorDb("Creature (Entry: %u) has non-existing Modelid_H1 (%u), setting it to 0", cInfo->Entry, cInfo->Modelid_H1);
const_cast<CreatureInfo*>(cInfo)->Modelid_H1 = 0;
}
if(cInfo->Modelid_H2 && !sCreatureModelStorage.LookupEntry<CreatureModelInfo>(cInfo->Modelid_H2))
{
sLog.outErrorDb("Creature (Entry: %u) has non-existing Modelid_H2 (%u), setting it to 0", cInfo->Entry, cInfo->Modelid_H2);
const_cast<CreatureInfo*>(cInfo)->Modelid_H2 = 0;
if(CreatureDisplayInfoEntry const* displayEntry = sCreatureDisplayInfoStore.LookupEntry(cInfo->DisplayID_H2))
{
sLog.outErrorDb("Creature (Entry: %u) has non-existing DisplayID_H2 id (%u), can crash client", cInfo->Entry, cInfo->DisplayID_H2);
const_cast<CreatureInfo*>(cInfo)->DisplayID_H2 = 0;
}
}
CreatureModelInfo const* minfo = sCreatureModelStorage.LookupEntry<CreatureModelInfo>(cInfo->DisplayID_A);
if (!minfo)
sLog.outErrorDb("Creature (Entry: %u) has non-existing modelId_A (%u)", cInfo->Entry, cInfo->DisplayID_A);
minfo = sCreatureModelStorage.LookupEntry<CreatureModelInfo>(cInfo->DisplayID_H);
if (!minfo)
sLog.outErrorDb("Creature (Entry: %u) has non-existing modelId_H (%u)", cInfo->Entry, cInfo->DisplayID_H);
if (cInfo->unit_class && ((1 << (cInfo->unit_class-1)) & CLASSMASK_ALL_CREATURES) == 0)
sLog.outErrorDb("Creature (Entry: %u) has invalid unit_class(%u) for creature_template", cInfo->Entry, cInfo->unit_class);
@@ -806,7 +819,10 @@ void ObjectMgr::LoadCreatureAddons()
if (addon->mount)
{
if (!sCreatureDisplayInfoStore.LookupEntry(addon->mount))
{
sLog.outErrorDb("Creature (Entry %u) have invalid displayInfoId for mount (%u) defined in `creature_template_addon`.",addon->guidOrEntry, addon->mount);
const_cast<CreatureDataAddon*>(addon)->mount = 0;
}
}
if (!sEmotesStore.LookupEntry(addon->emote))
@@ -833,7 +849,10 @@ void ObjectMgr::LoadCreatureAddons()
if (addon->mount)
{
if (!sCreatureDisplayInfoStore.LookupEntry(addon->mount))
{
sLog.outErrorDb("Creature (GUID %u) have invalid displayInfoId for mount (%u) defined in `creature_addon`.",addon->guidOrEntry, addon->mount);
const_cast<CreatureDataAddon*>(addon)->mount = 0;
}
}
if (!sEmotesStore.LookupEntry(addon->emote))
@@ -1130,8 +1149,8 @@ void ObjectMgr::LoadCreatures()
{
(const_cast<CreatureInfo*>(cInfo))->flags_extra |= CREATURE_FLAG_EXTRA_TRIGGER;
}
else if(data.displayid == cInfo->Modelid_A1 || data.displayid == cInfo->Modelid_A2
|| data.displayid == cInfo->Modelid_H1 || data.displayid == cInfo->Modelid_H2)
else if(data.displayid == cInfo->DisplayID_A || data.displayid == cInfo->DisplayID_A2
|| data.displayid == cInfo->DisplayID_H || data.displayid == cInfo->DisplayID_H2)
data.displayid = 0;
*/
@@ -1387,6 +1406,12 @@ void ObjectMgr::LoadGameobjects()
continue;
}
if(gInfo->displayId && !sGameObjectDisplayInfoStore.LookupEntry(gInfo->displayId))
{
sLog.outErrorDb("Gameobject (GUID: %u Entry %u GoType: %u) have invalid displayId (%u), not loaded.",guid, entry, gInfo->type, gInfo->displayId);
continue;
}
GameObjectData& data = mGameObjectDataMap[guid];
data.id = entry;
@@ -5077,7 +5102,7 @@ uint16 ObjectMgr::GetTaxiMount( uint32 id, uint32 team, bool allowed_alt_team /*
CreatureInfo const *ci = GetCreatureTemplate(mount_entry);
if(ci)
mount_id = ci->Modelid_A1;
mount_id = ci->DisplayID_A;
}
if (team == HORDE)
{
@@ -5088,7 +5113,7 @@ uint16 ObjectMgr::GetTaxiMount( uint32 id, uint32 team, bool allowed_alt_team /*
CreatureInfo const *ci = GetCreatureTemplate(mount_entry);
if(ci)
mount_id = ci->Modelid_H1;
mount_id = ci->DisplayID_H;
}
}
@@ -6011,6 +6036,8 @@ void ObjectMgr::LoadGameobjectInfo()
if (!goInfo)
continue;
// some GO types have unused go template, check goInfo->displayId at GO spawn data loading or ignore
switch(goInfo->type)
{
case GAMEOBJECT_TYPE_DOOR: //0

View File

@@ -189,10 +189,10 @@ void WorldSession::HandleCreatureQueryOpcode( WorldPacket & recv_data )
data << uint32(ci->rank); // Creature Rank (elite, boss, etc)
data << uint32(ci->unk1); // new in 3.1, creature entry?
data << uint32(ci->unk2); // new in 3.1, creature entry?
data << (uint32)ci->Modelid_A1; // Modelid_A1
data << (uint32)ci->Modelid_A2; // Modelid_A2
data << (uint32)ci->Modelid_H1; // Modelid_H1
data << (uint32)ci->Modelid_H2; // Modelid_H2
data << (uint32)ci->DisplayID_A; // DisplayID_A
data << (uint32)ci->DisplayID_A2; // DisplayID_A2
data << (uint32)ci->DisplayID_H; // DisplayID_H
data << (uint32)ci->DisplayID_H2; // DisplayID_H2
data << float(ci->unk16); // unk
data << float(ci->unk17); // unk
data << uint8(ci->RacialLeader);

View File

@@ -62,17 +62,17 @@ void Totem::InitStats(uint32 duration)
uint32 modelid = 0;
if(((Player*)m_owner)->GetTeam() == HORDE)
{
if(cinfo->Modelid_H1)
modelid = cinfo->Modelid_H1;
else if(cinfo->Modelid_H2)
modelid = cinfo->Modelid_H2;
if(cinfo->DisplayID_H)
modelid = cinfo->DisplayID_H;
else if(cinfo->DisplayID_H2)
modelid = cinfo->DisplayID_H2;
}
else
{
if(cinfo->Modelid_A1)
modelid = cinfo->Modelid_A1;
else if(cinfo->Modelid_A2)
modelid = cinfo->Modelid_A2;
if(cinfo->DisplayID_A)
modelid = cinfo->DisplayID_A;
else if(cinfo->DisplayID_A2)
modelid = cinfo->DisplayID_A2;
}
if (modelid)
SetDisplayId(modelid);