* fixed possible crash in defscript when an if block was appened to a script during runtime and this if was not endif'd

* more toNumber() -> toUint64() changes for number consistency
* fixed MyCharacter naming on char char list recv
* added script to list own/near player's inventory, for debugging. copy it into main scripts dir if you want to use it.
* inlined 2 funcs in DefScript
* changed args of script event "_onobjectdelete". @0 is now typeid, @1 out of range.
This commit is contained in:
false_genesis 2008-02-21 20:24:38 +00:00
parent 4dce611346
commit 4405563a6b
9 changed files with 191 additions and 75 deletions

View File

@ -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.

View File

@ -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

View File

@ -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++;

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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<num;i++){
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++)
for(unsigned int i=0;i<num;i++)
{
recvPacket >> 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!!