#include "gameres.h" #include "aconfig.h" #include "filesystem.h" #include "anetwork.h" #include #include #include #include #include #include #include GameRes::GameRes() {} // Public functions int GameRes::openDatFile(int id) { QStringList dat_files; dat_files << AConfig::getInstance()->getValue("Local", "file") << "client_general.dat" << "client_sound.dat" << "client_surface.dat" << "client_highres.dat"; if (dat_files[id] == nullptr) return -100; // -100 = incorrect id std::string filename = (AConfig::getInstance()->getValue("Local", "folder") + "/" + dat_files[id]).toStdString(); qDebug("%s:%i: %s%s", __FILE__, __LINE__, "Инициализация dat-файла. Открываем файл ", filename.c_str()); int dat_state = GameRes::getInstance()->datfiles_[id].InitDatFile(filename, 0); qDebug("%s:%i: %s%d", __FILE__, __LINE__, "Состояние dat-файла: ", dat_state); return dat_state; } int GameRes::closeDatFile(int id) { return datfiles_[id].CloseDatFile(); } void GameRes::applyPatch(QString name) { emit startedPatching(name); qDebug("%s:%i: %s%s", __FILE__, __LINE__, "Начинаем применение патча ", name.toStdString().c_str()); QDir dir(QApplication::applicationDirPath() + "/data"); if (!dir.exists()) { //emit applyAllFinished(-100); // -100 - not found data folder return; } QStringList paths = dir.entryList(QStringList(name + "*")); qDebug() << ("data/" + paths.first()); if(!paths.empty()) { db_.InitDatabase(("data/" + paths.first()).toStdString()); int indb = db_.CountRows(); qInfo("%s:%i: %s%d", __FILE__, __LINE__, "Файлов в обновлении: ", indb); int percent = -1; for (int i = 0; i <= indb; i++) { if (i * 100 / indb > percent) { percent = i * 100 / indb; qInfo("%s:%i: %s%d%s", __FILE__, __LINE__, "Применение обновления: ", percent, "%"); emit updatedPatchPercent(percent); } processFile(); } AConfig::getInstance()->setValue("Applied", name, paths.first()); db_.CloseDatabase(); } } void GameRes::setGameLocale(QString locale) { openDatFile(0); locale_ = datfiles_[0].current_locale(); if(locale_ == PATCHED) qDebug() << "Starting " + locale + " version. Current locale is PATCHED"; if(locale_ == ORIGINAL) qDebug() << "Starting " + locale + " version. Current locale is ORIGINAL"; if(locale_ != ORIGINAL && locale_ != PATCHED) qDebug() << "Starting " + locale + " version. Current locale is UNKNOWN"; if(locale == "RU" && locale_ != PATCHED) {qDebug()<< "Current locale Original"; datfiles_[0].SetLocale(PATCHED); locale_ = PATCHED;} if(locale == "Original" && locale_ != ORIGINAL) {qDebug()<< "Current locale RU"; datfiles_[0].SetLocale(ORIGINAL); locale_ = ORIGINAL;} closeDatFile(0); return; } void GameRes::saveAllDatFiles(){ for(int i = 0; i < 5; i++){ datfiles_[i].CloseDatFile(); } } int GameRes::startGame() { saveAllDatFiles(); QStringList args; args << "-skiprawdownload" << "-nosplash"; if (locale_ == PATCHED) args << "-disablePatch"; QFile f(AConfig::getInstance()->getValue("Local", "folder") + "/TurbineLauncher.exe"); QProcess process; if(FileSystem::fileExists(f.fileName())){ if (f.fileName().contains(" ")) f.setFileName("\"" + f.fileName() + "\""); process.startDetached(f.fileName(), args); process.waitForFinished(-1); process.deleteLater(); QApplication::quit(); return 0; } else { //QString text = "Запуск не удался"; //QString info = "Не удалось запустить игру. Во время запуска произшла непредвиденная ошибка (возможно, не найден файл TurbineLauncher.exe в папке с игрой. Проверьте в 'Настройках', что у вас указан верный путь к игре, и повторите попытку запуска)."; //app->helper->myDialogBox(text, info, "OK", "Отмена", "gandalf.png", "", "", 400, 160, true, false); return -100; } } void GameRes::installMicroPatch() { QString date = AConfig::getInstance()->getValue("Updates", "update"); if(date == "false") date = QDate::currentDate().toString("yyyy-MM-dd"); QTime time = QTime::currentTime(); int timestamp = dateToTimestamp(date + " " + time.toString("hh:mm:ss"), "yyyy-MM-dd hh:mm:ss") - 2592000; qInfo("%s:%i: %s", __FILE__, __LINE__, "Опция активна. Начинаем загрузку обновлений"); ANetwork::getInstance()->getMicroPatch(timestamp); connect(ANetwork::getInstance(), SIGNAL(ANetwork::getMicroPatchFinished(QString)), this, SLOT(applyMicroPatch(QString))); } void GameRes::applyAll() { // Применяем патч с заставочными экранами if (AConfig::getInstance()->getValue("Editor", "screens") == "true") { applyLoadscreens(); } // Применяем остальные патчи QStringList names; names << "fonts" << "sounds" << "texts" << "images" << "videos" << "textures"; QDir dir(QApplication::applicationDirPath() + "/data"); QStringList need; foreach(QString name, names){ QStringList list = dir.entryList(QStringList(name + "*")); if(list.size() > 0 && list.first() != ""){ QString isset = AConfig::getInstance()->getValue("Applied", name); if(list.first() != isset && AConfig::getInstance()->getValue("Editor", name) == "true") { need.append(name); } } } if(need.size() > 0){ openDatFile(0); foreach(QString name, need) { applyPatch(name); } } if(AConfig::getInstance()->getValue("Updates", "micro") == "true") installMicroPatch(); } int GameRes::checkDatFile() { openDatFile(0); if(datfiles_[0].CheckIfUpdatedByGame()) return 1; if(datfiles_[0].CheckIfNotPatched() && AConfig::getInstance()->getValue("Local", "runfirst") == "1") return 2; if(datfiles_[0].CheckIfPatchedByOldLauncher()) return 3; return 0; } QStringList GameRes::getLotroPath(){ QStringList paths; //#if defined(Q_WS_WIN) // Windows 7 QSettings m("HKEY_CLASSES_ROOT\\Local Settings\\Software\\Microsoft\\Windows\\Shell\\MuiCache", QSettings::NativeFormat); foreach (QString key, m.allKeys()) { if(key.contains("TurbineLauncher.exe") && FileSystem::fileExists(key)){ paths.append(key.replace("/TurbineLauncher.exe", "")); } } // Windows 8, 10 QSettings n("HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\12bbe590-c890-11d9-9669-0800200c9a66_is1", QSettings::NativeFormat); foreach (QString key, n.allKeys()) { qDebug() << key; if(key.contains("InstallLocation") || key.contains("installlocation")){ QString folder = n.value(key).toString().replace("\\", "/").replace("/TurbineLauncher.exe", "").replace("\"", ""); if(FileSystem::fileExists(folder + "/TurbineLauncher.exe")) paths.append(folder); } } //#else // Реализация под Linux //#endif return paths; } // Private functions void GameRes::processFile() { SubfileData subfile; subfile = db_.GetNextFile(); if (subfile.Empty()){ qInfo("%s:%i: %s", __FILE__, __LINE__, "Достигнут конец файла."); } else { int dat_id = subfile.options["did"].as(); int dat_state = datfiles_[dat_id].InitDatFile(getDatPath(dat_id), dat_id); if(dat_state > 0) datfiles_[dat_id].PatchFile(subfile); } } void GameRes::applyMicroPatch(QString filename) { emit startedPatching(" новые переводы"); db_.InitDatabase(filename.toStdString()); int indb = db_.CountRows(); qInfo("%s:%i: %s%d", __FILE__, __LINE__, "Файлов в обновлении: ", indb); int percent = -1; for(int i = 0; i < indb; i++) { if (i * 100 / indb > percent) { percent = i * 100 / indb; qInfo("%s:%i: %s%d%s", __FILE__, __LINE__, "Применение обновления: ", percent, "%"); emit updatedPatchPercent(percent); } processFile(); } db_.CloseDatabase(); QDir dir("/data/micro"); FileSystem::clearFolder(dir); //emit installMicroPatchFinished(0); } void GameRes::applyLoadscreens() { QString datafolder = QApplication::applicationDirPath() + "/data"; QDir dir(datafolder); if (!dir.exists()) return; QStringList paths = dir.entryList(QStringList("loadscreens*")); if(!paths.empty()){ if(paths.first() == AConfig::getInstance()->getValue("Applied", "screens")){ return; } QString lang = AConfig::getInstance()->getValue("Local", "lang"); QString folder = AConfig::getInstance()->getValue("Local", "folder") + "/raw/" + lang + "/logo/"; SubfileData subfile; QStringList filenames; QString mainscreen = (lang == "en" ? "lotro_ad_pregame.jpg" : "lotro_ad_pregame_" + lang + ".jpg"); 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 basename = datafolder + "/" + paths.first(); db_.InitDatabase(basename.toStdString()); int indb = db_.CountRows(); qInfo("%s:%i: %s%d", __FILE__, __LINE__, "Файлы загрузочных экранов: ", indb); for (int i = 0; i < indb; i++) { subfile = db_.GetNextFile(); qDebug() << i; if (!subfile.Empty()){ qInfo("%s:%i: %s", __FILE__, __LINE__, (folder + filenames[i]).toStdString().c_str()); QFile::remove(folder + filenames[i]); subfile.binary_data.WriteToFile((folder + filenames[i]).toStdString()); } } db_.CloseDatabase(); } qInfo("%s:%i: %s", __FILE__, __LINE__, "Выполнено."); } bool GameRes::isDatReady() { // Checks if file is ready to write data bool free = false; QString dir = AConfig::getInstance()->getValue("Local", "folder"); QString file = AConfig::getInstance()->getValue("Local", "file"); QFile fl(dir+"/" + file); qDebug() << fl.fileName(); if(FileSystem::fileExists(fl.fileName())){ QDir game_dir(dir); free = game_dir.rename(fl.fileName(), fl.fileName() + "99"); game_dir.rename(fl.fileName() + "99", fl.fileName()); } else { free = false; } if (free == true) qDebug() << "Dat is FREE"; else qDebug() << "Dat is BUSY"; return free; } std::string GameRes::getDatPath(int id){ QStringList dats; dats << AConfig::getInstance()->getValue("Local", "file") << "client_general.dat" << "client_sound.dat" << "client_surface.dat" << "client_highres.dat"; //std::string file = (app->config->getValue("Local", "folder") + "/" + dats.at(id)).toStdString(); return (AConfig::getInstance()->getValue("Local", "folder") + "/" + dats.at(id)).toStdString(); } int GameRes::dateToTimestamp(QString customDateString, QString format) { int timestamp = QDateTime::fromString(customDateString, format).toTime_t(); return timestamp; }