1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798 |
- //
- // Created by Иван_Архипов on 07.11.2017.
- //
- #include "SubDirectory.h"
- #include "DatFile.h"
- #include "DatException.h"
- #include "Subfile.h"
- #include "BinaryData.h"
- LOTRO_DAT::SubDirectory::SubDirectory() {
- offset_ = 0;
- }
- LOTRO_DAT::SubDirectory::SubDirectory(long long offset, DatFile *dat, long long max_subdirs) :
- offset_(offset), dat_(dat), max_subdirs_(max_subdirs) {
- try {
- MakeSubDirectories();
- } catch (...) {
- fprintf(stderr, "Unable to initialize directory at offset %lld. Initializing it as empty directory...\n", offset);
- subdirs_.clear();
- subfiles_.clear();
- return;
- }
- try {
- MakeSubFiles();
- } catch (...) {
- fprintf(stderr, "Unable to initialize directory at offset %lld. Initializing it as empty directory...\n", offset);
- subdirs_.clear();
- subfiles_.clear();
- return;
- }
- }
- void LOTRO_DAT::SubDirectory::MakeSubDirectories() {
- BinaryData data(1024);
- dat_->ReadData(data, 63 * 8, offset_);
- if (data.ToNumber<4>(0) != 0 || data.ToNumber<4>(4) != 0) {
- std::string err =
- std::string("Bad SubDirectory::MakeSubDirectories - first 8 bytes are not equal to 0 at offset ")
- + std::to_string(offset_);
- throw DatException(err.c_str(), SUBDIR_EXCEPTION);
- }
- for (unsigned int i = 8; i < 63 * 8; i += 8) {
- if (data.ToNumber<4>(i) == 0 || data.ToNumber<4>(i + 4) == 0)
- break;
- try {
- subdirs_.emplace_back(
- SubDirectory(
- data.ToNumber<4>(i + 4),
- dat_
- )
- );
- } catch (...) {
- fprintf(stderr, "Making SubDirectory at offset %lld failed, continuing\n", data.ToNumber<4>(i + 4));
- }
- }
- }
- void LOTRO_DAT::SubDirectory::MakeSubFiles() {
- BinaryData data(64 * 32);
- dat_->ReadData(data, 64 * 32, offset_ + 63 * 8);
- for (unsigned int i = 0; i < 61 * 32; i += 32) {
- if (data.ToNumber<4>(i + 8) < 0x32 || data.ToNumber<4>(i + 12) < 0x32)
- continue;
- subfiles_.emplace_back(
- Subfile(
- dat_,
- data.ToNumber<4>(i), // fragments_count
- data.ToNumber<4>(i + 4), // unknown1
- data.ToNumber<4>(i + 8), // file_id
- data.ToNumber<4>(i + 12), // file_offset
- data.ToNumber<4>(i + 16), // block_size
- data.ToNumber<4>(i + 20), // timestamp
- data.ToNumber<4>(i + 24), // version
- data.ToNumber<4>(i + 28) // block_size
- )
- );
- }
- }
- void LOTRO_DAT::SubDirectory::MakeDictionary(std::unordered_map<long long, Subfile *> &dict) {
- for (Subfile &i : subfiles_) {
- if (i.file_id() == 621002463)
- fprintf(stderr, "YAY!!!! offset = %lld\n", i.file_offset());
- if (dict.count(i.file_id()) == 0 || dict[i.file_id()]->timestamp() < i.timestamp())
- dict[i.file_id()] = &i;
- }
- for (SubDirectory &i : subdirs_)
- i.MakeDictionary(dict);
- }
|