Browse Source

- ZoneServer::GetClientBySpawn removed, no longer using the MutexMap to track the client, use the Player class instead.
- Addressed a crash cancelling a player trade
- Addressed a crash with spawn change packets overflowing during Pack()

Emagi 5 months ago
parent
commit
d32141898e

+ 2 - 3
EQ2/source/WorldServer/Bots/Bot.cpp

@@ -724,9 +724,8 @@ void Bot::Begin_Camp() {
 	if (!GetOwner())
 		return;
 
-	Client* client = GetZone()->GetClientBySpawn(GetOwner());
-	if (client)
-		client->GetPlayer()->SpawnedBots.erase(BotIndex);
+	if (GetOwner()->IsPlayer())
+		((Player*)GetOwner())->SpawnedBots.erase(BotIndex);
 	
 	camping = false;
 	immediate_camp = true;

+ 18 - 14
EQ2/source/WorldServer/Combat.cpp

@@ -102,7 +102,7 @@ bool Entity::AttackAllowed(Entity* target, float distance, bool range_attack) {
 	}
 
 	if (IsPlayer())
-		client = GetZone()->GetClientBySpawn(this);
+		client = ((Player*)this)->GetClient();
 
 	if (IsPet())
 		attacker = ((NPC*)this)->GetOwner();
@@ -328,10 +328,12 @@ void Entity::RangeAttack(Spawn* victim, float distance, Item* weapon, Item* ammo
 				else
 					((Player*)this)->equipment_list.RemoveItem(ammo->details.slot_id, true);
 
-				Client* client = GetZone()->GetClientBySpawn(this);
-				EQ2Packet* outapp = ((Player*)this)->GetEquipmentList()->serialize(client->GetVersion(), (Player*)this);
-				if(outapp)
-					client->QueuePacket(outapp);
+				Client* client = ((Player*)this)->GetClient();
+				if(client) {
+					EQ2Packet* outapp = ((Player*)this)->GetEquipmentList()->serialize(client->GetVersion(), (Player*)this);
+					if(outapp)
+						client->QueuePacket(outapp);
+				}
 			}
 
 			if(victim->IsNPC() && victim->EngagedInCombat() == false) {
@@ -434,7 +436,7 @@ bool Entity::SpellAttack(Spawn* victim, float distance, LuaSpell* luaspell, int8
 		if(spell->GetSpellData()->success_message.length() > 0){
 			Client* client = nullptr;
 			if(IsPlayer())
-				client = GetZone()->GetClientBySpawn(this);
+				client = ((Player*)this)->GetClient();
 			if(client){
 				string success_message = spell->GetSpellData()->success_message;
 				if(success_message.find("%t") < 0xFFFFFFFF)
@@ -495,7 +497,7 @@ bool Entity::SpellAttack(Spawn* victim, float distance, LuaSpell* luaspell, int8
 			else {
 				Client* client = 0;
 				if(IsPlayer())
-					client = GetZone()->GetClientBySpawn(this);
+					client = ((Player*)this)->GetClient();
 				if(client) {
 					client->GetPlayer()->InCombat(true, client->GetPlayer()->GetRangeAttack());
 				}
@@ -536,7 +538,7 @@ bool Entity::ProcAttack(Spawn* victim, int8 damage_type, int32 low_damage, int32
 		if (success_msg.length() > 0) {
 			Client* client = 0;
 			if(IsPlayer())
-				client = GetZone()->GetClientBySpawn(this);
+				client = ((Player*)this)->GetClient();
 			if(client) {
 				if(success_msg.find("%t") < 0xFFFFFFFF)
 					success_msg.replace(success_msg.find("%t"), 2, victim->GetName());
@@ -1349,12 +1351,14 @@ void Entity::KillSpawn(Spawn* dead, int8 type, int8 damage_type, int16 kill_blow
 		return;
 
 	if (IsPlayer()) {
-		Client* client = GetZone()->GetClientBySpawn(this);
-		PacketStruct* packet = configReader.getStruct("WS_EnterCombat", client->GetVersion());
-		if (packet) {
-			client->QueuePacket(packet->serialize());
+		Client* client = ((Player*)this)->GetClient();
+		if(client) {
+			PacketStruct* packet = configReader.getStruct("WS_EnterCombat", client->GetVersion());
+			if (packet) {
+				client->QueuePacket(packet->serialize());
+			}
+			safe_delete(packet);
 		}
-		safe_delete(packet);
 
 		((Player*)this)->InCombat(false);
 	}
@@ -1511,7 +1515,7 @@ void Player::ProcessCombat() {
 				RangeAttack(combat_target, distance, weapon, ammo);
 			}
 			else {
-				Client* client = GetZone()->GetClientBySpawn(this);
+				Client* client = ((Player*)this)->GetClient();
 				if (client) {
 					// Need to get messages from live, made these up so the player knows what is wrong in game if weapon or ammo are not valid
 					if (!ammo)

+ 66 - 32
EQ2/source/WorldServer/Commands/Commands.cpp

@@ -2095,7 +2095,7 @@ void Commands::Process(int32 index, EQ2_16BitString* command_parms, Client* clie
 			if(sep && sep->arg[1][0] && sep->IsNumber(1)){
 				if(strcmp(sep->arg[0], "inventory") == 0){
 					int32 item_index = atol(sep->arg[1]);
-					
+					//printf("Index provided: %u\n",item_index);
 					if(client->GetVersion() <= 546 && item_index <= 255) {
 						item_index = 255 - item_index;
 					}
@@ -3145,7 +3145,7 @@ void Commands::Process(int32 index, EQ2_16BitString* command_parms, Client* clie
 			if (!target && client->GetPlayer()->GetTarget() && client->GetPlayer()->GetTarget()->IsEntity()) {
 				target = (Entity*)client->GetPlayer()->GetTarget();
 				if (target->IsPlayer()) {
-					target_client = client->GetCurrentZone()->GetClientBySpawn(target);
+					target_client = ((Player*)target)->GetClient();
 				}
 			}
 
@@ -6295,12 +6295,13 @@ void Commands::Command_Guild(Client* client, Seperator* sep)
 		{
 			PendingGuildInvite* pgi = client->GetPendingGuildInvite();
 
-			if (pgi && pgi->guild && pgi->invited_by)
+			if (pgi && pgi->guild && pgi->invited_by && pgi->invited_by->IsPlayer())
 			{
-				Client* client_inviter = pgi->invited_by->GetZone()->GetClientBySpawn(pgi->invited_by);
+				Client* client_inviter = ((Player*)pgi->invited_by)->GetClient();
 
-				if (client_inviter)
+				if (client_inviter) {
 					client_inviter->Message(CHANNEL_NARRATIVE, "%s has declined your invitation to join %s.", client->GetPlayer()->GetName(), pgi->guild->GetName());
+				}
 			}
 			client->SetPendingGuildInvite(0);
 		}
@@ -6483,7 +6484,7 @@ void Commands::Command_GuildsAdd(Client* client, Seperator* sep)
 			if (sep->arg[1] && strlen(sep->arg[1]) > 0)
 				to_client = zone_list.GetClientByCharName(string(sep->arg[1]));
 			else if (client->GetPlayer()->GetTarget() && client->GetPlayer()->GetTarget()->IsPlayer())
-				to_client = client->GetPlayer()->GetTarget()->GetZone()->GetClientBySpawn(client->GetPlayer()->GetTarget());
+				to_client = ((Player*)client->GetPlayer()->GetTarget())->GetClient();
 
 			if (to_client)
 				guild->InvitePlayer(client, to_client->GetPlayer()->GetName());
@@ -6526,7 +6527,7 @@ void Commands::Command_GuildsCreate(Client* client, Seperator* sep)
 			}
 			else if (client->GetPlayer()->GetTarget() && client->GetPlayer()->GetTarget()->IsPlayer()) 
 			{
-				Client* to_client = client->GetPlayer()->GetTarget()->GetZone()->GetClientBySpawn(client->GetPlayer()->GetTarget());
+				Client* to_client = ((Player*)client->GetPlayer()->GetTarget())->GetClient();
 
 				if (to_client) 
 				{
@@ -6664,7 +6665,7 @@ void Commands::Command_GuildsRemove(Client* client, Seperator* sep)
 			if (sep->arg[1] && strlen(sep->arg[1]) > 0)
 				to_client = zone_list.GetClientByCharName(string(sep->arg[1]));
 			else if (client->GetPlayer()->GetTarget() && client->GetPlayer()->GetTarget()->IsPlayer())
-				to_client = client->GetPlayer()->GetTarget()->GetZone()->GetClientBySpawn(client->GetPlayer()->GetTarget());
+				to_client = ((Player*)client->GetPlayer()->GetTarget())->GetClient();
 
 			if (to_client) 
 			{
@@ -7491,8 +7492,11 @@ void Commands::Command_ModifyCharacter(Client* client, Seperator* sep)
 	int64 value = 0;
 
 	Player* player = client->GetPlayer();
-	if (player->HasTarget() && player->GetTarget()->IsPlayer())
+	Client* targetClient = client;
+	if (player->HasTarget() && player->GetTarget()->IsPlayer()) {
 		player = (Player*)player->GetTarget();
+		targetClient = player->GetClient();
+	}
 
 	// need at least 2 args for a valid command
 	if( sep && sep->arg[1] )
@@ -7511,7 +7515,9 @@ void Commands::Command_ModifyCharacter(Client* client, Seperator* sep)
 				}
 				else {
 					client->Message(CHANNEL_COLOR_YELLOW, "You give %s %llu copper coin%s", player->GetName(), value, (value > 1 ? "s" : ""));
-					client->GetCurrentZone()->GetClientBySpawn(player)->Message(CHANNEL_COLOR_YELLOW, "%s gave you %llu copper coin%s", client->GetPlayer()->GetName(), value, (value > 1 ? "s" : ""));
+					if(targetClient) {
+						targetClient->Message(CHANNEL_COLOR_YELLOW, "%s gave you %llu copper coin%s", client->GetPlayer()->GetName(), value, (value > 1 ? "s" : ""));
+					}
 				}
 			}
 
@@ -7525,7 +7531,9 @@ void Commands::Command_ModifyCharacter(Client* client, Seperator* sep)
 				}
 				else {
 					client->Message(CHANNEL_COLOR_YELLOW, "You give %s %llu silver coin%s", player->GetName(), value / 100, (value > 1 ? "s" : ""));
-					client->GetCurrentZone()->GetClientBySpawn(player)->Message(CHANNEL_COLOR_YELLOW, "%s gave you %llu silver coin%s", client->GetPlayer()->GetName(), value / 100, (value > 1 ? "s" : ""));
+					if(targetClient) {
+						targetClient->Message(CHANNEL_COLOR_YELLOW, "%s gave you %llu silver coin%s", client->GetPlayer()->GetName(), value / 100, (value > 1 ? "s" : ""));
+					}
 				}
 			}
 
@@ -7539,7 +7547,9 @@ void Commands::Command_ModifyCharacter(Client* client, Seperator* sep)
 				}
 				else {
 					client->Message(CHANNEL_COLOR_YELLOW, "You give %s %llu gold coin%s", player->GetName(), value / 10000, (value > 1 ? "s" : ""));
-					client->GetCurrentZone()->GetClientBySpawn(player)->Message(CHANNEL_COLOR_YELLOW, "%s gave you %llu gold coin%s", client->GetPlayer()->GetName(), value / 10000, (value > 1 ? "s" : ""));
+					if(targetClient) {
+						targetClient->Message(CHANNEL_COLOR_YELLOW, "%s gave you %llu gold coin%s", client->GetPlayer()->GetName(), value / 10000, (value > 1 ? "s" : ""));
+					}
 				}
 			}
 
@@ -7553,7 +7563,9 @@ void Commands::Command_ModifyCharacter(Client* client, Seperator* sep)
 				}
 				else {
 					client->Message(CHANNEL_COLOR_YELLOW, "You give %s %llu platinum coin%s", player->GetName(), value / 1000000, (value > 1 ? "s" : ""));
-					client->GetCurrentZone()->GetClientBySpawn(player)->Message(CHANNEL_COLOR_YELLOW, "%s gave you %llu platinum coin%s", client->GetPlayer()->GetName(), value / 1000000, (value > 1 ? "s" : ""));
+					if(targetClient) {				
+						targetClient->Message(CHANNEL_COLOR_YELLOW, "%s gave you %llu platinum coin%s", client->GetPlayer()->GetName(), value / 1000000, (value > 1 ? "s" : ""));
+					}
 				}
 			}
 
@@ -7578,7 +7590,9 @@ void Commands::Command_ModifyCharacter(Client* client, Seperator* sep)
 				}
 				else {
 					client->Message(CHANNEL_COLOR_YELLOW, "You take %llu copper coin%s from %s", value, (value > 1 ? "s" : ""), player->GetName());
-					client->GetCurrentZone()->GetClientBySpawn(player)->Message(CHANNEL_COLOR_YELLOW, "%s takes %llu copper coin%s from you", client->GetPlayer()->GetName(), value, (value > 1 ? "s" : ""));
+					if(targetClient) {				
+						targetClient->Message(CHANNEL_COLOR_YELLOW, "%s takes %llu copper coin%s from you", client->GetPlayer()->GetName(), value, (value > 1 ? "s" : ""));
+					}
 				}
 			}
 
@@ -7592,7 +7606,9 @@ void Commands::Command_ModifyCharacter(Client* client, Seperator* sep)
 				}
 				else {
 					client->Message(CHANNEL_COLOR_YELLOW, "You take %llu silver coin%s from %s", value / 100, (value > 1 ? "s" : ""), player->GetName());
-					client->GetCurrentZone()->GetClientBySpawn(player)->Message(CHANNEL_COLOR_YELLOW, "%s takes %llu silver coin%s from you", client->GetPlayer()->GetName(), value / 100, (value > 1 ? "s" : ""));
+					if(targetClient) {				
+						targetClient->Message(CHANNEL_COLOR_YELLOW, "%s takes %llu silver coin%s from you", client->GetPlayer()->GetName(), value / 100, (value > 1 ? "s" : ""));
+					}
 				}
 			}
 
@@ -7606,7 +7622,9 @@ void Commands::Command_ModifyCharacter(Client* client, Seperator* sep)
 				}
 				else {
 					client->Message(CHANNEL_COLOR_YELLOW, "You take %llu gold coin%s from %s", value / 10000, (value > 1 ? "s" : ""), player->GetName());
-					client->GetCurrentZone()->GetClientBySpawn(player)->Message(CHANNEL_COLOR_YELLOW, "%s takes %llu gold coin%s from you", client->GetPlayer()->GetName(), value / 10000, (value > 1 ? "s" : ""));
+					if(targetClient) {
+						targetClient->Message(CHANNEL_COLOR_YELLOW, "%s takes %llu gold coin%s from you", client->GetPlayer()->GetName(), value / 10000, (value > 1 ? "s" : ""));
+					}
 				}
 			}
 
@@ -7620,7 +7638,9 @@ void Commands::Command_ModifyCharacter(Client* client, Seperator* sep)
 				}
 				else {
 					client->Message(CHANNEL_COLOR_YELLOW, "You take %llu platinum coin%s from %s", value / 1000000, (value > 1 ? "s" : ""), player->GetName());
-					client->GetCurrentZone()->GetClientBySpawn(player)->Message(CHANNEL_COLOR_YELLOW, "%s takes %llu platinum coin%s from you", client->GetPlayer()->GetName(), value / 1000000, (value > 1 ? "s" : ""));
+					if(targetClient) {
+						targetClient->Message(CHANNEL_COLOR_YELLOW, "%s takes %llu platinum coin%s from you", client->GetPlayer()->GetName(), value / 1000000, (value > 1 ? "s" : ""));
+					}
 				}
 			}
 
@@ -7640,8 +7660,8 @@ void Commands::Command_ModifyCharacter(Client* client, Seperator* sep)
 					if (player) {
 						if (client->GetPlayer() == player)
 							client->ChangeTSLevel(player->GetTSLevel(), level);
-						else
-							player->GetZone()->GetClientBySpawn(player)->ChangeTSLevel(player->GetTSLevel(), level);
+						else if(targetClient)
+							targetClient->ChangeTSLevel(player->GetTSLevel(), level);
 					}
 				}
 				else
@@ -7731,8 +7751,11 @@ void Commands::Command_ModifyQuest(Client* client, Seperator* sep)
 	int64 value = 0;
 
 	Player* player = client->GetPlayer();
-	if (player->HasTarget() && player->GetTarget()->IsPlayer())
+	Client* targetClient = client;
+	if (player->HasTarget() && player->GetTarget()->IsPlayer()) {
 		player = (Player*)player->GetTarget();
+		targetClient = player->GetClient();
+	}
 
 	// need at least 2 args for a valid command
 
@@ -7801,7 +7824,9 @@ void Commands::Command_ModifyQuest(Client* client, Seperator* sep)
 						else
 						{
 							client->Message(CHANNEL_COLOR_YELLOW, "You have removed the quest %s from %s's journal", quest->GetName(), player->GetName());
-							client->GetCurrentZone()->GetClientBySpawn(player)->Message(CHANNEL_COLOR_YELLOW, "%s has removed the quest %s from your journal", client->GetPlayer()->GetName(), quest->GetName());
+							if(targetClient) {
+								targetClient->Message(CHANNEL_COLOR_YELLOW, "%s has removed the quest %s from your journal", client->GetPlayer()->GetName(), quest->GetName());
+							}
 						}
 					LogWrite(COMMAND__INFO, 0, "GM Command", "%s removed the quest %s from %s", client->GetPlayer()->GetName(), quest->GetName(), player->GetName());
 					lua_interface->CallQuestFunction(quest, "Deleted", client->GetPlayer());
@@ -7892,7 +7917,7 @@ void Commands::Command_ModifySkill(Client* client, Seperator* sep)
 
 				if (client->GetPlayer()->GetTarget() && client->GetPlayer()->GetTarget()->IsPlayer()) {
 					player = (Player*)client->GetPlayer()->GetTarget();
-					to_client = client->GetCurrentZone()->GetClientBySpawn(player);
+					to_client = player->GetClient();
 				}
 				else {
 					player = client->GetPlayer();
@@ -7929,7 +7954,7 @@ void Commands::Command_ModifySkill(Client* client, Seperator* sep)
 
 				if (client->GetPlayer()->GetTarget() && client->GetPlayer()->GetTarget()->IsPlayer()) {
 					player = (Player*)client->GetPlayer()->GetTarget();
-					to_client = client->GetCurrentZone()->GetClientBySpawn(player);
+					to_client = player->GetClient();
 				}
 				else {
 					player = client->GetPlayer();
@@ -7946,7 +7971,9 @@ void Commands::Command_ModifySkill(Client* client, Seperator* sep)
 						}
 						else {
 							client->Message(CHANNEL_STATUS, "Removed skill '%s' from player %s.", skill_name, player->GetName());
-							to_client->Message(CHANNEL_STATUS, "%s has removed skill '%s' from you.", client->GetPlayer()->GetName(), skill_name);
+							if(to_client) {
+								to_client->Message(CHANNEL_STATUS, "%s has removed skill '%s' from you.", client->GetPlayer()->GetName(), skill_name);
+							}
 						}
 					}
 					else {
@@ -7975,7 +8002,7 @@ void Commands::Command_ModifySkill(Client* client, Seperator* sep)
 
 				if (client->GetPlayer()->GetTarget() && client->GetPlayer()->GetTarget()->IsPlayer()) {
 					player = (Player*)client->GetPlayer()->GetTarget();
-					to_client = client->GetCurrentZone()->GetClientBySpawn(player);
+					to_client = player->GetClient();
 				}
 				else {
 					player = client->GetPlayer();
@@ -7988,8 +8015,9 @@ void Commands::Command_ModifySkill(Client* client, Seperator* sep)
 						player->GetSkills()->SetSkill(skill->skill_id, val);
 						if (client != to_client)
 							client->Message(CHANNEL_STATUS, "You set %s's '%s' skill to %i.", player->GetName(), skill_name, val);
-
-						to_client->Message(CHANNEL_STATUS, "Your '%s' skill has been set to %i.", skill_name, val);
+						if(to_client) {
+							to_client->Message(CHANNEL_STATUS, "Your '%s' skill has been set to %i.", skill_name, val);
+						}
 					}
 					else {
 						client->Message(CHANNEL_STATUS, "Target does not have the skill '%s'.", skill_name);
@@ -8632,7 +8660,7 @@ void Commands::Command_Skills(Client* client, Seperator* sep, int handler)
 	Client* to_client = 0;
 
 	if(client->GetPlayer()->GetTarget() && client->GetPlayer()->GetTarget()->IsPlayer())
-		to_client = client->GetPlayer()->GetTarget()->GetZone()->GetClientBySpawn(client->GetPlayer()->GetTarget());
+		to_client = ((Player*)client->GetPlayer()->GetTarget())->GetClient();
 
 	switch(handler)
 	{
@@ -11363,9 +11391,11 @@ void Commands::Command_Player_Coins(Client* client, Seperator* sep) {
 	// /player coins add 10
 	// /player coins add plat 10
 	Player* player = client->GetPlayer();
-	if (player->HasTarget() && player->GetTarget()->IsPlayer())
+	Client* targetClient = client;
+	if (player->HasTarget() && player->GetTarget()->IsPlayer()) {
 		player = (Player*)player->GetTarget();
-
+		targetClient = player->GetClient();
+	}
 
 	if (sep && sep->arg[0] && sep->arg[1]) {
 		const char* action = sep->arg[0];
@@ -11380,7 +11410,9 @@ void Commands::Command_Player_Coins(Client* client, Seperator* sep) {
 					client->Message(CHANNEL_COLOR_YELLOW, "You give yourself %llu coin%s", value, (value > 1 ? "s" : ""));
 				else {
 					client->Message(CHANNEL_COLOR_YELLOW, "You give %s %llu coin%s", player->GetName(), value, (value > 1 ? "s" : ""));
-					client->GetCurrentZone()->GetClientBySpawn(player)->Message(CHANNEL_COLOR_YELLOW, "%s gave you %llu coin%s", client->GetPlayer()->GetName(), value, (value > 1 ? "s" : ""));
+					if(targetClient) {
+						targetClient->Message(CHANNEL_COLOR_YELLOW, "%s gave you %llu coin%s", client->GetPlayer()->GetName(), value, (value > 1 ? "s" : ""));
+					}
 				}
 
 				return;
@@ -11405,7 +11437,9 @@ void Commands::Command_Player_Coins(Client* client, Seperator* sep) {
 					client->Message(CHANNEL_COLOR_YELLOW, "You give yourself %llu coin%s", value, (value > 1 ? "s" : ""));
 				else {
 					client->Message(CHANNEL_COLOR_YELLOW, "You give %s %llu coin%s", player->GetName(), value, (value > 1 ? "s" : ""));
-					client->GetCurrentZone()->GetClientBySpawn(player)->Message(CHANNEL_COLOR_YELLOW, "%s gave you %llu coin%s", client->GetPlayer()->GetName(), value, (value > 1 ? "s" : ""));
+					if(targetClient) {
+						targetClient->Message(CHANNEL_COLOR_YELLOW, "%s gave you %llu coin%s", client->GetPlayer()->GetName(), value, (value > 1 ? "s" : ""));
+					}
 				}
 				return;
 			}

+ 20 - 14
EQ2/source/WorldServer/Entity.cpp

@@ -2139,7 +2139,7 @@ int32 Entity::CheckWards(Entity* attacker, int32 damage, int8 damage_type) {
 
 			spell->damage_remaining = ward->DamageLeft;
 			if (spell->caster->IsPlayer())
-				ClientPacketFunctions::SendMaintainedExamineUpdate(GetZone()->GetClientBySpawn(spell->caster), spell->slot_pos, ward->DamageLeft, 1);
+				ClientPacketFunctions::SendMaintainedExamineUpdate(((Player*)spell->caster)->GetClient(), spell->slot_pos, ward->DamageLeft, 1);
 
 			if (!redirectDamage)
 				GetZone()->SendHealPacket(ward->Spell->caster, this, HEAL_PACKET_TYPE_ABSORB, damage, spell->spell->GetName());
@@ -2153,13 +2153,17 @@ int32 Entity::CheckWards(Entity* attacker, int32 damage, int8 damage_type) {
 			ward->LastRedirectDamage = redirectDamage;
 			if (this->IsPlayer())
 			{
-				Client* client = GetZone()->GetClientBySpawn(this);
-				client->Message(CHANNEL_COMBAT, "%s intercepted some of the damage intended for you!", spell->caster->GetName());
+				Client* client = this->GetClient();
+				if(client) {
+					client->Message(CHANNEL_COMBAT, "%s intercepted some of the damage intended for you!", spell->caster->GetName());
+				}
 			}
 			if (spell->caster && spell->caster->IsPlayer())
 			{
-				Client* client = GetZone()->GetClientBySpawn(spell->caster);
-				client->Message(CHANNEL_COMBAT, "YOU intercept some of the damage intended for %s!", this->GetName());
+				Client* client = ((Player*)spell->caster)->GetClient();
+				if(client) {
+					client->Message(CHANNEL_COMBAT, "YOU intercept some of the damage intended for %s!", this->GetName());
+				}
 			}
 
 			if (attacker && spell->caster)
@@ -2173,7 +2177,9 @@ int32 Entity::CheckWards(Entity* attacker, int32 damage, int8 damage_type) {
 		if (ward->MaxHitCount && spell->num_triggers && spell->caster->GetZone())
 		{
 			spell->num_triggers--;
-			ClientPacketFunctions::SendMaintainedExamineUpdate(spell->caster->GetZone()->GetClientBySpawn(spell->caster), spell->slot_pos, spell->num_triggers, 0);
+			if(spell->caster->IsPlayer()) {
+				ClientPacketFunctions::SendMaintainedExamineUpdate(((Player*)spell->caster)->GetClient(), spell->slot_pos, spell->num_triggers, 0);
+			}
 		}
 		
 		if (ward->MaxHitCount && ward->HitCount >= ward->MaxHitCount) // there isn't a max hit requirement with the hit count, so just go based on hit count
@@ -2569,10 +2575,10 @@ void Entity::AddStealthSpell(LuaSpell* spell) {
 		info_changed = true;
 		changed = true;
 		AddChangedZoneSpawn();
-		if (IsPlayer())
+		if (IsPlayer() && ((Player*)this)->GetClient())
 		{
 			((Player*)this)->SetCharSheetChanged(true);
-			GetZone()->SendAllSpawnsForVisChange(GetZone()->GetClientBySpawn(this));
+			GetZone()->SendAllSpawnsForVisChange(((Player*)this)->GetClient());
 		}
 	}
 }
@@ -2589,10 +2595,10 @@ void Entity::AddInvisSpell(LuaSpell* spell) {
 		info_changed = true;
 		changed = true;
 		AddChangedZoneSpawn();
-		if (IsPlayer())
+		if (IsPlayer() && ((Player*)this)->GetClient())
 		{
 			((Player*)this)->SetCharSheetChanged(true);
-			GetZone()->SendAllSpawnsForVisChange(GetZone()->GetClientBySpawn(this));
+			GetZone()->SendAllSpawnsForVisChange(((Player*)this)->GetClient());
 		}
 	}
 }
@@ -2608,10 +2614,10 @@ void Entity::RemoveInvisSpell(LuaSpell* spell) {
 		info_changed = true;
 		changed = true;
 		AddChangedZoneSpawn();
-		if (IsPlayer())
+		if (IsPlayer() && ((Player*)this)->GetClient())
 		{
 			((Player*)this)->SetCharSheetChanged(true);
-			GetZone()->SendAllSpawnsForVisChange(GetZone()->GetClientBySpawn(this));
+			GetZone()->SendAllSpawnsForVisChange(((Player*)this)->GetClient());
 		}
 	}
 }
@@ -2627,10 +2633,10 @@ void Entity::RemoveStealthSpell(LuaSpell* spell) {
 		info_changed = true;
 		changed = true;
 		AddChangedZoneSpawn();
-		if (IsPlayer())
+		if (IsPlayer() && ((Player*)this)->GetClient())
 		{
 			((Player*)this)->SetCharSheetChanged(true);
-			GetZone()->SendAllSpawnsForVisChange(GetZone()->GetClientBySpawn(this));
+			GetZone()->SendAllSpawnsForVisChange(((Player*)this)->GetClient());
 		}
 	}
 }

+ 2 - 2
EQ2/source/WorldServer/Guilds/Guild.cpp

@@ -655,10 +655,10 @@ bool Guild::AddNewGuildMember(Client *client, const char *invited_by, int8 rank)
 	player = client->GetPlayer();
 	assert(player);
 
-	if (members.count(player->GetCharacterID()) == 0 && !player->GetGuild()) {
+	if (members.count(player->GetCharacterID()) == 0 && !player->GetGuild() && ((Player*)player)->GetClient()) {
 		gm = new GuildMember;
 
-		gm->account_id = player->GetZone()->GetClientBySpawn(player)->GetAccountID();
+		gm->account_id = ((Player*)player)->GetClient()->GetAccountID();
 		gm->character_id = player->GetCharacterID();
 		strncpy(gm->name, player->GetName(), sizeof(gm->name));
 		gm->guild_status = 0;

+ 3 - 3
EQ2/source/WorldServer/Items/Items.cpp

@@ -1791,7 +1791,7 @@ void Item::serialize(PacketStruct* packet, bool show_name, Player* player, int16
 	int8 tmp_subtype = 0;
 	if (!packet || !player)
 		return;
-	client = player->GetZone()->GetClientBySpawn(player);
+	client = ((Player*)player)->GetClient();
 	if (!client)
 		return;
 	if(creator.length() > 0){
@@ -2374,7 +2374,7 @@ void Item::serialize(PacketStruct* packet, bool show_name, Player* player, int16
 						if(player && client->GetVersion() >= 284) {
 							packet->setSubstructDataByName("header_info", "footer_type", 0);
 							
-							spell->SetPacketInformation(packet, player->GetZone()->GetClientBySpawn(player));
+							spell->SetPacketInformation(packet, client);
 							if (player->HasSpell(skill_info->spell_id, skill_info->spell_tier, true)) {
 								packet->setDataByName("scribed", 1);
 							}
@@ -3539,7 +3539,7 @@ void PlayerItemList::AddItemToPacket(PacketStruct* packet, Player* player, Item*
 	Client *client;
 	if (!packet || !player)
 		return;
-	client = player->GetZone()->GetClientBySpawn(player);
+	client = ((Player*)player)->GetClient();
 	if (!client)
 		return;
 	

+ 20 - 30
EQ2/source/WorldServer/LuaFunctions.cpp

@@ -4094,8 +4094,8 @@ int EQ2Emu_lua_AddQuestStep(lua_State* state) {
 		QuestStep* quest_step = quest->AddQuestStep(step, QUEST_STEP_TYPE_NORMAL, description, ids, quantity, taskgroup, 0, 0, percentage, usableitemid);
 		if (quest_step && icon && quantity > 0)
 			quest_step->SetIcon(icon);
-		if (quest->GetPlayer()) {
-			Client* client = quest->GetPlayer()->GetZone()->GetClientBySpawn(quest->GetPlayer());
+		if (quest->GetPlayer() && ((Player*)quest->GetPlayer())->GetClient()) {
+			Client* client = ((Player*)quest->GetPlayer())->GetClient();
 			quest->GetPlayer()->GetZone()->SendQuestUpdates(client);
 		}
 	}
@@ -4130,8 +4130,8 @@ int EQ2Emu_lua_AddQuestStepKillLogic(lua_State* state, int8 type)
 		QuestStep* quest_step = quest->AddQuestStep(step, type, description, ids, quantity, taskgroup, 0, 0, percentage, 0);
 		if (quest_step && icon > 0 && quantity > 0)
 			quest_step->SetIcon(icon);
-		if (quest->GetPlayer()) {
-			Client* client = quest->GetPlayer()->GetZone()->GetClientBySpawn(quest->GetPlayer());
+		if (quest->GetPlayer() && ((Player*)quest->GetPlayer())->GetClient()) {
+			Client* client = ((Player*)quest->GetPlayer())->GetClient();
 			quest->GetPlayer()->GetZone()->SendQuestUpdates(client);
 		}
 		safe_delete(ids);
@@ -4172,8 +4172,8 @@ int EQ2Emu_lua_AddQuestStepChat(lua_State* state) {
 		QuestStep* quest_step = quest->AddQuestStep(step, QUEST_STEP_TYPE_CHAT, description, ids, quantity, taskgroup);
 		if (quest_step && icon > 0)
 			quest_step->SetIcon(icon);
-		if (quest->GetPlayer()) {
-			Client* client = quest->GetPlayer()->GetZone()->GetClientBySpawn(quest->GetPlayer());
+		if (quest->GetPlayer() && ((Player*)quest->GetPlayer())->GetClient()) {
+			Client* client = ((Player*)quest->GetPlayer())->GetClient();
 			if(client)
 				quest->GetPlayer()->GetZone()->SendQuestUpdates(client);
 		}
@@ -4209,8 +4209,8 @@ int EQ2Emu_lua_AddQuestStepObtainItem(lua_State* state) {
 		QuestStep* quest_step = quest->AddQuestStep(step, QUEST_STEP_TYPE_OBTAIN_ITEM, description, ids, quantity, taskgroup, 0, 0, percentage, 0);
 		if (quest_step && icon > 0 && quantity > 0)
 			quest_step->SetIcon(icon);
-		if (quest->GetPlayer()) {
-			Client* client = quest->GetPlayer()->GetZone()->GetClientBySpawn(quest->GetPlayer());
+		if (quest->GetPlayer() && ((Player*)quest->GetPlayer())->GetClient()) {
+			Client* client = ((Player*)quest->GetPlayer())->GetClient();
 			quest->GetPlayer()->GetZone()->SendQuestUpdates(client);
 		}
 		safe_delete(ids);
@@ -4253,8 +4253,8 @@ int EQ2Emu_lua_AddQuestStepZoneLoc(lua_State* state) {
 		safe_delete(locations); // gets duplicated into new table in QuestStep constructor
 		if (quest_step && icon > 0)
 			quest_step->SetIcon(icon);
-		if (quest->GetPlayer()) {
-			Client* client = quest->GetPlayer()->GetZone()->GetClientBySpawn(quest->GetPlayer());
+		if (quest->GetPlayer() && ((Player*)quest->GetPlayer())->GetClient()) {
+			Client* client = ((Player*)quest->GetPlayer())->GetClient();
 			quest->GetPlayer()->GetZone()->SendQuestUpdates(client);
 		}
 	}
@@ -4296,8 +4296,8 @@ int EQ2Emu_lua_AddQuestStepLocation(lua_State* state) {
 		safe_delete(locations); // gets duplicated into new table in QuestStep constructor
 		if (quest_step && icon > 0)
 			quest_step->SetIcon(icon);
-		if (quest->GetPlayer()) {
-			Client* client = quest->GetPlayer()->GetZone()->GetClientBySpawn(quest->GetPlayer());
+		if (quest->GetPlayer() && ((Player*)quest->GetPlayer())->GetClient()) {
+			Client* client = ((Player*)quest->GetPlayer())->GetClient();
 			quest->GetPlayer()->GetZone()->SendQuestUpdates(client);
 		}
 	}
@@ -4335,8 +4335,8 @@ int EQ2Emu_lua_AddQuestUsableItem(lua_State* state) {
 		safe_delete(locations); // gets duplicated into new table in QuestStep constructor
 		if (quest_step && icon > 0)
 			quest_step->SetIcon(icon);
-		if (quest->GetPlayer()) {
-			Client* client = quest->GetPlayer()->GetZone()->GetClientBySpawn(quest->GetPlayer());
+		if (quest->GetPlayer() && ((Player*)quest->GetPlayer())->GetClient()) {
+			Client* client = ((Player*)quest->GetPlayer())->GetClient();
 			quest->GetPlayer()->GetZone()->SendQuestUpdates(client);
 		}
 	}
@@ -4367,8 +4367,8 @@ int EQ2Emu_lua_AddQuestStepSpell(lua_State* state) {
 		QuestStep* quest_step = quest->AddQuestStep(step, QUEST_STEP_TYPE_SPELL, description, ids, quantity, taskgroup, 0, 0, percentage, 0);
 		if (quest_step && icon > 0 && quantity > 0)
 			quest_step->SetIcon(icon);
-		if (quest->GetPlayer()) {
-			Client* client = quest->GetPlayer()->GetZone()->GetClientBySpawn(quest->GetPlayer());
+		if (quest->GetPlayer() && ((Player*)quest->GetPlayer())->GetClient()) {
+			Client* client = ((Player*)quest->GetPlayer())->GetClient();
 			quest->GetPlayer()->GetZone()->SendQuestUpdates(client);
 		}
 		safe_delete(ids);
@@ -4403,8 +4403,8 @@ int EQ2Emu_lua_AddQuestStepCraft(lua_State* state) {
 		QuestStep* quest_step = quest->AddQuestStep(step, QUEST_STEP_TYPE_CRAFT, description, ids, quantity, taskgroup, 0, 0, percentage, 0);
 		if (quest_step && icon > 0 && quantity > 0)
 			quest_step->SetIcon(icon);
-		if (quest->GetPlayer()) {
-			Client* client = quest->GetPlayer()->GetZone()->GetClientBySpawn(quest->GetPlayer());
+		if (quest->GetPlayer() && ((Player*)quest->GetPlayer())->GetClient()) {
+			Client* client = ((Player*)quest->GetPlayer())->GetClient();
 			quest->GetPlayer()->GetZone()->SendQuestUpdates(client);
 		}
 		safe_delete(ids);
@@ -4439,8 +4439,8 @@ int EQ2Emu_lua_AddQuestStepHarvest(lua_State* state) {
 		QuestStep* quest_step = quest->AddQuestStep(step, QUEST_STEP_TYPE_HARVEST, description, ids, quantity, taskgroup, 0, 0, percentage, 0);
 		if (quest_step && icon > 0 && quantity > 0)
 			quest_step->SetIcon(icon);
-		if (quest->GetPlayer()) {
-			Client* client = quest->GetPlayer()->GetZone()->GetClientBySpawn(quest->GetPlayer());
+		if (quest->GetPlayer() && ((Player*)quest->GetPlayer())->GetClient()) {
+			Client* client = ((Player*)quest->GetPlayer())->GetClient();
 			quest->GetPlayer()->GetZone()->SendQuestUpdates(client);
 		}
 		safe_delete(ids);
@@ -4522,11 +4522,6 @@ int EQ2Emu_lua_UpdateQuestTaskGroupDescription(lua_State* state) {
 	lua_interface->ResetFunctionStack(state);
 	if (quest && step > 0 && description.length() > 0) {
 		quest->SetTaskGroupDescription(step, description, display_bullets);
-	/*	if (quest->GetPlayer()) {
-			Client* client = quest->GetPlayer()->GetZone()->GetClientBySpawn(quest->GetPlayer());
-			if (client)
-				client->SendQuestUpdateStep(quest, step, false);
-		}*/
 	}
 	return 0;
 }
@@ -4540,11 +4535,6 @@ int EQ2Emu_lua_UpdateQuestStepDescription(lua_State* state) {
 	lua_interface->ResetFunctionStack(state);
 	if (quest && step > 0 && description.length() > 0) {
 		quest->SetStepDescription(step, description);
-		/*if (quest->GetPlayer()) {
-			Client* client = quest->GetPlayer()->GetZone()->GetClientBySpawn(quest->GetPlayer());
-			if (client)
-				client->SendQuestUpdateStepImmediately(quest, step);
-		}*/
 	}
 	return 0;
 }

+ 3 - 4
EQ2/source/WorldServer/NPC_AI.cpp

@@ -96,14 +96,13 @@ void Brain::Think() {
 			if (run_back_distance > MAX_CHASE_DISTANCE || breakWaterPursuit) {
 				LogWrite(NPC_AI__DEBUG, 7, "NPC_AI", "Run back distance is greater then max chase distance, run_back_distance = %f", run_back_distance);
 				// Over the max chase distance, Check to see if the target is is a client
-				Client* client = target->GetZone()->GetClientBySpawn(target);
-				if (client)
+				if (target->IsPlayer() && ((Player*)target)->GetClient())
 				{
 					// Target is a client so send encounter break messages
 					if (m_body->HasSpawnGroup())
-						client->SimpleMessage(CHANNEL_NARRATIVE, "This encounter will no longer give encounter rewards.");
+						((Player*)target)->GetClient()->SimpleMessage(CHANNEL_NARRATIVE, "This encounter will no longer give encounter rewards.");
 					else
-						client->Message(CHANNEL_NARRATIVE, "%s is no longer worth any experience or treasure.", m_body->GetName());
+						((Player*)target)->GetClient()->Message(CHANNEL_NARRATIVE, "%s is no longer worth any experience or treasure.", m_body->GetName());
 				}
 				
 				// Clear the hate list for this NPC

+ 16 - 12
EQ2/source/WorldServer/Player.cpp

@@ -1213,7 +1213,7 @@ EQ2Packet* PlayerInfo::serialize(int16 version, int16 modifyPos, int32 modifyVal
 				control_packet->setDataByName("speed", player->GetSpeed());
 				control_packet->setDataByName("air_speed", player->GetAirSpeed());
 				control_packet->setDataByName("size", 0.51);
-				Client* client = player->GetZone()->GetClientBySpawn(player);
+				Client* client = player->GetClient();
 				if (client)
 					client->QueuePacket(control_packet->serialize());
 				safe_delete(control_packet);
@@ -1727,7 +1727,7 @@ bool Player::CanEquipItem(Item* item, int8 slot) {
 		return false;
 	
 	if (item) {
-		Client* client = GetZone()->GetClientBySpawn(this);
+		Client* client = GetClient();
 		if (client) {
 			if (item->IsWeapon() && slot == 1) {
 				bool dwable = item->IsDualWieldAble(client, item, slot);
@@ -1906,7 +1906,7 @@ vector<EQ2Packet*> Player::EquipItem(int16 index, int16 version, int8 appearance
 				lua_interface->RunZoneScript(zone_script, "item_equipped", GetZone(), this, item->details.item_id, item->name.c_str(), 0, item->details.unique_id);
 			int32 bag_id = item->details.inv_slot_id;
 			if (item->generic_info.condition == 0) {
-				Client* client = GetZone()->GetClientBySpawn(this);
+				Client* client = GetClient();
 				if (client) {
 					string popup_text = "Your ";
 					string popup_item = item->CreateItemLink(client->GetVersion(), true).c_str();
@@ -3191,7 +3191,7 @@ void Player::RemoveMaintainedSpell(LuaSpell* luaspell){
 		return;
 
 	bool found = false;
-	Client* client = GetZone()->GetClientBySpawn(this);
+	Client* client = GetClient();
 	LuaSpell* old_spell = 0;
 	LuaSpell* current_spell = 0;
 	GetMaintainedMutex()->writelock(__FUNCTION__, __LINE__);
@@ -4144,7 +4144,9 @@ bool Player::AddXP(int32 xp_amount){
 	float miniding_min_percent = ((int)(current_xp_percent/10)+1)*10;
 	while((xp_amount + GetXP()) >= GetNeededXP()){
 		if (!CheckLevelStatus(GetLevel() + 1)) {
-			GetZone()->GetClientBySpawn(this)->SimpleMessage(CHANNEL_COLOR_RED, "You do not have the required status to level up anymore!");
+			if(GetClient()) {
+				GetClient()->SimpleMessage(CHANNEL_COLOR_RED, "You do not have the required status to level up anymore!");
+			}
 			SetCharSheetChanged(true);	
 			return false;
 		}
@@ -4180,7 +4182,9 @@ bool Player::AddTSXP(int32 xp_amount){
 	float miniding_min_percent = ((int)(current_xp_percent/10)+1)*10;
 	while((xp_amount + GetTSXP()) >= GetNeededTSXP()){
 		if (!CheckLevelStatus(GetTSLevel() + 1)) {
-			GetZone()->GetClientBySpawn(this)->SimpleMessage(CHANNEL_COLOR_RED, "You do not have the required status to level up anymore!");
+			if(GetClient()) {
+				GetClient()->SimpleMessage(CHANNEL_COLOR_RED, "You do not have the required status to level up anymore!");
+			}
 			return false;
 		}
 		xp_amount -= GetNeededTSXP() - GetTSXP();
@@ -4344,7 +4348,7 @@ void Player::CheckQuestsCraftUpdate(Item* item, int32 qty){
 	}
 	MPlayerQuests.releasereadlock(__FUNCTION__, __LINE__);
 	if(update_list && update_list->size() > 0){
-		Client* client = GetZone()->GetClientBySpawn(this);
+		Client* client = GetClient();
 		if(client){
 			for(int8 i=0;i<update_list->size(); i++){
 				client->SendQuestUpdate(update_list->at(i));
@@ -4371,7 +4375,7 @@ void Player::CheckQuestsHarvestUpdate(Item* item, int32 qty){
 	}
 	MPlayerQuests.releasereadlock(__FUNCTION__, __LINE__);
 	if(update_list && update_list->size() > 0){
-		Client* client = GetZone()->GetClientBySpawn(this);
+		Client* client = GetClient();
 		if(client){
 			for(int8 i=0;i<update_list->size(); i++){
 				client->SendQuestUpdate(update_list->at(i));
@@ -5751,7 +5755,7 @@ map<string, int8>* Player::GetIgnoredPlayers(){
 bool Player::CheckLevelStatus(int16 new_level) {
 	int16 LevelCap					= rule_manager.GetGlobalRule(R_Player, MaxLevel)->GetInt16();
 	int16 LevelCapOverrideStatus	= rule_manager.GetGlobalRule(R_Player, MaxLevelOverrideStatus)->GetInt16();
-	if ( (LevelCap < new_level) && (LevelCapOverrideStatus > GetZone()->GetClientBySpawn(this)->GetAdminStatus()) )
+	if ( GetClient() && (LevelCap < new_level) && (LevelCapOverrideStatus > GetClient()->GetAdminStatus()) )
 			return false;
 	return true;
 }
@@ -6155,7 +6159,7 @@ void Player::AddPassiveSpell(int32 id, int8 tier)
 	// player has instead of going through all their spells.
 	passive_spells.push_back(id);
 
-	Client* client = GetZone()->GetClientBySpawn(this);
+	Client* client = GetClient();
 
 	// Don not apply passives if the client is null, zoning, or reviving
 	if (client == NULL || client->IsZoning() || IsResurrecting())
@@ -6463,7 +6467,7 @@ void Player::SendQuestRequiredSpawns(int32 quest_id){
 	m_playerSpawnQuestsRequired.readlock(__FUNCTION__, __LINE__);
 	if (player_spawn_quests_required.size() > 0 ) {
 		ZoneServer* zone = GetZone();
-		Client* client = zone->GetClientBySpawn(this);
+		Client* client = GetClient();
 		if (!client){
 			m_playerSpawnQuestsRequired.releasereadlock(__FUNCTION__, __LINE__);
 			return;
@@ -6496,7 +6500,7 @@ void Player::SendHistoryRequiredSpawns(int32 event_id){
 	m_playerSpawnHistoryRequired.readlock(__FUNCTION__, __LINE__);
 	if (player_spawn_history_required.size() > 0) {
 		ZoneServer* zone = GetZone();
-		Client* client = zone->GetClientBySpawn(this);
+		Client* client = GetClient();
 		if (!client){
 			m_playerSpawnHistoryRequired.releasereadlock(__FUNCTION__, __LINE__);
 			return;

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

@@ -60,7 +60,7 @@ bool PlayerGroup::AddMember(Entity* member) {
 	gmi->member = member;
 	gmi->leader = false;
 	if (member->IsPlayer())
-		gmi->client = member->GetZone()->GetClientBySpawn(member);
+		gmi->client = ((Player*)member)->GetClient();
 	else
 		gmi->client = 0;
 	gmi->mentor_target_char_id = 0;

+ 44 - 71
EQ2/source/WorldServer/Spawn.cpp

@@ -806,8 +806,8 @@ uchar* Spawn::spawn_vis_changes(Player* player, int16 version, int16* vis_packet
 		return nullptr;
 	}
 
-	uchar* tmp = new uchar[size + 10];
-	size = Pack(tmp, xor_vis_packet, size, size, version);
+	uchar* tmp = new uchar[size + 1000];
+	size = Pack(tmp, xor_vis_packet, size, size+1000, version);
 	player->vis_mutex.releasewritelock(__FUNCTION__, __LINE__);
 
 	int32 orig_size = size;
@@ -859,15 +859,17 @@ uchar* Spawn::spawn_pos_changes(Player* player, int16 version, int16* pos_packet
 		return nullptr;
 	}
 
+	int16 newSize = size + 1000;
 	uchar* tmp;
-	if (IsPlayer() && version > 283)
-		tmp = new uchar[size + 14];
-	else
-		tmp = new uchar[size + 10];
-	size = Pack(tmp, xor_pos_packet, size, size, version);
+	if (IsPlayer() && version > 283) {
+		tmp = new uchar[newSize];
+	}
+	else {
+		tmp = new uchar[newSize];
+	}
+	size = Pack(tmp, xor_pos_packet, size, newSize, version);
 	player->pos_mutex.releasewritelock(__FUNCTION__, __LINE__);
 
-
 	int32 orig_size = size;
 	// Needed for CoE+ clients
 	if (version >= 1188)
@@ -1182,8 +1184,8 @@ uchar* Spawn::spawn_vis_changes_ex(Player* player, int16 version, int16* vis_pac
 		return nullptr;
 	}
 
-	uchar* tmp = new uchar[size + 10];
-	size = Pack(tmp, xor_vis_packet, size, size, version);
+	uchar* tmp = new uchar[size + 1000];
+	size = Pack(tmp, xor_vis_packet, size, size+1000, version);
 
 	player->vis_mutex.releasewritelock(__FUNCTION__, __LINE__);
 
@@ -1247,12 +1249,17 @@ uchar* Spawn::spawn_pos_changes_ex(Player* player, int16 version, int16* pos_pac
 		return nullptr;
 	}
 
-	uchar* tmp = new uchar[size + 10];
-
-	size = Pack(tmp, xor_pos_packet, size, size, version);
-
+	int16 newSize = size + 1000;
+	uchar* tmp;
+	if (IsPlayer() && version > 283) {
+		tmp = new uchar[newSize];
+	}
+	else {
+		tmp = new uchar[newSize];
+	}
+	size = Pack(tmp, xor_pos_packet, size, newSize, version);
 	player->pos_mutex.releasewritelock(__FUNCTION__, __LINE__);
-
+	
 	int32 orig_size = size;
 
 	if (version >= 1188) {
@@ -1414,13 +1421,7 @@ void Spawn::SetHP(sint32 new_val, bool setUpdateFlags){
 	if(/*IsPlayer() &&*/ GetZone() && basic_info.cur_hp > 0 && basic_info.cur_hp < basic_info.max_hp)
 		GetZone()->AddDamagedSpawn(this);
 
-	if (IsEntity() && ((Entity*)this)->GetGroupMemberInfo()) {
-		((Entity*)this)->UpdateGroupMemberInfo();
-		if (IsPlayer())
-			world.GetGroupManager()->SendGroupUpdate(((Entity*)this)->GetGroupMemberInfo()->group_id, GetZone()->GetClientBySpawn(this));
-		else
-			world.GetGroupManager()->SendGroupUpdate(((Entity*)this)->GetGroupMemberInfo()->group_id);
-	}
+	SendGroupUpdate();
 
 	if ( IsPlayer() && new_val == 0 ) // fixes on death not showing hp update for players
 		((Player*)this)->SetCharSheetChanged(true);
@@ -1447,13 +1448,7 @@ void Spawn::SetTotalHP(sint32 new_val){
 	if(GetZone() && basic_info.cur_hp > 0 && basic_info.cur_hp < basic_info.max_hp)
 		GetZone()->AddDamagedSpawn(this);
 
-	if (IsEntity() && ((Entity*)this)->GetGroupMemberInfo()) {
-		((Entity*)this)->UpdateGroupMemberInfo();
-		if (IsPlayer())
-			world.GetGroupManager()->SendGroupUpdate(((Entity*)this)->GetGroupMemberInfo()->group_id, GetZone()->GetClientBySpawn(this));
-		else
-			world.GetGroupManager()->SendGroupUpdate(((Entity*)this)->GetGroupMemberInfo()->group_id);
-	}
+	SendGroupUpdate();
 
 	if (IsNPC() && ((NPC*)this)->IsPet() && ((NPC*)this)->GetOwner() != nullptr && ((NPC*)this)->GetOwner()->IsPlayer()) {
 		Player* player = (Player*)((NPC*)this)->GetOwner();
@@ -1476,13 +1471,7 @@ void Spawn::SetTotalHPBase(sint32 new_val)
 	if(GetZone() && basic_info.cur_hp > 0 && basic_info.cur_hp < basic_info.max_hp)
 		GetZone()->AddDamagedSpawn(this);
 
-	if (IsEntity() && ((Entity*)this)->GetGroupMemberInfo()) {
-		((Entity*)this)->UpdateGroupMemberInfo();
-		if (IsPlayer())
-			world.GetGroupManager()->SendGroupUpdate(((Entity*)this)->GetGroupMemberInfo()->group_id, GetZone()->GetClientBySpawn(this));
-		else
-			world.GetGroupManager()->SendGroupUpdate(((Entity*)this)->GetGroupMemberInfo()->group_id);
-	}
+	SendGroupUpdate();
 }
 sint32 Spawn::GetHP()
 {
@@ -1506,13 +1495,7 @@ void Spawn::SetPower(sint32 power, bool setUpdateFlags){
 	if(/*IsPlayer() &&*/ GetZone() && basic_info.cur_power < basic_info.max_power)
 		GetZone()->AddDamagedSpawn(this);
 
-	if (IsEntity() && ((Entity*)this)->GetGroupMemberInfo()) {
-		((Entity*)this)->UpdateGroupMemberInfo();
-		if (IsPlayer())
-			world.GetGroupManager()->SendGroupUpdate(((Entity*)this)->GetGroupMemberInfo()->group_id, GetZone()->GetClientBySpawn(this));
-		else
-			world.GetGroupManager()->SendGroupUpdate(((Entity*)this)->GetGroupMemberInfo()->group_id);
-	}
+	SendGroupUpdate();
 
 	if (IsNPC() && ((NPC*)this)->IsPet() && ((NPC*)this)->GetOwner() != nullptr && ((NPC*)this)->GetOwner()->IsPlayer()) {
 		Player* player = (Player*)((NPC*)this)->GetOwner();
@@ -1537,13 +1520,7 @@ void Spawn::SetTotalPower(sint32 new_val)
 	if(GetZone() && basic_info.cur_power < basic_info.max_power)
 		GetZone()->AddDamagedSpawn(this);
 
-	if (IsEntity() && ((Entity*)this)->GetGroupMemberInfo()) {
-		((Entity*)this)->UpdateGroupMemberInfo();
-		if (IsPlayer())
-			world.GetGroupManager()->SendGroupUpdate(((Entity*)this)->GetGroupMemberInfo()->group_id, GetZone()->GetClientBySpawn(this));
-		else
-			world.GetGroupManager()->SendGroupUpdate(((Entity*)this)->GetGroupMemberInfo()->group_id);
-	}
+	SendGroupUpdate();
 
 	if (IsNPC() && ((NPC*)this)->IsPet() && ((NPC*)this)->GetOwner() != nullptr && ((NPC*)this)->GetOwner()->IsPlayer()) {
 		Player* player = (Player*)((NPC*)this)->GetOwner();
@@ -1566,13 +1543,7 @@ void Spawn::SetTotalPowerBase(sint32 new_val)
 	if(GetZone() && basic_info.cur_power < basic_info.max_power)
 		GetZone()->AddDamagedSpawn(this);
 
-	if (IsEntity() && ((Entity*)this)->GetGroupMemberInfo()) {
-		((Entity*)this)->UpdateGroupMemberInfo();
-		if (IsPlayer())
-			world.GetGroupManager()->SendGroupUpdate(((Entity*)this)->GetGroupMemberInfo()->group_id, GetZone()->GetClientBySpawn(this));
-		else
-			world.GetGroupManager()->SendGroupUpdate(((Entity*)this)->GetGroupMemberInfo()->group_id);
-	}
+	SendGroupUpdate();
 }
 sint32 Spawn::GetPower()
 {
@@ -1607,13 +1578,7 @@ void Spawn::SetTotalSavagery(sint32 new_val)
 void Spawn::SetTotalSavageryBase(sint32 new_val){
 	SetInfo(&basic_info.savagery_base, new_val);
 
-	if (IsEntity() && ((Entity*)this)->GetGroupMemberInfo()) {
-		((Entity*)this)->UpdateGroupMemberInfo();
-		if (IsPlayer())
-			world.GetGroupManager()->SendGroupUpdate(((Entity*)this)->GetGroupMemberInfo()->group_id, GetZone()->GetClientBySpawn(this));
-		else
-			world.GetGroupManager()->SendGroupUpdate(((Entity*)this)->GetGroupMemberInfo()->group_id);
-	}
+	SendGroupUpdate();
 }
 sint32 Spawn::GetTotalSavagery()
 {
@@ -1647,13 +1612,7 @@ void Spawn::SetTotalDissonanceBase(sint32 new_val)
 {
 	SetInfo(&basic_info.dissonance_base, new_val);
 
-	if (IsEntity() && ((Entity*)this)->GetGroupMemberInfo()) {
-		((Entity*)this)->UpdateGroupMemberInfo();
-		if (IsPlayer())
-			world.GetGroupManager()->SendGroupUpdate(((Entity*)this)->GetGroupMemberInfo()->group_id, GetZone()->GetClientBySpawn(this));
-		else
-			world.GetGroupManager()->SendGroupUpdate(((Entity*)this)->GetGroupMemberInfo()->group_id);
-	}
+	SendGroupUpdate();
 }
 sint32 Spawn::GetTotalDissonance()
 {
@@ -4696,4 +4655,18 @@ void Spawn::AddIgnoredWidget(int32 id) {
 	if(ignored_widgets.find(id) == ignored_widgets.end()) {
 		ignored_widgets.insert(make_pair(id,true));
 	}
+}
+
+void Spawn::SendGroupUpdate() {
+	if (IsEntity() && ((Entity*)this)->GetGroupMemberInfo()) {
+		((Entity*)this)->UpdateGroupMemberInfo();
+		if (IsPlayer()) {
+			Client* client = ((Player*)this)->GetClient();
+			if(client) {
+				world.GetGroupManager()->SendGroupUpdate(((Entity*)this)->GetGroupMemberInfo()->group_id, client);
+			}
+		}
+		else
+			world.GetGroupManager()->SendGroupUpdate(((Entity*)this)->GetGroupMemberInfo()->group_id);
+	}
 }

+ 2 - 0
EQ2/source/WorldServer/Spawn.h

@@ -1314,6 +1314,8 @@ public:
 	
 	void AddIgnoredWidget(int32 id);
 	
+	void SendGroupUpdate();
+	
 	mutable std::shared_mutex MIgnoredWidgets;
 	std::map<int32, bool> ignored_widgets;
 	

+ 39 - 23
EQ2/source/WorldServer/SpellProcess.cpp

@@ -174,13 +174,16 @@ void SpellProcess::Process(){
 			if (cast_timer) {
 				if (cast_timer->timer->Check(false)) {
 					if (cast_timer->spell) {
-						Client* client = cast_timer->zone->GetClientBySpawn(cast_timer->spell->caster);
-						if (client) {
-							PacketStruct* packet = configReader.getStruct("WS_FinishCastSpell", client->GetVersion());
-							if (packet) {
-								packet->setMediumStringByName("spell_name", cast_timer->spell->spell->GetSpellData()->name.data.c_str());
-								client->QueuePacket(packet->serialize());
-								safe_delete(packet);
+						if (cast_timer->spell->caster && cast_timer->spell->caster->IsPlayer()) {
+							
+							Client* client = ((Player*)cast_timer->spell->caster)->GetClient();
+							if(client) {
+								PacketStruct* packet = configReader.getStruct("WS_FinishCastSpell", client->GetVersion());
+								if (packet) {
+									packet->setMediumStringByName("spell_name", cast_timer->spell->spell->GetSpellData()->name.data.c_str());
+									client->QueuePacket(packet->serialize());
+									safe_delete(packet);
+								}
 							}
 						}
 						if (cast_timer->spell && cast_timer->spell->caster)
@@ -303,7 +306,7 @@ void SpellProcess::CheckRecast(Spell* spell, Entity* caster, float timer_overrid
 		RecastTimer* timer = new RecastTimer;
 		timer->caster = caster;
 		if(caster->IsPlayer())
-			timer->client = caster->GetZone()->GetClientBySpawn(caster);
+			timer->client = ((Player*)caster)->GetClient();
 		else
 			timer->client = 0;
 		timer->spell = spell;
@@ -351,18 +354,25 @@ void SpellProcess::CheckInterrupt(InterruptStruct* interrupt){
 	if(!interrupt || !interrupt->interrupted || !interrupt->interrupted->IsEntity())
 		return;
 	Entity* entity = (Entity*)interrupt->interrupted;
-	Client* client = entity->GetZone()->GetClientBySpawn(entity);
-	if(client)
+	Client* client = nullptr;
+	
+	if(entity->IsPlayer()) {
+		client = ((Player*)entity)->GetClient();
+	}
+	
+	if(entity->IsPlayer() && client)
 		SendFinishedCast(GetLuaSpell(entity), client);
 	RemoveSpellTimersFromSpawn(entity, false);
 	entity->IsCasting(false);
 	entity->GetZone()->SendInterruptPacket(entity, interrupt->spell);
-	if(interrupt->error_code > 0)
+	if(interrupt->error_code > 0 && client)
 		entity->GetZone()->SendSpellFailedPacket(client, interrupt->error_code);
 	if(entity->IsPlayer())
 	{
 		((Player*)entity)->UnlockSpell(interrupt->spell->spell);
-		SendSpellBookUpdate(((Player*)entity)->GetClient());
+		if(client) {
+			SendSpellBookUpdate(client);
+		}
 	}
 }
 
@@ -468,7 +478,7 @@ bool SpellProcess::DeleteCasterSpell(LuaSpell* spell, string reason, bool removi
 							spell->caster->RemoveDetrimentalSpell(spell);
 					}
 					if(target && target->IsPlayer() && spell->spell->GetSpellData()->fade_message.length() > 0){
-						Client* client = target->GetZone()->GetClientBySpawn(target);
+						Client* client = ((Player*)target)->GetClient();
 						if(client){
 							bool send_to_sender = true;
 							string fade_message = spell->spell->GetSpellData()->fade_message;
@@ -478,7 +488,7 @@ bool SpellProcess::DeleteCasterSpell(LuaSpell* spell, string reason, bool removi
 						}
 					}
 					if (target && target->IsPlayer() && spell->spell->GetSpellData()->fade_message.length() > 0) {
-						Client* client = target->GetZone()->GetClientBySpawn(target);
+						Client* client = ((Player*)target)->GetClient();
 						if (client) {
 							bool send_to_sender = true;
 							string fade_message_others = spell->spell->GetSpellData()->fade_message_others;
@@ -863,7 +873,7 @@ void SpellProcess::AddSpellToQueue(Spell* spell, Entity* caster){
 		LogWrite(SPELL__DEBUG, 1, "Spell", "%s AddSpellToQueue casting %s.", caster->GetName(), spell->GetName());
 		spell_que.Put(caster, spell);
 		((Player*)caster)->QueueSpell(spell);
-		Client* client = caster->GetZone()->GetClientBySpawn(caster);
+		Client* client = ((Player*)caster)->GetClient();
 		if(client)
 			SendSpellBookUpdate(client);
 	}
@@ -874,7 +884,7 @@ void SpellProcess::RemoveSpellFromQueue(Spell* spell, Entity* caster, bool send_
 		LogWrite(SPELL__DEBUG, 1, "Spell", "%s RemoveSpellFromQueue casting %s.", caster->GetName(), spell->GetName());
 		spell_que.erase(caster);
 		((Player*)caster)->UnQueueSpell(spell);
-		Client* client = caster->GetZone()->GetClientBySpawn(caster);
+		Client* client = ((Player*)caster)->GetClient();
 		if(client && send_update)
 			SendSpellBookUpdate(client);
 	}
@@ -892,7 +902,7 @@ void SpellProcess::RemoveSpellFromQueue(Entity* caster, bool hostile_only) {
 				LogWrite(SPELL__DEBUG, 1, "Spell", "%s RemoveSpellFromQueue::Secondary casting %s.", caster->GetName(), spell->GetName());
 				spell_que.erase(caster);
 				((Player*)caster)->UnQueueSpell(spell);
-				Client* client = caster->GetZone()->GetClientBySpawn(caster);
+				Client* client = ((Player*)caster)->GetClient();
 				if (client)
 					SendSpellBookUpdate(client);
 			}
@@ -1045,7 +1055,7 @@ void SpellProcess::ProcessSpell(ZoneServer* zone, Spell* spell, Entity* caster,
 
 		if(caster->IsPlayer() && zone)
 		{
-			client = zone->GetClientBySpawn(caster);
+			client = ((Player*)caster)->GetClient();
 			//version = client->GetVersion();
 		}
 
@@ -1437,7 +1447,7 @@ void SpellProcess::ProcessSpell(ZoneServer* zone, Spell* spell, Entity* caster,
 				DeleteSpell(lua_spell);
 				return;
 			}
-			if(target->IsPlayer() && zone->GetClientBySpawn(target)->GetCurrentRez()->active){
+			if(target->IsPlayer() && ((Player*)target)->GetClient() && ((Player*)target)->GetClient()->GetCurrentRez()->active){
 				zone->SendSpellFailedPacket(client, SPELL_ERROR_ALREADY_CAST);
 				lua_spell->caster->GetZone()->GetSpellProcess()->RemoveSpellScriptTimerBySpell(lua_spell);
 				DeleteSpell(lua_spell);
@@ -1585,7 +1595,11 @@ void SpellProcess::ProcessSpell(ZoneServer* zone, Spell* spell, Entity* caster,
 
 void SpellProcess::ProcessEntityCommand(ZoneServer* zone, EntityCommand* entity_command, Entity* caster, Spawn* target, bool lock, bool in_heroic_opp)  {
 	if (zone && entity_command && caster && target && !target->IsPlayer()) {
-		Client* client = zone->GetClientBySpawn(caster);
+		Client* client = ((Player*)caster)->GetClient();
+		
+		if(!client) {
+			return;
+		}
 		if (caster->GetDistance(target) > entity_command->distance) {
 			zone->SendSpellFailedPacket(client, SPELL_ERROR_TOO_FAR_AWAY);
 			return;
@@ -1625,7 +1639,7 @@ bool SpellProcess::CastProcessedSpell(LuaSpell* spell, bool passive, bool in_her
 		return false;
 	Client* client = 0;
 	if(spell->caster && spell->caster->IsPlayer())
-		client = spell->caster->GetZone()->GetClientBySpawn(spell->caster);
+		client = ((Player*)spell->caster)->GetClient();
 	if (spell->spell->GetSpellData()->max_aoe_targets > 0 && spell->targets.size() == 0) {
 		GetSpellTargetsTrueAOE(spell);
 		if (spell->targets.size() == 0) {
@@ -1975,8 +1989,10 @@ void SpellProcess::Interrupted(Entity* caster, Spawn* interruptor, int16 error_c
 			Client* client = 0;
 			if(interruptor && interruptor->IsPlayer())
 			{
-				client = interruptor->GetZone()->GetClientBySpawn(interruptor);
-				client->Message(CHANNEL_SPELLS_OTHER, "You interrupt %s's ability to cast!", interruptor->GetName());
+				client = ((Player*)interruptor)->GetClient();
+				if(client) {
+					client->Message(CHANNEL_SPELLS_OTHER, "You interrupt %s's ability to cast!", caster->GetName());
+				}
 			}
 			
 		}

+ 48 - 34
EQ2/source/WorldServer/Trade.cpp

@@ -177,17 +177,19 @@ bool Trade::SetTradeAccepted(Entity* character) {
 	Entity* other = GetTradee(character);
 	if (other) {
 		if (other->IsPlayer()) {
-			Client* client = other->GetZone()->GetClientBySpawn(other);
-			PacketStruct* packet = configReader.getStruct("WS_PlayerTrade", client->GetVersion());
-			if (packet) {
-				packet->setDataByName("spawn_id", client->GetPlayer()->GetIDWithPlayerSpawn(character));
-				packet->setDataByName("type", 16);
-				client->QueuePacket(packet->serialize());
-				safe_delete(packet);
+			Client* client = ((Player*)other)->GetClient();
+			if(client) {
+				PacketStruct* packet = configReader.getStruct("WS_PlayerTrade", client->GetVersion());
+				if (packet) {
+					packet->setDataByName("spawn_id", client->GetPlayer()->GetIDWithPlayerSpawn(character));
+					packet->setDataByName("type", 16);
+					client->QueuePacket(packet->serialize());
+					safe_delete(packet);
+				}
 			}
 		}
 		else if (other->IsBot()) {
-			Client* client = character->GetZone()->GetClientBySpawn(character);
+			Client* client = ((Player*)character)->GetClient();
 			if (trader1_coins > 0) {
 				CancelTrade(other);
 				if (client)
@@ -230,13 +232,15 @@ void Trade::CancelTrade(Entity* character) {
 	Entity* other = GetTradee(character);
 	if (other){
 		if (other->IsPlayer()) {
-			Client* client = other->GetZone()->GetClientBySpawn(other);
-			PacketStruct* packet = configReader.getStruct("WS_PlayerTrade", client->GetVersion());
-			if (packet) {
-				packet->setDataByName("spawn_id", client->GetPlayer()->GetIDWithPlayerSpawn(character));
-				packet->setDataByName("type", 2);
-				client->QueuePacket(packet->serialize());
-				safe_delete(packet);
+			Client* client = ((Player*)other)->GetClient();
+			if(client) {
+				PacketStruct* packet = configReader.getStruct("WS_PlayerTrade", client->GetVersion());
+				if (packet) {
+					packet->setDataByName("spawn_id", client->GetPlayer()->GetIDWithPlayerSpawn(character));
+					packet->setDataByName("type", 2);
+					client->QueuePacket(packet->serialize());
+					safe_delete(packet);
+				}
 			}
 		}
 		else if (other->IsBot())
@@ -265,7 +269,7 @@ void Trade::CompleteTrade() {
 
 	if (trader1->IsPlayer()) {
 		Player* player = (Player*)trader1;
-		Client* client = player->GetZone()->GetClientBySpawn(player);
+		Client* client = ((Player*)player)->GetClient();
 		if (client) {
 			log_string += "Trader1 = ";
 			log_string += trader1->GetName();
@@ -304,7 +308,7 @@ void Trade::CompleteTrade() {
 
 	if (trader2->IsPlayer()) {
 		Player* player = (Player*)trader2;
-		Client* client = player->GetZone()->GetClientBySpawn(player);
+		Client* client = ((Player*)player)->GetClient();
 		if (client) {
 			log_string += "Trader2 = ";
 			log_string += trader2->GetName();
@@ -352,32 +356,39 @@ void Trade::CompleteTrade() {
 
 void Trade::OpenTradeWindow() {
 	if (trader1->IsPlayer()) {
-		Client* client = trader1->GetZone()->GetClientBySpawn(trader1);
-		PacketStruct* packet = configReader.getStruct("WS_PlayerTrade", client->GetVersion());
-		if (packet) {
-			packet->setDataByName("spawn_id", client->GetPlayer()->GetIDWithPlayerSpawn(trader2));
-			packet->setDataByName("type", 1);
-			client->QueuePacket(packet->serialize());
-			safe_delete(packet);
+		Client* client = ((Player*)trader1)->GetClient();
+		if(client) {
+			PacketStruct* packet = configReader.getStruct("WS_PlayerTrade", client->GetVersion());
+			if (packet) {
+				packet->setDataByName("spawn_id", client->GetPlayer()->GetIDWithPlayerSpawn(trader2));
+				packet->setDataByName("type", 1);
+				client->QueuePacket(packet->serialize());
+				safe_delete(packet);
+			}
 		}
 	}
 
 	if (trader2->IsPlayer()) {
-		Client* client = trader2->GetZone()->GetClientBySpawn(trader2);
-		PacketStruct* packet = configReader.getStruct("WS_PlayerTrade", client->GetVersion());
-		if (packet) {
-			packet->setDataByName("spawn_id", client->GetPlayer()->GetIDWithPlayerSpawn(trader1));
-			packet->setDataByName("type", 1);
-			client->QueuePacket(packet->serialize());
-			safe_delete(packet);
+		Client* client = ((Player*)trader2)->GetClient();
+		if(client) {
+			PacketStruct* packet = configReader.getStruct("WS_PlayerTrade", client->GetVersion());
+			if (packet) {
+				packet->setDataByName("spawn_id", client->GetPlayer()->GetIDWithPlayerSpawn(trader1));
+				packet->setDataByName("type", 1);
+				client->QueuePacket(packet->serialize());
+				safe_delete(packet);
+			}
 		}
 	}
 }
 
 void Trade::SendTradePacket() {
 	if (trader1->IsPlayer()) {
-		Client* client = trader1->GetZone()->GetClientBySpawn(trader1);
-
+		Client* client = ((Player*)trader1)->GetClient();
+		if(!client) {
+			return;
+		}
+		
 		PacketStruct* packet = configReader.getStruct("WS_PlayerTrade", client->GetVersion());
 		if (packet) {
 			packet->setDataByName("spawn_id", client->GetPlayer()->GetIDWithPlayerSpawn(trader2));
@@ -443,7 +454,10 @@ void Trade::SendTradePacket() {
 	}
 
 	if (trader2->IsPlayer()) {
-		Client* client = trader2->GetZone()->GetClientBySpawn(trader2);
+		Client* client = ((Player*)trader2)->GetClient();
+		if(!client) {
+			return;
+		}
 		PacketStruct* packet = configReader.getStruct("WS_PlayerTrade", client->GetVersion());
 		if (packet) {
 			packet->setDataByName("spawn_id", client->GetPlayer()->GetIDWithPlayerSpawn(trader1));

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

@@ -4061,7 +4061,7 @@ bool Client::Summon(const char* search_name) {
 		if (search_name) {
 			target = GetCurrentZone()->FindSpawn(GetPlayer(), search_name);
 			if (target && target->IsPlayer())
-				search_client = GetCurrentZone()->GetClientBySpawn(target);
+				search_client = target->GetClient();
 			if (!target) {
 				search_client = zone_list.GetClientByCharName(string(search_name));
 				if (search_client)
@@ -10838,9 +10838,7 @@ bool Client::HandleNewLogin(int32 account_id, int32 access_code)
 						SetAccountID(client->GetAccountID());
 						SetAdminStatus(client->GetAdminStatus());
 						SetCurrentZone(GetPlayer()->GetZone());
-						GetPlayer()->GetZone()->UpdateClientSpawnMap(GetPlayer(), this);
 						client->SetPlayer(current_player);
-						GetPlayer()->GetZone()->UpdateClientSpawnMap(current_player, client);
 						GetPlayer()->ResetSavedSpawns();
 						restore_ld_success = true;
 						

+ 33 - 42
EQ2/source/WorldServer/zoneserver.cpp

@@ -473,7 +473,7 @@ void ZoneServer::LoadSpellProcess(){
 
 void ZoneServer::LockAllSpells(Player* player) {
 	if (player && spellProcess) {
-		Client* client = GetClientBySpawn(player);
+		Client* client = ((Player*)player)->GetClient();
 		if (client)
 			spellProcess->LockAllSpells(client);
 	}
@@ -481,7 +481,7 @@ void ZoneServer::LockAllSpells(Player* player) {
 	
 void ZoneServer::UnlockAllSpells(Player* player) {
 	if (player && spellProcess) {
-		Client* client = GetClientBySpawn(player);
+		Client* client = ((Player*)player)->GetClient();
 		if (client)
 			spellProcess->UnlockAllSpells(client);
 	}
@@ -526,7 +526,7 @@ void ZoneServer::DeleteData(bool boot_clients){
 			if(!boot_clients && (spawn->IsPlayer() || spawn->IsBot()))
 				tmp_player_list.push_back(spawn);
 			else if(spawn->IsPlayer()){
-				Client* client = GetClientBySpawn(spawn);
+				Client* client = ((Player*)spawn)->GetClient();
 				if(client)
 					client->Disconnect();
 			}
@@ -739,7 +739,7 @@ void ZoneServer::RegenUpdate(){
 			if(spawn->IsEntity())
 				((Entity*)spawn)->DoRegenUpdate();
 			if(spawn->IsPlayer()){
-				Client* client = GetClientBySpawn(spawn);
+				Client* client = ((Player*)spawn)->GetClient();
 				if(client && client->IsReadyForUpdates())
 					client->QueuePacket(client->GetPlayer()->GetPlayerInfo()->serialize(client->GetVersion()));
 			}
@@ -1991,19 +1991,19 @@ void ZoneServer::RemoveChangedSpawn(Spawn* spawn){
 }
 
 void ZoneServer::AddDrowningVictim(Player* player){
-	Client* client = GetClientBySpawn(player);
+	Client* client = ((Player*)player)->GetClient();
 	if(client && drowning_victims.count(client) == 0)
 		drowning_victims.Put(client, Timer::GetCurrentTime2());
 }
 
 void ZoneServer::RemoveDrowningVictim(Player* player){
-	Client* client = GetClientBySpawn(player);
+	Client* client = ((Player*)player)->GetClient();
 	if(client)
 		drowning_victims.erase(client);
 }
 
 Client* ZoneServer::GetDrowningVictim(Player* player){
-	Client* client = GetClientBySpawn(player);
+	Client* client = ((Player*)player)->GetClient();
 	if(client && drowning_victims.count(client) > 0)
 		return(client);
 	return 0;
@@ -3258,7 +3258,7 @@ void ZoneServer::AddSpawn(Spawn* spawn) {
 	if(spawn->IsNPC())
 		AddEnemyList((NPC*)spawn);
 	if(spawn->IsPlayer() && ((Player*)spawn)->GetGroupMemberInfo())
-		world.GetGroupManager()->SendGroupUpdate(((Player*)spawn)->GetGroupMemberInfo()->group_id, GetClientBySpawn(spawn));
+		spawn->SendGroupUpdate();
 	if (spawn->IsPlayer()) {
 		((Player*)spawn)->GetInfoStruct()->set_rain(rain);
 		((Player*)spawn)->SetCharSheetChanged(true);
@@ -3358,7 +3358,6 @@ void ZoneServer::RemoveClient(Client* client)
 		
 		MClientList.writelock(__FUNCTION__, __LINE__);
 		LogWrite(ZONE__DEBUG, 0, "Zone", "Calling clients.Remove(client)...");
-		UpdateClientSpawnMap(client->GetPlayer(), 0); // address spawn map being prematurely cleared when client list is active
 		
 		std::vector<Client*>::iterator itr2 = find(clients.begin(), clients.end(), client);
 		if (itr2 != clients.end())
@@ -3688,10 +3687,6 @@ void ZoneServer::SendSpawn(Spawn* spawn, Client* client){
 		client->QueueStateCommand(client->GetPlayer()->GetIDWithPlayerSpawn(spawn), spawn->GetTrapState());
 }
 
-Client*	ZoneServer::GetClientBySpawn(Spawn* spawn){
-	return client_spawn_map.Get(spawn);
-}
-
 Client*	ZoneServer::GetClientByName(char* name) {
 	Client* ret = 0;
 	vector<Client*>::iterator itr;
@@ -4564,7 +4559,7 @@ void ZoneServer::SendCalculatedXP(Player* player, Spawn* victim){
 		else {
 			float xp = player->CalculateXP(victim);
 			if (xp > 0) {
-				Client* client = GetClientBySpawn(player);
+				Client* client = ((Player*)player)->GetClient();
 				if(!client)
 					return;
 				player->AddXP((int32)xp);
@@ -4738,7 +4733,7 @@ void ZoneServer::KillSpawn(bool spawnListLocked, Spawn* dead, Spawn* killer, boo
 		if(dead->IsPlayer()) 
 		{
 			((Player*)dead)->UpdatePlayerStatistic(STAT_PLAYER_TOTAL_DEATHS, 1);
-			client = GetClientBySpawn(dead);
+			client = ((Player*)dead)->GetClient();
 
 			((Entity*)dead)->HandleDeathExperienceDebt(killer);
 
@@ -4812,7 +4807,7 @@ void ZoneServer::KillSpawn(bool spawnListLocked, Spawn* dead, Spawn* killer, boo
 				spellProcess->RemoveSpellFromQueue((Player*)spawn, true);
 
 				// Get the client of the player
-				client = GetClientBySpawn(spawn);
+				client = ((Player*)spawn)->GetClient();
 				// valid client?
 				if (client) {
 					// Check for quest kill updates
@@ -4856,7 +4851,7 @@ void ZoneServer::KillSpawn(bool spawnListLocked, Spawn* dead, Spawn* killer, boo
 		// make sure the killer is a player and the dead spawn had a faction and wasn't a player
 		if (killer && killer->IsPlayer()) {
 			if (!dead->IsPlayer() && dead->GetFactionID() > 10) {
-			client = GetClientBySpawn(killer);
+			client = ((Player*)killer)->GetClient();
 			if (client)
 				ProcessFaction(dead, client);
 			}
@@ -4981,7 +4976,7 @@ void ZoneServer::SendDamagePacket(Spawn* attacker, Spawn* victim, int8 type1, in
 	PacketStruct* packet = 0;
 	Client* client = 0;
 	if (attacker && victim && victim->IsPlayer() && victim->GetTarget() == 0) {
-		client = GetClientBySpawn(victim);
+		client = ((Player*)victim)->GetClient();
 		if (client)
 			client->TargetSpawn(attacker);
 	}
@@ -5615,10 +5610,6 @@ vector<ZoneInfoSlideStruct*>* ZoneServer::GenerateTutorialSlides() {
 }
 
 EQ2Packet* ZoneServer::GetZoneInfoPacket(Client* client){
-	// this takes place when we get the LoginInfo for returning LD players
-	if(!client->GetPlayer()->IsReturningFromLD())
-		UpdateClientSpawnMap(client->GetPlayer(), client);
-	
 	PacketStruct* packet = configReader.getStruct("WS_ZoneInfo", client->GetVersion());
 	packet->setSmallStringByName("server1",net.GetWorldName());
 	packet->setSmallStringByName("server2",net.GetWorldName());
@@ -6049,7 +6040,7 @@ void ZoneServer::SendUpdateDefaultCommand(Spawn* spawn, const char* command, flo
 		if (!toPlayer->IsPlayer())
 			return;
 
-		Client* client = GetClientBySpawn(toPlayer);
+		Client* client = ((Player*)toPlayer)->GetClient();
 		if (client)
 		{
 			client->SendDefaultCommand(spawn, command, distance);
@@ -6642,7 +6633,7 @@ void ZoneServer::FindSpawn(Client* client, char* regSearchStr)
 
 void ZoneServer::AddPlayerTracking(Player* player) {
 	if (player && !player->GetIsTracking() && players_tracking.count(player->GetDatabaseID()) == 0) {
-		Client* client = GetClientBySpawn(player);
+		Client* client = ((Player*)player)->GetClient();
 		if (client) {
 			PacketStruct* packet = configReader.getStruct("WS_TrackingUpdate", client->GetVersion());
 			if (packet) {
@@ -6659,7 +6650,7 @@ void ZoneServer::AddPlayerTracking(Player* player) {
 
 void ZoneServer::RemovePlayerTracking(Player* player, int8 mode) {
 	if (player && player->GetIsTracking()) {
-		Client* client = GetClientBySpawn(player);
+		Client* client = ((Player*)player)->GetClient();
 		if (client) {
 			PacketStruct* packet = configReader.getStruct("WS_TrackingUpdate", client->GetVersion());
 			if (packet) {
@@ -6676,8 +6667,12 @@ void ZoneServer::RemovePlayerTracking(Player* player, int8 mode) {
 
 void ZoneServer::ProcessTracking() {
 	MutexMap<int32, Player*>::iterator itr = players_tracking.begin();
-	while (itr.Next())
-		ProcessTracking(GetClientBySpawn(itr->second));
+	while (itr.Next()) {
+		Player* player = itr->second;
+		if(player->GetClient()) {
+			ProcessTracking(player->GetClient());
+		}
+	}
 }
 
 void ZoneServer::ProcessTracking(Client* client) {
@@ -7090,15 +7085,17 @@ void ZoneServer::PlayAnimation(Spawn* spawn, int32 visual_state, Spawn* spawn2,
 		return;
 	if (spawn2){
 		if(hide_type == 1){
-			client = GetClientBySpawn(spawn2);
-			if(client){
-				packet = configReader.getStruct("WS_CannedEmote", client->GetVersion());
-				packet->setDataByName("spawn_id", client->GetPlayer()->GetIDWithPlayerSpawn(spawn));
-				packet->setDataByName("anim_type", visual_state);
-				client->QueuePacket(packet->serialize());
+			if(spawn2->IsPlayer()) {
+				client = ((Player*)spawn2)->GetClient();
+				if(client){
+					packet = configReader.getStruct("WS_CannedEmote", client->GetVersion());
+					packet->setDataByName("spawn_id", client->GetPlayer()->GetIDWithPlayerSpawn(spawn));
+					packet->setDataByName("anim_type", visual_state);
+					client->QueuePacket(packet->serialize());
+				}
+				safe_delete(packet);
+				return;
 			}
-			safe_delete(packet);
-			return;
 		}
 		if(hide_type == 2)
 			exclude_spawn = spawn2;
@@ -7283,7 +7280,7 @@ void ZoneServer::ResurrectSpawn(Spawn* spawn, Client* client) {
 
 	if(spawn->IsPlayer()){
 		spawn->SetSpawnType(4);
-		client = GetClientBySpawn(spawn);
+		client = ((Player*)spawn)->GetClient();
 		if(client){
 			packet = configReader.getStruct("WS_Resurrected", client->GetVersion());
 			if(packet){
@@ -8606,12 +8603,6 @@ void ZoneServer::ProcessQueuedStateCommands() // in a client list lock only
 	MLuaQueueStateCmd.unlock();
 }
 
-void ZoneServer::UpdateClientSpawnMap(Player* player, Client* client)
-{
-	// client may be null when passed
-	client_spawn_map.Put(player, client);
-}
-
 void ZoneServer::RemoveClientsFromZone(ZoneServer* zone) {
 	vector<Client*>::iterator itr;
 	MClientList.readlock(__FUNCTION__, __LINE__);

+ 0 - 3
EQ2/source/WorldServer/zoneserver.h

@@ -333,7 +333,6 @@ public:
 	void	SendSpellFailedPacket(Client* client, int16 error);
 	void	SendInterruptPacket(Spawn* interrupted, LuaSpell* spell, bool fizzle=false);
 	void	HandleEmote(Spawn* originator, string name);
-	Client*	GetClientBySpawn(Spawn* spawn);
 	Spawn*	GetSpawnByDatabaseID(int32 id);
 	Spawn*	GetSpawnByID(int32 id, bool spawnListLocked=false);
 	
@@ -704,7 +703,6 @@ public:
 	void	QueueStateCommandToClients(int32 spawn_id, int32 state);
 	void	QueueDefaultCommand(int32 spawn_id, std::string command, float distance);
 	void	ProcessQueuedStateCommands();
-	void	UpdateClientSpawnMap(Player* player, Client* client);
 	void	RemoveClientsFromZone(ZoneServer* zone);
 
 	void	WorldTimeUpdateTrigger() { sync_game_time_timer.Trigger(); }
@@ -816,7 +814,6 @@ private:
 	list<LocationTransportDestination*> transporter_locations;
 	
 	/* Mutex Maps */
-	MutexMap<Spawn*, Client*>						client_spawn_map;								// ok
 	MutexMap<Client*, int32>						drowning_victims;
 	MutexMap<int32, int32>							movement_spawns;								// 1st int32 = spawn id
 	MutexMap<int32, PlayerProximity*>				player_proximities;								// 1st int32 = spawn id