diff --git a/bin/scripts/uptime.def b/bin/scripts/uptime.def index 26d4891..308e1ae 100644 --- a/bin/scripts/uptime.def +++ b/bin/scripts/uptime.def @@ -4,6 +4,7 @@ // args: none // usage: - load the script to register the uptime counter // - call the script to say the uptime formatted in hours, mins & secs +// returns: uptime formatted as 0h 0m 0s #onload set,#uptime 0 @@ -15,15 +16,23 @@ set,s ${#uptime} set,h ${s} div,h 3600 +toint,h ${h} mod,s 3600 set,m ${s} div,m 60 +toint,m ${m} mod,s 60 +toint,s ${s} +set,str ${h}h ${m}m ${s}s +out UPTIME: ${#uptime} secs = ${str} -out UPTIME: ${#uptime} secs = ${h}h ${m}m ${s}s -say UPTIME: ${h} hours, ${m} minutes, ${s} seconds +if ${@inworld} + say UPTIME: ${h} hours, ${m} minutes, ${s} seconds +endif unset h unset m -unset s \ No newline at end of file +unset s + +return ${str} \ No newline at end of file diff --git a/src/Client/DefScript/DefScript.cpp b/src/Client/DefScript/DefScript.cpp index fa264d3..5f7a4ff 100644 --- a/src/Client/DefScript/DefScript.cpp +++ b/src/Client/DefScript/DefScript.cpp @@ -10,6 +10,12 @@ using namespace DefScriptTools; +enum DefScriptBlockType +{ + BLOCK_IF, + BLOCK_LOOP +}; + // --- SECTION FOR SCRIPT PACKAGES --- DefScriptPackage::DefScriptPackage() { @@ -72,6 +78,9 @@ void DefScriptPackage::_InitFunctions(void) AddFunc("smaller",&DefScriptPackage::func_smaller); AddFunc("strlen",&DefScriptPackage::func_strlen); AddFunc("tohex",&DefScriptPackage::func_tohex); + AddFunc("and",&DefScriptPackage::func_and); + AddFunc("or",&DefScriptPackage::func_or); + AddFunc("xor",&DefScriptPackage::func_xor); } void DefScriptPackage::AddFunc(std::string n,DefReturnResult (DefScriptPackage::*f)(CmdSet& Set)) @@ -339,6 +348,7 @@ DefReturnResult DefScriptPackage::RunScript(std::string name, CmdSet *pSet) { if(!Blocks.size()) { + printf("DEBUG: else-block without any block?! [%s:%u]\n",name.c_str(),i); r.ok=false; break; } @@ -346,26 +356,30 @@ DefReturnResult DefScriptPackage::RunScript(std::string name, CmdSet *pSet) if(b.type==BLOCK_IF && b.istrue) { for(i=b.startline;sc->GetLine(i)!="endif";i++); // skip lines until "endif" - Blocks.pop_back(); - } - if(b.type==BLOCK_IF && !b.istrue) - { - printf("DEBUG: else does not have an if-block that was false before"); + i--; // next line read will be "endif" } continue; } else if(line=="endif") { + if(!Blocks.size()) + { + printf("DEBUG: endif without any block [%s:%u]\n",name.c_str(),i); + r.ok=false; + break; + } if(Blocks.back().type!=BLOCK_IF) { printf("DEBUG: endif: closed block is not an if block! [%s:%u]\n",name.c_str(),i); + r.ok=false; break; } Blocks.pop_back(); continue; } + _DEFSC_DEBUG(printf("DefScript before: \"%s\"\n",line.c_str())); DefXChgResult final=ReplaceVars(line,pSet,0,true); - _DEFSC_DEBUG(printf("DefScript: \"%s\"\n",final.str.c_str())); + _DEFSC_DEBUG(printf("DefScript parsed: \"%s\"\n",final.str.c_str())); SplitLine(mySet,final.str); if(mySet.cmd=="if") { @@ -376,9 +390,9 @@ DefReturnResult DefScriptPackage::RunScript(std::string name, CmdSet *pSet) Blocks.push_back(b); if(!b.istrue) { - for(i=b.startline;sc->GetLine(i)!="else" && sc->GetLine(i)!="endif";i++); // skip lines until "else" - if(sc->GetLine(i)!="endif") - Blocks.pop_back(); + for(i=b.startline;sc->GetLine(i)!="else" && sc->GetLine(i)!="endif";i++); + i--; // next line read will be either "else" or "endif", decide then what to do + } continue; // and read line after "else" } @@ -669,8 +683,7 @@ DefXChgResult DefScriptPackage::ReplaceVars(std::string str, CmdSet *pSet, unsig res=RunSingleLine(str); str=res.ret; // returns empty string on invalid function!! xchg.result.ok=res.ok; - if(res.ok) - xchg.changed=true; + xchg.changed=true; //xchg.result.err += res.err; } else // if not allowed to run scripts via ?{...} diff --git a/src/Client/DefScript/DefScript.h b/src/Client/DefScript/DefScript.h index 6b896b4..0bbd73d 100644 --- a/src/Client/DefScript/DefScript.h +++ b/src/Client/DefScript/DefScript.h @@ -12,12 +12,6 @@ class DefScriptPackage; class DefScript; - -enum DefScriptBlockType -{ - BLOCK_IF, - BLOCK_LOOP -}; // general struct for if..else..endif / loop..endloop blocks struct Def_Block { @@ -175,6 +169,9 @@ private: DefReturnResult func_smaller(CmdSet&); DefReturnResult func_strlen(CmdSet&); DefReturnResult func_tohex(CmdSet&); + DefReturnResult func_and(CmdSet&); + DefReturnResult func_or(CmdSet&); + DefReturnResult func_xor(CmdSet&); // setup own function declarations here # include "DefScriptInterfaceInclude.h" diff --git a/src/Client/DefScript/DefScriptFunctions.cpp b/src/Client/DefScript/DefScriptFunctions.cpp index c14d53a..07a9242 100644 --- a/src/Client/DefScript/DefScriptFunctions.cpp +++ b/src/Client/DefScript/DefScriptFunctions.cpp @@ -241,8 +241,8 @@ DefReturnResult DefScriptPackage::func_mod(CmdSet& Set) } std::string vname=_NormalizeVarName(Set.arg[0], Set.myname); - uint64 a=(uint64)toNumber(variables.Get(vname)); - uint64 b=(uint64)toNumber(Set.defaultarg); + uint64 a=toUint64(variables.Get(vname)); + uint64 b=toUint64(Set.defaultarg); if(b==0) a=0; else @@ -350,12 +350,12 @@ DefReturnResult DefScriptPackage::func_equal(CmdSet& Set) DefReturnResult DefScriptPackage::func_smaller(CmdSet& Set) { - return toNumber(Set.defaultarg) < toNumber(Set.arg[0]); + return toNumber(Set.arg[0]) < toNumber(Set.defaultarg); } DefReturnResult DefScriptPackage::func_bigger(CmdSet& Set) { - return toNumber(Set.defaultarg) > toNumber(Set.arg[0]); + return toNumber(Set.arg[0]) > toNumber(Set.defaultarg); } DefReturnResult DefScriptPackage::func_not(CmdSet& Set) @@ -403,3 +403,19 @@ DefReturnResult DefScriptPackage::func_abs(CmdSet& Set) r.ret=toString(fabs(toNumber(Set.defaultarg))); return r; } + +DefReturnResult DefScriptPackage::func_and(CmdSet& Set) +{ + return isTrue(Set.defaultarg) && isTrue(Set.arg[0]); +} + +DefReturnResult DefScriptPackage::func_or(CmdSet& Set) +{ + return isTrue(Set.defaultarg) || isTrue(Set.arg[0]); +} + +DefReturnResult DefScriptPackage::func_xor(CmdSet& Set) +{ + return (isTrue(Set.defaultarg) && isTrue(Set.arg[0])) || ( (!isTrue(Set.defaultarg)) && (!isTrue(Set.arg[0]) ) ); +} + diff --git a/src/Client/DefScriptInterface.cpp b/src/Client/DefScriptInterface.cpp index 0eae996..25187ff 100644 --- a/src/Client/DefScriptInterface.cpp +++ b/src/Client/DefScriptInterface.cpp @@ -39,6 +39,8 @@ void DefScriptPackage::_InitDefScriptInterface(void) AddFunc("getname",&DefScriptPackage::SCGetName); AddFunc("getentry",&DefScriptPackage::SCGetName); AddFunc("getitemprotovalue",&DefScriptPackage::SCGetName); + AddFunc("getobjecttype",&DefScriptPackage::SCGetObjectType); + AddFunc("objectknown",&DefScriptPackage::SCObjectKnown); } DefReturnResult DefScriptPackage::SCshdn(CmdSet& Set) @@ -215,8 +217,7 @@ DefReturnResult DefScriptPackage::SCcastspell(CmdSet& Set) if (spellId <= 0) { - logerror("Invalid Script call: SCcastspell: SpellId not valid"); - DEF_RETURN_ERROR; + return false; } ((PseuInstance*)parentMethod)->GetWSession()->SendCastSpell(spellId); @@ -240,6 +241,7 @@ DefReturnResult DefScriptPackage::SCqueryitem(CmdSet& Set){ DefReturnResult DefScriptPackage::SCtarget(CmdSet& Set) { // TODO: special targets: _self _pet _nearest ... + DefReturnResult r; if(!(((PseuInstance*)parentMethod)->GetWSession() && ((PseuInstance*)parentMethod)->GetWSession()->IsValid())) { @@ -257,11 +259,17 @@ DefReturnResult DefScriptPackage::SCtarget(CmdSet& Set) uint64 guid = (((PseuInstance*)parentMethod)->GetWSession()->plrNameCache.GetGuid(Set.defaultarg)); if( guid && ((PseuInstance*)parentMethod)->GetWSession()->objmgr.GetObj(guid) ) // object must be near - ((PseuInstance*)parentMethod)->GetWSession()->SendSetSelection(guid); + { + ((PseuInstance*)parentMethod)->GetWSession()->SendSetSelection(guid); // will also set the target for myCharacter + r.ret=toString(guid); + } else + { logdetail("Target '%s' not found!",Set.defaultarg.c_str()); + return false; + } - return true; + return r; } DefReturnResult DefScriptPackage::SCloadscp(CmdSet& Set) @@ -416,6 +424,40 @@ DefReturnResult DefScriptPackage::SCGetEntry(CmdSet& Set) return r; } +DefReturnResult DefScriptPackage::SCGetObjectType(CmdSet& Set) +{ + if(!(((PseuInstance*)parentMethod)->GetWSession() && ((PseuInstance*)parentMethod)->GetWSession()->IsValid())) + { + logerror("Invalid Script call: SCGetObjectType: WorldSession not valid"); + DEF_RETURN_ERROR; + } + DefReturnResult r; + uint64 guid=DefScriptTools::toNumber(Set.defaultarg); + r.ret="0"; + Object *o=((PseuInstance*)parentMethod)->GetWSession()->objmgr.GetObj(guid); + if(o) + { + r.ret=DefScriptTools::toString((uint64)o->GetTypeId()); + } + else + { + logerror("SCGetObjectType: Object "I64FMT" not known",guid); + } + return r; +} + +DefReturnResult DefScriptPackage::SCObjectKnown(CmdSet& Set) +{ + if(!(((PseuInstance*)parentMethod)->GetWSession() && ((PseuInstance*)parentMethod)->GetWSession()->IsValid())) + { + logerror("Invalid Script call: SCObjectIsKnown: WorldSession not valid"); + DEF_RETURN_ERROR; + } + uint64 guid=DefScriptTools::toNumber(Set.defaultarg); + Object *o=((PseuInstance*)parentMethod)->GetWSession()->objmgr.GetObj(guid); + return o!=NULL; +} + DefReturnResult DefScriptPackage::SCGetItemProtoValue(CmdSet& Set) { if(!(((PseuInstance*)parentMethod)->GetWSession() && ((PseuInstance*)parentMethod)->GetWSession()->IsValid())) @@ -663,18 +705,17 @@ void DefScriptPackage::My_Run(std::string line, std::string username) } } - // temp fix to prevent users from executing scripts via return values exploit. example: - // -out ?{say .shutdown} - // note that the following code can still be executed: - // -out ${q}{say .shutdown} - // where var q = "?" - if(usrperm < 255 && line.find("?{")!=std::string::npos) + DefXChgResult final; + if(usrperm < 255) { - logerror("WARNING: %s wanted to exec \"%s\"",username.c_str(),line.c_str()); - return; + if(line.find("?{")!=std::string::npos) + logerror("WARNING: %s wanted to exec \"%s\"",username.c_str(),line.c_str()); + final=ReplaceVars(line,NULL,0,false); // prevent execution of embedded scripts (= using return values) that could trigger dangerous stuff. } + else + final=ReplaceVars(line,NULL,0,true); // exec as usual - DefXChgResult final=ReplaceVars(line,NULL,0,false); + CmdSet curSet; SplitLine(curSet,final.str); diff --git a/src/Client/DefScriptInterfaceInclude.h b/src/Client/DefScriptInterfaceInclude.h index 03daba3..7bd6997 100644 --- a/src/Client/DefScriptInterfaceInclude.h +++ b/src/Client/DefScriptInterfaceInclude.h @@ -31,5 +31,7 @@ DefReturnResult SCGetName(CmdSet&); DefReturnResult SCGetPlayerGuid(CmdSet&); DefReturnResult SCGetEntry(CmdSet&); DefReturnResult SCGetItemProtoValue(CmdSet&); +DefReturnResult SCGetObjectType(CmdSet&); +DefReturnResult SCObjectKnown(CmdSet&); #endif \ No newline at end of file diff --git a/src/Client/PseuWoW.cpp b/src/Client/PseuWoW.cpp index 4af2cb7..25e13ee 100644 --- a/src/Client/PseuWoW.cpp +++ b/src/Client/PseuWoW.cpp @@ -98,6 +98,7 @@ bool PseuInstance::Init(void) { _scp->variables.Set("@version_short",_ver_short); _scp->variables.Set("@version",_ver); + _scp->variables.Set("@inworld","false"); log("Loading DefScripts from folder '%s'",_scpdir.c_str()); diff --git a/src/Client/World/WorldSession.cpp b/src/Client/World/WorldSession.cpp index e7d9ed9..c1550a1 100644 --- a/src/Client/World/WorldSession.cpp +++ b/src/Client/World/WorldSession.cpp @@ -208,6 +208,7 @@ void WorldSession::_OnEnterWorld(void) if(!_logged) { _logged=true; + GetInstance()->GetScripts()->variables.Set("@inworld","true"); GetInstance()->GetScripts()->RunScript("_enterworld",NULL); } @@ -219,7 +220,7 @@ void WorldSession::_OnLeaveWorld(void) { _logged=false; GetInstance()->GetScripts()->RunScript("_leaveworld",NULL); - + GetInstance()->GetScripts()->variables.Set("@inworld","false"); } }