Forráskód Böngészése

Implemented DatStatus module and added status info updating to DatPatcher module

Signed-off-by: Ivan Arkhipov <e1.gildor@gmail.com>
Ivan Arkhipov 5 éve
szülő
commit
7340a19723

+ 12 - 6
include/DatSubsystems/DatStatus.h

@@ -7,16 +7,13 @@ namespace LOTRO_DAT {
     class DatFile;
 
     /*!
-     * \brief Модуль работы с локалями
+     * \brief Модуль статуса dat-файла
      * \author Gi1dor
      * \date 06.07.2018
      *
-     * Класс для работы с искуственно внедряемымыми в dat контейнер копиями файлов. Позволяет независимо хранить
-     * информацию о двух версиях каждого файла, которую можно подставлять в файловую систему.
-     * В рамках русификации хранит информацию об оригинальной и русифицированной версии тех файлов, для которых
-     * существует русификация.
+     * Класс для хранения информации о выполняемых процессах в dat-файле. Позволяет отслеживать прогресс выполнения
+     * во время операций создания резервных копий, применения патчей или извлечения файлов
      *
-     * \warning Данные локалей чувствительны к обновлениям игры и могут быть стёрты после них!
      * \warning Объекты этого класса не должны создаваться отдельно! Созданием и управлением ими занимается класс DatFile
      */
 
@@ -42,12 +39,21 @@ namespace LOTRO_DAT {
 
         std::string GetStatusText();
 
+        void UpdateAdditionalMessage(const std::string &message);
+
+        void RemoveAdditionalMessage();
+
+        std::string GetAdditionalMessage();
+
         bool CheckIfNotPatched();
 
+        void ClearAll();
+
     private:
         DatFile *dat;
         unsigned percentage;
         std::string status_text;
+        std::string additional_message;
     };
 }
 

+ 27 - 8
src/DatSubsystems/DatPatcher.cpp

@@ -19,12 +19,15 @@ namespace LOTRO_DAT {
     DatOperationResult<> DatPatcher::PatchFile(const SubfileData &data) {
         auto file_id = data.options["fid"].as<long long>();
 
+        dat->GetStatusModule().UpdateStatusText("Применение патча");
+        dat->GetStatusModule().UpdateAdditionalMessage("Применение файла " + std::to_string(file_id));
+
         auto getfile_operation = dat->GetFileSystem().GetFile(file_id);
         if (getfile_operation.result == ERROR)
             return DatOperationResult<>(ERROR,
                                         "PATCHSUBFILEDATA: Unable to find file with id " + std::to_string(file_id));
 
-        auto& file = getfile_operation.value;
+        auto &file = getfile_operation.value;
 
         // If file has inactive category, then we should set it to patched state in order to commit patch and
         // then in ApplyFilePatch() function, if new category is still inactive, return dictionary to its original state;
@@ -44,7 +47,7 @@ namespace LOTRO_DAT {
         if (getdata_operation.result == ERROR)
             return DatOperationResult<>(ERROR,
                                         "PATCHSUBFILEDATA: can't get file data for id = " + std::to_string(file_id));
-        auto& file_data = getdata_operation.value;
+        auto &file_data = getdata_operation.value;
 
         BinaryData patch_data = file->MakeForImport(file_data, data);
 
@@ -53,6 +56,8 @@ namespace LOTRO_DAT {
             return DatOperationResult<>(ERROR,
                                         "PATCHSUBFILEDATA: applyfilepatch failed for id = " + std::to_string(file_id));
 
+        dat->GetStatusModule().UpdateAdditionalMessage("Применение файла " + std::to_string(file_id) + " завершено");
+
         return DatOperationResult<>(SUCCESS);
     }
 
@@ -69,19 +74,30 @@ namespace LOTRO_DAT {
         if (!db)
             return DatOperationResult<int>(0, ERROR, "PATCHALLDATABASE: db is nullptr");
 
+        dat->GetStatusModule().UpdateStatusText("Применение патча");
+
         SubfileData data;
         data = db->GetNextFile();
 
         int successfully_patched = 0;
+        unsigned db_rows = db->CountRows();
 
-        while (!data.Empty()) {
+        for (unsigned i = 0; i < db_rows; ++i) {
             auto operation = PatchFile(data);
             if (operation.result == SUCCESS)
                 successfully_patched++;
 
+            if (dat->GetStatusModule().GetPercentage() != i * 100 / db_rows)
+                dat->GetStatusModule().UpdatePercentage(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) << "Successfully patched whole database";
         return DatOperationResult<int>(successfully_patched, SUCCESS);
     }
@@ -104,7 +120,7 @@ namespace LOTRO_DAT {
             dat->GetLocaleManager().SetLocale(DatLocaleManager::PATCHED);
         }
 
-        LOG(INFO) << "Patching file with id = " << file_id;
+        //LOG(INFO) << "Patching file with id = " << file_id;
 
         if (dat->GetLocaleManager().GetLocaleFile(file_id, DatLocaleManager::ORIGINAL).result == ERROR)
             dat->GetLocaleManager().UpdateLocaleFile(DatLocaleManager::ORIGINAL, SubFile(*file));
@@ -125,11 +141,13 @@ namespace LOTRO_DAT {
         data.Append(BinaryData::FromNumber<4>(0), 0); // set additional fragments count to zero
 
         if (file_id != data.ToNumber<4>(8))
-            LOG(WARNING) << "Created data's file_id " << file_id << "doesn't match to original: " << data.ToNumber<4>(8);
+            LOG(WARNING) << "Created data's file_id " << file_id << "doesn't match to original: "
+                         << data.ToNumber<4>(8);
 
         auto operation = dat->GetIO().WriteData(data, data.size(), new_file.file_offset());
         if (operation.result == ERROR)
-            return DatOperationResult<>(ERROR, "APPLYPATCHFILE: Unable to write data for file with id " + std::to_string(file_id));
+            return DatOperationResult<>(ERROR, "APPLYPATCHFILE: Unable to write data for file with id " +
+                                               std::to_string(file_id));
 
 
         dat->GetFileSystem().UpdateFileInfo(new_file);
@@ -138,10 +156,11 @@ namespace LOTRO_DAT {
 
         // If file category is inactive, then return file header data in dictionary to original state
         if (dat->GetLocaleManager().CategoryIsInactive(new_file.category))
-            dat->GetFileSystem().UpdateFileInfo(dat->GetLocaleManager().GetLocaleFile(file_id, DatLocaleManager::ORIGINAL).value);
+            dat->GetFileSystem().UpdateFileInfo(
+                    dat->GetLocaleManager().GetLocaleFile(file_id, DatLocaleManager::ORIGINAL).value);
 
         dat->GetLocaleManager().UpdateCategory(file_id, new_file.category);
-        LOG(INFO) << "Successfully patched file with id = " << file_id;
+        //LOG(INFO) << "Successfully patched file with id = " << file_id;
 
         return DatOperationResult<>(SUCCESS);
     }

+ 19 - 1
src/DatSubsystems/DatStatus.cpp

@@ -3,7 +3,7 @@
 
 namespace LOTRO_DAT {
     void DatStatus::UpdatePercentage(unsigned percent) {
-        percentage = std::min(100u, std::max(0u, percent));
+        percentage = std::min(100u, percent);
     }
 
     unsigned DatStatus::GetPercentage() {
@@ -28,4 +28,22 @@ namespace LOTRO_DAT {
 
     DatStatus::DatStatus(DatFile *datFilePtr) : dat(datFilePtr), percentage(0), status_text("none") {
     }
+
+    void DatStatus::UpdateAdditionalMessage(const std::string &message) {
+        additional_message = message;
+    }
+
+    void DatStatus::RemoveAdditionalMessage() {
+        additional_message = "none";
+    }
+
+    std::string DatStatus::GetAdditionalMessage() {
+        return additional_message == "none" ? "" : additional_message;
+    }
+
+    void DatStatus::ClearAll() {
+        RemoveAdditionalMessage();
+        RemoveStatusText();
+        UpdatePercentage(0);
+    }
 }