Browse Source

Merging LethalEncounter's support of classic (version 283) and dof (version 546)

Fix #145
Image 3 years ago
parent
commit
b698e847e1
47 changed files with 6812 additions and 16929 deletions
  1. 805 0
      DB/updates/opcodes_for_283_and_546.sql
  2. 37 24
      EQ2/source/LoginServer/LWorld.cpp
  3. 137 69
      EQ2/source/LoginServer/LoginDatabase.cpp
  4. 2 2
      EQ2/source/LoginServer/LoginDatabase.h
  5. 6 9
      EQ2/source/LoginServer/PacketHeaders.cpp
  6. 34 14
      EQ2/source/LoginServer/client.cpp
  7. 1 1
      EQ2/source/LoginServer/client.h
  8. 9 6
      EQ2/source/LoginServer/login_structs.h
  9. 27 20
      EQ2/source/WorldServer/ClientPacketFunctions.cpp
  10. 872 41
      EQ2/source/WorldServer/Commands/Commands.cpp
  11. 11 0
      EQ2/source/WorldServer/Commands/Commands.h
  12. 278 128
      EQ2/source/WorldServer/Items/Items.cpp
  13. 16 5
      EQ2/source/WorldServer/Items/Items.h
  14. 302 0
      EQ2/source/WorldServer/LuaFunctions.cpp
  15. 9 0
      EQ2/source/WorldServer/LuaFunctions.h
  16. 15 2
      EQ2/source/WorldServer/LuaInterface.cpp
  17. 1 1
      EQ2/source/WorldServer/LuaInterface.h
  18. 421 216
      EQ2/source/WorldServer/Player.cpp
  19. 7 2
      EQ2/source/WorldServer/Player.h
  20. 1 0
      EQ2/source/WorldServer/Quests.cpp
  21. 12 5
      EQ2/source/WorldServer/Skills.cpp
  22. 1 0
      EQ2/source/WorldServer/Skills.h
  23. 438 84
      EQ2/source/WorldServer/Spawn.cpp
  24. 55 2
      EQ2/source/WorldServer/Spawn.h
  25. 276 247
      EQ2/source/WorldServer/Spells.cpp
  26. 6 3
      EQ2/source/WorldServer/WorldDatabase.cpp
  27. 19 17
      EQ2/source/WorldServer/classes.cpp
  28. 335 135
      EQ2/source/WorldServer/client.cpp
  29. 7 6
      EQ2/source/WorldServer/client.h
  30. 161 60
      EQ2/source/WorldServer/zoneserver.cpp
  31. 1 1
      EQ2/source/WorldServer/zoneserver.h
  32. 19 3
      EQ2/source/common/ConfigReader.cpp
  33. 62 0
      EQ2/source/common/EQ2_Common_Structs.h
  34. 26 11
      EQ2/source/common/EQPacket.cpp
  35. 1 0
      EQ2/source/common/EQPacket.h
  36. 106 19
      EQ2/source/common/EQStream.cpp
  37. 16 0
      EQ2/source/common/EQStream.h
  38. 28 11
      EQ2/source/common/MiscFunctions.cpp
  39. 5 1
      EQ2/source/common/MiscFunctions.h
  40. 564 488
      EQ2/source/common/PacketStruct.cpp
  41. 167 150
      EQ2/source/common/PacketStruct.h
  42. 2 1
      EQ2/source/common/emu_oplist.h
  43. 84 48
      server/CommonStructs.xml
  44. 302 6
      server/ItemStructs.xml
  45. 113 96
      server/LoginStructs.xml
  46. 365 6
      server/SpawnStructs.xml
  47. 650 14989
      server/WorldStructs.xml

+ 805 - 0
DB/updates/opcodes_for_283_and_546.sql

@@ -0,0 +1,805 @@
+update opcodes set version_range1=547, version_range2=838 where version_range1=0 and version_range2=0;
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_LoginRequestMsg', 0);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_LoginByNumRequestMsg', 1);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_WSLoginRequestMsg', 2);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_ESLoginRequestMsg', 3);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_LoginReplyMsg', 4);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_WorldListMsg', 8);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_WorldStatusChangeMsg', 6);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_AllWSDescRequestMsg', 7);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_WSStatusReplyMsg', 5);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_AllCharactersDescRequestMsg', 9);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_AllCharactersDescReplyMsg', 10);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_CreateCharacterRequestMsg', 11);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_CreateCharacterReplyMsg', 12);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_WSCreateCharacterRequestMsg', 13);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_WSCreateCharacterReplyMsg', 14);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_DeleteCharacterRequestMsg', 15);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_DeleteCharacterReplyMsg', 16);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_PlayCharacterRequestMsg', 17);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_PlayCharacterReplyMsg', 18);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_ServerPlayCharacterRequestMsg', 19);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_ServerPlayCharacterReplyMsg', 20);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_ESInitMsg', 21);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_ESReadyForClientsMsg', 22);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_CreateZoneInstanceMsg', 23);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_ZoneInstanceCreateReplyMsg', 24);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_ZoneInstanceDestroyedMsg', 25);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_ExpectClientAsCharacterRequestMsg', 26);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_ExpectClientAsCharacterReplyMsg', 27);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_ZoneInfoMsg', 28);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_DoneLoadingZoneResourcesMsg', 29);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_DoneSendingInitialEntitiesMsg', 30);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_DoneLoadingEntityResourcesMsg', 31);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_PredictionUpdateMsg', 32);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_RemoteCmdMsg', 34);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_SetRemoteCmdsMsg', 33);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_GameWorldTimeMsg', 35);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_MOTDMsg', 36);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_ZoneMOTDMsg', 37);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_AvatarCreatedMsg', 38);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_AvatarDestroyedMsg', 39);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_RequestCampMsg', 40);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_CampStartedMsg', 41);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_CampAbortedMsg', 42);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_WhoQueryRequestMsg', 43);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_WhoQueryReplyMsg', 44);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_MonitorReplyMsg', 45);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_MonitorCharacterListMsg', 46);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_MonitorCharacterListRequestMsg', 47);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_ClientCmdMsg', 48);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_DispatchClientCmdMsg', 49);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_DispatchESMsg', 50);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_UpdateTargetMsg', 51);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_UpdateOpportunityMsg', 60);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_UpdateTargetLocMsg', 52);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_UpdateCharacterSheetMsg', 53);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_UpdateSpellBookMsg', 54);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_UpdateInventoryMsg', 56);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_UpdateRecipeBookMsg', 57);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_UpdateSkillBookMsg', 58);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_UpdateSkillsMsg', 59);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_ChangeZoneMsg', 62);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_ClientTeleportRequestMsg', 63);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_TeleportWithinZoneMsg', 64);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_TeleportWithinZoneNoReloadMsg', 65);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_MigrateClientToZoneRequestMsg', 66);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_MigrateClientToZoneReplyMsg', 67);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_ReadyToZoneMsg', 68);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_AddClientToGroupMsg', 69);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_AddGroupToGroupMsg', 70);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_RemoveClientFromGroupMsg', 71);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_RemoveGroupFromGroupMsg', 72);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_MakeGroupLeaderMsg', 73);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_GroupCreatedMsg', 74);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_GroupDestroyedMsg', 75);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_GroupMemberAddedMsg', 76);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_GroupMemberRemovedMsg', 77);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_GroupRemovedFromGroupMsg', 78);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_GroupLeaderChangedMsg', 79);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_GroupSettingsChangedMsg', 80);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_SendLatestRequestMsg', 81);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_ClearDataMsg', 82);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_SetSocialMsg', 83);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_ESStatusMsg', 84);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_ESZoneInstanceStatusMsg', 85);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_ZonesStatusRequestMsg', 86);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_ZonesStatusMsg', 87);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_ESWeatherRequestMsg', 88);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_ESWeatherRequestEndMsg', 89);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_WSWeatherUpdateMsg', 90);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_DialogSelectMsg', 91);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_DialogCloseMsg', 92);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_RemoveSpellEffectMsg', 93);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_RemoveConcentrationMsg', 94);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_QuestJournalOpenMsg', 95);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_QuestJournalInspectMsg', 96);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_QuestJournalSetVisibleMsg', 97);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_QuestJournalWaypointMsg', 98);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_CreateGuildRequestMsg', 99);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_CreateGuildReplyMsg', 100);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_GuildsayMsg', 101);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_GuildKickMsg', 102);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_GuildUpdateMsg', 103);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_FellowshipExpMsg', 104);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_ConsignmentUpdateMsg', 105);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_ConsignItemRequestMsg', 106);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_ConsignItemResponseMsg', 107);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_PurchaseConsignmentRequestMsg', 108);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_PurchaseConsignmentResponseMsg', 109);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_ProcessScriptMsg', 110);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_ProcessWorkspaceMsg', 111);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_HouseDeletedRemotelyMsg', 112);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_UpdateHouseDataMsg', 113);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_UpdateHouseAccessDataMsg', 114);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_PlayerHouseBaseScreenMsg', 115);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_PlayerHousePurchaseScreenMsg', 116);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_PlayerHouseAccessUpdateMsg', 117);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_PlayerHouseDisplayStatusMsg', 118);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_PlayerHouseCloseUIMsg', 119);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_BuyPlayerHouseMsg', 120);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_BuyPlayerHouseTintMsg', 121);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_CollectAllHouseItemsMsg', 122);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_RelinquishHouseMsg', 123);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EnterHouseMsg', 124);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_ExitHouseMsg', 125);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_ExamineConsignmentRequestMsg', 139);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EnterMoveObjectModeMsg', 130);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_PositionMoveableObject', 131);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_ShaderCustomizationMsg', 132);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_ReplaceableSubMeshesMsg', 133);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_ExamineConsignmentResponseMsg', 140);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_HouseDefaultAccessSetMsg', 126);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_HouseAccessSetMsg', 127);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_HouseAccessRemoveMsg', 128);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_PayHouseUpkeepMsg', 129);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_TintWidgetsMsg', 138);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_UISettingsResponseMsg', 141);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_KeymapLoadMsg', 142);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_KeymapNoneMsg', 143);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_KeymapDataMsg', 144);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_KeymapSaveMsg', 145);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_DispatchSpellCmdMsg', 146);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_HouseCustomizationScreenMsg', 134);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_CustomizationPurchaseRequestMsg', 135);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_CustomizationSetRequestMsg', 136);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_CustomizationReplyMsg', 137);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EntityVerbsRequestMsg', 148);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EntityVerbsReplyMsg', 149);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EntityVerbsVerbMsg', 150);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_ChatRelationshipUpdateMsg', 151);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_ChatFriendLoginStatusMsg', 152);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_ChatCreateChannelMsg', 228);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_ChatJoinChannelMsg', 229);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_ChatWhoChannelMsg', 230);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_ChatLeaveChannelMsg', 231);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_ChatTellChannelMsg', 232);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_ChatTellUserMsg', 233);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_ChatToggleFriendMsg', 234);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_ChatToggleIgnoreMsg', 235);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_ChatSendFriendsMsg', 236);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_ChatSendIgnoresMsg', 237);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_ChatFiltersMsg', 238);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_LootItemsRequestMsg', 153);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_StoppedLootingMsg', 154);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_SitMsg', 155);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_StandMsg', 156);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_SatMsg', 157);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_StoodMsg', 158);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_ExamineItemRequestMsg', 159);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_DefaultGroupOptionsRequestMsg', 160);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_DefaultGroupOptionsMsg', 161);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_GroupOptionsMsg', 162);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_DisplayGroupOptionsScreenMsg', 163);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_DisplayInnVisitScreenMsg', 164);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_DumpSchedulerMsg', 165);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_LSRequestPlayerDescMsg', 166);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_LSCheckAcctLockMsg', 167);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_WSAcctLockStatusMsg', 168);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_RequestHelpRepathMsg', 169);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_UpdateMotdMsg', 171);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_RequestTargetLocMsg', 170);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_PerformPlayerKnockbackMsg', 172);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_PerformCameraShakeMsg', 173);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_PopulateSkillMapsMsg', 174);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_CancelledFeignMsg', 175);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_SignalMsg', 176);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_ShowCreateFromRecipeUIMsg', 177);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_CancelCreateFromRecipeMsg', 178);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_BeginItemCreationMsg', 179);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_StopItemCreationMsg', 180);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_ShowItemCreationProcessUIMsg', 181);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_UpdateItemCreationProcessUIMsg', 182);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_DisplayTSEventReactionMsg', 183);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_ShowRecipeBookMsg', 184);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_KnowledgebaseRequestMsg', 185);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_KnowledgebaseResponseMsg', 186);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_CSTicketHeaderRequestMsg', 187);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_CSTicketInfoMsg', 188);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_CSTicketCommentRequestMsg', 189);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_CSTicketCommentResponseMsg', 190);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_CSTicketCreateMsg', 191);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_CSTicketAddCommentMsg', 192);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_CSTicketDeleteMsg', 193);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_CSTicketChangeNotificationMsg', 194);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_WorldDataUpdateMsg', 195);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_KnownLanguagesMsg', 196);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_LsRequestClientCrashLogMsg', 197);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_LsClientBaselogReplyMsg', 198);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_LsClientCrashlogReplyMsg', 199);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_LsClientAlertlogReplyMsg', 200);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_LsClientVerifylogReplyMsg', 201);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_ClientTeleportToLocationMsg', 202);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_UpdateClientPredFlagsMsg', 203);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_ChangeServerControlFlagMsg', 204);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_CSToolsRequestMsg', 205);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_CSToolsResponseMsg', 206);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_AddSocialStructureStandingMsg', 207);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_CreateBoatTransportsMsg', 208);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_PositionBoatTransportMsg', 209);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_MigrateBoatTransportMsg', 210);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_MigrateBoatTransportReplyMsg', 211);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_DisplayDebugNLLPointsMsg', 212);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_ExamineInfoRequestMsg', 213);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_QuickbarInitMsg', 214);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_QuickbarUpdateMsg', 215);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_MacroInitMsg', 216);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_MacroUpdateMsg', 217);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_QuestionnaireMsg', 218);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_LevelChangedMsg', 219);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_SpellGainedMsg', 220);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EncounterBrokenMsg', 221);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_OnscreenMsgMsg', 222);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_ModifyGuildMsg', 223);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_RewardPackMsg', 224);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_RenameGuildMsg', 225);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_ZoneToFriendRequestMsg', 226);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_ZoneToFriendReplyMsg', 227);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_WaypointRequestMsg', 239);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_WaypointReplyMsg', 240);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_WaypointSelectMsg', 241);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_WaypointUpdateMsg', 242);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_CharNameChangedMsg', 243);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_ShowZoneTeleporterDestinationsMsg', 244);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_SelectZoneTeleporterDestinationMsg', 245);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_ReloadLocalizedTxtMsg', 246);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_RequestGuildMembershipMsg', 247);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_GuildMembershipResponseMsg', 248);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_LeaveGuildNotifyMsg', 249);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_JoinGuildNotifyMsg', 250);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_AvatarUpdateMsg', 251);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_BioUpdateMsg', 252);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_InspectPlayerMsg', 253);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_WSServerLockMsg', 254);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_LSServerLockMsg', 255);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_CsCategoryRequestMsg', 256);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_CsCategoryResponseMsg', 257);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_KnowledgeWindowSlotMappingMsg', 258);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_LFGUpdateMsg', 259);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_AFKUpdateMsg', 260);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_UpdateActivePublicZonesMsg', 261);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_UnknownNpcMsg', 262);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_ConsumableItemsDetailsMsg', 263);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_ConsignViewCreateMsg', 264);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_ConsignViewGetPageMsg', 265);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_ConsignViewReleaseMsg', 266);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_UpdateDebugRadiiMsg', 268);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_ConsignRemoveItemsMsg', 267);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_SnoopMsg', 269);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_ReportMsg', 270);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_UpdateRaidMsg', 271);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_ConsignViewSortMsg', 272);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EqHearChatCmd', 273);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EqDisplayTextCmd', 274);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EqCreateGhostCmd', 275);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EqCreateWidgetCmd', 276);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EqCreateSignWidgetCmd', 277);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EqUpdateSignWidgetCmd', 332);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EqDestroyGhostCmd', 278);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EqUpdateGhostCmd', 279);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EqSetControlGhostCmd', 280);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EqSetPOVGhostCmd', 281);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EqHearCombatCmd', 282);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EqHearSpellCastCmd', 283);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EqHearSpellInterruptCmd', 284);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EqHearSpellFizzleCmd', 285);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EqHearConsiderCmd', 286);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EqUpdateSubClassesCmd', 287);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EqCreateListBoxCmd', 288);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EqSetDebugPathPointsCmd', 289);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EqCannedEmoteCmd', 290);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EqStateCmd', 291);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EqPlaySoundCmd', 292);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EqPlaySound3DCmd', 293);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EqPlayVoiceCmd', 294);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EqHearDrowningCmd', 295);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EqHearDeathCmd', 296);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EqGroupMemberRemovedCmd', 297);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EqHearChainEffectCmd', 298);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EqReceiveOfferCmd', 299);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EqInspectPCResultsCmd', 300);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EqDrawablePathGraphCmd', 301);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EqDialogOpenCmd', 302);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EqDialogCloseCmd', 303);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EqQuestJournalUpdateCmd', 304);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EqQuestGroupCmd', 306);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EqQuestJournalReplyCmd', 305);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EqStartBrokerCmd', 343);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EqUpdateMerchantCmd', 307);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EqUpdateStoreCmd', 308);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EqUpdatePlayerTradeCmd', 309);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EqHelpPathCmd', 310);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EqHelpPathClearCmd', 311);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EqUpdateBankCmd', 312);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EqExamineInfoCmd', 313);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EqUpdateLootCmd', 314);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EqJunctionListCmd', 315);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EqShowDeathWindowCmd', 316);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EqDisplaySpellFailCmd', 317);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EqSpellCastStartCmd', 318);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EqSpellCastEndCmd', 319);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EqResurrectedCmd', 320);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EqChoiceWinCmd', 321);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EqSetDefaultVerbCmd', 322);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EqInstructionWindowCmd', 323);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EqInstructionWindowCloseCmd', 324);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EqInstructionWindowGoalCmd', 325);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EqInstructionWindowTaskCmd', 326);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EqEnableGameEventCmd', 327);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EqShowWindowCmd', 328);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EqEnableWindowCmd', 329);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EqFlashWindowCmd', 330);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EqHearPlayFlavorCmd', 331);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EqDebugPVDCmd', 333);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EqShowBookCmd', 334);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EqQuestionnaireCmd', 335);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EqGetProbsCmd', 336);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EqHearHealCmd', 337);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EqChatChannelUpdateCmd', 338);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EqWhoChannelQueryReplyCmd', 339);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EqAvailWorldChannelsCmd', 340);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EqUpdateTargetCmd', 341);
+insert into opcodes (version_range1, version_range2, name, opcode) values(0, 283, 'OP_EqConsignmentItemsCmd', 342);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_LoginRequestMsg', 0);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_LoginByNumRequestMsg', 1);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_WSLoginRequestMsg', 2);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_ESLoginRequestMsg', 3);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_LoginReplyMsg', 4);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_WSStatusReplyMsg', 5);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_WorldStatusChangeMsg', 6);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_AllWSDescRequestMsg', 7);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_WorldListMsg', 8);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_AllCharactersDescRequestMsg', 9);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_AllCharactersDescReplyMsg', 10);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_CreateCharacterRequestMsg', 11);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_CreateCharacterReplyMsg', 12);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_WSCreateCharacterRequestMsg', 13);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_WSCreateCharacterReplyMsg', 14);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_ReskinCharacterRequestMsg', 15);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_DeleteCharacterRequestMsg', 16);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_DeleteCharacterReplyMsg', 17);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_PlayCharacterRequestMsg', 18);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_PlayCharacterReplyMsg', 19);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_ServerPlayCharacterRequestMsg', 20);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_ServerPlayCharacterReplyMsg', 21);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_ESInitMsg', 22);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_ESReadyForClientsMsg', 23);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_CreateZoneInstanceMsg', 24);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_ZoneInstanceCreateReplyMsg', 25);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_ZoneInstanceDestroyedMsg', 26);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_ExpectClientAsCharacterRequest', 27);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_ExpectClientAsCharacterReplyMs', 28);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_ZoneInfoMsg', 29);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_DoneLoadingZoneResourcesMsg', 30);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_DoneSendingInitialEntitiesMsg', 31);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_DoneLoadingEntityResourcesMsg', 32);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_DoneLoadingUIResourcesMsg', 33);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_PredictionUpdateMsg', 34);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_SetRemoteCmdsMsg', 35);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_RemoteCmdMsg', 36);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_GameWorldTimeMsg', 37);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_MOTDMsg', 38);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_ZoneMOTDMsg', 39);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_AvatarCreatedMsg', 40);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_AvatarDestroyedMsg', 41);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_RequestCampMsg', 42);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_CampStartedMsg', 43);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_CampAbortedMsg', 44);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_WhoQueryRequestMsg', 45);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_WhoQueryReplyMsg', 46);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_MonitorReplyMsg', 47);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_MonitorCharacterListMsg', 48);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_MonitorCharacterListRequestMsg', 49);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_ClientCmdMsg', 50);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_DispatchClientCmdMsg', 51);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_DispatchESMsg', 52);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_UpdateTargetMsg', 53);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_UpdateTargetLocMsg', 54);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_UpdateCharacterSheetMsg', 55);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_UpdateSpellBookMsg', 56);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_UpdateInventoryMsg', 58);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_UpdateRecipeBookMsg', 60);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_RequestRecipeDetailsMsg', 61);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_RecipeDetailsMsg', 62);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_UpdateSkillBookMsg', 63);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_UpdateSkillsMsg', 64);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_UpdateOpportunityMsg', 65);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_ChangeZoneMsg', 66);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_ClientTeleportRequestMsg', 68);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_TeleportWithinZoneMsg', 69);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_TeleportWithinZoneNoReloadMsg', 70);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_MigrateClientToZoneRequestMsg', 71);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_MigrateClientToZoneReplyMsg', 72);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_ReadyToZoneMsg', 73);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_AddClientToGroupMsg', 74);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_AddGroupToGroupMsg', 75);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_RemoveClientFromGroupMsg', 76);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_RemoveGroupFromGroupMsg', 77);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_MakeGroupLeaderMsg', 78);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_GroupCreatedMsg', 79);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_GroupDestroyedMsg', 80);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_GroupMemberAddedMsg', 81);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_GroupMemberRemovedMsg', 82);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_GroupRemovedFromGroupMsg', 83);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_GroupLeaderChangedMsg', 84);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_GroupResendOOZDataMsg', 85);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_GroupSettingsChangedMsg', 86);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_SendLatestRequestMsg', 88);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_ClearDataMsg', 89);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_SetSocialMsg', 90);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_ESStatusMsg', 91);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_ESZoneInstanceStatusMsg', 92);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_ZonesStatusRequestMsg', 93);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_ZonesStatusMsg', 94);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_ESWeatherRequestMsg', 95);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_ESWeatherRequestEndMsg', 96);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_WSWeatherUpdateMsg', 97);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_DialogSelectMsg', 98);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_DialogCloseMsg', 99);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_RemoveSpellEffectMsg', 100);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_RemoveConcentrationMsg', 101);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_QuestJournalOpenMsg', 102);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_QuestJournalInspectMsg', 103);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_QuestJournalSetVisibleMsg', 104);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_QuestJournalWaypointMsg', 105);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_CreateGuildRequestMsg', 106);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_CreateGuildReplyMsg', 107);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_GuildsayMsg', 108);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_GuildKickMsg', 109);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_GuildUpdateMsg', 110);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_DeleteGuildMsg', 111);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_FellowshipExpMsg', 112);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_ConsignmentCloseStoreMsg', 113);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_ConsignItemRequestMsg', 114);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_ConsignItemResponseMsg', 115);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_PurchaseConsignmentRequestMsg', 116);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_PurchaseConsignmentResponseMsg', 117);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_ProcessScriptMsg', 118);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_ProcessWorkspaceMsg', 119);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_HouseDeletedRemotelyMsg', 120);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_UpdateHouseDataMsg', 121);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_UpdateHouseAccessDataMsg', 122);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_PlayerHouseBaseScreenMsg', 123);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_PlayerHousePurchaseScreenMsg', 124);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_PlayerHouseAccessUpdateMsg', 125);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_PlayerHouseDisplayStatusMsg', 126);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_PlayerHouseCloseUIMsg', 127);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_BuyPlayerHouseMsg', 128);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_BuyPlayerHouseTintMsg', 129);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_CollectAllHouseItemsMsg', 130);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_RelinquishHouseMsg', 131);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EnterHouseMsg', 132);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_ExitHouseMsg', 133);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_HouseDefaultAccessSetMsg', 134);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_HouseAccessSetMsg', 135);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_HouseAccessRemoveMsg', 136);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_PayHouseUpkeepMsg', 137);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_MoveableObjectPlacementCriteri', 138);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EnterMoveObjectModeMsg', 139);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_PositionMoveableObject', 140);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_CancelMoveObjectModeMsg', 141);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_ShaderCustomizationMsg', 142);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_ReplaceableSubMeshesMsg', 143);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_HouseCustomizationScreenMsg', 144);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_CustomizationPurchaseRequestMs', 145);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_CustomizationSetRequestMsg', 146);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_CustomizationReplyMsg', 147);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_TintWidgetsMsg', 148);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_ExamineConsignmentRequestMsg', 149);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_ExamineConsignmentResponseMsg', 150);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_UISettingsResponseMsg', 151);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_UIResetMsg', 152);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_KeymapLoadMsg', 153);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_KeymapNoneMsg', 154);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_KeymapDataMsg', 155);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_KeymapSaveMsg', 156);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_DispatchSpellCmdMsg', 157);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EntityVerbsRequestMsg', 159);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EntityVerbsReplyMsg', 160);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EntityVerbsVerbMsg', 161);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_ChatRelationshipUpdateMsg', 162);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_LootItemsRequestMsg', 163);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_StoppedLootingMsg', 164);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_SitMsg', 165);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_StandMsg', 166);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_SatMsg', 167);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_StoodMsg', 168);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_ClearForTakeOffMsg', 169);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_ReadyForTakeOffMsg', 170);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_ShowIllusionsMsg', 171);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_HideIllusionsMsg', 172);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_ExamineItemRequestMsg', 173);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_ReadBookPageMsg', 174);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_DefaultGroupOptionsRequestMsg', 175);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_DefaultGroupOptionsMsg', 176);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_GroupOptionsMsg', 177);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_DisplayGroupOptionsScreenMsg', 178);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_DisplayInnVisitScreenMsg', 179);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_DumpSchedulerMsg', 180);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_LSRequestPlayerDescMsg', 181);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_LSCheckAcctLockMsg', 182);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_WSAcctLockStatusMsg', 183);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_RequestHelpRepathMsg', 184);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_RequestTargetLocMsg', 185);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_UpdateMotdMsg', 186);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_PerformPlayerKnockbackMsg', 187);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_PerformCameraShakeMsg', 188);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_PopulateSkillMapsMsg', 189);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_CancelledFeignMsg', 190);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_SignalMsg', 191);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_ShowCreateFromRecipeUIMsg', 192);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_CancelCreateFromRecipeMsg', 193);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_BeginItemCreationMsg', 194);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_StopItemCreationMsg', 195);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_ShowItemCreationProcessUIMsg', 196);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_UpdateItemCreationProcessUIMsg', 197);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_DisplayTSEventReactionMsg', 198);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_ShowRecipeBookMsg', 199);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_KnowledgebaseRequestMsg', 200);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_KnowledgebaseResponseMsg', 201);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_CSTicketHeaderRequestMsg', 202);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_CSTicketInfoMsg', 203);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_CSTicketCommentRequestMsg', 204);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_CSTicketCommentResponseMsg', 205);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_CSTicketCreateMsg', 206);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_CSTicketAddCommentMsg', 207);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_CSTicketDeleteMsg', 208);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_CSTicketChangeNotificationMsg', 209);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_WorldDataUpdateMsg', 210);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_KnownLanguagesMsg', 211);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_LsRequestClientCrashLogMsg', 212);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_LsClientBaselogReplyMsg', 213);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_LsClientCrashlogReplyMsg', 214);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_LsClientDetailedCrashlogReplyMsg', 215);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_LsClientAlertlogReplyMsg', 216);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_LsClientVerifylogReplyMsg', 217);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_ClientTeleportToLocationMsg', 218);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_UpdateClientPredFlagsMsg', 219);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_ChangeServerControlFlagMsg', 220);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_CSToolsRequestMsg', 221);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_CSToolsResponseMsg', 222);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_AddSocialStructureStandingMsg', 223);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_CreateBoatTransportsMsg', 224);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_PositionBoatTransportMsg', 225);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_MigrateBoatTransportMsg', 226);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_MigrateBoatTransportReplyMsg', 227);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_DisplayDebugNLLPointsMsg', 228);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_ExamineInfoRequestMsg', 229);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_QuickbarInitMsg', 230);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_QuickbarUpdateMsg', 231);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_MacroInitMsg', 232);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_MacroUpdateMsg', 233);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_QuestionnaireMsg', 234);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_LevelChangedMsg', 235);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_SpellGainedMsg', 236);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EncounterBrokenMsg', 237);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_OnscreenMsgMsg', 238);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_DisplayWarningMsg', 239);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_ModifyGuildMsg', 240);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_GuildEventMsg', 241);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_GuildEventAddMsg', 242);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_GuildEventActionMsg', 243);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_GuildEventListMsg', 244);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_RequestGuildEventDetailsMsg', 245);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_GuildEventDetailsMsg', 246);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_RequestGuildInfoMsg', 247);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_GuildBankActionMsg', 248);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_GuildBankActionResponseMsg', 249);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_GuildBankItemDetailsRequestMsg', 250);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_GuildBankItemDetailsResponseMs', 251);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_GuildBankUpdateMsg', 252);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_GuildBankEventListMsg', 253);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_RequestGuildBankEventDetailsMs', 254);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_RewardPackMsg', 255);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_RenameGuildMsg', 256);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_ZoneToFriendRequestMsg', 257);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_ZoneToFriendReplyMsg', 258);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_ChatCreateChannelMsg', 259);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_ChatJoinChannelMsg', 260);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_ChatWhoChannelMsg', 261);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_ChatLeaveChannelMsg', 262);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_ChatTellChannelMsg', 263);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_ChatTellUserMsg', 264);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_ChatToggleFriendMsg', 265);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_ChatToggleIgnoreMsg', 266);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_ChatSendFriendsMsg', 267);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_ChatSendIgnoresMsg', 268);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_ChatFiltersMsg', 269);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_MailGetHeadersMsg', 270);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_MailGetMessageMsg', 271);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_MailSendMessageMsg', 272);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_MailDeleteMessageMsg', 273);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_MailGetHeadersReplyMsg', 274);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_MailGetMessageReplyMsg', 275);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_MailSendMessageReplyMsg', 276);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_MailCommitSendMessageMsg', 277);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_MailSendSystemMessageMsg', 278);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_MailRemoveAttachFromMailMsg', 279);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_WaypointRequestMsg', 280);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_WaypointReplyMsg', 281);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_WaypointSelectMsg', 282);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_WaypointUpdateMsg', 283);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_CharNameChangedMsg', 284);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_ShowZoneTeleporterDestinations', 285);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_SelectZoneTeleporterDestinatio', 286);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_ReloadLocalizedTxtMsg', 287);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_RequestGuildMembershipMsg', 288);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_GuildMembershipResponseMsg', 289);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_LeaveGuildNotifyMsg', 290);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_JoinGuildNotifyMsg', 291);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_AvatarUpdateMsg', 292);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_BioUpdateMsg', 293);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_InspectPlayerMsg', 294);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_WSServerLockMsg', 295);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_LSServerLockMsg', 296);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_WSServerHideMsg', 297);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_CsCategoryRequestMsg', 298);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_CsCategoryResponseMsg', 299);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_KnowledgeWindowSlotMappingMsg', 300);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_LFGUpdateMsg', 301);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_AFKUpdateMsg', 302);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_AnonUpdateMsg', 303);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_UpdateActivePublicZonesMsg', 304);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_UnknownNpcMsg', 305);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_PromoFlagsDetailsMsg', 306);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_ConsignViewCreateMsg', 307);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_ConsignViewGetPageMsg', 308);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_ConsignViewReleaseMsg', 309);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_ConsignRemoveItemsMsg', 310);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_UpdateDebugRadiiMsg', 311);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_SnoopMsg', 312);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_ReportMsg', 313);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_UpdateRaidMsg', 314);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_ConsignViewSortMsg', 316);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_TitleUpdateMsg', 317);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_ClientFellMsg', 318);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_ClientInDeathRegionMsg', 319);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_CampClientMsg', 320);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_CSToolAccessResponseMsg', 321);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_GetAvatarAccessRequestForCSToo', 322);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_TrackingUpdateMsg', 323);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_BeginTrackingMsg', 324);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_StopTrackingMsg', 325);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_AdvancementRequestMsg', 326);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_UpdateAvgFrameTimeMsg', 327);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_MapFogDataInitMsg', 328);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_MapFogDataUpdateMsg', 329);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_CloseGroupInviteWindowMsg', 330);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_UpdateGroupMemberDataMsg', 331);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_WorldPingMsg', 332);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_MoveLogUpdateMsg', 333);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_OfferQuestMsg', 334);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_WorldShutdownUpdateMsg', 335);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_DisplayMailScreenMsg', 336);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_ClientIdleBeginMsg', 337);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_ClientIdleEndMsg', 338);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_PurchaseConsignmentLoreCheckRe', 339);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_NotifyApprenticeStoppedMentori', 340);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_CorruptedClientMsg', 341);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_WorldDataChangeMsg', 342);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_MailEventNotificationMsg', 343);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_RestartZoneMsg', 344);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_FlightPathsMsg', 345);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_CharacterLinkdeadMsg', 346);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_CharTransferStartRequestMsg', 347);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_CharTransferStartReplyMsg', 348);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_CharTransferRequestMsg', 349);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_CharTransferReplyMsg', 350);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_CharTransferRollbackRequestMsg', 351);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_CharTransferCommitRequestMsg', 352);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_CharTransferRollbackReplyMsg', 353);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_CharTransferCommitReplyMsg', 354);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_GetCharacterSerializedRequestM', 355);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_GetCharacterSerializedReplyMsg', 356);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_CreateCharFromCBBRequestMsg', 357);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_CreateCharFromCBBReplyMsg', 358);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_HousingDataChangedMsg', 359);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_HousingRestoreMsg', 360);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_AuctionItem', 361);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_AuctionItemReply', 362);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_AuctionCoin', 363);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_AuctionCoinReply', 364);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_AuctionCharacter', 365);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_AuctionCharacterReply', 366);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_AuctionCommitMsg', 367);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_AuctionAbortMsg', 368);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_CharTransferValidateRequestMsg', 369);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_CharTransferValidateReplyMsg', 370);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_RaceRestrictionMsg', 371);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_SetInstanceDisplayNameMsg', 372);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_GetAuctionAssetIDMsg', 373);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_GetAuctionAssetIDReplyMsg', 374);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_ResendWorldChannelsMsg', 375);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_DisplayExchangeScreenMsg', 376);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_AuditAuctionEventMsg', 377);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_InviteRequestMsg', 401);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_InviteResponseMsg', 402);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_InviteTargetResponseMsg', 403);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_InspectPlayerRequestMsg', 404);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_DispatchMsg', 405);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_DisplayEventMsg', 406);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_PrePossessionMsg', 407);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_PostPossessionMsg', 408);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqHearChatCmd', 411);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqDisplayTextCmd', 412);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqCreateGhostCmd', 413);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqCreateWidgetCmd', 414);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqCreateSignWidgetCmd', 415);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqDestroyGhostCmd', 416);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqUpdateGhostCmd', 417);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqSetControlGhostCmd', 418);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqSetPOVGhostCmd', 419);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqHearCombatCmd', 420);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqHearSpellCastCmd', 421);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqHearSpellInterruptCmd', 422);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqHearSpellFizzleCmd', 423);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqHearConsiderCmd', 424);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqUpdateSubClassesCmd', 425);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqCreateListBoxCmd', 426);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqSetDebugPathPointsCmd', 428);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqCannedEmoteCmd', 429);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqStateCmd', 430);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqPlaySoundCmd', 431);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqPlaySound3DCmd', 432);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqPlayVoiceCmd', 433);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqHearDrowningCmd', 434);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqHearDeathCmd', 435);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqGroupMemberRemovedCmd', 436);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqHearChainEffectCmd', 437);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqReceiveOfferCmd', 438);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqInspectPCResultsCmd', 439);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqDrawablePathGraphCmd', 440);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqDialogOpenCmd', 441);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqDialogCloseCmd', 442);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqFactionUpdateCmd', 443);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqCollectionUpdateCmd', 444);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqCollectionFilterCmd', 445);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqCollectionItemCmd', 446);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqQuestJournalUpdateCmd', 447);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqQuestJournalReplyCmd', 448);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqQuestGroupCmd', 449);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqUpdateMerchantCmd', 450);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqUpdateStoreCmd', 451);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqUpdatePlayerTradeCmd', 452);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqHelpPathCmd', 453);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqHelpPathClearCmd', 454);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqUpdateBankCmd', 455);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqExamineInfoCmd', 456);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqUpdateLootCmd', 457);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqJunctionListCmd', 458);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqShowDeathWindowCmd', 459);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqDisplaySpellFailCmd', 460);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqSpellCastStartCmd', 461);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqSpellCastEndCmd', 462);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqResurrectedCmd', 463);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqChoiceWinCmd', 464);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqSetDefaultVerbCmd', 465);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqInstructionWindowCmd', 466);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqInstructionWindowCloseCmd', 467);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqInstructionWindowGoalCmd', 468);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqInstructionWindowTaskCmd', 469);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqEnableGameEventCmd', 470);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqShowWindowCmd', 471);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqEnableWindowCmd', 472);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqFlashWindowCmd', 473);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqHearPlayFlavorCmd', 474);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqUpdateSignWidgetCmd', 475);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqDebugPVDCmd', 476);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqShowBookCmd', 477);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqQuestionnaireCmd', 478);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqGetProbsCmd', 479);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqHearHealCmd', 480);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqChatChannelUpdateCmd', 481);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqWhoChannelQueryReplyCmd', 482);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqAvailWorldChannelsCmd', 483);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqUpdateTargetCmd', 484);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqConsignmentItemsCmd', 485);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqStartBrokerCmd', 486);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqMapExplorationCmd', 487);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqStoreLogCmd', 488);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqSpellMoveToRangeAndRetryCmd', 489);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqUpdatePlayerMailCmd', 490);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqArenaResultsCmd', 491);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqGuildBankEventActionCmd', 492);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqGuildBankExamineInfoCmd', 493);
+INSERT INTO `opcodes` (`version_range1`, `version_range2`, `name`, `opcode`) VALUES (284, 546, 'OP_EqHearSpellNoLandCmd', 494);

+ 37 - 24
EQ2/source/LoginServer/LWorld.cpp

@@ -1142,37 +1142,50 @@ EQ2Packet* LWorldList::MakeServerListPacket(int8 lsadmin, int16 version) {
 	PacketStruct* packet = configReader.getStruct("LS_WorldList", version);
 	packet->setArrayLengthByName("num_worlds", tmpCount);
 
-	string world_data;	
-	for( map_list = worldmap.begin(); map_list != worldmap.end(); map_list++) {
+	string world_data;
+	for (map_list = worldmap.begin(); map_list != worldmap.end(); map_list++) {
 		LWorld* world = map_list->second;
 		if ((world->IsInit || (world->ShowDown() && world->ShowDownActive())) && world->GetType() == World) {
 			ServerNum++;
-			packet->setArrayDataByName("id", world->GetID(), ServerNum-1);
-
-			if (version < 1212)
-				packet->setArrayDataByName("allowed_races", 0xFFFFFFFF, ServerNum - 1);
-			else if (version < 60006)
-				packet->setArrayDataByName("allowed_races", 0x000FFFFF, ServerNum - 1); // + Freeblood
+			packet->setArrayDataByName("id", world->GetID(), ServerNum - 1);
+
+			if (version <= 283) {
+				packet->setArrayDataByName("name", world->GetName(), ServerNum - 1);
+				if (!world->ShowDown())
+					packet->setArrayDataByName("online", 1, ServerNum - 1);
+				if (world->IsLocked())
+					packet->setArrayDataByName("locked", 1, ServerNum - 1);
+				packet->setArrayDataByName("unknown2", 1, ServerNum - 1);
+				packet->setArrayDataByName("unknown3", 1, ServerNum - 1);
+				packet->setArrayDataByName("load", world->GetWorldStatus(), ServerNum - 1);
+			}
 			else
-				packet->setArrayDataByName("allowed_races", 0x001FFFFF, ServerNum - 1);	// + Aerakyn
+			{
+				if (version < 1212)
+					packet->setArrayDataByName("allowed_races", 0xFFFFFFFF, ServerNum - 1);
+				else if (version < 60006)
+					packet->setArrayDataByName("allowed_races", 0x000FFFFF, ServerNum - 1); // + Freeblood
+				else
+					packet->setArrayDataByName("allowed_races", 0x001FFFFF, ServerNum - 1);	// + Aerakyn
 
-			packet->setArrayDataByName("number_online_flag", 1, ServerNum-1);
-			packet->setArrayDataByName("num_players", world->GetPlayerNum(), ServerNum-1);
-			packet->setArrayDataByName("name", world->GetName(), ServerNum-1);
-			packet->setArrayDataByName("name2", world->GetName(), ServerNum-1);
-			packet->setArrayDataByName("feature_set",0, ServerNum-1);
+				packet->setArrayDataByName("number_online_flag", 1, ServerNum - 1);
+				packet->setArrayDataByName("num_players", world->GetPlayerNum(), ServerNum - 1);
+				packet->setArrayDataByName("name", world->GetName(), ServerNum - 1);
+				packet->setArrayDataByName("name2", world->GetName(), ServerNum - 1);
+				packet->setArrayDataByName("feature_set", 0, ServerNum - 1);
 
-			packet->setArrayDataByName("load", world->GetWorldStatus(), ServerNum-1);
-			if(world->IsLocked())
-				packet->setArrayDataByName("locked", 1, ServerNum - 1);
+				packet->setArrayDataByName("load", world->GetWorldStatus(), ServerNum - 1);
+				if (world->IsLocked())
+					packet->setArrayDataByName("locked", 1, ServerNum - 1);
 
-			if(world->ShowDown())
-				packet->setArrayDataByName("tag", 0, ServerNum - 1);
-			else
-				packet->setArrayDataByName("tag", 1, ServerNum - 1);
+				if (world->ShowDown())
+					packet->setArrayDataByName("tag", 0, ServerNum - 1);
+				else
+					packet->setArrayDataByName("tag", 1, ServerNum - 1);
 
-			if ( version < 1212 )
-				packet->setArrayDataByName("unknown", ServerNum, ServerNum - 1);
+				if (version < 1212)
+					packet->setArrayDataByName("unknown", ServerNum, ServerNum - 1);
+			}
 		}
 	}
 
@@ -1189,7 +1202,7 @@ EQ2Packet* LWorldList::MakeServerListPacket(int8 lsadmin, int16 version) {
 	ServerListData.insert(make_pair(version, pack));
 	MWorldMap.releasereadlock();
 
-	SetUpdateServerList( false );
+	SetUpdateServerList(false);
 
 	return ServerListData[version];
 }

+ 137 - 69
EQ2/source/LoginServer/LoginDatabase.cpp

@@ -130,6 +130,20 @@ void LoginDatabase::SetServerZoneDescriptions(int32 server_id, map<int32, LoginZ
 	}
 }
 
+//this is really just for the version that doesn't send the server id in its play request
+int32 LoginDatabase::GetServer(int32 accountID, int32 charID, string name) {
+	int32 id = 0;
+	Query query;
+	MYSQL_ROW row;
+	query.escaped_name = getEscapeString(name.c_str());
+	MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT server_id from login_characters where account_id=%i and char_id=%i and name='%s'", accountID, charID, query.escaped_name);
+	if (result && mysql_num_rows(result) == 1) {
+		row = mysql_fetch_row(result);
+		id = atoi(row[0]);
+	}
+	return id;
+}
+
 void LoginDatabase::LoadCharacters(LoginAccount* acct, int16 version){
 	if(acct != NULL)
 		acct->flushCharacters ( );
@@ -144,7 +158,11 @@ void LoginDatabase::LoadCharacters(LoginAccount* acct, int16 version){
 		MYSQL_ROW row3;
 		while ((row = mysql_fetch_row(result))) {
 			CharSelectProfile* player = new CharSelectProfile(version);
-			id = atoul(row[0]);
+			id = atoul(row[0]);		
+			//for (int i = 0; i < 10; i++)
+			//	player->packet->setDataByName("hair_type", 0, i);
+			//player->packet->setDataByName("test23", 413);
+			//player->packet->setDataByName("test24", 414);
 			player->packet->setDataByName("charid", id);
 			player->packet->setDataByName("server_id", atoul(row[1]));
 			player->packet->setMediumStringByName("name", row[2]);
@@ -156,10 +174,22 @@ void LoginDatabase::LoadCharacters(LoginAccount* acct, int16 version){
 			player->packet->setDataByName("body_age", atof(row[8]));
 			SetZoneInformation(atoi(row[1]), atoi(row[9]), version, player->packet);
 			player->packet->setDataByName("level", atoi(row[10]));
-			player->packet->setDataByName("soga_wing_type", atoi(row[11]));
-			player->packet->setDataByName("soga_chest_type", atoi(row[12]));
-			player->packet->setDataByName("soga_legs_type", atoi(row[13]));
-			player->packet->setDataByName("soga_hair_type", atoi(row[14]));
+			if(atoi(row[11]) > 0)
+				player->packet->setDataByName("soga_wing_type", atoi(row[11]));
+			else
+				player->packet->setDataByName("soga_wing_type", atoi(row[17]));
+			if(atoi(row[12]) > 0)
+				player->packet->setDataByName("soga_chest_type", atoi(row[12]));
+			else
+				player->packet->setDataByName("soga_chest_type", atoi(row[16]));
+			if(atoi(row[13]) > 0)
+				player->packet->setDataByName("soga_legs_type", atoi(row[13]));
+			else
+				player->packet->setDataByName("soga_legs_type", atoi(row[15]));
+			if(atoi(row[14]) > 0)
+				player->packet->setDataByName("soga_hair_type", atoi(row[14]));
+			else
+				player->packet->setDataByName("soga_hair_type", atoi(row[18]));
 			player->packet->setDataByName("legs_type", atoi(row[15]));
 			player->packet->setDataByName("chest_type", atoi(row[16]));
 			player->packet->setDataByName("wing_type", atoi(row[17]));
@@ -167,15 +197,12 @@ 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 >= 887)
-				player->packet->setDataByName("version", 6);
-			else if ( version == 546 )
+			if(version == 546)
 				player->packet->setDataByName("version", 11);
+			else if(version >= 887)
+				player->packet->setDataByName("version", 6);
 			else
 				player->packet->setDataByName("version", 5);
-
-			player->packet->setDataByName("client_version", version);
-
 			player->packet->setDataByName("account_id", acct->getLoginAccountID());
 			player->packet->setDataByName("account_id2", acct->getLoginAccountID());
 			
@@ -184,10 +211,14 @@ void LoginDatabase::LoadCharacters(LoginAccount* acct, int16 version){
 			if(row[22])
 				player->packet->setMediumStringByName("server_name", row[22]);
 			player->packet->setDataByName("hair_face_type", atoi(row[23]));
-			player->packet->setDataByName("soga_hair_face_type", atoi(row[24]));
-
-			player->packet->setDataByName("soga_race_type", atoi(row[25]));
-
+			if(atoi(row[24]) > 0)				
+				player->packet->setDataByName("soga_hair_face_type", atoi(row[24]));
+			else
+				player->packet->setDataByName("soga_hair_face_type", atoi(row[23]));
+			if(atoi(row[25]) > 0)
+				player->packet->setDataByName("soga_race_type", atoi(row[25]));
+			else
+				player->packet->setDataByName("soga_race_type", atoi(row[26]));
 			player->packet->setDataByName("race_type", atoi(row[26]));
 
 			player->packet->setDataByName("unknown3", 57);
@@ -206,7 +237,16 @@ void LoginDatabase::LoadCharacters(LoginAccount* acct, int16 version){
 				for(int i=0;(row3 = mysql_fetch_row(result3)) && i<24; i++){
 					player->packet->setEquipmentByName("equip", atoi(row3[1]), atoi(row3[2]), atoi(row3[3]), atoi(row3[4]), atoi(row3[5]), atoi(row3[6]), atoi(row3[7]), atoi(row3[0]));
 				}
-			}
+			}			
+			player->packet->setDataByName("mount", 1377);
+			player->packet->setDataByName("mount_color1", 57);
+			/*
+			enum NetAppearance::NetAppearanceFlags
+			{
+				NAF_INVISIBLE=1,
+				NAF_SHOW_HOOD=2
+			};
+			*/
 			acct->addCharacter(player);
 		}
 	}
@@ -264,9 +304,18 @@ void LoginDatabase::LoadAppearanceData(int32 char_id, PacketStruct* char_select_
 		if(atoi(row[1]) == 0)
 			char_select_packet->setColorByName(row[0], atoi(row[2]), atoi(row[3]), atoi(row[4]));
 		else{
-			char_select_packet->setDataByName(row[0], atoi(row[2]),0);
-			char_select_packet->setDataByName(row[0], atoi(row[3]),1);
-			char_select_packet->setDataByName(row[0], atoi(row[4]),2);
+			if (char_select_packet->GetVersion() <= 283)
+			{
+				char_select_packet->setDataByName(row[0], atoi(row[2]) * 2.5, 0);
+				char_select_packet->setDataByName(row[0], atoi(row[3]) * 2.5, 1);
+				char_select_packet->setDataByName(row[0], atoi(row[4]) * 2.5, 2);
+			}
+			else
+			{
+				char_select_packet->setDataByName(row[0], atoi(row[2]), 0);
+				char_select_packet->setDataByName(row[0], atoi(row[3]), 1);
+				char_select_packet->setDataByName(row[0], atoi(row[4]), 2);
+			}
 		}
 	}
 }
@@ -288,7 +337,7 @@ void LoginDatabase::DeactivateCharID(int32 server_id, int32 char_id, int32 excep
 	query.RunQuery2(Q_UPDATE, "update login_characters set deleted=1 where char_id=%u and server_id=%u and id!=%u",char_id,server_id,exception_id);
 }
 
-int32 LoginDatabase::SaveCharacter(PacketStruct* create, LoginAccount* acct, int32 world_charid){
+int32 LoginDatabase::SaveCharacter(PacketStruct* create, LoginAccount* acct, int32 world_charid, int32 client_version){
 	int32 ret_id = 0;
 	Query query;
 	string create_char = 
@@ -326,55 +375,74 @@ 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;
-	SaveCharacterColors(char_id,"skin_color", create->getType_EQ2_Color_ByName("skin_color"));
-	SaveCharacterColors(char_id,"eye_color", create->getType_EQ2_Color_ByName("eye_color"));
-	SaveCharacterColors(char_id,"hair_color1", create->getType_EQ2_Color_ByName("hair_color1"));
-	SaveCharacterColors(char_id,"hair_color2", create->getType_EQ2_Color_ByName("hair_color2"));
-	SaveCharacterColors(char_id,"hair_highlight", create->getType_EQ2_Color_ByName("hair_highlight"));
-	SaveCharacterColors(char_id,"hair_type_color", create->getType_EQ2_Color_ByName("hair_type_color"));
-	SaveCharacterColors(char_id,"hair_type_highlight_color", create->getType_EQ2_Color_ByName("hair_type_highlight_color"));
-	SaveCharacterColors(char_id,"hair_face_color", create->getType_EQ2_Color_ByName("hair_face_color"));
-	SaveCharacterColors(char_id,"hair_face_highlight_color", create->getType_EQ2_Color_ByName("hair_face_highlight_color"));
-	SaveCharacterColors(char_id,"wing_color1", create->getType_EQ2_Color_ByName("wing_color1"));
-	SaveCharacterColors(char_id,"wing_color2", create->getType_EQ2_Color_ByName("wing_color2"));
-	SaveCharacterColors(char_id,"shirt_color", create->getType_EQ2_Color_ByName("shirt_color"));
-	SaveCharacterColors(char_id,"unknown_chest_color", create->getType_EQ2_Color_ByName("unknown_chest_color"));
-	SaveCharacterColors(char_id,"pants_color", create->getType_EQ2_Color_ByName("pants_color"));
-	SaveCharacterColors(char_id,"unknown_legs_color", create->getType_EQ2_Color_ByName("unknown_legs_color"));
-	SaveCharacterColors(char_id,"unknown9", create->getType_EQ2_Color_ByName("unknown9"));
-	SaveCharacterFloats(char_id,"eye_type", create->getType_float_ByName("eyes2",0), create->getType_float_ByName("eyes2",1), create->getType_float_ByName("eyes2",2));
-	SaveCharacterFloats(char_id,"ear_type", create->getType_float_ByName("ears",0), create->getType_float_ByName("ears",1), create->getType_float_ByName("ears",2));
-	SaveCharacterFloats(char_id,"eye_brow_type", create->getType_float_ByName("eye_brows",0), create->getType_float_ByName("eye_brows",1), create->getType_float_ByName("eye_brows",2));
-	SaveCharacterFloats(char_id,"cheek_type", create->getType_float_ByName("cheeks",0), create->getType_float_ByName("cheeks",1), create->getType_float_ByName("cheeks",2));
-	SaveCharacterFloats(char_id,"lip_type", create->getType_float_ByName("lips",0), create->getType_float_ByName("lips",1), create->getType_float_ByName("lips",2));
-	SaveCharacterFloats(char_id,"chin_type", create->getType_float_ByName("chin",0), create->getType_float_ByName("chin",1), create->getType_float_ByName("chin",2));
-	SaveCharacterFloats(char_id,"nose_type", create->getType_float_ByName("nose",0), create->getType_float_ByName("nose",1), create->getType_float_ByName("nose",2));
-	SaveCharacterFloats(char_id,"body_size", create->getType_float_ByName("body_size",0), 0, 0);
-
-	SaveCharacterColors(char_id,"soga_skin_color", create->getType_EQ2_Color_ByName("soga_skin_color"));
-	SaveCharacterColors(char_id,"soga_eye_color", create->getType_EQ2_Color_ByName("soga_eye_color"));
-	SaveCharacterColors(char_id,"soga_hair_color1", create->getType_EQ2_Color_ByName("soga_hair_color1"));
-	SaveCharacterColors(char_id,"soga_hair_color2", create->getType_EQ2_Color_ByName("soga_hair_color2"));
-	SaveCharacterColors(char_id,"soga_hair_highlight", create->getType_EQ2_Color_ByName("soga_hair_highlight"));
-	SaveCharacterColors(char_id,"soga_hair_type_color", create->getType_EQ2_Color_ByName("soga_hair_type_color"));
-	SaveCharacterColors(char_id,"soga_hair_type_highlight_color", create->getType_EQ2_Color_ByName("soga_hair_type_highlight_color"));
-	SaveCharacterColors(char_id,"soga_hair_face_color", create->getType_EQ2_Color_ByName("soga_hair_face_color"));
-	SaveCharacterColors(char_id,"soga_hair_face_highlight_color", create->getType_EQ2_Color_ByName("soga_hair_face_highlight_color"));
-	SaveCharacterColors(char_id,"soga_wing_color1", create->getType_EQ2_Color_ByName("soga_wing_color1"));
-	SaveCharacterColors(char_id,"soga_wing_color2", create->getType_EQ2_Color_ByName("soga_wing_color2"));
-	SaveCharacterColors(char_id,"soga_shirt_color", create->getType_EQ2_Color_ByName("soga_shirt_color"));
-	SaveCharacterColors(char_id,"soga_unknown_chest_color", create->getType_EQ2_Color_ByName("soga_unknown_chest_color"));
-	SaveCharacterColors(char_id,"soga_pants_color", create->getType_EQ2_Color_ByName("soga_pants_color"));
-	SaveCharacterColors(char_id,"soga_unknown_legs_color", create->getType_EQ2_Color_ByName("soga_unknown_legs_color"));
-	SaveCharacterColors(char_id,"soga_unknown13", create->getType_EQ2_Color_ByName("soga_unknown13"));
-	SaveCharacterFloats(char_id,"soga_eye_type", create->getType_float_ByName("soga_eyes2",0), create->getType_float_ByName("soga_eyes2",1), create->getType_float_ByName("soga_eyes2",2));
-	SaveCharacterFloats(char_id,"soga_ear_type", create->getType_float_ByName("soga_ears",0), create->getType_float_ByName("soga_ears",1), create->getType_float_ByName("soga_ears",2));
-	SaveCharacterFloats(char_id,"soga_eye_brow_type", create->getType_float_ByName("soga_eye_brows",0), create->getType_float_ByName("soga_eye_brows",1), create->getType_float_ByName("soga_eye_brows",2));
-	SaveCharacterFloats(char_id,"soga_cheek_type", create->getType_float_ByName("soga_cheeks",0), create->getType_float_ByName("soga_cheeks",1), create->getType_float_ByName("soga_cheeks",2));
-	SaveCharacterFloats(char_id,"soga_lip_type", create->getType_float_ByName("soga_lips",0), create->getType_float_ByName("soga_lips",1), create->getType_float_ByName("soga_lips",2));
-	SaveCharacterFloats(char_id,"soga_chin_type", create->getType_float_ByName("soga_chin",0), create->getType_float_ByName("soga_chin",1), create->getType_float_ByName("soga_chin",2));
-	SaveCharacterFloats(char_id,"soga_nose_type", create->getType_float_ByName("soga_nose",0), create->getType_float_ByName("soga_nose",1), create->getType_float_ByName("soga_nose",2));
-
+	if (client_version <= 283) {
+		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));
+		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));
+		SaveCharacterFloats(char_id, "hair_color1", create->getType_float_ByName("hair_color1", 0), create->getType_float_ByName("hair_color1", 1), create->getType_float_ByName("hair_color1", 2));
+		SaveCharacterFloats(char_id, "hair_color2", create->getType_float_ByName("hair_color2", 0), create->getType_float_ByName("hair_color2", 1), create->getType_float_ByName("hair_color2", 2));
+		SaveCharacterFloats(char_id, "hair_highlight", create->getType_float_ByName("hair_highlight", 0), create->getType_float_ByName("hair_highlight", 1), create->getType_float_ByName("hair_highlight", 2));
+		SaveCharacterFloats(char_id, "hair_type_color", create->getType_float_ByName("hair_type_color", 0), create->getType_float_ByName("hair_type_color", 1), create->getType_float_ByName("hair_type_color", 2));
+		SaveCharacterFloats(char_id, "hair_type_highlight_color", create->getType_float_ByName("hair_type_highlight_color", 0), create->getType_float_ByName("hair_type_highlight_color", 1), create->getType_float_ByName("hair_type_highlight_color", 2));
+		SaveCharacterFloats(char_id, "hair_type_color", create->getType_float_ByName("hair_type_color", 0), create->getType_float_ByName("hair_type_color", 1), create->getType_float_ByName("hair_type_color", 2));
+		SaveCharacterFloats(char_id, "hair_type_highlight_color", create->getType_float_ByName("hair_type_highlight_color", 0), create->getType_float_ByName("hair_type_highlight_color", 1), create->getType_float_ByName("hair_type_highlight_color", 2));
+		SaveCharacterFloats(char_id, "hair_face_color", create->getType_float_ByName("hair_face_color", 0), create->getType_float_ByName("hair_face_color", 1), create->getType_float_ByName("hair_face_color", 2));
+		SaveCharacterFloats(char_id, "hair_face_highlight_color", create->getType_float_ByName("hair_face_highlight_color", 0), create->getType_float_ByName("hair_face_highlight_color", 1), create->getType_float_ByName("hair_face_highlight_color", 2));
+		SaveCharacterFloats(char_id, "shirt_color", create->getType_float_ByName("shirt_color", 0), create->getType_float_ByName("shirt_color", 1), create->getType_float_ByName("shirt_color", 2));
+		SaveCharacterFloats(char_id, "unknown_chest_color", create->getType_float_ByName("unknown_chest_color", 0), create->getType_float_ByName("unknown_chest_color", 1), create->getType_float_ByName("unknown_chest_color", 2));
+		SaveCharacterFloats(char_id, "pants_color", create->getType_float_ByName("pants_color", 0), create->getType_float_ByName("pants_color", 1), create->getType_float_ByName("pants_color", 2));
+		SaveCharacterFloats(char_id, "unknown_legs_color", create->getType_float_ByName("unknown_legs_color", 0), create->getType_float_ByName("unknown_legs_color", 1), create->getType_float_ByName("unknown_legs_color", 2));
+		SaveCharacterFloats(char_id, "unknown9", create->getType_float_ByName("unknown9", 0), create->getType_float_ByName("unknown9", 1), create->getType_float_ByName("unknown9", 2));
+	}
+	else {
+		SaveCharacterColors(char_id, "skin_color", create->getType_EQ2_Color_ByName("skin_color"));
+		SaveCharacterColors(char_id, "eye_color", create->getType_EQ2_Color_ByName("eye_color"));
+		SaveCharacterColors(char_id, "hair_color1", create->getType_EQ2_Color_ByName("hair_color1"));
+		SaveCharacterColors(char_id, "hair_color2", create->getType_EQ2_Color_ByName("hair_color2"));
+		SaveCharacterColors(char_id, "hair_highlight", create->getType_EQ2_Color_ByName("hair_highlight"));
+		SaveCharacterColors(char_id, "hair_type_color", create->getType_EQ2_Color_ByName("hair_type_color"));
+		SaveCharacterColors(char_id, "hair_type_highlight_color", create->getType_EQ2_Color_ByName("hair_type_highlight_color"));
+		SaveCharacterColors(char_id, "hair_face_color", create->getType_EQ2_Color_ByName("hair_face_color"));
+		SaveCharacterColors(char_id, "hair_face_highlight_color", create->getType_EQ2_Color_ByName("hair_face_highlight_color"));
+		SaveCharacterColors(char_id, "wing_color1", create->getType_EQ2_Color_ByName("wing_color1"));
+		SaveCharacterColors(char_id, "wing_color2", create->getType_EQ2_Color_ByName("wing_color2"));
+		SaveCharacterColors(char_id, "shirt_color", create->getType_EQ2_Color_ByName("shirt_color"));
+		SaveCharacterColors(char_id, "unknown_chest_color", create->getType_EQ2_Color_ByName("unknown_chest_color"));
+		SaveCharacterColors(char_id, "pants_color", create->getType_EQ2_Color_ByName("pants_color"));
+		SaveCharacterColors(char_id, "unknown_legs_color", create->getType_EQ2_Color_ByName("unknown_legs_color"));
+		SaveCharacterColors(char_id, "unknown9", create->getType_EQ2_Color_ByName("unknown9"));		
+
+		SaveCharacterColors(char_id, "soga_skin_color", create->getType_EQ2_Color_ByName("soga_skin_color"));
+		SaveCharacterColors(char_id, "soga_eye_color", create->getType_EQ2_Color_ByName("soga_eye_color"));
+		SaveCharacterColors(char_id, "soga_hair_color1", create->getType_EQ2_Color_ByName("soga_hair_color1"));
+		SaveCharacterColors(char_id, "soga_hair_color2", create->getType_EQ2_Color_ByName("soga_hair_color2"));
+		SaveCharacterColors(char_id, "soga_hair_highlight", create->getType_EQ2_Color_ByName("soga_hair_highlight"));
+		SaveCharacterColors(char_id, "soga_hair_type_color", create->getType_EQ2_Color_ByName("soga_hair_type_color"));
+		SaveCharacterColors(char_id, "soga_hair_type_highlight_color", create->getType_EQ2_Color_ByName("soga_hair_type_highlight_color"));
+		SaveCharacterColors(char_id, "soga_hair_face_color", create->getType_EQ2_Color_ByName("soga_hair_face_color"));
+		SaveCharacterColors(char_id, "soga_hair_face_highlight_color", create->getType_EQ2_Color_ByName("soga_hair_face_highlight_color"));
+		SaveCharacterColors(char_id, "soga_wing_color1", create->getType_EQ2_Color_ByName("soga_wing_color1"));
+		SaveCharacterColors(char_id, "soga_wing_color2", create->getType_EQ2_Color_ByName("soga_wing_color2"));
+		SaveCharacterColors(char_id, "soga_shirt_color", create->getType_EQ2_Color_ByName("soga_shirt_color"));
+		SaveCharacterColors(char_id, "soga_unknown_chest_color", create->getType_EQ2_Color_ByName("soga_unknown_chest_color"));
+		SaveCharacterColors(char_id, "soga_pants_color", create->getType_EQ2_Color_ByName("soga_pants_color"));
+		SaveCharacterColors(char_id, "soga_unknown_legs_color", create->getType_EQ2_Color_ByName("soga_unknown_legs_color"));
+		SaveCharacterColors(char_id, "soga_unknown13", create->getType_EQ2_Color_ByName("soga_unknown13"));
+		SaveCharacterFloats(char_id, "soga_eye_type", create->getType_float_ByName("soga_eyes2", 0), create->getType_float_ByName("soga_eyes2", 1), create->getType_float_ByName("soga_eyes2", 2));
+		SaveCharacterFloats(char_id, "soga_ear_type", create->getType_float_ByName("soga_ears", 0), create->getType_float_ByName("soga_ears", 1), create->getType_float_ByName("soga_ears", 2));
+		SaveCharacterFloats(char_id, "soga_eye_brow_type", create->getType_float_ByName("soga_eye_brows", 0), create->getType_float_ByName("soga_eye_brows", 1), create->getType_float_ByName("soga_eye_brows", 2));
+		SaveCharacterFloats(char_id, "soga_cheek_type", create->getType_float_ByName("soga_cheeks", 0), create->getType_float_ByName("soga_cheeks", 1), create->getType_float_ByName("soga_cheeks", 2));
+		SaveCharacterFloats(char_id, "soga_lip_type", create->getType_float_ByName("soga_lips", 0), create->getType_float_ByName("soga_lips", 1), create->getType_float_ByName("soga_lips", 2));
+		SaveCharacterFloats(char_id, "soga_chin_type", create->getType_float_ByName("soga_chin", 0), create->getType_float_ByName("soga_chin", 1), create->getType_float_ByName("soga_chin", 2));
+		SaveCharacterFloats(char_id, "soga_nose_type", create->getType_float_ByName("soga_nose", 0), create->getType_float_ByName("soga_nose", 1), create->getType_float_ByName("soga_nose", 2));
+	}
+	SaveCharacterFloats(char_id, "eye_type", create->getType_float_ByName("eyes2", 0), create->getType_float_ByName("eyes2", 1), create->getType_float_ByName("eyes2", 2));
+	SaveCharacterFloats(char_id, "ear_type", create->getType_float_ByName("ears", 0), create->getType_float_ByName("ears", 1), create->getType_float_ByName("ears", 2));
+	SaveCharacterFloats(char_id, "eye_brow_type", create->getType_float_ByName("eye_brows", 0), create->getType_float_ByName("eye_brows", 1), create->getType_float_ByName("eye_brows", 2));
+	SaveCharacterFloats(char_id, "cheek_type", create->getType_float_ByName("cheeks", 0), create->getType_float_ByName("cheeks", 1), create->getType_float_ByName("cheeks", 2));
+	SaveCharacterFloats(char_id, "lip_type", create->getType_float_ByName("lips", 0), create->getType_float_ByName("lips", 1), create->getType_float_ByName("lips", 2));
+	SaveCharacterFloats(char_id, "chin_type", create->getType_float_ByName("chin", 0), create->getType_float_ByName("chin", 1), create->getType_float_ByName("chin", 2));
+	SaveCharacterFloats(char_id, "nose_type", create->getType_float_ByName("nose", 0), create->getType_float_ByName("nose", 1), create->getType_float_ByName("nose", 2));
+	SaveCharacterFloats(char_id, "body_size", create->getType_float_ByName("body_size", 0), 0, 0);
 	return ret_id;
 }
 

+ 2 - 2
EQ2/source/LoginServer/LoginDatabase.h

@@ -42,7 +42,7 @@ public:
 	char* GetServerAccountName(int32 id);
 	bool  VerifyDelete(int32 account_id, int32 character_id, const char* name);
 	void SetServerZoneDescriptions(int32 server_id, map<int32, LoginZoneUpdate> zone_descriptions);
-
+	int32 GetServer(int32 accountID, int32 charID, string name);
 	void LoadCharacters(LoginAccount* acct, int16 version);
 	void CheckCharacterTimeStamps(LoginAccount* acct);
 	string GetCharacterName(int32 char_id , int32 server_id);
@@ -50,7 +50,7 @@ public:
 	void SaveCharacterFloats(int32 char_id, char* type, float float1, float float2, float float3);
 	int16 GetAppearanceID(string name);
 	void DeactivateCharID(int32 server_id, int32 char_id, int32 exception_id);
-	int32 SaveCharacter(PacketStruct* create, LoginAccount* acct, int32 world_charid);
+	int32 SaveCharacter(PacketStruct* create, LoginAccount* acct, int32 world_charid, int32 client_version);
 	void LoadAppearanceData(int32 char_id, PacketStruct* char_select_packet);
 	bool UpdateCharacterTimeStamp(int32 account_id, int32 character_id, int32 timestamp_update, int32 server_id);
 	bool UpdateCharacterLevel(int32 account_id, int32 character_id, int8 in_level, int32 server_id);

+ 6 - 9
EQ2/source/LoginServer/PacketHeaders.cpp

@@ -19,22 +19,19 @@ void LS_DeleteCharacterRequest::loadData(EQApplicationPacket* packet){
 }
 
 EQ2Packet* LS_CharSelectList::serialize(int16 version){
-
 	Clear();
 	AddData(num_characters);
 	AddData(char_data);
-
-	if (version == 546)
-	{
-		LS_CharListAccountInfoDoF account_info;
+	if (version <= 546) {
+		LS_CharListAccountInfoEarlyClient account_info;
 		account_info.account_id = account_id;
 		account_info.unknown1 = 0xFFFFFFFF;
 		account_info.unknown2 = 0;
 		account_info.unknown3 = 10;
+		account_info.unknown4 = 0;
 		AddData(account_info);
 	}
-	else
-	{
+	else {
 		LS_CharListAccountInfo account_info;
 		account_info.account_id = account_id;
 		account_info.unknown1 = 0xFFFFFFFF;
@@ -45,7 +42,7 @@ EQ2Packet* LS_CharSelectList::serialize(int16 version){
 			account_info.unknown5[i] = 0xFFFFFFFF;
 		account_info.unknown5[3] = 0;
 		AddData(account_info);
-	}
+	}	
 	return new EQ2Packet(OP_AllCharactersDescReplyMsg, getData(), getDataSize());
 }
 
@@ -64,7 +61,7 @@ void LS_CharSelectList::loadData(int32 account, vector<CharSelectProfile*> charl
 		int32 serverID = character->packet->getType_int32_ByName("server_id");
 		if(serverID == 0 || !world_list.FindByID(serverID))
 			continue;
-		num_characters++;
+		num_characters++;		
 		character->SaveData(version);
 		addChar(character->getData(), character->getDataSize());
 	}

+ 34 - 14
EQ2/source/LoginServer/client.cpp

@@ -246,22 +246,22 @@ bool Client::Process() {
 										}
 			case OP_LsClientCrashlogReplyMsg:{
 //				DumpPacket(app);
-				SaveErrorsToDB(app, "Crash Log");
+				SaveErrorsToDB(app, "Crash Log", GetVersion());
 				break;
 											 }
 			case OP_LsClientVerifylogReplyMsg:{
 //				DumpPacket(app);
-				SaveErrorsToDB(app, "Verify Log");
+				SaveErrorsToDB(app, "Verify Log", GetVersion());
 				break;
 											  }
 			case OP_LsClientAlertlogReplyMsg:{
 //				DumpPacket(app);
-				SaveErrorsToDB(app, "Alert Log");
+				SaveErrorsToDB(app, "Alert Log", GetVersion());
 				break;
 											 }
 			case OP_LsClientBaselogReplyMsg:{
 //				DumpPacket(app);
-				SaveErrorsToDB(app, "Base Log");
+				SaveErrorsToDB(app, "Base Log", GetVersion());
 				break;
 											}
 			case OP_AllCharactersDescRequestMsg:{
@@ -270,6 +270,7 @@ bool Client::Process() {
 			case OP_CreateCharacterRequestMsg:{
 				PacketStruct* packet = configReader.getStruct("CreateCharacter", GetVersion());
 
+				DumpPacket(app);
 				playWaitTimer = new Timer ( 15000 );
 				playWaitTimer->Start ( );
 				cout << "Char Create Request From: " << GetAccountName() << "....";
@@ -289,8 +290,13 @@ bool Client::Process() {
 						int16 out_version = GetVersion();
 						memcpy(outpack->pBuffer, &out_version, sizeof(int16));
 						memcpy(outpack->pBuffer + sizeof(int16), app->pBuffer, app->size);
-						uchar* tmp = outpack->pBuffer;
-						tmp+=7;
+						uchar* tmp = outpack->pBuffer;	
+						
+						if(out_version<=283)	
+							tmp+=2;	
+						else	
+							tmp += 7;
+						
 						int32 account_id = GetAccountID();
 						memcpy(tmp, &account_id, sizeof(int32));
 						world_server->SendPacket(outpack);
@@ -312,7 +318,12 @@ bool Client::Process() {
 
 				if(request && request->LoadPacketData(app->pBuffer,app->size)){
 					char_id = request->getType_int32_ByName("char_id");
-					server_id = request->getType_int32_ByName("server_id");
+					if (GetVersion() <= 283) {	
+						server_id = database.GetServer(GetAccountID(), char_id, request->getType_EQ2_16BitString_ByName("name").data);	
+					}	
+					else {	
+						server_id = request->getType_int32_ByName("server_id");	
+					}
 					LWorld* world = world_list.FindByID(server_id);
 					string name = database.GetCharacterName(char_id,server_id);
 					if(world && name.length() > 0){
@@ -394,16 +405,25 @@ bool Client::Process() {
 	return true;
 }
 
-void Client::SaveErrorsToDB(EQApplicationPacket* app, char* type){
+void Client::SaveErrorsToDB(EQApplicationPacket* app, char* type, int32 version){
 	int32 size = 0;
-	memcpy(&size, app->pBuffer + sizeof(int32), sizeof(int32));
+	z_stream zstream;
+	if (version >= 284) {
+		memcpy(&size, app->pBuffer + sizeof(int32), sizeof(int32));
+		zstream.next_in = app->pBuffer + 8;
+		zstream.avail_in = app->size - 8;
+	}
+	else { //box set
+		size = 0xFFFF;
+		zstream.next_in = app->pBuffer + 2;
+		zstream.avail_in = app->size - 2;
+	}
 	size++;
 	char* message = new char[size];
 	memset(message, 0, size);
-	z_stream zstream;
+	
 	int zerror = 0;
-	zstream.next_in		= app->pBuffer + 8;
-	zstream.avail_in	= app->size - 8;
+	
 	zstream.next_out	= (BYTE*)message;
 	zstream.avail_out	= size;
 	zstream.zalloc    = Z_NULL;
@@ -437,7 +457,7 @@ void Client::CharacterApproved(int32 server_id,int32 char_id)
 			EQ2Packet* outapp = packet->serialize();
 			QueuePacket(outapp);
 			safe_delete(packet);
-			database.SaveCharacter(createRequest, GetLoginAccount(),char_id);
+			database.SaveCharacter(createRequest, GetLoginAccount(),char_id, GetVersion());
 
 			// refresh characters for this account
 			database.LoadCharacters(GetLoginAccount(), GetVersion());
@@ -571,7 +591,7 @@ void Client::SendLoginAccepted() {
 void Client::SendWorldList(){
 	EQ2Packet* pack = world_list.MakeServerListPacket(lsadmin, version);
 	EQ2Packet* dupe = pack->Copy();
-	//DumpPacket(dupe->pBuffer,dupe->size);
+	DumpPacket(dupe->pBuffer,dupe->size);
 	QueuePacket(dupe);
 	return;
 }

+ 1 - 1
EQ2/source/LoginServer/client.h

@@ -33,7 +33,7 @@ public:
 	int8	LoginKey[10];	
 	int8	ClientSession[25];
 	bool	Process();
-	void	SaveErrorsToDB(EQApplicationPacket* app, char* type);
+	void	SaveErrorsToDB(EQApplicationPacket* app, char* type, int32 version);
 	void	CharacterApproved(int32 server_id,int32 char_id);
 	void	CharacterRejected(int8 reason_number);
 	EQStream* getConnection() { return eqnc; }

+ 9 - 6
EQ2/source/LoginServer/login_structs.h

@@ -35,13 +35,16 @@ struct LS_OLDPlayCharacterRequest{
 	int32	character_id;
 	EQ2_16BitString name;
 };
-struct LS_CharListAccountInfoDoF {
-	int32	account_id;
-	int32	unknown1;
-	int16	unknown2;
-	int8	unknown3;
+	
+struct LS_CharListAccountInfoEarlyClient {	
+	int32	account_id;	
+	int32	unknown1;	
+	int16	unknown2;	
+	int32	unknown3;	
+	int8	unknown4;	
+	//	int8	unknown7; // adds 'free' option..	
 };
-
+	
 struct LS_CharListAccountInfo{
 	int32	account_id;
 	int32	unknown1;

+ 27 - 20
EQ2/source/WorldServer/ClientPacketFunctions.cpp

@@ -116,13 +116,14 @@ void ClientPacketFunctions::SendSkillBook ( Client* client ){
 }
 
 // Jabantiz: Attempt to get the char trait list working
-void ClientPacketFunctions::SendTraitList ( Client* client ){
-	EQ2Packet* traitApp = master_trait_list.GetTraitListPacket(client);
-	//DumpPacket(traitApp);
-	if (traitApp){
-		client->QueuePacket(traitApp);
+void ClientPacketFunctions::SendTraitList(Client* client) {
+	if (client->GetVersion() >= 547) {
+		EQ2Packet* traitApp = master_trait_list.GetTraitListPacket(client);
+		//DumpPacket(traitApp);
+		if (traitApp) {
+			client->QueuePacket(traitApp);
+		}
 	}
-
 }
 
 void ClientPacketFunctions::SendAbilities ( Client* client ){
@@ -166,31 +167,37 @@ void ClientPacketFunctions::SendQuickBarInit ( Client* client ){
 void ClientPacketFunctions::SendCharacterMacros(Client* client) {
 	LogWrite(PACKET__DEBUG, 0, "Packet", "Sending Character Macro packet (WS_MacroInit, %i)", client->GetVersion());
 	map<int8, vector<MacroData*> >* macros = database.LoadCharacterMacros(client->GetCharacterID());
-	if(macros) {
+	if (macros) {
 		PacketStruct* macro_packet = configReader.getStruct("WS_MacroInit", client->GetVersion());
-		if(macro_packet) {
+		if (macro_packet) {
 			map<int8, vector<MacroData*> >::iterator itr;
 			macro_packet->setArrayLengthByName("macro_count", macros->size());
 			int8 x = 0;
-			for(itr=macros->begin();itr!=macros->end();itr++, x++) {
+			for (itr = macros->begin(); itr != macros->end(); itr++, x++) {
 				macro_packet->setArrayDataByName("number", itr->first, x);
-				if(itr->second.size() > 0) {
+				if (itr->second.size() > 0) {
 					LogWrite(PACKET__DEBUG, 5, "Packet", "Loading Macro %i, name: %s", itr->first, itr->second[0]->name.c_str());
 					macro_packet->setArrayDataByName("name", itr->second[0]->name.c_str(), x);
 				}
-				char tmp_details_count[25] = {0};
-				sprintf(tmp_details_count, "macro_details_count_%i", x);
-				macro_packet->setArrayLengthByName(tmp_details_count, itr->second.size());	
-				for(int8 i=0;i<itr->second.size();i++) {
-					char tmp_command[15] = {0};
-					sprintf(tmp_command, "command%i", x);
-					LogWrite(PACKET__DEBUG, 5, "Packet", "\tLoading Command %i: %s", itr->first, x, itr->second[i]->text.c_str());
-					macro_packet->setArrayDataByName(tmp_command, itr->second[i]->text.c_str(), i);
+				if (client->GetVersion() > 283) {
+					char tmp_details_count[25] = { 0 };
+					sprintf(tmp_details_count, "macro_details_count_%i", x);
+					macro_packet->setArrayLengthByName(tmp_details_count, itr->second.size());
+					for (int8 i = 0; i < itr->second.size(); i++) {
+						char tmp_command[15] = { 0 };
+						sprintf(tmp_command, "command%i", x);
+						LogWrite(PACKET__DEBUG, 5, "Packet", "\tLoading Command %i: %s", itr->first, x, itr->second[i]->text.c_str());
+						macro_packet->setArrayDataByName(tmp_command, itr->second[i]->text.c_str(), i);
+					}
+					macro_packet->setArrayDataByName("unknown2", 2, x);
+					macro_packet->setArrayDataByName("unknown3", 0xFFFFFFFF, x);
+				}
+				else {
+					if (itr->second.size() > 0)
+						macro_packet->setArrayDataByName("command", itr->second[0]->text.c_str(), x);
 				}
-				macro_packet->setArrayDataByName("unknown2", 2, x);
 				macro_packet->setArrayDataByName("icon", itr->second[0]->icon, x);
 				client->GetPlayer()->macro_icons[itr->first] = itr->second[0]->icon;
-				macro_packet->setArrayDataByName("unknown3", 0xFFFFFFFF, x);
 			}
 			EQ2Packet* packet = macro_packet->serialize();
 			client->QueuePacket(packet);

+ 872 - 41
EQ2/source/WorldServer/Commands/Commands.cpp

@@ -2198,22 +2198,7 @@ void Commands::Process(int32 index, EQ2_16BitString* command_parms, Client* clie
 			if(sep && sep->arg[0] && sep->IsNumber(0))
 				quest_id = atoul(sep->arg[0]);
 			if(quest_id > 0){
-				Quest* quest = client->GetPendingQuest(quest_id);
-				if(quest){
-					client->RemovePendingQuest(quest);
-					client->AddPlayerQuest(quest);
-					client->GetCurrentZone()->SendQuestUpdates(client);
-
-					// If character has already completed this quest once update the given date in the database
-					if (client->GetPlayer()->GetCompletedPlayerQuests()->count(quest_id) > 0) {
-						Quest* quest2 = client->GetPlayer()->GetCompletedQuest(quest_id);
-						if (quest2)
-							quest->SetCompleteCount(quest2->GetCompleteCount());
-
-						database.SaveCharRepeatableQuest(client, quest_id, quest->GetCompleteCount());
-						
-					}
-				}
+				client->AcceptQuest(quest_id);
 			}
 			break;
 								  }
@@ -2754,6 +2739,9 @@ void Commands::Process(int32 index, EQ2_16BitString* command_parms, Client* clie
 			break;
 		}
 		case COMMAND_KNOWLEDGEWINDOWSORT: {
+			if (client->GetVersion() <= 546)
+				break;
+
 			if (sep && sep->GetArgNumber() == 4)
 			{
 				int32 book = atoul(sep->arg[0]); // 0 - spells, 1 - combat, 2 - abilities, 3 - tradeskill
@@ -4434,27 +4422,29 @@ void Commands::Process(int32 index, EQ2_16BitString* command_parms, Client* clie
 void Commands::Command_AcceptAdvancement(Client* client, Seperator* sep)
 {
 	 Player *player = client->GetPlayer();
-	TraitData* trait = master_trait_list.GetTrait(atoul(sep->arg[0]));
-
-	// Check to see if this is a trait or grandmaster training (traits are always new spells, training is always upgrades)
-	if (!player->HasSpell(trait->spellID, 0, true)) 
-	{
-		Spell* spell = master_spell_list.GetSpell(trait->spellID, trait->tier);
-		player->AddSpellBookEntry(trait->spellID, trait->tier, player->GetFreeSpellBookSlot(spell->GetSpellData()->spell_book_type), spell->GetSpellData()->spell_book_type, spell->GetSpellData()->linked_timer, true);
-	}
-	else 
-	{
-		Spell* spell = master_spell_list.GetSpell(trait->spellID, trait->tier);
-		int8 old_slot = player->GetSpellSlot(spell->GetSpellID());
-		player->RemoveSpellBookEntry(spell->GetSpellID());
-		player->AddSpellBookEntry(spell->GetSpellID(), spell->GetSpellTier(), old_slot, spell->GetSpellData()->spell_book_type, spell->GetSpellData()->linked_timer, true);
-		player->UnlockSpell(spell);
-		client->SendSpellUpdate(spell);
-	}
-
-	// Spell book update
-	client->QueuePacket(player->GetSpellBookUpdatePacket(client->GetVersion()));
-	client->QueuePacket(master_trait_list.GetTraitListPacket(client));
+	 if (sep && sep->IsSet(0)) {
+		 TraitData* trait = master_trait_list.GetTrait(atoul(sep->arg[0]));
+
+		 // Check to see if this is a trait or grandmaster training (traits are always new spells, training is always upgrades)
+		 if (!player->HasSpell(trait->spellID, 0, true))
+		 {
+			 Spell* spell = master_spell_list.GetSpell(trait->spellID, trait->tier);
+			 player->AddSpellBookEntry(trait->spellID, trait->tier, player->GetFreeSpellBookSlot(spell->GetSpellData()->spell_book_type), spell->GetSpellData()->spell_book_type, spell->GetSpellData()->linked_timer, true);
+		 }
+		 else
+		 {
+			 Spell* spell = master_spell_list.GetSpell(trait->spellID, trait->tier);
+			 int8 old_slot = player->GetSpellSlot(spell->GetSpellID());
+			 player->RemoveSpellBookEntry(spell->GetSpellID());
+			 player->AddSpellBookEntry(spell->GetSpellID(), spell->GetSpellTier(), old_slot, spell->GetSpellData()->spell_book_type, spell->GetSpellData()->linked_timer, true);
+			 player->UnlockSpell(spell);
+			 client->SendSpellUpdate(spell);
+		 }
+
+		 // Spell book update
+		 client->QueuePacket(player->GetSpellBookUpdatePacket(client->GetVersion()));
+		 client->QueuePacket(master_trait_list.GetTraitListPacket(client));
+	 }
 }
 
 /* 
@@ -4473,8 +4463,8 @@ void Commands::Command_AFK(Client* client, Seperator* sep)
 
 	if (player->get_character_flag(CF_AFK))
 	{
-		//LogWrite(MISC__TODO, 1, "TODO", "player->SetActivityStatus(player->GetActivityStatus() + ACTIVITY_STATUS_AFK); <-- need to find this");
-		player->SetActivityStatus(player->GetActivityStatus() + ACTIVITY_STATUS_AFK);
+		LogWrite(MISC__TODO, 1, "TODO", "player->SetActivityStatus(player->GetActivityStatus() + ACTIVITY_STATUS_AFK); <-- need to find this");
+		/*player->SetActivityStatus(player->GetActivityStatus() + ACTIVITY_STATUS_AFK); <-- need to find this */
 
 		if (sep && sep->argplus[0])
 			player->SetAwayMessage("I am away from the keyboard, " + string(sep->argplus[0]));
@@ -4493,8 +4483,8 @@ void Commands::Command_AFK(Client* client, Seperator* sep)
 
 		player->GetZone()->SimpleMessage(CHANNEL_COLOR_YELLOW, message.c_str(), player, 30);
 	}
-	else
-		player->SetActivityStatus(player->GetActivityStatus() - ACTIVITY_STATUS_AFK);
+	/*else
+		player->SetActivityStatus(player->GetActivityStatus() - ACTIVITY_STATUS_AFK); <-- need to find this */
 }
 
 /* 
@@ -8360,6 +8350,847 @@ void Commands::Command_TellChannel(Client *client, Seperator *sep) {
 }
 
 void Commands::Command_Test(Client* client, EQ2_16BitString* command_parms) {
+	Seperator* sep = new Seperator(command_parms->data.c_str(), ' ', 50, 500, true);
+	if (sep->IsSet(0)) {
+		if (atoi(sep->arg[0]) == 1) {
+			PacketStruct* packet2 = configReader.getStruct("WS_SpellGainedMsg", client->GetVersion());
+			if (packet2) {
+				packet2->setDataByName("spell_type", 2);
+				packet2->setDataByName("spell_id", 8308);
+				packet2->setDataByName("spell_name", "Sprint");
+				packet2->setDataByName("add_silently", 0);
+				packet2->setDataByName("tier", 1);
+				packet2->setDataByName("blah1", 1);
+				packet2->setDataByName("blah2", 1);
+				EQ2Packet* outapp = packet2->serialize();
+				DumpPacket(outapp);
+				client->QueuePacket(outapp);
+				safe_delete(packet2);
+			}
+		}
+		else if (atoi(sep->arg[0]) == 2) {
+			PacketStruct* packet2 = configReader.getStruct("WS_GuildUpdate", client->GetVersion());
+			if (packet2) {
+				packet2->setDataByName("guild_name", "Test");
+				packet2->setDataByName("guild_motd", "Test MOTD");
+				packet2->setDataByName("guild_id", 1234);
+				packet2->setDataByName("guild_level", 1);
+				packet2->setDataByName("unknown", 2);
+				packet2->setDataByName("unknown2", 3);
+				packet2->setDataByName("exp_current", 1);
+				packet2->setDataByName("exp_to_next_level", 4);
+				EQ2Packet* outapp = packet2->serialize();
+				DumpPacket(outapp);
+				client->QueuePacket(outapp);
+				safe_delete(packet2);
+			}
+		}
+		else if (atoi(sep->arg[0]) == 3) {
+			PacketStruct* packet2 = configReader.getStruct("WS_JoinGuildNotify", client->GetVersion());
+			if (packet2) {
+				packet2->setDataByName("guild_id", 1234);
+				packet2->setDataByName("character_id", 1);
+				packet2->setDataByName("account_id", 2);
+				packet2->setDataByName("guild_level", 1);
+				packet2->setDataByName("name", "Test");
+				packet2->setDataByName("unknown2", 0);
+				packet2->setDataByName("unknown3", 1);
+				packet2->setDataByName("adventure_class", 6);
+				packet2->setDataByName("adventure_level", 7);
+				packet2->setDataByName("tradeskill_class", 4);
+				packet2->setDataByName("tradeskill_level", 5);
+				packet2->setDataByName("rank", 0);
+				packet2->setDataByName("member_flags", 2);
+				packet2->setDataByName("join_date", 1591112273);
+				packet2->setDataByName("guild_status", 2);
+				packet2->setDataByName("last_login", 1591132273);
+				packet2->setDataByName("recruiter_id", 1);
+				packet2->setDataByName("points", 2345);
+				packet2->setDataByName("note", "note");
+				packet2->setMediumStringByName("officer_note", "O note");
+				packet2->setMediumStringByName("zone", "Blah");
+
+				EQ2Packet* outapp = packet2->serialize();
+				DumpPacket(outapp);
+				client->QueuePacket(outapp);
+				safe_delete(packet2);
+			}
+		}
+		else if (atoi(sep->arg[0]) == 5) {
+			client->GetPlayer()->GetTarget();
+			int16 offset = atoi(sep->arg[2]);
+			int32 value1 = atol(sep->arg[4]);
+			EQ2Packet* outapp = client->GetPlayer()->GetPlayerInfo()->serialize(client->GetVersion(), offset, value1);
+			client->QueuePacket(outapp);
+		}
+		else if (atoi(sep->arg[0]) == 6) {
+			Spawn* spawn = client->GetPlayer()->GetTarget();
+			if (!spawn)
+				spawn = client->GetPlayer();
+			else if (spawn->IsEntity())
+				((Entity*)spawn)->SetSpeed(atof(sep->arg[4]));
+			spawn->RunToLocation(atof(sep->arg[1]), atof(sep->arg[2]), atof(sep->arg[3]));
+		}
+		else if (atoi(sep->arg[0]) == 7) {
+			int32 id = 0;
+			Spawn* spawn = client->GetCurrentZone()->GetSpawn(7720001);
+			if (spawn) {
+				spawn->SetX(client->GetPlayer()->GetX() + .5, false);
+				spawn->SetY(client->GetPlayer()->GetY(), false);
+				spawn->SetZ(client->GetPlayer()->GetZ() + .5, false);
+				float heading = client->GetPlayer()->GetHeading() + 180;
+				if (heading > 360)
+					heading -= 360;
+				spawn->SetLevel(5);
+				spawn->SetAdventureClass(4);
+				spawn->SetHeading(heading, false);
+				spawn->SetSpawnOrigX(spawn->GetX());
+				spawn->SetSpawnOrigY(spawn->GetY());
+				spawn->SetSpawnOrigZ(spawn->GetZ());
+				spawn->SetSpawnOrigHeading(spawn->GetHeading());
+				spawn->appearance.pos.grid_id = client->GetPlayer()->appearance.pos.grid_id;
+				spawn->appearance.targetable = 1;
+				if (spawn->IsNPC() && spawn->GetTotalHP() == 0) {
+					spawn->SetTotalHP(spawn->GetLevel() * 15);
+					spawn->SetHP(spawn->GetTotalHP());
+				}
+				if (spawn->GetTotalPower() == 0) {
+					spawn->SetTotalPower(spawn->GetLevel() * 15);
+					spawn->SetPower(spawn->GetTotalPower());
+				}
+				int16 offset = atoi(sep->arg[1]);
+				int32 value1 = atol(sep->arg[2]);
+				sprintf(spawn->appearance.name, "Offset %i", offset);
+				EQ2Packet* ret = spawn->spawn_serialize(client->GetPlayer(), client->GetVersion(), offset, value1);
+				DumpPacket(ret);
+				client->QueuePacket(ret);
+			}
+		}
+		else if (atoi(sep->arg[0]) == 8) {
+			int32 id = atoi(sep->arg[1]);
+			Spawn* spawn = client->GetCurrentZone()->GetSpawn(id);
+			if (spawn) {
+				spawn->SetX(client->GetPlayer()->GetX() + .5, false);
+				spawn->SetY(client->GetPlayer()->GetY(), false);
+				spawn->SetZ(client->GetPlayer()->GetZ() + .5, false);
+				float heading = client->GetPlayer()->GetHeading() + 180;
+				if (heading > 360)
+					heading -= 360;
+				spawn->SetLevel(5);
+				spawn->SetAdventureClass(4);
+				spawn->SetHeading(heading, false);
+				spawn->SetSpawnOrigX(spawn->GetX());
+				spawn->SetSpawnOrigY(spawn->GetY());
+				spawn->SetSpawnOrigZ(spawn->GetZ());
+				spawn->SetSpawnOrigHeading(spawn->GetHeading());
+				spawn->appearance.pos.grid_id = client->GetPlayer()->appearance.pos.grid_id;
+				spawn->appearance.targetable = 1;
+				if (spawn->IsNPC() && spawn->GetTotalHP() == 0) {
+					spawn->SetTotalHP(spawn->GetLevel() * 15);
+					spawn->SetHP(spawn->GetTotalHP());
+				}
+				if (spawn->GetTotalPower() == 0) {
+					spawn->SetTotalPower(spawn->GetLevel() * 15);
+					spawn->SetPower(spawn->GetTotalPower());
+				}
+				int16 offset = atoi(sep->arg[2]);
+				int16 offset2 = atoi(sep->arg[3]);
+				int32 value1 = atol(sep->arg[4]);
+				int16 offset3 = 0;
+				int16 offset4 = 0;
+				int32 value2 = 0;
+				if (sep->IsSet(7)) {
+					offset3 = atoi(sep->arg[5]);
+					offset4 = atoi(sep->arg[6]);
+					value2 = atol(sep->arg[7]);
+				}
+				sprintf(spawn->appearance.name, "Offset %i to %i", offset, offset2);
+				EQ2Packet* ret = spawn->spawn_serialize(client->GetPlayer(), client->GetVersion(), offset, value1, offset2, offset3, offset4, value2);
+				DumpPacket(ret);
+				client->QueuePacket(ret);
+			}
+		}
+		else if (atoi(sep->arg[0]) == 9) {
+			Item* item = master_item_list.GetItem(70007);
+			EQ2Packet* app = item->serialize(client->GetVersion(), true, client->GetPlayer());
+			if (sep->IsSet(2)) {
+				int8 offset = atoi(sep->arg[1]);
+				uchar* ptr2 = app->pBuffer;
+				ptr2 += offset;
+				if (sep->IsNumber(2)) {
+					int32 value1 = atol(sep->arg[2]);
+					if (value1 > 0xFFFF)
+						memcpy(ptr2, (uchar*)&value1, 4);
+					else if (value1 > 0xFF)
+						memcpy(ptr2, (uchar*)&value1, 2);
+					else
+						memcpy(ptr2, (uchar*)&value1, 1);
+				}
+				else {
+					int8 len = strlen(sep->arg[2]);
+					memcpy(ptr2, (uchar*)&len, 1);
+					ptr2 += 1;
+					memcpy(ptr2, sep->arg[2], len);
+				}
+			}
+			if (sep->IsSet(4)) {
+				int8 offset = atoi(sep->arg[3]);
+				uchar* ptr2 = app->pBuffer;
+				ptr2 += offset;
+				if (sep->IsNumber(4)) {
+					int32 value1 = atol(sep->arg[4]);
+					if (value1 > 0xFFFF)
+						memcpy(ptr2, (uchar*)&value1, 4);
+					else if (value1 > 0xFF)
+						memcpy(ptr2, (uchar*)&value1, 2);
+					else
+						memcpy(ptr2, (uchar*)&value1, 1);
+				}
+				else {
+					int8 len = strlen(sep->arg[4]);
+					memcpy(ptr2, (uchar*)&len, 1);
+					ptr2 += 1;
+					memcpy(ptr2, sep->arg[4], len);
+				}
+			}
+			DumpPacket(app);
+			client->QueuePacket(app);
+		}
+		else if (atoi(sep->arg[0]) == 10) {
+			PacketStruct* packet2 = configReader.getStruct("WS_QuestJournalUpdate", client->GetVersion());
+			if (packet2) {
+				packet2->setArrayLengthByName("num_quests", 1);
+				packet2->setArrayDataByName("active", 1);
+				packet2->setArrayDataByName("name", "Archetype Selection");
+				packet2->setArrayDataByName("quest_type", "Hallmark");
+				packet2->setArrayDataByName("quest_zone", "Hallmark");
+				packet2->setArrayDataByName("journal_updated", 1);
+				packet2->setArrayDataByName("quest_id", 5);
+				packet2->setArrayDataByName("day", 19);
+				packet2->setArrayDataByName("month", 6);
+				packet2->setArrayDataByName("year", 20);
+				packet2->setArrayDataByName("level", 2);
+				packet2->setArrayDataByName("encounter_level", 4);
+				packet2->setArrayDataByName("difficulty", 3);
+				packet2->setArrayDataByName("visible", 1);
+				packet2->setDataByName("visible_quest_id", 5);
+				packet2->setDataByName("player_crc", 2900677088);
+				packet2->setDataByName("player_name", "LethalEncounter");
+				EQ2Packet* app = packet2->serialize();
+				if (sep->IsSet(2)) {
+					int8 offset = atoi(sep->arg[1]);
+					uchar* ptr2 = app->pBuffer;
+					ptr2 += offset;
+					if (sep->IsNumber(2)) {
+						int32 value1 = atol(sep->arg[2]);
+						if (value1 > 0xFFFF)
+							memcpy(ptr2, (uchar*)&value1, 4);
+						else if (value1 > 0xFF)
+							memcpy(ptr2, (uchar*)&value1, 2);
+						else
+							memcpy(ptr2, (uchar*)&value1, 1);
+					}
+					else {
+						int8 len = strlen(sep->arg[2]);
+						memcpy(ptr2, (uchar*)&len, 1);
+						ptr2 += 1;
+						memcpy(ptr2, sep->arg[2], len);
+					}
+				}
+				DumpPacket(app);
+				client->QueuePacket(app);
+				safe_delete(packet2);
+			}
+		}
+		else if (atoi(sep->arg[0]) == 11) {
+			PacketStruct* packet2 = configReader.getStruct("WS_QuestJournalReply", client->GetVersion());
+			if (packet2) {
+				packet2->setDataByName("quest_id", 5);
+				packet2->setDataByName("player_crc", 2900677088);
+				packet2->setDataByName("name", "Archetype Selection");
+				packet2->setDataByName("description", "I have reported my profession to Garven Tralk");
+				packet2->setDataByName("type", "Hallmark");
+				packet2->setDataByName("complete_header", "To complete this quest, I must do the following tasks:");
+				packet2->setDataByName("day", 19);
+				packet2->setDataByName("month", 6);
+				packet2->setDataByName("year", 20);
+				packet2->setDataByName("level", 2);
+				packet2->setDataByName("encounter_level", 4);
+				packet2->setDataByName("difficulty", 3);
+				packet2->setDataByName("time_obtained", Timer::GetUnixTimeStamp());
+				packet2->setDataByName("timer_start", Timer::GetUnixTimeStamp());
+				packet2->setDataByName("timer_duration", 300);
+				packet2->setDataByName("timer_running", 1);
+				packet2->setArrayLengthByName("task_groups_completed", 0);
+				packet2->setArrayLengthByName("num_task_groups", 1);
+				packet2->setArrayDataByName("task_group", "I need to talk to Garven Tralk");
+				packet2->setSubArrayLengthByName("num_tasks", 1);
+				packet2->setSubArrayDataByName("task", "I need to talk to Garven Tralk");
+				packet2->setSubArrayLengthByName("num_updates", 1);
+				packet2->setSubArrayDataByName("update_currentval", 0);
+				packet2->setSubArrayDataByName("update_maxval", 1);
+				packet2->setSubArrayDataByName("icon", 11);
+
+				packet2->setArrayDataByName("waypoint", 0xFFFFFFFF);
+				packet2->setDataByName("journal_updated", 1);
+				EQ2Packet* app = packet2->serialize();
+				if (sep->IsSet(2)) {
+					int16 offset = atoi(sep->arg[1]);
+					uchar* ptr2 = app->pBuffer;
+					ptr2 += offset;
+					if (sep->IsNumber(2)) {
+						int32 value1 = atol(sep->arg[2]);
+						if (value1 > 0xFFFF)
+							memcpy(ptr2, (uchar*)&value1, 4);
+						else if (value1 > 0xFF)
+							memcpy(ptr2, (uchar*)&value1, 2);
+						else
+							memcpy(ptr2, (uchar*)&value1, 1);
+					}
+					else {
+						int16 len = strlen(sep->arg[2]);
+						memcpy(ptr2, (uchar*)&len, 2);
+						ptr2 += 2;
+						memcpy(ptr2, sep->arg[2], len);
+					}
+				}
+				DumpPacket(app);
+				client->QueuePacket(app);
+				safe_delete(packet2);
+			}
+		}
+		else if (atoi(sep->arg[0]) == 12) {
+			PacketStruct* packet2 = configReader.getStruct("WS_QuestJournalReply", client->GetVersion());
+			if (packet2) {
+				packet2->setDataByName("quest_id", 5);
+				packet2->setDataByName("player_crc", 2900677088);
+				packet2->setDataByName("name", "Archetype Selection");
+				packet2->setDataByName("description", "I have reported my profession to Garven Tralk.");
+				packet2->setDataByName("type", "Hallmark");
+				packet2->setDataByName("complete_header", "To complete this quest, I must do the following tasks:");
+				packet2->setDataByName("day", 19);
+				packet2->setDataByName("month", 6);
+				packet2->setDataByName("year", 20);
+				packet2->setDataByName("level", 2);
+				packet2->setDataByName("encounter_level", 4);
+				packet2->setDataByName("difficulty", 3);
+				packet2->setDataByName("time_obtained", Timer::GetUnixTimeStamp());
+				packet2->setDataByName("timer_start", Timer::GetUnixTimeStamp());
+				packet2->setDataByName("timer_duration", 300);
+				packet2->setDataByName("timer_running", 1);
+				packet2->setArrayLengthByName("task_groups_completed", 0);
+				packet2->setArrayLengthByName("num_task_groups", 1);
+				packet2->setArrayDataByName("task_group", "I need to talk to Garven Tralk");
+				packet2->setSubArrayLengthByName("num_tasks", 1);
+				packet2->setSubArrayDataByName("task", "I need to talk to Garven Tralk");
+				packet2->setSubArrayLengthByName("num_updates", 1);
+				packet2->setSubArrayDataByName("update_currentval", 0);
+				packet2->setSubArrayDataByName("update_maxval", 1);
+				packet2->setSubArrayDataByName("icon", 11);
+
+				packet2->setArrayDataByName("waypoint", 0xFFFFFFFF);
+				packet2->setDataByName("journal_updated", 1);
+				packet2->setSubstructDataByName("reward_data", "unknown1", 255);
+				packet2->setSubstructDataByName("reward_data", "reward", "Quest Reward!");
+				packet2->setSubstructDataByName("reward_data", "unknown2", 0x3f);
+				packet2->setSubstructDataByName("reward_data", "coin", 150);
+				packet2->setSubstructDataByName("reward_data", "status_points", 5);
+				packet2->setSubstructDataByName("reward_data", "exp_bonus", 10);
+				packet2->setSubstructArrayLengthByName("reward_data", "num_rewards", 1);
+				packet2->setSubstructArrayDataByName("reward_data", "reward_id", 123);
+				Item* item = master_item_list.GetItem(152755);
+				packet2->setArrayDataByName("reward_id", item->details.item_id);
+				packet2->setItemArrayDataByName("item", item, client->GetPlayer(), 0, 0, -1);
+				/*packet2->setSubstructDataByName("item", "unique_id", 567);
+				packet2->setSubstructDataByName("item", "broker_item_id", 0xFFFFFFFFFFFFFFFF);
+				packet2->setSubstructDataByName("item", "icon", 0xe7);
+				packet2->setSubstructDataByName("item", "tier", 4);
+				packet2->setSubstructDataByName("item", "flags", 0x60);
+				packet2->setSubstructArrayLengthByName("item", "stat_count", 1);
+				packet2->setSubstructDataByName("item", "stat_type", 1);
+				packet2->setSubstructDataByName("item", "stat_subtype", 2);
+				packet2->setSubstructDataByName("item", "value", 3);
+				packet2->setSubstructDataByName("item", "condition", 100);
+				packet2->setSubstructDataByName("item", "weight", 1);
+				packet2->setSubstructDataByName("item", "skill_req1", 0xacafa99e);
+				packet2->setSubstructDataByName("item", "skill_req2", 0xacafa99e);
+				packet2->setSubstructDataByName("item", "skill_min", 1);
+				packet2->setSubstructArrayLengthByName("item", "class_count", 3);
+				packet2->setSubstructDataByName("item", "adventure_class", 1);
+				packet2->setSubstructDataByName("item", "adventure_class", 11, 0, 1);
+				packet2->setSubstructDataByName("item", "adventure_class", 0x1f, 0, 2);
+				packet2->setSubstructDataByName("item", "tradeskill_class", 255);
+				packet2->setSubstructDataByName("item", "tradeskill_class", 255, 0, 1);
+				packet2->setSubstructDataByName("item", "tradeskill_class", 255, 0, 2);
+				packet2->setSubstructDataByName("item", "level", 0x1e);
+				packet2->setSubstructDataByName("item", "level", 100, 0, 1);
+				packet2->setSubstructDataByName("item", "level", 100, 0, 2);
+				packet2->setSubstructDataByName("item_footer", "name", "Footman Gloves");*/
+				//packet2->PrintPacket();
+				EQ2Packet* app = packet2->serialize();
+				if (sep->IsSet(2)) {
+					int16 offset = atoi(sep->arg[1]);
+					uchar* ptr2 = app->pBuffer;
+					ptr2 += offset;
+					if (sep->IsNumber(2)) {
+						int32 value1 = atol(sep->arg[2]);
+						if (value1 > 0xFFFF)
+							memcpy(ptr2, (uchar*)&value1, 4);
+						else if (value1 > 0xFF)
+							memcpy(ptr2, (uchar*)&value1, 2);
+						else
+							memcpy(ptr2, (uchar*)&value1, 1);
+					}
+					else {
+						int16 len = strlen(sep->arg[2]);
+						memcpy(ptr2, (uchar*)&len, 2);
+						ptr2 += 2;
+						memcpy(ptr2, sep->arg[2], len);
+					}
+				}
+				DumpPacket(app);
+				client->QueuePacket(app);
+				safe_delete(packet2);
+			}
+		}
+		else if (atoi(sep->arg[0]) == 13) {
+			PacketStruct* packet2 = configReader.getStruct("WS_OnScreenMsg", client->GetVersion());
+			if (packet2 && sep->IsSet(7)) {
+				packet2->setDataByName("unknown", atoi(sep->arg[1]));
+				char blah[128];
+				sprintf(blah, "\\#6EFF6EYou get better at \12\\#C8FFC8%s\\#6EFF6E! (7/15)", sep->arg[2]);
+				packet2->setDataByName("text", blah);
+				packet2->setDataByName("message_type", sep->arg[3]);
+				packet2->setDataByName("size", atof(sep->arg[4]));
+				packet2->setDataByName("red", atoi(sep->arg[5]));
+				packet2->setDataByName("green", atoi(sep->arg[6]));
+				packet2->setDataByName("blue", atoi(sep->arg[7]));
+				EQ2Packet* app = packet2->serialize();
+				DumpPacket(app);
+				client->QueuePacket(app);
+				safe_delete(packet2);
+			}
+		}
+		else if (atoi(sep->arg[0]) == 14) {
+			PacketStruct* packet2 = configReader.getStruct("WS_InstructionWindow", client->GetVersion());
+			if (packet2 && sep->IsSet(3)) {
+				packet2->setDataByName("open_seconds_min", atof(sep->arg[1]));
+				packet2->setDataByName("open_seconds_max", atof(sep->arg[2]));
+				packet2->setDataByName("voice_sync", atoi(sep->arg[3]));
+				packet2->setDataByName("text", "Welcome to Norrath, the world of EverQuest II. Left click on the help button at any time for more detailed help and information.");
+				packet2->setDataByName("voice", "voiceover/english/narrator/boat_06p_tutorial02/narrator_001_63779ca0.mp3");
+				packet2->setArrayLengthByName("num_goals", 1);
+				//packet2->setArrayDataByName("goal_text", )
+				packet2->setSubArrayLengthByName("num_tasks", 1);
+				packet2->setSubArrayDataByName("task_text", "continue");
+				packet2->setDataByName("complete_sound", "click");
+				packet2->setDataByName("signal", "introduction");
+				packet2->setDataByName("voice_key1", 0xcda65173);
+				packet2->setDataByName("voice_key2", 0x984bfc6d);
+				EQ2Packet* app = packet2->serialize();
+				DumpPacket(app);
+				client->QueuePacket(app);
+				safe_delete(packet2);
+				packet2 = configReader.getStruct("WS_ShowWindow", client->GetVersion());
+				packet2->setDataByName("window", "MainHUD.StartMenu");
+				packet2->setDataByName("show", 1);
+				app = packet2->serialize();
+				DumpPacket(app);
+				client->QueuePacket(app);
+				safe_delete(packet2);
+
+				packet2 = configReader.getStruct("WS_FlashWindow", client->GetVersion());
+				packet2->setDataByName("window", "MainHUD.StartMenu.help");
+				packet2->setDataByName("flash_seconds", 10);
+				app = packet2->serialize();
+				DumpPacket(app);
+				client->QueuePacket(app);
+				safe_delete(packet2);
+			}
+		}
+		else if (atoi(sep->arg[0]) == 15) {
+			PacketStruct* packet2 = configReader.getStruct("WS_UpdateLoot", client->GetVersion());
+			if (packet2) {
+				packet2->setArrayLengthByName("loot_count", 1);
+				packet2->setArrayDataByName("name", "Test");
+				packet2->setArrayDataByName("item_id", 1234);
+				packet2->setArrayDataByName("count", 1);
+				packet2->setArrayDataByName("icon", 258);
+				packet2->setArrayDataByName("ability_id", 0xFFFFFFFF);
+				Spawn* spawn = client->GetPlayer()->GetTarget();
+				if (spawn)
+					packet2->setDataByName("object_id", client->GetPlayer()->GetIDWithPlayerSpawn(spawn));
+				packet2->setDataByName("unknown3", 1);
+				packet2->setDataByName("unknown4", 1);
+				packet2->setDataByName("unknown5", 60);
+				EQ2Packet* app = packet2->serialize();
+				DumpPacket(app);
+				client->QueuePacket(app);
+				safe_delete(packet2);
+			}
+		}
+		else if (atoi(sep->arg[0]) == 16 && sep->IsNumber(1)) {
+			char blah[32];
+			sprintf(blah, "Testing: %i", atoi(sep->arg[1]));
+			client->SimpleMessage(atoi(sep->arg[1]), blah);
+		}
+		else if (atoi(sep->arg[0]) == 17 && sep->IsNumber(2)) {
+			if (sep->IsSet(2)) {
+				int16 offset = atoi(sep->arg[1]);
+				if (sep->IsNumber(2)) {
+					int32 value1 = atol(sep->arg[2]);
+					client->QueuePacket(client->GetPlayer()->GetPlayerInfo()->serialize(client->GetVersion(), offset, value1));
+					cout << "Sent" << endl;
+				}
+			}
+		}
+		else if (atoi(sep->arg[0]) == 18) {
+			PacketStruct* packet2 = configReader.getStruct("WS_QuestRewardPackMsg", client->GetVersion());
+			if (packet2) {
+				packet2->setSubstructDataByName("reward_data", "unknown1", 255);
+				packet2->setSubstructDataByName("reward_data", "reward", "Quest Reward!");
+				packet2->setSubstructDataByName("reward_data", "coin", 150);
+				packet2->setSubstructDataByName("reward_data", "status_points", 5);
+				packet2->setSubstructDataByName("reward_data", "exp_bonus", 10);
+				packet2->setSubstructArrayLengthByName("reward_data", "num_rewards", 4);
+				Item* item = new Item(master_item_list.GetItem(36212));
+				packet2->setArrayDataByName("reward_id", item->details.item_id);
+				item->stack_count = 20;
+				packet2->setItemArrayDataByName("item", item, client->GetPlayer(), 0, 0, -1);
+				safe_delete(item);
+				item = new Item(master_item_list.GetItem(36685));
+				item->stack_count = 20;
+				packet2->setArrayDataByName("reward_id", item->details.item_id);
+				packet2->setItemArrayDataByName("item", item, client->GetPlayer(), 1, 0, -1);
+				safe_delete(item);
+				item = master_item_list.GetItem(1414);
+				packet2->setArrayDataByName("reward_id", item->details.item_id);
+				packet2->setItemArrayDataByName("item", item, client->GetPlayer(), 2, 0, -1);
+				item = master_item_list.GetItem(75057);
+				packet2->setArrayDataByName("reward_id", item->details.item_id);
+				packet2->setItemArrayDataByName("item", item, client->GetPlayer(), 3, 0, -1);
+				EQ2Packet* app = packet2->serialize();
+				if (sep->IsSet(2)) {
+					int16 offset = atoi(sep->arg[1]);
+					uchar* ptr2 = app->pBuffer;
+					ptr2 += offset;
+					if (sep->IsNumber(2)) {
+						int32 value1 = atol(sep->arg[2]);
+						if (value1 > 0xFFFF)
+							memcpy(ptr2, (uchar*)&value1, 4);
+						else if (value1 > 0xFF)
+							memcpy(ptr2, (uchar*)&value1, 2);
+						else
+							memcpy(ptr2, (uchar*)&value1, 1);
+					}
+					else {
+						int16 len = strlen(sep->arg[2]);
+						memcpy(ptr2, (uchar*)&len, 2);
+						ptr2 += 2;
+						memcpy(ptr2, sep->arg[2], len);
+					}
+				}
+				DumpPacket(app);
+				client->QueuePacket(app);
+				safe_delete(packet2);
+			}
+		}
+		else if (atoi(sep->arg[0]) == 19) {
+			PacketStruct* packet2 = configReader.getStruct("WS_UpdateLoot", client->GetVersion());
+			Spawn* spawn = client->GetPlayer()->GetTarget();
+			if (packet2 && spawn) {
+				Item* item = master_item_list.GetItem(130053);
+				packet2->setArrayLengthByName("loot_count", 1);
+				packet2->setArrayDataByName("loot_id", item->details.item_id);
+				packet2->setArrayDataByName("unknown2", 1);
+				packet2->setItemArrayDataByName("item", item, client->GetPlayer(), 0, 0, 2, true);
+				packet2->setDataByName("display", 1);
+				packet2->setDataByName("unknown2b", 1);
+				packet2->setDataByName("unknown3", 0x3c);
+				packet2->setDataByName("spawn_id", client->GetPlayer()->GetIDWithPlayerSpawn(spawn));
+				packet2->PrintPacket();
+				EQ2Packet* app = packet2->serialize();
+				if (sep->IsSet(2)) {
+					int16 offset = atoi(sep->arg[1]);
+					int16 offset2 = 0;
+					int32 value1 = 0;
+					if (sep->IsSet(3)) {
+						offset2 = atoi(sep->arg[2]);
+						value1 = atol(sep->arg[3]);
+					}
+					else
+						value1 = atol(sep->arg[2]);
+					int16 offset3 = 0;
+					int16 offset4 = 0;
+					int32 value2 = 0;
+					if (sep->IsSet(6)) {
+						offset3 = atoi(sep->arg[4]);
+						offset4 = atoi(sep->arg[5]);
+						value2 = atol(sep->arg[6]);
+					}
+					offset--;
+					if (offset2 > 0 && offset2 >= offset) {
+						offset2--;
+						uchar* ptr2 = app->pBuffer;
+						ptr2 += offset;
+						for (int i = offset; i <= offset2; i++) {
+							if (value1 > 0xFFFF) {
+								memcpy(ptr2, (uchar*)&value1, 4);
+								i += 3;
+								ptr2 += 3;
+							}
+							else if (value1 > 0xFF) {
+								memcpy(ptr2, (uchar*)&value1, 2);
+								i++;
+								ptr2++;
+							}
+							else
+								memcpy(ptr2, (uchar*)&value1, 1);
+							ptr2++;
+						}
+					}
+					if (offset4 > 0 && offset4 >= offset3) {
+						offset3--;
+						offset4--;
+						uchar* ptr2 = app->pBuffer;
+						ptr2 += offset3;
+						for (int i = offset3; i <= offset4; i++) {
+							if (value2 > 0xFFFF) {
+								memcpy(ptr2, (uchar*)&value2, 4);
+								i += 3;
+								ptr2 += 3;
+							}
+							else if (value2 > 0xFF) {
+								memcpy(ptr2, (uchar*)&value2, 2);
+								i++;
+								ptr2++;
+							}
+							else
+								memcpy(ptr2, (uchar*)&value2, 1);
+							ptr2++;
+						}
+					}
+				}
+				DumpPacket(app);
+				client->QueuePacket(app);
+				safe_delete(packet2);
+			}
+		}
+		else if (atoi(sep->arg[0]) == 20) {
+			uchar blah[] = { 0x09,0x01,0x00,0x00,0xff,0xc9,0x01,0x03,0x00,0x4d,0xf0,0x00,0x00,0x01
+	,0x00,0x00,0x00,0x4d,0xf0,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xd7
+	,0x05,0x01,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+	,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x64,0x0a,0x8c,0x5a,0xf1,0xd2,0x8c,0x5a,0xf1
+	,0xd2,0x01,0x01,0x00,0xff,0x1e,0x00,0x01,0x03,0x03,0x00,0x00,0x00,0x03,0x07
+	,0x07,0x00,0x10,0x74,0x68,0x72,0x65,0x61,0x64,0x62,0x61,0x72,0x65,0x20,0x74,0x75
+	,0x6e,0x69,0x63,0x00,0x00,0x4e,0xf0,0x00,0x00,0x01,0x00,0x04,0x00,0x4e,0xf0,0x00
+	,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0a,0x00,0x01,0x60,0x00,0x00,0x00
+	,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+	,0x00,0x64,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x03
+	,0x00,0x00,0x00,0x05,0x04,0x04,0x00,0x00,0x00,0x00,0x09,0x73,0x6d,0x61,0x6c,0x6c
+	,0x20,0x62,0x61,0x67,0x00,0x00,0x4f,0xf0,0x00,0x00,0x01,0x00,0x04,0x00,0x4f,0xf0
+	,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x02,0x01,0x01,0x60,0x01,0x00
+	,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+	,0x00,0x00,0x64,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00
+	,0x03,0x00,0x00,0x00,0x00,0x00,0x0c,0x57,0x61,0x75,0x6c,0x6f,0x6e,0x27,0x73,0x20
+	,0x48,0x61,0x74,0x00,0x00,0x01,0x01,0x00,0x00,0x00,0x3c,0x00,0x00,0x00,0x0d,0x00
+	,0x00,0x00 };
+			EQ2Packet* app = new EQ2Packet(OP_ClientCmdMsg, blah, sizeof(blah));
+			if (sep->IsSet(2)) {
+				int16 offset = atoi(sep->arg[1]);
+				uchar* ptr2 = app->pBuffer;
+				ptr2 += offset;
+				if (sep->IsNumber(2)) {
+					int32 value1 = atol(sep->arg[2]);
+					if (value1 > 0xFFFF)
+						memcpy(ptr2, (uchar*)&value1, 4);
+					else if (value1 > 0xFF)
+						memcpy(ptr2, (uchar*)&value1, 2);
+					else
+						memcpy(ptr2, (uchar*)&value1, 1);
+				}
+				else {
+					int16 len = strlen(sep->arg[2]);
+					memcpy(ptr2, (uchar*)&len, 2);
+					ptr2 += 2;
+					memcpy(ptr2, sep->arg[2], len);
+				}
+			}
+			DumpPacket(app);
+			client->QueuePacket(app);
+		}
+	}
+
+	else if (atoi(sep->arg[0]) == 21) {
+		PacketStruct* packet2 = configReader.getStruct("WS_OfferQuest", client->GetVersion());
+		if (packet2) {
+			packet2->setDataByName("unknown0", 255);
+			packet2->setDataByName("reward", "New Quest");
+			packet2->setDataByName("title", "Title");
+			packet2->setDataByName("description", "description");
+			packet2->setDataByName("quest_difficulty", 3);
+			packet2->setDataByName("unknown1", 5);
+			packet2->setDataByName("level", 3);
+			packet2->setDataByName("coin", 150);
+			packet2->setDataByName("status_points", 5);
+			packet2->setDataByName("exp_bonus", 10);
+			packet2->setArrayLengthByName("num_rewards", 1);
+			Item* item = new Item(master_item_list.GetItem(36212));
+			packet2->setArrayDataByName("reward_id", item->details.item_id);
+			item->stack_count = 20;
+			packet2->setItemArrayDataByName("item", item, client->GetPlayer(), 0, 0, -1);
+			safe_delete(item);
+			char accept[35] = { 0 };
+			char decline[35] = { 0 };
+			sprintf(accept, "q_accept_pending_quest %u", 0);
+			sprintf(decline, "q_deny_pending_quest %u", 0);
+			packet2->setDataByName("accept_command", accept);
+			packet2->setDataByName("decline_command", decline);
+			EQ2Packet* app = packet2->serialize();
+			if (sep->IsSet(2)) {
+				int16 offset = atoi(sep->arg[1]);
+				uchar* ptr2 = app->pBuffer;
+				ptr2 += offset;
+				if (sep->IsNumber(2)) {
+					int32 value1 = atol(sep->arg[2]);
+					if (value1 > 0xFFFF)
+						memcpy(ptr2, (uchar*)&value1, 4);
+					else if (value1 > 0xFF)
+						memcpy(ptr2, (uchar*)&value1, 2);
+					else
+						memcpy(ptr2, (uchar*)&value1, 1);
+				}
+				else {
+					int16 len = strlen(sep->arg[2]);
+					memcpy(ptr2, (uchar*)&len, 2);
+					ptr2 += 2;
+					memcpy(ptr2, sep->arg[2], len);
+				}
+			}
+			DumpPacket(app);
+			client->QueuePacket(app);
+			safe_delete(packet2);
+		}
+	}
+	else if (atoi(sep->arg[0]) == 22) { //same as 21, but 8bit string
+		PacketStruct* packet2 = configReader.getStruct("WS_OfferQuest", client->GetVersion());
+		if (packet2) {
+			packet2->setDataByName("unknown0", 255);
+			packet2->setDataByName("reward", "New Quest");
+			packet2->setDataByName("title", "Title");
+			packet2->setDataByName("description", "description");
+			packet2->setDataByName("quest_difficulty", 3);
+			packet2->setDataByName("unknown1", 5);
+			packet2->setDataByName("level", 3);
+			packet2->setDataByName("coin", 150);
+			packet2->setDataByName("status_points", 5);
+			packet2->setDataByName("exp_bonus", 10);
+			packet2->setArrayLengthByName("num_rewards", 1);
+			Item* item = new Item(master_item_list.GetItem(36212));
+			packet2->setArrayDataByName("reward_id", item->details.item_id);
+			item->stack_count = 20;
+			packet2->setItemArrayDataByName("item", item, client->GetPlayer(), 0, 0, -1);
+			safe_delete(item);
+			char accept[35] = { 0 };
+			char decline[35] = { 0 };
+			sprintf(accept, "q_accept_pending_quest %u", 0);
+			sprintf(decline, "q_deny_pending_quest %u", 0);
+			packet2->setDataByName("accept_command", accept);
+			packet2->setDataByName("decline_command", decline);
+			EQ2Packet* app = packet2->serialize();
+			if (sep->IsSet(2)) {
+				int16 offset = atoi(sep->arg[1]);
+				uchar* ptr2 = app->pBuffer;
+				ptr2 += offset;
+				if (sep->IsNumber(2)) {
+					int32 value1 = atol(sep->arg[2]);
+					if (value1 > 0xFFFF)
+						memcpy(ptr2, (uchar*)&value1, 4);
+					else if (value1 > 0xFF)
+						memcpy(ptr2, (uchar*)&value1, 2);
+					else
+						memcpy(ptr2, (uchar*)&value1, 1);
+				}
+				else {
+					int8 len = strlen(sep->arg[2]);
+					memcpy(ptr2, (uchar*)&len, 1);
+					ptr2 += 1;
+					memcpy(ptr2, sep->arg[2], len);
+				}
+			}
+			DumpPacket(app);
+			client->QueuePacket(app);
+			safe_delete(packet2);
+		}
+	}
+	else {
+			PacketStruct* packet2 = configReader.getStruct("WS_ExamineSpellInfo", client->GetVersion());
+			if (packet2) {
+				packet2->setSubstructDataByName("info_header", "show_name", 1);
+				packet2->setSubstructDataByName("info_header", "unknown", 7);
+				packet2->setSubstructDataByName("info_header", "unknown2", 1);
+				packet2->setSubstructDataByName("info_header", "unknown3", 1);
+				packet2->setSubstructDataByName("info_header", "unknown4", 1);
+				packet2->setSubstructDataByName("info_header", "unknown5", 1);
+				packet2->setSubstructDataByName("info_header", "unknown6", "Testing");
+				packet2->setSubstructDataByName("info_header", "unknown7", "Testing");
+				packet2->setSubstructDataByName("info_header", "unknown8", 66);
+				packet2->setSubstructDataByName("info_header", "title", "Blah Title Blah");
+				packet2->setSubstructDataByName("info_header", "title_text", "Blah Blah");
+				packet2->setSubstructDataByName("info_header", "title_text2", "Blah Blah2");
+				packet2->setSubstructDataByName("info_header", "show_popup", 1);
+				packet2->setSubstructDataByName("info_header", "packettype", 3);
+				packet2->setSubstructDataByName("spell_info", "skill_name", "Testing");
+				packet2->setSubstructDataByName("spell_info", "level", 19);
+				packet2->setSubstructDataByName("spell_info", "tier", 1);
+				packet2->setSubstructDataByName("spell_info", "health_cost", 5);
+				packet2->setSubstructDataByName("spell_info", "min_class_skill_req", 3); 
+				packet2->setSubstructDataByName("spell_info", "mana_cost", 6);
+				packet2->setSubstructDataByName("spell_info", "req_concentration", 7);
+				packet2->setSubstructDataByName("spell_info", "cast_time", 200);
+				packet2->setSubstructDataByName("spell_info", "recovery", 220);
+				packet2->setSubstructDataByName("spell_info", "recast", 280);
+				packet2->setSubstructDataByName("spell_info", "beneficial", 1);
+				packet2->setSubstructDataByName("spell_info", "maintained", 1);
+				packet2->setSubstructDataByName("spell_info", "spell_book_type", 1);
+				packet2->setSubstructDataByName("spell_info", "quality", 3);
+
+				packet2->setSubstructDataByName("spell_info", "test_1a", 1);
+				packet2->setSubstructDataByName("spell_info", "test_1b", 1);
+				packet2->setSubstructDataByName("spell_info", "test_1c", 1);
+				packet2->setSubstructDataByName("spell_info", "test_1d", 1);
+				packet2->setSubstructDataByName("spell_info", "test_2a", 2);
+				packet2->setSubstructDataByName("spell_info", "test_2b", 2);
+				packet2->setSubstructDataByName("spell_info", "test_2c", 2);
+				packet2->setSubstructDataByName("spell_info", "test_2d", 2);
+				packet2->setSubstructDataByName("spell_info", "test_3", 3);
+				packet2->setSubstructDataByName("spell_info", "test_4", 4);
+				packet2->setSubstructDataByName("spell_info", "test_5", 5);
+				packet2->setSubstructDataByName("spell_info", "test_6", 6);
+				packet2->setSubstructDataByName("spell_info", "min_class_skill_req", 1);
+				packet2->setSubstructDataByName("spell_info", "min_class_skill_rec", 30123);
+				packet2->setSubstructDataByName("spell_info", "num_reagents", 1);
+				packet2->setSubstructArrayLengthByName("spell_info", "num_reagents", 1);
+				packet2->setArrayDataByName("reagent", "Alcohol");
+				packet2->setArrayDataByName("consumed", "123");
+				packet2->setSubstructDataByName("spell_info", "class_skill", 52);
+				packet2->setSubstructDataByName("spell_info", "id", 8308);
+				packet2->setSubstructDataByName("spell_info", "icon", 303);
+				packet2->setSubstructDataByName("spell_info", "icon2", 0xFFFF);
+				packet2->setSubstructDataByName("spell_info", "icontype", 317);
+				packet2->setSubstructDataByName("spell_info", "type", 2);
+				packet2->setSubstructDataByName("spell_info", "spell_text_color", 255);
+				packet2->setSubstructDataByName("spell_info", "duration1", 600);
+				packet2->setSubstructDataByName("spell_info", "duration2", 600);
+				packet2->setSubstructDataByName("spell_info", "name", "Sprint");
+				packet2->setSubstructDataByName("spell_info", "description", "Test description");
+				EQ2Packet* outapp = packet2->serialize();
+				DumpPacket(outapp);
+				client->QueuePacket(outapp);
+				safe_delete(packet2);
+			}
+		}
+	return;
 	PacketStruct* p = configReader.getStruct("WS_EqTargetItemCmd", client->GetVersion());
 	if (!p) return;
 

+ 11 - 0
EQ2/source/WorldServer/Commands/Commands.h

@@ -74,6 +74,17 @@ extern map<int16,OpcodeManager*>EQOpcodeManager;
 #define CHANNEL_OOC			32
 //#define CHANNEL_AUCTION		30
 
+#define CLASSIC_CLIENT_CHANNEL_SAY			10
+#define CLASSIC_CLIENT_CHANNEL_SHOUT		11
+#define CLASSIC_CLIENT_CHANNEL_EMOTE		12
+#define CLASSIC_CLIENT_CHANNEL_GROUP		26
+#define CLASSIC_CLIENT_CHANNEL_RAID			27
+#define CLASSIC_CLIENT_CHANNEL_GUILD		32
+#define CLASSIC_CLIENT_CHANNEL_OFFICER		33
+#define CLASSIC_CLIENT_CHANNEL_SAYTARGET	40 // you say to xxx
+#define CLASSIC_CLIENT_CHANNEL_TELL			41 // you tell xxx
+#define CLASSIC_CLIENT_CHANNEL_OOC			49
+
 #define CHANNEL_GAME_TEXT					1
 #define CHANNEL_DEFAULT						2
 #define CHANNEL_ERROR						3

+ 278 - 128
EQ2/source/WorldServer/Items/Items.cpp

@@ -1682,16 +1682,40 @@ void Item::serialize(PacketStruct* packet, bool show_name, Player* player, int16
 	packet->setSubstructDataByName("header_info", "unknown21", 0x00000000);
 	packet->setSubstructDataByName("header_info", "condition", generic_info.condition);
 	packet->setSubstructDataByName("header_info", "weight", generic_info.weight);
-	if(generic_info.skill_req1 == 0)
-		packet->setSubstructDataByName("header_info", "skill_req1", 0xFFFFFFFF);
-	else
-		packet->setSubstructDataByName("header_info", "skill_req1", generic_info.skill_req1);
-	if(generic_info.skill_req2 == 0)
-		packet->setSubstructDataByName("header_info", "skill_req2", 0xFFFFFFFF);
-	else
-		packet->setSubstructDataByName("header_info", "skill_req2", generic_info.skill_req2);
+	if (packet->GetVersion() <= 283) { //orig client only has one skill
+		if (generic_info.skill_req1 == 0 || generic_info.skill_req1 == 0xFFFFFFFF) {
+			if (generic_info.skill_req2 != 0 && generic_info.skill_req2 != 0xFFFFFFFF) {
+				packet->setSubstructDataByName("header_info", "skill_req1", generic_info.skill_req2);
+			}
+			else {
+				packet->setSubstructDataByName("header_info", "skill_req1", 0xFFFFFFFF);
+			}
+		}
+		else {
+			packet->setSubstructDataByName("header_info", "skill_req1", generic_info.skill_req1);
+		}
+	}
+	else {
+		if (generic_info.skill_req1 == 0)
+			packet->setSubstructDataByName("header_info", "skill_req1", 0xFFFFFFFF);
+		else
+			packet->setSubstructDataByName("header_info", "skill_req1", generic_info.skill_req1);
+		if (generic_info.skill_req2 == 0)
+			packet->setSubstructDataByName("header_info", "skill_req2", 0xFFFFFFFF);
+		else
+			packet->setSubstructDataByName("header_info", "skill_req2", generic_info.skill_req2);
+	}
 	if(generic_info.skill_min != 0)
 		packet->setSubstructDataByName("header_info", "skill_min", generic_info.skill_min);
+	if (client->GetVersion() <= 283) {
+		string flags;
+		if (CheckFlag(NO_TRADE))
+			flags += "NO-TRADE   ";
+		if (CheckFlag(NO_VALUE))
+			flags += "NO-VALUE   ";
+		if(flags.length() > 0)
+			packet->setSubstructDataByName("header_info", "flag_names", flags.c_str());
+	}
 	if(generic_info.adventure_classes > 0 || generic_info.tradeskill_classes > 0 || item_level_overrides.size() > 0){
 		//int64 classes = 0;
 		int16 tmp_level = 0;
@@ -1785,7 +1809,10 @@ void Item::serialize(PacketStruct* packet, bool show_name, Player* player, int16
 			classes = 36024082983773912;
 		
 	}
-
+	if (client->GetVersion() <= 283 && generic_info.adventure_default_level > 0) {
+		packet->setSubstructDataByName("header_info", "skill_min", (generic_info.adventure_default_level-1)*5+1);
+		packet->setSubstructDataByName("header_info", "skill_recommended", details.recommended_level * 5);
+	}
 	packet->setSubstructDataByName("footer", "recommended_level", details.recommended_level);
 	if(generic_info.adventure_default_level > 0){
 		packet->setSubstructDataByName("footer", "required_level", generic_info.adventure_default_level);
@@ -1799,6 +1826,14 @@ void Item::serialize(PacketStruct* packet, bool show_name, Player* player, int16
 		packet->setSubstructArrayLengthByName("header_info", "slot_count", slot_data.size());
 		for(int32 i=0;i<slot_data.size();i++){
 			int8 slot = slot_data[i];
+			if (client->GetVersion() <= 283) {
+				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)
+					slot = EQ2_ORIG_FOOD_SLOT;
+				else if(slot == EQ2_DRINK_SLOT)
+					slot = EQ2_ORIG_DRINK_SLOT;
+			}
 			packet->setArrayDataByName("slot", slot, i);
 		}
 	}
@@ -1810,95 +1845,130 @@ void Item::serialize(PacketStruct* packet, bool show_name, Player* player, int16
 		switch(generic_info.item_type){
 			case ITEM_TYPE_WEAPON:{
 				if(weapon_info){
-					packet->setDataByName("wield_type", weapon_info->wield_type);
-					packet->setDataByName("damage_low1", weapon_info->damage_low1);
-					packet->setDataByName("damage_high1", weapon_info->damage_high1);
-					packet->setDataByName("damage_low2", weapon_info->damage_low2);
-					packet->setDataByName("damage_high2", weapon_info->damage_high2);
-					packet->setDataByName("damage_low3", weapon_info->damage_low3);
-					packet->setDataByName("damage_high3", weapon_info->damage_high3);
-					packet->setDataByName("damage_type", weapon_type);
-					packet->setDataByName("delay", weapon_info->delay);
-					packet->setDataByName("rating", weapon_info->rating);
+					if (client->GetVersion() <= 283) {
+						packet->setSubstructDataByName("details", "wield_type", weapon_info->wield_type);
+						packet->setSubstructDataByName("details", "damage_low1", weapon_info->damage_low1);
+						packet->setSubstructDataByName("details", "damage_high1", weapon_info->damage_high1);
+						packet->setSubstructDataByName("details", "damage_low2", weapon_info->damage_low2);
+						packet->setSubstructDataByName("details", "damage_high2", weapon_info->damage_high2);
+						packet->setSubstructDataByName("details", "damage_type", weapon_type);
+						packet->setSubstructDataByName("details", "delay", weapon_info->delay);
+					}
+					else {
+						packet->setDataByName("wield_type", weapon_info->wield_type);
+						packet->setDataByName("damage_low1", weapon_info->damage_low1);
+						packet->setDataByName("damage_high1", weapon_info->damage_high1);
+						packet->setDataByName("damage_low2", weapon_info->damage_low2);
+						packet->setDataByName("damage_high2", weapon_info->damage_high2);
+						packet->setDataByName("damage_low3", weapon_info->damage_low3);
+						packet->setDataByName("damage_high3", weapon_info->damage_high3);
+						packet->setDataByName("damage_type", weapon_type);
+						packet->setDataByName("delay", weapon_info->delay);
+						packet->setDataByName("rating", weapon_info->rating);
+					}
 				}
 				break;
 			}
 			case ITEM_TYPE_RANGED:{
 				if(ranged_info){
-					packet->setDataByName("damage_low1", ranged_info->weapon_info.damage_low1);
-					packet->setDataByName("damage_high1", ranged_info->weapon_info.damage_high1);
-					packet->setDataByName("damage_low2", ranged_info->weapon_info.damage_low2);
-					packet->setDataByName("damage_high2", ranged_info->weapon_info.damage_high2);
-					packet->setDataByName("damage_low3", ranged_info->weapon_info.damage_low3);
-					packet->setDataByName("damage_high3", ranged_info->weapon_info.damage_high3);
-					packet->setDataByName("delay", ranged_info->weapon_info.delay);
-					packet->setDataByName("range_low", ranged_info->range_low);
-					packet->setDataByName("range_high", ranged_info->range_high);
-					packet->setDataByName("rating", ranged_info->weapon_info.rating);
+					if (client->GetVersion() <= 283) {
+						packet->setSubstructDataByName("details", "damage_low1", ranged_info->weapon_info.damage_low1);
+						packet->setSubstructDataByName("details", "damage_high1", ranged_info->weapon_info.damage_high1);
+						packet->setSubstructDataByName("details", "damage_low2", ranged_info->weapon_info.damage_low2);
+						packet->setSubstructDataByName("details", "damage_high2", ranged_info->weapon_info.damage_high2);
+						packet->setSubstructDataByName("details", "delay", ranged_info->weapon_info.delay);
+						packet->setSubstructDataByName("details", "range_low", ranged_info->range_low);
+						packet->setSubstructDataByName("details", "range_high", ranged_info->range_high);
+					}
+					else {
+						packet->setDataByName("damage_low1", ranged_info->weapon_info.damage_low1);
+						packet->setDataByName("damage_high1", ranged_info->weapon_info.damage_high1);
+						packet->setDataByName("damage_low2", ranged_info->weapon_info.damage_low2);
+						packet->setDataByName("damage_high2", ranged_info->weapon_info.damage_high2);
+						packet->setDataByName("damage_low3", ranged_info->weapon_info.damage_low3);
+						packet->setDataByName("damage_high3", ranged_info->weapon_info.damage_high3);
+						packet->setDataByName("delay", ranged_info->weapon_info.delay);
+						packet->setDataByName("range_low", ranged_info->range_low);
+						packet->setDataByName("range_high", ranged_info->range_high);
+						packet->setDataByName("rating", ranged_info->weapon_info.rating);
+					}
 				}
 				break;
 			}
 			case ITEM_TYPE_SHIELD:
 			case ITEM_TYPE_ARMOR:{
 				if(armor_info){
-					packet->setDataByName("mitigation_low", armor_info->mitigation_low);
-					packet->setDataByName("mitigation_high", armor_info->mitigation_high);
+					if (client->GetVersion() <= 283) {
+						packet->setSubstructDataByName("details", "mitigation_low", armor_info->mitigation_low);
+						packet->setSubstructDataByName("details", "mitigation_high", armor_info->mitigation_high);
+					}
+					else {
+						packet->setDataByName("mitigation_low", armor_info->mitigation_low);
+						packet->setDataByName("mitigation_high", armor_info->mitigation_high);
+					}
 				}
 				break;
 			}
 			case ITEM_TYPE_BAG:{
 				if(bag_info){
-					int16 free_slots=bag_info->num_slots;
-					if(player){
-						Item* bag = player->GetPlayerItemList()->GetItemFromUniqueID(details.unique_id, true);
-						if(bag && bag->IsBag()){
-							vector<Item*>* bag_items = player->GetPlayerItemList()->GetItemsInBag(bag);
-							if(bag_items->size() > bag->bag_info->num_slots){
-								free_slots = 0;
-								packet->setArrayLengthByName("num_names", bag->bag_info->num_slots);
-							}
-							else{
-								free_slots = bag->bag_info->num_slots - bag_items->size();
-								packet->setArrayLengthByName("num_names", bag_items->size());
-							}
-							vector<Item*>::iterator itr;
-							int16 i = 0;
-							Item* tmp_bag_item = 0;
-							for(itr = bag_items->begin(); itr != bag_items->end();itr++){
-								tmp_bag_item = *itr;
-								if(tmp_bag_item && tmp_bag_item->details.slot_id < bag->bag_info->num_slots){
-									packet->setArrayDataByName("item_name", tmp_bag_item->name.c_str(), i);
-									i++;
+					if (client->GetVersion() <= 283) {
+						if (bag_info->num_slots > CLASSIC_EQ_MAX_BAG_SLOTS)
+							bag_info->num_slots = CLASSIC_EQ_MAX_BAG_SLOTS;
+						packet->setSubstructDataByName("details", "num_slots", bag_info->num_slots);
+						packet->setSubstructDataByName("details", "weight_reduction", bag_info->weight_reduction);
+					}
+					else {
+						int16 free_slots = bag_info->num_slots;
+						if (player) {
+							Item* bag = player->GetPlayerItemList()->GetItemFromUniqueID(details.unique_id, true);
+							if (bag && bag->IsBag()) {
+								vector<Item*>* bag_items = player->GetPlayerItemList()->GetItemsInBag(bag);
+								if (bag_items->size() > bag->bag_info->num_slots) {
+									free_slots = 0;
+									packet->setArrayLengthByName("num_names", bag->bag_info->num_slots);
+								}
+								else {
+									free_slots = bag->bag_info->num_slots - bag_items->size();
+									packet->setArrayLengthByName("num_names", bag_items->size());
+								}
+								vector<Item*>::iterator itr;
+								int16 i = 0;
+								Item* tmp_bag_item = 0;
+								for (itr = bag_items->begin(); itr != bag_items->end(); itr++) {
+									tmp_bag_item = *itr;
+									if (tmp_bag_item && tmp_bag_item->details.slot_id < bag->bag_info->num_slots) {
+										packet->setArrayDataByName("item_name", tmp_bag_item->name.c_str(), i);
+										i++;
+									}
 								}
+								safe_delete(bag_items);
 							}
-							safe_delete(bag_items);
 						}
+						packet->setDataByName("num_slots", bag_info->num_slots);
+						packet->setDataByName("num_empty", free_slots);
+						packet->setDataByName("weight_reduction", bag_info->weight_reduction);
+						packet->setDataByName("item_score", 2);
+						//packet->setDataByName("unknown5", 0x1e50a86f);
+						//packet->setDataByName("unknown6", 0x2c17f61d);
+						//1 armorer
+						//2 weaponsmith
+						//4 tailor
+						//16 jeweler 
+						//32 sage
+						//64 alchemist
+						//120 all scholars
+						//250 all craftsman
+						//int8 blah[] = {0x00,0x00,0x01,0x01,0xb6,0x01,0x01};
+						//int8 blah[] = {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
+						int8 blah[] = { 0xd8,0x66,0x9b,0x6d,0xb6,0xfb,0x7f };
+						for (int8 i = 0; i < sizeof(blah); i++)
+							packet->setSubstructDataByName("footer", "footer_unknown_0", blah[i], 0, i);
 					}
-					packet->setDataByName("num_slots", bag_info->num_slots);
-					packet->setDataByName("num_empty", free_slots);
-					packet->setDataByName("weight_reduction", bag_info->weight_reduction);
-					packet->setDataByName("item_score", 2);
-					//packet->setDataByName("unknown5", 0x1e50a86f);
-					//packet->setDataByName("unknown6", 0x2c17f61d);
-					//1 armorer
-					//2 weaponsmith
-					//4 tailor
-					//16 jeweler 
-					//32 sage
-					//64 alchemist
-					//120 all scholars
-					//250 all craftsman
- 					//int8 blah[] = {0x00,0x00,0x01,0x01,0xb6,0x01,0x01};
-					//int8 blah[] = {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
-   					int8 blah[] = {0xd8,0x66,0x9b,0x6d,0xb6,0xfb,0x7f};
-					for(int8 i=0;i<sizeof(blah);i++)
-						packet->setSubstructDataByName("footer", "footer_unknown_0", blah[i], 0, i);
-					
 				}
 				break;
 			}
 			case ITEM_TYPE_FOOD:{
-				if(food_info){
+				if(food_info && client->GetVersion() >=284){
 					packet->setDataByName("food_type", food_info->type);
 					packet->setDataByName("level", food_info->level);
 					packet->setDataByName("duration", food_info->duration);
@@ -1910,7 +1980,7 @@ void Item::serialize(PacketStruct* packet, bool show_name, Player* player, int16
 				if(skill_info->spell_id > 0){
 					Spell* spell = master_spell_list.GetSpell(skill_info->spell_id, skill_info->spell_tier);
 					if(spell){
-						if(player) {
+						if(player && client->GetVersion() >= 284) {
 							packet->setSubstructDataByName("header_info", "footer_type", 0);
 							
 							spell->SetPacketInformation(packet, player->GetZone()->GetClientBySpawn(player));
@@ -1926,8 +1996,7 @@ void Item::serialize(PacketStruct* packet, bool show_name, Player* player, int16
 							packet->setDataByName("require_previous", 0);
 							
 						}
-						else {
-							
+						else {							
 							spell->SetPacketInformation(packet);
 						}
 
@@ -1937,7 +2006,7 @@ void Item::serialize(PacketStruct* packet, bool show_name, Player* player, int16
 				break;
 			}
 			case ITEM_TYPE_BAUBLE:{
-				if(bauble_info){
+				if(bauble_info && client->GetVersion() >= 284){
 					packet->setDataByName("cast", bauble_info->cast);
 					packet->setDataByName("recovery", bauble_info->recovery);
 					packet->setDataByName("duration", bauble_info->duration);
@@ -1953,7 +2022,7 @@ void Item::serialize(PacketStruct* packet, bool show_name, Player* player, int16
 				break;
 			}
 			case ITEM_TYPE_THROWN:{
-				if(thrown_info){
+				if(thrown_info && client->GetVersion() >= 284){
 					packet->setDataByName("range", thrown_info->range);
 					packet->setDataByName("damage_modifier", thrown_info->damage_modifier);
 					packet->setDataByName("hit_bonus", thrown_info->hit_bonus);
@@ -1962,7 +2031,7 @@ void Item::serialize(PacketStruct* packet, bool show_name, Player* player, int16
 				break;
 			}
 			case ITEM_TYPE_HOUSE:{
-				if(houseitem_info){
+				if(houseitem_info && client->GetVersion() >= 284){
 					packet->setDataByName("status_rent_reduction", houseitem_info->status_rent_reduction);
 					packet->setDataByName("coin_rent_reduction", houseitem_info->coin_rent_reduction);
 					packet->setDataByName("house_only", houseitem_info->house_only);
@@ -1970,7 +2039,7 @@ void Item::serialize(PacketStruct* packet, bool show_name, Player* player, int16
 				break;
 			}
 			case ITEM_TYPE_BOOK:{
-				if(book_info){
+				if(book_info && client->GetVersion() >= 284){
 					packet->setDataByName("language", book_info->language);
 					packet->setMediumStringByName("author", book_info->author.data.c_str());
 					packet->setMediumStringByName("title", book_info->title.data.c_str());
@@ -2001,22 +2070,23 @@ void Item::serialize(PacketStruct* packet, bool show_name, Player* player, int16
 			}
 			case ITEM_TYPE_ADORNMENT:{
 				//Adornements
-				packet->setDataByName("item_types",adornment_info->item_types);
-				packet->setDataByName("duration", adornment_info->duration); // need to calcualte for remaining duration
-				packet->setDataByName("slot_type", adornment_info->slot_type);
-				packet->setDataByName("footer_set_name", "test footer set name");
-				packet->setArrayLengthByName("footer_set_bonus_list_count", 1);// list of the bonus items
+				if (client->GetVersion() >= 284) {
+					packet->setDataByName("item_types", adornment_info->item_types);
+					packet->setDataByName("duration", adornment_info->duration); // need to calcualte for remaining duration
+					packet->setDataByName("slot_type", adornment_info->slot_type);
+					packet->setDataByName("footer_set_name", "test footer set name");
+					packet->setArrayLengthByName("footer_set_bonus_list_count", 1);// list of the bonus items
 					packet->setArrayDataByName("footer_set_bonus_items_needed", 2, 0);  //this is nember of items needed for granteing that  stat //name,value,array
 					packet->setSubArrayLengthByName("footer_set_bonus_stats_count", 2, 0);//name,value,array,subarray
-						packet->setSubArrayDataByName("set_stat_type", 5, 0,0);
-						packet->setSubArrayDataByName("set_stat_subtype", 1, 0, 0);
-						packet->setSubArrayDataByName("set_value", 25000, 0, 0);
+					packet->setSubArrayDataByName("set_stat_type", 5, 0, 0);
+					packet->setSubArrayDataByName("set_stat_subtype", 1, 0, 0);
+					packet->setSubArrayDataByName("set_value", 25000, 0, 0);
+				}
 						
-			}
-			
+			}			
 			case ITEM_TYPE_HOUSE_CONTAINER:{
 				//House Containers
-				if(housecontainer_info){
+				if(housecontainer_info && client->GetVersion() >= 284){
 					packet->setDataByName("allowed_types", housecontainer_info->allowed_types);
 					packet->setDataByName("num_slots", housecontainer_info->num_slots);
 					packet->setDataByName("broker_commission", housecontainer_info->broker_commission);
@@ -2120,10 +2190,13 @@ 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)
+	if(loot_item && version > 546)
 		packet = configReader.getStruct("WS_LootItemGeneric", version);
-	else{
-		switch(generic_info.item_type){
+	else{		
+		int8 tmpType = generic_info.item_type;
+		if (version <= 283 && generic_info.item_type > ITEM_TYPE_RECIPE)
+			tmpType = 0;
+		switch(tmpType){
 			case ITEM_TYPE_WEAPON:{
 				if(merchant_item)
 					packet = configReader.getStruct("WS_MerchantItemWeapon", version);
@@ -2236,6 +2309,8 @@ PacketStruct* Item::PrepareItem(int16 version, bool merchant_item, bool loot_ite
 					packet = configReader.getStruct("WS_ItemGeneric", version);
 			}
 		}
+		if (packet && loot_item)
+			packet->AddFlag("loot");
 	}
 	if(!packet){
 		LogWrite(ITEM__ERROR, 0, "Item", "Unhandled Item type: %i", (int)generic_info.item_type);
@@ -2248,6 +2323,10 @@ 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) {
+		include_twice = false;
+		packet_type = 0;
+	}
 	if(include_twice && IsBag() == false && IsBauble() == false && IsFood() == false)
 		serialize(packet, show_name, player, packet_type, 0x80, loot_item);
 	else
@@ -2270,8 +2349,24 @@ EQ2Packet* Item::serialize(int16 version, bool show_name, Player* player, bool i
 	if(include_twice && IsBag() == false && IsBauble() == false && IsFood() == false){
 		memcpy(out_ptr, (uchar*)generic_string_data->c_str() + 13, generic_string_data->length() -13);
 	}
-	int32 size2 = size-4;
-	memcpy(out_data, &size2, sizeof(int32));
+	int32 size2 = size;
+	if (version <= 283) {
+		uchar* out_ptr2 = out_data;
+		if (size2 >= 0xFF) {
+			size2 -= 3;			
+			out_ptr2[0] = 0xFF;
+			out_ptr2 += sizeof(int8);
+			memcpy(out_ptr2, &size2, sizeof(int16));
+		}
+		else {
+			size2 -= 1;
+			out_ptr2[0] = size2;
+		}
+	}
+	else {
+		size2 -= 4;
+		memcpy(out_data, &size2, sizeof(int32));
+	}
 	EQ2Packet* outapp = new EQ2Packet(OP_ClientCmdMsg, out_data, size);
 	//DumpPacket(outapp);
 	safe_delete(packet);
@@ -2971,6 +3066,7 @@ EQ2Packet* PlayerItemList::serialize(Player* player, int16 version){
 #endif
 		packet->setDataByName("equip_flag",0);
 		app = packet->serializeCountPacket(version, 1, orig_packet, xor_packet);
+		DumpPacket(app);
 		safe_delete(packet);
 	}
 	MPlayerItems.releasereadlock(__FUNCTION__, __LINE__);
@@ -2983,15 +3079,20 @@ void PlayerItemList::AddItemToPacket(PacketStruct* packet, Player* player, Item*
 	if (!packet || !player)
 		return;
 	client = player->GetZone()->GetClientBySpawn(player);
-	
-	
+	if (!client)
+		return;
 	
 	int32 menu_data = 3;
-
 	if(item->slot_data.size() > 0)
-		menu_data -= ITEM_MENU_TYPE_GENERIC;
-	if(item->details.num_slots > 0)
+		menu_data -= ITEM_MENU_TYPE_GENERIC;	
+
+	if (item->details.num_slots > 0) {
+		if (packet->GetVersion() <= 283 && item->details.num_slots > CLASSIC_EQ_MAX_BAG_SLOTS)
+			item->details.num_slots = CLASSIC_EQ_MAX_BAG_SLOTS;
 		menu_data += ITEM_MENU_TYPE_BAG;
+		if (item->details.num_free_slots == item->details.num_slots)
+			menu_data += ITEM_MENU_TYPE_EMPTY_BAG;
+	}
 	if (item->details.item_id == 21355) {
 		//menu_data += ITEM_MENU_TYPE_GENERIC;
 		//menu_data += ITEM_MENU_TYPE_EQUIP;
@@ -3006,7 +3107,7 @@ void PlayerItemList::AddItemToPacket(PacketStruct* packet, Player* player, Item*
 		//menu_data += ITEM_MENU_TYPE_BROKEN;
 	}
 	if (item->details.item_id == 21356) {
-		menu_data += ITEM_MENU_TYPE_TEST15;
+		//menu_data += ITEM_MENU_TYPE_TEST15;
 		menu_data += ITEM_MENU_TYPE_ATTUNED;
 		menu_data += ITEM_MENU_TYPE_ATTUNEABLE;
 		menu_data += ITEM_MENU_TYPE_BOOK;
@@ -3034,11 +3135,10 @@ void PlayerItemList::AddItemToPacket(PacketStruct* packet, Player* player, Item*
 	}
 	if(item->IsSkill()){
 		Spell* spell = master_spell_list.GetSpell(item->skill_info->spell_id, item->skill_info->spell_tier);
-		if (spell && spell->ScribeAllowed(player))
-			
+		if (spell && spell->ScribeAllowed(player))			
 			menu_data += ITEM_MENU_TYPE_SCRIBE;
 		else
-			menu_data += ITEM_MENU_TYPE_INVALID;
+			menu_data += ITEM_MENU_TYPE_INSUFFICIENT_KNOWLEDGE;
 	}
 	if(item->IsRecipeBook()){
 		//TODO: Add check to allow scribe
@@ -3050,19 +3150,41 @@ void PlayerItemList::AddItemToPacket(PacketStruct* packet, Player* player, Item*
 	}
 	if (item->generic_info.item_type == 18){
 		menu_data += ITEM_MENU_TYPE_UNPACK; 
-		packet->setSubstructArrayDataByName("items", "unknown3", ITEM_MENU_TYPE2_UNPACK, 0, i);
+		packet->setSubstructArrayDataByName("flag_names", "unknown3", ITEM_MENU_TYPE2_UNPACK, 0, i);
 	}
 
 	if(item->generic_info.condition == 0)
 		menu_data += ITEM_MENU_TYPE_BROKEN;
-	if(item->CheckFlag(ATTUNED) || item->CheckFlag(NO_TRADE))
-		menu_data += ITEM_MENU_TYPE_ATTUNED;
-	else if(item->CheckFlag(ATTUNEABLE))
-		menu_data += ITEM_MENU_TYPE_ATTUNEABLE;
+	if (client->GetVersion() <= 283){
+		string flags;
+		if (item->CheckFlag(NO_TRADE))
+			flags += "NO-TRADE   ";
+		if (item->CheckFlag(NO_VALUE))
+			flags += "NO-VALUE   ";
+		if (flags.length() > 0)
+			packet->setSubstructArrayDataByName("items", "flag_names", flags.c_str(), 0, i);
+	}
+
+	if (item->CheckFlag(ATTUNED) || item->CheckFlag(NO_TRADE)) {
+		if (client->GetVersion() <= 283)
+			menu_data += ORIG_ITEM_MENU_TYPE_ATTUNED;
+		else
+			menu_data += ITEM_MENU_TYPE_ATTUNED;
+	}
+	else if (item->CheckFlag(ATTUNEABLE)) {
+		if (client->GetVersion() <= 283)
+			menu_data += ORIG_ITEM_MENU_TYPE_ATTUNEABLE;
+		else
+			menu_data += ITEM_MENU_TYPE_ATTUNEABLE;
+	}
 	if (item->generic_info.usable == 1)
 		menu_data += ITEM_MENU_TYPE_USE;
-	if (item->details.count > 0 && item->stack_count > 1)
-		menu_data += ITEM_MENU_TYPE_DISPLAY_CHARGES;
+	if (item->details.count > 0 && item->stack_count > 1) {
+		if (client->GetVersion() <= 283)
+			menu_data += ORIG_ITEM_MENU_TYPE_STACKABLE;
+		else
+			menu_data += ITEM_MENU_TYPE_DISPLAY_CHARGES;
+	}
 	// Added the if (overflow) so mouseover examines work properly
 	if (overflow)
 		packet->setSubstructArrayDataByName("items", "unique_id", item->details.item_id, 0, i);
@@ -3351,12 +3473,15 @@ EQ2Packet* EquipmentItemList::serialize(int16 version, Player* player){
 		PacketStruct* packet2 = configReader.getStruct("Substruct_Item", version);
 		packet_size = packet2->GetTotalPacketSize();
 		safe_delete(packet2);
-		packet->setArrayLengthByName("item_count", NUM_SLOTS);
+		int8 num_slots = NUM_SLOTS;
+		if (version <= 564)
+			num_slots = 22;
+		packet->setArrayLengthByName("item_count", num_slots);
 		if(!orig_packet){
-			xor_packet = new uchar[packet_size*NUM_SLOTS];
-			orig_packet = new uchar[packet_size*NUM_SLOTS];
-			memset(xor_packet, 0, packet_size*NUM_SLOTS);
-			memset(orig_packet, 0, packet_size*NUM_SLOTS);
+			xor_packet = new uchar[packet_size* num_slots];
+			orig_packet = new uchar[packet_size* num_slots];
+			memset(xor_packet, 0, packet_size* num_slots);
+			memset(orig_packet, 0, packet_size* num_slots);
 		}
 		MEquipmentItems.lock();
 		int32 menu_data = 3;
@@ -3366,31 +3491,56 @@ EQ2Packet* EquipmentItemList::serialize(int16 version, Player* player){
 			if(item && item->details.item_id > 0){
 				if(item->slot_data.size() > 0)
 					menu_data -= ITEM_MENU_TYPE_GENERIC;
-				if(item->details.num_slots > 0)
+				if (item->details.num_slots > 0) {
+					if (packet->GetVersion() <= 283 && item->details.num_slots > CLASSIC_EQ_MAX_BAG_SLOTS)
+						item->details.num_slots = CLASSIC_EQ_MAX_BAG_SLOTS;
 					menu_data += ITEM_MENU_TYPE_BAG;
+					if (item->details.num_free_slots == item->details.num_slots)
+						menu_data += ITEM_MENU_TYPE_EMPTY_BAG;
+				}
 				if(item->IsSkill())
 					menu_data += ITEM_MENU_TYPE_SCRIBE;
 				if(item->generic_info.condition == 0)
 					menu_data += ITEM_MENU_TYPE_BROKEN2;
 				else if (item->generic_info.condition <= 20)
 					menu_data += ITEM_MENU_TYPE_DAMAGED;
-				if(item->CheckFlag(ATTUNED) || item->CheckFlag(NO_TRADE))
-					menu_data += ITEM_MENU_TYPE_ATTUNED;
-				else if(item->CheckFlag(ATTUNEABLE))
-					menu_data += ITEM_MENU_TYPE_ATTUNEABLE;
+				if (item->CheckFlag(ATTUNED) || item->CheckFlag(NO_TRADE)) {
+					if (version <= 283)
+						menu_data += ORIG_ITEM_MENU_TYPE_ATTUNED;
+					else
+						menu_data += ITEM_MENU_TYPE_ATTUNED;
+				}
+				else if (item->CheckFlag(ATTUNEABLE)) {
+					if (version <= 283)
+						menu_data += ORIG_ITEM_MENU_TYPE_ATTUNEABLE;
+					else
+						menu_data += ITEM_MENU_TYPE_ATTUNEABLE;
+				}
 				if (item->generic_info.usable == 1)
 					menu_data += ITEM_MENU_TYPE_USE;
 				if (item->IsFood())
 				{
-					menu_data += ITEM_MENU_TYPE_CONSUME;
-					if (player && ((item->IsFoodFood() && player->get_character_flag(CF_FOOD_AUTO_CONSUME)) || (item->IsFoodDrink() && player->get_character_flag(CF_DRINK_AUTO_CONSUME))))
-						menu_data += ITEM_MENU_TYPE_CONSUME_OFF;
+					if (version <= 283) {						
+						if (item->IsFoodDrink())
+							menu_data += ORIG_ITEM_MENU_TYPE_DRINK;
+						else
+							menu_data += ORIG_ITEM_MENU_TYPE_FOOD;
+					}
+					else {
+						menu_data += ITEM_MENU_TYPE_CONSUME;
+						if (player && ((item->IsFoodFood() && player->get_character_flag(CF_FOOD_AUTO_CONSUME)) || (item->IsFoodDrink() && player->get_character_flag(CF_DRINK_AUTO_CONSUME))))
+							menu_data += ITEM_MENU_TYPE_CONSUME_OFF;
+					}
 				}
 				packet->setSubstructArrayDataByName("items", "unique_id", item->details.unique_id, 0, i);
 				packet->setSubstructArrayDataByName("items", "bag_id", item->details.bag_id, 0, i);
 				packet->setSubstructArrayDataByName("items", "inv_slot_id", item->details.inv_slot_id, 0, i);
-				if(item->details.count > 0 && item->stack_count > 1)
-					menu_data += ITEM_MENU_TYPE_DISPLAY_CHARGES;
+				if (item->details.count > 0 && item->stack_count > 1) {
+					if (version <= 283)
+						menu_data += ORIG_ITEM_MENU_TYPE_STACKABLE;
+					else
+						menu_data += ITEM_MENU_TYPE_DISPLAY_CHARGES;
+				}
 				packet->setSubstructArrayDataByName("items", "menu_type", menu_data, 0, i);
 				packet->setSubstructArrayDataByName("items", "icon", item->details.icon, 0, i);
 				packet->setSubstructArrayDataByName("items", "slot_id", item->details.slot_id, 0, i);

+ 16 - 5
EQ2/source/WorldServer/Items/Items.h

@@ -63,6 +63,8 @@ extern MasterItemList master_item_list;
 #define EQ2_NAKED_CHEST_SLOT 28
 #define EQ2_NAKED_LEGS_SLOT 29
 #define EQ2_BACK_SLOT 30
+#define EQ2_ORIG_FOOD_SLOT 18
+#define EQ2_ORIG_DRINK_SLOT 19
 
 #define PRIMARY_SLOT 1
 #define SECONDARY_SLOT 2
@@ -95,7 +97,10 @@ extern MasterItemList master_item_list;
 #define NAKED_CHEST_SLOT 268435456
 #define NAKED_LEGS_SLOT 536870912
 #define BACK_SLOT 1073741824
+#define ORIG_FOOD_SLOT 524288
+#define ORIG_DRINK_SLOT 1048576
 
+#define CLASSIC_EQ_MAX_BAG_SLOTS 20
 #define NUM_BANK_SLOTS 12
 #define NUM_SHARED_BANK_SLOTS 8
 #define NUM_SLOTS 25
@@ -190,13 +195,13 @@ extern MasterItemList master_item_list;
 #define ITEM_MENU_TYPE_EQUIP			2 //1
 #define ITEM_MENU_TYPE_BAG				4//2
 #define ITEM_MENU_TYPE_HOUSE			8 //3 Place
-#define ITEM_MENU_TYPE_TEST12			16	//4
+#define ITEM_MENU_TYPE_EMPTY_BAG		16	//4
 #define ITEM_MENU_TYPE_SCRIBE			32//5
-#define ITEM_MENU_TYPE_TEST13			64//6
-#define ITEM_MENU_TYPE_INVALID			128//7
-#define ITEM_MENU_TYPE_TEST14			256//8
+#define ITEM_MENU_TYPE_BANK_BAG			64//6
+#define ITEM_MENU_TYPE_INSUFFICIENT_KNOWLEDGE			128//7
+#define ITEM_MENU_TYPE_ACTIVATE			256//8
 #define ITEM_MENU_TYPE_BROKEN			512//9
-#define ITEM_MENU_TYPE_TEST15			1024//10
+#define ITEM_MENU_TYPE_TWO_HANDED		1024//10
 #define ITEM_MENU_TYPE_ATTUNED			2048//11
 #define ITEM_MENU_TYPE_ATTUNEABLE		4096//12 
 #define ITEM_MENU_TYPE_BOOK				8192//13
@@ -219,6 +224,12 @@ extern MasterItemList master_item_list;
 #define ITEM_MENU_TYPE_REDEEM	        536870912 //29 //READ??
 #define ITEM_MENU_TYPE_TEST10			1073741824 //30
 #define ITEM_MENU_TYPE_UNPACK			2147483648//31 * on items i found this unpack is used at same time as UNPACK below
+#define ORIG_ITEM_MENU_TYPE_FOOD		2048
+#define ORIG_ITEM_MENU_TYPE_DRINK		4096
+#define ORIG_ITEM_MENU_TYPE_ATTUNED		8192
+#define ORIG_ITEM_MENU_TYPE_ATTUNEABLE	16384
+#define ORIG_ITEM_MENU_TYPE_BOOK		32768
+#define ORIG_ITEM_MENU_TYPE_STACKABLE	65536
 
 #define ITEM_MENU_TYPE2_TEST1			1 //0 auto consume on
 #define ITEM_MENU_TYPE2_TEST2			2 //1

+ 302 - 0
EQ2/source/WorldServer/LuaFunctions.cpp

@@ -9297,6 +9297,308 @@ int EQ2Emu_lua_ProcHate(lua_State* state) {
 	return 0;
 }
 
+int EQ2Emu_lua_AddLootToObject(lua_State* state) {
+	if (!lua_interface)
+		return 0;
+	Spawn* object = lua_interface->GetSpawn(state);
+	Spawn* player = lua_interface->GetSpawn(state, 2);
+	if (object && player && player->IsPlayer()) {
+		int32 coins = lua_interface->GetInt32Value(state, 3);
+		vector<Item*>* items = 0;
+		int i = 0;
+		int32 item_id = 0;
+		while ((item_id = lua_interface->GetInt32Value(state, 4 + i))) {
+			if (items == 0)
+				items = new vector<Item*>;
+			if (master_item_list.GetItem(item_id))
+				items->push_back(master_item_list.GetItem(item_id));
+			i++;
+		}
+		Client* client = 0;
+		client = object->GetZone()->GetClientBySpawn(player);
+		if (client) {
+			((Player*)player)->AddPendingLootItems(object->GetID(), items);
+		}
+		safe_delete(items);
+	}
+	return 0;
+}
+
+int EQ2Emu_lua_DisplayText(lua_State* state) {
+	if (!lua_interface)
+		return 0;
+	Spawn* player = lua_interface->GetSpawn(state);
+	int8 type = lua_interface->GetInt8Value(state, 2);
+	string text = lua_interface->GetStringValue(state, 3);
+	Client* client = 0;
+	if (player && player->IsPlayer())
+		client = player->GetZone()->GetClientBySpawn(player);
+	if (!client || text.length() == 0) {
+		lua_interface->LogError("%s: LUA DisplayText required parameters not given", lua_interface->GetScriptName(state));
+		return 0;
+	}
+	client->SimpleMessage(type, text.c_str());
+	return 0;
+}
+
+int EQ2Emu_lua_ShowLootWindow(lua_State* state) {
+	if (!lua_interface)
+		return 0;
+	Spawn* player = lua_interface->GetSpawn(state);
+	Spawn* spawn = lua_interface->GetSpawn(state, 2);
+	Client* client = 0;
+	if (player && player->IsPlayer())
+		client = player->GetZone()->GetClientBySpawn(player);
+	if (!client || !spawn) {
+		lua_interface->LogError("%s: LUA ShowLootWindow required parameters not given", lua_interface->GetScriptName(state));
+		return 0;
+	}
+	vector<Item*>* items = ((Player*)player)->GetPendingLootItems(spawn->GetID());
+	if (!items) {
+		lua_interface->LogError("%s: LUA ShowLootWindow has no items", lua_interface->GetScriptName(state));
+		return 0;
+	}
+	client->Loot(0, items, spawn);
+	/*PacketStruct* packet2 = configReader.getStruct("WS_UpdateLoot", client->GetVersion());
+	if (packet2) {
+		packet2->setArrayLengthByName("loot_count", items->size());
+		for(int i=0;i< items->size();i++){
+			Item* item = (*items)[0];
+			packet2->setArrayDataByName("name", item->name.c_str(), i);
+			packet2->setArrayDataByName("item_id", item->details.item_id, i);
+			packet2->setArrayDataByName("count", item->details.count, i);
+			packet2->setArrayDataByName("icon", item->details.icon, i);
+			if(item->generic_info.skill_req1 > 0 && item->generic_info.skill_req1 < 0xFFFFFFFF)
+				packet2->setArrayDataByName("ability_id", item->generic_info.skill_req1, i);
+			else if (item->generic_info.skill_req2 > 0 && item->generic_info.skill_req2 < 0xFFFFFFFF)
+				packet2->setArrayDataByName("ability_id", item->generic_info.skill_req2, i);
+			else
+				packet2->setArrayDataByName("ability_id", 0xFFFFFFFF, i);
+		}
+		packet2->setDataByName("object_id", spawn->GetID());
+		packet2->setDataByName("unknown3", 1);
+		packet2->setDataByName("unknown4", 1);
+		packet2->setDataByName("unknown5", 60);
+		EQ2Packet* app = packet2->serialize();
+		DumpPacket(app);
+		client->QueuePacket(app);
+		safe_delete(packet2);
+	}*/
+	return 0;
+}
+
+int EQ2Emu_lua_GetRandomSpawnByID(lua_State* state) {
+	if (!lua_interface)
+		return 0;
+	Spawn* spawnref = lua_interface->GetSpawn(state);
+	int32 spawn_id = lua_interface->GetInt32Value(state, 2);
+	if (spawn_id > 0 && spawnref) {
+		vector<Spawn*> spawns = spawnref->GetZone()->GetSpawnsByID(spawn_id);
+		if (spawns.size() == 0) {
+			lua_interface->LogError("%s: LUA EQ2Emu_lua_GetRandomSpawnByID command error: GetSpawnsByID returned no spawns", lua_interface->GetScriptName(state));
+			return 0;
+		}
+		Spawn* spawn = 0;
+		int16 index = MakeRandomInt(0, spawns.size());
+		if (index >= spawns.size() || index < 0)
+			index = 0;
+		spawn = spawns[index];
+		lua_interface->SetSpawnValue(state, spawn);
+		return 1;
+	}
+	else {
+		lua_interface->LogError("%s: LUA GetRandomSpawnByID required parameters not given", lua_interface->GetScriptName(state));
+	}
+
+	return 0;
+}
+
+int EQ2Emu_lua_AddPrimaryEntityCommandAllSpawns(lua_State* state) {
+	Spawn* player = lua_interface->GetSpawn(state);
+	int32 spawn_id = lua_interface->GetInt32Value(state, 2);
+	string name = lua_interface->GetStringValue(state, 3);
+	float distance = lua_interface->GetFloatValue(state, 4);
+	string command = lua_interface->GetStringValue(state, 5);
+	string error_text = lua_interface->GetStringValue(state, 6);
+	int16 cast_time = lua_interface->GetInt16Value(state, 7);
+	int32 spell_visual = lua_interface->GetInt32Value(state, 8);
+	if (spawn_id && player && player->IsPlayer() && name.length() > 0) {
+		if (distance == 0)
+			distance = 10.0f;
+		if (command.length() == 0)
+			command = name;
+		vector<Spawn*> spawns = player->GetZone()->GetSpawnsByID(spawn_id);
+		if (spawns.size() == 0) {
+			lua_interface->LogError("%s: LUA AddPrimaryEntityCommandAllSpawns command error: GetSpawnsByID returned no spawns", lua_interface->GetScriptName(state));
+			return 0;
+		}
+		Spawn* spawn = 0;
+		for (vector<Spawn*>::iterator itr = spawns.begin(); itr != spawns.end(); itr++) {
+			spawn = *itr;
+			if (spawn) {
+				spawn->AddPrimaryEntityCommand(name.c_str(), distance, command.c_str(), error_text.c_str(), cast_time, spell_visual);
+				player->GetZone()->SendUpdateDefaultCommand(spawn, command.c_str(), distance);
+			}
+		}
+
+	}
+	return 0;
+}
+
+int EQ2Emu_lua_InstructionWindow(lua_State* state) {
+	if (!lua_interface)
+		return 0;
+	Client* client = 0;
+	Spawn* player = lua_interface->GetSpawn(state);
+	float duration = lua_interface->GetFloatValue(state, 2);
+	string text = lua_interface->GetStringValue(state, 3);
+	string voice = lua_interface->GetStringValue(state, 4);
+	int32 voice_key1 = lua_interface->GetInt32Value(state, 5);
+	int32 voice_key2 = lua_interface->GetInt32Value(state, 6);
+	string signal = lua_interface->GetStringValue(state, 7);
+	string goal1 = lua_interface->GetStringValue(state, 8);
+	string task1 = lua_interface->GetStringValue(state, 9);
+	string goal2 = lua_interface->GetStringValue(state, 10);
+	string task2 = lua_interface->GetStringValue(state, 11);
+	string goal3 = lua_interface->GetStringValue(state, 12);
+	string task3 = lua_interface->GetStringValue(state, 13);
+	string goal4 = lua_interface->GetStringValue(state, 14);
+	string task4 = lua_interface->GetStringValue(state, 15);
+
+	if (!player) {
+		lua_interface->LogError("LUA InstructionWindow command error: spawn is not valid");
+		return 0;
+	}
+	if (!player->IsPlayer()) {
+		lua_interface->LogError("LUA InstructionWindow command error: spawn is not a player");
+		return 0;
+	}
+	if (player->GetZone())
+		client = player->GetZone()->GetClientBySpawn(player);
+
+	if (!client) {
+		lua_interface->LogError("LUA InstructionWindow command error: could not find client");
+		return 0;
+	}
+	if (text.length() == 0 || task1.length() == 0 || signal.length() == 0) {
+		lua_interface->LogError("LUA InstructionWindow required parameters not given");
+		return 0;
+	}
+	if (duration >= 0 && duration < 2)
+		duration = 2;
+	PacketStruct* packet = configReader.getStruct("WS_InstructionWindow", client->GetVersion());
+	if (packet) {
+		packet->setDataByName("open_seconds_max", duration);
+		packet->setDataByName("text", text.c_str());
+		packet->setDataByName("voice", voice.c_str());
+		int8 num_goals = 1;
+		if (task2.length() > 0)
+			num_goals++;
+		if (task3.length() > 0)
+			num_goals++;
+		if (task4.length() > 0)
+			num_goals++;
+		packet->setArrayLengthByName("num_goals", num_goals);
+		for (int8 i = 0; i < num_goals; i++) {
+			packet->setSubArrayLengthByName("num_tasks", 1, i);
+		}
+		if (goal1.length() > 0)
+			packet->setArrayDataByName("goal_text", goal1.c_str());
+		if (goal2.length() > 0)
+			packet->setArrayDataByName("goal_text", goal2.c_str(), 1);
+		if (goal3.length() > 0)
+			packet->setArrayDataByName("goal_text", goal3.c_str(), 2);
+		if (goal4.length() > 0)
+			packet->setArrayDataByName("goal_text", goal4.c_str(), 3);
+		packet->setSubArrayDataByName("task_text", task1.c_str());
+		if (task2.length() > 0)
+			packet->setSubArrayDataByName("task_text", task2.c_str(), 1);
+		if (task3.length() > 0)
+			packet->setSubArrayDataByName("task_text", task3.c_str(), 2);
+		if (task4.length() > 0)
+			packet->setSubArrayDataByName("task_text", task4.c_str(), 3);
+		packet->setDataByName("complete_sound", "click");
+		packet->setDataByName("signal", signal.c_str());
+		packet->setDataByName("voice_key1", voice_key1);
+		packet->setDataByName("voice_key2", voice_key2);
+		client->QueuePacket(packet->serialize());
+		safe_delete(packet);
+	}
+	return 0;
+}
+
+int EQ2Emu_lua_ShowWindow(lua_State* state) {
+	if (!lua_interface)
+		return 0;
+	Client* client = 0;
+	Spawn* player = lua_interface->GetSpawn(state);
+	string window = lua_interface->GetStringValue(state, 2);
+	int8 show = lua_interface->GetInt8Value(state, 3);
+	if (!player) {
+		lua_interface->LogError("LUA ShowWindow command error: spawn is not valid");
+		return 0;
+	}
+	if (!player->IsPlayer()) {
+		lua_interface->LogError("LUA ShowWindow command error: spawn is not a player");
+		return 0;
+	}
+	if (player->GetZone())
+		client = player->GetZone()->GetClientBySpawn(player);
+
+	if (!client) {
+		lua_interface->LogError("LUA ShowWindow command error: could not find client");
+		return 0;
+	}
+	if (window.length() == 0) {
+		lua_interface->LogError("LUA ShowWindow required parameters not given");
+		return 0;
+	}
+	PacketStruct* packet = configReader.getStruct("WS_ShowWindow", client->GetVersion());
+	if (packet) {
+		packet->setDataByName("window", window.c_str());
+		packet->setDataByName("show", show);
+		client->QueuePacket(packet->serialize());
+		safe_delete(packet);
+	}
+	return 0;
+}
+
+int EQ2Emu_lua_FlashWindow(lua_State* state) {
+	if (!lua_interface)
+		return 0;
+	Client* client = 0;
+	Spawn* player = lua_interface->GetSpawn(state);
+	string window = lua_interface->GetStringValue(state, 2);
+	float flash_seconds = lua_interface->GetFloatValue(state, 3);
+	if (!player) {
+		lua_interface->LogError("LUA FlashWindow command error: spawn is not valid");
+		return 0;
+	}
+	if (!player->IsPlayer()) {
+		lua_interface->LogError("LUA FlashWindow command error: spawn is not a player");
+		return 0;
+	}
+	if (player->GetZone())
+		client = player->GetZone()->GetClientBySpawn(player);
+
+	if (!client) {
+		lua_interface->LogError("LUA FlashWindow command error: could not find client");
+		return 0;
+	}
+	if (window.length() == 0) {
+		lua_interface->LogError("LUA FlashWindow required parameters not given");
+		return 0;
+	}
+	PacketStruct* packet = configReader.getStruct("WS_FlashWindow", client->GetVersion());
+	if (packet) {
+		packet->setDataByName("window", window.c_str());
+		packet->setDataByName("flash_seconds", flash_seconds);
+		client->QueuePacket(packet->serialize());
+		safe_delete(packet);
+	}
+	return 0;
+}
+
 int EQ2Emu_lua_CheckLOS(lua_State* state) {
 	if (!lua_interface)
 		return 0;

+ 9 - 0
EQ2/source/WorldServer/LuaFunctions.h

@@ -156,6 +156,7 @@ int EQ2Emu_lua_AddLootItem(lua_State* state);
 int EQ2Emu_lua_RemoveLootItem(lua_State* state);
 int EQ2Emu_lua_AddLootCoin(lua_State* state);
 int EQ2Emu_lua_GiveLoot(lua_State* state);
+int EQ2Emu_lua_AddLootToObject(lua_State* state);
 int EQ2Emu_lua_HasPendingLoot(lua_State* state);
 int EQ2Emu_lua_HasPendingLootItem(lua_State* state);
 int EQ2Emu_lua_CreateConversation(lua_State* state);
@@ -416,6 +417,14 @@ int EQ2Emu_lua_StartTransmute(lua_State* state);
 int EQ2Emu_lua_CompleteTransmute(lua_State* state);
 int EQ2Emu_lua_ProcHate(lua_State* state);
 
+int EQ2Emu_lua_DisplayText(lua_State* state);
+int EQ2Emu_lua_ShowLootWindow(lua_State* state);
+int EQ2Emu_lua_GetRandomSpawnByID(lua_State* state);
+int EQ2Emu_lua_AddPrimaryEntityCommandAllSpawns(lua_State* state);
+int EQ2Emu_lua_InstructionWindow(lua_State* state);
+int EQ2Emu_lua_ShowWindow(lua_State* state);
+int EQ2Emu_lua_FlashWindow(lua_State* state);
+
 int EQ2Emu_lua_CheckLOS(lua_State* state);
 int EQ2Emu_lua_CheckLOSByCoordinates(lua_State* state);
 

+ 15 - 2
EQ2/source/WorldServer/LuaInterface.cpp

@@ -1018,6 +1018,15 @@ void LuaInterface::RegisterFunctions(lua_State* state) {
 	lua_register(state, "CompleteTransmute", EQ2Emu_lua_CompleteTransmute);
 	lua_register(state, "ProcHate", EQ2Emu_lua_ProcHate);
 
+	lua_register(state, "GetRandomSpawnByID", EQ2Emu_lua_GetRandomSpawnByID);
+	lua_register(state, "AddLootToObject", EQ2Emu_lua_AddLootToObject);
+	lua_register(state, "ShowLootWindow", EQ2Emu_lua_ShowLootWindow);
+	lua_register(state, "AddPrimaryEntityCommandAllSpawns", EQ2Emu_lua_AddPrimaryEntityCommandAllSpawns);
+	lua_register(state, "InstructionWindow", EQ2Emu_lua_InstructionWindow);
+	lua_register(state, "ShowWindow", EQ2Emu_lua_ShowWindow);
+	lua_register(state, "FlashWindow", EQ2Emu_lua_FlashWindow);
+	lua_register(state, "DisplayText", EQ2Emu_lua_DisplayText);
+
 	lua_register(state, "CheckLOS", EQ2Emu_lua_CheckLOS);
 	lua_register(state, "CheckLOSByCoordinates", EQ2Emu_lua_CheckLOSByCoordinates);
 
@@ -1645,7 +1654,7 @@ bool LuaInterface::RunSpawnScript(string script_name, const char* function_name,
 		return false;
 }
 
-bool LuaInterface::RunZoneScript(string script_name, const char* function_name, ZoneServer* zone, Spawn* spawn, int32 grid_id)  {
+bool LuaInterface::RunZoneScript(string script_name, const char* function_name, ZoneServer* zone, Spawn* spawn, int32 grid_id, const char* signal) {
 	if (!zone)
 		return false;
 	lua_State* state = GetZoneScript(script_name.c_str(), true, true);
@@ -1659,7 +1668,7 @@ bool LuaInterface::RunZoneScript(string script_name, const char* function_name,
 			return false;
 		}
 		lua_getglobal(state, function_name);
-		if (!lua_isfunction(state, lua_gettop(state))){
+		if (!lua_isfunction(state, lua_gettop(state))) {
 			lua_pop(state, 1);
 			mutex->releasereadlock(__FUNCTION__);
 			UseZoneScript(script_name.c_str(), state, false);
@@ -1675,6 +1684,10 @@ bool LuaInterface::RunZoneScript(string script_name, const char* function_name,
 			SetInt32Value(state, grid_id);
 			num_params++;
 		}
+		if (signal) {
+			SetStringValue(state, signal);
+			num_params++;
+		}
 		if (!CallZoneScript(state, num_params)) {
 			if (mutex)
 				mutex->releasereadlock(__FUNCTION__, __LINE__);

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

@@ -220,7 +220,7 @@ public:
 	bool			CallItemScript(lua_State* state, int8 num_parameters);
 	bool			RunSpawnScript(string script_name, const char* function_name, Spawn* npc, Spawn* spawn = 0, const char* message = 0);
 	bool			CallSpawnScript(lua_State* state, int8 num_parameters);
-	bool			RunZoneScript(string script_name, const char* function_name, ZoneServer* zone, Spawn* spawn = 0, int32 grid_id = 0);
+	bool			RunZoneScript(string script_name, const char* function_name, ZoneServer* zone, Spawn* spawn = 0, int32 grid_id = 0, const char* signal = 0);
 	bool			CallZoneScript(lua_State* state, int8 num_parameters);
 	void			ResetFunctionStack(lua_State* state);
 	void			DestroySpells();

File diff suppressed because it is too large
+ 421 - 216
EQ2/source/WorldServer/Player.cpp


+ 7 - 2
EQ2/source/WorldServer/Player.h

@@ -315,8 +315,8 @@ class PlayerInfo {
 public:
 	~PlayerInfo();
 	PlayerInfo(Player* in_player);
-	
-	EQ2Packet* serialize(int16 version);
+
+	EQ2Packet* serialize(int16 version, int16 modifyPos = 0, int32 modifyValue = 0);
 	PacketStruct* serialize2(int16 version);
 	EQ2Packet* serialize3(PacketStruct* packet, int16 version);
 	EQ2Packet* serializePet(int16 version);
@@ -442,6 +442,8 @@ public:
 	bool CanEquipItem(Item* item);
 	void SetEquippedItemAppearances();
 	vector<EQ2Packet*>	UnequipItem(int16 index, sint32 bag_id, int8 slot, int16 version);
+	int8 ConvertSlotToClient(int8 slot, int16 version);
+	int8 ConvertSlotFromClient(int8 slot, int16 version);
 	EQ2Packet* SwapEquippedItems(int8 slot1, int8 slot2, int16 version);
 	EQ2Packet*	RemoveInventoryItem(int8 bag_slot, int8 slot);
 	EQ2Packet*	SendInventoryUpdate(int16 version);
@@ -554,6 +556,8 @@ public:
 	void	SetSpawnDeleteTime(int32 id, int32 time);
 	int32	GetSpawnDeleteTime(int32 id);
 	void	ClearEverything();
+	bool	IsFullyLoggedIn();
+	void	SetFullyLoggedIn(bool val);
 	bool	IsResurrecting();
 	void	SetResurrecting(bool val);
 	int8	GetArrowColor(int8 spawn_level);
@@ -875,6 +879,7 @@ private:
 	Spawn*              combat_target;
 	int32				char_id;
 	bool				quickbar_updated;
+	bool				fully_logged_in;
 	bool				resurrecting;
 	PlayerInfo*			info;
 	vector<SpellBookEntry*> spells;

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

@@ -845,6 +845,7 @@ void Quest::SetQuestID(int32 in_id){
 }
 
 EQ2Packet* Quest::OfferQuest(int16 version, Player* player){
+	return 0;
 	PacketStruct* packet = configReader.getStruct("WS_OfferQuest", version);
 	if(packet){	
 		packet->setDataByName("reward", "Quest Reward!");

+ 12 - 5
EQ2/source/WorldServer/Skills.cpp

@@ -319,18 +319,21 @@ EQ2Packet* PlayerSkillList::GetSkillPacket(int16 version){
 	PacketStruct* packet = configReader.getStruct("WS_UpdateSkillBook", version);
 	if(packet){
 		if(packet_count < skills.size()){
-			if(!orig_packet){
-				int16 size = 21*skills.size()+8;
+			int16 size = 21 * skills.size() + 8;
+			if (version <= 283) {
+				size = 12 * skills.size()+6;
+			}
+			if(!orig_packet){				
 				xor_packet = new uchar[size];
 				orig_packet = new uchar[size];
 				memset(xor_packet, 0, size);
 				memset(orig_packet, 0, size);
+				orig_packet_size = size;
 			}
 			else{
-				int16 size = 21*skills.size()+8;
 				uchar* tmp = new uchar[size];
 				memset(tmp, 0, size);
-				memcpy(tmp, orig_packet, 21*packet_count+8);
+				memcpy(tmp, orig_packet, orig_packet_size);
 				safe_delete_array(orig_packet);
 				orig_packet = tmp;
 				safe_delete_array(xor_packet);
@@ -368,8 +371,12 @@ EQ2Packet* PlayerSkillList::GetSkillPacket(int16 version){
 				i++;
 			}
 		}
-		EQ2Packet* ret = packet->serializeCountPacket(version, 1, orig_packet, xor_packet);
+		int8 offset = 1;
+		if (version <= 283)
+			offset = 0;
+		EQ2Packet* ret = packet->serializeCountPacket(version, offset, orig_packet, xor_packet);
 		//packet->PrintPacket();
+		//DumpPacket(orig_packet, orig_packet_size);
 		//DumpPacket(ret);
 		safe_delete(packet);
 		return ret;

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

@@ -138,6 +138,7 @@ private:
 	Mutex MSkillUpdates;
 	int16 packet_count;
 	uchar* orig_packet;
+	int16 orig_packet_size;
 	uchar* xor_packet;
 	map<int32, Skill*> skills;
 	map<string, Skill*> name_skill_map;

+ 438 - 84
EQ2/source/WorldServer/Spawn.cpp

@@ -46,7 +46,8 @@ Spawn::Spawn(){
 	merchant_min_level = 0;
 	merchant_max_level = 0;
 	memset(&appearance, 0, sizeof(AppearanceData)); 
-	memset(&basic_info, 0, sizeof(BasicInfoStruct)); 
+	memset(&basic_info, 0, sizeof(BasicInfoStruct));
+	appearance.pos.state = 0x4080;
 	appearance.encounter_level =6;
 	size = 32;
 	appearance.pos.collision_radius = 32;
@@ -206,8 +207,22 @@ void Spawn::InitializeVisPacketData(Player* player, PacketStruct* vis_packet) {
 
 	if (IsPlayer())
 		appearance.pos.grid_id = 0xFFFFFFFF;
-	if (appearance.targetable == 1 || appearance.show_level == 1 || appearance.display_name == 1){
-		if (!IsGroundSpawn()){
+
+	if (IsPlayer())
+		vis_packet->setDataByName("player", 1);
+	if (version <= 546) {
+		vis_packet->setDataByName("targetable", appearance.targetable);
+		vis_packet->setDataByName("show_name", appearance.display_name);
+		vis_packet->setDataByName("attackable", appearance.attackable);
+		if (IsPlayer()) {
+			if (((Player*)this)->IsGroupMember(player))
+				vis_packet->setDataByName("group_member", 1);
+		}
+
+	}
+
+	if (appearance.targetable == 1 || appearance.show_level == 1 || appearance.display_name == 1) {
+		if (!IsGroundSpawn()) {
 			int8 arrow_color = ARROW_COLOR_WHITE;
 			sint8 npc_con = player->GetFactions()->GetCon(faction_id);
 
@@ -218,20 +233,41 @@ void Spawn::InitializeVisPacketData(Player* player, PacketStruct* vis_packet) {
 
 			if (appearance.attackable == 1)
 				arrow_color = player->GetArrowColor(GetLevel());
+			/*if (version <= 283) {
+				if (GetMerchantID() > 0)
+					arrow_color += 7;
+				else {
+					if (primary_command_list.size() > 0) {
+						int16 len = strlen(primary_command_list[0]->command.c_str());
+						if(len >= 4 && strncmp(primary_command_list[0]->command.c_str(), "bank", 4) == 0)
+							arrow_color += 14;
+						else if (len >= 4 && strncmp(primary_command_list[0]->command.c_str(), "hail", 4) == 0)
+							arrow_color += 21;
+						else if (len >= 6 && strncmp(primary_command_list[0]->command.c_str(), "attack", 6) == 0) {
+							if (arrow_color > 5)
+								arrow_color = 34;
+							else
+								arrow_color += 29;
+						}
+					}
+				}
+			}*/
 			vis_packet->setDataByName("arrow_color", arrow_color);
 			vis_packet->setDataByName("locked_no_loot", appearance.locked_no_loot);
 			if (player->GetArrowColor(GetLevel()) == ARROW_COLOR_GRAY)
 				if (npc_con == -4)
 					npc_con = -3;
 			vis_packet->setDataByName("npc_con", npc_con);
-			if (appearance.attackable == 1 && IsNPC() && (player->GetFactions()->GetCon(faction_id) <= -4 || ((NPC*)this)->Brain()->GetHate(player) > 1))
+			if (appearance.attackable == 1 && IsNPC() && (player->GetFactions()->GetCon(faction_id) <= -4 || ((NPC*)this)->Brain()->GetHate(player) > 1)) {
 				vis_packet->setDataByName("npc_hate", ((NPC*)this)->Brain()->GetHatePercentage(player));
+				vis_packet->setDataByName("show_difficulty_arrows", 1);
+			}
 			int8 quest_flag = player->CheckQuestFlag(this);
 			if (version < 1188 && quest_flag >= 16)
 				quest_flag = 1;
-			vis_packet->setDataByName("quest_flag",quest_flag);
-			if( player->CheckQuestsKillUpdate(this, false)){
-			vis_packet->setDataByName("name_quest_icon", 1);
+			vis_packet->setDataByName("quest_flag", quest_flag);
+			if (player->CheckQuestsKillUpdate(this, false)) {
+				vis_packet->setDataByName("name_quest_icon", 1);
 			}
 		}
 	}
@@ -249,13 +285,17 @@ void Spawn::InitializeVisPacketData(Player* player, PacketStruct* vis_packet) {
 		if (appearance.show_command_icon == 1)
 			vis_flags += 2;
 		if (this == player) {
+			//if (version <= 283) {
+			//	vis_flags = 1;
+			//}
+			//else
 			vis_flags += 1;
 		}
 	}
 	else if (req_quests_override > 0)
 	{
 		//Check to see if there's an override value set
-			vis_flags = req_quests_override & 0xFF;
+		vis_flags = req_quests_override & 0xFF;
 	}
 
 	if (player->HasGMVision())
@@ -266,6 +306,9 @@ void Spawn::InitializeVisPacketData(Player* player, PacketStruct* vis_packet) {
 			vis_flags += 4;
 	}
 
+	if (version <= 546 && vis_flags > 0)
+		vis_flags = 1;
+	
 	vis_packet->setDataByName("vis_flags", vis_flags);
 
 
@@ -275,7 +318,6 @@ void Spawn::InitializeVisPacketData(Player* player, PacketStruct* vis_packet) {
 		if ((req_quests_override & 256) > 0)
 			vis_packet->setDataByName("hand_flag", 1);
 	}
-
 }
 
 void Spawn::InitializeFooterPacketData(Player* player, PacketStruct* footer) {
@@ -329,7 +371,7 @@ void Spawn::InitializeFooterPacketData(Player* player, PacketStruct* footer) {
 		footer->setDataByName("spawn_type", 3);
 }
 
-EQ2Packet* Spawn::spawn_serialize(Player* player, int16 version){
+EQ2Packet* Spawn::spawn_serialize(Player* player, int16 version, int16 offset, int32 value, int16 offset2, int16 offset3, int16 offset4, int32 value2) {
 	// If spawn is NPC AND is pet && owner is a player && owner is the player passed to this function && player's char sheet pet id is 0
 	if (IsNPC() && ((NPC*)this)->IsPet() && ((NPC*)this)->GetOwner()->IsPlayer() && player == ((NPC*)this)->GetOwner() && player->GetInfoStruct()->pet_id == 0) {
 		((Player*)((NPC*)this)->GetOwner())->GetInfoStruct()->pet_id = player->spawn_id;
@@ -343,7 +385,7 @@ EQ2Packet* Spawn::spawn_serialize(Player* player, int16 version){
 	}
 	else {
 		player->spawn_index++;
-		if(player->spawn_index == 255)
+		if (player->spawn_index == 255)
 			player->spawn_index++; //just so we dont have to worry about overloading
 		index = player->spawn_index;
 		player->player_spawn_index_map[this] = index;
@@ -362,17 +404,17 @@ EQ2Packet* Spawn::spawn_serialize(Player* player, int16 version){
 	header->ResetData();
 	InitializeHeaderPacketData(player, header, index);
 
-	PacketStruct* footer;
-	if(IsWidget())
+	PacketStruct* footer = 0;
+	if (IsWidget())
 		footer = player->GetWidgetFooterStruct();
-	else if(IsSign())
+	else if (IsSign())
 		footer = player->GetSignFooterStruct();
-	else
+	else if (version > 546)
 		footer = player->GetSpawnFooterStruct();
-
-	footer->ResetData();
-	InitializeFooterPacketData(player, footer);
-
+	if (footer) {
+		footer->ResetData();
+		InitializeFooterPacketData(player, footer);
+	}
 	PacketStruct* vis_struct = player->GetSpawnVisStruct();
 	PacketStruct* info_struct = player->GetSpawnInfoStruct();
 	PacketStruct* pos_struct = player->GetSpawnPosStruct();
@@ -389,7 +431,35 @@ EQ2Packet* Spawn::spawn_serialize(Player* player, int16 version){
 	pos_struct->ResetData();
 	InitializePosPacketData(player, pos_struct);
 
-	string* vis_data= vis_struct->serializeString();
+	if (version <= 283) {
+		if (offset == 777) {
+			info_struct->setDataByName("name", "This is a really long name\n");
+			info_struct->setDataByName("last_name", "This is a really long LAST name\n");
+			info_struct->setDataByName("name_suffix", "This is a really long SUFFIX\n");
+			info_struct->setDataByName("name_prefix", "This is a really long PREFIX\n");
+			info_struct->setDataByName("unknown", "This is a really long UNKNOWN\n");
+			info_struct->setDataByName("second_suffix", "This is a really long 2nd SUFFIX\n");
+		}
+		//info_struct->setDataByName("unknown2", 3, 0); // level
+		//info_struct->setDataByName("unknown2", 1, 1); //unknown, two down arrows
+		//info_struct->setDataByName("unknown2", 1, 2); //unknown
+		//info_struct->setDataByName("unknown2", 1, 3); //unknown
+		//info_struct->setDataByName("unknown2", 1, 4); //solo fight
+		//info_struct->setDataByName("unknown2", 1, 5); //unknown
+		//info_struct->setDataByName("unknown2", 1, 6);  //unknown
+		//info_struct->setDataByName("unknown2", 1, 7); //merchant
+		//info_struct->setDataByName("unknown2", 1, 8);  //unknown
+		//info_struct->setDataByName("unknown2", 1, 9); //unknown
+		//info_struct->setDataByName("unknown2", 1, 10);
+		//112: 00 00 00 01 02 03 04 05 - 06 07 08 09 0A 00 00 00 | ................ merchant, x4
+		//112: 00 00 00 01 02 03 04 05 - 00 00 00 00 00 00 00 00 | ................ x4, epic, indifferent
+		//info_struct->setDataByName("body_size", 42); 
+		//for(int i=0;i<8;i++)
+		//	info_struct->setDataByName("persistent_spell_visuals", 329, i);
+		//info_struct->setDataByName("persistent_spell_levels", 20);
+	}
+
+	string* vis_data = vis_struct->serializeString();
 	string* pos_data = pos_struct->serializeString();
 	string* info_data = info_struct->serializeString();
 
@@ -399,7 +469,7 @@ EQ2Packet* Spawn::spawn_serialize(Player* player, int16 version){
 	player->AddSpawnPosPacketForXOR(id, (uchar*)pos_data->c_str(), pos_data->length());
 	player->AddSpawnVisPacketForXOR(id, (uchar*)vis_data->c_str(), vis_data->length());
 	player->AddSpawnInfoPacketForXOR(id, (uchar*)info_data->c_str(), info_data->length());
-	
+
 	uchar* ptr = part2;
 	memcpy(ptr, pos_data->c_str(), pos_data->length());
 	ptr += pos_data->length();
@@ -411,41 +481,142 @@ EQ2Packet* Spawn::spawn_serialize(Player* player, int16 version){
 	player->vis_mutex.releasewritelock(__FUNCTION__, __LINE__);
 
 	string* part1 = header->serializeString();
-	string* part3 = footer->serializeString();
-
-	uchar tmp[900];
-	int32 origPart2Size = part2_size;
-	part2_size = Pack(tmp, part2, part2_size, 900, version);
-	int32 total_size = part1->length() + part2_size + part3->length() + 3;
-
-	uchar* final_packet = new uchar[total_size + 4];
+	string* part3 = 0;
+	if (footer)
+		part3 = footer->serializeString();
+
+	//uchar blah7[] = {0x01,0x01,0x00,0x00,0x01,0x01,0x00,0x01,0x01,0x00 };
+		//uchar blah7[] = { 0x03,0x01,0x00,0x01,0x01,0x01,0x00,0x01,0x01,0x00 }; base
+		//uchar blah7[] = { 0x03,0x00,0x00,0x01,0x01,0x01,0x00,0x01,0x01,0x00 }; //no change
+		//uchar blah7[] = { 0x03,0x00,0x00,0x00,0x01,0x01,0x00,0x01,0x01,0x00 }; //blue instead of green
+		//uchar blah7[] = { 0x03,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x01,0x00 }; //no change
+		//uchar blah7[] = { 0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x00 }; //not selectable
+		//uchar blah7[] = { 0x03,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x01,0x00 }; //no change
+		//uchar blah7[] = { 0x03,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00 }; //no longer have the two down arrows
+		//uchar blah7[] = { 0x01,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00 }; //arrow color green instead of white/gray
+		//memcpy(part2 + 77, blah7, sizeof(blah7));
+
+
+
+
+
+		//DumpPacket(part2, 885);	
+	if (offset > 0) {
+		if (offset4 > 0 && offset4 >= offset3) {
+			uchar* ptr2 = (uchar*)part2;
+			ptr2 += offset3;
+			while (offset4 >= offset3) {
+				int8 jumpsize = 1;
+				if (value2 > 0xFFFF) {
+					memcpy(ptr2, (uchar*)&value2, 4);
+					jumpsize = 4;
+				}
+				else if (value2 > 0xFF) {
+					memcpy(ptr2, (uchar*)&value2, 2);
+					jumpsize = 2;
+				}
+				else {
+					memcpy(ptr2, (uchar*)&value2, 1);
+					jumpsize = 1;
+				}
+				ptr2 += jumpsize;
+				offset4 -= jumpsize;
+			}
+		}
+		if (offset2 > 0 && offset2 >= offset) {
+			uchar* ptr2 = (uchar*)part2;
+			ptr2 += offset;
+			while (offset2 >= offset) {
+				int8 jumpsize = 1;
+				if (value > 0xFFFF) {
+					memcpy(ptr2, (uchar*)&value, 4);
+					jumpsize = 4;
+				}
+				else if (value > 0xFF) {
+					memcpy(ptr2, (uchar*)&value, 2);
+					jumpsize = 2;
+				}
+				else
+					memcpy(ptr2, (uchar*)&value, 1);
+				ptr2 += jumpsize;
+				offset2 -= jumpsize;
+			}
+		}
+		else {
+			uchar* ptr2 = (uchar*)part2;
+			ptr2 += offset;
+			if (value > 0xFFFF)
+				memcpy(ptr2, (uchar*)&value, 4);
+			else if (value > 0xFF)
+				memcpy(ptr2, (uchar*)&value, 2);
+			else
+				memcpy(ptr2, (uchar*)&value, 1);
+		}
+		cout << "setting offset: " << offset << " to: " << value << endl;
+	}
+	if (offset > 0)
+		DumpPacket(part2, part2_size);
+	uchar tmp[1100];
+	bool reverse = (version > 283);
+	part2_size = Pack(tmp, part2, part2_size, 1100, version, reverse);
+	int32 total_size = part1->length() + part2_size + 3;
+	if (part3)
+		total_size += part3->length();
+	int32 final_packet_size = total_size + 1;
+
+	if (version > 283)
+		final_packet_size += 3;
+	else {
+		if (final_packet_size >= 255) {
+			final_packet_size += 2;
+		}
+	}
+	uchar* final_packet = new uchar[final_packet_size];
 	ptr = final_packet;
-	memcpy(ptr, &total_size, sizeof(total_size));
-	ptr += sizeof(total_size);
+	if (version <= 283) {
+		if ((final_packet_size - total_size) > 1) {
+			memcpy(ptr, &oversized_packet, sizeof(oversized_packet));
+			ptr += sizeof(oversized_packet);
+			memcpy(ptr, &total_size, 2);
+			ptr += 2;
+		}
+		else {
+			memcpy(ptr, &total_size, 1);
+			ptr += 1;
+		}
+	}
+	else {
+		memcpy(ptr, &total_size, sizeof(total_size));
+		ptr += sizeof(total_size);
+	}
 
 	memcpy(ptr, &oversized_packet, sizeof(oversized_packet));
 	ptr += sizeof(oversized_packet);
-
+	if (opcode == 0) {
+		opcode = EQOpcodeManager[GetOpcodeVersion(version)]->EmuToEQ(OP_EqCreateGhostCmd);
+	}
 	memcpy(ptr, &opcode, sizeof(opcode));
 	ptr += sizeof(opcode);
-	
+
 	memcpy(ptr, part1->c_str(), part1->length());
 	ptr += part1->length();
 
+
 	memcpy(ptr, tmp, part2_size);
 	ptr += part2_size;
-	
-	memcpy(ptr, part3->c_str(), part3->length());
+
+	if (part3)
+		memcpy(ptr, part3->c_str(), part3->length());
 	delete[] part2;
 
-//	printf("%s (%i): p1: %i, p2:% i (%i), p3:% i, ts: %i\n", GetName(), GetID(), part1->length(), part2_size, origPart2Size, part3->length(), total_size);
+	//	printf("%s (%i): p1: %i, p2:% i (%i), p3:% i, ts: %i\n", GetName(), GetID(), part1->length(), part2_size, origPart2Size, part3->length(), total_size);
 
-	EQ2Packet* ret = new EQ2Packet(OP_ClientCmdMsg, final_packet, total_size + 4);
+	EQ2Packet* ret = new EQ2Packet(OP_ClientCmdMsg, final_packet, final_packet_size);
 	delete[] final_packet;
 
 	m_Update.releasewritelock(__FUNCTION__, __LINE__);
 
-  	return ret;
+	return ret;
 }
 
 uchar* Spawn::spawn_info_changes(Player* player, int16 version){
@@ -594,7 +765,7 @@ uchar* Spawn::spawn_pos_changes(Player* player, int16 version) {
 
 
 	uchar* tmp;
-	if (IsPlayer())
+	if (IsPlayer() && version > 283)
 		tmp = new uchar[size + 14];
 	else
 		tmp = new uchar[size + 10];
@@ -607,7 +778,7 @@ uchar* Spawn::spawn_pos_changes(Player* player, int16 version) {
 	if (version >= 1188)
 		size += 1;
 
-	if(IsPlayer())
+	if(IsPlayer() && version > 546)
 		size += 4;
 	size-=sizeof(int32);
 	size+=CheckOverLoadSize(index);
@@ -620,7 +791,7 @@ uchar* Spawn::spawn_pos_changes(Player* player, int16 version) {
 
 	// extra byte in coe+ clients, 0 for NPC's 1 for Players
 	int8 x = 0;
-	if(IsPlayer()){
+	if (IsPlayer() && version > 546) {
 		if (version >= 1188) {
 			// set x to 1 and add it to the packet
 			x = 1;
@@ -664,16 +835,40 @@ EQ2Packet* Spawn::player_position_update_packet(Player* player, int16 version){
 	int32 tmp_pos_packet_size = pos_packet_size;
 	m_Update.releasewritelock(__FUNCTION__, __LINE__);
 
-	int32 size = info_size + tmp_pos_packet_size + vis_size + 11;
+	int32 size = info_size + tmp_pos_packet_size + vis_size + 8;
+	if (version >= 284)
+		size += 3;
+	else if (version <= 283 && size >= 255) {//1 byte to 3 for overloaded val
+		size += 2;
+	}
 	static const int8 oversized = 255;
 	int16 opcode_val = EQOpcodeManager[GetOpcodeVersion(version)]->EmuToEQ(OP_EqUpdateGhostCmd);
 	uchar* tmp = new uchar[size];
 	memset(tmp, 0, size);
 	uchar* ptr = tmp;
-	size -=4;
-	memcpy(ptr, &size, sizeof(int32));
-	size +=4;
-	ptr += sizeof(int32);
+	if (version >= 284) {
+		size -= 4;
+		memcpy(ptr, &size, sizeof(int32));
+		size += 4;
+		ptr += sizeof(int32);
+	}
+	else {
+		if (size >= 255) {
+			memcpy(ptr, &oversized, sizeof(int8));
+			ptr += sizeof(int8);
+			size -= 3;
+			memcpy(ptr, &size, sizeof(int16));
+			size += 3;
+			ptr += 3;
+		}
+		else {
+			size -= 1;
+			memcpy(ptr, &size, sizeof(int8));
+			ptr += sizeof(int8);
+			size += 1;
+			ptr += 1;
+		}
+	}
 	memcpy(ptr, &oversized, sizeof(int8));
 	ptr += sizeof(int8);
 	memcpy(ptr, &opcode_val, sizeof(int16));
@@ -682,6 +877,7 @@ EQ2Packet* Spawn::player_position_update_packet(Player* player, int16 version){
 	ptr += info_size;
 	memcpy(ptr, pos_changes, tmp_pos_packet_size);
 	EQ2Packet* ret_packet = new EQ2Packet(OP_ClientCmdMsg, tmp, size);
+	DumpPacket(ret_packet);
 	delete[] tmp;
 	delete[] pos_changes;
 	return ret_packet;
@@ -726,19 +922,42 @@ EQ2Packet* Spawn::spawn_update_packet(Player* player, int16 version, bool overri
 	tmp_pos_packet_size = pos_packet_size;
 	tmp_vis_packet_size = vis_packet_size;
 
-	int32 size = info_packet_size + pos_packet_size + vis_packet_size + 11;
+	int32 size = info_packet_size + pos_packet_size + vis_packet_size + 8;
+	if (version >= 284)
+		size += 3;
+	else if (version <= 283 && size >= 255) {//1 byte to 3 for overloaded val
+		size += 2;
+	}
 	uchar* tmp = new uchar[size];
 	memset(tmp, 0, size);
 	uchar* ptr = tmp;
-	size -=4;
-	memcpy(ptr, &size, sizeof(int32));
-	size +=4;
-	ptr += sizeof(int32);
+	if (version >= 284) {
+		size -= 4;
+		memcpy(ptr, &size, sizeof(int32));
+		size += 4;
+		ptr += sizeof(int32);
+	}
+	else {
+		if (size >= 255) {
+			memcpy(ptr, &oversized, sizeof(int8));
+			ptr += sizeof(int8);
+			size -= 3;
+			memcpy(ptr, &size, sizeof(int16));
+			size += 3;
+			ptr += 3;
+		}
+		else {
+			size -= 1;
+			memcpy(ptr, &size, sizeof(int8));
+			ptr += sizeof(int8);
+			size += 1;
+		}
+	}
 	memcpy(ptr, &oversized, sizeof(int8));
 	ptr += sizeof(int8);
 	memcpy(ptr, &opcode_val, sizeof(int16));
 	ptr += sizeof(int16);
-	if (IsPlayer() == false){ //this isnt sent for player updates, it is sent on position update
+	if (IsPlayer() == false || version <= 546) { //this isnt sent for player updates, it is sent on position update
 		//int32 time = Timer::GetCurrentTime2();
 		packet_num = Timer::GetCurrentTime2();
 		memcpy(ptr, &packet_num, sizeof(int32));
@@ -937,7 +1156,7 @@ uchar* Spawn::spawn_pos_changes_ex(Player* player, int16 version) {
 		size += 1;
 	}
 
-	if (IsPlayer()) {
+	if (IsPlayer() && version > 546) {
 		size += 4;
 	}
 
@@ -953,17 +1172,18 @@ uchar* Spawn::spawn_pos_changes_ex(Player* player, int16 version) {
 	// extra byte in coe+ clients, 0 for NPC's 1 for Players
 	int8 x = 0;
 
-	if (version >= 1188) {
+	if (version > 546) {
 		if (IsPlayer()) {
-			x = 1;
-			memcpy(ptr, &x, sizeof(int8));
-			ptr += sizeof(int8);
-
+			if (version >= 1188) {
+				x = 1;
+				memcpy(ptr, &x, sizeof(int8));
+				ptr += sizeof(int8);
+			}
 			int32 now = Timer::GetCurrentTime2();
 			memcpy(ptr, &now, sizeof(int32));
 			ptr += sizeof(int32);
 		}
-		else {
+		else if (version >= 1188) {
 			memcpy(ptr, &x, sizeof(int8));
 			ptr += sizeof(int8);
 		}
@@ -1719,16 +1939,16 @@ void Spawn::InitializePosPacketData(Player* player, PacketStruct* packet, bool b
 		packet->setDataByName("pos_size_multiplier", 32); //32 is normal
 	}
 	else {
-			if (size == 0)
-				size = 32;
+		if (size == 0)
+			size = 32;
 
-			packet->setDataByName("pos_collision_radius", appearance.pos.collision_radius > 0 ? appearance.pos.collision_radius : 32);
+		packet->setDataByName("pos_collision_radius", appearance.pos.collision_radius > 0 ? appearance.pos.collision_radius : 32);
 
-			if (!IsPlayer())
-				packet->setDataByName("pos_size", size > 0 ? (((float)size) / 32.0f) : 1.0f);
-			else
-				packet->setDataByName("pos_size", 1.0f);
+		packet->setDataByName("pos_size", 1.0f);
 
+		if (!IsPlayer())
+			packet->setDataByName("pos_size_ratio", size > 0 ? (((float)size) / 32) : 1);
+		else
 			packet->setDataByName("pos_size_ratio", 1.0f);
 	}
 	packet->setDataByName("pos_state", appearance.pos.state);
@@ -1760,9 +1980,53 @@ void Spawn::InitializePosPacketData(Player* player, PacketStruct* packet, bool b
 	}
 
 	if (IsPlayer()) {
-		packet->setDataByName("pos_x_velocity", static_cast<sint16>(GetSpeedX() * 32));
-		packet->setDataByName("pos_y_velocity", static_cast<sint16>(GetSpeedY() * 32));
-		packet->setDataByName("pos_z_velocity", static_cast<sint16>(GetSpeedZ() * 32));
+		packet->setDataByName("pos_swim_speed_modifier", 20);
+		packet->setDataByName("pos_x_velocity", TransformFromFloat(GetSpeedX(), 5));
+		packet->setDataByName("pos_y_velocity", TransformFromFloat(GetSpeedY(), 5));
+		packet->setDataByName("pos_z_velocity", TransformFromFloat(GetSpeedZ(), 5));
+	}
+
+	if (appearance.pos.X2 == 0 && appearance.pos.Y2 == 0 && appearance.pos.Z2 && (appearance.pos.X != 0 || appearance.pos.Y != 0 || appearance.pos.Z != 0)) {
+		appearance.pos.X2 = appearance.pos.X;
+		appearance.pos.Y2 = appearance.pos.Y;
+		appearance.pos.Z2 = appearance.pos.Z;
+	}
+	if (appearance.pos.X3 == 0 && appearance.pos.Y3 == 0 && appearance.pos.Z3 && (appearance.pos.X != 0 || appearance.pos.Y != 0 || appearance.pos.Z != 0)) {
+		appearance.pos.X3 = appearance.pos.X;
+		appearance.pos.Y3 = appearance.pos.Y;
+		appearance.pos.Z3 = appearance.pos.Z;
+	}
+	//Transform To/From Float bits (original client)
+	//pos_loc_offset[3]: 5
+	//pos_x_velocity: 5
+	//pos_y_velocity: 5
+	//pos_z_velocity: 5
+	//pos_heading1: 6
+	//pos_heading2: 6
+	//pos_speed: 8
+	//pos_dest_loc_offset[3]: 5
+	//pos_dest_loc_offset2[3]: 5
+	//pos_heading_speed: 5
+	//pos_move_type: 5 (speed_modifier)
+	//pos_swim_speed_modifier: 5
+	//pos_side_speed: 8
+	//pos_vert_speed: 8
+	//pos_requested_pitch: 6
+	//pos_requested_pitch_speed: 5
+	//pos_pitch: 6
+	//pos_collision_radius: 5
+	//pos_size: 5
+	//actor_stop_range: 5
+	//this is for original box client, destinations used to be offsets
+	if (appearance.pos.X2 != 0 || appearance.pos.Y2 != 0 || appearance.pos.Z2 != 0) {
+		packet->setDataByName("pos_dest_loc_offset", TransformFromFloat(appearance.pos.X2 - appearance.pos.X, 5));
+		packet->setDataByName("pos_dest_loc_offset", TransformFromFloat(appearance.pos.Y2 - appearance.pos.Y, 5), 1);
+		packet->setDataByName("pos_dest_loc_offset", TransformFromFloat(appearance.pos.Z2 - appearance.pos.Z, 5), 2);
+	}
+	if (appearance.pos.X3 != 0 || appearance.pos.Y3 != 0 || appearance.pos.Z3 != 0) {
+		packet->setDataByName("pos_dest_loc_offset2", TransformFromFloat(appearance.pos.X3 - appearance.pos.X, 5));
+		packet->setDataByName("pos_dest_loc_offset2", TransformFromFloat(appearance.pos.Y3 - appearance.pos.Y, 5), 1);
+		packet->setDataByName("pos_dest_loc_offset2", TransformFromFloat(appearance.pos.Z3 - appearance.pos.Z, 5), 2);
 	}
 
 	bool bSendSpeed = true;
@@ -1868,24 +2132,48 @@ void Spawn::InitializeInfoPacketData(Player* spawn, PacketStruct* packet){
 
 	if(!spawnHiddenFromClient && (appearance.targetable == 1 || appearance.show_level == 1 || appearance.display_name == 1)){
 		appearance.locked_no_loot = 1; //for now
-		if(!IsObject() && !IsGroundSpawn() && !IsWidget() && !IsSign()){
+		if (!IsObject() && !IsGroundSpawn() && !IsWidget() && !IsSign()) {
 			int8 percent = 0;
-			if(GetHP() > 0)
-				percent = (int8)(((float)GetHP()/GetTotalHP()) * 100);
-			if(percent < 100){
- 				packet->setDataByName("hp_remaining", 100 ^ percent);
+			if (GetHP() > 0)
+				percent = (int8)(((float)GetHP() / GetTotalHP()) * 100);
+			if (version >= 284) {
+				if (percent < 100) {
+					packet->setDataByName("hp_remaining", 100 ^ percent);
+				}
+				else
+					packet->setDataByName("hp_remaining", 0);
 			}
-			else
-				packet->setDataByName("hp_remaining", 0);
-			if(GetTotalPower() > 0){
-				percent = (int8)(((float)GetPower()/GetTotalPower()) * 100);
-				if(percent > 0)
+			else {
+				if (percent > 100)
+					percent = 100;
+				packet->setDataByName("hp_remaining", percent);
+			}
+			if (GetTotalPower() > 0) {
+				percent = (int8)(((float)GetPower() / GetTotalPower()) * 100);
+				if (percent > 0)
 					packet->setDataByName("power_percent", percent);
 				else
 					packet->setDataByName("power_percent", 0);
 			}
 		}
 	}
+
+	if (version <= 546) {
+		packet->setDataByName("name", appearance.name);
+		for (int8 i = 0; i < 8; i++)
+			packet->setDataByName("unknown1", 0xFF, i);
+		if (appearance.show_level == 0)
+			packet->setDataByName("hide_health", 1);
+	}
+	if (GetHP() <= 0 && IsEntity())
+		packet->setDataByName("corpse", 1);
+	if (!IsPlayer())
+		packet->setDataByName("npc", 1);
+	if (GetMerchantID() > 0)
+		packet->setDataByName("merchant", 1);
+	if (EngagedInCombat())
+		packet->setDataByName("in_combat", 1);
+
 	packet->setDataByName("level", (int8)GetLevel());
 	packet->setDataByName("unknown4", (int8)GetLevel());
 	packet->setDataByName("difficulty", appearance.encounter_level); //6);
@@ -2143,9 +2431,32 @@ void Spawn::InitializeInfoPacketData(Player* spawn, PacketStruct* packet){
 	{
 		temp_activity_status = appearance.activity_status;
 
-		// WE ARE UNSURE OF THESE OLD CLIENT VALUES USED AS TEMP PLACEHOLDERS FOR NEWER CLIENTS
-		if ((appearance.activity_status & ACTIVITY_STATUS_AFK) > 0)
-			temp_activity_status -= ACTIVITY_STATUS_AFK;
+		if (version <= 546) {
+			temp_activity_status = 0xFF;
+			if (MeetsSpawnAccessRequirements(spawn))
+				packet->setDataByName("hand_icon", appearance.display_hand_icon);
+			else {
+				if ((req_quests_override & 256) > 0)
+					packet->setDataByName("hand_icon", 1);
+			}
+
+			if (IsPlayer()) {
+				if (((Player*)this)->get_character_flag(CF_AFK))
+					packet->setDataByName("afk", 1);
+				if ((appearance.activity_status & ACTIVITY_STATUS_ROLEPLAYING) > 0)
+					packet->setDataByName("roleplaying", 1);
+				if ((appearance.activity_status & ACTIVITY_STATUS_ANONYMOUS) > 0)
+					packet->setDataByName("anonymous", 1);
+				if ((appearance.activity_status & ACTIVITY_STATUS_LINKDEAD) > 0)
+					packet->setDataByName("linkdead", 1);
+				if ((appearance.activity_status & ACTIVITY_STATUS_CAMPING) > 0)
+					packet->setDataByName("camping", 1);
+				if ((appearance.activity_status & ACTIVITY_STATUS_LFG) > 0)
+					packet->setDataByName("lfg", 1);
+			}
+			if ((appearance.activity_status & ACTIVITY_STATUS_SOLID) > 0)
+				packet->setDataByName("solid", 1);
+		}
 
 	}
 
@@ -2156,12 +2467,12 @@ void Spawn::InitializeInfoPacketData(Player* spawn, PacketStruct* packet){
 		if (((Player*)this)->GetFollowTarget())
 			packet->setDataByName("follow_target", ((((Player*)this)->GetIDWithPlayerSpawn(((Player*)this)->GetFollowTarget()) * -1) - 1));
 		else
-			packet->setDataByName("follow_target", 0);
+			packet->setDataByName("follow_target", 0xFFFFFFFF);
 	}
 	if (GetTarget() && GetTarget()->GetTargetable())
 		packet->setDataByName("target_id", ((spawn->GetIDWithPlayerSpawn(GetTarget()) * -1) - 1));
 	else
-		packet->setDataByName("target_id", 0);
+		packet->setDataByName("target_id", 0xFFFFFFFF);
 
 	//Send spell effects for target window
 	if(IsEntity()){
@@ -3251,6 +3562,49 @@ void Spawn::CalculateNewFearpoint()
 	}
 }
 
+Item* Spawn::LootItem(int32 id) {
+	Item* ret = 0;
+	vector<Item*>::iterator itr;
+	MLootItems.lock();
+	for (itr = loot_items.begin(); itr != loot_items.end(); itr++) {
+		if ((*itr)->details.item_id == id) {
+			ret = *itr;
+			loot_items.erase(itr);
+			break;
+		}
+	}
+	MLootItems.unlock();
+	return ret;
+}
+
+int32 Spawn::GetLootItemID() {
+	int32 ret = 0;
+	vector<Item*>::iterator itr;
+	MLootItems.lock();
+	for (itr = loot_items.begin(); itr != loot_items.end(); itr++) {
+		ret = (*itr)->details.item_id;
+		break;
+	}
+	MLootItems.unlock();
+	return ret;
+}
+
+bool Spawn::HasLootItemID(int32 id) {
+	bool ret = false;
+
+	vector<Item*>::iterator itr;
+	MLootItems.readlock(__FUNCTION__, __LINE__);
+	for (itr = loot_items.begin(); itr != loot_items.end(); itr++) {
+		if ((*itr)->details.item_id == id) {
+			ret = true;
+			break;
+		}
+	}
+	MLootItems.releasereadlock(__FUNCTION__, __LINE__);
+
+	return ret;
+}
+
 void Spawn::CheckProximities()
 {
 	if (!has_spawn_proximities)

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

@@ -765,7 +765,7 @@ public:
 	vector<EntityCommand*>* GetSecondaryCommands() {return &secondary_command_list;}
 	EntityCommand* FindEntityCommand(string command, bool primaryOnly=false);
 	virtual EQ2Packet* serialize(Player* player, int16 version);
-	EQ2Packet* spawn_serialize(Player* player, int16 version);
+	EQ2Packet* spawn_serialize(Player* player, int16 version, int16 offset = 0, int32 value = 0, int16 offset2 = 0, int16 offset3 = 0, int16 offset4 = 0, int32 value2 = 0);
 	EQ2Packet* spawn_update_packet(Player* player, int16 version, bool override_changes = false, bool override_vis_changes = false);
 	EQ2Packet* player_position_update_packet(Player* player, int16 version);
 	uchar* spawn_info_changes(Player* spawn, int16 version);
@@ -809,6 +809,55 @@ public:
 	float			GetZOffset() { return z_offset; }
 	void			SetZOffset(float new_z_offset) { z_offset = new_z_offset; }
 
+	bool HasTrapTriggered() {
+		return trap_triggered;
+	}
+	void SetTrapTriggered(bool triggered) {
+		trap_triggered = triggered;
+	}
+	void AddLootItem(int32 id, int16 charges = 1) {
+		Item* master_item = master_item_list.GetItem(id);
+		if (master_item) {
+			Item* item = new Item(master_item);
+			item->details.count = charges;
+			loot_items.push_back(item);
+		}
+	}
+	bool HasLoot() {
+		if (loot_items.size() == 0 && loot_coins == 0)
+			return false;
+		return true;
+	}
+	bool HasLootItemID(int32 id);
+	int32 GetLootItemID();
+	Item* LootItem(int32 id);
+	vector<Item*>* GetLootItems() {
+		return &loot_items;
+	}
+	void LockLoot() {
+		MLootItems.lock();
+	}
+	void UnlockLoot() {
+		MLootItems.unlock();
+	}
+	int32 GetLootCoins() {
+		return loot_coins;
+	}
+	void SetLootCoins(int32 val) {
+		loot_coins = val;
+	}
+	void AddLootCoins(int32 coins) {
+		loot_coins += coins;
+	}
+
+	void ClearLootList() {
+		vector<Item*>::iterator itr;
+		for (itr = loot_items.begin(); itr != loot_items.end(); itr++)
+			safe_delete(*itr);
+
+		loot_items.clear();
+	}
+
 	Spawn*			GetTarget();
 	void			SetTarget(Spawn* spawn);
 	Spawn*			GetLastAttacker();
@@ -1103,8 +1152,12 @@ protected:
 	MutexList<SpawnProximity*> spawn_proximities;
 
 	void CheckProximities();
-private:	
+private:		
+	vector<Item*>	loot_items;
+	int32			loot_coins;
+	bool			trap_triggered;
 	deque<MovementLocation*>* movement_locations;
+	Mutex			MLootItems;
 	Mutex*			MMovementLocations;
 	Mutex*			MSpawnGroup;
 	int8			size_offset;

+ 276 - 247
EQ2/source/WorldServer/Spells.cpp

@@ -163,6 +163,7 @@ int16 Spell::GetLevelRequired(Player* player){
 	}
 	return ret;
 }
+
 void Spell::SetAAPacketInformation(PacketStruct* packet, AltAdvanceData* data, Client* client, bool display_tier) {
 	int8 current_tier = client->GetPlayer()->GetSpellTier(spell->id);
 	Spell* next_spell;
@@ -293,7 +294,7 @@ void Spell::SetAAPacketInformation(PacketStruct* packet, AltAdvanceData* data, C
 				// Magic damage min
 				if (effect_message.find("%DML") < 0xFFFFFFFF) {
 					int string_index = effect_message.find("%DML");
-					int data_index = stoi(effect_message.substr(string_index+4, 2));
+					int data_index = stoi(effect_message.substr(string_index + 4, 2));
 					float value;
 					if (lua_data[data_index]->type == 1)
 						value = lua_data[data_index]->float_value * client->GetPlayer()->GetLevel();
@@ -308,7 +309,7 @@ void Spell::SetAAPacketInformation(PacketStruct* packet, AltAdvanceData* data, C
 				// Magic damage max
 				if (effect_message.find("%DMH") < 0xFFFFFFFF) {
 					int string_index = effect_message.find("%DMH");
-					int data_index = stoi(effect_message.substr(string_index+4, 2));
+					int data_index = stoi(effect_message.substr(string_index + 4, 2));
 					float value;
 					if (lua_data[data_index]->type == 1)
 						value = lua_data[data_index]->float_value * client->GetPlayer()->GetLevel();
@@ -323,7 +324,7 @@ void Spell::SetAAPacketInformation(PacketStruct* packet, AltAdvanceData* data, C
 				// level based Magic damage min
 				if (effect_message.find("%LDML") < 0xFFFFFFFF) {
 					int string_index = effect_message.find("%LDML");
-					int data_index = stoi(effect_message.substr(string_index+5, 2));
+					int data_index = stoi(effect_message.substr(string_index + 5, 2));
 					float value;
 					if (lua_data[data_index]->type == 1)
 						value = lua_data[data_index]->float_value * client->GetPlayer()->GetLevel();
@@ -338,7 +339,7 @@ void Spell::SetAAPacketInformation(PacketStruct* packet, AltAdvanceData* data, C
 				// level based Magic damage max
 				if (effect_message.find("%LDMH") < 0xFFFFFFFF) {
 					int string_index = effect_message.find("%LDMH");
-					int data_index = stoi(effect_message.substr(string_index+5, 2));
+					int data_index = stoi(effect_message.substr(string_index + 5, 2));
 					float value;
 					if (lua_data[data_index]->type == 1)
 						value = lua_data[data_index]->float_value * client->GetPlayer()->GetLevel();
@@ -495,204 +496,21 @@ void Spell::SetAAPacketInformation(PacketStruct* packet, AltAdvanceData* data, C
 					string damage = to_string((int)round(value));
 					damage.erase(damage.find_last_not_of('0') + 1, std::string::npos);
 					effect_message.replace(effect_message.find("%DML"), 6, damage);
-				}
-					// Magic damage max
-					if (effect_message.find("%DMH") < 0xFFFFFFFF) {
-						int string_index = effect_message.find("%DMH");
-						int data_index = stoi(effect_message.substr(string_index + 4, 2));
-						float value;
-						if (next_spell->lua_data[data_index]->type == 1)
-							value = next_spell->lua_data[data_index]->float_value * client->GetPlayer()->GetLevel();
-						else
-							value = next_spell->lua_data[data_index]->int_value * client->GetPlayer()->GetLevel();
-						value *= ((client->GetPlayer()->GetInfoStruct()->potency / 100) + 1);
-						int32 mod = (int32)min(client->GetPlayer()->GetInfoStruct()->ability_modifier, (float)(value / 2));
-						value += mod;
-						string damage = to_string((int)round(value));
-						damage.erase(damage.find_last_not_of('0') + 1, std::string::npos);
-						effect_message.replace(effect_message.find("%DMH"), 6, damage);
-					}
-					// level based Magic damage min
-					if (effect_message.find("%LDML") < 0xFFFFFFFF) {
-						int string_index = effect_message.find("%LDML");
-						int data_index = stoi(effect_message.substr(string_index + 5, 2));
-						float value;
-						if (next_spell->lua_data[data_index]->type == 1)
-							value = next_spell->lua_data[data_index]->float_value * client->GetPlayer()->GetLevel();
-						else
-							value = next_spell->lua_data[data_index]->int_value * client->GetPlayer()->GetLevel();
-						value *= ((client->GetPlayer()->GetInfoStruct()->potency / 100) + 1);
-						int32 mod = (int32)min(client->GetPlayer()->GetInfoStruct()->ability_modifier, (float)(value / 2));
-						value += mod;
-						string damage = to_string((int)round(value));
-						effect_message.replace(effect_message.find("%LDML"), 7, damage);
-					}
-					// level based Magic damage max
-					if (effect_message.find("%LDMH") < 0xFFFFFFFF) {
-						int string_index = effect_message.find("%LDMH");
-						int data_index = stoi(effect_message.substr(string_index + 5, 2));
-						float value;
-						if (next_spell->lua_data[data_index]->type == 1)
-							value = next_spell->lua_data[data_index]->float_value * client->GetPlayer()->GetLevel();
-						else
-							value = next_spell->lua_data[data_index]->int_value * client->GetPlayer()->GetLevel();
-						value *= ((client->GetPlayer()->GetInfoStruct()->potency / 100) + 1);
-						int32 mod = (int32)min(client->GetPlayer()->GetInfoStruct()->ability_modifier, (float)(value / 2));
-						value += mod;
-						string damage = to_string((int)round(value));
-						effect_message.replace(effect_message.find("%LDMH"), 7, damage);
-					}
-					//GetZone()->SimpleMessage(CHANNEL_COLOR_SPELL_EFFECT, effect_message.c_str(), victim, 50);
-					packet->setArrayDataByName("next_effect", effect_message.c_str(), i);
-				}
-					   			 		
-			packet->setArrayDataByName("next_percentage", next_spell->effects[i]->percentage, i);
-
-		}
-		if (display_tier == true)
-			packet->setSubstructDataByName("spell_info", "next_display_spell_tier", 1);// spell->display_spell_tier);
-		else
-			packet->setSubstructDataByName("spell_info", "next_display_spell_tier", 1);//0
-		packet->setSubstructDataByName("spell_info", "next_unknown_1", 1);//0
-		packet->setSubstructDataByName("spell_info", "next_range", spell2->range);
-		packet->setSubstructDataByName("spell_info", "next_duration_1", spell2->duration1);
-		packet->setSubstructDataByName("spell_info", "next_duration_2", spell2->duration2);
-
-		packet->setSubstructDataByName("spell_info", "next_can_effect_raid", spell2->can_effect_raid);
-		packet->setSubstructDataByName("spell_info", "next_affect_only_group_members", spell2->affect_only_group_members);
-		packet->setSubstructDataByName("spell_info", "next_group_spell", spell2->group_spell);
-		packet->setSubstructDataByName("spell_info", "next_resistibility", spell2->resistibility);
-		packet->setSubstructDataByName("spell_info", "next_name", &(spell2->name));
-		packet->setSubstructDataByName("spell_info", "next_description", &(spell2->description));
-	
-	}
-}
-	void Spell::SetPacketInformation(PacketStruct* packet, Client* client, bool display_tier) {
-		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() >= 60114) {
-			packet->setSubstructDataByName("spell_info", "version", 0x03);
-			packet->setSubstructDataByName("spell_info", "sub_version", 4890);
-		}
-		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->GetPlayer()));
-			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", "target", spell->target_type);
-		packet->setSubstructDataByName("spell_info", "recovery", spell->recovery);
-		packet->setSubstructDataByName("spell_info", "health_upkeep", spell->hp_upkeep);
-		packet->setSubstructDataByName("spell_info", "health_req", hp_req);
-		packet->setSubstructDataByName("spell_info", "tier", spell->tier);
-		packet->setSubstructDataByName("spell_info", "power_req", power_req);
-		packet->setSubstructDataByName("spell_info", "power_upkeep", spell->power_upkeep);
-
-		packet->setSubstructDataByName("spell_info", "cast_time", spell->cast_time);
-		packet->setSubstructDataByName("spell_info", "recast", spell->recast);
-		packet->setSubstructDataByName("spell_info", "radius", spell->radius);
-		packet->setSubstructDataByName("spell_info", "req_concentration", spell->req_concentration);
-		//packet->setSubstructDataByName("spell_info","req_concentration2", 2);
-		packet->setSubstructDataByName("spell_info", "max_aoe_targets", spell->max_aoe_targets);
-		packet->setSubstructDataByName("spell_info", "friendly_spell", spell->friendly_spell);
-		packet->setSubstructArrayLengthByName("spell_info", "num_effects", effects.size());
-		for (int32 i = 0; i < effects.size(); i++) {
-			
-			packet->setArrayDataByName("subbulletflag", effects[i]->subbullet, i);
-			string effect_message;
-			if (effects[i]->description.length() > 0) {
-				effect_message = effects[i]->description;
-				if (effect_message.find("%LM") < 0xFFFFFFFF) {
-					int string_index = effect_message.find("%LM");
-					int data_index = stoi(effect_message.substr(string_index + 3, 2));
-					float value;
-					if (lua_data[data_index]->type == 1)
-						value = lua_data[data_index]->float_value * client->GetPlayer()->GetLevel();
-					else
-						value = lua_data[data_index]->int_value * client->GetPlayer()->GetLevel();
-					string strValue = to_string(value);
-					strValue.erase(strValue.find_last_not_of('0') + 1, std::string::npos);
-					effect_message.replace(effect_message.find("%LM"), 5, strValue);
-				}
-				// Magic damage min
-				if (effect_message.find("%DML") < 0xFFFFFFFF) {
-					int string_index = effect_message.find("%DML");
-					int data_index = stoi(effect_message.substr(string_index + 4, 2));
-					float value;
-					if (lua_data[data_index]->type == 1)
-						value = lua_data[data_index]->float_value * client->GetPlayer()->GetLevel();
-					else
-						value = lua_data[data_index]->int_value * client->GetPlayer()->GetLevel();
-					value *= ((client->GetPlayer()->GetInfoStruct()->potency / 100) + 1);
-					int32 mod = (int32)min(client->GetPlayer()->GetInfoStruct()->ability_modifier, (float)(value / 2));
-					value += mod;
-					string damage = to_string((int)round(value));
-					effect_message.replace(effect_message.find("%DML"), 6, damage);
 				}
 				// Magic damage max
 				if (effect_message.find("%DMH") < 0xFFFFFFFF) {
 					int string_index = effect_message.find("%DMH");
 					int data_index = stoi(effect_message.substr(string_index + 4, 2));
 					float value;
-					if (lua_data[data_index]->type == 1)
-						value = lua_data[data_index]->float_value * client->GetPlayer()->GetLevel();
+					if (next_spell->lua_data[data_index]->type == 1)
+						value = next_spell->lua_data[data_index]->float_value * client->GetPlayer()->GetLevel();
 					else
-						value = lua_data[data_index]->int_value * client->GetPlayer()->GetLevel();
+						value = next_spell->lua_data[data_index]->int_value * client->GetPlayer()->GetLevel();
 					value *= ((client->GetPlayer()->GetInfoStruct()->potency / 100) + 1);
 					int32 mod = (int32)min(client->GetPlayer()->GetInfoStruct()->ability_modifier, (float)(value / 2));
 					value += mod;
 					string damage = to_string((int)round(value));
+					damage.erase(damage.find_last_not_of('0') + 1, std::string::npos);
 					effect_message.replace(effect_message.find("%DMH"), 6, damage);
 				}
 				// level based Magic damage min
@@ -700,10 +518,10 @@ void Spell::SetAAPacketInformation(PacketStruct* packet, AltAdvanceData* data, C
 					int string_index = effect_message.find("%LDML");
 					int data_index = stoi(effect_message.substr(string_index + 5, 2));
 					float value;
-					if (lua_data[data_index]->type == 1)
-						value = lua_data[data_index]->float_value * client->GetPlayer()->GetLevel();
+					if (next_spell->lua_data[data_index]->type == 1)
+						value = next_spell->lua_data[data_index]->float_value * client->GetPlayer()->GetLevel();
 					else
-						value = lua_data[data_index]->int_value * client->GetPlayer()->GetLevel();
+						value = next_spell->lua_data[data_index]->int_value * client->GetPlayer()->GetLevel();
 					value *= ((client->GetPlayer()->GetInfoStruct()->potency / 100) + 1);
 					int32 mod = (int32)min(client->GetPlayer()->GetInfoStruct()->ability_modifier, (float)(value / 2));
 					value += mod;
@@ -715,10 +533,10 @@ void Spell::SetAAPacketInformation(PacketStruct* packet, AltAdvanceData* data, C
 					int string_index = effect_message.find("%LDMH");
 					int data_index = stoi(effect_message.substr(string_index + 5, 2));
 					float value;
-					if (lua_data[data_index]->type == 1)
-						value = lua_data[data_index]->float_value * client->GetPlayer()->GetLevel();
+					if (next_spell->lua_data[data_index]->type == 1)
+						value = next_spell->lua_data[data_index]->float_value * client->GetPlayer()->GetLevel();
 					else
-						value = lua_data[data_index]->int_value * client->GetPlayer()->GetLevel();
+						value = next_spell->lua_data[data_index]->int_value * client->GetPlayer()->GetLevel();
 					value *= ((client->GetPlayer()->GetInfoStruct()->potency / 100) + 1);
 					int32 mod = (int32)min(client->GetPlayer()->GetInfoStruct()->ability_modifier, (float)(value / 2));
 					value += mod;
@@ -726,31 +544,221 @@ void Spell::SetAAPacketInformation(PacketStruct* packet, AltAdvanceData* data, C
 					effect_message.replace(effect_message.find("%LDMH"), 7, damage);
 				}
 				//GetZone()->SimpleMessage(CHANNEL_COLOR_SPELL_EFFECT, effect_message.c_str(), victim, 50);
+				packet->setArrayDataByName("next_effect", effect_message.c_str(), i);
 			}
-			packet->setArrayDataByName("effect", effect_message.c_str(), i);
-			packet->setArrayDataByName("percentage", effects[i]->percentage, i);
+
+			packet->setArrayDataByName("next_percentage", next_spell->effects[i]->percentage, i);
+
 		}
 		if (display_tier == true)
-			packet->setSubstructDataByName("spell_info", "display_spell_tier", spell->display_spell_tier);
+			packet->setSubstructDataByName("spell_info", "next_display_spell_tier", 1);// spell->display_spell_tier);
 		else
-			packet->setSubstructDataByName("spell_info", "display_spell_tier", 0);
-		packet->setSubstructDataByName("spell_info", "range", spell->range);
-		packet->setSubstructDataByName("spell_info", "duration1", spell->duration1);
-		packet->setSubstructDataByName("spell_info", "duration2", spell->duration2);
-
-		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);
-		packet->setSubstructDataByName("spell_info", "name", &(spell->name));
-		packet->setSubstructDataByName("spell_info", "description", &(spell->description));
-		//packet->PrintPacket();
+			packet->setSubstructDataByName("spell_info", "next_display_spell_tier", 1);//0
+		packet->setSubstructDataByName("spell_info", "next_unknown_1", 1);//0
+		packet->setSubstructDataByName("spell_info", "next_range", spell2->range);
+		packet->setSubstructDataByName("spell_info", "next_duration_1", spell2->duration1);
+		packet->setSubstructDataByName("spell_info", "next_duration_2", spell2->duration2);
+
+		packet->setSubstructDataByName("spell_info", "next_can_effect_raid", spell2->can_effect_raid);
+		packet->setSubstructDataByName("spell_info", "next_affect_only_group_members", spell2->affect_only_group_members);
+		packet->setSubstructDataByName("spell_info", "next_group_spell", spell2->group_spell);
+		packet->setSubstructDataByName("spell_info", "next_resistibility", spell2->resistibility);
+		packet->setSubstructDataByName("spell_info", "next_name", &(spell2->name));
+		packet->setSubstructDataByName("spell_info", "next_description", &(spell2->description));
+
+	}
 }
-EQ2Packet* Spell::SerializeSpecialSpell(Client* client, bool display, int8 packet_type, int8 sub_packet_type){
+void Spell::SetPacketInformation(PacketStruct* packet, Client* client, bool display_tier) {
+	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() >= 60114) {
+		packet->setSubstructDataByName("spell_info", "version", 0x03);
+		packet->setSubstructDataByName("spell_info", "sub_version", 4890);
+	}
+	else if (packet->GetVersion() <= 546) {
+		packet->setSubstructDataByName("spell_info", "version", 0x10);
+		packet->setSubstructDataByName("spell_info", "sub_version", 0x0f);
+	}
+	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->GetPlayer()));
+		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", "target", spell->target_type);
+	packet->setSubstructDataByName("spell_info", "recovery", spell->recovery);
+	packet->setSubstructDataByName("spell_info", "health_upkeep", spell->hp_upkeep);
+	packet->setSubstructDataByName("spell_info", "health_req", hp_req);
+	packet->setSubstructDataByName("spell_info", "tier", spell->tier);
+	packet->setSubstructDataByName("spell_info", "power_req", power_req);
+	packet->setSubstructDataByName("spell_info", "power_upkeep", spell->power_upkeep);
+
+	packet->setSubstructDataByName("spell_info", "cast_time", spell->cast_time);
+	packet->setSubstructDataByName("spell_info", "recast", spell->recast);
+	packet->setSubstructDataByName("spell_info", "radius", spell->radius);
+	packet->setSubstructDataByName("spell_info", "req_concentration", spell->req_concentration);
+	//packet->setSubstructDataByName("spell_info","req_concentration2", 2);
+	packet->setSubstructDataByName("spell_info", "max_aoe_targets", spell->max_aoe_targets);
+	packet->setSubstructDataByName("spell_info", "friendly_spell", spell->friendly_spell);
+	packet->setSubstructArrayLengthByName("spell_info", "num_effects", effects.size());
+	for (int32 i = 0; i < effects.size(); i++) {
+
+		packet->setArrayDataByName("subbulletflag", effects[i]->subbullet, i);
+		string effect_message;
+		if (effects[i]->description.length() > 0) {
+			effect_message = effects[i]->description;
+			if (effect_message.find("%LM") < 0xFFFFFFFF) {
+				int string_index = effect_message.find("%LM");
+				int data_index = stoi(effect_message.substr(string_index + 3, 2));
+				float value;
+				if (lua_data[data_index]->type == 1)
+					value = lua_data[data_index]->float_value * client->GetPlayer()->GetLevel();
+				else
+					value = lua_data[data_index]->int_value * client->GetPlayer()->GetLevel();
+				string strValue = to_string(value);
+				strValue.erase(strValue.find_last_not_of('0') + 1, std::string::npos);
+				effect_message.replace(effect_message.find("%LM"), 5, strValue);
+			}
+			// Magic damage min
+			if (effect_message.find("%DML") < 0xFFFFFFFF) {
+				int string_index = effect_message.find("%DML");
+				int data_index = stoi(effect_message.substr(string_index + 4, 2));
+				float value;
+				if (lua_data[data_index]->type == 1)
+					value = lua_data[data_index]->float_value * client->GetPlayer()->GetLevel();
+				else
+					value = lua_data[data_index]->int_value * client->GetPlayer()->GetLevel();
+				value *= ((client->GetPlayer()->GetInfoStruct()->potency / 100) + 1);
+				int32 mod = (int32)min(client->GetPlayer()->GetInfoStruct()->ability_modifier, (float)(value / 2));
+				value += mod;
+				string damage = to_string((int)round(value));
+				effect_message.replace(effect_message.find("%DML"), 6, damage);
+			}
+			// Magic damage max
+			if (effect_message.find("%DMH") < 0xFFFFFFFF) {
+				int string_index = effect_message.find("%DMH");
+				int data_index = stoi(effect_message.substr(string_index + 4, 2));
+				float value;
+				if (lua_data[data_index]->type == 1)
+					value = lua_data[data_index]->float_value * client->GetPlayer()->GetLevel();
+				else
+					value = lua_data[data_index]->int_value * client->GetPlayer()->GetLevel();
+				value *= ((client->GetPlayer()->GetInfoStruct()->potency / 100) + 1);
+				int32 mod = (int32)min(client->GetPlayer()->GetInfoStruct()->ability_modifier, (float)(value / 2));
+				value += mod;
+				string damage = to_string((int)round(value));
+				effect_message.replace(effect_message.find("%DMH"), 6, damage);
+			}
+			// level based Magic damage min
+			if (effect_message.find("%LDML") < 0xFFFFFFFF) {
+				int string_index = effect_message.find("%LDML");
+				int data_index = stoi(effect_message.substr(string_index + 5, 2));
+				float value;
+				if (lua_data[data_index]->type == 1)
+					value = lua_data[data_index]->float_value * client->GetPlayer()->GetLevel();
+				else
+					value = lua_data[data_index]->int_value * client->GetPlayer()->GetLevel();
+				value *= ((client->GetPlayer()->GetInfoStruct()->potency / 100) + 1);
+				int32 mod = (int32)min(client->GetPlayer()->GetInfoStruct()->ability_modifier, (float)(value / 2));
+				value += mod;
+				string damage = to_string((int)round(value));
+				effect_message.replace(effect_message.find("%LDML"), 7, damage);
+			}
+			// level based Magic damage max
+			if (effect_message.find("%LDMH") < 0xFFFFFFFF) {
+				int string_index = effect_message.find("%LDMH");
+				int data_index = stoi(effect_message.substr(string_index + 5, 2));
+				float value;
+				if (lua_data[data_index]->type == 1)
+					value = lua_data[data_index]->float_value * client->GetPlayer()->GetLevel();
+				else
+					value = lua_data[data_index]->int_value * client->GetPlayer()->GetLevel();
+				value *= ((client->GetPlayer()->GetInfoStruct()->potency / 100) + 1);
+				int32 mod = (int32)min(client->GetPlayer()->GetInfoStruct()->ability_modifier, (float)(value / 2));
+				value += mod;
+				string damage = to_string((int)round(value));
+				effect_message.replace(effect_message.find("%LDMH"), 7, damage);
+			}
+			//GetZone()->SimpleMessage(CHANNEL_COLOR_SPELL_EFFECT, effect_message.c_str(), victim, 50);
+		}
+		packet->setArrayDataByName("effect", effect_message.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);
+	packet->setSubstructDataByName("spell_info", "range", spell->range);
+	packet->setSubstructDataByName("spell_info", "duration1", spell->duration1);
+	packet->setSubstructDataByName("spell_info", "duration2", spell->duration2);
+
+	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);
+	packet->setSubstructDataByName("spell_info", "name", &(spell->name));
+	packet->setSubstructDataByName("spell_info", "description", &(spell->description));
+	//packet->PrintPacket();
+}
+EQ2Packet* Spell::SerializeSpecialSpell(Client* client, bool display, int8 packet_type, int8 sub_packet_type) {
+	if (client->GetVersion() <= 283)
+		return SerializeSpell(client, display, false, packet_type, 0, "WS_ExaminePartialSpellInfo");
 	return SerializeSpell(client, display, false, packet_type, sub_packet_type, "WS_ExamineSpecialSpellInfo");
 }
 
-EQ2Packet* Spell::SerializeAASpell(Client* client,int8 tier, AltAdvanceData* data, bool display, bool trait_display, int8 packet_type, int8 sub_packet_type, const char* struct_name){
+
+EQ2Packet* Spell::SerializeAASpell(Client* client, int8 tier, AltAdvanceData* data, bool display, bool trait_display, int8 packet_type, int8 sub_packet_type, const char* struct_name) {
 	if (!client)
 		return 0;
 	int16 version = 1;
@@ -797,14 +805,14 @@ EQ2Packet* Spell::SerializeAASpell(Client* client,int8 tier, AltAdvanceData* dat
 	if (sub_packet_type == 0x81)
 		SetAAPacketInformation(packet, data, client);
 	else
-		SetAAPacketInformation(packet,data, client, true);
+		SetAAPacketInformation(packet, data, client, true);
 	packet->setSubstructDataByName("spell_info", "uses_remaining", 0xFFFF);
 	packet->setSubstructDataByName("spell_info", "damage_remaining", 0xFFFF);
 	//packet->PrintPacket();
 	// This adds the second portion to the spell packet. Could be used for bonuses etc.?
 	string* data1 = packet->serializeString();
-	uchar*  data2 = (uchar*)data1->c_str();
-	uchar*  ptr2 = data2;
+	uchar* data2 = (uchar*)data1->c_str();
+	uchar* ptr2 = data2;
 	int32 size = data1->length();// *2;
 	////uchar* data3 = new uchar[size];
 	////memcpy(data3, data2, data1->length());
@@ -916,7 +924,7 @@ EQ2Packet* Spell::SerializeAASpell(Client* client,int8 tier, AltAdvanceData* dat
 	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);		
+		packet->setArrayDataByName("percentage", effects[i]->percentage, i);
 	}
 	//if (display_tier == true)
 	packet->setSubstructDataByName("spell_info", "display_spell_tier", spell->display_spell_tier);
@@ -950,35 +958,51 @@ EQ2Packet* Spell::SerializeAASpell(Client* client,int8 tier, AltAdvanceData* dat
 	*/
 }
 
-EQ2Packet* Spell::SerializeSpell(Client* client, bool display, bool trait_display, int8 packet_type, int8 sub_packet_type, const char* struct_name){
+EQ2Packet* Spell::SerializeSpell(Client* client, bool display, bool trait_display, int8 packet_type, int8 sub_packet_type, const char* struct_name) {
 	int16 version = 1;
-	if(client)
+	if (client)
 		version = client->GetVersion();
-	if(!struct_name)
+	if (!struct_name)
 		struct_name = "WS_ExamineSpellInfo";
+	if (version <= 283) {
+		if (packet_type == 1)
+			struct_name = "WS_ExamineEffectInfo";
+		else if (!display)
+			struct_name = "WS_ExaminePartialSpellInfo";
+		else
+			struct_name = "WS_ExamineSpellInfo";
+	}
 	PacketStruct* packet = configReader.getStruct(struct_name, version);
-	if(display)
+	if (display)
 		packet->setSubstructDataByName("info_header", "show_name", 1);
-	else
+	else {
 		if (!trait_display)
 			packet->setSubstructDataByName("info_header", "show_popup", 1);
 		else
 			packet->setSubstructDataByName("info_header", "show_popup", 0);
-	
-	if(packet_type > 0)
-		packet->setSubstructDataByName("info_header", "packettype", packet_type*256 + 0xFE);
-	else
-		packet->setSubstructDataByName("info_header", "packettype", GetItemPacketType(version));
+	}
+	if (version > 546) {
+		if (packet_type > 0)
+			packet->setSubstructDataByName("info_header", "packettype", packet_type * 256 + 0xFE);
+		else
+			packet->setSubstructDataByName("info_header", "packettype", GetItemPacketType(version));
+	}
+	else {
+		if (packet_type == 3 || packet_type == 0)
+			packet->setSubstructDataByName("info_header", "packettype", 3); // 0: item, 1: effect, 2: recipe, 3: spell/ability
+		else
+			packet->setSubstructDataByName("info_header", "packettype", 1);
+	}
 	//packet->setDataByName("unknown2",5);
 	//packet->setDataByName("unknown7", 1);
 	//packet->setDataByName("unknown9", 20);
 	//packet->setDataByName("unknown10", 1, 2);
-	if(sub_packet_type == 0)
+	if (sub_packet_type == 0)
 		sub_packet_type = 0x83;
 	packet->setSubstructDataByName("info_header", "packetsubtype", sub_packet_type);
 	//packet->setDataByName("unknown3",2);
 	//packet->setDataByName("unknown7", 50);
-	if(sub_packet_type == 0x81)
+	if (sub_packet_type == 0x81)
 		SetPacketInformation(packet, client);
 	else
 		SetPacketInformation(packet, client, true);
@@ -993,24 +1017,29 @@ EQ2Packet* Spell::SerializeSpell(Client* client, bool display, bool trait_displa
 	else {
 		offset = 14;
 	}
-	string* data1 = packet->serializeString();
-	uchar*  data2 = (uchar*)data1->c_str();
-	uchar*  ptr2 = data2;
-	int32 size = data1->length() * 2;
-	uchar* data3 = new uchar[size];
-	memcpy(data3, data2, data1->length());
-	uchar* ptr = data3;
-	size -=offset+3;
-	memcpy(ptr, &size, sizeof(int32)); 
-	size +=3;
-	ptr += data1->length();
-	ptr2 += offset;
-	memcpy(ptr, ptr2, data1->length() - offset);
-
-	EQ2Packet* outapp = new EQ2Packet(OP_ClientCmdMsg, data3, size);
+	EQ2Packet* outapp = 0;
+	if (version > 546) {
+		string* data1 = packet->serializeString();
+		uchar* data2 = (uchar*)data1->c_str();
+		uchar* ptr2 = data2;
+		int32 size = data1->length() * 2;
+		uchar* data3 = new uchar[size];
+		memcpy(data3, data2, data1->length());
+		uchar* ptr = data3;
+		size -= offset + 3;
+		memcpy(ptr, &size, sizeof(int32));
+		size += 3;
+		ptr += data1->length();
+		ptr2 += offset;
+		memcpy(ptr, ptr2, data1->length() - offset);
+
+		outapp = new EQ2Packet(OP_ClientCmdMsg, data3, size);
+		safe_delete_array(data3);
+		safe_delete(packet);
+	}
+	else
+		outapp = packet->serialize();
 	//DumpPacket(outapp);
-	safe_delete_array(data3);
-	safe_delete(packet);
 	return outapp;
 }
 

+ 6 - 3
EQ2/source/WorldServer/WorldDatabase.cpp

@@ -2011,8 +2011,11 @@ void WorldDatabase::UpdateRandomize(int32 spawn_id, sint32 value) {
 int32 WorldDatabase::SaveCharacter(PacketStruct* create, int32 loginID){
 	Query query;
 	int8 race_id = create->getType_int8_ByName("race");
-	int8 class_id = create->getType_int8_ByName("class");//Normal server
-	//int8 class_id = 0; //CLassic Server Only
+	int8 orig_class_id = create->getType_int8_ByName("class");//Normal server
+	int8 class_id = orig_class_id;
+	if ( create->GetVersion() <= 546 )
+		class_id = 0; //Classic Server Only
+
 	int8 gender_id = create->getType_int8_ByName("gender");
 	sint16 auto_admin_status = 0;
 
@@ -2053,7 +2056,7 @@ int32 WorldDatabase::SaveCharacter(PacketStruct* create, int32 loginID){
 						create->getType_int32_ByName("server_id"), 
 						create->getType_EQ2_16BitString_ByName("name").data.c_str(), 
 						race_id, 
-						class_id, 
+						orig_class_id,
 						gender_id, 
 						create->getType_int8_ByName("deity"), 
 						create->getType_float_ByName("body_size"), 

+ 19 - 17
EQ2/source/WorldServer/classes.cpp

@@ -133,29 +133,31 @@ int8 Classes::GetSecondaryBaseClass(int8 class_id){
 }
 
 int8 Classes::GetTSBaseClass(int8 class_id) {
-	class_id += 42;
 	int8 ret = 0;	
-	if(class_id >= ARTISAN)
-		ret = ARTISAN;
+	if (class_id + 42 >= ARTISAN)
+		ret = ARTISAN - 44;
+	else
+		ret = class_id;
 
-	LogWrite(WORLD__DEBUG, 5, "World", "%s returning base tradeskill class ID: %i", __FUNCTION__, ret - 44);
-	return ret - 44;
+	LogWrite(WORLD__DEBUG, 5, "World", "%s returning base tradeskill class ID: %i", __FUNCTION__, ret);
+	return ret;
 }
 
 int8 Classes::GetSecondaryTSBaseClass(int8 class_id) {
-	class_id += 42;
-	int8 ret = 0;
-	if (class_id == ARTISAN)
-		ret = ARTISAN;
-	if (class_id >= CRAFTSMAN && class_id < OUTFITTER)
-		ret = CRAFTSMAN;
-	if (class_id >= OUTFITTER && class_id < SCHOLAR)
-		ret = OUTFITTER;
-	if (class_id >= SCHOLAR)
-		ret = SCHOLAR;
+	int8 ret = class_id + 42;
+	if (ret == ARTISAN)
+		ret = ARTISAN - 44;
+	else if (ret >= CRAFTSMAN && ret < OUTFITTER)
+		ret = CRAFTSMAN - 44;
+	else if (ret >= OUTFITTER && ret < SCHOLAR)
+		ret = OUTFITTER - 44;
+	else if (ret >= SCHOLAR)
+		ret = SCHOLAR - 44;
+	else
+		ret = class_id;
 
-	LogWrite(WORLD__DEBUG, 5, "World", "%s returning secondary tradeskill class ID: %i", __FUNCTION__, ret - 44);
-	return ret - 44;
+	LogWrite(WORLD__DEBUG, 5, "World", "%s returning secondary tradeskill class ID: %i", __FUNCTION__, ret);
+	return ret;
 }
 
 sint8 Classes::GetClassID(const char* name){

+ 335 - 135
EQ2/source/WorldServer/client.cpp

@@ -317,7 +317,8 @@ void Client::SendLoginInfo() {
 
 	ClientPacketFunctions::SendLoginAccepted(this);
 
-	//ClientPacketFunctions::SendAbilities ( this );
+	ClientPacketFunctions::SendAbilities ( this );
+
 	ClientPacketFunctions::SendCommandNamePacket(this);
 
 	ClientPacketFunctions::SendQuickBarInit(this);
@@ -341,8 +342,12 @@ void Client::SendLoginInfo() {
 	database.LoadPlayerMail(this);
 	LogWrite(CCLIENT__DEBUG, 0, "Client", "Send Quest Journal...");
 	SendQuestJournal(true);
-	master_aa_list.DisplayAA(this, 0, 3);
-	SendCollectionList();
+
+	if (version > 546) // right version? possibly not!
+		master_aa_list.DisplayAA(this, 0, 3);
+
+	if (version > 283)
+		SendCollectionList();
 	SendBiography();
 
 	map<int32, Quest*>::iterator itr;
@@ -371,13 +376,14 @@ void Client::SendLoginInfo() {
 		guild->SendAllGuildEvents(this);
 		guild->SendGuildMemberList(this);
 	}*/
-
-	LogWrite(CCLIENT__DEBUG, 0, "Client", "Loading Faction Updates...");
-	EQ2Packet* outapp = player->GetFactions()->FactionUpdate(GetVersion());
-	if (outapp) {
-		LogWrite(CCLIENT__PACKET, 0, "Client", "Dump/Print Packet in func: %s, line: %i", __FUNCTION__, __LINE__);
-		//DumpPacket(outapp);
-		QueuePacket(outapp);
+	if (version > 283) {
+		LogWrite(CCLIENT__DEBUG, 0, "Client", "Loading Faction Updates...");
+		EQ2Packet* outapp = player->GetFactions()->FactionUpdate(GetVersion());
+		if (outapp) {
+			LogWrite(CCLIENT__PACKET, 0, "Client", "Dump/Print Packet in func: %s, line: %i", __FUNCTION__, __LINE__);
+			//DumpPacket(outapp);
+			QueuePacket(outapp);
+		}
 	}
 
 	LogWrite(CCLIENT__DEBUG, 0, "Client", "Send Command List...");
@@ -575,11 +581,13 @@ void Client::HandlePlayerRevive(int32 point_id)
 	zone_desc = GetCurrentZone()->GetZoneDescription();
 	Message(CHANNEL_COLOR_REVIVE, "Reviving in %s at %s.", zone_desc.c_str(), location_name);
 	player->SetSpawnType(4);
-	packet = configReader.getStruct("WS_CancelMoveObjectMode", GetVersion());
-	if (packet)
-	{
-		QueuePacket(packet->serialize());
-		safe_delete(packet);
+	if (version > 283) {
+		packet = configReader.getStruct("WS_CancelMoveObjectMode", GetVersion());
+		if (packet)
+		{
+			QueuePacket(packet->serialize());
+			safe_delete(packet);
+		}
 	}
 
 	packet = configReader.getStruct("WS_TeleportWithinZone", GetVersion());
@@ -596,7 +604,10 @@ void Client::HandlePlayerRevive(int32 point_id)
 	if (packet)
 	{
 		packet->setDataByName("spawn_id", 0xFFFFFFFF);
-		packet->setDataByName("unknown2", 255);
+		packet->setDataByName("speed", 32);
+		packet->setDataByName("unknown2", 0);
+		//DoF Merge: old value and speed wasn't included
+		//packet->setDataByName("unknown2", 255);
 		QueuePacket(packet->serialize());
 		safe_delete(packet);
 	}
@@ -632,15 +643,23 @@ void Client::SendCharInfo() {
 		packet->setDataByName("spawn_id", player->GetIDWithPlayerSpawn(player));
 		packet->setDataByName("size", .56);
 		packet->setDataByName("unknown2", 255);
+		packet->setDataByName("speed", player->GetSpeed());
+		packet->setDataByName("air_speed", player->GetAirSpeed());
 		EQ2Packet* app = packet->serialize();
 		QueuePacket(app);
 		safe_delete(packet);
+
+	}
+	if (version <= 283) {
+		//le: hack to allow client time to zone in, it gets stuck on Loading UI Resources if we go too fast, need to figure it out.  Probably something it doesnt like with ExamineInfo packets
+		Sleep(2000);
 	}
+	//sending bad spawn packet?
 
 	//SendAchievementsList();
 	ClientPacketFunctions::SendCharacterSheet(this);
 	ClientPacketFunctions::SendTraitList(this);// moved from below
-	//ClientPacketFunctions::SendAbilities(this);
+	ClientPacketFunctions::SendAbilities(this);
 
 	ClientPacketFunctions::SendSkillBook(this);
 	if (!player->IsResurrecting()) {
@@ -690,13 +709,16 @@ void Client::SendCharInfo() {
 			QueuePacket(items->at(i)->serialize(GetVersion(), false, GetPlayer()));
 	}
 	safe_delete(items);
-	SendTitleUpdate();
+	if (version > 283) {
+		SendTitleUpdate();
+	}
 
 	GetPlayer()->ChangePrimaryWeapon();
 	GetPlayer()->ChangeSecondaryWeapon();
 	GetPlayer()->ChangeRangedWeapon();
 	database.LoadBuyBacks(this);
-	master_aa_list.DisplayAA(this, 0, 0);
+	if (version > 546)
+		master_aa_list.DisplayAA(this, 0, 0);
 
 	string zone_motd = GetCurrentZone()->GetZoneMOTD();
 	if (zone_motd.length() > 0 && zone_motd[0] != ' ') {
@@ -748,14 +770,17 @@ void Client::SendCharInfo() {
 		}
 	}
 
-	ClientPacketFunctions::SendHousingList(this);
+	if (version > 546)
+		ClientPacketFunctions::SendHousingList(this);
 }
 
 void Client::SendZoneSpawns() {
 	//Allows us to place spawns almost anywhere
-	uchar blah[] = { 0x00,0x3C,0x1C,0x46,0x00,0x3C,0x1C,0x46,0x00,0x3C,0x1C,0x46 };
-	EQ2Packet* app = new EQ2Packet(OP_MoveableObjectPlacementCriteri, blah, sizeof(blah));
-	QueuePacket(app);
+	if (version > 283) {
+		uchar blah[] = { 0x00,0x3C,0x1C,0x46,0x00,0x3C,0x1C,0x46,0x00,0x3C,0x1C,0x46 };
+		EQ2Packet* app = new EQ2Packet(OP_MoveableObjectPlacementCriteri, blah, sizeof(blah));
+		QueuePacket(app);
+	}
 
 	ClientPacketFunctions::SendSkillSlotMappings(this);
 	ClientPacketFunctions::SendGameWorldTime(this);
@@ -778,20 +803,22 @@ void Client::SendZoneInfo() {
 	if (zone) {
 		EQ2Packet* packet = zone->GetZoneInfoPacket(this);
 		QueuePacket(packet);
-		PacketStruct* fog_packet = configReader.getStruct("WS_FogInit", GetVersion());
+		if (version > 283) {
+			PacketStruct* fog_packet = configReader.getStruct("WS_FogInit", GetVersion());
 
-		LogWrite(CCLIENT__PACKET, 0, "Client", "Dump/Print Packet in func: %s, line: %i", __FUNCTION__, __LINE__);
+			LogWrite(CCLIENT__PACKET, 0, "Client", "Dump/Print Packet in func: %s, line: %i", __FUNCTION__, __LINE__);
 #if EQDEBUG >= 9
-		fog_packet->PrintPacket();
+			fog_packet->PrintPacket();
 #endif
 
-		if (fog_packet) {
-			database.LoadFogInit(zone->GetZoneFile(), fog_packet);
-			QueuePacket(fog_packet->serialize());
-			safe_delete(fog_packet);
-		}
+			if (fog_packet) {
+				database.LoadFogInit(zone->GetZoneFile(), fog_packet);
+				QueuePacket(fog_packet->serialize());
+				safe_delete(fog_packet);
+			}
 
-		zone->SendFlightPathsPackets(this);
+			zone->SendFlightPathsPackets(this);
+		}
 	}
 	/*
 	uchar blah[] ={0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x01,0x00,0x00,0x00,0x00
@@ -857,10 +884,16 @@ void Client::SendDefaultGroupOptions() {
 	6 - group autolock
 	7 - solo autolock
 	*/
-	uchar blah7[] = { 0x01,0x01,0x01,0x01,0x00,0x00,0x00 };
-	EQ2Packet* app7 = new EQ2Packet(OP_DefaultGroupOptionsMsg, blah7, sizeof(blah7));
-	QueuePacket(app7);
-
+	PacketStruct* default_options = configReader.getStruct("WS_DefaultGroupOptions", GetVersion());
+	if (default_options) {
+		default_options->setDataByName("loot_method", 1);
+		default_options->setDataByName("loot_items_rarity", 1);
+		default_options->setDataByName("auto_split_coin", 1);
+		default_options->setDataByName("default_yell_method", 1);
+		EQ2Packet* app7 = default_options->serialize();
+		QueuePacket(app7);
+		safe_delete(default_options);
+	}
 }
 
 bool Client::HandlePacket(EQApplicationPacket* app) {
@@ -904,7 +937,7 @@ bool Client::HandlePacket(EQApplicationPacket* app) {
 			// test the original location of Version for clients older than 1212
 			version = request->getType_int16_ByName("version");
 
-			if (version >= 1212 || EQOpcodeManager.count(GetOpcodeVersion(version)) == 0) {
+			if (version == 0 || version >= 1212 || EQOpcodeManager.count(GetOpcodeVersion(version)) == 0) {
 				// must be new client data version method, re-fetch the packet
 				safe_delete(request);
 				request = configReader.getStruct("LoginByNumRequest", 1212);
@@ -937,6 +970,7 @@ bool Client::HandlePacket(EQApplicationPacket* app) {
 	case OP_SysClient: {
 		LogWrite(OPCODE__DEBUG, 1, "Opcode", "Opcode 0x%X (%i): OP_SysClient", opcode, opcode);
 		LogWrite(CCLIENT__DEBUG, 0, "Client", "Client '%s' (%u) is ready for spawn updates.", GetPlayer()->GetName(), GetPlayer()->GetCharacterID());
+		GetPlayer()->SetFullyLoggedIn(true);
 
 		if (!ready_for_updates)
 			database.loadCharacterProperties(this);
@@ -1120,10 +1154,16 @@ bool Client::HandlePacket(EQApplicationPacket* app) {
 			int16 icon = macro_update->getType_int16_ByName("icon");
 			string name = macro_update->getType_EQ2_8BitString_ByName("name").data;
 			int8 count = macro_update->getType_int8_ByName("macro_count");
-			for (int8 i = 0; i < count; i++) {
-				char tmp_command[15] = { 0 };
-				sprintf(tmp_command, "command_%i", i);
-				update->push_back(macro_update->getType_EQ2_16BitString_ByName(tmp_command).data);
+
+			if (GetVersion() <= 283) {
+				update->push_back(macro_update->getType_EQ2_8BitString_ByName("command").data);
+			}
+			else {
+				for (int8 i = 0; i < count; i++) {
+					char tmp_command[15] = { 0 };
+					sprintf(tmp_command, "command_%i", i);
+					update->push_back(macro_update->getType_EQ2_16BitString_ByName(tmp_command).data);
+				}
 			}
 			if (name.length() == 0)
 				database.UpdateCharacterMacro(GetCharacterID(), number, 0, icon, update);
@@ -1281,6 +1321,11 @@ bool Client::HandlePacket(EQApplicationPacket* app) {
 		}
 		break;
 	}
+	case OP_DoneLoadingUIResourcesMsg: {
+		EQ2Packet* app = new EQ2Packet(OP_DoneLoadingUIResourcesMsg, 0, 0);
+		QueuePacket(app);
+		break;
+	}
 	case OP_DoneLoadingZoneResourcesMsg: {
 		LogWrite(OPCODE__DEBUG, 1, "Opcode", "Opcode 0x%X (%i): OP_DoneLoadingZoneResourcesMsg", opcode, opcode);
 		SendZoneSpawns();
@@ -1477,14 +1522,26 @@ bool Client::HandlePacket(EQApplicationPacket* app) {
 		GetCurrentZone()->GetTradeskillMgr()->StopCrafting(this);
 		break;
 	}
-							   //case OP_SignalMsg:{
-							   //	LogWrite(OPCODE__DEBUG, 1, "Opcode", "Opcode 0x%X (%i): OP_SignalMsg", opcode, opcode);
-							   //	//if(app->size == 25 && app->pBuffer[0] == 0x17 && app->pBuffer[24] == 0x79)
-							   //	//	GetPlayer()->ModifySpellStatus(0, 66, true);
-							   //	if(connected && player->GetHP() == 0)
-							   //		DisplayDeadWindow();
-							   //	break;
-							   //				  }
+	case OP_SignalMsg: {
+		PacketStruct* packet = configReader.getStruct("WS_Signal", GetVersion());
+		if (packet) {
+			packet->LoadPacketData(app->pBuffer, app->size);
+			EQ2_16BitString str = packet->getType_EQ2_16BitString_ByName("signal");
+			if (str.size > 0) {
+				if (strcmp(str.data.c_str(), "sys_client_avatar_ready") == 0) {
+					GetPlayer()->SetFullyLoggedIn(true);
+					ready_for_updates = true;
+					GetPlayer()->SendSpawnChanges(true);
+				}
+				const char* zone_script = world.GetZoneScript(player->GetZone()->GetZoneID());
+				if (zone_script && lua_interface)
+				{
+					lua_interface->RunZoneScript(zone_script, "signal_changed", player->GetZone(), player, 0, str.data.c_str());
+				}
+			}
+		}
+		break;
+	}
 	case OP_EntityVerbsRequestMsg: {
 		LogWrite(OPCODE__DEBUG, 1, "Opcode", "Opcode 0x%X (%i): OP_EntityVerbsRequestMsg", opcode, opcode);
 		HandleVerbRequest(app);
@@ -1582,8 +1639,31 @@ bool Client::HandlePacket(EQApplicationPacket* app) {
 	}
 	case OP_PredictionUpdateMsg: {
 		LogWrite(OPCODE__DEBUG, 1, "Opcode", "Opcode 0x%X (%i): OP_PredictionUpdateMsg", opcode, opcode);
-		EQ2Packet* app = new EQ2Packet(OP_PredictionUpdateMsg, 0, 0);
-		QueuePacket(app);
+		if (version <= 546) {
+			int8 offset = 9;
+			if (app->pBuffer[0] == 0xFF)
+				offset += 2;
+			if (app->size > offset) {
+				if (player->IsCasting()) {
+					float distance = 0;
+					float x = player->GetX();
+					float y = player->GetY();
+					float z = player->GetZ();
+					player->PrepareIncomingMovementPacket(app->size - offset, app->pBuffer + offset, version);
+					distance = player->GetDistance(x, y, z, false);
+					if (distance > .5)
+						current_zone->Interrupted(player, 0, SPELL_ERROR_INTERRUPTED, false, true);
+				}
+				else
+					player->PrepareIncomingMovementPacket(app->size - offset, app->pBuffer + offset, version);
+				//DumpPacket(app);
+			}
+		}
+		else {
+			EQ2Packet* app = new EQ2Packet(OP_PredictionUpdateMsg, 0, 0);
+			QueuePacket(app);
+			LogWrite(CCLIENT__PACKET, 0, "Client", "Dump/Print Packet in func: %s, line: %i", __FUNCTION__, __LINE__);
+		}
 		break;
 	}
 	case OP_RemoteCmdMsg: {
@@ -2171,7 +2251,7 @@ bool Client::HandlePacket(EQApplicationPacket* app) {
 	return ret;
 }
 
-bool Client::HandleLootItem(Entity* entity, Item* item) {
+bool Client::HandleLootItem(Spawn* entity, Item* item) {
 	if (!item) {
 		SimpleMessage(CHANNEL_COLOR_YELLOW, "Unable to find item to loot!");
 		return false;
@@ -2219,7 +2299,7 @@ bool Client::HandleLootItem(Entity* entity, Item* item) {
 	return false;
 }
 
-bool Client::HandleLootItem(Entity* entity, int32 item_id) {
+bool Client::HandleLootItem(Spawn* entity, int32 item_id) {
 	if (!entity) {
 		return false;
 	}
@@ -2294,17 +2374,17 @@ void Client::HandleLoot(EQApplicationPacket* app) {
 					if (packet) {
 						packet->LoadPacketData(app->pBuffer, app->size);
 						item_id = packet->getType_int32_ByName("item_id");
-						HandleLootItem((Entity*)spawn, item_id);
+						HandleLootItem(spawn, item_id);
 						safe_delete(packet);
 					}
 				}
 				EQ2Packet* outapp = player->SendInventoryUpdate(GetVersion());
 				if (outapp)
 					QueuePacket(outapp);
-				Loot((Entity*)spawn);
-				if (!((Entity*)spawn)->HasLoot()) {
+				Loot(spawn);
+				if (!spawn->HasLoot()) {
 					CloseLoot();
-					if (((Entity*)spawn)->IsNPC())
+					if (spawn->IsNPC())
 						GetCurrentZone()->RemoveDeadSpawn(spawn);
 				}
 			}
@@ -2387,6 +2467,13 @@ void Client::HandleExamineInfoRequest(EQApplicationPacket* app) {
 	//DumpPacket(app);
 
 	int8 type = app->pBuffer[0];
+	//283: item: 0, effect: 1, recipe: 2, spell: 3
+	if (version <= 283) {
+		if (type == 1)
+			type = 4;
+		else if (type == 2)
+			type = 5;
+	}
 	if (type == 3) {
 		Spell* spell = 0;
 		bool trait_display;
@@ -2398,6 +2485,11 @@ void Client::HandleExamineInfoRequest(EQApplicationPacket* app) {
 		int32 id = request->getType_int32_ByName("id");
 		int32 tier = request->getType_int32_ByName("tier");
 		int32 trait_tier = request->getType_int32_ByName("unknown_id");
+		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)
+			display = request->getType_int8_ByName("display");
 		//printf("Type: (%i) Tier: (%u) Unknown ID: (%u) Item ID: (%u)\n",type,tier,trait_tier,id);
 
 		if (trait_tier != 0xFFFFFFFF) {
@@ -2414,7 +2506,7 @@ void Client::HandleExamineInfoRequest(EQApplicationPacket* app) {
 
 		if (spell && sent_spell_details.count(id) == 0) {
 			sent_spell_details[id] = true;
-			EQ2Packet* app = spell->SerializeSpell(this, false, trait_display);
+			EQ2Packet* app = spell->SerializeSpell(this, display, trait_display);
 			//DumpPacket(app);
 			QueuePacket(app);
 		}
@@ -2522,7 +2614,7 @@ void Client::HandleExamineInfoRequest(EQApplicationPacket* app) {
 		}
 		request->LoadPacketData(app->pBuffer, app->size);
 		int32 id = request->getType_int32_ByName("id");
-		//int16 unknown5 = request->getType_sint16_ByName("unknown5");
+		int16 display = request->getType_int8_ByName("partial_info");
 		SpellEffects* effect = player->GetSpellEffect(id);
 		//printf("Type: (%i) Unknown5: (%i) Item ID: (%u)\n",type,unknown5,id);
 		if (effect) {
@@ -2530,7 +2622,10 @@ void Client::HandleExamineInfoRequest(EQApplicationPacket* app) {
 			Spell* spell = master_spell_list.GetSpell(id, tier);
 			if (spell && sent_spell_details.count(id) == 0) {
 				sent_spell_details[id] = true;
-				EQ2Packet* app = spell->SerializeSpecialSpell(this, false, 0x00, 0x81);
+				int8 type = 0;
+				if (version <= 283)
+					type = 1;
+				EQ2Packet* app = spell->SerializeSpecialSpell(this, false, type, 0x81);
 				//DumpPacket(app);
 				QueuePacket(app);
 			}
@@ -3862,7 +3957,9 @@ void Client::ChangeLevel(int16 old_level, int16 new_level) {
 	// to when you are actually able to select traits.
 	QueuePacket(GetPlayer()->GetPlayerInfo()->serialize(GetVersion()));
 	QueuePacket(master_trait_list.GetTraitListPacket(this));
-	master_aa_list.DisplayAA(this, 0, 0);
+
+	if (version > 546)
+		master_aa_list.DisplayAA(this, 0, 0);
 
 	if (GetPlayer()->SpawnedBots.size() > 0) {
 		map<int32, int32>::iterator itr;
@@ -4069,7 +4166,7 @@ void Client::ChangeTSLevel(int16 old_level, int16 new_level) {
 	QueuePacket(master_trait_list.GetTraitListPacket(this));
 }
 
-void Client::SendPendingLoot(int32 total_coins, Entity* entity) {
+void Client::SendPendingLoot(int32 total_coins, Spawn* entity) {
 	if (entity)
 		Loot(total_coins, player->GetPendingLootItems(entity->GetID()), entity);
 }
@@ -4119,7 +4216,7 @@ string Client::GetCoinMessage(int32 total_coins) {
 	return message;
 }
 
-void Client::Loot(int32 total_coins, vector<Item*>* items, Entity* entity) {
+void Client::Loot(int32 total_coins, vector<Item*>* items, Spawn* entity) {
 	if (!entity) {
 		CloseLoot();
 		return;
@@ -4152,73 +4249,126 @@ void Client::Loot(int32 total_coins, vector<Item*>* items, Entity* entity) {
 	if (packet) {
 		vector<Item*>::iterator itr;
 		int32 packet_size = 0;
-		if (items && items->size() > 0) {
-			packet->setDataByName("loot_count", items->size());
-			packet->setDataByName("display", 1);
-		}
-		packet->setDataByName("unknown2", 1);
-		if (version >= 1096)
-			packet->setDataByName("unknown3", 0x78);
-		else
-			packet->setDataByName("unknown3", 0x3C);
-
-		packet->setDataByName("loot_id", entity->GetID());
-		EQ2Packet* tmpPacket = packet->serialize();
-		packet_size += tmpPacket->size;
+		EQ2Packet* outapp = 0;
 		uchar* data = 0;
-		if (items && items->size() > 0) {
-			data = new uchar[items->size() * 1000 + packet_size];
-			memset(data, 0, items->size() * 1000 + packet_size);
-		}
-		else {
-			data = new uchar[packet_size];
-			memset(data, 0, packet_size);
-		}
-		uchar* ptr = data;
-		memcpy(ptr, tmpPacket->pBuffer, tmpPacket->size);
-		ptr += tmpPacket->size;
-		safe_delete(tmpPacket);
-		Item* item = 0;
-		if (items && items->size() > 0) {
-			for (itr = items->begin(); itr != items->end(); itr++) {
-				item = *itr;
-				memcpy(ptr, &item->details.item_id, sizeof(int32));
-				ptr += sizeof(int32);
-				packet_size += sizeof(int32);
-
-				tmpPacket = item->serialize(GetVersion(), true, GetPlayer(), false, 1, 0, false, true);
-
-				int8 offset = 0;
-				if (GetVersion() >= 1188) {
-					offset = 13;
+		if (GetVersion() >= 284) {
+			if (GetVersion() > 546) {
+				if (items && items->size() > 0) {
+					packet->setDataByName("loot_count", items->size());
+					packet->setDataByName("display", 1);
 				}
-				else if (GetVersion() >= 860) {
-					offset = 11;
+				packet->setDataByName("loot_type", 1);
+				if (version >= 1096)
+					packet->setDataByName("lotto_timeout", 0x78);
+				else
+					packet->setDataByName("lotto_timeout", 0x3C);
+
+				packet->setDataByName("loot_id", entity->GetID());
+				EQ2Packet* tmpPacket = packet->serialize();
+				packet_size += tmpPacket->size;
+				if (items && items->size() > 0) {
+					data = new uchar[items->size() * 1000 + packet_size];
+					memset(data, 0, items->size() * 1000 + packet_size);
 				}
 				else {
-					offset = 10;
+					data = new uchar[packet_size];
+					memset(data, 0, packet_size);
 				}
+				uchar* ptr = data;
+				memcpy(ptr, tmpPacket->pBuffer, tmpPacket->size);
+				ptr += tmpPacket->size;
+				safe_delete(tmpPacket);
+				Item* item = 0;
+				if (items && items->size() > 0) {
+					for (itr = items->begin(); itr != items->end(); itr++) {
+						item = *itr;
+						memcpy(ptr, &item->details.item_id, sizeof(int32));
+						ptr += sizeof(int32);
+						packet_size += sizeof(int32);
+
+						tmpPacket = item->serialize(GetVersion(), true, GetPlayer(), false, 1, 0, false, true);
+
+						int8 offset = 0;
+						if (GetVersion() >= 1188) {
+							offset = 13;
+						}
+						else if (GetVersion() >= 860) {
+							offset = 11;
+						}
+						else if (GetVersion() <= 546) {
+							offset = 19;
+						}
+						else {
+							offset = 10;
+						}
 
-				memcpy(ptr, tmpPacket->pBuffer + offset, tmpPacket->size - offset);
-				ptr += tmpPacket->size - offset;
-				packet_size += tmpPacket->size - offset;
+						memcpy(ptr, tmpPacket->pBuffer + offset, tmpPacket->size - offset);
+						ptr += tmpPacket->size - offset;
+						packet_size += tmpPacket->size - offset;
 
-				safe_delete(tmpPacket);
+						safe_delete(tmpPacket);
+					}
+				}
+				packet_size -= sizeof(int32);
+				memcpy(data, &packet_size, sizeof(int32));
+				packet_size += sizeof(int32);
+				outapp = new EQ2Packet(OP_ClientCmdMsg, data, packet_size);
+			}
+			else {
+				if (items->size() > 0) {
+					packet->setArrayLengthByName("loot_count", items->size());
+					Item* item = 0;
+					if (items && items->size() > 0) {
+						int i = 0;
+						for (itr = items->begin(); itr != items->end(); itr++) {
+							item = *itr;
+							packet->setArrayDataByName("loot_id", item->details.item_id, i);
+							packet->setItemArrayDataByName("item", item, GetPlayer(), i, 0, 2, true);
+							i++;
+						}
+					}
+					packet->setDataByName("display", 1);
+				}
+				packet->setDataByName("loot_type", 1); // normal
+				packet->setDataByName("lotto_timeout", 0x3c); // 60 seconds
+				packet->setDataByName("spawn_id", entity->GetID());
+				outapp = packet->serialize();
 			}
 		}
-		packet_size -= sizeof(int32);
-		memcpy(data, &packet_size, sizeof(int32));
-		packet_size += sizeof(int32);
-		EQ2Packet* outapp = new EQ2Packet(OP_ClientCmdMsg, data, packet_size);
-		//DumpPacket(outapp);
-		QueuePacket(outapp);
+		else {
+			if (items && items->size() > 0) {
+				packet->setArrayLengthByName("loot_count", items->size());
+				for (int i = 0; i < items->size(); i++) {
+					Item* item = (*items)[i];
+					packet->setArrayDataByName("name", item->name.c_str(), i);
+					packet->setArrayDataByName("item_id", item->details.item_id, i);
+					packet->setArrayDataByName("count", item->details.count, i);
+					packet->setArrayDataByName("icon", item->details.icon, i);
+					if (item->generic_info.skill_req1 > 0 && item->generic_info.skill_req1 < 0xFFFFFFFF)
+						packet->setArrayDataByName("ability_id", item->generic_info.skill_req1, i);
+					else if (item->generic_info.skill_req2 > 0 && item->generic_info.skill_req2 < 0xFFFFFFFF)
+						packet->setArrayDataByName("ability_id", item->generic_info.skill_req2, i);
+					else
+						packet->setArrayDataByName("ability_id", 0xFFFFFFFF, i);
+				}
+			}
+			packet->setDataByName("object_id", entity->GetID());
+			packet->setDataByName("unknown3", 1);
+			packet->setDataByName("unknown4", 1);
+			packet->setDataByName("unknown5", 60);
+			outapp = packet->serialize();
+		}
+		if (outapp) {
+			DumpPacket(outapp);
+			QueuePacket(outapp);
+		}
 		safe_delete_array(data);
 		safe_delete(packet);
 	}
 
 }
 
-void Client::Loot(Entity* entity, bool attemptDisarm) {
+void Client::Loot(Spawn* entity, bool attemptDisarm) {
 	if (entity->IsNPC() && ((NPC*)entity)->Brain()->CheckLootAllowed(GetPlayer())) {
 		int32 total_coins = entity->GetLootCoins();
 		entity->LockLoot();
@@ -4232,7 +4382,7 @@ void Client::Loot(Entity* entity, bool attemptDisarm) {
 
 }
 
-void Client::OpenChest(Entity* entity, bool attemptDisarm)
+void Client::OpenChest(Spawn* entity, bool attemptDisarm)
 {
 	if (!entity)
 		return;
@@ -4284,7 +4434,7 @@ void Client::OpenChest(Entity* entity, bool attemptDisarm)
 			{
 				if (disarmSkill->CheckDisarmSkill(entity->GetLevel(), chest_difficulty) < 1)
 				{
-					CastGroupOrSelf(entity, nextTrap.spell_id, nextTrap.spell_tier,
+					CastGroupOrSelf(entity && entity->IsEntity() ? (Entity*)entity : 0, nextTrap.spell_id, nextTrap.spell_tier,
 						rule_manager.GetGlobalRule(R_Loot, ChestTriggerRadiusGroup)->GetFloat());
 					Message(CHANNEL_COLOR_WHITE, "You trigger the trap on %s!", modelName.c_str());
 				}
@@ -4298,7 +4448,7 @@ void Client::OpenChest(Entity* entity, bool attemptDisarm)
 			}
 			else // no disarm skill, always fail
 			{
-				CastGroupOrSelf(entity, nextTrap.spell_id, nextTrap.spell_tier,
+				CastGroupOrSelf(entity && entity->IsEntity() ? (Entity*)entity : 0, nextTrap.spell_id, nextTrap.spell_tier,
 					rule_manager.GetGlobalRule(R_Loot, ChestTriggerRadiusGroup)->GetFloat());
 				Message(CHANNEL_COLOR_WHITE, "You trigger the trap on %s!", modelName.c_str());
 			}
@@ -4711,10 +4861,15 @@ void Client::CheckPlayerQuestsSpellUpdate(Spell* spell) {
 }
 
 void Client::AddPendingQuest(Quest* quest) {
-	player->pending_quests[quest->GetQuestID()] = quest;
-	EQ2Packet* outapp = quest->OfferQuest(GetVersion(), player);
-	//DumpPacket(outapp);
-	QueuePacket(outapp);
+	if (version <= 283) { //this client doesn't ask if you want the quest, so auto accept
+		AcceptQuest(quest->GetQuestID());
+	}
+	else {
+		player->pending_quests[quest->GetQuestID()] = quest;
+		EQ2Packet* outapp = quest->OfferQuest(GetVersion(), player);
+		//DumpPacket(outapp);
+		QueuePacket(outapp);
+	}
 }
 
 Quest* Client::GetActiveQuest(int32 quest_id) {
@@ -4727,6 +4882,23 @@ Quest* Client::GetActiveQuest(int32 quest_id) {
 	return 0;
 }
 
+void Client::AcceptQuest(int32 id) {
+	Quest* quest = GetPendingQuest(id);
+	if (quest) {
+		RemovePendingQuest(quest);
+		AddPlayerQuest(quest);
+		GetCurrentZone()->SendQuestUpdates(this);
+
+		// If character has already completed this quest once update the given date in the database
+		if (GetPlayer()->GetCompletedPlayerQuests()->count(id) > 0) {
+			Quest* quest2 = GetPlayer()->GetCompletedQuest(id);
+			if (quest2)
+				quest->SetCompleteCount(quest2->GetCompleteCount());
+			database.SaveCharRepeatableQuest(this, id, quest->GetCompleteCount());
+		}
+	}
+}
+
 Quest* Client::GetPendingQuest(int32 id) {
 	if (player->pending_quests.count(id) > 0) {
 		LogWrite(CCLIENT__DEBUG, 0, "Client", "Found %u pending quests for char_id: %u", player->pending_quests.count(id), player->GetCharacterID());
@@ -5401,16 +5573,22 @@ bool Client::AddItem(Item* item) {
 	if (!item) {
 		return false;
 	}
-	if (item->IsBag())
+	if (item->IsBag()) {
+		if (GetVersion() <= 283 && item->details.num_slots > CLASSIC_EQ_MAX_BAG_SLOTS)
+			item->details.num_slots = CLASSIC_EQ_MAX_BAG_SLOTS;
 		item->details.bag_id = item->details.unique_id;
+	}
 	if (player->AddItem(item)) {
 		EQ2Packet* outapp = player->SendInventoryUpdate(GetVersion());
 		if (outapp) {
+			//DumpPacket(outapp);
 			QueuePacket(outapp);
 			//resend bag desc with new item name added	
-			outapp = player->SendBagUpdate(item->details.inv_slot_id, GetVersion());
-			if (outapp)
+			outapp = player->SendBagUpdate(item->details.unique_id, GetVersion());
+			if (outapp) {
+				//DumpPacket(outapp);
 				QueuePacket(outapp);
+			}
 			/*EQ2Packet* app = item->serialize(client->GetVersion(), false);
 			DumpPacket(app);
 			client->QueuePacket(app);
@@ -8263,7 +8441,7 @@ void Client::SendLastNameConfirmation() {
 		packet->setDataByName("accept_text", "Yes");
 		packet->setDataByName("accept_command", "confirmedlastname");
 		packet->setDataByName("cancel_text", "No");
-		packet->setDataByName("unknown2", 50);
+		packet->setDataByName("max_length", 50);
 		packet->setDataByName("unknown4", 1);
 		packet->setDataByName("unknown5", 1);
 		QueuePacket(packet->serialize());
@@ -8619,21 +8797,41 @@ void Client::MakeSpawnChangePacket(map<int32, SpawnData> info_changes, map<int32
 {
 	static const int8 oversized = 255;
 	int16 opcode_val = EQOpcodeManager[GetOpcodeVersion(version)]->EmuToEQ(OP_EqUpdateGhostCmd);
-	int32 size = info_size + pos_size + vis_size + 11;
+	int32 size = info_size + pos_size + vis_size + 8;
+	if (version > 283) //version 283 and below uses an overload for size, not always 4 bytes
+		size += 3;
 	size += CheckOverLoadSize(info_size);
 	size += CheckOverLoadSize(pos_size);
 	size += CheckOverLoadSize(vis_size);
-
+	if (version <= 283 && size >= 255) {//1 byte to 3 for overloaded val
+		size += 2;
+	}
 	uchar* tmp = new uchar[size];
 	uchar* ptr = tmp;
 
 	memset(tmp, 0, size);
-
-	size -= 4;
-	memcpy(ptr, &size, sizeof(int32));
-	size += 4;
-	ptr += sizeof(int32);
-
+	if (version <= 283) {
+		if (size >= 255) {
+			size -= 3;
+			memcpy(ptr, &oversized, sizeof(int8));
+			ptr += sizeof(int8);
+			memcpy(ptr, &size, sizeof(int16));
+			ptr += sizeof(int16);
+			size += 3;
+		}
+		else {
+			size -= 1;
+			memcpy(ptr, &size, sizeof(int8));
+			ptr += sizeof(int8);
+			size += 1;
+		}
+	}
+	else {
+		size -= 4;
+		memcpy(ptr, &size, sizeof(int32));
+		ptr += sizeof(int32);
+		size += 4;
+	}
 	memcpy(ptr, &oversized, sizeof(int8));
 	ptr += sizeof(int8);
 
@@ -8670,8 +8868,10 @@ void Client::MakeSpawnChangePacket(map<int32, SpawnData> info_changes, map<int32
 
 	EQ2Packet* packet = new EQ2Packet(OP_ClientCmdMsg, tmp, size);
 
-	//	DumpPacket(packet->pBuffer, packet->size);
 	if (packet) {
+		/*char blah[64];
+		snprintf(blah, 64, "Sending %i", current_time);
+		SimpleMessage(4, blah);*/
 		QueuePacket(packet);
 	}
 

+ 7 - 6
EQ2/source/WorldServer/client.h

@@ -165,8 +165,8 @@ public:
 	void	SendPlayerDeathWindow();
 	float	DistanceFrom(Client* client);
 	void	SendDefaultGroupOptions();
-	bool	HandleLootItem(Entity* entity, int32 item_id);
-	bool	HandleLootItem(Entity* entity, Item* item);
+	bool	HandleLootItem(Spawn* entity, int32 item_id);
+	bool	HandleLootItem(Spawn* entity, Item* item);
 	void	HandleLoot(EQApplicationPacket* app);
 	void	HandleSkillInfoRequest(EQApplicationPacket* app);
 	void	HandleExamineInfoRequest(EQApplicationPacket* app);
@@ -241,10 +241,10 @@ public:
 	void	Save();
 	bool	remove_from_list;
 	void	CloseLoot();
-	void	SendPendingLoot(int32 total_coins, Entity* entity);
-	void	Loot(int32 total_coins, vector<Item*>* items, Entity* entity);
-	void	Loot(Entity* entity, bool attemptDisarm=true);
-	void	OpenChest(Entity* entity, bool attemptDisarm=true);
+	void	SendPendingLoot(int32 total_coins, Spawn* entity);
+	void	Loot(int32 total_coins, vector<Item*>* items, Spawn* entity);
+	void	Loot(Spawn* entity, bool attemptDisarm=true);
+	void	OpenChest(Spawn* entity, bool attemptDisarm=true);
 	void	CastGroupOrSelf(Entity* source, uint32 spellID, uint32 spellTier=1, float restrictiveRadius=0.0f);
 	void	CheckPlayerQuestsKillUpdate(Spawn* spawn);
 	void	CheckPlayerQuestsChatUpdate(Spawn* spawn);
@@ -252,6 +252,7 @@ public:
 	void	CheckPlayerQuestsSpellUpdate(Spell* spell);
 	void	CheckPlayerQuestsLocationUpdate();
 	void	AddPendingQuest(Quest* quest);
+	void	AcceptQuest(int32 id);
 	Quest*	GetPendingQuest(int32 id);
 	void	RemovePendingQuest(Quest* quest);
 	void	SetPlayerQuest(Quest* quest, map<int32, int32>* progress);

+ 161 - 60
EQ2/source/WorldServer/zoneserver.cpp

@@ -1808,8 +1808,8 @@ Spawn* ZoneServer::FindSpawn(Player* searcher, const char* name){
 	return closest;
 }
 
-void ZoneServer::AddChangedSpawn(Spawn* spawn){
-	if(!spawn || (spawn->IsPlayer() && !spawn->info_changed && !spawn->vis_changed))
+void ZoneServer::AddChangedSpawn(Spawn* spawn) {
+	if (!spawn || (spawn->IsPlayer() && !spawn->info_changed && !spawn->vis_changed) || (spawn->IsPlayer() && ((Player*)spawn)->IsFullyLoggedIn() == false))
 		return;
 	if (changed_spawns.count(spawn->GetID()) == 0)
 		changed_spawns.Add(spawn->GetID());
@@ -2608,10 +2608,11 @@ void ZoneServer::AddSpawnGroupLocation(int32 group_id, int32 location_id, int32
 	MSpawnGroupAssociation.releasewritelock(__FUNCTION__, __LINE__);
 }
 
-void ZoneServer::CallSpawnScript(Spawn* npc, int8 type, Spawn* spawn, const char* message){
+bool ZoneServer::CallSpawnScript(Spawn* npc, int8 type, Spawn* spawn, const char* message){
+
 	LogWrite(SPAWN__TRACE, 0, "Spawn", "Enter %s", __FUNCTION__);
 	if(!npc)
-		return;
+		return false;
 
 	const char* script = npc->GetSpawnScript();
 	if ( script == nullptr || strlen(script) < 1 )
@@ -2651,7 +2652,10 @@ void ZoneServer::CallSpawnScript(Spawn* npc, int8 type, Spawn* spawn, const char
 			}
 		}
 	}
+
+	bool result = false;
 	if(lua_interface && script){
+		result = true; // default to true, if we don't match a switch case, return false in default case
 		switch(type){
 			case SPAWN_SCRIPT_SPAWN:{
 				lua_interface->RunSpawnScript(script, "spawn", npc);
@@ -2727,9 +2731,16 @@ void ZoneServer::CallSpawnScript(Spawn* npc, int8 type, Spawn* spawn, const char
 				lua_interface->RunSpawnScript(script, "prespawn", npc);
 				break;
 			}
+			default:
+			{
+				result = false;
+				break;
+			}
 		}
 	}
 	LogWrite(SPAWN__TRACE, 0, "Spawn", "Exit %s", __FUNCTION__);
+
+	return result;
 }
 
 void ZoneServer::DeleteTransporters() {
@@ -3138,16 +3149,60 @@ void ZoneServer::SimpleMessage(int8 type, const char* message, Spawn* from, floa
 	MClientList.releasereadlock(__FUNCTION__, __LINE__);
 }
 
-void ZoneServer::HandleChatMessage(Client* client, Spawn* from, const char* to, int16 channel, const char* message, float distance, const char* channel_name, bool show_bubble, int32 language){
-	if((!distance || from->GetDistance(client->GetPlayer()) <= distance) && (!from || !client->GetPlayer()->IsIgnored(from->GetName()))){
+void ZoneServer::HandleChatMessage(Client* client, Spawn* from, const char* to, int16 channel, const char* message, float distance, const char* channel_name, bool show_bubble, int32 language) {
+	if ((!distance || from->GetDistance(client->GetPlayer()) <= distance) && (!from || !client->GetPlayer()->IsIgnored(from->GetName()))) {
+		if (client->GetVersion() <= 283) {
+			switch (channel) {
+			case CHANNEL_SAY: {
+				channel = CLASSIC_CLIENT_CHANNEL_SAY;
+				break;
+			}
+			case CHANNEL_SHOUT: {
+				channel = CLASSIC_CLIENT_CHANNEL_SHOUT;
+				break;
+			}
+			case CHANNEL_EMOTE: {
+				channel = CLASSIC_CLIENT_CHANNEL_EMOTE;
+				break;
+			}
+			case CHANNEL_GROUP: {
+				channel = CLASSIC_CLIENT_CHANNEL_GROUP;
+				break;
+			}
+			case CHANNEL_RAID: {
+				channel = CLASSIC_CLIENT_CHANNEL_RAID;
+				break;
+			}
+			case CHANNEL_GUILD: {
+				channel = CLASSIC_CLIENT_CHANNEL_GUILD;
+				break;
+			}
+			case CHANNEL_OFFICER: {
+				channel = CLASSIC_CLIENT_CHANNEL_OFFICER;
+				break;
+			}
+			case CHANNEL_SAYTARGET: {
+				channel = CLASSIC_CLIENT_CHANNEL_SAYTARGET;
+				break;
+			}
+			case CHANNEL_TELL: {
+				channel = CLASSIC_CLIENT_CHANNEL_TELL;
+				break;
+			}
+			case CHANNEL_OOC: {
+				channel = CLASSIC_CLIENT_CHANNEL_OOC;
+				break;
+			}
+			}
+		}
 		PacketStruct* packet = configReader.getStruct("WS_HearChat", client->GetVersion());
-		if(packet){
-			if(from)
+		if (packet) {
+			if (from)
 				packet->setMediumStringByName("from", from->GetName());
-			if(client->GetPlayer() != from)
+			if (client->GetPlayer() != from)
 				packet->setMediumStringByName("to", client->GetPlayer()->GetName());
 			packet->setDataByName("channel", channel);
-			if(from && ((from == client->GetPlayer()) || (client->GetPlayer()->WasSentSpawn(from->GetID()) && !client->GetPlayer()->WasSpawnRemoved(from))))
+			if (from && ((from == client->GetPlayer()) || (client->GetPlayer()->WasSentSpawn(from->GetID()) && !client->GetPlayer()->WasSpawnRemoved(from))))
 				packet->setDataByName("from_spawn_id", client->GetPlayer()->GetIDWithPlayerSpawn(from));
 			else
 				packet->setDataByName("from_spawn_id", 0xFFFFFFFF);
@@ -3161,9 +3216,11 @@ void ZoneServer::HandleChatMessage(Client* client, Spawn* from, const char* to,
 				packet->setDataByName("understood", 1);
 
 			show_bubble == true ? packet->setDataByName("show_bubble", 1) : packet->setDataByName("show_bubble", 0);
-			if(channel_name)
+			if (channel_name)
 				packet->setMediumStringByName("channel_name", channel_name);
-			client->QueuePacket(packet->serialize());
+			EQ2Packet* outapp = packet->serialize();
+			DumpPacket(outapp);
+			client->QueuePacket(outapp);
 			safe_delete(packet);
 		}
 	}
@@ -4454,16 +4511,16 @@ void ZoneServer::KillSpawn(bool spawnListLocked, Spawn* dead, Spawn* killer, boo
 	safe_delete(encounter);
 }
 
-void ZoneServer::SendDamagePacket(Spawn* attacker, Spawn* victim, int8 type1, int8 type2, int8 damage_type, int16 damage, const char* spell_name){
+void ZoneServer::SendDamagePacket(Spawn* attacker, Spawn* victim, int8 type1, int8 type2, int8 damage_type, int16 damage, const char* spell_name) {
 	//Scat: was set but never being used anywhere. i see references to 0xFFFFFFFF below so could be old code not used anymore
 	//int32 attacker_id = 0xFFFFFFFF;
 	//if(attacker)
 	//	attacker_id = attacker->GetID();
 	PacketStruct* packet = 0;
 	Client* client = 0;
-	if(attacker && victim && victim->IsPlayer() && victim->GetTarget() == 0){
+	if (attacker && victim && victim->IsPlayer() && victim->GetTarget() == 0) {
 		client = GetClientBySpawn(victim);
-		if(client)
+		if (client)
 			client->TargetSpawn(attacker);
 	}
 
@@ -4471,61 +4528,104 @@ void ZoneServer::SendDamagePacket(Spawn* attacker, Spawn* victim, int8 type1, in
 	MClientList.readlock(__FUNCTION__, __LINE__);
 	for (client_itr = clients.begin(); client_itr != clients.end(); client_itr++) {
 		client = *client_itr;
-		if(!client || (client->GetPlayer() != attacker && client->GetPlayer() != victim && ((attacker && client->GetPlayer()->WasSentSpawn(attacker->GetID()) == false) || (victim && client->GetPlayer()->WasSentSpawn(victim->GetID()) == false))))
+		if (!client || (client->GetPlayer() != attacker && client->GetPlayer() != victim && ((attacker && client->GetPlayer()->WasSentSpawn(attacker->GetID()) == false) || (victim && client->GetPlayer()->WasSentSpawn(victim->GetID()) == false))))
 			continue;
-		if((attacker && client->GetPlayer()->WasSpawnRemoved(attacker)) || (victim && client->GetPlayer()->WasSpawnRemoved(victim)))
+		if ((attacker && client->GetPlayer()->WasSpawnRemoved(attacker)) || (victim && client->GetPlayer()->WasSpawnRemoved(victim)))
 			continue;
-		if(attacker && attacker->GetDistance(client->GetPlayer()) > 50)
+		if (attacker && attacker->GetDistance(client->GetPlayer()) > 50)
 			continue;
-		if(victim && victim->GetDistance(client->GetPlayer()) > 50)
+		if (victim && victim->GetDistance(client->GetPlayer()) > 50)
 			continue;
-		switch(type1){
-			case DAMAGE_PACKET_TYPE_SIPHON_SPELL:
-			case DAMAGE_PACKET_TYPE_SIPHON_SPELL2:
-				packet = configReader.getStruct("WS_HearSiphonSpellDamage", client->GetVersion());
-				break;
-			case DAMAGE_PACKET_TYPE_MULTIPLE_DAMAGE:
+		switch (type1) {
+		case DAMAGE_PACKET_TYPE_SIPHON_SPELL:
+		case DAMAGE_PACKET_TYPE_SIPHON_SPELL2:
+			packet = configReader.getStruct("WS_HearSiphonSpellDamage", client->GetVersion());
+			break;
+		case DAMAGE_PACKET_TYPE_MULTIPLE_DAMAGE:
+			if (client->GetVersion() > 283)
 				packet = configReader.getStruct("WS_HearMultipleDamage", client->GetVersion());
-				break;
-			case DAMAGE_PACKET_TYPE_SIMPLE_CRIT_DMG:
-			case DAMAGE_PACKET_TYPE_SIMPLE_DAMAGE:
+			else
 				packet = configReader.getStruct("WS_HearSimpleDamage", client->GetVersion());
-				break;
-			case DAMAGE_PACKET_TYPE_SPELL_DAMAGE2:
-			case DAMAGE_PACKET_TYPE_SPELL_DAMAGE3:
-			case DAMAGE_PACKET_TYPE_SPELL_CRIT_DMG:
-			case DAMAGE_PACKET_TYPE_SPELL_DAMAGE:
+			break;
+		case DAMAGE_PACKET_TYPE_SIMPLE_CRIT_DMG:
+		case DAMAGE_PACKET_TYPE_SIMPLE_DAMAGE:
+			packet = configReader.getStruct("WS_HearSimpleDamage", client->GetVersion());
+			break;
+		case DAMAGE_PACKET_TYPE_SPELL_DAMAGE2:
+		case DAMAGE_PACKET_TYPE_SPELL_DAMAGE3:
+		case DAMAGE_PACKET_TYPE_SPELL_CRIT_DMG:
+		case DAMAGE_PACKET_TYPE_SPELL_DAMAGE:
+			if (client->GetVersion() > 283)
 				packet = configReader.getStruct("WS_HearSpellDamage", client->GetVersion());
-				if (packet)
-					packet->setSubstructDataByName("header", "unknown", 5);
-				break;
-			case DAMAGE_PACKET_TYPE_RANGE_DAMAGE:
-				packet = configReader.getStruct("WS_HearRangeDamage", client->GetVersion());
-				break;
-			case DAMAGE_PACKET_TYPE_RANGE_SPELL_DMG:
-			case DAMAGE_PACKET_TYPE_RANGE_SPELL_DMG2:
-				packet = configReader.getStruct("WS_HearRangeDamage", client->GetVersion());
-				break;
-			default:
-				LogWrite(ZONE__ERROR, 0, "Zone", "Unknown Damage Packet type: %i in ZoneServer::SendDamagePacket.", type1);
-				MClientList.releasereadlock(__FUNCTION__, __LINE__);
-				return;
+			else
+				packet = configReader.getStruct("WS_HearSimpleDamage", client->GetVersion());
+			if (packet)
+				packet->setSubstructDataByName("header", "unknown", 5);
+			break;
+		case DAMAGE_PACKET_TYPE_RANGE_DAMAGE:
+			packet = configReader.getStruct("WS_HearRangeDamage", client->GetVersion());
+			break;
+		case DAMAGE_PACKET_TYPE_RANGE_SPELL_DMG:
+		case DAMAGE_PACKET_TYPE_RANGE_SPELL_DMG2:
+			packet = configReader.getStruct("WS_HearRangeDamage", client->GetVersion());
+			break;
+		default:
+			LogWrite(ZONE__ERROR, 0, "Zone", "Unknown Damage Packet type: %i in ZoneServer::SendDamagePacket.", type1);
+			MClientList.releasereadlock(__FUNCTION__, __LINE__);
+			return;
 		}
 
-		if(packet){
-			packet->setSubstructDataByName("header", "packet_type", type1);
-			packet->setSubstructDataByName("header", "result_type", type2);
-			if(!attacker)
+		if (packet) {
+			if (client->GetVersion() >= 284) {
+				packet->setSubstructDataByName("header", "packet_type", type1);
+				packet->setSubstructDataByName("header", "result_type", type2);
+			}
+			else {
+				switch (type2) {
+				case DAMAGE_PACKET_RESULT_MISS:
+					packet->setSubstructDataByName("header", "result_type", 1);
+					break;
+				case DAMAGE_PACKET_RESULT_DODGE:
+					packet->setSubstructDataByName("header", "result_type", 2);
+					break;
+				case DAMAGE_PACKET_RESULT_PARRY:
+					packet->setSubstructDataByName("header", "result_type", 3);
+					break;
+				case DAMAGE_PACKET_RESULT_RIPOSTE:
+					packet->setSubstructDataByName("header", "result_type", 4);
+					break;
+				case DAMAGE_PACKET_RESULT_BLOCK:
+					packet->setSubstructDataByName("header", "result_type", 5);
+					break;
+				case DAMAGE_PACKET_RESULT_INVULNERABLE:
+					packet->setSubstructDataByName("header", "result_type", 7);
+					break;
+				case DAMAGE_PACKET_RESULT_RESIST:
+					packet->setSubstructDataByName("header", "result_type", 9);
+					break;
+				case DAMAGE_PACKET_RESULT_REFLECT:
+					packet->setSubstructDataByName("header", "result_type", 10);
+					break;
+				case DAMAGE_PACKET_RESULT_IMMUNE:
+					packet->setSubstructDataByName("header", "result_type", 11);
+					break;
+				}
+				packet->setSubstructDataByName("header", "normal_hit", 1);
+				packet->setSubstructDataByName("header", "defender_proxy", client->GetPlayer()->GetIDWithPlayerSpawn(victim));
+			}
+			if (!attacker)
 				packet->setSubstructDataByName("header", "attacker", 0xFFFFFFFF);
 			else
 				packet->setSubstructDataByName("header", "attacker", client->GetPlayer()->GetIDWithPlayerSpawn(attacker));
-			packet->setSubstructDataByName("header", "defender", client->GetPlayer()->GetIDWithPlayerSpawn(victim));			
+			packet->setSubstructDataByName("header", "defender", client->GetPlayer()->GetIDWithPlayerSpawn(victim));
 			packet->setDataByName("damage_type", damage_type);
 			packet->setDataByName("damage", damage);
-			if(spell_name)
-				packet->setSmallStringByName("spell_name", spell_name);
+			if (spell_name) {
+				packet->setDataByName("spell", 1);
+				packet->setDataByName("spell_name", spell_name);
+			}
 			EQ2Packet* app = packet->serialize();
-		    //DumpPacket(app);
+			//DumpPacket(app);
 			client->QueuePacket(app);
 			safe_delete(packet);
 			packet = 0;
@@ -4847,10 +4947,10 @@ EQ2Packet* ZoneServer::GetZoneInfoPacket(Client* client){
 	packet->setSmallStringByName("upload_page", "test_upload.m");
 	packet->setSmallStringByName("upload_key", "dsya987yda9");
 	packet->setSmallStringByName("zone", GetZoneFile());
-	packet->setSmallStringByName("zone2", GetZoneName());
+	//packet->setSmallStringByName("zone2", GetZoneName());
 
-	if ( strlen(GetZoneSkyFile()) > 0 )
-		packet->setSmallStringByName("zone_unknown2", GetZoneSkyFile()); // used for the sky map
+	//if ( strlen(GetZoneSkyFile()) > 0 )
+	//	packet->setSmallStringByName("zone_unknown2", GetZoneSkyFile()); // used for the sky map
 
 	packet->setSmallStringByName("zone_desc", GetZoneDescription());
 	packet->setSmallStringByName("char_name", client->GetPlayer()->GetName());
@@ -5872,9 +5972,10 @@ void ZoneServer::ProcessAggroChecks(Spawn* spawn) {
 		CheckEnemyList((NPC*)spawn);
 }
 
-void ZoneServer::SendUpdateTitles(Client *client, Title *suffix, Title *prefix) {
+void ZoneServer::SendUpdateTitles(Client* client, Title* suffix, Title* prefix) {
 	assert(client);
-	SendUpdateTitles(client->GetPlayer(), suffix, prefix);
+	if (client->GetVersion() > 546)
+		SendUpdateTitles(client->GetPlayer(), suffix, prefix);
 }
 
 void ZoneServer::SendUpdateTitles(Spawn *spawn, Title *suffix, Title *prefix) {

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

@@ -283,7 +283,7 @@ public:
 	
 	EQ2Packet* GetZoneInfoPacket(Client* client);
 	Spawn*	FindSpawn(Player* searcher, const char* name);
-	void	CallSpawnScript(Spawn* npc, int8 type, Spawn* spawn = 0, const char* message = 0);
+	bool	CallSpawnScript(Spawn* npc, int8 type, Spawn* spawn = 0, const char* message = 0);
 	void	SendSpawnVisualState(Spawn* spawn, int16 type);
 	void	SendSpellFailedPacket(Client* client, int16 error);
 	void	SendInterruptPacket(Spawn* interrupted, LuaSpell* spell);

+ 19 - 3
EQ2/source/common/ConfigReader.cpp

@@ -74,11 +74,17 @@ PacketStruct* ConfigReader::getStruct(const char* name, int16 version){
 	if(struct_versions){
 		vector<PacketStruct*>::iterator iter;
 		for(iter = struct_versions->begin(); iter != struct_versions->end(); iter++){
-			if(!latest_version || ( (*iter)->GetVersion() > latest_version->GetVersion() && (*iter)->GetVersion() <= version) )
+			if((*iter)->GetVersion() <= version && (!latest_version || (*iter)->GetVersion() > latest_version->GetVersion()))
 				latest_version = *iter;
+		}		
+		if (latest_version) {
+			if(strlen(latest_version->GetOpcodeType()) == 0 || latest_version->GetOpcode() != OP_Unknown)
+				new_latest_version = new PacketStruct(latest_version, version);
+			else {
+				cout << "here: " << latest_version->GetOpcodeType() << endl;
+				LogWrite(PACKET__ERROR, 0, "Packet", "Could not find valid opcode for Packet Struct '%s' and client version %d", latest_version->GetOpcodeType(), version);
+			}
 		}
-		if(latest_version)
-			new_latest_version = new PacketStruct(latest_version, version);
 			
 	}
 	MStructs.unlock();
@@ -174,6 +180,9 @@ void ConfigReader::loadDataStruct(PacketStruct* packet, XMLNode parentNode, bool
 			const char* if_not_variable = parentNode.getChildNode("Data", x).getAttribute("IfVariableNotSet");
 			const char* if_equals_variable = parentNode.getChildNode("Data", x).getAttribute("IfVariableEquals");
 			const char* if_not_equals_variable = parentNode.getChildNode("Data", x).getAttribute("IfVariableNotEquals");
+			const char* optional = parentNode.getChildNode("Data", x).getAttribute("Optional");
+			const char* if_flag_not_set_variable = parentNode.getChildNode("Data", x).getAttribute("IfFlagNotSet");
+			const char* if_flag_set_variable = parentNode.getChildNode("Data", x).getAttribute("IfFlagSet");
 
 			//const char* type2criteria = parentNode.getChildNode("Data", x).getAttribute("Type2Criteria");	// JA: LE added to PacketAnalyzer for Items parsing - 12.2012
 			//const char* criteria = parentNode.getChildNode("Data", x).getAttribute("Criteria");				// JA: LE added to PacketAnalyzer for Items parsing - 12.2012
@@ -227,6 +236,9 @@ void ConfigReader::loadDataStruct(PacketStruct* packet, XMLNode parentNode, bool
 							ds2->SetIfNotSetVariable(ds->GetIfNotSetVariable());
 							ds2->SetIfEqualsVariable(ds->GetIfEqualsVariable());
 							ds2->SetIfNotEqualsVariable(ds->GetIfNotEqualsVariable());
+							ds2->SetIfFlagNotSetVariable(ds->GetIfFlagNotSetVariable());
+							ds2->SetIfFlagSetVariable(ds->GetIfFlagSetVariable());
+							ds2->SetIsOptional(ds->IsOptional());							
 							packet->add(ds2);
 						}
 					}
@@ -280,6 +292,10 @@ void ConfigReader::loadDataStruct(PacketStruct* packet, XMLNode parentNode, bool
 			ds->SetIfNotSetVariable(if_not_variable);
 			ds->SetIfEqualsVariable(if_equals_variable);
 			ds->SetIfNotEqualsVariable(if_not_equals_variable);
+			ds->SetIfFlagNotSetVariable(if_flag_not_set_variable);
+			ds->SetIfFlagSetVariable(if_flag_set_variable);
+			if (optional && strlen(optional) > 0 && (strcmp("true", optional) == 0 || strcmp("TRUE", optional) == 0 || strcmp("True", optional) == 0))
+				ds->SetIsOptional(true);
 			packet->add(ds);
 		}
 }

+ 62 - 0
EQ2/source/common/EQ2_Common_Structs.h

@@ -56,6 +56,33 @@ struct LS_LoginResponse{
 	int16	unknown12;
 };
 #pragma pack()
+enum EQ2_EquipmentSlot {
+	slot_primary=0,
+	slot_secondary=1,
+	slot_head=2,
+	slot_chest=3,
+	slot_shoulders=4,
+	slot_forearms=5,
+	slot_hands=6,
+	slot_legs=7,
+	slot_feet=8,
+	slot_left_ring=9,
+	slot_right_ring=10,
+	slot_ears=11,
+	slot_neck=12,
+	slot_left_wrist=13,
+	slot_right_wrist=14,
+	slot_ranged=15,
+	slot_ammo=16,
+	slot_waist=17,
+	slot_activate1=18,
+	slot_activate2=19,
+	slot_textures=20,
+	slot_hair=21,
+	slot_beard=22,
+	slot_naked_chest=23,
+	slot_naked_legs=24
+};
 struct EQ2_EquipmentItem{
 	int16		type;
 	EQ2_Color	color;
@@ -166,6 +193,7 @@ struct AppearanceData {
 	int8			icon;
 	int8            hide_hood;
 	int8			show_level;
+
 	int8			locked_no_loot;
 	int8			quest_flag;
 	int8			heroic_flag;
@@ -223,6 +251,40 @@ struct Player_Update{
 /*0144*/	float	speed_y;
 /*0148*/	float	speed_z;
 };
+struct Player_Update283 {
+	/*0000*/	int32	activity;
+	/*0004*/	int32	movement_mode; // 1
+	/*0008*/	float	direction1;
+	/*0012*/	float	desiredpitch;
+	/*0016*/	float	desired_heading_speed;
+	/*0020*/	float	desired_pitch_speed;
+	/*0024*/	float	collision_radius;
+	/*0028*/	float	collision_scale;
+	/*0032*/	float	temp_scale;
+	/*0036*/	float	speed_modifier;
+	/*0040*/	float	swim_speed_modifier;
+	/*0044*/	float	speed;
+	/*0048*/	float	side_speed;
+	/*0052*/	float	vert_speed;
+	/*0056*/	float	orig_x;
+	/*0060*/	float	orig_y;
+	/*0064*/	float	orig_z;
+	/*0068*/	float	orig_x2;
+	/*0072*/	float	orig_y2;
+	/*0076*/	float	orig_z2;
+	/*0080*/	int32	face_actor_id;
+	/*0084*/	int32	face_actor_range;
+	/*0088*/	int32	grid_location;
+	/*0092*/	float	x;
+	/*0096*/	float	y;
+	/*0100*/	float	z;
+	/*0104*/	float	direction2;
+	/*0108*/	float	pitch;
+	/*0112*/	float	roll;
+	/*0116*/	float	speed_x;
+	/*0120*/	float	speed_y;
+	/*0124*/	float	speed_z;
+};//0128
 struct Player_Update1096{
 /*0000*/	int32	activity;
 /*0004*/	float	unknown2; // 1

+ 26 - 11
EQ2/source/common/EQPacket.cpp

@@ -54,26 +54,40 @@ EQPacket::EQPacket(const uint16 op, const unsigned char *buf, uint32 len)
 		}
 	}
 }
-int8 EQ2Packet::PreparePacket(int16 MaxLen){
+
+const char* EQ2Packet::GetOpcodeName() {
+	int16 OpcodeVersion = GetOpcodeVersion(version);
+	if (EQOpcodeManager.count(OpcodeVersion) > 0)
+		return EQOpcodeManager[OpcodeVersion]->EmuToName(login_op);
+	else
+		return NULL;
+}
+
+int8 EQ2Packet::PreparePacket(int16 MaxLen) {
 	int16 OpcodeVersion = GetOpcodeVersion(version);
 
 	// stops a crash for incorrect version
-	if(EQOpcodeManager.count(OpcodeVersion) == 0)
+	if (EQOpcodeManager.count(OpcodeVersion) == 0)
 	{
-		LogWrite(PACKET__ERROR, 0, "Packet", "Version %i is not listed in the opcodes table.",version);
+		LogWrite(PACKET__ERROR, 0, "Packet", "Version %i is not listed in the opcodes table.", version);
 		return -1;
 	}
 
 	packet_prepared = true;
 
 	int16 login_opcode = EQOpcodeManager[OpcodeVersion]->EmuToEQ(login_op);
+	if (login_opcode == 0xcdcd)
+	{
+		LogWrite(PACKET__ERROR, 0, "Packet", "Version %i is not listed in the opcodes table for opcode %s", version, EQOpcodeManager[OpcodeVersion]->EmuToName(login_op));
+		return -1;
+	}
 	int8 offset = 0;
 	//one of the int16s is for the seq, other is for the EQ2 opcode and compressed flag (OP_Packet is the header, not the opcode)
 	int32 new_size = size + sizeof(int16) + sizeof(int8);
 	bool oversized = false;
-	if(login_opcode != 2){
-		new_size+=sizeof(int8); //for opcode
-		if(login_opcode >= 255){
+	if (login_opcode != 2) {
+		new_size += sizeof(int8); //for opcode
+		if (login_opcode >= 255) {
 			new_size += sizeof(int16);
 			oversized = true;
 		}
@@ -81,10 +95,10 @@ int8 EQ2Packet::PreparePacket(int16 MaxLen){
 			login_opcode = ntohs(login_opcode);
 	}
 	uchar* new_buffer = new uchar[new_size];
-	memset(new_buffer,0,new_size);
+	memset(new_buffer, 0, new_size);
 	uchar* ptr = new_buffer + sizeof(int16); // sequence is first
-	if(login_opcode != 2){
-		if(oversized){
+	if (login_opcode != 2) {
+		if (oversized) {
 			ptr += sizeof(int8); //compressed flag
 			int8 addon = 0xff;
 			memcpy(ptr, &addon, sizeof(int8));
@@ -93,7 +107,7 @@ int8 EQ2Packet::PreparePacket(int16 MaxLen){
 		memcpy(ptr, &login_opcode, sizeof(int16));
 		ptr += sizeof(int16);
 	}
-	else{
+	else {
 		memcpy(ptr, &login_opcode, sizeof(int8));
 		ptr += sizeof(int8);
 	}
@@ -104,6 +118,7 @@ int8 EQ2Packet::PreparePacket(int16 MaxLen){
 	size = new_size;
 	return offset;
 }
+
 uint32 EQProtocolPacket::serialize(unsigned char *dest, int8 offset) const
 {
 	if (opcode>0xff)  {
@@ -270,7 +285,7 @@ bool EQ2Packet::AppCombine(EQ2Packet* rhs){
 		safe_delete(rhs);
 		result=true;
 	}
-	else if((size + rhs->size + 6) < 255){
+	else if (rhs->size > 2 && size > 2 && (size + rhs->size + 6) < 255) {
 		int32 tmp_size = size - 2;
 		int32 tmp_size2 = rhs->size - 2;
 		opcode=OP_AppCombined;

+ 1 - 0
EQ2/source/common/EQPacket.h

@@ -144,6 +144,7 @@ public:
 		return new_packet;
 	}
 	int8 PreparePacket(int16 MaxLen);
+	const char* GetOpcodeName();
 	EmuOpcode login_op;
 };
 class EQApplicationPacket : public EQPacket {

+ 106 - 19
EQ2/source/common/EQStream.cpp

@@ -136,6 +136,13 @@ EQStream::EQStream(sockaddr_in addr){
 	client_version = 0;
 	received_packets = 0;
 	sent_packets = 0;
+
+#ifdef WRITE_PACKETS
+	write_packets = 0;
+	char write_packets_filename[64];
+	snprintf(write_packets_filename, sizeof(write_packets_filename), "PacketLog%i.log", Timer::GetCurrentTime2());
+	write_packets = fopen(write_packets_filename, "w+");
+#endif
 }
 
 EQProtocolPacket* EQStream::ProcessEncryptedData(uchar* data, int32 size, int16 opcode){
@@ -203,7 +210,12 @@ bool EQStream::HandleEmbeddedPacket(EQProtocolPacket *p, int16 offset, int16 len
 				DumpPacket(newpacket);
 #endif
 				EQApplicationPacket* ap = newpacket->MakeApplicationPacket(2);
+				if (ap->version == 0)
+					ap->version = client_version;
 				InboundQueuePush(ap);
+#ifdef WRITE_PACKETS
+				WritePackets(ap->GetOpcodeName(), p->pBuffer + 1 + offset, length, false);
+#endif
 				safe_delete(newpacket);
 			}
 			else
@@ -317,6 +329,11 @@ void EQStream::ProcessPacket(EQProtocolPacket *p, EQProtocolPacket* lastp)
 #ifdef LE_DEBUG
 								printf( "OP_AppCombined Here2:\n");
 								DumpPacket(ap);
+#endif
+								if (ap->version == 0)
+									ap->version = client_version;
+#ifdef WRITE_PACKETS
+								WritePackets(ap->GetOpcodeName(), p->pBuffer + processed + offset, subpacket_length, false);
 #endif
 								InboundQueuePush(ap);
 								safe_delete(newpacket);
@@ -375,7 +392,12 @@ void EQStream::ProcessPacket(EQProtocolPacket *p, EQProtocolPacket* lastp)
 						EQProtocolPacket* newpacket = ProcessEncryptedPacket(p);
 						MCombineQueueLock.unlock();
 						if(newpacket){
-							EQApplicationPacket *ap = newpacket->MakeApplicationPacket(2);
+							EQApplicationPacket* ap = newpacket->MakeApplicationPacket(2);
+							if (ap->version == 0)
+								ap->version = client_version;
+#ifdef WRITE_PACKETS
+							WritePackets(ap->GetOpcodeName(), p->pBuffer, p->size, false);
+#endif
 							InboundQueuePush(ap);
 							safe_delete(newpacket);
 						}
@@ -435,7 +457,13 @@ void EQStream::ProcessPacket(EQProtocolPacket *p, EQProtocolPacket* lastp)
 									MCombineQueueLock.lock();
 									EQProtocolPacket* p2 = ProcessEncryptedData(oversize_buffer, oversize_offset, p->opcode);
 									MCombineQueueLock.unlock();
-									EQApplicationPacket *ap = p2->MakeApplicationPacket(2);
+									EQApplicationPacket* ap = p2->MakeApplicationPacket(2);
+									ap->copyInfo(p);
+									if (ap->version == 0)
+										ap->version = client_version;
+#ifdef WRITE_PACKETS
+									WritePackets(ap->GetOpcodeName(), oversize_buffer, oversize_offset, false);
+#endif
 									ap->copyInfo(p);
 									InboundQueuePush(ap);
 									safe_delete(p2);
@@ -623,24 +651,15 @@ void EQStream::ProcessPacket(EQProtocolPacket *p, EQProtocolPacket* lastp)
 				//EQApplicationPacket *ap = p->MakeApplicationPacket(app_opcode_size);
 				//InboundQueuePush(ap);
 
-				printf("!!!!!!!!!GarbageBEFORE Packet!!!!!!!!!!!!!:\n");
-				DumpPacket(p->pBuffer, p->size);
-				LogWrite(PACKET__INFO, 0, "Packet", "Received unknown packet type");
-				crypto->RC4Decrypt(p->pBuffer, p->size);
-				LogWrite(PACKET__ERROR, 0, "Packet", "Garbage packet?!:");
-				printf("!!!!!!!!!GarbageAFTER Packet!!!!!!!!!!!!!:\n");
-				DumpPacket(p->pBuffer, p->size);
-
-				if (oversize_buffer) {
-					printf("!!!!!!!!!OverSizedBufferExists: %i, %i, %i!!!!!!!!!!!!!:\n", oversize_offset, p->size, oversize_length);
-				}
-
-				if (lastp)
-				{
-					printf("!!!!!!!!!PREVIOUSPACKET!!!!!!!!!!!!!:\n");
-					DumpPacket(lastp->pBuffer, lastp->size);
-				}
+				EQApplicationPacket* ap = p->MakeApplicationPacket(app_opcode_size);
+				if (ap->version == 0)
+					ap->version = client_version;
+#ifdef WRITE_PACKETS
+				WritePackets(ap->GetOpcodeName(), p->pBuffer, p->size, false);
+#endif
 				//InboundQueuePush(ap);
+				LogWrite(PACKET__INFO, 0, "Packet", "Received unknown packet type, not adding to inbound queue");
+				safe_delete(ap);
 				//SendDisconnect();
 				break;
 		}
@@ -763,6 +782,70 @@ void EQStream::UnPreparePacket(EQ2Packet* app){
 	}
 }
 
+#ifdef WRITE_PACKETS
+char EQStream::GetChar(uchar in)
+{
+	if (in < ' ' || in > '~')
+		return '.';
+	return (char)in;
+}
+void EQStream::WriteToFile(char* pFormat, ...) {
+	va_list args;
+	va_start(args, pFormat);
+	vfprintf(write_packets, pFormat, args);
+	va_end(args);
+}
+
+void EQStream::WritePackets(const char* opcodeName, uchar* data, int32 size, bool outgoing) {
+	MWritePackets.lock();
+	struct in_addr ip_addr;
+	ip_addr.s_addr = remote_ip;
+	char timebuffer[80];
+	time_t rawtime;
+	struct tm* timeinfo;
+	time(&rawtime);
+	timeinfo = localtime(&rawtime);
+	strftime(timebuffer, 80, "%m/%d/%Y %H:%M:%S", timeinfo);
+	if (outgoing)
+		WriteToFile("-- %s --\n%s\nSERVER -> %s\n", opcodeName, timebuffer, inet_ntoa(ip_addr));
+	else
+		WriteToFile("-- %s --\n%s\n%s -> SERVER\n", opcodeName, timebuffer, inet_ntoa(ip_addr));
+	int i;
+	int nLines = size / 16;
+	int nExtra = size % 16;
+	uchar* pPtr = data;
+	for (i = 0; i < nLines; i++)
+	{
+		WriteToFile("%4.4X:\t%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c\n", i * 16, pPtr[0], pPtr[1], pPtr[2], pPtr[3], pPtr[4], pPtr[5], pPtr[6], pPtr[7], pPtr[8], pPtr[9], pPtr[10], pPtr[11], pPtr[12], pPtr[13], pPtr[14], pPtr[15], GetChar(pPtr[0]), GetChar(pPtr[1]), GetChar(pPtr[2]), GetChar(pPtr[3]), GetChar(pPtr[4]), GetChar(pPtr[5]), GetChar(pPtr[6]), GetChar(pPtr[7]), GetChar(pPtr[8]), GetChar(pPtr[9]), GetChar(pPtr[10]), GetChar(pPtr[11]), GetChar(pPtr[12]), GetChar(pPtr[13]), GetChar(pPtr[14]), GetChar(pPtr[15]));
+		pPtr += 16;
+	}
+	if (nExtra)
+	{
+		WriteToFile("%4.4X\t", nLines * 16);
+		for (i = 0; i < nExtra; i++)
+		{
+			WriteToFile("%2.2X ", pPtr[i]);
+		}
+		for (i; i < 16; i++)
+			WriteToFile("   ");
+		for (i = 0; i < nExtra; i++)
+		{
+			WriteToFile("%c", GetChar(pPtr[i]));
+		}
+		WriteToFile("\n");
+	}
+	WriteToFile("\n\n");
+	fflush(write_packets);
+	MWritePackets.unlock();
+}
+
+void EQStream::WritePackets(EQ2Packet* app, bool outgoing) {
+	if (app->version == 0)
+		app->version = client_version;
+	WritePackets(app->GetOpcodeName(), app->pBuffer, app->size, outgoing);
+}
+#endif
+
 void EQStream::PreparePacket(EQ2Packet* app, int8 offset){
 	app->setVersion(client_version);
 	compressed_offset = 0;
@@ -781,6 +864,10 @@ void EQStream::PreparePacket(EQ2Packet* app, int8 offset){
 	printf( "After Prepare in %s, line %i:\n", __FUNCTION__, __LINE__);
 	DumpPacket(app);
 #endif
+#ifdef WRITE_PACKETS
+	if (!app->eq2_compressed && !app->packet_encrypted)
+		WritePackets(app, true);
+#endif
 
 	if(!app->eq2_compressed && app->size>128){
 		compressed_offset = EQ2_Compress(app);

+ 16 - 0
EQ2/source/common/EQStream.h

@@ -38,6 +38,9 @@
 #include "Crypto.h"
 #include "zlib.h"
 #include "timer.h"
+#ifdef WRITE_PACKETS
+#include <stdarg.h>
+#endif
 
 using namespace std;
 
@@ -164,6 +167,15 @@ class EQStream {
 		uint8 active_users;	//how many things are actively using this
 		Mutex MInUse;
 
+#ifdef WRITE_PACKETS
+		FILE* write_packets = NULL;
+		char GetChar(uchar in);
+		void WriteToFile(char* pFormat, ...);
+		void WritePackets(const char* opcodeName, uchar* data, int32 size, bool outgoing);
+		void WritePackets(EQ2Packet* app, bool outgoing);
+		Mutex MWritePackets;
+#endif
+
 		EQStreamState State;
 		Mutex MState;
 
@@ -249,6 +261,10 @@ class EQStream {
 			for (oop = OutOfOrderpackets.begin(); oop != OutOfOrderpackets.end(); oop++){
 				safe_delete(oop->second);
 			}
+#ifdef WRITE_PACKETS			
+			if (write_packets)
+				fclose(write_packets);
+#endif
 		}
 		inline void SetFactory(EQStreamFactory *f) { Factory=f; }
 		void init(bool resetSession = true);

+ 28 - 11
EQ2/source/common/MiscFunctions.cpp

@@ -422,7 +422,7 @@ bool Unpack(int32 srcLen, uchar* data, uchar* dst, int16 dstLen, int16 version,
     return srcLen <= 0;
 }
 
-int32 Pack(uchar* data, uchar* src, int16 srcLen, int16 dstLen, int16 version) {
+int32 Pack(uchar* data, uchar* src, int16 srcLen, int16 dstLen, int16 version, bool reverse) {
 	int16	real_pos = 4;
     int32	pos     = 0;
     int32	code    = 0;
@@ -430,17 +430,22 @@ int32 Pack(uchar* data, uchar* src, int16 srcLen, int16 dstLen, int16 version) {
     int		codeLen = 0;
     int8	zeroLen = 0;
 	memset(data,0,dstLen);
-
+	if (version > 1 && version <= 283)
+		reverse = false;
     while(pos < srcLen) {
         if(src[pos] || codeLen) {
             if(!codeLen) {
-                if(zeroLen > 5) {
+                /*if(zeroLen > 5) {
 					data[real_pos++] = zeroLen;
                     zeroLen = 0;
                 }
 				else if(zeroLen >= 1 && zeroLen<=5){
 					for(;zeroLen>0;zeroLen--)
 						codeLen++;
+				}*/
+				if (zeroLen) {
+					data[real_pos++] = zeroLen;
+					zeroLen = 0;
 				}
                 codePos = real_pos;
                 code    = 0;
@@ -472,7 +477,8 @@ int32 Pack(uchar* data, uchar* src, int16 srcLen, int16 dstLen, int16 version) {
     } else if(zeroLen) {
         data[real_pos++] = zeroLen;
     }
-	Reverse(data + 4, real_pos - 4);
+	if(reverse)
+		Reverse(data + 4, real_pos - 4);
     int32 dataLen = real_pos - 4;
 	memcpy(&data[0], &dataLen, sizeof(int32));
     return dataLen + 4;
@@ -528,6 +534,15 @@ void Encode(uchar* dst, uchar* src, int16 len) {
     memcpy(dst, data, len);
 	safe_delete_array(data);
 }
+
+float TransformToFloat(sint16 data, int8 bits) {
+	return (float)(data / (float)(1 << bits));
+}
+
+sint16 TransformFromFloat(float data, int8 bits) {
+	return (sint16)(data * (1 << bits));
+}
+
 void	SetColor(EQ2_Color* color, long data){
 	memcpy(color, &data, sizeof(EQ2_Color));
 }
@@ -794,20 +809,22 @@ int16 GetItemPacketType(int32 version) {
 		item_version = 0x3EFE;
 	else if (version >= 1188)
 		item_version = 0x3DFE;
-	else if(version >= 1096)
+	else if (version >= 1096)
 		item_version = 0x35FE;
-	else if(version >= 1027)
+	else if (version >= 1027)
 		item_version = 0x31FE;
-	else if(version >= 1008)
+	else if (version >= 1008)
 		item_version = 0x2CFE;
-	else if(version >= 927)
+	else if (version >= 927)
 		item_version = 0x23FE;
-	else if(version >= 893)
+	else if (version >= 893)
 		item_version = 0x22FE;
-	else if(version >= 860)
+	else if (version >= 860)
 		item_version = 0x20FE;
-	else
+	else if (version > 546)
 		item_version = 0x1CFE;
+	else
+		item_version = 0;
 
 	return item_version;
 }

+ 5 - 1
EQ2/source/common/MiscFunctions.h

@@ -48,6 +48,10 @@ sint16  storeInt16String(uchar* buffer, int16 buffer_size, string in_str);
 sint16   storeInt8String(uchar* buffer, int16 buffer_size, string in_str);
 int		MakeRandomInt(int low, int high);
 float	MakeRandomFloat(float low, float high);
+
+float TransformToFloat(sint16 data, int8 bits);
+sint16 TransformFromFloat(float data, int8 bits);
+
 int32	GenerateEQ2Color(float r, float g, float b);
 int32	GenerateEQ2Color(float* rgb[3]);
 void	SetColor(EQ2_Color* color, long data);
@@ -56,7 +60,7 @@ int8	MakeInt8(uchar* data, int16* size);
 int8	MakeInt8(float* input);
 bool	Unpack(int32 srcLen, uchar* data, uchar* dst, int16 dstLen, int16 version = 0, bool reverse = true);
 bool	Unpack(uchar* data, uchar* dst, int16 dstLen, int16 version = 0, bool reverse = true);
-int32	Pack(uchar* data, uchar* src, int16 srcLen, int16 dstLen, int16 version = 0);
+int32	Pack(uchar* data, uchar* src, int16 srcLen, int16 dstLen, int16 version = 0, bool reverse = true);
 void	Reverse(uchar* input, int32 srcLen);
 void	Encode(uchar* dst, uchar* src, int16 len);
 void	Decode(uchar* dst, uchar* src, int16 len);

File diff suppressed because it is too large
+ 564 - 488
EQ2/source/common/PacketStruct.cpp


+ 167 - 150
EQ2/source/common/PacketStruct.h

@@ -1,21 +1,21 @@
-/*  
-    EQ2Emulator:  Everquest II Server Emulator
-    Copyright (C) 2007  EQ2EMulator Development Team (http://www.eq2emulator.net)
+/*
+	EQ2Emulator:  Everquest II Server Emulator
+	Copyright (C) 2007  EQ2EMulator Development Team (http://www.eq2emulator.net)
 
-    This file is part of EQ2Emulator.
+	This file is part of EQ2Emulator.
 
-    EQ2Emulator is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
+	EQ2Emulator is free software: you can redistribute it and/or modify
+	it under the terms of the GNU General Public License as published by
+	the Free Software Foundation, either version 3 of the License, or
+	(at your option) any later version.
 
-    EQ2Emulator is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
+	EQ2Emulator is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
 
-    You should have received a copy of the GNU General Public License
-    along with EQ2Emulator.  If not, see <http://www.gnu.org/licenses/>.
+	You should have received a copy of the GNU General Public License
+	along with EQ2Emulator.  If not, see <http://www.gnu.org/licenses/>.
 */
 #ifndef __EQ2_PACKETSTRUCT__
 #define __EQ2_PACKETSTRUCT__
@@ -29,7 +29,7 @@
 class Item;
 class Player;
 #endif
-extern map<int16,OpcodeManager*>EQOpcodeManager;
+extern map<int16, OpcodeManager*>EQOpcodeManager;
 using namespace std;
 
 #define DATA_STRUCT_NONE				0
@@ -52,7 +52,7 @@ using namespace std;
 #define DATA_STRUCT_ITEM				17
 #define DATA_STRUCT_SINT64				18
 
-class DataStruct{
+class DataStruct {
 public:
 	DataStruct();
 	DataStruct(DataStruct* data_struct);
@@ -78,40 +78,53 @@ public:
 	void	SetIfNotSetVariable(const char* variable);
 	void	SetIfEqualsVariable(const char* variable);
 	void	SetIfNotEqualsVariable(const char* variable);
+	void	SetIfFlagSetVariable(const char* variable);
+	void	SetIfFlagNotSetVariable(const char* variable);
 	void	SetIsSet(bool val);
-	
+	void	SetIsOptional(bool val);
+
 	int8	GetPackedIndex();
-	const char*	GetPackedSizeVariable();
-	const char*	GetArraySizeVariable();
+	const char* GetPackedSizeVariable();
+	const char* GetArraySizeVariable();
 	int8	GetDefaultValue();
 	int8	GetOversized();
 	int8	GetOversizedByte();
 	int8	GetMaxArraySize();
 	int8	GetType();
 	int8	GetType2();
-	const char*	GetName();
+	const char* GetName();
 	string	GetStringName();
 	int32	GetLength();
 	bool	AddToStruct();
 	int8	GetAddType();
 	int32	GetItemSize();
 	bool	GetIfSet();
-	const char*	GetIfSetVariable();
+	const char* GetIfSetVariable();
 	bool	GetIfNotSet();
-	const char*	GetIfNotSetVariable();
+	const char* GetIfNotSetVariable();
 	bool	GetIfEquals();
-	const char*	GetIfEqualsVariable();
+	const char* GetIfEqualsVariable();
 	bool	GetIfNotEquals();
-	const char*	GetIfNotEqualsVariable();
+	const char* GetIfNotEqualsVariable();
+	bool	GetIfFlagSet();
+	const char* GetIfFlagSetVariable();
+	bool	GetIfFlagNotSet();
+	const char* GetIfFlagNotSetVariable();
 	bool	IsSet();
+	bool	IsOptional();
 	int32 GetDataSizeInBytes();
 
 private:
 	bool	is_set;
 	bool	if_not_set;
+	bool	optional;
 	bool	if_set;
 	bool	if_not_equals;
 	bool	if_equals;
+	bool	if_flag_set;
+	bool	if_flag_not_set;
+	string	if_flag_not_set_variable;
+	string	if_flag_set_variable;
 	string	if_not_equals_variable;
 	string	if_equals_variable;
 	string	if_not_set_variable;
@@ -129,7 +142,7 @@ private:
 	int32	length;
 	int32	item_size;
 };
-class PacketStruct : public DataBuffer{
+class PacketStruct : public DataBuffer {
 public:
 	PacketStruct();
 	PacketStruct(PacketStruct* packet, bool sub);
@@ -148,73 +161,73 @@ public:
 	void setMediumString(DataStruct* data_struct, const char* text, int32 index = 0);
 	void setLargeString(DataStruct* data_struct, const char* text, int32 index = 0);
 	void renameSubstructArray(const char* substruct, int32 index);
-	template<class Data> void setSubstructSubstructDataByName(const char* substruct_name1, const char* substruct_name2, const char* name, Data data, int32 substruct_index1 = 0, int32 substruct_index2 = 0, int32 index = 0){
-		char tmp[15] = {0};
-		sprintf(tmp,"_%i_%i",substruct_index1, substruct_index2);
+	template<class Data> void setSubstructSubstructDataByName(const char* substruct_name1, const char* substruct_name2, const char* name, Data data, int32 substruct_index1 = 0, int32 substruct_index2 = 0, int32 index = 0) {
+		char tmp[15] = { 0 };
+		sprintf(tmp, "_%i_%i", substruct_index1, substruct_index2);
 		string name2 = string(substruct_name1).append("_").append(substruct_name2).append("_").append(name).append(tmp);
 		setData(findStruct(name2.c_str(), index), data, index);
 	}
-	template<class Data> void setSubstructDataByName(const char* substruct_name, const char* name, Data data, int32 substruct_index = 0, int32 index = 0){
-		char tmp[10] = {0};
-		sprintf(tmp,"_%i",substruct_index);
+	template<class Data> void setSubstructDataByName(const char* substruct_name, const char* name, Data data, int32 substruct_index = 0, int32 index = 0) {
+		char tmp[10] = { 0 };
+		sprintf(tmp, "_%i", substruct_index);
 		string name2 = string(substruct_name).append("_").append(name).append(tmp);
 		setData(findStruct(name2.c_str(), index), data, index);
 	}
-	template<class Data> void setSubstructColorByName(const char* substruct_name, const char* name, Data data, int32 substruct_index = 0, int32 index = 0){
-		char tmp[10] = {0};
-		sprintf(tmp,"_%i",substruct_index);
+	template<class Data> void setSubstructColorByName(const char* substruct_name, const char* name, Data data, int32 substruct_index = 0, int32 index = 0) {
+		char tmp[10] = { 0 };
+		sprintf(tmp, "_%i", substruct_index);
 		string name2 = string(substruct_name).append("_").append(name).append(tmp);
 		setColor(findStruct(name2.c_str(), index), data, index);
 	}
-	template<class Data> void setSubstructArrayDataByName(const char* substruct_name, const char* name, Data data, int32 index = 0, int32 substruct_index = 0){
-		char tmp[10] = {0};
-		sprintf(tmp,"_%i",substruct_index);
+	template<class Data> void setSubstructArrayDataByName(const char* substruct_name, const char* name, Data data, int32 index = 0, int32 substruct_index = 0) {
+		char tmp[10] = { 0 };
+		sprintf(tmp, "_%i", substruct_index);
 		string name2 = string(substruct_name).append("_").append(name).append(tmp);
 		setData(findStruct(name2.c_str(), substruct_index, index), data, index);
 	}
-	template<class Data> void setSubstructArrayColorByName(const char* substruct_name, const char* name, Data data, int32 substruct_index = 0, int32 index = 0){
-		char tmp[10] = {0};
-		sprintf(tmp,"_%i",substruct_index);
+	template<class Data> void setSubstructArrayColorByName(const char* substruct_name, const char* name, Data data, int32 substruct_index = 0, int32 index = 0) {
+		char tmp[10] = { 0 };
+		sprintf(tmp, "_%i", substruct_index);
 		string name2 = string(substruct_name).append("_").append(name).append(tmp);
 		setColor(findStruct(name2.c_str(), index, substruct_index), data, index);
 	}
-	template<class Data> void setDataByName(const char* name, Data data, int32 index = 0, bool use_second_type = false){
+	template<class Data> void setDataByName(const char* name, Data data, int32 index = 0, bool use_second_type = false) {
 		setData(findStruct(name, index), data, index, use_second_type);
 	}
-	template<class Data> void setDataByName(const char* name, Data* data, int32 index = 0, bool use_second_type = false){
+	template<class Data> void setDataByName(const char* name, Data* data, int32 index = 0, bool use_second_type = false) {
 		setData(findStruct(name, index), data, index, use_second_type);
 	}
-	template<class Data> void setSubArrayDataByName(const char* name, Data data, int32 index1 = 0, int32 index2 = 0, int32 index3 = 0){
-		char tmp[20] = {0};
-		sprintf(tmp,"%i_%i", index1, index2);
+	template<class Data> void setSubArrayDataByName(const char* name, Data data, int32 index1 = 0, int32 index2 = 0, int32 index3 = 0) {
+		char tmp[20] = { 0 };
+		sprintf(tmp, "%i_%i", index1, index2);
 		string name2 = string(name).append(tmp);
 		setData(findStruct(name2.c_str(), index2, index3), data, index3);
 	}
-	template<class Data> void setArrayDataByName(const char* name, Data data, int32 index1 = 0, int32 index2 = 0, bool use_second_type = false){
-		char tmp[10] = {0};
-		sprintf(tmp,"_%i",index1);
+	template<class Data> void setArrayDataByName(const char* name, Data data, int32 index1 = 0, int32 index2 = 0, bool use_second_type = false) {
+		char tmp[10] = { 0 };
+		sprintf(tmp, "_%i", index1);
 		string name2 = string(name).append(tmp);
 		setData(findStruct(name2.c_str(), index1, index2), data, index2, use_second_type);
 	}
-	void setArrayAddToPacketByName(const char* name, bool new_val, int32 index1 = 0, int32 index2 = 0){
-		char tmp[10] = {0};
-		sprintf(tmp,"_%i",index1);
+	void setArrayAddToPacketByName(const char* name, bool new_val, int32 index1 = 0, int32 index2 = 0) {
+		char tmp[10] = { 0 };
+		sprintf(tmp, "_%i", index1);
 		string name2 = string(name).append(tmp);
 		DataStruct* data = findStruct(name2.c_str(), index2);
-		if(data)
+		if (data)
 			data->SetAddToStruct(new_val);
 	}
-	void setAddToPacketByName(const char* name, bool new_val, int32 index = 0){
+	void setAddToPacketByName(const char* name, bool new_val, int32 index = 0) {
 		DataStruct* data = findStruct(name, index);
-		if(data)
+		if (data)
 			data->SetAddToStruct(new_val);
 	}
-	void setAddTypePacketByName(const char* name, int8 new_val, int32 index = 0){
+	void setAddTypePacketByName(const char* name, int8 new_val, int32 index = 0) {
 		DataStruct* data = findStruct(name, index);
-		if(data)
+		if (data)
 			data->SetAddType(new_val);
 	}
-	const char*	GetOpcodeType();
+	const char* GetOpcodeType();
 	bool	IsSubPacket();
 	void	IsSubPacket(bool new_val);
 	int32	GetSubPacketSize();
@@ -276,29 +289,30 @@ public:
 	void setData(DataStruct* data_struct, EQ2_16BitString* input_string, int32 index, bool use_second_type = false);
 	void setData(DataStruct* data_struct, EQ2_32BitString* input_string, int32 index, bool use_second_type = false);
 
-	template<class Data> void setData(DataStruct* data_struct, Data* data, int32 index, bool use_second_type = false){
+	template<class Data> void setData(DataStruct* data_struct, Data* data, int32 index, bool use_second_type = false) {
 		if (!data_struct)
 			return;
+		data_struct->SetIsOptional(false);
 		int8 type_to_use = (use_second_type) ? data_struct->GetType2() : data_struct->GetType();
-		if(type_to_use >= DATA_STRUCT_EQ2_8BIT_STRING && type_to_use <= DATA_STRUCT_EQ2_32BIT_STRING){
-			if(type_to_use == DATA_STRUCT_EQ2_8BIT_STRING){
-					setSmallString(data_struct, data, index);
+		if (type_to_use >= DATA_STRUCT_EQ2_8BIT_STRING && type_to_use <= DATA_STRUCT_EQ2_32BIT_STRING) {
+			if (type_to_use == DATA_STRUCT_EQ2_8BIT_STRING) {
+				setSmallString(data_struct, data, index);
 			}
-			else if(type_to_use == DATA_STRUCT_EQ2_16BIT_STRING){
-					setMediumString(data_struct, data, index);
+			else if (type_to_use == DATA_STRUCT_EQ2_16BIT_STRING) {
+				setMediumString(data_struct, data, index);
 			}
-			else{
-					setLargeString(data_struct, data, index);
+			else {
+				setLargeString(data_struct, data, index);
 			}
 		}
 		else {
-			if(data_struct && index == 0 && data_struct->GetLength() > 1){
-				if(type_to_use == DATA_STRUCT_CHAR){
-					for(int32 i=0;data && i<data_struct->GetLength() && i < strlen(data);i++)
+			if (data_struct && index == 0 && data_struct->GetLength() > 1) {
+				if (type_to_use == DATA_STRUCT_CHAR) {
+					for (int32 i = 0; data && i < data_struct->GetLength() && i < strlen(data); i++)
 						setData(data_struct, data[i], i);
 				}
-				else{
-					for(int32 i=0;i<data_struct->GetLength();i++)
+				else {
+					for (int32 i = 0; i < data_struct->GetLength(); i++)
 						setData(data_struct, data[i], i);
 				}
 			}
@@ -306,8 +320,9 @@ public:
 				setData(data_struct, *data, index);
 		}
 	}
-	template<class Data> void setData(DataStruct* data_struct, Data data, int32 index, bool use_second_type = false){
-		if(data_struct && index < data_struct->GetLength()){
+	template<class Data> void setData(DataStruct* data_struct, Data data, int32 index, bool use_second_type = false) {
+		if (data_struct && index < data_struct->GetLength()) {
+			data_struct->SetIsOptional(false);
 			int8 type_to_use = (use_second_type) ? data_struct->GetType2() : data_struct->GetType();
 			if (use_second_type) {
 				// Need to figure out why type2 always seems to be 205
@@ -315,123 +330,124 @@ public:
 				//type_to_use = DATA_STRUCT_SINT16; // 9;
 				data_struct->SetType(type_to_use);
 			}
-			switch(type_to_use){
-				case DATA_STRUCT_INT8:
-					setDataType(data_struct, (int8)data, index);
-					break;
-				case DATA_STRUCT_INT16:
-					setDataType(data_struct, (int16)data, index);
-					break;
-				case DATA_STRUCT_INT32:
-					setDataType(data_struct, (int32)data, index);
-					break;
-				case DATA_STRUCT_INT64:
-					setDataType(data_struct, (int64)data, index);
-					break;
-				case DATA_STRUCT_SINT8:
-					setDataType(data_struct, (sint8)data, index);
-					break;
-				case DATA_STRUCT_SINT16:
-					setDataType(data_struct, (sint16)data, index);
-					break;
-				case DATA_STRUCT_SINT32:
-					setDataType(data_struct, (sint32)data, index);
-					break;
-				case DATA_STRUCT_SINT64:
-					setDataType(data_struct, (sint64)data, index);
-					break;
-				case DATA_STRUCT_CHAR:
-					setDataType(data_struct, (char)data, index);
-					break;
-				case DATA_STRUCT_FLOAT:
-					setDataType(data_struct, (float)data, index);
-					break;
-				case DATA_STRUCT_DOUBLE:
-					setDataType(data_struct, (double)data, index);
-					break;
-				case DATA_STRUCT_COLOR:
-					setColor(data_struct, *((EQ2_Color*)&data), index);
-					break;
-				case DATA_STRUCT_EQUIPMENT:
-					setEquipmentByName(data_struct, *((EQ2_EquipmentItem*)&data), index);
-					break;
-				case DATA_STRUCT_ITEM:
-					break;
+			switch (type_to_use) {
+			case DATA_STRUCT_INT8:
+				setDataType(data_struct, (int8)data, index);
+				break;
+			case DATA_STRUCT_INT16:
+				setDataType(data_struct, (int16)data, index);
+				break;
+			case DATA_STRUCT_INT32:
+				setDataType(data_struct, (int32)data, index);
+				break;
+			case DATA_STRUCT_INT64:
+				setDataType(data_struct, (int64)data, index);
+				break;
+			case DATA_STRUCT_SINT8:
+				setDataType(data_struct, (sint8)data, index);
+				break;
+			case DATA_STRUCT_SINT16:
+				setDataType(data_struct, (sint16)data, index);
+				break;
+			case DATA_STRUCT_SINT32:
+				setDataType(data_struct, (sint32)data, index);
+				break;
+			case DATA_STRUCT_SINT64:
+				setDataType(data_struct, (sint64)data, index);
+				break;
+			case DATA_STRUCT_CHAR:
+				setDataType(data_struct, (char)data, index);
+				break;
+			case DATA_STRUCT_FLOAT:
+				setDataType(data_struct, (float)data, index);
+				break;
+			case DATA_STRUCT_DOUBLE:
+				setDataType(data_struct, (double)data, index);
+				break;
+			case DATA_STRUCT_COLOR:
+				setColor(data_struct, *((EQ2_Color*)&data), index);
+				break;
+			case DATA_STRUCT_EQUIPMENT:
+				setEquipmentByName(data_struct, *((EQ2_EquipmentItem*)&data), index);
+				break;
+			case DATA_STRUCT_ITEM:
+				break;
 			}
 		}
 	}
 
-	template<class Data> void setSubArrayLengthByName(const char* name, Data data, int32 index1 = 0, int32 index2 = 0){
-		char tmp[10] = {0};
-		sprintf(tmp,"_%i",index1);
+	template<class Data> void setSubArrayLengthByName(const char* name, Data data, int32 index1 = 0, int32 index2 = 0) {
+		char tmp[10] = { 0 };
+		sprintf(tmp, "_%i", index1);
 		string name2 = string(name).append(tmp);
 		DataStruct* data_struct = findStruct(name2.c_str(), index2);
 		setData(data_struct, data, index2);
-		UpdateArrayByArrayLength(data_struct, index2, data);	
+		UpdateArrayByArrayLength(data_struct, index2, data);
 	}
-	template<class Data> void setArrayLengthByName(const char* name, Data data, int32 index = 0){
+	template<class Data> void setArrayLengthByName(const char* name, Data data, int32 index = 0) {
 		DataStruct* data_struct = findStruct(name, index);
 		setData(data_struct, data, index);
-		UpdateArrayByArrayLength(data_struct, index, data);	
+		UpdateArrayByArrayLength(data_struct, index, data);
 	}
-	template<class Data> void setSubstructArrayLengthByName(const char* substruct_name, const char* name, Data data, int32 substruct_index = 0, int32 index = 0){
-		char tmp[10] = {0};
-		sprintf(tmp,"_%i",substruct_index);
+	template<class Data> void setSubstructArrayLengthByName(const char* substruct_name, const char* name, Data data, int32 substruct_index = 0, int32 index = 0) {
+		char tmp[10] = { 0 };
+		sprintf(tmp, "_%i", substruct_index);
 		string name2 = string(substruct_name).append("_").append(name).append(tmp);
 
 		DataStruct* data_struct = findStruct(name2.c_str(), index);
 		setData(data_struct, data, index);
-		UpdateArrayByArrayLength(data_struct, index, data);	
+		UpdateArrayByArrayLength(data_struct, index, data);
 	}
 	void UpdateArrayByArrayLengthName(const char* name, int32 index, int32 size);
 	void UpdateArrayByArrayLength(DataStruct* data_struct, int32 index, int32 size);
 	bool StructLoadData(DataStruct* data_struct, void* data, int32 len, bool useType2 = false);
 	bool LoadPacketData(uchar* data, int32 data_len);
-	
-	void setColorByName(const char* name, EQ2_Color* data, int32 index = 0){
-		if(data)
+	bool CheckFlagExists(const char* name);
+
+	void setColorByName(const char* name, EQ2_Color* data, int32 index = 0) {
+		if (data)
 			setColorByName(name, data->red, data->green, data->blue, index);
 	}
-	void setColorByName(const char* name, EQ2_Color data, int32 index = 0){
+	void setColorByName(const char* name, EQ2_Color data, int32 index = 0) {
 		setColorByName(name, data.red, data.green, data.blue, index);
 	}
-	void setColor(DataStruct* data_struct, EQ2_Color data, int32 index = 0){
-		if(data_struct){
+	void setColor(DataStruct* data_struct, EQ2_Color data, int32 index = 0) {
+		if (data_struct) {
 			EQ2_Color* ptr = (EQ2_Color*)struct_data[data_struct];
 			ptr[index] = data;
 		}
 	}
-	void setColorByName(const char* name, int8 red, int8 green, int8 blue, int32 index = 0){
+	void setColorByName(const char* name, int8 red, int8 green, int8 blue, int32 index = 0) {
 		setColor(findStruct(name, index), red, green, blue, index);
 	}
 	void setColor(DataStruct* data, int8 red, int8 green, int8 blue, int32 index);
-	void setEquipmentByName(DataStruct* data_struct, EQ2_EquipmentItem data, int32 index = 0){
-		if(data_struct){
+	void setEquipmentByName(DataStruct* data_struct, EQ2_EquipmentItem data, int32 index = 0) {
+		if (data_struct) {
 			EQ2_EquipmentItem* ptr = (EQ2_EquipmentItem*)struct_data[data_struct];
 			ptr[index] = data;
 		}
 	}
 #ifdef WORLD	
-	void setItem(DataStruct* ds, Item* item, Player* player, int32 index, sint8 offset = 0);
-	void setItemByName(const char* name, Item* item, Player* player, int32 index = 0, sint8 offset = 0);
-	void setItemArrayDataByName(const char* name, Item* item, Player* player, int32 index1 = 0, int32 index2 = 0, sint8 offset = 0);
+	void setItem(DataStruct* ds, Item* item, Player* player, int32 index, sint8 offset = 0, bool loot_item = false);
+	void setItemByName(const char* name, Item* item, Player* player, int32 index = 0, sint8 offset = 0, bool loot_item = false);
+	void setItemArrayDataByName(const char* name, Item* item, Player* player, int32 index1 = 0, int32 index2 = 0, sint8 offset = 0, bool loot_item = false);
 #endif
-	void setEquipmentByName(const char* name, EQ2_EquipmentItem data, int32 index = 0){
+	void setEquipmentByName(const char* name, EQ2_EquipmentItem data, int32 index = 0) {
 		setEquipmentByName(findStruct(name, index), data, index);
 	}
-	void setEquipmentByName(const char* name, EQ2_EquipmentItem* data, int32 size){
+	void setEquipmentByName(const char* name, EQ2_EquipmentItem* data, int32 size) {
 		DataStruct* data_struct = findStruct(name, 0);
-		if(data_struct){
-			for(int32 i=0;i<size;i++)
+		if (data_struct) {
+			for (int32 i = 0; i < size; i++)
 				setEquipmentByName(data_struct, data[i], i);
 		}
 	}
-	void setEquipmentByName(const char* name, int32 type, int8 c_red, int8 c_blue, int8 c_green, int8 h_red, int8 h_blue, int8 h_green, int32 index = 0){
-		setEquipment(findStruct(name,index), type, c_red, c_blue, c_green, h_red, h_blue, h_green, index);
+	void setEquipmentByName(const char* name, int32 type, int8 c_red, int8 c_blue, int8 c_green, int8 h_red, int8 h_blue, int8 h_green, int32 index = 0) {
+		setEquipment(findStruct(name, index), type, c_red, c_blue, c_green, h_red, h_blue, h_green, index);
 	}
 	void setEquipment(DataStruct* data, int16 type, int8 c_red, int8 c_blue, int8 c_green, int8 h_red, int8 h_blue, int8 h_green, int32 index);
 	void remove(DataStruct* data);
-	vector<DataStruct*>* getStructs(){ return &structs; }
+	vector<DataStruct*>* getStructs() { return &structs; }
 	DataStruct* findStruct(const char* name, int32 index);
 	DataStruct* findStruct(const char* name, int32 index1, int32 index2);
 	void remove(const char* name);
@@ -442,12 +458,12 @@ public:
 	EQ2Packet* serialize();
 	EQ2Packet* serializeCountPacket(int16 version, int8 offset = 0, uchar* orig_packet = 0, uchar* xor_packet = 0);
 	string* serializeString();
-	int32 GetVersion(){ return version; }
-	void SetVersion(int32 in_version){ version = in_version; }
+	int32 GetVersion() { return version; }
+	void SetVersion(int32 in_version) { version = in_version; }
 	bool SetOpcode(const char* new_opcode);
-	EmuOpcode GetOpcode(){ return opcode; }
-	const char* GetName(){ return name.c_str(); }
-	void SetName(const char* in_name){ name = string(in_name); }
+	EmuOpcode GetOpcode() { return opcode; }
+	const char* GetName() { return name.c_str(); }
+	void SetName(const char* in_name) { name = string(in_name); }
 	bool LoadedSuccessfully() { return loadedSuccessfully; }
 	bool IsStringValueType(string in_name, int32 index);
 	bool IsColorValueType(string in_name, int32 index);
@@ -459,6 +475,7 @@ public:
 	vector<DataStruct*> GetDataStructs();
 	void AddPackedData();
 	void ResetData();
+	void AddFlag(const char* name);
 
 private:
 	PacketStruct* parent;
@@ -471,6 +488,7 @@ private:
 	int16 version;
 	int16 client_version;
 	vector<PacketStruct*> arrays;
+	vector<string> flags;
 	map<DataStruct*, void*> struct_data;
 	map<int8, string> packed_data;
 	map<string, DataStruct*> struct_map;
@@ -478,5 +496,4 @@ private:
 	vector<DataStruct*> orig_structs;
 	vector<PacketStruct*> orig_packets;
 };
-#endif
-
+#endif

+ 2 - 1
EQ2/source/common/emu_oplist.h

@@ -32,6 +32,7 @@ N(OP_CreateCharacterRequestMsg),
 N(OP_DoneLoadingZoneResourcesMsg),
 N(OP_DoneSendingInitialEntitiesMsg),
 N(OP_DoneLoadingEntityResourcesMsg),
+N(OP_DoneLoadingUIResourcesMsg),
 N(OP_PredictionUpdateMsg),
 N(OP_RemoteCmdMsg),
 N(OP_SetRemoteCmdsMsg),
@@ -197,7 +198,7 @@ N(OP_PerformPlayerKnockbackMsg),
 N(OP_PerformCameraShakeMsg),
 N(OP_PopulateSkillMapsMsg),
 N(OP_CancelledFeignMsg),
-//N(OP_SignalMsg),
+N(OP_SignalMsg),
 N(OP_SkillInfoRequest),
 N(OP_SkillInfoResponse),
 N(OP_ShowCreateFromRecipeUIMsg),

+ 84 - 48
server/CommonStructs.xml

@@ -3,6 +3,90 @@
 This allows multiple struct version to coexist on the same server.  Elements that arent used in the source code are set
 to zero and treated like placeholders." /> 
 <Struct Name="CreateCharacter" ClientVersion="1" OpcodeName="OP_CreateCharacterRequestMsg">
+<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="unknown1" Type="int8" Size="2" />
+<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="546" 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="int16" />
+<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="547" OpcodeName="OP_CreateCharacterRequestMsg">
 <Data ElementName="unknown0" Type="int8" />
 <Data ElementName="unknown1" Type="int32" />
 <Data ElementName="account_id" Type="int32"  />
@@ -82,54 +166,6 @@ to zero and treated like placeholders." />
 <Data ElementName="soga_body_size" Type="float" Size="1" />
 <Data ElementName="soga_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" />
-<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="unknown0x" Type="int8" />
-<Data ElementName="race_file" Type="EQ2_16Bit_String" />
-<Data ElementName="skin_color" Type="EQ2_Color" Size="1" />
-<Data ElementName="skin_color2" Type="EQ2_Color" Size="1" />
-<Data ElementName="eye_color" Type="EQ2_Color" Size="1" />
-<Data ElementName="hair_color1" Type="EQ2_Color" Size="1" />
-<Data ElementName="hair_color2" Type="EQ2_Color" Size="1" />
-<Data ElementName="hair_highlight" Type="EQ2_Color" Size="1" />
-<Data ElementName="unknown8" Type="int8" Size="68" />
-<Data ElementName="hair_file" Type="EQ2_16Bit_String" />
-<Data ElementName="hair_type_color" Type="EQ2_Color" Size="1" />
-<Data ElementName="hair_type_highlight_color" Type="EQ2_Color" Size="1" />
-<Data ElementName="hair_face_color" Type="EQ2_Color" Size="1" />
-<Data ElementName="hair_face_highlight_color" Type="EQ2_Color" Size="1" />
-<Data ElementName="unknown1x" Type="int8" Size="38" />
-<Data ElementName="chest_file" Type="EQ2_16Bit_String" />
-<Data ElementName="shirt_color" Type="EQ2_Color" Size="1" />
-<Data ElementName="unknown_chest_color" Type="EQ2_Color" Size="1" />
-<Data ElementName="unknown2x" Type="int8" Size="9" />
-<Data ElementName="legs_file" Type="EQ2_16Bit_String" />
-<Data ElementName="pants_color" Type="EQ2_Color" Size="1" />
-<Data ElementName="unknown_legs_color" Type="EQ2_Color" Size="1" />
-<Data ElementName="unknown9" Type="EQ2_Color" Size="1" />
-<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" />
-<Data ElementName="soga_version" Type="int8" />
-<Data ElementName="unknown3x" Type="EQ2_Color" Size="27" />
-</Struct>
 <Struct Name="CreateCharacter" ClientVersion="869" OpcodeName="OP_CreateCharacterRequestMsg">
 <Data ElementName="unknown0" Type="int8" />
 <Data ElementName="unknown1" Type="int32" />

+ 302 - 6
server/ItemStructs.xml

@@ -1,5 +1,73 @@
 <EQ2Emulator>
 <Struct Name="Substruct_BaseItemDescription" ClientVersion="1" >
+	<Data ElementName="unknownblah" Type="int8" Size="3" />
+    <Data ElementName="unique_id" Type="int32" Size="1" />
+    <Data ElementName="icon" Type="int16" Size="1" />
+    <Data ElementName="flag_names" Type="EQ2_8Bit_String" Size="1" />
+    <Data ElementName="unknown8_1" Type="int8" Size="17" />
+    <Data ElementName="stat_count" Type="int8" />
+    <Data ElementName="stat_array" Type="Array" ArraySizeVariable="stat_count">
+      <Data ElementName="stat_type" Type="int16" OversizedValue="127" OversizedByte="127" Size="1" />
+      <Data ElementName="stat_subtype" Type="sint16" OversizedValue="127" OversizedByte="127" Size="1" />
+      <Data ElementName="value" Type="sint16" OversizedValue="127" OversizedByte="127" Size="1" />
+      <Data ElementName="stat_name" Type="EQ2_8Bit_String" Size="1" />
+    </Data>
+    <Data ElementName="stat_string_count" Type="int8" />
+    <Data ElementName="stat_string_array" Type="Array" ArraySizeVariable="stat_string_count">
+      <Data ElementName="stat_string" Type="EQ2_8Bit_String" Size="1" />
+      <Data ElementName="adornment_flag" Type="int8" Size="1" />
+      <Data ElementName="adornment_array" Type="Array" ArraySizeVariable="adornment_flag">
+        <Data ElementName="adornment_unknown" Type="int8" Size="1" />
+      </Data>
+      <Data ElementName="stat_description" Type="EQ2_16Bit_String" Size="1" />
+    </Data>
+    <Data ElementName="condition" Type="int8" Size="1" />   
+	<Data ElementName="weight" Type="int16" OversizedValue="127" OversizedByte="127" Size="1" />
+	<Data ElementName="skill_req1" Type="int32" Size="1" />
+    <Data ElementName="skill_min" Type="int16" OversizedValue="127" OversizedByte="127" Size="1" />
+	<Data ElementName="skill_recommended" Type="int16" OversizedValue="127" OversizedByte="127" Size="1" />	
+    <Data ElementName="slot_count" Type="int8" />
+    <Data ElementName="slot_array" Type="Array" ArraySizeVariable="slot_count">
+      <Data ElementName="slot" Type="int8" Size="1" />
+    </Data>
+  </Struct>
+<Struct Name="Substruct_BaseItemDescription" ClientVersion="546" >
+    <Data ElementName="unknown" Type="int8" Size="1" />
+    <Data ElementName="unique_id" Type="int32" Size="1" />
+    <Data ElementName="broker_item_id" Type="int64" Size="1" />   
+    <Data ElementName="icon" Type="int16" Size="1" />
+    <Data ElementName="tier" Type="int8" Size="1" />
+    <Data ElementName="flags" Type="int32" Size="1" />
+    <Data ElementName="unknown8_1" Type="int8" Size="15" />
+    <Data ElementName="stat_count" Type="int8" />
+    <Data ElementName="stat_array" Type="Array" ArraySizeVariable="stat_count">
+      <Data ElementName="stat_type" Type="int16" OversizedValue="127" OversizedByte="127" Size="1" />
+      <Data ElementName="stat_subtype" Type="sint16" OversizedValue="127" OversizedByte="127" Size="1" />
+      <Data ElementName="value" Type="sint16" OversizedValue="127" OversizedByte="127" Size="1" />
+      <Data ElementName="stat_name" Type="EQ2_8Bit_String" Size="1" />
+    </Data>
+    <Data ElementName="stat_string_count" Type="int8" />
+    <Data ElementName="stat_string_array" Type="Array" ArraySizeVariable="stat_string_count">
+      <Data ElementName="stat_string" Type="EQ2_8Bit_String" Size="1" />
+    </Data>
+    <Data ElementName="condition" Type="int8" Size="1" />
+    <Data ElementName="weight" Type="int16" OversizedValue="127" OversizedByte="127" Size="1" />
+    <Data ElementName="skill_req1" Type="int32" Size="1" />
+    <Data ElementName="skill_req2" Type="int32" Size="1" />
+    <Data ElementName="skill_min" Type="int16" OversizedValue="127" OversizedByte="127" Size="1" />
+    <Data ElementName="class_count" Type="int8" />
+    <Data ElementName="class_array" Type="Array" ArraySizeVariable="class_count">
+      <Data ElementName="adventure_class" Type="int8" Size="1" />
+      <Data ElementName="tradeskill_class" Type="int8" Size="1" />
+      <Data ElementName="level" Type="int16" Size="1" />
+    </Data>
+    <Data ElementName="slot_count" Type="int8" />
+    <Data ElementName="slot_array" Type="Array" ArraySizeVariable="slot_count">
+      <Data ElementName="slot" Type="int8" Size="1" />
+    </Data>
+    <Data ElementName="footer_type" Type="int32" Size="1" />
+  </Struct>
+  <Struct Name="Substruct_BaseItemDescription" ClientVersion="547" >
     <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" />
@@ -957,6 +1025,21 @@
 <Data ElementName="bag_id" Type="int32" Size="1" />
 <Data ElementName="inv_slot_id" Type="int32" Size="1" />
 <Data ElementName="menu_type" Type="int32" Size="1" />
+<Data ElementName="slot_id" Type="int8" Size="1" />
+<Data ElementName="index" Type="int16" Size="1" />
+<Data ElementName="icon" Type="int16" Size="1" />
+<Data ElementName="count" Type="int8" Size="1" />
+<Data ElementName="level" Type="int8" Size="1" />
+<Data ElementName="tier" Type="int8" Size="1" />
+<Data ElementName="num_slots" Type="int8" Size="1" />
+<Data ElementName="item_id" Type="sint32" Size="1" />
+<Data ElementName="name" Type="char" Size="81" />
+</Struct>
+<Struct Name="Substruct_Item" ClientVersion="547" >
+<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" />
+<Data ElementName="menu_type" Type="int32" Size="1" />
 <Data ElementName="index" Type="int16" Size="1" />
 <Data ElementName="icon" Type="int16" Size="1" />
 <Data ElementName="slot_id" Type="int8" Size="1" />
@@ -1208,6 +1291,20 @@
 <Data ElementName="unknown6" Type="int8" Size="16" />
 </Struct>
 <Struct Name="Substruct_ItemFooter" ClientVersion="1" >
+<Data ElementName="name" Type="EQ2_8Bit_String" Size="1" />
+<Data ElementName="description" Type="EQ2_16Bit_String" Size="1" />
+</Struct>
+<Struct Name="Substruct_ItemFooter" ClientVersion="546" >
+<Data ElementName="num_effects" Type="int8" Size="1"  IfFlagNotSet="loot" /> 
+<Data ElementName="effect_array" Type="Array" ArraySizeVariable="num_effects" IfFlagNotSet="loot">
+	<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="name" Type="EQ2_8Bit_String" Size="1" />
+<Data ElementName="description" Type="EQ2_16Bit_String" Size="1" />
+</Struct>
+<Struct Name="Substruct_ItemFooter" ClientVersion="547" >
 <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" />
@@ -3686,6 +3783,16 @@
 <Data ElementName="info" Substruct="Substruct_BaseItemDescription" Size="1" />
 <Data ElementName="item_type" Type="int8" Size="1" />
 </Struct>
+<Struct Name="Substruct_ItemDescription" ClientVersion="546" >
+<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" />
+</Struct>
+<Struct Name="Substruct_ItemDescription" ClientVersion="547" >
+<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" />
+</Struct>
 <Struct Name="Substruct_ItemDescription" ClientVersion="860" >
 <Data ElementName="info_header" Substruct="WS_ExamineInfoHeader" Size="1" />
 <Data ElementName="info" Substruct="Substruct_BaseItemDescription" Size="1" />
@@ -3813,6 +3920,10 @@
 <Data ElementName="info_header" Substruct="WS_ExamineInfoHeader" Size="1" />
 <Data ElementName="info" Substruct="Substruct_BaseItemDescription" Size="1" />
 </Struct>
+<Struct Name="Substruct_LootItemDescription" ClientVersion="546" >
+<Data ElementName="info_header" Substruct="WS_ExamineInfoHeader" Size="1" />
+<Data ElementName="info" Substruct="Substruct_BaseItemDescription" Size="1" />
+</Struct>
 <Struct Name="Substruct_LootItemDescription" ClientVersion="860" >
 <Data ElementName="info_header" Substruct="WS_ExamineInfoHeader" Size="1" />
 <Data ElementName="info" Substruct="Substruct_BaseItemDescription" Size="1" />
@@ -3953,6 +4064,14 @@
 </Data>
 <Data ElementName="equip_flag" Type="int8" Size="1" />
 </Struct>
+<Struct Name="WS_UpdateInventory" ClientVersion="547" OpcodeName="OP_UpdateInventoryMsg" >
+<Data ElementName="item_count" Type="int16" />
+<Data ElementName="packed_size" Type="int32" />
+<Data ElementName="item_array" Type="Array" ArraySizeVariable="item_count">
+  <Data ElementName="items" Substruct="Substruct_Item" Size="1" />
+</Data>
+<Data ElementName="equip_flag" Type="int8" Size="1" />
+</Struct>
 <Struct Name="WS_UpdateInventory" ClientVersion="893" OpcodeName="OP_UpdateInventoryMsg" >
 <Data ElementName="item_count" Type="int16" />
 <Data ElementName="packed_size" Type="int32" />
@@ -4045,7 +4164,30 @@
 <Data ElementName="header" Substruct="Substruct_ItemDescription" Size="1" />
 <Data ElementName="footer" Substruct="Substruct_ItemFooter" Size="1" />
 </Struct>
-<Struct Name="WS_ItemRange" ClientVersion="1" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqExamineInfoCmd">
+<Struct Name="WS_ItemGeneric" ClientVersion="546" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqExamineInfoCmd">
+<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">
+<Data ElementName="header" Substruct="Substruct_ItemDescription" Size="1" />
+<Data ElementName="footer" Substruct="Substruct_ItemFooter" Size="1" />
+</Struct>
+<Struct Name="WS_ItemRange" ClientVersion="546" 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" />
+<Data ElementName="damage_low2" Type="int16" Size="1" OversizedValue="127" OversizedByte="127" />
+<Data ElementName="damage_high2" Type="int16" Size="1" OversizedValue="127" OversizedByte="127" />
+<Data ElementName="damage_low3" Type="int16" Size="1" OversizedValue="127" OversizedByte="127" />
+<Data ElementName="damage_high3" Type="int16" Size="1" OversizedValue="127" OversizedByte="127" />
+<Data ElementName="delay" Type="int16" Size="1" OversizedValue="127" OversizedByte="127" />
+<Data ElementName="range_low" Type="int16" Size="1" OversizedValue="127" OversizedByte="127" />
+<Data ElementName="range_high" Type="int16" Size="1" OversizedValue="127" OversizedByte="127" />
+<Data ElementName="damage_type" Type="int8" Size="1" />
+<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">
 <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" />
@@ -4068,7 +4210,15 @@
 <Data ElementName="damage_type" Type="int32" Size="1" />
 <Data ElementName="footer" Substruct="Substruct_ItemFooter" Size="1" />
 </Struct>
-<Struct Name="WS_ItemWeapon" ClientVersion="1" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqExamineInfoCmd">
+<Struct Name="WS_ItemThrown" ClientVersion="546" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqExamineInfoCmd">
+<Data ElementName="header" Substruct="Substruct_ItemDescription" Size="1" />
+<Data ElementName="range" Type="sint32" Size="1" />
+<Data ElementName="damage_modifier" Type="sint32" Size="1" />
+<Data ElementName="hit_bonus" Type="float" Size="1" />
+<Data ElementName="damage_type" Type="int32" Size="1" />
+<Data ElementName="footer" Substruct="Substruct_ItemFooter" Size="1" />
+</Struct>
+<Struct Name="WS_ItemWeapon" ClientVersion="546" 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" />
@@ -4082,13 +4232,39 @@
 <Data ElementName="rating" Type="float" Size="1" />
 <Data ElementName="footer" Substruct="Substruct_ItemFooter" Size="1" />
 </Struct>
-<Struct Name="WS_ItemArmor" ClientVersion="1" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqExamineInfoCmd">
+<Struct Name="WS_ItemArmor" ClientVersion="546" 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="1" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqExamineInfoCmd">
+<Struct Name="WS_ItemShield" ClientVersion="546" 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_ItemWeapon" ClientVersion="547" 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" />
+<Data ElementName="damage_high1" Type="int16" OversizedValue="127" OversizedByte="127" Size="1" />
+<Data ElementName="damage_low2" Type="int16" OversizedValue="127" OversizedByte="127" Size="1" />
+<Data ElementName="damage_high2" Type="int16" OversizedValue="127" OversizedByte="127" Size="1" />
+<Data ElementName="damage_low3" Type="int16" OversizedValue="127" OversizedByte="127" Size="1" />
+<Data ElementName="damage_high3" Type="int16" OversizedValue="127" OversizedByte="127" Size="1" />
+<Data ElementName="delay" Type="int16" OversizedValue="127" OversizedByte="127" Size="1" />
+<Data ElementName="damage_type" Type="int8" Size="1" />
+<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">
+<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">
 <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" />
@@ -4117,8 +4293,112 @@
 </Data>
 <Data ElementName="footer" Substruct="Substruct_ItemFooter" Size="1" />
 </Struct>
+<Struct Name="WS_ItemWeaponDetails"  ClientVersion="1">
+<Data ElementName="wield_type" Type="int8" Size="1" />
+<Data ElementName="damage_low1" Type="int16" OversizedValue="127" OversizedByte="127" Size="1" />
+<Data ElementName="damage_high1" Type="int16" OversizedValue="127" OversizedByte="127" Size="1" />
+<Data ElementName="damage_low2" Type="int16" OversizedValue="127" OversizedByte="127" Size="1" />
+<Data ElementName="damage_high2" Type="int16" OversizedValue="127" OversizedByte="127" Size="1" />
+<Data ElementName="delay" Type="int8" Size="1" />
+<Data ElementName="damage_type" Type="int8" Size="1" />
+</Struct>
+<Struct Name="WS_ItemRangeDetails"  ClientVersion="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" />
+<Data ElementName="damage_low2" Type="int16" Size="1" OversizedValue="127" OversizedByte="127" />
+<Data ElementName="damage_high2" Type="int16" Size="1" OversizedValue="127" OversizedByte="127" />
+<Data ElementName="delay" Type="int8" Size="1"/>
+<Data ElementName="range_low" Type="int16" Size="1" OversizedValue="127" OversizedByte="127" />
+
+<Data ElementName="damage_type" Type="int8" Size="1" />
+</Struct>
+<Struct Name="WS_ItemArmorDetails" ClientVersion="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" />
+</Struct>
+<Struct Name="WS_ItemShieldDetails" ClientVersion="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" />
+</Struct>
+<Struct Name="WS_ItemBagDetails"  ClientVersion="1">
+<Data ElementName="num_slots" Type="int8" Size="1" />
+<Data ElementName="weight_reduction" Type="int8" Size="1" />
+</Struct>
+<Struct Name="WS_ItemRecipeBookDetails" ClientVersion="1">
+<Data ElementName="num_recipes" Type="int16" Size="1" OversizedValue="127" />
+<Data ElementName="recipe_array" Type="Array" ArraySizeVariable="num_recipes">
+	<Data ElementName="recipe_name" Type="EQ2_8Bit_String" Size="1" />
+</Data>
+</Struct>
+<Struct Name="WS_ItemWeapon" ClientVersion="1" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqExamineInfoCmd">
+<Data ElementName="header" Substruct="Substruct_ItemDescription" Size="1" />
+<Data ElementName="details" Substruct="WS_ItemWeaponDetails" Size="1" />
+<Data ElementName="range_filler" Substruct="WS_ItemRangeDetails" Size="1" />
+<Data ElementName="armor_filler" Substruct="WS_ItemArmorDetails" Size="1" />
+<Data ElementName="shield_filler" Substruct="WS_ItemShieldDetails" Size="1" />
+<Data ElementName="bag_filler" Substruct="WS_ItemBagDetails" Size="1" />
+<Data ElementName="skill_filler" Substruct="WS_SpellInfo" Size="1" />
+<Data ElementName="recipe_filler" Substruct="WS_ItemRecipeBookDetails" Size="1" />
+<Data ElementName="footer" Substruct="Substruct_ItemFooter" Size="1" />
+</Struct>
+<Struct Name="WS_ItemRange" ClientVersion="1" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqExamineInfoCmd">
+<Data ElementName="header" Substruct="Substruct_ItemDescription" Size="1" />
+<Data ElementName="details" Substruct="WS_ItemRangeDetails" Size="1" />
+<Data ElementName="armor_filler" Substruct="WS_ItemArmorDetails" Size="1" />
+<Data ElementName="shield_filler" Substruct="WS_ItemShieldDetails" Size="1" />
+<Data ElementName="bag_filler" Substruct="WS_ItemBagDetails" Size="1" />
+<Data ElementName="skill_filler" Substruct="WS_SpellInfo" Size="1" />
+<Data ElementName="recipe_filler" Substruct="WS_ItemRecipeBookDetails" Size="1" />
+<Data ElementName="footer" Substruct="Substruct_ItemFooter" Size="1" />
+</Struct>
+<Struct Name="WS_ItemArmor" ClientVersion="1" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqExamineInfoCmd">
+<Data ElementName="header" Substruct="Substruct_ItemDescription" Size="1" />
+<Data ElementName="details" Substruct="WS_ItemArmorDetails" Size="1" />
+<Data ElementName="shield_filler" Substruct="WS_ItemShieldDetails" Size="1" />
+<Data ElementName="bag_filler" Substruct="WS_ItemBagDetails" Size="1" />
+<Data ElementName="skill_filler" Substruct="WS_SpellInfo" Size="1" />
+<Data ElementName="recipe_filler" Substruct="WS_ItemRecipeBookDetails" Size="1" />
+<Data ElementName="footer" Substruct="Substruct_ItemFooter" Size="1" />
+</Struct>
+<Struct Name="WS_ItemShield" ClientVersion="1" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqExamineInfoCmd">
+<Data ElementName="header" Substruct="Substruct_ItemDescription" Size="1" />
+<Data ElementName="details" Substruct="WS_ItemShieldDetails" Size="1" />
+<Data ElementName="bag_filler" Substruct="WS_ItemBagDetails" Size="1" />
+<Data ElementName="skill_filler" Substruct="WS_SpellInfo" Size="1" />
+<Data ElementName="recipe_filler" Substruct="WS_ItemRecipeBookDetails" Size="1" />
+<Data ElementName="footer" Substruct="Substruct_ItemFooter" Size="1" />
+</Struct>
 <Struct Name="WS_ItemBag" ClientVersion="1" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqExamineInfoCmd">
 <Data ElementName="header" Substruct="Substruct_ItemDescription" Size="1" />
+<Data ElementName="details" Substruct="WS_ItemBagDetails" Size="1" />
+<Data ElementName="skill_filler" Substruct="WS_SpellInfo" Size="1" />
+<Data ElementName="recipe_filler" Substruct="WS_ItemRecipeBookDetails" Size="1" />
+<Data ElementName="footer" Substruct="Substruct_ItemFooter" Size="1" />
+</Struct>
+<Struct Name="WS_ItemSkill" ClientVersion="1" 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="recipe_filler" Substruct="WS_ItemRecipeBookDetails" Size="1" />
+<Data ElementName="footer" Substruct="Substruct_ItemFooter" Size="1" />
+</Struct>
+<Struct Name="WS_ItemRecipeBook" ClientVersion="1" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqExamineInfoCmd">
+<Data ElementName="header" Substruct="Substruct_ItemDescription" Size="1" />
+<Data ElementName="details" Substruct="WS_ItemRecipeBookDetails" Size="1" />
+<Data ElementName="footer" Substruct="Substruct_ItemFooter" Size="1" />
+</Struct>
+<Struct Name="WS_ItemBag" ClientVersion="546" 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" />
+<Data ElementName="weight_reduction" Type="int16" Size="1" />
+<Data ElementName="num_names" Type="int8" Size="1" />
+<Data ElementName="name_array" Type="Array" ArraySizeVariable="num_names">
+	<Data ElementName="item_name" Type="EQ2_8Bit_String" Size="1" />
+</Data>
+<Data ElementName="footer" Substruct="Substruct_ItemFooter" Size="1" />
+</Struct>
+<Struct Name="WS_ItemBag" ClientVersion="547" 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" />
 <Data ElementName="weight_reduction" Type="int16" Size="1" />
@@ -4132,6 +4412,18 @@
 <Struct Name="WS_ItemFood" ClientVersion="1" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqExamineInfoCmd">
 <Data ElementName="header" Substruct="Substruct_ItemDescription" Size="1" />
 <Data ElementName="food_type" Type="int8" Size="1" />
+<Data ElementName="footer" Substruct="Substruct_ItemFooter" Size="1" />
+</Struct>
+<Struct Name="WS_ItemFood" ClientVersion="546" 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" />
+<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">
+<Data ElementName="header" Substruct="Substruct_ItemDescription" Size="1" />
+<Data ElementName="food_type" Type="int8" Size="1" />
 <Data ElementName="level" Type="int8" Size="1" />
 <Data ElementName="duration" Type="float" Size="1" />
 <Data ElementName="footer" Substruct="Substruct_ItemFooter" Size="1" />
@@ -4149,7 +4441,7 @@
 <Data ElementName="display_until_cancelled" Type="int8" Size="1" />
 <Data ElementName="footer" Substruct="Substruct_ItemFooter" Size="1" />
 </Struct>
-<Struct Name="WS_ItemSkill" ClientVersion="1" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqExamineInfoCmd">
+<Struct Name="WS_ItemSkill" ClientVersion="547" 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" />
@@ -4170,7 +4462,7 @@
 <Data ElementName="fence_commission" Type="int16" Size="1" />
 <Data ElementName="footer" Substruct="Substruct_ItemFooter" Size="1" />
 </Struct>
-<Struct Name="WS_ItemRecipeBook" ClientVersion="1" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqExamineInfoCmd">
+<Struct Name="WS_ItemRecipeBook" ClientVersion="547" 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">
@@ -8020,6 +8312,10 @@
 <Data ElementName="header" Substruct="Substruct_LootItemDescription" Size="1" />
 <Data ElementName="footer" Substruct="Substruct_ItemFooter" Size="1" />
 </Struct>
+<Struct Name="WS_LootItemGeneric" ClientVersion="546" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqExamineInfoCmd">
+<Data ElementName="header" Substruct="Substruct_LootItemDescription" Size="1" />
+<Data ElementName="footer" Substruct="Substruct_ItemFooter" Size="1" />
+</Struct>
 <Struct Name="WS_LootItemGeneric" ClientVersion="860" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqExamineInfoCmd">
 <Data ElementName="header" Substruct="Substruct_LootItemDescription" Size="1" />
 <Data ElementName="footer" Substruct="Substruct_ItemFooter" Size="1" />

+ 113 - 96
server/LoginStructs.xml

@@ -34,17 +34,15 @@ to zero and treated like placeholders." />
 <Data ElementName="max_characters" Type="int32" Size="1" />
 </Struct>
 <Struct Name="LS_LoginRequest" ClientVersion="1" OpcodeName="OP_LoginRequestMsg">
-<Data ElementName="accesscode" Type="EQ2_16BitString" />
-<Data ElementName="unknown1" Type="EQ2_16BitString" />
+<Data ElementName="sessionID" Type="EQ2_16BitString" />
+<Data ElementName="sessionRecycleToken" Type="EQ2_16BitString" />
 <Data ElementName="username" Type="EQ2_16BitString" />
 <Data ElementName="password" Type="EQ2_16Bit_String" />
-<Data ElementName="unknown2" Type="int8" Size="8" />
-<!--<Data ElementName="unknown3" Type="int8" Size="2" />-->
+<Data ElementName="acctNum" Type="int32" Size="1" />
+<Data ElementName="passCode" Type="int32" Size="1" />
 <Data ElementName="version" Type="int16" />
-<!--<Data ElementName="unknown3" Type="int16" />-->
-<!--<Data ElementName="unknown4" Type="int32" />-->
 </Struct>
-<Struct Name="LS_LoginRequest" ClientVersion="1212" OpcodeName="OP_LoginRequestMsg">
+<Struct Name="LS_LoginRequest" ClientVersion="547" OpcodeName="OP_LoginRequestMsg">
 <Data ElementName="accesscode" Type="EQ2_16BitString" />
 <Data ElementName="unknown1" Type="EQ2_16BitString" />
 <Data ElementName="username" Type="EQ2_16BitString" />
@@ -57,40 +55,17 @@ to zero and treated like placeholders." />
 <Data ElementName="unknown6" Type="int16" />
 <Data ElementName="unknown7" Type="EQ2_16Bit_String" />
 </Struct>
-<!--<Struct Name="LS_WorldList" ClientVersion="1" OpcodeName="OP_WorldListMsg">
-<Data ElementName="num_worlds" Type="int8" />
-<Data ElementName="world_list" Type="Array" ArraySizeVariable="num_worlds">
-  <Data ElementName="id" Type="int32" Size="1" />
-  <Data ElementName="name" Type="EQ2_16Bit_String" />
-  <Data ElementName="name2" Type="EQ2_16Bit_String" />
-  <Data ElementName="tag" Type="int8" Size="1" />
-  <Data ElementName="locked" Type="int8" Size="1" />
-  <Data ElementName="hidden" Type="int8" Size="1" />
-  <Data ElementName="unknown" Type="int8" Size="1" />
-  <Data ElementName="num_players" Type="int16" Size="1" />
-  <Data ElementName="load" Type="int8" Size="1" />
-  <Data ElementName="number_online_flag" Type="int8" Size="1" />
-  <Data ElementName="feature_set" Type="int8" Size="1" />
-  <Data ElementName="allowed_races" Type="int32" Size="1" />
-</Data>
-</Struct>-->
 <Struct Name="LS_WorldList" ClientVersion="1" OpcodeName="OP_WorldListMsg">
 <Data ElementName="num_worlds" Type="int8" />
 <Data ElementName="world_list" Type="Array" ArraySizeVariable="num_worlds">
   <Data ElementName="id" Type="int32" Size="1" />
   <Data ElementName="name" Type="EQ2_16Bit_String" />
-  <Data ElementName="name2" Type="EQ2_16Bit_String" />
-  <Data ElementName="tag" Type="int8" Size="1" />
+  <Data ElementName="online" Type="int8" Size="1" />
   <Data ElementName="locked" Type="int8" Size="1" />
-  <Data ElementName="hidden" Type="int8" Size="1" />
-  <Data ElementName="unknown" Type="int8" Size="1" />
-  <Data ElementName="num_players" Type="int16" Size="1" />
+  <Data ElementName="unknown2" Type="int8" Size="1" />
+  <Data ElementName="unknown3" Type="int8" Size="1" />
   <Data ElementName="load" Type="int8" Size="1" />
-  <Data ElementName="number_online_flag" Type="int8" Size="1" />
-  <Data ElementName="feature_set" Type="int8" Size="2" />
-  <Data ElementName="allowed_races" Type="int32" Size="1" />
 </Data>
-<Data ElementName="unknown2" Type="int8" />
 </Struct>
 <Struct Name="LS_WorldList" ClientVersion="546" OpcodeName="OP_WorldListMsg">
 <Data ElementName="num_worlds" Type="int8" />
@@ -105,6 +80,7 @@ to zero and treated like placeholders." />
   <Data ElementName="num_players" Type="int16" Size="1" />
   <Data ElementName="load" Type="int8" Size="1" />
   <Data ElementName="number_online_flag" Type="int8" Size="1" />
+  <Data ElementName="unknown2" Type="int8" Size="1" />
   <Data ElementName="allowed_races" Type="int32" Size="1" />
 </Data>
 </Struct>
@@ -171,6 +147,10 @@ to zero and treated like placeholders." />
 </Struct>
 <Struct Name="LS_PlayRequest" ClientVersion="1" OpcodeName="OP_PlayCharacterRequestMsg">
 <Data ElementName="char_id" Type="int32" Size="1" />
+<Data ElementName="name" Type="EQ2_16BitString" />
+</Struct>
+<Struct Name="LS_PlayRequest" ClientVersion="284" OpcodeName="OP_PlayCharacterRequestMsg">
+<Data ElementName="char_id" Type="int32" Size="1" />
 <Data ElementName="server_id" Type="int32" Size="1" />
 <Data ElementName="unknown" Type="int8" Size="3" />
 </Struct>
@@ -205,15 +185,12 @@ to zero and treated like placeholders." />
 <Data ElementName="account_id" Type="int32" Size="1" />
 <Data ElementName="access_code" Type="int32" Size="1" />
 </Struct>
-<Struct Name="CharSelectProfile" ClientVersion="1">
-<Data ElementName="version" Type="int32" Size="1" />
+<Struct Name="CharSelectProfile" ClientVersion="1"> 
 <Data ElementName="charid" Type="int32" Size="1" />
 <Data ElementName="server_id" Type="int32" Size="1" />
 <Data ElementName="name" Type="EQ2_16BitString" Size="1" />
-<Data ElementName="unknown" Type="int8" Size="1" />
 <Data ElementName="race" Type="int8" Size="1" />
 <Data ElementName="class" Type="int8" Size="1" />
-<Data ElementName="gender" Type="int8" Size="1" />
 <Data ElementName="level" Type="int32" Size="1" />
 <Data ElementName="zone" Type="EQ2_16BitString" Size="1" />
 <Data ElementName="unknown1" Type="int32" Size="1" />
@@ -224,32 +201,24 @@ to zero and treated like placeholders." />
 <Data ElementName="unknown4" Type="int32" Size="1" />
 <Data ElementName="zonename2" Type="EQ2_16BitString" Size="1" />
 <Data ElementName="zonedesc" Type="EQ2_16BitString" Size="1" />
-<Data ElementName="unknown5" Type="int32" Size="1" />
-<Data ElementName="server_name" Type="EQ2_16BitString" Size="1" />
-<Data ElementName="account_id" Type="int32" Size="1" />
-<Data ElementName="unknown6" Type="int8" Size="2" />
-<Data ElementName="unknown7" Type="int32" Size="1" />
-<Data ElementName="unknown8" Type="int8" Size="1" />
+<Data ElementName="version" Type="int8" Size="1" />
 <Data ElementName="race_type" Type="int16" Size="1" />
-<Data ElementName="skin_color" Type="EQ2_Color" />
-<Data ElementName="eye_color" Type="EQ2_Color" />
-<Data ElementName="equip" Type="EQ2_EquipmentItem" Size="25" />
+<Data ElementName="skin_color" Type="sint8" Size="3" />
+<Data ElementName="eye_color" Type="sint8" Size="3" />
+<Data ElementName="equip" Type="EQ2_EquipmentItem" Size="21" />
 <Data ElementName="hair_type" Type="int16" Size="1" />
-<Data ElementName="hair_type_color" Type="EQ2_Color" />
-<Data ElementName="hair_type_highlight_color" Type="EQ2_Color" />
+<Data ElementName="hair_type_color" Type="sint8" Size="3" />
+<Data ElementName="hair_type_highlight_color" Type="sint8" Size="3" />
 <Data ElementName="hair_face_type" Type="int16" Size="1" />
-<Data ElementName="hair_face_color" Type="EQ2_Color" />
-<Data ElementName="hair_face_highlight_color" Type="EQ2_Color" />
-<Data ElementName="wing_type" Type="int16" Size="1" />
-<Data ElementName="wing_color1" Type="EQ2_Color" />
-<Data ElementName="wing_color2" Type="EQ2_Color" />
+<Data ElementName="hair_face_color" Type="sint8" Size="3" />
+<Data ElementName="hair_face_highlight_color" Type="sint8" Size="3" />
 <Data ElementName="chest_type" Type="int16" Size="1" />
-<Data ElementName="shirt_color" Type="EQ2_Color" />
-<Data ElementName="unknown_chest_color" Type="EQ2_Color" />
+<Data ElementName="shirt_color" Type="sint8" Size="3" />
+<Data ElementName="unknown_chest_color" Type="sint8" Size="3" />
 <Data ElementName="legs_type" Type="int16" Size="1" />
-<Data ElementName="pants_color" Type="EQ2_Color" />
-<Data ElementName="unknown_legs_color" Type="EQ2_Color" />
-<Data ElementName="unknown9" Type="EQ2_Color" />
+<Data ElementName="pants_color" Type="sint8" Size="3" />
+<Data ElementName="unknown_legs_color" Type="sint8" Size="3" />
+<Data ElementName="unknown9" Type="sint8" Size="3" />
 <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" />
@@ -258,32 +227,15 @@ to zero and treated like placeholders." />
 <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="unknown10" Type="int8" Size="9" />
-<Data ElementName="hair_color1" Type="EQ2_Color" />
-<Data ElementName="hair_color2" Type="EQ2_Color" />
-<Data ElementName="unknown11" Type="int8" Size="13" />
-<Data ElementName="soga_race_type" Type="int16" Size="1" />
-<Data ElementName="soga_skin_color" Type="EQ2_Color" />
-<Data ElementName="soga_eye_color" Type="EQ2_Color" />
-<Data ElementName="Unknown12" Type="int8" Size="3" />
-<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="unknown13" Type="int16" Size="1" />
-<Data ElementName="soga_hair_color1" Type="EQ2_Color"  />
-<Data ElementName="soga_hair_color2" Type="EQ2_Color"  />
-<Data ElementName="unknown14" Type="EQ2_Color" />
-<Data ElementName="soga_hair_type" Type="int16" Size="1" />
-<Data ElementName="soga_hair_type_color" Type="EQ2_Color" />
-<Data ElementName="soga_hair_type_highlight_color" Type="EQ2_Color" />
-<Data ElementName="soga_hair_face_type" Type="int16" Size="1" />
-<Data ElementName="soga_hair_face_color" Type="EQ2_Color" />
-<Data ElementName="soga_hair_face_highlight_color" Type="EQ2_Color" />
-<Data ElementName="unknown15" Type="int8" Size="7" />
+<Data ElementName="bump_scale" Type="sint8" Size="1" />
+<Data ElementName="mount" Type="int16" Size="1" />
+<Data ElementName="mount_color1" Type="sint8" Size="3" />
+<Data ElementName="mount_color2" Type="sint8" Size="3" />
+<Data ElementName="hair_color1" Type="sint8" Size="3" />
+<Data ElementName="hair_color2" Type="sint8" Size="3" />
+<Data ElementName="hair_color3" Type="sint8" Size="3" />
+<Data ElementName="flags" Type="int8" Size="1" />
+<Data ElementName="unknown11" Type="int8" Size="14" />
 </Struct>
 <Struct Name="CharSelectProfile" ClientVersion="546">
 <Data ElementName="charid" Type="int32" Size="1" />
@@ -305,9 +257,9 @@ to zero and treated like placeholders." />
 <Data ElementName="unknown5" Type="int32" Size="1" /> <!-- 4 -->
 <Data ElementName="version" Type="int8" Size="1" /> <!-- 4 -->
 <Data ElementName="race_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="equip" Type="EQ2_EquipmentItem" Size="25" />
+<Data ElementName="skin_color" Type="sint8" Size="3" />
+<Data ElementName="eye_color" Type="sint8" Size="3" />
+<Data ElementName="equip" Type="EQ2_EquipmentItem" Size="23" />
 <Data ElementName="hair_type" Type="int16" Size="1" />
 <Data ElementName="hair_type_color" Type="EQ2_Color" Size="1" />
 <Data ElementName="hair_type_highlight_color" Type="EQ2_Color" Size="1" />
@@ -330,12 +282,14 @@ to zero and treated like placeholders." />
 <Data ElementName="nose_type" Type="sint8" Size="3" />
 <Data ElementName="body_size" Type="sint8" Size="1" />
 <Data ElementName="bump_scale" Type="sint8" Size="1" />
-<Data ElementName="hair_color1" Type="EQ2_Color" Size="1" />
-<Data ElementName="hair_color2" Type="EQ2_Color" Size="1" />
-<Data ElementName="hair_color3" Type="EQ2_Color" Size="1" />
-<Data ElementName="unknown11" Type="int8" Size="1" />
-
-<Data ElementName="soga_race_type" Type="int16" Size="1" />
+<Data ElementName="mount" Type="int16" Size="1" />
+<Data ElementName="mount_color1" Type="sint8" Size="3" />
+<Data ElementName="mount_color2" Type="sint8" Size="3" />
+<Data ElementName="hair_color1" Type="sint8" Size="3" />
+<Data ElementName="hair_color2" Type="sint8" Size="3" />
+<Data ElementName="hair_color3" Type="sint8" Size="3" />
+<Data ElementName="unknown11" Type="int8" Size="10" />
+<Data ElementName="soga_race_type" Type="int16" Size="1" />57
 <Data ElementName="soga_skin_color" Type="EQ2_Color" />
 <Data ElementName="soga_eye_color" Type="EQ2_Color" />
 <Data ElementName="Unknown12" Type="int8" Size="3" />
@@ -346,17 +300,72 @@ to zero and treated like placeholders." />
 <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="unknown13" Type="int16" Size="1" />
 <Data ElementName="soga_hair_color1" Type="EQ2_Color"  />
+<Data ElementName="soga_chest_type" Type="int16" Size="1" />
 <Data ElementName="soga_hair_color2" Type="EQ2_Color"  />
-<Data ElementName="unknown14" Type="EQ2_Color" />
+<Data ElementName="soga_hair_color3" Type="EQ2_Color"  />
 <Data ElementName="soga_hair_type" Type="int16" Size="1" />
 <Data ElementName="soga_hair_type_color" Type="EQ2_Color" />
 <Data ElementName="soga_hair_type_highlight_color" Type="EQ2_Color" />
 <Data ElementName="soga_hair_face_type" Type="int16" Size="1" />
 <Data ElementName="soga_hair_face_color" Type="EQ2_Color" />
 <Data ElementName="soga_hair_face_highlight_color" Type="EQ2_Color" />
-<Data ElementName="flags" Type="int8" Size="1" /> <!-- 4 -->
+</Struct>
+<Struct Name="CharSelectProfile" ClientVersion="547"> 
+<Data ElementName="version" Type="int32" Size="1" />
+<Data ElementName="charid" Type="int32" Size="1" />
+<Data ElementName="server_id" Type="int32" Size="1" />
+<Data ElementName="name" Type="EQ2_16BitString" Size="1" />
+<Data ElementName="unknown" Type="int8" Size="1" />
+<Data ElementName="race" Type="int8" Size="1" />
+<Data ElementName="class" Type="int8" Size="1" />
+<Data ElementName="gender" Type="int8" Size="1" />
+<Data ElementName="level" Type="int32" Size="1" />
+<Data ElementName="zone" Type="EQ2_16BitString" Size="1" />
+<Data ElementName="unknown1" Type="int32" Size="1" />
+<Data ElementName="unknown2" Type="int32" Size="1" />
+<Data ElementName="created_date" Type="int32" Size="1" />
+<Data ElementName="last_played" Type="int32" Size="1" />
+<Data ElementName="unknown3" Type="int32" Size="1" />
+<Data ElementName="unknown4" Type="int32" Size="1" />
+<Data ElementName="zonename2" Type="EQ2_16BitString" Size="1" />
+<Data ElementName="zonedesc" Type="EQ2_16BitString" Size="1" />
+<Data ElementName="unknown5" Type="int32" Size="1" />
+<Data ElementName="server_name" Type="EQ2_16BitString" Size="1" />
+<Data ElementName="account_id" Type="int32" Size="1" />
+<Data ElementName="unknown6" Type="int8" Size="2" />
+<Data ElementName="unknown7" Type="int32" Size="1" />
+<Data ElementName="unknown8" Type="int8" Size="1" />
+<Data ElementName="race_type" Type="int16" Size="1" />
+<Data ElementName="skin_color" Type="EQ2_Color" />
+<Data ElementName="eye_color" Type="EQ2_Color" />
+<Data ElementName="equip" Type="EQ2_EquipmentItem" Size="25" />
+<Data ElementName="hair_type" Type="int16" Size="1" />
+<Data ElementName="hair_type_color" Type="EQ2_Color" />
+<Data ElementName="hair_type_highlight_color" Type="EQ2_Color" />
+<Data ElementName="hair_face_type" Type="int16" Size="1" />
+<Data ElementName="hair_face_color" Type="EQ2_Color" />
+<Data ElementName="hair_face_highlight_color" Type="EQ2_Color" />
+<Data ElementName="chest_type" Type="int16" Size="1" />
+<Data ElementName="shirt_color" Type="EQ2_Color" />
+<Data ElementName="unknown_chest_color" Type="EQ2_Color" />
+<Data ElementName="legs_type" Type="int16" Size="1" />
+<Data ElementName="pants_color" Type="EQ2_Color" />
+<Data ElementName="unknown_legs_color" Type="EQ2_Color" />
+<Data ElementName="unknown9" Type="EQ2_Color" />
+<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="unknown10" Type="int8" Size="9" />
+<Data ElementName="hair_color1" Type="EQ2_Color" />
+<Data ElementName="hair_color2" Type="EQ2_Color" />
+<Data ElementName="unknown11" Type="int8" Size="13" />
+<Data ElementName="unknown15" Type="int8" Size="7" />
 </Struct>
 <Struct Name="CharSelectProfile" ClientVersion="887">
 <Data ElementName="version" Type="int32" Size="1" />
@@ -524,6 +533,14 @@ to zero and treated like placeholders." />
 </Struct>
 <Struct Name="LS_LoginReplyMsg" ClientVersion="1" OpcodeName="OP_LoginReplyMsg">
 <Data ElementName="login_response" Type="int8" Size="1" />
+<Data ElementName="worldName" Type="EQ2_16Bit_String" Size="1" />
+<Data ElementName="parental_control_flag" Type="int8" Size="1" />
+<Data ElementName="parental_control_timer" Type="int32" Size="2" />
+<Data ElementName="parental_control_next" Type="int32" Size="1" />
+<Data ElementName="account_id" Type="int32" Size="1" />
+</Struct>
+<Struct Name="LS_LoginReplyMsg" ClientVersion="284" OpcodeName="OP_LoginReplyMsg">
+<Data ElementName="login_response" Type="int8" Size="1" />
 <Data ElementName="unknown" Type="EQ2_16Bit_String" Size="1" />
 <Data ElementName="parental_control_flag" Type="int8" Size="1" />
 <Data ElementName="parental_control_timer" Type="int32" Size="1" />

+ 365 - 6
server/SpawnStructs.xml

@@ -2,6 +2,44 @@
 <Struct Name="WS_SpawnStruct_Header" ClientVersion="1">
 <Data ElementName="index" Type="int16" Size="1" OversizedValue="255" />
 <Data ElementName="spawn_id" 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" />
+	<Data ElementName="command_list_max_distance" Type="float" Size="1" />
+	<Data ElementName="command_list_error" Type="EQ2_16Bit_String" Size="1" />
+	<Data ElementName="command_list_command" Type="EQ2_16Bit_String" />
+</Data>
+<Data ElementName="default_command" Type="EQ2_16Bit_String" Size="1" />
+<Data ElementName="max_distance" Type="float" Size="1" />
+<Data ElementName="group_size" Type="int8" Size="1" />
+<Data ElementName="group_array" Type="Array" ArraySizeVariable="group_size">
+	<Data ElementName="group_spawn_id" Type="int32" />
+</Data>
+<Data ElementName="time_stamp" Type="int32" Size="1" />
+</Struct>
+<Struct Name="WS_SpawnStruct_Header" ClientVersion="546">
+<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="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" />
+	<Data ElementName="command_list_max_distance" Type="float" Size="1" />
+	<Data ElementName="command_list_error" Type="EQ2_16Bit_String" Size="1" />
+	<Data ElementName="command_list_command" Type="EQ2_16Bit_String" />
+</Data>
+<Data ElementName="default_command" Type="EQ2_16Bit_String" Size="1" />
+<Data ElementName="max_distance" Type="float" Size="1" />
+<Data ElementName="group_size" Type="int8" Size="1" />
+<Data ElementName="group_array" Type="Array" ArraySizeVariable="group_size">
+	<Data ElementName="group_spawn_id" Type="int32" />
+</Data>
+<Data ElementName="time_stamp" Type="int32" Size="1" />
+</Struct>
+<Struct Name="WS_SpawnStruct_Header" ClientVersion="547">
+<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" />
@@ -45,7 +83,69 @@
 </Data>
 <Data ElementName="time_stamp" Type="int32" Size="1" />
 </Struct>
-<Struct Name="Substruct_SpawnPositionStruct" ClientVersion="1" >
+<Struct Name="Substruct_SpawnPositionStruct" ClientVersion="1" Comment="77 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_dest_loc_offset" Type="sint16" Size="3" /> <!-- 0x1b -->
+<Data ElementName="pos_dest_loc_offset2" Type="sint16" Size="3" /> <!-- 0x21 -->
+<Data ElementName="pos_heading_speed" Type="sint16" Size="1" /> <!-- 0x27 -->
+<Data ElementName="pos_move_type" Type="sint16" Size="1" /> <!-- 0x29 -->
+<Data ElementName="pos_swim_speed_modifier" Type="sint16" Size="1" /> <!-- 0x2b -->
+<Data ElementName="pos_side_speed" Type="sint16" Size="1" /> <!-- 0x2d -->
+<Data ElementName="pos_vert_speed" Type="sint16" Size="1" /> <!-- 0x2f -->
+<Data ElementName="pos_requested_pitch" Type="sint16" Size="1" /> <!-- 0x31 -->
+<Data ElementName="pos_requested_pitch_speed" Type="sint16" Size="1" /> <!-- 0x33 -->
+<Data ElementName="pos_x" Type="float" Size="1" /> <!-- 0x35 -->
+<Data ElementName="pos_y" Type="float" Size="1" /> <!-- 0x39 -->
+<Data ElementName="pos_z" Type="float" Size="1" /> <!-- 0x3d -->
+<Data ElementName="pos_pitch" Type="sint16" Size="1" /> <!-- 0x41 -->
+<Data ElementName="pos_collision_radius" Type="sint16" Size="1" /> <!-- 0x43 -->
+<Data ElementName="pos_size" Type="sint16" Size="1" /> <!-- 0x45 -->
+<Data ElementName="face_actor_id" Type="int32" Size="1" /> <!-- 0x47 -->
+<Data ElementName="actor_stop_range" Type="sint16" Size="1" /> <!-- 0x4b -->
+</Struct>
+<Struct Name="Substruct_SpawnPositionStruct" ClientVersion="546" 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_pitch" 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_unknown4" 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" />
@@ -251,7 +351,211 @@
 <Data ElementName="pos_roll" Type="sint16" />
 <Data ElementName="unknown12" Type="int16" Size="2" />
 </Struct>
-<Struct Name="Substruct_SpawnInfoStruct" ClientVersion="1" >
+<Struct Name="Substruct_SpawnInfoStruct" ClientVersion="1" Comment="796 bytes">
+<Data ElementName="hp_remaining" Type="int32" Size="1" /> <!-- 0 -->
+<Data ElementName="power_percent" Type="int32" Size="1" /> <!-- 4 -->
+<Data ElementName="follow_target" Type="int32" Size="1" /> <!-- 12 -->
+<Data ElementName="target_id" Type="int32" Size="1" /> <!-- 8 -->
+<Data ElementName="unknown1" Type="int8" Size="8" /> <!-- 16 -->
+<Data ElementName="corpse" Type="int8" Size="1" /> <!-- 24 -->
+<Data ElementName="class" Type="int8" Size="1" /> <!-- 25 -->
+<Data ElementName="level" Type="int8" Size="1" /> <!-- 26 -->
+<Data ElementName="difficulty" Type="int8" Size="1" /> <!-- 27 -->
+<Data ElementName="unknown3" Type="int8" Size="1" /> <!-- 28 -->
+<Data ElementName="heroic_flag" Type="int8" Size="1" /> <!-- 29 -->
+<Data ElementName="npc" Type="int8" Size="1" /> <!-- 30 -->
+<Data ElementName="unknown6" Type="int8" Size="1" /> <!-- 31 -->
+<Data ElementName="unknown7" Type="int8" Size="1" /> <!-- 32 -->
+<Data ElementName="merchant" Type="int8" Size="1" /> <!-- 33 -->
+<Data ElementName="unknown9" Type="int8" Size="1" /> <!-- 34 -->
+<Data ElementName="unknown10" Type="int8" Size="1" /> <!-- 35 -->
+<Data ElementName="no_arrow_color_or_highlight" Type="int8" Size="1" /> <!-- 36 -->
+<Data ElementName="no_arrow_color_or_healthbar" Type="int8" Size="1" /> <!-- 37 -->
+<Data ElementName="hand_icon" Type="int8" Size="1" /> <!-- 38   127 -->
+<Data ElementName="hide_health" Type="int8" Size="1" /> <!-- 39 -->
+<Data ElementName="unknown15" Type="int8" Size="1" /> <!-- 40 -->
+<Data ElementName="house_icon" Type="int8" Size="1" /> <!-- 41 -->
+<Data ElementName="in_combat" Type="int8" Size="1" /> <!-- 42 -->
+<Data ElementName="afk" Type="int8" Size="1" /> <!-- 43 -->
+<Data ElementName="roleplaying" Type="int8" Size="1" /> <!-- 44 -->
+<Data ElementName="anonymous" Type="int8" Size="1" /> <!-- 45 -->
+<Data ElementName="linkdead" Type="int8" Size="1" /> <!-- 46 -->
+<Data ElementName="camping" Type="int8" Size="1" /> <!-- 47 -->
+<Data ElementName="lfg" Type="int8" Size="1" /> <!-- 48 -->
+<Data ElementName="solid_object" Type="int8" Size="1" /> <!-- 49 -->
+<Data ElementName="unknown25" Type="int8" Size="1" /> <!-- 50 -->
+<Data ElementName="unknown26" Type="int8" Size="1" /> <!-- 51 -->
+<Data ElementName="unknown27" Type="int8" Size="1" /> <!-- 52 -->
+<Data ElementName="unknown28" Type="int8" Size="1" /> <!-- 53 -->
+<Data ElementName="activity_status" Type="int32" Size="1" /> <!-- 54, not really used in this version -->
+<Data ElementName="model_type" Type="int16" Size="1" /> <!-- 58 -->
+<Data ElementName="skin_color" Type="EQ2_Color" Size="1" /> <!-- 60 -->
+<Data ElementName="eye_color" Type="EQ2_Color" Size="1" /> <!-- 63 -->
+<Data ElementName="equipment_types" Type="int16" Size="21" /> <!-- 66 -->
+<Data ElementName="hair_type_id" Type="int16" Size="1" />
+<Data ElementName="facial_hair_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="equipment_colors" Type="EQ2_Color" Size="21" /> <!-- 116 -->
+<Data ElementName="hair_type_color" Type="EQ2_Color" />
+<Data ElementName="hair_face_color" Type="EQ2_Color" />
+<Data ElementName="chest_type_color" Type="EQ2_Color" Size="1" />
+<Data ElementName="legs_type_color" Type="EQ2_Color" Size="1" />
+<Data ElementName="equipment_highlights" Type="EQ2_Color" Size="21" /> <!-- 191 -->
+<Data ElementName="hair_type_highlight_color" Type="EQ2_Color" />
+<Data ElementName="hair_face_highlight_color" Type="EQ2_Color" />
+<Data ElementName="chest_type_highlight_color" Type="EQ2_Color" Size="1" />
+<Data ElementName="legs_type_highlight_color" Type="EQ2_Color" Size="1" />
+<Data ElementName="skull_type" Type="sint8" Size="3" /> <!-- 266 -->
+<Data ElementName="eye_type" Type="sint8" Size="3" /> <!-- 269 -->
+<Data ElementName="ear_type" Type="sint8" Size="3" /> <!-- 272 -->
+<Data ElementName="eye_brow_type" Type="sint8" Size="3" /> <!-- 275 -->
+<Data ElementName="cheek_type" Type="sint8" Size="3" /> <!-- 278 -->
+<Data ElementName="lip_type" Type="sint8" Size="3" /> <!-- 281 -->
+<Data ElementName="chin_type" Type="sint8" Size="3" /> <!-- 284 -->
+<Data ElementName="nose_type" Type="sint8" Size="3" /> <!-- 287 -->
+<Data ElementName="body_size" Type="sint8" Size="1" /> <!-- 290 -->
+<Data ElementName="bump_size" Type="sint8" Size="1" /> <!-- 291 -->
+<Data ElementName="mount_type" Type="int16" Size="1" /> <!-- 292 -->
+<Data ElementName="mount_color" Type="EQ2_Color" /> <!-- 294 -->
+<Data ElementName="mount_saddle_color" Type="EQ2_Color" /> <!-- 297 -->
+<Data ElementName="hair_color1" Type="EQ2_Color" /> <!-- 300 -->
+<Data ElementName="hair_color2" Type="EQ2_Color" /> <!-- 303 -->
+<Data ElementName="hair_highlight" Type="EQ2_Color" /> <!-- 306 -->
+<Data ElementName="flags" Type="int8" Size="1" /><!-- 309 1 == invisible, 2 == show_hood, 8 == crouch -->
+<Data ElementName="temporary_scale" Type="float" Size="1" /> <!-- 310 -->
+<Data ElementName="name" Type="char" Size="64" /> <!-- 314 -->
+<Data ElementName="last_name" Type="char" Size="64" /> <!-- 378 -->
+<Data ElementName="name_suffix" Type="char" Size="64" /> <!-- 442 -->
+<Data ElementName="name_prefix" Type="char" Size="64" /> <!-- 506 -->
+<Data ElementName="unknown31" Type="char" Size="64" /> <!-- 570 -->
+<Data ElementName="second_suffix" Type="char" Size="64" /> <!-- 634 -->
+<Data ElementName="persistent_spell_visuals" Type="int16" Size="8" /> <!-- 698 -->
+<Data ElementName="persistent_spell_levels" Type="int8" Size="8" /> <!-- 714 -->
+<Data ElementName="unknown32" Type="int8" Size="64" /> <!-- 722 -->
+<Data ElementName="action_state" Type="int16" Size="1" /> <!-- 786 -->
+<Data ElementName="visual_state" Type="int16" Size="1" /> <!-- 788 -->
+<Data ElementName="mood_state" Type="int16" Size="1" /> <!-- 790 -->
+<Data ElementName="emote_state" Type="int16" Size="1" /> <!-- 792 -->
+<Data ElementName="race" Type="int8" Size="1" /> <!-- 794 -->
+<Data ElementName="gender" Type="int8" Size="1" /> <!-- 795 -->
+</Struct>
+<Struct Name="Substruct_SpawnInfoStruct" ClientVersion="546" >
+<Data ElementName="hp_remaining" Type="int32" Size="1" /> <!-- 0 -->
+<Data ElementName="power_percent" Type="int32" Size="1" /> <!-- 4 -->
+<Data ElementName="spells" Substruct="Substruct_TargetSpellEffects" Size="30" /> <!-- 8 -->
+<Data ElementName="follow_target" Type="int32" Size="1" /> <!-- 278 -->
+<Data ElementName="target_id" Type="int32" Size="1" /> <!-- 282 -->
+<Data ElementName="unknown5" Type="int8" Size="8" /> <!-- 286 -->
+<Data ElementName="corpse" Type="int8" Size="1" /> <!-- 295 -->
+<Data ElementName="class" Type="int8" Size="1" /> <!-- 296 -->
+<Data ElementName="effective_level" Type="int8" Size="1" />
+<Data ElementName="level" Type="int8" Size="1" /> <!-- 297 -->
+<Data ElementName="difficulty" Type="int8" Size="1" /> <!-- 298 -->
+<Data ElementName="unknown6" Type="int8" Size="1" /> <!-- 299 -->
+<Data ElementName="heroic_flag" Type="int8" Size="1" /> <!-- 300 -->
+<Data ElementName="npc" Type="int8" Size="1" /> <!-- 301 -->
+<Data ElementName="unknown7" Type="int8" Size="1" /> <!-- 303 -->
+<Data ElementName="unknown8" Type="int8" Size="1" /> <!-- 303 -->
+<Data ElementName="merchant" Type="int8" Size="1" /> <!-- 304 -->
+<Data ElementName="unknown9" Type="int8" Size="1" /> <!-- 305 -->
+<Data ElementName="unknown10" Type="int8" Size="1" /> <!-- 306 -->
+<Data ElementName="no_arrow_color_or_highlight" Type="int8" Size="1" /> <!-- 307 -->
+<Data ElementName="no_arrow_color_or_healthbar" Type="int8" Size="1" /> <!-- 308 -->
+<Data ElementName="hand_icon" Type="int8" Size="1" /> <!-- 309   127 -->
+<Data ElementName="hide_health" Type="int8" Size="1" /> <!-- 310 -->
+<Data ElementName="unknown11" Type="int8" Size="1" /> <!-- 311 -->
+<Data ElementName="house_icon" Type="int8" Size="1" /> <!-- 312 -->
+<Data ElementName="in_combat" Type="int8" Size="1" /> <!-- 313 -->
+<Data ElementName="afk" Type="int8" Size="1" /> <!-- 314 -->
+<Data ElementName="roleplaying" Type="int8" Size="1" /> <!-- 315 -->
+<Data ElementName="anonymous" Type="int8" Size="1" /> <!-- 316 -->
+<Data ElementName="linkdead" Type="int8" Size="1" /> <!-- 317 -->
+<Data ElementName="camping" Type="int8" Size="1" /> <!-- 318 -->
+<Data ElementName="lfg" Type="int8" Size="1" /> <!-- 319 -->
+<Data ElementName="solid_object" Type="int8" Size="1" /> <!-- 320 -->
+<Data ElementName="unknown12" Type="int8" Size="1" /> <!-- 321 -->
+<Data ElementName="unknown13" Type="int8" Size="1" /> <!-- 322 -->
+<Data ElementName="unknown14" Type="int8" Size="1" /> <!-- 323 -->
+<Data ElementName="unknown15" Type="int8" Size="1" /> <!-- 324 -->
+<Data ElementName="unknown16" Type="int8" Size="1" /> <!-- 325 -->
+<Data ElementName="unknown17" Type="int8" Size="1" /> <!-- 326 -->
+<Data ElementName="activity_status" 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="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="unknown" Type="int8" Size="6" /> <!-- 657 -->
+<Data ElementName="flags" Type="int8" Size="1" /><!-- 663 1 == invisible, 2 == show_hood, 8 == crouch -->
+<Data ElementName="unknown" 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="547" >
 <Data ElementName="hp_remaining" Type="int8" Size="1" />
 <Data ElementName="unknown2a" Type="int8" Size="3" />
 <Data ElementName="power_percent" Type="int8" Size="1" />
@@ -334,7 +638,7 @@
 <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" />
+<Data ElementName="gender" Type="int8" Size="1" /> <!-- total 722 -->
 </Struct>
 <Struct Name="Substruct_SpawnInfoStruct" ClientVersion="860" >
 <Data ElementName="hp_remaining" Type="int8" Size="1" />
@@ -2071,6 +2375,12 @@
 <Data ElementName="spawn_type" Type="int8" Size="1" />
 </Struct>
 <Struct Name="WS_WidgetSpawnStruct_Footer" ClientVersion="1">
+<Data ElementName="widget_id" Type="int32" Size="1" />
+<Data ElementName="widget_x" Type="float" Size="1" />
+<Data ElementName="widget_y" Type="float" Size="1" />
+<Data ElementName="widget_z" Type="float" Size="1" />
+</Struct>
+<Struct Name="WS_WidgetSpawnStruct_Footer" ClientVersion="547">
 <Data ElementName="name" Type="EQ2_16Bit_String" Size="1" />
 <Data ElementName="unknown1" Type="float" Size="1" />
 <Data ElementName="unknown2" Type="float" Size="1" />
@@ -2117,6 +2427,16 @@
 <Data ElementName="widget_z" Type="float" Size="1" />
 </Struct>
 <Struct Name="WS_SignWidgetSpawnStruct_Footer" ClientVersion="1">
+<Data ElementName="widget_id" Type="int32" Size="1" />
+<Data ElementName="widget_x" Type="float" Size="1" />
+<Data ElementName="widget_y" Type="float" Size="1" />
+<Data ElementName="widget_z" Type="float" Size="1" />
+<Data ElementName="title" Type="EQ2_16Bit_String" Size="1" />
+<Data ElementName="description" Type="EQ2_16Bit_String" Size="1" />
+<Data ElementName="sign_distance" Type="float" Size="1" />
+<Data ElementName="show" Type="int16" 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" />
@@ -2175,7 +2495,38 @@
 	<Data ElementName="unkString" Type="EQ2_16Bit_String" />
 </Data>
 </Struct>
-<Struct Name="Substruct_SpawnVisualizationInfoStruct" ClientVersion="1">
+<Struct Name="Substruct_SpawnVisualizationInfoStruct" ClientVersion="1" Comment="12 bytes">
+<Data ElementName="arrow_color" Type="int8" Size="1" /> <!-- 1-6 arrow colors, 7-13 merchant, 14-20 bank, 21-28 hail, 29-34 attack, 35-43 window icons, 46 saw, 47 house -->
+<Data ElementName="locked_no_loot" Type="int8" Size="1" />
+<Data ElementName="npc_con" Type="sint8" Size="1" />
+<Data ElementName="group_member" Type="int8" Size="1" />
+<Data ElementName="vis_flags" Type="int8" Size="1" />
+<Data ElementName="targetable" Type="int8" Size="1" />
+<Data ElementName="red_glow" Type="int8" Size="1" />
+<Data ElementName="show_name" Type="int8" Size="1" />
+<Data ElementName="attackable" Type="int8" Size="1" />
+<Data ElementName="unknown10" Type="int8" Size="1" />
+<Data ElementName="unknown11" Type="int8" Size="1" />
+<Data ElementName="unknown12" Type="int8" Size="1" />
+</Struct>
+<Struct Name="Substruct_SpawnVisualizationInfoStruct" ClientVersion="546" Comment="78 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="unknown1" Type="int8" Size="1" />
+<Data ElementName="vis_flags" Type="int8" Size="1" />
+<Data ElementName="targetable" Type="int8" Size="1" />
+<Data ElementName="red_glow" Type="int8" Size="1" />
+<Data ElementName="show_name" Type="int8" Size="1" />
+<Data ElementName="attackable" Type="int8" Size="1" />
+<Data ElementName="unknown2" Type="int8" Size="1" />
+<Data ElementName="unknown3" Type="int8" Size="1" />
+<Data ElementName="unknown4" Type="int8" Size="1" />
+<Data ElementName="unknown5" Type="int8" Size="1" />
+<Data ElementName="guild" Type="int8" Size="64" />
+</Struct>
+<Struct Name="Substruct_SpawnVisualizationInfoStruct" ClientVersion="547">
 <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" />
@@ -2247,7 +2598,6 @@
 <Data ElementName="tag2" Type="int8" Size="1" />
 <Data ElementName="unknown2" Type="int8" Size="3" />
 </Struct>
-
 <Struct Name="Substruct_SpawnVisualizationInfoStruct" ClientVersion="60055">
 <Data ElementName="unknown" Type="int32" Size="1" />
 <Data ElementName="arrow_color" Type="int8" Size="1" />
@@ -2268,12 +2618,21 @@
 <Data ElementName="tag2" Type="int8" Size="1" />
 <Data ElementName="unknown3" Type="int8" Size="1" />
 </Struct>
-
 <Struct Name="WS_SpawnStruct" ClientVersion="1">
 <Data ElementName="position" Substruct="Substruct_SpawnPositionStruct" Size="1" />
 <Data ElementName="vis" Substruct="Substruct_SpawnVisualizationInfoStruct" Size="1" />
 <Data ElementName="info" Substruct="Substruct_SpawnInfoStruct" Size="1" />
 </Struct>
+<Struct Name="WS_SpawnStruct" ClientVersion="546">
+<Data ElementName="position" Substruct="Substruct_SpawnPositionStruct" Size="1" />
+<Data ElementName="vis" Substruct="Substruct_SpawnVisualizationInfoStruct" Size="1" />
+<Data ElementName="info" Substruct="Substruct_SpawnInfoStruct" Size="1" />
+</Struct>
+<Struct Name="WS_SpawnStruct" ClientVersion="547">
+<Data ElementName="position" Substruct="Substruct_SpawnPositionStruct" Size="1" />
+<Data ElementName="vis" Substruct="Substruct_SpawnVisualizationInfoStruct" Size="1" />
+<Data ElementName="info" Substruct="Substruct_SpawnInfoStruct" Size="1" />
+</Struct>
 <Struct Name="WS_SpawnStruct" ClientVersion="860">
 <Data ElementName="position" Substruct="Substruct_SpawnPositionStruct" Size="1" />
 <Data ElementName="vis" Substruct="Substruct_SpawnVisualizationInfoStruct" Size="1" />

File diff suppressed because it is too large
+ 650 - 14989
server/WorldStructs.xml


Some files were not shown because too many files changed in this diff