|
@@ -53,8 +53,13 @@ namespace LOTRO_DAT {
|
|
|
long long locale_offset = locale_offset_data.ToNumber<4>(0);
|
|
|
|
|
|
if (locale_offset == 0 || locale_offset + 8 >= dat->GetIO().GetActualDatSize().value) {
|
|
|
- LOG(INFO) << "Dictionary offset is empty or incorrect. Passing.";
|
|
|
- return DatOperationResult<>();
|
|
|
+ if (CheckLocaleCorrect()) {
|
|
|
+ LOG(INFO) << "Dictionary offset is empty or incorrect. Passing.";
|
|
|
+ return DatOperationResult<>();
|
|
|
+ } else {
|
|
|
+ return DatOperationResult<>(ERROR,
|
|
|
+ "Locale dict is incorrect, through patched mark is standing. Dat file may be corrupted");
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
BinaryData locale_info(12);
|
|
@@ -68,10 +73,11 @@ namespace LOTRO_DAT {
|
|
|
if (CheckLocaleCorrect())
|
|
|
return DatOperationResult<>(SUCCESS);
|
|
|
else
|
|
|
- return DatOperationResult<>(ERROR, "Version of locales' dictionary is incorrect, through patched mark is standing. Dat file may be corrupted");
|
|
|
+ return DatOperationResult<>(ERROR,
|
|
|
+ "Version of locales' dictionary is incorrect, through patched mark is standing. Dat file may be corrupted");
|
|
|
}
|
|
|
|
|
|
- BinaryData dicts_data = BinaryData((unsigned)dict_size);
|
|
|
+ BinaryData dicts_data = BinaryData((unsigned) dict_size);
|
|
|
dat->GetIO().ReadData(dicts_data, dict_size - 12, locale_offset + 12);
|
|
|
|
|
|
if (dicts_data.size() < 15) {
|
|
@@ -83,7 +89,8 @@ namespace LOTRO_DAT {
|
|
|
std::string hi = std::string((char *) (hi_data.data()));
|
|
|
|
|
|
if (hi != "Hi from Gi1dor!")
|
|
|
- return DatOperationResult<>(ERROR, "INITLOCALE: Data in locales' dictionary is incorrect (couldn't receive 'Hello').");
|
|
|
+ return DatOperationResult<>(ERROR,
|
|
|
+ "INITLOCALE: Data in locales' dictionary is incorrect (couldn't receive 'Hello').");
|
|
|
|
|
|
int offset = 15;
|
|
|
BinaryData current_locale_data = dicts_data.CutData(offset, offset + 4) + BinaryData("\0", 1);
|
|
@@ -91,7 +98,8 @@ namespace LOTRO_DAT {
|
|
|
offset += 4;
|
|
|
|
|
|
if (locale != "PATC" && locale != "ORIG")
|
|
|
- return DatOperationResult<>(ERROR, "INITLOCALE: Data in locales' dictionary is incorrect (current locale mark is invalid).");
|
|
|
+ return DatOperationResult<>(ERROR,
|
|
|
+ "INITLOCALE: Data in locales' dictionary is incorrect (current locale mark is invalid).");
|
|
|
|
|
|
current_locale_ = (locale == "PATC" ? PATCHED : ORIGINAL);
|
|
|
|
|
@@ -118,8 +126,9 @@ namespace LOTRO_DAT {
|
|
|
LOG(INFO) << "Finished initialising locales";
|
|
|
|
|
|
if (CheckLocaleCorrect()) {
|
|
|
- dat->GetIO().file_size = locale_info.ToNumber<4>(8);
|
|
|
- LOG(INFO) << "Locales initialisation success. Dictionary size is " << dict_size << ". Version is " << dict_version << ". Localed .dat size = " << dat->GetIO().file_size;
|
|
|
+ dat->GetFileSystem().patched_file_end = locale_info.ToNumber<4>(8);
|
|
|
+ LOG(INFO) << "Locales initialisation success. Dictionary size is " << dict_size << ". Version is "
|
|
|
+ << dict_version << ". Localed .dat size = " << dat->GetFileSystem().patched_file_end;
|
|
|
return DatOperationResult<>(SUCCESS);
|
|
|
} else {
|
|
|
orig_dict_.clear();
|
|
@@ -131,7 +140,6 @@ namespace LOTRO_DAT {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-
|
|
|
/*!
|
|
|
* \Author Gi1dor
|
|
|
* \date 06.07.2018
|
|
@@ -145,8 +153,8 @@ namespace LOTRO_DAT {
|
|
|
dat->GetStatusModule().SetStatus(DatStatus::E_COMMITING);
|
|
|
|
|
|
dat->GetStatusModule().SetDebugMessage("Changing locale to " +
|
|
|
- (locale == PATCHED ? std::string(" patched version")
|
|
|
- : std::string(" original version")));
|
|
|
+ (locale == PATCHED ? std::string(" patched version")
|
|
|
+ : std::string(" original version")));
|
|
|
|
|
|
LOG(INFO) << "Setting locale to " << (locale == PATCHED ? " PATCHED" : " ORIGINAL");
|
|
|
if (!dat)
|
|
@@ -161,7 +169,7 @@ namespace LOTRO_DAT {
|
|
|
return DatOperationResult<>(SUCCESS);
|
|
|
}
|
|
|
|
|
|
- std::map<long long, SubFile>& dict = GetLocaleDictReference(locale);
|
|
|
+ std::map<long long, SubFile> &dict = GetLocaleDictReference(locale);
|
|
|
for (const auto &file : dict) {
|
|
|
long long file_id = file.first;
|
|
|
|
|
@@ -203,31 +211,6 @@ namespace LOTRO_DAT {
|
|
|
* \Author Gi1dor
|
|
|
* \date 06.07.2018
|
|
|
* Деинициализация модуля. Должна происходить перед деинициализацией модулей ввода-вывода и файловой системы.
|
|
|
- * Записывает словарь. Если ранее словарь не существовал - новый будет записан в конец файла.
|
|
|
- * Для словаря выделяется блок не менее 20мб
|
|
|
- *
|
|
|
- * \warning Не должна вызываться вручную! Автоматически вызывается в функции Deinitialise класса DatFile
|
|
|
- *
|
|
|
- * Структура словарей локализации:
|
|
|
- * ======== LOCALE DICT STRUCTURE =========
|
|
|
- * 4 bytes for dict size (in bytes)
|
|
|
- * 4 bytes for locale version
|
|
|
- * 4 bytes for .dat file size (with patches)
|
|
|
- * 15 bytes for "Hi from Gi1dor"
|
|
|
- * 4 bytes for LOCALE
|
|
|
- * 4 bytes for orig_dict.size()
|
|
|
- * (32 + 4) * orig_dict.size() bytes for orig_dict data
|
|
|
- * 4 bytes for patch_dict.size()
|
|
|
- * (32 + 4) * patch_dict.size() bytes for patch_dict data
|
|
|
- * 4 bytes for inactive_categories dict
|
|
|
- * 4 * inactive_categories.size() bytes for inactive_categories data
|
|
|
- * ========================================
|
|
|
- * Помимо этого:
|
|
|
- * 0x128-0x12C - 0, если выбрана локаль ORIGINAL и обновление клиентом игры не испортит .dat file
|
|
|
- * значение переменной-размера .dat файла (оффсет 0x148), в противном случае.
|
|
|
- * Отличие значения в 0x128 от 0 и значения в 0x148 => файл ресурсов мог быть повреждён
|
|
|
- *
|
|
|
- * 0x12C-0x130 - Офсет начала словаря локализации
|
|
|
*/
|
|
|
|
|
|
DatOperationResult<> DatLocaleManager::DeInit() {
|
|
@@ -235,103 +218,7 @@ namespace LOTRO_DAT {
|
|
|
if (!dat)
|
|
|
return DatOperationResult<>(ERROR, "LOCALEDEINIT: no connection with Dat (dat is nullptr)");
|
|
|
|
|
|
- if (patch_dict_.empty()) {
|
|
|
- dat->GetIO().WriteData(BinaryData::FromNumber<4>(0), 4, 300);
|
|
|
- return DatOperationResult<>(SUCCESS);
|
|
|
- }
|
|
|
-
|
|
|
- BinaryData binary_data = BinaryData(4 + 4 + 4 + 14 + 15 + 4
|
|
|
- + 4 + (32 + 4) * orig_dict_.size()
|
|
|
- + 4 + (32 + 4) * patch_dict_.size()
|
|
|
- + 4 + 4 * inactive_categories.size());
|
|
|
-
|
|
|
- // First 12 bytes will be filled just before writing data to file
|
|
|
- size_t current_size = 12;
|
|
|
-
|
|
|
- binary_data.Append(BinaryData("Hi from Gi1dor!", 15), current_size);
|
|
|
- current_size += 15;
|
|
|
-
|
|
|
- binary_data.Append(BinaryData((current_locale_ == ORIGINAL ? "ORIG" : "PATC"), 4), current_size);
|
|
|
- current_size += 4;
|
|
|
-
|
|
|
- binary_data.Append(BinaryData::FromNumber<4>(orig_dict_.size()), current_size);
|
|
|
- current_size += 4;
|
|
|
-
|
|
|
- for (const auto &file : orig_dict_) {
|
|
|
- binary_data.Append(file.second.MakeHeaderData(), current_size);
|
|
|
- current_size += 32;
|
|
|
- binary_data.Append(BinaryData::FromNumber<4>(file.second.category), current_size);
|
|
|
- current_size += 4;
|
|
|
- }
|
|
|
-
|
|
|
- binary_data.Append(BinaryData::FromNumber<4>(patch_dict_.size()), current_size);
|
|
|
- current_size += 4;
|
|
|
-
|
|
|
- for (const auto &file : patch_dict_) {
|
|
|
- binary_data.Append(file.second.MakeHeaderData(), current_size);
|
|
|
- current_size += 32;
|
|
|
- binary_data.Append(BinaryData::FromNumber<4>(file.second.category), current_size);
|
|
|
- current_size += 4;
|
|
|
- }
|
|
|
-
|
|
|
- binary_data.Append(BinaryData::FromNumber<4>(inactive_categories.size()), current_size);
|
|
|
- current_size += 4;
|
|
|
- for (auto patch_id : inactive_categories) {
|
|
|
- binary_data.Append(BinaryData::FromNumber<4>(patch_id), current_size);
|
|
|
- current_size += 4;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- BinaryData dicts_data(4);
|
|
|
- dat->GetIO().ReadData(dicts_data, 4, 300);
|
|
|
- long long dict_offset = dicts_data.ToNumber<4>(0);
|
|
|
- dat->GetIO().ReadData(dicts_data, 4, dict_offset);
|
|
|
- long long dict_size = dicts_data.ToNumber<4>(0);
|
|
|
-
|
|
|
- if (binary_data.size() > dict_size || dict_offset == 0) {
|
|
|
- long long new_dict_offset = dat->GetIO().file_size + 12;
|
|
|
-
|
|
|
- // Updating first 12 bytes
|
|
|
- binary_data.Append(BinaryData::FromNumber<4>(std::max(binary_data.size() + 4, 20u * 1024u * 1024u)), 0);
|
|
|
- binary_data.Append(BinaryData::FromNumber<4>(101), 4);
|
|
|
- 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)
|
|
|
- return DatOperationResult<>(ERROR, "LOCALEDEINIT: Cannot write locales");
|
|
|
-
|
|
|
- dat->GetIO().WriteData(BinaryData::FromNumber<4>(new_dict_offset), 4, 300);
|
|
|
-
|
|
|
- if (current_locale_ == PATCHED) {
|
|
|
- BinaryData file_size_flag(4);
|
|
|
- dat->GetIO().ReadData(file_size_flag, 4, 0x148);
|
|
|
- dat->GetIO().WriteData(file_size_flag, 4, 296);
|
|
|
- } else {
|
|
|
- dat->GetIO().WriteData(BinaryData::FromNumber<4>(0), 4, 296);
|
|
|
- }
|
|
|
-
|
|
|
- dat->GetIO().file_size += binary_data.size();
|
|
|
-
|
|
|
- // Adding space for 20 megabytes locales file in total.
|
|
|
- BinaryData nulls(unsigned(20 * 1024 * 1024));
|
|
|
- dat->GetIO().WriteData(nulls, nulls.size(), dat->GetIO().file_size);
|
|
|
- dat->GetIO().file_size += nulls.size();
|
|
|
- } else {
|
|
|
- binary_data.Append(BinaryData::FromNumber<4>(std::max(binary_data.size() + 4, 20u * 1024u * 1024u)), 0);
|
|
|
- binary_data.Append(BinaryData::FromNumber<4>(101), 4);
|
|
|
- binary_data.Append(BinaryData::FromNumber<4>(dat->GetIO().file_size), 8);
|
|
|
-
|
|
|
- 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)
|
|
|
- return DatOperationResult<>(ERROR, "LOCALEDEINIT: Cannot write locales. ERRMSG: " + operation.msg);
|
|
|
- }
|
|
|
-
|
|
|
- LOG(INFO) << "Locales committed successfully";
|
|
|
-
|
|
|
-
|
|
|
- return DatOperationResult<>(SUCCESS);
|
|
|
+ return CommitLocales();
|
|
|
}
|
|
|
|
|
|
|
|
@@ -344,7 +231,7 @@ namespace LOTRO_DAT {
|
|
|
*/
|
|
|
|
|
|
void DatLocaleManager::UpdateLocaleFile(DatLocaleManager::LOCALE locale, const SubFile &file) {
|
|
|
- std::map<long long, SubFile>& dict = GetLocaleDictReference(locale);
|
|
|
+ std::map<long long, SubFile> &dict = GetLocaleDictReference(locale);
|
|
|
dict[file.file_id()] = file;
|
|
|
}
|
|
|
|
|
@@ -357,9 +244,11 @@ namespace LOTRO_DAT {
|
|
|
*/
|
|
|
|
|
|
DatOperationResult<SubFile> DatLocaleManager::GetLocaleFile(long long file_id, DatLocaleManager::LOCALE locale) {
|
|
|
- std::map<long long, SubFile>& dict = GetLocaleDictReference(locale);
|
|
|
+ std::map<long long, SubFile> &dict = GetLocaleDictReference(locale);
|
|
|
if (dict.count(file_id) == 0)
|
|
|
- return DatOperationResult<SubFile>(SubFile(), ERROR, "GETLOCFILE: cannot get file with id = " + std::to_string(file_id) + " from dict " + std::to_string(locale));
|
|
|
+ return DatOperationResult<SubFile>(SubFile(), ERROR,
|
|
|
+ "GETLOCFILE: cannot get file with id = " + std::to_string(file_id) +
|
|
|
+ " from dict " + std::to_string(locale));
|
|
|
return DatOperationResult<SubFile>(dict[file_id], SUCCESS);
|
|
|
}
|
|
|
|
|
@@ -406,8 +295,6 @@ namespace LOTRO_DAT {
|
|
|
long long dict_version = locale_info.ToNumber<4>(4);
|
|
|
|
|
|
fprintf(file, "Locales' dictionary size = %lld, version = %lld\n", dict_size, dict_version);
|
|
|
-
|
|
|
- dat->GetIO().file_size = locale_info.ToNumber<4>(8);
|
|
|
}
|
|
|
|
|
|
fprintf(file, "Current locale id = %d\n", current_locale_);
|
|
@@ -435,15 +322,15 @@ namespace LOTRO_DAT {
|
|
|
long long locale_offset = locale_offset_data.ToNumber<4>(0);
|
|
|
|
|
|
if (locale_offset == 0 || locale_offset + 8 >= dat->GetIO().GetActualDatSize().value)
|
|
|
- return locale_status == ORIGINAL;
|
|
|
+ return locale_status == 0;
|
|
|
|
|
|
BinaryData dicts_data = BinaryData(4);
|
|
|
auto operation = dat->GetIO().ReadData(dicts_data, 4, locale_offset + 12 + 15);
|
|
|
if (operation.result == ERROR)
|
|
|
- return locale_status == ORIGINAL;
|
|
|
+ return locale_status == 0;
|
|
|
|
|
|
BinaryData locale_data = dicts_data + BinaryData("\0", 1);
|
|
|
- std::string locale((char *)(locale_data.data()));
|
|
|
+ std::string locale((char *) (locale_data.data()));
|
|
|
|
|
|
LOCALE dat_locale = (locale == "PATC" ? PATCHED : ORIGINAL);
|
|
|
|
|
@@ -452,12 +339,8 @@ namespace LOTRO_DAT {
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
- BinaryData original_filesize_variable(4);
|
|
|
- dat->GetIO().ReadData(original_filesize_variable, 4, 0x148);
|
|
|
- long long original_filesize = original_filesize_variable.ToNumber<4>(0);
|
|
|
-
|
|
|
- if (locale_status != original_filesize) {
|
|
|
- LOG(ERROR) << "CHCKLOCALECORRECT: locale & file size values doesn't match!";
|
|
|
+ if (locale_status != 0 && locale_status != dat->GetIO().getHeaderHash()){
|
|
|
+ LOG(ERROR) << "CHCKLOCALECORRECT: Locale hash doesn't match!";
|
|
|
return false;
|
|
|
}
|
|
|
|
|
@@ -499,4 +382,136 @@ namespace LOTRO_DAT {
|
|
|
const std::set<long long> &DatLocaleManager::GetInactiveCategories() {
|
|
|
return inactive_categories;
|
|
|
}
|
|
|
+
|
|
|
+ /*!
|
|
|
+ * \Author Gi1dor
|
|
|
+ * \date 21.10.2018
|
|
|
+ * Записывает словарь. Если ранее словарь не существовал - новый будет записан в конец файла.
|
|
|
+ * Для словаря выделяется блок не менее 20мб
|
|
|
+ *
|
|
|
+ * \warning Не должна вызываться вручную! Автоматически вызывается в функции Deinitialise класса DatFile
|
|
|
+ *
|
|
|
+ * Структура словарей локализации:
|
|
|
+ * ======== LOCALE DICT STRUCTURE =========
|
|
|
+ * 4 bytes for dict size (in bytes)
|
|
|
+ * 4 bytes for locale version
|
|
|
+ * 4 bytes for .dat file size (with patches)
|
|
|
+ * 15 bytes for "Hi from Gi1dor"
|
|
|
+ * 4 bytes for LOCALE
|
|
|
+ * 4 bytes for orig_dict.size()
|
|
|
+ * (32 + 4) * orig_dict.size() bytes for orig_dict data
|
|
|
+ * 4 bytes for patch_dict.size()
|
|
|
+ * (32 + 4) * patch_dict.size() bytes for patch_dict data
|
|
|
+ * 4 bytes for inactive_categories dict
|
|
|
+ * 4 * inactive_categories.size() bytes for inactive_categories data
|
|
|
+ * ========================================
|
|
|
+ * Помимо этого:
|
|
|
+ * 0x128-0x12C - 0, если выбрана локаль ORIGINAL и обновление клиентом игры не испортит .dat file
|
|
|
+ * значение переменной-размера .dat файла (оффсет 0x148), в противном случае.
|
|
|
+ * Отличие значения в 0x128 от 0 и значения в 0x148 => файл ресурсов мог быть повреждён
|
|
|
+ *
|
|
|
+ * 0x12C-0x130 - Офсет начала словаря локализации
|
|
|
+ */
|
|
|
+
|
|
|
+ DatOperationResult<> DatLocaleManager::CommitLocales() {
|
|
|
+ if (patch_dict_.empty()) {
|
|
|
+ dat->GetIO().WriteData(BinaryData::FromNumber<4>(0), 4, 300);
|
|
|
+ return DatOperationResult<>(SUCCESS);
|
|
|
+ }
|
|
|
+
|
|
|
+ BinaryData binary_data = BinaryData(4 + 4 + 4 + 14 + 15 + 4
|
|
|
+ + 4 + (32 + 4) * orig_dict_.size()
|
|
|
+ + 4 + (32 + 4) * patch_dict_.size()
|
|
|
+ + 4 + 4 * inactive_categories.size());
|
|
|
+
|
|
|
+ // First 12 bytes will be filled just before writing data to file
|
|
|
+ size_t current_size = 12;
|
|
|
+
|
|
|
+ binary_data.Append(BinaryData("Hi from Gi1dor!", 15), current_size);
|
|
|
+ current_size += 15;
|
|
|
+
|
|
|
+ binary_data.Append(BinaryData((current_locale_ == ORIGINAL ? "ORIG" : "PATC"), 4), current_size);
|
|
|
+ current_size += 4;
|
|
|
+
|
|
|
+ binary_data.Append(BinaryData::FromNumber<4>(orig_dict_.size()), current_size);
|
|
|
+ current_size += 4;
|
|
|
+
|
|
|
+ for (const auto &file : orig_dict_) {
|
|
|
+ binary_data.Append(file.second.MakeHeaderData(), current_size);
|
|
|
+ current_size += 32;
|
|
|
+ binary_data.Append(BinaryData::FromNumber<4>(file.second.category), current_size);
|
|
|
+ current_size += 4;
|
|
|
+ }
|
|
|
+
|
|
|
+ binary_data.Append(BinaryData::FromNumber<4>(patch_dict_.size()), current_size);
|
|
|
+ current_size += 4;
|
|
|
+
|
|
|
+ for (const auto &file : patch_dict_) {
|
|
|
+ binary_data.Append(file.second.MakeHeaderData(), current_size);
|
|
|
+ current_size += 32;
|
|
|
+ binary_data.Append(BinaryData::FromNumber<4>(file.second.category), current_size);
|
|
|
+ current_size += 4;
|
|
|
+ }
|
|
|
+
|
|
|
+ binary_data.Append(BinaryData::FromNumber<4>(inactive_categories.size()), current_size);
|
|
|
+ current_size += 4;
|
|
|
+ for (auto patch_id : inactive_categories) {
|
|
|
+ binary_data.Append(BinaryData::FromNumber<4>(patch_id), current_size);
|
|
|
+ current_size += 4;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ BinaryData dicts_data(4);
|
|
|
+ dat->GetIO().ReadData(dicts_data, 4, 300);
|
|
|
+ long long dict_offset = dicts_data.ToNumber<4>(0);
|
|
|
+ dat->GetIO().ReadData(dicts_data, 4, dict_offset);
|
|
|
+ long long dict_size = dicts_data.ToNumber<4>(0);
|
|
|
+
|
|
|
+ if (binary_data.size() > dict_size || dict_offset == 0) {
|
|
|
+ long long new_dict_offset = dat->GetFileSystem().patched_file_end + 12;
|
|
|
+
|
|
|
+ // Updating first 12 bytes
|
|
|
+ binary_data.Append(BinaryData::FromNumber<4>(std::max(binary_data.size() + 4, 20u * 1024u * 1024u)), 0);
|
|
|
+ binary_data.Append(BinaryData::FromNumber<4>(101), 4);
|
|
|
+ binary_data.Append(
|
|
|
+ BinaryData::FromNumber<4>(dat->GetFileSystem().patched_file_end + binary_data.size() + 20 * 1024 * 1024), 8);
|
|
|
+
|
|
|
+ auto operation = dat->GetIO().WriteData(binary_data, binary_data.size(), new_dict_offset);
|
|
|
+ if (operation.result != SUCCESS)
|
|
|
+ return DatOperationResult<>(ERROR, "LOCALEDEINIT: Cannot write locales");
|
|
|
+
|
|
|
+ dat->GetIO().WriteData(BinaryData::FromNumber<4>(new_dict_offset), 4, 300);
|
|
|
+
|
|
|
+ if (current_locale_ == PATCHED) {
|
|
|
+ dat->GetIO().WriteData(BinaryData::FromNumber<4>(dat->GetIO().getHeaderHash()), 4, 296);
|
|
|
+ } else {
|
|
|
+ dat->GetIO().WriteData(BinaryData::FromNumber<4>(0), 4, 296);
|
|
|
+ }
|
|
|
+ dat->GetFileSystem().patched_file_end += binary_data.size();
|
|
|
+
|
|
|
+ LOG(INFO) << "Writing 20 mbytes to " << dat->GetFileSystem().patched_file_end;
|
|
|
+
|
|
|
+ BinaryData nulls(unsigned(20 * 1024 * 1024));
|
|
|
+ dat->GetIO().WriteData(nulls, nulls.size(), dat->GetFileSystem().patched_file_end);
|
|
|
+ dat->GetFileSystem().patched_file_end += nulls.size();
|
|
|
+ } else {
|
|
|
+ binary_data.Append(BinaryData::FromNumber<4>(std::max(binary_data.size() + 4, 20u * 1024u * 1024u)), 0);
|
|
|
+ binary_data.Append(BinaryData::FromNumber<4>(101), 4);
|
|
|
+ binary_data.Append(BinaryData::FromNumber<4>(dat->GetFileSystem().patched_file_end), 8);
|
|
|
+
|
|
|
+ if (current_locale_ == PATCHED) {
|
|
|
+ dat->GetIO().WriteData(BinaryData::FromNumber<4>(dat->GetIO().getHeaderHash()), 4, 296);
|
|
|
+ } else {
|
|
|
+ dat->GetIO().WriteData(BinaryData::FromNumber<4>(0), 4, 296);
|
|
|
+ }
|
|
|
+
|
|
|
+ auto operation = dat->GetIO().WriteData(binary_data, binary_data.size(), dict_offset);
|
|
|
+
|
|
|
+ if (operation.result != SUCCESS)
|
|
|
+ return DatOperationResult<>(ERROR, "LOCALEDEINIT: Cannot write locales. ERRMSG: " + operation.msg);
|
|
|
+ }
|
|
|
+
|
|
|
+ LOG(INFO) << "Locales committed successfully";
|
|
|
+ return DatOperationResult<>(SUCCESS);
|
|
|
+ }
|
|
|
}
|