Browse Source

Mutex handling fixes, ptr crash fix and loose pointer cleanup related to lua spells

Emagi 1 month ago
parent
commit
27130d0aae

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

@@ -1777,7 +1777,7 @@ void Entity::CalculateSpellBonuses(ItemStatsValues* stats){
 			for (tier_itr = sort_itr->second.begin(); tier_itr != sort_itr->second.end(); tier_itr++){
 				LuaSpell* current_spell = tier_itr->first;
 				sint8 current_tier = 0;
-				if (current_spell && ((current_tier = current_spell->spell->GetSpellTier()) > highest_tier)) {
+				if (current_spell && current_spell->spell && ((current_tier = current_spell->spell->GetSpellTier()) > highest_tier)) {
 					highest_tier = current_tier;
 					key = current_spell;
 				}

+ 22 - 4
EQ2/source/WorldServer/LuaInterface.cpp

@@ -523,7 +523,7 @@ const char* LuaInterface::GetScriptName(lua_State* state)
 	MRegionScripts.releasewritelock(__FUNCTION__, __LINE__);
 
 	MSpells.lock();
-	LuaSpell* spell = GetCurrentSpell(state);
+	LuaSpell* spell = GetCurrentSpell(state, false);
 	if (spell)
 	{
 		const char* fileName = (spell->file_name.length() > 0) ? spell->file_name.c_str() : "";
@@ -609,10 +609,27 @@ std::string LuaInterface::AddSpawnPointers(LuaSpell* spell, bool first_cast, boo
 	return functionCalled;
 }
 
-LuaSpell* LuaInterface::GetCurrentSpell(lua_State* state) {
+LuaSpell* LuaInterface::GetCurrentSpell(lua_State* state, bool needsLock) {
+	LuaSpell* spell = 0;
+	
+	if(needsLock)
+		MSpells.lock();
+	
 	if(current_spells.count(state) > 0)
-		return current_spells[state];
-	return 0;
+		spell = current_spells[state];
+	
+	if(needsLock)
+		MSpells.unlock();
+	
+	return spell;
+}
+
+void LuaInterface::RemoveCurrentSpell(lua_State* state) {
+	MSpells.lock();
+	map<lua_State*, LuaSpell*>::iterator itr = current_spells.find(state);
+	if(itr != current_spells.end())
+		current_spells.erase(itr);
+	MSpells.unlock();
 }
 
 bool LuaInterface::CallSpellProcess(LuaSpell* spell, int8 num_parameters, std::string customFunction) {
@@ -1589,6 +1606,7 @@ void LuaInterface::DeletePendingSpells(bool all) {
 			}
 
 			SetLuaUserDataStale(spell);
+			RemoveCurrentSpell(spell->state);
 			safe_delete(spell);
 		}
 	}

+ 2 - 1
EQ2/source/WorldServer/LuaInterface.h

@@ -232,7 +232,8 @@ public:
 	void			SetOptionWindowValue(lua_State* state, vector<OptionWindowOption>* optionWindow);
 
 	std::string		AddSpawnPointers(LuaSpell* spell, bool first_cast, bool precast = false, const char* function = 0, SpellScriptTimer* timer = 0, bool passLuaSpell=false, Spawn* altTarget = 0);
-	LuaSpell*		GetCurrentSpell(lua_State* state);
+	LuaSpell*		GetCurrentSpell(lua_State* state, bool needsLock = true);
+	void			RemoveCurrentSpell(lua_State* state);
 	bool			CallSpellProcess(LuaSpell* spell, int8 num_parameters, std::string functionCalled);
 	LuaSpell*		GetSpell(const char* name);
 	void			UseItemScript(const char* name, lua_State* state, bool val);

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

@@ -2931,6 +2931,7 @@ void SpellProcess::DeleteSpell(LuaSpell* spell)
 	}
 	
 	lua_interface->SetLuaUserDataStale(spell);
+	lua_interface->RemoveCurrentSpell(spell->state);
 	safe_delete(spell);
 }