Browse Source

Major changes in DatStatus, removed .exe & .a from git

Ivan Arkhipov 5 years ago
parent
commit
cf6ad384c9

+ 1 - 4
.gitignore

@@ -21,7 +21,4 @@ debug_build/*
 release_build/*
 bin/*
 install/*
-
-
-!bin/LotRO_dat_extractor.exe
-!bin/LotRO_dat_patcher.exe
+lib/*

BIN
bin/LotRO_dat_extractor.exe


BIN
bin/LotRO_dat_patcher.exe


+ 2 - 0
include/DatSubsystems/DatFileSystem.h

@@ -56,6 +56,8 @@ namespace LOTRO_DAT {
 
         DatOperationResult<> UpdateFileInfo(const SubFile& file);
 
+        int GetInitialisedFilesNumber() const;
+
         void PrintInformaion(FILE* file);
 
         DatOperationResult<> DeInit();

+ 1 - 1
include/DatSubsystems/DatPatcher.h

@@ -35,7 +35,7 @@ namespace LOTRO_DAT {
 
         explicit DatPatcher(DatFile *datFilePtr);
 
-        DatOperationResult<> PatchFile(const SubfileData &data);
+        DatOperationResult<> PatchFile(const SubfileData &data, bool single_file = true);
 
         DatOperationResult<int> PatchAllDatabase(Database *db);
 

+ 20 - 12
include/DatSubsystems/DatStatus.h

@@ -19,6 +19,17 @@ namespace LOTRO_DAT {
 
     class DatStatus {
     public:
+        enum DAT_STATUS: int {
+            E_INITIALISING,
+            E_EXTRACTING,
+            E_PATCHING,
+            E_COMMITING,
+            E_BACKUP_CREATING,
+            E_BACKUP_RESTORING,
+            E_BACKUP_REMOVING,
+            E_FREE
+        };
+
         DatStatus() = delete;
 
         DatStatus(const DatStatus &other) = delete;
@@ -29,21 +40,17 @@ namespace LOTRO_DAT {
 
         explicit DatStatus(DatFile *datFilePtr);
 
-        void UpdatePercentage(unsigned percent);
+        void SetPercentage(unsigned percent);
 
         unsigned GetPercentage();
 
-        void UpdateStatusText(const std::string &message);
-
-        void RemoveStatusText();
+        void SetDebugMessage(const std::string &message);
 
-        std::string GetStatusText();
+        std::string GetDebugMessage();
 
-        void UpdateAdditionalMessage(const std::string &message);
+        void SetStatus(DAT_STATUS status);
 
-        void RemoveAdditionalMessage();
-
-        std::string GetAdditionalMessage();
+        DAT_STATUS GetStatus();
 
         bool CheckIfNotPatched();
 
@@ -51,9 +58,10 @@ namespace LOTRO_DAT {
 
     private:
         DatFile *dat;
-        unsigned percentage;
-        std::string status_text;
-        std::string additional_message;
+        unsigned percentage_;
+        DAT_STATUS status_;
+
+        std::string debug_message;
     };
 }
 

BIN
lib/libLotroDat.dll.a


BIN
lib/libLotroDat_static.a


+ 21 - 3
src/DatSubsystems/DatBackupManager.cpp

@@ -9,7 +9,7 @@
 #include "EasyLogging++/easylogging++.h"
 
 namespace LOTRO_DAT {
-    DatBackupManager::DatBackupManager(DatFile *datFilePtr) {}
+    DatBackupManager::DatBackupManager(DatFile *datFilePtr): dat(datFilePtr) {}
 
 
     /*!
@@ -22,7 +22,9 @@ namespace LOTRO_DAT {
 
     bool DatBackupManager::CheckIfBackupAvailable(const std::string &backup_datname) {
         DatFile file;
-        return file.Initialise(backup_datname, 0).result == SUCCESS && file.Initialized();
+        bool result = file.Initialise(backup_datname, 0).result == SUCCESS && file.Initialized();
+        file.Deinitialize();
+        return result;
     }
 
 
@@ -39,7 +41,11 @@ namespace LOTRO_DAT {
         if (!file)
             return DatOperationResult<>(ERROR, "CREATEBACKUP: cannot open file " + backup_datname);
 
+        dat->GetStatusModule().SetStatus(DatStatus::E_BACKUP_CREATING);
+        dat->GetStatusModule().SetPercentage(0);
+        dat->GetStatusModule().SetDebugMessage("Creating backup " + backup_datname + " from " + dat->GetIO().GetFilename().value);
         auto operation = CopyDatFile(*dat, file);
+        dat->GetStatusModule().ClearAll();
 
         fclose(file);
 
@@ -70,7 +76,11 @@ namespace LOTRO_DAT {
         if (!file)
             return DatOperationResult<>(ERROR, "RESTOREFROMBACKUP: cannot open file " + backup_datname);
 
+        dat->GetStatusModule().SetStatus(DatStatus::E_BACKUP_RESTORING);
+        dat->GetStatusModule().SetPercentage(0);
+        dat->GetStatusModule().SetDebugMessage("Restoring file " + dat->GetIO().GetFilename().value +  " from backup " + backup_datname);
         auto operation = CopyDatFile(backup_file, file);
+        dat->GetStatusModule().ClearAll();
 
         fclose(file);
         if (operation.result == ERROR)
@@ -89,8 +99,14 @@ namespace LOTRO_DAT {
      */
 
     DatOperationResult<> DatBackupManager::RemoveBackup(const std::string &backup_datname) {
+        dat->GetStatusModule().SetStatus(DatStatus::E_BACKUP_REMOVING);
+        dat->GetStatusModule().SetPercentage(0);
+        dat->GetStatusModule().SetDebugMessage("Removing backup file " + backup_datname);
+
         if (remove(backup_datname.c_str()) != 0)
-         LOG(INFO) << "Removed backup file " << backup_datname;
+            LOG(INFO) << "Removed backup file " << backup_datname;
+
+        dat->GetStatusModule().ClearAll();
         return DatOperationResult<>(SUCCESS);
     }
 
@@ -111,6 +127,8 @@ namespace LOTRO_DAT {
 
         BinaryData data(COPY_BLOCK_SIZE);
         for (unsigned i = 0; i < parts_count; i++) {
+            dat->GetStatusModule().SetPercentage(i * 100 / (unsigned)parts_count);
+
             auto operation = source.GetIO().ReadData(data, std::min((long long)(COPY_BLOCK_SIZE), elapsed_size), newfile_size);
             if (operation.result == ERROR)
                 return DatOperationResult<>(ERROR, "Copy failed. Read data error");

+ 38 - 6
src/DatSubsystems/DatExporter.cpp

@@ -26,11 +26,19 @@ namespace LOTRO_DAT {
 
     DatOperationResult<int> DatExporter::ExtractAllFilesByType(const FILE_TYPE &type, std::string output_directory_path) {
         int success_exported = 0;
+        int iterated_files = 0;
 
-        auto operation = dat->GetFileSystem().PerformOperationOnAllFiles([&success_exported, this, type, &output_directory_path](std::shared_ptr<SubFile>& file) -> void {
+        dat->GetStatusModule().SetStatus(DatStatus::E_EXTRACTING);
+        dat->GetStatusModule().SetPercentage(0);
+        dat->GetStatusModule().SetDebugMessage("Starting extracting files of type " + std::to_string(type));
+
+        auto operation = dat->GetFileSystem().PerformOperationOnAllFiles([&iterated_files, &success_exported, this, type, &output_directory_path](std::shared_ptr<SubFile>& file) -> void {
+            iterated_files++;
+            dat->GetStatusModule().SetPercentage(iterated_files * 100u / dat->GetFileSystem().GetInitialisedFilesNumber());
             if (file->FileType() != type)
                 return;
             SubfileData export_file = file->PrepareForExport(dat->GetFileSystem().GetFileData(file->file_id(), 8).value);
+            dat->GetStatusModule().SetDebugMessage("Extracting file " + std::to_string(file->file_id()) + " (Files by type -> directory)");
 
             if (export_file.Empty())
                 return;
@@ -45,6 +53,8 @@ namespace LOTRO_DAT {
             if (result)
                 success_exported++;
         });
+
+        dat->GetStatusModule().ClearAll();
         return DatOperationResult<int>(success_exported, SUCCESS);
     }
 
@@ -58,14 +68,22 @@ namespace LOTRO_DAT {
      */
 
     DatOperationResult<> DatExporter::ExtractFileById(long long file_id, std::string output_filename) {
+        dat->GetStatusModule().SetStatus(DatStatus::E_EXTRACTING);
+        dat->GetStatusModule().SetPercentage(0);
+        dat->GetStatusModule().SetDebugMessage("Extracting file " + std::to_string(file_id) + " to file " + output_filename);
+
         auto operation_GetFileData = dat->GetFileSystem().GetFileData(file_id, 8);
-        if (operation_GetFileData.result == ERROR)
+        if (operation_GetFileData.result == ERROR) {
+            dat->GetStatusModule().ClearAll();
             return DatOperationResult<>(ERROR, "EXTRACTFILEBYID: Can't get data for id = " + std::to_string(file_id));
-
+        }
 
         auto operation_GetFilePointer = dat->GetFileSystem().GetFile(file_id);
-        if (operation_GetFileData.result == ERROR)
-            return DatOperationResult<>(ERROR, "EXTRACTFILEBYID: Can't get pointer for id = " + std::to_string(file_id));
+        if (operation_GetFileData.result == ERROR) {
+            dat->GetStatusModule().ClearAll();
+            return DatOperationResult<>(ERROR,
+                                        "EXTRACTFILEBYID: Can't get pointer for id = " + std::to_string(file_id));
+        }
 
         std::shared_ptr<SubFile> file = operation_GetFilePointer.value;
 
@@ -78,6 +96,7 @@ namespace LOTRO_DAT {
         else
             result = export_data.binary_data.WriteToFile(output_filename + file->Extension());
 
+        dat->GetStatusModule().ClearAll();
         if (!result)
             return DatOperationResult<>(ERROR, "EXTRACTFILEBYID: Cannot write to file" + output_filename + file->Extension());
 
@@ -100,11 +119,22 @@ namespace LOTRO_DAT {
         if (!db)
             return DatOperationResult<int>(0, ERROR, "EXTRACTALLBYTYPETODB: database is nullptr");
 
+        dat->GetStatusModule().SetStatus(DatStatus::E_EXTRACTING);
+        dat->GetStatusModule().SetPercentage(0);
+        dat->GetStatusModule().SetDebugMessage("Initialising extraction of files by type " + std::to_string(type) + "to database...");
+
         int success_exported = 0;
-        auto operation = dat->GetFileSystem().PerformOperationOnAllFiles([&success_exported, this, type, db](std::shared_ptr<SubFile>& file) {
+        int iterated_files = 0;
+
+        auto operation = dat->GetFileSystem().PerformOperationOnAllFiles([&success_exported, &iterated_files, this, type, db](std::shared_ptr<SubFile>& file) {
+            iterated_files++;
+            dat->GetStatusModule().SetPercentage(iterated_files * 100u / dat->GetFileSystem().GetInitialisedFilesNumber());
+
             if (file->FileType() != type)
                 return;
 
+            dat->GetStatusModule().SetDebugMessage("Extracting file " + std::to_string(file->file_id()) + " (Files by type -> directory)");
+
             SubfileData export_file = file->PrepareForExport(dat->GetFileSystem().GetFileData(file->file_id(), 8).value);
 
             bool result = db->PushFile(export_file);
@@ -112,6 +142,8 @@ namespace LOTRO_DAT {
             if (result)
                 success_exported++;
         });
+
+        dat->GetStatusModule().ClearAll();
         return DatOperationResult<int>(success_exported, SUCCESS);
     }
 

+ 5 - 3
src/DatSubsystems/DatFileSystem.cpp

@@ -18,9 +18,7 @@ namespace LOTRO_DAT {
      * \param[in] datFilePtr Указатель на объект управляющего класса DatFile
      */
 
-    DatFileSystem::DatFileSystem(DatFile *datFilePtr) : dat(datFilePtr) {
-        LOG(INFO) << "Initialization of empty DatFileSystem";
-    }
+    DatFileSystem::DatFileSystem(DatFile *datFilePtr) : dat(datFilePtr) {}
 
     /*!
      * \author Gi1dor
@@ -494,4 +492,8 @@ namespace LOTRO_DAT {
             function(file_pair.second);
         return DatOperationResult<>();
     }
+
+    int DatFileSystem::GetInitialisedFilesNumber() const {
+        return dictionary_.size();
+    }
 }

+ 24 - 10
src/DatSubsystems/DatLocaleManager.cpp

@@ -135,10 +135,12 @@ namespace LOTRO_DAT {
      */
 
     DatOperationResult<> DatLocaleManager::SetLocale(DatLocaleManager::LOCALE locale) {
-        dat->GetStatusModule().UpdateStatusText("Смена локали");
-        dat->GetStatusModule().UpdateAdditionalMessage("Смена локали на " +
-                                                       (locale == PATCHED ? std::string(" русифицированную версию")
-                                                                          : std::string(" оригинальную версию")));
+        if (dat->GetStatusModule().GetStatus() == DatStatus::E_FREE)
+            dat->GetStatusModule().SetStatus(DatStatus::E_COMMITING);
+
+        dat->GetStatusModule().SetDebugMessage("Changing locale to " +
+                                                       (locale == PATCHED ? std::string(" patched version")
+                                                                          : std::string(" original version")));
 
         LOG(INFO) << "Setting locale to " << (locale == PATCHED ? " PATCHED" : " ORIGINAL");
         if (!dat)
@@ -146,6 +148,10 @@ namespace LOTRO_DAT {
 
         if (current_locale_ == locale) {
             LOG(INFO) << "Locale is already " << locale << ", nothing to do.";
+
+            if (dat->GetStatusModule().GetStatus() == DatStatus::E_COMMITING)
+                dat->GetStatusModule().ClearAll();
+
             return DatOperationResult<>(SUCCESS);
         }
 
@@ -168,7 +174,10 @@ namespace LOTRO_DAT {
             dat->GetFileSystem().UpdateFileInfo(file.second);
         }
         current_locale_ = locale;
-        dat->GetStatusModule().ClearAll();
+
+        if (dat->GetStatusModule().GetStatus() == DatStatus::E_COMMITING)
+            dat->GetStatusModule().ClearAll();
+
         return DatOperationResult<>(SUCCESS);
     }
 
@@ -213,8 +222,9 @@ namespace LOTRO_DAT {
      */
 
     DatOperationResult<> DatLocaleManager::DeInit() {
-        dat->GetStatusModule().UpdateStatusText("Сохранение данных");
-        dat->GetStatusModule().UpdateAdditionalMessage("Запись и обновление внутренних данных");
+        dat->GetStatusModule().SetStatus(DatStatus::E_COMMITING);
+        dat->GetStatusModule().SetDebugMessage("Unitinialising... (LocaleManager)");
+
 
         LOG(INFO) << "Committing locales...";
         if (!dat)
@@ -282,9 +292,10 @@ namespace LOTRO_DAT {
             binary_data.Append(BinaryData::FromNumber<4>(dat->GetIO().file_size + binary_data.size() + 20 * 1024 * 1024), 8);
 
             auto operation = dat->GetIO().WriteData(binary_data, binary_data.size(), new_dict_offset);
-            if (operation.result != SUCCESS)
+            if (operation.result != SUCCESS) {
+                dat->GetStatusModule().ClearAll();
                 return DatOperationResult<>(ERROR, "LOCALEDEINIT: Cannot write locales");
-
+            }
 
             dat->GetIO().WriteData(BinaryData::FromNumber<4>(new_dict_offset), 4, 300);
             dat->GetIO().WriteData(BinaryData::FromNumber<4>(current_locale_), 4, 296);
@@ -302,8 +313,11 @@ namespace LOTRO_DAT {
 
             dat->GetIO().WriteData(BinaryData::FromNumber<4>(current_locale_), 4, 296, 0);
             auto operation = dat->GetIO().WriteData(binary_data, binary_data.size(), dict_offset);
-            if (operation.result != SUCCESS)
+
+            if (operation.result != SUCCESS) {
+                dat->GetStatusModule().ClearAll();
                 return DatOperationResult<>(ERROR, "LOCALEDEINIT: Cannot write locales. ERRMSG: " + operation.msg);
+            }
         }
 
         LOG(INFO) << "Locales commited successfully";

+ 34 - 16
src/DatSubsystems/DatPatcher.cpp

@@ -14,18 +14,29 @@ namespace LOTRO_DAT {
      * Обновление файла. Записывает данные файла в dat контейнер, используя информацию в SubfileData. Если ранее файл не существовал - он не будет создан (вернёт ошибку).
      * \warning В процессе применения локаль будет автоматически переключена в положение PATCHED
      * \param[in] data Новые данные файла
+     * \param[in] single_file Флаг, который означает, что применяемый патч состоит из одного файла.
+     * Если true, то функция будет управлять состоянием DatStatus и обновлять его.
+     * Иначе эта обязанность делегируется вызывающей функции
      */
 
-    DatOperationResult<> DatPatcher::PatchFile(const SubfileData &data) {
+    DatOperationResult<> DatPatcher::PatchFile(const SubfileData &data, bool single_file) {
         auto file_id = data.options["fid"].as<long long>();
 
-        dat->GetStatusModule().UpdateStatusText("Применение патча");
-        dat->GetStatusModule().UpdateAdditionalMessage("Применение файла " + std::to_string(file_id));
+        if (single_file) {
+            dat->GetStatusModule().SetStatus(DatStatus::E_PATCHING);
+            dat->GetStatusModule().SetPercentage(0);
+        }
+
+        dat->GetStatusModule().SetDebugMessage("Patching file with id " + std::to_string(file_id));
 
         auto getfile_operation = dat->GetFileSystem().GetFile(file_id);
-        if (getfile_operation.result == ERROR)
+        if (getfile_operation.result == ERROR) {
+            if (single_file)
+                dat->GetStatusModule().ClearAll();
+
             return DatOperationResult<>(ERROR,
                                         "PATCHSUBFILEDATA: Unable to find file with id " + std::to_string(file_id));
+        }
 
         auto &file = getfile_operation.value;
 
@@ -44,20 +55,28 @@ namespace LOTRO_DAT {
             file->category = 1;
 
         auto getdata_operation = dat->GetFileSystem().GetFileData(file_id, 0);
-        if (getdata_operation.result == ERROR)
+
+        if (getdata_operation.result == ERROR) {
+            if (single_file)
+                dat->GetStatusModule().ClearAll();
+
             return DatOperationResult<>(ERROR,
                                         "PATCHSUBFILEDATA: can't get file data for id = " + std::to_string(file_id));
+        }
+
         auto &file_data = getdata_operation.value;
 
         BinaryData patch_data = file->MakeForImport(file_data, data);
 
         auto result = ApplyFilePatch(file, patch_data);
+
+        if (single_file)
+            dat->GetStatusModule().ClearAll();
+
         if (result.result == ERROR)
             return DatOperationResult<>(ERROR,
                                         "PATCHSUBFILEDATA: applyfilepatch failed for id = " + std::to_string(file_id));
 
-        dat->GetStatusModule().UpdateAdditionalMessage("Применение файла " + std::to_string(file_id) + " завершено");
-
         return DatOperationResult<>(SUCCESS);
     }
 
@@ -74,7 +93,9 @@ namespace LOTRO_DAT {
         if (!db)
             return DatOperationResult<int>(0, ERROR, "PATCHALLDATABASE: db is nullptr");
 
-        dat->GetStatusModule().UpdateStatusText("Применение патча");
+        dat->GetStatusModule().SetStatus(DatStatus::E_PATCHING);
+        dat->GetStatusModule().SetPercentage(0);
+        dat->GetStatusModule().SetDebugMessage("Patching database...");
 
         SubfileData data;
         data = db->GetNextFile();
@@ -83,22 +104,19 @@ namespace LOTRO_DAT {
         unsigned db_rows = db->CountRows();
 
         for (unsigned i = 0; i < db_rows; ++i) {
-            auto operation = PatchFile(data);
+            auto operation = PatchFile(data, false);
             if (operation.result == SUCCESS)
                 successfully_patched++;
 
-            if (dat->GetStatusModule().GetPercentage() != i * 100 / db_rows)
-                dat->GetStatusModule().UpdatePercentage(i * 100 / db_rows);
+            dat->GetStatusModule().SetPercentage(i * 100 / db_rows);
 
             data = db->GetNextFile();
         }
 
-        dat->GetStatusModule().RemoveStatusText();
-        dat->GetStatusModule().UpdateAdditionalMessage("Применение патча закончено. Успешно применено " +
-                                                       std::to_string(successfully_patched) + " из " +
-                                                       std::to_string(db_rows) + " файлов");
+        LOG(INFO) << "Database import success: patched " + std::to_string(successfully_patched) + " out of " +
+                                                       std::to_string(db_rows) + " files";
 
-        LOG(INFO) << "Successfully patched whole database";
+        dat->GetStatusModule().ClearAll();
         return DatOperationResult<int>(successfully_patched, SUCCESS);
     }
 

+ 17 - 24
src/DatSubsystems/DatStatus.cpp

@@ -2,48 +2,41 @@
 #include <DatFile.h>
 
 namespace LOTRO_DAT {
-    void DatStatus::UpdatePercentage(unsigned percent) {
-        percentage = std::min(100u, percent);
+    void DatStatus::SetPercentage(unsigned percent) {
+        percentage_ = std::min(100u, percent);
     }
 
     unsigned DatStatus::GetPercentage() {
-        return percentage;
+        return percentage_;
     }
 
-    void DatStatus::UpdateStatusText(const std::string &message) {
-        status_text = message;
+    bool DatStatus::CheckIfNotPatched() {
+        return dat->GetLocaleManager().patch_dict_.empty();
     }
 
-    void DatStatus::RemoveStatusText() {
-        status_text = "none";
+    DatStatus::DatStatus(DatFile *datFilePtr) : dat(datFilePtr), percentage_(0), status_(E_FREE) {
     }
 
-    std::string DatStatus::GetStatusText() {
-        return status_text == "none" ? "Свободен" : status_text;
+    void DatStatus::ClearAll() {
+        debug_message = "";
+        status_ = E_FREE;
     }
 
-    bool DatStatus::CheckIfNotPatched() {
-        return dat->GetLocaleManager().patch_dict_.empty();
-    }
+    void DatStatus::SetStatus(DatStatus::DAT_STATUS status) {
+        status_ = status;
 
-    DatStatus::DatStatus(DatFile *datFilePtr) : dat(datFilePtr), percentage(0), status_text("none") {
     }
 
-    void DatStatus::UpdateAdditionalMessage(const std::string &message) {
-        additional_message = message;
+    DatStatus::DAT_STATUS DatStatus::GetStatus() {
+        return status_;
     }
 
-    void DatStatus::RemoveAdditionalMessage() {
-        additional_message = "none";
-    }
+    void DatStatus::SetDebugMessage(const std::string &message) {
+        debug_message = message;
 
-    std::string DatStatus::GetAdditionalMessage() {
-        return additional_message == "none" ? "" : additional_message;
     }
 
-    void DatStatus::ClearAll() {
-        RemoveAdditionalMessage();
-        RemoveStatusText();
-        UpdatePercentage(0);
+    std::string DatStatus::GetDebugMessage() {
+        return debug_message;
     }
 }