Browse Source

KoS CD Disc Support!!!
- Fixed a glitch in DoF and KoS clients trying to show classes it does not understand in items display
- Fixed recipient of a trade in DoF/KoS not able to see items (forgot to set the item name oops!)
- Fixed AFK flag being put on players (visually)

Emagi 2 weeks ago
parent
commit
9bf3154123

+ 3 - 3
EQ2/source/LoginServer/LoginDatabase.cpp

@@ -76,7 +76,7 @@ void LoginDatabase::SetZoneInformation(int32 server_id, int32 zone_id, int32 ver
 			MYSQL_ROW row2;
 			if(result2 && (row2 = mysql_fetch_row(result2))) {
 
-				if (version != 546 && version < 1212)
+				if (version < 546 && version > 561 && version < 1212)
 				{
 					if (row2[0])
 					{
@@ -272,7 +272,7 @@ void LoginDatabase::LoadCharacters(LoginAccount* acct, int16 version){
 			player->packet->setDataByName("created_date", atol(row[19]));
 			if (row[20])
 				player->packet->setDataByName("last_played", atol(row[20]));
-			if(version == 546)
+			if(version == 546 || version == 561)
 				player->packet->setDataByName("version", 11);
 			else if(version >= 887)
 				player->packet->setDataByName("version", 6);
@@ -440,7 +440,7 @@ int32 LoginDatabase::SaveCharacter(PacketStruct* create, LoginAccount* acct, int
 	//mark any remaining characters with same id as deleted (creates problems if world deleted their db and started assigning new char ids)
 	DeactivateCharID(create->getType_int32_ByName("server_id"), world_charid, last_insert_id);
 	int32 char_id = last_insert_id;
-	if (client_version <= 546) {
+	if (client_version <= 561) {
 		float classic_multiplier = 250.0f;
 		SaveCharacterFloats(char_id, "skin_color", create->getType_float_ByName("skin_color", 0), create->getType_float_ByName("skin_color", 1), create->getType_float_ByName("skin_color", 2), classic_multiplier);
 		SaveCharacterFloats(char_id, "eye_color", create->getType_float_ByName("eye_color", 0), create->getType_float_ByName("eye_color", 1), create->getType_float_ByName("eye_color", 2), classic_multiplier);

+ 1 - 1
EQ2/source/LoginServer/PacketHeaders.cpp

@@ -24,7 +24,7 @@ EQ2Packet* LS_CharSelectList::serialize(int16 version){
 	Clear();
 	AddData(num_characters);
 	AddData(char_data);
-	if (version <= 546) {
+	if (version <= 561) {
 		LS_CharListAccountInfoEarlyClient account_info;
 		account_info.account_id = account_id;
 		account_info.unknown1 = 0xFFFFFFFF;

+ 3 - 2
EQ2/source/LoginServer/client.cpp

@@ -278,7 +278,8 @@ bool Client::Process() {
 				playWaitTimer->Start ( );
 				
 				LogWrite(WORLD__INFO, 1, "World", "Character creation request from account %s", GetAccountName());
-				if(packet->LoadPacketData(app->pBuffer,app->size, GetVersion() <= 546 ? false : true)){
+				if(packet->LoadPacketData(app->pBuffer,app->size, GetVersion() <= 561 ? false : true)){
+					DumpPacket(app->pBuffer, app->size);
 					packet->setDataByName("account_id",GetAccountID());
 					LWorld* world_server = world_list.FindByID(packet->getType_int32_ByName("server_id"));
 					if(!world_server)
@@ -467,7 +468,7 @@ void Client::CharacterApproved(int32 server_id,int32 char_id)
 			
 			SendCharList();
 
-			if (GetVersion() <= 546)
+			if (GetVersion() <= 561)
 			{
 				pending_play_char_id = char_id;
 				ServerPacket* outpack = new ServerPacket(ServerOP_UsertoWorldReq, sizeof(UsertoWorldRequest_Struct));

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

@@ -77,7 +77,7 @@ void ClientPacketFunctions::SendLoginAccepted ( Client* client ){
 }
 
 void ClientPacketFunctions::SendCommandList ( Client* client ){
-	EQ2Packet* app = commands.GetRemoteCommands()->serialize();
+	EQ2Packet* app = commands.GetRemoteCommands()->serialize(client->GetVersion());
 	client->QueuePacket(app);
 }
 
@@ -118,7 +118,7 @@ void ClientPacketFunctions::SendSkillBook ( Client* client ){
 
 // Jabantiz: Attempt to get the char trait list working
 void ClientPacketFunctions::SendTraitList(Client* client) {
-	if (client->GetVersion() >= 547) {
+	if (client->GetVersion() >= 562) {
 		EQ2Packet* traitApp = master_trait_list.GetTraitListPacket(client);
 		//DumpPacket(traitApp);
 		if (traitApp) {
@@ -405,7 +405,7 @@ void ClientPacketFunctions::SendFlyMode(Client* client, int8 flymode, bool updat
 {
 	if (updateCharProperty)
 		database.insertCharacterProperty(client, CHAR_PROPERTY_FLYMODE, (char*)std::to_string(flymode).c_str());
-	if(client->GetVersion() <= 546) {
+	if(client->GetVersion() <= 561) {
 		if(flymode) {
 			// old flymode
 			SendServerControlFlagsClassic(client, flymode, 1);

+ 28 - 23
EQ2/source/WorldServer/Commands/Commands.cpp

@@ -80,7 +80,7 @@ extern Classes classes;
 #endif
 
 
-EQ2Packet* RemoteCommands::serialize(){
+EQ2Packet* RemoteCommands::serialize(int16 version){
 	buffer.clear();
 	vector<EQ2_RemoteCommandString>::iterator command_list;
 	buffer.append((char*)&num_commands, sizeof(int16));
@@ -2102,7 +2102,7 @@ void Commands::Process(int32 index, EQ2_16BitString* command_parms, Client* clie
 					int32 item_index = atol(sep->arg[1]);
 					
 					LogWrite(COMMAND__DEBUG, 5, "Command", "/info inventory item original index %u", item_index);
-					if(client->GetVersion() <= 546) {
+					if(client->GetVersion() <= 561) {
 						if(item_index <= 255) {
 							item_index = 255 - item_index;
 						}
@@ -2122,7 +2122,7 @@ void Commands::Process(int32 index, EQ2_16BitString* command_parms, Client* clie
 							break;
 						
 						EQ2Packet* app = 0;
-						if(client->GetVersion() <= 546) {
+						if(client->GetVersion() <= 561) {
 							app = item->serialize(client->GetVersion(), true, client->GetPlayer());
 						}
 						else {
@@ -2262,7 +2262,7 @@ void Commands::Process(int32 index, EQ2_16BitString* command_parms, Client* clie
 					LogWrite(COMMAND__DEBUG, 5, "Command", "/info effect: Spell ID: %u", spell_id);
 					int8 tier = client->GetPlayer()->GetSpellTier(spell_id);
 					int8 type = 0;
-					if (client->GetVersion() <= 546)
+					if (client->GetVersion() <= 561)
 						type = 1;
 					EQ2Packet* outapp = master_spell_list.GetSpecialSpellPacket(spell_id, tier, client, true, type);
 					if (outapp){
@@ -2286,7 +2286,7 @@ void Commands::Process(int32 index, EQ2_16BitString* command_parms, Client* clie
 						}
 						Item* tradeItem = client->GetPlayer()->trade->GetTraderSlot(traderToCheck, slot_id);
 						if(tradeItem != nullptr) {
-							EQ2Packet* app = tradeItem->serialize(client->GetVersion(), true, client->GetPlayer(), true, 0, 0, client->GetVersion() > 546 ? true : false);
+							EQ2Packet* app = tradeItem->serialize(client->GetVersion(), true, client->GetPlayer(), true, 0, 0, client->GetVersion() > 561 ? true : false);
 							client->QueuePacket(app);
 						}
 					}
@@ -3416,7 +3416,7 @@ void Commands::Process(int32 index, EQ2_16BitString* command_parms, Client* clie
 			break;
 		}
 		case COMMAND_GROUP_ACCEPT_INVITE: {
-			if((sep && sep->arg[0] && strcmp(sep->arg[0], "group") == 0) || (!sep && client->GetVersion() <= 546)) {
+			if((sep && sep->arg[0] && strcmp(sep->arg[0], "group") == 0) || (!sep && client->GetVersion() <= 561)) {
 				int8 result = world.GetGroupManager()->AcceptInvite(client->GetPlayer());
 
 				if (result == 0)
@@ -3717,12 +3717,12 @@ void Commands::Process(int32 index, EQ2_16BitString* command_parms, Client* clie
 		}
 		case COMMAND_KNOWLEDGEWINDOWSORT: {
 
-			if (sep && (client->GetVersion() <= 546 && sep->GetArgNumber() == 3) || sep->GetArgNumber() == 4)
+			if (sep && (client->GetVersion() <= 561 && sep->GetArgNumber() == 3) || sep->GetArgNumber() == 4)
 			{
 				int32 book = atoul(sep->arg[0]); // 0 - spells, 1 - combat, 2 - abilities, 3 - tradeskill
 				
 				// cannot sort the ability book in this client it is greyed out
-				if (client->GetVersion() <= 546 && book == SPELL_BOOK_TYPE_ABILITY)
+				if (client->GetVersion() <= 561 && book == SPELL_BOOK_TYPE_ABILITY)
 					break;
 			
 				int32 sort_by = atoul(sep->arg[1]); // 0 - alpha, 1 - level, 2 - category
@@ -3730,7 +3730,7 @@ void Commands::Process(int32 index, EQ2_16BitString* command_parms, Client* clie
 				int32 pattern = atoul(sep->arg[3]); // 0 - zigzag, 1 - down, 2 - across
 				int32 maxlvlonly = 0;
 				
-				if(client->GetVersion() > 546 && sep->arg[4][0]) {
+				if(client->GetVersion() > 561 && sep->arg[4][0]) {
 					maxlvlonly = atoul(sep->arg[4]); // checkbox for newer clients
 				}
 				client->GetPlayer()->ResortSpellBook(sort_by, order, pattern, maxlvlonly, book);
@@ -3805,7 +3805,7 @@ void Commands::Process(int32 index, EQ2_16BitString* command_parms, Client* clie
 			int32 spawn_id = 0;
 			if(sep && sep->arg[0]) {
 				spawn_id = atoul(sep->arg[0]);
-				ph = world.GetPlayerHouse(client, spawn_id, client->GetVersion() > 546 ? spawn_id : 0, nullptr);
+				ph = world.GetPlayerHouse(client, spawn_id, client->GetVersion() > 561 ? spawn_id : 0, nullptr);
 			}
 			
 			if(!ph) {
@@ -3845,7 +3845,7 @@ void Commands::Process(int32 index, EQ2_16BitString* command_parms, Client* clie
 						database.LoadDeposits(ph);
 						client->PlaySound("coin_cha_ching");
 						HouseZone* hz = world.GetHouseZone(ph->house_id);
-						ClientPacketFunctions::SendBaseHouseWindow(client, hz, ph, client->GetVersion() <= 546 ? spawn_id : client->GetPlayer()->GetID());
+						ClientPacketFunctions::SendBaseHouseWindow(client, hz, ph, client->GetVersion() <= 561 ? spawn_id : client->GetPlayer()->GetID());
 					}
 					else
 					{
@@ -3876,7 +3876,7 @@ void Commands::Process(int32 index, EQ2_16BitString* command_parms, Client* clie
 				if (ph)
 					hz = world.GetHouseZone(ph->house_id);
 				// there is a arg[1] that is true/false, but not sure what it is for investigate more later
-				ClientPacketFunctions::SendBaseHouseWindow(client, hz, ph, client->GetVersion() <= 546 ? spawn_id : client->GetPlayer()->GetID());
+				ClientPacketFunctions::SendBaseHouseWindow(client, hz, ph, client->GetVersion() <= 561 ? spawn_id : client->GetPlayer()->GetID());
 			}
 			else if (client->GetCurrentZone()->GetInstanceType() != 0)
 			{
@@ -3887,7 +3887,7 @@ void Commands::Process(int32 index, EQ2_16BitString* command_parms, Client* clie
 				if ( ph )
 					hz = world.GetHouseZone(ph->house_id);
 
-				ClientPacketFunctions::SendBaseHouseWindow(client, hz, ph, client->GetVersion() <= 546 ? spawn_id : client->GetPlayer()->GetID());
+				ClientPacketFunctions::SendBaseHouseWindow(client, hz, ph, client->GetVersion() <= 561 ? spawn_id : client->GetPlayer()->GetID());
 				client->GetCurrentZone()->SendHouseItems(client);
 			}
 			break;
@@ -5745,7 +5745,7 @@ void Commands::Command_AcceptAdvancement(Client* client, Seperator* sep)
 	 if (sep && sep->IsSet(0)) {
 		 int32 trait_id = atoul(sep->arg[0]);
 		 TraitData* trait = nullptr;
-		 if(client->GetVersion() <= 547) {
+		 if(client->GetVersion() <= 561) {
 			 trait = master_trait_list.GetTraitByItemID(trait_id);
 		 }
 		 else {
@@ -5791,7 +5791,7 @@ void Commands::Command_AcceptAdvancement(Client* client, Seperator* sep)
 		 client->QueuePacket(player->GetSpellBookUpdatePacket(client->GetVersion()));
 		 client->QueuePacket(master_trait_list.GetTraitListPacket(client));
 		 
-		 if(client->GetVersion() <= 547) {
+		 if(client->GetVersion() <= 546) {
 			master_trait_list.ChooseNextTrait(client);
 		 }
 	 }
@@ -5830,6 +5830,11 @@ void Commands::Command_AFK(Client* client, Seperator* sep)
 
 		player->GetZone()->SimpleMessage(CHANNEL_COLOR_YELLOW, message.c_str(), player, 30);
 	}
+	
+	if (player->get_character_flag(CF_AFK))
+		player->SetActivityStatus(player->GetActivityStatus() + ACTIVITY_STATUS_AFK);
+	else
+		player->SetActivityStatus(player->GetActivityStatus() - ACTIVITY_STATUS_AFK);
 }
 
 /* 
@@ -8565,7 +8570,7 @@ void Commands::Command_ShowHelm(Client* client, Seperator* sep)
 {
 	Player* player = client->GetPlayer();
 	
-	if(client->GetVersion() <= 546) {
+	if(client->GetVersion() <= 561) {
 		return; // not allowed/supported
 	}
 	
@@ -8607,7 +8612,7 @@ void Commands::Command_ShowHood(Client* client, Seperator* sep)
 		if (strncasecmp(value, "true", strlen(value)) == 0) 
 		{
 			player->toggle_character_flag(CF_HIDE_HOOD);
-			if(client->GetVersion() > 546) { // no hide helm support in DoF
+			if(client->GetVersion() > 561) { // no hide helm support in DoF
 				player->toggle_character_flag(CF_HIDE_HELM);
 			}
 		}
@@ -8633,7 +8638,7 @@ void Commands::Command_ShowHoodHelm(Client* client, Seperator* sep)
 {
 	Player* player = client->GetPlayer();
 	
-	if(client->GetVersion() <= 546) {
+	if(client->GetVersion() <= 561) {
 		return; // not allowed/supported
 	}
 	
@@ -9203,7 +9208,7 @@ void Commands::Command_Toggle_AutoConsume(Client* client, Seperator* sep)
 		if (client->GetVersion() <= 283) {
 			slot += 4;
 		}
-		else if (client->GetVersion() <= 546) {
+		else if (client->GetVersion() <= 561) {
 			slot += 2;
 		}
 		if (slot == EQ2_FOOD_SLOT)
@@ -10717,7 +10722,7 @@ void Commands::Command_Test(Client* client, EQ2_16BitString* command_parms) {
 			client->SendRecipeList();
 		}
 		else if (atoi(sep->arg[0]) == 32 && sep->IsNumber(1) && sep->IsNumber(2)) {
-			if(client->GetVersion() <= 546) {
+			if(client->GetVersion() <= 561) {
 				int32 param = atoul(sep->arg[1]);
 				int32 paramvalue = atoul(sep->arg[2]);
 				client->Message(CHANNEL_COLOR_YELLOW, "Send control flag param %u param value %u", param, paramvalue);
@@ -11187,7 +11192,7 @@ void Commands::Command_Wind(Client* client, Seperator* sep) {
 
 void Commands::Command_SendMerchantWindow(Client* client, Seperator* sep, bool sell) {
 	Spawn* spawn = client->GetPlayer()->GetTarget();
-	if(client->GetVersion() <= 546) {
+	if(client->GetVersion() <= 561) {
 		sell = false; // doesn't support in the same way as AoM just open the normal buy/sell window
 	}
 	if(spawn) {
@@ -11202,7 +11207,7 @@ void Commands::Command_SendMerchantWindow(Client* client, Seperator* sep, bool s
 			if(!(spawn->GetMerchantType() & MERCHANT_TYPE_NO_BUY_BACK))
 				client->SendBuyBackList(sell);
 
-			if(client->GetVersion() > 546) {
+			if(client->GetVersion() > 561) {
 				PacketStruct* packet = configReader.getStruct("WS_UpdateMerchant", client->GetVersion());
 				if (packet) {
 					packet->setDataByName("spawn_id", 0xFFFFFFFF);
@@ -11319,7 +11324,7 @@ void Commands::Command_ConsumeFood(Client* client, Seperator* sep) {
 		if (client->GetVersion() <= 283) {
 			slot += 4;
 		}
-		else if (client->GetVersion() <= 546) {
+		else if (client->GetVersion() <= 561) {
 			slot += 2;
 		}
 		Item* item = player->GetEquipmentList()->GetItem(slot);

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

@@ -273,7 +273,7 @@ public:
 		return 0xFFFFFFFF;
 	}
 	string			buffer;
-	EQ2Packet*	serialize();
+	EQ2Packet*	serialize(int16 version = 0);
 	map<string, map <string, EQ2_RemoteCommandString> > subcommands;
 };
 class Commands{

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

@@ -699,7 +699,7 @@ bool Guild::AddNewGuildMember(Client *client, const char *invited_by, int8 rank)
 		SendGuildBankEventList(client);
 		SendAllGuildEvents(client);
 		SendGuildMemberList(client);
-		if(client->GetVersion() > 546)
+		if(client->GetVersion() > 561)
 			client->GetCurrentZone()->SendUpdateTitles(client->GetPlayer());
 
 		if (invited_by) {

+ 2 - 2
EQ2/source/WorldServer/Housing/HousingPackets.cpp

@@ -70,7 +70,7 @@ void ClientPacketFunctions::SendHousePurchase(Client* client, HouseZone* hz, int
 }
 
 void ClientPacketFunctions::SendHousingList(Client* client) {
-	if(client->GetVersion() <= 546) {
+	if(client->GetVersion() <= 561) {
 		return; // not supported
 	}
 	
@@ -140,7 +140,7 @@ void ClientPacketFunctions::SendBaseHouseWindow(Client* client, HouseZone* hz, P
 	PacketStruct* packet = nullptr;
 
 
-	if(client->GetVersion() > 546 && client->GetCurrentZone()->GetInstanceType() != PERSONAL_HOUSE_INSTANCE
+	if(client->GetVersion() > 561 && client->GetCurrentZone()->GetInstanceType() != PERSONAL_HOUSE_INSTANCE
 			&& client->GetCurrentZone()->GetInstanceType() != GUILD_HOUSE_INSTANCE) {
 		packet = configReader.getStruct("WS_UpdateHouseAccessDataMsg", client->GetVersion());
 		

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

@@ -1906,7 +1906,7 @@ void Item::serialize(PacketStruct* packet, bool show_name, Player* player, int16
 			else {
 				packet->setArrayDataByName("stat_type", stat_type, i-dropstat);
 				
-				if(client->GetVersion() <= 546 && stat_type == 5) {
+				if(client->GetVersion() <= 561 && stat_type == 5) {
 					valueSet = true;
 					// DoF client has to be goofy about this junk, stat_subtype is the stat value, value is always "9" and we set the stat_name to the appropriate stat (but power=mana)
 					packet->setArrayDataByName("stat_subtype", (sint16)statValue , i - dropstat);
@@ -2108,7 +2108,7 @@ void Item::serialize(PacketStruct* packet, bool show_name, Player* player, int16
 					tradeskill_class_levels[i] = tmp_level;
 			}
 		}
-		if (client->GetVersion() <= 546) { //simplify display (if possible)
+		if (client->GetVersion() <= 561) { //simplify display (if possible)
 			map<int8, int16> new_adv_class_levels;
 			for (int i = 1; i <= 31; i += 10) {
 				bool add_archetype = CheckArchetypeAdvClass(i, &adv_class_levels);
@@ -2219,7 +2219,7 @@ void Item::serialize(PacketStruct* packet, bool show_name, Player* player, int16
 				else if(slot == EQ2_DRINK_SLOT)
 					slot = EQ2_ORIG_DRINK_SLOT;
 			}
-			else if (client->GetVersion() <= 546) {
+			else if (client->GetVersion() <= 561) {
 				if (slot > EQ2_EARS_SLOT_1 && slot <= EQ2_WAIST_SLOT) //they added a second ear slot later, adjust for only 1 original slot
 					slot -= 1;
 				else if (slot == EQ2_FOOD_SLOT)
@@ -2237,7 +2237,7 @@ void Item::serialize(PacketStruct* packet, bool show_name, Player* player, int16
 		int8 tmpType = generic_info.item_type;
 		if (client->GetVersion() <= 283 && generic_info.item_type > ITEM_TYPE_RECIPE)
 			tmpType = 0;
-		else if(client->GetVersion() <= 546 && (generic_info.item_type > ITEM_TYPE_HOUSE || generic_info.item_type == ITEM_TYPE_BAUBLE))
+		else if(client->GetVersion() <= 561 && (generic_info.item_type > ITEM_TYPE_HOUSE || generic_info.item_type == ITEM_TYPE_BAUBLE))
 			tmpType = 0;
 		
 		packet->setSubstructDataByName("header", "item_type", tmpType);
@@ -2591,20 +2591,20 @@ void Item::serialize(PacketStruct* packet, bool show_name, Player* player, int16
 
 PacketStruct* Item::PrepareItem(int16 version, bool merchant_item, bool loot_item){
 	PacketStruct* packet = 0;
-	if(loot_item && version > 546)
+	if(loot_item && version > 561)
 		packet = configReader.getStruct("WS_LootItemGeneric", version);
-	else if(loot_item && version <= 546) {
+	else if(loot_item && version <= 561) {
 		packet = configReader.getStruct("WS_ItemGeneric", version);
 		packet->AddFlag("loot");
 	}
-	else if(version <= 546 && (generic_info.item_type > ITEM_TYPE_HOUSE || generic_info.item_type == ITEM_TYPE_BAUBLE)) {
+	else if(version <= 561 && (generic_info.item_type > ITEM_TYPE_HOUSE || generic_info.item_type == ITEM_TYPE_BAUBLE)) {
 		packet = configReader.getStruct("WS_ItemGeneric", version);
 	}
 	else{
 		int8 tmpType = generic_info.item_type;
 		if (version <= 283 && generic_info.item_type > ITEM_TYPE_RECIPE)
 			tmpType = 0;
-		else if(version <= 546 && (generic_info.item_type > ITEM_TYPE_HOUSE || generic_info.item_type == ITEM_TYPE_BAUBLE))
+		else if(version <= 561 && (generic_info.item_type > ITEM_TYPE_HOUSE || generic_info.item_type == ITEM_TYPE_BAUBLE))
 			tmpType = 0;
 		
 		switch(tmpType){
@@ -2734,7 +2734,7 @@ EQ2Packet* Item::serialize(int16 version, bool show_name, Player* player, bool i
 	PacketStruct* packet = PrepareItem(version, merchant_item, loot_item);
 	if(!packet)
 		return 0;
-	if (version <= 546) {
+	if (version <= 561) {
 		include_twice = false;
 		packet_type = 0;
 	}
@@ -3529,7 +3529,7 @@ bool PlayerItemList::MoveItem(sint32 to_bag_id, int16 from_index, sint8 to, int8
 
 EQ2Packet* PlayerItemList::serialize(Player* player, int16 version){
 	bool firstRun = false;
-	if(version <= 547 && !packet_count) {
+	if(version <= 561 && !packet_count) {
 		firstRun = true;
 	}
 	EQ2Packet* app = 0;
@@ -3765,7 +3765,7 @@ void PlayerItemList::AddItemToPacket(PacketStruct* packet, Player* player, Item*
 	if (overflow)
 		packet->setSubstructArrayDataByName("items", "index", 0xFFFF, 0, i);
 	else {
-		if(packet->GetVersion() <= 546) {
+		if(packet->GetVersion() <= 561) {
 				/* DoF client and earlier side automatically assigns indexes
 				** we have to send 0xFF or else all index is set to 255 on client
 				** and then examine inventory won't work */
@@ -4494,7 +4494,7 @@ int8 EquipmentItemList::GetFreeSlot(Item* tmp, int8 slot_id, int16 version){
 			}
 			else if ( slot == EQ2_LRING_SLOT || slot == EQ2_EARS_SLOT_1 || slot == EQ2_LWRIST_SLOT || slot == EQ2_CHARM_SLOT_1)
 			{
-				if(version <= 546 && slot == EQ2_EARS_SLOT_1)
+				if(version <= 561 && slot == EQ2_EARS_SLOT_1)
 					continue;
 			
 				Item* rslot = GetItem(slot+1);
@@ -4559,7 +4559,7 @@ int8 EquipmentItemList::GetSlotByItem(Item* item) {
 
 string Item::CreateItemLink(int16 client_Version, bool bUseUniqueID) {
 	ostringstream ss;
-	if(client_Version > 546)
+	if(client_Version > 561)
 		ss << "\\aITEM " << details.item_id << ' ' << (bUseUniqueID ? details.unique_id : 0) << ':' << name << "\\/a";
 	else {
 		if(bUseUniqueID)

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

@@ -317,7 +317,7 @@ bool LoginServer::Process() {
 			int8 resp = 0;
 			int32 acct_id = 0;
 			int32 char_id = 0;
-			if(packet && packet->LoadPacketData(pack->pBuffer+sizeof(int16),pack->size - sizeof(int16), version <= 546 ? false : true)){
+			if(packet && packet->LoadPacketData(pack->pBuffer+sizeof(int16),pack->size - sizeof(int16), version <= 561 ? false : true)){
 				EQ2_16BitString name = packet->getType_EQ2_16BitString_ByName("name");
 				resp = database.CheckNameFilter(name.data.c_str());
 				acct_id = packet->getType_int32_ByName("account_id");

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

@@ -810,6 +810,7 @@ EQ2Packet* PlayerInfo::serialize(int16 version, int16 modifyPos, int32 modifyVal
 		packet->setDataByName("aa_blue_bar", 0);// dov confirmed
 		packet->setDataByName("bonus_achievement_xp", 0); // dov confirmed
 
+		packet->setDataByName("level_events", 32);// dov confirmed
 		packet->setDataByName("items_found", 62);// dov confirmed
 		packet->setDataByName("named_npcs_killed", 192);// dov confirmed
 		packet->setDataByName("quests_completed", 670);// dov confirmed
@@ -988,7 +989,7 @@ EQ2Packet* PlayerInfo::serialize(int16 version, int16 modifyPos, int32 modifyVal
 		packet->setDataByName("unknown168", 168);
 		packet->setDataByName("decrease_falling_dmg", 169);
 
-		if (version <= 546) {
+		if (version <= 561) {
 			packet->setDataByName("exp_yellow", info_struct->get_xp_yellow() / 10);
 			packet->setDataByName("exp_blue", info_struct->get_xp_blue()/10);
 		}
@@ -997,7 +998,7 @@ EQ2Packet* PlayerInfo::serialize(int16 version, int16 modifyPos, int32 modifyVal
 			packet->setDataByName("exp_blue", info_struct->get_xp_blue());
 		}
 		
-		if (version <= 546) {
+		if (version <= 561) {
 			packet->setDataByName("tradeskill_exp_yellow", info_struct->get_tradeskill_exp_yellow() / 10);
 			packet->setDataByName("tradeskill_exp_blue", info_struct->get_tradeskill_exp_blue() / 10);
 		}
@@ -1180,6 +1181,8 @@ EQ2Packet* PlayerInfo::serialize(int16 version, int16 modifyPos, int32 modifyVal
 		string* data = packet->serializeString();
 		int32 size = data->length();
 
+		//DumpPacket((uchar*)data->c_str(), data->size());
+		//packet->PrintPacket();
 		uchar* tmp = new uchar[size];
 		bool reverse = version > 283;
 		if (!changes) {
@@ -1363,7 +1366,7 @@ int16 Player::ConvertSlotToClient(int8 slot, int16 version) {
 		else if (slot > EQ2_EARS_SLOT_1 && slot <= EQ2_WAIST_SLOT)
 			slot -= 1;
 	}
-	else if (version <= 546) {
+	else if (version <= 561) {
 		if (slot == EQ2_FOOD_SLOT)
 			slot = EQ2_DOF_FOOD_SLOT;
 		else if (slot == EQ2_DRINK_SLOT)
@@ -1383,7 +1386,7 @@ int16 Player::ConvertSlotFromClient(int8 slot, int16 version) {
 		else if (slot > EQ2_EARS_SLOT_1 && slot <= EQ2_WAIST_SLOT)
 			slot += 1;
 	}
-	else if (version <= 546) {
+	else if (version <= 561) {
 		if (slot == EQ2_DOF_FOOD_SLOT)
 			slot = EQ2_FOOD_SLOT;
 		else if (slot == EQ2_DOF_DRINK_SLOT)
@@ -1395,7 +1398,7 @@ int16 Player::ConvertSlotFromClient(int8 slot, int16 version) {
 }
 
 int16 Player::GetNumSlotsEquip(int16 version) {
-	if(version <= 546) {
+	if(version <= 561) {
 		return CLASSIC_NUM_SLOTS;
 	}
 	
@@ -1406,7 +1409,7 @@ int8 Player::GetMaxBagSlots(int16 version) {
 	if(version <= 283) {
 		return CLASSIC_EQ_MAX_BAG_SLOTS;
 	}
-	else if(version = 546) {
+	else if(version <= 561) {
 		return DOF_EQ_MAX_BAG_SLOTS;
 	}
 	
@@ -1721,7 +1724,7 @@ EQ2Packet* Player::SwapEquippedItems(int8 slot1, int8 slot2, int16 version, int1
 	return 0;
 }
 bool Player::CanEquipItem(Item* item, int8 slot) {
-	if(client && client->GetVersion() <= 546 && slot == EQ2_EARS_SLOT_2)
+	if(client && client->GetVersion() <= 561 && slot == EQ2_EARS_SLOT_2)
 		return false;
 	
 	if (item) {
@@ -4654,7 +4657,7 @@ PacketStruct* Player::GetQuestJournalPacket(Quest* quest, int16 version, int32 c
 		if (updated) {
 			packet->setArrayDataByName("quest_updated", 1);
 			packet->setArrayDataByName("journal_updated", 1);
-		}		
+		}
 		if(version >= 546)
 			packet->setDataByName("unknown3", 1);
 		packet->setDataByName("visible_quest_id", quest->GetQuestID());
@@ -6667,7 +6670,7 @@ void PlayerControlFlags::SendControlFlagUpdates(Client* client){
 		ptr = &itr->second;
 		for (itr2 = ptr->begin(); itr2 != ptr->end(); itr2++){
 			int32 param = itr2->first;
-			if(client->GetVersion() <= 546) {
+			if(client->GetVersion() <= 561) {
 				if(itr->first == 1) { // first set of flags DoF only supports these
 					bool skip = false;
 					switch(itr2->first) {

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

@@ -1007,7 +1007,7 @@ EQ2Packet* Quest::QuestJournalReply(int16 version, int32 player_crc, Player* pla
 
 		packet->setDataByName("bullets", 1);
 		if (old_completed_quest) {
-			if (version >= 1096 || version == 546) {
+			if (version >= 1096 || version == 546 || version == 561) {
 				packet->setDataByName("complete", 1);
 				packet->setDataByName("complete2", 1);
 				packet->setDataByName("complete3", 1);
@@ -1021,7 +1021,7 @@ EQ2Packet* Quest::QuestJournalReply(int16 version, int32 player_crc, Player* pla
 			}
 		}
 		// must always send for newer clients like AoM or else crash!
-		else if (GetCompleted() && ((version >= 1096) || (version == 546 && HasSentLastUpdate()))) { //need to send last quest update before erasing all progress of the quest
+		else if (GetCompleted() && ((version >= 1096) || ((version == 561 || version == 546) && HasSentLastUpdate()))) { //need to send last quest update before erasing all progress of the quest
 			packet->setDataByName("complete", 1);
 			packet->setDataByName("complete2", 1);
 			packet->setDataByName("complete3", 1);
@@ -1246,7 +1246,7 @@ EQ2Packet* Quest::QuestJournalReply(int16 version, int32 player_crc, Player* pla
 
 
 		string reward_str = "";
-		if (version >= 1096 || version == 546)
+		if (version >= 1096 || version == 546 ||  version == 561)
 			reward_str = "reward_data_";
 		string tmp = reward_str + "reward";
 		packet->setDataByName(tmp.c_str(), "Quest Reward!");

+ 3 - 3
EQ2/source/WorldServer/Recipes/Recipe.cpp

@@ -388,7 +388,7 @@ EQ2Packet * Recipe::SerializeRecipe(Client *client, Recipe *recipe, bool display
 	else
 		packet->setSubstructDataByName("info_header", "show_popup", 1);
 	
-	if(client->GetVersion() <= 546) {
+	if(client->GetVersion() <= 561) {
 		packet->setSubstructDataByName("info_header", "packettype", 0x02);
 	}
 	else if(packet_type > 0)
@@ -520,7 +520,7 @@ EQ2Packet * Recipe::SerializeRecipe(Client *client, Recipe *recipe, bool display
 	// Check to see if we have a primary component (slot = 0)
 	vector<Item*> itemss;
 	if (recipe->components.count(0) > 0) {
-		if(client->GetVersion() <= 546) {
+		if(client->GetVersion() <= 561) {
 			packet->setSubstructDataByName("recipe_info", "primary_count", 1);
 		}	
 		
@@ -598,7 +598,7 @@ EQ2Packet * Recipe::SerializeRecipe(Client *client, Recipe *recipe, bool display
 		
 	}
 	
-	if(client->GetVersion() <= 546) {
+	if(client->GetVersion() <= 561) {
 		packet->setSubstructDataByName("recipe_info", "fuel_count", 1);
 		packet->setSubstructDataByName("recipe_info", "fuel_comp", recipe->fuel_comp_title);
 		packet->setSubstructDataByName("recipe_info", "fuel_comp_qty", recipe->fuel_comp_qty);

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

@@ -355,13 +355,13 @@ EQ2Packet* PlayerSkillList::GetSkillPacket(int16 version){
 					skill_count++;
 			}
 			int16 size = 0;
-			if (version > 546) {
+			if (version > 561) {
 				size = 21 * skill_count + 8;
 			}
 			else if (version <= 283) {
 				size = 12 * skill_count + 6;
 			}
-			else if (version <= 546) {
+			else if (version <= 561) {
 				size = 21 * skill_count + 7;
 			}
 			
@@ -393,7 +393,7 @@ EQ2Packet* PlayerSkillList::GetSkillPacket(int16 version){
 				int16 skill_max_with_bonuses = CalculateSkillMaxValue(skill->skill_id, skill->max_val);
 				int16 skill_with_bonuses = int(CalculateSkillValue(skill->skill_id, skill->current_val));
 				packet->setArrayDataByName("skill_id", skill->skill_id, i);
-				if (version <= 546 && skill->skill_type >= SKILL_TYPE_GENERAL) { //covert it to DOF types
+				if (version <= 561 && skill->skill_type >= SKILL_TYPE_GENERAL) { //covert it to DOF types
 					packet->setArrayDataByName("type", skill->skill_type-2, i);					
 				}
 				else if(version >= 60085 && skill->skill_type >= 12) {

+ 69 - 18
EQ2/source/WorldServer/Spawn.cpp

@@ -240,7 +240,7 @@ void Spawn::InitializeHeaderPacketData(Player* player, PacketStruct* header, int
 				header->setArrayDataByName("command_list_command", primary_command_list[i]->command.c_str(), i);
 			}
 		}
-		if (header->GetVersion() <= 546) {
+		if (header->GetVersion() <= 561) {
 			header->setMediumStringByName("default_command", primary_command_list[0]->name.c_str());
 		}
 		else
@@ -289,7 +289,7 @@ void Spawn::InitializeVisPacketData(Player* player, PacketStruct* vis_packet) {
 
 	if (IsPlayer())
 		vis_packet->setDataByName("player", 1);
-	if (version <= 546) {
+	if (version <= 561) {
 		vis_packet->setDataByName("targetable", appearance.targetable);
 		vis_packet->setDataByName("show_name", appearance.display_name);
 		vis_packet->setDataByName("attackable", appearance.attackable);
@@ -411,7 +411,7 @@ void Spawn::InitializeVisPacketData(Player* player, PacketStruct* vis_packet) {
 		if ((req_quests_override & 256) > 0)
 			vis_packet->setDataByName("hand_flag", 1);
 	}
-	if (version == 546 && GetMerchantID() > 0) {
+	if ((version == 546 || version == 561) && GetMerchantID() > 0) {
 		vis_packet->setDataByName("guild", "<Merchant>");
 	}
 }
@@ -501,7 +501,7 @@ EQ2Packet* Spawn::spawn_serialize(Player* player, int16 version, int16 offset, i
 		footer = player->GetWidgetFooterStruct();
 	else if (IsSign())
 		footer = player->GetSignFooterStruct();
-	else if (version > 546)
+	else if (version > 561)
 		footer = player->GetSpawnFooterStruct();
 	if (footer) {
 		footer->ResetData();
@@ -715,7 +715,6 @@ EQ2Packet* Spawn::spawn_serialize(Player* player, int16 version, int16 offset, i
 	delete[] part2;
 
 	//printf("SpawnPacket %s (id: %u, index: %u) to %s: p1: %i, p2: %i, p3: %i, ts: %i. poslength: %u, infolength: %u, vislength: %u\n", GetName(), GetID(), index, player->GetName(), part1->length(), part2_size, (part3 != nullptr) ? part3->length() : -1, total_size, poslength, infolength, vislength);
-
 	EQ2Packet* ret = new EQ2Packet(OP_ClientCmdMsg, final_packet, final_packet_size);
 	delete[] final_packet;
 
@@ -878,7 +877,7 @@ uchar* Spawn::spawn_pos_changes(Player* player, int16 version, int16* pos_packet
 	if (version >= 1188)
 		size += 1;
 
-	if(IsPlayer() && version > 546)
+	if(IsPlayer() && version > 561)
 		size += 4;
 	size-=sizeof(int32);
 	size+=CheckOverLoadSize(index);
@@ -891,7 +890,7 @@ uchar* Spawn::spawn_pos_changes(Player* player, int16 version, int16* pos_packet
 
 	// extra byte in coe+ clients, 0 for NPC's 1 for Players
 	int8 x = 0;
-	if (IsPlayer() && version > 546) {
+	if (IsPlayer() && version > 561) {
 		if (version >= 1188) {
 			// set x to 1 and add it to the packet
 			x = 1;
@@ -1273,7 +1272,7 @@ uchar* Spawn::spawn_pos_changes_ex(Player* player, int16 version, int16* pos_pac
 		size += 1;
 	}
 
-	if (IsPlayer() && version > 546) {
+	if (IsPlayer() && version > 561) {
 		size += 4;
 	}
 
@@ -1289,7 +1288,7 @@ uchar* Spawn::spawn_pos_changes_ex(Player* player, int16 version, int16* pos_pac
 	// extra byte in coe+ clients, 0 for NPC's 1 for Players
 	int8 x = 0;
 
-	if (version > 546) {
+	if (version > 561) {
 		if (IsPlayer()) {
 			if (version >= 1188) {
 				x = 1;
@@ -2316,6 +2315,7 @@ void Spawn::InitializeInfoPacketData(Player* spawn, PacketStruct* packet) {
 			int8 percent = 0;
 			if (GetHP() > 0)
 				percent = (int8)(((float)GetHP() / GetTotalHP()) * 100);
+			
 			if (version >= 284) {
 				if (percent < 100) {
 					packet->setDataByName("hp_remaining", 100 ^ percent);
@@ -2338,7 +2338,7 @@ void Spawn::InitializeInfoPacketData(Player* spawn, PacketStruct* packet) {
 		}
 	}
 
-	if (version <= 546) {
+	if (version <= 561) {
 		packet->setDataByName("name", appearance.name);
 		for (int8 i = 0; i < 8; i++)
 			packet->setDataByName("unknown1", 0xFF, i);
@@ -2354,7 +2354,7 @@ void Spawn::InitializeInfoPacketData(Player* spawn, PacketStruct* packet) {
 		packet->setDataByName("npc", 1);
 	if (GetMerchantID() > 0)
 		packet->setDataByName("merchant", 1);
-		
+	
 	packet->setDataByName("effective_level", IsEntity() && ((Entity*)this)->GetInfoStruct()->get_effective_level() != 0 ? (int8)((Entity*)this)->GetInfoStruct()->get_effective_level() : (int8)GetLevel());
 	packet->setDataByName("level", (int8)GetLevel());
 	packet->setDataByName("unknown4", (int8)GetLevel());
@@ -2513,7 +2513,7 @@ void Spawn::InitializeInfoPacketData(Player* spawn, PacketStruct* packet) {
 		//Hide hood check
 		bool vis_hide_hood = false;
 		if (IsPlayer() && ((Player*)this)->get_character_flag(CF_HIDE_HOOD)) {
-			if(version > 546) {
+			if(version > 561) {
 				vis_flag += INFO_VIS_FLAG_HIDE_HOOD;
 			}
 			vis_hide_hood = true;
@@ -2522,11 +2522,11 @@ void Spawn::InitializeInfoPacketData(Player* spawn, PacketStruct* packet) {
 			classicFlags += INFO_CLASSIC_FLAG_SHOW_HOOD;
 		}
 		
-		if(!vis_hide_hood && appearance.hide_hood && version > 546) {
+		if(!vis_hide_hood && appearance.hide_hood && version > 561) {
 			vis_flag += INFO_VIS_FLAG_HIDE_HOOD;
 		}
 			
-		if(version <= 546) {
+		if(version <= 561) {
 			packet->setDataByName("flags", classicFlags);
 		}
 		packet->setDataByName("visual_flag", vis_flag);
@@ -2645,7 +2645,7 @@ void Spawn::InitializeInfoPacketData(Player* spawn, PacketStruct* packet) {
 		temp_activity_status = 0;
 	}
 	temp_activity_status += (IsNPC() || IsObject() || IsGroundSpawn()) ? 1 << 1 : 0;
-	if (version >= 1188) {
+	if (version > 561) {
 		// Fix widget or sign having 'Play Legends of Norrath' or 'Tell' options in right click (client hard-coded entity commands)
 		if(IsWidget() || IsSign())
 			temp_activity_status = 2;
@@ -2696,6 +2696,57 @@ void Spawn::InitializeInfoPacketData(Player* spawn, PacketStruct* packet) {
 			temp_activity_status += ACTIVITY_STATUS_ISTRANSPORT_1188;
 		}
 	}
+	else if (version == 561) {
+		// Fix widget or sign having 'Play Legends of Norrath' or 'Tell' options in right click (client hard-coded entity commands)
+		if(IsWidget() || IsSign())
+			temp_activity_status = 2;
+
+		if (IsGroundSpawn() || GetShowHandIcon())
+			temp_activity_status += ACTIVITY_STATUS_INTERACTABLE_561;
+
+		if ((appearance.activity_status & ACTIVITY_STATUS_ROLEPLAYING) > 0)
+			temp_activity_status += ACTIVITY_STATUS_ROLEPLAYING_561;
+
+		if ((appearance.activity_status & ACTIVITY_STATUS_ANONYMOUS) > 0)
+			temp_activity_status += ACTIVITY_STATUS_ANONYMOUS_561;
+
+		if ((appearance.activity_status & ACTIVITY_STATUS_LINKDEAD) > 0)
+			temp_activity_status += ACTIVITY_STATUS_LINKDEAD_561;
+
+		if ((appearance.activity_status & ACTIVITY_STATUS_CAMPING) > 0)
+			temp_activity_status += ACTIVITY_STATUS_CAMPING_561;
+
+		if ((appearance.activity_status & ACTIVITY_STATUS_LFG) > 0)
+			temp_activity_status += ACTIVITY_STATUS_LFG_561;
+
+		if ((appearance.activity_status & ACTIVITY_STATUS_LFW) > 0)
+			temp_activity_status += ACTIVITY_STATUS_LFW_561;
+
+		if ((appearance.activity_status & ACTIVITY_STATUS_SOLID) > 0)
+			temp_activity_status += ACTIVITY_STATUS_SOLID_561;
+
+		if ((appearance.activity_status & ACTIVITY_STATUS_IMMUNITY_GAINED) > 0)
+			temp_activity_status += ACTIVITY_STATUS_IMMUNITY_GAINED_561;
+
+		if ((appearance.activity_status & ACTIVITY_STATUS_IMMUNITY_REMAINING) > 0)
+			temp_activity_status += ACTIVITY_STATUS_IMMUNITY_REMAINING_561;
+
+		if ((appearance.activity_status & ACTIVITY_STATUS_AFK) > 0)
+			temp_activity_status += ACTIVITY_STATUS_AFK_561;
+
+		if (EngagedInCombat())
+			temp_activity_status += ACTIVITY_STATUS_INCOMBAT_561;
+
+		// if this is either a boat or lift let the client be manipulated by the object
+		// doesn't work for DoF client version 546
+		if (appearance.icon == 28 || appearance.icon == 12 || IsTransportSpawn())
+		{
+			// there is some other flags that setting with a transport breaks their solidity/ability to properly transport
+			// thus we just consider the following flags for now as all necessary
+			temp_activity_status = ACTIVITY_STATUS_SOLID_561;
+			temp_activity_status += ACTIVITY_STATUS_ISTRANSPORT_561;
+		}
+	}
 	else
 	{
 		temp_activity_status = appearance.activity_status;
@@ -2744,8 +2795,8 @@ void Spawn::InitializeInfoPacketData(Player* spawn, PacketStruct* packet) {
 	*/
 	if (IsPlayer()) {
 		if (((Player*)this)->GetFollowTarget())
-			packet->setDataByName("follow_target", version <= 547 ? (((Player*)this)->GetIDWithPlayerSpawn(((Player*)this)->GetFollowTarget())) : ((((Player*)this)->GetIDWithPlayerSpawn(((Player*)this)->GetFollowTarget()) * -1) - 1));
-		else if(version <= 547) {
+			packet->setDataByName("follow_target", version <= 561 ? (((Player*)this)->GetIDWithPlayerSpawn(((Player*)this)->GetFollowTarget())) : ((((Player*)this)->GetIDWithPlayerSpawn(((Player*)this)->GetFollowTarget()) * -1) - 1));
+		else if(version <= 561) {
 			packet->setDataByName("follow_target", 0xFFFFFFFF);
 		}
 		//else
@@ -2756,7 +2807,7 @@ void Spawn::InitializeInfoPacketData(Player* spawn, PacketStruct* packet) {
 	//}
 	
 	// i think this is used in DoF as a way to make a client say they are in combat with this target and cannot camp, it forces you to stand up if self spawn sends this data
-	if ((version > 546 || spawn != this) && GetTarget() && GetTarget()->GetTargetable())
+	if ((version > 561 || spawn != this) && GetTarget() && GetTarget()->GetTargetable())
 		packet->setDataByName("target_id", ((spawn->GetIDWithPlayerSpawn(GetTarget()) * -1) - 1));
 	else
 		packet->setDataByName("target_id", 0xFFFFFFFF);

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

@@ -123,6 +123,30 @@
 // WE ARE UNSURE OF THESE OLD CLIENT VALUES USED AS TEMP PLACEHOLDERS FOR NEWER CLIENTS
 #define ACTIVITY_STATUS_AFK					32768 // whats the real one?
 
+#define ACTIVITY_STATUS_CORPSE_561					1
+#define ACTIVITY_STATUS_NPC_561						1<<1
+#define ACTIVITY_STATUS_STATICOBJECT_561			1<<2
+#define ACTIVITY_STATUS_MERCHANT_561				1<<4
+#define ACTIVITY_STATUS_HIDEICON_561				1<<8
+#define ACTIVITY_STATUS_INTERACTABLE_561			1<<9
+#define ACTIVITY_STATUS_NOTARGET_561				1<<10
+#define ACTIVITY_STATUS_ISTRANSPORT_561				1<<11
+#define ACTIVITY_STATUS_SHOWHOUSEICON_561			1<<12
+#define ACTIVITY_STATUS_LOOTABLE_561				1<<13
+#define ACTIVITY_STATUS_INCOMBAT_561				1<<14
+#define ACTIVITY_STATUS_AFK_561						1<<15
+#define ACTIVITY_STATUS_ROLEPLAYING_561				1<<16
+#define ACTIVITY_STATUS_ANONYMOUS_561				1<<17
+#define ACTIVITY_STATUS_LINKDEAD_561				1<<18
+#define ACTIVITY_STATUS_CAMPING_561					1<<19
+#define ACTIVITY_STATUS_LFG_561						1<<20
+#define ACTIVITY_STATUS_LFW_561						1<<21
+
+#define ACTIVITY_STATUS_SOLID_561					1<<23 //used by zone objects to remain solid
+#define ACTIVITY_STATUS_MENTORING_561				1<<28
+#define ACTIVITY_STATUS_IMMUNITY_GAINED_561			1<<30
+#define ACTIVITY_STATUS_IMMUNITY_REMAINING_561		1<<31
+
 #define ACTIVITY_STATUS_MERCENARY_1188				1<<2
 #define ACTIVITY_STATUS_STATICOBJECT_1188			1<<3
 #define ACTIVITY_STATUS_MERCHANT_1188				1<<4

+ 34 - 139
EQ2/source/WorldServer/Spells.cpp

@@ -364,6 +364,7 @@ void Spell::SetAAPacketInformation(PacketStruct* packet, AltAdvanceData* data, C
 		if (spell->type != 2) {
 			packet->setArrayLengthByName("current_num_levels", 0);
 			for (int32 i = 0; i < levels.size(); i++) {
+				// revisit when implementing AA and use AppendLevelInformation instead (this struct doesn't even exist yet for KoS)
 				packet->setArrayDataByName("spell_info_aa_adventure_class", levels[i]->adventure_class, i);
 				packet->setArrayDataByName("spell_info_aa_tradeskill_class", levels[i]->tradeskill_class, i);
 				packet->setArrayDataByName("spell_info_aa_spell_level", levels[i]->spell_level, i);
@@ -699,9 +700,35 @@ void Spell::SetAAPacketInformation(PacketStruct* packet, AltAdvanceData* data, C
 	}
 }
 
+void Spell::AppendLevelInformation(PacketStruct* packet) {
+	if(!packet)
+		return;
+	
+	vector <LevelArray*> newLevels;
+	vector <LevelArray*>* tmpArray = &levels;
+	if(packet->GetVersion() <= 561) {
+		for (int32 i = 0; i < tmpArray->size(); i++) {
+			LevelArray* levelData = tmpArray->at(i);
+			if((levelData->adventure_class != 255 && levelData->adventure_class > CLASSIC_MAX_ADVENTURE_CLASS) || (levelData->tradeskill_class != 255 && levelData->tradeskill_class > CLASSIC_MAX_TRADESKILL_CLASS))
+				continue;
+			
+			newLevels.push_back(levelData);
+		}
+		tmpArray = &newLevels;
+	}
+	
+	packet->setSubstructArrayLengthByName("spell_info", "num_levels", tmpArray->size());
+	for (int32 i = 0; i < tmpArray->size(); i++) {
+		LevelArray* levelData = tmpArray->at(i);
+		packet->setArrayDataByName("adventure_class", levelData->adventure_class, i);
+		packet->setArrayDataByName("tradeskill_class", levelData->tradeskill_class, i);
+		packet->setArrayDataByName("spell_level", levelData->spell_level, i);
+	}
+}
+
 sint16 Spell::TranslateClientSpellIcon(int16 version) {
 	sint16 spell_icon = GetSpellIcon();
-	if(version <= 546) {
+	if(version <= 561) {
 		switch(spell_icon) {
 			case 772: // tracking
 				spell_icon = 231; // ??
@@ -743,7 +770,7 @@ void Spell::SetPacketInformation(PacketStruct* packet, Client* client, bool disp
 		packet->setSubstructDataByName("spell_info", "version", 0x03);
 		packet->setSubstructDataByName("spell_info", "sub_version", 4890);
 	}
-	else if (packet->GetVersion() <= 546) {
+	else if (packet->GetVersion() <= 561) {
 		packet->setSubstructDataByName("spell_info", "version", 0x10);
 		packet->setSubstructDataByName("spell_info", "sub_version", 0x0f);
 	}
@@ -770,12 +797,7 @@ void Spell::SetPacketInformation(PacketStruct* packet, Client* client, bool disp
 	else
 		packet->setSubstructDataByName("spell_info", "spell_text_color", 3);
 	if (spell->type != 2) {
-		packet->setSubstructArrayLengthByName("spell_info", "num_levels", levels.size());
-		for (int32 i = 0; i < levels.size(); i++) {
-			packet->setArrayDataByName("adventure_class", levels[i]->adventure_class, i);
-			packet->setArrayDataByName("tradeskill_class", levels[i]->tradeskill_class, i);
-			packet->setArrayDataByName("spell_level", levels[i]->spell_level, i);
-		}
+		AppendLevelInformation(packet);
 	}
 	packet->setSubstructDataByName("spell_info", "unknown9", 20);
 	int16 hp_req = 0;
@@ -805,7 +827,7 @@ void Spell::SetPacketInformation(PacketStruct* packet, Client* client, bool disp
 	packet->setSubstructDataByName("spell_info", "tier", spell->tier);
 	packet->setSubstructDataByName("spell_info", "power_req", power_req);
 	packet->setSubstructDataByName("spell_info", "power_upkeep", spell->power_upkeep);
-	if (packet->GetVersion() <= 546) {//cast times are displayed differently on new clients
+	if (packet->GetVersion() <= 561) {//cast times are displayed differently on new clients
 		packet->setSubstructDataByName("spell_info", "cast_time", spell->cast_time/10);
 	}
 	else {
@@ -1031,133 +1053,6 @@ EQ2Packet* Spell::SerializeAASpell(Client* client, int8 tier, AltAdvanceData* da
 	//safe_delete_array(data3);
 	safe_delete(packet);
 	return outapp;
-	/*PacketStruct* packet = configReader.getStruct("WS_ExamineAASpellInfo", client->GetVersion());
-	packet->setSubstructDataByName("info_header", "show_name", 0);
-	packet->setSubstructDataByName("info_header", "show_popup", 0);
-	packet->setSubstructDataByName("info_header", "packettype", packet_type);
-	packet->setSubstructDataByName("info_header", "packetsubtype", sub_packet_type);
-	packet->setSubstructDataByName("Spell_info", "aa_id", data->spellID);
-	packet->setSubstructDataByName("Spell_info", "aa_tab_id", data->group);
-	packet->setSubstructDataByName("Spell_info", "aa_icon", data->icon);
-	packet->setSubstructDataByName("Spell_info", "aa_icon2", data->icon2);
-	packet->setSubstructDataByName("Spell_info", "current_rank", 0); // how to get this info to here?
-	packet->setSubstructDataByName("Spell_info", "max_rank", data->maxRank);
-	packet->setSubstructDataByName("Spell_info", "rank_cost", data->rankCost);
-	packet->setSubstructDataByName("spell_info", "unknown2", 20);
-	// Spell info
-	packet->setSubstructDataByName("spell_info", "id", spell->id);
-	packet->setSubstructDataByName("spell_info", "icon", spell->icon);
-	packet->setSubstructDataByName("spell_info", "icon2", spell->icon_heroic_op);	// fix struct element name eventually
-	packet->setSubstructDataByName("spell_info", "icontype", spell->icon_backdrop);	// fix struct element name eventually
-
-	if (packet->GetVersion() >= 63119) {
-		packet->setSubstructDataByName("spell_info", "version", 0x04);
-		packet->setSubstructDataByName("spell_info", "sub_version", 0x24);
-	}
-	else if (packet->GetVersion() >= 1193) {
-		packet->setSubstructDataByName("spell_info", "version", 0x00);
-		packet->setSubstructDataByName("spell_info", "sub_version", 0xD9);
-	}
-	else {
-		packet->setSubstructDataByName("spell_info", "version", 0x11);
-		packet->setSubstructDataByName("spell_info", "sub_version", 0x14);
-	}
-
-	packet->setSubstructDataByName("spell_info", "type", spell->type);
-	packet->setSubstructDataByName("spell_info", "unknown_MJ1d", 1); //63119 test
-	packet->setSubstructDataByName("spell_info", "class_skill", spell->class_skill);
-	packet->setSubstructDataByName("spell_info", "mastery_skill", spell->mastery_skill);
-	packet->setSubstructDataByName("spell_info", "duration_flag", spell->duration_until_cancel);
-	if (client && spell->type != 2) {
-		sint8 spell_text_color = client->GetPlayer()->GetArrowColor(GetLevelRequired(client));
-		if (spell_text_color != ARROW_COLOR_WHITE && spell_text_color != ARROW_COLOR_RED && spell_text_color != ARROW_COLOR_GRAY)
-			spell_text_color = ARROW_COLOR_WHITE;
-		spell_text_color -= 6;
-		if (spell_text_color < 0)
-			spell_text_color *= -1;
-		packet->setSubstructDataByName("spell_info", "spell_text_color", spell_text_color);
-	}
-	else
-		packet->setSubstructDataByName("spell_info", "spell_text_color", 3);
-	if (spell->type != 2) {
-		packet->setSubstructArrayLengthByName("spell_info", "num_levels", levels.size());
-		for (int32 i = 0; i < levels.size(); i++) {
-			packet->setArrayDataByName("adventure_class", levels[i]->adventure_class, i);
-			packet->setArrayDataByName("tradeskill_class", levels[i]->tradeskill_class, i);
-			packet->setArrayDataByName("spell_level", levels[i]->spell_level, i);
-		}
-	}
-	//packet->setSubstructDataByName("spell_info", "unknown9", 20);
-	int16 hp_req = 0;
-	int16 power_req = 0;
-	if (client) {
-		hp_req = GetHPRequired(client->GetPlayer());
-		power_req = GetPowerRequired(client->GetPlayer());
-
-		// might need version checks around these?
-		if (client->GetVersion() >= 1193)
-		{
-			int16 savagery_req = GetSavageryRequired(client->GetPlayer()); // dunno why we need to do this
-			packet->setSubstructDataByName("spell_info", "savagery_req", savagery_req);
-			packet->setSubstructDataByName("spell_info", "savagery_upkeep", spell->savagery_upkeep);
-		}
-		if (client->GetVersion() >= 57048)
-		{
-			int16 dissonance_req = GetDissonanceRequired(client->GetPlayer()); // dunno why we need to do this
-			packet->setSubstructDataByName("spell_info", "dissonance_req", dissonance_req);
-			packet->setSubstructDataByName("spell_info", "dissonance_upkeep", spell->dissonance_upkeep);
-		}
-	}
-	packet->setSubstructDataByName("spell_info", "tier", spell->tier);
-	packet->setSubstructDataByName("spell_info", "health_req", hp_req);
-	packet->setSubstructDataByName("spell_info", "health_upkeep", spell->hp_upkeep);
-	packet->setSubstructDataByName("spell_info", "power_req", power_req);
-	packet->setSubstructDataByName("spell_info", "power_upkeep", spell->power_upkeep);
-	packet->setSubstructDataByName("spell_info", "req_concentration", spell->req_concentration);
-	//packet->setDataByName("req_concentration2", 2);
-	packet->setSubstructDataByName("spell_info", "cast_time", spell->cast_time);
-	packet->setSubstructDataByName("spell_info", "recovery", spell->recovery);
-	packet->setSubstructDataByName("spell_info", "recast", spell->recast);
-	packet->setSubstructDataByName("spell_info", "radius", spell->radius);
-	packet->setSubstructDataByName("spell_info", "max_aoe_targets", spell->max_aoe_targets);
-	packet->setSubstructDataByName("spell_info", "friendly_spell", spell->friendly_spell);
-	//reageants??
-	packet->setSubstructArrayLengthByName("spell_info", "num_effects", effects.size());
-	for (int32 i = 0; i < effects.size(); i++) {
-		packet->setArrayDataByName("subbulletflag", effects[i]->subbullet, i);
-		packet->setArrayDataByName("effect", effects[i]->description.c_str(), i);
-		packet->setArrayDataByName("percentage", effects[i]->percentage, i);
-	}
-	//if (display_tier == true)
-	packet->setSubstructDataByName("spell_info", "display_spell_tier", spell->display_spell_tier);
-	//else
-	//	packet->setSubstructDataByName("spell_info", "display_spell_tier", 0);
-
-	// minimum range??
-	packet->setSubstructDataByName("spell_info", "range", spell->range);
-	packet->setSubstructDataByName("spell_info", "duration1", spell->duration1);
-	packet->setSubstructDataByName("spell_info", "duration2", spell->duration2);
-	//unknown9 ??
-	//duration flag??
-	packet->setSubstructDataByName("spell_info", "target", spell->target_type);
-	packet->setSubstructDataByName("spell_info", "can_effect_raid", spell->can_effect_raid);
-	packet->setSubstructDataByName("spell_info", "affect_only_group_members", spell->affect_only_group_members);
-	packet->setSubstructDataByName("spell_info", "group_spell", spell->group_spell);
-	packet->setSubstructDataByName("spell_info", "resistibility", spell->resistibility);
-	//unknown11 ??
-	//hit_bonus ??
-	//unknown12 ??
-	packet->setSubstructDataByName("spell_info", "name", &(spell->name));
-	packet->setSubstructDataByName("spell_info", "description", &(spell->description));
-	EQ2Packet* packetdata = packet->serialize();
-	//EQ2Packet* app = new EQ2Packet(OP_AdventureList, packetdata->pBuffer, packetdata->size);
-	EQ2Packet* app = new EQ2Packet(OP_ClientCmdMsg, packetdata->pBuffer, packetdata->size);
-	packet->PrintPacket();
-	//DumpPacket(app);
-	safe_delete(packet);
-	safe_delete(data);
-	return app;
-	*/
 }
 
 EQ2Packet* Spell::SerializeSpell(Client* client, bool display, bool trait_display, int8 packet_type, int8 sub_packet_type, const char* struct_name, bool send_partial_packet) {
@@ -1166,7 +1061,7 @@ EQ2Packet* Spell::SerializeSpell(Client* client, bool display, bool trait_displa
 		version = client->GetVersion();
 	if (!struct_name)
 		struct_name = "WS_ExamineSpellInfo";
-	if (version <= 546) {
+	if (version <= 561) {
 		if (packet_type == 1)
 			struct_name = "WS_ExamineEffectInfo";
 		else if (!display && (version<=283 || send_partial_packet))
@@ -1183,7 +1078,7 @@ EQ2Packet* Spell::SerializeSpell(Client* client, bool display, bool trait_displa
 		else
 			packet->setSubstructDataByName("info_header", "show_popup", 0);
 	}
-	if (version > 546) {
+	if (version > 561) {
 		if (packet_type > 0)
 			packet->setSubstructDataByName("info_header", "packettype", packet_type * 256 + 0xFE);
 		else
@@ -1220,7 +1115,7 @@ EQ2Packet* Spell::SerializeSpell(Client* client, bool display, bool trait_displa
 		offset = 14;
 	}
 	EQ2Packet* outapp = 0;
-	if (version > 546) {
+	if (version > 561) {
 		string* data1 = packet->serializeString();
 		uchar* data2 = (uchar*)data1->c_str();
 		uchar* ptr2 = data2;

+ 1 - 0
EQ2/source/WorldServer/Spells.h

@@ -339,6 +339,7 @@ public:
 	sint16 TranslateClientSpellIcon(int16 version);
 	void SetPacketInformation(PacketStruct* packet, Client* client = 0, bool display_tier = false);
 	void SetAAPacketInformation(PacketStruct* packet, AltAdvanceData* data, Client* client = 0, bool display_tier = false);
+	void AppendLevelInformation(PacketStruct* packet);
 	int8 GetSpellTier();
 	int32 GetSpellDuration();
 	int16 GetSpellIcon();

+ 38 - 33
EQ2/source/WorldServer/Trade.cpp

@@ -16,13 +16,13 @@ Trade::Trade(Entity* trader1, Entity* trader2) {
 	trade_max_slots = 12;
 	
 	if(trader1->IsPlayer()) {
-		if(((Player*)trader1)->GetClient() && ((Player*)trader1)->GetClient()->GetVersion() <= 547) {
+		if(((Player*)trader1)->GetClient() && ((Player*)trader1)->GetClient()->GetVersion() <= 561) {
 			trade_max_slots = 6;
 		}
 	}
 	
 	if(trader2->IsPlayer()) {
-		if(((Player*)trader2)->GetClient() && ((Player*)trader2)->GetClient()->GetVersion() <= 547) {
+		if(((Player*)trader2)->GetClient() && ((Player*)trader2)->GetClient()->GetVersion() <= 561) {
 			trade_max_slots = 6;
 		}
 	}
@@ -482,6 +482,7 @@ void Trade::SendTradePacket() {
 			packet->setDataByName("their_plat", plat);
 
 			LogWrite(PLAYER__ERROR, 0, "Trade", "packet sent");
+			packet->PrintPacket();
 			client->QueuePacket(packet->serialize());
 			safe_delete(packet);
 		}
@@ -492,24 +493,25 @@ void Trade::SendTradePacket() {
 		if(!client) {
 			return;
 		}
-		PacketStruct* packet = configReader.getStruct("WS_PlayerTrade", client->GetVersion());
-		if (packet) {
-			packet->setDataByName("spawn_id", client->GetPlayer()->GetIDWithPlayerSpawn(trader1));
-			packet->setDataByName("type", 1);
+		PacketStruct* packet2 = configReader.getStruct("WS_PlayerTrade", client->GetVersion());
+		if (packet2) {
+			packet2->setDataByName("spawn_id", client->GetPlayer()->GetIDWithPlayerSpawn(trader1));
+			packet2->setDataByName("type", 1);
 
 			int8 size = (int8)(trader2_items.size());
 			int8 i = 0;
 			map<int8, TradeItemInfo>::iterator itr;
 
-			packet->setArrayLengthByName("your_item_count", size);
+			packet2->setArrayLengthByName("your_item_count", size);
 			for (itr = trader2_items.begin(); itr != trader2_items.end(); itr++) {
-				packet->setArrayDataByName("your_item_unknown1", 1, i);
-				packet->setArrayDataByName("your_item_unknown2", 1, i);
-				packet->setArrayDataByName("your_item_slot", itr->first, i);
-				packet->setArrayDataByName("your_item_id", itr->second.item->details.item_id, i);
-				packet->setArrayDataByName("your_item_quantity", itr->second.quantity, i);
-				packet->setArrayDataByName("your_item_icon", itr->second.item->details.icon, i);
-				packet->setArrayDataByName("your_item_background", 0, i); // No clue on this value yet
+				packet2->setArrayDataByName("your_item_unknown1", 1, i);
+				packet2->setArrayDataByName("your_item_unknown2", 1, i);
+				packet2->setArrayDataByName("your_item_slot", itr->first, i);
+				packet2->setArrayDataByName("your_item_id", itr->second.item->details.item_id, i);
+				packet2->setArrayDataByName("your_item_name", itr->second.item->name.c_str(), i);
+				packet2->setArrayDataByName("your_item_quantity", itr->second.quantity, i);
+				packet2->setArrayDataByName("your_item_icon", itr->second.item->details.icon, i);
+				packet2->setArrayDataByName("your_item_background", 0, i); // No clue on this value yet
 				i++;
 			}
 			int32 plat = 0;
@@ -518,23 +520,24 @@ void Trade::SendTradePacket() {
 			int32 copper = 0;
 
 			CalculateCoins(trader2_coins, plat, gold, silver, copper);
-			packet->setDataByName("your_copper", copper);
-			packet->setDataByName("your_silver", silver);
-			packet->setDataByName("your_gold", gold);
-			packet->setDataByName("your_plat", plat);
+			packet2->setDataByName("your_copper", copper);
+			packet2->setDataByName("your_silver", silver);
+			packet2->setDataByName("your_gold", gold);
+			packet2->setDataByName("your_plat", plat);
 
 			size = (int8)(trader1_items.size());
 			i = 0;
 
-			packet->setArrayLengthByName("their_item_count", size);
+			packet2->setArrayLengthByName("their_item_count", size);
 			for (itr = trader1_items.begin(); itr != trader1_items.end(); itr++) {
-				packet->setArrayDataByName("their_item_unknown1", 1, i);
-				packet->setArrayDataByName("their_item_unknown2", 1, i);
-				packet->setArrayDataByName("their_item_slot", itr->first, i);
-				packet->setArrayDataByName("their_item_id", itr->second.item->details.item_id, i);
-				packet->setArrayDataByName("their_item_quantity", itr->second.quantity, i);
-				packet->setArrayDataByName("their_item_icon", itr->second.item->details.icon, i);
-				packet->setArrayDataByName("their_item_background", 0, i); // No clue on this value yet
+				packet2->setArrayDataByName("their_item_unknown1", 1, i);
+				packet2->setArrayDataByName("their_item_unknown2", 1, i);
+				packet2->setArrayDataByName("their_item_slot", itr->first, i);
+				packet2->setArrayDataByName("their_item_id", itr->second.item->details.item_id, i);
+				packet2->setArrayDataByName("their_item_name", itr->second.item->name.c_str(), i);
+				packet2->setArrayDataByName("their_item_quantity", itr->second.quantity, i);
+				packet2->setArrayDataByName("their_item_icon", itr->second.item->details.icon, i);
+				packet2->setArrayDataByName("their_item_background", 0, i); // No clue on this value yet
 				i++;
 			}
 
@@ -544,13 +547,15 @@ void Trade::SendTradePacket() {
 			copper = 0;
 
 			CalculateCoins(trader1_coins, plat, gold, silver, copper);
-			packet->setDataByName("their_copper", copper);
-			packet->setDataByName("their_silver", silver);
-			packet->setDataByName("their_gold", gold);
-			packet->setDataByName("their_plat", plat);
-
-			client->QueuePacket(packet->serialize());
-			safe_delete(packet);
+			packet2->setDataByName("their_copper", copper);
+			packet2->setDataByName("their_silver", silver);
+			packet2->setDataByName("their_gold", gold);
+			packet2->setDataByName("their_plat", plat);
+			
+			LogWrite(PLAYER__ERROR, 0, "Trade", "packet sent #2");
+			packet2->PrintPacket();
+			client->QueuePacket(packet2->serialize());
+			safe_delete(packet2);
 		}
 	}
 }

+ 1 - 1
EQ2/source/WorldServer/Tradeskills/TradeskillsPackets.cpp

@@ -346,7 +346,7 @@ void ClientPacketFunctions::SendCreateFromRecipe(Client* client, int32 recipeID)
 			item_player = 0;
 			item_player = client->GetPlayer()->item_list.GetItemFromID((*itr));
 
-			if(client->GetVersion() <= 546) {
+			if(client->GetVersion() <= 561) {
 				packet->setDataByName("fuel_qty", item->details.count);
 				packet->setDataByName("fuel_icon", item->details.icon);
 			}

+ 2 - 2
EQ2/source/WorldServer/Widget.cpp

@@ -426,7 +426,7 @@ void Widget::HandleUse(Client* client, string command, int8 overrideWidgetType){
 		PlayerHouse* ph = nullptr;
 		
 		int32 id = 0;
-		if(client->GetVersion() <= 546) {
+		if(client->GetVersion() <= 561) {
 			id = client->GetPlayer()->GetIDWithPlayerSpawn(this);
 			ph = world.GetPlayerHouse(client, id, 0, &hz);
 		}
@@ -440,7 +440,7 @@ void Widget::HandleUse(Client* client, string command, int8 overrideWidgetType){
 		
 		if (ph && hz) {
 			// if we aren't in our own house we should get the full list of houses we can visit
-			if ( client->GetCurrentZone()->GetInstanceType() != Instance_Type::PERSONAL_HOUSE_INSTANCE && client->GetVersion() > 546 )
+			if ( client->GetCurrentZone()->GetInstanceType() != Instance_Type::PERSONAL_HOUSE_INSTANCE && client->GetVersion() > 561 )
 				ClientPacketFunctions::SendHouseVisitWindow(client, world.GetAllPlayerHousesByHouseID(hz->id));
 
 			ClientPacketFunctions::SendBaseHouseWindow(client, hz, ph, id);

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

@@ -2295,7 +2295,7 @@ int8 World::TranslateSlotSubTypeToClient(Client* client, int8 stat_type, sint16
 	int8 new_subtype = (int8)sub_type;
 	switch(stat_type) {
 		case 2: {
-			if(client->GetVersion() <= 546) {
+			if(client->GetVersion() <= 561) {
 				if(sub_type == (ITEM_STAT_VS_POISON-200)) // poison
 					new_subtype = 9;
 				else if(sub_type == (ITEM_STAT_VS_DISEASE-200)) // disease

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

@@ -96,6 +96,8 @@ using namespace std;
 	//52 - jeweler
 	//53 - sage
 	//54 - alch
+#define CLASSIC_MAX_ADVENTURE_CLASS 40 // there is a 41, but its 'scantestbase'
+#define CLASSIC_MAX_TRADESKILL_CLASS 13
 #define MAX_CLASSES		58
 
 class Classes {

+ 54 - 50
EQ2/source/WorldServer/client.cpp

@@ -405,7 +405,7 @@ void Client::SendLoginInfo() {
 	LogWrite(CCLIENT__DEBUG, 0, "Client", "Send Quest Journal...");
 	SendQuestJournal(true, 0, false);
 
-	if (version > 546) // right version? possibly not!
+	if (version > 561) // right version? possibly not!
 		master_aa_list.DisplayAA(this, 0, 3);
 
 	if (version > 283)
@@ -454,9 +454,11 @@ void Client::SendLoginInfo() {
 	ClientPacketFunctions::SendCommandList(this);
 
 	LogWrite(CCLIENT__DEBUG, 0, "Client", "Send Language Updates...");
+	
+	// kos doesn't like one of these language or instance list
 	SendLanguagesUpdate(database.GetCharacterCurrentLang(GetCharacterID(), player));
 
-	ClientPacketFunctions::SendInstanceList(this);
+	//ClientPacketFunctions::SendInstanceList(this);
 
 	SendZoneInfo();
 	/*Spell* spell = 0;
@@ -524,7 +526,7 @@ void Client::DisplayDeadWindow()
 	player->SetPower(0);
 	GetCurrentZone()->TriggerCharSheetTimer();
 
-	if(GetVersion() <= 546) {
+	if(GetVersion() <= 561) {
 		ClientPacketFunctions::SendServerControlFlagsClassic(this, 8, 1);
 		ClientPacketFunctions::SendServerControlFlagsClassic(this, 16, 1);
 	}
@@ -547,7 +549,7 @@ void Client::DisplayDeadWindow()
 
 void Client::HandlePlayerRevive(int32 point_id)
 {
-	if(GetVersion() <= 546) {
+	if(GetVersion() <= 561) {
 		ClientPacketFunctions::SendServerControlFlagsClassic(this, 8, 0);
 		ClientPacketFunctions::SendServerControlFlagsClassic(this, 16, 0);
 	}
@@ -729,7 +731,7 @@ void Client::SendCharInfo() {
 	//sending bad spawn packet?
 
 	//SendAchievementsList();
-	//if (version > 546)
+	//if (version > 561)
 		//ClientPacketFunctions::SendHousingList(this);
 	
 	ClientPacketFunctions::SendCharacterSheet(this);
@@ -804,7 +806,7 @@ void Client::SendCharInfo() {
 	if(!GetPlayer()->IsReturningFromLD()) {
 		database.LoadBuyBacks(this);
 	}
-	if (version > 546)
+	if (version > 561)
 		master_aa_list.DisplayAA(this, 0, 0);
 
 	string zone_motd = GetCurrentZone()->GetZoneMOTD();
@@ -943,7 +945,7 @@ void Client::SendZoneInfo() {
 	if (zone) {
 		EQ2Packet* packet = zone->GetZoneInfoPacket(this);
 		QueuePacket(packet);
-		if (version > 283) {
+		if (version > 561) {
 			PacketStruct* fog_packet = configReader.getStruct("WS_FogInit", GetVersion());
 
 			LogWrite(CCLIENT__PACKET, 0, "Client", "Dump/Print Packet in func: %s, line: %i", __FUNCTION__, __LINE__);
@@ -1526,11 +1528,11 @@ bool Client::HandlePacket(EQApplicationPacket* app) {
 		break;
 	}
 	case OP_DoneLoadingUIResourcesMsg: {
-		if(GetVersion() <= 547) {
+		if(GetVersion() <= 561) {
 			ClientPacketFunctions::SendUpdateSpellBook(this);
 		}
 			// need to quickly flash the DoF client the rest of their inventory
-		if(GetVersion() <= 547) {
+		if(GetVersion() <= 561) {
 			EQ2Packet* item_app = player->GetPlayerItemList()->serialize(GetPlayer(), GetVersion());
 			if (item_app) {
 				QueuePacket(item_app);
@@ -1878,7 +1880,7 @@ bool Client::HandlePacket(EQApplicationPacket* app) {
 						player_pos_changed = true;
 						GetPlayer()->AddChangedZoneSpawn();
 						ProcessZoneIgnoreWidgets();
-						if (version <= 547) {
+						if (version <= 561) {
 							master_trait_list.ChooseNextTrait(this);
 						}
 						
@@ -1933,7 +1935,7 @@ bool Client::HandlePacket(EQApplicationPacket* app) {
 					if (command.size > 0) {
 						string command_name = command.data;					
 						if (command_name.find(" ") < 0xFFFFFFFF) {
-							if (GetVersion() <= 546) { //this version uses commands in the form "Buy From Merchant" instead of buy_from_merchant
+							if (GetVersion() <= 561) { //this version uses commands in the form "Buy From Merchant" instead of buy_from_merchant
 								string::size_type pos = command_name.find(" ");
 								while(pos != string::npos){
 									command_name.replace(pos, 1, "_");
@@ -2019,7 +2021,7 @@ bool Client::HandlePacket(EQApplicationPacket* app) {
 	}
 	case OP_PredictionUpdateMsg: {
 		LogWrite(OPCODE__DEBUG, 1, "Opcode", "Opcode 0x%X (%i): OP_PredictionUpdateMsg", opcode, opcode);
-		if (version <= 546) {
+		if (version <= 561) {
 			int8 offset = 9;
 			if (app->pBuffer[0] == 0xFF)
 				offset += 2;
@@ -2264,7 +2266,7 @@ bool Client::HandlePacket(EQApplicationPacket* app) {
 		if (packet) {
 			if(packet->LoadPacketData(app->pBuffer, app->size)) {
 				int64 house_id = 0;
-				if(GetVersion() <= 546) {
+				if(GetVersion() <= 561) {
 					house_id = packet->getType_int32_ByName("house_id");
 				}
 				else {
@@ -2305,7 +2307,7 @@ bool Client::HandlePacket(EQApplicationPacket* app) {
 						world.AddPlayerHouse(GetPlayer()->GetCharacterID(), hz->id, unique_id, instance_zone->GetInstanceID(), upkeep_due, 0, 0, GetPlayer()->GetName());
 						//ClientPacketFunctions::SendHousingList(this);
 						PlayerHouse* ph = world.GetPlayerHouseByUniqueID(unique_id);
-						ClientPacketFunctions::SendBaseHouseWindow(this, hz, ph, GetVersion() <= 546 ? house_id : this->GetPlayer()->GetID());
+						ClientPacketFunctions::SendBaseHouseWindow(this, hz, ph, GetVersion() <= 561 ? house_id : this->GetPlayer()->GetID());
 						PlaySound("coin_cha_ching");
 					}
 					else if (status_req <= available_status && got_bank_money == 1) {
@@ -2325,7 +2327,7 @@ bool Client::HandlePacket(EQApplicationPacket* app) {
 							int64 unique_id = database.AddPlayerHouse(GetPlayer()->GetCharacterID(), hz->id, instance_zone->GetInstanceID(), upkeep_due);
 							world.AddPlayerHouse(GetPlayer()->GetCharacterID(), hz->id, unique_id, instance_zone->GetInstanceID(), upkeep_due, 0, 0, GetPlayer()->GetName());
 							PlayerHouse* ph = world.GetPlayerHouseByUniqueID(unique_id);
-							ClientPacketFunctions::SendBaseHouseWindow(this, hz, ph, GetVersion() <= 546 ? house_id : this->GetPlayer()->GetID());
+							ClientPacketFunctions::SendBaseHouseWindow(this, hz, ph, GetVersion() <= 561 ? house_id : this->GetPlayer()->GetID());
 							PlaySound("coin_cha_ching");
 					}
 					else
@@ -2351,7 +2353,7 @@ bool Client::HandlePacket(EQApplicationPacket* app) {
 				int64 house_id = 0;
 				int32 spawn_index = 0;
 				
-				if(GetVersion() <= 546) {
+				if(GetVersion() <= 561) {
 					spawn_index = packet->getType_int32_ByName("house_id");
 				}
 				else {
@@ -2377,14 +2379,14 @@ bool Client::HandlePacket(EQApplicationPacket* app) {
 			if(packet->LoadPacketData(app->pBuffer, app->size)) {
 				int64 house_id = 0;
 				
-				if(GetVersion() <= 546) {
+				if(GetVersion() <= 561) {
 					house_id = packet->getType_int32_ByName("house_id");
 				}
 				else {
 					house_id = packet->getType_int64_ByName("house_id");
 				}
 				HouseZone* hz = nullptr;
-				PlayerHouse* ph = world.GetPlayerHouse(this, GetVersion() <= 546 ? house_id : 0, GetVersion() > 546 ? house_id : 0, &hz);
+				PlayerHouse* ph = world.GetPlayerHouse(this, GetVersion() <= 561 ? house_id : 0, GetVersion() > 561 ? house_id : 0, &hz);
 				if (ph)
 				{
 					if (!hz)
@@ -2463,7 +2465,7 @@ bool Client::HandlePacket(EQApplicationPacket* app) {
 						ph->upkeep_due = upkeep_due;
 						database.SetHouseUpkeepDue(GetCharacterID(), ph->house_id, ph->instance_id, ph->upkeep_due);
 						//ClientPacketFunctions::SendHousingList(this);
-						ClientPacketFunctions::SendBaseHouseWindow(this, hz, ph, GetVersion() <= 546 ? house_id : this->GetPlayer()->GetID());
+						ClientPacketFunctions::SendBaseHouseWindow(this, hz, ph, GetVersion() <= 561 ? house_id : this->GetPlayer()->GetID());
 						PlaySound("coin_cha_ching");
 					}
 					else if (!statusReq && got_bank_money == 1) {
@@ -2484,7 +2486,7 @@ bool Client::HandlePacket(EQApplicationPacket* app) {
 
 						ph->upkeep_due = upkeep_due;
 						database.SetHouseUpkeepDue(GetCharacterID(), ph->house_id, ph->instance_id, ph->upkeep_due);
-						ClientPacketFunctions::SendBaseHouseWindow(this, hz, ph, GetVersion() <= 546 ? house_id : this->GetPlayer()->GetID());
+						ClientPacketFunctions::SendBaseHouseWindow(this, hz, ph, GetVersion() <= 561 ? house_id : this->GetPlayer()->GetID());
 						PlaySound("coin_cha_ching");
 					}
 					else
@@ -2697,7 +2699,7 @@ bool Client::HandlePacket(EQApplicationPacket* app) {
 	{
 		LogWrite(OPCODE__DEBUG, 1, "Opcode", "Opcode 0x%X (%i): OP_SubmitCharCust", opcode, opcode);
 		PacketStruct* packet = configReader.getStruct("WS_SubmitCharCust", version);
-		if (packet && packet->LoadPacketData(app->pBuffer, app->size, GetVersion() <= 546 ? false : true)) {
+		if (packet && packet->LoadPacketData(app->pBuffer, app->size, GetVersion() <= 561 ? false : true)) {
 			int8 type = packet->getType_int8_ByName("type");
 			if (type == 0) {
 				/*if (player->custNPC) {
@@ -2867,7 +2869,7 @@ bool Client::HandleLootItem(Spawn* entity, Item* item, Spawn* target, bool overr
 
 			lootingClient->CheckPlayerQuestsItemUpdate(item);
 
-			if (GetVersion() <= 546) {
+			if (GetVersion() <= 561) {
 				EQ2Packet* outapp = lootingPlayer->SendInventoryUpdate(GetVersion());
 				if (outapp)
 					lootingClient->QueuePacket(outapp);
@@ -2922,7 +2924,7 @@ void Client::HandleLootItemRequestPacket(EQApplicationPacket* app) {
 							if (loot_all) {
 								player->RemovePendingLootItem(loot_id, item->details.item_id);
 
-								if (GetVersion() <= 546) {
+								if (GetVersion() <= 561) {
 									EQ2Packet* outapp = player->SendInventoryUpdate(GetVersion());
 									if (outapp)
 										QueuePacket(outapp);
@@ -2995,7 +2997,7 @@ void Client::HandleLootItemRequestPacket(EQApplicationPacket* app) {
 							if (button_clicked == 3) { // decline
 								break;
 							}
-							if (GetVersion() <= 546) {
+							if (GetVersion() <= 561) {
 								button_clicked = 1; // selecting is need
 							}
 							spawn->AddNeedGreedItemRequest(item_id, GetPlayer()->GetID(), (button_clicked == 1));
@@ -3031,7 +3033,7 @@ void Client::HandleLootItemRequestPacket(EQApplicationPacket* app) {
 					}
 				}
 
-				if (GetVersion() > 546) {
+				if (GetVersion() > 561) {
 					EQ2Packet* outapp = player->SendInventoryUpdate(GetVersion());
 					if (outapp)
 						QueuePacket(outapp);
@@ -3161,9 +3163,9 @@ void Client::HandleExamineInfoRequest(EQApplicationPacket* app) {
 		bool display = true;
 		if (version <= 283 && request->getType_int8_ByName("display") == 1) // this is really requesting a partial packet
 			display = false;
-		else if (version <= 546)
+		else if (version <= 561)
 			display = request->getType_int8_ByName("display");
-		else if (version > 546)
+		else if (version > 561)
 			display = false; // clients default is false otherwise it pops up a window when hovering over the knowledge book abilities
 
 		//printf("Type: (%i) Tier: (%u) Unknown ID: (%u) Item ID: (%u)\n",type,tier,trait_tier,id);
@@ -3198,8 +3200,8 @@ void Client::HandleExamineInfoRequest(EQApplicationPacket* app) {
 			//DumpPacket(app);
 			QueuePacket(app);
 		}
-		else if(spell && GetVersion() <=546 && CountSentSpell(spell->GetSpellID(), spell->GetSpellTier())) {
-			EQ2Packet* app = spell->SerializeSpell(this, display, trait_display, GetVersion() <= 546 ? true : false);
+		else if(spell && GetVersion() <=561 && CountSentSpell(spell->GetSpellID(), spell->GetSpellTier())) {
+			EQ2Packet* app = spell->SerializeSpell(this, display, trait_display, GetVersion() <= 561 ? true : false);
 			//DumpPacket(app);
 			QueuePacket(app);
 		}
@@ -3307,7 +3309,7 @@ void Client::HandleExamineInfoRequest(EQApplicationPacket* app) {
 		Item* item = master_item_list.GetItem(id);
 		if (item) {
 			//only display popup for non merchant links
-			EQ2Packet* app = item->serialize(GetVersion(), (request->getType_int8_ByName("show_popup") != 0), GetPlayer(), true, 0, 0, GetVersion() > 546 ? true : false);
+			EQ2Packet* app = item->serialize(GetVersion(), (request->getType_int8_ByName("show_popup") != 0), GetPlayer(), true, 0, 0, GetVersion() > 561 ? true : false);
 			
 			QueuePacket(app);
 		}
@@ -3369,7 +3371,7 @@ void Client::HandleExamineInfoRequest(EQApplicationPacket* app) {
 		if(GetVersion() < 546) {
 			id = request->getType_int32_ByName("id");
 		}
-		else if(GetVersion() == 546) {
+		else if(GetVersion() <= 561) {
 			id = request->getType_int32_ByName("unique_id");
 		}
 		else {
@@ -3425,7 +3427,7 @@ void Client::HandleExamineInfoRequest(EQApplicationPacket* app) {
 			SetSentSpell(spell->GetSpellID(), spell->GetSpellTier());
 		//	EQ2Packet* app = spell->SerializeAASpell(this,tier, data, false, GetItemPacketType(GetVersion()), 0x04);
 		LogWrite(WORLD__INFO, 0, "WORLD", "Examine Info Request-> Spell ID: %u", spell->GetSpellID());
-		if(GetVersion() > 546) {
+		if(GetVersion() > 561) {
 			EQ2Packet* app = master_spell_list.GetAASpellPacket(id, tier, this, false, 0x4F);//0x45 change version to match client
 			/////////////////////////////////////////GetAASpellPacket(int32 id, int8 tier, Client* client, bool display, int8 packet_type) {
 			//DumpPacket(app);
@@ -4080,7 +4082,7 @@ int8 Client::GetMessageChannelColor(int8 channel_type) {
 			}
 		}
 	}
-	else if (GetVersion() <= 546) {
+	else if (GetVersion() <= 561) {
 		if (channel_type < 20)
 			return channel_type;
 		switch (channel_type) {
@@ -5174,7 +5176,7 @@ void Client::ChangeLevel(int16 old_level, int16 new_level) {
 	QueuePacket(GetPlayer()->GetPlayerInfo()->serialize(GetVersion()));
 
 	GetPlayer()->need_trait_update = true;
-	if (version > 547) {
+	if (version > 561) {
 		QueuePacket(master_trait_list.GetTraitListPacket(this));
 		master_aa_list.DisplayAA(this, 0, 0);
 	}
@@ -5390,7 +5392,7 @@ void Client::ChangeTSLevel(int16 old_level, int16 new_level) {
 }
 
 void Client::CloseLoot(int32 spawn_id) {
-	if (GetVersion() > 546) {
+	if (GetVersion() > 561) {
 		PacketStruct* packet = configReader.getStruct("WS_CloseWindow", GetVersion());
 		if (packet) {
 			packet->setDataByName("window_id", 4);
@@ -8345,7 +8347,7 @@ void Client::SendBuyMerchantList(bool sell) {
 						packet->setArrayDataByName("station_cash", ItemInfo.price_stationcash, i);
 					}
 				}
-				if (GetVersion() <= 546) {
+				if (GetVersion() <= 561) {
 					//buy is 0 so dont need to set it
 					if (sell)
 						packet->setDataByName("type", 1);
@@ -8368,7 +8370,7 @@ void Client::SendBuyMerchantList(bool sell) {
 			PacketStruct* packet = configReader.getStruct("WS_UpdateMerchant", GetVersion());
 			if (packet) {
 				packet->setDataByName("spawn_id", player->GetIDWithPlayerSpawn(spawn));
-				if (GetVersion() <= 546) {
+				if (GetVersion() <= 561) {
 					//buy is 0 so dont need to set it
 					if (sell)
 						packet->setDataByName("type", 1);
@@ -8492,7 +8494,7 @@ void Client::SendSellMerchantList(bool sell) {
 					if (GetVersion() <= 1096)
 						packet->setArrayDataByName("description", item->description.c_str(), i);
 				}
-				if (GetVersion() <= 546) {
+				if (GetVersion() <= 561) {
 					packet->setDataByName("type", 1);
 				}
 				else {
@@ -8516,7 +8518,7 @@ void Client::SendSellMerchantList(bool sell) {
 }
 
 void Client::SendBuyBackList(bool sell) {
-	if (GetVersion() <= 546) //this wasn't added until LU37 on July 31st 2007, well after the DoF client
+	if (GetVersion() <= 561) //this wasn't added until LU37 on July 31st 2007, well after the DoF client
 		return;
 	Spawn* spawn = GetMerchantTransaction();
 	if (spawn && spawn->GetMerchantID() > 0 && spawn->IsClientInMerchantLevelRange(this)) {
@@ -8637,7 +8639,7 @@ void Client::SendRepairList() {
 				if (GetVersion() <= 1096)
 					packet->setArrayDataByName("description", item->description.c_str(), i);
 			}
-			if (GetVersion() <= 546) {
+			if (GetVersion() <= 561) {
 				packet->setDataByName("type", 112);
 			}
 			else {
@@ -8648,7 +8650,7 @@ void Client::SendRepairList() {
 			//DumpPacket(outapp);
 			QueuePacket(outapp);
 			
-			/*if (GetVersion() <= 546) {
+			/*if (GetVersion() <= 561) {
 				packet->setDataByName("type", 16);
 				EQ2Packet* outapp2 = packet->serialize();
 				QueuePacket(outapp2);
@@ -8717,7 +8719,7 @@ void Client::ShowLottoWindow() {
 			//	packet->setArrayDataByName("quantity", item->details.count);
 			packet->setArrayDataByName("stack_size2", item->details.count);
 			packet->setArrayDataByName("description", item->description.c_str());
-			if (GetVersion() <= 546) {
+			if (GetVersion() <= 561) {
 				packet->setDataByName("type", 128);
 			}
 			else {
@@ -8825,7 +8827,7 @@ void Client::PlayLotto(int32 price, int32 ticket_item_id) {
 }
 
 void Client::SendGuildCreateWindow() {
-	if (GetVersion() <= 546) {
+	if (GetVersion() <= 561) {
 		SimpleMessage(0, "Not implemented on this client...yet?");
 	}
 	else {
@@ -9785,7 +9787,7 @@ void Client::SetReadyForUpdates() {
 
 	ready_for_updates = true;
 	
-	if(GetVersion() <= 547) {
+	if(GetVersion() <= 561) {
 		SendRecipeList();
 	}
 }
@@ -10098,7 +10100,7 @@ void Client::InspectPlayer(Player* player_to_inspect) {
 			for (size_t i = 0; i < biography.length(); i++)
 				packet->setArrayDataByName("biography_char", biography[i], i);
 			
-			if(GetVersion() <= 546) {
+			if(GetVersion() <= 561) {
 				for(int32 s=0;s<22;s++) {
 					int32 slot = s;
 					
@@ -10512,7 +10514,7 @@ void Client::DisplayCollectionComplete(Collection* collection) {
 	reward_items = collection->GetRewardItems();
 	selectable_reward_items = collection->GetSelectableRewardItems();
 
-	if (GetVersion() <= 546) {
+	if (GetVersion() <= 561) {
 			int32 source_id = collection->GetID();
 			PacketStruct* packet2 = configReader.getStruct("WS_QuestRewardPackMsg", GetVersion());
 			if (packet2) {
@@ -10720,7 +10722,7 @@ void Client::SendRecipeList() {
 	int16 i = 0;
 	Recipe* recipe;
 	
-	if(version <= 546) {
+	if(version <= 561) {
 		PacketStruct* packet = 0;
 		if (!(packet = configReader.getStruct("WS_UpdateRecipeBook", GetVersion()))) {
 			return;
@@ -11748,7 +11750,7 @@ void Client::SendShowBook(Spawn* sender, string title, int8 language, int8 num_p
 	if(language > 0 && !GetPlayer()->HasLanguage(language))
 		packet->setDataByName("language", language);
 	
-	if (GetVersion() > 546)
+	if (GetVersion() > 561)
 		packet->setDataByName("unknown5", 1, 4);
 
 	packet->setArrayLengthByName("num_pages", num_pages);
@@ -11769,6 +11771,7 @@ void Client::SendShowBook(Spawn* sender, string title, int8 language, int8 num_p
 			}
 			// DoF trial
 			case 546:
+			case 561:
 			{
 				if (p == 0)
 					packet->setDataByName("cover_page", page.c_str());
@@ -11817,7 +11820,7 @@ void Client::SendShowBook(Spawn* sender, string title, int8 language, vector<Ite
 	if(language > 0 && !GetPlayer()->HasLanguage(language))
 		packet->setDataByName("language", language);
 
-	if (GetVersion() > 546)
+	if (GetVersion() > 561)
 		packet->setDataByName("unknown5", 1, 4);
 
 	packet->setArrayLengthByName("num_pages", pages.size());
@@ -11837,6 +11840,7 @@ void Client::SendShowBook(Spawn* sender, string title, int8 language, vector<Ite
 		}
 		// DoF trial
 		case 546:
+		case 561:
 		{
 			if (p == 0)
 				packet->setDataByName("cover_page", pageText.c_str());
@@ -12845,7 +12849,7 @@ void Client::SendHearCast(Spawn* caster, Spawn* target, int32 spell_visual, int1
 
 int32 Client::GetSpellVisualOverride(int32 spell_visual) {
 	int32 visual = spell_visual;
-	if(GetVersion() <= 546) { // spell's spell_visual field is based on newer clients, DoF has to convert
+	if(GetVersion() <= 561) { // spell's spell_visual field is based on newer clients, DoF has to convert
 		Emote* spellVisualEmote = visual_states.FindSpellVisualByID(visual, 60085);
 		if(spellVisualEmote != nullptr && spellVisualEmote->GetMessageString().size() > 0) {
 			spellVisualEmote = visual_states.FindSpellVisual(spellVisualEmote->GetMessageString(), GetVersion());

+ 9 - 9
EQ2/source/WorldServer/zoneserver.cpp

@@ -3941,7 +3941,7 @@ void ZoneServer::PlayFlavor(Client* client, Spawn* spawn, const char* mp3, const
 		if(text)
 			packet->setMediumStringByName("text", text);
 		if(emote) {
-			if(client->GetVersion() > 546) {
+			if(client->GetVersion() > 561) {
 				packet->setMediumStringByName("emote", emote);
 			}
 			else {
@@ -5215,7 +5215,7 @@ void ZoneServer::SendDamagePacket(Spawn* attacker, Spawn* victim, int8 type1, in
 			packet = configReader.getStruct("WS_HearSiphonSpellDamage", client->GetVersion());
 			break;
 		case DAMAGE_PACKET_TYPE_MULTIPLE_DAMAGE:
-			if (client->GetVersion() > 546)
+			if (client->GetVersion() > 561)
 				packet = configReader.getStruct("WS_HearMultipleDamage", client->GetVersion());
 			else
 				packet = configReader.getStruct("WS_HearSimpleDamage", client->GetVersion());
@@ -5228,7 +5228,7 @@ void ZoneServer::SendDamagePacket(Spawn* attacker, Spawn* victim, int8 type1, in
 		case DAMAGE_PACKET_TYPE_SPELL_DAMAGE3:
 		case DAMAGE_PACKET_TYPE_SPELL_CRIT_DMG:
 		case DAMAGE_PACKET_TYPE_SPELL_DAMAGE:
-			if (client->GetVersion() > 546)
+			if (client->GetVersion() > 561)
 				packet = configReader.getStruct("WS_HearSpellDamage", client->GetVersion());
 			else
 				packet = configReader.getStruct("WS_HearSimpleDamage", client->GetVersion());
@@ -5249,7 +5249,7 @@ void ZoneServer::SendDamagePacket(Spawn* attacker, Spawn* victim, int8 type1, in
 		}
 		
 		if (packet) {
-			if (client->GetVersion() > 546) {
+			if (client->GetVersion() > 561) {
 				packet->setSubstructDataByName("header", "packet_type", type1);
 				packet->setSubstructDataByName("header", "result_type", type2);
 				packet->setDataByName("damage_type", damage_type);
@@ -5356,7 +5356,7 @@ void ZoneServer::SendThreatPacket(Spawn* caster, Spawn* target, int32 threat_amt
 		if(target && target->GetDistance(client->GetPlayer()) > 50)
 			continue;
 		
-		if(client->GetVersion() <= 547) {
+		if(client->GetVersion() <= 561) {
 			int8 channel = 46;
 			
 			if(client->GetPlayer() == caster || client->GetPlayer() == target)
@@ -5427,7 +5427,7 @@ void ZoneServer::SendSpellFailedPacket(Client* client, int16 error){
 		/*		Temp solution, need to modify the error code before this function and while we still have access to the spell/combat art		*/
 		error = master_spell_list.GetSpellErrorValue(client->GetVersion(), error);
 
-		if(client->GetVersion() <= 546 && error) {
+		if(client->GetVersion() <= 561 && error) {
 			error += 1;
 		}
 		packet->setDataByName("error_code", error);
@@ -7037,7 +7037,7 @@ void ZoneServer::ProcessAggroChecks(Spawn* spawn) {
 
 void ZoneServer::SendUpdateTitles(Client* client, Title* suffix, Title* prefix) {
 	assert(client);
-	if (client->GetVersion() > 546)
+	if (client->GetVersion() > 561)
 		SendUpdateTitles(client->GetPlayer(), suffix, prefix);
 }
 
@@ -7053,7 +7053,7 @@ void ZoneServer::SendUpdateTitles(Spawn *spawn, Title *suffix, Title *prefix) {
 	for (itr = clients.begin(); itr != clients.end(); itr++) {
 		current_client = *itr;
 
-		if (current_client->GetVersion() <= 546)
+		if (current_client->GetVersion() <= 561)
 			continue;
 
 		if (!(packet = configReader.getStruct("WS_UpdateTitle", current_client->GetVersion())))
@@ -7525,7 +7525,7 @@ void ZoneServer::ResurrectSpawn(Spawn* spawn, Client* client) {
 			}
 			safe_delete(packet);
 			
-			if(client->GetVersion() <= 546) {
+			if(client->GetVersion() <= 561) {
 				ClientPacketFunctions::SendServerControlFlagsClassic(client, 8, 0);
 				ClientPacketFunctions::SendServerControlFlagsClassic(client, 16, 0);
 			}

+ 6 - 6
EQ2/source/common/PacketStruct.cpp

@@ -1795,7 +1795,7 @@ void PacketStruct::serializePacket(bool clear) {
 		int32 size = client_data.length() + 3; //gotta add the opcode and oversized
 		int8 oversized = 0xFF;
 		int16 OpcodeVersion = GetOpcodeVersion(client_version);
-		if (opcode_val == EQOpcodeManager[OpcodeVersion]->EmuToEQ(OP_EqExamineInfoCmd) && client_version > 546)
+		if (opcode_val == EQOpcodeManager[OpcodeVersion]->EmuToEQ(OP_EqExamineInfoCmd) && client_version > 561)
 			size += (size - 9);
 		if (client_version <= 283) {
 			if (size >= 255) {
@@ -2561,7 +2561,7 @@ void PacketStruct::setItem(DataStruct* ds, Item* item, Player* player, int32 ind
 	
 	if(!item) {
 		if(make_empty_item_packet) {
-			if(client_version <= 546) {
+			if(client_version <= 561) {
 				// for player inspection this will offset the parts of the packet that have no items
 				uchar bogusItemBuffer[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x8C,0x5A,0xF1,0xD2,0x8C,0x5A,0xF1,0xD2,0x01,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00};
 				bogusItemBuffer[World::newValue] = 0x00;
@@ -2583,7 +2583,7 @@ void PacketStruct::setItem(DataStruct* ds, Item* item, Player* player, int32 ind
 	if (packet) {
 		int16 item_version = GetItemPacketType(packet->GetVersion());
 		// newer clients can handle the item structure without the loot_item flag set to true, older clients like DoF need a smaller subpacket of item
-		item->serialize(packet, true, player, item_version, 0, (packet->GetVersion() <= 546) ? loot_item : false);
+		item->serialize(packet, true, player, item_version, 0, (packet->GetVersion() <= 561) ? loot_item : false);
 
 		string* generic_string_data = packet->serializeString();
 		int32 size = generic_string_data->length(); // had to set to 81
@@ -2599,7 +2599,7 @@ void PacketStruct::setItem(DataStruct* ds, Item* item, Player* player, int32 ind
 			return;
 		}
 		size -= (9 + offset);
-		if (client_version > 546 && item->IsBag() == false && item->IsBauble() == false && item->IsFood() == false && (offset == 0 || offset == -1 || offset == 2))
+		if (client_version > 561 && item->IsBag() == false && item->IsBauble() == false && item->IsFood() == false && (offset == 0 || offset == -1 || offset == 2))
 			size = (size * 2) - 5;
 		uchar* out_data = new uchar[size + 1];
 		memset(out_data, 0, size+1);
@@ -2608,14 +2608,14 @@ void PacketStruct::setItem(DataStruct* ds, Item* item, Player* player, int32 ind
 		//DumpPacket((uchar*)generic_string_data->c_str() + (9 + offset), size);
 		//without these it will prompt for your character name
 		if (offset == 0 || offset == -1 || offset == 2) {
-			if (client_version <= 546 && item->details.count > 0)
+			if (client_version <= 561 && item->details.count > 0)
 				out_data[0] = item->details.count;
 			else
 				out_data[0] = 1;
 		}
 		//
 		out_ptr += generic_string_data->length() - (10 + offset);
-		if (client_version > 546 && item->IsBag() == false && item->IsBauble() == false && item->IsFood() == false && (offset == 0 || offset == -1 || offset == 2)) {
+		if (client_version > 561 && item->IsBag() == false && item->IsBauble() == false && item->IsFood() == false && (offset == 0 || offset == -1 || offset == 2)) {
 			out_data[4] = 0x80;
 			memcpy(out_ptr, (uchar*)generic_string_data->c_str() + (13 + offset), generic_string_data->length() - (13 + offset));
 		}

+ 43 - 1
server/CommonStructs.xml

@@ -43,7 +43,6 @@ to zero and treated like placeholders." />
 <Data ElementName="body_size" Type="float" Size="1" />
 <Data ElementName="body_age" Type="float" Size="1" />
 </Struct>
-
 <Struct Name="CreateCharacter" ClientVersion="546" OpcodeName="OP_CreateCharacterRequestMsg">
 <Data ElementName="unknown0" Type="int8" />
 <Data ElementName="unknown1" Type="int32" />
@@ -88,6 +87,49 @@ to zero and treated like placeholders." />
 <Data ElementName="body_size" Type="float" Size="1" />
 <Data ElementName="body_age" Type="float" Size="1" />
 </Struct>
+<Struct Name="CreateCharacter" ClientVersion="561" OpcodeName="OP_CreateCharacterRequestMsg">
+<Data ElementName="unknown0" Type="int8" />
+<Data ElementName="unknown1" Type="int32" />
+<Data ElementName="account_id" Type="int32" />
+<Data ElementName="server_id" Type="int32" />
+<Data ElementName="name" Type="EQ2_16Bit_String" />
+<Data ElementName="race" Type="int8" />
+<Data ElementName="gender" Type="int8" />
+<Data ElementName="deity" Type="int8" />
+<Data ElementName="class" Type="int8" />
+<Data ElementName="level" Type="int8" />
+<Data ElementName="starting_zone" Type="int8" />
+<Data ElementName="version" Type="int8" />
+<Data ElementName="race_file" Type="EQ2_16Bit_String" />
+<Data ElementName="skin_color" Type="float" Size="3" />
+<Data ElementName="eye_color" Type="float" Size="3" />
+<Data ElementName="hair_color1" Type="float" Size="3" />
+<Data ElementName="hair_color2" Type="float" Size="3" />
+<Data ElementName="hair_highlight" Type="float" Size="3" />
+<Data ElementName="unknown2" Type="int8" Size="26" />
+<Data ElementName="hair_file" Type="EQ2_16Bit_String" />
+<Data ElementName="hair_type_color" Type="float" Size="3" />
+<Data ElementName="hair_type_highlight_color" Type="float" Size="3" />
+<Data ElementName="face_file" Type="EQ2_16Bit_String" />
+<Data ElementName="hair_face_color" Type="float" Size="3" />
+<Data ElementName="hair_face_highlight_color" Type="float" Size="3" />
+<Data ElementName="chest_file" Type="EQ2_16Bit_String" />
+<Data ElementName="shirt_color" Type="float" Size="3" />
+<Data ElementName="unknown_chest_color" Type="float" Size="3" />
+<Data ElementName="legs_file" Type="EQ2_16Bit_String" />
+<Data ElementName="pants_color" Type="float" Size="3" />
+<Data ElementName="unknown_legs_color" Type="float" Size="3" />
+<Data ElementName="unknown9" Type="float" Size="3" />
+<Data ElementName="eyes2" Type="float" Size="3" />
+<Data ElementName="ears" Type="float" Size="3" />
+<Data ElementName="eye_brows" Type="float" Size="3" />
+<Data ElementName="cheeks" Type="float" Size="3" />
+<Data ElementName="lips" Type="float" Size="3" />
+<Data ElementName="chin" Type="float" Size="3" />
+<Data ElementName="nose" Type="float" Size="3" />
+<Data ElementName="body_size" Type="float" Size="1" />
+<Data ElementName="body_age" Type="float" Size="1" />
+</Struct>
 <Struct Name="CreateCharacter" ClientVersion="562" OpcodeName="OP_CreateCharacterRequestMsg">
 <Data ElementName="unknown0" Type="int8" />
 <Data ElementName="unknown1" Type="int32" />

+ 16 - 16
server/ItemStructs.xml

@@ -67,7 +67,7 @@
     </Data>
     <Data ElementName="footer_type" Type="int32" Size="1" />
   </Struct>
-  <Struct Name="Substruct_BaseItemDescription" ClientVersion="547" >
+  <Struct Name="Substruct_BaseItemDescription" ClientVersion="562" >
     <Data ElementName="creator_flag" Type="int8" Size="1" />
     <Data ElementName="creator" Type="EQ2_8Bit_String" Size="1" />
     <Data ElementName="adornment" Type="EQ2_16Bit_String" Size="1" />
@@ -1052,7 +1052,7 @@
 <Data ElementName="name" Type="char" Size="64" />
 <Data ElementName="unknown6" Type="int8" Size="17" />
 </Struct>
-<Struct Name="Substruct_Item" ClientVersion="547" >
+<Struct Name="Substruct_Item" ClientVersion="562" >
 <Data ElementName="unique_id" Type="int32" Size="1" />
 <Data ElementName="bag_id" Type="int32" Size="1" />
 <Data ElementName="inv_slot_id" Type="int32" Size="1" />
@@ -1325,7 +1325,7 @@
 <Data ElementName="name" Type="EQ2_8Bit_String" Size="1" />
 <Data ElementName="description" Type="EQ2_16Bit_String" Size="1" />
 </Struct>
-<Struct Name="Substruct_ItemFooter" ClientVersion="547" >
+<Struct Name="Substruct_ItemFooter" ClientVersion="562" >
 <Data ElementName="num_effects" Type="int8" IfVariableNotSet="header_info_header_unknown_0_0,header_unknown_0" />
 <Data ElementName="effect_array" Type="Array" ArraySizeVariable="num_effects">
 	<Data ElementName="subbulletflag" Type="int8" Size = "1" />
@@ -3809,7 +3809,7 @@
 <Data ElementName="info" Substruct="Substruct_BaseItemDescription" Size="1" />
 <Data ElementName="item_type" Type="int8" Size="1" />
 </Struct>
-<Struct Name="Substruct_ItemDescription" ClientVersion="547" >
+<Struct Name="Substruct_ItemDescription" ClientVersion="562" >
 <Data ElementName="info_header" Substruct="WS_ExamineInfoHeader" Size="1" />
 <Data ElementName="info" Substruct="Substruct_BaseItemDescription" Size="1" />
 <Data ElementName="item_type" Type="int8" Size="1" />
@@ -4093,7 +4093,7 @@
 </Data>
 <Data ElementName="equip_flag" Type="int8" Size="1" />
 </Struct>
-<Struct Name="WS_UpdateInventory" ClientVersion="547" OpcodeName="OP_UpdateInventoryMsg" >
+<Struct Name="WS_UpdateInventory" ClientVersion="562" OpcodeName="OP_UpdateInventoryMsg" >
 <Data ElementName="item_count" Type="int16" />
 <Data ElementName="packed_size" Type="int32" />
 <Data ElementName="item_array" Type="Array" ArraySizeVariable="item_count">
@@ -4197,7 +4197,7 @@
 <Data ElementName="header" Substruct="Substruct_ItemDescription" Size="1" />
 <Data ElementName="footer" Substruct="Substruct_ItemFooter" Size="1" />
 </Struct>
-<Struct Name="WS_ItemGeneric" ClientVersion="547" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqExamineInfoCmd">
+<Struct Name="WS_ItemGeneric" ClientVersion="562" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqExamineInfoCmd">
 <Data ElementName="header" Substruct="Substruct_ItemDescription" Size="1" />
 <Data ElementName="footer" Substruct="Substruct_ItemFooter" Size="1" />
 </Struct>
@@ -4215,7 +4215,7 @@
 <Data ElementName="rating" Type="float" Size="1" />
 <Data ElementName="footer" Substruct="Substruct_ItemFooter" Size="1" />
 </Struct>
-<Struct Name="WS_ItemRange" ClientVersion="547" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqExamineInfoCmd">
+<Struct Name="WS_ItemRange" ClientVersion="562" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqExamineInfoCmd">
 <Data ElementName="header" Substruct="Substruct_ItemDescription" Size="1" />
 <Data ElementName="damage_low1" Type="int16" Size="1" OversizedValue="127" OversizedByte="127" />
 <Data ElementName="damage_high1" Type="int16" Size="1" OversizedValue="127" OversizedByte="127" />
@@ -4272,7 +4272,7 @@
 <Data ElementName="mitigation_high" Type="int16" Size="1" OversizedValue="127" OversizedByte="127" />
 <Data ElementName="footer" Substruct="Substruct_ItemFooter" Size="1" />
 </Struct>
-<Struct Name="WS_ItemWeapon" ClientVersion="547" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqExamineInfoCmd">
+<Struct Name="WS_ItemWeapon" ClientVersion="562" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqExamineInfoCmd">
 <Data ElementName="header" Substruct="Substruct_ItemDescription" Size="1" />
 <Data ElementName="wield_type" Type="int8" Size="1" />
 <Data ElementName="damage_low1" Type="int16" OversizedValue="127" OversizedByte="127" Size="1" />
@@ -4286,13 +4286,13 @@
 <Data ElementName="rating" Type="float" Size="1" />
 <Data ElementName="footer" Substruct="Substruct_ItemFooter" Size="1" />
 </Struct>
-<Struct Name="WS_ItemArmor" ClientVersion="547" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqExamineInfoCmd">
+<Struct Name="WS_ItemArmor" ClientVersion="562" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqExamineInfoCmd">
 <Data ElementName="header" Substruct="Substruct_ItemDescription" Size="1" />
 <Data ElementName="mitigation_low" Type="int16" Size="1" OversizedValue="127" OversizedByte="127" />
 <Data ElementName="mitigation_high" Type="int16" Size="1" OversizedValue="127" OversizedByte="127" />
 <Data ElementName="footer" Substruct="Substruct_ItemFooter" Size="1" />
 </Struct>
-<Struct Name="WS_ItemShield" ClientVersion="547" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqExamineInfoCmd">
+<Struct Name="WS_ItemShield" ClientVersion="562" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqExamineInfoCmd">
 <Data ElementName="header" Substruct="Substruct_ItemDescription" Size="1" />
 <Data ElementName="mitigation_low" Type="int16" Size="1" OversizedValue="127" OversizedByte="127" />
 <Data ElementName="mitigation_high" Type="int16" Size="1" OversizedValue="127" OversizedByte="127" />
@@ -4340,7 +4340,7 @@
 
 <Data ElementName="damage_type" Type="int8" Size="1" />
 </Struct>
-<Struct Name="WS_ItemRangeDetails"  ClientVersion="547">
+<Struct Name="WS_ItemRangeDetails"  ClientVersion="562">
 <Data ElementName="damage_low1" Type="int16" Size="1" OversizedValue="127" OversizedByte="127" />
 <Data ElementName="damage_high1" Type="int16" Size="1" OversizedValue="127" OversizedByte="127" />
 <Data ElementName="damage_low2" Type="int16" Size="1" OversizedValue="127" OversizedByte="127" />
@@ -4435,7 +4435,7 @@
 </Data>
 <Data ElementName="footer" Substruct="Substruct_ItemFooter" Size="1" />
 </Struct>
-<Struct Name="WS_ItemBag" ClientVersion="547" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqExamineInfoCmd">
+<Struct Name="WS_ItemBag" ClientVersion="562" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqExamineInfoCmd">
 <Data ElementName="header" Substruct="Substruct_ItemDescription" Size="1" />
 <Data ElementName="num_slots" Type="int8" Size="1" />
 <Data ElementName="num_empty" Type="int8" Size="1" />
@@ -4459,7 +4459,7 @@
 <Data ElementName="duration" Type="float" Size="1" />
 <Data ElementName="footer" Substruct="Substruct_ItemFooter" Size="1" />
 </Struct>
-<Struct Name="WS_ItemFood" ClientVersion="547" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqExamineInfoCmd">
+<Struct Name="WS_ItemFood" ClientVersion="562" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqExamineInfoCmd">
 <Data ElementName="header" Substruct="Substruct_ItemDescription" Size="1" />
 <Data ElementName="food_type" Type="int8" Size="1" />
 <Data ElementName="level" Type="int8" Size="1" />
@@ -4479,7 +4479,7 @@
 <Data ElementName="display_until_cancelled" Type="int8" Size="1" />
 <Data ElementName="footer" Substruct="Substruct_ItemFooter" Size="1" />
 </Struct>
-<Struct Name="WS_ItemBauble" ClientVersion="547" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqExamineInfoCmd">
+<Struct Name="WS_ItemBauble" ClientVersion="562" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqExamineInfoCmd">
 <Data ElementName="header" Substruct="Substruct_ItemDescription" Size="1" />
 <Data ElementName="cast" Type="int16" Size="1" OversizedValue="127" OversizedByte="127" />
 <Data ElementName="recovery" Type="int16" Size="1" OversizedValue="127" OversizedByte="127" />
@@ -4498,7 +4498,7 @@
 <Data ElementName="scribed" Type="int8" Size="1" />
 <Data ElementName="footer" Substruct="Substruct_SkillItemFooter" Size="1" />
 </Struct>
-<Struct Name="WS_ItemSkill" ClientVersion="547" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqExamineInfoCmd">
+<Struct Name="WS_ItemSkill" ClientVersion="562" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqExamineInfoCmd">
 <Data ElementName="header" Substruct="Substruct_ItemDescription" Size="1" />
 <Data ElementName="spell_info" Substruct="WS_SpellInfo" Size="1" />
 <Data ElementName="scribed" Type="int8" Size="1" />
@@ -4544,7 +4544,7 @@
 <Data ElementName="scribed" Type="int8" Size="1" />
 <Data ElementName="footer" Substruct="Substruct_ItemFooter" Size="1" />
 </Struct>
-<Struct Name="WS_ItemRecipeBook" ClientVersion="547" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqExamineInfoCmd">
+<Struct Name="WS_ItemRecipeBook" ClientVersion="562" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqExamineInfoCmd">
 <Data ElementName="header" Substruct="Substruct_ItemDescription" Size="1" />
 <Data ElementName="num_recipes" Type="int16" Size="1" OversizedValue="127" />
 <Data ElementName="recipe_array" Type="Array" ArraySizeVariable="num_recipes">

+ 136 - 128
server/SpawnStructs.xml

@@ -37,12 +37,11 @@
 </Data>
 <Data ElementName="time_stamp" Type="int32" Size="1" />
 </Struct>
-<Struct Name="WS_SpawnStruct_Header" ClientVersion="547">
+<Struct Name="WS_SpawnStruct_Header" ClientVersion="561">
 <Data ElementName="index" Type="int16" Size="1" OversizedValue="255" />
 <Data ElementName="spawn_id" Type="int32" Size="1" />
 <Data ElementName="spawn_anim" Type="int16" Size="1" />
 <Data ElementName="unknown2" Type="int32" Size="1" />
-<Data ElementName="crc" Type="int32" Size="1" />
 <Data ElementName="command_list" Type="int8" Size="1" />
 <Data ElementName="command_list_array" Type="Array" ArraySizeVariable="command_list">
 	<Data ElementName="command_list_name" Type="EQ2_16Bit_String" />
@@ -145,37 +144,38 @@
 <Data ElementName="actor_stop_range" Type="sint16" Size="1" /> <!-- 0x54 -->
 <Data ElementName="pos_roll" Type="sint16" Size="1" /> <!-- 0x56 -->
 </Struct>
-<Struct Name="Substruct_SpawnPositionStruct" ClientVersion="547">
-<Data ElementName="pos_grid_id" Type="int32" Size="1" />
-<Data ElementName="pos_x" Type="float" Size="1" />
-<Data ElementName="pos_y" Type="float" Size="1" />
-<Data ElementName="pos_z" Type="float" Size="1" />
-<Data ElementName="pos_x_velocity" Type="sint16" Size="1" />
-<Data ElementName="pos_y_velocity" Type="sint16" Size="1" />
-<Data ElementName="pos_z_velocity" Type="sint16" Size="1" />
-<Data ElementName="pos_heading1" Type="sint16" Size="1" />
-<Data ElementName="pos_heading2" Type="sint16" Size="1" />
-<Data ElementName="pos_speed" Type="int16" Size="1" />
-<Data ElementName="pos_state" Type="int16" Size="1" />
-<Data ElementName="pos_unknown2" Type="int8" Size="4" />
-<Data ElementName="pos_unknown3a" Type="int8" Size="2" />
-<Data ElementName="pos_movement_mode" Type="int8" Size="1" />
-<Data ElementName="pos_unknown3b" Type="int8" Size="1" />
-<Data ElementName="pos_next_x" Type="float" Size="1" />
-<Data ElementName="pos_next_y" Type="float" Size="1" />
-<Data ElementName="pos_next_z" Type="float" Size="1" />
-<Data ElementName="pos_x3" Type="float" Size="1" />
-<Data ElementName="pos_y3" Type="float" Size="1" />
-<Data ElementName="pos_z3" Type="float" Size="1" />
-<Data ElementName="pos_unknown4" Type="int16" Size="2" />
-<Data ElementName="pos_move_type" Type="int16" Size="1" />
-<Data ElementName="pos_unknown6" Type="int16" Size="3" />
-<Data ElementName="pos_side_speed" Type="int16" Size="1" />
-<Data ElementName="pos_unknown6a" Type="int16" Size="4" />
-<Data ElementName="pos_collision_radius" Type="int16" Size="1" />
-<Data ElementName="pos_size" Type="int16" Size="1" />
-<Data ElementName="pos_size_multiplier" Type="int16" Size="1" />
-<Data ElementName="pos_unknown10" Type="int16" Size="6" />
+<Struct Name="Substruct_SpawnPositionStruct" ClientVersion="561" Comment="88 bytes">
+<Data ElementName="pos_grid_id" Type="int32" Size="1" />      
+<Data ElementName="pos_loc_offset" Type="sint16" Size="3" />  <!-- 0x4 -->
+<Data ElementName="pos_x_velocity" Type="sint16" Size="1" /> <!-- 0x0a -->
+<Data ElementName="pos_y_velocity" Type="sint16" Size="1" /> <!-- 0x0c -->
+<Data ElementName="pos_z_velocity" Type="sint16" Size="1" />   <!-- 0x0e -->
+<Data ElementName="pos_heading1" Type="sint16" Size="1" />    <!-- 0x10 -->
+<Data ElementName="pos_heading2" Type="sint16" Size="1" />    <!-- 0x12 -->
+<Data ElementName="pos_speed" Type="sint16" Size="1" />        <!-- 0x14 -->
+<Data ElementName="pos_state" Type="int32" Size="1" />        <!-- 0x16 -->
+<Data ElementName="pos_movement_mode" Type="int8" Size="1" /> <!-- 0x1a -->
+<Data ElementName="pos_unknown1" Type="int8" Size="1" /> <!-- 0x1b -->
+<Data ElementName="pos_dest_loc_offset" Type="sint16" Size="3" /> <!-- 0x1c -->
+<Data ElementName="pos_dest_loc_offset2" Type="sint16" Size="3" /> <!-- 0x22 -->
+<Data ElementName="pos_heading_speed" Type="sint16" Size="1" /> <!-- 0x28 -->
+<Data ElementName="pos_move_type" Type="sint16" Size="1" /> <!-- 0x2a -->
+<Data ElementName="pos_swim_speed_modifier" Type="sint16" Size="1" /> <!-- 0x2c -->
+<Data ElementName="pos_side_speed" Type="sint16" Size="1" /> <!-- 0x2e -->
+<Data ElementName="pos_vert_speed" Type="sint16" Size="1" /> <!-- 0x30 -->
+<Data ElementName="pos_requested_pitch" Type="sint16" Size="1" /> <!-- 0x32 -->
+<Data ElementName="pos_requested_pitch_speed" Type="sint16" Size="1" /> <!-- 0x34 -->
+<Data ElementName="pos_unknown2" Type="int8" Size="6" /> <!-- 0x36 -->
+<Data ElementName="pos_x" Type="float" Size="1" /> <!-- 0x3c -->
+<Data ElementName="pos_y" Type="float" Size="1" /> <!-- 0x40 -->
+<Data ElementName="pos_z" Type="float" Size="1" /> <!-- 0x44 -->
+<Data ElementName="pos_pitch2" Type="sint16" Size="1" /> <!-- 0x48 -->
+<Data ElementName="pos_collision_radius" Type="sint16" Size="1" /> <!-- 0x4a -->
+<Data ElementName="pos_size" Type="sint16" Size="1" /> <!-- 0x4c -->
+<Data ElementName="pos_unknown3" Type="sint16" Size="1" /> <!-- 0x4e -->
+<Data ElementName="face_actor_id" Type="int32" Size="1" /> <!-- 0x50 -->
+<Data ElementName="actor_stop_range" Type="sint16" Size="1" /> <!-- 0x54 -->
+<Data ElementName="pos_roll" Type="sint16" Size="1" /> <!-- 0x56 -->
 </Struct>
 <Struct Name="Substruct_SpawnPositionStruct" ClientVersion="927" >
 <Data ElementName="pos_grid_id" Type="int32" Size="1" />
@@ -473,8 +473,8 @@
 <Data ElementName="anonymous" Type="int8" Size="1" /> <!-- 317 -->
 <Data ElementName="linkdead" Type="int8" Size="1" /> <!-- 318 -->
 <Data ElementName="camping" Type="int8" Size="1" /> <!-- 319 -->
-<Data ElementName="unknown12" Type="int8" Size="1" /> <!-- 320 -->
-<Data ElementName="unknown13" Type="int8" Size="1" /> <!-- 321 -->
+<Data ElementName="unknown12" Type="int8" Size="1" /> <!-- 320 --> <!-- looking for group? -->
+<Data ElementName="unknown13" Type="int8" Size="1" /> <!-- 321 --> <!-- looking for work? -->
 <Data ElementName="solid_object" Type="int8" Size="1" /> <!-- 322 -->
 <Data ElementName="unknown14" Type="int8" Size="1" /> <!-- 323 -->
 <Data ElementName="unknown15" Type="int8" Size="1" /> <!-- 324 -->
@@ -558,92 +558,102 @@
 <Data ElementName="race" Type="int8" Size="1" /> <!-- 1087 -->
 <Data ElementName="gender" Type="int8" Size="1" /> <!-- 1088 -->
 </Struct>
-<Struct Name="Substruct_SpawnInfoStruct" ClientVersion="547" >
-<Data ElementName="hp_remaining" Type="int8" Size="1" />
-<Data ElementName="unknown2a" Type="int8" Size="3" />
-<Data ElementName="power_percent" Type="int8" Size="1" />
-<Data ElementName="unknown2b" Type="int8" Size="1" />
-<Data ElementName="unknown3" Type="int8" Size="288" />
-<Data ElementName="class" Type="int8" Size="1" />
-<Data ElementName="unknown4" Type="int8" Size="1" />
-<Data ElementName="level" Type="int8" Size="1" />
-<Data ElementName="difficulty" Type="int8" Size="1" />
-<Data ElementName="unknown5" Type="int8" Size="1" />
-<Data ElementName="heroic_flag" Type="int8" Size="1" />
-<Data ElementName="spawn_type" Type="int8" Size="1" />
-<Data ElementName="icon" Type="int8" Size="1" />
-<Data ElementName="activity_status" Type="int32" Size="1" />
-<Data ElementName="unknown6" Type="int8" Size="6" />
-<Data ElementName="unknown7" Type="float" Size="1" />
-<Data ElementName="model_type" Type="int16" Size="1" />
-<Data ElementName="soga_model_type" Type="int16" Size="1" />
-<Data ElementName="skin_color" Type="EQ2_Color" Size="1" />
-<Data ElementName="eye_color" Type="EQ2_Color" Size="1" />
-<Data ElementName="soga_eye_color" Type="EQ2_Color" />
-<Data ElementName="soga_skin_color" Type="EQ2_Color" />
-<Data ElementName="equipment_types" Type="int16" Size="25" />
-<Data ElementName="hair_type_id" Type="int16" Size="1" />
-<Data ElementName="facial_hair_type_id" Type="int16" Size="1" />
-<Data ElementName="wing_type_id" Type="int16" Size="1" />
-<Data ElementName="chest_type_id" Type="int16" Size="1" />
-<Data ElementName="legs_type_id" Type="int16" Size="1" />
-<Data ElementName="soga_hair_type_id" Type="int16" Size="1" />
-<Data ElementName="soga_facial_hair_type_id" Type="int16" Size="1" />
-<Data ElementName="equipment_colors" Type="EQ2_Color" Size="25" />
-<Data ElementName="hair_type_color" Type="EQ2_Color" />
-<Data ElementName="hair_face_color" Type="EQ2_Color" />
-<Data ElementName="wing_color1" Type="EQ2_Color" />
-<Data ElementName="unknown10" Type="EQ2_Color" Size="2" />
-<Data ElementName="equipment_highlights" Type="EQ2_Color" Size="25" />
-<Data ElementName="hair_type_highlight_color" Type="EQ2_Color" />
-<Data ElementName="hair_face_highlight_color" Type="EQ2_Color" />
-<Data ElementName="wing_color2" Type="EQ2_Color" />
-<Data ElementName="unknown11" Type="EQ2_Color" Size="2" />
-<Data ElementName="soga_hair_type_color" Type="EQ2_Color" />
-<Data ElementName="soga_hair_type_highlight_color" Type="EQ2_Color" />
-<Data ElementName="soga_hair_face_color" Type="EQ2_Color" />
-<Data ElementName="soga_hair_face_highlight_color" Type="EQ2_Color" />
-<Data ElementName="unknown12" Type="EQ2_Color" Size="1" />
-<Data ElementName="eye_type" Type="sint8" Size="3" />
-<Data ElementName="ear_type" Type="sint8" Size="3" />
-<Data ElementName="eye_brow_type" Type="sint8" Size="3" />
-<Data ElementName="cheek_type" Type="sint8" Size="3" />
-<Data ElementName="lip_type" Type="sint8" Size="3" />
-<Data ElementName="chin_type" Type="sint8" Size="3" />
-<Data ElementName="nose_type" Type="sint8" Size="3" />
-<Data ElementName="body_size" Type="sint8" Size="1" />
-<Data ElementName="unknown13" Type="int32" Size="1" />
-<Data ElementName="soga_eye_type" Type="sint8" Size="3" />
-<Data ElementName="soga_ear_type" Type="sint8" Size="3" />
-<Data ElementName="soga_eye_brow_type" Type="sint8" Size="3" />
-<Data ElementName="soga_cheek_type" Type="sint8" Size="3" />
-<Data ElementName="soga_lip_type" Type="sint8" Size="3" />
-<Data ElementName="soga_chin_type" Type="sint8" Size="3" />
-<Data ElementName="soga_nose_type" Type="sint8" Size="3" />
-<Data ElementName="unknown14" Type="int16" Size="1" />
-<Data ElementName="unknown15" Type="int16" Size="4" />
-<Data ElementName="mount_type" Type="int16" Size="1" />
-<Data ElementName="mount_color" Type="EQ2_Color" />
-<Data ElementName="mount_saddle_color" Type="EQ2_Color" />
-<Data ElementName="hair_color1" Type="EQ2_Color" />
-<Data ElementName="hair_color2" Type="EQ2_Color" />
-<Data ElementName="hair_highlight" Type="EQ2_Color" />
-<Data ElementName="soga_hair_color1" Type="EQ2_Color"  />
-<Data ElementName="soga_hair_color2" Type="EQ2_Color"  />
-<Data ElementName="soga_hair_highlight" Type="EQ2_Color" />
+<Struct Name="Substruct_SpawnInfoStruct" ClientVersion="561" >
+<Data ElementName="hp_remaining" Type="int32" Size="1" /> <!-- 0 -->
+<Data ElementName="power_percent" Type="int32" Size="1" /> <!-- 4 -->
+<Data ElementName="spell_effects" Substruct="Substruct_TargetSpellEffects" Size="30" /> <!-- 278 -->
+<Data ElementName="target_id" Type="int32" Size="1" /> <!-- 282 -->
+<Data ElementName="follow_target" Type="int32" Size="1" /> <!-- 286 -->
+<Data ElementName="unknown4" Type="int8" Size="7" /> <!-- 290 -->
+<Data ElementName="corpse" Type="int8" Size="1" /> <!-- 297 -->
+<Data ElementName="class" Type="int8" Size="1" /> <!-- 298 -->
+<Data ElementName="effective_level" Type="int8" Size="1" /> <!-- 299 -->
+<Data ElementName="level" Type="int8" Size="1" /> <!-- 300 -->
+<Data ElementName="difficulty" Type="int8" Size="1" /> <!-- 301 -->
+<Data ElementName="unknown6" Type="int8" Size="1" /> <!-- 302 -->
+<Data ElementName="heroic_flag" Type="int8" Size="1" /> <!-- 303 -->
+<Data ElementName="activity_status" Type="int32" Size="1" /> <!-- 304 -->
+<Data ElementName="unknown5" Type="int8" Size="3" /> <!-- 308 -->
+<!-- some strange model/race change -->
+<Data ElementName="flags" Type="int8" Size="1" /> <!-- 314 -->
+<Data ElementName="unknowndata" Type="int32" Size="1" /> <!-- 327 -->
+<Data ElementName="model_type" Type="int16" Size="1" /> <!-- 331 -->
+<Data ElementName="soga_model_type" Type="int16" Size="1" /> <!-- 333 -->
+<Data ElementName="skin_color" Type="EQ2_Color" Size="1" /> <!-- 335 -->
+<Data ElementName="eye_color" Type="EQ2_Color" Size="1" /> <!-- 338 -->
+<Data ElementName="soga_eye_color" Type="EQ2_Color" /> <!-- 341 -->
+<Data ElementName="soga_skin_color" Type="EQ2_Color" /> <!-- 344 -->
+<Data ElementName="equipment_types" Type="int16" Size="23" /> <!-- 347 -->
+<Data ElementName="hair_type_id" Type="int16" Size="1" /> <!-- 393 -->
+<Data ElementName="facial_hair_type_id" Type="int16" Size="1" /> <!-- 395 -->
+<Data ElementName="chest_type_id" Type="int16" Size="1" /> <!-- 397 -->
+<Data ElementName="legs_type_id" Type="int16" Size="1" /> <!-- 399 -->
+<Data ElementName="soga_hair_type_id" Type="int16" Size="1" /> <!-- 401 -->
+<Data ElementName="soga_facial_hair_type_id" Type="int16" Size="1" /> <!-- 403 -->
+<Data ElementName="equipment_colors" Type="EQ2_Color" Size="23" /> <!-- 405 -->
+<Data ElementName="hair_type_color" Type="EQ2_Color" /> <!-- 474 -->
+<Data ElementName="hair_face_color" Type="EQ2_Color" /> <!-- 477 -->
+<Data ElementName="chest_type_color" Type="EQ2_Color" Size="1" /> <!-- 480 -->
+<Data ElementName="legs_type_color" Type="EQ2_Color" Size="1" /> <!-- 483 -->
+<Data ElementName="equipment_highlights" Type="EQ2_Color" Size="23" /> <!-- 486 -->
+<Data ElementName="hair_type_highlight_color" Type="EQ2_Color" /> <!-- 555 -->
+<Data ElementName="hair_face_highlight_color" Type="EQ2_Color" /> <!-- 558 -->
+<Data ElementName="chest_type_highlight_color" Type="EQ2_Color" Size="1" /> <!-- 561 -->
+<Data ElementName="legs_type_highlight_color" Type="EQ2_Color" Size="1" /> <!-- 564 -->
+<Data ElementName="soga_hair_type_color" Type="EQ2_Color" /> <!-- 567 -->
+<Data ElementName="soga_hair_type_highlight_color" Type="EQ2_Color" /> <!-- 570 -->
+<Data ElementName="soga_hair_face_color" Type="EQ2_Color" /> <!-- 573 -->
+<Data ElementName="soga_hair_face_highlight_color" Type="EQ2_Color" /> <!-- 576 -->
+<Data ElementName="skull_type" Type="sint8" Size="3" /> <!-- 579 -->
+<Data ElementName="eye_type" Type="sint8" Size="3" /> <!-- 582 -->
+<Data ElementName="ear_type" Type="sint8" Size="3" /> <!-- 585 -->
+<Data ElementName="eye_brow_type" Type="sint8" Size="3" /> <!-- 588 -->
+<Data ElementName="cheek_type" Type="sint8" Size="3" /> <!-- 591 -->
+<Data ElementName="lip_type" Type="sint8" Size="3" /> <!-- 594 -->
+<Data ElementName="chin_type" Type="sint8" Size="3" /> <!-- 597 -->
+<Data ElementName="nose_type" Type="sint8" Size="3" /> <!-- 600 -->
+<Data ElementName="body_size" Type="sint8" Size="1" /> <!-- 603 -->
+<Data ElementName="bump_size" Type="sint8" Size="1" /> <!-- 604 -->
+<Data ElementName="soga_skull_type" Type="sint8" Size="3" /> <!-- 605 -->
+<Data ElementName="soga_eye_type" Type="sint8" Size="3" /> <!-- 608 -->
+<Data ElementName="soga_ear_type" Type="sint8" Size="3" /> <!-- 611 -->
+<Data ElementName="soga_eye_brow_type" Type="sint8" Size="3" /> <!-- 614 -->
+<Data ElementName="soga_cheek_type" Type="sint8" Size="3" /> <!-- 617 -->
+<Data ElementName="soga_lip_type" Type="sint8" Size="3" /> <!-- 620 -->
+<Data ElementName="soga_chin_type" Type="sint8" Size="3" /> <!-- 623 -->
+<Data ElementName="soga_nose_type" Type="sint8" Size="3" /> <!-- 626 -->
+<Data ElementName="soga_body_size" Type="sint8" Size="1" /> <!-- 629 -->
+<Data ElementName="soga_bump_size" Type="sint8" Size="1" /> <!-- 630 -->
+<Data ElementName="mount_type" Type="int16" Size="1" /> <!-- 631 -->
+<Data ElementName="mount_color" Type="EQ2_Color" /> <!-- 633 -->
+<Data ElementName="mount_saddle_color" Type="EQ2_Color" /> <!-- 636 -->
+<Data ElementName="hair_color1" Type="EQ2_Color" /> <!-- 639 -->
+<Data ElementName="hair_color2" Type="EQ2_Color" /> <!-- 642 -->
+<Data ElementName="hair_highlight" Type="EQ2_Color" /> <!-- 645 -->
+<Data ElementName="soga_hair_color1" Type="EQ2_Color" /> <!-- 648 -->
+<Data ElementName="soga_hair_color2" Type="EQ2_Color" /> <!-- 651 -->
+<Data ElementName="soga_hair_highlight" Type="EQ2_Color" /> <!-- 654 -->
 <Data ElementName="combat_voice" Type="int16" Size="1" />
 <Data ElementName="emote_voice" Type="int16" Size="1" />
-<Data ElementName="unknown17" Type="int8" Size="2" />
-<Data ElementName="visual_flag" Type="int8" Size="1" />
-<Data ElementName="interaction_flag" Type="int8" Size="1" />
-<Data ElementName="unknown18" Type="int8" Size="32" />
-<Data ElementName="action_state" Type="int16" Size="1" />
-<Data ElementName="visual_state" Type="int16" Size="1" />
-<Data ElementName="mood_state" Type="int16" Size="1" />
-<Data ElementName="race" Type="int8" Size="1" />
-<Data ElementName="gender" Type="int8" Size="1" /> <!-- total 722 -->
+<Data ElementName="unknown" Type="int8" Size="3" /> <!-- 657 -->
+<Data ElementName="unknown2" Type="int8" Size="3" /> <!-- 664 -->
+<Data ElementName="temporary_scale" Type="float" Size="1" /> <!-- 667 -->
+<Data ElementName="name" Type="char" Size="64" /> <!-- 671 -->
+<Data ElementName="last_name" Type="char" Size="64" /> <!-- 735 -->
+<Data ElementName="name_suffix" Type="char" Size="64" /> <!-- 799 -->
+<Data ElementName="name_prefix" Type="char" Size="64" /> <!-- 863 -->
+<Data ElementName="unknown31" Type="char" Size="64" /> <!--927-->
+<Data ElementName="second_suffix" Type="char" Size="64" /> <!-- 991 -->
+<Data ElementName="persistent_spell_visuals" Type="int16" Size="8" /> <!-- 1055 -->
+<Data ElementName="persistent_spell_levels" Type="int8" Size="8" /> <!-- 1071 -->
+<Data ElementName="action_state" Type="int16" Size="1" /> <!-- 1079 -->
+<Data ElementName="visual_state" Type="int16" Size="1" /> <!-- 1081 -->
+<Data ElementName="mood_state" Type="int16" Size="1" /> <!-- 1083 -->
+<Data ElementName="emote_state" Type="int16" Size="1" /> <!-- 1085 -->
+<Data ElementName="race" Type="int8" Size="1" /> <!-- 1087 -->
+<Data ElementName="gender" Type="int8" Size="1" /> <!-- 1088 -->
 </Struct>
-<Struct Name="Substruct_SpawnInfoStruct" ClientVersion="860" >
+<Struct Name="Substruct_SpawnInfoStruct" ClientVersion="562" >
 <Data ElementName="hp_remaining" Type="int8" Size="1" />
 <Data ElementName="unknown2a" Type="int8" Size="3" />
 <Data ElementName="power_percent" Type="int8" Size="1" />
@@ -2404,7 +2414,7 @@
 <Data ElementName="widget_y" Type="float" Size="1" />
 <Data ElementName="widget_z" Type="float" Size="1" />
 </Struct>
-<Struct Name="WS_WidgetSpawnStruct_Footer" ClientVersion="547">
+<Struct Name="WS_WidgetSpawnStruct_Footer" ClientVersion="562">
 <Data ElementName="name" Type="EQ2_16Bit_String" Size="1" />
 <Data ElementName="unknown1" Type="float" Size="1" />
 <Data ElementName="unknown2" Type="float" Size="1" />
@@ -2471,11 +2481,7 @@
 <Data ElementName="show" Type="int16" Size="1" />
 <Data ElementName="language" Type="int8" Size="1" />
 </Struct>
-<Struct Name="WS_SignWidgetSpawnStruct_Footer" ClientVersion="547">
-<Data ElementName="name" Type="EQ2_16Bit_String" Size="1" />
-<Data ElementName="unknown1a" Type="float" Size="1" />
-<Data ElementName="unknown1b" Type="float" Size="1" />
-<Data ElementName="unknown1c" Type="float" Size="1" />
+<Struct Name="WS_SignWidgetSpawnStruct_Footer" ClientVersion="561">
 <Data ElementName="widget_id" Type="int32" Size="1" />
 <Data ElementName="widget_x" Type="float" Size="1" />
 <Data ElementName="widget_y" Type="float" Size="1" />
@@ -2562,14 +2568,16 @@
 <Data ElementName="unknown5" Type="int8" Size="1" />
 <Data ElementName="guild" Type="char" Size="64" />
 </Struct>
-<Struct Name="Substruct_SpawnVisualizationInfoStruct" ClientVersion="547">
+<Struct Name="Substruct_SpawnVisualizationInfoStruct" ClientVersion="561" Comment="66 bytes">
 <Data ElementName="arrow_color" Type="int8" Size="1" />
 <Data ElementName="locked_no_loot" Type="int8" Size="1" />
 <Data ElementName="npc_con" Type="sint8" Size="1" />
 <Data ElementName="quest_flag" Type="int8" Size="1" />
 <Data ElementName="vis_flags" Type="int8" Size="1" />
-<Data ElementName="unknownb" Type="int8" Size="4" />
-<Data ElementName="hand_flag" Type="int8" Size="1" />
+<Data ElementName="unknown1" Type="int8" Size="1" />
+<Data ElementName="targetable" Type="int8" Size="1" />
+<Data ElementName="red_glow" Type="int8" Size="1" />
+<Data ElementName="guild" Type="char" Size="64" />
 </Struct>
 <Struct Name="Substruct_SpawnVisualizationInfoStruct" ClientVersion="936">
 <Data ElementName="arrow_color" Type="int8" Size="1" />
@@ -2664,7 +2672,7 @@
 <Data ElementName="vis" Substruct="Substruct_SpawnVisualizationInfoStruct" Size="1" />
 <Data ElementName="info" Substruct="Substruct_SpawnInfoStruct" Size="1" />
 </Struct>
-<Struct Name="WS_SpawnStruct" ClientVersion="547">
+<Struct Name="WS_SpawnStruct" ClientVersion="561">
 <Data ElementName="position" Substruct="Substruct_SpawnPositionStruct" Size="1" />
 <Data ElementName="vis" Substruct="Substruct_SpawnVisualizationInfoStruct" Size="1" />
 <Data ElementName="info" Substruct="Substruct_SpawnInfoStruct" Size="1" />

+ 471 - 62
server/WorldStructs.xml

@@ -10,7 +10,7 @@ to zero and treated like placeholders." />
    <Data ElementName="description" Type="EQ2_16Bit_String" />
 </Data>
 </Struct>
-<Struct Name="WS_SkillMap" ClientVersion="547" OpcodeName="OP_PopulateSkillMapsMsg" >
+<Struct Name="WS_SkillMap" ClientVersion="562" OpcodeName="OP_PopulateSkillMapsMsg" >
 <Data ElementName="skill_count" Type="int32" /> 
 <Data ElementName="skill_array" Type="Array" ArraySizeVariable="skill_count"> 
    <Data ElementName="skill_id" Type="int32" /> 
@@ -114,7 +114,7 @@ to zero and treated like placeholders." />
 <Data ElementName="version"  Type="int16" />
 <Data ElementName="unknown2"  Type="int32" Size="5" />
 </Struct>
-<Struct Name="LoginByNumRequest" ClientVersion="547" >
+<Struct Name="LoginByNumRequest" ClientVersion="562" >
 <Data ElementName="account_id"  Type="int32" />
 <Data ElementName="access_code"  Type="int32" />
 <Data ElementName="unknown"  Type="int32" />
@@ -154,6 +154,20 @@ to zero and treated like placeholders." />
 <Data ElementName="unknown15" Type="int8" Size="11" />
 <Data ElementName="unknown02" Type="int8" Size="1" />
 </Struct>
+<Struct Name="LS_LoginResponse" ClientVersion="561" OpcodeName="OP_LoginReplyMsg">
+<Data ElementName="reply_code" Type="int8" Size="1" />
+<Data ElementName="unknown01" Type="int8" Size="22" />
+<Data ElementName="unknown02" Type="int8" Size="1" />
+<Data ElementName="unknown03" Type="sint32" Size="1" />
+<Data ElementName="unknown04" Type="sint32" Size="1" />
+<Data ElementName="unknown05" Type="sint32" Size="1" />
+<Data ElementName="accountid" Type="int32" Size="1" />
+<Data ElementName="unknown06" Type="int8" Size="7" />
+<Data ElementName="unknown07" Type="int32" Size="1" />
+<Data ElementName="unknown08" Type="int32" Size="1" />
+<Data ElementName="unknown09" Type="int32" Size="1" />
+<Data ElementName="unknown10" Type="int32" Size="1" />
+</Struct>
 <Struct Name="LS_LoginResponse" ClientVersion="1096" OpcodeName="OP_LoginReplyMsg">
 <Data ElementName="reply_code" Type="int8" Size="1" />
 <Data ElementName="unknown01" Type="int8" Size="22" />
@@ -408,7 +422,7 @@ to zero and treated like placeholders." />
 <Data ElementName="minute" Type="int8" Size="1" />
 <Data ElementName="unknown" Type="int8" Size="1" />
 </Struct>
-<Struct Name="WS_GameWorldTime" ClientVersion="547" OpcodeName="OP_GameWorldTimeMsg">
+<Struct Name="WS_GameWorldTime" ClientVersion="562" OpcodeName="OP_GameWorldTimeMsg">
 <Data ElementName="year" Type="int16" Size="1" />
 <Data ElementName="month" Type="int8" Size="1" />
 <Data ElementName="day" Type="int8" Size="1" />
@@ -431,7 +445,7 @@ to zero and treated like placeholders." />
 <Data ElementName="seconds" Type="int8" Size="1" />
 <Data ElementName="camp_desktop" Type="int8" Size="1" />
 </Struct>
-<Struct Name="WS_Camp" ClientVersion="547" OpcodeName="OP_CampStartedMsg" >
+<Struct Name="WS_Camp" ClientVersion="562" OpcodeName="OP_CampStartedMsg" >
 <Data ElementName="seconds" Type="int8" Size="1" />
 <Data ElementName="camp_desktop" Type="int8" Size="1" />
 <Data ElementName="camp_char_select" Type="int8" Size="1" />
@@ -449,7 +463,7 @@ to zero and treated like placeholders." />
 <Data ElementName="quit" Type="int8" Size="1" />
 <Data ElementName="camp_desktop" Type="int8" Size="1" />
 </Struct>
-<Struct Name="WS_RequestCamp" ClientVersion="547" OpcodeName="OP_RequestCampMsg">
+<Struct Name="WS_RequestCamp" ClientVersion="562" OpcodeName="OP_RequestCampMsg">
 <Data ElementName="quit" Type="int8" Size="1" />
 <Data ElementName="camp_desktop" Type="int8" Size="1" />
 <Data ElementName="camp_char_select" Type="int16" Size="1" />
@@ -482,7 +496,7 @@ to zero and treated like placeholders." />
 <Data ElementName="icon_type" Type="int16" Size="1" />
 <Data ElementName="unknown5" Type="int32" Size="1" />
 </Struct>
-<Struct Name="WS_SpellGainedMsg" ClientVersion="547" OpcodeName="OP_SpellGainedMsg">
+<Struct Name="WS_SpellGainedMsg" ClientVersion="562" OpcodeName="OP_SpellGainedMsg">
 <Data ElementName="spell_type" Type="int8" Size="1" />
 <Data ElementName="spell_id" Type="int32" Size="1" />
 <Data ElementName="unique_id" Type="int32" Size="1" />
@@ -529,7 +543,7 @@ to zero and treated like placeholders." />
    <Data ElementName="icon" Type="int16" Size="1" /> 
 </Data>
 </Struct>
-<Struct Name="WS_MacroInit" ClientVersion="547" OpcodeName="OP_MacroInitMsg" > 
+<Struct Name="WS_MacroInit" ClientVersion="562" OpcodeName="OP_MacroInitMsg" > 
 <Data ElementName="macro_count" Type="int32" />
 <Data ElementName="macro_array" Type="Array" ArraySizeVariable="macro_count">
    <Data ElementName="number" Type="int8" />
@@ -559,7 +573,7 @@ to zero and treated like placeholders." />
 </Data>
 <Data ElementName="icon" Type="int16" Size="1" /> 
 </Struct>
-<Struct Name="WS_MacroUpdate" ClientVersion="547" OpcodeName="OP_MacroUpdateMsg" > 
+<Struct Name="WS_MacroUpdate" ClientVersion="562" OpcodeName="OP_MacroUpdateMsg" > 
 <Data ElementName="number" Type="int8" />
 <Data ElementName="name" Type="EQ2_8Bit_String" />
 <Data ElementName="macro_count" Type="int8" />
@@ -639,7 +653,64 @@ to zero and treated like placeholders." />
 	<Data ElementName="adv_id" Type="int16" />
 </Data>
 </Struct>
-<Struct Name="WS_ZoneInfo" ClientVersion="547" OpcodeName="OP_ZoneInfoMsg">
+<Struct Name="WS_ZoneInfo" ClientVersion="561" OpcodeName="OP_ZoneInfoMsg">
+<Data ElementName="server1" Type="EQ2_8Bit_String" />
+<Data ElementName="server2" Type="EQ2_8Bit_String" />
+<Data ElementName="expansions_enabled" Type="int32" Size="1" />
+<Data ElementName="unknown1" Type="int32" Size="1" />
+<Data ElementName="auction_website" Type="EQ2_8Bit_String" />
+<Data ElementName="auction_port" Type="int32" Size="1" />
+<Data ElementName="upload_page" Type="EQ2_8Bit_String" />
+<Data ElementName="upload_key" Type="EQ2_8Bit_String" />
+<Data ElementName="zone" Type="EQ2_8Bit_String" />
+<Data ElementName="zone2" Type="EQ2_8Bit_String" />
+<Data ElementName="parent_zone" Type="EQ2_8Bit_String" />
+<Data ElementName="zone_unknown2" Type="EQ2_8Bit_String" />
+<Data ElementName="zone_desc" Type="EQ2_8Bit_String" />
+<Data ElementName="char_name" Type="EQ2_8Bit_String" />
+<Data ElementName="x" Type="float" Size="1" />
+<Data ElementName="y" Type="float" Size="1" />
+<Data ElementName="z" Type="float" Size="1" />
+<Data ElementName="year" Type="int16" Size="1" />
+<Data ElementName="month" Type="int8" Size="1" />
+<Data ElementName="day" Type="int8" Size="1" />
+<Data ElementName="hour" Type="int8" Size="1" />
+<Data ElementName="minute" Type="int8" Size="1" />
+<Data ElementName="seconds" Type="int8" Size="1" />
+<Data ElementName="unknown7" Type="float" Size="2" />
+<Data ElementName="num_slides" Type="int8" Size="1" />
+<Data ElementName="slide_array" Type="Array" ArraySizeVariable="num_slides">
+	<Data ElementName="unknown1" Type="float" Size="2" />
+	<Data ElementName="unknown2" Type="int32" Size="2" />
+	<Data ElementName="unknown3" Type="int32" Size="1" />
+	<Data ElementName="unknown4" Type="int32" Size="1" />
+	<Data ElementName="slide" Type="EQ2_8Bit_String" />
+	<Data ElementName="voiceover" Type="EQ2_8Bit_String" />
+	<Data ElementName="key1" Type="int32" Size="1" />
+	<Data ElementName="key2" Type="int32" Size="1" />
+	<Data ElementName="num_transitions" Type="int8" Size="1" />
+	<Data ElementName="transitions_array" Type="Array" ArraySizeVariable="num_transitions">
+		<Data ElementName="transition_x" Type="int32" Size="1" />
+		<Data ElementName="transition_y" Type="int32" Size="1" />
+		<Data ElementName="transition_zoom" Type="float" Size="1" />
+		<Data ElementName="transition_time" Type="float" Size="1" />
+	</Data>
+</Data>
+<Data ElementName="unknown8" Type="int8" Size="1" />
+<Data ElementName="unknown9" Type="float" Size="1" />
+<Data ElementName="zone_flags" Type="int32" Size="1" />
+<Data ElementName="num_adv" Type="int32" Size="1" />
+<Data ElementName="adv_array" Type="Array" ArraySizeVariable="num_adv">
+	<Data ElementName="adv_name" Type="EQ2_16Bit_String" />
+	<Data ElementName="adv_id" Type="int16" />
+</Data>
+<Data ElementName="num_client_setup" Type="int32" Size="1" />
+<Data ElementName="client_cmd_array" Type="Array" ArraySizeVariable="num_client_setup">
+	<Data ElementName="client_cmds" Type="EQ2_8Bit_String" />
+</Data>
+<Data ElementName="unknown11" Type="int32" Size="1" />
+</Struct>
+<Struct Name="WS_ZoneInfo" ClientVersion="562" OpcodeName="OP_ZoneInfoMsg">
 <Data ElementName="server1" Type="EQ2_8Bit_String" />
 <Data ElementName="auction_website" Type="EQ2_8Bit_String" />
 <Data ElementName="auction_port" Type="int32" Size="1" />
@@ -1425,6 +1496,19 @@ to zero and treated like placeholders." />
 <Data ElementName="total_time" Type="float" Size="1" />
 <Data ElementName="expire_timestamp" Type="int32" Size="1" />
 </Struct>
+<Struct Name="Substruct_MaintainedEffects" ClientVersion="561">
+<Data ElementName="name" Type="char" Size="60" />
+<Data ElementName="target" Type="int32" Size="1" />
+<Data ElementName="target_type" Type="int8" Size="1" />
+<Data ElementName="spell_id" Type="int32" Size="1" />
+<Data ElementName="slot_pos" Type="int32" Size="1" />
+<Data ElementName="icon" Type="int16" Size="1" />
+<Data ElementName="icon_type" Type="int16" Size="1" />
+<Data ElementName="unknown3" Type="int8" Size="1" />
+<Data ElementName="conc_used" Type="int8" Size="1" />
+<Data ElementName="total_time" Type="float" Size="1" />
+<Data ElementName="expire_timestamp" Type="int32" Size="1" />
+</Struct>
 <Struct Name="Substruct_MaintainedEffects" ClientVersion="1193">
 <Data ElementName="name" Type="char" Size="60" />
 <Data ElementName="target" Type="int32" Size="1" />
@@ -1490,7 +1574,7 @@ to zero and treated like placeholders." />
 <Data ElementName="zone" Type="char" Size="60" />
 <Data ElementName="instance" Type="int8" Size="1" />
 </Struct>
-<Struct Name="Substruct_GroupMember" ClientVersion="547" >
+<Struct Name="Substruct_GroupMember" ClientVersion="562" >
 <Data ElementName="spawn_id" Type="int32" Size="1" />
 <Data ElementName="pet_id" Type="int32" Size="1" />
 <Data ElementName="hp_current" Type="sint32" Size="1" />
@@ -2007,6 +2091,238 @@ to zero and treated like placeholders." />
 <Data ElementName="house_zone" Type="char" Size="61" /> <!-- 4776 -->
 <Data ElementName="bind_zone" Type="char" Size="61" /> <!-- 4837 -->
 </Struct>
+<Struct Name="WS_CharacterSheet" ClientVersion="561" OpcodeName="OP_UpdateCharacterSheetMsg">
+<Data ElementName="character_name" Type="char" Size="41" /> <!-- starting at byte 1 -->
+<Data ElementName="race" Type="int8" Size="1" />  <!-- 42 -->
+<Data ElementName="gender" Type="int8" Size="1" />  <!-- 43 -->
+<Data ElementName="class1" Type="int32" Size="1" /> <!-- 44 -->
+<Data ElementName="class2" Type="int32" Size="1" /> <!-- 48 -->
+<Data ElementName="class3" Type="int32" Size="1" /> <!-- 52 -->
+<Data ElementName="tradeskill_class1" Type="int32" Size="1" /> <!-- 56 -->
+<Data ElementName="tradeskill_class2" Type="int32" Size="1" /> <!-- 60 -->
+<Data ElementName="tradeskill_class3" Type="int32" Size="1" /> <!-- 64 -->
+<Data ElementName="level" Type="int16" Size="1" />  <!-- 68 -->
+<Data ElementName="effective_level" Type="int16" Size="1" />  <!-- 70 -->
+<Data ElementName="tradeskill_level" Type="int16" Size="1" />  <!-- 72 -->
+<Data ElementName="gm_level" Type="int32" Size="1" /> <!-- 74 -->
+<Data ElementName="account_age_base" Type="int16" Size="1" />  <!-- 78 -->
+<Data ElementName="trial_isle_bonus" Type="sint16" Size="1" /> <!-- 80 -->
+<Data ElementName="all_access_bonus" Type="sint16" Size="1" /> <!-- 82 -->
+<Data ElementName="bc_bonus" Type="sint16" Size="1" /> <!-- 84 -->
+<Data ElementName="dof_bonus" Type="sint16" Size="1" /> <!-- 86 -->
+<Data ElementName="froglok_bonus" Type="sint16" Size="1" /> <!-- 88 -->
+<Data ElementName="auction_access_bonus" Type="sint16" Size="1" /> <!-- 90 -->
+<Data ElementName="ss_bonus" Type="sint16" Size="1" /> <!-- 92 -->
+<Data ElementName="exp2_bonus" Type="sint16" Size="1" /> <!-- 94 -->
+<Data ElementName="exp3_bonus" Type="sint16" Size="1" /> <!-- 96 -->
+<Data ElementName="freeplay_bonus" Type="sint16" Size="1" /> <!-- 98 -->
+<Data ElementName="freeplay_limit_exceeded_bonus" Type="sint16" Size="1" /> <!-- 100 -->
+<Data ElementName="last_name" Type="char" Size="20" /> <!-- 102 -->
+<Data ElementName="unknown1" Type="int8" Size="1" /> <!-- 122, resets emote and combat selections -->
+<Data ElementName="current_hp" Type="int32" Size="1" /> <!-- 123 -->
+<Data ElementName="max_hp" Type="int32" Size="1" /> <!-- 127 -->
+<Data ElementName="base_hp" Type="int32" Size="1" /> <!-- 131 -->
+<Data ElementName="current_power" Type="int32" Size="1" /> <!-- 135 -->
+<Data ElementName="max_power" Type="int32" Size="1" /> <!-- 139 -->
+<Data ElementName="base_power" Type="int32" Size="1" /> <!-- 143 -->
+<Data ElementName="conc_used" Type="int8" Size="1" /> <!-- 144 -->
+<Data ElementName="conc_max" Type="int8" Size="1" /> <!-- 145 -->
+<Data ElementName="attack" Type="int16" Size="1" /> <!-- 147 -->
+<Data ElementName="attack_base" Type="int16" Size="1" /> <!-- 149 -->
+<Data ElementName="mitigation_cur" Type="int16" Size="1" /> <!-- 151 -->
+<Data ElementName="mitigation_max" Type="int16" Size="1" /> <!-- 153 -->
+<Data ElementName="absorb" Type="int16" Size="1" /> <!-- 155 -->
+<Data ElementName="avoidance_cur" Type="int16" Size="1" /> <!-- 157 -->
+<Data ElementName="avoidance_max" Type="int16" Size="1" /> <!-- 159 -->
+<Data ElementName="avoidance_base" Type="int16" Size="1" /> <!-- 161 -->
+<Data ElementName="unknown2" Type="int16" Size="1" /> <!-- 163 -->
+<Data ElementName="avoidance_parry_chance" Type="int16" Size="1" /> <!-- 165 -->
+<Data ElementName="avoidance_parry_chance_base" Type="int16" Size="1" /> <!-- 167 -->
+<Data ElementName="avoidance_deflection_chance" Type="int16" Size="1" /> <!-- 169 -->
+<Data ElementName="avoidance_deflection_chance_base" Type="int16" Size="1" /> <!-- 171 -->
+<Data ElementName="avoidance_block_chance" Type="int16" Size="1" /> <!-- 173 -->
+<Data ElementName="avoidance_block_chance_base" Type="int16" Size="1" /> <!-- 175 -->
+<Data ElementName="str" Type="int16" Size="1" /> <!-- 177 -->
+<Data ElementName="sta" Type="int16" Size="1" /> <!-- 179 -->
+<Data ElementName="agi" Type="int16" Size="1" /> <!-- 181 -->
+<Data ElementName="wis" Type="int16" Size="1" /> <!-- 183 -->
+<Data ElementName="int" Type="int16" Size="1" /> <!-- 185 -->
+<Data ElementName="str_base" Type="int16" Size="1" /> <!-- 187 -->
+<Data ElementName="sta_base" Type="int16" Size="1" /> <!-- 189 -->
+<Data ElementName="agi_base" Type="int16" Size="1" /> <!-- 191 -->
+<Data ElementName="wis_base" Type="int16" Size="1" /> <!-- 193 -->
+<Data ElementName="int_base" Type="int16" Size="1" /> <!-- 195 -->
+<Data ElementName="slashing" Type="int16" Size="1" /> <!-- 197 -->
+<Data ElementName="crushing" Type="int16" Size="1" /> <!-- 199 -->
+<Data ElementName="piercing" Type="int16" Size="1" /> <!-- 201 -->
+<Data ElementName="heat" Type="int16" Size="1" /> <!-- 203 -->
+<Data ElementName="cold" Type="int16" Size="1" /> <!-- 205 -->
+<Data ElementName="magic" Type="int16" Size="1" /> <!-- 207 -->
+<Data ElementName="mental" Type="int16" Size="1" /> <!-- 209 -->
+<Data ElementName="divine" Type="int16" Size="1" /> <!-- 211 -->
+<Data ElementName="disease" Type="int16" Size="1" /> <!-- 213 -->
+<Data ElementName="poison" Type="int16" Size="1" /> <!-- 215 -->
+<Data ElementName="slashing_base" Type="int16" Size="1" /> <!-- 217 -->
+<Data ElementName="crushing_base" Type="int16" Size="1" /> <!-- 219 -->
+<Data ElementName="piercing_base" Type="int16" Size="1" /> <!-- 221 -->
+<Data ElementName="heat_base" Type="int16" Size="1" /> <!-- 223 -->
+<Data ElementName="cold_base" Type="int16" Size="1" /> <!-- 225 -->
+<Data ElementName="magic_base" Type="int16" Size="1" /> <!-- 227 -->
+<Data ElementName="mental_base" Type="int16" Size="1" /> <!-- 229 -->
+<Data ElementName="divine_base" Type="int16" Size="1" /> <!-- 231 -->
+<Data ElementName="disease_base" Type="int16" Size="1" /> <!-- 235 -->
+<Data ElementName="poison_base" Type="int16" Size="1" /> <!-- 237 -->
+<Data ElementName="slashing_absorb" Type="int16" Size="1" /> <!-- 239 -->
+<Data ElementName="crushing_absorb" Type="int16" Size="1" /> <!-- 241 -->
+<Data ElementName="piercing_absorb" Type="int16" Size="1" /> <!-- 243 -->
+<Data ElementName="heat_absorb" Type="int16" Size="1" /> <!-- 245 -->
+<Data ElementName="cold_absorb" Type="int16" Size="1" /> <!-- 247 -->
+<Data ElementName="magic_absorb" Type="int16" Size="1" /> <!-- 249 -->
+<Data ElementName="mental_absorb" Type="int16" Size="1" /> <!-- 251 -->
+<Data ElementName="divine_absorb" Type="int16" Size="1" /> <!-- 253 -->
+<Data ElementName="disease_absorb" Type="int16" Size="1" /> <!-- 255 -->
+<Data ElementName="poison_absorb" Type="int16" Size="1" /> <!-- 257 -->
+<Data ElementName="exp_yellow" Type="int16" Size="1" /> <!-- 259 -->
+<Data ElementName="exp_blue" Type="int16" Size="1" /> <!-- 261 -->
+<Data ElementName="exp_debt" Type="int16" Size="1" /> <!-- 263 -->
+<Data ElementName="tradeskill_exp_yellow" Type="int16" Size="1" /> <!-- 265 -->
+<Data ElementName="tradeskill_exp_blue" Type="int16" Size="1" /> <!-- 267 -->
+<Data ElementName="tradeskill_exp_debt" Type="int16" Size="1" /> <!-- 269 -->
+<Data ElementName="adventure_exp_vitality" Type="int16" Size="1" /> <!-- 271 -->
+<Data ElementName="xp_yellow_vitality_bar" Type="int16" Size="1" /> <!-- 273 -->
+<Data ElementName="xp_blue_vitality_bar" Type="int16" Size="1" /> <!-- 275 -->
+<Data ElementName="adventure_exp_vitality" Type="int16" Size="1" /> <!-- 277 -->
+<Data ElementName="xp_yellow_vitality_bar" Type="int16" Size="1" /> <!-- 279 -->
+<Data ElementName="xp_blue_vitality_bar" Type="int16" Size="1" /> <!-- 281 -->
+<Data ElementName="mentoring_xp_bonus" Type="float" Size="1" /> <!-- 285 -->
+<Data ElementName="assigned_aa" Type="int16" Size="1" />
+<Data ElementName="max_aa" Type="int16" Size="1" />
+<Data ElementName="unassigned_aa" Type="int16" Size="1" />
+<Data ElementName="combat_exp_enabled" Type="int8" Size="1" /> <!-- 0x90 -->
+<Data ElementName="unknownx" Type="int8" Size="1" />
+<Data ElementName="aa_green_bar" Type="int16" Size="1" />
+<Data ElementName="level_events" Type="int32" Size="1" />
+<Data ElementName="items_found" Type="int32" Size="1" /> <!-- 303 -->
+<Data ElementName="named_npcs_killed" Type="int32" Size="1" /> <!-- 307 -->
+<Data ElementName="quests_completed" Type="int32" Size="1" /> <!-- 311 -->
+<Data ElementName="exploration_events" Type="int32" Size="1" /> <!-- 315 -->
+<Data ElementName="completed_collections" Type="int32" Size="1" /> <!-- 319 -->
+<Data ElementName="unkspace2" Type="int8" Size="8" /> <!-- 327 -->
+<Data ElementName="coins_copper" Type="int32" Size="1" /> <!-- 332 -->
+<Data ElementName="coins_silver" Type="int32" Size="1" /> <!-- 336 -->
+<Data ElementName="coins_gold" Type="int32" Size="1" /> <!-- 340 -->
+<Data ElementName="coins_plat" Type="int32" Size="1" /> <!-- 344 -->
+<Data ElementName="weight" Type="int32" Size="1" />  <!-- 348 -->
+<Data ElementName="max_weight" Type="int32" Size="1" /> <!-- 352 -->
+<Data ElementName="unkspace3" Type="int8" Size="1" /> <!-- 353 -->
+<Data ElementName="spell_effects" Substruct="Substruct_SpellEffects" Size="30" /> <!-- 923 -->
+<Data ElementName="unknown5y" Type="int8" Size="19" /> <!-- 942 -->
+<Data ElementName="trauma" Type="int8" Size="1" /> <!-- 943 -->
+<Data ElementName="arcane" Type="int8" Size="1" /> <!-- 944 -->
+<Data ElementName="noxious" Type="int8" Size="1" /> <!-- 945 -->
+<Data ElementName="elemental" Type="int8" Size="1" /> <!-- 946 -->
+<Data ElementName="maintained_effects" Substruct="Substruct_MaintainedEffects" Size="30" /> <!-- 915 -->
+<Data ElementName="breath" Type="float" Size="1" /> <!-- 3525 -->
+<Data ElementName="breathable_environments" Type="int32" Size="1" /> <!-- 3529 -->
+<Data ElementName="flags" Type="int32" Size="1" />
+<Data ElementName="auto_attack" Type="int8" /> <!-- 3533 -->
+<Data ElementName="ranged_auto_attack" Type="int8" /> <!-- 3534 -->
+<Data ElementName="can_cast" Type="int8" Size="1" /> <!-- 3535 -->
+<Data ElementName="pre_zoning" Type="int8" Size="1" /> <!-- 3536 -->
+<Data ElementName="max_level" Type="int8" Size="1" /> <!-- 3537 -->
+<Data ElementName="max_TS_level" Type="int8" Size="1" /> <!-- 3538 -->
+<Data ElementName="feigndeath_state" Type="int8" Size="1" /> <!-- 3539 -->
+<Data ElementName="advancement_available" Type="int8" Size="1" /> <!-- 3540 -->
+<Data ElementName="unknown4" Type="char" Size="20" /> <!-- 3553 -->
+<Data ElementName="unknown5x" Type="int8" Size="216" /> <!-- 3573 -->
+<Data ElementName="spell_prop_hpregen" Type="int32" Size="1" /> <!-- 3809 -->
+<Data ElementName="spell_prop_manaregen" Type="int32" Size="1" /> <!-- 3813 -->
+<Data ElementName="spell_prop_hpregenppt" Type="int32" Size="1" /> <!-- 3817 -->
+<Data ElementName="spell_prop_mpregenppt" Type="int32" Size="1" /> <!-- 3821 -->
+<Data ElementName="spell_prop_combat_hpregenppt" Type="int32" Size="1" /> <!-- 3825 -->
+<Data ElementName="spell_prop_combat_mpregenppt" Type="int32" Size="1" /> <!-- 3829 -->
+<Data ElementName="spell_prop_maxhp" Type="int32" Size="1" /> <!-- 3833 -->
+<Data ElementName="spell_prop_maxhpperc" Type="int32" Size="1" /> <!-- 3837 -->
+<Data ElementName="spell_prop_speed" Type="int32" Size="1" /> <!-- 3841 -->
+<Data ElementName="spell_prop_slow" Type="int32" Size="1" /> <!-- 3845 -->
+<Data ElementName="spell_prop_mountspeed" Type="int32" Size="1" /> <!-- 3849 -->
+<Data ElementName="spell_prop_offensivespeed" Type="int32" Size="1" /> <!-- 3853 -->
+<Data ElementName="spell_prop_attackspeed" Type="int32" Size="1" /> <!-- 3857 -->
+<Data ElementName="spell_prop_maxmana" Type="int32" Size="1" /> <!-- 3861 -->
+<Data ElementName="spell_prop_maxmanaperc" Type="int32" Size="1" /> <!-- 3865 -->
+<Data ElementName="spell_prop_maxattperc" Type="int32" Size="1" /> <!-- 3869 -->
+<Data ElementName="spell_prop_healinhibit" Type="int32" Size="1" /> <!-- 3873 -->
+<Data ElementName="spell_prop_maxconcentration" Type="int32" Size="1" /> <!-- 3877 -->
+<Data ElementName="spell_prop_screen_blur" Type="int32" Size="1" />  <!-- 3881 -->
+<Data ElementName="spell_prop_redlight" Type="int32" Size="1" /> <!-- 3885 -->
+<Data ElementName="spell_prop_greenlight" Type="int32" Size="1" /> <!-- 3889 -->
+<Data ElementName="spell_prop_bluelight" Type="int32" Size="1" /> <!-- 3893 -->
+<Data ElementName="spell_prop_momentumbonus" Type="int32" Size="1" /> <!-- 3897 -->
+<Data ElementName="spell_prop_dmgmomentummod" Type="int32" Size="1" /> <!-- 3901 -->
+<Data ElementName="spell_prop_healmomentummod" Type="int32" Size="1" /> <!-- 3905 -->
+<Data ElementName="spell_prop_magiclevelimmunity" Type="int32" Size="1" /> <!-- 3909 -->
+<Data ElementName="spell_prop_hategainmod" Type="int32" Size="1" /> <!-- 3913 -->
+<Data ElementName="spell_prop_combatexpmod" Type="int32" Size="1" /> <!-- 3917 -->
+<Data ElementName="spell_prop_tradeskillexpmod" Type="int32" Size="1" /> <!-- 3921 -->
+<Data ElementName="spell_prop_sizemod" Type="int32" Size="1" /> <!-- 3925 -->
+<Data ElementName="spell_prop_dps" Type="int32" Size="1" /> <!-- 3929 -->
+<Data ElementName="spell_prop_stealth" Type="int32" Size="1" /> <!-- 3933 -->
+<Data ElementName="spell_prop_invis" Type="int32" Size="1" /> <!-- 3937 -->
+<Data ElementName="spell_prop_seeinvis" Type="int32" Size="1" /> <!-- 3941 -->
+<Data ElementName="spell_prop_seestealth" Type="int32" Size="1" /> <!-- 3945 -->
+<Data ElementName="spell_prop_effective_level_mod" Type="int32" Size="1" /> <!-- 3949 -->
+<Data ElementName="spell_prop_ripostechance" Type="int32" Size="1" /> <!-- 3953 -->
+<Data ElementName="spell_prop_parrychance" Type="int32" Size="1" /> <!-- 3957 -->
+<Data ElementName="spell_prop_aeautoattackchance" Type="int32" Size="1" /> <!-- 3961 -->
+<Data ElementName="spell_prop_item_hp_regen_percent" Type="int32" Size="1" /> <!-- 3965 -->
+<Data ElementName="spell_prop_item_power_regen_percent" Type="int32" Size="1" /> <!-- 3969 -->
+<Data ElementName="spell_prop_melee_crit_chance" Type="int32" Size="1" /> <!-- 3973 -->
+<Data ElementName="spell_prop_dmg_spell_chance" Type="int32" Size="1" /> <!-- 3977 -->
+<Data ElementName="spell_prop_heal_spell_crit_chance" Type="int32" Size="1" /> <!-- 3981 -->
+<Data ElementName="spell_state_root" Type="int8" Size="1" /> <!-- 3985 -->
+<Data ElementName="spell_state_charm" Type="int8" Size="1" /> <!-- 3986 -->
+<Data ElementName="spell_state_stun" Type="int8" Size="1" /> <!-- 3987 -->
+<Data ElementName="spell_state_stifle" Type="int8" Size="1" /> <!-- 3988 -->
+<Data ElementName="spell_state_fear" Type="int8" Size="1" /> <!-- 3989 -->
+<Data ElementName="spell_state_noaa" Type="int8" Size="1" /> <!-- 3990 -->
+<Data ElementName="spell_state_ultravision" Type="int8" Size="1" /> <!-- 3991 -->
+<Data ElementName="spell_state_infravision" Type="int8" Size="1" /> <!-- 3992 -->
+<Data ElementName="spell_state_sonicvision" Type="int8" Size="1" /> <!-- 3993 -->
+<Data ElementName="spell_state_fishvision" Type="int8" Size="1" /> <!-- 3994 -->
+<Data ElementName="spell_state_feigndeath" Type="int8" Size="1" /> <!-- 3995 -->
+<Data ElementName="spell_state_auravision" Type="int8" Size="1" /> <!-- 3996 -->
+<Data ElementName="spell_state_breath_water" Type="int8" Size="1" /> <!-- 3997 -->
+<Data ElementName="spell_state_noaoe" Type="int8" Size="1" /> <!-- 3998 -->
+<Data ElementName="spell_state_tradeskill_noconsume" Type="int8" Size="1" /> <!-- 3999 -->
+<Data ElementName="spell_state_sink_like_stone" Type="int8" Size="1" /> <!-- 4000 -->
+<Data ElementName="spell_state_sink_like_stone_superjump" Type="int8" Size="1" /> <!-- 4001 -->
+<Data ElementName="spell_state_no_direct_aoe" Type="int8" Size="1" /> <!-- 4002 -->
+<Data ElementName="spell_state_calm" Type="int8" Size="1" /> <!-- 4003 -->
+<Data ElementName="spell_state_harmony" Type="int8" Size="1" /> <!-- 4004 -->
+<Data ElementName="spell_state_always_crit_melee" Type="int8" Size="1" /> <!-- 4005 -->
+<Data ElementName="spell_state_always_crit_dmg_spell" Type="int8" Size="1" /> <!-- 4006 -->
+<Data ElementName="spell_state_always_crit_heal_spell" Type="int8" Size="1" /> <!-- 4007 -->
+<Data ElementName="current_PCA" Type="int32" Size="1" /> <!-- 4008, parental control alarm -->
+<Data ElementName="rain" Type="float" Size="1" /><!-- 4757 -->
+<Data ElementName="rain2" Type="float" Size="1" /><!-- 4761 -->
+<Data ElementName="unknown6" Type="int8" Size="1" /> <!-- 4773 -->
+<Data ElementName="group_members" Substruct="Substruct_GroupMember" Size="5" /> <!-- 4012 -->
+<Data ElementName="leader_index" Type="int32" Size="1" /> <!-- 4697 -->
+<Data ElementName="pet_id" Type="int32" Size="1" /> <!-- 4701 -->
+<Data ElementName="pet_name" Type="char" Size="32" /> <!-- 4705 -->
+<Data ElementName="unknown6" Type="int8" Size="9" /><!-- 4745 -->
+<Data ElementName="pet_health_pct" Type="float" Size="1" /> <!-- 4737 -->
+<Data ElementName="pet_power_pct" Type="float" Size="1" /><!-- 4741 -->
+<Data ElementName="unknown185" Type="int8" Size="1" />
+<Data ElementName="pet_movement" Type="int8" Size="1" />
+<Data ElementName="pet_behavior" Type="int8" Size="1" />
+<Data ElementName="status_points" Type="int32" Size="1" /> <!-- 4765 -->
+<Data ElementName="guild_status" Type="int32" Size="1" /> <!-- 4769 -->
+<Data ElementName="lifetime_guild_status" Type="int32" Size="1" /> <!-- 4769 -->
+<Data ElementName="unknown7" Type="int8" Size="12" /> <!-- 4773 -->
+<Data ElementName="house_zone" Type="char" Size="61" /> <!-- 4776 -->
+<Data ElementName="bind_zone" Type="char" Size="61" /> <!-- 4837 -->
+</Struct>
 <Struct Name="WS_CharacterSheet" ClientVersion="60114" OpcodeName="OP_UpdateCharacterSheetMsg">
 <Data ElementName="character_name" Type="char" Size="40" /> <!-- 40 -->
 <Data ElementName="unknown_1_1_MJ" Type="int16" Size="1" /> <!-- 41 -->
@@ -2138,13 +2454,12 @@ to zero and treated like placeholders." />
 <Data ElementName="assigned_aa" Type="int16" Size="1" />
 <Data ElementName="max_aa" Type="int16" Size="1" />
 <Data ElementName="unassigned_aa" Type="int16" Size="1" />
-<Data ElementName="aa_green_bar" Type="int16" Size="1" />
+<Data ElementName="aa_blue_bar" Type="int16" Size="1" />
 <Data ElementName="adv_xp_to_aa_xp_slider" Type="int16" Size="1" />
 <Data ElementName="adv_xp_to_aa_xp_max" Type="int16" Size="1" />
-<Data ElementName="aa_blue_bar" Type="int16" Size="1" />
+<Data ElementName="unknown_green_bar" Type="int16" Size="1" />
 <Data ElementName="bonus_achievement_xp" Type="int16" Size="1" />
-<Data ElementName="unknown22" Type="int8" Size="2" />
-<Data ElementName="unknown23" Type="int8" Size="2" />
+<Data ElementName="level_events" Type="int32" Size="1" />
 <Data ElementName="items_found" Type="int32" Size="1" />
 <Data ElementName="named_npcs_killed" Type="int32" Size="1" />
 <Data ElementName="quests_completed" Type="int32" Size="1" />
@@ -2797,7 +3112,7 @@ to zero and treated like placeholders." />
 <Data ElementName="language" Type="int8" />
 <Data ElementName="understood" Type="int8" />
 </Struct>
-<Struct Name="WS_PlayFlavor" ClientVersion="547" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqHearPlayFlavorCmd">
+<Struct Name="WS_PlayFlavor" ClientVersion="561" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqHearPlayFlavorCmd">
 <Data ElementName="spawn_id" Type="int32" Size="1" />
 <Data ElementName="unknown1" Type="int32" Size="1" />
 <Data ElementName="mp3" Type="EQ2_16Bit_String" Size="1" />
@@ -2821,7 +3136,7 @@ to zero and treated like placeholders." />
 <Struct Name="WS_PlaySound" ClientVersion="1" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqPlaySoundCmd">
 <Data ElementName="name" Type="EQ2_16Bit_String" Size="1" />
 </Struct>
-<Struct Name="WS_PlaySound" ClientVersion="547" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqPlaySoundCmd">
+<Struct Name="WS_PlaySound" ClientVersion="562" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqPlaySoundCmd">
 <Data ElementName="name" Type="EQ2_16Bit_String" Size="1" />
 <Data ElementName="unknown" Type="float" Size="1" />
 </Struct>
@@ -2882,7 +3197,7 @@ to zero and treated like placeholders." />
 <Data ElementName="result_type" Type="int8" />
 <Data ElementName="combat_chat_method" Type="int32" /> <!-- should probably always be 0 -->
 </Struct>
-<Struct Name="WS_HearDamage_Header" ClientVersion="547" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqHearCombatCmd">
+<Struct Name="WS_HearDamage_Header" ClientVersion="562" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqHearCombatCmd">
 <Data ElementName="packet_type" Type="int8" />
 <Data ElementName="result_type" Type="int8" />
 <Data ElementName="attacker" Type="int32" />
@@ -2923,7 +3238,7 @@ to zero and treated like placeholders." />
 <Data ElementName="spell" Type="int8" />
 <Data ElementName="spell_name" Type="EQ2_16Bit_String" Size="1" />
 </Struct>
-<Struct Name="WS_HearSimpleDamage" ClientVersion="547" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqHearCombatCmd">
+<Struct Name="WS_HearSimpleDamage" ClientVersion="562" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqHearCombatCmd">
 <Data ElementName="header" Substruct="WS_HearDamage_Header" Size="1" />
 <Data ElementName="damage_type" Type="int8" />
 <Data ElementName="damage" Type="int16" />
@@ -2953,7 +3268,7 @@ to zero and treated like placeholders." />
 <Data ElementName="spell" Type="int8" />
 <Data ElementName="spell_name" Type="EQ2_16Bit_String" Size="1" />
 </Struct>
-<Struct Name="WS_HearSiphonSpellDamage" ClientVersion="547" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqHearCombatCmd">
+<Struct Name="WS_HearSiphonSpellDamage" ClientVersion="562" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqHearCombatCmd">
 <Data ElementName="header" Substruct="WS_HearDamage_Header" Size="1" />
 <Data ElementName="siphon_type" Type="int8" />
 <Data ElementName="siphon_subtype" Type="int8" />
@@ -3204,7 +3519,7 @@ to zero and treated like placeholders." />
 <Data ElementName="defender" Type="int32" />
 <Data ElementName="blow_type" Type="int8" />
 </Struct>
-<Struct Name="WS_HearDeath" ClientVersion="547" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqHearDeathCmd">
+<Struct Name="WS_HearDeath" ClientVersion="562" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqHearDeathCmd">
 <Data ElementName="attacker" Type="int32" />
 <Data ElementName="defender" Type="int32" />
 <Data ElementName="blow_type" Type="int16" />
@@ -3348,7 +3663,7 @@ to zero and treated like placeholders." />
       <Data ElementName="unknown5" Type="int8" Size="1" />
       <Data ElementName="status" Type="int8" Size="1" />
 </Struct>
-<Struct Name="SubStruct_UpdateSpellBook" ClientVersion="547">
+<Struct Name="SubStruct_UpdateSpellBook" ClientVersion="562">
       <Data ElementName="spell_id" Type="int32" />
       <Data ElementName="unique_id" Type="int32" />
       <Data ElementName="recast_available" Type="int32" Size="1" />
@@ -3519,7 +3834,7 @@ to zero and treated like placeholders." />
   <Data ElementName="spells" Substruct="SubStruct_UpdateSpellBook" Size="1" />
 </Data>
 </Struct>
-<Struct Name="WS_UpdateSpellBook" ClientVersion="547" OpcodeName="OP_UpdateSpellBookMsg" >
+<Struct Name="WS_UpdateSpellBook" ClientVersion="562" OpcodeName="OP_UpdateSpellBookMsg" >
 <Data ElementName="spell_count" Type="int16" />
 <Data ElementName="packed_size" Type="int32" />
 <Data ElementName="spell_array" Type="Array" ArraySizeVariable="spell_count">
@@ -3595,7 +3910,13 @@ to zero and treated like placeholders." />
 <Data ElementName="partial_packet" Type="int8" Size="1" />
 <Data ElementName="packettype" Type="int32" Size="1" />
 </Struct>
-<Struct Name="WS_ExamineInfoHeader" ClientVersion="547" >
+<Struct Name="WS_ExamineInfoHeader" ClientVersion="561" >
+<Data ElementName="show_name" Type="int8" Size="1" />
+<Data ElementName="simplename" Type="EQ2_8Bit_String" Size="1" />
+<Data ElementName="partial_packet" Type="int8" Size="1" />
+<Data ElementName="packettype" Type="int32" Size="1" />
+</Struct>
+<Struct Name="WS_ExamineInfoHeader" ClientVersion="562" >
 <Data ElementName="show_name" Type="int8" Size="1" />
 <Data ElementName="unknown" Type="int8" Size="1" />
 <Data ElementName="show_popup" Type="int8" Size="1" />
@@ -3782,6 +4103,27 @@ to zero and treated like placeholders." />
 <Data ElementName="name" Type="EQ2_8Bit_String" Size="1" />
 <Data ElementName="description" Type="EQ2_16Bit_String" Size="1" />
 </Struct>
+<Struct Name="WS_SpecialSpellInfo" ClientVersion="561">
+<Data ElementName="id" Type="int32" />
+<Data ElementName="icon" Type="int16" Size="1" />
+<Data ElementName="icontype" Type="int16" Size="1" />
+<Data ElementName="tier" Type="int8" Size="1" />
+<Data ElementName="num_effects" Type="int8" />
+<Data ElementName="effect_array" Type="Array" ArraySizeVariable="num_effects">
+  <Data ElementName="subbulletflag" Type="int8" Size="1" />
+  <Data ElementName="effect" Type="EQ2_16Bit_String" Size="1" />
+  <Data ElementName="percentage" Type="int8" Size="1" />
+</Data>
+<Data ElementName="display_spell_tier" Type="int8" Size="1" />
+<Data ElementName="uses_remaining" Type="int16" Size="1" />
+<Data ElementName="unknown" Type="int8" Size="1" />
+<Data ElementName="damage_remaining" Type="int16" Size="1" />
+<Data ElementName="unknown2" Type="int8" Size="1" />
+<Data ElementName="unknown3" Type="int16" Size="1" />
+<Data ElementName="unknown4" Type="int16" Size="1" />
+<Data ElementName="name" Type="EQ2_8Bit_String" Size="1" />
+<Data ElementName="description" Type="EQ2_16Bit_String" Size="1" />
+</Struct>
 <Struct Name="WS_SpecialSpellInfo" ClientVersion="1008">
 <Data ElementName="id" Type="int32" />
 <Data ElementName="icon" Type="int16" Size="1" />
@@ -4784,6 +5126,15 @@ to zero and treated like placeholders." />
 <Data ElementName="name" Type="EQ2_8Bit_String" Size="1" />
 <Data ElementName="description" Type="EQ2_16Bit_String" Size="1" />
 </Struct>
+<Struct Name="WS_EffectInfo" ClientVersion="561">
+<Data ElementName="id" Type="int32" />
+<Data ElementName="icon" Type="int16" Size="1" />
+<Data ElementName="icontype" Type="int16" Size="1" />
+<Data ElementName="type" Type="int16" Size="1" /> <!-- spell=0, combat_art=1, ability=2 -->
+<Data ElementName="unknown" Type="int8" Size="2" />
+<Data ElementName="name" Type="EQ2_8Bit_String" Size="1" />
+<Data ElementName="description" Type="EQ2_16Bit_String" Size="1" />
+</Struct>
 <Struct Name="WS_PartialSpellInfo" ClientVersion="1">
 <Data ElementName="id" Type="int32" />
 <Data ElementName="icon" Type="int16" Size="1" />
@@ -4857,7 +5208,7 @@ to zero and treated like placeholders." />
 <Data ElementName="name" Type="EQ2_8Bit_String" Size="1" />
 <Data ElementName="description" Type="EQ2_16Bit_String" Size="1" />
 </Struct>
-<Struct Name="WS_SpellInfo" ClientVersion="547">
+<Struct Name="WS_SpellInfo" ClientVersion="561">
 <Data ElementName="id" Type="int32" />
 <Data ElementName="icon" Type="int16" Size="1" />
 <Data ElementName="icon2" Type="int16" Size="1" />
@@ -4880,7 +5231,7 @@ to zero and treated like placeholders." />
 <Data ElementName="health_upkeep" Type="int16" Size="1" OversizedValue="127" OversizedByte="127" />
 <Data ElementName="power_req" Type="int16" Size="1" OversizedValue="127" OversizedByte="127" />
 <Data ElementName="power_upkeep" Type="int16" Size="1" OversizedValue="127" OversizedByte="127" />
-<Data ElementName="req_concentration" Type="int16" Size="1" />
+<Data ElementName="req_concentration" Type="int16" Size="1" OversizedValue="127" OversizedByte="127" />
 <Data ElementName="cast_time" Type="int16" Size="1" OversizedValue="127" OversizedByte="127" />
 <Data ElementName="recovery" Type="int16" Size="1" OversizedValue="127" OversizedByte="127" />
 <Data ElementName="recast" Type="float" Size="1" />
@@ -4904,16 +5255,14 @@ to zero and treated like placeholders." />
 <Data ElementName="range" Type="float" Size="1" />
 <Data ElementName="duration1" Type="int32" Size="1" />
 <Data ElementName="duration2" Type="int32" Size="1" />
-<Data ElementName="unknown9" Type="int8" Size="1" />
-<Data ElementName="duration_flag" Type="int8" Size="1" />
+<Data ElementName="unknown9" Type="int8" Size="1" /> <!-- UpdateCount -->
+<Data ElementName="duration_flag" Type="int8" Size="1" /> <!-- DoesNotExpire -->
 <Data ElementName="target" Type="int8" Size="1" />
 <Data ElementName="can_effect_raid" Type="int8" Size="1" />
 <Data ElementName="affect_only_group_members" Type="int8" Size="1" />
-<Data ElementName="group_spell" Type="int8" Size="1" />
+<Data ElementName="group_spell" Type="int8" Size="1" /> <!-- this is actually Maintained flag -->
 <Data ElementName="resistibility" Type="float" Size="1" />
-<Data ElementName="unknown11" Type="int8" Size="6" />
-<Data ElementName="hit_bonus" Type="float" Size="1" />
-<Data ElementName="unknown12" Type="int8" Size="1" />
+<Data ElementName="unknown1" Type="int8" Size="4" />
 <Data ElementName="name" Type="EQ2_8Bit_String" Size="1" />
 <Data ElementName="description" Type="EQ2_16Bit_String" Size="1" />
 </Struct>
@@ -6259,6 +6608,10 @@ to zero and treated like placeholders." />
 <Data ElementName="info_header" Substruct="WS_ExamineInfoHeader" Size="1" />
 <Data ElementName="spell_info" Substruct="WS_EffectInfo" Size="1" />
 </Struct>
+<Struct Name="WS_ExamineEffectInfo" ClientVersion="561" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqExamineInfoCmd">
+<Data ElementName="info_header" Substruct="WS_ExamineInfoHeader" Size="1" />
+<Data ElementName="spell_info" Substruct="WS_EffectInfo" Size="1" />
+</Struct>
 <Struct Name="WS_ExaminePartialSpellInfo" ClientVersion="1" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqExamineInfoCmd">
 <Data ElementName="info_header" Substruct="WS_ExamineInfoHeader" Size="1" />
 <Data ElementName="spell_info" Substruct="WS_PartialSpellInfo" Size="1" />
@@ -6271,10 +6624,18 @@ to zero and treated like placeholders." />
 <Data ElementName="info_header" Substruct="WS_ExamineInfoHeader" Size="1" />
 <Data ElementName="spell_info" Substruct="WS_SpellInfo" Size="1" />
 </Struct>
+<Struct Name="WS_ExamineSpellInfo" ClientVersion="561" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqExamineInfoCmd">
+<Data ElementName="info_header" Substruct="WS_ExamineInfoHeader" Size="1" />
+<Data ElementName="spell_info" Substruct="WS_SpellInfo" Size="1" />
+</Struct>
 <Struct Name="WS_ExamineSpecialSpellInfo" ClientVersion="1" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqExamineInfoCmd">
 <Data ElementName="info_header" Substruct="WS_ExamineInfoHeader" Size="1" />
 <Data ElementName="spell_info" Substruct="WS_SpecialSpellInfo" Size="1" />
 </Struct>
+<Struct Name="WS_ExamineSpecialSpellInfo" ClientVersion="561" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqExamineInfoCmd">
+<Data ElementName="info_header" Substruct="WS_ExamineInfoHeader" Size="1" />
+<Data ElementName="spell_info" Substruct="WS_SpecialSpellInfo" Size="1" />
+</Struct>
 <Struct Name="WS_ExamineSpellInfo" ClientVersion="860" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqExamineInfoCmd">
 <Data ElementName="info_header" Substruct="WS_ExamineInfoHeader" Size="1" />
 <Data ElementName="spell_info" Substruct="WS_SpellInfo" Size="1" />
@@ -6493,7 +6854,7 @@ to zero and treated like placeholders." />
 <Data ElementName="parameter" Type="int32" />
 <Data ElementName="value" Type="int32" />
 </Struct>
-<Struct Name="WS_ServerControlFlags" ClientVersion="547" OpcodeName="OP_ChangeServerControlFlagMsg" >
+<Struct Name="WS_ServerControlFlags" ClientVersion="562" OpcodeName="OP_ChangeServerControlFlagMsg" >
 <Data ElementName="parameter1" Type="int8" />
 <Data ElementName="parameter2" Type="int8" />
 <Data ElementName="parameter3" Type="int8" />
@@ -6522,7 +6883,7 @@ to zero and treated like placeholders." />
 <Data ElementName="id" Type="int32" />
 <Data ElementName="partial_info" Type="int8" />
 </Struct>
-<Struct Name="WS_ExamineSpellEffectRequest" ClientVersion="547" >
+<Struct Name="WS_ExamineSpellEffectRequest" ClientVersion="562" >
 <Data ElementName="type" Type="int8" Size="1" />
 <Data ElementName="id" Type="int32" />
 <Data ElementName="unknown5" Type="int16" />
@@ -6594,7 +6955,7 @@ to zero and treated like placeholders." />
 <Data ElementName="unknown5" Type="int8" />
 <Data ElementName="show_popup" Type="int8" />
 </Struct>
-<Struct Name="WS_ExamineInfoItemLinkRequest" ClientVersion="547" >
+<Struct Name="WS_ExamineInfoItemLinkRequest" ClientVersion="562" >
 <Data ElementName="type" Type="int8" Size="1" />
 <Data ElementName="unknown" Type="int32" Size="3" />
 <Data ElementName="unique_id" Type="int32" />
@@ -6732,7 +7093,7 @@ to zero and treated like placeholders." />
 <Data ElementName="cast_time" Type="float" />
 <Data ElementName="spell_level" Type="int8" />
 </Struct>
-<Struct Name="WS_HearCastSpell" ClientVersion="547" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqHearSpellCastCmd">
+<Struct Name="WS_HearCastSpell" ClientVersion="562" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqHearSpellCastCmd">
 <Data ElementName="spawn_id" Type="int32" />
 <Data ElementName="num_targets" Type="int16" />
 <Data ElementName="target_array" Type="Array" ArraySizeVariable="num_targets">
@@ -7154,7 +7515,21 @@ to zero and treated like placeholders." />
 <Data ElementName="channel_name" Type="EQ2_16Bit_String" />
 <Data ElementName="show_bubble" Type="int8" Size="1" />
 </Struct>
-<Struct Name="WS_HearChat" ClientVersion="547" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqHearChatCmd" >
+<Struct Name="WS_HearChat" ClientVersion="561" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqHearChatCmd" >
+<Data ElementName="unknown" Type="int16" />
+<Data ElementName="from_spawn_id" Type="int32" />
+<Data ElementName="to_spawn_id" Type="int32" />
+<Data ElementName="from" Type="EQ2_16Bit_String" />
+<Data ElementName="to" Type="EQ2_16Bit_String" />
+<Data ElementName="channel" Type="int8" />
+<Data ElementName="language" Type="int8" />
+<Data ElementName="message" Type="EQ2_16Bit_String" />
+<Data ElementName="channel_name" Type="EQ2_16Bit_String" />
+<Data ElementName="show_bubble" Type="int8" Size="1" />
+<Data ElementName="understood" Type="int8" Size="1" />
+<Data ElementName="unknown4" Type="int8" Size="1" />
+</Struct>
+<Struct Name="WS_HearChat" ClientVersion="562" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqHearChatCmd" >
 <Data ElementName="unknown" Type="int16" />
 <Data ElementName="from_spawn_id" Type="int32" />
 <Data ElementName="to_spawn_id" Type="int32" />
@@ -7190,7 +7565,7 @@ to zero and treated like placeholders." />
 <Struct Name="WS_StoppedLooting" ClientVersion="1" OpcodeName="OP_StoppedLootingMsg" >
 <Data ElementName="spawn_id" Type="int32" />
 </Struct>
-<Struct Name="WS_CloseWindow" ClientVersion="547" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqCloseWindowCmd" >
+<Struct Name="WS_CloseWindow" ClientVersion="562" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqCloseWindowCmd" >
 <Data ElementName="window_id" Type="int16" />
 <Data ElementName="index" Type="int8" />
 </Struct>
@@ -7223,7 +7598,7 @@ to zero and treated like placeholders." />
 	<Data ElementName="lotto_timeout" Type="int32" />
 	<Data ElementName="spawn_id" Type="int32"/>
 </Struct>
-<Struct Name="WS_UpdateLoot" ClientVersion="547" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqUpdateLootCmd" >
+<Struct Name="WS_UpdateLoot" ClientVersion="562" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqUpdateLootCmd" >
 <Data ElementName="loot_count" Type="int16" />
 <Data ElementName="display" Type="int8" />
 <Data ElementName="loot_type" Type="int32" />
@@ -7343,7 +7718,7 @@ to zero and treated like placeholders." />
 <Data ElementName="player_name" Type="EQ2_16Bit_String" Size="1" />
 <Data ElementName="used_quests" Type="int16" Size="1" />
 </Struct>
-<Struct Name="WS_QuestJournalUpdate" ClientVersion="547" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqQuestJournalUpdateCmd" >
+<Struct Name="WS_QuestJournalUpdate" ClientVersion="562" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqQuestJournalUpdateCmd" >
 <Data ElementName="num_quests" Type="int16" />
 <Data ElementName="quests_array" Type="Array" ArraySizeVariable="num_quests">
 	<Data ElementName="active" Type="int8" Size="1" />
@@ -7489,7 +7864,7 @@ to zero and treated like placeholders." />
 <Data ElementName="decline_command" Type="EQ2_8Bit_String" Size="1" />
 <Data ElementName="description" Type="EQ2_16Bit_String" Size="1" />
 </Struct>
-<Struct Name="WS_OfferQuest" ClientVersion="547" OpcodeName="OP_OfferQuestMsg" >
+<Struct Name="WS_OfferQuest" ClientVersion="562" OpcodeName="OP_OfferQuestMsg" >
 <Data ElementName="unknown0" Type="int8" Size="1" />
 <Data ElementName="reward" Type="EQ2_16Bit_String" Size="1" />
 <Data ElementName="title" Type="EQ2_16Bit_String" Size="1" />
@@ -7675,7 +8050,7 @@ to zero and treated like placeholders." />
 	<Data ElementName="waypoint_y" Type="float" Size="1" />
 	<Data ElementName="waypoint_z" Type="float" Size="1" />
 </Struct>
-<Struct Name="WS_GlowPath" ClientVersion="547" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqHelpPathCmd" >
+<Struct Name="WS_GlowPath" ClientVersion="562" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqHelpPathCmd" >
 	<Data ElementName="num_points" Type="int16" />
 	<Data ElementName="points_array" Type="Array" ArraySizeVariable="num_points">
 		<Data ElementName="x" Type="float" Size="1" />
@@ -7697,7 +8072,7 @@ to zero and treated like placeholders." />
 	</Data>
 	<Data ElementName="unknown" Type="int32" />
 </Struct>
-<Struct Name="WS_WaypointUpdate" ClientVersion="547" OpcodeName="OP_WaypointUpdateMsg">
+<Struct Name="WS_WaypointUpdate" ClientVersion="562" OpcodeName="OP_WaypointUpdateMsg">
 	<Data ElementName="num_updates" Type="int32" />
 	<Data ElementName="update_array" Type="Array" ArraySizeVariable="num_updates">
 		<Data ElementName="waypoint_name" Type="EQ2_16Bit_string" />
@@ -7710,7 +8085,7 @@ to zero and treated like placeholders." />
 <Struct Name="WS_WaypointSelect" ClientVersion="1" OpcodeName="OP_WaypointSelectMsg">
 	<Data ElementName="selection" Type="int32" />
 </Struct>
-<Struct Name="WS_WaypointSelect" ClientVersion="547" OpcodeName="OP_WaypointSelectMsg">
+<Struct Name="WS_WaypointSelect" ClientVersion="562" OpcodeName="OP_WaypointSelectMsg">
 	<Data ElementName="num_selections" Type="int32" />
 	<Data ElementName="selection_array" Type="Array" ArraySizeVariable="num_selections">
 		<Data ElementName="waypoint_name" Type="EQ2_16Bit_string" />
@@ -7818,7 +8193,7 @@ to zero and treated like placeholders." />
 <Data ElementName="reward_data" Substruct="Substruct_JournalRewardData" IfVariableNotSet="complete" />
 <Data ElementName="unknown6" Type="int8" Size="1" />
 </Struct>
-<Struct Name="WS_QuestJournalReply" ClientVersion="547" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqQuestJournalReplyCmd" >
+<Struct Name="WS_QuestJournalReply" ClientVersion="562" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqQuestJournalReplyCmd" >
 <Data ElementName="quest_id" Type="int32" Size="1" />
 <Data ElementName="player_crc" Type="int32" Size="1" />
 <Data ElementName="name" Type="EQ2_16Bit_String" Size="1" />
@@ -9061,7 +9436,7 @@ to zero and treated like placeholders." />
 <Data ElementName="key1" Type="int32" Size="1" />
 <Data ElementName="key2" Type="int32" Size="1" />
 </Struct>
-<Struct Name="WS_DialogOpen" ClientVersion="547" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqDialogOpenCmd" >
+<Struct Name="WS_DialogOpen" ClientVersion="562" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqDialogOpenCmd" >
 <Data ElementName="conversation_id" Type="int32" Size="1" />
 <Data ElementName="title" Type="EQ2_16Bit_String" Size="1" />
 <Data ElementName="text" Type="EQ2_16Bit_String" Size="1" />
@@ -9116,7 +9491,7 @@ to zero and treated like placeholders." />
 </Data>
 <Data ElementName="unknown3" Type="int8" />
 </Struct>
-<Struct Name="WS_FactionUpdate" ClientVersion="547" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqFactionUpdateCmd" >
+<Struct Name="WS_FactionUpdate" ClientVersion="562" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqFactionUpdateCmd" >
 <Data ElementName="num_factions" Type="int16" />
 <Data ElementName="response_array" Type="Array" ArraySizeVariable="num_factions">
 	<Data ElementName="faction_id" Type="int32" />
@@ -9415,7 +9790,7 @@ to zero and treated like placeholders." />
 <Data ElementName="type" Type="int8" /> <!-- 0==buy, 1==sell, 16==repair, 128==goblin game -->
 <Data ElementName="unknown" Type="int8" Size="2" />
 </Struct>
-<Struct Name="WS_UpdateMerchant" ClientVersion="547" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqUpdateMerchantCmd">
+<Struct Name="WS_UpdateMerchant" ClientVersion="562" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqUpdateMerchantCmd">
 <Data ElementName="spawn_id" Type="int32" />
 <Data ElementName="num_items" Type="int16" />
 <Data ElementName="item_array" Type="Array" ArraySizeVariable="num_items">
@@ -9781,11 +10156,11 @@ to zero and treated like placeholders." />
 <Data ElementName="spawn_id" Type="int32" />
 <Data ElementName="state" Type="int16" />
 </Struct>
-<Struct Name="WS_StateCmd" ClientVersion="547" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqStateCmd">
+<Struct Name="WS_StateCmd" ClientVersion="562" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqStateCmd">
 <Data ElementName="spawn_id" Type="int32" />
 <Data ElementName="state" Type="int32" />
 </Struct>
-<Struct Name="WS_EnterCombat" ClientVersion="547" OpcodeName="OP_AttackAllowed">
+<Struct Name="WS_EnterCombat" ClientVersion="562" OpcodeName="OP_AttackAllowed">
 <Data ElementName="response" Type="int8" />
 </Struct>
 <Struct Name="WS_StartBroker" ClientVersion="1" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqStartBrokerCmd">
@@ -9866,6 +10241,34 @@ to zero and treated like placeholders." />
 <Data ElementName="per_page" Type="int32" Size="1" />
 <Data ElementName="page" Type="int32" Size="1" />
 </Struct>
+<Struct Name="WS_BrokerItems" ClientVersion="561" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqConsignmentItemsCmd" >  
+    <Data ElementName="unknown15z" Type="int8" Size="2" />  
+<Data ElementName="num_items" Type="int32" Size="1"/>
+<Data ElementName="item_array" Type="Array" ArraySizeVariable="num_items">
+    <Data ElementName="unknown" Type="int32" Size="1" />
+    <Data ElementName="unknowny" Type="int16" Size="1" />
+    <Data ElementName="item_id" Type="int64" Size="1" />
+    <Data ElementName="quantity" Type="int32" Size="1" />
+    <Data ElementName="unknown15x" Type="int8" Size="4" />
+    <Data ElementName="string_two" Type="EQ2_16Bit_String" Size="1" />
+    <Data ElementName="string_x" Type="EQ2_16Bit_String" Size="1" />
+    <Data ElementName="unknown15y" Type="int8" Size="6" />
+	<Data ElementName="stack_size" Type="int16" Size="1" />
+	<Data ElementName="unknown3" Type="int8" Size="14" />
+	<Data ElementName="icon" Type="int16" Size="1" />
+    <Data ElementName="item_name" Type="EQ2_16Bit_String" Size="1" />
+    <Data ElementName="unknown15x" Type="int8" Size="2" />
+	<Data ElementName="sell_price" Type="int64" Size="1" />
+    <Data ElementName="unknown15spacey" Type="int8" Size="28" />
+    <Data ElementName="seller_name" Type="EQ2_16Bit_String" Size="1" />
+    <Data ElementName="icon" Type="int16" Size="1" />
+    <Data ElementName="unknown" Type="int8" Size="10" />
+</Data>
+<Data ElementName="unknown" Type="int32" Size="1" />
+<Data ElementName="num_pages" Type="int32" Size="1" />
+<Data ElementName="per_page" Type="int32" Size="1" />
+<Data ElementName="page" Type="int32" Size="1" />
+</Struct>
 <Struct Name="WS_BrokerItems" ClientVersion="972" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqConsignmentItemsCmd" >
 <Data ElementName="unknown" Type="int8" />
 <Data ElementName="num_items" Type="int32" />
@@ -10341,7 +10744,7 @@ to zero and treated like placeholders." />
 <Data ElementName="exp_current" Type="int64" Size="1" />
 <Data ElementName="exp_to_next_level" Type="int64" Size="1" />
 </Struct>
-<Struct Name="WS_GuildUpdate" ClientVersion="547" OpcodeName="OP_GuildUpdateMsg">
+<Struct Name="WS_GuildUpdate" ClientVersion="562" OpcodeName="OP_GuildUpdateMsg">
 <Data ElementName="guild_name" Type="EQ2_16Bit_String" Size="1" />
 <Data ElementName="guild_motd" Type="EQ2_16Bit_String" Size="1" />
 <Data ElementName="guild_id" Type="int32" Size="1" />
@@ -15771,7 +16174,7 @@ to zero and treated like placeholders." />
 	<Data ElementName="claimed_on_this_char" Type="int8" Size="1" />		
 </Data>
 </Struct>
-<Struct Name="WS_PromoFlagsDetails" ClientVersion="547" OpcodeName="OP_PromoFlagsDetailsMsg">
+<Struct Name="WS_PromoFlagsDetails" ClientVersion="562" OpcodeName="OP_PromoFlagsDetailsMsg">
 <Data ElementName="num_claim_items" Type="int32" Size="1" />
 <Data ElementName="claim_items_array" Type="Array" ArraySizeVariable="num_claim_items">
 	<Data ElementName="id" Type="int32" Size="1" />
@@ -16529,7 +16932,7 @@ to zero and treated like placeholders." />
 <Data ElementName="spawn_id" Type="int32" Size="1" />
 <Data ElementName="unknown" Type="int8" Size="1" />
 </Struct>
-<Struct Name="WS_UpdateCreateItem" ClientVersion="547" OpcodeName="OP_UpdateItemCreationProcessUIMsg">
+<Struct Name="WS_UpdateCreateItem" ClientVersion="562" OpcodeName="OP_UpdateItemCreationProcessUIMsg">
 <Data ElementName="effect" Type="int8" Size="1" />
 <Data ElementName="total_durability" Type="int32" Size="1" />
 <Data ElementName="total_progress" Type="int32" Size="1" />
@@ -16665,7 +17068,7 @@ to zero and treated like placeholders." />
 <Struct Name="WS_ShowRecipeBook" ClientVersion="546" OpcodeName="OP_ShowRecipeBookMsg">
 <Data ElementName="device" Type="char" Size="42" />
 </Struct>
-<Struct Name="WS_ShowRecipeBook" ClientVersion="547" OpcodeName="OP_ShowRecipeBookMsg">
+<Struct Name="WS_ShowRecipeBook" ClientVersion="562" OpcodeName="OP_ShowRecipeBookMsg">
 <Data ElementName="device" Type="char" Size="42" />
 <Data ElementName="unknown1" Type="int8" Size="1" />
 <Data ElementName="unknown2" Type="int32" />
@@ -16903,7 +17306,7 @@ to zero and treated like placeholders." />
   <Data ElementName="channel_name" Type="EQ2_16Bit_String" />
 </Data>
 </Struct>
-<Struct Name="WS_AvailWorldChannels" ClientVersion="547" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqAvailWorldChannelsCmd">
+<Struct Name="WS_AvailWorldChannels" ClientVersion="562" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqAvailWorldChannelsCmd">
 <Data ElementName="num_channels" Type="int32" Size="1" />
 <Data ElementName="channel_array" Type="Array" ArraySizeVariable="num_channels">
   <Data ElementName="channel_name" Type="EQ2_16Bit_String" />
@@ -17987,7 +18390,7 @@ to zero and treated like placeholders." />
 <Data ElementName="text_required" Type="int8" Size="1" />
 <Data ElementName="max_length" Type="int32" Size="1" />
 </Struct>
-<Struct Name="WS_ChoiceWindow" ClientVersion="547" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqChoiceWinCmd">
+<Struct Name="WS_ChoiceWindow" ClientVersion="562" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqChoiceWinCmd">
 <Data ElementName="text" Type="EQ2_16Bit_String" />
 <Data ElementName="accept_text" Type="EQ2_16Bit_String" />
 <Data ElementName="accept_command" Type="EQ2_16Bit_String" />
@@ -18017,7 +18420,7 @@ to zero and treated like placeholders." />
 <Data ElementName="unknown1" Type="int8" Size="2"/>
 <Data ElementName="enable_buy" Type="int8" />
 </Struct>
-<Struct Name="WS_PlayerHousePurchase" ClientVersion="547" OpcodeName="OP_PlayerHousePurchaseScreenMsg">
+<Struct Name="WS_PlayerHousePurchase" ClientVersion="562" OpcodeName="OP_PlayerHousePurchaseScreenMsg">
 <Data ElementName="house_name" Type="EQ2_16Bit_String" />
 <Data ElementName="house_id" Type="int64" />
 <Data ElementName="spawn_id" Type="int32" />
@@ -18032,7 +18435,7 @@ to zero and treated like placeholders." />
 <Struct Name="WS_BuyHouse" ClientVersion="1" OpcodeName="OP_BuyPlayerHouseMsg">
 <Data ElementName="house_id" Type="int32" />
 </Struct>
-<Struct Name="WS_BuyHouse" ClientVersion="547" OpcodeName="OP_BuyPlayerHouseMsg">
+<Struct Name="WS_BuyHouse" ClientVersion="562" OpcodeName="OP_BuyPlayerHouseMsg">
 <Data ElementName="house_id" Type="int64" />
 </Struct>
 <Struct Name="WS_PlayerHouseBaseScreen" ClientVersion="1" OpcodeName="OP_PlayerHouseBaseScreenMsg">
@@ -18087,7 +18490,7 @@ to zero and treated like placeholders." />
 <Data ElementName="get_portal_flag" Type="int8" />
 <Data ElementName="unknown6" Type="int8" />
 </Struct>
-<Struct Name="WS_PlayerHouseBaseScreen" ClientVersion="547" OpcodeName="OP_PlayerHouseBaseScreenMsg">
+<Struct Name="WS_PlayerHouseBaseScreen" ClientVersion="562" OpcodeName="OP_PlayerHouseBaseScreenMsg">
 <Data ElementName="house_id" Type="int64" />
 <Data ElementName="spawn_id" Type="int32" /><!-- spawn id of the door -->
 <Data ElementName="house_name" Type="EQ2_16Bit_String" />
@@ -18391,7 +18794,7 @@ to zero and treated like placeholders." />
 <Struct Name="WS_EnterHouse" ClientVersion="1" OpcodeName="OP_EnterHouseMsg">
 <Data ElementName="house_id" Type="int32" />
 </Struct>
-<Struct Name="WS_EnterHouse" ClientVersion="547" OpcodeName="OP_EnterHouseMsg">
+<Struct Name="WS_EnterHouse" ClientVersion="562" OpcodeName="OP_EnterHouseMsg">
 <Data ElementName="house_id" Type="int64" />
 <Data ElementName="spawn_id" Type="int32" />
 </Struct>
@@ -18399,7 +18802,7 @@ to zero and treated like placeholders." />
 <Data ElementName="house_id" Type="int32" />
 <Data ElementName="unknown" Type="int8" Size="3" />
 </Struct>
-<Struct Name="WS_PayUpkeep" ClientVersion="547" OpcodeName="OP_PayHouseUpkeepMsg">
+<Struct Name="WS_PayUpkeep" ClientVersion="562" OpcodeName="OP_PayHouseUpkeepMsg">
 <Data ElementName="house_id" Type="int64" />
 <Data ElementName="unknown" Type="int8" Size="3" />
 </Struct>
@@ -18944,7 +19347,7 @@ to zero and treated like placeholders." />
   <Data ElementName="unknown2" Type="int32" />
   <Data ElementName="unknown3" Type="int32" />
 </Struct>
-<Struct Name="WS_UpdateHouseAccessDataMsg" ClientVersion="547" OpcodeName="OP_UpdateHouseAccessDataMsg">
+<Struct Name="WS_UpdateHouseAccessDataMsg" ClientVersion="562" OpcodeName="OP_UpdateHouseAccessDataMsg">
   <Data ElementName="success" Type="int32"/>
   <Data ElementName="house_id" Type="int64" />
   <Data ElementName="unknown2" Type="int32" />
@@ -19152,6 +19555,12 @@ to zero and treated like placeholders." />
 <Data ElementName="spell_icon_backdrop" Type="int16" />
 <Data ElementName="spell_triggercount" Type="int8" />
 </Struct>
+<Struct Name="Substruct_TargetSpellEffects" ClientVersion="561">
+<Data ElementName="spell_id" Type="int32" />
+<Data ElementName="spell_icon" Type="int16" />
+<Data ElementName="spell_icon_backdrop" Type="int16" />
+<Data ElementName="spell_triggercount" Type="int8" />
+</Struct>
 <Struct Name="Substruct_TargetSpellEffects" ClientVersion="1188">
 <Data ElementName="spell_id" Type="int32" />
 <Data ElementName="spell_icon" Type="int16" />
@@ -19555,7 +19964,7 @@ to zero and treated like placeholders." />
 <Struct Name="WS_PerformCameraShakeMsg" ClientVersion="1" OpcodeName="OP_PerformCameraShakeMsg">
 	<Data ElementName="intensity" Type="float" /> <!-- client supported range is 0.01 - 1.0 -->
 </Struct>
-<Struct Name="WS_PerformCameraShakeMsg" ClientVersion="547" OpcodeName="OP_PerformCameraShakeMsg">
+<Struct Name="WS_PerformCameraShakeMsg" ClientVersion="562" OpcodeName="OP_PerformCameraShakeMsg">
 	<Data ElementName="intensity" Type="float" /> <!-- client supported range is 0.01 - 1.0 -->
 	<Data ElementName="direction" Type="int8" /> <!-- 0 = up/down camera shake, 1 = all around shake of camera -->
 </Struct>