1
0

Additional changes made to remove use of spell pointer in recast timer unlock spell logic, assure we have no crash in this area

This commit is contained in:
Emagi 2025-05-30 11:03:36 -04:00
parent 80f56f68c4
commit 6d52f19108
4 changed files with 33 additions and 3 deletions

View File

@ -2751,6 +2751,26 @@ void Player::UnlockSpell(Spell* spell) {
MSpellsBook.releasewritelock(__FUNCTION__, __LINE__);
}
void Player::UnlockSpell(int32 spell_id, int32 linked_timer_id) {
vector<SpellBookEntry*>::iterator itr;
SpellBookEntry* spell2;
MSpellsBook.writelock(__FUNCTION__, __LINE__);
for (itr = spells.begin(); itr != spells.end(); itr++) {
spell2 = *itr;
if (spell2->spell_id == spell_id || (linked_timer_id > 0 && linked_timer_id == spell2->timer))
{
spell2->in_use = false;
spell2->recast_available = 0;
if(all_spells_locked)
spell2->in_remiss = true;
else
AddSpellStatus(spell2, SPELL_STATUS_LOCK, false);
}
}
MSpellsBook.releasewritelock(__FUNCTION__, __LINE__);
}
void Player::LockTSSpells() {
vector<SpellBookEntry*>::iterator itr;

View File

@ -967,6 +967,7 @@ public:
/// <summary>Unlocks the given spell as well as all spells with shared timers</summary>
void UnlockSpell(Spell* spell);
void UnlockSpell(int32 spell_id, int32 linked_timer_id);
/// <summary>Locks all ts spells and unlocks all normal spells</summary>
void LockTSSpells();

View File

@ -242,8 +242,8 @@ void SpellProcess::Process(){
recast_timer = itr->value;
if(recast_timer->timer->Check(false)){
MaintainedEffects* effect = 0;
if(recast_timer->caster && (!(effect = recast_timer->caster->GetMaintainedSpell(recast_timer->spell_id)) || !effect->spell->spell->GetSpellData()->duration_until_cancel))
UnlockSpell(recast_timer->client, recast_timer->spell);
if(recast_timer->caster && !recast_timer->stay_locked && (!(effect = recast_timer->caster->GetMaintainedSpell(recast_timer->spell_id)) || !effect->spell->spell->GetSpellData()->duration_until_cancel))
UnlockSpell(recast_timer->client, recast_timer->spell_id, recast_timer->linked_timer);
safe_delete(recast_timer->timer);
recast_timers.Remove(recast_timer, true);
}
@ -357,7 +357,7 @@ void SpellProcess::CheckRecast(Spell* spell, Entity* caster, float timer_overrid
timer->type_group_spell_id = spell->GetSpellData()->type_group_spell_id;
timer->linked_timer = spell->GetSpellData()->linked_timer;
timer->spell_id = spell->GetSpellID();
timer->stay_locked = spell->GetStayLocked();
recast_timers.Add(timer);
}
if(caster->IsPlayer()){
@ -791,6 +791,13 @@ void SpellProcess::UnlockSpell(Client* client, Spell* spell){
}
}
void SpellProcess::UnlockSpell(Client* client, int32 spell_id, int32 link_timer_id){
if(client && client->GetPlayer() && spell_id) {
client->GetPlayer()->UnlockSpell(spell_id, link_timer_id);
SendSpellBookUpdate(client);
}
}
bool SpellProcess::CheckPower(LuaSpell* spell){
int16 req = 0;
if(spell->caster){

View File

@ -149,6 +149,7 @@ struct RecastTimer{
int32 spell_id;
int32 linked_timer;
int32 type_group_spell_id;
bool stay_locked;
};
/// <summary> Handles all spell casts for a zone, only 1 SpellProcess per zone </summary>
@ -259,6 +260,7 @@ public:
/// <param name='client'>The client to unlock the spell for</param>
/// <param name='spell'>The spell to unlock</param>
void UnlockSpell(Client* client, Spell* spell);
void UnlockSpell(Client* client, int32 spell_id, int32 link_timer_id);
/// <summary>Remove the given spell for the given caster from the SpellProcess</summary>
/// <param name='caster'>The spawn to remove the spell for</param>