Skip to content

Commit

Permalink
Core/Corpses: Fixed client crashes with player corpses
Browse files Browse the repository at this point in the history
Closes #25714
  • Loading branch information
Shauren committed Dec 13, 2020
1 parent 015666b commit 93f2aff
Show file tree
Hide file tree
Showing 9 changed files with 33 additions and 25 deletions.
4 changes: 3 additions & 1 deletion sql/base/characters_database.sql
Original file line number Diff line number Diff line change
Expand Up @@ -1857,6 +1857,7 @@ CREATE TABLE `corpse` (
`displayId` int(10) unsigned NOT NULL DEFAULT '0',
`itemCache` text NOT NULL,
`race` tinyint(3) unsigned NOT NULL DEFAULT '0',
`class` tinyint(3) unsigned NOT NULL DEFAULT '0',
`gender` tinyint(3) unsigned NOT NULL DEFAULT '0',
`flags` tinyint(3) unsigned NOT NULL DEFAULT '0',
`dynFlags` tinyint(3) unsigned NOT NULL DEFAULT '0',
Expand Down Expand Up @@ -3820,7 +3821,8 @@ INSERT INTO `updates` VALUES
('2020_06_17_00_characters.sql','C3EE0D751E4B97CDF15F3BE27AAAE3646514A358','ARCHIVED','2020-06-17 17:04:56',0),
('2020_08_14_00_characters.sql','355685FF86EE64E2ED9D4B7D1311D53A9C2E0FA5','ARCHIVED','2020-08-14 21:41:24',0),
('2020_10_20_00_characters.sql','744F2A36865761920CE98A6DDE3A3BADF44D1E77','ARCHIVED','2020-10-20 21:36:49',0),
('2020_11_16_00_characters.sql','33D5C7539E239132923D01F4B6EAD5F3EF3EEB69','RELEASED','2020-11-16 19:16:31',0);
('2020_11_16_00_characters.sql','33D5C7539E239132923D01F4B6EAD5F3EF3EEB69','RELEASED','2020-11-16 19:16:31',0),
('2020_12_13_00_characters.sql','6AC743240033DED2C402ECB894A59D79EF607920','RELEASED','2020-12-13 18:36:58',0);
/*!40000 ALTER TABLE `updates` ENABLE KEYS */;
UNLOCK TABLES;

Expand Down
3 changes: 3 additions & 0 deletions sql/updates/characters/master/2020_12_13_00_characters.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
ALTER TABLE `corpse` ADD `class` tinyint(3) unsigned NOT NULL DEFAULT '0' AFTER `race`;

UPDATE `corpse` SET `class`=(SELECT c.`class` FROM `characters` c WHERE c.`guid`=`guid`);
Original file line number Diff line number Diff line change
Expand Up @@ -421,8 +421,8 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_DEL_PLAYER_HOMEBIND, "DELETE FROM character_homebind WHERE guid = ?", CONNECTION_ASYNC);

// Corpse
PrepareStatement(CHAR_SEL_CORPSES, "SELECT posX, posY, posZ, orientation, mapId, displayId, itemCache, race, gender, flags, dynFlags, time, corpseType, instanceId, guid FROM corpse WHERE mapId = ? AND instanceId = ?", CONNECTION_SYNCH);
PrepareStatement(CHAR_INS_CORPSE, "INSERT INTO corpse (guid, posX, posY, posZ, orientation, mapId, displayId, itemCache, race, gender, flags, dynFlags, time, corpseType, instanceId) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_CORPSES, "SELECT posX, posY, posZ, orientation, mapId, displayId, itemCache, race, class, gender, flags, dynFlags, time, corpseType, instanceId, guid FROM corpse WHERE mapId = ? AND instanceId = ?", CONNECTION_SYNCH);
PrepareStatement(CHAR_INS_CORPSE, "INSERT INTO corpse (guid, posX, posY, posZ, orientation, mapId, displayId, itemCache, race, class, gender, flags, dynFlags, time, corpseType, instanceId) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_CORPSE, "DELETE FROM corpse WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_CORPSES_FROM_MAP, "DELETE cp, c FROM corpse_phases cp INNER JOIN corpse c ON cp.OwnerGuid = c.guid WHERE c.mapId = ? AND c.instanceId = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_CORPSE_PHASES, "SELECT cp.OwnerGuid, cp.PhaseId FROM corpse_phases cp LEFT JOIN corpse c ON cp.OwnerGuid = c.guid WHERE c.mapId = ? AND c.instanceId = ?", CONNECTION_SYNCH);
Expand Down
18 changes: 10 additions & 8 deletions src/server/game/Entities/Corpse/Corpse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ void Corpse::SaveToDB()
stmt->setUInt32(index++, m_corpseData->DisplayID); // displayId
stmt->setString(index++, items.str()); // itemCache
stmt->setUInt8 (index++, m_corpseData->RaceID); // race
stmt->setUInt8 (index++, m_corpseData->Class); // class
stmt->setUInt8 (index++, m_corpseData->Sex); // gender
stmt->setUInt8 (index++, m_corpseData->Flags); // flags
stmt->setUInt8 (index++, m_corpseData->DynamicFlags); // dynFlags
Expand Down Expand Up @@ -165,8 +166,8 @@ void Corpse::DeleteFromDB(ObjectGuid const& ownerGuid, CharacterDatabaseTransact

bool Corpse::LoadCorpseFromDB(ObjectGuid::LowType guid, Field* fields)
{
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
// SELECT posX, posY, posZ, orientation, mapId, displayId, itemCache, bytes1, race, gender, dynFlags, time, corpseType, instanceId, guid FROM corpse WHERE mapId = ? AND instanceId = ?
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
// SELECT posX, posY, posZ, orientation, mapId, displayId, itemCache, race, class, gender, flags, dynFlags, time, corpseType, instanceId, guid FROM corpse WHERE mapId = ? AND instanceId = ?

float posX = fields[0].GetFloat();
float posY = fields[1].GetFloat();
Expand All @@ -184,15 +185,16 @@ bool Corpse::LoadCorpseFromDB(ObjectGuid::LowType guid, Field* fields)
SetItem(index, atoul(items[index]));

SetRace(fields[7].GetUInt8());
SetSex(fields[8].GetUInt8());
SetFlags(fields[9].GetUInt8());
SetCorpseDynamicFlags(CorpseDynFlags(fields[10].GetUInt8()));
SetOwnerGUID(ObjectGuid::Create<HighGuid::Player>(fields[14].GetUInt64()));
SetClass(fields[8].GetUInt8());
SetSex(fields[9].GetUInt8());
SetFlags(fields[10].GetUInt8());
SetCorpseDynamicFlags(CorpseDynFlags(fields[11].GetUInt8()));
SetOwnerGUID(ObjectGuid::Create<HighGuid::Player>(fields[15].GetUInt64()));
SetFactionTemplate(sChrRacesStore.AssertEntry(m_corpseData->RaceID)->FactionID);

m_time = time_t(fields[11].GetUInt32());
m_time = time_t(fields[12].GetUInt32());

uint32 instanceId = fields[13].GetUInt32();
uint32 instanceId = fields[14].GetUInt32();

// place
SetLocationInstanceId(instanceId);
Expand Down
1 change: 1 addition & 0 deletions src/server/game/Entities/Corpse/Corpse.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ class TC_GAME_API Corpse : public WorldObject, public GridObject<Corpse>
void SetGuildGUID(ObjectGuid guildGuid) { SetUpdateFieldValue(m_values.ModifyValue(&Corpse::m_corpseData).ModifyValue(&UF::CorpseData::GuildGUID), guildGuid); }
void SetDisplayId(uint32 displayId) { SetUpdateFieldValue(m_values.ModifyValue(&Corpse::m_corpseData).ModifyValue(&UF::CorpseData::DisplayID), displayId); }
void SetRace(uint8 race) { SetUpdateFieldValue(m_values.ModifyValue(&Corpse::m_corpseData).ModifyValue(&UF::CorpseData::RaceID), race); }
void SetClass(uint8 playerClass) { SetUpdateFieldValue(m_values.ModifyValue(&Corpse::m_corpseData).ModifyValue(&UF::CorpseData::Class), playerClass); }
void SetSex(uint8 sex) { SetUpdateFieldValue(m_values.ModifyValue(&Corpse::m_corpseData).ModifyValue(&UF::CorpseData::Sex), sex); }
void SetFlags(uint32 flags) { SetUpdateFieldValue(m_values.ModifyValue(&Corpse::m_corpseData).ModifyValue(&UF::CorpseData::Flags), flags); }
void SetFactionTemplate(int32 factionTemplate) { SetUpdateFieldValue(m_values.ModifyValue(&Corpse::m_corpseData).ModifyValue(&UF::CorpseData::FactionTemplate), factionTemplate); }
Expand Down
10 changes: 5 additions & 5 deletions src/server/game/Entities/Object/Updates/UpdateFields.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4483,9 +4483,9 @@ void CorpseData::WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVi
{
data << uint32(Items[i]);
}
data << uint8(Unused);
data << uint8(RaceID);
data << uint8(Sex);
data << uint8(Class);
data << uint32(Customizations.size());
data << uint32(Flags);
data << int32(FactionTemplate);
Expand Down Expand Up @@ -4553,15 +4553,15 @@ void CorpseData::WriteUpdate(ByteBuffer& data, UpdateMask<33> const& changesMask
}
if (changesMask[7])
{
data << uint8(Unused);
data << uint8(RaceID);
}
if (changesMask[8])
{
data << uint8(RaceID);
data << uint8(Sex);
}
if (changesMask[9])
{
data << uint8(Sex);
data << uint8(Class);
}
if (changesMask[10])
{
Expand Down Expand Up @@ -4596,9 +4596,9 @@ void CorpseData::ClearChangesMask()
Base::ClearChangesMask(PartyGUID);
Base::ClearChangesMask(GuildGUID);
Base::ClearChangesMask(DisplayID);
Base::ClearChangesMask(Unused);
Base::ClearChangesMask(RaceID);
Base::ClearChangesMask(Sex);
Base::ClearChangesMask(Class);
Base::ClearChangesMask(Flags);
Base::ClearChangesMask(FactionTemplate);
Base::ClearChangesMask(StateSpellVisualKitID);
Expand Down
6 changes: 3 additions & 3 deletions src/server/game/Entities/Object/Updates/UpdateFields.h
Original file line number Diff line number Diff line change
Expand Up @@ -837,9 +837,9 @@ struct CorpseData : public IsUpdateFieldStructureTag, public HasChangesMask<33>
UpdateField<ObjectGuid, 0, 4> PartyGUID;
UpdateField<ObjectGuid, 0, 5> GuildGUID;
UpdateField<uint32, 0, 6> DisplayID;
UpdateField<uint8, 0, 7> Unused;
UpdateField<uint8, 0, 8> RaceID;
UpdateField<uint8, 0, 9> Sex;
UpdateField<uint8, 0, 7> RaceID;
UpdateField<uint8, 0, 8> Sex;
UpdateField<uint8, 0, 9> Class;
UpdateField<uint32, 0, 10> Flags;
UpdateField<int32, 0, 11> FactionTemplate;
UpdateField<uint32, 0, 12> StateSpellVisualKitID;
Expand Down
1 change: 1 addition & 0 deletions src/server/game/Entities/Player/Player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4437,6 +4437,7 @@ Corpse* Player::CreateCorpse()

corpse->SetRace(getRace());
corpse->SetSex(GetNativeSex());
corpse->SetClass(getClass());
corpse->SetCustomizations(Trinity::Containers::MakeIteratorPair(m_playerData->Customizations.begin(), m_playerData->Customizations.end()));
corpse->SetFlags(flags);
corpse->SetDisplayId(GetNativeDisplayId());
Expand Down
11 changes: 5 additions & 6 deletions src/server/game/Maps/Map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4789,8 +4789,8 @@ void Map::LoadCorpseData()
stmt->setUInt32(0, GetId());
stmt->setUInt32(1, GetInstanceId());

// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
// SELECT posX, posY, posZ, orientation, mapId, displayId, itemCache, bytes1, bytes2, flags, dynFlags, time, corpseType, instanceId, guid FROM corpse WHERE mapId = ? AND instanceId = ?
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
// SELECT posX, posY, posZ, orientation, mapId, displayId, itemCache, race, class, gender, flags, dynFlags, time, corpseType, instanceId, guid FROM corpse WHERE mapId = ? AND instanceId = ?
PreparedQueryResult result = CharacterDatabase.Query(stmt);
if (!result)
return;
Expand Down Expand Up @@ -4838,8 +4838,8 @@ void Map::LoadCorpseData()
do
{
Field* fields = result->Fetch();
CorpseType type = CorpseType(fields[12].GetUInt8());
ObjectGuid::LowType guid = fields[14].GetUInt64();
CorpseType type = CorpseType(fields[13].GetUInt8());
ObjectGuid::LowType guid = fields[15].GetUInt64();
if (type >= MAX_CORPSE_TYPE || type == CORPSE_BONES)
{
TC_LOG_ERROR("misc", "Corpse (guid: " UI64FMTD ") have wrong corpse type (%u), not loading.", guid, type);
Expand Down Expand Up @@ -4935,11 +4935,10 @@ Corpse* Map::ConvertCorpseToBones(ObjectGuid const& ownerGuid, bool insignia /*=
bones->SetDisplayId(corpse->m_corpseData->DisplayID);
bones->SetRace(corpse->m_corpseData->RaceID);
bones->SetSex(corpse->m_corpseData->Sex);
bones->SetClass(corpse->m_corpseData->Class);
bones->SetCustomizations(Trinity::Containers::MakeIteratorPair(corpse->m_corpseData->Customizations.begin(), corpse->m_corpseData->Customizations.end()));
bones->SetFlags(corpse->m_corpseData->Flags | CORPSE_FLAG_BONES);
bones->SetFactionTemplate(corpse->m_corpseData->FactionTemplate);
for (uint32 i = 0; i < EQUIPMENT_SLOT_END; ++i)
bones->SetItem(i, corpse->m_corpseData->Items[i]);

bones->SetCellCoord(corpse->GetCellCoord());
bones->Relocate(corpse->GetPositionX(), corpse->GetPositionY(), corpse->GetPositionZ(), corpse->GetOrientation());
Expand Down

0 comments on commit 93f2aff

Please sign in to comment.