// Ryzom - MMORPG Framework // Copyright (C) 2010 Winch Gate Property Limited // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as // published by the Free Software Foundation, either version 3 of the // License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . //----------------------------------------------------------------------------- // includes //----------------------------------------------------------------------------- // game share #include "game_share/utils.h" #include "game_share/file_description_container.h" // local #include "repository.h" //------------------------------------------------------------------------------------------------- // namespaces //------------------------------------------------------------------------------------------------- using namespace std; using namespace NLMISC; //------------------------------------------------------------------------------------------------- // constants & utilities //------------------------------------------------------------------------------------------------- NLMISC::CSString getRepositoryIndexFileName(const NLMISC::CSString& repositoryName) { return "repository_"+repositoryName+".idx"; } //----------------------------------------------------------------------------- // methods CRepository //----------------------------------------------------------------------------- bool CRepository::init(const NLMISC::CSString& name,const NLMISC::CSString& directory,const NLMISC::CSString& filespec,const NLMISC::CSString& lockFilespecs) { _Name= name.unquoteIfQuoted(); _TargetDirectory= NLMISC::CPath::standardizePath(directory.unquoteIfQuoted()); filespec.splitBySeparator('|',_Filespec); if (_Filespec.empty()) _Filespec.push_back("*"); lockFilespecs.splitBySeparator('|',_LockFilespecs); nldebug("Repository %s: %s",_Name.c_str(),_TargetDirectory.c_str()); nldebug("- filespec: %s",NLMISC::CSString().join(_Filespec,';').c_str()); nldebug("- avoid filespec: %s",NLMISC::CSString().join(_LockFilespecs,';').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); } // if we have a saved file that gives timestamp / size / checksum correspondances then load it NLMISC::CSString index; if (NLMISC::CFile::fileExists(_TargetDirectory+getRepositoryIndexFileName(_Name))) { index.readFromFile(_TargetDirectory+getRepositoryIndexFileName(_Name)); } if (!index.empty()) { nlinfo("GUSREP_Reading index file: %s",(_TargetDirectory+getRepositoryIndexFileName(_Name)).c_str()); NLMISC::CVectorSString lines; index.splitLines(lines); for (uint32 i=0;isecond.FileSize= NLMISC::CFile::getFileSize(_TargetDirectory+fileName); fileIt->second.FileTime= NLMISC::CFile::getFileModificationDate(_TargetDirectory+fileName); fileIt->second.Checksum= NLMISC::getMD5(_TargetDirectory+fileName); } void CRepository::addFileStub(NLMISC::CSString fileName) { nldebug(("Adding repository stub for file: '"+fileName+"'").c_str()); // if the name of the file that has changed contains the target directory name then crop it if (fileName.left(_TargetDirectory.size())==_TargetDirectory) { fileName=fileName.leftCrop(_TargetDirectory.size()); } // make sure the file didn't already exist in the map TFiles::iterator fileIt= _Files.end(); fileIt=_Files.find(fileName); BOMB_IF(fileIt!= _Files.end(),"Failed to add stub for file that already exists: '"+fileName+"'",return); // create the new map entry and set properties to 0 _Files[fileName].FileSize= 0; _Files[fileName].FileTime= 0; } uint32 CRepository::update() { // setup a variable to hold our return value uint32 result= 0; // make sure there are no 'avoid' files about CFileDescriptionContainer fdc; for (uint32 i=0;i<_LockFilespecs.size();++i) { fdc.addFileSpec(_LockFilespecs[i]); } if (!fdc.empty()) { // some avoid files have been found so build a list of them NLMISC::CSString s; for (uint32 i=0;isecond.FileSize,it->second.FileTime,it->second.Checksum.toString().c_str(),it->first.c_str()); } fileIndex.writeToFile(_TargetDirectory+getRepositoryIndexFileName(_Name)); } uint32 CRepository::size() const { return _Files.size(); } const CRepository::CFilesMapEntry& CRepository::operator[](const NLMISC::CSString& key) const { return const_cast(this)->_Files[key]; } CRepository::iterator CRepository::find(const NLMISC::CSString& key) { return _Files.find(key); } CRepository::const_iterator CRepository::find(const NLMISC::CSString& key) const { return _Files.find(key); } CRepository::iterator CRepository::begin() { return _Files.begin(); } CRepository::const_iterator CRepository::begin() const { return _Files.begin(); } CRepository::iterator CRepository::end() { return _Files.end(); } CRepository::const_iterator CRepository::end() const { return _Files.end(); } void CRepository::fillShortList(std::vector &files) const { // start by clearing out any previous contents in the files vector files.clear(); // iterate over the repository adding files to the files vector const_iterator it= _Files.begin(); const_iterator itEnd= _Files.end(); for (;it!=itEnd;++it) { // append a new entry to the vector vectAppend(files); // setup data for the (new) back vector entry files.back().setFileName(it->first); files.back().setChecksum(it->second.Checksum); nlinfo("sending info on file: '%s'",files.back().getFileName().c_str()); } }