// // Created by kikab on 04.06.2018. // #include #include #include #include #include namespace LOTRO_DAT{ DatFileSystem::DatFileSystem(DatFile *datFilePtr) : dat(datFilePtr) { LOG(INFO) << "Initialization of empty DatFileSystem"; } DatOperationResult DatFileSystem::GetFileData(long long file_id, long long int offset) { if (!dat) return DatOperationResult(BinaryData(), ERROR, "DatFileSystem error: no connection with Dat (dat is nullptr)"); if (dictionary_.count(file_id)) return DatOperationResult(BinaryData(), ERROR, "DatFileSystem error: no file found with id = " + std::to_string(file_id)); auto file = dictionary_[file_id]; LOG(DEBUG) << "Getting file " << file->file_id() << " data"; BinaryData mfile_id(20); auto operation = dat->getIO().ReadData(mfile_id, 20, file->file_offset() + 8); if (operation.result == ERROR) { LOG(ERROR) << "Error while reading file " << file->file_id() << " header (offset = " << file->file_offset() << "); Message: " << operation.msg << "Aborting."; return DatOperationResult(BinaryData(), ERROR, std::string("DatFileSystem error: Read ") + std::to_string(file_id) + " error." + operation.msg); } if (!mfile_id.CheckCompression() && file->file_id() != mfile_id.ToNumber<4>(0)) { LOG(ERROR) << "Bad DatFile::GetFileData() - file_id in SubFile (" << file->file_id() << ") doesn't match to file_id (" << mfile_id.ToNumber<4>(0) << ")in DatFile."; return DatOperationResult(BinaryData(), ERROR, std::string("DatFileSystem error: Read ") + std::to_string(file_id) + " error: SubFile value differs from value in dict"); } BinaryData data((unsigned)(file->file_size() + (8 - offset))); if (file->block_size() >= file->file_size() + 8) { dat->getIO().ReadData(data, file->file_size() + (8 - offset), file->file_offset() + offset); return DatOperationResult(data, SUCCESS); } BinaryData fragments_count(4); dat->getIO().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; dat->getIO().ReadData(data, current_block_size, file->file_offset() + offset); BinaryData FragmentsDictionary(8 * unsigned(fragments_number)); dat->getIO().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); dat->getIO().ReadData(data, std::min(fragment_size, file->file_size() - current_block_size), fragment_offset, current_block_size); current_block_size += fragment_size; } LOG(DEBUG) << "Successfully got file " << file->file_id() << " data"; return DatOperationResult(data, SUCCESS); } DatOperationResult DatFileSystem::GetFile(long long file_id) { } DatOperationResult<> DatFileSystem::UpdateFile(const SubFile &file) { } DatOperationResult<> DatFileSystem::MakeDirectories() { } DatOperationResult<> DatFileSystem::MakeDictionary() { } DatOperationResult<> DatFileSystem::CommitDirectories() { } DatOperationResult<> DatFileSystem::Init() {} DatOperationResult<> DatFileSystem::DeInit() {} }