|
@@ -8,6 +8,7 @@
|
|
|
#include "Common/DatException.h"
|
|
|
#include "SubDirectory.h"
|
|
|
#include "Subfile.h"
|
|
|
+#include "yaml-cpp/yaml.h"
|
|
|
|
|
|
#include <locale>
|
|
|
|
|
@@ -21,13 +22,10 @@ namespace LOTRO_DAT {
|
|
|
DatFile::DatFile(const char *filename, int dat_id) {
|
|
|
dat_id_ = dat_id;
|
|
|
dat_state_ = CLOSED;
|
|
|
- printf("state1\n");
|
|
|
OpenDatFile(filename);
|
|
|
- printf("state2\n");
|
|
|
ReadSuperBlock();
|
|
|
- printf("state3\n");
|
|
|
MakeDirectories();
|
|
|
- printf("end\n");
|
|
|
+
|
|
|
try {
|
|
|
MakeDictionary();
|
|
|
} catch (...) {
|
|
@@ -60,7 +58,16 @@ namespace LOTRO_DAT {
|
|
|
if (dat_state_ != READY) {
|
|
|
throw DatException("Bad DatFile::ExtractFile() - invalid DatFile state!", EXPORT_EXCEPTION);
|
|
|
}
|
|
|
- return dictionary_[file_id]->ExportFile(path.c_str());
|
|
|
+ BinaryData file_data = GetFileData(dictionary_[file_id], 8);
|
|
|
+ long long export_size = 0;
|
|
|
+ std::vector<BinaryData> binary_data;
|
|
|
+ std::vector<std::u16string> text_data;
|
|
|
+ std::vector<YAML::Node> options;
|
|
|
+ dictionary_[file_id]->PrepareForExport(file_data, export_size, binary_data, text_data, options);
|
|
|
+
|
|
|
+ for (int i = 0; i < export_size; ++i) {
|
|
|
+ binary_data[i].WriteToFile(path + "_" + std::to_string(i) + options[i]["extension"].as<std::string>());
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
|
|
@@ -74,7 +81,14 @@ namespace LOTRO_DAT {
|
|
|
if (dat_state_ != READY) {
|
|
|
throw DatException("Bad DatFile::ExtractFile() - invalid DatFile state!", EXPORT_EXCEPTION);
|
|
|
}
|
|
|
- return dictionary_[file_id]->ExportFile(db);
|
|
|
+
|
|
|
+ BinaryData file_data = GetFileData(dictionary_[file_id], 8);
|
|
|
+ long long export_size = 0;
|
|
|
+ std::vector<BinaryData> binary_data;
|
|
|
+ std::vector<std::u16string> text_data;
|
|
|
+ std::vector<YAML::Node> options;
|
|
|
+ dictionary_[file_id]->PrepareForExport(file_data, export_size, binary_data, text_data, options);
|
|
|
+
|
|
|
}
|
|
|
|
|
|
|
|
@@ -91,9 +105,9 @@ namespace LOTRO_DAT {
|
|
|
|
|
|
int success = 0;
|
|
|
for (auto i : dictionary_) {
|
|
|
- FILE_TYPE ext = i.second->ext();
|
|
|
+ FILE_TYPE ext = i.second->FileType();
|
|
|
if (ext == type) {
|
|
|
- success += i.second->ExportFile((path + std::to_string(i.second->file_id())).c_str());
|
|
|
+ success += ExtractFile(i.second->file_id(), (path + std::to_string(i.second->file_id())));
|
|
|
}
|
|
|
}
|
|
|
return success;
|
|
@@ -111,55 +125,14 @@ namespace LOTRO_DAT {
|
|
|
|
|
|
int success = 0;
|
|
|
for (auto i : dictionary_) {
|
|
|
- FILE_TYPE ext = i.second->ext();
|
|
|
+ FILE_TYPE ext = i.second->FileType();
|
|
|
if (ext == type) {
|
|
|
- success += i.second->ExportFile(db);
|
|
|
+ success += ExtractFile(i.second->file_id(), db);
|
|
|
}
|
|
|
}
|
|
|
return success;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- bool DatFile::PatchTextFile(long long file_id, long long gossip_id, std::string text, std::string args_order,
|
|
|
- std::string args) {
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- bool DatFile::PatchTextFile(long long file_id, long long gossip_id, Database *db) {
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- bool DatFile::PatchBinaryFile(long long file_id, std::string file_path) {
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- bool DatFile::PatchBinaryFile(long long file_id, Database *db) {
|
|
|
- return false;
|
|
|
- }
|
|
|
|
|
|
void DatFile::OpenDatFile(const char *dat_name) {
|
|
|
if (dat_state_ != CLOSED)
|
|
@@ -291,16 +264,8 @@ namespace LOTRO_DAT {
|
|
|
fopen_s(&f, (path + "dict.txt").c_str(), "w");
|
|
|
fprintf(f, "file_id offset size size2 extension\n");
|
|
|
for (auto i : dictionary_) {
|
|
|
- std::string extension = "unk";
|
|
|
- FILE_TYPE ext = i.second->ext();
|
|
|
- if (ext == TEXT) extension = "txt";
|
|
|
- if (ext == JPG) extension = "jpg";
|
|
|
- if (ext == DDS) extension = "dds";
|
|
|
- if (ext == WAV) extension = "wav";
|
|
|
- if (ext == OGG) extension = "ogg";
|
|
|
- if (ext == FONT) extension = "font";
|
|
|
fprintf(f, "%lld %lld %lld %lld %s\n", i.second->file_id(), i.second->file_offset(), i.second->file_size(),
|
|
|
- i.second->block_size(), extension.c_str());
|
|
|
+ i.second->block_size(), i.second->Extension());
|
|
|
}
|
|
|
fclose(f);
|
|
|
}
|
|
@@ -308,5 +273,40 @@ namespace LOTRO_DAT {
|
|
|
long long DatFile::files_number() const {
|
|
|
return dictionary_.size();
|
|
|
}
|
|
|
+
|
|
|
+ BinaryData DatFile::GetFileData(const Subfile *file, long long int offset = 0) {
|
|
|
+ BinaryData mfile_id(4);
|
|
|
+ ReadData(mfile_id, 4, file->file_offset() + 8);
|
|
|
+ if (file->file_id() != mfile_id.ToNumber<4>(0))
|
|
|
+ throw DatException("Bad DatFile::GetFileData() - file_id in Subfile doesn't match to file_id in DatFile.", READ_EXCEPTION);
|
|
|
+
|
|
|
+ BinaryData data((unsigned)(file->file_size()));
|
|
|
+ if (file->block_size() >= file->file_size() + 8) {
|
|
|
+ ReadData(data, file->file_size(), file->file_offset() + offset);
|
|
|
+ return data;
|
|
|
+ }
|
|
|
+
|
|
|
+ BinaryData fragments_count(4);
|
|
|
+ ReadData(fragments_count, 4, file->file_offset());
|
|
|
+
|
|
|
+ long long fragments_number = fragments_count.ToNumber<4>(0);
|
|
|
+
|
|
|
+ long long current_block_size = file->block_size() - offset - 8 * fragments_number;
|
|
|
+
|
|
|
+ ReadData(data, current_block_size , file->file_offset() + offset);
|
|
|
+
|
|
|
+ BinaryData FragmentsDictionary(8 * unsigned(fragments_number));
|
|
|
+ ReadData(FragmentsDictionary, 8 * unsigned(fragments_number), file->file_offset() + file->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);
|
|
|
+ ReadData(data, std::min(fragment_size, file->file_size() - current_block_size), fragment_offset, current_block_size );
|
|
|
+ current_block_size += fragment_size;
|
|
|
+ }
|
|
|
+
|
|
|
+ return data;
|
|
|
+ }
|
|
|
}
|
|
|
}
|