// // Created by Иван_Архипов on 31.10.2017. // #ifndef LOTRO_DAT_PATCHER_DATFILE_H #define LOTRO_DAT_PATCHER_DATFILE_H #ifdef LOTRO_DAT_EXPORTS #define LOTRO_DAT_API __declspec(dllexport) #else #define LOTRO_DAT_API __declspec(dllimport) #endif #include #include #include #include #include #include #include #include "Database.h" // Dat file names definitions #define CLIENT_LOCAL_ENGLISH 0 #define CLIENT_GENERAL 1 #define CLIENT_SOUND 2 #define CLIENT_SURFACE 3 #define CLIENT_HIGHRES 4 extern "C++" { namespace LOTRO_DAT { class BinaryData; class DatException; class SubDirectory; class Subfile; class SubfileData; enum FILE_TYPE : int { TEXT, JPG, DDS, WAV, OGG, FONT, UNKNOWN }; enum DAT_STATE { CLOSED = 1, SUCCESS_OPENED = 2, SUCCESS_SUPERBLOCK = 3, SUCCESS_DIRECTORIES = 4, SUCCESS_DICTIONARY = 5, READY = 6, UPDATED = 7 }; enum LOCALE : unsigned { ORIGINAL = 0, PATCHED = 1 }; class DatFile { friend class SubDirectory; public: DatFile(); bool InitDatFile(const std::string &filename, int dat_id); DAT_STATE DatFileState() const; virtual ~DatFile(); bool ExtractFile(long long file_id, const std::string &path = ""); bool ExtractFile(long long file_id, Database *db); int ExtractAllFilesByType(FILE_TYPE type, std::string path = ""); int ExtractAllFilesByType(FILE_TYPE type, Database *db); bool PatchFile(const char *filename, YAML::Node options); bool PatchFile(const SubfileData &data); bool PatchAllDatabase(Database *db); void WriteUnorderedDictionary(std::string path) const; long long files_number() const; BinaryData GetFileData(const Subfile *file, long long offset = 0); bool CommitChanges(); bool CloseDatFile(); private: // INIT SECTION void OpenDatFile(const char *dat_name); void ReadSuperBlock(); void MakeDirectories(); void MakeDictionary(); // READ-WRITE SECTION void ReadData(BinaryData &data, long long size, long long offset = 0, long long data_offset = 0); void WriteData(const BinaryData &data, long long size, long long offset = 0, long long data_offset = 0); // PATCH SECTION void ApplyFilePatch(Subfile *file, const BinaryData &data); std::vector > GetFragmentationJournal(); void UpdateHeader(); void UpdateSubdirectories(); void UpdateFragmentationJournal(const std::vector > &journal); // LOCALE MANAGING SECTION private: void InitLocale(LOCALE locale, const char* dict_name); void SaveLocale(LOCALE locale, const char* filename); void CommitLocales(); public: void SetLocale(LOCALE locale); bool CheckIfUpdatedByGame(); void RepairPatches(Database *db); LOCALE current_locale(); private: std::unordered_map* GetLocaleDictReference(LOCALE locale); private: LOCALE current_locale_; std::string filename_; std::unordered_map orig_dict_; std::unordered_map patch_dict_; std::unordered_map pending_patch_; private: FILE *file_handler_; SubDirectory *root_directory_; std::unordered_set patched_list; std::unordered_map dictionary_; long long constant1_; long long constant2_; long long file_size_; long long version1_; long long version2_; long long root_directory_offset_; long long fragmentation_journal_offset_; DAT_STATE dat_state_; int dat_id_; }; } } #endif //LOTRO_DAT_PATCHER_DATFILE_H