/* * This file contains minor utility functions */ #include #include #include #include #include #include #include #include #include #include #include #include "models/settings.h" #include "utils.h" bool checkInternetConnection(QUrl url) { QNetworkAccessManager nam; QNetworkRequest req(url); QNetworkReply* reply = nam.get(req); QEventLoop loop; QObject::connect(qApp, &QApplication::aboutToQuit, &loop, &QEventLoop::quit); QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit); QTimer request_timeout_timer; QObject::connect(&request_timeout_timer, &QTimer::timeout, &loop, &QEventLoop::quit); request_timeout_timer.start(2000); // 2 seconds connection timeout loop.exec(); return reply->bytesAvailable(); } void logMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg) { QString message_type; switch (type) { case QtDebugMsg: message_type = "[DEBG]"; break; case QtInfoMsg: message_type = "[INFO]"; break; case QtWarningMsg: message_type = "[WARN]"; break; case QtCriticalMsg: message_type = "[CRIT]"; break; case QtFatalMsg: message_type = "[FATL]"; break; default: message_type = "[UNKN]"; break; } QString filename = context.category; QString function = context.function; QString line_number = QString::number(context.line); QString s = QString("%1: %2 ||| %3:%4 %5\n") .arg(message_type) .arg(msg) .arg(filename) .arg(line_number) .arg(function); #ifndef QT_DEBUG if (type != QtDebugMsg) { QFile log_file("legacy_log.txt"); QFileInfo log_file_info(log_file); if (log_file_info.size() >= 10 * 1024 * 1024) { QFile::remove("legacy_log.old.txt"); QFile::copy("legacy_log.txt", "legacy_log.old.txt"); QFile::remove("legacy_log.txt"); } log_file.open(QIODevice::ReadWrite | QIODevice::Append); QTextStream stream(&log_file); stream << s; log_file.close(); } #endif #if defined(QT_DEBUG) || defined(DEBUG) fprintf(stderr, "%s", qUtf8Printable(s)); fflush(stderr); #endif } bool isRunning(const QString &process) { QProcess tasklist; tasklist.start( "tasklist", QStringList() << "/NH" << "/FO" << "CSV" << "/FI" << QString("IMAGENAME eq %1").arg(process)); tasklist.waitForFinished(); QString output = tasklist.readAllStandardOutput(); return output.startsWith(QString("\"%1").arg(process)); } AppErrorStatus validateFile(QString name, QString path){ QFileInfo check_file(path); if(!check_file.exists() || !check_file.isFile()){ qCritical() << "Failed CheckAppPrerequisities: file " + name + " do not exist!"; return E_DAT_FILES_MISSING; } if (!QFile::setPermissions(path,QFileDevice::ReadUser |QFileDevice::WriteUser |QFileDevice::ExeUser)){ qCritical() << "Failed CheckAppPrerequisities: incorrect " + name + " permissions!"; return E_WRONG_FILE_PERMISSIONS; } if (LOTRO_DAT::DatFile::checkIfPatchedByLegacyV1(check_file.absoluteFilePath().toStdString())){ qCritical() << "Failed CheckAppPrerequisities: found Legacy v1 patch mark in " + name + "!"; return E_PATCHED_BY_OLD_LEGACY; } return E_NO_ERRORS; } AppErrorStatus CheckAppPrerequesities(){ qInfo() << "Starting CheckAppPrerequisities..."; if(isRunning("LotroLauncher.exe") || isRunning("lotroclient.exe") || isRunning("lotroclient64.exe")){ qCritical() << "Failed CheckAppPrerequisites: found running LOTRO client!"; return E_LOTRO_RUNNING; } QString game_folder_path = Settings::getValue("Lotro/game_path").toString(); QString locale_prefix = Settings::getValue("Lotro/original_locale").toString(); qInfo() << "CheckAppPrerequisities: game folder path=" << game_folder_path; qInfo() << "CheckAppPrerequisities: locale prefix =" << locale_prefix; // Checking LotroLauncher.exe availability QFileInfo lotro_launcher_exe(game_folder_path + "/LotroLauncher.exe"); if(!lotro_launcher_exe.exists()){ qCritical() << "Failed CheckAppPrerequisities: cannot find file LotroLauncher.exe"; return E_WRONG_GAME_FOLDER; } else { if (!QFile::setPermissions(lotro_launcher_exe.absoluteFilePath(), QFileDevice::ReadUser | QFileDevice::WriteUser | QFileDevice::ExeUser)) { qCritical() << "Failed CheckAppPrerequisities: cannot check executable permissions for LotroLauncher.exe"; return E_WRONG_FILE_PERMISSIONS; } } // Checking DAT files availability & correctness AppErrorStatus result = validateFile("client_local", game_folder_path + "/client_local_" + locale_prefix + ".dat"); if(result != E_NO_ERRORS) return result; result = validateFile("client_general", game_folder_path + "/client_general.dat"); if(result != E_NO_ERRORS) return result; result = validateFile("client_surface", game_folder_path + "/client_surface.dat"); if(result != E_NO_ERRORS) return result; // Проверка интернет-соединения if (!checkInternetConnection(QUrl(Settings::getValue("Network/patch_updates_url").toString()))){ qCritical() << "Failed CheckAppPrerequisities: no server connection!"; return E_NO_SERVER_CONNECTION; } qInfo() << "CheckAppPrerequisities: successful, no errors found!"; return E_NO_ERRORS; } QDebug operator<<(QDebug dbg, const AppErrorStatus &status) { bool patched_by_old_legacy = (status == E_PATCHED_BY_OLD_LEGACY); bool wrong_game_folder = (status == E_WRONG_GAME_FOLDER); bool dat_files_missing = (status == E_DAT_FILES_MISSING); bool wrong_file_permissions = (status == E_WRONG_FILE_PERMISSIONS); bool dat_file_incorrect = (status == E_DAT_FILE_INCORRECT); bool no_server_connection = (status == E_NO_SERVER_CONNECTION); dbg.nospace() << "ErrorStatus: " << (wrong_game_folder ? "Wrong game folder! " : "") << (dat_files_missing ? "Dat files missing! " : "") << (wrong_file_permissions ? "Wrong file permissions! " : "") << (dat_file_incorrect ? "Incorrect dat file! " : "") << (no_server_connection ? "No server connection! " : "") << (patched_by_old_legacy ? "Patched by legacy v1! ": "") << ";"; return dbg; }