|
@@ -13,11 +13,11 @@
|
|
|
#include <EasyLogging++/easylogging++.h>
|
|
|
#include <unistd.h>
|
|
|
|
|
|
+#include <locale>
|
|
|
+
|
|
|
#define ELPP_FEATURE_CRASH_LOG
|
|
|
INITIALIZE_EASYLOGGINGPP
|
|
|
|
|
|
-#include <locale>
|
|
|
-
|
|
|
#ifdef WIN32
|
|
|
#define fseek _fseeki64
|
|
|
#define ftell _ftelli64
|
|
@@ -31,6 +31,7 @@ namespace LOTRO_DAT {
|
|
|
dat_state_ = CLOSED;
|
|
|
root_directory_ = nullptr;
|
|
|
file_handler_ = nullptr;
|
|
|
+ free_buffered_size_ = 0;
|
|
|
|
|
|
el::Configurations defaultConf;
|
|
|
defaultConf.setToDefault();
|
|
@@ -71,6 +72,7 @@ namespace LOTRO_DAT {
|
|
|
current_locale_ = ORIGINAL;
|
|
|
root_directory_ = nullptr;
|
|
|
file_handler_ = nullptr;
|
|
|
+ free_buffered_size_ = 0;
|
|
|
filename_ = "none";
|
|
|
|
|
|
DAT_RESULT result;
|
|
@@ -116,14 +118,20 @@ namespace LOTRO_DAT {
|
|
|
}
|
|
|
return_value = std::max(return_value, result);
|
|
|
|
|
|
+ LOG(INFO) << "File " << filename << " opened successfully!";
|
|
|
+ filename_ = filename;
|
|
|
+ dat_state_ = READY;
|
|
|
+
|
|
|
+ LOG(INFO) << "Making last preparations...";
|
|
|
+ return_value = std::max(return_value, result);
|
|
|
+
|
|
|
if (return_value >= 2) {
|
|
|
- LOG(WARNING) << "Dat file is corrupted. Trying to delete corrupted dictionary rows";
|
|
|
+ LOG(WARNING) << "Dat file could be corrupted. Trying to delete corrupted dictionary rows";
|
|
|
if (RepairDatFile() != SUCCESS)
|
|
|
return CRITICAL_DAT_ERROR;
|
|
|
}
|
|
|
- LOG(INFO) << "File " << filename << " opened successfully!";
|
|
|
- filename_ = filename;
|
|
|
- dat_state_ = READY;
|
|
|
+
|
|
|
+ LOG(INFO) << "Preparations made successfully! Init return value = " << return_value;
|
|
|
return return_value;
|
|
|
}
|
|
|
|
|
@@ -270,48 +278,6 @@ namespace LOTRO_DAT {
|
|
|
return success;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
- DAT_RESULT DatFile::PatchFile(const char *filename, YAML::Node options) {
|
|
|
- LOG(DEBUG) << "Patching file with filename" << filename << " and id = " << options["fid"].as<long long>();
|
|
|
- if (dat_state_ < READY) {
|
|
|
- LOG(ERROR) << "Dat state isn't READY. Cannot patch.";
|
|
|
- return INCORRECT_STATE_ERROR;
|
|
|
- }
|
|
|
-
|
|
|
- if (options["did"].IsDefined() && options["did"].as<int>() != dat_id_)
|
|
|
- return INCORRECT_DAT_ID;
|
|
|
-
|
|
|
- BinaryData data;
|
|
|
- data.ReadFromFile(filename);
|
|
|
-
|
|
|
- auto file_id = options["fid"].as<long long>();
|
|
|
-
|
|
|
- if (dictionary_[file_id] == nullptr) {
|
|
|
- LOG(ERROR) << "Cannot patch file - there is no file in dictionary with file_id = " << file_id;
|
|
|
- return NO_FILE_ERROR;
|
|
|
- }
|
|
|
-
|
|
|
- BinaryData old_data = GetFileData(dictionary_[file_id]);
|
|
|
- if (old_data.Empty()) {
|
|
|
- LOG(ERROR) << "GetFileData returned empty data. Aborting.";
|
|
|
- return DAT_PATCH_FILE_ERROR;
|
|
|
- }
|
|
|
-
|
|
|
- data = dictionary_[file_id]->MakeForImport(old_data, SubfileData(data, u"", options));
|
|
|
-
|
|
|
- try {
|
|
|
- DAT_RESULT result = ApplyFilePatch(dictionary_[file_id], data);
|
|
|
- if (result != SUCCESS)
|
|
|
- return result;
|
|
|
- } catch (std::exception &e) {
|
|
|
- LOG(ERROR) << "Caught " << e.what() << " exception.";
|
|
|
- return FAILED;
|
|
|
- }
|
|
|
- LOG(DEBUG) << "Successfully patched file with filename = " << filename << " and id = "
|
|
|
- << options["fid"].as<long long>();
|
|
|
- return SUCCESS;
|
|
|
- }
|
|
|
-
|
|
|
|
|
|
DAT_RESULT DatFile::PatchFile(const SubfileData &data) {
|
|
|
LOG(DEBUG) << "Patching file with id = " << data.options["fid"].as<long long>() << ".";
|
|
@@ -358,14 +324,10 @@ namespace LOTRO_DAT {
|
|
|
}
|
|
|
|
|
|
BinaryData patch_data = file->MakeForImport(old_data, data);
|
|
|
- try {
|
|
|
- DAT_RESULT result = ApplyFilePatch(file, patch_data);
|
|
|
- if (result != SUCCESS)
|
|
|
- return result;
|
|
|
- } catch (std::exception &e) {
|
|
|
- LOG(ERROR) << "Caught " << e.what() << " exception";
|
|
|
- return FAILED;
|
|
|
- }
|
|
|
+ DAT_RESULT result = ApplyFilePatch(file, patch_data);
|
|
|
+ if (result != SUCCESS)
|
|
|
+ return result;
|
|
|
+
|
|
|
LOG(DEBUG) << "Patched successfully file " << data.options["fid"].as<long long>() << ".";
|
|
|
return SUCCESS;
|
|
|
}
|
|
@@ -387,9 +349,6 @@ namespace LOTRO_DAT {
|
|
|
LOG(ERROR) << "Cannot patch file" << data.options["fid"].as<long long>() << " continuing";
|
|
|
data = db->GetNextFile();
|
|
|
}
|
|
|
- DAT_RESULT result = CommitChanges();
|
|
|
- if (result != SUCCESS)
|
|
|
- return result;
|
|
|
LOG(INFO) << "Successfully patched whole database";
|
|
|
return SUCCESS;
|
|
|
}
|
|
@@ -408,10 +367,11 @@ namespace LOTRO_DAT {
|
|
|
return WRITE_TO_FILE_ERROR;
|
|
|
}
|
|
|
|
|
|
- fprintf(f, "file_id offset size size2 extension\n");
|
|
|
+ fprintf(f, "unk1 file_id offset size1 timestamp version size2 unknown2 type\n");
|
|
|
for (auto i : dictionary_) {
|
|
|
- fprintf(f, "%lld %lld %lld %lld %s\n", i.second->file_id(), i.second->file_offset(), i.second->file_size(),
|
|
|
- i.second->block_size(), i.second->Extension().c_str());
|
|
|
+ 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());
|
|
|
}
|
|
|
fclose(f);
|
|
|
LOG(INFO) << "Unordered dictionary was written successfully to " << path << "dict.txt";
|
|
@@ -430,54 +390,50 @@ namespace LOTRO_DAT {
|
|
|
|
|
|
BinaryData DatFile::GetFileData(const Subfile *file, long long int offset) {
|
|
|
LOG(DEBUG) << "Getting file " << file->file_id() << " data";
|
|
|
- try {
|
|
|
- BinaryData mfile_id(20);
|
|
|
- ReadData(mfile_id, 20, file->file_offset() + 8);
|
|
|
- if (mfile_id.Empty()) {
|
|
|
- LOG(ERROR) << "Error while reading file " << file->file_id() << " header (offset = "
|
|
|
- << file->file_offset() << "); Aborting.";
|
|
|
- return BinaryData(0);
|
|
|
- }
|
|
|
- if (!mfile_id.CheckCompression() && file->file_id() != mfile_id.ToNumber<4>(0)) {
|
|
|
- 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);
|
|
|
- }
|
|
|
+ BinaryData mfile_id(20);
|
|
|
+ ReadData(mfile_id, 20, file->file_offset() + 8);
|
|
|
+ if (mfile_id.Empty()) {
|
|
|
+ LOG(ERROR) << "Error while reading file " << file->file_id() << " header (offset = "
|
|
|
+ << file->file_offset() << "); Aborting.";
|
|
|
+ return BinaryData(0);
|
|
|
+ }
|
|
|
|
|
|
- BinaryData data((unsigned) (file->file_size() + (8 - offset)));
|
|
|
- if (file->block_size() >= file->file_size() + 8) {
|
|
|
- ReadData(data, file->file_size() + (8 - offset), file->file_offset() + offset);
|
|
|
- return data;
|
|
|
- }
|
|
|
+ if (!mfile_id.CheckCompression() && file->file_id() != mfile_id.ToNumber<4>(0)) {
|
|
|
+ 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);
|
|
|
+ }
|
|
|
|
|
|
- BinaryData fragments_count(4);
|
|
|
- ReadData(fragments_count, 4, file->file_offset());
|
|
|
+ BinaryData data((unsigned)(file->file_size() + (8 - offset)));
|
|
|
+ if (file->block_size() >= file->file_size() + 8) {
|
|
|
+ ReadData(data, file->file_size() + (8 - offset), file->file_offset() + offset);
|
|
|
+ return data;
|
|
|
+ }
|
|
|
|
|
|
- long long fragments_number = fragments_count.ToNumber<4>(0);
|
|
|
+ BinaryData fragments_count(4);
|
|
|
+ ReadData(fragments_count, 4, file->file_offset());
|
|
|
|
|
|
- long long current_block_size = file->block_size() - offset - 8 * fragments_number;
|
|
|
+ long long fragments_number = fragments_count.ToNumber<4>(0);
|
|
|
|
|
|
- ReadData(data, current_block_size, file->file_offset() + offset);
|
|
|
+ long long current_block_size = file->block_size() - offset - 8 * fragments_number;
|
|
|
|
|
|
- BinaryData FragmentsDictionary(8 * unsigned(fragments_number));
|
|
|
- ReadData(FragmentsDictionary, 8 * unsigned(fragments_number),
|
|
|
- file->file_offset() + file->block_size() - 8 * fragments_number);
|
|
|
+ ReadData(data, current_block_size, file->file_offset() + offset);
|
|
|
|
|
|
+ BinaryData FragmentsDictionary(8 * unsigned(fragments_number));
|
|
|
+ ReadData(FragmentsDictionary, 8 * unsigned(fragments_number),
|
|
|
+ file->file_offset() + file->block_size() - 8 * fragments_number);
|
|
|
|
|
|
- for (long long i = 0; i < fragments_number; i++) {
|
|
|
- long long fragment_size = FragmentsDictionary.ToNumber<4>(8 * i);
|
|
|
- long long fragment_offset = FragmentsDictionary.ToNumber<4>(8 * i + 4);
|
|
|
- ReadData(data, std::min(fragment_size, file->file_size() - current_block_size), fragment_offset,
|
|
|
- current_block_size);
|
|
|
- current_block_size += fragment_size;
|
|
|
- }
|
|
|
- LOG(DEBUG) << "Successfully got file " << file->file_id() << " data";
|
|
|
- return data;
|
|
|
- } catch (std::exception &e) {
|
|
|
- LOG(ERROR) << "Caught " << e.what() << " exception";
|
|
|
+
|
|
|
+ for (long long i = 0; i < fragments_number; i++) {
|
|
|
+ long long fragment_size = FragmentsDictionary.ToNumber<4>(8 * i);
|
|
|
+ long long fragment_offset = FragmentsDictionary.ToNumber<4>(8 * i + 4);
|
|
|
+ ReadData(data, std::min(fragment_size, file->file_size() - current_block_size), fragment_offset,
|
|
|
+ current_block_size);
|
|
|
+ current_block_size += fragment_size;
|
|
|
}
|
|
|
- return BinaryData(0);
|
|
|
+ LOG(DEBUG) << "Successfully got file " << file->file_id() << " data";
|
|
|
+ return data;
|
|
|
}
|
|
|
|
|
|
|
|
@@ -553,6 +509,7 @@ namespace LOTRO_DAT {
|
|
|
|
|
|
root_directory_ = new SubDirectory((unsigned) root_directory_offset_, this);
|
|
|
dat_state_ = SUCCESS_DIRECTORIES;
|
|
|
+
|
|
|
LOG(DEBUG) << "Directories made successfully";
|
|
|
return SUCCESS;
|
|
|
}
|
|
@@ -619,19 +576,16 @@ namespace LOTRO_DAT {
|
|
|
|
|
|
|
|
|
|
|
|
- DAT_RESULT DatFile::ApplyFilePatch(Subfile *file, const BinaryData &data) {
|
|
|
+
|
|
|
+ DAT_RESULT DatFile::ApplyFilePatch(Subfile *file, BinaryData &data) {
|
|
|
LOG(DEBUG) << "Applying " << file->file_id() << " patch.";
|
|
|
+
|
|
|
if (data.Empty()) {
|
|
|
LOG(ERROR) << "Error caused during making file for import. Cannot patch file " << file->file_id();
|
|
|
return FAILED;
|
|
|
}
|
|
|
|
|
|
auto file_id = file->file_id();
|
|
|
- if (patched_list.count(file_id) != 0) {
|
|
|
- LOG(WARNING) << "Warning: DatFile::ApplyFilePatch - found 2 files in patch with the same file_id = "
|
|
|
- << file->file_id() << " Passing last...";
|
|
|
- return DUBLICATE_PATCH_FILES_ERROR;
|
|
|
- }
|
|
|
|
|
|
if (current_locale() != PATCHED && file_id != 2013266257) {
|
|
|
LOG(INFO) << "Changing locale to PATCHED(RU) in order to patch file";
|
|
@@ -644,55 +598,42 @@ namespace LOTRO_DAT {
|
|
|
orig_dict_[file_id] = new Subfile(this, file->MakeHeaderData());
|
|
|
}
|
|
|
|
|
|
- auto journal = GetFragmentationJournal();
|
|
|
|
|
|
- if ((patch_dict_.count(file_id) == 0 && file_id != 2013266257)
|
|
|
- || data.size() > file->block_size() || file->file_size() + 8 > file->block_size()) {
|
|
|
- if (journal[0].second != file_size_) {
|
|
|
- journal[0].second = file_size_;
|
|
|
- }
|
|
|
+ if ((patch_dict_.count(file_id) == 0 && file_id != 2013266257) || data.size() > file->block_size()
|
|
|
+ || file->file_size() + 8 > file->block_size()) {
|
|
|
|
|
|
- file->file_size_ = data.size() - 8;
|
|
|
- file->file_offset_ = journal[0].second;
|
|
|
+ file->file_offset_ = file_size_;
|
|
|
file->block_size_ = std::max((long long)data.size(), file->block_size_);
|
|
|
|
|
|
- journal[0].second += file->block_size_;
|
|
|
-
|
|
|
- BinaryData nulls((unsigned)file->block_size_);
|
|
|
- WriteData(nulls, nulls.size(), file_size_);
|
|
|
+ free_buffered_size_ = std::max(0ll, free_buffered_size_ - file->block_size_);
|
|
|
+ AddBufferedSize();
|
|
|
|
|
|
this->file_size_ += file->block_size_;
|
|
|
}
|
|
|
|
|
|
file->file_size_ = data.size() - 8;
|
|
|
- file->block_size_ = std::max(file->block_size_, file->file_size_ + 8);
|
|
|
-
|
|
|
- BinaryData fragments_count(4);
|
|
|
- fragments_count = BinaryData::FromNumber<4>(0);
|
|
|
|
|
|
- BinaryData file_data = fragments_count + data.CutData(4);
|
|
|
+ data.Append(BinaryData::FromNumber<4>(0), 0);
|
|
|
|
|
|
- if (file_id != file_data.ToNumber<4>(8)) {
|
|
|
+ if (file_id != data.ToNumber<4>(8)) {
|
|
|
LOG(ERROR) << "Created data's file_id doesn't match to original! Patch wasn't written to .dat file";
|
|
|
return INCORRECT_PATCH_FILE;
|
|
|
}
|
|
|
|
|
|
- WriteData(file_data, file_data.size(), file->file_offset());
|
|
|
-
|
|
|
- patched_list.insert(file_id);
|
|
|
+ WriteData(data, data.size(), file->file_offset());
|
|
|
|
|
|
+ patch_dict_.erase(file_id);
|
|
|
if (file_id != 2013266257) {
|
|
|
- patch_dict_.erase(file_id);
|
|
|
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_;
|
|
|
+ file->file_offset_ = orig_dict_[file_id]->file_offset_;
|
|
|
+ file->file_size_ = orig_dict_[file_id]->file_size_;
|
|
|
+ file->block_size_ = orig_dict_[file_id]->block_size_;
|
|
|
+ file->timestamp_ = orig_dict_[file_id]->timestamp_;
|
|
|
+ file->version_ = orig_dict_[file_id]->version_;
|
|
|
}
|
|
|
|
|
|
if (orig_dict_.count(file_id) != 0 && file_id != 2013266257)
|
|
@@ -700,31 +641,36 @@ namespace LOTRO_DAT {
|
|
|
if (patch_dict_.count(file_id) != 0 && file_id != 2013266257)
|
|
|
patch_dict_[file_id]->category = file->category;
|
|
|
|
|
|
- UpdateFragmentationJournal(journal);
|
|
|
+
|
|
|
+
|
|
|
+ pending_dictionary_.insert(file_id);
|
|
|
+
|
|
|
LOG(DEBUG) << "Successfully applied file " << file->file_id() << " patch.";
|
|
|
return SUCCESS;
|
|
|
}
|
|
|
|
|
|
- DAT_RESULT DatFile::UpdateSubdirectories() {
|
|
|
-
|
|
|
- LOG(DEBUG) << "Started updating subdirectories";
|
|
|
- root_directory_->UpdateDirectories(patched_list, dictionary_);
|
|
|
- LOG(DEBUG) << "Finished updating subdirectories";
|
|
|
- return SUCCESS;
|
|
|
- }
|
|
|
+ DAT_RESULT DatFile::ClearFragmentationJournal() {
|
|
|
+ LOG(DEBUG) << "Clearing fragmentation journal";
|
|
|
+
|
|
|
+ long long offset = 0;
|
|
|
+ BinaryData data(32);
|
|
|
+ DAT_RESULT res = ReadData(data, 32, fragmentation_journal_offset_ + 8 + offset);
|
|
|
|
|
|
- std::vector<std::pair<long long, long long> > DatFile::GetFragmentationJournal() {
|
|
|
- LOG(DEBUG) << "Getting fragmentation journal";
|
|
|
- BinaryData data(8);
|
|
|
- DAT_RESULT res = ReadData(data, 8, fragmentation_journal_offset_ + 8);
|
|
|
- std::vector<std::pair<long long, long long> > result;
|
|
|
if (res != SUCCESS) {
|
|
|
LOG(ERROR) << "Error " << res << " while reading data";
|
|
|
- return result;
|
|
|
+ return FAILED;
|
|
|
}
|
|
|
- result.emplace_back(std::make_pair(data.ToNumber<4>(0), data.ToNumber<4>(4)));
|
|
|
+
|
|
|
+ BinaryData nulls = BinaryData(32);
|
|
|
+
|
|
|
+ while (data != nulls && !data.Empty()) {
|
|
|
+ WriteData(nulls, 32, fragmentation_journal_offset_ + 8 + offset);
|
|
|
+ offset += 32;
|
|
|
+ ReadData(data, 32, fragmentation_journal_offset_ + 8 + offset);
|
|
|
+ }
|
|
|
+
|
|
|
LOG(DEBUG) << "Finished getting fragmentation journal";
|
|
|
- return result;
|
|
|
+ return SUCCESS;
|
|
|
}
|
|
|
|
|
|
DAT_RESULT DatFile::UpdateHeader() {
|
|
@@ -740,42 +686,6 @@ namespace LOTRO_DAT {
|
|
|
return SUCCESS;
|
|
|
}
|
|
|
|
|
|
- DAT_RESULT DatFile::UpdateFragmentationJournal(const std::vector<std::pair<long long, long long> > &journal) {
|
|
|
- LOG(DEBUG) << "Updating fragmentation journal";
|
|
|
- for (unsigned i = 0; i < journal.size(); i++) {
|
|
|
- long long size = journal[i].first;
|
|
|
- long long offset = journal[i].second;
|
|
|
-
|
|
|
- WriteData(BinaryData::FromNumber<4>(size), 4, fragmentation_journal_offset_ + 8 * (i + 1));
|
|
|
- WriteData(BinaryData::FromNumber<4>(offset), 4, fragmentation_journal_offset_ + 8 * (i + 1) + 4);
|
|
|
- }
|
|
|
- LOG(DEBUG) << "Finished updating fragmentation journal";
|
|
|
- return SUCCESS;
|
|
|
- }
|
|
|
-
|
|
|
- DAT_RESULT DatFile::CommitChanges() {
|
|
|
- LOG(INFO) << "Started commiting changes";
|
|
|
- if (dat_state_ != UPDATED) {
|
|
|
- LOG(DEBUG) << "Commiting changes to file with state != UPDATED. Nothing to do";
|
|
|
- return SUCCESS;
|
|
|
- }
|
|
|
-
|
|
|
- LOG(INFO) << "There are some updated files. Rewriting dictionary...";
|
|
|
- CommitLocales();
|
|
|
-
|
|
|
- auto journal = GetFragmentationJournal();
|
|
|
- UpdateFragmentationJournal(journal);
|
|
|
-
|
|
|
- UpdateHeader();
|
|
|
- UpdateSubdirectories();
|
|
|
- LOG(INFO) << "Changed " << patched_list.size() << " files...";
|
|
|
-
|
|
|
- patched_list.clear();
|
|
|
- dat_state_ = READY;
|
|
|
- LOG(INFO) << "Done Commiting changes!";
|
|
|
- return SUCCESS;
|
|
|
- }
|
|
|
-
|
|
|
DAT_RESULT DatFile::CloseDatFile() {
|
|
|
LOG(INFO) << "Closing DatFile";
|
|
|
if (dat_state_ == CLOSED) {
|
|
@@ -783,10 +693,13 @@ namespace LOTRO_DAT {
|
|
|
return SUCCESS;
|
|
|
}
|
|
|
|
|
|
- CommitChanges();
|
|
|
+
|
|
|
+ CommitLocales();
|
|
|
+ CommitDirectories();
|
|
|
+ UpdateHeader();
|
|
|
+ ClearFragmentationJournal();
|
|
|
|
|
|
orig_dict_.clear();
|
|
|
- patched_list.clear();
|
|
|
pending_patch_.clear();
|
|
|
|
|
|
current_locale_ = ORIGINAL;
|
|
@@ -798,7 +711,7 @@ namespace LOTRO_DAT {
|
|
|
delete root_directory_;
|
|
|
|
|
|
dictionary_.clear();
|
|
|
- patched_list.clear();
|
|
|
+ free_buffered_size_ = 0;
|
|
|
|
|
|
truncate64(filename_.c_str(), file_size_);
|
|
|
filename_ = "none";
|
|
@@ -943,7 +856,6 @@ namespace LOTRO_DAT {
|
|
|
return SUCCESS;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
DAT_RESULT DatFile::SetLocale(LOCALE locale) {
|
|
|
LOG(INFO) << "Setting locale to " << (locale == PATCHED ? " PATCHED" : " ORIGINAL");
|
|
|
if (dat_state_ < READY) {
|
|
@@ -978,12 +890,11 @@ namespace LOTRO_DAT {
|
|
|
dictionary_[file_id]->timestamp_ = new_file->timestamp_;
|
|
|
dictionary_[file_id]->version_ = new_file->version_;
|
|
|
|
|
|
- patched_list.insert(file.first);
|
|
|
+ pending_dictionary_.insert(file_id);
|
|
|
dat_state_ = UPDATED;
|
|
|
}
|
|
|
|
|
|
current_locale_ = locale;
|
|
|
- CommitChanges();
|
|
|
LOG(INFO) << "Locale set successfull";
|
|
|
return SUCCESS;
|
|
|
}
|
|
@@ -1013,7 +924,6 @@ namespace LOTRO_DAT {
|
|
|
dat_state_ = UPDATED;
|
|
|
}
|
|
|
}
|
|
|
- CommitChanges();
|
|
|
LOG(INFO) << "Dat file " << (updated ? "WAS " : "WASN'T ") << "updated by game.";
|
|
|
return updated;
|
|
|
}
|
|
@@ -1029,7 +939,6 @@ namespace LOTRO_DAT {
|
|
|
}
|
|
|
data = db->GetNextFile();
|
|
|
}
|
|
|
- CommitChanges();
|
|
|
LOG(INFO) << "Successfully repaired with database";
|
|
|
return SUCCESS;
|
|
|
}
|
|
@@ -1136,7 +1045,7 @@ namespace LOTRO_DAT {
|
|
|
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);
|
|
|
+ pending_dictionary_.insert(file_id);
|
|
|
}
|
|
|
}
|
|
|
LOG(INFO) << "Category " << category << " enabled successfully";
|
|
@@ -1158,7 +1067,7 @@ namespace LOTRO_DAT {
|
|
|
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);
|
|
|
+ pending_dictionary_.insert(file_id);
|
|
|
}
|
|
|
}
|
|
|
LOG(INFO) << "Category " << category << " disabled successfully";
|
|
@@ -1184,5 +1093,21 @@ namespace LOTRO_DAT {
|
|
|
const std::string &DatFile::filename() const {
|
|
|
return filename_;
|
|
|
}
|
|
|
+
|
|
|
+ DAT_RESULT DatFile::CommitDirectories() {
|
|
|
+ for (auto file_id : pending_dictionary_) {
|
|
|
+ WriteData(dictionary_[file_id]->MakeHeaderData(), 32, dictionary_[file_id]->dictionary_offset());
|
|
|
+ }
|
|
|
+ pending_dictionary_.clear();
|
|
|
+ return SUCCESS;
|
|
|
+ }
|
|
|
+
|
|
|
+ void DatFile::AddBufferedSize() {
|
|
|
+ if (free_buffered_size_ >= MIN_BUFFERED_SIZE)
|
|
|
+ return;
|
|
|
+ BinaryData nulls(MAX_BUFFERED_SIZE);
|
|
|
+ WriteData(nulls, MAX_BUFFERED_SIZE, file_size_);
|
|
|
+ free_buffered_size_ = MAX_BUFFERED_SIZE;
|
|
|
+ }
|
|
|
}
|
|
|
}
|