// 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 . #ifndef BNP_PATCH_H #define BNP_PATCH_H //----------------------------------------------------------------------------- // includes //----------------------------------------------------------------------------- #include "nel/misc/types_nl.h" #include "nel/misc/common.h" #include "nel/misc/debug.h" #include "nel/misc/sha1.h" #include "persistent_data.h" //----------------------------------------------------------------------------- // class IVersionNumberGenerator //----------------------------------------------------------------------------- class IVersionNumberGenerator { public: // reserver the next version number (if we don't already have one) virtual void grabVersionNumber() =0; // get the current reserved version number // return ~0u if none reserved virtual uint32 getPackageVersionNumber() =0; }; //----------------------------------------------------------------------------- // class CBNPFileVersion //----------------------------------------------------------------------------- class CBNPFileVersion { public: DECLARE_PERSISTENCE_METHODS public: // ctor CBNPFileVersion(); // setup record contents from a file name and version number // returns false if the file didn't exist bool setup(const std::string &fileName, uint32 versionNumber); void setVersionNumber(uint32 nVersionNumber); void set7ZipFileSize(uint32 n7ZFileSize); void setPatchSize(uint32 nPatchSize); void setTimeStamp(uint32 nTimeStamp); // accessors uint32 getVersionNumber() const; uint32 getTimeStamp() const; uint32 get7ZFileSize() const; uint32 getFileSize() const; uint32 getPatchSize() const; CHashKey getHashKey() const; // == operator bool operator==(const CBNPFileVersion& other) const; // != operator bool operator!=(const CBNPFileVersion& other) const; private: uint32 _VersionNumber; uint32 _FileTime; uint32 _FileSize; uint32 _7ZFileSize; uint32 _PatchSize; std::vector _HashKey; }; //----------------------------------------------------------------------------- // class CBNPFile //----------------------------------------------------------------------------- class CBNPFile { public: DECLARE_PERSISTENCE_METHODS public: // ctor CBNPFile(); // add a version to the file // returns false if file not found bool addVersion(const std::string& bnpDirectory, const std::string& refDirectory, IVersionNumberGenerator& version); // get the last existing version number less than or equal to parameter in the file's history uint32 getLatestVersionNumber(uint32 max=~0u) const; // get number of versions in the versions vector uint32 versionCount() const; // get the nth version from the version vector const CBNPFileVersion& getVersion(uint32 idx) const; CBNPFileVersion& getVersion(uint32 idx); // _FileName write accessor void setFileName(const std::string& fileName); // _FileName read accessor const std::string& getFileName() const; // _Incrmental flag write accessor void setIncremental(bool value); // _Incrmental flag read accessor bool isIncremental(); private: bool _IsIncremental; std::string _FileName; std::vector _Versions; }; //----------------------------------------------------------------------------- // class CBNPFileSet //----------------------------------------------------------------------------- class CBNPFileSet { public: DECLARE_PERSISTENCE_METHODS public: // add a version to the file // returns highest version number in files after operation uint32 addVersion(const std::string& bnpDirectory, const std::string& refDirectory, IVersionNumberGenerator& version); // look through the refferenced files for the highest version number uint32 getVersionNumber() const; void clear(); uint32 fileCount() const; const CBNPFile& getFile(uint32 idx) const; const CBNPFile* getFileByName(const std::string& fileName) const; CBNPFile& getFile(uint32 idx); CBNPFile* getFileByName(const std::string& fileName); void addFile(const std::string& fileName,bool isIncremental=true); void removeFile(const std::string &filename); private: std::vector _Files; }; //----------------------------------------------------------------------------- // class CBNPCategory //----------------------------------------------------------------------------- class CBNPCategory { public: DECLARE_PERSISTENCE_METHODS public: // ctor CBNPCategory(); const std::string& getName() const; void setName(const std::string& name); void setOptional(bool value); bool isOptional() const; void setUnpackTo(const std::string &pathName); const std::string &getUnpackTo() const; void setIncremental(bool value); bool isIncremental() const; void setCatRequired(const std::string &cat); const std::string &getCatRequired() const; void setHidden(bool value); bool isHidden() const; uint32 fileCount() const; const std::string& getFile(uint32 idx) const; void addFile(const std::string& fileName); bool hasFile(const std::string &fileName) const; private: std::string _Name; bool _IsOptional; std::string _UnpackTo; bool _IsIncremental; std::string _CatRequired; // Name of the category required bool _Hidden; // If optional but not displayed std::vector _Files; }; //----------------------------------------------------------------------------- // class CBNPCategorySet //----------------------------------------------------------------------------- class CBNPCategorySet { public: DECLARE_PERSISTENCE_METHODS public: void clear(); // file accessors uint32 fileCount() const; const std::string& getFile(uint32 idx) const; // category accessors uint32 categoryCount() const; CBNPCategory& getCategory(uint32 idx); const CBNPCategory& getCategory(uint32 idx) const; void deleteCategory(uint32 index); // check whether a named category exists and add a new one if need be const CBNPCategory* getCategory(const std::string& categoryName) const; CBNPCategory* getCategory(const std::string& categoryName, bool addIfNotExist); void addFile(const std::string& categoryName,const std::string& fileName); // lookup a file and check whether it's flagged as non-incremental bool isFileIncremental(const std::string& fileName) const; const CBNPCategory* getCategoryFromFile(const std::string &fileName) const; private: std::vector _Category; }; //----------------------------------------------------------------------------- // class CProductDescriptionForClient //----------------------------------------------------------------------------- // This object is created by the patch generator, stored to a bin file, and // used at patch time on the client to identify the required patch set class CProductDescriptionForClient { public: DECLARE_PERSISTENCE_METHODS public: void clear(); // a few read and write accessors used for getting and setting parts of the complete data set void setCategories(CPersistentDataRecord &pdr); void setFiles(CPersistentDataRecord &pdr); void getCategories(CPersistentDataRecord &pdr); void getFiles(CPersistentDataRecord &pdr); // load from file bool load(const std::string& filePath); const CBNPCategorySet &getCategories() { return _Categories; } const CBNPFileSet &getFiles() { return _Files; } void serial(NLMISC::IStream &f); private: CBNPCategorySet _Categories; CBNPFileSet _Files; }; //================================================================================================ //================================================================================================ //================================================================================================ //================================================================================================ //#if 0 // ////----------------------------------------------------------------------------- //// class CBNPPatchDescription ////----------------------------------------------------------------------------- //// a little object used to describe patches in CBNPUnpatcher class // //class CBNPPatchDescription //{ //public: // // ctor // CBNPPatchDescription(const std::string& targetFileName,uint32 version,uint32 size,bool requiresDownload); // // // read accessors // const std::string& getTargetFileName() const { return _TargetFileName; } // const std::string& getRefFileName() const { return _TargetFileName; } // uint32 getVersion() const { return _Version; } // uint32 getSize() const { return _Size; } // bool getRequiresDownload() const { return _RequiresDownload; } // // // accessors for the patcher // std::string getPatchFileName() const; // //private: // std::string _TargetFileName; // uint32 _Version; // uint32 _Size; // bool _RequiresDownload; //}; // // ////----------------------------------------------------------------------------- //// class CBNPUnpatcher ////----------------------------------------------------------------------------- //// This class, derived from CProductDescriptionForClient is used on the client //// to read and interpret the index file retrieved from the patch server // //class CBNPUnpatcher: public CProductDescriptionForClient //{ //public: // //------------------------------------------------------------------------- // // initialisation // // // ctor - initialises paths etc // // also call scanForFiles() // CBNPUnpatcher(const std::string& productName,uint32 version,const std::string& appRootDirectory,const std::string& patchDirectory); // // // get the version number for this index file (deduced from the highest // // version number found in the file list that it contains) and compare to // // the version number supplied in the ctor // bool isIndexUpToDate(); // // // get hold of the download record for the index file // CBNPPatchDescription getIndexFileDownloadDescription(); // // // //------------------------------------------------------------------------- // // accessors for directories // // std::string getRootDirectory() const; // std::string getDataDirectory() const; // std::string getPatchDirectory() const; // // // //------------------------------------------------------------------------- // // accessors for retrieving info on required patches // // // return true if the installed product is completely up to date (no new patches exist) // bool isUpToDate(); // // // return true if mandatory patches exist that have not been applied // bool isPatchMandatory(); // // // return true if there are no mandatory patches but there are optional patches // bool isPatchOptional(); // // // return true if patches exist that have not been applied for the // // optional categories that have been flagged as selected // bool isPatchRequired(); // // // return true if it's necessary to download patches for the selected options // bool isDownloadRequired(); // // // return true if it's necessary to download the next patch that needs to be applied (in order) // bool isNextPatchDownloadRequired(); // // // //------------------------------------------------------------------------- // // crunching routines // // // scan the directories for files - identifies the set of required patches // // and also the set of these patches that is missing from the patch directory // void scanForFiles(); // // // apply the mandatory and selected optional patches // // nlerror if isDownloadRequired() is not false // void applyPatches(); // // // apply the next patch (in order) // // nlerror if isNextPatchDownloadRequired() is not false // void applyNextPatch(); // // // //------------------------------------------------------------------------- // // managing the set of selected optional patch categories // // // get the names of all optional categories // void getAllOptionalCategories(std::vector& result); // // // get the names of the optional categories that require patching // void getPatchableOptionalCategories(std::vector& result); // // // select or unselect an optional package // void setOptionalCategorySelectFlag(const std::string& categoryName, bool value); // // // select or unselect all optional packages // void setAllOptionalCategorySelectFlags(bool value); // // // //------------------------------------------------------------------------- // // getting lists of applicable patches // // // get the ordered list of mandatory + optional patches that need to be applied to update selected packages // void getSelectedPatches(std::vector& result); // // // get the ordered list of optional patches that need to be applied to update selected packages // void getSelectedOptionalPatches(std::vector& result); // // // get the ordered list of patches that need to be applied for a minimum update // void getMandatoryPatches(std::vector& result); // // // get an ordered list of the patches that need to be applied for a full update // void getAllPatches(std::vector& result); // // // get the name of the next patch that needs to be applied (for progress display) // const std::string& getNextPatchName(); // // // get the patch description for the next patch to apply // CBNPPatchDescription getNextPatch(); // // // get the list of patches required for selected options that are not present in the local patch directory // void getSelectedDownloadPatches(std::vector& result); // // // get the list of all patches that are not present in the local patch directory // void getAllDownloadPatches(std::vector& result); // // //private: // // //------------------------------------------------------------------------- // // private utility routines // // // workhorse routine used by isPatchMandatory(), isPatchOptional() & isPatchRequired() // bool _isPatch(bool isBySelectionFlag,bool isOptionalFlag=false); // // // //------------------------------------------------------------------------- // // private data // // std::string _AppRootDirectory; // std::string _PatchDirectory; // std::string _ProductName; // uint32 _Version; // std::set _SelectedCategories; //}; // //#endif #endif