aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGiacomo Pozzoni <giacomopoz@gmail.com>2018-12-14 22:01:16 +0100
committerShauren <shauren.trinity@gmail.com>2021-11-16 20:36:58 +0100
commitd5c41d23e67e3813adf09ee84afa636b2192c891 (patch)
tree865a196a5dacfdf75aead0bf48afdd9c808515c6
parentaea3022e8974d2520bdd2427b1c83aa5cfbb1254 (diff)
Core/Misc: Log more information in asserts (#22783)
* Core/Misc: Log more information in asserts Add a new function GetDebugInfos() to types that could trigger an ASSERT() to easily include more useful information in crashlogs. This is an initial commit that requires many more commits to implement the new GetDebugInfos() function in all required types. If the type doesn't have the function, the global default one is picked which doesn't log anything. * Core/Misc: Fix dynamic build Add missing attribute for dynamic build * Core/Misc: Fix gcc/clang build * Core/Misc: Rename GetDebugInfos() to GetDebugInfo() * Core/Misc: Fix FormatAssertionMessage() adding an extra '\0' * Core/Misc: Add GetDebugInfo support to Unit * Core/Misc: Add GetDebugInfo support to Creature * Core/Misc: Add more info to GetDebugInfo for Creature * Core/Misc: Add GetDebugInfo support to GameObject * Core/Misc: Add GetDebugInfo support to Player * Core/Misc: Add more GetDebugInfo info * Core/Misc: Add GetDebugInfo support to Item * Core/Misc: Add GetDebugInfo support to Bag * Core/Misc: Add GetDebugInfo support to Transport * Core/Misc: Add GetDebugInfo support to TempSummon, Minion, Guardian, Pet * Core/Misc: Add GetDebugInfo support to Map, InstanceMap * Core/Misc: Add GetDebugInfo support to Spell * Core/Misc: Fix build warning * Core/Misc: Add GetDebugInfo support to Aura * Core/Misc: Add GetDebugInfo support to UnitAI (cherry picked from commit 9a924fb9d557434c5a2e4020c80db6e6bfe466ad)
-rw-r--r--src/common/Debugging/Errors.cpp17
-rw-r--r--src/common/Debugging/Errors.h12
-rw-r--r--src/server/game/AI/CoreAI/UnitAI.cpp9
-rw-r--r--src/server/game/AI/CoreAI/UnitAI.h2
-rw-r--r--src/server/game/Entities/Creature/Creature.cpp9
-rw-r--r--src/server/game/Entities/Creature/Creature.h2
-rw-r--r--src/server/game/Entities/Creature/TemporarySummon.cpp28
-rw-r--r--src/server/game/Entities/Creature/TemporarySummon.h7
-rw-r--r--src/server/game/Entities/GameObject/GameObject.cpp8
-rw-r--r--src/server/game/Entities/GameObject/GameObject.h2
-rw-r--r--src/server/game/Entities/Item/Container/Bag.cpp8
-rw-r--r--src/server/game/Entities/Item/Container/Bag.h4
-rw-r--r--src/server/game/Entities/Item/Item.cpp12
-rw-r--r--src/server/game/Entities/Item/Item.h2
-rw-r--r--src/server/game/Entities/Object/Object.cpp17
-rw-r--r--src/server/game/Entities/Object/Object.h4
-rw-r--r--src/server/game/Entities/Object/Position.cpp7
-rw-r--r--src/server/game/Entities/Object/Position.h2
-rw-r--r--src/server/game/Entities/Pet/Pet.cpp9
-rw-r--r--src/server/game/Entities/Pet/Pet.h2
-rw-r--r--src/server/game/Entities/Player/Player.cpp7
-rw-r--r--src/server/game/Entities/Player/Player.h2
-rw-r--r--src/server/game/Entities/Transport/Transport.cpp8
-rw-r--r--src/server/game/Entities/Transport/Transport.h2
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp13
-rw-r--r--src/server/game/Entities/Unit/Unit.h2
-rw-r--r--src/server/game/Maps/Map.cpp19
-rw-r--r--src/server/game/Maps/Map.h4
-rw-r--r--src/server/game/Spells/Auras/SpellAuras.cpp20
-rw-r--r--src/server/game/Spells/Auras/SpellAuras.h2
-rw-r--r--src/server/game/Spells/Spell.cpp10
-rw-r--r--src/server/game/Spells/Spell.h2
32 files changed, 234 insertions, 20 deletions
diff --git a/src/common/Debugging/Errors.cpp b/src/common/Debugging/Errors.cpp
index 9f832caff4d..7ad137715da 100644
--- a/src/common/Debugging/Errors.cpp
+++ b/src/common/Debugging/Errors.cpp
@@ -58,8 +58,8 @@ namespace
int32 length = vsnprintf(nullptr, 0, format, len);
va_end(len);
- formatted.resize(length + 1);
- vsnprintf(&formatted[0], length + 1, format, args);
+ formatted.resize(length);
+ vsnprintf(&formatted[0], length, format, args);
return formatted;
}
@@ -68,20 +68,20 @@ namespace
namespace Trinity
{
-void Assert(char const* file, int line, char const* function, char const* message)
+void Assert(char const* file, int line, char const* function, std::string debugInfo, char const* message)
{
- std::string formattedMessage = StringFormat("\n%s:%i in %s ASSERTION FAILED:\n %s\n", file, line, function, message);
+ std::string formattedMessage = StringFormat("\n%s:%i in %s ASSERTION FAILED:\n %s\n", file, line, function, message) + debugInfo + '\n';
fprintf(stderr, "%s", formattedMessage.c_str());
fflush(stderr);
Crash(formattedMessage.c_str());
}
-void Assert(char const* file, int line, char const* function, char const* message, char const* format, ...)
+void Assert(char const* file, int line, char const* function, std::string debugInfo, char const* message, char const* format, ...)
{
va_list args;
va_start(args, format);
- std::string formattedMessage = StringFormat("\n%s:%i in %s ASSERTION FAILED:\n %s\n", file, line, function, message) + FormatAssertionMessage(format, args) + '\n';
+ std::string formattedMessage = StringFormat("\n%s:%i in %s ASSERTION FAILED:\n %s\n", file, line, function, message) + FormatAssertionMessage(format, args) + '\n' + debugInfo + '\n';
va_end(args);
fprintf(stderr, "%s", formattedMessage.c_str());
@@ -137,3 +137,8 @@ void AbortHandler(int sigval)
}
} // namespace Trinity
+
+std::string GetDebugInfo()
+{
+ return "";
+}
diff --git a/src/common/Debugging/Errors.h b/src/common/Debugging/Errors.h
index f64bff72fd1..befb269a120 100644
--- a/src/common/Debugging/Errors.h
+++ b/src/common/Debugging/Errors.h
@@ -19,11 +19,12 @@
#define TRINITYCORE_ERRORS_H
#include "Define.h"
+#include <string>
namespace Trinity
{
- DECLSPEC_NORETURN TC_COMMON_API void Assert(char const* file, int line, char const* function, char const* message) ATTR_NORETURN;
- DECLSPEC_NORETURN TC_COMMON_API void Assert(char const* file, int line, char const* function, char const* message, char const* format, ...) ATTR_NORETURN ATTR_PRINTF(5, 6);
+ DECLSPEC_NORETURN TC_COMMON_API void Assert(char const* file, int line, char const* function, std::string debugInfo, char const* message) ATTR_NORETURN;
+ DECLSPEC_NORETURN TC_COMMON_API void Assert(char const* file, int line, char const* function, std::string debugInfo, char const* message, char const* format, ...) ATTR_NORETURN ATTR_PRINTF(6, 7);
DECLSPEC_NORETURN TC_COMMON_API void Fatal(char const* file, int line, char const* function, char const* message, ...) ATTR_NORETURN ATTR_PRINTF(4, 5);
@@ -37,6 +38,8 @@ namespace Trinity
} // namespace Trinity
+TC_COMMON_API std::string GetDebugInfo();
+
#if TRINITY_COMPILER == TRINITY_COMPILER_MICROSOFT
#define ASSERT_BEGIN __pragma(warning(push)) __pragma(warning(disable: 4127))
#define ASSERT_END __pragma(warning(pop))
@@ -49,7 +52,8 @@ namespace Trinity
#define EXCEPTION_ASSERTION_FAILURE 0xC0000420L
#endif
-#define WPAssert(cond, ...) ASSERT_BEGIN do { if (!(cond)) Trinity::Assert(__FILE__, __LINE__, __FUNCTION__, #cond, ##__VA_ARGS__); } while(0) ASSERT_END
+#define WPAssert(cond, ...) ASSERT_BEGIN do { if (!(cond)) Trinity::Assert(__FILE__, __LINE__, __FUNCTION__, GetDebugInfo(), #cond, ##__VA_ARGS__); } while(0) ASSERT_END
+#define WPAssert_NODEBUGINFO(cond, ...) ASSERT_BEGIN do { if (!(cond)) Trinity::Assert(__FILE__, __LINE__, __FUNCTION__, "", #cond, ##__VA_ARGS__); } while(0) ASSERT_END
#define WPFatal(cond, ...) ASSERT_BEGIN do { if (!(cond)) Trinity::Fatal(__FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); } while(0) ASSERT_END
#define WPError(cond, msg) ASSERT_BEGIN do { if (!(cond)) Trinity::Error(__FILE__, __LINE__, __FUNCTION__, (msg)); } while(0) ASSERT_END
#define WPWarning(cond, msg) ASSERT_BEGIN do { if (!(cond)) Trinity::Warning(__FILE__, __LINE__, __FUNCTION__, (msg)); } while(0) ASSERT_END
@@ -57,8 +61,10 @@ namespace Trinity
#ifdef PERFORMANCE_PROFILING
#define ASSERT(cond, ...) ((void)0)
+#define ASSERT_NODEBUGINFO(cond, ...) ((void)0)
#else
#define ASSERT WPAssert
+#define ASSERT_NODEBUGINFO WPAssert_NODEBUGINFO
#endif
#define ABORT WPAbort
diff --git a/src/server/game/AI/CoreAI/UnitAI.cpp b/src/server/game/AI/CoreAI/UnitAI.cpp
index fe16a56497f..b9c805503e8 100644
--- a/src/server/game/AI/CoreAI/UnitAI.cpp
+++ b/src/server/game/AI/CoreAI/UnitAI.cpp
@@ -27,6 +27,7 @@
#include "SpellAuras.h"
#include "SpellInfo.h"
#include "SpellMgr.h"
+#include <sstream>
void UnitAI::AttackStart(Unit* victim)
{
@@ -312,6 +313,14 @@ void UnitAI::SortByDistance(std::list<Unit*> list, bool ascending)
list.sort(Trinity::ObjectDistanceOrderPred(me, ascending));
}
+std::string UnitAI::GetDebugInfo() const
+{
+ std::stringstream sstr;
+ sstr << std::boolalpha
+ << "Me: " << (me ? me->GetDebugInfo() : "NULL");
+ return sstr.str();
+}
+
DefaultTargetSelector::DefaultTargetSelector(Unit const* unit, float dist, bool playerOnly, bool withTank, int32 aura)
: me(unit), m_dist(dist), m_playerOnly(playerOnly), except(!withTank ? me->GetThreatManager().GetCurrentVictim() : nullptr), m_aura(aura)
{
diff --git a/src/server/game/AI/CoreAI/UnitAI.h b/src/server/game/AI/CoreAI/UnitAI.h
index 5e5f657b08a..f1d0d862f26 100644
--- a/src/server/game/AI/CoreAI/UnitAI.h
+++ b/src/server/game/AI/CoreAI/UnitAI.h
@@ -326,6 +326,8 @@ class TC_GAME_API UnitAI
// Called when a game event starts or ends
virtual void OnGameEvent(bool /*start*/, uint16 /*eventId*/) { }
+ virtual std::string GetDebugInfo() const;
+
private:
UnitAI(UnitAI const& right) = delete;
UnitAI& operator=(UnitAI const& right) = delete;
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp
index 1d21caa6689..f29d04677f9 100644
--- a/src/server/game/Entities/Creature/Creature.cpp
+++ b/src/server/game/Entities/Creature/Creature.cpp
@@ -3374,3 +3374,12 @@ bool Creature::IsEscortNPC(bool onlyIfActive)
return ai->IsEscortNPC(onlyIfActive);
return false;
}
+
+std::string Creature::GetDebugInfo() const
+{
+ std::stringstream sstr;
+ sstr << Unit::GetDebugInfo() << "\n"
+ << "AIName: " << GetAIName() << " ScriptName: " << GetScriptName()
+ << " WaypointPath: " << GetWaypointPath() << " SpawnId: " << GetSpawnId();
+ return sstr.str();
+}
diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h
index bca4874df5f..cfc4b025562 100644
--- a/src/server/game/Entities/Creature/Creature.h
+++ b/src/server/game/Entities/Creature/Creature.h
@@ -367,6 +367,8 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma
void AtEnterCombat() override;
void AtExitCombat() override;
+ std::string GetDebugInfo() const override;
+
protected:
bool CreateFromProto(ObjectGuid::LowType guidlow, uint32 entry, CreatureData const* data = nullptr, uint32 vehId = 0);
bool InitEntry(uint32 entry, CreatureData const* data = nullptr);
diff --git a/src/server/game/Entities/Creature/TemporarySummon.cpp b/src/server/game/Entities/Creature/TemporarySummon.cpp
index 96c62d9b924..e21d3624e32 100644
--- a/src/server/game/Entities/Creature/TemporarySummon.cpp
+++ b/src/server/game/Entities/Creature/TemporarySummon.cpp
@@ -23,6 +23,7 @@
#include "ObjectAccessor.h"
#include "Pet.h"
#include "Player.h"
+#include <sstream>
TempSummon::TempSummon(SummonPropertiesEntry const* properties, Unit* owner, bool isWorldObject) :
Creature(isWorldObject), m_Properties(properties), m_type(TEMPSUMMON_MANUAL_DESPAWN),
@@ -276,6 +277,15 @@ void TempSummon::RemoveFromWorld()
Creature::RemoveFromWorld();
}
+std::string TempSummon::GetDebugInfo() const
+{
+ std::stringstream sstr;
+ sstr << Creature::GetDebugInfo() << "\n"
+ << std::boolalpha
+ << "TempSummonType : " << std::to_string(GetSummonType()) << " Summoner: " << GetSummonerGUID().ToString();
+ return sstr.str();
+}
+
Minion::Minion(SummonPropertiesEntry const* properties, Unit* owner, bool isWorldObject)
: TempSummon(properties, owner, isWorldObject), m_owner(owner)
{
@@ -316,7 +326,7 @@ void Minion::setDeathState(DeathState s)
Unit* owner = GetOwner();
if (!owner || owner->GetTypeId() != TYPEID_PLAYER || owner->GetMinionGUID() != GetGUID())
return;
-
+
for (Unit* controlled : owner->m_Controlled)
{
if (controlled->GetEntry() == GetEntry() && controlled->IsAlive())
@@ -334,6 +344,15 @@ bool Minion::IsGuardianPet() const
return IsPet() || (m_Properties && m_Properties->Control == SUMMON_CATEGORY_PET);
}
+std::string Minion::GetDebugInfo() const
+{
+ std::stringstream sstr;
+ sstr << TempSummon::GetDebugInfo() << "\n"
+ << std::boolalpha
+ << "Owner: " << (GetOwner() ? GetOwner()->GetGUID().ToString() : "");
+ return sstr.str();
+}
+
Guardian::Guardian(SummonPropertiesEntry const* properties, Unit* owner, bool isWorldObject) : Minion(properties, owner, isWorldObject)
, m_bonusSpellDamage(0)
{
@@ -370,6 +389,13 @@ void Guardian::InitSummon()
}
}
+std::string Guardian::GetDebugInfo() const
+{
+ std::stringstream sstr;
+ sstr << Minion::GetDebugInfo();
+ return sstr.str();
+}
+
Puppet::Puppet(SummonPropertiesEntry const* properties, Unit* owner)
: Minion(properties, owner, false) //maybe true?
{
diff --git a/src/server/game/Entities/Creature/TemporarySummon.h b/src/server/game/Entities/Creature/TemporarySummon.h
index 6ecb2ef17a0..688b640d1ef 100644
--- a/src/server/game/Entities/Creature/TemporarySummon.h
+++ b/src/server/game/Entities/Creature/TemporarySummon.h
@@ -56,10 +56,12 @@ class TC_GAME_API TempSummon : public Creature
Unit* GetSummoner() const;
Creature* GetSummonerCreatureBase() const;
ObjectGuid GetSummonerGUID() const { return m_summonerGUID; }
- TempSummonType const& GetSummonType() { return m_type; }
+ TempSummonType GetSummonType() const { return m_type; }
uint32 GetTimer() const { return m_timer; }
SummonPropertiesEntry const* const m_Properties;
+
+ std::string GetDebugInfo() const override;
private:
TempSummonType m_type;
uint32 m_timer;
@@ -94,6 +96,8 @@ class TC_GAME_API Minion : public TempSummon
bool IsSpiritWolf() const { return GetEntry() == PET_SPIRIT_WOLF; } // Spirit wolf from feral spirits
bool IsGuardianPet() const;
+
+ std::string GetDebugInfo() const override;
protected:
Unit* const m_owner;
float m_followAngle;
@@ -119,6 +123,7 @@ class TC_GAME_API Guardian : public Minion
int32 GetBonusDamage() const { return m_bonusSpellDamage; }
float GetBonusStatFromOwner(Stats stat) const { return m_statFromOwner[stat]; }
void SetBonusDamage(int32 damage);
+ std::string GetDebugInfo() const override;
protected:
int32 m_bonusSpellDamage;
float m_statFromOwner[MAX_STATS];
diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp
index 7f4bd3e02c6..999ecab0538 100644
--- a/src/server/game/Entities/GameObject/GameObject.cpp
+++ b/src/server/game/Entities/GameObject/GameObject.cpp
@@ -2839,3 +2839,11 @@ void GameObject::CreateModel()
if (m_model && m_model->isMapObject())
AddFlag(GO_FLAG_MAP_OBJECT);
}
+
+std::string GameObject::GetDebugInfo() const
+{
+ std::stringstream sstr;
+ sstr << WorldObject::GetDebugInfo() << "\n"
+ << "SpawnId: " << GetSpawnId() << " GoState: " << std::to_string(GetGoState()) << " ScriptId: " << GetScriptId() << " AIName: " << GetAIName();
+ return sstr.str();
+}
diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h
index a12e96572da..4be1cf2ee59 100644
--- a/src/server/game/Entities/GameObject/GameObject.h
+++ b/src/server/game/Entities/GameObject/GameObject.h
@@ -308,6 +308,8 @@ class TC_GAME_API GameObject : public WorldObject, public GridObject<GameObject>
void AIM_Destroy();
bool AIM_Initialize();
+ std::string GetDebugInfo() const override;
+
UF::UpdateField<UF::GameObjectData, 0, TYPEID_GAMEOBJECT> m_gameObjectData;
protected:
diff --git a/src/server/game/Entities/Item/Container/Bag.cpp b/src/server/game/Entities/Item/Container/Bag.cpp
index 96449083294..8e4ef213eb8 100644
--- a/src/server/game/Entities/Item/Container/Bag.cpp
+++ b/src/server/game/Entities/Item/Container/Bag.cpp
@@ -23,6 +23,7 @@
#include "Log.h"
#include "UpdateData.h"
#include "Player.h"
+#include <sstream>
Bag::Bag(): Item()
{
@@ -281,6 +282,13 @@ Item* Bag::GetItemByPos(uint8 slot) const
return nullptr;
}
+std::string Bag::GetDebugInfo() const
+{
+ std::stringstream sstr;
+ sstr << Item::GetDebugInfo();
+ return sstr.str();
+}
+
uint32 GetBagSize(Bag const* bag)
{
return bag->GetBagSize();
diff --git a/src/server/game/Entities/Item/Container/Bag.h b/src/server/game/Entities/Item/Container/Bag.h
index 3bf36e3c5ea..574a57f323f 100644
--- a/src/server/game/Entities/Item/Container/Bag.h
+++ b/src/server/game/Entities/Item/Container/Bag.h
@@ -26,7 +26,6 @@
class TC_GAME_API Bag : public Item
{
public:
-
Bag();
~Bag();
@@ -35,7 +34,6 @@ class TC_GAME_API Bag : public Item
bool Create(ObjectGuid::LowType guidlow, uint32 itemid, ItemContext context, Player const* owner) override;
- void Clear();
void StoreItem(uint8 slot, Item* pItem, bool update);
void RemoveItem(uint8 slot, bool update);
@@ -64,6 +62,8 @@ class TC_GAME_API Bag : public Item
void BuildValuesUpdateForPlayerWithMask(UpdateData* data, UF::ObjectData::Mask const& requestedObjectMask, UF::ItemData::Mask const& requestedItemMask,
UF::ContainerData::Mask const& requestedContainerMask, Player const* target) const;
+ std::string GetDebugInfo() const override;
+
UF::UpdateField<UF::ContainerData, 0, TYPEID_CONTAINER> m_containerData;
protected:
diff --git a/src/server/game/Entities/Item/Item.cpp b/src/server/game/Entities/Item/Item.cpp
index fbbb94df1f1..2fe2f2247b9 100644
--- a/src/server/game/Entities/Item/Item.cpp
+++ b/src/server/game/Entities/Item/Item.cpp
@@ -1554,7 +1554,7 @@ Item* Item::CreateItem(uint32 itemEntry, uint32 count, ItemContext context, Play
if (count > proto->GetMaxStackSize())
count = proto->GetMaxStackSize();
- ASSERT(count != 0, "proto->Stackable == 0 but checked at loading already");
+ ASSERT_NODEBUGINFO(count != 0, "proto->Stackable == 0 but checked at loading already");
Item* item = NewItemOrBag(proto);
if (item->Create(sObjectMgr->GetGenerator<HighGuid::Item>().Generate(), itemEntry, context, player))
@@ -2694,6 +2694,16 @@ int32 Item::GetRequiredLevel() const
return _bonusData.RequiredLevel;
}
+std::string Item::GetDebugInfo() const
+{
+ std::stringstream sstr;
+ sstr << Object::GetDebugInfo() << "\n"
+ << std::boolalpha
+ << "Owner: " << GetOwnerGUID().ToString() << " Count: " << GetCount()
+ << " BagSlot: " << std::to_string(GetBagSlot()) << " Slot: " << std::to_string(GetSlot()) << " Equipped: " << IsEquipped();
+ return sstr.str();
+}
+
void BonusData::Initialize(ItemTemplate const* proto)
{
Quality = proto->GetQuality();
diff --git a/src/server/game/Entities/Item/Item.h b/src/server/game/Entities/Item/Item.h
index 98877b06b80..b0f05500b06 100644
--- a/src/server/game/Entities/Item/Item.h
+++ b/src/server/game/Entities/Item/Item.h
@@ -421,6 +421,8 @@ class TC_GAME_API Item : public Object
void SetPetitionId(uint32 petitionId) { SetUpdateFieldValue(m_values.ModifyValue(&Item::m_itemData).ModifyValue(&UF::ItemData::Enchantment, 0).ModifyValue(&UF::ItemEnchantment::ID), petitionId); }
void SetPetitionNumSignatures(uint32 signatures) { SetUpdateFieldValue(m_values.ModifyValue(&Item::m_itemData).ModifyValue(&UF::ItemData::Enchantment, 0).ModifyValue(&UF::ItemEnchantment::Duration), signatures); }
+ std::string GetDebugInfo() const override;
+
UF::UpdateField<UF::ItemData, 0, TYPEID_ITEM> m_itemData;
protected:
diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp
index c255ebbfaf4..e05beed9feb 100644
--- a/src/server/game/Entities/Object/Object.cpp
+++ b/src/server/game/Entities/Object/Object.cpp
@@ -52,6 +52,7 @@
#include "World.h"
#include "WorldSession.h"
#include <G3D/Vector3.h>
+#include <sstream>
constexpr float VisibilityDistances[AsUnderlyingType(VisibilityDistanceType::Max)] =
{
@@ -747,6 +748,13 @@ void Object::BuildFieldsUpdate(Player* player, UpdateDataMapType& data_map) cons
BuildValuesUpdateBlockForPlayer(&iter->second, iter->first);
}
+std::string Object::GetDebugInfo() const
+{
+ std::stringstream sstr;
+ sstr << GetGUID().ToString() + " Entry " << GetEntry();
+ return sstr.str();
+}
+
void MovementInfo::OutDebug()
{
TC_LOG_DEBUG("misc", "MOVEMENT INFO");
@@ -3272,6 +3280,15 @@ float WorldObject::GetMapHeight(float x, float y, float z, bool vmap/* = true*/,
return GetMap()->GetHeight(GetPhaseShift(), x, y, z, vmap, distanceToSearch);
}
+std::string WorldObject::GetDebugInfo() const
+{
+ std::stringstream sstr;
+ sstr << WorldLocation::GetDebugInfo() << "\n"
+ << Object::GetDebugInfo() << "\n"
+ << "Name: " << GetName();
+ return sstr.str();
+}
+
template TC_GAME_API void WorldObject::GetGameObjectListWithEntryInGrid(std::list<GameObject*>&, uint32, float) const;
template TC_GAME_API void WorldObject::GetGameObjectListWithEntryInGrid(std::deque<GameObject*>&, uint32, float) const;
template TC_GAME_API void WorldObject::GetGameObjectListWithEntryInGrid(std::vector<GameObject*>&, uint32, float) const;
diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h
index b194f96f8c0..8af47209787 100644
--- a/src/server/game/Entities/Object/Object.h
+++ b/src/server/game/Entities/Object/Object.h
@@ -229,6 +229,8 @@ class TC_GAME_API Object
AddToObjectUpdateIfNeeded();
}
+ virtual std::string GetDebugInfo() const;
+
protected:
Object();
@@ -666,6 +668,8 @@ class TC_GAME_API WorldObject : public Object, public WorldLocation
float GetMapWaterOrGroundLevel(float x, float y, float z, float* ground = nullptr) const;
float GetMapHeight(float x, float y, float z, bool vmap = true, float distanceToSearch = 50.0f) const; // DEFAULT_HEIGHT_SEARCH in map.h
+ std::string GetDebugInfo() const override;
+
// Event handler
EventProcessor m_Events;
diff --git a/src/server/game/Entities/Object/Position.cpp b/src/server/game/Entities/Object/Position.cpp
index b969a5492a9..7a5b8f47f00 100644
--- a/src/server/game/Entities/Object/Position.cpp
+++ b/src/server/game/Entities/Object/Position.cpp
@@ -199,3 +199,10 @@ ByteBuffer& operator<<(ByteBuffer& buf, Position::ConstStreamer<Position::Packed
buf.appendPackXYZ(streamer.Pos->GetPositionX(), streamer.Pos->GetPositionY(), streamer.Pos->GetPositionZ());
return buf;
}
+
+std::string WorldLocation::GetDebugInfo() const
+{
+ std::stringstream sstr;
+ sstr << "MapID: " << m_mapId << " " << Position::ToString();
+ return sstr.str();
+}
diff --git a/src/server/game/Entities/Object/Position.h b/src/server/game/Entities/Object/Position.h
index 0954169e756..ad5dc5a390a 100644
--- a/src/server/game/Entities/Object/Position.h
+++ b/src/server/game/Entities/Object/Position.h
@@ -186,6 +186,8 @@ public:
uint32 GetMapId() const { return m_mapId; }
uint32 m_mapId;
+
+ std::string GetDebugInfo() const;
};
TC_GAME_API ByteBuffer& operator<<(ByteBuffer& buf, Position::ConstStreamer<Position::XY> const& streamer);
diff --git a/src/server/game/Entities/Pet/Pet.cpp b/src/server/game/Entities/Pet/Pet.cpp
index 8e1926ab99c..3cfac35c530 100644
--- a/src/server/game/Entities/Pet/Pet.cpp
+++ b/src/server/game/Entities/Pet/Pet.cpp
@@ -1865,3 +1865,12 @@ std::string Pet::GenerateActionBarData() const
return ss.str();
}
+
+std::string Pet::GetDebugInfo() const
+{
+ std::stringstream sstr;
+ sstr << Guardian::GetDebugInfo() << "\n"
+ << std::boolalpha
+ << "PetType: " << std::to_string(getPetType());
+ return sstr.str();
+}
diff --git a/src/server/game/Entities/Pet/Pet.h b/src/server/game/Entities/Pet/Pet.h
index 05c937a2b21..047df2581ae 100644
--- a/src/server/game/Entities/Pet/Pet.h
+++ b/src/server/game/Entities/Pet/Pet.h
@@ -148,6 +148,8 @@ class TC_GAME_API Pet : public Guardian
Player* GetOwner() const;
+ std::string GetDebugInfo() const override;
+
protected:
PetType m_petType;
int32 m_duration; // time until unsummon (used mostly for summoned guardians and not used for controlled pets)
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 4a8c17a6b3c..2cf5af44a50 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -28955,3 +28955,10 @@ bool Player::CanEnableWarModeInArea() const
return area->Flags[1] & AREA_FLAG_2_CAN_ENABLE_WAR_MODE;
}
+
+std::string Player::GetDebugInfo() const
+{
+ std::stringstream sstr;
+ sstr << Unit::GetDebugInfo();
+ return sstr.str();
+}
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index df930b20727..a9798329b4e 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -2717,6 +2717,8 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
bool CanEnableWarModeInArea() const;
+ std::string GetDebugInfo() const override;
+
UF::UpdateField<UF::PlayerData, 0, TYPEID_PLAYER> m_playerData;
UF::UpdateField<UF::ActivePlayerData, 0, TYPEID_ACTIVE_PLAYER> m_activePlayerData;
diff --git a/src/server/game/Entities/Transport/Transport.cpp b/src/server/game/Entities/Transport/Transport.cpp
index fd0bf28c85c..b0e63770133 100644
--- a/src/server/game/Entities/Transport/Transport.cpp
+++ b/src/server/game/Entities/Transport/Transport.cpp
@@ -31,6 +31,7 @@
#include "UpdateData.h"
#include "Vehicle.h"
#include <G3D/Vector3.h>
+#include <sstream>
Transport::Transport() : GameObject(),
_transportInfo(nullptr), _isMoving(true), _pendingStop(false),
@@ -773,3 +774,10 @@ void Transport::BuildUpdate(UpdateDataMapType& data_map)
ClearUpdateMask(true);
}
+
+std::string Transport::GetDebugInfo() const
+{
+ std::stringstream sstr;
+ sstr << GameObject::GetDebugInfo();
+ return sstr.str();
+}
diff --git a/src/server/game/Entities/Transport/Transport.h b/src/server/game/Entities/Transport/Transport.h
index 2a5c2340cf7..a8c8a6ae8ff 100644
--- a/src/server/game/Entities/Transport/Transport.h
+++ b/src/server/game/Entities/Transport/Transport.h
@@ -100,6 +100,8 @@ class TC_GAME_API Transport : public GameObject, public TransportBase
TransportTemplate const* GetTransportTemplate() const { return _transportInfo; }
+ std::string GetDebugInfo() const override;
+
private:
void MoveToNextWaypoint();
float CalculateSegmentPos(float perc);
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index c6a300bbfb2..24686921572 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -987,7 +987,7 @@ bool Unit::HasBreakableByDamageCrowdControlAura(Unit* excludeCasterChannel) cons
{
Player* he = duel_wasMounted ? victim->GetCharmer()->ToPlayer() : victim->ToPlayer();
- ASSERT(he && he->duel);
+ ASSERT_NODEBUGINFO(he && he->duel);
if (duel_wasMounted) // In this case victim == mount
victim->SetHealth(1);
@@ -13227,3 +13227,14 @@ float Unit::GetCollisionHeight() const
float const collisionHeight = scaleMod * modelData->CollisionHeight * modelData->ModelScale * displayInfo->CreatureModelScale;
return collisionHeight == 0.0f ? DEFAULT_COLLISION_HEIGHT : collisionHeight;
}
+
+std::string Unit::GetDebugInfo() const
+{
+ std::stringstream sstr;
+ sstr << WorldObject::GetDebugInfo() << "\n"
+ << std::boolalpha
+ << "IsAIEnabled: " << IsAIEnabled() << " DeathState: " << std::to_string(getDeathState())
+ << " UnitMovementFlags: " << GetUnitMovementFlags() << " ExtraUnitMovementFlags: " << GetExtraUnitMovementFlags()
+ << " Class: " << std::to_string(getClass());
+ return sstr.str();
+}
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index 95c205cadfd..ab1f5896009 100644
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -1833,6 +1833,8 @@ class TC_GAME_API Unit : public WorldObject
uint16 GetVirtualItemAppearanceMod(uint32 slot) const;
void SetVirtualItem(uint32 slot, uint32 itemId, uint16 appearanceModId = 0, uint16 itemVisual = 0);
+ std::string GetDebugInfo() const override;
+
UF::UpdateField<UF::UnitData, 0, TYPEID_UNIT> m_unitData;
protected:
diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp
index 4415caef224..27e3c0f0a59 100644
--- a/src/server/game/Maps/Map.cpp
+++ b/src/server/game/Maps/Map.cpp
@@ -53,6 +53,7 @@
#include "WeatherMgr.h"
#include "World.h"
#include "WorldSession.h"
+#include <sstream>
#include "Hacks/boost_1_74_fibonacci_heap.h"
BOOST_1_74_FIBONACCI_HEAP_MSVC_COMPILE_FIX(RespawnListContainer::value_type)
@@ -4974,3 +4975,21 @@ void Map::UpdateAreaDependentAuras()
}
}
}
+
+std::string Map::GetDebugInfo() const
+{
+ std::stringstream sstr;
+ sstr << std::boolalpha
+ << "Id: " << GetId() << " InstanceId: " << GetInstanceId() << " Difficulty: " << std::to_string(GetDifficultyID())
+ << " HasPlayers: " << HavePlayers();
+ return sstr.str();
+}
+
+std::string InstanceMap::GetDebugInfo() const
+{
+ std::stringstream sstr;
+ sstr << Map::GetDebugInfo() << "\n"
+ << std::boolalpha
+ << "ScriptId: " << GetScriptId() << " ScriptName: " << GetScriptName();
+ return sstr.str();
+}
diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h
index cd80657860e..88da98bcdb0 100644
--- a/src/server/game/Maps/Map.h
+++ b/src/server/game/Maps/Map.h
@@ -577,6 +577,8 @@ class TC_GAME_API Map : public GridRefManager<NGridType>
_updateObjects.erase(obj);
}
+ virtual std::string GetDebugInfo() const;
+
private:
void LoadMapAndVMap(int gx, int gy);
void LoadVMap(int gx, int gy);
@@ -889,6 +891,8 @@ class TC_GAME_API InstanceMap : public Map
uint32 GetMaxResetDelay() const;
virtual void InitVisibilityDistance() override;
+
+ std::string GetDebugInfo() const override;
private:
bool m_resetAfterUnload;
bool m_unloadWhenEmpty;
diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp
index b45f3e48c67..ace2c4492e9 100644
--- a/src/server/game/Spells/Auras/SpellAuras.cpp
+++ b/src/server/game/Spells/Auras/SpellAuras.cpp
@@ -37,6 +37,7 @@
#include "Util.h"
#include "Vehicle.h"
#include "World.h"
+#include <sstream>
class ChargeDropEvent : public BasicEvent
{
@@ -293,8 +294,8 @@ void AuraApplication::ClientUpdate(bool remove)
uint32 Aura::BuildEffectMaskForOwner(SpellInfo const* spellProto, uint32 availableEffectMask, WorldObject* owner)
{
- ASSERT(spellProto);
- ASSERT(owner);
+ ASSERT_NODEBUGINFO(spellProto);
+ ASSERT_NODEBUGINFO(owner);
uint32 effMask = 0;
switch (owner->GetTypeId())
{
@@ -323,7 +324,7 @@ uint32 Aura::BuildEffectMaskForOwner(SpellInfo const* spellProto, uint32 availab
Aura* Aura::TryRefreshStackOrCreate(AuraCreateInfo& createInfo)
{
- ASSERT(createInfo.Caster || !createInfo.CasterGUID.IsEmpty());
+ ASSERT_NODEBUGINFO(createInfo.Caster || !createInfo.CasterGUID.IsEmpty());
if (createInfo.IsRefresh)
*createInfo.IsRefresh = false;
@@ -421,7 +422,7 @@ Aura* Aura::Create(AuraCreateInfo& createInfo)
effMask = createInfo._targetEffectMask;
effMask = Aura::BuildEffectMaskForOwner(createInfo._spellInfo, effMask, createInfo._owner);
- ASSERT(effMask);
+ ASSERT_NODEBUGINFO(effMask);
Unit* unit = createInfo._owner->ToUnit();
aura->ToUnitAura()->AddStaticApplication(unit, effMask);
@@ -429,7 +430,7 @@ Aura* Aura::Create(AuraCreateInfo& createInfo)
}
case TYPEID_DYNAMICOBJECT:
createInfo._auraEffectMask = Aura::BuildEffectMaskForOwner(createInfo._spellInfo, createInfo._auraEffectMask, createInfo._owner);
- ASSERT(createInfo._auraEffectMask);
+ ASSERT_NODEBUGINFO(createInfo._auraEffectMask);
aura = new DynObjAura(createInfo);
break;
@@ -2360,6 +2361,15 @@ void Aura::CallScriptAfterEffectProcHandlers(AuraEffect* aurEff, AuraApplication
}
}
+std::string Aura::GetDebugInfo() const
+{
+ std::stringstream sstr;
+ sstr << std::boolalpha
+ << "Id: " << GetId() << " Caster: " << GetCasterGUID().ToString()
+ << "\nOwner: " << (GetOwner() ? GetOwner()->GetDebugInfo() : "NULL");
+ return sstr.str();
+}
+
UnitAura::UnitAura(AuraCreateInfo const& createInfo)
: Aura(createInfo)
{
diff --git a/src/server/game/Spells/Auras/SpellAuras.h b/src/server/game/Spells/Auras/SpellAuras.h
index 8f843d5ab95..ee0e79b2604 100644
--- a/src/server/game/Spells/Auras/SpellAuras.h
+++ b/src/server/game/Spells/Auras/SpellAuras.h
@@ -302,6 +302,8 @@ class TC_GAME_API Aura
AuraEffectVector const& GetAuraEffects() const { return _effects; }
+ virtual std::string GetDebugInfo() const;
+
private:
AuraScript* GetScriptByType(std::type_info const& type) const;
void _DeleteRemovedApplications();
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index fb1a81e91eb..cbcf5218f14 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -57,6 +57,7 @@
#include "World.h"
#include "WorldSession.h"
#include <numeric>
+#include <sstream>
extern NonDefaultConstructible<SpellEffectHandlerFn> SpellEffectHandlers[TOTAL_SPELL_EFFECTS];
@@ -8189,6 +8190,15 @@ void Spell::CancelGlobalCooldown()
m_caster->ToUnit()->GetSpellHistory()->CancelGlobalCooldown(m_spellInfo);
}
+std::string Spell::GetDebugInfo() const
+{
+ std::stringstream sstr;
+ sstr << std::boolalpha
+ << "Id: " << GetSpellInfo()->Id << " OriginalCaster: " << m_originalCasterGUID.ToString()
+ << " State: " << getState();
+ return sstr.str();
+}
+
namespace Trinity
{
diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h
index 903930d58cd..981d03f8232 100644
--- a/src/server/game/Spells/Spell.h
+++ b/src/server/game/Spells/Spell.h
@@ -621,6 +621,8 @@ class TC_GAME_API Spell
int64 GetGameObjectTargetCountForEffect(SpellEffIndex effect) const;
int64 GetItemTargetCountForEffect(SpellEffIndex effect) const;
+ std::string GetDebugInfo() const;
+
protected:
bool HasGlobalCooldown() const;
void TriggerGlobalCooldown();