Bläddra i källkod

Minor implementations & fixes

Ivan Arkhipov 6 år sedan
förälder
incheckning
793ac24b01

BIN
bin/LotRO_dat_extractor.exe


BIN
bin/LotRO_dat_patcher.exe


BIN
lib/libLotroDat.dll.a


BIN
lib/libLotroDat_static.a


+ 5 - 2
src/DatFile.cpp

@@ -1016,7 +1016,8 @@ namespace LOTRO_DAT {
             return DAT_READ_ERROR;
         }
 
-        fseek(file_handler_, offset, SEEK_SET);
+        if (offset != ftell(file_handler_))
+            fseek(file_handler_, offset, SEEK_SET);
         fread(data.data() + data_offset, unsigned(size), 1, file_handler_);
         return SUCCESS;
     }
@@ -1027,7 +1028,9 @@ namespace LOTRO_DAT {
             return INCORRECT_STATE_ERROR;
         }
 
-        fseek(file_handler_, offset, SEEK_SET);
+        if (offset != ftell(file_handler_))
+            fseek(file_handler_, offset, SEEK_SET);
+
         if (data_offset + size > data.size()) {
             LOG(ERROR) << "Trying to write more than BinaryData size";
             return DAT_WRITE_ERROR;

+ 22 - 14
src/SubDirectory.cpp

@@ -20,9 +20,12 @@
 
 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>();
 
@@ -46,7 +49,7 @@ namespace LOTRO_DAT {
         }
 
         if (data.ToNumber<4>(0) != 0 || data.ToNumber<4>(4) != 0) {
-            LOG(DEBUG) << "first 8 bytes are not equal to 0 at offset " << offset_;
+            LOG(WARNING) << "first 8 bytes are not equal to 0 at offset " << offset_;
             return false;
         }
 
@@ -54,10 +57,10 @@ namespace LOTRO_DAT {
             if (data.ToNumber<4>(i) == 0 || data.ToNumber<4>(i + 4) == 0)
                 break;
 
-            if (visited_subdirectories_.count(data.ToNumber<4>(i + 4)) > 0) {
-                LOG(DEBUG) << "Visiting subdirectory at offset " << data.ToNumber<4>(i + 4) << " more than one time. Passing.";
-                continue;
-            }
+//            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_);
@@ -92,6 +95,8 @@ namespace LOTRO_DAT {
         BinaryData headers(32 * unsigned(subfiles_number));
         dat_.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));
 
@@ -120,13 +125,16 @@ namespace LOTRO_DAT {
                     header.ToNumber<4>(28) // unknown2 - must be zero??
             );
 
-            if (dat_.CorrectSubfile(subfiles_[i])) {
+            // 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;
-            }
+//            } 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;
     }
@@ -177,11 +185,11 @@ namespace LOTRO_DAT {
 
     FILE_TYPE SubDirectory::GetSubfileType(long long file_id, long long file_offset) const {
         // Text check based on file_id
-        if ((file_id >> 24ll) == 0x25ll)
+        if (((unsigned long long) file_id >> 24ull) == 0x25ull)
             return TEXT;
 
         // Font check based on file_id
-        if ((file_id >> 24ll) == 0x42ll)
+        if (((unsigned long long) file_id >> 24ull) == 0x42ull)
             return FONT;
 
         BinaryData header(64);
@@ -194,7 +202,7 @@ namespace LOTRO_DAT {
 
 
         // jpeg / dds check
-        if ((file_id >> 24ll) == 0x41ll) {
+        if (((unsigned long long) file_id >> 24ull) == 0x41ull) {
             long long soi = header.ToNumber<2>(24);
             long long marker = header.ToNumber<2>(26);
 

+ 8 - 0
src/SubFile.cpp

@@ -27,6 +27,14 @@ namespace LOTRO_DAT {
         version_ = header.ToNumber<4>(20); // version
         block_size_ = header.ToNumber<4>(24); // block_size
         unknown2_ = header.ToNumber<4>(28); // 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..?";
+            file_id_ = -1;
+            return;
+        }
+
     }
 
     SubFile::SubFile(DatFile &dat, long long dictionary_offset, long long unknown1, long long file_id,

+ 56 - 31
src/Subfiles/TextSubFile.cpp

@@ -79,9 +79,9 @@ namespace LOTRO_DAT {
         SubfileData result;
         long long offset = 9; // first 4 bytes - file_id, then 4 bytes - unknown, then 1 byte - unknown
 
-        long long text_fragment_num = file_data.ToNumber<1>(offset);
-        if ((text_fragment_num & 0x80) != 0) {
-            text_fragment_num = (((text_fragment_num ^ 0x80) << 8) | file_data.ToNumber<1>(offset + 1));
+        auto text_fragment_num = unsigned(file_data.ToNumber<1>(offset));
+        if ((text_fragment_num & 0x80u) != 0) {
+            text_fragment_num = (((text_fragment_num ^ 0x80u) << 8u) | unsigned(file_data.ToNumber<1>(offset + 1)));
             offset += 1;
         }
         offset += 1;
@@ -132,7 +132,6 @@ namespace LOTRO_DAT {
             text_pieces_.clear();
             argument_references_.clear();
             argument_strings_.clear();
-
             return old_data;
         }
 
@@ -141,9 +140,14 @@ namespace LOTRO_DAT {
         long long offset = 9 + 8; // first 8 bytes - file_info. After them:
         // first 4 bytes - file_id, then 4 bytes - unknown, then 1 byte - unknown
 
-        long long text_fragment_num = old_data.ToNumber<1>(offset);
-        if ((text_fragment_num & 0x80) != 0) {
-            text_fragment_num = (((text_fragment_num ^ 0x80) << 8) | old_data.ToNumber<1>(offset + 1));
+        if (old_data.ToNumber<4>(8) != file_id_) {
+            std::cout << "Error: file_id mismatch. Found " << old_data.ToNumber<4>(8) << ", expected: " << file_id_
+                      << "\n";
+        }
+
+        auto text_fragment_num = unsigned(old_data.ToNumber<1>(offset));
+        if ((text_fragment_num & 0x80u) != 0) {
+            text_fragment_num = (((text_fragment_num ^ 0x80u) << 8u) | unsigned(old_data.ToNumber<1>(offset + 1)));
             offset += 1;
         }
         offset += 1;
@@ -222,7 +226,7 @@ namespace LOTRO_DAT {
             if (pointer1 == std::u16string::npos)
                 pointer1 = data.text_data.length();
             fragment.text = data.text_data.substr(pointer, pointer1 - pointer);
-            pointer = pointer1  + 3;
+            pointer = pointer1 + 3;
 
             patch_fragments_.push_back(fragment);
         }
@@ -234,14 +238,14 @@ namespace LOTRO_DAT {
 
     void TextSubFile::MakePieces(const BinaryData &data, long long &offset) {
         LOG(DEBUG) << "Started making pieces";
-        long long num_pieces = data.ToNumber<4>(offset);
+        auto num_pieces = unsigned(data.ToNumber<4>(offset));
         offset += 4;
 
         text_pieces_.resize(num_pieces);
         for (long long j = 0; j < num_pieces; j++) {
-            long long piece_size = data.ToNumber<1>(offset);
-            if ((piece_size & 128) != 0) {
-                piece_size = (((piece_size ^ 128) << 8) | data.ToNumber<1>(offset + 1));
+            auto piece_size = unsigned(data.ToNumber<1>(offset));
+            if ((piece_size & 128u) != 0) {
+                piece_size = (((piece_size ^ 128u) << 8u) | unsigned(data.ToNumber<1>(offset + 1)));
                 offset += 1;
             }
             offset += 1;
@@ -249,9 +253,9 @@ namespace LOTRO_DAT {
             BinaryData piece_data = data.CutData(offset, offset + piece_size * 2);
             std::u16string piece;
 
-            for (long long k = 0; k < piece_size; k++) {
-                char16_t c = char16_t(
-                        ((short(piece_data[2 * unsigned(k) + 1])) << 8) | (short(piece_data[2 * unsigned(k)])));
+            for (unsigned k = 0; k < piece_size; k++) {
+                auto c = char16_t((unsigned(piece_data[2u * k + 1u])) << 8u); // First byte
+                c |= (short(piece_data[2u * k]));                    // Second byte
                 piece += c;
             }
 
@@ -264,7 +268,7 @@ namespace LOTRO_DAT {
     void TextSubFile::MakeArgumentReferences(const BinaryData &data, long long &offset) {
         LOG(DEBUG) << "Started making argument references";
 
-        long long num_references = data.ToNumber<4>(offset);
+        auto num_references = unsigned(data.ToNumber<4>(offset));
         offset += 4;
 
         argument_references_.resize(num_references);
@@ -277,19 +281,19 @@ namespace LOTRO_DAT {
 
     void TextSubFile::MakeArgumentStrings(const BinaryData &data, long long &offset) {
         LOG(DEBUG) << "Started making argument strings";
-        long long num_arg_strings = data.ToNumber<1>(offset);
+        auto num_arg_strings = unsigned(data.ToNumber<1>(offset));
         offset += 1;
 
         argument_strings_.resize(num_arg_strings);
         for (long long j = 0; j < num_arg_strings; j++) {
-            long long num_args = data.ToNumber<4>(offset);
+            auto num_args = unsigned(data.ToNumber<4>(offset));
             offset += 4;
 
             argument_strings_[j].resize(num_args);
             for (long long k = 0; k < num_args; k++) {
-                long long string_size = data.ToNumber<1>(offset);
-                if ((string_size & 0x80) != 0) {
-                    string_size = (((string_size ^ 0x80) << 8) | data.ToNumber<1>(offset + 1));
+                auto string_size = unsigned(data.ToNumber<1>(offset));
+                if ((string_size & 0x80u) != 0) {
+                    string_size = (((string_size ^ 0x80u) << 8u) | unsigned(data.ToNumber<1>(offset + 1)));
                     offset += 1;
                 }
                 offset += 1;
@@ -314,6 +318,11 @@ namespace LOTRO_DAT {
         // Deleting '[' and ']' brackets
         std::u16string text_data = new_data.text.substr(1, new_data.text.size() - 2) + file_data;
 
+
+        if (file_id_ == 620757423 && new_data.fragment_id == 96627013) {
+            std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> codecvt;
+            std::cout << "AAAAAAAAAAAAA: " << codecvt.to_bytes(text_data) << std::endl;
+        }
         text_pieces_.clear();
 
         const std::u16string DNT = u"<--DO_NOT_TOUCH!-->";
@@ -321,7 +330,7 @@ namespace LOTRO_DAT {
         size_t next = text_data.find(DNT, prev);
 
         while (next != std::string::npos) {
-            std::u16string piece = text_data.substr(prev, next - prev);
+            std::u16string piece = (next - prev == 0) ? u" " : text_data.substr(prev, next - prev);
             text_pieces_.push_back(piece);
             prev = next + DNT.length();
             next = text_data.find(DNT, prev);
@@ -329,6 +338,15 @@ namespace LOTRO_DAT {
 
         text_pieces_.push_back(text_data.substr(prev));
 
+        if (file_id_ == 620757423 && new_data.fragment_id == 96627013) {
+            std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> codecvt;
+            std::cout << "PIECES: SIZE = " << text_pieces_.size() << "..." << std::endl;
+            for (const auto &i : text_pieces_) {
+                std::cout << "   PIECE='" << codecvt.to_bytes(i) << "'\n";
+            }
+        }
+
+
         // Building BinaryData from pieces
         unsigned buffer_offset = 0;
 
@@ -336,12 +354,12 @@ namespace LOTRO_DAT {
         buffer_offset += 4;
 
         for (const std::u16string &piece : text_pieces_) {
-            long long piece_size = piece.length();
+            unsigned piece_size = piece.length();
             if (piece_size < 128) {
                 buffer_.Append(BinaryData::FromNumber<1>(piece_size), buffer_offset);
                 buffer_offset += 1;
             } else {
-                buffer_.Append(BinaryData::FromNumberRAW<2>((piece_size | 32768)), buffer_offset);
+                buffer_.Append(BinaryData::FromNumberRAW<2>((piece_size | 32768u)), buffer_offset);
                 buffer_offset += 2;
             }
 
@@ -360,12 +378,18 @@ namespace LOTRO_DAT {
         // Moving &offset pointer in &data
         GetArgumentReferenceData(data, offset);
 
+        if (file_id_ == 620757423 && new_data.fragment_id == 96627013) {
+            std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> codecvt;
+            std::cout << "ARG_REFS: " << new_data.args << std::endl;
+        }
+
         // If there are no args - making 4 null-bytes and return;
         if (new_data.args.empty()) {
             BinaryData result = BinaryData::FromNumber<4>(0);
             return result;
         }
 
+
         // Parsing arguments from list in options["args"]
         std::string args_list = new_data.args;
         argument_references_.clear();
@@ -395,7 +419,8 @@ namespace LOTRO_DAT {
     BinaryData TextSubFile::BuildArgumentStrings(const BinaryData &data, const TextFragment &, long long &offset) {
         LOG(DEBUG) << "Started building argument strings";
         LOG(DEBUG) << "Built arg strings successfully";
-        return GetArgumentStringsData(data, offset);
+        GetArgumentStringsData(data, offset);
+        return BinaryData::FromNumber<1>(0);
     }
 
     // Get BinaryData contents of pieces/arguments/argument strings
@@ -408,9 +433,9 @@ namespace LOTRO_DAT {
         offset += 4;
 
         for (long long j = 0; j < num_pieces; j++) {
-            long long piece_size = data.ToNumber<1>(offset);
-            if ((piece_size & 128) != 0) {
-                piece_size = (((piece_size ^ 128) << 8) | data.ToNumber<1>(offset + 1));
+            auto piece_size = unsigned(data.ToNumber<1>(offset));
+            if ((piece_size & 128u) != 0) {
+                piece_size = (((piece_size ^ 128u) << 8u) | unsigned(data.ToNumber<1>(offset + 1)));
                 offset += 1;
             }
             offset += 1;
@@ -442,9 +467,9 @@ namespace LOTRO_DAT {
             offset += 4;
 
             for (long long k = 0; k < num_args; k++) {
-                long long string_size = data.ToNumber<1>(offset);
-                if ((string_size & 0x80) != 0) {
-                    string_size = (((string_size ^ 0x80) << 8) | data.ToNumber<1>(offset + 1));
+                auto string_size = unsigned(data.ToNumber<1>(offset));
+                if ((string_size & 0x80u) != 0) {
+                    string_size = (((string_size ^ 0x80u) << 8u) | unsigned(data.ToNumber<1>(offset + 1)));
                     offset += 1;
                 }
                 offset += 1;