浏览代码

Ver. 3.3.0. Added functions for checking if DatFile was modified during game update

Ivan Arkhipov 6 年之前
父节点
当前提交
a20fae19a7
共有 7 个文件被更改,包括 54 次插入12 次删除
  1. 5 2
      CHANGELOG
  2. 3 1
      include/DatFile.h
  3. 二进制
      lib/libLotroDat.dll.a
  4. 二进制
      lib/libLotroDat_static.a
  5. 41 7
      src/DatFile.cpp
  6. 1 1
      src/Examples/extractor_example.cpp
  7. 4 1
      src/Examples/patcher_example.cpp

+ 5 - 2
CHANGELOG

@@ -1,6 +1,6 @@
 ----------------------------------------------------------------------
 Version 1.0.0
-	* First beta version of library, with most functions for extracting/patching already implemented
+    * First beta version of library, with most functions for extracting/patching already implemented
 ----------------------------------------------------------------------	
 Version 1.0.2
     * Fixed issue when some text files were patched but didn't appear in game ("<string error DID.." error due to incomplete dictionary update)
@@ -23,4 +23,7 @@ Version 3.1.0
 ----------------------------------------------------------------------
 Version 3.2.0
     * Added checkers for situations when .dat file wasn't patched at all or was patched by old launcher
-----------------------------------------------------------------------
+----------------------------------------------------------------------
+Version 3.3.0
+    * Added check and repair functions for situation, when .dat file was patched by LotRO launcher because of official update
+----------------------------------------------------------------------

+ 3 - 1
include/DatFile.h

@@ -150,6 +150,8 @@ namespace LOTRO_DAT {
 
         void RepairPatches(Database *db);
 
+        void FinishRepairingPatches();
+
         LOCALE current_locale();
 
         void EnableCategory(int category);
@@ -172,7 +174,7 @@ namespace LOTRO_DAT {
 
         std::unordered_map<long long, Subfile*> orig_dict_;
         std::unordered_map<long long, Subfile*> patch_dict_;
-        std::unordered_map<long long, Subfile*> pending_patch_;
+        std::unordered_set<long long> pending_patch_;
         std::unordered_set<long long> inactive_categories;
 
     private:

二进制
lib/libLotroDat.dll.a


二进制
lib/libLotroDat_static.a


+ 41 - 7
src/DatFile.cpp

@@ -803,11 +803,47 @@ namespace LOTRO_DAT {
     }
 
     bool DatFile::CheckIfUpdatedByGame() {
-        return false;
+        if (!pending_patch_.empty())
+            return true;
+        if (current_locale_ == ORIGINAL)
+            return false;
+
+        bool updated = false;
+
+        for (auto i : dictionary_) {
+            long long file_id = i.first;
+            Subfile* subfile = i.second;
+            if (inactive_categories.count(subfile->category) > 0)
+                continue;
+            if (patch_dict_.count(file_id) > 0
+                && (subfile->file_size() != patch_dict_[file_id]->file_size()
+                || subfile->file_offset() != patch_dict_[file_id]->file_offset()
+                || subfile->block_size() != patch_dict_[file_id]->block_size())) {
+                orig_dict_.erase(file_id);
+                patch_dict_.erase(file_id);
+                pending_patch_.insert(file_id);
+                updated = true;
+                dat_state_ = UPDATED;
+            }
+        }
+        CommitChanges();
+        return updated;
     }
 
     void DatFile::RepairPatches(Database *db) {
+        SubfileData data;
+        data = db->GetNextFile();
+        while (!data.Empty()) {
+            if (pending_patch_.count(data.options["fid"].as<long long>()) > 0) {
+                PatchFile(data);
+            }
+            data = db->GetNextFile();
+        }
+        CommitChanges();
+    }
 
+    void DatFile::FinishRepairingPatches() {
+        pending_patch_.clear();
     }
 
     LOCALE DatFile::current_locale() {
@@ -887,16 +923,15 @@ namespace LOTRO_DAT {
     }
 
     void DatFile::EnableCategory(int category) {
-        std::cout << "Disabling category " << category << std::endl;
+        std::cout << "Enabling category " << category << std::endl;
         if (inactive_categories.count(category) == 0)
             return;
         inactive_categories.erase(category);
+        dat_state_ = UPDATED;
 
         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_;
@@ -912,13 +947,11 @@ namespace LOTRO_DAT {
         if (inactive_categories.count(category) != 0)
             return;
         inactive_categories.insert(category);
+        dat_state_ = UPDATED;
 
         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_;
@@ -940,5 +973,6 @@ namespace LOTRO_DAT {
     bool DatFile::CheckIfPatchedByOldLauncher() {
         return dictionary_.count(620750000) > 0;
     }
+
 }
 }

+ 1 - 1
src/Examples/extractor_example.cpp

@@ -36,7 +36,7 @@ const bool exportUnknownToDb = false;
 // There is no need to change anything else
 
 int main() {
-    std::cout << "Gi1dor's LotRO .dat extractor ver. 3.2.0" << std::endl;
+    std::cout << "Gi1dor's LotRO .dat extractor ver. 3.3.0" << std::endl;
     const clock_t begin_time = clock();
 
     mkdir("Extracted data", 744);

+ 4 - 1
src/Examples/patcher_example.cpp

@@ -16,7 +16,7 @@ using namespace LOTRO_DAT;
 using namespace std;
 
 int main() {
-    std::cout << "Gi1dor's LotRO .dat patcher ver. 3.2.0" << std::endl;
+    std::cout << "Gi1dor's LotRO .dat patcher ver. 3.3.0" << std::endl;
     freopen("errors.log", "w", stderr);
 
     setbuf(stdout, NULL);
@@ -66,6 +66,9 @@ int main() {
     if (file.CheckIfPatchedByOldLauncher())
         std::cout << "MESSAGE: Dat file was patched by old launcher. Capability isn't guaranteed! Some functions may not work properly!!!\n";
 
+    if (file.CheckIfUpdatedByGame())
+        std::cout << "MESSAGE: .dat file was updated by game! Need to repair patches with functions RepairPatches() and FinishRepairingPatches()\n";
+
     std::cout << "Files number: " << file.files_number() << std::endl;
 
     while (true) {