|
@@ -18,22 +18,22 @@ LOTRO_DAT::Subfile::Subfile() {
|
|
|
compressed_ = false;
|
|
|
}
|
|
|
|
|
|
-LOTRO_DAT::Subfile::Subfile(DatFile *dat, long long unknown0, long long unknown1, long long file_id, long long file_offset, long long size1,
|
|
|
- long long timestamp, long long version, long long size2) :
|
|
|
- dat_(dat), unknown0_(unknown0), unknown1_(unknown1), file_id_(file_id), file_offset_(file_offset),
|
|
|
- size1_(size1), timestamp_(timestamp), version_(version), size2_(size2) {
|
|
|
+LOTRO_DAT::Subfile::Subfile(DatFile *dat, 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) :
|
|
|
+ dat_(dat), fragments_count_(fragments_count), unknown1_(unknown1), file_id_(file_id), file_offset_(file_offset),
|
|
|
+ file_size_(file_size), timestamp_(timestamp), version_(version), block_size_(block_size) {
|
|
|
|
|
|
- if (size1_ > MAXSIZE)
|
|
|
+ if (file_size_ > MAXSIZE)
|
|
|
throw DatException("Bad Subfile::Subfile() - File size is too much... Maybe it's incorrect..?", SUBFILE_EXCEPTION);
|
|
|
ext_ = GetExtension();
|
|
|
|
|
|
BinaryData header(20);
|
|
|
- dat_->ReadData(header, 10, file_offset_);
|
|
|
+ dat_->ReadData(header, 10, file_offset_ + 8);
|
|
|
compressed_ = header.CheckCompression();
|
|
|
}
|
|
|
|
|
|
-long long LOTRO_DAT::Subfile::unknown0() const {
|
|
|
- return unknown0_;
|
|
|
+long long LOTRO_DAT::Subfile::fragments_count() const {
|
|
|
+ return fragments_count_;
|
|
|
}
|
|
|
|
|
|
long long LOTRO_DAT::Subfile::unknown1() const {
|
|
@@ -48,8 +48,8 @@ long long LOTRO_DAT::Subfile::file_offset() const {
|
|
|
return file_offset_;
|
|
|
}
|
|
|
|
|
|
-long long LOTRO_DAT::Subfile::size1() const {
|
|
|
- return size1_;
|
|
|
+long long LOTRO_DAT::Subfile::file_size() const {
|
|
|
+ return file_size_;
|
|
|
}
|
|
|
|
|
|
long long LOTRO_DAT::Subfile::timestamp() const {
|
|
@@ -60,8 +60,8 @@ long long LOTRO_DAT::Subfile::version() const {
|
|
|
return version_;
|
|
|
}
|
|
|
|
|
|
-long long LOTRO_DAT::Subfile::size2() const {
|
|
|
- return size2_;
|
|
|
+long long LOTRO_DAT::Subfile::block_size() const {
|
|
|
+ return block_size_;
|
|
|
}
|
|
|
|
|
|
LOTRO_DAT::EXTENSION LOTRO_DAT::Subfile::GetExtension() const {
|
|
@@ -177,22 +177,32 @@ bool LOTRO_DAT::Subfile::ExportFileAsTXT(const char *filename, Database *db) con
|
|
|
throw DatException("ExportAsTXT function is not implemented yet", EXPORT_EXCEPTION);
|
|
|
}
|
|
|
|
|
|
-LOTRO_DAT::BinaryData LOTRO_DAT::Subfile::GetFileData() const {
|
|
|
- BinaryData data((unsigned)size1());
|
|
|
- if (size2() >= size1() + 8) {
|
|
|
- dat_->ReadData(data, size1(), file_offset() + 8);
|
|
|
+LOTRO_DAT::BinaryData LOTRO_DAT::Subfile::GetFileData(long long offset) const {
|
|
|
+ BinaryData data((unsigned)(file_size()));
|
|
|
+ if (block_size() >= file_size() + 8) {
|
|
|
+ dat_->ReadData(data, file_size(), file_offset() + offset);
|
|
|
return data;
|
|
|
}
|
|
|
|
|
|
- long long first_block_size = size2() - 8 - 4;
|
|
|
+ BinaryData fragments_count(4);
|
|
|
+ dat_->ReadData(fragments_count, 4, file_offset());
|
|
|
+ long long fragments_number = fragments_count.ToNumber<4>(0);
|
|
|
+
|
|
|
+ long long current_block_size = block_size() - offset - 8 * fragments_number;
|
|
|
|
|
|
- dat_->ReadData(data, first_block_size, file_offset() + 8);
|
|
|
+ dat_->ReadData(data, current_block_size , file_offset() + offset);
|
|
|
|
|
|
- BinaryData newFragmentOffset(4);
|
|
|
- dat_->ReadData(newFragmentOffset, 4, file_offset() + size2() - 4);
|
|
|
- long long part_offset = newFragmentOffset.ToNumber<4>(0);
|
|
|
+ BinaryData FragmentsDictionary(8 * unsigned(fragments_number));
|
|
|
+ dat_->ReadData(FragmentsDictionary, 8 * unsigned(fragments_number), file_offset() + block_size() - 8 * fragments_number);
|
|
|
+
|
|
|
+
|
|
|
+ for (long long i = 0; i < fragments_number; i++) {
|
|
|
+ long long fragment_size = FragmentsDictionary.ToNumber<4>(8 * i);
|
|
|
+ long long fragment_offset = FragmentsDictionary.ToNumber<4>(8 * i + 4);
|
|
|
+ dat_->ReadData(data, std::min(fragment_size, file_size() - current_block_size), fragment_offset, current_block_size );
|
|
|
+ current_block_size += fragment_size;
|
|
|
+ }
|
|
|
|
|
|
- dat_->ReadData(data, size1() - first_block_size, part_offset, first_block_size);
|
|
|
return data;
|
|
|
}
|
|
|
|