Plantage : m_playerStorage netait alloue nulle part
Le serveur est tombe le 24/08/2026 dans le Temple du Serpent de jade, SIGSEGV. Pile du vidage memoire, sans ambiguite : PlayerStorage::IsEntryExists <- spell_monk_mastery_combo_strikes::HandleHit <- Spell::HandleEffects <- HandleCastSpellOpcode Larret est a IsEntryExists+4, cest-a-dire au tout premier acces a this. m_playerStorage est DECLARE dans Player.h et lu par GetStorage(), mais alloue NULLE PART dans tout le depot : ni liste dinitialisation, ni corps du constructeur, aucune affectation. Le pointeur contenait donc des ordures des la construction du joueur. Quatre scripts du Moine le deferencent sans controle dans spell_monk.cpp — maitrise « Frappes combinees », Poings de furie. Le premier moine a en declencher un faisait tomber le worldserver. Ce netait quune question de temps : la classe est utilisee depuis toujours sans jamais avoir existe. La classe PlayerStorage est parfaitement fonctionnelle, il ne manquait que son allocation. Elle est desormais creee dans le constructeur et liberee dans le destructeur : le plantage disparait ET la maitrise du Moine devient operante. Ceinture et bretelles : les quatre appels recoivent en plus une garde de nullite, pour quun oubli similaire ne soit plus jamais fatal.
This commit is contained in:
@@ -146,6 +146,19 @@ uint64 const MAX_MONEY_AMOUNT = 99999999999ULL;
|
||||
|
||||
Player::Player(WorldSession* session) : Unit(true), m_sceneMgr(this), m_archaeologyPlayerMgr(this)
|
||||
{
|
||||
// SylvaniaCore : m_playerStorage etait DECLARE dans Player.h mais alloue
|
||||
// NULLE PART dans tout le depot. Le pointeur contenait donc des ordures
|
||||
// des la construction du joueur, et GetStorage() les renvoyait telles
|
||||
// quelles. Quatre scripts du Moine le deferencent sans controle
|
||||
// (spell_monk.cpp, maitrise « Frappes combinees » notamment) : le premier
|
||||
// moine a declencher lun deux faisait tomber le worldserver.
|
||||
// Plantage constate le 24/08/2026 dans le Temple du Serpent de jade,
|
||||
// pile : PlayerStorage::IsEntryExists <- spell_monk_mastery_combo_strikes.
|
||||
// La classe PlayerStorage est parfaitement fonctionnelle, il ne manquait
|
||||
// que son allocation : la fonctionnalite devient operante par la meme
|
||||
// occasion.
|
||||
m_playerStorage = new PlayerStorage(this);
|
||||
|
||||
_lastSummonedBattlePet = 0;
|
||||
|
||||
FakerMoveTimer = 0;
|
||||
@@ -425,6 +438,10 @@ Player::~Player()
|
||||
|
||||
delete PlayerTalkClass;
|
||||
|
||||
// SylvaniaCore : pendant de l'allocation ajoutee au constructeur.
|
||||
delete m_playerStorage;
|
||||
m_playerStorage = nullptr;
|
||||
|
||||
for (size_t x = 0; x < ItemSetEff.size(); x++)
|
||||
delete ItemSetEff[x];
|
||||
|
||||
|
||||
@@ -1283,6 +1283,8 @@ public:
|
||||
return false;
|
||||
|
||||
PlayerStorage* storage = caster->GetStorage();
|
||||
if (!storage)
|
||||
return false;
|
||||
|
||||
// Don't handle first cast after login or death
|
||||
if (!storage->IsEntryExists(STORAGE_MONK_COMBO_STRIKES))
|
||||
@@ -1385,6 +1387,9 @@ public:
|
||||
return;
|
||||
|
||||
PlayerStorage* storage = caster->ToPlayer()->GetStorage();
|
||||
if (!storage)
|
||||
return;
|
||||
|
||||
int32 spellId = (int32)GetSpellInfo()->Id;
|
||||
|
||||
if (storage->IsEntryExists(STORAGE_MONK_COMBO_STRIKES))
|
||||
@@ -1408,6 +1413,8 @@ public:
|
||||
return;
|
||||
|
||||
PlayerStorage* storage = caster->ToPlayer()->GetStorage();
|
||||
if (!storage)
|
||||
return;
|
||||
|
||||
// Prevent handling next cast
|
||||
storage->SetEntry(STORAGE_MONK_COMBO_STRIKES, (int32)GetSpellInfo()->Id + 1);
|
||||
@@ -1475,6 +1482,9 @@ public:
|
||||
|
||||
Player* player = caster->ToPlayer();
|
||||
PlayerStorage* storage = player->GetStorage();
|
||||
if (!storage)
|
||||
return;
|
||||
|
||||
int32 spellHandleId;
|
||||
|
||||
if (GetSpellInfo()->Id == SPELL_MONK_FISTS_OF_FURY_DAMAGE)
|
||||
|
||||
Reference in New Issue
Block a user