123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173 |
- #include <DatFile.h>
- #include <DatSubsystems/DatExporter.h>
- #include <DatSubsystems/DatFileSystem.h>
- #include <BinaryData.h>
- #include <SubfileData.h>
- #include <SubFile.h>
- #include <string>
- #include <fstream>
- #include <algorithm>
- namespace LOTRO_DAT {
- DatExporter::DatExporter(DatFile *datFilePtr) : dat(datFilePtr) {
- }
- /*!
- * \author Gi1dor
- * \date 05.07.2018
- * Извлечение в папку всех файлов, имеющих заданный тип
- * \param[in] type Тип файлов
- * \param[in] output_directory_path путь к папке, куда будут записаны файлы. Имя экспортируемого файла - file_id.ext, где file_id - id файла, ext - его расширение
- *
- * \returns DatOperationResult.value - количество извлечённых файлов
- */
- DatOperationResult<int> DatExporter::ExtractAllFilesByType(const FILE_TYPE &type, std::string output_directory_path) {
- int success_exported = 0;
- int iterated_files = 0;
- dat->GetStatusModule().SetStatus(DatStatus::E_EXTRACTING);
- dat->GetStatusModule().SetPercentage(0);
- dat->GetStatusModule().SetDebugMessage("Starting extracting files of type " + std::to_string(type));
- auto operation = dat->GetFileSystem().PerformOperationOnAllFiles([&iterated_files, &success_exported, this, type, &output_directory_path](std::shared_ptr<SubFile>& file) -> void {
- iterated_files++;
- dat->GetStatusModule().SetPercentage(iterated_files * 100u / dat->GetFileSystem().GetInitialisedFilesNumber());
- if ((file->FileType() & type) == 0)
- return;
- SubfileData export_file = file->PrepareForExport(dat->GetFileSystem().GetFileData(file->file_id(), 8).value);
- dat->GetStatusModule().SetDebugMessage("Extracting file " + std::to_string(file->file_id()) + " (Files by type -> directory)");
- if (export_file.Empty())
- return;
- bool result;
- if (type == TEXT)
- result = WriteStringToFile(export_file.text_data, output_directory_path + std::to_string(file->file_id()) + file->Extension()).result;
- else
- result = export_file.binary_data.WriteToFile(output_directory_path + std::to_string(file->file_id()) + file->Extension());
- if (result)
- success_exported++;
- });
- dat->GetStatusModule().ClearAll();
- return DatOperationResult<int>(success_exported, SUCCESS);
- }
- /*!
- * \author Gi1dor
- * \date 05.07.2018
- * Извлечение файла по его id
- * \param[in] file_id id файла
- * \param[in] output_filename - имя файла, куда будет записаны данные.
- */
- DatOperationResult<> DatExporter::ExtractFileById(long long file_id, std::string output_filename) {
- dat->GetStatusModule().SetStatus(DatStatus::E_EXTRACTING);
- dat->GetStatusModule().SetPercentage(0);
- dat->GetStatusModule().SetDebugMessage("Extracting file " + std::to_string(file_id) + " to file " + output_filename);
- auto operation_GetFileData = dat->GetFileSystem().GetFileData(file_id, 8);
- if (operation_GetFileData.result == ERROR) {
- dat->GetStatusModule().ClearAll();
- return DatOperationResult<>(ERROR, "EXTRACTFILEBYID: Can't get data for id = " + std::to_string(file_id));
- }
- auto operation_GetFilePointer = dat->GetFileSystem().GetFile(file_id);
- if (operation_GetFileData.result == ERROR) {
- dat->GetStatusModule().ClearAll();
- return DatOperationResult<>(ERROR,
- "EXTRACTFILEBYID: Can't get pointer for id = " + std::to_string(file_id));
- }
- std::shared_ptr<SubFile> file = operation_GetFilePointer.value;
- SubfileData export_data = file->PrepareForExport(operation_GetFileData.value);
- bool result;
- if (file->FileType() == TEXT)
- result = WriteStringToFile(export_data.text_data, output_filename + file->Extension()).result;
- else
- result = export_data.binary_data.WriteToFile(output_filename + file->Extension());
- dat->GetStatusModule().ClearAll();
- if (!result)
- return DatOperationResult<>(ERROR, "EXTRACTFILEBYID: Cannot write to file" + output_filename + file->Extension());
- return DatOperationResult<>(SUCCESS);
- }
- /*!
- * \author Gi1dor
- * \date 05.07.2018
- * Извлечение в базу данных всех файлов, имеющих заданный тип
- * \param[in] type Тип файлов
- * \param[in] db Указатель на объект базы данных
- *
- * \returns DatOperationResult.value - количество извлечённых файлов
- */
- DatOperationResult<int> DatExporter::ExtractAllFilesByType(const FILE_TYPE &type, Database *db) {
- if (!db)
- return DatOperationResult<int>(0, ERROR, "EXTRACTALLBYTYPETODB: database is nullptr");
- dat->GetStatusModule().SetStatus(DatStatus::E_EXTRACTING);
- dat->GetStatusModule().SetPercentage(0);
- dat->GetStatusModule().SetDebugMessage("Initialising extraction of files by type " + std::to_string(type) + "to database...");
- int success_exported = 0;
- int iterated_files = 0;
- auto operation = dat->GetFileSystem().PerformOperationOnAllFiles([&success_exported, &iterated_files, this, type, db](std::shared_ptr<SubFile>& file) {
- iterated_files++;
- dat->GetStatusModule().SetPercentage(iterated_files * 100u / dat->GetFileSystem().GetInitialisedFilesNumber());
- if ((file->FileType() & type) == 0)
- return;
- dat->GetStatusModule().SetDebugMessage("Extracting file " + std::to_string(file->file_id()) + " (Files by type -> directory)");
- SubfileData export_file = file->PrepareForExport(dat->GetFileSystem().GetFileData(file->file_id(), 8).value);
- bool result = db->PushFile(export_file);
- if (result)
- success_exported++;
- });
- dat->GetStatusModule().ClearAll();
- return DatOperationResult<int>(success_exported, SUCCESS);
- }
- /*!
- * \author Gi1dor
- * \date 05.07.2018
- * Запись строки в формате UTF-16 в файл
- * \param[in] str Строка для записи в файл
- * \param[in] path Путь к файлу, в который строка будет записана
- *
- * \warning Путь к файлу должен быть корректным (папки должны существовать). Если и сам файл существует, то он будет перезаписан
- */
- DatOperationResult<> DatExporter::WriteStringToFile(const std::u16string &str, const std::string &path) {
- std::basic_ofstream<char16_t> output_stream(path, std::ios::out);
- if (!output_stream.is_open())
- return DatOperationResult<>(ERROR, "WRITESTRINGTOFILE: cant open file " + path);
- output_stream << str;
- output_stream.close();
- return DatOperationResult<>();
- }
- };
|