|
@@ -21,6 +21,13 @@ namespace LOTRO_DAT {
|
|
|
offset_ = 0;
|
|
|
}
|
|
|
|
|
|
+ SubDirectory::~SubDirectory() {
|
|
|
+ for (Subfile* file : subfiles_)
|
|
|
+ delete file;
|
|
|
+ for (SubDirectory *directory : subdirs_)
|
|
|
+ delete directory;
|
|
|
+ }
|
|
|
+
|
|
|
SubDirectory::SubDirectory(long long offset, DatFile *dat, long long max_subdirs) :
|
|
|
dat_(dat), offset_(offset), max_subdirs_(max_subdirs) {
|
|
|
try {
|
|
@@ -63,13 +70,8 @@ namespace LOTRO_DAT {
|
|
|
break;
|
|
|
|
|
|
try {
|
|
|
- subdirs_.emplace_back(
|
|
|
- SubDirectory(
|
|
|
- data.ToNumber<4>(i + 4),
|
|
|
- dat_
|
|
|
- )
|
|
|
- );
|
|
|
-
|
|
|
+ SubDirectory *subdir = new SubDirectory(data.ToNumber<4>(i + 4), dat_);
|
|
|
+ subdirs_.push_back(subdir);
|
|
|
} catch (std::exception &e) {
|
|
|
fprintf(stderr, "Caught %s exception.", e.what());
|
|
|
|
|
@@ -85,8 +87,16 @@ namespace LOTRO_DAT {
|
|
|
for (unsigned int i = 0; i < 61 * 32; i += 32) {
|
|
|
if (data.ToNumber<4>(i + 8) < 0x32 || data.ToNumber<4>(i + 12) < 0x32)
|
|
|
continue;
|
|
|
+
|
|
|
+ BinaryData mfile_id(4);
|
|
|
+ dat_->ReadData(mfile_id, 4, data.ToNumber<4>(i + 12) + 8);
|
|
|
+
|
|
|
+ if (data.ToNumber<4>(i + 8) != mfile_id.ToNumber<4>(0)) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
subfiles_.push_back(
|
|
|
MakeSubfile(
|
|
|
+ offset_ + 63 * 8 + i,
|
|
|
data.ToNumber<4>(i), // fragments_count
|
|
|
data.ToNumber<4>(i + 4), // unknown1
|
|
|
data.ToNumber<4>(i + 8), // file_id
|
|
@@ -106,22 +116,39 @@ namespace LOTRO_DAT {
|
|
|
dict[i->file_id()] = i;
|
|
|
}
|
|
|
|
|
|
- for (SubDirectory &i : subdirs_)
|
|
|
- i.MakeDictionary(dict);
|
|
|
+ for (SubDirectory *i : subdirs_)
|
|
|
+ i->MakeDictionary(dict);
|
|
|
}
|
|
|
|
|
|
- void SubDirectory::UpdateDirectories(std::unordered_map<long long, BinaryData *> &patched_files) {
|
|
|
+ void SubDirectory::UpdateDirectories(std::unordered_map<long long, BinaryData *> &patched_files, std::unordered_map<long long, Subfile*> &dict) {
|
|
|
for (unsigned i = 0; i < subfiles_.size(); i++) {
|
|
|
- if (patched_files.count(subfiles_[i]->file_id()) != 0) {
|
|
|
- dat_->WriteData(*patched_files[subfiles_[i]->file_id()], 32, offset_ + 63ll * 8ll + i * 32);
|
|
|
+ long long file_id = subfiles_[i]->file_id();
|
|
|
+
|
|
|
+ if (patched_files.count(file_id) != 0) {
|
|
|
+ BinaryData data(32);
|
|
|
+ dat_->ReadData(data, 32, subfiles_[i]->dictionary_offset());
|
|
|
+ if (data != *patched_files[file_id])
|
|
|
+ continue;
|
|
|
+
|
|
|
+ BinaryData header = dict[subfiles_[i]->file_id()]->MakeHeaderData();
|
|
|
+ BinaryData write_data(4);
|
|
|
+
|
|
|
+ write_data.FromNumber<4>(dict[file_id]->file_offset());
|
|
|
+ dat_->WriteData(write_data, 4, subfiles_[i]->dictionary_offset() + 12);
|
|
|
+
|
|
|
+ write_data.FromNumber<4>(dict[file_id]->file_size());
|
|
|
+ dat_->WriteData(write_data, 4, subfiles_[i]->dictionary_offset() + 16);
|
|
|
+
|
|
|
+ write_data.FromNumber<4>(dict[file_id]->block_size());
|
|
|
+ dat_->WriteData(write_data, 4, subfiles_[i]->dictionary_offset() + 28);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- for (SubDirectory &i : subdirs_)
|
|
|
- i.UpdateDirectories(patched_files);
|
|
|
+ for (SubDirectory *i : subdirs_)
|
|
|
+ i->UpdateDirectories(patched_files, dict);
|
|
|
}
|
|
|
|
|
|
- Subfile *SubDirectory::MakeSubfile(long long fragments_count, long long unknown1, long long file_id,
|
|
|
+ Subfile *SubDirectory::MakeSubfile(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) {
|
|
|
|
|
@@ -129,19 +156,19 @@ namespace LOTRO_DAT {
|
|
|
|
|
|
switch (type) {
|
|
|
case TEXT:
|
|
|
- return dynamic_cast<Subfile *>(new TextSubfile(dat_, fragments_count, unknown1, file_id, file_offset, file_size, timestamp, version, block_size));
|
|
|
+ return dynamic_cast<Subfile *>(new TextSubfile(dat_, dictionary_offset, fragments_count, unknown1, file_id, file_offset, file_size, timestamp, version, block_size));
|
|
|
case JPG:
|
|
|
- return dynamic_cast<Subfile *>(new JpgSubfile(dat_, fragments_count, unknown1, file_id, file_offset, file_size, timestamp, version, block_size));
|
|
|
+ return dynamic_cast<Subfile *>(new JpgSubfile(dat_, dictionary_offset, fragments_count, unknown1, file_id, file_offset, file_size, timestamp, version, block_size));
|
|
|
case DDS:
|
|
|
- return dynamic_cast<Subfile *>(new DdsSubfile(dat_, fragments_count, unknown1, file_id, file_offset, file_size, timestamp, version, block_size));
|
|
|
+ return dynamic_cast<Subfile *>(new DdsSubfile(dat_, dictionary_offset, fragments_count, unknown1, file_id, file_offset, file_size, timestamp, version, block_size));
|
|
|
case WAV:
|
|
|
- return dynamic_cast<Subfile *>(new WavSubfile(dat_, fragments_count, unknown1, file_id, file_offset, file_size, timestamp, version, block_size));
|
|
|
+ return dynamic_cast<Subfile *>(new WavSubfile(dat_, dictionary_offset, fragments_count, unknown1, file_id, file_offset, file_size, timestamp, version, block_size));
|
|
|
case OGG:
|
|
|
- return dynamic_cast<Subfile *>(new OggSubfile(dat_, fragments_count, unknown1, file_id, file_offset, file_size, timestamp, version, block_size));
|
|
|
+ return dynamic_cast<Subfile *>(new OggSubfile(dat_, dictionary_offset, fragments_count, unknown1, file_id, file_offset, file_size, timestamp, version, block_size));
|
|
|
case FONT:
|
|
|
- return dynamic_cast<Subfile *>(new FontSubfile(dat_, fragments_count, unknown1, file_id, file_offset, file_size, timestamp, version, block_size));
|
|
|
+ return dynamic_cast<Subfile *>(new FontSubfile(dat_, dictionary_offset, fragments_count, unknown1, file_id, file_offset, file_size, timestamp, version, block_size));
|
|
|
case UNKNOWN:
|
|
|
- return dynamic_cast<Subfile *>(new UnknownSubfile(dat_, fragments_count, unknown1, file_id, file_offset, file_size, timestamp, version, block_size));
|
|
|
+ return dynamic_cast<Subfile *>(new UnknownSubfile(dat_, dictionary_offset, fragments_count, unknown1, file_id, file_offset, file_size, timestamp, version, block_size));
|
|
|
}
|
|
|
throw DatException("Bad SubDirectory::MakeSubfile() - unable to recognize file_type!", SUBFILE_EXCEPTION);
|
|
|
}
|