Pārlūkot izejas kodu

Version 6.0.0pre

Ivan Arkhipov 6 gadi atpakaļ
vecāks
revīzija
e536c87af4

+ 17 - 8
CMakeLists.txt

@@ -5,7 +5,7 @@ set(CMAKE_CXX_STANDARD 14)
 set(PROJECT_BINARY_DIR bin)
 set(PROJECT_VERSION 5.2.0)
 
-SET(CMAKE_CXX_FLAGS  "${CMAKE_CXX_FLAGS} ${GCC_COVERAGE_COMPILE_FLAGS} -O2 -Wall -Wextra")
+SET(CMAKE_CXX_FLAGS  "${CMAKE_CXX_FLAGS} ${GCC_COVERAGE_COMPILE_FLAGS} -O3 -Wall -Wextra")
 SET(CMAKE_EXE_LINKER_FLAGS  "${CMAKE_EXE_LINKER_FLAGS} ${GCC_COVERAGE_LINK_FLAGS}")
 
 if (MSVS)
@@ -24,13 +24,22 @@ SET(LIBRARY_OUTPUT_PATH ${CMAKE_OUTPUT_DIR})
 
 
 set(HEADER_FILES
-    ${CMAKE_SOURCE_DIR}/include/BinaryData.h
-    ${CMAKE_SOURCE_DIR}/include/Database.h
-    ${CMAKE_SOURCE_DIR}/include/DatFile.h
-    ${CMAKE_SOURCE_DIR}/include/LotroDat.h
-    ${CMAKE_SOURCE_DIR}/include/SubDirectory.h
-    ${CMAKE_SOURCE_DIR}/include/Subfile.h
-    ${CMAKE_SOURCE_DIR}/include/SubfileData.h
+        ${CMAKE_SOURCE_DIR}/include/LotroDat.h
+        ${CMAKE_SOURCE_DIR}/include/SubfileData.h
+
+        ${CMAKE_SOURCE_DIR}/include/DatFile.h
+        ${CMAKE_SOURCE_DIR}/include/BinaryData.h
+        ${CMAKE_SOURCE_DIR}/include/Database.h
+        ${CMAKE_SOURCE_DIR}/include/Subfile.h
+        ${CMAKE_SOURCE_DIR}/include/SubDirectory.h
+
+        ${CMAKE_SOURCE_DIR}/include/Subfiles/TextSubfile.h
+        ${CMAKE_SOURCE_DIR}/include/Subfiles/JpgSubfile.h
+        ${CMAKE_SOURCE_DIR}/include/Subfiles/DdsSubfile.h
+        ${CMAKE_SOURCE_DIR}/include/Subfiles/OggSubfile.h
+        ${CMAKE_SOURCE_DIR}/include/Subfiles/FontSubfile.h
+        ${CMAKE_SOURCE_DIR}/include/Subfiles/WavSubfile.h
+        ${CMAKE_SOURCE_DIR}/include/Subfiles/UnknownSubfile.h
 )
 
 set(SOURCE_FILES

BIN
bin/LotRO_dat_extractor.exe


BIN
bin/LotRO_dat_patcher.exe


+ 13 - 11
include/DatFile.h

@@ -31,7 +31,7 @@ namespace LOTRO_DAT {
 
     class SubDirectory;
 
-    class Subfile;
+    class SubFile;
 
     class SubfileData;
 
@@ -90,6 +90,8 @@ namespace LOTRO_DAT {
 
     public:
         DatFile();
+        explicit DatFile(const DatFile &other) = delete;
+        DatFile& operator=(const DatFile &other) = delete;
 
         DAT_RESULT InitDatFile(const std::string &filename, int dat_id);
 
@@ -122,7 +124,7 @@ namespace LOTRO_DAT {
 
         const std::string& filename() const;
 
-        BinaryData GetFileData(const Subfile *file, long long offset = 0);
+        BinaryData GetFileData(const std::shared_ptr<SubFile>& file, long long offset = 0);
 
         DAT_RESULT CloseDatFile();
 
@@ -146,13 +148,13 @@ namespace LOTRO_DAT {
 
         // PATCH SECTION
 
-        DAT_RESULT ApplyFilePatch(Subfile *file, BinaryData &data);
+        DAT_RESULT ApplyFilePatch(std::shared_ptr<SubFile> file, BinaryData &data);
 
     private:
         long long free_buffered_size_;
 
-        const long long MAX_BUFFERED_SIZE = 10 * 1024 * 1024; // 50 megabytes;
-        const long long MIN_BUFFERED_SIZE = 1 * 1024 * 1024; // 5 megabytes;
+        const unsigned MAX_BUFFERED_SIZE = 10 * 1024 * 1024; // 50 megabytes;
+        const unsigned MIN_BUFFERED_SIZE = 1 * 1024 * 1024; // 5 megabytes;
 
         void AddBufferedSize();
 
@@ -185,7 +187,7 @@ namespace LOTRO_DAT {
 
         DAT_RESULT RepairDatFile();
 
-        bool CorrectSubfile(Subfile *file);
+        bool CorrectSubfile(std::shared_ptr<SubFile> file);
 
         bool CheckIfUpdatedByGame();
 
@@ -203,25 +205,25 @@ namespace LOTRO_DAT {
 
         DAT_RESULT RemoveBackup(const std::string &backup_datname);
     private:
-        std::map<long long, Subfile*>* GetLocaleDictReference(LOCALE locale);
+        std::map<long long, std::shared_ptr<SubFile>>& GetLocaleDictReference(LOCALE locale);
 
     private:
         LOCALE current_locale_;
 
         std::string filename_;
 
-        std::map<long long, Subfile*> orig_dict_;
-        std::map<long long, Subfile*> patch_dict_;
+        std::map<long long, std::shared_ptr<SubFile>> orig_dict_;
+        std::map<long long, std::shared_ptr<SubFile>> patch_dict_;
         std::set<long long> pending_patch_;
         std::set<long long> inactive_categories;
 
     private:
         FILE *file_handler_;
 
-        SubDirectory *root_directory_;
+        std::shared_ptr<SubDirectory> root_directory_;
 
         std::set<long long> pending_dictionary_;
-        std::map<long long, Subfile *> dictionary_;
+        std::map<long long, std::shared_ptr<SubFile> > dictionary_;
 
         long long constant1_;
         long long constant2_;

+ 4 - 1
include/SubDirectory.h

@@ -26,12 +26,13 @@ namespace LOTRO_DAT
     {
     public:
         struct SubDirectoryOffsetComp {
-            bool operator() (const SubDirectory* f, const SubDirectory *s){
+            bool operator() (const std::shared_ptr<SubDirectory> &f, const std::shared_ptr<SubDirectory> &s){
                 if (!f || !s)
                     return false;
                 return f->offset_ < s->offset_;
             }
         };
+
         SubDirectory() = delete;
         explicit SubDirectory(const SubDirectory& other) = delete;
         SubDirectory& operator =(const SubDirectory &other) = delete;
@@ -43,6 +44,8 @@ namespace LOTRO_DAT
         bool MakeSubDirectories();
         bool MakeSubFiles();
 
+        void clear();
+
         static std::unordered_set<long long> visited_subdirectories_;
         static std::unordered_set<long long> visited_subfiles_;
         static std::set<std::shared_ptr<SubDirectory>, SubDirectoryOffsetComp> subdir_init_queue_;

+ 1 - 1
include/SubFile.h

@@ -27,7 +27,7 @@ namespace LOTRO_DAT
     public:
         SubFile() = delete;
         explicit SubFile(const SubFile &other) = delete;
-		SubFile &operator =(const SubFile &other) = delete;
+		SubFile &operator =(const SubFile &other);
 
         SubFile(DatFile &dat, const BinaryData &header);
 		SubFile(DatFile &dat, long long dictionary_offset, long long fragments_count, long long unknown1,

BIN
lib/libLotroDat.dll.a


BIN
lib/libLotroDat_static.a


+ 58 - 35
src/DatFile.cpp

@@ -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_;
         //truncate64(filename_.c_str(), file_size_);
 
         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];
 
 //        if (!CorrectSubfile(file)) {
 //            if (current_locale_ == PATCHED && patch_dict_.count(file_id) > 0) {
@@ -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.";
 
 //        if (patch_dict_.size() == 0 && pending_dictionary_.size() == 0) {
@@ -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()); // Создали новое значение
         }
 
         // If category is forbidden, then return file header data to original state
@@ -921,7 +944,7 @@ namespace LOTRO_DAT {
     // INPUT-OUTPUT SECTION
     //------------------------------------------------//
 
-    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 {
     // CHECKERS SECTION
     //------------------------------------------------//
 
-    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];

+ 25 - 17
src/SubDirectory.cpp

@@ -6,15 +6,17 @@
 #include "DatFile.h"
 #include "SubFile.h"
 #include "BinaryData.h"
+#include "SubfileData.h"
 #include "EasyLogging++/easylogging++.h"
 
-#include "Subfiles/TextSubfile.h"
-#include "Subfiles/DdsSubfile.h"
-#include "Subfiles/FontSubfile.h"
-#include "Subfiles/JpgSubfile.h"
-#include "Subfiles/OggSubfile.h"
-#include "Subfiles/WavSubfile.h"
-#include "Subfiles/UnknownSubfile.h"
+#include "Subfiles/TextSubFile.h"
+#include "Subfiles/DdsSubFile.h"
+#include "Subfiles/FontSubFile.h"
+#include "Subfiles/JpgSubFile.h"
+#include "Subfiles/OggSubFile.h"
+#include "Subfiles/WavSubFile.h"
+#include "Subfiles/UnknownSubFile.h"
+
 
 namespace LOTRO_DAT {
     std::unordered_set<long long> SubDirectory::visited_subdirectories_ = std::unordered_set<long long>();
@@ -58,7 +60,7 @@ namespace LOTRO_DAT {
             }
             visited_subdirectories_.insert(data.ToNumber<4>(i + 4));
 
-            SubDirectory *subdir = new SubDirectory(data.ToNumber<4>(i + 4), dat_);
+            std::shared_ptr<SubDirectory> subdir = std::make_shared<SubDirectory>(data.ToNumber<4>(i + 4), dat_);
 
             //if (subdir->subfiles_.empty() && subdir->subdirs_.empty()) {
             //    LOG(WARNING) << "Sub-subdirectory is empty or made empty... Dictionary offset = " << offset_ + i << "; Passing others";
@@ -122,7 +124,6 @@ namespace LOTRO_DAT {
                 visited_subfiles_.insert(subfiles_[i]->file_id());
             } else {
                 LOG(WARNING) << "Incorrect SubFile in directory at offset " << offset_ + 63 * 8 + 4 + 32 * i << " (id = " << subfiles_[i]->file_id() << ");";
-                delete subfiles_[i];
                 subfiles_[i] = nullptr;
                 break;
             }
@@ -132,6 +133,8 @@ namespace LOTRO_DAT {
 
     void SubDirectory::MakeDictionary(std::map<long long, std::shared_ptr<SubFile> > &dict) {
         for (const std::shared_ptr<SubFile> &file: subfiles_) {
+            if (!file)
+                continue;
             if (dict.count(file->file_id() != 0)) {
                 LOG(WARNING) << "Found multiple instances of file " << file->file_id() << " at dictionary offset "
                              << file->dictionary_offset() << ". Base offset = " << dict[file->file_id()]->dictionary_offset();
@@ -154,22 +157,22 @@ namespace LOTRO_DAT {
 
         switch (type) {
             case TEXT:
-                return std::dynamic_pointer_cast<SubFile>(std::make_shared<TextSubfile>(dat_, dictionary_offset, unknown1, file_id, file_offset, file_size, timestamp, version, block_size, unknown2));
+                return std::dynamic_pointer_cast<SubFile>(std::make_shared<TextSubFile>(dat_, dictionary_offset, unknown1, file_id, file_offset, file_size, timestamp, version, block_size, unknown2));
             case JPG:
-                return std::dynamic_pointer_cast<SubFile>(std::make_shared<JpgSubfile>(dat_, dictionary_offset, unknown1, file_id, file_offset, file_size, timestamp, version, block_size, unknown2));
+                return std::dynamic_pointer_cast<SubFile>(std::make_shared<JpgSubFile>(dat_, dictionary_offset, unknown1, file_id, file_offset, file_size, timestamp, version, block_size, unknown2));
             case DDS:
-                return std::dynamic_pointer_cast<SubFile>(std::make_shared<DdsSubfile>(dat_, dictionary_offset, unknown1, file_id, file_offset, file_size, timestamp, version, block_size, unknown2));
+                return std::dynamic_pointer_cast<SubFile>(std::make_shared<DdsSubFile>(dat_, dictionary_offset, unknown1, file_id, file_offset, file_size, timestamp, version, block_size, unknown2));
             case WAV:
-                return std::dynamic_pointer_cast<SubFile>(std::make_shared<WavSubfile>(dat_, dictionary_offset, unknown1, file_id, file_offset, file_size, timestamp, version, block_size, unknown2));
+                return std::dynamic_pointer_cast<SubFile>(std::make_shared<WavSubFile>(dat_, dictionary_offset, unknown1, file_id, file_offset, file_size, timestamp, version, block_size, unknown2));
             case OGG:
-                return std::dynamic_pointer_cast<SubFile>(std::make_shared<OggSubfile>(dat_, dictionary_offset, unknown1, file_id, file_offset, file_size, timestamp, version, block_size, unknown2));
+                return std::dynamic_pointer_cast<SubFile>(std::make_shared<OggSubFile>(dat_, dictionary_offset, unknown1, file_id, file_offset, file_size, timestamp, version, block_size, unknown2));
             case FONT:
-                return std::dynamic_pointer_cast<SubFile>(std::make_shared<FontSubfile>(dat_, dictionary_offset, unknown1, file_id, file_offset, file_size, timestamp, version, block_size, unknown2));
+                return std::dynamic_pointer_cast<SubFile>(std::make_shared<FontSubFile>(dat_, dictionary_offset, unknown1, file_id, file_offset, file_size, timestamp, version, block_size, unknown2));
             case UNKNOWN:
-                return std::dynamic_pointer_cast<SubFile>(std::make_shared<UnknownSubfile>(dat_, dictionary_offset, unknown1, file_id, file_offset, file_size, timestamp, version, block_size, unknown2));
+                return std::dynamic_pointer_cast<SubFile>(std::make_shared<UnknownSubFile>(dat_, dictionary_offset, unknown1, file_id, file_offset, file_size, timestamp, version, block_size, unknown2));
         }
         LOG(ERROR) << "Incorrect file type..";
-        return std::dynamic_pointer_cast<SubFile>(std::make_shared<UnknownSubfile>(dat_, dictionary_offset, unknown1, file_id, file_offset, file_size, timestamp, version, block_size, unknown2));
+        return std::dynamic_pointer_cast<SubFile>(std::make_shared<UnknownSubFile>(dat_, dictionary_offset, unknown1, file_id, file_offset, file_size, timestamp, version, block_size, unknown2));
     }
 
     FILE_TYPE SubDirectory::GetSubfileType(long long file_id, long long file_offset) const {
@@ -211,4 +214,9 @@ namespace LOTRO_DAT {
 
         return UNKNOWN;
     }
+
+    void SubDirectory::clear() {
+        subfiles_.clear();
+        subdirs_.clear();
+    }
 };

+ 1 - 2
src/SubFile.cpp

@@ -158,11 +158,10 @@ namespace LOTRO_DAT {
     }
 
     SubFile &SubFile::operator=(const SubFile &b) {
-        if (*this == b)
+        if (*this == b || &dat_ != &b.dat_)
             return *this;
 
         category = b.category;
-        dat_ = b.dat_;
         unknown1_ = b.unknown1_; // unknown1
         file_id_ = b.file_id_; // file_id
         file_offset_ = b.file_offset_; // file_offset

+ 0 - 2
src/Subfiles/WavSubFile.cpp

@@ -10,8 +10,6 @@
 #include "EasyLogging++/easylogging++.h"
 
 namespace LOTRO_DAT {
-    WavSubFile::WavSubFile() = default;
-
     WavSubFile::WavSubFile(DatFile &dat, long long dictionary_offset, long long unknown1,
                            long long file_id, long long file_offset, long long file_size,
                            long long timestamp, long long version, long long block_size, long long unknown2)