Browse Source

Additional protections for GetZone not being set on spell->caster within LUA function usage

Emagi 1 year ago
parent
commit
ed35cb6516
2 changed files with 23 additions and 14 deletions
  1. 16 10
      EQ2/source/WorldServer/LuaFunctions.cpp
  2. 7 4
      EQ2/source/WorldServer/LuaInterface.cpp

+ 16 - 10
EQ2/source/WorldServer/LuaFunctions.cpp

@@ -6400,7 +6400,7 @@ int EQ2Emu_lua_GetWardAmountLeft(lua_State* state) {
 		return 0;
 	}
 
-	if (spell->caster->GetZone()->GetSpawnByID(spell->targets.at(0))->IsEntity()) {
+	if (spell->caster && spell->caster->GetZone() && spell->caster->GetZone()->GetSpawnByID(spell->targets.at(0))->IsEntity()) {
 		Entity* target = (Entity*)spell->caster->GetZone()->GetSpawnByID(spell->targets.at(0));
 		WardInfo* ward = target->GetWard(spell->spell->GetSpellID());
 		if (ward) {
@@ -6426,7 +6426,7 @@ int EQ2Emu_lua_GetWardValue(lua_State* state) {
 
 	lua_interface->ResetFunctionStack(state);
 	
-	if (spell->caster->GetZone()->GetSpawnByID(spell->targets.at(0))->IsEntity()) {
+	if (spell->caster && spell->caster->GetZone() && spell->caster->GetZone()->GetSpawnByID(spell->targets.at(0))->IsEntity()) {
 
 		Entity* target = (Entity*)spell->caster->GetZone()->GetSpawnByID(spell->targets.at(0));
 		WardInfo* ward = target->GetWard(spell->spell->GetSpellID());
@@ -8393,7 +8393,7 @@ int EQ2Emu_lua_AddProc(lua_State* state) {
 		return 0;
 	}
 	
-	if (spell && use_all_spelltargets) {
+	if (spell && spell->caster && spell->caster->GetZone() && use_all_spelltargets) {
 		Spawn* target;
 		spell->MSpellTargets.readlock(__FUNCTION__, __LINE__);
 		for (int8 i = 0; i < spell->targets.size(); i++) {
@@ -8441,7 +8441,7 @@ int EQ2Emu_lua_RemoveProc(lua_State* state) {
 		return 0;
 	}
 
-	if (spell) {
+	if (spell && spell->caster && spell->caster->GetZone()) {
 		Spawn* target;
 		spell->MSpellTargets.readlock(__FUNCTION__, __LINE__);
 		for (int8 i = 0; i < spell->targets.size(); i++) {
@@ -8762,7 +8762,7 @@ int EQ2Emu_lua_AddSpellTimer(lua_State* state) {
 		return 0;
 	}
 
-	if (!spell) {
+	if (!spell || (!spell->caster || !spell->caster->GetZone())) {
 		lua_interface->LogError("%s: LUA AddSpellTimer command error: spell not found, AddSpellTimer must be used in a spell script", lua_interface->GetScriptName(state));
 		return 0;
 	}
@@ -9545,6 +9545,12 @@ int EQ2Emu_lua_RemoveTriggerFromSpell(lua_State* state) {
 		lua_interface->ResetFunctionStack(state);
 		return 0;
 	}
+	
+	if (!spell->caster || !spell->caster->GetZone()) {
+		lua_interface->LogError("%s: LUA RemoveTriggerFromSpell command error: caster / caster zone must be set!", lua_interface->GetScriptName(state));
+		lua_interface->ResetFunctionStack(state);
+		return 0;
+	}
 
 	int16 remove_count = lua_interface->GetInt16Value(state);
 
@@ -9631,7 +9637,7 @@ int EQ2Emu_lua_AddImmunitySpell(lua_State* state) {
 		Entity* entity = ((Entity*)spawn);
 		entity->AddImmunity(spell, type);
 	}
-	else {
+	else if(spell->caster && spell->caster->GetZone()) {
 		spell->MSpellTargets.readlock(__FUNCTION__, __LINE__);
 		for (int8 i = 0; i < spell->targets.size(); i++) {
 			spawn = spell->caster->GetZone()->GetSpawnByID(spell->targets.at(i));
@@ -9668,7 +9674,7 @@ int EQ2Emu_lua_RemoveImmunitySpell(lua_State* state) {
 		Entity* entity = ((Entity*)spawn);
 		entity->RemoveImmunity(spell, type);
 	}
-	else {
+	else if(spell->caster && spell->caster->GetZone()) {
 		spell->MSpellTargets.readlock(__FUNCTION__, __LINE__);
 		for (int8 i = 0; i < spell->targets.size(); i++) {
 			spawn = spell->caster->GetZone()->GetSpawnByID(spell->targets.at(i));
@@ -9715,7 +9721,7 @@ int EQ2Emu_lua_SetSpellSnareValue(lua_State* state) {
 
 		((Entity*)spawn)->SetSnareValue(spell, val);
 	}
-	else {
+	else if(spell->caster && spell->caster->GetZone()) {
 		spell->MSpellTargets.readlock(__FUNCTION__, __LINE__);
 		for (int8 i = 0; i < spell->targets.size(); i++) {
 			spawn = spell->caster->GetZone()->GetSpawnByID(spell->targets.at(i));
@@ -10912,13 +10918,13 @@ int EQ2Emu_lua_Evac(lua_State* state) {
 
 		LuaSpell* spell = lua_interface->GetCurrentSpell(state);
 		
-		if(!spell) {
+		if(!spell || !spell->caster || !spell->caster->GetZone()) {
 			lua_interface->ResetFunctionStack(state);
 			return 0;
 		}
 		
 		ZoneServer* zone = spell->caster->GetZone();
-
+		
 		float x = spell->caster->GetZone()->GetSafeX();
 		float y = spell->caster->GetZone()->GetSafeY();
 		float z = spell->caster->GetZone()->GetSafeZ();

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

@@ -572,7 +572,7 @@ std::string LuaInterface::AddSpawnPointers(LuaSpell* spell, bool first_cast, boo
 		SetSpellValue(spell->state, spell);
 
 	Spawn* temp_spawn = 0;
-	if (timer && timer->caster && spell->caster)
+	if (timer && timer->caster && spell->caster && spell->caster->GetZone())
 		temp_spawn = spell->caster->GetZone()->GetSpawnByID(timer->caster);
 
 	if (temp_spawn)
@@ -582,7 +582,7 @@ std::string LuaInterface::AddSpawnPointers(LuaSpell* spell, bool first_cast, boo
 
 	temp_spawn = 0;
 
-	if (timer && timer->target && spell->caster)
+	if (timer && timer->target && spell->caster && spell->caster->GetZone())
 		temp_spawn = spell->caster->GetZone()->GetSpawnByID(timer->target);
 
 	if (temp_spawn)
@@ -822,6 +822,9 @@ void LuaInterface::RemoveSpell(LuaSpell* spell, bool call_remove_function, bool
 			else if(spell->caster->GetZone()) {
 				spawn_wrapper->spawn = spell->caster->GetZone()->GetSpawnByID(spell->initial_target);
 			}
+			else {
+				spawn_wrapper->spawn = nullptr; // we need it set to something or else the ptr could be loose
+			}
 			AddUserDataPtr(spawn_wrapper, spawn_wrapper->spawn);
 			lua_pushlightuserdata(spell->state, spawn_wrapper);
 		}
@@ -1549,10 +1552,10 @@ void LuaInterface::DeletePendingSpells(bool all) {
 			spell = *del_itr;
 			
 			
-			if (spell->caster) {
+			if (spell->caster && spell->caster->GetZone()) {
 				spell->caster->GetZone()->GetSpellProcess()->DeleteActiveSpell(spell);
 			}
-			else if(spell->targets.size() > 0) {
+			else if(spell->targets.size() > 0 && spell->caster && spell->caster->GetZone()) {
 				spell->MSpellTargets.readlock(__FUNCTION__, __LINE__);
 				for (int8 i = 0; i < spell->targets.size(); i++) {
 					Spawn* target = spell->caster->GetZone()->GetSpawnByID(spell->targets.at(i));