diff --git a/bin/scripts/__core_eventstubs.def b/bin/scripts/__core_eventstubs.def index 109fa57..3f34d44 100644 --- a/bin/scripts/__core_eventstubs.def +++ b/bin/scripts/__core_eventstubs.def @@ -50,7 +50,8 @@ endif #script=_onobjectdelete // @def: GUID of deleted object -// @0: [out of range object deletion=true, else false] +// @0: TypeID of deleted object +// @1: [out of range object deletion=true, else false] // The object can be accessed with the object handling functions listed above. // It will be deleted right after handling this script. diff --git a/bin/scripts/optional/item_debugger.def b/bin/scripts/optional/item_debugger.def new file mode 100644 index 0000000..768caf6 --- /dev/null +++ b/bin/scripts/optional/item_debugger.def @@ -0,0 +1,113 @@ +// Item/Inventory debugger +// Using Player/Item fields +// Works for 2.3.x +// Usage: As soon as this file is loaded, the debugger will be attached automatically (put this file in /scripts/ directory) +// Known problems: If player/item names are not yet known, this script will display empty names. At second time everything will be fine. + +#script=itemdebugger_loader +#onload +if ?{not ?{ishooked _onobjectcreate}} + hookstart _onobjectcreate +#escape-all=1 + hookadd if ?{equal,4 ${@0}} // MaNGOS creates the player object after all items are created, so just need to check for that and read everything out of the player fields + hookadd playeritemdebugger ${@def} + hookadd endif +#escape-all=0 + hookend +endif +if ?{not ?{ishooked _onobjectdelete}} + hookstart _onobjectdelete +#escape-all=1 + hookadd if ?{or,?{equal,1 ${@0}} ?{equal,2 ${@0}}} + hookadd itemdebugger_del ${@def} + hookadd endif +#escape-all=0 + hookend +endif +#/onload +logdetail Item debugger attached + + + +#script=playeritemdebugger +// @def: player guid + +set,pguid ${@def} +set,pname ?{getname,guid ${pguid}} + +// between these fields all item guids are stored (check UpdateFields.h) +set,fstart 0x26E // PLAYER_FIELD_INV_SLOT_HEAD +set,fend 0x35A // PLAYER_FIELD_KEYRING_SLOT_1 + 64 + +set,f ${fstart} +set,slot 0 +loop + if ?{bigger_eq,${f} ${fend}} + exitloop + endif + set,iguid ?{getobjectvalue,${f},i64 ${pguid}} + if ${iguid} + //-- show info about item + itemdebugger,{Player '${pname}' Slot ${slot} (field ${f}): } ${iguid} + + //-- Iterate over bags -- + if ?{equal,2 ?{getobjecttype ${iguid}}} + bagitemdebugger ${iguid} + endif + endif + + add,f 2 + add,slot 1 +endloop + + +#script=bagitemdebugger +set,bagslots ?{getobjectvalue,60 ${@def}} // CONTAINER_FIELD_NUM_SLOTS +set,j 0 +loop + set,t ${j} + mul,t 2 + if ?{bigger,${t} ${bagslots}} // max. bag size = 36 slots + exitloop + endif + set,field 62 // CONTAINER_FIELD_SLOT_1 - 36 + add,field ${t} + set,itemguid ?{getobjectvalue,${field},i64 ${@def}} + itemdebugger,{Bag slot ${j} (field: ${field}) -> } ${itemguid} + + add,j 1 +endloop + + +#script=itemdebugger +// @def: item guid +// @0: text prefix +set,itemguid ${@def} +if ?{not ?{objectknown ${itemguid}}} + return +endif + +if ${itemguid} + set,itemname ?{getname,guid ${itemguid}} + set,itementry ?{getentry ${itemguid}} + log ${@0}Item: '${itemname}' (${itementry}) [${itemguid}] +endif + + +#script=itemdebugger_del +// @def: item guid + +set,itemguid ${@def} +//if ?{not ?{objectknown ${itemguid}}} +// return +//endif + +if ${itemguid} + set,itemname ?{getname,guid ${itemguid}} + set,itementry ?{getentry ${itemguid}} + set,owner ?{getobjectvalue,6,i64 ${itemguid}} + set,ownername ?{getname,guid ${owner}} + + log Delete Item: '${itemname}' (${itementry}) (${ownername}) [${itemguid}] +endif + diff --git a/src/Client/DefScript/DefScript.cpp b/src/Client/DefScript/DefScript.cpp index fd855eb..827cd5f 100644 --- a/src/Client/DefScript/DefScript.cpp +++ b/src/Client/DefScript/DefScript.cpp @@ -531,16 +531,6 @@ std::string DefScript::GetName(void) return scriptname; } -unsigned int DefScript::GetLines(void) -{ - return Line.size(); -} - -std::string DefScript::GetLine(unsigned int id) -{ - return Line[id]; -} - bool DefScript::AddLine(std::string l){ if(l.empty()) return false; @@ -703,7 +693,7 @@ DefReturnResult DefScriptPackage::RunScript(std::string name, CmdSet *pSet,std:: if(!b.istrue) { unsigned int other_ifs=0; - for(i=b.startline+1;;i++) + for(i=b.startline+1; i < sc->GetLines() ;i++) { if(!memcmp(sc->GetLine(i).c_str(),"if ",3)) other_ifs++; diff --git a/src/Client/DefScript/DefScript.h b/src/Client/DefScript/DefScript.h index 03ad3ac..86179f0 100644 --- a/src/Client/DefScript/DefScript.h +++ b/src/Client/DefScript/DefScript.h @@ -84,8 +84,9 @@ class DefScript { public: DefScript(DefScriptPackage *p); ~DefScript(); - std::string GetLine(unsigned int); - unsigned int GetLines(void); + + inline std::string GetLine(unsigned int id) { return Line[id]; } + inline unsigned int DefScript::GetLines(void) { return Line.size(); } bool AddLine(std::string ); std::string GetName(void); void SetName(std::string); diff --git a/src/Client/DefScript/DefScriptFunctions.cpp b/src/Client/DefScript/DefScriptFunctions.cpp index 28c038c..cfee77e 100644 --- a/src/Client/DefScript/DefScriptFunctions.cpp +++ b/src/Client/DefScript/DefScriptFunctions.cpp @@ -180,7 +180,7 @@ DefReturnResult DefScriptPackage::func_setscriptpermission(CmdSet& Set) DefReturnResult DefScriptPackage::func_toint(CmdSet& Set) { DefReturnResult r; - std::string num=toString(floor(toNumber(Set.defaultarg))); + std::string num=toString(toUint64(Set.defaultarg)); if(!Set.arg[0].empty()) { std::string vname=_NormalizeVarName(Set.arg[0], Set.myname); diff --git a/src/Client/DefScriptInterface.cpp b/src/Client/DefScriptInterface.cpp index 1c3f390..30e6b5b 100644 --- a/src/Client/DefScriptInterface.cpp +++ b/src/Client/DefScriptInterface.cpp @@ -381,7 +381,7 @@ DefReturnResult DefScriptPackage::SCScpSectionExists(CmdSet& Set) dbname=Set.arg[0]; return (!Set.defaultarg.empty()) && (!dbname.empty()) && ((PseuInstance*)parentMethod)->dbmgr.HasDB(dbname) - && ((PseuInstance*)parentMethod)->dbmgr.GetDB(dbname).HasField((uint32)DefScriptTools::toNumber(Set.defaultarg)); + && ((PseuInstance*)parentMethod)->dbmgr.GetDB(dbname).HasField((uint32)DefScriptTools::toUint64(Set.defaultarg)); } DefReturnResult DefScriptPackage::SCScpEntryExists(CmdSet& Set) @@ -391,7 +391,7 @@ DefReturnResult DefScriptPackage::SCScpEntryExists(CmdSet& Set) if(!Set.arg[0].empty()) dbname=Set.arg[0]; if(!Set.arg[1].empty()) - keyid=(uint32)DefScriptTools::toNumber(Set.arg[1]); + keyid=(uint32)DefScriptTools::toUint64(Set.arg[1]); return (!Set.defaultarg.empty()) && (!dbname.empty()) && ((PseuInstance*)parentMethod)->dbmgr.HasDB(dbname) && ((PseuInstance*)parentMethod)->dbmgr.GetDB(dbname).HasField(keyid) @@ -411,7 +411,7 @@ DefReturnResult DefScriptPackage::SCGetScpValue(CmdSet& Set) if(!Set.arg[0].empty()) dbname=Set.arg[0]; if(!Set.arg[1].empty()) - keyid=(uint32)DefScriptTools::toNumber(Set.arg[1]); + keyid=(uint32)DefScriptTools::toUint64(Set.arg[1]); if(!Set.defaultarg.empty()) entry=Set.defaultarg; if( (!entry.empty()) && (!dbname.empty()) @@ -555,7 +555,7 @@ DefReturnResult DefScriptPackage::SCObjectKnown(CmdSet& Set) logerror("Invalid Script call: SCObjectIsKnown: WorldSession not valid"); DEF_RETURN_ERROR; } - uint64 guid=DefScriptTools::toNumber(Set.defaultarg); + uint64 guid=DefScriptTools::toUint64(Set.defaultarg); Object *o=((PseuInstance*)parentMethod)->GetWSession()->objmgr.GetObj(guid); return o!=NULL; } @@ -590,7 +590,7 @@ DefReturnResult DefScriptPackage::SCGetItemProtoValue(CmdSet& Set) DEF_RETURN_ERROR; } DefReturnResult r; - uint32 entry=DefScriptTools::toNumber(Set.arg[0]); + uint32 entry=DefScriptTools::toUint64(Set.arg[0]); ItemProto *proto=((PseuInstance*)parentMethod)->GetWSession()->objmgr.GetItemProto(entry); if(proto) { @@ -880,7 +880,7 @@ DefReturnResult DefScriptPackage::SCGetRace(CmdSet &Set) DEF_RETURN_ERROR; } - uint64 guid = DefScriptTools::toNumber(Set.defaultarg); + uint64 guid = DefScriptTools::toUint64(Set.defaultarg); Object *o = ws->objmgr.GetObj(guid); if(o && (o->GetTypeId() == TYPEID_UNIT || o->GetTypeId() == TYPEID_PLAYER)) { @@ -898,7 +898,7 @@ DefReturnResult DefScriptPackage::SCGetClass(CmdSet &Set) DEF_RETURN_ERROR; } - uint64 guid = DefScriptTools::toNumber(Set.defaultarg); + uint64 guid = DefScriptTools::toUint64(Set.defaultarg); Object *o = ws->objmgr.GetObj(guid); if(o && (o->GetTypeId() == TYPEID_UNIT || o->GetTypeId() == TYPEID_PLAYER)) { @@ -1153,7 +1153,7 @@ DefReturnResult DefScriptPackage::SCSpoofWorldPacket(CmdSet &Set) ByteBuffer *bb = bytebuffers.GetNoCreate(_NormalizeVarName(Set.defaultarg,Set.myname)); if(bb) { - uint32 opcode = (uint32)DefScriptTools::toNumber(Set.arg[0]); + uint32 opcode = (uint32)DefScriptTools::toUint64(Set.arg[0]); if(opcode) // ok, here again CMSG_NULL_ACTION doesnt work, but who cares { WorldPacket *wp = new WorldPacket(opcode, bb->size()); // will be deleted by the opcode handler later diff --git a/src/Client/World/Object.cpp b/src/Client/World/Object.cpp index 55d0c30..2418d94 100644 --- a/src/Client/World/Object.cpp +++ b/src/Client/World/Object.cpp @@ -114,9 +114,11 @@ void WorldSession::_HandleDestroyObjectOpcode(WorldPacket& recvPacket) // call script just before object removal if(GetInstance()->GetScripts()->ScriptExists("_onobjectdelete")) { + Object *o = objmgr.GetObj(guid); CmdSet Set; Set.defaultarg = toString(guid); - Set.arg[0] = "false"; // out of range = false + Set.arg[0] = o ? toString(o->GetTypeId()) : ""; + Set.arg[1] = "false"; // out of range = false GetInstance()->GetScripts()->RunScript("_onobjectdelete", &Set); } diff --git a/src/Client/World/UpdateData.cpp b/src/Client/World/UpdateData.cpp index 3a0341c..f91df91 100644 --- a/src/Client/World/UpdateData.cpp +++ b/src/Client/World/UpdateData.cpp @@ -185,9 +185,11 @@ void WorldSession::_HandleUpdateObjectOpcode(WorldPacket& recvPacket) // call script just before object removal if(GetInstance()->GetScripts()->ScriptExists("_onobjectdelete")) { + Object *del_obj = objmgr.GetObj(uguid); CmdSet Set; Set.defaultarg = toString(uguid); - Set.arg[0] = "true"; // out of range = true + Set.arg[0] = del_obj ? toString(del_obj->GetTypeId()) : ""; + Set.arg[1] = "true"; // out of range = true GetInstance()->GetScripts()->RunScript("_onobjectdelete", &Set); } diff --git a/src/Client/World/WorldSession.cpp b/src/Client/World/WorldSession.cpp index 686024a..728c39c 100644 --- a/src/Client/World/WorldSession.cpp +++ b/src/Client/World/WorldSession.cpp @@ -446,47 +446,50 @@ void WorldSession::_HandleAuthResponseOpcode(WorldPacket& recvPacket) void WorldSession::_HandleCharEnumOpcode(WorldPacket& recvPacket) { uint8 num; - PlayerEnum plr[10]; // max characters per realm is 10 - uint8 dummy8; + uint8 charId; + PlayerEnum plr[10]; // max characters per realm is 10 + uint8 dummy8; - recvPacket >> num; - if(num==0){ - logerror("No chars found!"); - GetInstance()->SetError(); - return; - } + recvPacket >> num; + if(num==0) + { + logerror("No chars found!"); + GetInstance()->SetError(); + return; + } logdetail("Chars in list: %u\n",num); _LoadCache(); // we are about to login, so we need cache data - for(unsigned int i=0;i> plr[i]._guid; - recvPacket >> plr[i]._name; - recvPacket >> plr[i]._race; - recvPacket >> plr[i]._class; - recvPacket >> plr[i]._gender; - recvPacket >> plr[i]._bytes1; - recvPacket >> plr[i]._bytes2; - recvPacket >> plr[i]._bytes3; - recvPacket >> plr[i]._bytes4; - recvPacket >> plr[i]._bytesx; - recvPacket >> plr[i]._level; - recvPacket >> plr[i]._zoneId; - recvPacket >> plr[i]._mapId; - recvPacket >> plr[i]._x; - recvPacket >> plr[i]._y; - recvPacket >> plr[i]._z; - recvPacket >> plr[i]._guildId; - recvPacket >> dummy8; - recvPacket >> plr[i]._flags; - recvPacket >> dummy8 >> dummy8 >> dummy8; - recvPacket >> plr[i]._petInfoId; - recvPacket >> plr[i]._petLevel; - recvPacket >> plr[i]._petFamilyId; - for(unsigned int inv=0;inv<20;inv++) + for(unsigned int i=0;i> plr[i]._items[inv].displayId >> plr[i]._items[inv].inventorytype; - } - plrNameCache.AddInfo(plr[i]._guid, plr[i]._name); + recvPacket >> plr[i]._guid; + recvPacket >> plr[i]._name; + recvPacket >> plr[i]._race; + recvPacket >> plr[i]._class; + recvPacket >> plr[i]._gender; + recvPacket >> plr[i]._bytes1; + recvPacket >> plr[i]._bytes2; + recvPacket >> plr[i]._bytes3; + recvPacket >> plr[i]._bytes4; + recvPacket >> plr[i]._bytesx; + recvPacket >> plr[i]._level; + recvPacket >> plr[i]._zoneId; + recvPacket >> plr[i]._mapId; + recvPacket >> plr[i]._x; + recvPacket >> plr[i]._y; + recvPacket >> plr[i]._z; + recvPacket >> plr[i]._guildId; + recvPacket >> dummy8; + recvPacket >> plr[i]._flags; + recvPacket >> dummy8 >> dummy8 >> dummy8; + recvPacket >> plr[i]._petInfoId; + recvPacket >> plr[i]._petLevel; + recvPacket >> plr[i]._petFamilyId; + for(unsigned int inv=0;inv<20;inv++) + { + recvPacket >> plr[i]._items[inv].displayId >> plr[i]._items[inv].inventorytype; + } + plrNameCache.AddInfo(plr[i]._guid, plr[i]._name); } bool char_found=false; @@ -499,31 +502,34 @@ void WorldSession::_HandleCharEnumOpcode(WorldPacket& recvPacket) GetDBMgr().GetClassName_(plr[i]._class).c_str(), GetDBMgr().GetMapName(plr[i]._mapId).c_str(), GetDBMgr().GetZoneName(plr[i]._zoneId).c_str()); + logdetail("-> coords: map=%u zone=%u x=%f y=%f z=%f", plr[i]._mapId,plr[i]._zoneId,plr[i]._x,plr[i]._y,plr[i]._z); - for(unsigned int inv=0;inv<20;inv++) - { - if(plr[i]._items[inv].displayId) - logdebug("-> Has Item: Model=%u InventoryType=%u",plr[i]._items[inv].displayId,plr[i]._items[inv].inventorytype); - } - if(plr[i]._name==GetInstance()->GetConf()->charname) - { - char_found=true; - _myGUID=plr[i]._guid; - GetInstance()->GetScripts()->variables.Set("@myguid",toString(plr[i]._guid)); - GetInstance()->GetScripts()->variables.Set("@myrace",toString(plr[i]._race)); - } + + for(unsigned int inv=0;inv<20;inv++) + { + if(plr[i]._items[inv].displayId) + logdebug("-> Has Item: Model=%u InventoryType=%u",plr[i]._items[inv].displayId,plr[i]._items[inv].inventorytype); + } + if(plr[i]._name==GetInstance()->GetConf()->charname) + { + charId = i; + char_found=true; + _myGUID=plr[i]._guid; + GetInstance()->GetScripts()->variables.Set("@myguid",toString(plr[i]._guid)); + GetInstance()->GetScripts()->variables.Set("@myrace",toString(plr[i]._race)); + } } if(!char_found) { - logerror("Character \"%s\" was not found on char list!",GetInstance()->GetConf()->charname.c_str()); + logerror("Character \"%s\" was not found on char list!", plr[charId]._name.c_str()); GetInstance()->SetError(); return; } else { - log("Entering World with Character \"%s\"...",GetInstance()->GetConf()->charname.c_str()); + log("Entering World with Character \"%s\"...", plr[charId]._name.c_str()); // create the character and add it to the objmgr. // note: this is the only object that has to stay in memory unless its explicitly deleted by the server! @@ -531,6 +537,7 @@ void WorldSession::_HandleCharEnumOpcode(WorldPacket& recvPacket) MyCharacter *my = new MyCharacter(); my->Create(_myGUID); objmgr.Add(my); + my->SetName(plr[charId]._name); // TODO: initialize the world here, and load required maps. // must remove appropriate code from _HandleLoginVerifyWorldOpcode() then!!