diff --git a/bin/scripts/_startup.def b/bin/scripts/_startup.def index 056767a..e396c85 100644 --- a/bin/scripts/_startup.def +++ b/bin/scripts/_startup.def @@ -11,18 +11,20 @@ CONFIG //they will get loaded automatically if needed LOADALL -// load the uptime counter -LOADDEF uptime - // RELOADDEF myscript // ... // set permissions for internal functions INTERNAL_PERM +// Load some SCP files +LOADALLSCP // do more stuff here in future... +// load the uptime counter +LOADDEF uptime + LOG * StartUp complete! diff --git a/bin/scripts/append.def b/bin/scripts/append.def new file mode 100644 index 0000000..6221ab3 --- /dev/null +++ b/bin/scripts/append.def @@ -0,0 +1,15 @@ +#permission=255 + +// usage: append text to a string. +// args: +// @def: text to append +// @0: variable to which the text should be appended + +// get the var name if the original variable +SET,v #${@caller}::${@0} +// if it has not been set before, init it now +DEFAULT,${v} +// append to the original var. inner ${..} gets the var name, outer ${..} get the value of the var name we just got. +SET,${v} ${${v}}${@def} +// remove the name placeholder +UNSET v \ No newline at end of file diff --git a/bin/scripts/internal_perm.def b/bin/scripts/internal_perm.def index d90f47a..35004b5 100644 --- a/bin/scripts/internal_perm.def +++ b/bin/scripts/internal_perm.def @@ -1,6 +1,8 @@ +#psermission=255 LOG * Assigning permissions for internal functions... +// default permission level for all internal script commands set,p 255 // this is important because players could reset permissions for dangerous functions @@ -24,7 +26,6 @@ SETSCRIPTPERMISSION,pow ${p} SETSCRIPTPERMISSION,bitor ${p} SETSCRIPTPERMISSION,bitand ${p} SETSCRIPTPERMISSION,bitxor ${p} -SETSCRIPTPERMISSION,sendchatmessage ${p} SETSCRIPTPERMISSION,pause ${p} // emotes are not relly dangerous, allow for all users @@ -39,6 +40,8 @@ SETSCRIPTPERMISSION,applypermissions ${p} SETSCRIPTPERMISSION,log ${p} SETSCRIPTPERMISSION,logdetail ${p} SETSCRIPTPERMISSION,logdebug ${p} +SETSCRIPTPERMISSION,target ${p} +SETSCRIPTPERMISSION,loadscp ${p} UNSET p diff --git a/bin/scripts/loadallscp.def b/bin/scripts/loadallscp.def new file mode 100644 index 0000000..5bfa040 --- /dev/null +++ b/bin/scripts/loadallscp.def @@ -0,0 +1,9 @@ +#permission=255 + +LOG * Loading SCP data storages... + +// TODO: load stuff here +// example: +// LOADSCP,test data/test.scp + +LOG * SCP loaded. \ No newline at end of file diff --git a/src/Client/DefScript/DefScript.cpp b/src/Client/DefScript/DefScript.cpp index 8c6a154..af818ea 100644 --- a/src/Client/DefScript/DefScript.cpp +++ b/src/Client/DefScript/DefScript.cpp @@ -80,6 +80,7 @@ DefScriptFunctionTable *DefScriptPackage::_GetFunctionTable(void) const {"castspell", &DefScriptPackage::SCcastspell}, {"queryitem", &DefScriptPackage::SCqueryitem}, {"target", &DefScriptPackage::SCtarget}, + {"loadscp", &DefScriptPackage::SCloadscp}, // table termination {NULL,NULL} diff --git a/src/Client/DefScript/DefScript.h b/src/Client/DefScript/DefScript.h index d7ea620..fd5e312 100644 --- a/src/Client/DefScript/DefScript.h +++ b/src/Client/DefScript/DefScript.h @@ -25,12 +25,22 @@ typedef __int64_t def_int64; class DefScriptPackage; class DefScript; -struct DefXChgResult { +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. +}; + + class CmdSet { public: CmdSet(DefScript *p); @@ -163,6 +173,7 @@ private: bool SCcastspell(CmdSet); bool SCqueryitem(CmdSet); bool SCtarget(CmdSet); + bool SCloadscp(CmdSet); // Own variable declarations std::map my_usrPermissionMap; diff --git a/src/Client/DefScript/VarSet.cpp b/src/Client/DefScript/VarSet.cpp index 78ec9e2..f77d2b9 100644 --- a/src/Client/DefScript/VarSet.cpp +++ b/src/Client/DefScript/VarSet.cpp @@ -110,43 +110,41 @@ bool VarSet::ReadVarsFromFile(std::string fn) } if(line.at(0)=='[' && line.at(line.length()-1)==']') { - prefix=line.substr(1,line.length()-2); - if(!prefix.empty()) + std::string loadinfo; + loadinfo=line.substr(1,line.length()-2); + if(!loadinfo.empty()) { - if(prefix.at(0)=='#') - prefix=toLower(prefix); - if(prefix=="#uppercase") + if(loadinfo.at(0)=='#') + loadinfo=toLower(loadinfo); + if(loadinfo=="#uppercase") { upper=true; lower=false; - prefix.clear(); } - else if(prefix=="#normal") + else if(loadinfo=="#normal") { upper=false; lower=false; - prefix.clear(); } - else if(prefix=="#lowercase") + else if(loadinfo=="#lowercase") { lower=true; upper=false; - prefix.clear(); } - else if(prefix=="#noprefix") + else if(loadinfo=="#noprefix") { prefix.clear(); } else { - prefix+="::"; + prefix=loadinfo+"::"; } } } else { unsigned int pos=line.find("="); - if(pos) + if(pos!=std::string::npos) { std::string v=line.substr(0,pos);; diff --git a/src/Client/DefScriptInterface.cpp b/src/Client/DefScriptInterface.cpp index b91c287..e507bcc 100644 --- a/src/Client/DefScriptInterface.cpp +++ b/src/Client/DefScriptInterface.cpp @@ -9,6 +9,7 @@ #include "WorldSession.h" #include "Channel.h" #include "CacheHandler.h" +#include "SCPDatabase.h" bool DefScriptPackage::SCshdn(CmdSet Set) { @@ -236,6 +237,23 @@ bool DefScriptPackage::SCtarget(CmdSet Set) return true; } +bool DefScriptPackage::SCloadscp(CmdSet Set) +{ + if(Set.arg[0].empty() || Set.defaultarg.empty()) + return true; + std::string dbname = stringToLower(Set.arg[0]); + uint32 sections=((PseuInstance*)parentMethod)->GetSCPDatabase(dbname).LoadFromFile((char*)Set.defaultarg.c_str()); + if(sections) + { + logdetail("Loaded SCP: \"%s\" [%s] (%u sections)",dbname.c_str(),Set.defaultarg.c_str(),sections); + } + else + { + logerror("Failed to load SCP: \"%s\" [%s]",dbname.c_str(),Set.defaultarg.c_str()); + } + return true; +} + void DefScriptPackage::My_LoadUserPermissions(VarSet &vs) diff --git a/src/Client/PseuWoW.cpp b/src/Client/PseuWoW.cpp index 45a1a7b..bd8d645 100644 --- a/src/Client/PseuWoW.cpp +++ b/src/Client/PseuWoW.cpp @@ -27,9 +27,14 @@ void PseuInstanceRunnable::run(void) _i = new PseuInstance(this); _i->SetConfDir("./conf/"); _i->SetScpDir("./scripts/"); - _i->Init(); - // more - _i->Run(); + if(_i->Init()) + { + _i->Run(); + } + else + { + getchar(); + } delete _i; } @@ -53,6 +58,7 @@ PseuInstance::PseuInstance(PseuInstanceRunnable *run) _startrealm=true; createWorldSession=false; _error=false; + _initialized=false; } @@ -230,10 +236,17 @@ void PseuInstance::Sleep(uint32 msecs) GetRunnable()->sleep(msecs); } +SCPDatabase& PseuInstance::GetSCPDatabase(std::string dbname) +{ + return _dbmap[dbname]; +} + PseuInstanceConf::PseuInstanceConf() { + enablecli=false; + exitonerror=false; } void PseuInstanceConf::ApplyFromVarSet(VarSet &v) diff --git a/src/Client/PseuWoW.h b/src/Client/PseuWoW.h index 5f56f82..5fb6550 100644 --- a/src/Client/PseuWoW.h +++ b/src/Client/PseuWoW.h @@ -7,6 +7,7 @@ #include "Auth/BigNumber.h" #include "DefScript/DefScript.h" #include "Network/SocketHandler.h" +#include "SCPDatabase.h" class RealmSocket; class WorldSession; @@ -70,6 +71,7 @@ class PseuInstance void SetSessionKey(BigNumber key) { _sessionkey = key; } BigNumber GetSessionKey(void) { return _sessionkey; } void SetError(void) { _error = true; } + SCPDatabase& GetSCPDatabase(std::string); @@ -103,6 +105,7 @@ class PseuInstance SocketHandler _sh; CliRunnable *_cli; ZThread::Thread _clithread; + std::map _dbmap; }; diff --git a/src/Client/SCPDatabase.cpp b/src/Client/SCPDatabase.cpp new file mode 100644 index 0000000..ce7d911 --- /dev/null +++ b/src/Client/SCPDatabase.cpp @@ -0,0 +1,53 @@ +#include +#include "common.h" +#include "SCPDatabase.h" + + +uint32 SCPDatabase::LoadFromFile(char *fn) +{ + std::fstream fh; + std::string line,value,entry,storage; + uint32 id=0,sections=0; + char c; + + fh.open(fn,std::ios_base::in); + if( !fh.is_open() ) + return 0; + while(!fh.eof()) + { + c=fh.get(); + if(c=='\n' || fh.eof()) + { + if(line.empty()) + continue; + while(line[0]==' ' || line[0]=='\t') + line.erase(0,1); + if(line.empty() || (line.length() > 1 && (line[0]=='/' && line[1]=='/')) ) + { + line.clear(); + continue; + } + if(line[0]=='[') + { + id=(uint32)toInt(line.c_str()+1); // start reading after '[' + sections++; + } + else + { + uint32 pos=line.find("="); + if(pos!=std::string::npos) + { + entry=stringToLower(line.substr(0,pos)); + value=line.substr(pos+1,line.length()-1); + _map[id].Set(entry,value); + } + // else invalid line, must have '=' + } + line.clear(); + } + else + line+=c; // fill up line until a newline is reached (see above) + } + fh.close(); + return sections; +} \ No newline at end of file diff --git a/src/Client/SCPDatabase.h b/src/Client/SCPDatabase.h new file mode 100644 index 0000000..f45f44a --- /dev/null +++ b/src/Client/SCPDatabase.h @@ -0,0 +1,40 @@ +#ifndef _SCPDATABASE_H +#define _SCPDATABASE_H + +#include + +struct SCPEntry +{ + std::string entry; + std::string value; +}; + +typedef std::map SCPEntryMap; + +class SCPField +{ +public: + std::string GetString(std::string entry) { return _map[entry]; } + uint64 GetInteger(std::string entry) { return toInt(_map[entry]); } + double GetDouble(std::string entry) { return strtod(_map[entry].c_str(),NULL); } + void Set(std::string entry,std::string value) { _map[entry]=value; } + +private: + SCPEntryMap _map; +}; + +typedef std::map SCPFieldMap; + + +class SCPDatabase +{ +public: + SCPField& GetField(uint32 id) { return _map[id]; } + uint32 LoadFromFile(char*); + +private: + SCPFieldMap _map; + +}; + +#endif diff --git a/src/PseuWoW.vcproj b/src/PseuWoW.vcproj index 0ffe6d3..ce6a9fe 100644 --- a/src/PseuWoW.vcproj +++ b/src/PseuWoW.vcproj @@ -185,6 +185,12 @@ + + + + diff --git a/src/shared/tools.cpp b/src/shared/tools.cpp index f9d4cb0..d5af563 100644 --- a/src/shared/tools.cpp +++ b/src/shared/tools.cpp @@ -59,3 +59,14 @@ std::string getDateString(void) return std::string(str); } +uint64 toInt(std::string str) +{ + if(str.empty()) + return 0; + str=stringToUpper(str); + if(str.length() > 2 && str[0]=='0' && str[1]=='X') + return strtoul(&(str.c_str()[2]),NULL,16); + else + return strtoul(str.c_str(),NULL,10); +} + diff --git a/src/shared/tools.h b/src/shared/tools.h index 61d0416..27104c5 100644 --- a/src/shared/tools.h +++ b/src/shared/tools.h @@ -13,5 +13,6 @@ std::string stringToUpper(std::string); std::string stringToLower(std::string); std::string toString(uint64); std::string getDateString(void); +uint64 toInt(std::string); #endif \ No newline at end of file