/* missing: OP_TGB OP_GuildMemberList */ //opcode_dispatch.h /* There are currently eight (times two) dispatch modes possible, the different modes for a given state differ only in the arguments which are passed to the dispatch function. The variable length versions ensure that the packet is AT LEAST as long as the supplied structure. The variable length versions should only be used when the packet is truely variable length, and usage of the raw versions should be avoided as much as reasonable. There is almost no valid reason to use the raw version. Use the zero length version when the packet should be zero length. the 'struct' passed can also be a raw type like 'float' or 'uint32' in the case that the packet only contains that single variable. Connecting state: IN_C(opcode, struct) -> Typed dispatch in connecting mode Dispatch Prototype: void Client::Handle_Connect_opcode(struct *packet); IN_Cv(opcode, struct) -> Typed dispatch in connecting mode, variable length Dispatch Prototype: void Client::Handle_Connect_opcode(struct *packet, uint32 length); IN_Cz(opcode) -> Zero length dispatch in connecting mode Dispatch Prototype: void Client::Handle_Connect_opcode(); IN_Cr(opcode) -> Raw dispatch in connecting mode Dispatch Prototype: void Client::Handle_Connect_opcode(const EQApplicationPacket *app); Connected state: IN(opcode, struct) -> Typed dispatch in connected mode Dispatch Prototype: void Client::Handle_opcode(struct *packet); INv(opcode, struct) -> Typed dispatch in connected mode, variable length Dispatch Prototype: void Client::Handle_opcode(struct *packet, uint32 length); INz(opcode) -> Zero length dispatch in connected mode Dispatch Prototype: void Client::Handle_opcode(); INr(opcode) -> Raw dispatch in connected mode Dispatch Prototype: void Client::Handle_opcode(const EQApplicationPacket *app); All of the above functions apply to OUT mode as well. lines prefixed with //alt: provide information about alternate structures for an opcode, mainly used by opcode finder */ //IN_C(OP_SetDataRate, float); IN_C(OP_ZoneEntry, ClientZoneEntry_Struct); IN_C(OP_SetServerFilter, SetServerFilter_Struct); IN_Cz(OP_SendAATable); IN_Cz(OP_SendTributes); IN_Cz(OP_SendGuildTributes); IN_Cz(OP_SendAAStats); IN_Cz(OP_ReqClientSpawn); IN_Cz(OP_ReqNewZone); IN_Cz(OP_SendExpZonein); //IN_Cr(OP_ZoneComplete); //these three should stay raw, since we ignore their contents and //they overlap with the connected opcodes IN_Cr(OP_SpawnAppearance); IN_Cr(OP_WearChange); IN_Cr(OP_ClientUpdate); IN_Cz(OP_ClientReady); IN_C(OP_ClientError, ClientError_Struct); IN_C(OP_ApproveZone, ApproveZone_Struct); IN_Cr(OP_TGB); IN(OP_AckPacket, uint32); IN(OP_ClientUpdate, PlayerPositionUpdateClient_Struct); IN(OP_AutoAttack, uint32); IN(OP_AutoAttack2, uint32); INv(OP_Consent, Consent_Struct); INv(OP_ConsentDeny, Consent_Struct); IN(OP_TargetMouse, ClientTarget_Struct); IN(OP_TargetCommand, ClientTarget_Struct); IN(OP_Shielding, Shielding_Struct); INr(OP_Jump); //? INr(OP_AdventureInfoRequest); INr(OP_AdventureRequest); IN(OP_LDoNButton, bool); //not sure on length INr(OP_LeaveAdventure); IN(OP_Consume, Consume_Struct); IN(OP_AdventureMerchantRequest, AdventureMerchant_Struct); IN(OP_AdventureMerchantPurchase, Adventure_Purchase_Struct); IN(OP_ConsiderCorpse, Consider_Struct); IN(OP_Consider, Consider_Struct); INr(OP_Begging); //? INr(OP_TestBuff); IN(OP_Surname, Surname_Struct); INr(OP_YellForHelp); IN(OP_Assist, EntityId_Struct); //generic IN(OP_GMTraining, GMTrainee_Struct); IN(OP_GMEndTraining, GMTrainEnd_Struct); IN(OP_GMTrainSkill, GMSkillChange_Struct); IN(OP_RequestDuel, Duel_Struct); IN(OP_DuelResponse, DuelResponse_Struct); IN(OP_DuelResponse2, Duel_Struct); IN(OP_SpawnAppearance, SpawnAppearance_Struct); IN(OP_BazaarInspect, BazaarInspect_Struct); IN(OP_Death, Death_Struct); IN(OP_MoveCoin, MoveCoin_Struct); IN(OP_ItemLinkClick, ItemViewRequest_Struct); IN(OP_MoveItem, MoveItem_Struct); INz(OP_Camp); //? INz(OP_Logout); INz(OP_SenseHeading); //? INz(OP_FeignDeath); //? INz(OP_Sneak); //? INz(OP_Hide); //? INv(OP_ChannelMessage, ChannelMessage_Struct); IN(OP_WearChange, WearChange_Struct); IN(OP_DeleteSpawn, EntityId_Struct); //client->server follows OP_SaveOnZoneReq IN(OP_SaveOnZoneReq, Save_Struct); //follows OP_ZoneChange IN(OP_Save, Save_Struct); IN(OP_WhoAllRequest, Who_All_Struct); IN(OP_GMZoneRequest, GMZoneRequest_Struct); IN(OP_GMZoneRequest2, uint32); IN(OP_EndLootRequest, EntityId_Struct); //follows OP_LootRequest IN(OP_LootRequest, EntityId_Struct); //entity must be a corpse IN(OP_Dye, DyeStruct); INr(OP_ConfirmDelete); //? IN(OP_LootItem, LootingItem_Struct); INr(OP_GuildDelete); //? IN(OP_GuildPublicNote, GuildUpdate_PublicNote); INz(OP_GetGuildsList); //? IN(OP_SetGuildMOTD, GuildMOTD_Struct); IN(OP_SetRunMode, SetRunMode_Struct); INz(OP_GuildPeace); //? INz(OP_GuildWar); //? IN(OP_GuildLeader, GuildMakeLeader); IN(OP_GuildDemote, GuildDemoteStruct); IN(OP_GuildInvite, GuildCommand_Struct); IN(OP_GuildRemove, GuildCommand_Struct); IN(OP_GuildInviteAccept, GuildInviteAccept_Struct); IN(OP_ManaChange, ManaChange_Struct); //possibly zero len too //alt:INz(OP_ManaChange); IN(OP_MemorizeSpell, MemorizeSpell_Struct); IN(OP_SwapSpell, SwapSpell_Struct); IN(OP_CastSpell, CastSpell_Struct); IN(OP_DeleteItem, DeleteItem_Struct); IN(OP_CombatAbility, CombatAbility_Struct); IN(OP_Taunt, ClientTarget_Struct); INz(OP_InstillDoubt); IN(OP_RezzAnswer, Resurrect_Struct); IN(OP_GMSummon, GMSummon_Struct); IN(OP_TradeBusy, TradeBusy_Struct); IN(OP_TradeRequest, TradeRequest_Struct); IN(OP_TradeRequestAck, TradeRequest_Struct); //follows OP_TradeRequest IN(OP_CancelTrade, CancelTrade_Struct); IN(OP_TradeAcceptClick, TradeAccept_Struct); IN(OP_BoardBoat, EntityId_Struct); //not really the struct, just 4 bytes INz(OP_LeaveBoat); //? IN(OP_RandomReq, RandomReq_Struct); IN(OP_Buff, SpellBuffFade_Struct); IN(OP_GMHideMe, SpawnAppearance_Struct); IN(OP_GMNameChange, GMName_Struct); IN(OP_GMKill, GMKill_Struct); IN(OP_GMLastName, GMLastName_Struct); IN(OP_GMToggle, GMToggle_Struct); IN(OP_LFGCommand, LFG_Struct); IN(OP_GMGoto, GMSummon_Struct); INv(OP_TraderShop, TraderClick_Struct); IN(OP_ShopRequest, Merchant_Click_Struct); IN(OP_Bazaar, BazaarSearch_Struct); //alt:IN(OP_Bazaar, BazaarWelcome_Struct); //alternate structure for OP_Bazaar IN(OP_ShopPlayerBuy, Merchant_Sell_Struct); IN(OP_ShopPlayerSell, Merchant_Purchase_Struct); INr(OP_ShopEnd); //? IN(OP_CloseContainer, ClickObjectAction_Struct); IN(OP_ClickObjectAction, ClickObjectAction_Struct); IN(OP_ClickObject, ClickObject_Struct); IN(OP_RecipesFavorite, TradeskillFavorites_Struct); IN(OP_RecipesSearch, RecipesSearch_Struct); IN(OP_RecipeDetails, uint32); //there is also a complicated OP_RecipeDetails reply struct OUT IN(OP_RecipeAutoCombine, RecipeAutoCombine_Struct); IN(OP_TradeSkillCombine, NewCombine_Struct); IN(OP_ItemName, ItemNamePacket_Struct); IN(OP_AugmentItem, AugmentItem_Struct); IN(OP_ClickDoor, ClickDoor_Struct); INr(OP_CreateObject); //? IN(OP_FaceChange, FaceChange_Struct); IN(OP_GroupInvite, GroupInvite_Struct); IN(OP_GroupInvite2, GroupInvite_Struct); //will generally follow OP_GroupInvite for next invite IN(OP_GroupFollow, GroupGeneric_Struct); //will follow invite IN(OP_GroupFollow2, GroupGeneric_Struct); //will follow invite2 INr(OP_GroupAcknowledge); //? IN(OP_GroupCancelInvite, GroupGeneric_Struct); //follows invite or invite2 IN(OP_GroupDisband, GroupGeneric_Struct); INr(OP_GroupDelete); //? IN(OP_GMEmoteZone, GMEmoteZone_Struct); IN(OP_InspectRequest, Inspect_Struct); IN(OP_InspectAnswer, Inspect_Struct); //follows request IN(OP_DeleteSpell, DeleteSpell_Struct); IN(OP_PetitionBug, PetitionBug_Struct); IN(OP_Bug, BugStruct); //all these petition opcodes need checking //converted most of them to raw so they wouldent cause problems INr(OP_Petition); //used to be just a string IN(OP_PetitionCheckIn, Petition_Struct); IN(OP_PetitionResolve, PetitionUpdate_Struct); IN(OP_PetitionDelete, PetitionUpdate_Struct); INr(OP_PetitionUnCheckout); //prolly 4 bytes in length INr(OP_PetitionQue); INr(OP_PDeletePetition); //used to be just a string INr(OP_PetitionCheckout); //prolly 4 bytes in length INr(OP_PetitionRefresh); IN(OP_PetCommands, PetCommand_Struct); IN(OP_ReadBook, BookRequest_Struct); IN(OP_Emote, Emote_Struct); #ifdef DISJOINT_STATES IN(OP_SetServerFilter, SetServerFilter_Struct); #endif IN(OP_GMDelCorpse, GMDelCorpse_Struct); IN(OP_GMKick, GMKick_Struct); INr(OP_GMServers); //? IN(OP_Illusion, Illusion_Struct); IN(OP_GMBecomeNPC, BecomeNPC_Struct); INz(OP_Fishing); //? INz(OP_Forage); //? INz(OP_Mend); //? IN(OP_EnvDamage, EnvDamage2_Struct); IN(OP_Damage, CombatDamage_Struct); IN(OP_AAAction, AA_Action); IN(OP_TraderBuy, TraderBuy_Struct); IN(OP_Trader, Trader_ShowItems_Struct); IN(OP_GMFind, GMSummon_Struct); IN(OP_PickPocket, PickPocket_Struct); IN(OP_Bind_Wound, BindWound_Struct); INr(OP_TrackTarget); INr(OP_Track); INz(OP_TrackUnknown); //follows OP_Track #ifdef DISJOINT_STATES IN(OP_ClientError, ClientError_Struct); #endif INr(OP_ReloadUI); //? INr(OP_TGB); //4 bytes, value is 0, 1, or 2 IN(OP_Split, Split_Struct); INz(OP_SenseTraps); //? INz(OP_DisarmTraps); //? IN(OP_OpenTributeMaster, StartTribute_Struct); IN(OP_OpenGuildTributeMaster, StartTribute_Struct); IN(OP_TributeItem, TributeItem_Struct); IN(OP_TributeMoney, TributeMoney_Struct); IN(OP_SelectTribute, SelectTributeReq_Struct); IN(OP_TributeUpdate, TributeInfo_Struct); IN(OP_TributeToggle, uint32); //value is 0 or 1 IN(OP_TributeNPC, uint32); //contains tribute master entity ID INr(OP_CrashDump); INr(OP_ControlBoat); INr(OP_DumpName); INr(OP_SetRunMode); INr(OP_SafeFallSuccess); INr(OP_Heartbeat); INr(OP_SafePoint); INr(OP_Ignore); IN(OP_FindPersonRequest, FindPersonRequest_Struct); IN(OP_LeadershipExpToggle, uint8); IN(OP_PurchaseLeadershipAA, uint32); //value is < _maxLeaderAA INr(OP_ClearTitle); //follows OP_SendTitleList INr(OP_BankerChange); IN(OP_SetTitle, SetTitle_Struct); INz(OP_RequestTitles); IN(OP_ItemVerifyRequest, ItemVerifyRequest_Struct); /* for now we are listing outgoing packets which are NOT also incoming packets */ OUTz(OP_ClearObject); OUTz(OP_FinishTrade); //follows OP_TradeAcceptClick OUTz(OP_GMEndTrainingResponse); //follows OP_GMTraining OUTz(OP_LootComplete); //follows OP_LootItem OUTz(OP_WorldObjectsSent); OUTz(OP_FinishWindow); OUTz(OP_FinishWindow2); //OUTz(OP_TradeSkillCombine); //OUTv(OP_AdventureDetails, strlen(AF.text)+1); //OUTv(OP_AdventureInfo, strlen(buffer1)+1); //OUTv(OP_AdventureInfo, strlen(p)+1); //OUTv(OP_AdventureMerchantResponse, strlen(msg)+2); OUTv(OP_ItemPacket, ItemPacket_Struct); OUTv(OP_ColoredText, ColoredText_Struct); OUTv(OP_ItemRecastDelay, ItemRecastDelay_Struct); OUTv(OP_FormattedMessage, FormattedMessage_Struct); OUTv(OP_GuildMemberList, uint32); //variable length, but nasty OUTv(OP_InterruptCast, InterruptCast_Struct); OUTv(OP_ItemLinkResponse, ItemPacket_Struct); OUTv(OP_ZoneSpawns, Spawn_Struct); OUTv(OP_CompletedTasks, TaskHistory_Struct); OUTv(OP_CharInventory, ItemPacket_Struct); OUTv(OP_CustomTitles, Titles_Struct); OUTv(OP_SpawnDoor, Door_Struct); OUTv(OP_SendZonepoints, ZonePoints); OUTv(OP_TributeInfo, TributeAbility_Struct); OUTv(OP_GuildTributeInfo, GuildTributeAbility_Struct); OUTv(OP_SendTitleList, TitleList_Struct); //these arnt used anymore //OUTv(OP_ItemLinkText, strlen(itemlink)+14+strlen(charname)); //OUTv(OP_ItemLinkText, strlen(name2)+68); OUT(OP_SendMaxCharacters, MaxCharacters_Struct); OUT(OP_AAExpUpdate, AAExpUpdate_Struct); OUT(OP_Action, Action_Struct); OUT(OP_AdventureData, AdventureRequestResponse_Struct); OUT(OP_AdventureFinish, AdventureFinish_Struct); OUT(OP_AdventurePointsUpdate, AdventurePoints_Update_Struct); OUT(OP_Animation, Animation_Struct); OUT(OP_AnnoyingZoneUnknown, AnnoyingZoneUnknown_Struct); OUT(OP_BankerChange, BankerChange_Struct); OUT(OP_BecomeTrader, BecomeTrader_Struct); OUT(OP_BeginCast, BeginCast_Struct); OUT(OP_Charm, Charm_Struct); OUT(OP_CameraEffect, Camera_Struct); OUT(OP_ClickObjectAction, ClickObjectAction_Struct); OUT(OP_ConsentResponse, ConsentResponse_Struct); //OUT(OP_ConsumeAmmo, MoveItem_Struct); OUT(OP_EnduranceUpdate, EnduranceUpdate_Struct); OUT(OP_ExpUpdate, ExpUpdate_Struct); OUT(OP_GroundSpawn, Object_Struct); OUT(OP_GroupUpdate, GroupJoin_Struct); //takes on 3 sizes... //alt:OUT(OP_GroupUpdate, GroupUpdate2_Struct); //alt:OUT(OP_GroupUpdate, GroupUpdate_Struct); OUT(OP_GuildMOTD, GuildMOTD_Struct); OUT(OP_GuildManageAdd, GuildJoin_Struct); OUT(OP_GuildManageRemove, GuildManageRemove_Struct); OUT(OP_GuildManageStatus, GuildManageStatus_Struct); OUT(OP_GuildMemberUpdate, GuildMemberUpdate_Struct); OUT(OP_HPUpdate, SpawnHPUpdate_Struct); OUT(OP_IncreaseStats, IncreaseStat_Struct); OUT(OP_ItemVerifyReply, ItemVerifyReply_Struct); OUT(OP_LFGAppearance, LFG_Appearance_Struct); OUT(OP_LeadershipExpUpdate, LeadershipExpUpdate_Struct); OUT(OP_LevelAppearance, LevelAppearance_Struct); OUT(OP_LevelUpdate, LevelUpdate_Struct); OUT(OP_ManaUpdate, ManaUpdate_Struct); OUT(OP_MobEnduranceUpdate, MobEnduranceUpdate_Struct); OUT(OP_MobHealth, MobHealth_Struct); OUT(OP_MobManaUpdate, MobManaUpdate_Struct); OUT(OP_MobRename, MobRename_Struct); OUT(OP_MoneyOnCorpse, moneyOnCorpseStruct); //follows OP_LootRequest OUT(OP_MoneyUpdate, MoneyUpdate_Struct); OUT(OP_MoveDoor, MoveDoor_Struct); OUT(OP_NewSpawn, NewSpawn_Struct); OUT(OP_NewZone, NewZone_Struct); OUT(OP_PetitionCheckout, Petition_Struct); OUT(OP_PetitionUpdate, PetitionUpdate_Struct); OUT(OP_PlayerProfile, PlayerProfile_Struct); OUT(OP_RaidUpdate, ZoneInSendName_Struct); //alt:OUTv(OP_RaidUpdate, RaidMembers_Struct); OUT(OP_RandomReply, RandomReply_Struct); OUT(OP_RecipeReply, RecipeReply_Struct); OUT(OP_RequestClientZoneChange, RequestClientZoneChange_Struct); OUT(OP_RespondAA, AATable_Struct); OUT(OP_RezzRequest, Resurrect_Struct); OUT(OP_SetTitleReply, SetTitleReply_Struct); OUT(OP_ShopDelItem, Merchant_DelItem_Struct); OUT(OP_SimpleMessage, SimpleMessage_Struct); OUT(OP_SkillUpdate, SkillUpdate_Struct); OUT(OP_SomeItemPacketMaybe, Arrow_Struct); OUT(OP_SpellEffect, SpellEffect_Struct); OUT(OP_Stamina, Stamina_Struct); OUT(OP_Stun, Stun_Struct); OUT(OP_TargetReject, TargetReject_Struct); OUT(OP_TimeOfDay, TimeOfDay_Struct); OUT(OP_Track, Track_Struct); OUT(OP_TradeCoins, TradeCoin_Struct); OUT(OP_TradeMoneyUpdate, TradeMoneyUpdate_Struct); OUT(OP_TraderDelItem, TraderDelItem_Struct); OUT(OP_TraderItemUpdate, TraderItemUpdate_Struct); OUT(OP_TributeTimer, uint32); OUT(OP_UpdateLeadershipAA, UpdateLeadershipAA_Struct); OUT(OP_Weather, Weather_Struct); OUT(OP_ZoneChange, ZoneChange_Struct); OUT(OP_ZoneInUnknown, ZoneInUnknown_Struct); //this is the set of opcodes which are already listed //in the IN section above, but are also sent OUT #ifdef DISJOINT_DIRECTIONS OUTz(OP_ClientReady); //follows OP_SetServerFilter OUTz(OP_Dye); OUTz(OP_GMKick); OUTz(OP_SendAAStats); //follows OP_ReqNewZone OUTz(OP_SendExpZonein); //follows OP_SendZonepoints OUTv(OP_ReadBook, BookText_Struct); OUTv(OP_SendAATable, SendAA_Struct); OUT(OP_AAAction, UseAA_Struct); OUT(OP_Bazaar, BazaarReturnDone_Struct); //alt:OUT(OP_Bazaar, BazaarWelcome_Struct); OUT(OP_Buff, SpellBuffFade_Struct); OUT(OP_ClickObject, ClickObject_Struct); OUT(OP_ClientUpdate, PlayerPositionUpdateServer_Struct); OUT(OP_SpawnPositionUpdate, SpawnPositionUpdate_Struct); OUT(OP_Consider, Consider_Struct); OUT(OP_Damage, CombatDamage_Struct); OUT(OP_Death, Death_Struct); OUT(OP_DeleteSpawn, EntityId_Struct); OUT(OP_DeleteSpell, DeleteSpell_Struct); OUT(OP_EmoteAnim, EmoteAnim_Struct); OUT(OP_GMFind, GMSummon_Struct); OUT(OP_GMKick, GMKick_Struct); OUT(OP_GMKill, GMKill_Struct); OUT(OP_GMLastName, GMLastName_Struct); OUT(OP_GMNameChange, GMName_Struct); OUT(OP_GMSummon, GMSummon_Struct); OUT(OP_GMZoneRequest, GMZoneRequest_Struct); OUT(OP_Illusion, Illusion_Struct); OUT(OP_ItemName, ItemNamePacket_Struct); OUT(OP_ManaChange, ManaChange_Struct); //alt:OUTz(OP_ManaChange); //takes on at least two lengths OUT(OP_MemorizeSpell, MemorizeSpell_Struct); OUT(OP_MoveItem, MoveItem_Struct); OUT(OP_PickPocket, sPickPocket_Struct); OUT(OP_RecipeAutoCombine, RecipeAutoCombine_Struct); OUT(OP_RequestDuel, Duel_Struct); OUT(OP_ShopPlayerBuy, Merchant_Sell_Struct); OUT(OP_ShopPlayerSell, Merchant_Purchase_Struct); OUT(OP_ShopRequest, Merchant_Click_Struct); OUT(OP_SpawnAppearance, SpawnAppearance_Struct); OUT(OP_TradeRequestAck, TradeRequest_Struct); OUT(OP_Trader, TraderBuy_Struct); //3 possible lengths //alt:OUT(OP_Trader, Trader_ShowItems_Struct); //alt:OUT(OP_Trader, Trader_Struct); OUT(OP_TraderBuy, TraderBuy_Struct); OUTv(OP_TraderShop, TraderClick_Struct); OUT(OP_WearChange, WearChange_Struct); OUT(OP_ZoneEntry, ServerZoneEntry_Struct); #endif /* //... client_packet.h #define IN_C(op, s) \ void Handle_Connect_##op (s *in); #define IN_Cv(op, s) \ void Handle_Connect_##op (s *in, uint32 length); #define IN_Cz(op) \ void Handle_Connect_##op (); #define IN_Cr(op) \ void Handle_Connect_##op (const EQApplicationPacket *app); #define IN(op, s) \ void Handle_##op (s *in); #define INv(op, s) \ void Handle_##op (s *in, uint32 length); #define INz(op) \ void Handle_##op (); #define INr(op) \ void Handle_##op (const EQApplicationPacket *app); #define OUT_C(op, s) #define OUT_Cv(op, s) #define OUT_Cz(op) #define OUT_Cr(op) #define OUT(op, s) #define OUTv(op, s) #define OUTz(op) #define OUTr(op) #include "opcode_dispatch.h" #undef IN_C #undef IN_Cr #undef IN_Cv #undef IN_Cz #undef IN #undef INr #undef INv #undef INz #undef OUT_C #undef OUT_Cr #undef OUT_Cv #undef OUT_Cz #undef OUT #undef OUTr #undef OUTv #undef OUTz class OpcodeDispatcher { public: virtual void dispatch(Client *on, const EQApplicationPacket *app) = 0; }; class RawOpcodeDispatcher : public OpcodeDispatcher { public: typedef void (Client::*proc)(const EQApplicationPacket *app); RawOpcodeDispatcher(proc p) { d = p; } virtual void dispatch(Client *on, const EQApplicationPacket *app) { (on->*d)(app); } protected: proc d; }; class ZeroOpcodeDispatcher : public OpcodeDispatcher { public: typedef void (Client::*proc)(); ZeroOpcodeDispatcher(proc p) { d = p; } virtual void dispatch(Client *on, const EQApplicationPacket *app) { if(app->size != 0) { //error.. return; } (on->*d)(); } protected: proc d; }; template class TypedOpcodeDispatcher : public OpcodeDispatcher { public: typedef void (Client::*proc)(T *packet); TypedOpcodeDispatcher(proc p, const char *sn) { d = p; struct_name = sn; } virtual void dispatch(Client *on, const EQApplicationPacket *app) { if(app->size != sizeof(T)) { //error.. return; } T * tmp = (T *) app->pBuffer; (on->*d)(tmp); } protected: proc d; const char *struct_name; }; template class TypedVarOpcodeDispatcher : public OpcodeDispatcher { public: typedef void (Client::*proc)(T *packet, uint32 length); TypedVarOpcodeDispatcher(proc p, const char *sn) { d = p; struct_name = sn; } virtual void dispatch(Client *on, const EQApplicationPacket *app) { if(app->size < sizeof(T)) { //error.. return; } T * tmp = (T *) app->pBuffer; (on->*d)(tmp, app->size); } protected: proc d; const char *struct_name; }; //... client_packet.cpp void MapOpcodes() { //.. #define IN_C(op, s) \ ConnectingOpcodes[op] = new TypedOpcodeDispatcher(&Client::Handle_Connect_##op , #s); #define IN_Cv(op, s) \ ConnectingOpcodes[op] = new TypedVarOpcodeDispatcher(&Client::Handle_Connect_##op , #s); #define IN_Cz(op) \ ConnectingOpcodes[op] = new ZeroOpcodeDispatcher(&Client::Handle_Connect_##op); #define IN_Cr(op) \ ConnectingOpcodes[op] = new RawOpcodeDispatcher(&Client::Handle_Connect_##op); #define IN(op, s) \ ConnectedOpcodes[op] = new TypedOpcodeDispatcher(&Client::Handle_##op , #s); #define INv(op, s) \ ConnectedOpcodes[op] = new TypedVarOpcodeDispatcher(&Client::Handle_##op , #s); #define INz(op) \ ConnectedOpcodes[op] = new ZeroOpcodeDispatcher(&Client::Handle_##op); #define INr(op) \ ConnectedOpcodes[op] = new RawOpcodeDispatcher(&Client::Handle_##op); #define OUT_C(op, s) #define OUT_Cv(op, s) #define OUT_Cz(op) #define OUT_Cr(op) #define OUT(op, s) #define OUTv(op, s) #define OUTz(op) #define OUTr(op) #include "opcode_dispatch.h" #undef IN_C #undef IN_Cr #undef IN_Cv #undef IN_Cz #undef IN #undef INr #undef INv #undef INz #undef OUT_C #undef OUT_Cr #undef OUT_Cv #undef OUT_Cz #undef OUT #undef OUTr #undef OUTv #undef OUTz */