|
@@ -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);
|
|
|
-
|
|
|
-
|
|
|
- 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_);
|