* implemented DefScript return values. use like vars: ?{func}

* note that this version might still be buggy! please test and give feedback on forum!
* added a temp workaround to prevent the execution of dangerous scripts over return values as ingame commands.
( -out ?{say .shutdown} )
This commit is contained in:
False.Genesis 2007-03-10 23:54:29 +00:00
parent 36aa23dadb
commit 6c2355b75c
9 changed files with 574 additions and 390 deletions

View File

@ -6,6 +6,7 @@
#include <sstream>
#include "VarSet.h"
#include "DefScript.h"
#include "DefScriptTools.h"
// --- SECTION FOR SCRIPT PACKAGES ---
DefScriptPackage::DefScriptPackage()
@ -262,9 +263,8 @@ bool DefScript::AddLine(std::string l){
// --- SECTION FOR COMMAND SETS ---
CmdSet::CmdSet(DefScript *p){
CmdSet::CmdSet(){
Clear();
owner = p;
}
CmdSet::~CmdSet(){
@ -286,17 +286,33 @@ void CmdSet::Clear()
// the referred pSet is the parent from which RunScript() has been called
bool DefScriptPackage::RunScript(std::string name, CmdSet *pSet)
bool DefScriptPackage::BoolRunScript(std::string name, CmdSet *pSet)
{
DefReturnResult r = RunScript(name,pSet);
return r.ok;
}
// the referred pSet is the parent from which RunScript() has been called
DefReturnResult DefScriptPackage::RunScript(std::string name, CmdSet *pSet)
{
DefReturnResult r;
if(!ScriptExists(name))
if(!LoadByName(name))
return false; // doesnt exist & cant be loaded
{
r.ok=false; // doesnt exist & cant be loaded
r.ret="";
return r;
}
DefScript *sc = GetScript(name);
if(!sc)
return false;
{
r.ok=false;
r.ret="";
return r;
}
CmdSet temp(sc);
CmdSet temp;
if(!pSet)
{
pSet = &temp;
@ -306,40 +322,43 @@ bool DefScriptPackage::RunScript(std::string name, CmdSet *pSet)
for(unsigned int i=0;i<sc->GetLines();i++)
{
CmdSet curSet(NULL);
DefXChgResult final=ReplaceVars(sc->GetLine(i),pSet,false);
//printf("SC: \"%s\"\n",final.str.c_str());
curSet=SplitLine(final.str);
curSet.owner=sc; // must set the owner after SplitLine()
curSet.myname=name;
curSet.caller=pSet?pSet->myname:"";
Interpret(curSet);
CmdSet mySet;
DefXChgResult final=ReplaceVars(sc->GetLine(i),pSet,0);
_DEFSC_DEBUG(printf("DefScript: \"%s\"\n",final.str.c_str()));
SplitLine(mySet,final.str);
mySet.myname=name;
mySet.caller=pSet?pSet->myname:"";
r=Interpret(mySet);
if(r.mustreturn)
{
r.mustreturn=false;
break;
}
}
return true;
return r;
}
bool DefScriptPackage::RunSingleLine(std::string line){
DefXChgResult final=ReplaceVars(line,NULL,false);
CmdSet curSet=SplitLine(final.str);
return Interpret(curSet);
DefReturnResult DefScriptPackage::RunSingleLine(std::string line){
DefXChgResult final=ReplaceVars(line,NULL,0);
CmdSet Set;
SplitLine(Set,final.str);
return Interpret(Set);
}
bool DefScriptPackage::RunSingleLineFromScript(std::string line, DefScript *pScript){
CmdSet Set(pScript);
Set.myname=pScript->GetName(); // temp fix, this needs to be cleaned up later
DefXChgResult final=ReplaceVars(line,&Set,false);
CmdSet curSet=SplitLine(final.str);
curSet.myname=pScript->GetName(); // temp fix, this needs to be cleaned up later
return Interpret(curSet);
DefReturnResult DefScriptPackage::RunSingleLineFromScript(std::string line, DefScript *pScript){
CmdSet Set;
Set.myname=pScript->GetName();
DefXChgResult final=ReplaceVars(line,&Set,0);
SplitLine(Set,final.str);
return Interpret(Set);
}
CmdSet DefScriptPackage::SplitLine(std::string line){
void DefScriptPackage::SplitLine(CmdSet& Set,std::string line){
unsigned int i=0;
unsigned int bracketsOpen=0,curParam=0;
bool cmdDefined=false;
std::string tempLine;
CmdSet outSet(NULL);
// extract cmd+params and txt
for(i=0;i<line.length();i++){
@ -352,10 +371,10 @@ CmdSet DefScriptPackage::SplitLine(std::string line){
if( line.at(i)==',' && !bracketsOpen)
{
if(!cmdDefined){
outSet.cmd=tempLine;
Set.cmd=tempLine;
cmdDefined=true;
} else {
outSet.arg[curParam]=tempLine;
Set.arg[curParam]=tempLine;
curParam++;
}
tempLine.clear();
@ -364,14 +383,14 @@ CmdSet DefScriptPackage::SplitLine(std::string line){
else if( line.at(i)==' ' && !bracketsOpen)
{
if(!cmdDefined){
outSet.cmd=tempLine;
Set.cmd=tempLine;
cmdDefined=true;
} else {
outSet.arg[curParam]=tempLine;
Set.arg[curParam]=tempLine;
}
outSet.defaultarg=line.substr(i,line.length()-i);
outSet.defaultarg.erase(0,1);
Set.defaultarg=line.substr(i,line.length()-i);
Set.defaultarg.erase(0,1);
//tempLine.clear();
break;
@ -383,13 +402,12 @@ CmdSet DefScriptPackage::SplitLine(std::string line){
}
if(!cmdDefined)
outSet.cmd=tempLine;
if(cmdDefined && !outSet.cmd.empty() && outSet.defaultarg.empty())
outSet.arg[curParam]=tempLine;
Set.cmd=tempLine;
if(cmdDefined && !Set.cmd.empty() && Set.defaultarg.empty())
Set.arg[curParam]=tempLine;
outSet.cmd.assign(strlwr((char*)outSet.cmd.c_str())); // TODO: use toLower() instead!
outSet.owner=GetScript(outSet.cmd);
return RemoveBrackets(outSet);
Set.cmd = DefScriptTools::stringToLower(Set.cmd); // lowercase cmd
RemoveBrackets(Set); // TODO: call this somewhere else as soon as IF and LOOP statements are implemented!
}
std::string DefScriptPackage::RemoveBracketsFromString(std::string t){
@ -408,7 +426,7 @@ std::string DefScriptPackage::RemoveBracketsFromString(std::string t){
if(t[i]=='{')
{
if(i>0 && t[i-1]=='$')
if(i>0 && (t[i-1]=='$' || t[i-1]=='?') )
isVar=true;
if(!bo)
ob=i;
@ -438,8 +456,7 @@ std::string DefScriptPackage::RemoveBracketsFromString(std::string t){
return t;
}
CmdSet DefScriptPackage::RemoveBrackets(CmdSet oldSet){
CmdSet Set=oldSet;
void DefScriptPackage::RemoveBrackets(CmdSet& Set){
std::string t;
for(unsigned int a=0;a<MAXARGS+2;a++){
if(a==0)
@ -461,12 +478,10 @@ CmdSet DefScriptPackage::RemoveBrackets(CmdSet oldSet){
else
Set.arg[a-2]=t;
}
return Set;
}
DefXChgResult DefScriptPackage::ReplaceVars(std::string str, CmdSet *pSet, bool isVar){
DefXChgResult DefScriptPackage::ReplaceVars(std::string str, CmdSet *pSet, unsigned char VarType){
unsigned int
openingBracket=0, // defines the position from where the recursive call is started
@ -474,13 +489,11 @@ DefXChgResult DefScriptPackage::ReplaceVars(std::string str, CmdSet *pSet, bool
bracketsOpen=0, // amount of brackets opened
bLen=0; // the lenth of the string in brackets, e.g. ${abc} == 3
bool
nextIsVar=false, // true if the last bracket was preceded by '$'
hasVar=false, // true if openingBracket (= the first bracket) was preceded by '$'
hasChanged=false; // additional helper. once true, xchg.result will be true later also
// isVar (arg) : defines if the current string is a variable (can only be true in recursive calls!)
unsigned char
nextVar=DEFSCRIPT_NONE; // '$' or '?'
bool
hasChanged=false, // additional helper. once true, xchg.result will be true later also
hasVar=false; // true if openingBracket (= the first bracket) was preceded by '$' or '?'
std::string subStr;
DefXChgResult xchg;
@ -495,7 +508,13 @@ DefXChgResult DefScriptPackage::ReplaceVars(std::string str, CmdSet *pSet, bool
{
hasVar=true;
if(!bracketsOpen)
nextIsVar=true;
nextVar=DEFSCRIPT_VAR;
}
if(i>0 && str[i-1]=='?')
{
hasVar=true;
if(!bracketsOpen)
nextVar=DEFSCRIPT_FUNC;
}
bracketsOpen++;
}
@ -507,7 +526,7 @@ DefXChgResult DefScriptPackage::ReplaceVars(std::string str, CmdSet *pSet, bool
if(!bracketsOpen)
{
closingBracket=i;
if(!nextIsVar && isVar && !hasVar) // remove brackets in var names, like ${var{ia}ble}
if(nextVar==DEFSCRIPT_NONE && VarType!=DEFSCRIPT_NONE && !hasVar) // remove brackets in var names, like ${var{ia}ble}
{
str.erase(closingBracket,1);
str.erase(openingBracket,1);
@ -519,66 +538,82 @@ DefXChgResult DefScriptPackage::ReplaceVars(std::string str, CmdSet *pSet, bool
bLen=closingBracket-openingBracket-1;
subStr=str.substr(openingBracket+1,bLen);
//printf("SUBSTR: \"%s\"\n",subStr.c_str());
xchg=ReplaceVars(subStr,pSet,nextIsVar);
if( (!nextIsVar) && hasVar && xchg.changed )
xchg=ReplaceVars(subStr,pSet,nextVar);
if( nextVar==DEFSCRIPT_NONE && hasVar && xchg.changed )
{
str.erase(openingBracket+1,subStr.length());
str.insert(openingBracket+1,xchg.str);
hasVar=false;
nextIsVar=false;
i-=(subStr.length()+1);
hasChanged=true;
}
else if( nextIsVar && hasVar && xchg.changed )
else if( nextVar!=DEFSCRIPT_NONE && hasVar && xchg.changed )
{
str.erase(openingBracket-1,bLen+3); // remove ${...} (+3 because of '${}')
i-=(bLen+2); // adjust position
str.insert(i,xchg.str);
//i--;
hasVar=false;
nextIsVar=false;
nextVar=DEFSCRIPT_NONE;
}
}
}
} // end if '}'
} // end for
if(!bracketsOpen && isVar)
if(!bracketsOpen && VarType!=DEFSCRIPT_NONE)
{
std::string vname=_NormalizeVarName(str, (pSet==NULL) ? "" : pSet->myname);
if(vname[0]=='@')
if(VarType==DEFSCRIPT_VAR)
{
std::stringstream vns;
std::string subs=vname.substr(1,str.length()-1);
unsigned int vn=atoi( subs.c_str() );
vns << vn;
if(pSet && vns.str()==subs) // resolve arg macros @0 - @99
str=pSet->arg[vn];
else if(pSet && subs=="def")
str=pSet->defaultarg;
else if(pSet && subs=="myname")
str=pSet->myname;
else if(pSet && subs=="cmd")
str=pSet->cmd;
else if(pSet && subs=="caller")
str=pSet->caller;
else if(subs=="n")
str="\n";
else if(variables.Exists(vname))
str=variables.Get(vname);
else
std::string vname=_NormalizeVarName(str, (pSet==NULL) ? "" : pSet->myname);
if(vname[0]=='@')
{
// TODO: call custom macro table
//...
str.clear();
}
xchg.changed=true;
}
else
if(variables.Exists(vname))
{
str=variables.Get(vname);
std::stringstream vns;
std::string subs=vname.substr(1,str.length()-1);
unsigned int vn=atoi( subs.c_str() );
vns << vn;
if(pSet && vns.str()==subs) // resolve arg macros @0 - @99
str=pSet->arg[vn];
else if(pSet && subs=="def")
str=pSet->defaultarg;
else if(pSet && subs=="myname")
str=pSet->myname;
else if(pSet && subs=="cmd")
str=pSet->cmd;
else if(pSet && subs=="caller")
str=pSet->caller;
else if(subs=="n")
str="\n";
else if(variables.Exists(vname))
str=variables.Get(vname);
else
{
// TODO: call custom macro table
//...
str.clear();
}
xchg.changed=true;
}
else
{
if(variables.Exists(vname))
{
str=variables.Get(vname);
xchg.changed=true;
}
}
}
else if(VarType==DEFSCRIPT_FUNC)
{
DefReturnResult res;
if(pSet)
res=RunSingleLineFromScript(str,GetScript(pSet->myname));
else
res=RunSingleLine(str);
str=res.ret; // returns empty string on invalid function!!
xchg.result.ok=res.ok;
if(res.ok)
xchg.changed=true;
//xchg.result.err += res.err;
}
}
xchg.str = str;
@ -607,12 +642,12 @@ std::string DefScriptPackage::_NormalizeVarName(std::string vn_in, std::string s
return vn;
}
bool DefScriptPackage::Interpret(CmdSet Set)
DefReturnResult DefScriptPackage::Interpret(CmdSet& Set)
{
bool result=false;
DefReturnResult result;
// first search if the script is defined in the internal functions
for(unsigned int i=0;result==false;i++)
for(unsigned int i=0;;i++)
{
if(functionTable[i].func==NULL || functionTable[i].name==NULL) // reached the end of the table?
{
@ -621,18 +656,23 @@ bool DefScriptPackage::Interpret(CmdSet Set)
if(Set.cmd==functionTable[i].name)
{
result=(this->*functionTable[i].func)(Set);
break;
return result;
}
}
// if nothing has been found its maybe an external script file to run
if(!result)
if(Set.cmd=="return")
{
result=RunScript(Set.cmd, &Set);
if((!result) /*&& Script[Set.cmd]->GetDebug()*/)
std::cout << "Could not execute script command '" << Set.cmd << "'\n";
result.mustreturn=true;
result.ret=Set.defaultarg;
return result;
}
// if nothing has been found its maybe an external script file to run
result=RunScript(Set.cmd, &Set);
if((!result.ok) /*&& Script[Set.cmd]->GetDebug()*/)
std::cout << "Could not execute script command '" << Set.cmd << "'\n";
return result;
}

View File

@ -2,48 +2,39 @@
#ifndef __DEFSCRIPT_H
#define __DEFSCRIPT_H
#define MAXARGS 99
#ifdef _DEBUG
# define _DEFSC_DEBUG(code) code;
#else
# define _DEFSC_DEBUG(code) /* code */
#endif
#if COMPILER == COMPILER_MICROSOFT
typedef __int64 def_int64;
#else
typedef __int64_t def_int64;
#endif
#include <map>
#include <deque>
#include "VarSet.h"
#include "DynamicEvent.h"
#include "DefScriptDefines.h"
class DefScriptPackage;
class DefScript;
struct DefReturnResult
{
DefReturnResult() { ok=true; mustreturn=false; ret="true"; }
DefReturnResult(bool b) { ok=b; mustreturn=false; ret=b?"true":"false"; }
bool ok; // true if the execution of the current statement was successful
bool mustreturn;
std::string ret; // return value used by ?{..}
//bool abrt; // true if ALL current script execution must be aborted.
//std::string err; // error string, including tracestack, etc.
};
struct DefXChgResult
{
DefXChgResult() { changed=false; }
bool changed;
std::string str;
};
struct SecReturnResult
{
bool ok; // true if the execution of the current statement was successful
bool abrt; // true if ALL current script execution must be aborted.
std::string ret; // return value used by ?{..}
std::string err; // error string, including tracestack, etc.
};
DefReturnResult result;
};
class CmdSet {
public:
CmdSet(DefScript *p);
CmdSet();
~CmdSet();
void Clear();
std::string cmd;
@ -51,13 +42,11 @@ class CmdSet {
std::string defaultarg;
std::string myname;
std::string caller;
DefScript *owner;
void *ptr;
};
struct DefScriptFunctionTable {
char *name;
bool (DefScriptPackage::*func)(CmdSet Set);
DefReturnResult (DefScriptPackage::*func)(CmdSet& Set);
};
class DefScript {
@ -84,9 +73,7 @@ private:
unsigned char permission;
bool debugmode;
DefScriptPackage *_parent;
//CmdSet _mySet;
DefScriptPackage *_parent;
};
@ -99,29 +86,30 @@ public:
DefScript *GetScript(std::string);
unsigned int GetScripts(void);
bool LoadScriptFromFile(std::string,std::string);
bool RunScript(std::string,CmdSet*);
DefReturnResult RunScript(std::string,CmdSet*);
bool BoolRunScript(std::string,CmdSet*);
unsigned int GetScriptID(std::string);
bool RunSingleLine(std::string);
DefReturnResult RunSingleLine(std::string);
bool ScriptExists(std::string);
VarSet variables;
void SetPath(std::string);
bool LoadByName(std::string);
void SetFunctionTable(DefScriptFunctionTable*);
std::string _NormalizeVarName(std::string, std::string);
bool RunSingleLineFromScript(std::string line, DefScript *pScript);
DefReturnResult RunSingleLineFromScript(std::string line, DefScript *pScript);
DefScript_DynamicEventMgr *GetEventMgr(void);
std::string scPath;
// Own executor functions
void My_LoadUserPermissions(VarSet&);
bool My_Run(std::string line,std::string username);
void My_Run(std::string line,std::string username);
private:
DefXChgResult ReplaceVars(std::string, CmdSet*, bool);
CmdSet SplitLine(std::string);
bool Interpret(CmdSet);
CmdSet RemoveBrackets(CmdSet);
DefXChgResult ReplaceVars(std::string str, CmdSet* pSet, unsigned char VarType);
void SplitLine(CmdSet&,std::string);
DefReturnResult Interpret(CmdSet&);
void RemoveBrackets(CmdSet&);
std::string RemoveBracketsFromString(std::string);
DefScriptFunctionTable *_GetFunctionTable(void) const;
DefScriptFunctionTable *functionTable;
@ -132,48 +120,48 @@ private:
std::map<std::string,unsigned char> scriptPermissionMap;
// Usable internal basic functions:
bool func_default(CmdSet);
bool func_set(CmdSet);
bool func_unset(CmdSet);
bool func_loaddef(CmdSet);
bool func_reloaddef(CmdSet);
bool func_out(CmdSet);
bool func_eof(CmdSet);
bool func_shdn(CmdSet);
bool func_setscriptpermission(CmdSet);
bool func_toint(CmdSet);
bool func_add(CmdSet);
bool func_sub(CmdSet);
bool func_mul(CmdSet);
bool func_div(CmdSet);
bool func_mod(CmdSet);
bool func_pow(CmdSet);
bool func_bitor(CmdSet);
bool func_bitand(CmdSet);
bool func_bitxor(CmdSet);
bool func_addevent(CmdSet);
bool func_removeevent(CmdSet);
DefReturnResult func_default(CmdSet&);
DefReturnResult func_set(CmdSet&);
DefReturnResult func_unset(CmdSet&);
DefReturnResult func_loaddef(CmdSet&);
DefReturnResult func_reloaddef(CmdSet&);
DefReturnResult func_out(CmdSet&);
DefReturnResult func_eof(CmdSet&);
DefReturnResult func_shdn(CmdSet&);
DefReturnResult func_setscriptpermission(CmdSet&);
DefReturnResult func_toint(CmdSet&);
DefReturnResult func_add(CmdSet&);
DefReturnResult func_sub(CmdSet&);
DefReturnResult func_mul(CmdSet&);
DefReturnResult func_div(CmdSet&);
DefReturnResult func_mod(CmdSet&);
DefReturnResult func_pow(CmdSet&);
DefReturnResult func_bitor(CmdSet&);
DefReturnResult func_bitand(CmdSet&);
DefReturnResult func_bitxor(CmdSet&);
DefReturnResult func_addevent(CmdSet&);
DefReturnResult func_removeevent(CmdSet&);
// Useable own internal functions:
bool SCpause(CmdSet);
bool SCSendChatMessage(CmdSet);
bool SCsavecache(CmdSet);
bool SCemote(CmdSet);
bool SCfollow(CmdSet);
bool SCshdn(CmdSet);
bool SCjoinchannel(CmdSet);
bool SCleavechannel(CmdSet);
bool SCloadconf(CmdSet);
bool SCapplypermissions(CmdSet);
bool SCapplyconf(CmdSet);
bool SClog(CmdSet);
bool SClogdetail(CmdSet);
bool SClogdebug(CmdSet);
bool SClogerror(CmdSet);
bool SCcastspell(CmdSet);
bool SCqueryitem(CmdSet);
bool SCtarget(CmdSet);
bool SCloadscp(CmdSet);
DefReturnResult SCpause(CmdSet&);
DefReturnResult SCSendChatMessage(CmdSet&);
DefReturnResult SCsavecache(CmdSet&);
DefReturnResult SCemote(CmdSet&);
DefReturnResult SCfollow(CmdSet&);
DefReturnResult SCshdn(CmdSet&);
DefReturnResult SCjoinchannel(CmdSet&);
DefReturnResult SCleavechannel(CmdSet&);
DefReturnResult SCloadconf(CmdSet&);
DefReturnResult SCapplypermissions(CmdSet&);
DefReturnResult SCapplyconf(CmdSet&);
DefReturnResult SClog(CmdSet&);
DefReturnResult SClogdetail(CmdSet&);
DefReturnResult SClogdebug(CmdSet&);
DefReturnResult SClogerror(CmdSet&);
DefReturnResult SCcastspell(CmdSet&);
DefReturnResult SCqueryitem(CmdSet&);
DefReturnResult SCtarget(CmdSet&);
DefReturnResult SCloadscp(CmdSet&);
// Own variable declarations
std::map<std::string, unsigned char> my_usrPermissionMap;

View File

@ -0,0 +1,26 @@
#ifndef DEFSCRIPTDEFINES_H
#define DEFSCRIPTDEFINES_H
#define MAXARGS 99
#ifdef _DEBUG
# define _DEFSC_DEBUG(code) code;
#else
# define _DEFSC_DEBUG(code)
#endif
#if COMPILER == COMPILER_MICROSOFT
typedef __int64 int64;
typedef unsigned __int64 uint64;
#else
typedef __int64_t int64;
typedef unsigned __int64_t uint64;
#endif
enum VariableType
{
DEFSCRIPT_NONE=0,
DEFSCRIPT_VAR,
DEFSCRIPT_FUNC
};
#endif

View File

@ -6,29 +6,38 @@
#include <sstream>
#include <math.h>
#include "DefScript.h"
#include "DefScriptTools.h"
using namespace DefScriptTools;
bool DefScriptPackage::func_shdn(CmdSet Set){
DefReturnResult DefScriptPackage::func_shdn(CmdSet& Set){
DefReturnResult r;
//exit(0);
// need to define own
SCshdn(Set);
return true;
return r;
}
bool DefScriptPackage::func_eof(CmdSet Set){
// do nothing still
return true;
}
bool DefScriptPackage::func_out(CmdSet Set){
DefReturnResult DefScriptPackage::func_out(CmdSet& Set){
DefReturnResult r;
printf("%s\n",Set.defaultarg.c_str());
return true;
r.ret=Set.defaultarg;
return r;
}
bool DefScriptPackage::func_loaddef(CmdSet Set){
DefReturnResult DefScriptPackage::func_loaddef(CmdSet& Set){
DefReturnResult r;
if( ScriptExists(Set.defaultarg) )
return true;
{
r.ret="exists";
return r;
}
return func_reloaddef(Set);
}
DefReturnResult DefScriptPackage::func_reloaddef(CmdSet& Set){
DefReturnResult r;
bool result=false;
std::string fn;
if(Set.arg[0].empty())
@ -45,267 +54,282 @@ bool DefScriptPackage::func_loaddef(CmdSet Set){
fn=Set.arg[0];
result=LoadScriptFromFile(fn,Set.defaultarg);
}
r.ret=fn;
if(!result)
{
std::cout << "Could not load script '" << Set.defaultarg << "' [" << fn << "]\n";
return true;
r.ret="";
}
return r;
}
bool DefScriptPackage::func_reloaddef(CmdSet Set){
bool result=false;
std::string fn;
if(Set.arg[0].empty())
{
result=LoadByName(Set.defaultarg);
fn=(scPath + Set.defaultarg).append(".def");
}
else
{
std::string::size_type pos = Set.arg[0].find('/');
if(pos == std::string::npos)
fn=scPath+Set.arg[0];
else
fn=Set.arg[0];
result=LoadScriptFromFile(fn,Set.defaultarg);
}
if(!result)
std::cout << "Could not load script '" << Set.defaultarg << "' [" << fn << "]\n";
return true;
}
bool DefScriptPackage::func_unset(CmdSet Set){
DefReturnResult DefScriptPackage::func_unset(CmdSet& Set){
DefReturnResult r;
r.ret=Set.defaultarg;
if(Set.defaultarg.empty()){
//if(curIsDebug)
// printf("Can't unset, no variable name given.\n");
return false;
return r;
}
if(Set.defaultarg.at(0)=='@'){
//if(curIsDebug)
// printf("Can't unset macros!\n");
return false;
return r;
}
std::string vn=_NormalizeVarName(Set.defaultarg, Set.caller);
variables.Unset(vn);
//std::cout<<"Unset var '"<<Set->defaultarg<<"'\n";
return true;
return r;
}
bool DefScriptPackage::func_set(CmdSet Set){
DefReturnResult DefScriptPackage::func_set(CmdSet& Set){
DefReturnResult r;
if(Set.arg[0].empty()){
//if(curIsDebug)
// printf("Can't assign value, no variable name given.\n");
return false;
return r;
}
if(Set.arg[0].at(0)=='@'){
//if(curIsDebug)
// printf("Can't assign value to a macro!\n");
return false;
return r;
}
std::string vname,vval=Set.defaultarg;
vname=_NormalizeVarName(Set.arg[0], Set.myname);
if(!stricmp(Set.arg[1].c_str(),"onfail") && vval.find("${")!=std::string::npos)
vval=Set.arg[2];
//if(!stricmp(Set.arg[1].c_str(),"onfail") && vval.find("${")!=std::string::npos)
// vval=Set.arg[2];
variables.Set(vname,vval);
if(Set.owner && Set.owner->GetDebug())
r.ret=vval;
DefScript *sc = GetScript(Set.myname);
if(sc && sc->GetDebug())
printf("VAR: %s = '%s'\n",vname.c_str(),vval.c_str());
return true;
return r;
}
bool DefScriptPackage::func_default(CmdSet Set){
DefReturnResult DefScriptPackage::func_default(CmdSet& Set){
DefReturnResult r;
if(Set.arg[0].empty()){
//if(curIsDebug)
// printf("Can't assign value, no variable name given.\n");
return false;
return r;
}
if(Set.arg[0].at(0)=='@'){
//if(curIsDebug)
// printf("Can't assign value to a macro!\n");
return false;
return r;
}
std::string vname,vval=Set.defaultarg;
vname=_NormalizeVarName(Set.arg[0], Set.caller);
if(variables.Get(vname).empty())
variables.Set(vname,vval); // set only if it has no value
{
variables.Set(vname,vval); // set only if it has no value or the var doesnt exist
r.ret=vval;
}
else
{
r.ret=variables.Get(vname);
}
return true;
return r;
}
bool DefScriptPackage::func_setscriptpermission(CmdSet Set)
DefReturnResult DefScriptPackage::func_setscriptpermission(CmdSet& Set)
{
DefReturnResult r;
if(Set.defaultarg.empty() || Set.arg[0].empty())
return false;
return r;
scriptPermissionMap[Set.arg[0]] = atoi(Set.defaultarg.c_str());
return true;
return r;
}
bool DefScriptPackage::func_toint(CmdSet Set)
DefReturnResult DefScriptPackage::func_toint(CmdSet& Set)
{
if(Set.arg[0].empty())
return false;
std::string vname=_NormalizeVarName(Set.arg[0], Set.myname);
def_int64 myint = strtol(Set.defaultarg.c_str(), NULL, 10);
std::stringstream ss;
ss << myint;
variables.Set(vname,ss.str());
return true;
}
bool DefScriptPackage::func_add(CmdSet Set)
{
if(Set.arg[0].empty())
return false;
std::string vname=_NormalizeVarName(Set.arg[0], Set.myname);
long long myvar = strtol(variables.Get(vname).c_str(), NULL, 10);
def_int64 myadd = strtol(Set.defaultarg.c_str(), NULL, 10);
myvar += myadd;
std::stringstream ss;
ss << myvar;
variables.Set(vname,ss.str());
return true;
}
bool DefScriptPackage::func_sub(CmdSet Set)
{
if(Set.arg[0].empty())
return false;
std::string vname=_NormalizeVarName(Set.arg[0], Set.myname);
def_int64 myvar = strtol(variables.Get(vname).c_str(), NULL, 10);
def_int64 myadd = strtol(Set.defaultarg.c_str(), NULL, 10);
myvar -= myadd;
std::stringstream ss;
ss << myvar;
variables.Set(vname,ss.str());
return true;
}
bool DefScriptPackage::func_mul(CmdSet Set)
{
if(Set.arg[0].empty())
return false;
std::string vname=_NormalizeVarName(Set.arg[0], Set.myname);
def_int64 myvar = strtol(variables.Get(vname).c_str(), NULL, 10);
def_int64 myadd = strtol(Set.defaultarg.c_str(), NULL, 10);
myvar *= myadd;
std::stringstream ss;
ss << myvar;
variables.Set(vname,ss.str());
return true;
}
bool DefScriptPackage::func_div(CmdSet Set)
{
if(Set.arg[0].empty())
return false;
std::string vname=_NormalizeVarName(Set.arg[0], Set.myname);
def_int64 myvar = strtol(variables.Get(vname).c_str(), NULL, 10);
def_int64 myadd = strtol(Set.defaultarg.c_str(), NULL, 10);
if(myadd==0)
DefReturnResult r;
std::string num=toString(floor(toNumber(Set.defaultarg.c_str())));
if(!Set.arg[0].empty())
{
// TODO: some error handling
variables.Set(vname,"0");
std::string vname=_NormalizeVarName(Set.arg[0], Set.myname);
variables.Set(vname,num);
}
myvar /= myadd;
std::stringstream ss;
ss << myvar;
variables.Set(vname,ss.str());
return true;
r.ret=num;
return r;
}
bool DefScriptPackage::func_mod(CmdSet Set)
DefReturnResult DefScriptPackage::func_add(CmdSet& Set)
{
DefReturnResult r;
if(Set.arg[0].empty())
return false;
{
return r;
}
std::string vname=_NormalizeVarName(Set.arg[0], Set.myname);
def_int64 myvar = strtol(variables.Get(vname).c_str(), NULL, 10);
def_int64 myadd = strtol(Set.defaultarg.c_str(), NULL, 10);
myvar %= myadd;
std::stringstream ss;
ss << myvar;
variables.Set(vname,ss.str());
return true;
double a=toNumber(variables.Get(vname));
double b=toNumber(Set.defaultarg.c_str());
a+=b;
variables.Set(vname,toString(a));
r.ret=toString(a);
return r;
}
bool DefScriptPackage::func_pow(CmdSet Set)
DefReturnResult DefScriptPackage::func_sub(CmdSet& Set)
{
DefReturnResult r;
if(Set.arg[0].empty())
return false;
{
return r;
}
std::string vname=_NormalizeVarName(Set.arg[0], Set.myname);
def_int64 myvar = strtol(variables.Get(vname).c_str(), NULL, 10);
def_int64 myadd = strtol(Set.defaultarg.c_str(), NULL, 10);
long double myd=(long double)myvar,mya=(long double)myadd;
myd = (long double)pow(myd,mya);
myvar = (def_int64)myd;
std::stringstream ss;
ss << myvar;
variables.Set(vname,ss.str());
return true;
double a=toNumber(variables.Get(vname));
double b=toNumber(Set.defaultarg.c_str());
a-=b;
variables.Set(vname,toString(a));
r.ret=toString(a);
return r;
}
bool DefScriptPackage::func_bitor(CmdSet Set)
DefReturnResult DefScriptPackage::func_mul(CmdSet& Set)
{
DefReturnResult r;
if(Set.arg[0].empty())
return false;
{
return r;
}
std::string vname=_NormalizeVarName(Set.arg[0], Set.myname);
def_int64 myvar = strtol(variables.Get(vname).c_str(), NULL, 10);
def_int64 myadd = strtol(Set.defaultarg.c_str(), NULL, 10);
myvar |= myadd;
std::stringstream ss;
ss << myvar;
variables.Set(vname,ss.str());
return true;
double a=toNumber(variables.Get(vname));
double b=toNumber(Set.defaultarg.c_str());
a*=b;
variables.Set(vname,toString(a));
r.ret=toString(a);
return r;
}
bool DefScriptPackage::func_bitand(CmdSet Set)
DefReturnResult DefScriptPackage::func_div(CmdSet& Set)
{
DefReturnResult r;
if(Set.arg[0].empty())
return false;
{
return r;
}
std::string vname=_NormalizeVarName(Set.arg[0], Set.myname);
def_int64 myvar = strtol(variables.Get(vname).c_str(), NULL, 10);
def_int64 myadd = strtol(Set.defaultarg.c_str(), NULL, 10);
myvar &= myadd;
std::stringstream ss;
ss << myvar;
variables.Set(vname,ss.str());
return true;
double a=toNumber(variables.Get(vname));
double b=toNumber(Set.defaultarg.c_str());
if(b==0)
a=0;
else
a/=b;
variables.Set(vname,toString(a));
r.ret=toString(a);
return r;
}
bool DefScriptPackage::func_bitxor(CmdSet Set)
DefReturnResult DefScriptPackage::func_mod(CmdSet& Set)
{
DefReturnResult r;
if(Set.arg[0].empty())
return false;
{
return r;
}
std::string vname=_NormalizeVarName(Set.arg[0], Set.myname);
def_int64 myvar = strtol(variables.Get(vname).c_str(), NULL, 10);
def_int64 myadd = strtol(Set.defaultarg.c_str(), NULL, 10);
myvar ^= myadd;
std::stringstream ss;
ss << myvar;
variables.Set(vname,ss.str());
return true;
uint64 a=(uint64)toNumber(variables.Get(vname));
uint64 b=(uint64)toNumber(Set.defaultarg.c_str());
if(b==0)
a=0;
else
a%=b;
variables.Set(vname,toString(a));
r.ret=toString(a);
return r;
}
bool DefScriptPackage::func_addevent(CmdSet Set)
DefReturnResult DefScriptPackage::func_pow(CmdSet& Set)
{
DefReturnResult r;
if(Set.arg[0].empty())
{
return r;
}
std::string vname=_NormalizeVarName(Set.arg[0], Set.myname);
double a=toNumber(variables.Get(vname));
double b=toNumber(Set.defaultarg.c_str());
a=pow(a,b);
variables.Set(vname,toString(a));
r.ret=toString(a);
return r;
}
DefReturnResult DefScriptPackage::func_bitor(CmdSet& Set)
{
DefReturnResult r;
if(Set.arg[0].empty())
{
return r;
}
std::string vname=_NormalizeVarName(Set.arg[0], Set.myname);
uint64 a=(uint64)toNumber(variables.Get(vname));
uint64 b=(uint64)toNumber(Set.defaultarg.c_str());
a|=b;
variables.Set(vname,toString(a));
r.ret=toString(a);
return r;
}
DefReturnResult DefScriptPackage::func_bitand(CmdSet& Set)
{
DefReturnResult r;
if(Set.arg[0].empty())
{
return r;
}
std::string vname=_NormalizeVarName(Set.arg[0], Set.myname);
uint64 a=(uint64)toNumber(variables.Get(vname));
uint64 b=(uint64)toNumber(Set.defaultarg.c_str());
a&=b;
variables.Set(vname,toString(a));
r.ret=toString(a);
return r;
}
DefReturnResult DefScriptPackage::func_bitxor(CmdSet& Set)
{
DefReturnResult r;
if(Set.arg[0].empty())
{
return r;
}
std::string vname=_NormalizeVarName(Set.arg[0], Set.myname);
uint64 a=(uint64)toNumber(variables.Get(vname));
uint64 b=(uint64)toNumber(Set.defaultarg.c_str());
a^=b;
variables.Set(vname,toString(a));
r.ret=toString(a);
return r;
}
DefReturnResult DefScriptPackage::func_addevent(CmdSet& Set)
{
DefReturnResult r;
GetEventMgr()->Add(Set.arg[0],Set.defaultarg,atoi(Set.arg[1].c_str()),Set.myname.c_str());
return true;
return r;
}
bool DefScriptPackage::func_removeevent(CmdSet Set)
DefReturnResult DefScriptPackage::func_removeevent(CmdSet& Set)
{
DefReturnResult r;
GetEventMgr()->Remove(Set.defaultarg);
return true;
return r;
}

View File

@ -0,0 +1,70 @@
#include <string>
#include <iostream>
#include <sstream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#include <cctype>
#include "DefScriptDefines.h"
#include "DefScriptTools.h"
std::string DefScriptTools::stringToLower(std::string s)
{
std::transform(s.begin(), s.end(), s.begin(), std::tolower);
return s;
}
std::string DefScriptTools::stringToUpper(std::string s)
{
std::transform(s.begin(), s.end(), s.begin(), std::toupper);
return s;
}
std::string DefScriptTools::toString(double num)
{
std::stringstream ss;
ss << num;
return ss.str();
}
std::string DefScriptTools::toString(uint64 num)
{
std::stringstream ss;
ss << num;
return ss.str();
}
// convert a string into double
// valid input formats:
// normal numbers: 5439
// hex numbers: 0xa56ff, 0XFF, 0xDEADBABE, etc (must begin with 0x)
// float numbers: 99.65, 0.025
// negative numbers: -100, -0x3d, -55.123
double DefScriptTools::toNumber(std::string str)
{
double num;
bool negative=false;
if(str.empty())
return 0;
if(str[0]=='-')
{
str.erase(0,1);
negative=true;
}
if(str.find('.')==std::string::npos)
{
str=stringToUpper(str);
if(str.length() > 2 && str[0]=='0' && str[1]=='X')
num = strtoul(&(str.c_str()[2]),NULL,16);
else
num = strtoul(str.c_str(),NULL,10);
}
else
{
num = strtod(str.c_str(),NULL);
}
if(negative)
num = -num;
return num;
}

View File

@ -0,0 +1,15 @@
#ifndef _DEFSCRIPTTOOLS_H
#define _DEFSCRIPTTOOLS_H
namespace DefScriptTools
{
std::string stringToUpper(std::string);
std::string stringToLower(std::string);
std::string toString(double);
std::string toString(uint64);
double toNumber(std::string);
}
#endif

View File

@ -11,18 +11,18 @@
#include "CacheHandler.h"
#include "SCPDatabase.h"
bool DefScriptPackage::SCshdn(CmdSet Set)
DefReturnResult DefScriptPackage::SCshdn(CmdSet& Set)
{
((PseuInstance*)parentMethod)->Stop();
return true;
}
bool DefScriptPackage::SCpause(CmdSet Set){
DefReturnResult DefScriptPackage::SCpause(CmdSet& Set){
((PseuInstance*)parentMethod)->Sleep(atoi(Set.defaultarg.c_str()));
return true;
}
bool DefScriptPackage::SCSendChatMessage(CmdSet Set){
DefReturnResult DefScriptPackage::SCSendChatMessage(CmdSet& Set){
if(!(((PseuInstance*)parentMethod)->GetWSession() && ((PseuInstance*)parentMethod)->GetWSession()->IsValid()))
{
logerror("Invalid Script call: SCSendChatMessage: WorldSession not valid");
@ -49,7 +49,7 @@ bool DefScriptPackage::SCSendChatMessage(CmdSet Set){
return true;
}
bool DefScriptPackage::SCsavecache(CmdSet Set){
DefReturnResult DefScriptPackage::SCsavecache(CmdSet& Set){
((PseuInstance*)parentMethod)->SaveAllCache();
std::stringstream str;
if(((PseuInstance*)parentMethod)->GetWSession() && ((PseuInstance*)parentMethod)->GetWSession()->IsValid())
@ -66,7 +66,7 @@ bool DefScriptPackage::SCsavecache(CmdSet Set){
return true;
}
bool DefScriptPackage::SCemote(CmdSet Set){
DefReturnResult DefScriptPackage::SCemote(CmdSet& Set){
if(Set.defaultarg.empty())
return true;
if(!(((PseuInstance*)parentMethod)->GetWSession() && ((PseuInstance*)parentMethod)->GetWSession()->IsValid()))
@ -79,7 +79,7 @@ bool DefScriptPackage::SCemote(CmdSet Set){
return true;
}
bool DefScriptPackage::SCfollow(CmdSet Set){
DefReturnResult DefScriptPackage::SCfollow(CmdSet& Set){
WorldSession *ws=((PseuInstance*)parentMethod)->GetWSession();
if(Set.defaultarg.empty()){
ws->SendChatMessage(CHAT_MSG_SAY,0,"Stopping! (Please give me a Playername to follow!)","");
@ -97,7 +97,7 @@ bool DefScriptPackage::SCfollow(CmdSet Set){
}
bool DefScriptPackage::SCjoinchannel(CmdSet Set){
DefReturnResult DefScriptPackage::SCjoinchannel(CmdSet& Set){
if(Set.defaultarg.empty())
return true;
if(!(((PseuInstance*)parentMethod)->GetWSession() && ((PseuInstance*)parentMethod)->GetWSession()->IsValid()))
@ -109,7 +109,7 @@ bool DefScriptPackage::SCjoinchannel(CmdSet Set){
return true;
}
bool DefScriptPackage::SCleavechannel(CmdSet Set){
DefReturnResult DefScriptPackage::SCleavechannel(CmdSet& Set){
if(Set.defaultarg.empty())
return true;
if(!(((PseuInstance*)parentMethod)->GetWSession() && ((PseuInstance*)parentMethod)->GetWSession()->IsValid()))
@ -121,7 +121,7 @@ bool DefScriptPackage::SCleavechannel(CmdSet Set){
return true;
}
bool DefScriptPackage::SCloadconf(CmdSet Set){
DefReturnResult DefScriptPackage::SCloadconf(CmdSet& Set){
if(Set.defaultarg.empty())
return true;
std::string fn;
@ -136,37 +136,37 @@ bool DefScriptPackage::SCloadconf(CmdSet Set){
return true;
}
bool DefScriptPackage::SCapplypermissions(CmdSet Set){
DefReturnResult DefScriptPackage::SCapplypermissions(CmdSet& Set){
this->My_LoadUserPermissions(variables);
return true;
}
bool DefScriptPackage::SCapplyconf(CmdSet Set){
DefReturnResult DefScriptPackage::SCapplyconf(CmdSet& Set){
((PseuInstance*)parentMethod)->GetConf()->ApplyFromVarSet(variables);
return true;
}
bool DefScriptPackage::SClog(CmdSet Set){
DefReturnResult DefScriptPackage::SClog(CmdSet& Set){
log(Set.defaultarg.c_str());
return true;
}
bool DefScriptPackage::SClogdetail(CmdSet Set){
DefReturnResult DefScriptPackage::SClogdetail(CmdSet& Set){
logdetail(Set.defaultarg.c_str());
return true;
}
bool DefScriptPackage::SClogdebug(CmdSet Set){
DefReturnResult DefScriptPackage::SClogdebug(CmdSet& Set){
logdebug(Set.defaultarg.c_str());
return true;
}
bool DefScriptPackage::SClogerror(CmdSet Set){
DefReturnResult DefScriptPackage::SClogerror(CmdSet& Set){
logerror(Set.defaultarg.c_str());
return true;
}
bool DefScriptPackage::SCcastspell(CmdSet Set)
DefReturnResult DefScriptPackage::SCcastspell(CmdSet& Set)
{
if(Set.defaultarg.empty())
return true;
@ -188,7 +188,7 @@ bool DefScriptPackage::SCcastspell(CmdSet Set)
return true;
}
bool DefScriptPackage::SCqueryitem(CmdSet Set){
DefReturnResult DefScriptPackage::SCqueryitem(CmdSet& Set){
uint32 id = atoi(Set.defaultarg.c_str());
if(!id)
return true;
@ -202,7 +202,7 @@ bool DefScriptPackage::SCqueryitem(CmdSet Set){
return true;
}
bool DefScriptPackage::SCtarget(CmdSet Set)
DefReturnResult DefScriptPackage::SCtarget(CmdSet& Set)
{
// TODO: special targets: _self _pet _nearest ...
@ -229,7 +229,7 @@ bool DefScriptPackage::SCtarget(CmdSet Set)
return true;
}
bool DefScriptPackage::SCloadscp(CmdSet Set)
DefReturnResult DefScriptPackage::SCloadscp(CmdSet& Set)
{
if(Set.arg[0].empty() || Set.defaultarg.empty())
return true;
@ -264,13 +264,10 @@ void DefScriptPackage::My_LoadUserPermissions(VarSet &vs)
}
}
bool DefScriptPackage::My_Run(std::string line, std::string username)
void DefScriptPackage::My_Run(std::string line, std::string username)
{
DefXChgResult final=ReplaceVars(line,NULL,false);
CmdSet curSet=SplitLine(final.str);
uint8 scperm=0,usrperm=0;
for (std::map<std::string,unsigned char>::iterator i = my_usrPermissionMap.begin(); i != my_usrPermissionMap.end(); i++)
{
if(i->first == username)
@ -279,6 +276,21 @@ bool 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)
{
logerror("WARNING: %s wanted to exec \"%s\"",username.c_str(),line.c_str());
return;
}
DefXChgResult final=ReplaceVars(line,NULL,false);
CmdSet curSet;
SplitLine(curSet,final.str);
for (std::map<std::string,unsigned char>::iterator i = scriptPermissionMap.begin(); i != scriptPermissionMap.end(); i++)
{
if(i->first == curSet.cmd)
@ -289,15 +301,14 @@ bool DefScriptPackage::My_Run(std::string line, std::string username)
if(usrperm < scperm)
{
CmdSet Set(NULL);
CmdSet Set;
Set.arg[0] = username;
Set.arg[1] = toString(usrperm);
Set.arg[2] = toString(scperm);
Set.arg[3] = curSet.cmd;
RunScript("_nopermission",&Set);
return false;
return;
}
Interpret(curSet);
return true;
}
}

View File

@ -100,7 +100,8 @@ bool PseuInstance::Init(void) {
_scp->variables.Set("@version",_ver);
log("Loading DefScripts from folder '%s'",_scpdir.c_str());
if(!_scp->RunScript("_startup",NULL))
if(!_scp->BoolRunScript("_startup",NULL))
{
logerror("Error executing '_startup.def'");
SetError();

View File

@ -239,9 +239,18 @@
Name="VCCustomBuildTool"/>
</FileConfiguration>
</File>
<File
RelativePath=".\Client\DefScript\DefScriptDefines.h">
</File>
<File
RelativePath=".\Client\DefScript\DefScriptFunctions.cpp">
</File>
<File
RelativePath=".\Client\DefScript\DefScriptTools.cpp">
</File>
<File
RelativePath=".\Client\DefScript\DefScriptTools.h">
</File>
<File
RelativePath=".\Client\DefScript\DynamicEvent.cpp">
</File>