Browse Source

Simplified SubDirectory structure (initialisation moved to DatFileSystem class) & improved SubFile (each concrete SubFile initialises using abstract SubFile object

Ivan Arkhipov 5 years ago
parent
commit
cdcdcb1739

+ 11 - 43
include/SubDirectory.h

@@ -5,63 +5,31 @@
 #ifndef LOTRO_DAT_PATCHER_SUBDIRECTORY_H
 #define LOTRO_DAT_PATCHER_SUBDIRECTORY_H
 
-#include <vector>
-#include <map>
-#include <queue>
-#include <unordered_map>
-#include <unordered_set>
-#include "SubFile.h"
-
-
 extern "C++"
 {
-namespace LOTRO_DAT
-{
-    enum FILE_TYPE : int;
-    class DatFile;
-    class BinaryData;
-    class SubFile;
-
-    class SubDirectory
-    {
+namespace LOTRO_DAT {
+    class SubDirectory {
     public:
-        struct SubDirectoryOffsetComp {
-            bool operator() (const std::shared_ptr<SubDirectory> &f, const std::shared_ptr<SubDirectory> &s){
-                if (!f || !s)
-                    return false;
-                return f->offset_ < s->offset_;
+        struct SubDirectoryOffsetComparator {
+            bool operator()(const SubDirectory &f, const SubDirectory &s) {
+                return f.offset_ < s.offset_;
             }
         };
 
         SubDirectory() = delete;
-        explicit SubDirectory(const SubDirectory& other) = delete;
-        SubDirectory& operator =(const SubDirectory &other) = delete;
 
-        SubDirectory(long long offset, DatFile &dat, long long max_subdirs = 63);
-        ~SubDirectory();
-        void MakeDictionary(std::map<long long, std::shared_ptr<SubFile>> &dict);
+        explicit SubDirectory(const SubDirectory &other) = delete;
 
-        bool MakeSubDirectories();
-        bool MakeSubFiles();
+        SubDirectory &operator=(const SubDirectory &other) = delete;
 
-        void clear();
+        SubDirectory(long long unknown, long long offset);
 
-        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_;
-        static std::set<std::shared_ptr<SubDirectory>, SubDirectoryOffsetComp> subfile_init_queue_;
+    public:
+        long long offset();
 
     private:
-        std::shared_ptr<SubFile> MakeSubfile(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);
-
-        FILE_TYPE GetSubfileType(long long file_id, long long file_offset) const;
-        DatFile &dat_;
+        long long unknown_;
         long long offset_;
-        long long max_subdirs_;
-
-        std::vector<std::shared_ptr<SubDirectory>> subdirs_;
-        std::vector<std::shared_ptr<SubFile>> subfiles_;
     };
 }
 };

+ 12 - 3
include/SubFile.h

@@ -22,9 +22,16 @@ namespace LOTRO_DAT
 
     class SubFile
     {
-        friend class DatFile;
+        friend class DatFileSystem;
 		friend class SubDirectory;
     public:
+        struct SubFileIdComparator {
+            bool operator() (const SubFile &f, const SubFile &s){
+                return f.file_id_ < s.file_id_;
+            }
+        };
+
+
         SubFile();
         SubFile(const SubFile &other) = default;
 		SubFile &operator =(const SubFile &other) = default;
@@ -39,9 +46,7 @@ namespace LOTRO_DAT
         virtual std::string Extension() const;
 
         virtual SubfileData PrepareForExport(const BinaryData &file_data);
-
         virtual BinaryData MakeForImport(const BinaryData &old_data, const SubfileData &data);
-
 		BinaryData MakeHeaderData() const;
 
 		long long dictionary_offset() const;
@@ -57,6 +62,10 @@ namespace LOTRO_DAT
 		bool operator ==(const SubFile &b) const;
 		bool operator !=(const SubFile &b) const;
 
+
+        static FILE_TYPE GetSubfileType(DatFile& dat, SubFile preinit_file);
+        static std::shared_ptr<SubFile> MakeSubfile(DatFile& dat, SubFile preinit_file);
+
         long long category;
 
 	protected:

+ 1 - 3
include/Subfiles/DdsSubFile.h

@@ -14,9 +14,7 @@ namespace LOTRO_DAT {
         explicit DdsSubFile(const DdsSubFile &other) = delete;
         DdsSubFile &operator =(const DdsSubFile &other) = delete;
 
-        DdsSubFile(DatFile &dat, long long dictionary_offset, long long fragments_count, 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);
+        DdsSubFile(DatFile &dat, SubFile preinit_file);
 
         FILE_TYPE FileType() const override;
 

+ 1 - 3
include/Subfiles/FontSubFile.h

@@ -15,9 +15,7 @@ namespace LOTRO_DAT {
         explicit FontSubFile(const FontSubFile &other) = delete;
         FontSubFile &operator =(const FontSubFile &other) = delete;
 
-        FontSubFile(DatFile &dat, long long dictionary_offset, long long fragments_count, 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);
+        FontSubFile(DatFile &dat, SubFile preinit_file);
 
         FILE_TYPE FileType() const override;
 

+ 1 - 3
include/Subfiles/JpgSubFile.h

@@ -15,9 +15,7 @@ namespace LOTRO_DAT {
         explicit JpgSubFile(const JpgSubFile &other) = delete;
         JpgSubFile &operator =(const JpgSubFile &other) = delete;
 
-        JpgSubFile(DatFile &dat, long long dictionary_offset, long long fragments_count, 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);
+        JpgSubFile(DatFile &dat, SubFile preinit_file);
 
 
         FILE_TYPE FileType() const override;

+ 1 - 3
include/Subfiles/OggSubFile.h

@@ -14,9 +14,7 @@ namespace LOTRO_DAT {
         explicit OggSubFile(const OggSubFile &other) = delete;
         OggSubFile &operator =(const OggSubFile &other) = delete;
 
-        OggSubFile(DatFile &dat, long long dictionary_offset,  long long fragments_count, 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);
+        OggSubFile(DatFile &dat, SubFile preinit_file);
 
         FILE_TYPE FileType() const override;
         std::string Extension() const override;

+ 1 - 3
include/Subfiles/TextSubFile.h

@@ -30,9 +30,7 @@ namespace LOTRO_DAT {
         SubFile &operator =(const TextSubFile &other) = delete;
 
 
-        TextSubFile(DatFile &dat, long long dictionary_offset, long long fragments_count, 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);
+        TextSubFile(DatFile &dat, SubFile preinit_file);
 
         FILE_TYPE FileType() const override;
 

+ 1 - 3
include/Subfiles/UnknownSubFile.h

@@ -14,9 +14,7 @@ namespace LOTRO_DAT {
         explicit UnknownSubFile(const UnknownSubFile &other) = delete;
         SubFile &operator =(const UnknownSubFile &other) = delete;
 
-        UnknownSubFile(DatFile &dat, long long dictionary_offset, long long fragments_count, 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);
+        UnknownSubFile(DatFile &dat, SubFile preinit_file);
 
         FILE_TYPE FileType() const override;
         std::string Extension() const override;

+ 1 - 3
include/Subfiles/WavSubFile.h

@@ -14,9 +14,7 @@ namespace LOTRO_DAT {
         explicit WavSubFile(const WavSubFile &other) = delete;
         WavSubFile &operator =(const WavSubFile &other) = delete;
 
-        WavSubFile(DatFile &dat, long long dictionary_offset, long long fragments_count, 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);
+        WavSubFile(DatFile &dat, SubFile preinit_file);
 
 
         FILE_TYPE FileType() const override;

+ 4 - 0
src/Examples/info_gatherer.cpp

@@ -0,0 +1,4 @@
+//
+// Created by kikab on 10.06.2018.
+//
+

+ 5 - 222
src/SubDirectory.cpp

@@ -1,231 +1,14 @@
 //
 // Created by Иван_Архипов on 07.11.2017.
 //
-#include "SubDirectory.h"
-
-#include "DatFile.h"
-#include "SubFile.h"
-#include "BinaryData.h"
-#include "SubfileData.h"
-#include "EasyLogging++/easylogging++.h"
-#include "DatOperationResult.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 <SubDirectory.h>
 
 namespace LOTRO_DAT {
-    std::unordered_set<long long> SubDirectory::visited_subdirectories_ = std::unordered_set<long long>();
-
-    std::unordered_set<long long> SubDirectory::visited_subfiles_ = std::unordered_set<long long>();
-
-    std::set<std::shared_ptr<SubDirectory>, SubDirectory::SubDirectoryOffsetComp> SubDirectory::subdir_init_queue_
-           = std::set<std::shared_ptr<SubDirectory>, SubDirectory::SubDirectoryOffsetComp>();
-
-    std::set<std::shared_ptr<SubDirectory>, SubDirectory::SubDirectoryOffsetComp> SubDirectory::subfile_init_queue_
-            = std::set<std::shared_ptr<SubDirectory>, SubDirectory::SubDirectoryOffsetComp>();
-
-
-    SubDirectory::~SubDirectory() {
-        subfiles_.clear();
-        subdirs_.clear();
-    }
-
-    SubDirectory::SubDirectory(long long offset, DatFile &dat, long long max_subdirs) :
-            dat_(dat), offset_(offset), max_subdirs_(max_subdirs) {
-    }
-
-    bool SubDirectory::MakeSubDirectories() {
-        BinaryData data(1024);
-        dat_.getIO().ReadData(data, 63 * 8, offset_);
-
-        if (data.Empty()) {
-            LOG(ERROR) << "(READ ERROR) Incorrect directory at offset " << offset_;
-            return false;
-        }
-
-        if (data.ToNumber<4>(0) != 0 || data.ToNumber<4>(4) != 0) {
-            LOG(WARNING) << "first 8 bytes are not equal to 0 at offset " << offset_;
-            return false;
-        }
-
-        for (unsigned int i = 8; i < 63 * 8; i += 8) {
-            if (data.ToNumber<4>(i) == 0 || data.ToNumber<4>(i + 4) == 0)
-                break;
-
-//            if (visited_subdirectories_.count(data.ToNumber<4>(i + 4)) > 0) {
-//                LOG(WARNING) << "Visiting subdirectory at offset " << data.ToNumber<4>(i + 4) << " more than one time. Passing.";
-//                continue;
-//            }
-            visited_subdirectories_.insert(data.ToNumber<4>(i + 4));
-
-            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";
-            //    break;
-            //} else {
-                subdirs_.push_back(subdir);
-                subdir_init_queue_.insert(subdir);
-            //}
-        }
-        return true;
-    }
-
-    bool SubDirectory::MakeSubFiles() {
-        BinaryData data = BinaryData(4);
-        dat_.getIO().ReadData(data, 4, offset_ + 63 * 8);
-
-        if (data.Empty()) {
-            LOG(ERROR) << "(READ ERROR) Incorrect directory at offset " << offset_;
-            return false;
-        }
-
-        auto subfiles_number = data.ToNumber<4>(0);
-        if (subfiles_number >= 64) {
-            LOG(ERROR) << "Incorrect directory (subfiles_num >= 64) at offset " << offset_;
-            return false;
-        }
-
-        subfiles_.resize(unsigned(subfiles_number), nullptr);
-        BinaryData headers(32 * unsigned(subfiles_number));
-        dat_.getIO().ReadData(headers, 32 * subfiles_number, offset_ + 63 * 8 + 4);
-
-        // LOG(INFO) << "============== DIRECTORY offset = " << offset_ <<  "=======================";
-
-        for (int i = 0; i < subfiles_number; i++) {
-            BinaryData header = headers.CutData(32 * i, 32 * (i + 1));
-
-            if (header.Empty()) {
-                LOG(ERROR) << "(READ ERROR) Incorrect directory (unable to read subfile data) at offset " << offset_;
-                return false;
-            }
-
-            if (header.ToNumber<4>(20) == 0 || header.ToNumber<4>(28) != 0)
-                continue;
-
-            if (visited_subfiles_.count(header.ToNumber<4>(4))) {
-                LOG(ERROR) << "Found duplicate file with id " << header.ToNumber<4>(4);
-                break;
-            }
-
-            subfiles_[i] = MakeSubfile(
-                    offset_ + 63 * 8 + 4 + 32 * i,
-                    header.ToNumber<4>(0), // unknown1
-                    header.ToNumber<4>(4), // file_id
-                    header.ToNumber<4>(8), // file_offset
-                    header.ToNumber<4>(12), // file_size
-                    header.ToNumber<4>(16), // timestamp
-                    header.ToNumber<4>(20), // version
-                    header.ToNumber<4>(24), // block_size
-                    header.ToNumber<4>(28) // unknown2 - must be zero??
-            );
-
-            // LOG(INFO) << subfiles_[i]->file_id();
-
-
-            //if (dat_.CorrectSubfile(subfiles_[i])) {
-                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() << ");";
-//                subfiles_[i] = nullptr;
-//                break;
-//            }
-        }
-        return true;
-    }
-
-    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();
-                //if (!dat_.CorrectSubfile(file) || dat_.CorrectSubfile(dict[file->file_id_]))
-                //    continue;
-            }
-            dict[file->file_id()] = file;
-        }
-
-        for (const auto &dir : subdirs_) {
-            dir->MakeDictionary(dict);
-        }
-    }
-
-    std::shared_ptr<SubFile> SubDirectory::MakeSubfile(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) {
-
-        FILE_TYPE type = GetSubfileType(file_id, file_offset);
-
-        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));
-            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));
-            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));
-            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));
-            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));
-            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));
-            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));
-        }
-        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));
-    }
-
-    FILE_TYPE SubDirectory::GetSubfileType(long long file_id, long long file_offset) const {
-        // Text check based on file_id
-        if (((unsigned long long) file_id >> 24ull) == 0x25ull)
-            return TEXT;
-
-        // Font check based on file_id
-        if (((unsigned long long) file_id >> 24ull) == 0x42ull)
-            return FONT;
-
-        BinaryData header(64);
-        dat_.getIO().ReadData(header, 64, (unsigned) file_offset + 8);
-
-        if (header.Empty()) {
-            LOG(ERROR) << "Unable to read file header. file_id = " << file_id << ", offset = " << offset_;
-            return UNKNOWN;
-        }
-
-
-        // jpeg / dds check
-        if (((unsigned long long) file_id >> 24ull) == 0x41ull) {
-            long long soi = header.ToNumber<2>(24);
-            long long marker = header.ToNumber<2>(26);
-
-            //auto markerSize = header.ToNumber<short>(28);
-            //auto four = header.ToNumber<int>(30);
-
-            if ((soi == 0xD8FFll && marker == 0xE0FFll) || marker == 0xE1FFll)
-                return JPG;
-            return DDS;
-        }
-
-        // Ogg and Wav check
-        if (header[8] == 0x4F && header[9] == 0x67 && header[10] == 0x67 && header[11] == 0x53)
-            return OGG;
-        if (header[8] == 0x52 && header[9] == 0x49 && header[10] == 0x46 && header[11] == 0x46)
-            return WAV;
-
-        return UNKNOWN;
+    SubDirectory::SubDirectory(long long unknown, long long offset) :
+            unknown_(unknown), offset_(offset) {
     }
 
-    void SubDirectory::clear() {
-        subfiles_.clear();
-        subdirs_.clear();
+    long long SubDirectory::offset() {
+        return offset_;
     }
 };

+ 89 - 19
src/SubFile.cpp

@@ -8,26 +8,29 @@
 #include "SubfileData.h"
 #include "EasyLogging++/easylogging++.h"
 
+#include "DatOperationResult.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 <algorithm>
 #include <SubFile.h>
 
 
 const long long MAXSIZE = 50ll * 1024ll * 1024ll; // Setting maximal file size 50 MB; Files with size more than 50 mb
-                                                  // will be recognized as incorrect and passed.
-                                                  // This should be done because of not completely correct implementation
-                                                  // of Subfiles and Subdirectories search in DatFile.
-namespace LOTRO_DAT {
-    SubFile::SubFile() : dat_(nullptr) {
-        category = 0;
+// will be recognized as incorrect and passed.
+// This should be done because of not completely correct implementation
+// of Subfiles and Subdirectories search in DatFile.
 
-        unknown1_ = 0;
-        file_id_ = 0;
-        file_offset_ = 0;
-        file_size_ = 0;
-        timestamp_ = 0;
-        version_ = 0;
-        block_size_ = 0;
-        unknown2_ = 0;
+namespace LOTRO_DAT {
+    SubFile::SubFile() : dat_(nullptr), category(0), unknown1_(0), file_id_(0), file_offset_(0), file_size_(0),
+                         timestamp_(0), version_(0), block_size_(0), unknown2_(0) {
     }
 
     SubFile::SubFile(DatFile &dat, const BinaryData &header) : dat_(&dat) {
@@ -52,15 +55,15 @@ namespace LOTRO_DAT {
     }
 
     SubFile::SubFile(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) :
+                     long long file_offset, long long file_size, long long timestamp, long long version,
+                     long long block_size, long long unknown2) :
             category(0), dat_(&dat), dictionary_offset_(dictionary_offset), unknown1_(unknown1), file_id_(file_id),
-            file_offset_(file_offset),
-            file_size_(file_size), timestamp_(timestamp), version_(version), block_size_(block_size), unknown2_(unknown2) {
+            file_offset_(file_offset), file_size_(file_size), timestamp_(timestamp), version_(version),
+            block_size_(block_size), unknown2_(unknown2) {
 
         if (file_size_ > MAXSIZE) {
             LOG(ERROR) << "Bad SubFile::SubFile() - File size of file " << file_id << " with offset " << file_offset
-                       <<" is too much... Maybe it's incorrect..?";
+                       << " is too much... Maybe it's incorrect..?";
             file_id_ = -1;
             return;
         }
@@ -178,4 +181,71 @@ namespace LOTRO_DAT {
     bool SubFile::operator!=(const SubFile &b) const {
         return !(*this == b);
     }
+
+
+    static std::shared_ptr<SubFile> SubFile::MakeSubfile(DatFile &dat, SubFile preinit_file) {
+        FILE_TYPE type = SubFile::GetSubfileType(dat, preinit_file);
+
+        switch (type) {
+            case TEXT:
+                return std::dynamic_pointer_cast<SubFile>(std::make_shared<TextSubFile>(preinit_file));
+            case JPG:
+                return std::dynamic_pointer_cast<SubFile>(std::make_shared<JpgSubFile>(preinit_file));
+            case DDS:
+                return std::dynamic_pointer_cast<SubFile>(std::make_shared<DdsSubFile>(preinit_file));
+            case WAV:
+                return std::dynamic_pointer_cast<SubFile>(std::make_shared<WavSubFile>(preinit_file));
+            case OGG:
+                return std::dynamic_pointer_cast<SubFile>(std::make_shared<OggSubFile>(preinit_file));
+            case FONT:
+                return std::dynamic_pointer_cast<SubFile>(std::make_shared<FontSubFile>(preinit_file));
+            case UNKNOWN:
+                return std::dynamic_pointer_cast<SubFile>(std::make_shared<UnknownSubFile>(preinit_file));
+        }
+        LOG(ERROR) << "Incorrect file type..";
+        return std::dynamic_pointer_cast<SubFile>(std::make_shared<UnknownSubFile>(preinit_file));
+    }
+
+    static FILE_TYPE SubFile::GetSubfileType(DatFile &dat, SubFile preinit_file) {
+        // Text check based on file_id
+        if (((unsigned long long) preinit_file.file_id_ >> 24ull) == 0x25ull)
+            return TEXT;
+
+        // Font check based on file_id
+        if (((unsigned long long) preinit_file.file_id_ >> 24ull) == 0x42ull)
+            return FONT;
+
+        BinaryData header(64);
+        dat.getIO().ReadData(header, 64, (unsigned) preinit_file.file_offset_ + 8);
+
+        if (header.Empty()) {
+            LOG(ERROR) << "Unable to read file header. file_id = " << preinit_file.file_id_ << ", offset = "
+                       << preinit_file.file_offset_;
+            return UNKNOWN;
+        }
+
+
+        // jpeg / dds check
+        if (((unsigned long long) preinit_file.file_id_ >> 24ull) == 0x41ull) {
+            long long soi = header.ToNumber<2>(24);
+            long long marker = header.ToNumber<2>(26);
+
+            //auto markerSize = header.ToNumber<short>(28);
+            //auto four = header.ToNumber<int>(30);
+
+            if ((soi == 0xD8FFll && marker == 0xE0FFll) || marker == 0xE1FFll)
+                return JPG;
+            return DDS;
+        }
+
+        // Ogg and Wav check
+        if (header[8] == 0x4F && header[9] == 0x67 && header[10] == 0x67 && header[11] == 0x53)
+            return OGG;
+        if (header[8] == 0x52 && header[9] == 0x49 && header[10] == 0x46 && header[11] == 0x46)
+            return WAV;
+
+        return UNKNOWN;
+    }
+
+
 };

+ 1 - 5
src/Subfiles/DdsSubFile.cpp

@@ -10,11 +10,7 @@
 #include "EasyLogging++/easylogging++.h"
 
 namespace LOTRO_DAT {
-    DdsSubFile::DdsSubFile(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)
-            : SubFile(dat, dictionary_offset, unknown1, file_id, file_offset, file_size,
-                      timestamp, version, block_size, unknown2) {
+    DdsSubFile::DdsSubFile(DatFile &dat, SubFile preinit_file) : SubFile(preinit_file) {
     }
 
     FILE_TYPE DdsSubFile::FileType() const {

+ 1 - 5
src/Subfiles/FontSubFile.cpp

@@ -10,11 +10,7 @@
 #include "EasyLogging++/easylogging++.h"
 
 namespace LOTRO_DAT {
-    FontSubFile::FontSubFile(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)
-            : SubFile(dat, dictionary_offset, unknown1, file_id, file_offset, file_size,
-                      timestamp, version, block_size, unknown2) {
+    FontSubFile::FontSubFile(DatFile &dat, SubFile preinit_file) : SubFile(preinit_file) {
     }
 
     FILE_TYPE FontSubFile::FileType() const {

+ 1 - 5
src/Subfiles/JpgSubFile.cpp

@@ -9,11 +9,7 @@
 #include "SubfileData.h"
 
 namespace LOTRO_DAT {
-    JpgSubFile::JpgSubFile(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)
-            : SubFile(dat, dictionary_offset, unknown1, file_id, file_offset, file_size,
-                      timestamp, version, block_size, unknown2) {
+    JpgSubFile::JpgSubFile(DatFile &dat, SubFile preinit_file) : SubFile(preinit_file) {
     }
 
     FILE_TYPE JpgSubFile::FileType() const {

+ 1 - 5
src/Subfiles/OggSubFile.cpp

@@ -10,11 +10,7 @@
 #include "EasyLogging++/easylogging++.h"
 
 namespace LOTRO_DAT {
-    OggSubFile::OggSubFile(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)
-            : SubFile(dat, dictionary_offset, unknown1, file_id, file_offset, file_size,
-                      timestamp, version, block_size, unknown2) {
+    OggSubFile::OggSubFile(DatFile &dat, SubFile preinit_file) : SubFile(preinit_file) {
     }
 
     FILE_TYPE OggSubFile::FileType() const {

+ 1 - 5
src/Subfiles/TextSubFile.cpp

@@ -51,11 +51,7 @@ std::string argumentsFromUtf16(const std::u16string &args) {
 namespace LOTRO_DAT {
     BinaryData TextSubFile::buffer_ = BinaryData(10 * 1024 * 1024);
 
-    TextSubFile::TextSubFile(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)
-            : SubFile(dat, dictionary_offset, unknown1, file_id, file_offset, file_size,
-                      timestamp, version, block_size, unknown2) {
+    TextSubFile::TextSubFile(DatFile &dat, SubFile preinit_file) : SubFile(preinit_file) {
     }
 
     FILE_TYPE TextSubFile::FileType() const {

+ 1 - 5
src/Subfiles/UnknownSubFile.cpp

@@ -10,11 +10,7 @@
 #include "EasyLogging++/easylogging++.h"
 
 namespace LOTRO_DAT {
-    UnknownSubFile::UnknownSubFile(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)
-            : SubFile(dat, dictionary_offset, unknown1, file_id, file_offset, file_size,
-                      timestamp, version, block_size, unknown2) {
+    UnknownSubFile::UnknownSubFile(DatFile &dat, SubFile preinit_file) : SubFile(preinit_file) {
     }
 
     FILE_TYPE UnknownSubFile::FileType() const {

+ 1 - 5
src/Subfiles/WavSubFile.cpp

@@ -10,11 +10,7 @@
 #include "EasyLogging++/easylogging++.h"
 
 namespace LOTRO_DAT {
-    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)
-            : SubFile(dat, dictionary_offset, unknown1, file_id, file_offset, file_size,
-                      timestamp, version, block_size, unknown2) {
+    WavSubFile::WavSubFile(DatFile &dat, SubFile preinit_file) : SubFile(preinit_file) {
     }
 
     FILE_TYPE WavSubFile::FileType() const {