|
@@ -1,6 +1,7 @@
|
|
|
#include "lotrodatmanager.h"
|
|
|
#include "filesystem.h"
|
|
|
#include "LotroDat/Subfiles/TextSubFile.h"
|
|
|
+#include "models/patchdownloader.h"
|
|
|
|
|
|
#include <QtConcurrent/QtConcurrent>
|
|
|
#include <QFontDatabase>
|
|
@@ -14,406 +15,339 @@
|
|
|
Q_DECLARE_METATYPE(LOTRO_DAT::FILE_TYPE)
|
|
|
Q_DECLARE_METATYPE(LOTRO_DAT::SubfileData)
|
|
|
|
|
|
-LotroDatManager::LotroDatManager(QSettings* app_settings_, QObject *parent) :
|
|
|
- QObject(parent), app_settings(app_settings_) {
|
|
|
+LotroDatManager::LotroDatManager(QSettings* settings, PatchDownloader* downloader, QObject *parent) :
|
|
|
+ QObject(parent), app_settings(settings), patch_downloader(downloader) {
|
|
|
|
|
|
qRegisterMetaType<LOTRO_DAT::FILE_TYPE>();
|
|
|
qRegisterMetaType<LOTRO_DAT::SubfileData>();
|
|
|
}
|
|
|
|
|
|
-void LotroDatManager::initialiseDatFile(QString file_path) {
|
|
|
- emit processStarted("initialiseDatFile", {file_path});
|
|
|
-
|
|
|
- qDebug() << "Initialising file " << file_path;
|
|
|
-
|
|
|
- if (!FileSystem::fileExists(file_path)) {
|
|
|
- emit caughtError(QString("initialiseDatFile"), {QString("Ошибка инициализации"), QString("Файл " + file_path + " несуществует! Невозможно инициализировать файл ресурсов.")});
|
|
|
- emit processFinished("initialiseDatFile", {QString("Error"), file_path});
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- file.Initialise((file_path).toStdString(), 0);
|
|
|
- emit processFinished("initialiseDatFile", {QString("Success"), file_path});
|
|
|
-}
|
|
|
-
|
|
|
-void LotroDatManager::deinitialiseDatFile()
|
|
|
+bool LotroDatManager::Initialised()
|
|
|
{
|
|
|
- emit processStarted("deintialiseDatFile", {});
|
|
|
- qDebug() << "Deinitialising file...";
|
|
|
- file.Deinitialize();
|
|
|
- emit processFinished("deinitialiseDatFile", {});
|
|
|
+ return client_local_file.Initialized() && client_general_file.Initialized();
|
|
|
}
|
|
|
|
|
|
-void LotroDatManager::changeLocale() {
|
|
|
- qDebug() << "Changing locale of dat file...";
|
|
|
- // Setting locale, opposite to current
|
|
|
- auto current_locale = file.GetLocaleManager().GetCurrentLocale();
|
|
|
- auto new_locale = current_locale == LOTRO_DAT::DatLocaleManager::PATCHED ?
|
|
|
- LOTRO_DAT::DatLocaleManager::ORIGINAL :
|
|
|
- LOTRO_DAT::DatLocaleManager::PATCHED;
|
|
|
-
|
|
|
- QString old_locale_name = (current_locale == LOTRO_DAT::DatLocaleManager::PATCHED ? "Русифицированная" : "Оригинальная");
|
|
|
- QString new_locale_name = (new_locale == LOTRO_DAT::DatLocaleManager::PATCHED ? "Русифицированная" : "Оригинальная");
|
|
|
- emit processStarted("changeLocale", {old_locale_name, new_locale_name});
|
|
|
-
|
|
|
-
|
|
|
- auto operation = file.GetLocaleManager().SetLocale(new_locale);
|
|
|
-
|
|
|
- auto new_current_locale = file.GetLocaleManager().GetCurrentLocale();
|
|
|
- QString new_current_locale_name = (new_current_locale == LOTRO_DAT::DatLocaleManager::PATCHED ? "Русифицированная" : "Оригинальная");
|
|
|
-
|
|
|
- if (operation.result == LOTRO_DAT::SUCCESS) {
|
|
|
- emit processFinished("changeLocale", {"Success", new_current_locale_name});
|
|
|
- } else {
|
|
|
- emit caughtError("changeLocale", {"Ошибка смены локали!", QString("Не удалось сменить локаль игры! Текущая локаль: ") + new_current_locale_name});
|
|
|
- emit processFinished("changeLocale", {"Error", new_current_locale_name});
|
|
|
- }
|
|
|
+bool LotroDatManager::NotPatched()
|
|
|
+{
|
|
|
+ return !client_local_file.GetStatusModule().CheckIfNotPatched() && !client_local_file.GetStatusModule().CheckIfNotPatched();
|
|
|
}
|
|
|
|
|
|
-void LotroDatManager::getLocaleFileContents(long long file_id, int locale) {
|
|
|
- emit processStarted("getLocaleFileContents", {file_id, locale});
|
|
|
-
|
|
|
- auto getfile_op = file.GetLocaleManager().GetLocaleFile(file_id, (LOTRO_DAT::DatLocaleManager::LOCALE)locale);
|
|
|
- if (!getfile_op.result) {
|
|
|
- emit caughtError("getLocaleFileContents", {"Файл не найден!", QString("Не удаётся найти файл с id ") + QString::number(file_id)});
|
|
|
- emit processFinished("getLocaleFileContents", {"Error"});
|
|
|
+void LotroDatManager::InitialiseManager()
|
|
|
+{
|
|
|
+ emit processStarted();
|
|
|
+ QString game_folder = app_settings->value("General/game_folder_path", QString()).toString();
|
|
|
+ QString locale_prefix = app_settings->value("General/original_locale", "English").toString();
|
|
|
+ if (game_folder.isEmpty() || !FileSystem::fileExists(game_folder + "client_local_" + locale_prefix + ".dat")
|
|
|
+ || !FileSystem::fileExists(game_folder + "client_general.dat")) {
|
|
|
+
|
|
|
+ emit caughtError(QString("InitialiseManager"), {"FileNotFound"});
|
|
|
+ emit processFinished();
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- LOTRO_DAT::SubFile subfile = getfile_op.value;
|
|
|
+ auto client_local_init_res = client_local_file.Initialise((game_folder + "/client_local_" + locale_prefix + ".dat").toStdString(), 0);
|
|
|
+ auto client_general_init_res = client_general_file.Initialise((game_folder + "/client_general.dat").toStdString(), 1);
|
|
|
|
|
|
- auto getrealfile_op = file.GetFileSystem().GetFile(file_id);
|
|
|
- if (!getfile_op.result) {
|
|
|
- emit caughtError("getLocaleFileContents", {"Файл не найден!", QString("Не удаётся найти в словаре файл с id ") + QString::number(file_id)});
|
|
|
- emit processFinished("getLocaleFileContents", {"Error"});
|
|
|
- return;
|
|
|
- }
|
|
|
+ if (client_local_init_res.result != LOTRO_DAT::SUCCESS
|
|
|
+ || client_general_init_res.result != LOTRO_DAT::SUCCESS) {
|
|
|
+ client_local_file.Deinitialize();
|
|
|
+ client_general_file.Deinitialize();
|
|
|
|
|
|
- if (getrealfile_op.value->FileType() != LOTRO_DAT::TEXT) {
|
|
|
- emit caughtError("getLocaleFileContents", {"Некорректный формат!", QString("Получение данных локали доступно только для текстовых файлов!")});
|
|
|
- emit processFinished("getLocaleFileContents", {"Error"});
|
|
|
+ emit caughtError(QString("InitialiseManager"), {"InitialisationError"});
|
|
|
+ emit processFinished();
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- LOTRO_DAT::TextSubFile text_subfile(subfile);
|
|
|
+ emit processFinished();
|
|
|
+}
|
|
|
|
|
|
- auto getfiledata_op = file.GetFileSystem().GetFileData(subfile, 8);
|
|
|
+void LotroDatManager::DeinitialiseManager()
|
|
|
+{
|
|
|
+ emit processStarted();
|
|
|
+ client_local_file.Deinitialize();
|
|
|
+ client_general_file.Deinitialize();
|
|
|
+ emit processFinished();
|
|
|
+}
|
|
|
|
|
|
- if (getfile_op.result == LOTRO_DAT::ERROR) {
|
|
|
- emit caughtError("getLocaleFileContents", {"Ошибка извлечения!", QString("Обнаружены некорректные данные файла в словаре! Файл ресурсов мог быть повреждён!\nid = ") + QString::number(file_id) + ", locale_id = " + QString::number(locale)});
|
|
|
- emit processFinished("getLocaleFileContents", {"Error"});
|
|
|
- return;
|
|
|
- }
|
|
|
+void LotroDatManager::StartGame(LOTRO_DAT::DatLocaleManager::LOCALE locale)
|
|
|
+{
|
|
|
+ emit processStarted();
|
|
|
|
|
|
- LOTRO_DAT::SubfileData result = text_subfile.PrepareForExport(getfiledata_op.value);
|
|
|
- emit localeFileContentsReceived(locale, result);
|
|
|
- emit processFinished("getLocaleFileContents", {"Success", file_id, locale});
|
|
|
-}
|
|
|
+ client_general_file.GetLocaleManager().SetLocale(locale);
|
|
|
+ client_local_file.GetLocaleManager().SetLocale(locale);
|
|
|
|
|
|
-void LotroDatManager::importFilesFromDatabase(QString database_path) {
|
|
|
- emit processStarted("importFilesFromDatabase", {database_path});
|
|
|
+ QString game_folder = app_settings->value("General/game_folder_path", QString()).toString();
|
|
|
|
|
|
- if (!FileSystem::fileExists(database_path)) {
|
|
|
- emit caughtError(QString("importFilesFromDatabase"), {QString("Ошибка импорта!"), QString("Файл " + database_path + " не существует! Невозможно инициализировать базу данных!")});
|
|
|
- emit processFinished("importFilesFromDatabase", {QString("Error")});
|
|
|
+ if (!FileSystem::fileExists(QApplication::applicationDirPath() + "/GameLauncher.exe")) {
|
|
|
+ emit caughtError("StartGame", {"NoGameLauncherInLegacyDir"});
|
|
|
+ emit processFinished();
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- LOTRO_DAT::Database db;
|
|
|
- if (!db.InitDatabase(database_path.toStdString())) {
|
|
|
- emit caughtError("importFilesFromDatabase", {QString("Ошибка импорта!"), QString("Внутренняя ошибка инициализации базы данных!")});
|
|
|
- emit processFinished("importFilesFromDatabase", {QString("Error")});
|
|
|
+ if (!QFile::remove(game_folder + "/LotroLauncher.exe")) {
|
|
|
+ emit caughtError("StartGame", {"NoAccessToLotroLauncher"});
|
|
|
+ emit processFinished();
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- auto patch_operation = file.GetPatcher().PatchAllDatabase(&db);
|
|
|
-
|
|
|
- if (patch_operation.result == LOTRO_DAT::SUCCESS) {
|
|
|
- file.GetFileSystem().CommitDirectories();
|
|
|
- file.GetLocaleManager().CommitLocales();
|
|
|
- emit processFinished("importFilesFromDatabase", {QString("Success"), patch_operation.value});
|
|
|
- } else {
|
|
|
- emit processFinished("importFilesFromDatabase", {QString("Error"), 0});
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-void LotroDatManager::importFile(long long file_id, QString file_path) {
|
|
|
- emit processStarted("importFile", {file_id, file_path});
|
|
|
-
|
|
|
- if (!FileSystem::fileExists(file_path)) {
|
|
|
- emit caughtError("importFile", {QString("Ошибка импорта!"), QString("Файл ") + file_path + QString(" не существует!")});
|
|
|
- emit processFinished("importFile", {QString("Error")});
|
|
|
+ if (!QFile::copy(QApplication::applicationDirPath() + "/GameLauncher.exe", game_folder + "/LotroLauncher.exe")) {
|
|
|
+ emit caughtError("StartGame", {"NoAccessToGameLauncher"});
|
|
|
+ emit processFinished();
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- LOTRO_DAT::SubfileData data;
|
|
|
-
|
|
|
- data.options["fid"] = file_id;
|
|
|
-
|
|
|
- auto getfile_op = file.GetFileSystem().GetFile(file_id);
|
|
|
- if (getfile_op.result == LOTRO_DAT::ERROR) {
|
|
|
- emit caughtError("importFile", {QString("Ошибка импорта!"), QString("Файл с id ") + QString::number(file_id) + QString(" не существует в ресурсах игры! Невозможно импортировать :/")});
|
|
|
- emit processFinished("importFile", {QString("Error")});
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- std::shared_ptr<LOTRO_DAT::SubFile> subfile = getfile_op.value;
|
|
|
- data.options["ext"] = subfile->Extension();
|
|
|
- data.options["cat"] = subfile->category;
|
|
|
-
|
|
|
- if (subfile->FileType() == LOTRO_DAT::TEXT) {
|
|
|
- std::basic_ifstream<char16_t> input_stream(file_path.toStdString(), std::ios::in);
|
|
|
- if (!input_stream.is_open()) {
|
|
|
- emit caughtError("importFile", {QString("Ошибка импорта!"), QString("Текстовый файл ") + file_path + QString(" не удаётся открыть!")});
|
|
|
- emit processFinished("importFile", {QString("Error")});
|
|
|
- return;
|
|
|
- }
|
|
|
+ startLotroLauncherWithParameters(locale);
|
|
|
+ emit processFinished();
|
|
|
+}
|
|
|
|
|
|
- std::basic_stringstream<char16_t> strStream;
|
|
|
- strStream << input_stream.rdbuf();//read the file
|
|
|
- data.text_data = strStream.str();//str holds the content of the file
|
|
|
+void LotroDatManager::ChangeTranslationLanguage()
|
|
|
+{
|
|
|
+ DeinitialiseManager();
|
|
|
+ InitialiseManager();
|
|
|
+}
|
|
|
|
|
|
- input_stream.close();
|
|
|
- } else {
|
|
|
- QFile data_file(file_path);
|
|
|
- data_file.open(QIODevice::ReadOnly);
|
|
|
+void LotroDatManager::InstallActivePatches()
|
|
|
+{
|
|
|
+ InstallPatches();
|
|
|
+ ApplyTexts();
|
|
|
+ ApplyImages();
|
|
|
+ ApplySounds();
|
|
|
+ InstallLoadscreens();
|
|
|
+ InstallVideos();
|
|
|
+}
|
|
|
|
|
|
- if (!data_file.isOpen()) {
|
|
|
- emit caughtError("importFile", {QString("Ошибка импорта!"), QString("Файл ") + file_path + QString(" не удаётся открыть!")});
|
|
|
- emit processFinished("importFile", {QString("Error")});
|
|
|
- return;
|
|
|
+void LotroDatManager::InstallPatches()
|
|
|
+{
|
|
|
+ const QStringList all_patch_names = {"sound", "text", "image", "texture"};
|
|
|
+ foreach (QString patch_name, all_patch_names) {
|
|
|
+ if (app_settings->value("patch_databases/" + patch_name, "Disabled").toString() == "Disabled")
|
|
|
+ continue;
|
|
|
+
|
|
|
+ QString database_path = patch_downloader->getDatabasePathByPatchName(patch_name);
|
|
|
+ LOTRO_DAT::Database db;
|
|
|
+ if (!db.InitDatabase(database_path.toStdString())) {
|
|
|
+ emit caughtError("InstallPatches", {"ErrorInitDatabase"});
|
|
|
+ continue;
|
|
|
}
|
|
|
|
|
|
- QByteArray contents = data_file.readAll();
|
|
|
- data.binary_data = LOTRO_DAT::BinaryData(contents.constData(), contents.size());
|
|
|
- }
|
|
|
-
|
|
|
+ if (client_local_file.GetPatcher().PatchAllDatabase(&db).result != LOTRO_DAT::SUCCESS)
|
|
|
+ emit caughtError("InstallPatches", {"ErrorCannotPatch", "client_local"});
|
|
|
|
|
|
- auto patchfile_op = file.GetPatcher().PatchFile(data);
|
|
|
+ if (client_general_file.GetPatcher().PatchAllDatabase(&db).result != LOTRO_DAT::SUCCESS)
|
|
|
+ emit caughtError("InstallPatches", {"ErrorCannotPatch", "client_general"});
|
|
|
|
|
|
- if (patchfile_op.result == LOTRO_DAT::SUCCESS) {
|
|
|
- file.GetFileSystem().CommitDirectories();
|
|
|
- file.GetLocaleManager().CommitLocales();
|
|
|
- emit processFinished("importFile", {QString("Success")});
|
|
|
- } else {
|
|
|
- emit caughtError("importFile", {QString("Ошибка импорта!"), QString("Возникла внутренняя ошибка применения патча. Импорт завершился с ошибкой")});
|
|
|
- emit processFinished("importFile", {QString("Error")});
|
|
|
+ db.CloseDatabase();
|
|
|
}
|
|
|
- return;
|
|
|
}
|
|
|
|
|
|
-void LotroDatManager::importTextFragment(long long file_id, long long fragment_id,
|
|
|
- QString fragment_contents, QString arguments) {
|
|
|
- emit processStarted("importTextFragment", {file_id, fragment_id});
|
|
|
+void LotroDatManager::InstallLoadscreens()
|
|
|
+{
|
|
|
+ emit processStarted();
|
|
|
|
|
|
- if (fragment_contents.contains("DO_NOT_TOUCH-1!")) {
|
|
|
- emit caughtError("importTextFragment", {"Ошибка формата!", QString("Текстовые данные содержат указатели на аргументы DO_NOT_TOUCH! с встроенным указанием порядка аргументов (как на сайте) Такого быть не должно! Пользуйтесь порядком перечисления аргументов внизу")});
|
|
|
- emit processFinished("importTextFragment", {"Error"});
|
|
|
+ if (app_settings->value("patch_databases/loadscreen", "Disabled").toString() == "Disabled")
|
|
|
return;
|
|
|
- }
|
|
|
|
|
|
- auto getfile_op = file.GetFileSystem().GetFile(file_id);
|
|
|
- if (!getfile_op.result) {
|
|
|
- emit caughtError("importTextFragment", {"Файл не найден!", QString("Не удаётся найти в ресурсах файл с id ") + QString::number(file_id)});
|
|
|
- emit processFinished("importTextFragment", {"Error"});
|
|
|
+ QString game_folder = app_settings->value("General/game_folder_path", QString()).toString();
|
|
|
+ QString locale_prefix = app_settings->value("General/original_locale", "English").toString();
|
|
|
+
|
|
|
+ QString raw_folder;
|
|
|
+ if (locale_prefix == "English")
|
|
|
+ raw_folder = "en";
|
|
|
+ if (locale_prefix == "DE")
|
|
|
+ raw_folder = "de";
|
|
|
+ if (locale_prefix == "FR")
|
|
|
+ raw_folder = "fr";
|
|
|
+
|
|
|
+ QString folder = game_folder + "/raw/" + raw_folder + "/logo/";
|
|
|
+
|
|
|
+ QString mainscreen =
|
|
|
+ game_folder == "en"
|
|
|
+ ? "lotro_ad_pregame.jpg"
|
|
|
+ : "lotro_ad_pregame_" + game_folder + ".jpg";
|
|
|
+
|
|
|
+ QStringList filenames;
|
|
|
+ filenames << mainscreen
|
|
|
+ << "lotro_generic_teleport_screen_01.jpg"
|
|
|
+ << "lotro_generic_teleport_screen_02.jpg"
|
|
|
+ << "lotro_generic_teleport_screen_03.jpg"
|
|
|
+ << "lotro_generic_teleport_screen_04.jpg"
|
|
|
+ << "lotro_generic_teleport_screen_05.jpg"
|
|
|
+ << "lotro_generic_teleport_screen_06.jpg"
|
|
|
+ << "lotro_generic_teleport_screen_07.jpg"
|
|
|
+ << "lotro_generic_teleport_screen_08.jpg"
|
|
|
+ << "lotro_generic_teleport_screen_09.jpg"
|
|
|
+ << "lotro_generic_teleport_screen_10.jpg";
|
|
|
+
|
|
|
+
|
|
|
+ QString database_path = patch_downloader->getDatabasePathByPatchName("loadscreen");
|
|
|
+ LOTRO_DAT::Database db;
|
|
|
+ if (!db.InitDatabase(database_path.toStdString())) {
|
|
|
+ emit caughtError("InstallLoadscreens", {"ErrorInitDatabase"});
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- auto subfile = getfile_op.value;
|
|
|
+ for (size_t i = 0; i < qMin(db.CountRows(), size_t(filenames.size())); i++) {
|
|
|
+ LOTRO_DAT::SubfileData subfile = db.GetNextFile();
|
|
|
|
|
|
- auto getfiledata_op = file.GetFileSystem().GetFileData(*subfile, 8);
|
|
|
+ if (subfile.binary_data.Empty())
|
|
|
+ continue;
|
|
|
|
|
|
- if (getfile_op.result == LOTRO_DAT::ERROR) {
|
|
|
- emit caughtError("importTextFragment", {"Ошибка импорта!", QString("Обнаружены некорректные данные файла в словаре! Файл ресурсов мог быть повреждён!\nid = ") + QString::number(file_id)});
|
|
|
- emit processFinished("importTextFragment", {"Error"});
|
|
|
- return;
|
|
|
+ QFile::remove(folder + filenames[i]);
|
|
|
+ subfile.binary_data.WriteToFile((folder + filenames[i]).toStdString());
|
|
|
}
|
|
|
+ db.CloseDatabase();
|
|
|
|
|
|
- LOTRO_DAT::SubfileData data = subfile->PrepareForExport(getfiledata_op.value);
|
|
|
- if (data.Empty()) {
|
|
|
- emit caughtError("importTextFragment", {"Ошибка импорта!", QString("Не удалось подготовить файл к изменению фрагмента!\nid = ") + QString::number(file_id)});
|
|
|
- emit processFinished("importTextFragment", {"Error"});
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- unsigned beginning = data.text_data.find(QString::number(fragment_id).toStdU16String(), 0);
|
|
|
- if (beginning == std::u16string::npos) {
|
|
|
- emit caughtError("importTextFragment", {"Ошибка импорта!", QString("Не удалось найти фрагмент в файле!\nid = ") + QString::number(file_id) + "\nfragment_id = " + QString::number(fragment_id)});
|
|
|
- emit processFinished("importTextFragment", {"Error"});
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- unsigned ending = data.text_data.find(QString("|||").toStdU16String(), beginning);
|
|
|
-
|
|
|
- QString new_fragment = QString::number(fragment_id) + ":::" + arguments + ":::" + fragment_contents;
|
|
|
- std::u16string new_text = data.text_data.substr(0, beginning) + new_fragment.toStdU16String() + data.text_data.substr(ending);
|
|
|
- data.text_data = new_text;
|
|
|
-
|
|
|
- auto patchfile_op = file.GetPatcher().PatchFile(data);
|
|
|
-
|
|
|
- if (patchfile_op.result == LOTRO_DAT::SUCCESS) {
|
|
|
- file.GetFileSystem().CommitDirectories();
|
|
|
- file.GetLocaleManager().CommitLocales();
|
|
|
- emit processFinished("importTextFragment", {QString("Success")});
|
|
|
- } else {
|
|
|
- emit caughtError("importTextFragment", {QString("Ошибка импорта!"), QString("Возникла внутренняя ошибка применения патча. Импорт завершился с ошибкой")});
|
|
|
- emit processFinished("importTextFragment", {QString("Error")});
|
|
|
- }
|
|
|
+ emit processFinished();
|
|
|
}
|
|
|
|
|
|
-void LotroDatManager::getTextFragment(long long file_id, long long fragment_id) {
|
|
|
- emit processStarted("getTextFragment", {file_id, fragment_id});
|
|
|
-
|
|
|
- auto getfile_op = file.GetFileSystem().GetFile(file_id);
|
|
|
- if (!getfile_op.result) {
|
|
|
- emit caughtError("getTextFragment", {"Файл не найден!", QString("Не удаётся найти в ресурсах файл с id ") + QString::number(file_id)});
|
|
|
- emit processFinished("getTextFragment", {"Error"});
|
|
|
+void LotroDatManager::InstallVideos()
|
|
|
+{
|
|
|
+ emit processStarted();
|
|
|
+ if (app_settings->value("patch_databases/video", "Disabled").toString() == "Disabled")
|
|
|
return;
|
|
|
- }
|
|
|
|
|
|
- auto subfile = getfile_op.value;
|
|
|
+ QString game_folder = app_settings->value("General/game_folder_path", QString()).toString();
|
|
|
|
|
|
- auto getfiledata_op = file.GetFileSystem().GetFileData(*subfile, 8);
|
|
|
+ QString database_path = patch_downloader->getDatabasePathByPatchName("loadscreen");
|
|
|
|
|
|
- if (getfile_op.result == LOTRO_DAT::ERROR) {
|
|
|
- emit caughtError("getTextFragment", {"Ошибка импорта!", QString("Обнаружены некорректные данные файла в словаре! Файл ресурсов мог быть повреждён!\nid = ") + QString::number(file_id)});
|
|
|
- emit processFinished("getTextFragment", {"Error"});
|
|
|
+ LOTRO_DAT::Database db;
|
|
|
+ if (!db.InitDatabase(database_path.toStdString())) {
|
|
|
+ emit caughtError("InstallVideos", {"ErrorInitDatabase"});
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- LOTRO_DAT::SubfileData data = subfile->PrepareForExport(getfiledata_op.value);
|
|
|
- if (data.Empty()) {
|
|
|
- emit caughtError("getTextFragment", {"Ошибка импорта!", QString("Не удалось подготовить файл к изменению фрагмента!\nid = ") + QString::number(file_id)});
|
|
|
- emit processFinished("getTextFragment", {"Error"});
|
|
|
- return;
|
|
|
- }
|
|
|
+ for(size_t i = 0; i < db.CountRows(); i++) {
|
|
|
+ LOTRO_DAT::SubfileData subfile = db.GetNextFile();
|
|
|
|
|
|
- unsigned beginning = data.text_data.find(QString::number(fragment_id).toStdU16String(), 0);
|
|
|
- if (beginning == std::u16string::npos) {
|
|
|
- emit caughtError("getTextFragment", {"Ошибка импорта!", QString("Не удалось найти фрагмент в файле!\nid = ") + QString::number(file_id) + "\nfragment_id = " + QString::number(fragment_id)});
|
|
|
- emit processFinished("getTextFragment", {"Error"});
|
|
|
- return;
|
|
|
- }
|
|
|
+ if (subfile.Empty())
|
|
|
+ continue;
|
|
|
|
|
|
- unsigned ending = data.text_data.find(QString("|||").toStdU16String(), beginning);
|
|
|
+ QString filename = QString::fromStdString(subfile.options["name"].as<std::string>());
|
|
|
+ QUrl url = QString::fromStdString(subfile.options["url"].as<std::string>());
|
|
|
+ QString hash = QString::fromStdString(subfile.options["hash"].as<std::string>());
|
|
|
+ QString target_folder = game_folder + "/" + QString::fromStdString(subfile.options["folder"].as<std::string>()) + "/";
|
|
|
|
|
|
- unsigned size = std::u16string::npos;
|
|
|
+ if (!QDir(target_folder).exists())
|
|
|
+ QDir(target_folder).mkpath(target_folder);
|
|
|
|
|
|
- if (ending != std::u16string::npos)
|
|
|
- size = ending - beginning;
|
|
|
+ if (FileSystem::fileExists(target_folder + filename))
|
|
|
+ QFile::remove(target_folder + filename);
|
|
|
|
|
|
- std::u16string str = data.text_data.substr(beginning, size);
|
|
|
+ Downloader video_downloader;
|
|
|
+ video_downloader.setUrl(url);
|
|
|
+ video_downloader.targetFile = new QFile(target_folder + filename);
|
|
|
+ video_downloader.targetFile->open(QIODevice::ReadWrite);
|
|
|
+ video_downloader.start();
|
|
|
+ video_downloader.waitForDownloaded();
|
|
|
+ video_downloader.targetFile->close();
|
|
|
+ video_downloader.targetFile->deleteLater();
|
|
|
|
|
|
- QStringList splitted_fragment = QString::fromStdU16String(str).split(":::");
|
|
|
- if (splitted_fragment.size() != 3) {
|
|
|
- emit caughtError("getTextFragment", {"Ошибка импорта!", QString("Получены некорректные данные фрагмента!\nДанные:") + QString::fromStdU16String(str)});
|
|
|
- emit processFinished("getTextFragment", {"Error"});
|
|
|
- return;
|
|
|
+ if (FileSystem::fileHash(target_folder + filename) != hash) {
|
|
|
+ emit caughtError("InstallVideos", {"IncorrectHash", hash, FileSystem::fileHash(target_folder + filename), target_folder, filename, url});
|
|
|
+ }
|
|
|
}
|
|
|
+ db.CloseDatabase();
|
|
|
|
|
|
- emit textFragmentReceived(splitted_fragment.at(1), splitted_fragment.at(2));
|
|
|
- emit processFinished("getTextFragment", {"Success"});
|
|
|
+ emit processFinished();
|
|
|
}
|
|
|
|
|
|
-void LotroDatManager::createCoreStatusFile(QString output_filename) {
|
|
|
- emit processStarted("createCoreStatusFile", {output_filename});
|
|
|
- auto gatherinfo_op = file.GatherInformation(output_filename.toStdString());
|
|
|
+void LotroDatManager::InstallUpdates()
|
|
|
+{
|
|
|
+ // TODO
|
|
|
+}
|
|
|
|
|
|
- if (gatherinfo_op.result == LOTRO_DAT::SUCCESS) {
|
|
|
- emit processFinished("createCoreStatusFile", {"Success", output_filename});
|
|
|
- } else {
|
|
|
- emit caughtError("createCoreStatusFile", {"Ошибка сбора информации!", QString("Не удаётся создать файл информации ядра")});
|
|
|
- emit processFinished("createCoreStatusFile", {"Error", output_filename});
|
|
|
- }
|
|
|
+void LotroDatManager::InstallMicroPatch()
|
|
|
+{
|
|
|
+ // TODO
|
|
|
}
|
|
|
|
|
|
-void LotroDatManager::extractSingleFile(QString output_filename, long long file_id) {
|
|
|
- emit processStarted("extractSingleFile", {output_filename, file_id});
|
|
|
- auto extractfile_op = file.GetExporter().ExtractFileById(file_id, output_filename.toStdString());
|
|
|
- if (extractfile_op.result == LOTRO_DAT::SUCCESS) {
|
|
|
- emit processFinished("extractSingleFile", {"Success", output_filename, file_id});
|
|
|
- } else {
|
|
|
- emit caughtError("extractSingleFile", {"Ошибка экспорта!", QString("Не удаётся экспортировать файл " + QString::number(file_id) + " в файл " + output_filename)});
|
|
|
- emit processFinished("extractSingleFile", {"Error", output_filename});
|
|
|
- }
|
|
|
+void LotroDatManager::CreateBackup()
|
|
|
+{
|
|
|
+ emit processStarted();
|
|
|
+ QString locale_prefix = app_settings->value("General/original_locale", "English").toString();
|
|
|
+ client_local_file.GetBackupManager().CreateBackup((QApplication::applicationDirPath() + "/backup/client_local_" + locale_prefix + ".dat").toStdString());
|
|
|
+ client_general_file.GetBackupManager().CreateBackup((QApplication::applicationDirPath() + "/backup/client_general.dat").toStdString());
|
|
|
+ emit processFinished();
|
|
|
}
|
|
|
|
|
|
-void LotroDatManager::extractSingleFileToDatabase(QString database_path, long long file_id) {
|
|
|
- emit processStarted("extractSingleFileToDatabase", {database_path, file_id});
|
|
|
- LOTRO_DAT::Database db;
|
|
|
- if (!db.InitDatabase(database_path.toStdString())) {
|
|
|
- emit caughtError("extractSingleFileToDatabase", {"Ошибка экспорта!", QString("Не удаётся создать/открыть базу данных " + database_path)});
|
|
|
- emit processFinished("extractSingleFileToDatabase", {"Error", database_path});
|
|
|
- return;
|
|
|
- }
|
|
|
+void LotroDatManager::RestoreFromBackup()
|
|
|
+{
|
|
|
+ emit processStarted();
|
|
|
+ QString locale_prefix = app_settings->value("General/original_locale", "English").toString();
|
|
|
+ client_local_file.GetBackupManager().RestoreFromBackup((QApplication::applicationDirPath() + "/backup/client_local_" + locale_prefix + ".dat").toStdString());
|
|
|
+ client_general_file.GetBackupManager().RestoreFromBackup((QApplication::applicationDirPath() + "/backup/client_general.dat").toStdString());
|
|
|
+ emit processFinished();
|
|
|
+}
|
|
|
|
|
|
- auto extractfile_op = file.GetExporter().ExtractFileById(file_id, &db);
|
|
|
+void LotroDatManager::RemoveBackup()
|
|
|
+{
|
|
|
+ emit processStarted();
|
|
|
+ QString locale_prefix = app_settings->value("General/original_locale", "English").toString();
|
|
|
+ client_local_file.GetBackupManager().RemoveBackup((QApplication::applicationDirPath() + "/backup/client_local_" + locale_prefix + ".dat").toStdString());
|
|
|
+ client_general_file.GetBackupManager().RemoveBackup((QApplication::applicationDirPath() + "/backup/client_general.dat").toStdString());
|
|
|
+ emit processFinished();
|
|
|
+}
|
|
|
|
|
|
- if (extractfile_op.result == LOTRO_DAT::SUCCESS) {
|
|
|
- emit processFinished("extractSingleFileToDatabase", {"Success", database_path, file_id});
|
|
|
+void LotroDatManager::ApplyTexts()
|
|
|
+{
|
|
|
+ if (app_settings->value("patch_options/texts_general", "Disabled").toString() == "Enabled") {
|
|
|
+ client_local_file.GetLocaleManager().EnableCategory(100);
|
|
|
} else {
|
|
|
- emit caughtError("extractSingleFileToDatabase", {"Ошибка экспорта!", QString("Не удаётся экспортировать файл " + QString::number(file_id) + " в базу данных " + database_path)});
|
|
|
- emit processFinished("extractSingleFileToDatabase", {"Error", database_path});
|
|
|
+ client_local_file.GetLocaleManager().DisableCategory(100);
|
|
|
}
|
|
|
-}
|
|
|
|
|
|
-void LotroDatManager::extractGrouppedFiles(QString output_foldername, LOTRO_DAT::FILE_TYPE type) {
|
|
|
- emit processStarted("extractGrouppedFiles", {output_foldername, type});
|
|
|
- auto extractfile_op = file.GetExporter().ExtractAllFilesByType(type, output_foldername.toStdString());
|
|
|
- if (extractfile_op.result == LOTRO_DAT::SUCCESS) {
|
|
|
- emit processFinished("extractGrouppedFiles", {"Success", output_foldername, type, extractfile_op.value});
|
|
|
+ if (app_settings->value("patch_options/texts_emotes", "Disabled").toString() == "Enabled") {
|
|
|
+ client_local_file.GetLocaleManager().EnableCategory(101);
|
|
|
} else {
|
|
|
- emit caughtError("extractGrouppedFiles", {"Ошибка экспорта!", QString("Не удаётся экспортировать файлы с типом " + QString::number(type) + " в папку " + output_foldername)});
|
|
|
- emit processFinished("extractGrouppedFiles", {"Error", output_foldername, type, extractfile_op.value});
|
|
|
+ client_local_file.GetLocaleManager().DisableCategory(101);
|
|
|
}
|
|
|
-}
|
|
|
|
|
|
-void LotroDatManager::extractGrouppedFilesToDatabase(QString database_path, LOTRO_DAT::FILE_TYPE type) {
|
|
|
- emit processStarted(QString("extractGrouppedFilesToDatabase"), {database_path, type});
|
|
|
- LOTRO_DAT::Database db;
|
|
|
- if (!db.InitDatabase(database_path.toStdString())) {
|
|
|
- emit caughtError("extractGrouppedFilesToDatabase", {"Ошибка экспорта!", QString("Не удаётся создать/открыть базу данных " + database_path)});
|
|
|
- emit processFinished("extractGrouppedFilesToDatabase", {"Error", database_path});
|
|
|
- return;
|
|
|
+ if (app_settings->value("patch_options/texts_items", "Disabled").toString() == "Enabled") {
|
|
|
+ client_local_file.GetLocaleManager().EnableCategory(102);
|
|
|
+ } else {
|
|
|
+ client_local_file.GetLocaleManager().DisableCategory(102);
|
|
|
}
|
|
|
+ emit processFinished();
|
|
|
+}
|
|
|
|
|
|
- auto extractfile_op = file.GetExporter().ExtractAllFilesByType(type, &db);
|
|
|
- if (extractfile_op.result == LOTRO_DAT::SUCCESS) {
|
|
|
- emit processFinished("extractGrouppedFilesToDatabase", {"Success", database_path, type, extractfile_op.value});
|
|
|
+void LotroDatManager::ApplyImages() {
|
|
|
+ emit processStarted();
|
|
|
+ if (app_settings->value("patch_options/maps", "Disabled").toString() == "Enabled") {
|
|
|
+ client_local_file.GetLocaleManager().EnableCategory(200);
|
|
|
} else {
|
|
|
- emit caughtError("extractGrouppedFilesToDatabase", {"Ошибка экспорта!", QString("Не удаётся экспортировать файлы с типом " + QString::number(type) + " в базу данных " + database_path)});
|
|
|
- emit processFinished("extractGrouppedFilesToDatabase", {"Error", database_path, extractfile_op.value});
|
|
|
+ client_local_file.GetLocaleManager().DisableCategory(200);
|
|
|
}
|
|
|
+ emit processFinished();
|
|
|
}
|
|
|
|
|
|
-void LotroDatManager::getUnactiveCategories() {
|
|
|
- emit processStarted("getUnactiveCategories", {});
|
|
|
-
|
|
|
- const std::set<long long>& categories = file.GetLocaleManager().GetInactiveCategories();
|
|
|
-
|
|
|
- QStringList result;
|
|
|
- for (long long category : categories) {
|
|
|
- result.append(QString::number(category));
|
|
|
+void LotroDatManager::ApplySounds() {
|
|
|
+ emit processStarted();
|
|
|
+ if (app_settings->value("patch_options/sounds", "Disabled").toString() == "Enabled") {
|
|
|
+ client_local_file.GetLocaleManager().EnableCategory(300);
|
|
|
+ } else {
|
|
|
+ client_local_file.GetLocaleManager().DisableCategory(300);
|
|
|
}
|
|
|
|
|
|
- qDebug() << "Received category set: " << result;
|
|
|
-
|
|
|
- emit unactiveCategoriesReceived(result);
|
|
|
- emit processFinished("getUnactiveCategories", {"Success"});
|
|
|
+ if (app_settings->value("patch_options/video", "Disabled").toString() == "Enabled") {
|
|
|
+ client_local_file.GetLocaleManager().EnableCategory(103);
|
|
|
+ } else {
|
|
|
+ client_local_file.GetLocaleManager().DisableCategory(103);
|
|
|
+ }
|
|
|
+ emit processFinished();
|
|
|
}
|
|
|
|
|
|
-void LotroDatManager::startGame() {
|
|
|
- emit processStarted("startGame", {});
|
|
|
-
|
|
|
+bool LotroDatManager::startLotroLauncherWithParameters(LOTRO_DAT::DatLocaleManager::LOCALE locale)
|
|
|
+{
|
|
|
QStringList args;
|
|
|
- args << "-skiprawdownload" << "-nosplash";
|
|
|
- if (file.GetLocaleManager().GetCurrentLocale() == LOTRO_DAT::DatLocaleManager::PATCHED)
|
|
|
+ args << "-skiprawdownload";
|
|
|
+ if (locale == LOTRO_DAT::DatLocaleManager::PATCHED)
|
|
|
args << "-disablePatch";
|
|
|
|
|
|
- file.Deinitialize();
|
|
|
+ client_general_file.Deinitialize();
|
|
|
+ client_local_file.Deinitialize();
|
|
|
|
|
|
if(FileSystem::fileExists(QApplication::applicationDirPath() + "/user.ini")){
|
|
|
- QSettings login(QApplication::applicationDirPath() + "/user.ini", QSettings::IniFormat );
|
|
|
+ QSettings login(QApplication::applicationDirPath() + "/user.ini", QSettings::IniFormat);
|
|
|
login.beginGroup("Account");
|
|
|
QString username = login.value("username", "").toString();
|
|
|
QString password = login.value("password", "").toString();
|
|
@@ -423,108 +357,16 @@ void LotroDatManager::startGame() {
|
|
|
|
|
|
qDebug() << "Запускаем игру со следующими аргументами: " << args;
|
|
|
|
|
|
- QFile f(app_settings->value("Local", "folder").toString() + "/LotroLauncher.exe");
|
|
|
+ QFile f(app_settings->value("General/game_folder_path", "none").toString() + "/LotroLauncher.exe");
|
|
|
QProcess process;
|
|
|
|
|
|
if (FileSystem::fileExists(f.fileName())) {
|
|
|
if(f.fileName().contains(" ")) f.setFileName("\"" + f.fileName() + "\"");
|
|
|
process.startDetached(f.fileName(), args);
|
|
|
process.waitForFinished(-1);
|
|
|
- emit processFinished("startGame", {});
|
|
|
+ return true;
|
|
|
} else {
|
|
|
- emit caughtError("startGame", {"Ошибка запуска игры!", QString("Не удалось найти файл LotroLauncher в папке: ") + app_settings->value("Local", "folder").toString()});
|
|
|
- emit processFinished("startGame", {"Error"});
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-void LotroDatManager::getLocaleFileInfo(long long file_id, int locale) {
|
|
|
- emit processStarted("getLocaleFileInfo", {file_id, locale});
|
|
|
-
|
|
|
- auto getfile_op = file.GetLocaleManager().GetLocaleFile(file_id, (LOTRO_DAT::DatLocaleManager::LOCALE)locale);
|
|
|
- if (!getfile_op.result) {
|
|
|
- emit caughtError("getLocaleFileInfo", {"Файл не найден!", QString("Не удаётся найти в ресурсах файл с id ") + QString::number(file_id)});
|
|
|
- emit processFinished("getLocaleFileInfo", {"Error"});
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- LOTRO_DAT::SubFile subfile = getfile_op.value;
|
|
|
-
|
|
|
- QString result = "Locale file info:\n "
|
|
|
- "dictionary_offset: " + QString::number(subfile.dictionary_offset()) + "\n"
|
|
|
- "unknown1: " + QString::number(subfile.unknown1()) + "\n"
|
|
|
- "file_id: " + QString::number(subfile.file_id()) + "\n"
|
|
|
- "file_offset: " + QString::number(subfile.file_offset()) + "\n"
|
|
|
- "file_size: " + QString::number(subfile.file_size()) + "\n"
|
|
|
- "timestamp: " + QString::number(subfile.timestamp()) + "\n"
|
|
|
- "version: " + QString::number(subfile.version()) + "\n"
|
|
|
- "block_size: " + QString::number(subfile.block_size()) + "\n"
|
|
|
- "unknown2: " + QString::number(subfile.file_id()) + "\n"
|
|
|
- "category: " + QString::number(subfile.category) + "\n";
|
|
|
-
|
|
|
- emit localeFileInfoReceived(locale, result);
|
|
|
- emit processFinished("getLocaleFileInfo", {"Success"});
|
|
|
-}
|
|
|
-
|
|
|
-void LotroDatManager::getFileInfo(long long file_id) {
|
|
|
- emit processStarted(QString("getFileInfo"), {file_id});
|
|
|
-
|
|
|
- auto getfile_op = file.GetFileSystem().GetFile(file_id);
|
|
|
- if (!getfile_op.result) {
|
|
|
- emit caughtError("getFileInfo", {"Файл не найден!", QString("Не удаётся найти файл с id ") + QString::number(file_id)});
|
|
|
- emit processFinished("getFileInfo", {"Error"});
|
|
|
- return;
|
|
|
+ emit caughtError("startLotroLauncherWithParameters", {"LotroLauncherNotFound"});
|
|
|
+ return false;
|
|
|
}
|
|
|
-
|
|
|
- LOTRO_DAT::SubFile subfile = *getfile_op.value;
|
|
|
-
|
|
|
- QString result = "Locale file info:\n "
|
|
|
- "dictionary_offset: " + QString::number(subfile.dictionary_offset()) + "\n"
|
|
|
- "unknown1: " + QString::number(subfile.unknown1()) + "\n"
|
|
|
- "file_id: " + QString::number(subfile.file_id()) + "\n"
|
|
|
- "file_offset: " + QString::number(subfile.file_offset()) + "\n"
|
|
|
- "file_size: " + QString::number(subfile.file_size()) + "\n"
|
|
|
- "timestamp: " + QString::number(subfile.timestamp()) + "\n"
|
|
|
- "version: " + QString::number(subfile.version()) + "\n"
|
|
|
- "block_size: " + QString::number(subfile.block_size()) + "\n"
|
|
|
- "unknown2: " + QString::number(subfile.file_id()) + "\n";
|
|
|
-
|
|
|
- emit fileInfoReceived(result);
|
|
|
- emit processFinished("getFileInfo", {"Success"});
|
|
|
-}
|
|
|
-
|
|
|
-void LotroDatManager::disableCategory(long long category_id)
|
|
|
-{
|
|
|
- emit processStarted(QString("disableCategory"), {category_id});
|
|
|
- file.GetLocaleManager().DisableCategory(category_id);
|
|
|
- file.GetLocaleManager().CommitLocales();
|
|
|
- file.GetFileSystem().CommitDirectories();
|
|
|
- getUnactiveCategories();
|
|
|
- emit processFinished("disableCategory", {"Success"});
|
|
|
-}
|
|
|
-
|
|
|
-void LotroDatManager::enableCategory(long long category_id)
|
|
|
-{
|
|
|
- emit processStarted(QString("enableCategory"), {category_id});
|
|
|
- file.GetLocaleManager().EnableCategory(category_id);
|
|
|
- file.GetLocaleManager().CommitLocales();
|
|
|
- file.GetFileSystem().CommitDirectories();
|
|
|
- getUnactiveCategories();
|
|
|
- emit processFinished("enableCategory", {"Success"});
|
|
|
-}
|
|
|
-
|
|
|
-LOTRO_DAT::DatStatus *LotroDatManager::getStatusModule()
|
|
|
-{
|
|
|
- return &file.GetStatusModule();
|
|
|
-}
|
|
|
-
|
|
|
-bool LotroDatManager::initialised() {
|
|
|
- return file.Initialized();
|
|
|
-}
|
|
|
-
|
|
|
-int LotroDatManager::currentLocale() {
|
|
|
- return file.GetLocaleManager().GetCurrentLocale();
|
|
|
-}
|
|
|
-
|
|
|
-bool LotroDatManager::notPatched() {
|
|
|
- return file.GetStatusModule().CheckIfNotPatched();
|
|
|
}
|