|
@@ -6,7 +6,7 @@
|
|
|
#include "BinaryData.h"
|
|
|
|
|
|
#include "SubDirectory.h"
|
|
|
-#include "Subfile.h"
|
|
|
+#include "SubFile.h"
|
|
|
#include "SubfileData.h"
|
|
|
|
|
|
#include <EasyLogging++/easylogging++.h>
|
|
@@ -86,6 +86,7 @@ namespace LOTRO_DAT {
|
|
|
DAT_RESULT result;
|
|
|
DAT_RESULT return_value = SUCCESS;
|
|
|
|
|
|
+ LOG(INFO) << "Opening .dat file " << filename;
|
|
|
result = OpenDatFile(filename.c_str());
|
|
|
if (result != SUCCESS) {
|
|
|
LOG(ERROR) << "Unable to perform opening file. Aborting.";
|
|
@@ -94,6 +95,8 @@ namespace LOTRO_DAT {
|
|
|
}
|
|
|
return_value = std::max(return_value, result);
|
|
|
|
|
|
+ LOG(INFO) << "Starting ReadSuperBlock";
|
|
|
+
|
|
|
result = ReadSuperBlock();
|
|
|
if (result <= 0) {
|
|
|
LOG(ERROR) << "Unable to read super block. Aborting.";
|
|
@@ -102,6 +105,8 @@ namespace LOTRO_DAT {
|
|
|
}
|
|
|
return_value = std::max(return_value, result);
|
|
|
|
|
|
+ LOG(INFO) << "Starting MakeDirectories";
|
|
|
+
|
|
|
result = MakeDirectories();
|
|
|
if (result <= 0) {
|
|
|
LOG(ERROR) << "Unable to make directories. Aborting.";
|
|
@@ -110,6 +115,8 @@ namespace LOTRO_DAT {
|
|
|
}
|
|
|
return_value = std::max(return_value, result);
|
|
|
|
|
|
+ LOG(INFO) << "Starting MakeDictionary";
|
|
|
+
|
|
|
result = MakeDictionary();
|
|
|
if (result <= 0) {
|
|
|
LOG(ERROR) << "Unable to make dictionary. Aborting.";
|
|
@@ -118,6 +125,8 @@ namespace LOTRO_DAT {
|
|
|
}
|
|
|
return_value = std::max(return_value, result);
|
|
|
|
|
|
+ LOG(INFO) << "Starting InitLocales";
|
|
|
+
|
|
|
result = InitLocales();
|
|
|
if (result <= 0) {
|
|
|
LOG(ERROR) << "Unable to initialize locales. Aborting.";
|
|
@@ -147,7 +156,8 @@ namespace LOTRO_DAT {
|
|
|
InitDatFile(filename, dat_id);
|
|
|
}
|
|
|
|
|
|
-
|
|
|
+ std::cout << "Visited subdirs: " << SubDirectory::visited_subdirectories_.size() << std::endl;
|
|
|
+ std::cout << "Visited files: " << SubDirectory::visited_subfiles_.size() << std::endl;
|
|
|
dat_without_patches_ = CheckIfNotPatched();
|
|
|
LOG(INFO) << "Preparations made successfully! Init return value = " << return_value;
|
|
|
return return_value;
|
|
@@ -222,7 +232,25 @@ namespace LOTRO_DAT {
|
|
|
return INCORRECT_STATE_ERROR;
|
|
|
}
|
|
|
|
|
|
- root_directory_ = new SubDirectory((unsigned) root_directory_offset_, this);
|
|
|
+ root_directory_ = std::make_shared<SubDirectory>((unsigned) root_directory_offset_, *this);
|
|
|
+ SubDirectory::subdir_init_queue_.insert(root_directory_);
|
|
|
+
|
|
|
+ while (!SubDirectory::subdir_init_queue_.empty()) {
|
|
|
+ std::shared_ptr<SubDirectory> dir = *SubDirectory::subdir_init_queue_.begin();
|
|
|
+ SubDirectory::subdir_init_queue_.erase(SubDirectory::subdir_init_queue_.begin());
|
|
|
+ if (dir->MakeSubDirectories())
|
|
|
+ SubDirectory::subfile_init_queue_.insert(dir);
|
|
|
+ else
|
|
|
+ dir->clear();
|
|
|
+ }
|
|
|
+
|
|
|
+ while (!SubDirectory::subfile_init_queue_.empty()) {
|
|
|
+ std::shared_ptr<SubDirectory> dir = *SubDirectory::subfile_init_queue_.begin();
|
|
|
+ SubDirectory::subfile_init_queue_.erase(SubDirectory::subfile_init_queue_.begin());
|
|
|
+ if (!dir->MakeSubFiles())
|
|
|
+ dir->clear();
|
|
|
+ }
|
|
|
+
|
|
|
dat_state_ = SUCCESS_DIRECTORIES;
|
|
|
|
|
|
LOG(DEBUG) << "Directories made successfully";
|
|
@@ -328,7 +356,7 @@ namespace LOTRO_DAT {
|
|
|
size_t orig_dict_size = size_t(dicts_data.CutData(offset, offset + 4).ToNumber<4>(0));
|
|
|
offset += 4;
|
|
|
for (size_t i = 0; i < orig_dict_size; i++) {
|
|
|
- auto file = new Subfile(this, dicts_data.CutData(offset, offset + 32));
|
|
|
+ auto file = std::make_shared<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);
|
|
@@ -341,7 +369,7 @@ namespace LOTRO_DAT {
|
|
|
size_t patch_dict_size = size_t(dicts_data.CutData(offset, offset + 4).ToNumber<4>(0));
|
|
|
offset += 4;
|
|
|
for (size_t i = 0; i < patch_dict_size; i++) {
|
|
|
- auto file = new Subfile(this, dicts_data.CutData(offset, offset + 32));
|
|
|
+ auto file = std::make_shared<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);
|
|
@@ -370,7 +398,7 @@ namespace LOTRO_DAT {
|
|
|
}
|
|
|
|
|
|
DAT_RESULT DatFile::PerformDictionaryCheck() {
|
|
|
- for (auto mpair : dictionary_) {
|
|
|
+ for (const auto& mpair : dictionary_) {
|
|
|
auto file = mpair.second;
|
|
|
auto file_id = mpair.first;
|
|
|
if (CorrectSubfile(file))
|
|
@@ -423,7 +451,6 @@ namespace LOTRO_DAT {
|
|
|
fclose(file_handler_);
|
|
|
}
|
|
|
SubDirectory::visited_subdirectories_.clear();
|
|
|
- delete root_directory_;
|
|
|
|
|
|
|
|
|
free_buffered_size_ = 0;
|
|
@@ -487,7 +514,7 @@ namespace LOTRO_DAT {
|
|
|
binary_data.Append(BinaryData::FromNumber<4>(orig_dict_.size()), current_size);
|
|
|
current_size += 4;
|
|
|
|
|
|
- for (auto file : orig_dict_) {
|
|
|
+ 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);
|
|
@@ -497,7 +524,7 @@ namespace LOTRO_DAT {
|
|
|
binary_data.Append(BinaryData::FromNumber<4>(patch_dict_.size()), current_size);
|
|
|
current_size += 4;
|
|
|
|
|
|
- for (auto file : patch_dict_) {
|
|
|
+ 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);
|
|
@@ -595,17 +622,13 @@ namespace LOTRO_DAT {
|
|
|
}
|
|
|
|
|
|
DAT_RESULT DatFile::RepairDatFile() {
|
|
|
- for (auto file : dictionary_) {
|
|
|
+ for (const auto& file : dictionary_) {
|
|
|
auto subfile = file.second;
|
|
|
auto file_id = file.first;
|
|
|
|
|
|
if (CorrectSubfile(subfile))
|
|
|
continue;
|
|
|
|
|
|
- orig_dict_.clear();
|
|
|
- patch_dict_.clear();
|
|
|
- return SUCCESS;
|
|
|
-
|
|
|
if (orig_dict_.count(file_id) == 0 || subfile->file_offset() == orig_dict_[file_id]->file_offset())
|
|
|
return CRITICAL_DAT_ERROR;
|
|
|
|
|
@@ -702,7 +725,7 @@ namespace LOTRO_DAT {
|
|
|
}
|
|
|
|
|
|
int success = 0;
|
|
|
- for (auto i : dictionary_) {
|
|
|
+ for (const auto& i : dictionary_) {
|
|
|
FILE_TYPE file_type = i.second->FileType();
|
|
|
if (file_type == type) {
|
|
|
success += (ExtractFile(i.second->file_id(), (path + std::to_string(i.second->file_id()))) == SUCCESS
|
|
@@ -722,7 +745,7 @@ namespace LOTRO_DAT {
|
|
|
}
|
|
|
|
|
|
int success = 0;
|
|
|
- for (auto i : dictionary_) {
|
|
|
+ for (const auto& i : dictionary_) {
|
|
|
FILE_TYPE file_type = i.second->FileType();
|
|
|
if (file_type == type) {
|
|
|
success += (ExtractFile(i.second->file_id(), db) == SUCCESS ? 1 : 0);
|
|
@@ -755,7 +778,7 @@ namespace LOTRO_DAT {
|
|
|
LOG(ERROR) << "Cannot patch file - there is no file in dictionary with file_id = " << file_id;
|
|
|
return NO_FILE_ERROR;
|
|
|
}
|
|
|
- Subfile *file = dictionary_[file_id];
|
|
|
+ std::shared_ptr<SubFile> file = dictionary_[file_id];
|
|
|
|
|
|
|
|
|
|
|
@@ -826,7 +849,7 @@ namespace LOTRO_DAT {
|
|
|
}
|
|
|
|
|
|
fprintf(f, "unk1 file_id offset size1 timestamp version size2 unknown2 type\n");
|
|
|
- for (auto i : dictionary_) {
|
|
|
+ for (const auto& i : dictionary_) {
|
|
|
fprintf(f, "%lld %lld %lld %lld %lld %lld %lld %lld %s\n", i.second->unknown1(), i.second->file_id(),
|
|
|
i.second->file_offset(), i.second->file_size(), i.second->timestamp(), i.second->version(),
|
|
|
i.second->block_size(), i.second->unknown2(), i.second->Extension().c_str());
|
|
@@ -836,7 +859,7 @@ namespace LOTRO_DAT {
|
|
|
return SUCCESS;
|
|
|
}
|
|
|
|
|
|
- DAT_RESULT DatFile::ApplyFilePatch(Subfile *file, BinaryData &data) {
|
|
|
+ DAT_RESULT DatFile::ApplyFilePatch(std::shared_ptr<SubFile> file, BinaryData &data) {
|
|
|
LOG(DEBUG) << "Applying " << file->file_id() << " patch.";
|
|
|
|
|
|
|
|
@@ -860,7 +883,7 @@ namespace LOTRO_DAT {
|
|
|
dat_state_ = UPDATED;
|
|
|
|
|
|
if (orig_dict_.count(file_id) == 0 && file_id != 2013266257) {
|
|
|
- orig_dict_[file_id] = new Subfile(this, file->MakeHeaderData());
|
|
|
+ orig_dict_[file_id] = std::make_shared<SubFile>(*this, file->MakeHeaderData());
|
|
|
}
|
|
|
|
|
|
|
|
@@ -892,7 +915,7 @@ namespace LOTRO_DAT {
|
|
|
|
|
|
patch_dict_.erase(file_id);
|
|
|
if (file_id != 2013266257) {
|
|
|
- patch_dict_[file_id] = new Subfile(this, file->MakeHeaderData());
|
|
|
+ patch_dict_[file_id] = std::make_shared<SubFile>(*this, file->MakeHeaderData());
|
|
|
}
|
|
|
|
|
|
|
|
@@ -921,7 +944,7 @@ namespace LOTRO_DAT {
|
|
|
|
|
|
|
|
|
|
|
|
- BinaryData DatFile::GetFileData(const Subfile *file, long long int offset) {
|
|
|
+ BinaryData DatFile::GetFileData(const std::shared_ptr<SubFile>& file, long long int offset) {
|
|
|
LOG(DEBUG) << "Getting file " << file->file_id() << " data";
|
|
|
|
|
|
BinaryData mfile_id(20);
|
|
@@ -933,7 +956,7 @@ namespace LOTRO_DAT {
|
|
|
}
|
|
|
|
|
|
if (!mfile_id.CheckCompression() && file->file_id() != mfile_id.ToNumber<4>(0)) {
|
|
|
- LOG(ERROR) << "Bad DatFile::GetFileData() - file_id in Subfile ("
|
|
|
+ LOG(ERROR) << "Bad DatFile::GetFileData() - file_id in SubFile ("
|
|
|
<< file->file_id()
|
|
|
<< ") doesn't match to file_id (" << mfile_id.ToNumber<4>(0) << ")in DatFile.";
|
|
|
return BinaryData(0);
|
|
@@ -1032,14 +1055,14 @@ namespace LOTRO_DAT {
|
|
|
|
|
|
dat_state_ = UPDATED;
|
|
|
auto dict = GetLocaleDictReference(locale);
|
|
|
- for (auto file : *dict) {
|
|
|
+ for (const auto& file : dict) {
|
|
|
if (file.second == nullptr)
|
|
|
continue;
|
|
|
|
|
|
if (dictionary_.count(file.first) == 0) {
|
|
|
LOG(WARNING) << "In locale dictionary there is file with file_id = " << file.first
|
|
|
<< "which is not in .dat file! Passing it and removing from locale dictionary";
|
|
|
- dict->erase(file.first);
|
|
|
+ dict.erase(file.first);
|
|
|
continue;
|
|
|
}
|
|
|
if (dictionary_[file.first]->MakeHeaderData().CutData(8, 16) ==
|
|
@@ -1048,7 +1071,7 @@ namespace LOTRO_DAT {
|
|
|
continue;
|
|
|
|
|
|
long long file_id = file.first;
|
|
|
- Subfile *new_file = file.second;
|
|
|
+ std::shared_ptr<SubFile> new_file = file.second;
|
|
|
|
|
|
*dictionary_[file_id] = *new_file;
|
|
|
|
|
@@ -1073,15 +1096,15 @@ namespace LOTRO_DAT {
|
|
|
return current_locale_;
|
|
|
}
|
|
|
|
|
|
- std::map<long long, Subfile *> *DatFile::GetLocaleDictReference(LOCALE locale) {
|
|
|
+ std::map<long long, std::shared_ptr<SubFile> > &DatFile::GetLocaleDictReference(LOCALE locale) {
|
|
|
switch (locale) {
|
|
|
case PATCHED:
|
|
|
- return &patch_dict_;
|
|
|
+ return patch_dict_;
|
|
|
case ORIGINAL:
|
|
|
- return &orig_dict_;
|
|
|
+ return orig_dict_;
|
|
|
default:
|
|
|
LOG(ERROR) << "Unknown locale! Returning original";
|
|
|
- return &orig_dict_;
|
|
|
+ return orig_dict_;
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -1089,7 +1112,7 @@ namespace LOTRO_DAT {
|
|
|
|
|
|
|
|
|
|
|
|
- bool DatFile::CorrectSubfile(Subfile *file) {
|
|
|
+ bool DatFile::CorrectSubfile(std::shared_ptr<SubFile> file) {
|
|
|
BinaryData mfile_id(20);
|
|
|
ReadData(mfile_id, 20, file->file_offset() + 8);
|
|
|
if (mfile_id.Empty())
|
|
@@ -1105,9 +1128,9 @@ namespace LOTRO_DAT {
|
|
|
|
|
|
bool updated = false;
|
|
|
|
|
|
- for (auto i : dictionary_) {
|
|
|
+ for (const auto& i : dictionary_) {
|
|
|
long long file_id = i.first;
|
|
|
- Subfile *subfile = i.second;
|
|
|
+ std::shared_ptr<SubFile> subfile = i.second;
|
|
|
if (patch_dict_.count(file_id) == 0)
|
|
|
continue;
|
|
|
|
|
@@ -1147,7 +1170,7 @@ namespace LOTRO_DAT {
|
|
|
inactive_categories.erase(category);
|
|
|
dat_state_ = UPDATED;
|
|
|
|
|
|
- for (auto file : dictionary_) {
|
|
|
+ for (auto &file : dictionary_) {
|
|
|
auto file_id = file.first;
|
|
|
if (patch_dict_.count(file_id) > 0 && patch_dict_[file_id]->category == category) {
|
|
|
*file.second = *patch_dict_[file_id];
|
|
@@ -1165,7 +1188,7 @@ namespace LOTRO_DAT {
|
|
|
inactive_categories.insert(category);
|
|
|
dat_state_ = UPDATED;
|
|
|
|
|
|
- for (auto file : dictionary_) {
|
|
|
+ for (auto &file : dictionary_) {
|
|
|
auto file_id = file.first;
|
|
|
if (orig_dict_.count(file_id) && orig_dict_[file_id]->category == category) {
|
|
|
*file.second = *orig_dict_[file_id];
|