bool CStateManager::endState(const NLMISC::CSString& stateName) { uint32 i; // make sure the state is already active for (i=0;i<_States.size();++i) { if (_States[i]==stateName) { break; } } if (i==_States.size()) { nlwarning("Cannot end state as it is not already active: %s",stateName.c_str()); return false; } // set the state as inactive _States.erase(_States.begin()+i); // write the states to a file NLMISC::CSString stateTxt; stateTxt.join(_States,"\n"); stateTxt.writeToFile(StateFileName); // execute the end_state script CScriptManager::getInstance()->runScript("end_"+stateName); return true; }
bool CCharScanScriptFile::parseFile(const std::string& fileName, CCharScanScript* container) { _FileName= fileName; // read the content of the input file bool result; NLMISC::CSString fileContent; result=fileContent.readFromFile(fileName); if (result==false) { nlwarning("Failed to read script file: %s",fileName.c_str()); return false; } // split the file into lines and execute them one by one NLMISC::CVectorSString lines; fileContent.splitLines(lines); for (uint32 i=0;i<lines.size();++i) { // strip comments and leading and trailing blanks CSString theLine= lines[i].replace("//","\xff").splitTo('\xff').strip(); if (theLine.empty()) continue; CCharScanScriptCommandRegistry::getInstance()->execute(*this,theLine,container); } return true; }
bool applyFirstPatch(const NLMISC::CSString& patchFile,const NLMISC::CSString& destFile) { nlinfo("APPLY FIRST PATCH: %s => %s",patchFile.c_str(),destFile.c_str()); NLMISC::CSString cmd= "xdelta patch "+patchFile+" /dev/null "+destFile; bool ok= system(cmd.c_str())==0; return ok; }
bool applyPatch(const NLMISC::CSString& patchFile,const NLMISC::CSString& srcFile,const NLMISC::CSString& destFile) { nlinfo("APPLY PATCH: %s to file %s => %s",patchFile.c_str(),srcFile.c_str(),destFile.c_str()); NLMISC::CSString cmd= "xdelta patch "+patchFile+" "+srcFile+" "+destFile; bool ok= system(cmd.c_str())==0; return ok; }
uint32 getFileVersion(const NLMISC::CSString& fileName) { // start at the back of the file name and scan forwards until we find a '/' or '\\' or ':' or a digit uint32 i= fileName.size(); while (i--) { char c= fileName[i]; // if we've hit a directory name separator then we haven't found a version number so drop out if (c=='/' || c=='\\' || c==':') return ~0u; // if we've found a digit then construct the rest of the version number and return if (isdigit(c)) { uint32 firstDigit= i; while (firstDigit!=0 && isdigit(fileName[firstDigit-1])) { --firstDigit; } return fileName.leftCrop(firstDigit).left(i-firstDigit+1).atoui(); } } // default to our 'invalid' value return ~0u; }
bool untarIfNeeded(const NLMISC::CSString& destFile) { if (destFile.right(4)==".tgz" || destFile.right(7)==".tar.gz") { return untar(destFile); } return true; }
void CStateManager::addValidState(const NLMISC::CSString& stateName) { if (stateName.countWords()!=1) { nlwarning("Invalid state name: %s",stateName.c_str()); return; } _ValidStates.insert(stateName.strip()); }
// The following routine returns the account id for a given file name // returns 0 for files that do not contain a recognisable account id. // The account id is assumed to be the first integer found between 2 '_' characters. eg for file 'account_123_4_pdr.bin' the value would be 123 static uint32 getAccountIdFromFileName(NLMISC::CSString filename) { uint32 accountId; do { DROP_IF(filename.empty(),"No account number found in file: "+filename,return 0); accountId= filename.strtok("_.").atoui(); } while (accountId==0); return accountId; }
static void addToFdc(const NLMISC::CSString& filespec, CFileDescriptionContainer& result) { if (filespec.left(1)=="@") { readFileList(filespec.leftCrop(1),result); } else { result.addFileSpec(filespec); } }
bool CUserComponentValidator::setUserComponentToSave(const std::string& filename, const CUserComponentValidator::TValues& values, std::string& headerMD5, const std::string &body) { _Filename = filename; // std::ostringstream out2; // out2.str(body); // _UserComponentBody =out2.str(); _UserComponentBody = body; { NLMISC::CHashKeyMD5 md5Id = NLMISC::getMD5((uint8*)_UserComponentBody.data(), (uint32)_UserComponentBody.size()); _BodyMd5 = md5Id.toString().c_str(); } // out2.str(""); // out2 << NLMISC::toString("-- BodyMD5 = '%s'\n", _BodyMd5.c_str() ); // TValues::const_iterator first(values.begin()), last(values.end()); // for (; first != last; ++first) // { //>first->second.c_str()) "\n" => "\\n" // NLMISC::CSString tmp = first->second.c_str(); // tmp = tmp.replace("\n", "\\n"); // out2 << NLMISC::toString("-- %s = '%s'\n", first->first.c_str(), tmp.c_str()); // } // _HeaderBody =out2.str(); _HeaderBody = NLMISC::toString("-- BodyMD5 = '%s'\n", _BodyMd5.c_str() ); TValues::const_iterator first(values.begin()), last(values.end()); for (; first != last; ++first) { //>first->second.c_str()) "\n" => "\\n" NLMISC::CSString tmp = first->second.c_str(); tmp = tmp.replace("\n", "\\n"); _HeaderBody += NLMISC::toString("-- %s = '%s'\n", first->first.c_str(), tmp.c_str()); } std::string headerBodyMd5; { NLMISC::CHashKeyMD5 md5Id = NLMISC::getMD5((uint8*)_HeaderBody.data(), (uint32)_HeaderBody.size()); _HeaderMd5 = md5Id.toString().c_str(); headerMD5 = _HeaderMd5; } return true; }
CStateManager::CStateManager() { // read the states from a file NLMISC::CSString stateTxt; if (NLMISC::CFile::fileExists(StateFileName)) { stateTxt.readFromFile(StateFileName); stateTxt.splitLines(_States); } // display the loaded state list display(); }
bool CRepository::init(const NLMISC::CSString& name,const NLMISC::CSString& directory) { _Name= name.unquoteIfQuoted(); _TargetDirectory= NLMISC::CPath::standardizePath(directory.unquoteIfQuoted()); nldebug("Repository %s: %s",_Name.c_str(),_TargetDirectory.c_str()); // check whether the target directory exists if (!NLMISC::CFile::isDirectory(_TargetDirectory)) { // the directory didn't exist so try to create it... NLMISC::CFile::createDirectoryTree(_TargetDirectory); DROP_IF(!NLMISC::CFile::isDirectory(_TargetDirectory),"Failed to create target directory: \""+_TargetDirectory+"\"",return false); }
// The following routine builds a timestamp value from a date string in the format <dd>/<mm>/<yyyy> // If the text doesn't match the expected format then ~0u is returned static uint32 buildTimestampFromDateStr(const NLMISC::CSString& dateStr) { // setup a new time structure, extracting the day, month and year values from the argument string struct tm tmstruct; NLMISC::CSString txt= dateStr.strip(); tmstruct.tm_mday = txt.splitTo('/',true,true).atoi(); tmstruct.tm_mon = txt.splitTo('/',true,true).atoi() -1; tmstruct.tm_year = txt.atoi(); if (tmstruct.tm_year<100) tmstruct.tm_year= ((tmstruct.tm_year+30)%100)+1970; // make sure the day month and year are valid DROP_IF(tmstruct.tm_year<1970 || tmstruct.tm_year>=2100,"FILE_LIST_BUILDER 'Since' invalid year: "+dateStr,return ~0u); DROP_IF(tmstruct.tm_mon<0 || tmstruct.tm_mon>=12,"FILE_LIST_BUILDER 'Since' invalid month: "+dateStr,return ~0u); DROP_IF(tmstruct.tm_mday<1 || tmstruct.tm_mday>31,"FILE_LIST_BUILDER 'Since' invalid day: "+dateStr,return ~0u); // complete initialisation of tm struct (and map year into range from 1970 up tmstruct.tm_year -= 1900; tmstruct.tm_wday = 0; tmstruct.tm_yday = 0; tmstruct.tm_isdst = 0; // build a time_t value for the start of the day tmstruct.tm_sec = 0; tmstruct.tm_min = 0; tmstruct.tm_hour = 0; return (uint32)mktime( &tmstruct ); }
bool CScenarioValidator::setScenarioToSave(const std::string& filename, CObject* scenario, const CScenarioValidator::TValues& values, std::string& headerMD5) { _Filename = filename; //std::ostringstream out2; //out2.str(""); std::string out2; if (!scenario) { return false; } //out2 <<"scenario = "<< *scenario ; out2 += "scenario = "; scenario->serialize(out2); _ScenarioBody = out2; { NLMISC::CHashKeyMD5 md5Id = NLMISC::getMD5((uint8*)_ScenarioBody.data(),(uint32) _ScenarioBody.size()); _BodyMd5 = md5Id.toString().c_str(); } out2.clear(); //out2.str(""); out2 += NLMISC::toString("-- BodyMD5 = '%s'\n", _BodyMd5.c_str() ); TValues::const_iterator first(values.begin()), last(values.end()); for (; first != last; ++first) { //>first->second.c_str()) "\n" => "\\n" NLMISC::CSString tmp = first->second.c_str(); tmp = tmp.replace("\n", "\\n"); out2 += NLMISC::toString("-- %s = '%s'\n", first->first.c_str(), tmp.c_str()); } _HeaderBody =out2; std::string headerBodyMd5; { NLMISC::CHashKeyMD5 md5Id = NLMISC::getMD5((uint8*)_HeaderBody.data(), (uint32)_HeaderBody.size()); _HeaderMd5 = md5Id.toString().c_str(); headerMD5 = _HeaderMd5; } return true; }
void CFactionChannel::cbChatText(TChannelRank rank,const TCharacterId& id,GUS::TClientId clientId,const NLMISC::CSString& txt) { if (txt.leftStrip().left(1)=="/") { // execute a command CFactionChannelContext context(this,rank,id,clientId); CTxtCommandResult result= ECFCCommandSet->execute(context,txt.leftStrip().leftCrop(1)); switch (result.getType()) { case CTxtCommandResult::SUCCESS: getChannel().sendMessage(clientId,"*","Command executed: "+txt); break; case CTxtCommandResult::SYNTAX_ERROR: getChannel().sendMessage(clientId,"*","Error in command parameter syntax: "+txt); break; case CTxtCommandResult::BAD_PERMISSION: getChannel().sendMessage(clientId,"*","You don't have permission to execute this command: "+txt); break; case CTxtCommandResult::UNKNOWN_COMMAND: getChannel().sendMessage(clientId,"*","Unknown command - try '/help' to see the valid command list: "+txt.firstWordConst()); break; case CTxtCommandResult::EXECUTION_ERROR: default: getChannel().sendMessage(clientId,"*","Error trying to execute command: "+txt); break; } if (result.getReason()!="" && !result.getReason().empty()) getChannel().sendMessage(clientId,"*",result.getReason()); return; } // make sure the use has the right to chat in the channel at the moment if (rank<_MinChatRank) { getChannel().sendMessage(clientId,"system","Players of your rank are currently not able to chat in this channel"); return; } // broadcast the message back to the chat getChannel().broadcastMessage(id,txt); }
void CFileReceiver::_logError(const NLMISC::CSString& msg) const { const CAdministeredModuleBase* adminModule= dynamic_cast<const CAdministeredModuleBase*>(_Parent); if (adminModule!=NULL) { adminModule->registerError(msg); } else { nlwarning("CFileReceiver: %s",msg.c_str()); } }
void CFileReceiver::_downloadLog(const NLMISC::CSString& fileName,uint32 bytesSoFar, uint32 bytesExpected) const { const CAdministeredModuleBase* adminModule= dynamic_cast<const CAdministeredModuleBase*>(_Parent); if (adminModule!=NULL) { adminModule->setStateVariable(fileName,NLMISC::toString("%d/%d",bytesSoFar,bytesExpected)); } else { nldebug("CFileReceiver_Download: %s: %d/%d",fileName.c_str(),bytesSoFar,bytesExpected); } }
bool untar(const NLMISC::CSString& destFile) { bool ok; nlinfo("SPA UNPACK TAR BALL: %s",destFile.c_str()); NLMISC::CSString oldPath= NLMISC::CPath::getCurrentPath(); NLMISC::CSString newPath= NLMISC::CFile::getPath(destFile); ok= NLMISC::CPath::setCurrentPath(newPath.c_str()); DROP_IF(!ok,"Patching error - failed to change directory to: "+newPath,return false); NLMISC::CSString cmd; cmd+= "tar xzfv "+NLMISC::CFile::getFilename(destFile); nldebug("- system: %s",cmd.c_str()); ok= system(cmd.c_str())==0; ok= NLMISC::CPath::setCurrentPath(oldPath.c_str()); DROP_IF(!ok,"Patching error - failed to change directory to: "+oldPath,return false); return ok; }
void CFileReceiver::_log(const NLMISC::CSString& msg) const { const CAdministeredModuleBase* adminModule= dynamic_cast<const CAdministeredModuleBase*>(_Parent); if (adminModule!=NULL) { adminModule->registerProgress(msg); } else { nldebug("CFileReceiver_%s",msg.c_str()); } }
NLMISC::CSString extractNamedParameter(const NLMISC::CSString& argName,NLMISC::CSString rawArgs) { while (!rawArgs.empty()) { NLMISC::CSString keyword; NLMISC::CSString args; keyword= rawArgs.firstWord(true); rawArgs=rawArgs.strip(); if (rawArgs[0]=='(') { args=rawArgs.matchDelimiters(true).stripBlockDelimiters(); } if (keyword==argName) { return args; } } return NLMISC::CSString(); }
bool CStateManager::beginState(const NLMISC::CSString& stateName) { // make sure the state is valid if (_ValidStates.find(stateName.strip())==_ValidStates.end()) { nlwarning("Cannot start state as it is not in valid state list: %s",stateName.c_str()); return false; } // make sure the state isn't already active for (uint32 i=0;i<_States.size();++i) { if (_States[i]==stateName) { nlwarning("Cannot start state as it is already active: %s",stateName.c_str()); return false; } } // set the state as active _States.push_back(stateName); // write the states to a file NLMISC::CSString stateTxt; stateTxt.join(_States,"\n"); stateTxt.writeToFile(StateFileName); // execute the begin_state script CScriptManager::getInstance()->runScript("begin_"+stateName); return true; }
static void readFileList(const NLMISC::CSString& fileListName, CFileDescriptionContainer& result) { // read the file list from disk (the result will be empty if the file list didn't exist) NLMISC::CSString fileList; fileList.readFromFile(fileListName); // split the file list text block into lines NLMISC::CVectorSString files; fileList.splitLines(files); // iterate over the lies in the input file for(uint32 i=0;i<files.size();++i) { // clean lines up, stripping spaces and quotes NLMISC::CSString theFile= files[i].strip().unquoteIfQuoted(); // skip empty lines and comments if (theFile.empty() || theFile.left(1)=="#") continue; // add the file name to the result result.addFile(theFile); } }
CHashKeyMD5 safeGetMD5(const NLMISC::CSString& fileName) { while (true) { try { CHashKeyMD5 result= NLMISC::getMD5(fileName); return result; } catch(...) { nlwarning("Exception thrown in getMD5(\"%s\") ... will try again in a few seconds",fileName.c_str()); nlSleep(3); } } }
bool CScenarioValidator::setScenarioToLoad( const std::string& filename, CScenarioValidator::TValues& values, std::string& md5, std::string& signature, bool checkMD5) { values.clear(); _Filename = filename; _Values.clear(); // open our input file NLMISC::CIFile inf; if (!inf.open(_Filename, true) ) { nlwarning("Can't load scenario %s", _Filename.c_str()); return false; } try { static const char * header = "---- Header\n"; static const char * slashheader = "---- /Header\n\n"; static const char * comment = "-- "; static const unsigned int headerLen = (unsigned int)strlen(header); static const unsigned int slasheaderLen = (unsigned int)strlen(slashheader); static const unsigned int commentLen = (unsigned int)strlen(comment); NLMISC::CSString tmp; tmp.resize( inf.getFileSize() ); inf.serialBuffer((uint8*)&tmp[0], (uint)tmp.size()); _ScenarioBody = tmp.replace("\r\n", "\n"); // Scenario without header if (_ScenarioBody.size() < headerLen ||_ScenarioBody.substr(0, headerLen) != header ) { md5 = ""; signature = ""; inf.close(); return true; } std::string::size_type endHeader = _ScenarioBody.find(slashheader, headerLen); if (endHeader == std::string::npos ) { inf.close(); return false; } std::string::size_type startHeader = headerLen; std::vector<std::string> lines; NLMISC::splitString( _ScenarioBody.substr(startHeader, endHeader - startHeader), "'\n", lines); std::vector<std::string>::const_iterator firstLine(lines.begin()), lastLine(lines.end()); std::vector<std::string> result; for (; firstLine != lastLine ; ++firstLine) { result.clear(); NLMISC::splitString(*firstLine, " = '", result); if (result.size() == 1) { result.push_back(""); } if (result.size() == 2) { if (result[0].find(comment) != std::string::npos) { //>result[1]"\\n" => "\n" NLMISC::CSString tmp = result[1]; tmp = tmp.replace("\\n", "\n"); values.push_back( std::make_pair( result[0].substr(commentLen), tmp)); } } } if (values.size() >=2 && values[0].first == "Version" && values[1].first == "Signature" && values[2].first == "HeaderMD5" && values[3].first =="BodyMD5") { std::string headerBodyMd5; std::string::size_type subHeader = _ScenarioBody.find("-- BodyMD5", startHeader); if (checkMD5) { std::string md5Id1 = NLMISC::getMD5((uint8*)(_ScenarioBody.data() + subHeader), (uint32)(endHeader - subHeader)).toString(); if (values[2].second != md5Id1 ) { return false; } std::string md5Id2 = NLMISC::getMD5((uint8*)(_ScenarioBody.data() + endHeader + slasheaderLen), (uint32)(_ScenarioBody.size() - (endHeader + slasheaderLen))).toString(); if (values[3].second != md5Id2) { return false; } } md5 = values[2].second; signature = values[1].second; } } catch(...) { _Values = values; nlwarning("Can't load scenario %s", _Filename.c_str()); return false; } _Values = values; // close the file inf.close(); return true; }