// // Created by Иван_Архипов on 30.10.2017. // #include #include #include #ifdef _WIN32 #include #define mkdir(dir, mode) _mkdir(dir) #endif #include "LotroDat.h" using namespace LOTRO_DAT; // Change these variables to true if you want export category to files. bool exportTextsToFiles = false; bool exportImagesToFiles = false; bool exportFontsToFiles = false; bool exportSoundsToFiles = false; bool exportTexturesToFiles = false; bool exportUnknownToFiles = false; // Change these variables to true if you want export category to databases. bool exportTextsToDb = false; bool exportImagesToDb = false; bool exportFontsToDb = false; bool exportSoundsToDb = false; bool exportTexturesToDb = false; bool exportUnknownToDb = false; // There is no need to change anything else void DatStatusChangedHandler(DatStatus::ProgressInfo info) { if (info.status == DatStatus::DAT_STATUS::E_FREE) { std::cout << "DatStatus: operation finished" << std::endl; return; } if (info.status == DatStatus::DAT_STATUS::E_BACKUP_CREATING) { std::cout << "DatStatus: creating backup " << info.percentage << "% " << "(" << info.finished_parts << "/" << info.total_parts << ")" << std::endl; return; } if (info.status == DatStatus::DAT_STATUS::E_BACKUP_REMOVING) { std::cout << "DatStatus: removing backup " << info.percentage << "% " << "(" << info.finished_parts << "/" << info.total_parts << ")" << std::endl; return; } if (info.status == DatStatus::DAT_STATUS::E_BACKUP_RESTORING) { std::cout << "DatStatus: restoring backup " << info.percentage << "% " << "(" << info.finished_parts << "/" << info.total_parts << ")" << std::endl; return; } if (info.status == DatStatus::DAT_STATUS::E_COMMITING) { std::cout << "DatStatus: applying locales " << info.percentage << "% " << "(" << info.finished_parts << "/" << info.total_parts << ")" << std::endl; return; } if (info.status == DatStatus::DAT_STATUS::E_EXTRACTING) { std::cout << "DatStatus: extracting data " << info.percentage << "% " << "(" << info.finished_parts << "/" << info.total_parts << ")" << std::endl; return; } if (info.status == DatStatus::DAT_STATUS::E_GATHERING_INFO) { std::cout << "DatStatus: gathering info " << info.percentage << "% " << "(" << info.finished_parts << "/" << info.total_parts << ")" << std::endl; return; } if (info.status == DatStatus::DAT_STATUS::E_INITIALISING) { std::cout << "DatStatus: initialising " << info.percentage << "% " << "(" << info.finished_parts << "/" << info.total_parts << ")" << std::endl; return; } if (info.status == DatStatus::DAT_STATUS::E_PATCHING) { std::cout << "DatStatus: applying patch " << info.percentage << "% " << "(" << info.finished_parts << "/" << info.total_parts << ")" << std::endl; return; } } int main() { std::cout.precision(1); std::cout << std::fixed; std::cout << "Gi1dor's LotRO .dat extractor ver. " << LOTRO_DAT_VERSION << std::endl; std::cout << "Hello! I'm a basic shell version of .dat file extractor. I can open .dat file directly, " "if you write path to it (with name of file) in file \"dat_file_path.txt\"\n"; DatFile file; std::ifstream in("dat_file_path.txt"); if (!in.fail()) { std::string filename; std::getline(in, filename); std::string file_id_str; std::getline(in, file_id_str); int file_id = 0; try { file_id = stoi(file_id_str); } catch (std::invalid_argument) { file_id = -1; std::cout << "Invalid file_id on second line of file dat_file_path.txt!\n\n"; } if (file_id != -1) { std::cout << "Using .dat file from dat_file_path.txt...\n"; std::cout << "Opening file " << filename << " with id = " << file_id << std::endl; auto operation = file.Initialise(filename, file_id); if (operation.result == false) { std::cout << "Dat initialisation failed. Error message: " << operation.msg << "\n"; } } } while (!file.Initialized()) { std::cout << "Please, tell, where the .dat file is\n"; std::cout << "Enter path to file (including filename): "; std::string filename; std::getline(std::cin, filename); std::cout << "Enter file id: "; std::string file_id_str; std::getline(std::cin, file_id_str); int file_id = 0; try { file_id = stoi(file_id_str); } catch (std::invalid_argument) { std::cout << "Invalid command entered!\n\n"; continue; } std::cout << "Opening file " << filename << std::endl; auto operation = file.Initialise(filename, file_id); if (operation.result == false) { std::cout << "Dat initialisation failed. Error message: " << operation.msg << "\nTo try again enter path to .dat file\n"; } } std::cout << "Great! File initialised successfully!\n"; file.GetStatusModule().AddStatusChangedCallbackFunction(&DatStatusChangedHandler); std::cout << "Gathering file information...\n"; file.GatherInformation("dat_info.log"); while (true) { std::cout << "Please, choose, what should I do. I can extract .dat file to files (press 1), " "open another .dat file (press 2), or configure, what should I extract. Choose, what to do or exit (press -1)\n"; std::cout << "Enter number of command (1-3): "; std::string command; std::getline(std::cin, command); int cmd = -10; try { cmd = stoi(command); } catch (std::invalid_argument) { std::cout << "Invalid command entered!\n\n"; continue; } if (cmd == -1) { std::cout << "Exiting. Thanks for using me!\n"; break; } if (cmd == 1) { const clock_t begin_time = clock(); mkdir("Extracted data", 744); std::time_t result = std::time(nullptr); char *ttime = std::asctime(std::localtime(&result)); auto *out_time = new char[25]; memcpy(out_time, ttime, 24); out_time[24] = '\0'; std::string filename = file.GetIO().GetFilename().value; std::cout << "FILENAME = " << filename << std::endl; std::string output_dir = std::string("Extracted data\\") + filename.substr(std::max(filename.length() - 16, 0u), 16) + " " + std::string(out_time) + "\\"; std::replace(output_dir.begin(), output_dir.end(), ':', '-'); mkdir(output_dir.c_str(), 744); std::cout << "Beginning unpacking... Please, wait for some minutes." "\nMaybe it's a good idea to have a cup of tea, while unpacker is working...\n" << std::flush; Database output_db; if (exportImagesToDb) { output_db.InitDatabase(output_dir + std::string("Images.db")); int extracted_jpg_files_num = file.GetExporter().ExtractAllFilesByType(JPG, &output_db).value; std::cout << "Extracted " << extracted_jpg_files_num << " .jpg files to Images.db" << std::endl << std::flush; output_db.CloseDatabase(); } if (exportSoundsToDb) { output_db.InitDatabase(output_dir + std::string("Sounds.db")); int extracted_wav_files_num = file.GetExporter().ExtractAllFilesByType(WAV, &output_db).value; int extracted_ogg_files_num = file.GetExporter().ExtractAllFilesByType(OGG, &output_db).value; std::cout << "Extracted " << extracted_wav_files_num << " .wav files to Sounds.db" << std::endl << std::flush; std::cout << "Extracted " << extracted_ogg_files_num << " .ogg files to Sounds.db" << std::endl << std::flush; output_db.CloseDatabase(); } if (exportTextsToDb) { output_db.InitDatabase(output_dir + std::string("Texts.db")); int extracted_text_files_num = file.GetExporter().ExtractAllFilesByType(TEXT, &output_db).value; std::cout << "Extracted " << extracted_text_files_num << " text files to Texts.db" << std::endl << std::flush; output_db.CloseDatabase(); } if (exportFontsToDb) { output_db.InitDatabase(output_dir + std::string("Fonts.db")); int extracted_font_files_num = file.GetExporter().ExtractAllFilesByType(FONT, &output_db).value; std::cout << "Extracted " << extracted_font_files_num << " font files to Fonts.db" << std::endl << std::flush; output_db.CloseDatabase(); } if (exportTexturesToDb) { output_db.InitDatabase(output_dir + std::string("Textures.db")); int extracted_dds_files_num = file.GetExporter().ExtractAllFilesByType(DDS, &output_db).value; std::cout << "Extracted " << extracted_dds_files_num << " .dds files to Textures.db" << std::endl << std::flush; output_db.CloseDatabase(); } if (exportImagesToFiles) { mkdir((output_dir + "jpg").c_str(), 744); int extracted_jpg_files_num = file.GetExporter().ExtractAllFilesByType(JPG, output_dir + "jpg\\").value; std::cout << "Extracted " << extracted_jpg_files_num << " .jpg files to directory" << std::endl << std::flush; } if (exportTexturesToFiles) { mkdir((output_dir + "dds").c_str(), 744); int extracted_dds_files_num = file.GetExporter().ExtractAllFilesByType(DDS, output_dir + "dds\\").value; std::cout << "Extracted " << extracted_dds_files_num << " .dds files to directory" << std::endl << std::flush; } if (exportSoundsToFiles) { mkdir((output_dir + "wav").c_str(), 744); int extracted_wav_files_num = file.GetExporter().ExtractAllFilesByType(WAV, output_dir + "wav\\").value; std::cout << "Extracted " << extracted_wav_files_num << " .wav files to directory" << std::endl << std::flush; mkdir((output_dir + "ogg").c_str(), 744); int extracted_ogg_files_num = file.GetExporter().ExtractAllFilesByType(OGG, output_dir + "ogg\\").value; std::cout << "Extracted " << extracted_ogg_files_num << " .ogg files to directory" << std::endl << std::flush; } if (exportFontsToFiles) { mkdir((output_dir + "fonts").c_str(), 744); int extracted_font_files_num = file.GetExporter().ExtractAllFilesByType(FONT, output_dir + "fonts\\").value; std::cout << "Extracted " << extracted_font_files_num << " font files to directory" << std::endl << std::flush; } if (exportUnknownToFiles) { mkdir((output_dir + "unknown").c_str(), 744); int extracted_unknown_files_num = file.GetExporter().ExtractAllFilesByType(UNKNOWN, output_dir + "unknown\\").value; std::cout << "Extracted " << extracted_unknown_files_num << " unknown files to directory" << std::endl << std::flush; } if (exportTextsToFiles) { mkdir((output_dir + "texts").c_str(), 744); int extracted_text_files_num = file.GetExporter().ExtractAllFilesByType(TEXT, output_dir + "texts\\").value; std::cout << "Extracted " << extracted_text_files_num << " text files to directory" << std::endl << std::flush; } fprintf(stdout, "Spent %f seconds on running unpacker! Thank you for your patience!\n", float(clock() - begin_time) / CLOCKS_PER_SEC); } if (cmd == 2) { std::cout << "Closing file...\n"; file.Deinitialize(); while (!file.Initialized()) { std::cout << "Please, tell, where the .dat file is\n"; std::cout << "Enter path to file (including filename): "; std::string filename; std::getline(std::cin, filename); std::cout << "Opening file " << filename << std::endl; auto operation = file.Initialise(filename, 0); if (operation.result == false) { std::cout << "Some error caused while opening the file... " "Could you enter .dat filename once more?" << std::endl; std::cout << "Error message: " << operation.msg << std::endl; file.Deinitialize(); } } } if (cmd == 3) { std::cout << "Current parameters:\n"; std::cout << "(01) Export texts to files - " << (exportTextsToFiles ? "true\n" : "false\n"); std::cout << "(02) Export texts to database - " << (exportTextsToDb ? "true\n" : "false\n"); std::cout << "(11) Export images to files - " << (exportImagesToFiles ? "true\n" : "false\n"); std::cout << "(12) Export images to database - " << (exportImagesToDb ? "true\n" : "false\n"); std::cout << "(21) Export fonts to files - " << (exportFontsToFiles ? "true\n" : "false\n"); std::cout << "(22) Export fonts to database - " << (exportFontsToDb ? "true\n" : "false\n"); std::cout << "(31) Export sounds to files - " << (exportSoundsToFiles ? "true\n" : "false\n"); std::cout << "(32) Export sounds to database - " << (exportSoundsToDb ? "true\n" : "false\n"); std::cout << "(41) Export textures to files - " << (exportTexturesToFiles ? "true\n" : "false\n"); std::cout << "(42) Export textures to database - " << (exportTexturesToDb ? "true\n" : "false\n"); std::cout << "(51) Export unknown files to files - " << (exportUnknownToFiles ? "true\n" : "false\n"); std::cout << "(52) Export unknown files to database - " << (exportUnknownToDb ? "true\n" : "false\n"); std::cout << "Enter number of parameter to change (or -1 to exit this menu): "; int number = 0; std::cin >> number; std::string tmp; std::getline(std::cin, tmp); if (number == -1) { std::cout << "Returning to main menu..\n"; cmd = 0; } else { switch (number) { case 01: exportTextsToFiles = !exportTextsToFiles; break; case 02: exportTextsToDb = !exportTextsToDb; break; case 11: exportImagesToFiles = !exportImagesToFiles; break; case 12: exportImagesToDb = !exportImagesToDb; break; case 21: exportFontsToFiles = !exportFontsToFiles; break; case 22: exportFontsToDb = !exportFontsToDb; break; case 31: exportSoundsToFiles = !exportSoundsToFiles; break; case 32: exportSoundsToDb = !exportSoundsToDb; break; case 41: exportTexturesToFiles = !exportTexturesToFiles; break; case 42: exportTexturesToDb = !exportTexturesToDb; break; case 51: exportUnknownToFiles = !exportTexturesToFiles; break; case 52: exportUnknownToDb = !exportTexturesToDb; break; default: std::cout << "Incorrect number. Returning to main menu..\n"; } } } } file.Deinitialize(); system("pause"); return 0; }