Browse Source

Ver 1.2.2 Release

Ivan Arkhipov 6 years ago
parent
commit
95f4910276
13 changed files with 231 additions and 192 deletions
  1. 14 16
      anetwork.cpp
  2. 10 9
      config.cpp
  3. 13 12
      downloadmanager.cpp
  4. 2 1
      downloadmanager.h
  5. 16 12
      helper.cpp
  6. 1 1
      helper.h
  7. 97 88
      lotromanager.cpp
  8. 2 2
      lotromanager.h
  9. 15 3
      main.cpp
  10. 43 38
      mainwindow.cpp
  11. 5 5
      mainwindow.h
  12. 9 3
      mainwindow.ui
  13. 4 2
      ui_mainwindow.h

+ 14 - 16
anetwork.cpp

@@ -17,8 +17,7 @@ ANetwork::ANetwork(QObject*) {
 }
 
 QString ANetwork::query(QUrl url){
-    App *app = &App::getInstance();
-    QNetworkAccessManager* manager = new QNetworkAccessManager(app->window);
+    QNetworkAccessManager* manager = new QNetworkAccessManager();
     QNetworkRequest request(url);
     QNetworkReply* reply = manager->get(request);
     QEventLoop loop;
@@ -34,8 +33,7 @@ QString ANetwork::query(QUrl url){
 }
 
 QByteArray ANetwork::query_binary(QUrl url){
-    App *app = &App::getInstance();
-    QNetworkAccessManager* manager = new QNetworkAccessManager(app->window);
+    QNetworkAccessManager* manager = new QNetworkAccessManager();
     QNetworkRequest request(url);
     QNetworkReply* reply = manager->get(request);
     QEventLoop loop;
@@ -51,7 +49,7 @@ QString ANetwork::getCoupon(){
     QString content = this->query(app->config->getValue("Network", "coupon") + ".txt");
     if (content != "error"){
         app->config->setValue("Values", "coupon", content);
-        qInfo("%s:%i: %s%s", __FILE__, __LINE__, "Ответ сервера: ", content.toLocal8Bit().data());
+        qInfo("%s:%i: %s%s", __FILE__, __LINE__, "Ответ сервера: ", content.toUtf8().data());
         qInfo("%s:%i: %s", __FILE__, __LINE__, "Данные получены. Производим установку значений.");
     } else {
         qWarning("%s:%i: %s", __FILE__, __LINE__, "Не удалось получить информацию с сервера");
@@ -71,7 +69,7 @@ QString ANetwork::getFootMessage(){
     if (content != "error"){
         qInfo("%s:%i: %s", __FILE__, __LINE__, "Данные получены");
         app->config->setValue("Values", "foot", content);
-        qInfo("%s:%i: %s%s", __FILE__, __LINE__, "Ответ сервера: ", content.toLocal8Bit().data());
+        qInfo("%s:%i: %s%s", __FILE__, __LINE__, "Ответ сервера: ", content.toUtf8().data());
     } else {
         qWarning("%s:%i: %s", __FILE__, __LINE__, "Не удалось получить информацию с сервера");
         content = app->config->getValue("Values", "foot");
@@ -102,7 +100,7 @@ QString ANetwork::getServers(){
     app->logSectionStart("Статусы серверов");
     QString content = this->query(app->config->getValue("Network", "servers") + ".txt");
     if (content != "error"){
-        qInfo("%s:%i: %s%s", __FILE__, __LINE__, "Ответ сервера: ", content.toLocal8Bit().data());
+        qInfo("%s:%i: %s%s", __FILE__, __LINE__, "Ответ сервера: ", content.toUtf8().data());
         qInfo("%s:%i: %s", __FILE__, __LINE__, "Данные получены. Производим установку значений.");
         app->config->setValue("Values", "servers", content);
         qDebug() << content;
@@ -158,8 +156,8 @@ QString ANetwork::getServers(){
 
 void ANetwork::UpdatePatches() {
     App *app = &App::getInstance();
-    if (app->state == "busy") {
-        qInfo("%s:%i: %s", __FILE__, __LINE__, "Проверка актуальности патчей запущена во время выполения операции. Прерываю проверку");
+    if (app->state != "free") {
+        qInfo("%s:%i: %s", __FILE__, __LINE__, "Проверка актуальности патчей запущена во время выполения другой операции. Прерываю проверку");
         return;
     }
 
@@ -188,7 +186,7 @@ void ANetwork::UpdatePatches() {
         }
 
         QStringList paths = dir.entryList(QStringList(s + "*"));
-        qDebug("%s:%i: %s%s", __FILE__, __LINE__, "Найденные патчи: ", QString(paths.join(' ')).toLocal8Bit().data());
+        qDebug("%s:%i: %s%s", __FILE__, __LINE__, "Найденные патчи: ", QString(paths.join(' ')).toUtf8().data());
 
 
         QString dateline = app->config->getValue("Datetime", s);
@@ -199,7 +197,7 @@ void ANetwork::UpdatePatches() {
         }
 
         if (paths.empty()) {
-            qDebug("%s:%i: %s%s", __FILE__, __LINE__, "Патч отсутствует: ", s.toLocal8Bit().data());
+            qDebug("%s:%i: %s%s", __FILE__, __LINE__, "Патч отсутствует: ", s.toUtf8().data());
             version = "100";
             emit changePatchStatus(s, "В очереди");
             query.addQueryItem(s.left(s.length() - 1), version);
@@ -210,9 +208,9 @@ void ANetwork::UpdatePatches() {
         QString hash = FileSystem::fileHash(datafolder + "/" + paths.first(), QCryptographicHash::Md5);
         if(hash != app->config->getValue("Hashes", s)) {
             qDebug("%s:%i: %s\n%s%s\n%s%s\n%s%s", __FILE__, __LINE__, "Неверный хэш файла! (удаляю файл)",
-                   "Файл: " , paths.first().toLocal8Bit().data(),
-                   "Высчитанный хэш: ", hash.toLocal8Bit().data(),
-                   "Хэш конфигурации: ", app->config->getValue("Hashes", s).toLocal8Bit().data()
+                   "Файл: " , paths.first().toUtf8().data(),
+                   "Высчитанный хэш: ", hash.toUtf8().data(),
+                   "Хэш конфигурации: ", app->config->getValue("Hashes", s).toUtf8().data()
                    );
 
             QFile base(datafolder + "/" + paths.first());
@@ -225,7 +223,7 @@ void ANetwork::UpdatePatches() {
     }
 
     url.setQuery(query.query());
-    qDebug("%s:%i: %s%s", __FILE__, __LINE__, "Запрашиваем информацию о патчах: ", url.fileName().toLocal8Bit().data());
+    qDebug("%s:%i: %s%s", __FILE__, __LINE__, "Запрашиваем информацию о патчах: ", url.fileName().toUtf8().data());
     qDebug() << "\nЗапрос на сервер: " << url;
     QString content = this->query(url);
     if(content == "error"){
@@ -305,7 +303,7 @@ QString ANetwork::getMicroPath(int timestamp){
     qInfo("%s:%i: %s", __FILE__, __LINE__, "Загрузка микропатча завершена.");
 
 
-    //LotroManager::getInstance().database_.InitDatabase(filename.toLocal8Bit().data());
+    //LotroManager::getInstance().database_.InitDatabase(filename.toUtf8().data());
     //int indb = LotroManager::getInstance().database_.CountRows();
     //qInfo("%s:%i: %s%i", __FILE__, __LINE__, "Патч содержит строк: ", indb);
     //for(int i = 0; i<=indb; i++) LotroManager::getInstance().processFile();

+ 10 - 9
config.cpp

@@ -48,6 +48,7 @@ void AConfig::saveConfig(){
 
     // Local
     settings.setValue("Local/file", "client_local_English.dat");
+    settings.setValue("Local/lang", "en");
 
     //Datetime
     settings.setValue("Datetime/texts", "-1");
@@ -118,7 +119,7 @@ void AConfig::loadSkin(){
     qInfo("%s:%i: %s", __FILE__, __LINE__, "Начинаем настройку элементов");
 
     foreach (QString item, items){
-        qInfo("%s:%i: %s%s", __FILE__, __LINE__, "Устанавливаем настройки для ", item.toLocal8Bit().data());
+        qInfo("%s:%i: %s%s", __FILE__, __LINE__, "Устанавливаем настройки для ", item.toUtf8().data());
         QWidget* obj = app->window->findChild<QWidget*>(item);
         if (obj != nullptr){
             obj->installEventFilter(app->window);
@@ -132,7 +133,7 @@ void AConfig::loadSkin(){
                 ));
             }
 
-            qInfo("%s:%i: %s%s", __FILE__, __LINE__, item.toLocal8Bit().data(), ": настройка геометрии завершена");
+            qInfo("%s:%i: %s%s", __FILE__, __LINE__, item.toUtf8().data(), ": настройка геометрии завершена");
 
             if(settings.value("shadow") != k){
                 QString color = settings.value("shcolor") != k ? settings.value("shcolor").toString() : "#222";
@@ -141,7 +142,7 @@ void AConfig::loadSkin(){
                 int offset_y = settings.value("shy") != k ? settings.value("shy").toInt() : 1;
                 app->helper->applyShadow(obj, color, blur, offset_x, offset_y);
             }
-            qInfo("%s:%i: %s%s", __FILE__, __LINE__, item.toLocal8Bit().data(), ":  настройка теней завершена");
+            qInfo("%s:%i: %s%s", __FILE__, __LINE__, item.toUtf8().data(), ":  настройка теней завершена");
 
             if(settings.value("text") != k){
                 QString text = settings.value("text").toString();
@@ -156,7 +157,7 @@ void AConfig::loadSkin(){
                    QLabel * l = dynamic_cast<QLabel* >(obj);
                    l->setText(settings.value("text").toString());
                 }
-                qInfo("%s:%i: %s%s", __FILE__, __LINE__, item.toLocal8Bit().data(), ": текст установлен");
+                qInfo("%s:%i: %s%s", __FILE__, __LINE__, item.toUtf8().data(), ": текст установлен");
             }
 
             if(settings.value("align") != k){
@@ -165,13 +166,13 @@ void AConfig::loadSkin(){
                 if(settings.value("align") == "center") lab->setAlignment(Qt::AlignCenter);
                 if(settings.value("align") == "right") lab->setAlignment(Qt::AlignRight);
             }
-            qInfo("%s:%i: %s%s", __FILE__, __LINE__, item.toLocal8Bit().data(), ": настройки позиционирования применены");
+            qInfo("%s:%i: %s%s", __FILE__, __LINE__, item.toUtf8().data(), ": настройки позиционирования применены");
 
             settings.endGroup();
         } else  {
             if(item == "mainWindow") {
                 settings.beginGroup(item);
-                qInfo("%s:%i: %s%s", __FILE__, __LINE__, item.toLocal8Bit().data(), ": обработка параметров главного окна");
+                qInfo("%s:%i: %s%s", __FILE__, __LINE__, item.toUtf8().data(), ": обработка параметров главного окна");
                 int w = settings.value("width").toInt();
                 int h = settings.value("height").toInt();
 
@@ -185,7 +186,7 @@ void AConfig::loadSkin(){
                 app->window->move(center);
                 settings.endGroup();
             }
-            qInfo("%s:%i: %s%s", __FILE__, __LINE__, item.toLocal8Bit().data(), ": закончен просчет геометрии");
+            qInfo("%s:%i: %s%s", __FILE__, __LINE__, item.toUtf8().data(), ": закончен просчет геометрии");
 
             if(item == "htmlColors") {
                 settings.beginGroup(item);
@@ -194,7 +195,7 @@ void AConfig::loadSkin(){
                 }
                 settings.endGroup();
             }
-            qInfo("%s:%i: %s%s", __FILE__, __LINE__, item.toLocal8Bit().data(), ": загружены HTML-цвета");
+            qInfo("%s:%i: %s%s", __FILE__, __LINE__, item.toUtf8().data(), ": загружены HTML-цвета");
         }
     }
     qInfo("%s:%i: %s", __FILE__, __LINE__, "Выполнено.");
@@ -267,6 +268,6 @@ const char * AConfig::getDatPath(int id){
     QStringList dats;
     dats << app->config->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 (app->config->getValue("Local", "folder") + "/" + dats.at(id)).toLocal8Bit().data();
+    return (app->config->getValue("Local", "folder") + "/" + dats.at(id)).toUtf8().data();
 }
 

+ 13 - 12
downloadmanager.cpp

@@ -19,21 +19,21 @@ DownloadManager::DownloadManager(QObject *parent)
 
 void DownloadManager::append(const QStringList &urlList){
     foreach (QString url, urlList)
-        append(QUrl::fromEncoded(url.toLocal8Bit()));
+        append(QUrl::fromEncoded(url.toUtf8()));
 
     if (downloadQueue.isEmpty())
         QTimer::singleShot(0, this, SIGNAL(finished()));
 }
 
 void DownloadManager::append(const QUrl &url){
-    qDebug("%s:%i: %s%s", __FILE__, __LINE__, "Добавлен файл для скачивания: ", url.fileName().toLocal8Bit().data());
+    qDebug("%s:%i: %s%s", __FILE__, __LINE__, "Добавлен файл для скачивания: ", url.fileName().toUtf8().data());
 
     if (downloadQueue.count(url) == 0) {
         downloadQueue.enqueue(url);
         ++totalCount;
     } else {
         qDebug("%s:%i: %s %s%s", __FILE__, __LINE__, "Не добавляю закачку "
-               , url.fileName().toLocal8Bit().data()
+               , url.fileName().toUtf8().data()
                , ", так как она уже находится в очереди закачек");
     }
     qDebug("%s:%i: %s%i", __FILE__, __LINE__, "Загрузок в списке: ", totalCount);
@@ -51,6 +51,7 @@ void DownloadManager::startNextDownload() {
     current_speed = "";
     bytesReceivedBeforeSecond = 0;
     timeElapsedBeforeSecond = 0;
+    elapsed_time = "высчитывается...";
 
     if (busy) {
         qWarning("%s:%i: %s", __FILE__, __LINE__, "Ошибка! Обнаружена попытка начала загрузки, когда не завершилась другая загрузка");
@@ -72,7 +73,7 @@ void DownloadManager::startNextDownload() {
     QUrl url = downloadQueue.dequeue();
     QString filename = QFileInfo(url.path()).fileName();
     output.setFileName(QApplication::applicationDirPath() + "/data/" + filename);
-    qDebug("%s:%i: %s%s", __FILE__, __LINE__, "Начата загрузка файла: ", filename.toLocal8Bit().data());
+    qDebug("%s:%i: %s%s", __FILE__, __LINE__, "Начата загрузка файла: ", filename.toUtf8().data());
 
     // Проверяем целостность файла и игнорируем в случае если он цел
     QString hash = FileSystem::fileHash(QApplication::applicationDirPath() + "/data/" + filename, QCryptographicHash::Md5);
@@ -82,13 +83,13 @@ void DownloadManager::startNextDownload() {
     QString keyname = ptype.first();
     if(keyname == "loadscreens") keyname = "screens";
     if(hash == app->config->getValue("Hashes", ptype.first()) && app->config->getValue("Editor", keyname) == "true"){
-        qDebug("%s:%i: %s%s", __FILE__, __LINE__, "Проверка хэша успешно завершена: ", filename.toLocal8Bit().data());
+        qDebug("%s:%i: %s%s", __FILE__, __LINE__, "Проверка хэша успешно завершена: ", filename.toUtf8().data());
         busy = false;
         QTimer::singleShot(0, this, SLOT(startNextDownload()));
         return;
     }
 
-    qDebug("%s:%i: %s%s", __FILE__, __LINE__, "Хэш файла не совпал: ", filename.toLocal8Bit().data());
+    qDebug("%s:%i: %s%s", __FILE__, __LINE__, "Хэш файла не совпал: ", filename.toUtf8().data());
     QStringList parsename = filename.split("_");
     QString name = parsename[0] + "Status";
     download_name = parsename[0];
@@ -103,14 +104,14 @@ void DownloadManager::startNextDownload() {
 
     if (!output.open(QIODevice::WriteOnly)) {
         qWarning("%s:%i: %s%s", __FILE__, __LINE__, "Произошла остановка скачивания (не могу открыть файл) "
-                 , filename.toLocal8Bit().data());
+                 , filename.toUtf8().data());
         emit changePatchStatus(download_name, "Ошибка записи");
         busy = false;
         QTimer::singleShot(0, this, SLOT(startNextDownload()));
         return;
     }
 
-    qInfo("%s:%i: %s%s", __FILE__, __LINE__, "Начинаем скачивание ", url.fileName().toLocal8Bit().data());
+    qInfo("%s:%i: %s%s", __FILE__, __LINE__, "Начинаем скачивание ", url.fileName().toUtf8().data());
 
     QNetworkRequest request(url);
     currentDownload = manager.get(request);
@@ -147,16 +148,16 @@ void DownloadManager::downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
         timeElapsedBeforeSecond = downloadTime.elapsed();
         bytesReceivedBeforeSecond = bytesReceived;
         current_speed = speedtext;
+        elapsed_time = app->helper->countFormattedElapsedTime(bytesTotal - bytesReceived, bytesReceived * 1000.0 / downloadTime.elapsed());
     }
 
     if (current_speed == "")
         current_speed = speedtext;
 
-    QString elapsed_time = app->helper->countFormattedElapsedTime(bytesTotal - bytesReceived, bytesReceived * 1000.0 / downloadTime.elapsed());
 
     emit changePatchStatus(download_name, "Загрузка ... <br/>" + percenttext + "% (" + current_speed + ")");
     emit changeHint("Загрузка патча " + LotroManager::getInstance().patchTitleFromName(download_name),
-                    "Завершено " + percenttext + "% (" + current_speed + "). Осталось примерно " + elapsed_time);
+                    "Завершено " + percenttext + "% (" + current_speed + "). Оставшееся время: " + elapsed_time);
 }
 
 void DownloadManager::downloadFinished() {
@@ -170,7 +171,7 @@ void DownloadManager::downloadFinished() {
     app->helper->setState("free");// говорим что приложение освободилось
 
     if (currentDownload->error()) {
-        qWarning("%s:%i: %s%s", __FILE__, __LINE__, "Загрузка не удалась: ", currentDownload->errorString().toLocal8Bit().data());
+        qWarning("%s:%i: %s%s", __FILE__, __LINE__, "Загрузка не удалась: ", currentDownload->errorString().toUtf8().data());
         emit changePatchStatus(download_name, "Не удалась");
     } else {
         emit changePatchStatus(download_name, "Готово");
@@ -196,7 +197,7 @@ void DownloadManager::abortDownload(QString name){
     if(download_name == name){
        if(app->state != "free" &&  currentDownload != NULL && currentDownload->isOpen()) {
             qDebug() << "Прерываем закачку " + download_name;
-            qInfo("%s:%i: %s%s", __FILE__, __LINE__, "Пользователь прервал закачку файла ", download_name.toLocal8Bit().data());
+            qInfo("%s:%i: %s%s", __FILE__, __LINE__, "Пользователь прервал закачку файла ", download_name.toUtf8().data());
             emit changePatchStatus(name, "Отменён");
             currentDownload->abort();
        }

+ 2 - 1
downloadmanager.h

@@ -44,9 +44,10 @@ private:
     QQueue<QUrl> downloadQueue;
     QNetworkReply *currentDownload;
     QFile output;
+
     QTime downloadTime;
     QString download_name;
-
+    QString elapsed_time;
     QStringList downloaded_list;
 
     int bytesReceivedBeforeSecond; // Нужны для подсчёта текущей скорости скачивания, а не

+ 16 - 12
helper.cpp

@@ -44,10 +44,10 @@ void Helper::loadNews(){
         return;
     }
     QStringList data = response.split(":::");
-    qInfo("%s:%i: %s%s", __FILE__, __LINE__, "Получено новостей - ", QString::number(data.count()).toLocal8Bit().data());
+    qInfo("%s:%i: %s%s", __FILE__, __LINE__, "Получено новостей - ", QString::number(data.count()).toUtf8().data());
     int counter = 1;
     foreach(QString news, data){
-        qInfo("%s:%i: %s%s", __FILE__, __LINE__, "Начинаем размещение новости №", QString::number(counter).toLocal8Bit().data());
+        qInfo("%s:%i: %s%s", __FILE__, __LINE__, "Начинаем размещение новости №", QString::number(counter).toUtf8().data());
         QStringList item = news.split("|");
         QLabel* image = app->window->ui->newsbox->findChild<QLabel*>("news" + QString::number(counter) + "Image");
         QLabel* title = app->window->ui->newsbox->findChild<QLabel*>("news" + QString::number(counter) + "Title");
@@ -69,7 +69,7 @@ void Helper::loadNews(){
         title->setText(html);
         teaser->setText(item[2]);
         counter = counter+1;
-        qInfo("%s:%i: %s %s %s", __FILE__, __LINE__, "Размещена новость:", html.toLocal8Bit().data(), QString(item[2]).toUtf8().data());
+        qInfo("%s:%i: %s %s %s", __FILE__, __LINE__, "Размещена новость:", html.toUtf8().data(), QString(item[2]).toUtf8().data());
     }
     qInfo("%s:%i: %s", __FILE__, __LINE__, "Выполнено.");
     app->logSectionEnd();
@@ -175,7 +175,7 @@ QString Helper::getSkinName() {
     App *app = &App::getInstance();
     QString skin = app->config->getValue("Global", "current_theme");
     if(skin == "-1") skin = app->config->getValue("Global", "default_theme");
-    qInfo("%s:%i: %s%s", __FILE__, __LINE__, "Текущая тема оформления: ", skin.toLocal8Bit().data());
+    qInfo("%s:%i: %s%s", __FILE__, __LINE__, "Текущая тема оформления: ", skin.toUtf8().data());
     return skin;
 }
 
@@ -189,17 +189,16 @@ void Helper::applyShadow(QWidget * obj, QString color, int blur, int offset_x, i
 }
 
 void Helper::myDialogBox(QString text, QString info, QString okText, QString cancelText, QString image, QString okAnswer, QString cancelAnswer,
-                        int w, int h, bool, bool is_cancel, bool prevent_dublicates){
-    if (last_message_msg == info && prevent_dublicates)
-        return;
-
-    last_message_msg = info;
+                        int w, int h, bool, bool is_cancel, bool stop_process) {
 
     App *app = &App::getInstance();
 
-    if(okAnswer == "") okAnswer = "close";
+    if (okAnswer == "")
+        okAnswer = "close";
     app->helper->dialog_ok_answer = okAnswer;
-    if(cancelAnswer == "") cancelAnswer = "close";
+
+    if (cancelAnswer == "")
+        cancelAnswer = "close";
     app->helper->dialog_cancel_answer = cancelAnswer;
 
     app->window->ui->okButton->setText(okText);
@@ -243,7 +242,6 @@ void Helper::myDialogBox(QString text, QString info, QString okText, QString can
      );
 
 
-
     if(is_cancel){
        app->window->ui->cancelButton->setGeometry(
            app->window->ui->dialog->rect().left() + app->window->ui->dialog->width() - app->window->ui->cancelButton->width() - 20,
@@ -267,6 +265,9 @@ void Helper::myDialogBox(QString text, QString info, QString okText, QString can
          );
     }
 
+    if (stop_process)
+        app->state = "dialog";
+
     app->window->ui->dialogHeader->setText(text);
     app->window->ui->dialogInfo->setText(info);
     app->window->ui->dialogImage->setText("");
@@ -275,6 +276,9 @@ void Helper::myDialogBox(QString text, QString info, QString okText, QString can
 
 void Helper::setState(QString state){
     App *app = &App::getInstance();
+    qInfo("%s:%i: %s%s%s%s", __FILE__, __LINE__, "Устанавливается состояние: ", state.toUtf8().data(),
+          ". Предыдущее состояние: ", app->state.toUtf8().data());
+
     if(state == "busy"){
         app->window->ui->closeButton->setEnabled(false);
         app->window->ui->enterButton->setEnabled(false);

+ 1 - 1
helper.h

@@ -29,7 +29,7 @@ class Helper:public QObject {
     void setState(QString state);
     void applyShadow(QWidget *obj, QString color, int blur, int offset_x, int offset_y);
     void myDialogBox(QString text, QString info, QString okText, QString cancelText, QString image,
-                   QString okAnswer, QString cancelAnswer, int w, int h, bool textshadow = false, bool is_cancel = false, bool prevent_dublicates = true);
+                   QString okAnswer, QString cancelAnswer, int w, int h, bool textshadow = false, bool is_cancel = false, bool stop_process = false);
     int dateToTimestamp(QString customDateString, QString format);
     void addComboItem(QComboBox* combo, QString itemName, QIcon* icon);
 

+ 97 - 88
lotromanager.cpp

@@ -7,8 +7,9 @@
 #include <QDate>
 #include <QTime>
 
-LotroManager::LotroManager(QObject *parent) : QObject(parent){
-    dat_files_.resize(5);
+LotroManager::LotroManager(QObject *parent) : QObject(parent),
+                                              dat_files_(std::vector<LOTRO_DAT::DatFile>(5)),
+                                              database_(LOTRO_DAT::Database()) {
     busy_ = false;
 
     connect(this, SIGNAL(dat_operation_started(QString)), this, SLOT(on_dat_operation_started(QString)));
@@ -16,25 +17,53 @@ LotroManager::LotroManager(QObject *parent) : QObject(parent){
 }
 
 bool LotroManager::execute(QString command, QString args, QString name) {
-    qInfo("%s:%i: %s%s", __FILE__, __LINE__, "Вызываем execute() команды ", command.toLocal8Bit().data());
+    qInfo("%s:%i: %s%s", __FILE__, __LINE__, "Вызываем execute() команды ", command.toUtf8().data());
 
     if (busy_) {
         qWarning("%s:%i: %s", __FILE__, __LINE__, "Ошибка! Уже выполняется другой процесс с данными!");
+        emit dat_operation_finished(command, args, name, "error");
         return false;
     }
 
     if (std::find(available_operations_.begin(), available_operations_.end(), command)
             == available_operations_.end()) {
 
-        qWarning("%s:%i: %s%s%s", __FILE__, __LINE__, "Ошибка! Операция ", command.toLocal8Bit().data(), " не найдена в списке доступных!");
+        qWarning("%s:%i: %s%s%s", __FILE__, __LINE__, "Ошибка! Операция ", command.toUtf8().data(), " не найдена в списке доступных!");
+        emit dat_operation_finished(command, args, name, "error");
+        return false;
+    }
+
+    App* app = &App::getInstance();
+    QString filename = app->config->getValue("Local", "folder") + "/" + app->config->getValue("Local", "file");
+    QString execpath = app->config->getValue("Local", "folder") + "/" + "TurbineLauncher.exe";
+
+    if (!FileSystem::fileExists(filename) && FileSystem::fileExists(execpath) && command != "StartGame") {
+        qWarning("%s:%i: %s\n", __FILE__, __LINE__, "Файл данных не найден, но папка верная");
+        QString text = "Не найден файл ресурсов";
+        QString msg = "Файла ресурсов " + filename + ", похоже, не существует. Запустить лаунчер игры для "
+                                                     "начала автоматического скачивания?<p>При запуске "
+                                                     "лаунчера игры проверьте, что язык, выбранный в лаунчере и язык, "
+                                                     "выбранный в Наследии, совпадают.<br>Язык в Наследии: <b>"
+                + app->config->getValue("Local", "lang") + "</b></p>";
+        app->helper->myDialogBox(text, msg, "OK", "Отмена", "gandalf.png", "loaddatfile", "", 420, 205, true, true, true);
+        emit dat_operation_finished(command, args, name, "error");
+        return false;
+    }
+
+    if (!FileSystem::fileExists(execpath)) {
+        QString text = "Не найдены файлы игры!";
+        QString msg = "Похоже, папка с игрой указана неверно. Укажите, пожалуйста, путь к папке с игрой. "
+                      "Опознать папку с игрой можно по наличию папок 3rdparty, backup, bindat, de, en, forward и т.п.";
+        app->helper->myDialogBox(text, msg, "OK", "Выход", "gandalf.png", "choosedatpath", "exit", 400, 170, true, true, true);
+        emit dat_operation_finished(command, args, name, "error");
         return false;
     }
 
     if (command == "StartGame") {
         QtConcurrent::run([=]() {
             emit dat_operation_started(command, args, name);
-            startGame();
-            emit dat_operation_finished(command, args, name);
+            bool result = startGame();
+            emit dat_operation_finished(command, args, name, result ? "" : "error");
         });
         return true;
     }
@@ -124,16 +153,16 @@ bool LotroManager::isBusy() {
 }
 
 void LotroManager::on_dat_operation_started(QString command, QString, QString name) {
-    qInfo("%s:%i: %s%s %s %s", __FILE__, __LINE__, "Получен сигнал начала операции ", command.toLocal8Bit().data()
-          , "с именем", name.toLocal8Bit().data());
+    qInfo("%s:%i: %s%s %s %s", __FILE__, __LINE__, "Получен сигнал начала операции ", command.toUtf8().data()
+          , "с именем", name.toUtf8().data());
     busy_ = true;
 }
 
 void LotroManager::on_dat_operation_finished(QString command, QString, QString name, QString result) {
     qInfo("%s:%i: %s%s %s %s %s %s", __FILE__, __LINE__
-          , "Получен сигнал завершения операции ", command.toLocal8Bit().data()
-          , "с именем", name.toLocal8Bit().data()
-          , "с результатом", result.toLocal8Bit().data());
+          , "Получен сигнал завершения операции ", command.toUtf8().data()
+          , "с именем", name.toUtf8().data()
+          , "с результатом", result.toUtf8().data());
     busy_ = false;
 }
 
@@ -142,7 +171,7 @@ void LotroManager::saveDatFiles() {
         dat_file.CloseDatFile();
 }
 
-void LotroManager::startGame(){
+bool LotroManager::startGame(){
     App *app = &App::getInstance();
 
     for (auto &dat_file : dat_files_)
@@ -172,13 +201,13 @@ void LotroManager::startGame(){
         if(f.fileName().contains(" ")) f.setFileName("\"" + f.fileName() + "\"");
         process.startDetached(f.fileName(), args);
         process.waitForFinished(-1);
-        process.deleteLater();
-        QApplication::quit();
+        return true;
     } else {
         QString text = "Запуск не удался";
         QString info = "Не удалось запустить игру. Не найден файл TurbineLauncher.exe или невозможно получить к нему доступ. "
                        "Проверьте в разделе 'Настройки', что у вас указан верный путь к игре, закрыт лаунчер игры и повторите попытку запуска.";
-        app->helper->myDialogBox(text, info, "OK", "Отмена", "gandalf.png", "", "", 400, 160, true, false);
+        app->helper->myDialogBox(text, info, "OK", "Отмена", "gandalf.png", "", "", 400, 160, true, true);
+        return false;
     }
 }
 
@@ -199,27 +228,8 @@ bool LotroManager::openDatFile(int id) {
         QString filename = app->config->getValue("Local", "folder") + "/" + dat_files_name_list[id];
         QString execpath = app->config->getValue("Local", "folder") + "/" + "TurbineLauncher.exe";
 
-        if (!FileSystem::fileExists(filename) && FileSystem::fileExists(execpath)) {
-            qWarning("%s:%i: %s\n", __FILE__, __LINE__, "Файл данных не найден, но папка верная");
-            QString text = "Не найден файл ресурсов";
-            QString msg = "Файла ресурсов " + filename + ", похоже, не существует. Запустить лаунчер игры для "
-                                                         "начала автоматического скачивания?";
-            app->helper->myDialogBox(text, msg, "OK", "Отмена", "gandalf.png", "loaddatfile", "", 400, 180, true, true);
-            app->helper->setState("free");
-            return false;
-        }
-
-        if (!FileSystem::fileExists(filename) && !FileSystem::fileExists(execpath)) {
-            QString text = "Не найдены файлы игры!";
-            QString msg = "Похоже, папка с игрой указана неверно. Укажите, пожалуйста, путь к папке с игрой. "
-                          "Опознать папку с игрой можно по наличию папок 3rdparty, backup, bindat, de, en, forward и т.п.";
-            app->helper->myDialogBox(text, msg, "OK", "Выход", "gandalf.png", "choosedatpath", "exit", 400, 170, true, true);
-            app->helper->setState("free");
-            return false;
-        }
-
-        qDebug("%s:%i: %s%s", __FILE__, __LINE__, "Инициализация dat-файла. Открываем файл ", filename.toLocal8Bit().toStdString().c_str());
-        int dat_state = dat_files_[id].InitDatFile(filename.toLocal8Bit().toStdString(), id);
+        qDebug("%s:%i: %s%s", __FILE__, __LINE__, "Инициализация dat-файла. Открываем файл ", filename.toUtf8().toStdString().c_str());
+        int dat_state = dat_files_[id].InitDatFile(filename.toUtf8().toStdString(), id);
         qDebug("%s:%i: %s%d", __FILE__, __LINE__, "Состояние dat-файла: ", dat_state);
 
         if(dat_state > 0) {
@@ -228,7 +238,6 @@ bool LotroManager::openDatFile(int id) {
             QString text = "Нет доступа к  файлам игры";
             QString info = "Возможно в данный момент запущены клиент или лаунчер игры либо попытка доступа блокируется настройкой прав, антивирусом или другими приложениями. Завершите все процессы, использующие файлы игры и повторите попытку.";
             app->helper->myDialogBox(text, info, "OK", "Отмена", "gandalf.png", "", "", 400, 200, true, false);
-            app->helper->setState("free");
             return false;
         }
     }
@@ -236,6 +245,9 @@ bool LotroManager::openDatFile(int id) {
 }
 
 void LotroManager::applyPatch(QString name) {
+    if (!correctPatchName(name))
+        return;
+
     if (name == "loadscreens") {
         applyLoadscreens();
         return;
@@ -248,7 +260,7 @@ void LotroManager::applyPatch(QString name) {
     App *app = &App::getInstance();
     emit changeHint("Применение патчей", "Ожидайте. Идёт применение выбранных патчей");
 
-    qDebug("%s:%i: %s%s", __FILE__, __LINE__, "Начинаем применение патча ", name.toLocal8Bit().data());
+    qDebug("%s:%i: %s%s", __FILE__, __LINE__, "Начинаем применение патча ", name.toUtf8().data());
 
     QDir dir(QApplication::applicationDirPath() + "/data");
     if (!dir.exists()) {
@@ -257,7 +269,7 @@ void LotroManager::applyPatch(QString name) {
     }
 
     QStringList paths = dir.entryList(QStringList(name + "*"));
-    qInfo("%s:%i: %s%s%s%s", __FILE__, __LINE__, "Для патча ", name.toLocal8Bit().data(), " найдены пути:", QString(paths.join(',')).toLocal8Bit().data());
+    qInfo("%s:%i: %s%s%s%s", __FILE__, __LINE__, "Для патча ", name.toUtf8().data(), " найдены пути:", QString(paths.join(',')).toUtf8().data());
 
     if (paths.empty()) {
         emit changePatchStatus(name, "Не найден");
@@ -265,10 +277,10 @@ void LotroManager::applyPatch(QString name) {
         return;
     }
 
-    qDebug() << QString("data/" + paths.first()).toLocal8Bit().data();
-    qInfo("%s:%i: %s%s", __FILE__, __LINE__, "Инициализируем базу данных: ", QString("data/" + paths.first()).toLocal8Bit().data());
+    qDebug() << QString("data/" + paths.first()).toUtf8().data();
+    qInfo("%s:%i: %s%s", __FILE__, __LINE__, "Инициализируем базу данных: ", QString("data/" + paths.first()).toUtf8().data());
 
-    if (!database_.InitDatabase(QString("data/" + paths.first()).toLocal8Bit().data())) {
+    if (!database_.InitDatabase(QString("data/" + paths.first()).toUtf8().data())) {
         emit changePatchStatus(name, "Ошибка патча!");
         emit changeHint("Применение патча завершено", "Патч " + patchTitleFromName(name) + " НЕ установлен (ошибка чтения патча)");
         return;
@@ -284,16 +296,12 @@ void LotroManager::applyPatch(QString name) {
     for(int i = 0; i < indb; i++) {
         qint64 current_timestamp = QDateTime::currentDateTime().toMSecsSinceEpoch();
 
-        QString elapsed_time;
         if (current_timestamp - start_time < 1000)
             elapsed_time = " высчитывается...";
-        else
-            elapsed_time = app->helper->countFormattedElapsedTime(indb - i, double(i * 1000.0) / double(current_timestamp - start_time));
-
-        if (current_timestamp - last_second_time >= 1000) {
+        else if (current_timestamp - last_second_time >= 1000) {
             last_second_time = current_timestamp;
-            current_elapsed_time = elapsed_time;
             last_second_files_count = i;
+            elapsed_time = app->helper->countFormattedElapsedTime(indb - i, double(i * 1000.0) / double(current_timestamp - start_time));
         }
 
         processFile();
@@ -302,7 +310,7 @@ void LotroManager::applyPatch(QString name) {
                                      + QString("%"));
         emit changeHint("Применение патча " + patchTitleFromName(name)
                         , "Завершено " + QString::fromLatin1("%1").arg(i*100.0/indb, 3, 'f', 1)
-                        + "% Осталось примерно " + current_elapsed_time);
+                        + "% Оставшееся время: " + elapsed_time);
 
     }
 
@@ -357,7 +365,7 @@ void LotroManager::applyMicroPatch(){
     app->window->ui->hintLabel->setText("Установка последних обновлений");
     app->window->ui->exthintLabel->setText("Подождите пока закончится применение обновлений");
 
-    database_.InitDatabase(app->network->micropatch.toLocal8Bit().data());
+    database_.InitDatabase(app->network->micropatch.toUtf8().data());
     int indb = database_.CountRows();
     qInfo("%s:%i: %s%d", __FILE__, __LINE__, "Файлов в обновлении: ", indb);
 
@@ -377,58 +385,59 @@ void LotroManager::applyMicroPatch(){
 void LotroManager::applyLoadscreens(){
     App *app = &App::getInstance();
     app->logSectionStart("Установка заставочных экранов");
-    app->helper->setState("busy");
 
     QString datafolder = QApplication::applicationDirPath() + "/data";
     QDir dir(datafolder);
-    if (!dir.exists())
+    if (!dir.exists()) {
+        emit changePatchStatus("loadscreens", "Не найден!");
         return;
+    }
     QStringList paths = dir.entryList(QStringList("loadscreens*"));
 
-    if(!paths.empty()){
+    if(paths.empty()){
+        emit changePatchStatus("loadscreens", "Не найден!");
+        return;
+    }
 
-        if(paths.first() == app->config->getValue("Applied", "screens")){
-            app->helper->setState("free");
-            return;
-        }
+    if (paths.first() == app->config->getValue("Applied", "screens")){
+        return;
+    }
 
-        QString lang = app->config->getValue("Local", "lang");
+    QString lang = app->config->getValue("Local", "lang");
 
-        if (lang == "-1") {
-            app->config->setValue("Local", "lang", "en");
-            lang = "en";
-        }
+    if (lang == "-1") {
+        app->config->setValue("Local", "lang", "en");
+        lang = "en";
+    }
 
-        QString folder = app->config->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();
-        database_.InitDatabase(basename.toStdString());
-        int indb = database_.CountRows();
-        qInfo("%s:%i: %s%d", __FILE__, __LINE__, "Файлы загрузочных экранов: ", indb);
-        for(int i = 0; i<indb; i++){
-            subfile = database_.GetNextFile();
-            qDebug() << i;
-            if (!subfile.Empty()){
-                qInfo("%s:%i: %s", __FILE__, __LINE__, (folder + filenames[i]).toLocal8Bit().data());
-                QFile::remove(folder + filenames[i]);
-                subfile.binary_data.WriteToFile((folder + filenames[i]).toStdString());
-            }
+    QString folder = app->config->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();
+    database_.InitDatabase(basename.toStdString());
+    int indb = database_.CountRows();
+    qInfo("%s:%i: %s%d", __FILE__, __LINE__, "Файлы загрузочных экранов: ", indb);
+    for(int i = 0; i<indb; i++){
+        subfile = database_.GetNextFile();
+        qDebug() << i;
+        if (!subfile.Empty()){
+            qInfo("%s:%i: %s", __FILE__, __LINE__, (folder + filenames[i]).toUtf8().data());
+            QFile::remove(folder + filenames[i]);
+            subfile.binary_data.WriteToFile((folder + filenames[i]).toStdString());
         }
-        database_.CloseDatabase();
-
     }
-    app->helper->setState("free");
-    app->window->ui->loadscreensStatus->setText("Готово");
+    database_.CloseDatabase();
     app->config->setValue("Applied", "screens", paths.first());
+    emit changePatchStatus("loadscreens", "Готово");
     qInfo("%s:%i: %s", __FILE__, __LINE__, "Выполнено.");
     app->logSectionEnd();
+
 }
 
 void LotroManager::processFile(){
@@ -491,7 +500,7 @@ void LotroManager::prepareMicroPatch(){
     qInfo("%s:%i: %s", __FILE__, __LINE__, "Опция активна. Начинаем загрузку обновлений");
     app->network->micropatch = QApplication::applicationDirPath() + "/data/micro/" + QString::number(timestamp) + ".db";
     if(!FileSystem::fileExists(app->network->micropatch)){
-        qInfo("%s:%i: %s%s", __FILE__, __LINE__, "Файл патча: ", app->network->micropatch.toLocal8Bit().data());
+        qInfo("%s:%i: %s%s", __FILE__, __LINE__, "Файл патча: ", app->network->micropatch.toUtf8().data());
         app->network->micropatch = app->network->getMicroPath(timestamp);
     }
     app->window->ui->hintLabel->setText("Загрузка завершена");

+ 2 - 2
lotromanager.h

@@ -29,7 +29,7 @@ public:
 
 private:
 
-    void startGame();
+    bool startGame();
 
     bool openDatFile(int id);
 
@@ -67,7 +67,7 @@ private:
     qint64 last_second_files_count;
     qint64 last_second_time;
     qint64 start_time;
-    QString current_elapsed_time;
+    QString elapsed_time;
 
     LOTRO_DAT::LOCALE dat_locale_;
     std::vector<LOTRO_DAT::DatFile> dat_files_;

+ 15 - 3
main.cpp

@@ -16,7 +16,7 @@
 
 void myMessageOutput(QtMsgType type, const QMessageLogContext &, const QString &msg)
 {
-    QByteArray localMsg = msg.toLocal8Bit().data();
+    QByteArray localMsg = msg.toUtf8().data();
     const char * format = "[" + QDate::currentDate().toString(Qt::ISODate).toUtf8() + " " + QTime::currentTime().toString(Qt::ISODate).toUtf8() + "]";
     switch (type) {
     case QtDebugMsg:
@@ -37,7 +37,10 @@ void myMessageOutput(QtMsgType type, const QMessageLogContext &, const QString &
     }
 }
 
-int main(int argc, char *argv[]){
+//#define DEBUG
+//#define DEBUG_EXPIRE 1523304000 // 2018-09-03 23:00:00
+
+int main(int argc, char *argv[]) {
     freopen("log.txt", "w", stdout);
     freopen("log.txt", "a", stderr);
 
@@ -45,10 +48,19 @@ int main(int argc, char *argv[]){
         QApplication a(argc, argv);
         QMessageBox msgBox;
         msgBox.setIcon(QMessageBox::Warning);
+
+#ifdef DEBUG
+        msgBox.setText("ЭТО ТЕСТОВАЯ ВЕРСИЯ ЛАУНЧЕРА! НЕ ДЛЯ РАСПРОСТРАНЕНИЯ!");
+        msgBox.exec();
+        long long cur_time = time(0);
+        if (cur_time >= DEBUG_EXPIRE)
+            return 0;
+#else
         msgBox.setText("Запуск Наследия невозможен без лаунчера. Используйте лаунчер Наследия для запуска приложения!");
         msgBox.exec();
         a.exit(0);
-        return 0;
+        return 0;  
+#endif
     }
 
     setbuf(stdout, NULL);

+ 43 - 38
mainwindow.cpp

@@ -72,51 +72,51 @@ MainWindow::MainWindow( double scale_factor, QMainWindow* parent) :
     connect(app->window->ui->skinSelect, SIGNAL(currentIndexChanged(int)), this, SLOT(saveSkin()));
 
     connect(std::addressof(LotroManager::getInstance()),
-            SIGNAL(dat_operation_finished(QString, QString, QString, QString)),
+            &LotroManager::dat_operation_finished,
             this,
-            SLOT(on_lotro_manager_finished(QString, QString, QString, QString)));
+            &MainWindow::lotro_manager_finished);
 
     connect(std::addressof(LotroManager::getInstance()),
-            SIGNAL(dat_operation_started(QString, QString, QString)),
+            &LotroManager::dat_operation_started,
             this,
-            SLOT(on_lotro_manager_started(QString, QString, QString)));
+            &MainWindow::lotro_manager_started);
 
 
     connect(std::addressof(LotroManager::getInstance()),
-            SIGNAL(changePatchStatus(QString, QString)),
+            &LotroManager::changePatchStatus,
             this,
-            SLOT(on_change_patch_status(QString, QString)));
+            &MainWindow::change_patch_status);
 
     connect(std::addressof(LotroManager::getInstance()),
-            SIGNAL(changeHint(QString, QString)),
+            &LotroManager::changeHint,
             this,
-            SLOT(on_change_hint(QString, QString)));
+            &MainWindow::change_hint);
 
     connect(app->network,
-            SIGNAL(changePatchStatus(QString, QString)),
+            &ANetwork::changePatchStatus,
             this,
-            SLOT(on_change_patch_status(QString, QString)));
+            &MainWindow::change_patch_status);
 
     connect(app->network,
-            SIGNAL(changeHint(QString,QString)),
+            &ANetwork::changeHint,
             this,
-            SLOT(on_change_hint(QString,QString)));
+            &MainWindow::change_hint);
 
 
     connect(app->downloader,
-            SIGNAL(changePatchStatus(QString, QString)),
+            &DownloadManager::changePatchStatus,
             this,
-            SLOT(on_change_patch_status(QString, QString)));
+            &MainWindow::change_patch_status);
 
     connect(app->downloader,
-            SIGNAL(changeHint(QString,QString)),
+            &DownloadManager::changeHint,
             this,
-            SLOT(on_change_hint(QString,QString)));
+            &MainWindow::change_hint);
 
     connect(app->downloader,
-            SIGNAL(allDownloadsFinished(QStringList)),
+            &DownloadManager::allDownloadsFinished,
             this,
-            SLOT(on_patches_updated(QStringList)));
+            &MainWindow::patches_updated);
 
     app->helper->loadNews();
     app->network->getFootMessage();
@@ -129,13 +129,15 @@ MainWindow::MainWindow( double scale_factor, QMainWindow* parent) :
     LotroManager::getInstance().execute("CheckDatFile", "", "init_check_dat");
 }
 
-void MainWindow::on_lotro_manager_started(QString command, QString args, QString name) {
+void MainWindow::lotro_manager_started(QString command, QString args, QString name) {
     App* app = &App::getInstance();
     app->helper->setState("busy");
 }
 
-void MainWindow::on_lotro_manager_finished(QString command, QString args, QString name, QString result) {
+void MainWindow::lotro_manager_finished(QString command, QString args, QString name, QString result) {
     App* app = &App::getInstance();
+    if (app->state == "busy")
+        app->helper->setState("free");
 
     if (name == "init_check_dat") {
         PostDatFileCheckTransactions(result.toInt());
@@ -161,29 +163,27 @@ void MainWindow::on_lotro_manager_finished(QString command, QString args, QStrin
         return;
     }
 
-    if (name == "start_game") {
+    if (name == "start_game" && result != "error") {
         QApplication::exit();
         return;
     }
-
-    app->helper->setState("free");
 }
 
-void MainWindow::on_patches_updated(QStringList patches) {
+void MainWindow::patches_updated(QStringList patches) {
     App* app = &App::getInstance();
     if (app->downloader->getDownloadedCount() == 0)
         return;
     LotroManager::getInstance().execute("ApplyPatchList", QString(patches.join('|')), "");
 }
 
-void MainWindow::on_change_patch_status(QString patch_name, QString new_status) {
+void MainWindow::change_patch_status(QString patch_name, QString new_status) {
     QLabel* obj = ui->mainbox->findChild<QLabel*>(patch_name + "Status");
     if (obj != nullptr){
         obj->setText(new_status);
     }
 }
 
-void MainWindow::on_change_hint(QString title, QString hint) {
+void MainWindow::change_hint(QString title, QString hint) {
     ui->hintLabel->setText(title);
     ui->exthintLabel->setText(hint);
 }
@@ -219,9 +219,8 @@ void MainWindow::PostDatFileCheckTransactions(int check_result) {
     if(app->config->getValue("Local", "runfirst") == "-1") {
         qInfo("%s:%i: %s", __FILE__, __LINE__, "Показываем мастер начальных настроек.");
         app->helper->setState("runfirst");
-    } else {
-        app->helper->setState("free");
     }
+
     qInfo("%s:%i: %s", __FILE__, __LINE__, "Выполнено.");
     app->logSectionEnd();
 
@@ -242,7 +241,7 @@ MainWindow::~MainWindow()
 
 void MainWindow::closeEvent(QCloseEvent *e){
     App *app = &App::getInstance();
-    if(app->state == "busy") e->ignore();
+    if(app->state != "free") e->ignore();
 }
 
 void MainWindow::mouseMoveEvent( QMouseEvent* e ) {
@@ -332,7 +331,7 @@ void MainWindow::on_mainButton_clicked(){
     app->helper->checkTab("mainbox");
     app->window->ui->titleLabel->setText("Патчи");
 
-    if (app->state != "busy") {
+    if (app->state == "free") {
         QtConcurrent::run(app->network, &app->network->UpdatePatches);
     }
 }
@@ -550,15 +549,18 @@ void MainWindow::on_designButton_clicked(){
 void MainWindow::on_repairButton_clicked(){
    App *app = &App::getInstance();
    app->config->deleteSection("Applied");
-   LotroManager::getInstance().execute("ApplyGlobal", "", "");
    app->helper->checkTab("mainbox");
+   LotroManager::getInstance().execute("ApplyGlobal", "", "");
 }
 
 void MainWindow::on_okButton_clicked(){
     App *app = &App::getInstance();
     QStringList commands = app->helper->dialog_ok_answer.split(" ");
-    foreach(QString command, commands){
-        if(command == "close"){
+    foreach(QString command, commands) {
+        if (app->state == "dialog")
+            app->helper->setState("free");
+
+        if (command == "close"){
             this->ui->dialogbox->hide();
         }
 
@@ -594,12 +596,14 @@ void MainWindow::on_okButton_clicked(){
 
         if(command == "choosedatpath") {
             app->helper->checkTab("optbox");
+            app->state = "free";
             emit app->window->ui->lotropathButton->clicked(true);
         }
 
         if(command == "writefolder"){
-            if(app->window->ui->dialogList->currentItem()){
-                QString path = app->window->ui->dialogList->currentItem()->text();qDebug() << path;
+            if (app->window->ui->dialogList->currentItem()) {
+                QString path = app->window->ui->dialogList->currentItem()->text();
+                qDebug() << path;
                 app->window->ui->lotropathLabel->setText(path);
                 app->config->setValue("Local", "folder", path);
                 app->window->ui->dialogList->clear();
@@ -608,15 +612,14 @@ void MainWindow::on_okButton_clicked(){
                 QString text = "Завершающий этап";
                 QString info = "Необходимые приготовления завершены. Сейчас вы будете перенаправлены в раздел «Настройки», где сможете выбрать патчи, которые хотите установить. После этого перейдите в раздел «Патчи» для начала их загрузки и применения.";
                 app->helper->myDialogBox(text, info, "OK", "Отмена", "gandalf.png", "close gotooptions", "",400, 200, true, false);
-
             } else {
                 break;
             }
-
         }
 
         if(command == "gotooptions"){
             app->helper->checkTab("optbox");
+            app->state = "free";
             app->config->setValue("Local", "runfirst", "1");
         }
 
@@ -640,8 +643,10 @@ void MainWindow::on_cancelButton_clicked(){
     App *app = &App::getInstance();
     QStringList commands = app->helper->dialog_cancel_answer.split(" ");
     foreach(QString command, commands){
-        if(command == "close")
+        if(command == "close") {
             this->ui->dialogbox->hide();
+            app->helper->setState("free");
+        }
         if (command == "exit")
             QApplication::exit(0);
     }

+ 5 - 5
mainwindow.h

@@ -28,13 +28,13 @@ signals:
     void datFileChecked(int result);
 
 private slots:
-    void on_lotro_manager_finished(QString command, QString args, QString name, QString result = "");
-    void on_lotro_manager_started(QString command, QString args, QString name);
+    void lotro_manager_finished(QString command, QString args, QString name, QString result);
+    void lotro_manager_started(QString command, QString args, QString name);
 
-    void on_patches_updated(QStringList patches);
+    void patches_updated(QStringList patches);
 
-    void on_change_patch_status(QString patch_name, QString new_status);
-    void on_change_hint(QString title, QString hint);
+    void change_patch_status(QString patch_name, QString new_status);
+    void change_hint(QString title, QString hint);
 
 private:
     void PostDatFileCheckTransactions(int check_result);

+ 9 - 3
mainwindow.ui

@@ -6,8 +6,8 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>526</width>
-    <height>306</height>
+    <width>613</width>
+    <height>528</height>
    </rect>
   </property>
   <property name="windowTitle">
@@ -976,6 +976,9 @@
      <property name="text">
       <string>Новость загружается...</string>
      </property>
+     <property name="openExternalLinks">
+      <bool>true</bool>
+     </property>
     </widget>
     <widget class="QLabel" name="news4Teaser">
      <property name="geometry">
@@ -1002,6 +1005,9 @@
      <property name="text">
       <string>Новость загружается...</string>
      </property>
+     <property name="openExternalLinks">
+      <bool>true</bool>
+     </property>
     </widget>
    </widget>
    <widget class="QGroupBox" name="helpbox">
@@ -1755,7 +1761,7 @@
      </rect>
     </property>
     <property name="text">
-     <string>Наследие: v1.1.0</string>
+     <string>Наследие: v1.2.2</string>
     </property>
    </widget>
    <widget class="QPushButton" name="designButton">

+ 4 - 2
ui_mainwindow.h

@@ -151,7 +151,7 @@ public:
     {
         if (MainWindow->objectName().isEmpty())
             MainWindow->setObjectName(QStringLiteral("MainWindow"));
-        MainWindow->resize(526, 306);
+        MainWindow->resize(613, 528);
         MainWindow->setWindowOpacity(1);
         MainWindow->setStyleSheet(QStringLiteral(""));
         centralWidget = new QWidget(MainWindow);
@@ -387,12 +387,14 @@ public:
         news3Title->setObjectName(QStringLiteral("news3Title"));
         news3Title->setGeometry(QRect(70, 110, 371, 21));
         news3Title->setCursor(QCursor(Qt::PointingHandCursor));
+        news3Title->setOpenExternalLinks(true);
         news4Teaser = new QLabel(newsbox);
         news4Teaser->setObjectName(QStringLiteral("news4Teaser"));
         news4Teaser->setGeometry(QRect(70, 180, 351, 16));
         news4Title = new QLabel(newsbox);
         news4Title->setObjectName(QStringLiteral("news4Title"));
         news4Title->setGeometry(QRect(70, 160, 371, 21));
+        news4Title->setOpenExternalLinks(true);
         helpbox = new QGroupBox(centralWidget);
         helpbox->setObjectName(QStringLiteral("helpbox"));
         helpbox->setGeometry(QRect(430, 240, 431, 221));
@@ -738,7 +740,7 @@ public:
         goTitle->setText(QApplication::translate("MainWindow", "\320\222\320\276 \321\207\321\202\320\276 \320\261\321\203\320\264\320\265\320\274 \320\270\320\263\321\200\320\260\321\202\321\214 \321\201\320\265\320\263\320\276\320\264\320\275\321\217?", Q_NULLPTR));
         goHeader->setText(QApplication::translate("MainWindow", "\320\227\320\260\320\277\321\203\321\201\320\272 \320\270\320\263\321\200\321\213", Q_NULLPTR));
         goHint->setText(QApplication::translate("MainWindow", "\320\237\320\276\320\264\320\263\320\276\321\202\320\276\320\262\320\272\320\260 \321\204\320\260\320\271\320\273\320\276\320\262 \320\273\320\276\320\272\320\260\320\273\320\270\320\267\320\260\321\206\320\270\320\270 ...", Q_NULLPTR));
-        labelVersion->setText(QApplication::translate("MainWindow", "\320\235\320\260\321\201\320\273\320\265\320\264\320\270\320\265: v1.1.0", Q_NULLPTR));
+        labelVersion->setText(QApplication::translate("MainWindow", "\320\235\320\260\321\201\320\273\320\265\320\264\320\270\320\265: v1.2.2", Q_NULLPTR));
         designButton->setText(QApplication::translate("MainWindow", "\320\236\320\261\320\275\320\276\320\262\320\270\321\202\321\214", Q_NULLPTR));
         mainTitle->setText(QApplication::translate("MainWindow", "\320\222\320\273\320\260\321\201\321\202\320\265\320\273\320\270\320\275 \320\272\320\276\320\273\320\265\321\206 \320\236\320\275\320\273\320\260\320\271\320\275: \320\235\320\260\321\201\320\273\320\265\320\264\320\270\320\265", Q_NULLPTR));
     } // retranslateUi