Browse Source

Fix #167: Addressed bad memory handling of threat transfer and potential hanging lua spell ptr

Emagi 1 year ago
parent
commit
397bf5f465

+ 5 - 0
EQ2/source/WorldServer/Entity.cpp

@@ -105,6 +105,7 @@ Entity::~Entity(){
 	immunities.clear();
 	if(!IsPlayer())
 		DeleteSpellEffects();
+	safe_delete(m_threatTransfer);
 }
 
 void Entity::DeleteSpellEffects(bool removeClient)
@@ -2139,6 +2140,10 @@ float Entity::GetAirSpeed() {
 	return ret;
 }
 
+void Entity::SetThreatTransfer(ThreatTransfer* transfer) {
+	safe_delete(m_threatTransfer);
+	m_threatTransfer = transfer;	
+}
 int8 Entity::GetTraumaCount() {
 	return det_count_list[DET_TYPE_TRAUMA];
 }

+ 1 - 1
EQ2/source/WorldServer/Entity.h

@@ -1687,7 +1687,7 @@ public:
 	void SetSpeed(float val, bool override_ = false) { if ((base_speed == 0.0f && val > 0.0f) || override_) base_speed = val;  speed = val; }
 	void SetSpeedMultiplier(float val) { speed_multiplier = val; }
 
-	void SetThreatTransfer(ThreatTransfer* transfer) { m_threatTransfer = transfer; }
+	void SetThreatTransfer(ThreatTransfer* transfer);
 	ThreatTransfer* GetThreatTransfer() { return m_threatTransfer; }
 	int8 GetTraumaCount();
 	int8 GetArcaneCount();

+ 5 - 2
EQ2/source/WorldServer/LuaFunctions.cpp

@@ -8894,8 +8894,11 @@ int EQ2Emu_lua_RemoveThreatTransfer(lua_State* state) {
 
 	if (((Entity*)spawn)->GetThreatTransfer() && ((Entity*)spawn)->GetThreatTransfer()->Spell == spell) {
 		ThreatTransfer* transfer = ((Entity*)spawn)->GetThreatTransfer();
-		((Entity*)spawn)->SetThreatTransfer(0);
-		safe_delete(transfer);
+		if(transfer && transfer->Spell != spell) {
+			lua_interface->LogError("%s: LUA RemoveThreatTransfer called, but there was a different spell set for the threat transfer.", lua_interface->GetScriptName(state));
+			return 0;
+		}
+		((Entity*)spawn)->SetThreatTransfer(nullptr);
 	}
 
 	return 0;

+ 3 - 1
EQ2/source/WorldServer/SpellProcess.cpp

@@ -379,7 +379,6 @@ bool SpellProcess::DeleteCasterSpell(LuaSpell* spell, string reason, bool removi
 	Spawn* target = 0;
 	bool target_valid = false;
 	if(spell) {
-		
 		spell->MSpellTargets.writelock(__FUNCTION__, __LINE__);
 		if(remove_target && spell->targets.size() > 1) {
 			for (int32 i = 0; i < spell->targets.size(); i++) {		
@@ -408,6 +407,9 @@ bool SpellProcess::DeleteCasterSpell(LuaSpell* spell, string reason, bool removi
 		if (active_spells.count(spell) > 0)
 			active_spells.Remove(spell);
 		if (spell->caster) {
+			if(spell->caster->GetThreatTransfer() && spell->caster->GetThreatTransfer()->Spell == spell) {
+				spell->caster->SetThreatTransfer(nullptr);
+			}
 			if (spell->spell->GetSpellData()->cast_type == SPELL_CAST_TYPE_TOGGLE){
 				
 				int8 actual_concentration = spell->spell->GetSpellData()->req_concentration;