|
@@ -32,7 +32,8 @@ namespace LOTRO_DAT {
|
|
|
|
|
|
auto getfile_operation = GetFile(file_id);
|
|
|
if (getfile_operation.result == ERROR)
|
|
|
- return DatOperationResult<BinaryData>(BinaryData(), ERROR, "DATFSGETFILEDATA: no file with id = " + std::to_string(file_id));
|
|
|
+ return DatOperationResult<BinaryData>(BinaryData(), ERROR,
|
|
|
+ "DATFSGETFILEDATA: no file with id = " + std::to_string(file_id));
|
|
|
|
|
|
auto file = getfile_operation.value;
|
|
|
|
|
@@ -40,7 +41,8 @@ namespace LOTRO_DAT {
|
|
|
BinaryData mfile_id(20);
|
|
|
auto operation = CheckCorrectSubfile(file);
|
|
|
if (operation.result == ERROR || !operation.value)
|
|
|
- return DatOperationResult<BinaryData>(BinaryData(), ERROR, "DATFSGETFILEDATA: Incorrect file" + std::to_string(file_id));
|
|
|
+ return DatOperationResult<BinaryData>(BinaryData(), ERROR,
|
|
|
+ "DATFSGETFILEDATA: Incorrect file" + std::to_string(file_id));
|
|
|
|
|
|
|
|
|
BinaryData data((unsigned) (file->file_size() + (8 - offset)));
|
|
@@ -137,7 +139,8 @@ namespace LOTRO_DAT {
|
|
|
|
|
|
DatOperationResult<bool> DatFileSystem::CheckCorrectSubfile(const std::shared_ptr<SubFile> &file) {
|
|
|
if (!dat)
|
|
|
- return DatOperationResult<bool>(false, ERROR, "DATFSCORRECTSUBFILE: no connection with Dat (dat is nullptr)");
|
|
|
+ return DatOperationResult<bool>(false, ERROR,
|
|
|
+ "DATFSCORRECTSUBFILE: no connection with Dat (dat is nullptr)");
|
|
|
|
|
|
BinaryData mfile_id(20);
|
|
|
auto operation = dat->getIO().ReadData(mfile_id, 20, file->file_offset() + 8);
|
|
@@ -154,7 +157,7 @@ namespace LOTRO_DAT {
|
|
|
* \date 29.06.2018
|
|
|
* Записывает все изменения структуры файловой системы в dat-файл.
|
|
|
*/
|
|
|
-
|
|
|
+
|
|
|
DatOperationResult<> DatFileSystem::CommitDirectories() {
|
|
|
if (!dat)
|
|
|
return DatOperationResult<>(ERROR, "DATFSCOMMITDIRS: no connection with Dat (dat is nullptr)");
|
|
@@ -189,7 +192,7 @@ namespace LOTRO_DAT {
|
|
|
* \date 29.06.2018
|
|
|
* Подготавливает файловую систему для работы
|
|
|
*/
|
|
|
-
|
|
|
+
|
|
|
DatOperationResult<> DatFileSystem::Init() {
|
|
|
if (!dat)
|
|
|
return DatOperationResult<>(ERROR, "DATFSINIT: no connection with Dat (dat is nullptr)");
|
|
@@ -208,19 +211,21 @@ namespace LOTRO_DAT {
|
|
|
*
|
|
|
* \return Вернёт DatOperationResult<>(ERROR), если случилась ошибка записи структуры файлов в dat файл
|
|
|
*/
|
|
|
-
|
|
|
+
|
|
|
DatOperationResult<> DatFileSystem::DeInit() {
|
|
|
if (!dat)
|
|
|
return DatOperationResult<>(ERROR, "DATFSDEINIT: no connection with Dat (dat is nullptr)");
|
|
|
|
|
|
auto operation = CommitDirectories();
|
|
|
+
|
|
|
dictionary_.clear();
|
|
|
|
|
|
visited_subdirectories_offsets_.clear();
|
|
|
visited_subfiles_ids_.clear();
|
|
|
|
|
|
- subfile_init_queue_.clear();
|
|
|
subdir_init_queue_.clear();
|
|
|
+ subfile_init_map_.clear();
|
|
|
+ subfile_init_queue_.clear();
|
|
|
|
|
|
subfile_pending_update.clear();
|
|
|
|
|
@@ -229,7 +234,7 @@ namespace LOTRO_DAT {
|
|
|
return DatOperationResult<>(SUCCESS);
|
|
|
}
|
|
|
|
|
|
-
|
|
|
+
|
|
|
|
|
|
* \author Gi1dor
|
|
|
* \date 29.06.2018
|
|
@@ -243,11 +248,13 @@ namespace LOTRO_DAT {
|
|
|
LOG(ERROR) << "DATFSPRINTINFO: no connection with Dat (dat is nullptr)";
|
|
|
return;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
InitAllFiles();
|
|
|
|
|
|
fprintf(file, "============= FS INFO SECTION =============\n");
|
|
|
- fprintf(file, "Files number: %d\n", dictionary_.size());
|
|
|
+ fprintf(file, "Files in dictionary number: %d\n", dictionary_.size());
|
|
|
+ fprintf(file, "Files visited: %d\n", visited_subfiles_ids_.size());
|
|
|
+ fprintf(file, "Folders visited: %d\n", visited_subdirectories_offsets_.size());
|
|
|
|
|
|
std::vector<size_t> filetypes_count(7, 0);
|
|
|
|
|
@@ -280,24 +287,36 @@ namespace LOTRO_DAT {
|
|
|
if (!dat)
|
|
|
return DatOperationResult<>(ERROR, "DATFSINITSUBFILE: no connection with Dat (dat is nullptr)");
|
|
|
|
|
|
-
|
|
|
- while (subfile_init_queue_.count(file_id) == 0) {
|
|
|
+ while (subfile_init_map_.count(file_id) == 0) {
|
|
|
if (subdir_init_queue_.empty())
|
|
|
return DatOperationResult<>(ERROR,
|
|
|
"DATFSINITSUBFILE: Cannot init file with id = "
|
|
|
+ std::to_string(file_id) + " (NOT FOUND)");
|
|
|
|
|
|
SubDirectory dir = *subdir_init_queue_.begin();
|
|
|
- InitSubDirectory(dir);
|
|
|
subdir_init_queue_.erase(subdir_init_queue_.begin());
|
|
|
+ InitSubDirectory(dir);
|
|
|
}
|
|
|
|
|
|
- SubFile file = subfile_init_queue_[file_id];
|
|
|
- subfile_init_queue_.erase(file_id);
|
|
|
-
|
|
|
+ SubFile file = subfile_init_map_[file_id];
|
|
|
+ subfile_init_queue_.erase(file);
|
|
|
+ subfile_init_map_.erase(file_id);
|
|
|
|
|
|
auto initialised_file = SubFile::MakeSubfile(*dat, file);
|
|
|
- dictionary_[initialised_file->file_id()] = initialised_file;
|
|
|
+
|
|
|
+ if (dictionary_.count(file_id) > 0 && CheckCorrectSubfile(initialised_file)) {
|
|
|
+ LOG(WARNING) << "Dublicate files id = " << file_id << "dictionary offsets = "
|
|
|
+ << dictionary_[file_id]->dictionary_offset() << " and "
|
|
|
+ << initialised_file->dictionary_offset();
|
|
|
+ if (CheckCorrectSubfile(dictionary_[file_id]))
|
|
|
+ LOG(ERROR) << " FILE IN DICTIONARY IS ALREADY CORRECT!";
|
|
|
+
|
|
|
+ dictionary_[file_id] = initialised_file;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (dictionary_.count(file_id) == 0)
|
|
|
+ dictionary_[file_id] = initialised_file;
|
|
|
+
|
|
|
return DatOperationResult<>();
|
|
|
}
|
|
|
|
|
@@ -317,8 +336,8 @@ namespace LOTRO_DAT {
|
|
|
|
|
|
while (!subdir_init_queue_.empty()) {
|
|
|
SubDirectory dir = *subdir_init_queue_.begin();
|
|
|
- InitSubDirectory(dir);
|
|
|
subdir_init_queue_.erase(subdir_init_queue_.begin());
|
|
|
+ InitSubDirectory(dir);
|
|
|
}
|
|
|
return DatOperationResult<>();
|
|
|
}
|
|
@@ -337,10 +356,11 @@ namespace LOTRO_DAT {
|
|
|
return DatOperationResult<>(ERROR, "DATFSINITALLFILES: no connection with Dat (dat is nullptr)");
|
|
|
|
|
|
InitAllDirectories();
|
|
|
+ std::cout << "DONE ALL DIRS" << std::endl;
|
|
|
+
|
|
|
while (!subfile_init_queue_.empty()) {
|
|
|
- long long file_id = (*subfile_init_queue_.begin()).first;
|
|
|
- InitSubFile(file_id);
|
|
|
- subfile_init_queue_.erase(file_id);
|
|
|
+ SubFile file = *subfile_init_queue_.begin();
|
|
|
+ InitSubFile(file.file_id());
|
|
|
}
|
|
|
return DatOperationResult<>();
|
|
|
}
|
|
@@ -371,23 +391,28 @@ namespace LOTRO_DAT {
|
|
|
* block_size - размер блока данных, выделенного под файл
|
|
|
* unknown2 - неизвестное поле
|
|
|
*
|
|
|
- * \param[in] dir Указатель на объект папки
|
|
|
+ * \param[in] dir объект папки SubDirectory
|
|
|
* \return Объект DatOperationResult
|
|
|
*/
|
|
|
|
|
|
DatOperationResult<> DatFileSystem::InitSubDirectory(SubDirectory dir) {
|
|
|
if (!dat)
|
|
|
return DatOperationResult<>(ERROR, "DATFSINITSUBDIR: no connection with Dat (dat is nullptr)");
|
|
|
-
|
|
|
BinaryData subdir_data(63 * 8 + 4 + 32 * 64);
|
|
|
auto operation = dat->getIO().ReadData(subdir_data, 63 * 8 + 4 + 32 * 64, dir.offset());
|
|
|
- if (!operation.result == SUCCESS)
|
|
|
+ if (operation.result == ERROR)
|
|
|
return DatOperationResult<>(ERROR, "DATFSINITSUBDIR: cannot init dir (read error) with offset = " +
|
|
|
std::to_string((dir.offset())));
|
|
|
|
|
|
if (subdir_data.ToNumber<4>(0) != 0 || subdir_data.ToNumber<4>(4) != 0)
|
|
|
return DatOperationResult<>(ERROR, "DATFSINITSUBDIR: incorrect dir. Nulls must be at first 8 bytes of dir");
|
|
|
|
|
|
+
|
|
|
+ long long subfiles_number = subdir_data.ToNumber<4>(63 * 8);
|
|
|
+ if (subfiles_number >= 64)
|
|
|
+ return DatOperationResult<>(ERROR, "DATINITSUBDIR: incorrect subdir: files number > 64");
|
|
|
+
|
|
|
+
|
|
|
|
|
|
for (unsigned i = 8; i < 63 * 8; i += 8) {
|
|
|
if (subdir_data.ToNumber<4>(i) == 0 || subdir_data.ToNumber<4>(i + 4) == 0)
|
|
@@ -396,6 +421,9 @@ namespace LOTRO_DAT {
|
|
|
long long unknown = subdir_data.ToNumber<4>(i);
|
|
|
long long offset = subdir_data.ToNumber<4>(i + 4);
|
|
|
|
|
|
+ if (unknown == 0 || offset == 0)
|
|
|
+ break;
|
|
|
+
|
|
|
if (visited_subdirectories_offsets_.count(offset) != 0)
|
|
|
continue;
|
|
|
|
|
@@ -403,11 +431,7 @@ namespace LOTRO_DAT {
|
|
|
subdir_init_queue_.insert(SubDirectory(unknown, offset));
|
|
|
}
|
|
|
|
|
|
-
|
|
|
- long long subfiles_number = subdir_data.ToNumber<4>(63 * 8);
|
|
|
- if (subfiles_number >= 64)
|
|
|
- return DatOperationResult<>(ERROR, "DATINITSUBDIR: incorrect subdir: files number > 64");
|
|
|
-
|
|
|
+
|
|
|
|
|
|
for (int i = 0; i < subfiles_number; i++) {
|
|
|
long long header_start = 63 * 8 + 4 + 32 * i;
|
|
@@ -432,6 +456,7 @@ namespace LOTRO_DAT {
|
|
|
break;
|
|
|
|
|
|
visited_subfiles_ids_.insert(file.file_id());
|
|
|
+ subfile_init_map_[file.file_id_] = file;
|
|
|
subfile_init_queue_.insert(file);
|
|
|
}
|
|
|
return DatOperationResult<>();
|