DatExporter.cpp 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. #include <DatFile.h>
  2. #include <DatSubsystems/DatExporter.h>
  3. #include <DatSubsystems/DatFileSystem.h>
  4. #include <BinaryData.h>
  5. #include <SubfileData.h>
  6. #include <SubFile.h>
  7. #include <string>
  8. #include <fstream>
  9. #include <algorithm>
  10. namespace LOTRO_DAT {
  11. DatExporter::DatExporter(DatFile *datFilePtr) : dat(datFilePtr) {
  12. }
  13. /*!
  14. * \author Gi1dor
  15. * \date 05.07.2018
  16. * Извлечение в папку всех файлов, имеющих заданный тип
  17. * \param[in] type Тип файлов
  18. * \param[in] output_directory_path путь к папке, куда будут записаны файлы. Имя экспортируемого файла - file_id.ext, где file_id - id файла, ext - его расширение
  19. *
  20. * \returns DatOperationResult.value - количество извлечённых файлов
  21. */
  22. DatOperationResult<int> DatExporter::ExtractAllFilesByType(const FILE_TYPE &type, std::string output_directory_path) {
  23. int success_exported = 0;
  24. auto operation = dat->getFileSystem().PerformOperationOnAllFiles([&success_exported, this, type, &output_directory_path](std::shared_ptr<SubFile>& file) -> void {
  25. if (file->FileType() != type)
  26. return;
  27. SubfileData export_file = file->PrepareForExport(dat->getFileSystem().GetFileData(file->file_id(), 8).value);
  28. if (export_file.Empty())
  29. return;
  30. bool result;
  31. if (type == TEXT)
  32. result = WriteStringToFile(export_file.text_data, output_directory_path + std::to_string(file->file_id()) + file->Extension()).result;
  33. else
  34. result = export_file.binary_data.WriteToFile(output_directory_path + std::to_string(file->file_id()) + file->Extension());
  35. if (result)
  36. success_exported++;
  37. });
  38. return DatOperationResult<int>(success_exported, SUCCESS);
  39. }
  40. /*!
  41. * \author Gi1dor
  42. * \date 05.07.2018
  43. * Извлечение файла по его id
  44. * \param[in] file_id id файла
  45. * \param[in] output_filename - имя файла, куда будет записаны данные.
  46. */
  47. DatOperationResult<> DatExporter::ExtractFileById(long long file_id, std::string output_filename) {
  48. auto operation_GetFileData = dat->getFileSystem().GetFileData(file_id, 8);
  49. if (operation_GetFileData.result == ERROR)
  50. return DatOperationResult<>(ERROR, "EXTRACTFILEBYID: Can't get data for id = " + std::to_string(file_id));
  51. auto operation_GetFilePointer = dat->getFileSystem().GetFile(file_id);
  52. if (operation_GetFileData.result == ERROR)
  53. return DatOperationResult<>(ERROR, "EXTRACTFILEBYID: Can't get pointer for id = " + std::to_string(file_id));
  54. std::shared_ptr<SubFile> file = operation_GetFilePointer.value;
  55. SubfileData export_data = file->PrepareForExport(operation_GetFileData.value);
  56. bool result;
  57. if (file->FileType() == TEXT)
  58. result = WriteStringToFile(export_data.text_data, output_filename + file->Extension()).result;
  59. else
  60. result = export_data.binary_data.WriteToFile(output_filename + file->Extension());
  61. if (!result)
  62. return DatOperationResult<>(ERROR, "EXTRACTFILEBYID: Cannot write to file" + output_filename + file->Extension());
  63. return DatOperationResult<>(SUCCESS);
  64. }
  65. /*!
  66. * \author Gi1dor
  67. * \date 05.07.2018
  68. * Извлечение в базу данных всех файлов, имеющих заданный тип
  69. * \param[in] type Тип файлов
  70. * \param[in] db Указатель на объект базы данных
  71. *
  72. * \returns DatOperationResult.value - количество извлечённых файлов
  73. */
  74. DatOperationResult<int> DatExporter::ExtractAllFilesByType(const FILE_TYPE &type, Database *db) {
  75. if (!db)
  76. return DatOperationResult<int>(0, ERROR, "EXTRACTALLBYTYPETODB: database is nullptr");
  77. int success_exported = 0;
  78. auto operation = dat->getFileSystem().PerformOperationOnAllFiles([&success_exported, this, type, db](std::shared_ptr<SubFile>& file) {
  79. if (file->FileType() != type)
  80. return;
  81. SubfileData export_file = file->PrepareForExport(dat->getFileSystem().GetFileData(file->file_id(), 8).value);
  82. bool result = db->PushFile(export_file);
  83. if (result)
  84. success_exported++;
  85. });
  86. return DatOperationResult<int>(success_exported, SUCCESS);
  87. }
  88. /*!
  89. * \author Gi1dor
  90. * \date 05.07.2018
  91. * Запись строки в формате UTF-16 в файл
  92. * \param[in] str Строка для записи в файл
  93. * \param[in] path Путь к файлу, в который строка будет записана
  94. *
  95. * \warning Путь к файлу должен быть корректным (папки должны существовать). Если и сам файл существует, то он будет перезаписан
  96. */
  97. DatOperationResult<> DatExporter::WriteStringToFile(const std::u16string &str, const std::string &path) {
  98. std::basic_ofstream<char16_t> output_stream(path, std::ios::out);
  99. if (!output_stream.is_open())
  100. return DatOperationResult<>(ERROR, "WRITESTRINGTOFILE: cant open file " + path);
  101. output_stream << str;
  102. output_stream.close();
  103. return DatOperationResult<>();
  104. }
  105. };