Browse Source

Implemented tristate patch mark instead of locale dict version

Ivan Arkhipov 4 years ago
parent
commit
d518d28b13
1 changed files with 59 additions and 49 deletions
  1. 59 49
      src/DatSubsystems/DatLocaleManager.cpp

+ 59 - 49
src/DatSubsystems/DatLocaleManager.cpp

@@ -35,9 +35,10 @@ namespace LOTRO_DAT {
      * 4 * inactive_categories.size()   bytes for inactive_categories data
      * ========================================
      * Помимо этого:
-     * 0x128-0x12C - 0, если .dat файл не был изменен библиотекой или активна локаль ORIGINAL и обновление клиентом игры не испортит .dat file
-     *               Версия словаря локалей, если активна локаль PATCHED  и обновление клиентом игры может испортить .dat file
-     *               Отличие значения в 0x128 от версии словаря локалей => файл ресурсов мог быть повреждён или структура устарела и необходимо перекачать
+     * 0x128-0x12C - 0, если .dat файл не был изменен библиотекой, обновление клиентом игры не испортит .dat file
+     *               1, если активна локаль ORIGINAL, обновление клиентом игры не испортит .dat file
+     *               2, если активна локаль PATCHED, обновление клиентом игры может испортить .dat file
+     *
      * 0x12C-0x130 - Офсет начала словаря локализации (offset)
      *
      * \warning Если flag != 0 и offset == 0 - то dat файл считается повреждённым. Проверка осуществляется функцией CheckLocaleCorrect
@@ -64,7 +65,7 @@ namespace LOTRO_DAT {
         if (!operation.result) {
             dict_offset_ = 0;
             dict_size_ = 0;
-            LOG(WARNING) << "LOCALEINIT: Locale offset is incorrect, skipping initialization";
+            LOG(WARNING) << "LOCALEINIT: Locale offset is incorrect, skipping initialization.";
             return DatOperationResult<>(SUCCESS);
         }
 
@@ -76,14 +77,14 @@ namespace LOTRO_DAT {
         if (dict_version != DAT_LOCALE_DICT_VERSION) {
             dict_offset_ = 0;
             dict_size_ = 0;
-            LOG(WARNING) << "LOCALEINIT: Locale dictionary version is outdated, passing it.";
+            LOG(WARNING) << "LOCALEINIT: Locale dictionary version is outdated, skipping initialization.";
             return DatOperationResult<>(SUCCESS);
         }
 
         if (dat_file_header_hash != dat->GetIO().GetHeaderHash()) {
             dict_offset_ = 0;
             dict_size_ = 0;
-            LOG(WARNING) << "LOCALEINIT: Locale header hash does not match real dat file header hash. Passing initialization!";
+            LOG(WARNING) << "LOCALEINIT: Locale header hash does not match real dat file header hash, skipping initialization.";
             return DatOperationResult<>(SUCCESS);
         }
 
@@ -94,13 +95,21 @@ namespace LOTRO_DAT {
         std::string hi = std::string((char *) (hi_data.data()));
         if (hi != "Hi from Gi1dor!") {
             dict_offset_ = 0;
-            LOG(WARNING) << "LOCALEINIT: couldn't receive Hello, skipping initialization";
+            dict_size_ = 0;
+            LOG(WARNING) << "LOCALEINIT: couldn't receive Hello, skipping initialization.";
             return DatOperationResult<>(SUCCESS);
         }
 
         int offset = 15;
         BinaryData current_locale_data = dicts_data.CutData(offset, offset + 4) + BinaryData("\0", 1);
         std::string locale((char *) (current_locale_data.data()));
+        if (locale != "PATC" && locale != "ORIG") {
+            dict_offset_ = 0;
+            dict_size_ = 0;
+            LOG(WARNING) << "LOCALEINIT: locale status in dict seems incorrect, skipping initialization.";
+            return DatOperationResult<>(SUCCESS);
+        }
+
         current_locale_ = (locale == "PATC" ? PATCHED : ORIGINAL);
         offset += 4;
         
@@ -321,6 +330,8 @@ namespace LOTRO_DAT {
     /*!
      * \Author Gi1dor
      * \date 06.07.2018
+     * TODO: update descr
+     * 
      * Осуществляет проверку корректности dat файла с позиции локалей
      * Файл считается некорректным, если активной является альтернативная локаль, причём нет возможности вернуть оригинальную (блок локалей неверный/повреждён)
      * Байты 0x128-0x12C равны 0, если на момент пользования патчером активна оригинальная локаль, и DatIO::file_size, если нет
@@ -328,38 +339,42 @@ namespace LOTRO_DAT {
      */
 
     bool DatLocaleManager::CheckLocaleCorrect() {
-        BinaryData locale_dict_version_data(4); // 0, если файл не был пропатчен или активна локаль ORIGINAL,
-                                                // DAT_LOCALE_DICT_VERSION иначе 
-
-        dat->GetIO().ReadData(locale_dict_version_data, 4, 296);
-        uint32_t locale_dict_version = locale_dict_version_data.ToNumber<4>(0);
+        BinaryData patch_mark_data(4);
+        dat->GetIO().ReadData(patch_mark_data, 4, 296);
+        uint32_t patch_mark = patch_mark_data.ToNumber<4>(0);
 
         BinaryData locale_offset_data(4);
         dat->GetIO().ReadData(locale_offset_data, 4, 300);
         long long locale_offset = locale_offset_data.ToNumber<4>(0);
 
-        if (locale_offset == 0) {
-            if (locale_dict_version == 0) {
-                LOG(INFO) << "CHCKLOCALECORRECT: No file patch info found, check successfull!";
-                return true;
-            } else {
-                LOG(ERROR) << "CHCKLOCALECORRECT: Locale offset is null, but patch mark exists!";
-                return false;
-            }
+        LOG(INFO) << "CHCKLOCALECORRECT: patch mark = " << patch_mark << ", locale_offset =  " << locale_offset;
+        
+        if (patch_mark == 0 && locale_offset == 0) {
+            LOG(INFO) << "CHCKLOCALECORRECT: No file patch info found, check successfull!";
+            return true;
+        }
+
+        if (patch_mark == 0 && locale_offset != 0) {
+            LOG(ERROR) << "CHCKLOCALECORRECT: Locale dict exists, but patch mark is incorrect!";
+            return false;
+        }
+
+        if (patch_mark != 0 && locale_offset == 0) {
+            LOG(ERROR) << "CHCKLOCALECORRECT: Locale offset is null, but patch mark exists!";
+            return false;
+        }
+
+        if (patch_mark == 1) {
+            LOG(INFO) << "CHCKLOCALECORRECT: Patch mark is original, so skipping dat locale dict correctness check";
+            return true;
         }
 
         BinaryData locale_dict_header(16 + 15 + 4);
         auto operation = dat->GetIO().ReadData(locale_dict_header, 16 + 15 + 4, locale_offset);
-        LOG(INFO) << std::string((char* )BinaryData(locale_dict_header + BinaryData("\0", 1)).data());
 
         if (!operation.result) {
-            if (locale_dict_version != 0) {
-                LOG(ERROR) << "CHCKLOCALECORRECT: incorrect locale offset (cannot read data at offset" << locale_offset << ")";
-                return false;
-            } else {
-                LOG(WARNING) << "CHCKLOCALECORRECT: incorrect locale offset (cannot read data at offset" << locale_offset << "), but patch mark is not standing, so passing by";
-                return true;
-            }
+            LOG(ERROR) << "CHCKLOCALECORRECT: incorrect locale offset (cannot read data at offset" << locale_offset << ")";
+            return false;
         }
 
         long long dict_version = locale_dict_header.ToNumber<4>(4);
@@ -375,34 +390,29 @@ namespace LOTRO_DAT {
             return false;
         }
 
-        if (locale_string != "PATC" && locale_string != "ORIG") {
+        if (locale_string != "PATC" && locale_string != "ORIG" && patch_mark != 2) {
             LOG(ERROR) << "CHCKLOCALECORRECT: Data in locales' dictionary is incorrect (current locale mark is invalid)." << locale_string;
             return false;
         }
 
         LOCALE file_locale = (locale_string == "PATC" ? PATCHED : ORIGINAL);
 
-        if (file_locale == ORIGINAL && locale_dict_version != 0) {
-            LOG(ERROR) << "CHCKLOCALECORRECT: Locale from dictionary is original, but patched mark already exists!";
-            return false;
-        }
-
-        if (file_locale == PATCHED && locale_dict_version != DAT_LOCALE_DICT_VERSION) {
-            LOG(ERROR) << "CHCKLOCALECORRECT: Locale from dictionary is PATCHED, but patched mark version is incorrect!";
+        if ((file_locale == ORIGINAL && patch_mark != 1) || (file_locale == PATCHED && patch_mark != 2)) {
+            LOG(ERROR) << "CHCKLOCALECORRECT: Locale from dictionary does not match patch mark in header!";
             return false;
         }
 
-        if (hi_string != "Hi from Gi1dor!" && locale_dict_version != 0) {
+        if (hi_string != "Hi from Gi1dor!") {
             LOG(ERROR) << "CHCKLOCALECORRECT: Data in locales' dictionary is incorrect (couldn't receive 'Hello').";
             return false;
         }
-        
-        if (dat_header_hashsum != dat->GetIO().GetHeaderHash() && locale_dict_version != 0) {
+
+        if (dat_header_hashsum != dat->GetIO().GetHeaderHash()) {
             LOG(ERROR) << "CHCKLOCALECORRECT: Dat header checksum from header does not match dat header checksum from locale dictionary!";
             return false;
         }
 
-        LOG(INFO) << "CHCKLOCALECORRECT: All checks passed successfully!";
+        LOG(INFO) << "CHCKLOCALECORRECT: All checks passed successfully, no critical errors found!";
         return true;
     }
 
@@ -466,9 +476,9 @@ namespace LOTRO_DAT {
      * 4 * inactive_categories.size()   bytes for inactive_categories data
      * ========================================
      * Помимо этого:
-     * 0x128-0x12C - 0, если .dat файл не был изменен библиотекой или активна локаль ORIGINAL и обновление клиентом игры не испортит .dat file
-     *               Версия словаря локалей, если активна локаль PATCHED  и обновление клиентом игры может испортить .dat file
-     *               Отличие значения в 0x128 от версии словаря локалей => файл ресурсов мог быть повреждён или структура устарела и необходимо перекачать
+     * 0x128-0x12C - 0, если .dat файл не был изменен библиотекой, обновление клиентом игры не испортит .dat file
+     *               1, если активна локаль ORIGINAL, обновление клиентом игры не испортит .dat file
+     *               2, если активна локаль PATCHED, обновление клиентом игры может испортить .dat file
      *
      * 0x12C-0x130 - Офсет начала словаря локализации
      */
@@ -546,10 +556,10 @@ namespace LOTRO_DAT {
 
             dat->GetIO().WriteData(BinaryData::FromNumber<4>(new_dict_offset), 4, 300);
 
-            if (current_locale_ == PATCHED) {
-                dat->GetIO().WriteData(BinaryData::FromNumber<4>(DAT_LOCALE_DICT_VERSION), 4, 296);
+            if (current_locale_ == ORIGINAL) {
+                dat->GetIO().WriteData(BinaryData::FromNumber<4>(1), 4, 296);
             } else {
-                dat->GetIO().WriteData(BinaryData::FromNumber<4>(0), 4, 296);
+                dat->GetIO().WriteData(BinaryData::FromNumber<4>(2), 4, 296);
             }
             dat->GetFileSystem().patched_file_end += binary_data.size();
 
@@ -564,10 +574,10 @@ namespace LOTRO_DAT {
             binary_data.Append(BinaryData::FromNumber<4>(dat->GetFileSystem().patched_file_end), 8);
             binary_data.Append(BinaryData::FromNumber<4>(dat->GetIO().GetHeaderHash()), 12);
 
-            if (current_locale_ == PATCHED) {
-                dat->GetIO().WriteData(BinaryData::FromNumber<4>(DAT_LOCALE_DICT_VERSION), 4, 296);
+            if (current_locale_ == ORIGINAL) {
+                dat->GetIO().WriteData(BinaryData::FromNumber<4>(1), 4, 296);
             } else {
-                dat->GetIO().WriteData(BinaryData::FromNumber<4>(0), 4, 296);
+                dat->GetIO().WriteData(BinaryData::FromNumber<4>(2), 4, 296);
             }
 
             auto operation = dat->GetIO().WriteData(binary_data, binary_data.size(), dict_offset_);