|
@@ -24,11 +24,15 @@ namespace LOTRO_DAT {
|
|
|
|
|
|
bool DatFile::InitDatFile(const std::string &filename, int dat_id) {
|
|
|
try {
|
|
|
- if (dat_state_ != CLOSED)
|
|
|
+ if (dat_state_ != CLOSED && filename == filename_)
|
|
|
+ return true;
|
|
|
+
|
|
|
+ if (dat_state_ != CLOSED && filename != filename_)
|
|
|
CloseDatFile();
|
|
|
|
|
|
dat_id_ = dat_id;
|
|
|
dat_state_ = CLOSED;
|
|
|
+ current_locale_ = ORIGINAL;
|
|
|
root_directory_ = nullptr;
|
|
|
file_handler_ = nullptr;
|
|
|
|
|
@@ -243,9 +247,14 @@ namespace LOTRO_DAT {
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
+ if (data.options["cat"].IsDefined())
|
|
|
+ file->category = data.options["cat"].as<long long>();
|
|
|
+ else
|
|
|
+ fprintf(stderr, "WARNING DatFile::PatchFile() - category option 'cat' was not set in patch subfile with id = %lld\n", file_id);
|
|
|
+
|
|
|
BinaryData old_data = GetFileData(file);
|
|
|
BinaryData patch_data = file->MakeForImport(old_data, data);
|
|
|
- ApplyFilePatch(dictionary_[file_id], patch_data, rewrite_original);
|
|
|
+ ApplyFilePatch(file, patch_data, rewrite_original);
|
|
|
return true;
|
|
|
}
|
|
|
|
|
@@ -458,7 +467,6 @@ namespace LOTRO_DAT {
|
|
|
|
|
|
|
|
|
|
|
|
-
|
|
|
void DatFile::ApplyFilePatch(Subfile *file, const BinaryData &data, bool rewrite_original) {
|
|
|
if (patched_list.count(file->file_id()) != 0) {
|
|
|
fprintf(stderr, "Warning: DatFile::ApplyFilePatch - found 2 files in patch with the same file_id = %lld. Passing last...\n", file->file_id());
|
|
@@ -471,7 +479,7 @@ namespace LOTRO_DAT {
|
|
|
dat_state_ = UPDATED;
|
|
|
|
|
|
if (orig_dict_.count(file->file_id()) == 0 && !rewrite_original) {
|
|
|
- orig_dict_[file->file_id()] = new Subfile(this, dictionary_[file->file_id()]->MakeHeaderData());
|
|
|
+ orig_dict_[file->file_id()] = new Subfile(this, file->MakeHeaderData());
|
|
|
}
|
|
|
|
|
|
auto journal = GetFragmentationJournal();
|
|
@@ -512,6 +520,20 @@ namespace LOTRO_DAT {
|
|
|
patch_dict_[file_id] = new Subfile(this, file->MakeHeaderData());
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+ if (inactive_categories.count(file->category) != 0) {
|
|
|
+ dictionary_[file_id]->file_offset_ = orig_dict_[file_id]->file_offset_;
|
|
|
+ dictionary_[file_id]->file_size_ = orig_dict_[file_id]->file_size_;
|
|
|
+ dictionary_[file_id]->block_size_ = orig_dict_[file_id]->block_size_;
|
|
|
+ dictionary_[file_id]->timestamp_ = orig_dict_[file_id]->timestamp_;
|
|
|
+ dictionary_[file_id]->version_ = orig_dict_[file_id]->version_;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (orig_dict_.count(file_id) != 0)
|
|
|
+ orig_dict_[file_id]->category = file->category;
|
|
|
+ if (patch_dict_.count(file_id) != 0)
|
|
|
+ patch_dict_[file_id]->category = file->category;
|
|
|
+
|
|
|
UpdateFragmentationJournal(journal);
|
|
|
}
|
|
|
|
|
@@ -655,9 +677,11 @@ namespace LOTRO_DAT {
|
|
|
|
|
|
|
|
|
|
|
|
-
|
|
|
+
|
|
|
|
|
|
-
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
|
|
|
size_t orig_dict_size = size_t(dicts_data.CutData(offset, offset + 4).ToNumber<4>(0));
|
|
|
offset += 4;
|
|
@@ -665,8 +689,12 @@ namespace LOTRO_DAT {
|
|
|
auto file = new Subfile(this, dicts_data.CutData(offset, offset + 32));
|
|
|
orig_dict_[file->file_id()] = file;
|
|
|
offset += 32;
|
|
|
- }
|
|
|
+ orig_dict_[file->file_id()]->category = dicts_data.ToNumber<4>(offset);
|
|
|
+ offset += 4;
|
|
|
|
|
|
+ if (orig_dict_[file->file_id()]->category == 0)
|
|
|
+ fprintf(stderr, "WARNING DatFile::InitLocales() - file category is undefined (0)!\n");
|
|
|
+ }
|
|
|
|
|
|
size_t patch_dict_size = size_t(dicts_data.CutData(offset, offset + 4).ToNumber<4>(0));
|
|
|
offset += 4;
|
|
@@ -674,10 +702,26 @@ namespace LOTRO_DAT {
|
|
|
auto file = new Subfile(this, dicts_data.CutData(offset, offset + 32));
|
|
|
patch_dict_[file->file_id()] = file;
|
|
|
offset += 32;
|
|
|
+ patch_dict_[file->file_id()]->category = dicts_data.ToNumber<4>(offset);
|
|
|
+ offset += 4;
|
|
|
+ if (patch_dict_[file->file_id()]->category == 0)
|
|
|
+ fprintf(stderr, "WARNING DatFile::InitLocales() - file category is undefined (0)!\n");
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ size_t active_patches_dict_size = size_t(dicts_data.CutData(offset, offset + 4).ToNumber<4>(0));
|
|
|
+ offset += 4;
|
|
|
+ for (size_t i = 0; i < active_patches_dict_size; i++) {
|
|
|
+ inactive_categories.insert(dicts_data.ToNumber<4>(offset));
|
|
|
+ offset += 4;
|
|
|
}
|
|
|
|
|
|
std::cout << "There are " << patch_dict_.size() << " files in patch locale dictionary" << std::endl;
|
|
|
std::cout << "There are " << orig_dict_.size() << " files in original locale dictionary" << std::endl;
|
|
|
+ std::cout << "Unactive patches now: ";
|
|
|
+ for (auto i : inactive_categories)
|
|
|
+ std:: cout << i;
|
|
|
+ std::cout << std::endl;
|
|
|
}
|
|
|
|
|
|
std::unordered_map<long long, Subfile *> *DatFile::GetLocaleDictReference(LOCALE locale) {
|
|
@@ -711,7 +755,7 @@ namespace LOTRO_DAT {
|
|
|
continue;
|
|
|
}
|
|
|
if (dictionary_[file.first]->MakeHeaderData().CutData(8, 16) ==
|
|
|
- file.second->MakeHeaderData().CutData(8, 16))
|
|
|
+ file.second->MakeHeaderData().CutData(8, 16) || inactive_categories.count(orig_dict_[file.first]->category) != 0)
|
|
|
continue;
|
|
|
|
|
|
long long file_id = file.first;
|
|
@@ -756,7 +800,7 @@ namespace LOTRO_DAT {
|
|
|
}
|
|
|
|
|
|
void DatFile::CommitLocales() {
|
|
|
- std::cout << "Commiting locales..." << std::endl;
|
|
|
+ std::cout << "Committing locales..." << std::endl;
|
|
|
SubfileData data = dictionary_[2013266257]->PrepareForExport(GetFileData(dictionary_[2013266257]));
|
|
|
data.options["fid"] = "2013266257";
|
|
|
data.options["ext"] = ".unknown";
|
|
@@ -767,11 +811,16 @@ namespace LOTRO_DAT {
|
|
|
|
|
|
|
|
|
|
|
|
-
|
|
|
+
|
|
|
|
|
|
-
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
|
|
|
- data.binary_data = BinaryData(14 + 15 + 4 + 4 + orig_dict_.size() * 32 + 4 + patch_dict_.size() * 32);
|
|
|
+ data.binary_data = BinaryData(14 + 15 + 4
|
|
|
+ + 4 + (32 + 4) * orig_dict_.size()
|
|
|
+ + 4 + (32 + 4) * patch_dict_.size()
|
|
|
+ + 4 + 4 * inactive_categories.size());
|
|
|
|
|
|
size_t current_size = 0;
|
|
|
data.binary_data.Append(GetFileData(dictionary_[2013266257u]).CutData(0, 14), current_size);
|
|
@@ -789,6 +838,8 @@ namespace LOTRO_DAT {
|
|
|
for (auto file : orig_dict_) {
|
|
|
data.binary_data.Append(file.second->MakeHeaderData(), current_size);
|
|
|
current_size += 32;
|
|
|
+ data.binary_data.Append(BinaryData::FromNumber<4>(file.second->category), current_size);
|
|
|
+ current_size += 4;
|
|
|
}
|
|
|
|
|
|
data.binary_data.Append(BinaryData::FromNumber<4>(patch_dict_.size()), current_size);
|
|
@@ -797,10 +848,67 @@ namespace LOTRO_DAT {
|
|
|
for (auto file : patch_dict_) {
|
|
|
data.binary_data.Append(file.second->MakeHeaderData(), current_size);
|
|
|
current_size += 32;
|
|
|
+ data.binary_data.Append(BinaryData::FromNumber<4>(file.second->category), current_size);
|
|
|
+ current_size += 4;
|
|
|
+ }
|
|
|
+
|
|
|
+ data.binary_data.Append(BinaryData::FromNumber<4>(inactive_categories.size()), current_size);
|
|
|
+ current_size += 4;
|
|
|
+ for (auto patch_id : inactive_categories) {
|
|
|
+ data.binary_data.Append(BinaryData::FromNumber<4>(patch_id), current_size);
|
|
|
+ current_size += 4;
|
|
|
}
|
|
|
|
|
|
PatchFile(data, true);
|
|
|
std::cout << "Done!" << std::endl;
|
|
|
}
|
|
|
+
|
|
|
+ void DatFile::EnableCategory(int category) {
|
|
|
+ std::cout << "Disabling category " << category << std::endl;
|
|
|
+ if (inactive_categories.count(category) == 0)
|
|
|
+ return;
|
|
|
+ inactive_categories.erase(category);
|
|
|
+
|
|
|
+ for (auto file : dictionary_) {
|
|
|
+ auto file_id = file.first;
|
|
|
+ if (patch_dict_.count(file_id) > 0 && patch_dict_[file_id]->category == category) {
|
|
|
+ dat_state_ = UPDATED;
|
|
|
+
|
|
|
+ file.second->file_offset_ = patch_dict_[file_id]->file_offset_;
|
|
|
+ file.second->file_size_ = patch_dict_[file_id]->file_size_;
|
|
|
+ file.second->block_size_ = patch_dict_[file_id]->block_size_;
|
|
|
+ file.second->timestamp_ = patch_dict_[file_id]->timestamp_;
|
|
|
+ file.second->version_ = patch_dict_[file_id]->version_;
|
|
|
+ patched_list.insert(file_id);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ void DatFile::DisableCategory(int category) {
|
|
|
+ std::cout << "Disabling category " << category << std::endl;
|
|
|
+ if (inactive_categories.count(category) != 0)
|
|
|
+ return;
|
|
|
+ inactive_categories.insert(category);
|
|
|
+
|
|
|
+ for (auto file : dictionary_) {
|
|
|
+ auto file_id = file.first;
|
|
|
+
|
|
|
+ if (orig_dict_.count(file_id) && orig_dict_[file_id]->category == category) {
|
|
|
+ dat_state_ = UPDATED;
|
|
|
+
|
|
|
+ file.second->file_offset_ = orig_dict_[file_id]->file_offset_;
|
|
|
+ file.second->file_size_ = orig_dict_[file_id]->file_size_;
|
|
|
+ file.second->block_size_ = orig_dict_[file_id]->block_size_;
|
|
|
+ file.second->timestamp_ = orig_dict_[file_id]->timestamp_;
|
|
|
+ file.second->version_ = orig_dict_[file_id]->version_;
|
|
|
+ patched_list.insert(file_id);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const std::unordered_set<long long>& DatFile::GetInactiveCategoriesList() {
|
|
|
+ return inactive_categories;
|
|
|
+ }
|
|
|
+
|
|
|
}
|
|
|
}
|