Rev 130 | Rev 160 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed
#include "OriginalFiles.h"#include "File.h"#include "Logging/Log.h"#include "BaseFile.h"#include "spk.h"//#include "ProgressInfo.h"namespace SPK {void AddLogEntry(int type, CyString args, CyStringList *errors){if ( errors ) errors->PushBack(args, ERRORLOG_OLD(type));}COriginalFiles::COriginalFiles(const Utils::String &dir) : _sDir(dir){}COriginalFiles::~COriginalFiles(void){reset();}int COriginalFiles::count() const{return _lFiles.size();}/*** Check for original file** Checks if the file is an original file or not*/bool COriginalFiles::isOriginal(C_File *f) const{if ( _getFile(f) )return true;return false;}void COriginalFiles::installed(CBaseFile *package){for ( CListNode<C_File> *oNode = _lFiles.Front(); oNode; oNode = oNode->next() ){C_File *of = oNode->Data();for ( CListNode<C_File> *checkNode = package->GetFileList()->Front(); checkNode; checkNode = checkNode->next() ){C_File *f = checkNode->Data();// match the same filetypeif ( of->GetFileType() != f->GetFileType() )continue;// same fileif ( of->GetFilename().Compare(f->GetFilename()) )_storeOverride(f);}}}void COriginalFiles::backup(CBaseFile *package, CyStringList *errors){// backup any original files before installingCLog::log(CLog::Log_Install, 3, "Checking for any original files to backup");CDirIO oDir(_sDir + "/PluginManager/Original");for ( CListNode<C_File> *oNode = _lFiles.Front(); oNode; oNode = oNode->next() ){C_File *of = oNode->Data();for ( CListNode<C_File> *checkNode = package->GetFileList()->Front(); checkNode; checkNode = checkNode->next() ){C_File *f = checkNode->Data();// match the same filetypeif ( of->GetFileType() != f->GetFileType() )continue;// same fileif ( of->GetFilename().Compare(f->GetFilename()) ){// check if original file already exists (assume already backed up)if ( !backupFile(of, errors) )continue;break;}}}}bool COriginalFiles::backupFile(C_File *f, CyStringList *errors){Utils::String newDir = "PluginManager/Original/" + f->getDirectory(NULL);CDirIO oDir(_sDir);if ( oDir.exists(newDir + "/" + f->GetFilename().ToString()) )return true;// make sure the directory exisstsif ( !oDir.exists(newDir) ){if ( !oDir.Create(newDir) ){CLog::logf(CLog::Log_Install, 2, "Unable to create directory to backup original files, %s", newDir.c_str());AddLogEntry(SPKINSTALL_CREATEDIRECTORY_FAIL, newDir, errors);return false;}CLog::logf(CLog::Log_Install, 2, "Created new directory, %s", newDir.c_str());AddLogEntry(SPKINSTALL_CREATEDIRECTORY, newDir, errors);}// now lets copy the fileCFileIO CopyFile(f->filePointer());if ( CopyFile.copy(oDir.File(newDir + "/" + f->GetFilename().ToString()).ToString()) ){CLog::logf(CLog::Log_Install, 2, "Original file: %s has been backed up", f->GetNameDirectory(NULL).c_str());AddLogEntry(SPKINSTALL_ORIGINAL_BACKUP, f->GetNameDirectory(NULL), errors);return true;}else{CLog::logf(CLog::Log_Install, 2, "Failed to backup the original file: %s", f->GetNameDirectory(NULL).c_str());AddLogEntry(SPKINSTALL_ORIGINAL_BACKUP_FAIL, f->GetNameDirectory(NULL), errors);return false;}}bool COriginalFiles::doBackup(C_File *f, CyStringList *errors){bool backed = false;C_File *of = this->_getFile(f);if ( of ) {// check if the orignal file is already backed upif ( !CFileIO::Exists(_sDir + "/PluginManager/Original/" + f->GetNameDirectory(NULL).ToString()) ){// lets back up the file nowbacked = this->backupFile(of, errors);}}return backed;}int COriginalFiles::restoreAll(CProgressInfo *info, int files, int max){for ( CListNode<C_File> *oNode = _lFiles.Front(); oNode; oNode = oNode->next() ){// update the progressif ( info ) info->UpdateProgress(files, max);++files;C_File *f = oNode->Data();CFileIO of(_sDir + "/PluginManager/Original/" + f->GetNameDirectory(NULL).ToString());if ( of.exists() )of.Rename(_sDir + "/" + f->GetNameDirectory(NULL).ToString());delete oNode->Data();}_lFiles.clear();return files;}bool COriginalFiles::restoreFile(C_File *f, CyStringList *errors){bool original = false;// check if its an original file and restoreif ( this->isOriginal(f) ){CFileIO of(_sDir + "/PluginManager/Original/" + f->GetNameDirectory(NULL).ToString());if ( of.exists() ){original = true;if ( of.Rename(_sDir + "/" + f->GetNameDirectory(NULL).ToString()) )AddLogEntry(SPKINSTALL_ORIGINAL_RESTORE, f->GetNameDirectory(NULL), errors);elseAddLogEntry(SPKINSTALL_ORIGINAL_RESTORE_FAIL, f->GetNameDirectory(NULL), errors);CFileIO backupFile(_sDir + "/PluginManager/Original/Replacements/" + f->GetNameDirectory(NULL).ToString());if ( backupFile.exists() ) backupFile.remove();}}return original;}void COriginalFiles::parse(const Utils::String &data){C_File *uf = new C_File();uf->setFileType((FileType)data.token(" ", 1).toLong());// Extra files also contain a directory, so make sure we split that upif (uf->fileType() == FILETYPE_EXTRA ){uf->SetDir(data.tokens(" ", 2).tokens(":", 2));uf->SetFilename(data.tokens(" ", 2).token(":", 1));}elseuf->SetFilename(data.tokens(" ", 2));// set the complete filename, GetNameDirectory returns the directory based on the file typeuf->SetFilename(_sDir + "/" + uf->GetNameDirectory(NULL).ToString());_lFiles.push_back(uf);}void COriginalFiles::update(bool bForce, const CLinkList<C_File> *pFiles){if ( _lFiles.empty() || bForce ){_storeFiles(FILETYPE_SCRIPT, "scripts", pFiles);_storeFiles(FILETYPE_TEXT, "t", pFiles);_storeFiles(FILETYPE_SOUND, "soundtrack", pFiles);_storeFiles(FILETYPE_EXTRA, "mov", pFiles);}}bool COriginalFiles::writeData(CyStringList *lines){bool addAny = false;if ( !_lFiles.empty() ){for ( CListNode<C_File> *node = _lFiles.Front(); node; node = node->next() ){C_File *uf = node->Data();Utils::String uString = "Original: ";uString += Utils::String::Number((long)uf->GetFileType()) + " ";uString += uf->GetFilename().ToString();// add the directory for Extra filesif ( uf->GetFileType() == FILETYPE_EXTRA && !uf->GetDir().Empty()){uString += ":";uString += uf->GetDir().ToString();}lines->PushBack(CyString(uString));addAny = true;}}return addAny;}void COriginalFiles::reset(){_lFiles.MemoryClear();}/*** Update original files list** Scan the current directory for any fiels that are already there, ie ones that have not been installed* Original files should be all the scripts/sounds, etc that are in an unmodified game directory** Save list of files and check if any packages overright these files* Any file that gets overrighten from this list will automatically be backed up, and restored once the packages are removed*/void COriginalFiles::_storeFiles(FileType filetype, const Utils::String &searchPath, const CLinkList<C_File> *pFiles){Utils::String ext = "pck";switch ( filetype ){case FILETYPE_SOUND:ext = "mp3";break;}CDirIO Dir(_sDir + "/" + searchPath);CyStringList *files = Dir.DirList();if ( !files )return;for ( SStringList *node = files->Head(); node; node = node->next ){CFileIO File(Dir.File(node->str));if ( File.extension().Compare(ext) )_add(filetype, File.filename(), searchPath, pFiles);}delete files;}/*** Get original file** Finds a matching original file entry and returns it*/C_File *COriginalFiles::_getFile(C_File *file) const{if ( !file ) return NULL;for ( CListNode<C_File> *node = _lFiles.Front(); node; node = node->next() ){C_File *of = node->Data();// not of the same file typeif ( of->GetFileType() != file->GetFileType() )continue;// same file name, must be the same fileif ( of->GetFilename().Compare(file->GetFilename()) )return of;}return NULL;}/*** Adds a file onto the original files list** Checks if it already exists so we dont create multiples*/void COriginalFiles::_add(FileType filetype, const Utils::String &filename, const Utils::String &searchPath, const CLinkList<C_File> *pFiles){// dont add plugin manager as original filesif ( filetype == FILETYPE_SCRIPT && filename.isin("!init.pmanager") )return;// first check if a matching one existsfor ( CListNode<C_File> *node = _lFiles.Front(); node; node = node->next() ){C_File *file = node->Data();if ( file->GetFileType() != filetype )continue;if ( file->GetFilename().Compare(CyString(filename)) )return;}// check that no packages are currently using them either, not original if being used alreadyfor ( CListNode<C_File> *node = pFiles->Front(); node; node = node->next() ){C_File *file = node->Data();if ( file->GetFileType() != filetype )continue;if ( file->GetFilename().Compare(CyString(filename)) )return;}// add the file entry to the listC_File *of = new C_File(filename);of->setFileType(filetype);if (filetype == FILETYPE_EXTRA)of->SetDir(searchPath);of->SetFilename(_sDir + "/" + of->GetNameDirectory(NULL).ToString());_lFiles.push_back(of);}void COriginalFiles::_storeOverride(C_File *f){CDirIO oDir(_sDir + "/PluginManager/Original/Replacements");if ( !oDir.exists() ) oDir.Create();CFileIO file(oDir.file(f->GetNameDirectory(NULL).ToString()));if ( !file.GetDirIO().exists() ) file.GetDirIO().Create();CFileIO fromFile(f->GetFilePointer());fromFile.copy(file.fullFilename(), true);}}