diff --git a/src/Client/DefScript/DefScript.cpp b/src/Client/DefScript/DefScript.cpp index 92f767f..d770b31 100644 --- a/src/Client/DefScript/DefScript.cpp +++ b/src/Client/DefScript/DefScript.cpp @@ -158,7 +158,24 @@ void DefScriptPackage::_InitFunctions(void) AddFunc("bbsetrpos",&DefScriptPackage::func_bbsetrpos); AddFunc("bbsetwpos",&DefScriptPackage::func_bbsetwpos); AddFunc("bbsize",&DefScriptPackage::func_bbsize); - + + // file functions + AddFunc("fopen",&DefScriptPackage::func_fopen); + AddFunc("fclose",&DefScriptPackage::func_fclose); + AddFunc("fisopen",&DefScriptPackage::func_fisopen); + AddFunc("feof",&DefScriptPackage::func_feof); + AddFunc("frpos",&DefScriptPackage::func_frpos); + AddFunc("fwpos",&DefScriptPackage::func_fwpos); + AddFunc("fdel",&DefScriptPackage::func_fdel); + AddFunc("fflush",&DefScriptPackage::func_fflush); + AddFunc("fwrite",&DefScriptPackage::func_fwrite); + AddFunc("fread",&DefScriptPackage::func_fread); + AddFunc("freadb",&DefScriptPackage::func_freadb); + AddFunc("fwriteb",&DefScriptPackage::func_fwriteb); + AddFunc("freadbb",&DefScriptPackage::func_freadbb); + AddFunc("fwritebb",&DefScriptPackage::func_fwritebb); + AddFunc("fsize",&DefScriptPackage::func_fsize); + AddFunc("fexists",&DefScriptPackage::func_fileexists); // name alternative for "fileexists" } void DefScriptPackage::AddFunc(std::string n,DefReturnResult (DefScriptPackage::*f)(CmdSet& Set), bool esc) diff --git a/src/Client/DefScript/DefScript.h b/src/Client/DefScript/DefScript.h index 36e194e..7c28b8b 100644 --- a/src/Client/DefScript/DefScript.h +++ b/src/Client/DefScript/DefScript.h @@ -137,6 +137,7 @@ public: void DelFunc(std::string); TypeStorage lists; TypeStorage bytebuffers; + TypeStorage files; std::string SecureString(std::string); std::string EscapeString(std::string); std::string UnescapeString(std::string); @@ -253,6 +254,23 @@ private: DefReturnResult func_bbtextlike(CmdSet&); DefReturnResult func_bbsize(CmdSet&); + // file functions + DefReturnResult DefScriptPackage::func_fopen(CmdSet&); + DefReturnResult DefScriptPackage::func_fclose(CmdSet&); + DefReturnResult DefScriptPackage::func_fisopen(CmdSet&); + DefReturnResult DefScriptPackage::func_feof(CmdSet&); + DefReturnResult DefScriptPackage::func_frpos(CmdSet&); + DefReturnResult DefScriptPackage::func_fwpos(CmdSet&); + DefReturnResult DefScriptPackage::func_fdel(CmdSet&); + DefReturnResult DefScriptPackage::func_fflush(CmdSet&); + DefReturnResult DefScriptPackage::func_fwrite(CmdSet&); + DefReturnResult DefScriptPackage::func_fread(CmdSet&); + DefReturnResult DefScriptPackage::func_freadb(CmdSet&); + DefReturnResult DefScriptPackage::func_fwriteb(CmdSet&); + DefReturnResult DefScriptPackage::func_freadbb(CmdSet&); + DefReturnResult DefScriptPackage::func_fwritebb(CmdSet&); + DefReturnResult DefScriptPackage::func_fsize(CmdSet&); + // setup own function declarations here # include "DefScriptInterfaceInclude.h" diff --git a/src/Client/DefScript/DefScriptBBFunctions.cpp b/src/Client/DefScript/DefScriptBBFunctions.cpp index 8ec820f..4ab006f 100644 --- a/src/Client/DefScript/DefScriptBBFunctions.cpp +++ b/src/Client/DefScript/DefScriptBBFunctions.cpp @@ -38,7 +38,7 @@ DefReturnResult DefScriptPackage::func_bbdelete(CmdSet& Set) // Appends data to ByteBuffer // @def - data // @0 - bytebuffer identifier -// @1 - datatype of added data (uint8,uint16,uint32,uint64,float,double,string) +// @1 - datatype of added data (uint8,uint16,uint32,uint64,float,double,string,strnz) DefReturnResult DefScriptPackage::func_bbappend(CmdSet& Set) { ByteBuffer *bb = bytebuffers.Get(_NormalizeVarName(Set.arg[0],Set.myname)); @@ -173,4 +173,3 @@ DefReturnResult DefScriptPackage::func_bbsize(CmdSet& Set) return DefScriptTools::toString((uint64)bb->size()); } - \ No newline at end of file diff --git a/src/Client/DefScript/DefScriptFileFunctions.cpp b/src/Client/DefScript/DefScriptFileFunctions.cpp new file mode 100644 index 0000000..4e3510e --- /dev/null +++ b/src/Client/DefScript/DefScriptFileFunctions.cpp @@ -0,0 +1,290 @@ +#include +#include +#include +#include +#include "DefScript.h" +#include "DefScriptTools.h" +#include "SysDefs.h" + +using namespace DefScriptTools; + +#define FH_MACRO_READ_I(_f,_sty,_ty) if(_sty==(#_ty)) { _ty _in; (_f)->read((char*)&_in,sizeof(_ty)); return toString((uint64)_in); } +#define FH_MACRO_READ_F(_f,_sty,_ty) if(_sty==(#_ty)) { _ty _in; (_f)->read((char*)&_in,sizeof(_ty)); return toString((ldbl)_in); } + +DefReturnResult DefScriptPackage::func_fopen(CmdSet& Set) +{ + std::fstream *fh = files.Get(_NormalizeVarName(Set.arg[0],Set.myname)); + if(fh->is_open()) + return ""; + std::string mode = stringToLower(Set.arg[1]); + std::ios::openmode m = 0; + if(mode.find('b') != std::string::npos) + m |= std::ios_base::binary; + if(mode.find('a') != std::string::npos) + m |= std::ios_base::app; + if(mode.find('r') != std::string::npos) + m |= std::ios_base::in; + if(mode.find('w') != std::string::npos) + m |= std::ios_base::out; + + // sort out some possible errors with bad open modes + if(m & std::ios_base::app) + m |= std::ios_base::out; // always open for writing when appending + if(m == 0 || m == std::ios_base::binary) + m |= std::ios_base::out | std::ios_base::in; // if no openmode or binary only specified, use both r+w additionally + + fh->open(Set.defaultarg.c_str(), m); + + // if the file didnt open properly, like if a not existing file opened in read+write mode, + // try fallback mode with write mode only + if(!fh->is_open() && (m & std::ios_base::in)) + { + m &= (~std::ios_base::in); + fh->open(Set.defaultarg.c_str(), m); + } + _DEFSC_DEBUG( if(!fh->is_open()) printf("DefScript: Can't open file '%s'\n",Set.defaultarg.c_str())); + return fh->is_open(); +} + +DefReturnResult DefScriptPackage::func_fclose(CmdSet& Set) +{ + std::fstream *fh = files.GetNoCreate(_NormalizeVarName(Set.defaultarg,Set.myname)); + if(fh) + { + fh->flush(); + fh->close(); + files.DeleteByPtr(fh); + return true; + } + return false; +} + +DefReturnResult DefScriptPackage::func_fisopen(CmdSet& Set) +{ + std::fstream *fh = files.GetNoCreate(_NormalizeVarName(Set.defaultarg,Set.myname)); + return fh && fh->good() && fh->is_open(); +} + +DefReturnResult DefScriptPackage::func_feof(CmdSet& Set) +{ + std::fstream *fh = files.GetNoCreate(_NormalizeVarName(Set.defaultarg,Set.myname)); + return (!fh) || fh->eof(); +} + +DefReturnResult DefScriptPackage::func_frpos(CmdSet& Set) +{ + std::fstream *fh = files.GetNoCreate(_NormalizeVarName(Set.defaultarg,Set.myname)); + if(!fh) + return ""; + return toString((uint64)fh->tellg()); +} + +DefReturnResult DefScriptPackage::func_fwpos(CmdSet& Set) +{ + std::fstream *fh = files.GetNoCreate(_NormalizeVarName(Set.defaultarg,Set.myname)); + if(!fh) + return ""; + return toString((uint64)fh->tellp()); +} + +DefReturnResult DefScriptPackage::func_fdel(CmdSet& Set) +{ + return (remove(Set.defaultarg.c_str()) == 0); +} + +DefReturnResult DefScriptPackage::func_fflush(CmdSet& Set) +{ + std::fstream *fh = files.GetNoCreate(_NormalizeVarName(Set.defaultarg,Set.myname)); + if(fh && fh->is_open()) + fh->flush(); + return ""; +} + +DefReturnResult DefScriptPackage::func_fwrite(CmdSet& Set) +{ + std::fstream *fh = files.GetNoCreate(_NormalizeVarName(Set.arg[0],Set.myname)); + if(fh && fh->is_open()) + { + *fh << Set.defaultarg; + return true; + } + return false; +} + +DefReturnResult DefScriptPackage::func_fread(CmdSet& Set) +{ + std::fstream *fh = files.GetNoCreate(_NormalizeVarName(Set.arg[1],Set.myname)); + if(fh && fh->is_open()) + { + uint64 bytes; + uint64 read = 0; + if(stringToLower(Set.defaultarg) == "all") + bytes = -1LL; + else + bytes = toUint64(Set.defaultarg); + std::string ret; + ret.reserve(bytes); + for(uint64 i = 0; i < bytes && !fh->eof(); i++) + { + ret += fh->get(); + read++; + } + return toString(read); + } + return ""; +} + +DefReturnResult DefScriptPackage::func_freadb(CmdSet& Set) +{ + std::fstream *fh = files.GetNoCreate(_NormalizeVarName(Set.arg[0],Set.myname)); + if(fh && fh->is_open()) + { + std::string t = stringToLower(Set.defaultarg); + if(t == "string") + { + std::string ret; + while(char c = fh->get() && !fh->eof()) + ret += c; + return ret; + } + else if(t == "strnz") + { + uint32 bytes = (uint32)toUint64(Set.arg[1]); + if(bytes) + { + std::string g; + for(uint32 i = 0; i < bytes; i++) + { + g += fh->get(); + } + return g; + } + return ""; + } + FH_MACRO_READ_I(fh,t,uint8); + FH_MACRO_READ_I(fh,t,uint16); + FH_MACRO_READ_I(fh,t,uint32); + FH_MACRO_READ_I(fh,t,uint64); + FH_MACRO_READ_F(fh,t,float); + FH_MACRO_READ_F(fh,t,double); + } + return ""; +} + +DefReturnResult DefScriptPackage::func_fwriteb(CmdSet& Set) +{ + std::fstream *fh = files.GetNoCreate(_NormalizeVarName(Set.arg[0],Set.myname)); + if(fh && fh->is_open()) + { + std::string t = stringToLower(Set.arg[1]); + if(t == "string") + { + fh->write(Set.defaultarg.c_str(), Set.defaultarg.size() + 1); // also put \0 + return true; + } + else if(t == "strnz") + { + fh->write(Set.defaultarg.c_str(), Set.defaultarg.size()); // skip \0 + return true; + } + else if(t == "uint8") + { + uint8 o = (uint8)toUint64(Set.defaultarg); + fh->write((char*)&o,sizeof(uint8)); + return true; + } + else if(t == "uint16") + { + uint16 o = (uint16)toUint64(Set.defaultarg); + fh->write((char*)&o,sizeof(uint16)); + return true; + } + else if(t == "uint32") + { + uint32 o = (uint32)toUint64(Set.defaultarg); + fh->write((char*)&o,sizeof(uint32)); + return true; + } + else if(t == "uint64") + { + uint64 o = toUint64(Set.defaultarg); + fh->write((char*)&o,sizeof(uint64)); + return true; + } + else if(t == "float") + { + float o = (float)toNumber(Set.defaultarg); + fh->write((char*)&o,sizeof(float)); + return true; + } + else if(t == "double") + { + double o = (double)toNumber(Set.defaultarg); + fh->write((char*)&o,sizeof(double)); + return true; + } + + } + return false; +} + +DefReturnResult DefScriptPackage::func_fwritebb(CmdSet& Set) +{ + std::fstream *fh = files.GetNoCreate(_NormalizeVarName(Set.arg[0],Set.myname)); + if(fh && fh->is_open()) + { + ByteBuffer *bb = bytebuffers.GetNoCreate(_NormalizeVarName(Set.defaultarg,Set.myname)); + if(bb) + { + uint32 bytes = (uint32)toUint64(Set.arg[1]); + if(!bytes) + { + bytes = bb->size(); + } + if(bytes) + { + fh->write((char*)bb->contents(), bytes); + } + return toString((uint64)bytes); + } + } + return ""; +} + +DefReturnResult DefScriptPackage::func_freadbb(CmdSet& Set) +{ + std::fstream *fh = files.GetNoCreate(_NormalizeVarName(Set.arg[0],Set.myname)); + if(fh && fh->is_open()) + { + ByteBuffer *bb = bytebuffers.Get(_NormalizeVarName(Set.defaultarg,Set.myname)); + uint32 bytes = (uint32)toUint64(Set.arg[1]); + if(!bytes) + { + // get amount of remaining bytes + std::ios::pos_type oldpos = fh->tellg(); + fh->seekg(0,std::ios_base::end); + bytes = uint32(fh->tellg() - oldpos); + fh->seekg(oldpos,std::ios_base::beg); + } + if(bytes) + { + bb->resize(bb->size() + bytes); + fh->read((char*)bb->contents(), bytes); + } + return toString((uint64)bytes); + } + return ""; +} + +DefReturnResult DefScriptPackage::func_fsize(CmdSet& Set) +{ + std::ifstream f; + f.open(Set.defaultarg.c_str(), std::ios_base::binary | std::ios_base::in); + if (!f.good() || f.eof() || !f.is_open()) { return ""; } + f.seekg(0, std::ios_base::beg); + std::ifstream::pos_type begin_pos = f.tellg(), end_pos; + f.seekg(0, std::ios_base::end); + end_pos = f.tellg(); + f.close(); + return toString((uint64)(end_pos - begin_pos)); +} diff --git a/src/Client/DefScript/DefScriptTools.cpp b/src/Client/DefScript/DefScriptTools.cpp index 3ce1200..d2bb97f 100644 --- a/src/Client/DefScript/DefScriptTools.cpp +++ b/src/Client/DefScript/DefScriptTools.cpp @@ -43,6 +43,7 @@ std::string DefScriptTools::toString(uint64 num) ss << num; return ss.str(); } + // convert a string into ldbl // valid input formats: // normal numbers: 5439 diff --git a/src/Client/DefScript/TypeStorage.h b/src/Client/DefScript/TypeStorage.h index 6fecf51..c7d1ae9 100644 --- a/src/Client/DefScript/TypeStorage.h +++ b/src/Client/DefScript/TypeStorage.h @@ -10,6 +10,7 @@ public: ~TypeStorage(); bool Exists(std::string); void Delete(std::string); + void DeleteByPtr(T*); T *Get(std::string); T *GetNoCreate(std::string); void Assign(std::string,T*); @@ -55,6 +56,20 @@ template void TypeStorage::Delete(std::string s) } } +// delete object with that ptr, if present +template void TypeStorage::DeleteByPtr(T *ptr) +{ + for(std::map::iterator it = _storage.begin(); it != _storage.end(); it++) + { + if(it->second == ptr) + { + delete it->second; + _storage.erase(it); + return; + } + } +} + // return the the object with that name. return NULL if not found template T *TypeStorage::GetNoCreate(std::string s) { diff --git a/src/PseuWoW.vcproj b/src/PseuWoW.vcproj index 7f30a2b..1856ad3 100644 --- a/src/PseuWoW.vcproj +++ b/src/PseuWoW.vcproj @@ -224,6 +224,9 @@ + +