utils.cpp 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. /*
  2. * This file contains minor utility functions
  3. */
  4. #include <QNetworkAccessManager>
  5. #include <QNetworkReply>
  6. #include <QEventLoop>
  7. #include <QFile>
  8. #include <QTimer>
  9. #include <QLockFile>
  10. #include <QDir>
  11. #include <QMessageBox>
  12. #include <QProcess>
  13. #include <QApplication>
  14. #include <LotroDat/datfile.h>
  15. #include "models/settings.h"
  16. #include "utils.h"
  17. bool checkInternetConnection(QUrl url) {
  18. QNetworkAccessManager nam;
  19. QNetworkRequest req(url);
  20. QNetworkReply* reply = nam.get(req);
  21. QEventLoop loop;
  22. QObject::connect(qApp, &QApplication::aboutToQuit, &loop, &QEventLoop::quit);
  23. QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
  24. QTimer request_timeout_timer;
  25. QObject::connect(&request_timeout_timer, &QTimer::timeout, &loop, &QEventLoop::quit);
  26. request_timeout_timer.start(2000); // 2 seconds connection timeout
  27. loop.exec();
  28. return reply->bytesAvailable();
  29. }
  30. void logMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
  31. {
  32. QString message_type;
  33. switch (type) {
  34. case QtDebugMsg:
  35. message_type = "[DEBG]";
  36. break;
  37. case QtInfoMsg:
  38. message_type = "[INFO]";
  39. break;
  40. case QtWarningMsg:
  41. message_type = "[WARN]";
  42. break;
  43. case QtCriticalMsg:
  44. message_type = "[CRIT]";
  45. break;
  46. case QtFatalMsg:
  47. message_type = "[FATL]";
  48. break;
  49. default:
  50. message_type = "[UNKN]";
  51. break;
  52. }
  53. QString filename = context.category;
  54. QString function = context.function;
  55. QString line_number = QString::number(context.line);
  56. QString s = QString("%1: %2 ||| %3:%4 %5\n")
  57. .arg(message_type)
  58. .arg(msg)
  59. .arg(filename)
  60. .arg(line_number)
  61. .arg(function);
  62. #ifndef QT_DEBUG
  63. if (type != QtDebugMsg) {
  64. QFile log_file("legacy_log.txt");
  65. QFileInfo log_file_info(log_file);
  66. if (log_file_info.size() >= 10 * 1024 * 1024) {
  67. QFile::remove("legacy_log.old.txt");
  68. QFile::copy("legacy_log.txt", "legacy_log.old.txt");
  69. QFile::remove("legacy_log.txt");
  70. }
  71. log_file.open(QIODevice::ReadWrite | QIODevice::Append);
  72. QTextStream stream(&log_file);
  73. stream << s;
  74. log_file.close();
  75. }
  76. #endif
  77. #if defined(QT_DEBUG) || defined(DEBUG)
  78. fprintf(stderr, "%s", qUtf8Printable(s));
  79. fflush(stderr);
  80. #endif
  81. }
  82. bool isRunning(const QString &process) {
  83. QProcess tasklist;
  84. tasklist.start(
  85. "tasklist",
  86. QStringList() << "/NH"
  87. << "/FO" << "CSV"
  88. << "/FI" << QString("IMAGENAME eq %1").arg(process));
  89. tasklist.waitForFinished();
  90. QString output = tasklist.readAllStandardOutput();
  91. return output.startsWith(QString("\"%1").arg(process));
  92. }
  93. AppErrorStatus validateFile(QString name, QString path){
  94. QFileInfo check_file(path);
  95. if(!check_file.exists() || !check_file.isFile()){
  96. qCritical() << "Failed CheckAppPrerequisities: file " + name + " do not exist!";
  97. return E_DAT_FILES_MISSING;
  98. }
  99. if (!QFile::setPermissions(path,QFileDevice::ReadUser |QFileDevice::WriteUser |QFileDevice::ExeUser)){
  100. qCritical() << "Failed CheckAppPrerequisities: incorrect " + name + " permissions!";
  101. return E_WRONG_FILE_PERMISSIONS;
  102. }
  103. if (LOTRO_DAT::DatFile::checkIfPatchedByLegacyV1(check_file.absoluteFilePath().toStdString())){
  104. qCritical() << "Failed CheckAppPrerequisities: found Legacy v1 patch mark in " + name + "!";
  105. return E_PATCHED_BY_OLD_LEGACY;
  106. }
  107. return E_NO_ERRORS;
  108. }
  109. AppErrorStatus CheckAppPrerequesities(){
  110. qInfo() << "Starting CheckAppPrerequisities...";
  111. if(isRunning("LotroLauncher.exe") || isRunning("lotroclient.exe") || isRunning("lotroclient64.exe")){
  112. qCritical() << "Failed CheckAppPrerequisites: found running LOTRO client!";
  113. return E_LOTRO_RUNNING;
  114. }
  115. QString game_folder_path = Settings::getValue("Lotro/game_path").toString();
  116. QString locale_prefix = Settings::getValue("Lotro/original_locale").toString();
  117. qInfo() << "CheckAppPrerequisities: game folder path=" << game_folder_path;
  118. qInfo() << "CheckAppPrerequisities: locale prefix =" << locale_prefix;
  119. // Checking LotroLauncher.exe availability
  120. QFileInfo lotro_launcher_exe(game_folder_path + "/LotroLauncher.exe");
  121. if(!lotro_launcher_exe.exists()){
  122. qCritical() << "Failed CheckAppPrerequisities: cannot find file LotroLauncher.exe";
  123. return E_WRONG_GAME_FOLDER;
  124. } else {
  125. if (!QFile::setPermissions(lotro_launcher_exe.absoluteFilePath(),
  126. QFileDevice::ReadUser | QFileDevice::WriteUser | QFileDevice::ExeUser)) {
  127. qCritical() << "Failed CheckAppPrerequisities: cannot check executable permissions for LotroLauncher.exe";
  128. return E_WRONG_FILE_PERMISSIONS;
  129. }
  130. }
  131. // Checking DAT files availability & correctness
  132. AppErrorStatus result = validateFile("client_local", game_folder_path + "/client_local_" + locale_prefix + ".dat");
  133. if(result != E_NO_ERRORS) return result;
  134. result = validateFile("client_general", game_folder_path + "/client_general.dat");
  135. if(result != E_NO_ERRORS) return result;
  136. result = validateFile("client_surface", game_folder_path + "/client_surface.dat");
  137. if(result != E_NO_ERRORS) return result;
  138. // Проверка интернет-соединения
  139. if (!checkInternetConnection(QUrl(Settings::getValue("Network/patch_updates_url").toString()))){
  140. qCritical() << "Failed CheckAppPrerequisities: no server connection!";
  141. return E_NO_SERVER_CONNECTION;
  142. }
  143. qInfo() << "CheckAppPrerequisities: successful, no errors found!";
  144. return E_NO_ERRORS;
  145. }
  146. QDebug operator<<(QDebug dbg, const AppErrorStatus &status)
  147. {
  148. bool patched_by_old_legacy = (status == E_PATCHED_BY_OLD_LEGACY);
  149. bool wrong_game_folder = (status == E_WRONG_GAME_FOLDER);
  150. bool dat_files_missing = (status == E_DAT_FILES_MISSING);
  151. bool wrong_file_permissions = (status == E_WRONG_FILE_PERMISSIONS);
  152. bool dat_file_incorrect = (status == E_DAT_FILE_INCORRECT);
  153. bool no_server_connection = (status == E_NO_SERVER_CONNECTION);
  154. dbg.nospace() << "ErrorStatus: "
  155. << (wrong_game_folder ? "Wrong game folder! " : "")
  156. << (dat_files_missing ? "Dat files missing! " : "")
  157. << (wrong_file_permissions ? "Wrong file permissions! " : "")
  158. << (dat_file_incorrect ? "Incorrect dat file! " : "")
  159. << (no_server_connection ? "No server connection! " : "")
  160. << (patched_by_old_legacy ? "Patched by legacy v1! ": "")
  161. << ";";
  162. return dbg;
  163. }