From 74bb1a8a42b1c0b18a5e92324e07cc57915d1000 Mon Sep 17 00:00:00 2001 From: "False.Genesis" Date: Tue, 13 Nov 2007 20:44:55 +0000 Subject: [PATCH] * added possibility to hook scripts to incoming opcodes * fixed a few bugs with script hooks (scripts must be uppercased!!) * added script funcs: GetOpcodeName, GetOpcodeID * fixed possible crash at const char *GetOpcodeName() * added script SendWhoForPlayer until CMSG_WHO correctly implemented into core --- bin/scripts/__core_func.def | 14 ++--- bin/scripts/opcode_who_forplayer.def | 22 +++++++ src/Client/DefScriptInterface.cpp | 12 ++++ src/Client/DefScriptInterfaceInclude.h | 2 + src/Client/World/Opcodes.cpp | 19 ++++++- src/Client/World/Opcodes.h | 1 + src/Client/World/WorldSession.cpp | 79 +++++++++++++++----------- 7 files changed, 107 insertions(+), 42 deletions(-) create mode 100644 bin/scripts/opcode_who_forplayer.def diff --git a/bin/scripts/__core_func.def b/bin/scripts/__core_func.def index fe596b4..b49f94c 100644 --- a/bin/scripts/__core_func.def +++ b/bin/scripts/__core_func.def @@ -142,14 +142,14 @@ return ${outstr} // purpose: append a line of code to a script // args: @0: script name; @def: code // be sure that the code you append is valid and working DefScript code! (no if/loop block mismatches, etc) -// if you need to use { or }, escape them: "appenddef,myscript log Myscript: finished, @def=$\{@def\}" -if ?{and,{?{strlen ${@def}}} ?{strlen ${@0}}} - if ?{not ?{ScriptExists ${@0}}} - createdef ${@0} - logdebug AppendDef: ${@0} didnt exist, created +// if you need to use { or }, escape them: "appenddef,myscript log Myscript: finished, @def=$\{@def\}" +set,sc ?{lowercase ${@0}} +if ?{and,{?{strlen ${@def}}} ?{strlen ${sc}}} + if ?{not ?{ScriptExists ${sc}}} + createdef ${sc} endif - lpushback,{#DEFSCRIPT::SCRIPT::${@0}} ${@def} + lpushback,{#DEFSCRIPT::SCRIPT::${sc}} ${@def} unset cmd endif @@ -161,5 +161,5 @@ endif // @0: script name // @def: line of text to look for -return ?{lcontains,{#DEFSCRIPT::SCRIPT::${@0}} ${@def}} +return ?{lcontains,{#DEFSCRIPT::SCRIPT::?{lowercase ${@0}}} ${@def}} diff --git a/bin/scripts/opcode_who_forplayer.def b/bin/scripts/opcode_who_forplayer.def new file mode 100644 index 0000000..97fc608 --- /dev/null +++ b/bin/scripts/opcode_who_forplayer.def @@ -0,0 +1,22 @@ +// temporary wrapper for requesting info about a certain player until implemented into the core +#script=SendWhoForPlayer + +// minlvl 0 +bbappend,pkt,uint32 0 +// maxlvl 100 +bbappend,pkt,uint32 100 +// player name, case-sensitive string +bbappend,pkt,string ${@def} +// no guild, empty string +bbappend,pkt,string +// racemask - all races +bbappend,pkt,uint32 0xFFFFFFFF +// classmask - all classes +bbappend,pkt,uint32 0xFFFFFFFF +// 0 zones to check +bbappend,pkt,uint32 0 +// 0 additional strings +bbappend,pkt,uint32 0 + +SendWorldPacket,{?{GetOpcodeID CMSG_WHO}} pkt +bbdelete pkt \ No newline at end of file diff --git a/src/Client/DefScriptInterface.cpp b/src/Client/DefScriptInterface.cpp index 967ddad..6e4dd4f 100644 --- a/src/Client/DefScriptInterface.cpp +++ b/src/Client/DefScriptInterface.cpp @@ -51,6 +51,8 @@ void DefScriptPackage::_InitDefScriptInterface(void) AddFunc("getrace",&DefScriptPackage::SCGetRace); AddFunc("getclass",&DefScriptPackage::SCGetClass); AddFunc("sendworldpacket",&DefScriptPackage::SCSendWorldPacket); + AddFunc("getopcodename",&DefScriptPackage::SCGetOpcodeName); + AddFunc("getopcodeid",&DefScriptPackage::SCGetOpcodeID); } DefReturnResult DefScriptPackage::SCshdn(CmdSet& Set) @@ -886,6 +888,16 @@ DefReturnResult DefScriptPackage::SCSendWorldPacket(CmdSet &Set) return false; } +DefReturnResult DefScriptPackage::SCGetOpcodeID(CmdSet &Set) +{ + uint32 id = GetOpcodeID(Set.defaultarg.c_str()); + return id != (uint32)(-1) ? toString(id) : ""; +} + +DefReturnResult DefScriptPackage::SCGetOpcodeName(CmdSet &Set) +{ + return GetOpcodeName((uint32)DefScriptTools::toUint64(Set.defaultarg)); +} diff --git a/src/Client/DefScriptInterfaceInclude.h b/src/Client/DefScriptInterfaceInclude.h index c01aa6e..c03e81a 100644 --- a/src/Client/DefScriptInterfaceInclude.h +++ b/src/Client/DefScriptInterfaceInclude.h @@ -42,5 +42,7 @@ DefReturnResult SCGetObjectValue(CmdSet&); DefReturnResult SCGetRace(CmdSet&); DefReturnResult SCGetClass(CmdSet&); DefReturnResult SCSendWorldPacket(CmdSet&); +DefReturnResult SCGetOpcodeName(CmdSet&); +DefReturnResult SCGetOpcodeID(CmdSet&); #endif \ No newline at end of file diff --git a/src/Client/World/Opcodes.cpp b/src/Client/World/Opcodes.cpp index afdacea..2c6a4cc 100644 --- a/src/Client/World/Opcodes.cpp +++ b/src/Client/World/Opcodes.cpp @@ -19,7 +19,7 @@ /** \file \ingroup u2w */ - +#include "common.h" #include "Opcodes.h" @@ -986,11 +986,24 @@ const char* worldOpcodeNames[] = "UNKNOWN953", // 953 "SMSG_UNKNOWN_954", // 954 "SMSG_UNKNOWN_955", // 955 - //there would be declared new opcode, id 956 - //do not forget to change MAX_OPCODE_ID, if you add a line here! + "" // last entry should be empty }; const char *GetOpcodeName(unsigned int id) { + if(id > MAX_OPCODE_ID) + return ""; return worldOpcodeNames[id]; } + +const unsigned int GetOpcodeID(const char *name) +{ + for(unsigned int i=0; strlen(worldOpcodeNames[i]); i++) + { + if(!stricmp(worldOpcodeNames[i], name)) + { + return i; + } + } + return -1; // invalid name +} diff --git a/src/Client/World/Opcodes.h b/src/Client/World/Opcodes.h index 1f514c4..3fffa39 100644 --- a/src/Client/World/Opcodes.h +++ b/src/Client/World/Opcodes.h @@ -24,6 +24,7 @@ #define _OPCODES_H const char *GetOpcodeName(unsigned int); +const unsigned int GetOpcodeID(const char *); /// List of OpCodes enum OpCodes diff --git a/src/Client/World/WorldSession.cpp b/src/Client/World/WorldSession.cpp index d707c4b..b4e982e 100644 --- a/src/Client/World/WorldSession.cpp +++ b/src/Client/World/WorldSession.cpp @@ -113,56 +113,71 @@ void WorldSession::Update(void) } } + DefScriptPackage *sc = GetInstance()->GetScripts(); OpcodeHandler *table = _GetOpcodeHandlerTable(); uint16 hpos; bool known=false; - while(pktQueue.size()) + + while(pktQueue.size()) + { + WorldPacket *packet = pktQueue.next(); + + for (hpos = 0; table[hpos].handler != NULL; hpos++) { - WorldPacket *packet = pktQueue.next(); + if (table[hpos].opcode == packet->GetOpcode()) + { + known=true; + break; + } + } - for (hpos = 0; table[hpos].handler != NULL; hpos++) - { - if (table[hpos].opcode == packet->GetOpcode()) - { - known=true; - break; - } - } + bool hideOpcode = false; - bool hideOpcode = false; + // TODO: Maybe make table or something with all the frequently opcodes + if (packet->GetOpcode() == SMSG_MONSTER_MOVE) + { + hideOpcode = true; + } - // TODO: Maybe make table or something with all the frequently opcodes - if (packet->GetOpcode() == SMSG_MONSTER_MOVE) - { - hideOpcode = true; - } - - if( (known && GetInstance()->GetConf()->showopcodes==1) - || ((!known) && GetInstance()->GetConf()->showopcodes==2) - || (GetInstance()->GetConf()->showopcodes==3) ) - { + if( (known && GetInstance()->GetConf()->showopcodes==1) + || ((!known) && GetInstance()->GetConf()->showopcodes==2) + || (GetInstance()->GetConf()->showopcodes==3) ) + { if(!(GetInstance()->GetConf()->hidefreqopcodes && hideOpcode)) - logcustom(1,YELLOW,">> Opcode %u [%s] (%s, %u bytes)", packet->GetOpcode(), GetOpcodeName(packet->GetOpcode()), known ? "Known" : "UNKNOWN", packet->size()); - } + logcustom(1,YELLOW,">> Opcode %u [%s] (%s, %u bytes)", packet->GetOpcode(), GetOpcodeName(packet->GetOpcode()), known ? "Known" : "UNKNOWN", packet->size()); + } - if(known) + try { - try - { + // call the opcode handler + if(known) (this->*table[hpos].handler)(*packet); - } - catch (...) + + // if there is a script attached to that opcode, call it now. + // note: the pkt rpos needs to be reset in by the scripts! + std::string scname = "opcode::"; + scname += stringToLower(GetOpcodeName(packet->GetOpcode())); + if(sc->ScriptExists(scname)) { - logerror("Exception while handling opcode %u!",packet->GetOpcode()); - logerror("Data: pktsize=%u, handler=0x%X queuesize=%u",packet->size(),table[hpos].handler,pktQueue.size()); + std::string pktname = "PACKET::"; + pktname += GetOpcodeName(packet->GetOpcode()); + GetInstance()->GetScripts()->bytebuffers.Assign(pktname,packet); + sc->RunScript(scname,NULL); + GetInstance()->GetScripts()->bytebuffers.Unlink(pktname); } + + } + catch (...) + { + logerror("Exception while handling opcode %u!",packet->GetOpcode()); + logerror("Data: pktsize=%u, handler=0x%X queuesize=%u",packet->size(),table[hpos].handler,pktQueue.size()); } - delete packet; + delete packet; known=false; - } + } _DoTimedActions();