Browse Source

Changed export functions format

TextSubfile exports to whole file (it's better for patching), so there's
no need to keep functionality for exporting to many database rows.
Moreover, this shouldn't be done as there should be only one row with
specific file_id, otherwise there will be problems with patching
Ivan Arkhipov 7 years ago
parent
commit
e605a4a75a

+ 10 - 17
Source/DatFile.cpp

@@ -87,20 +87,15 @@ namespace LOTRO_DAT {
             return false;
         }
 
-        std::vector<SubfileData> export_data;
-
         try {
-            export_data = dictionary_[file_id]->PrepareForExport(file_data);
+            SubfileData export_data = dictionary_[file_id]->PrepareForExport(file_data);
+            export_data.binary_data.WriteToFile(path + export_data.options["ext"].as<std::string>());
         } catch (std::exception &e) {
             fprintf(stderr, "Caught %s exception.", e.what());
 
             fprintf(stderr, "Unable to extract file due to uncaught exception while preparing file for export. Passing...\n");
             return false;
         }
-
-        for (int i = 0; i < export_data.size(); ++i) {
-            export_data[i].binary_data.WriteToFile(path + "_" + std::to_string(i) + export_data[i].options["ext"].as<std::string>());
-        }
         return true;
     }
 
@@ -127,7 +122,7 @@ namespace LOTRO_DAT {
             return false;
         }
 
-        std::vector<SubfileData> export_data;
+        SubfileData export_data;
 
         try {
             export_data = dictionary_[file_id]->PrepareForExport(file_data);
@@ -138,16 +133,14 @@ namespace LOTRO_DAT {
             return false;
         }
 
-        for (int i = 0; i < export_data.size(); ++i) {
-            try {
-                db->PushFile(export_data[i]);
-            } catch (std::exception &e) {
-                fprintf(stderr, "Caught %s exception.", e.what());
-                printf("Caught %s exception.", e.what());
-                fflush(stdout);
+        try {
+            db->PushFile(export_data);
+        } catch (std::exception &e) {
+            fprintf(stderr, "Caught %s exception.", e.what());
+            printf("Caught %s exception.", e.what());
+            fflush(stdout);
 
-                fprintf(stderr, "Unable to put file or it's part to database. Continuing without this part. Database may be not complete\n");
-            }
+            fprintf(stderr, "Unable to put file or it's part to database. Continuing without this part. Database may be not complete\n");
         }
         return true;
     }

+ 2 - 1
Source/Subfile.cpp

@@ -6,6 +6,7 @@
 #include "BinaryData.h"
 #include "DatFile.h"
 #include "Common/DatException.h"
+#include "SubfileData.h"
 
 #include <algorithm>
 
@@ -94,7 +95,7 @@ namespace LOTRO_DAT {
     ///  3) field options - YAML field, which consists of some parameters of file such as file_id, extension and so on.
     /// Returns true if preparation was success. Otherwise returns false;
 
-    std::vector<SubfileData> Subfile::PrepareForExport(const BinaryData &file_data) {
+    SubfileData Subfile::PrepareForExport(const BinaryData &file_data) {
         throw DatException("Bad Subfile::PrepareForExport() - function is not implemented for this type.", EXPORT_EXCEPTION);
     }
 

+ 1 - 1
Source/Subfile.h

@@ -32,7 +32,7 @@ namespace LOTRO_DAT
         virtual FILE_TYPE FileType() const;
         virtual std::string Extension() const;
 
-        virtual std::vector<SubfileData> PrepareForExport(const BinaryData &file_data);
+        virtual SubfileData PrepareForExport(const BinaryData &file_data);
 
         virtual BinaryData MakeForImport(const BinaryData &old_data, const SubfileData &data);
 

+ 6 - 7
Source/Subfiles/DdsSubfile.cpp

@@ -27,7 +27,7 @@ namespace LOTRO_DAT {
         return ".dds";
     }
 
-    std::vector<SubfileData> DdsSubfile::PrepareForExport(const BinaryData &file_data) {
+    SubfileData DdsSubfile::PrepareForExport(const BinaryData &file_data) {
         BinaryData data = file_data;
         if (data.CheckCompression())
             data = data.DecompressData(4);
@@ -135,12 +135,11 @@ namespace LOTRO_DAT {
                 throw DatException("Bad DdsSubfile::PrepareAsBinary() - unknown header format.", EXPORT_EXCEPTION);
         }
 
-        std::vector<SubfileData> output(1);
-        output[0].binary_data = (ddsData);
-        output[0].text_data = (u"");
-        output[0].options["fid"] = file_id();
-        output[0].options["ext"] = Extension();
-        return output;
+        SubfileData result;
+        result.binary_data = ddsData;
+        result.options["fid"] = file_id();
+        result.options["ext"] = Extension();
+        return result;
     }
 
     BinaryData DdsSubfile::MakeForImport(const BinaryData &old_data, const SubfileData &data) {

+ 1 - 1
Source/Subfiles/DdsSubfile.h

@@ -20,7 +20,7 @@ namespace LOTRO_DAT {
 
         std::string Extension() const override;
 
-        std::vector<SubfileData> PrepareForExport(const BinaryData &file_data) override;
+        SubfileData PrepareForExport(const BinaryData &file_data) override;
 
         BinaryData MakeForImport(const BinaryData &old_data, const SubfileData &data) override;
     };

+ 6 - 7
Source/Subfiles/FontSubfile.cpp

@@ -26,13 +26,12 @@ namespace LOTRO_DAT {
         return ".fontbin";
     }
 
-    std::vector<SubfileData> FontSubfile::PrepareForExport(const BinaryData &file_data) {
-        std::vector<SubfileData> output(1);
-        output[0].binary_data = file_data;
-        output[0].text_data = u"";
-        output[0].options["fid"] = file_id();
-        output[0].options["ext"] = Extension();
-        return output;
+    SubfileData FontSubfile::PrepareForExport(const BinaryData &file_data) {
+        SubfileData result;
+        result.binary_data = file_data;
+        result.options["fid"] = file_id();
+        result.options["ext"] = Extension();
+        return result;
     }
 
     BinaryData FontSubfile::MakeForImport(const BinaryData &old_data, const SubfileData &data) {

+ 1 - 1
Source/Subfiles/FontSubfile.h

@@ -20,7 +20,7 @@ namespace LOTRO_DAT {
 
         std::string Extension() const override;
 
-        std::vector<SubfileData> PrepareForExport(const BinaryData &file_data) override;
+        SubfileData PrepareForExport(const BinaryData &file_data) override;
 
         BinaryData MakeForImport(const BinaryData &old_data, const SubfileData &data) override;
 

+ 6 - 7
Source/Subfiles/JpgSubfile.cpp

@@ -26,13 +26,12 @@ namespace LOTRO_DAT {
         return std::string(".jpg");
     }
 
-    std::vector<SubfileData> JpgSubfile::PrepareForExport(const BinaryData &file_data) {
-        std::vector<SubfileData> output(1);
-        output[0].binary_data = file_data.CutData(24);
-        output[0].text_data = u"";
-        output[0].options["fid"] = file_id();
-        output[0].options["ext"] = Extension();
-        return output;
+    SubfileData JpgSubfile::PrepareForExport(const BinaryData &file_data) {
+        SubfileData result;
+        result.binary_data = file_data.CutData(24);
+        result.options["fid"] = file_id();
+        result.options["ext"] = Extension();
+        return result;
     }
 
     BinaryData JpgSubfile::MakeForImport(const BinaryData &old_data, const SubfileData &data) {

+ 1 - 1
Source/Subfiles/JpgSubfile.h

@@ -22,7 +22,7 @@ namespace LOTRO_DAT {
 
         std::string Extension() const override;
 
-        std::vector<SubfileData> PrepareForExport(const BinaryData &file_data) override;
+        SubfileData PrepareForExport(const BinaryData &file_data) override;
 
         BinaryData MakeForImport(const BinaryData &old_data, const SubfileData &data) override;
     };

+ 6 - 6
Source/Subfiles/OggSubfile.cpp

@@ -26,12 +26,12 @@ namespace LOTRO_DAT {
         return ".ogg";
     }
 
-    std::vector<SubfileData> OggSubfile::PrepareForExport(const BinaryData &file_data) {
-        std::vector<SubfileData> output(1);
-        output[0].binary_data = file_data.CutData(8);
-        output[0].options["fid"] = file_id();
-        output[0].options["ext"] = Extension();
-        return output;
+    SubfileData OggSubfile::PrepareForExport(const BinaryData &file_data) {
+        SubfileData result;
+        result.binary_data = file_data.CutData(8);
+        result.options["fid"] = file_id();
+        result.options["ext"] = Extension();
+        return result;
     }
 
     BinaryData OggSubfile::MakeForImport(const BinaryData &old_data, const SubfileData &data) {

+ 1 - 1
Source/Subfiles/OggSubfile.h

@@ -19,7 +19,7 @@ namespace LOTRO_DAT {
         FILE_TYPE FileType() const override;
         std::string Extension() const override;
 
-        std::vector<SubfileData> PrepareForExport(const BinaryData &file_data) override;
+        SubfileData PrepareForExport(const BinaryData &file_data) override;
 
         BinaryData MakeForImport(const BinaryData &old_data, const SubfileData &data) override;
     };

+ 24 - 16
Source/Subfiles/TextSubfile.cpp

@@ -7,6 +7,18 @@
 #include "../DatFile.h"
 #include "../Common/DatException.h"
 #include "../SubfileData.h"
+#include <algorithm>
+
+std::u16string to_utf16(long long x)
+{
+    std::u16string res;
+    while (x > 0) {
+        res += u'0' + short(x % 10);
+        x /= 10ll;
+    }
+    std::reverse(res.begin(), res.end());
+    return res;
+}
 
 namespace LOTRO_DAT {
     TextSubfile::TextSubfile() = default;
@@ -26,8 +38,8 @@ namespace LOTRO_DAT {
         return std::string(".txt");
     }
 
-    std::vector<SubfileData> TextSubfile::PrepareForExport(const BinaryData &file_data) {
-        std::vector<SubfileData> result;
+    SubfileData TextSubfile::PrepareForExport(const BinaryData &file_data) {
+        SubfileData result;
         if (file_size() <= 10) // File is empty, nothing to do;
             return result;
 
@@ -53,23 +65,21 @@ namespace LOTRO_DAT {
                 text += text_pieces[j] + u"<--DO_NOT_TOUCH!-->";
             text += text_pieces[text_pieces.size() - 1] + u"]";
 
-            std::string arguments;
+            std::u16string arguments;
             for (size_t j = 0; j + 1 < arg_references.size(); j++)
-                arguments += std::to_string(arg_references[j]) + "-";
+                arguments += to_utf16(arg_references[j]) + u"-";
             if (!arg_references.empty())
-                arguments += std::to_string(arg_references[arg_references.size() - 1]);
-
-            SubfileData subfile;
+                arguments += to_utf16(arg_references[arg_references.size() - 1]);
 
-            subfile.text_data = text;
-            subfile.options["fid"] = file_id();
-            subfile.options["gid"] = fragment_id;
-            subfile.options["ext"] = Extension();
-            if (!arg_references.empty())
-                subfile.options["args"] = arguments;
+            if (result.text_data.length() > 0)
+                result.text_data += u"|||";
 
-            result.push_back(subfile);
+            result.text_data += to_utf16(fragment_id) + u":::";
+            result.text_data += arguments + u":::";
+            result.text_data += text;
         }
+        result.options["fid"] = file_id();
+        result.options["ext"] = Extension();
         return result;
     }
 
@@ -192,8 +202,6 @@ namespace LOTRO_DAT {
         return arg_strings;
     }
 
-
-
     BinaryData TextSubfile::BuildPieces(const BinaryData &data, const SubfileData &new_data, long long &offset) {
         // Moving &offset pointer in &data
         GetPieceData(data, offset);

+ 3 - 1
Source/Subfiles/TextSubfile.h

@@ -21,7 +21,7 @@ namespace LOTRO_DAT {
 
         std::string Extension() const override;
 
-        std::vector<SubfileData> PrepareForExport(const BinaryData &file_data) override;
+        SubfileData PrepareForExport(const BinaryData &file_data) override;
 
         BinaryData MakeForImport(const BinaryData &old_data, const SubfileData &data) override;
 
@@ -32,6 +32,8 @@ namespace LOTRO_DAT {
 
         std::vector<std::vector<BinaryData>> MakeArgumentStrings(const BinaryData &data, long long &offset);
 
+        std::vector<SubfileData> FileFragments;
+
         BinaryData BuildPieces(const BinaryData &data, const SubfileData &new_data, long long &offset);
 
         BinaryData BuildArgumentReferences(const BinaryData &data, const SubfileData &new_data, long long &offset);

+ 5 - 5
Source/Subfiles/UnknownSubfile.cpp

@@ -26,11 +26,11 @@ namespace LOTRO_DAT {
         return std::string(".unknown");
     }
 
-    std::vector<SubfileData> UnknownSubfile::PrepareForExport(const BinaryData &file_data) {
-        std::vector<SubfileData> result(1);
-        result[0].binary_data = file_data;
-        result[0].options["fid"] = file_id();
-        result[0].options["ext"] = Extension();
+    SubfileData UnknownSubfile::PrepareForExport(const BinaryData &file_data) {
+        SubfileData result;
+        result.binary_data = file_data;
+        result.options["fid"] = file_id();
+        result.options["ext"] = Extension();
         return result;
     }
 

+ 1 - 1
Source/Subfiles/UnknownSubfile.h

@@ -19,7 +19,7 @@ namespace LOTRO_DAT {
         FILE_TYPE FileType() const override;
         std::string Extension() const override;
 
-        std::vector<SubfileData> PrepareForExport(const BinaryData &file_data) override;
+        SubfileData PrepareForExport(const BinaryData &file_data) override;
 
         BinaryData MakeForImport(const BinaryData &old_data, const SubfileData &data) override;
 

+ 5 - 5
Source/Subfiles/WavSubfile.cpp

@@ -26,11 +26,11 @@ namespace LOTRO_DAT {
         return ".wav";
     }
 
-    std::vector<SubfileData> WavSubfile::PrepareForExport(const BinaryData &file_data) {
-        std::vector<SubfileData> result(1);
-        result[0].binary_data = file_data.CutData(8);
-        result[0].options["fid"] = file_id();
-        result[0].options["ext"] = Extension();
+    SubfileData WavSubfile::PrepareForExport(const BinaryData &file_data) {
+        SubfileData result;
+        result.binary_data = file_data.CutData(8);
+        result.options["fid"] = file_id();
+        result.options["ext"] = Extension();
         return result;
     }
 

+ 1 - 1
Source/Subfiles/WavSubfile.h

@@ -21,7 +21,7 @@ namespace LOTRO_DAT {
 
         std::string Extension() const override;
 
-        std::vector<SubfileData> PrepareForExport(const BinaryData &file_data) override;
+        SubfileData PrepareForExport(const BinaryData &file_data) override;
 
         BinaryData MakeForImport(const BinaryData &old_data, const SubfileData &data) override;
 

+ 17 - 16
Source/Tests/extract_test.cpp

@@ -22,16 +22,16 @@ const std::string filename = "client_local_English.dat";
 // Change these variables to true if you want export catecory to files.
 const bool exportImagesToFiles = false;
 const bool exportFontsToFiles = false;
-const bool exportSoundsToFiles = true;
+const bool exportSoundsToFiles = false;
 const bool exportTexturesToFiles = false;
 const bool exportUnknownToFiles = false;
 
 // Change these variables to true if you want export catecory to databases.
-const bool exportTextsToDb = false;
-const bool exportImagesToDb = false;
-const bool exportFontsToDb = false;
+const bool exportTextsToDb = true;
+const bool exportImagesToDb = true;
+const bool exportFontsToDb = true;
 const bool exportSoundsToDb = true;
-const bool exportTexturesToDb = false;
+const bool exportTexturesToDb = true;
 const bool exportUnknownToDb = false;
 // There is no need to change anything else
 
@@ -63,37 +63,38 @@ int main() {
         std::cout << "Beginning unpacking... Please, wait for some minutes."
         "\nMaybe it's a good idea to have a cup of tea, while unpacker is working...\n" << std::flush;
 
-
+        Database *out = new Database("out.db");
         if (exportImagesToDb) {
-            Database *images = new Database(output_dir + std::string("Images.db"));
+            Database *images = out;//new Database(output_dir + std::string("Images.db"));
             std::cout << "Extracted " << a.ExtractAllFilesByType(JPG, images) << " .jpg files to Images.db" << std::endl << std::flush;
-            delete images;
+//            delete images;
         }
 
         if (exportSoundsToDb) {
-            Database *sounds = new Database(output_dir + std::string("Sounds.db"));
+            Database *sounds = out;//new Database(output_dir + std::string("Sounds.db"));
             std::cout << "Extracted " << a.ExtractAllFilesByType(WAV, sounds) << " .wav files to Sounds.db" << std::endl << std::flush;
             std::cout << "Extracted " << a.ExtractAllFilesByType(OGG, sounds) << " .ogg files to Sounds.db" << std::endl << std::flush;
-            delete sounds;
+//            delete sounds;
         }
 
         if (exportTextsToDb) {
-            Database *texts = new Database(output_dir + std::string("Texts.db"));
+            Database *texts = out;//new Database(output_dir + std::string("Texts.db"));
             std::cout << "Extracted " << a.ExtractAllFilesByType(TEXT, texts) << " text files to Texts.db" << std::endl << std::flush;
-            delete texts;
+//            delete texts;
         }
 
         if (exportFontsToDb) {
-            Database *fonts = new Database(output_dir + std::string("Fonts.db"));
+            Database *fonts = out;//new Database(output_dir + std::string("Fonts.db"));
             std::cout << "Extracted " << a.ExtractAllFilesByType(FONT, fonts) << " font files to Fonts.db" << std::endl << std::flush;
-            delete fonts;
+//            delete fonts;
         }
 
         if (exportTexturesToDb) {
-            Database *textures = new Database(output_dir + std::string("Textures.db"));
+            Database *textures = out;//new Database(output_dir + std::string("Textures.db"));
             std::cout << "Extracted " << a.ExtractAllFilesByType(DDS, textures) << " .dds files to Textures.db" << std::endl << std::flush;
-            delete textures;
+//            delete textures;
         }
+        delete out;
 
         if (exportUnknownToDb) {
             Database *unknown = new Database(output_dir + std::string("Unknown.db"));