فهرست منبع

Ver. 5.1.1. See changelog for more information

Ivan Arkhipov 6 سال پیش
والد
کامیت
0b7b48e9f6

+ 4 - 0
CHANGELOG

@@ -49,4 +49,8 @@ Version 5.1.0
     * Added additional compilation flags in order to improve speed.
     * Changed locales' file structure and placement. Old structure made .dat file have a chance to break while game updating.
     * Improved stability and safety while reading files' data.
+----------------------------------------------------------------------
+Version 5.1.1
+    * Fixed problem, when game update caused .dat file corruption ("Unable to send request" error after update).
+    * Improved locales' file commit process. Now fixed place in .dat file is reserved for locales, they won't 'eat' more data after every patch apply.
 ----------------------------------------------------------------------

BIN
bin/LotRO_dat_extractor.exe


BIN
bin/LotRO_dat_patcher.exe


+ 2 - 0
include/DatFile.h

@@ -223,6 +223,8 @@ namespace LOTRO_DAT {
         long long file_size_;
         long long version1_;
         long long version2_;
+        long long fragmentation_journal_size_;
+        long long fragmentation_journal_end_;
         long long root_directory_offset_;
         long long fragmentation_journal_offset_;
 

BIN
lib/libLotroDat.dll.a


BIN
lib/libLotroDat_static.a


+ 38 - 8
src/DatFile.cpp

@@ -476,6 +476,8 @@ namespace LOTRO_DAT {
         version1_ = data.ToNumber<4>(0x14C);
         version2_ = data.ToNumber<4>(0x150);
         fragmentation_journal_offset_ = data.ToNumber<4>(0x154);
+        fragmentation_journal_end_ = data.ToNumber<4>(0x158);
+        fragmentation_journal_size_ = data.ToNumber<4>(0x15C);
         root_directory_offset_ = data.ToNumber<4>(0x160);
         auto size1 = data.ToNumber<4>(0x148);
 
@@ -687,6 +689,8 @@ namespace LOTRO_DAT {
         WriteData(BinaryData::FromNumber<4>(version1_), 4, 0x14C);
         WriteData(BinaryData::FromNumber<4>(version2_), 4, 0x150);
         WriteData(BinaryData::FromNumber<4>(fragmentation_journal_offset_), 4, 0x154);
+        WriteData(BinaryData::FromNumber<4>(fragmentation_journal_end_), 4, 0x158);
+        WriteData(BinaryData::FromNumber<4>(fragmentation_journal_size_), 4, 0x15C);
         WriteData(BinaryData::FromNumber<4>(root_directory_offset_), 4, 0x160);
         LOG(DEBUG) << "Finished updating header";
         return SUCCESS;
@@ -704,9 +708,11 @@ namespace LOTRO_DAT {
         if (!pending_dictionary_.empty()) {
             CommitLocales();
             CommitDirectories();
+            fragmentation_journal_end_ = 0;
+            fragmentation_journal_size_ = 0;
             UpdateHeader();
         }
-        //ClearFragmentationJournal();
+        ClearFragmentationJournal();
 
         orig_dict_.clear();
         pending_patch_.clear();
@@ -739,8 +745,8 @@ namespace LOTRO_DAT {
         ReadData(dicts_data, 4, 300);
         long long dict_offset = dicts_data.ToNumber<4>(0);
 
-        if (dict_offset == 0) {
-            LOG(INFO) << "Dictionary offset is empty. Passing.";
+        if (dict_offset == 0 || dict_offset + 8 >= file_size_) {
+            LOG(INFO) << "Dictionary offset is empty or incorrect. Passing.";
             return SUCCESS;
         }
 
@@ -759,6 +765,11 @@ namespace LOTRO_DAT {
         dicts_data = BinaryData((unsigned)dict_size);
         ReadData(dicts_data, dict_size, dict_offset + 8);
 
+        if (dicts_data.size() < 15) {
+            LOG(ERROR) << "Incorrect dictionary. Passing.";
+            return FAILED;
+        }
+
         BinaryData hi_data = dicts_data.CutData(0, 15) + BinaryData("\0", 1);
         std::string hi = std::string((char *) (hi_data.data()));
         LOG(DEBUG) << "hi info is " << hi;
@@ -1032,11 +1043,30 @@ namespace LOTRO_DAT {
             current_size += 4;
         }
 
-        WriteData(BinaryData::FromNumber<4>(binary_data.size()), 4, file_size_);
-        WriteData(BinaryData::FromNumber<4>(100), 4, file_size_ + 4);
-        WriteData(binary_data, binary_data.size(), file_size_ + 8);
-        WriteData(BinaryData::FromNumber<4>(file_size_), 4, 300);
-        file_size_ += binary_data.size() + 8;
+
+        BinaryData dicts_data(4);
+        ReadData(dicts_data, 4, 300);
+        long long dict_offset = dicts_data.ToNumber<4>(0);
+        ReadData(dicts_data, 4, dict_offset);
+        long long dict_size = dicts_data.ToNumber<4>(0);
+
+        if (binary_data.size() > dict_size) {
+            WriteData(BinaryData::FromNumber<4>(std::max(binary_data.size(), 20u * 1024u * 1024u)), 4, file_size_);
+            WriteData(BinaryData::FromNumber<4>(100), 4, file_size_ + 4);
+            WriteData(binary_data, binary_data.size(), file_size_ + 8);
+            WriteData(BinaryData::FromNumber<4>(file_size_), 4, 300);
+            file_size_ += binary_data.size();
+
+            // Adding space for 25 megabytes locales file in total.
+            BinaryData nulls(unsigned(20 * 1024 * 1024));
+            WriteData(nulls, nulls.size(), file_size_);
+            file_size_ += nulls.size();
+
+        } else {
+            WriteData(BinaryData::FromNumber<4>(std::max(binary_data.size(), 20u * 1024u * 1024u)), 4, dict_offset);
+            WriteData(BinaryData::FromNumber<4>(100), 4, dict_offset + 4);
+            WriteData(binary_data, binary_data.size(), dict_offset + 8);
+        }
         LOG(INFO) << "Locales commited successfully";
         return SUCCESS;
     }

+ 1 - 1
src/Examples/extractor_example.cpp

@@ -31,7 +31,7 @@ bool exportUnknownToDb = false;
 // There is no need to change anything else
 
 int main() {
-    std::cout << "Gi1dor's LotRO .dat extractor ver. 5.1.0" << std::endl;
+    std::cout << "Gi1dor's LotRO .dat extractor ver. 5.1.1" << std::endl;
 
     std::cout << "Hello! I'm a basic shell version of .dat file extractor. I can open .dat file directly, "
             "if you write path to it (with name of file) in file \"dat_file_path.txt\"\n";

+ 1 - 1
src/Examples/patcher_example.cpp

@@ -15,7 +15,7 @@ using namespace LOTRO_DAT;
 using namespace std;
 
 int main() {
-    std::cout << "Gi1dor's LotRO .dat patcher ver. 5.1.0" << std::endl;
+    std::cout << "Gi1dor's LotRO .dat patcher ver. 5.1.1" << std::endl;
     freopen("patcher_errors.log", "w", stderr);
 
     setbuf(stdout, nullptr);