Browse Source

Moved all lotro operations from Helper to LotroManager class

Ivan Arkhipov 6 years ago
parent
commit
1ac6a87ce5
14 changed files with 514 additions and 490 deletions
  1. 3 0
      Legacy.pro
  2. 3 16
      app.h
  3. 0 8
      config.cpp
  4. 0 1
      config.h
  5. 2 0
      filesystem.cpp
  6. 6 398
      helper.cpp
  7. 5 10
      helper.h
  8. 413 4
      lotromanager.cpp
  9. 19 8
      lotromanager.h
  10. 36 18
      mainwindow.cpp
  11. 8 8
      mainwindow.ui
  12. 7 7
      network.cpp
  13. 5 5
      res/styles/lotro/skin.ini
  14. 7 7
      ui_mainwindow.h

+ 3 - 0
Legacy.pro

@@ -55,6 +55,9 @@ RESOURCES += \
     res.qrc \
     res.qrc
 
+CONFIG += c++14
+
+
 win32:RC_ICONS = $$PWD/res/appicon.ico
 
 unix:!macx|win32: LIBS += -L$$PWD/lib/lib/ -lLotroDat_static

+ 3 - 16
app.h

@@ -38,22 +38,17 @@ class App {
 
 public:
     App() {
-        instance = nullptr;
         config = new AConfig();
         network = new ANetwork();
         helper = new Helper();
         downloader = new DownloadManager();
         writtenLabel = new QLabel();
-        //datfile  = new DatFile();
-        db  = new Database();
         buildSeparators(9472, 65507, 45, 60, 48, 85);//9472 создаем разделители
     }
 
     static App& getInstance() {
-        if (instance == nullptr) {
-            instance = new App();
-        }
-        return *instance;
+        static App instance;
+        return instance;
     }
 
     AConfig * config;
@@ -63,12 +58,10 @@ public:
     DownloadManager * downloader;
     QLabel * writtenLabel;
     QString state;
-    //DatFile * datfile;
-    Database * db;
+
     QString app_folder = "";
     QString qsep, qsepn, tsep, tsepn, bsep, bsepn;
     QString stylehtml;
-    DatFile datfiles[5];
     bool ready = true;
 
     void log(QString msg){
@@ -102,11 +95,5 @@ public:
         for(int i = 0; i < qsize; i++){ qsep.append(QChar(QChar(qcode))); }
         qsepn = qsep + "\n";
     }
-
-
-
-private:
-    static App * instance;
-
 };
 #endif // APP_H

+ 0 - 8
config.cpp

@@ -262,14 +262,6 @@ QStringList AConfig::getLotroPath(){
     return paths;
 }
 
-void AConfig::saveAllDatFiles(){
-    App *app = &App::getInstance();
-    for(int i = 0; i < 5; i++){
-        //app->datfiles[i].CommitChanges();
-        app->datfiles[i].CloseDatFile();
-    }
-}
-
 const char * AConfig::getDatPath(int id){
     App *app = &App::getInstance();
     QStringList dats;

+ 0 - 1
config.h

@@ -25,7 +25,6 @@ class AConfig {
     void deleteSection(QString section);
     QStringList getLotroPath();
     const char *getDatPath(int id);
-    void saveAllDatFiles();
 
     QString conffile;
 };

+ 2 - 0
filesystem.cpp

@@ -6,6 +6,8 @@ bool FileSystem::fileExists(QString path) {
     bool exists = check_file.exists() && check_file.isFile();
     if (exists == false)
         qWarning("%s:%i: %s%s", __FILE__, __LINE__, "Файл не найден: ", path.toStdString().c_str());
+    else
+        qInfo("%s:%i: %s%s", __FILE__, __LINE__, "Файл найден: ", path.toStdString().c_str());
     return exists;
 }
 

+ 6 - 398
helper.cpp

@@ -6,7 +6,6 @@ Helper::Helper()
 
 }
 
-
 int Helper::getVersion(QString string) {
     std::string str(string.toLatin1().data());
     int version = 0;
@@ -179,8 +178,6 @@ QString Helper::getSkinName() {
     return skin;
 }
 
-
-
 void Helper::applyShadow(QWidget * obj, QString color, int blur, int offset_x, int offset_y){
     QGraphicsDropShadowEffect *pLabelTextShadowEffect = new QGraphicsDropShadowEffect(obj);
     pLabelTextShadowEffect->setColor(QColor(color));
@@ -191,7 +188,11 @@ 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){
+                        int w, int h, bool, bool is_cancel, bool prevent_dublicates){
+    if (last_message_msg == info && prevent_dublicates)
+        return;
+
+    last_message_msg = info;
 
     App *app = &App::getInstance();
 
@@ -312,374 +313,13 @@ int Helper::dateToTimestamp(QString customDateString, QString format){
     return timestamp;
 }
 
-void Helper::installMicroPatch(){
-    App *app = &App::getInstance();
-    if(app->config->getValue("Updates", "micro") != "true") return;
-
-    app->helper->setState("busy");
-    app->window->ui->hintLabel->setText("Установка последних обновлений");
-    app->window->ui->exthintLabel->setText("Идет проверка и установка новых обновлений");
-    QFuture<void> future = QtConcurrent::run([=]() {
-        app->helper->prepareMicroPatch();
-        app->helper->applyMicroPatch();
-        QDir dir("/data/micro");
-        FileSystem::clearFolder(dir);
-    });
-    app->window->ui->hintLabel->setText("Установка завершена");
-    app->window->ui->exthintLabel->setText("Обновления успешно установлены");
-    app->helper->setState("free");
-
-}
-
-void Helper::prepareMicroPatch(){
-    App *app = &App::getInstance();
-    app->logSectionStart("Автоматическая проверка обновлений");
-    app->helper->setState("busy");
-    app->window->ui->hintLabel->setText("Загрузка последних обновлений");
-    app->window->ui->exthintLabel->setText("Подождите пока загрузятся последние изменения в системе переводов");
-
-    QString date = app->config->getValue("Updates", "update");
-    if (date == QDate::currentDate().toString("yyyy-MM-dd"))
-        return;
-
-    if (date == "false" || date == "-1")
-        date = QDate::currentDate().toString("yyyy-MM-dd");
-
-    //QTime time = QTime::currentTime();
-    //int seconds = QTime(0, 0, 0).secsTo(time);
-    //int timestamp = app->helper->dateToTimestamp(date + " " + time.toString("hh:mm:ss"), "yyyy-MM-dd hh:mm:ss") - seconds - 1209600;
-    int timestamp = app->helper->dateToTimestamp(date, "yyyy-MM-dd") - 1209600;
-
-    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->helper->stringToChar(app->network->micropatch));
-        app->network->micropatch = app->network->getMicroPath(timestamp);
-    }
-    app->window->ui->hintLabel->setText("Загрузка завершена");
-    app->window->ui->exthintLabel->setText("Все обновления были успешно загружены и доступны к установке");
-
-    app->helper->setState("free");
-    qInfo("%s:%i: %s", __FILE__, __LINE__, "Выполнено.");
-    app->logSectionEnd();
-}
-
-void Helper::applyMicroPatch(){
-    App *app = &App::getInstance();
-    app->logSectionStart("Установка мгновенных обновлений");
-    app->helper->setState("busy");
-    app->window->ui->hintLabel->setText("Установка последних обновлений");
-    app->window->ui->exthintLabel->setText("Подождите пока закончится применение обновлений");
-
-    app->db->InitDatabase(app->helper->stringToChar(app->network->micropatch));
-    int indb = app->db->CountRows();
-    qInfo("%s:%i: %s%d", __FILE__, __LINE__, "Файлов в обновлении: ", indb);
-    for(int i = 0; i<=indb; i++){ processFile(); }
-    //for (int i = 0; i < 5; i++) app->datfiles[i].CommitChanges();
-    app->db->CloseDatabase();
-
-    app->config->setValue("Updates", "update", QDate::currentDate().toString("yyyy-MM-dd"));
-
-    app->helper->setState("free");
-    qInfo("%s:%i: %s", __FILE__, __LINE__, "Выполнено.");
-    app->logSectionEnd();
-}
-
-void Helper::applyLoadscreens(){
-    App *app = &App::getInstance();
-    app->logSectionStart("Установка заставочных экранов");
-    app->helper->setState("busy");
-
-    QString datafolder = QApplication::applicationDirPath() + "/data";
-    QDir dir(datafolder);
-    if (!dir.exists())
-        return;
-    QStringList paths = dir.entryList(QStringList("loadscreens*"));
-
-    if(!paths.empty()){
-
-        if(paths.first() == app->config->getValue("Applied", "screens")){
-            app->helper->setState("free");
-            return;
-        }
-
-        QString lang = app->config->getValue("Local", "lang");
-
-        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();
-        app->db->InitDatabase(basename.toStdString());
-        int indb = app->db->CountRows();
-        qInfo("%s:%i: %s%d", __FILE__, __LINE__, "Файлы загрузочных экранов: ", indb);
-        for(int i = 0; i<indb; i++){
-            subfile = app->db->GetNextFile();
-            qDebug() << i;
-            if (!subfile.Empty()){
-                qInfo("%s:%i: %s", __FILE__, __LINE__, app->helper->stringToChar(folder + filenames[i]));
-                QFile::remove(folder + filenames[i]);
-                subfile.binary_data.WriteToFile((folder + filenames[i]).toStdString());
-            }
-        }
-        app->db->CloseDatabase();
-
-    }
-    app->helper->setState("free");
-    app->window->ui->loadscreensStatus->setText("Готово");
-    app->config->setValue("Applied", "screens", paths.first());
-    qInfo("%s:%i: %s", __FILE__, __LINE__, "Выполнено.");
-    app->logSectionEnd();
-}
-
 void Helper::addComboItem(QComboBox* combo, QString itemName, QIcon* icon){
     combo->insertItem(0, itemName);
     combo->setItemIcon(0, *icon);
 }
 
-void Helper::saveLocale(int locale, QPushButton * button){
-    App *app = &App::getInstance();
-    QString file;
-
-    if(locale == 0) file = "client_local_English.dat";
-    if(locale == 1) file = "client_local_DE.dat";
-    if(locale == 2) file = "client_local_FR.dat";
-    if(FileSystem::fileExists(app->config->getValue("Local", "folder") + "/" + file)){
-        app->window->ui->enButton->setEnabled(true);
-        app->window->ui->deButton->setEnabled(true);
-        app->window->ui->frButton->setEnabled(true);
-        button->setEnabled(false);
-        app->config->setValue("Local", "file", file);
-    } else {
-        QString text = "Данная локализация отсутствует";
-        QString info = "В настоящий момент вы не можете выбрать данную опцию, поскольку файл " + file + " отсутствует в вашем игровом клиенте. Чтобы скачать его, запустите официальный лаунчер, выберите желаемый язык в верхней правой части окна и дождитесь, когда загрузка необходимых файлов завершится.";
-        app->helper->myDialogBox(text, info, "OK", "Отмена", "gandalf.png", "", "", 400, 220, true, false);
-    }
-}
-
-bool Helper::setGameLocale(QString locale){
-    App *app = &App::getInstance();
-    app->window->ui->goHint->show();
-    app->helper->setState("busy");
-    app->window->ui->goLocal->setEnabled(false);
-    app->window->ui->goOriginal->setEnabled(false);
-    app->window->ui->goCancel->setEnabled(false);
-
-    if(app->helper->openDatFile(0)){
-        LOCALE loc = app->datfiles[0].current_locale();
-        dat_locale = loc;
-
-        if(loc == PATCHED) qDebug() << "Starting " + locale + " version. Current locale is PATCHED";
-        if(loc == ORIGINAL) qDebug() << "Starting " + locale + " version. Current locale is ORIGINAL";
-        if(loc != ORIGINAL && loc != PATCHED) qDebug() << "Starting " + locale + " version. Current locale is UNKNOWN";
-
-        if(locale == "RU" && loc != PATCHED){ qDebug()<< "Current locale Original"; app->datfiles[0].SetLocale(PATCHED); dat_locale = PATCHED;}
-        if(locale == "Original" && loc != ORIGINAL){ qDebug()<< "Current locale RU"; app->datfiles[0].SetLocale(ORIGINAL); dat_locale = ORIGINAL;}
-        app->helper->closeDatFile(0);
-    }
-
-    app->window->ui->goHint->hide();
-    app->window->ui->goProgress->hide();
-    app->window->ui->startbox->hide();
-    app->window->ui->goLocal->setEnabled(true);
-    app->window->ui->goOriginal->setEnabled(true);
-    app->window->ui->goCancel->setEnabled(true);
-    app->helper->setState("free");
-    qDebug() << "Locale changed";
-
-    return true;
-}
-
-void Helper::startGame(){
-    App *app = &App::getInstance();
-    app->config->saveAllDatFiles();
-    QStringList args;
-    args << "-skiprawdownload" << "-nosplash";
-    if (dat_locale == PATCHED)
-        args << "-disablePatch";
-
-    QFile f(app->config->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();
-    } else {
-        QString text = "Запуск не удался";
-        QString info = "Не удалось запустить игру. Во время запуска произшла непредвиденная ошибка (возможно, не найден файл TurbineLauncher.exe в папке с игрой. Проверьте в 'Настройках', что у вас указан верный путь к игре, и повторите попытку запуска).";
-        app->helper->myDialogBox(text, info, "OK", "Отмена", "gandalf.png", "", "", 400, 160, true, false);
-    }
-}
-
-bool Helper::openDatFile(int id){
-    App *app = &App::getInstance();
-    QStringList dat_files;
-    dat_files << app->config->getValue("Local", "file") << "client_general.dat" << "client_sound.dat" << "client_surface.dat" << "client_highres.dat";
-    if(dat_files[id] != nullptr) {
-        qDebug() << dat_files[id];
-        const char * filename = app->helper->stringToChar(app->config->getValue("Local", "folder") + "/" + dat_files[id]);
-        std::string file = app->config->getDatPath(0);
-        qDebug("%s:%i: %s%s", __FILE__, __LINE__, "Инициализация dat-файла. Открываем файл ", filename);
-        int dat_state = app->datfiles[id].InitDatFile(file, 0);
-        qDebug("%s:%i: %s%d", __FILE__, __LINE__, "Состояние dat-файла: ", dat_state);
-        if(dat_state > 0){
-            app->helper->setState("busy");
-            return true;
-        } else {
-            QString text = "Нет доступа к  файлам игры";
-            QString info = "Возможно в данный момент запущены клиент или лаунчер игры либо попытка доступа блокируется настройкой прав, антивирусом или другими приложениями. Завершите все процессы, использующие файлы игры и повторите попытку.";
-            app->helper->myDialogBox(text, info, "OK", "Отмена", "gandalf.png", "", "", 550, 200, true, false);
-            app->helper->setState("free");
-            return false;
-        }
-    }
-    return true;
-}
-
-void Helper::closeDatFile(int id){
-    App *app = &App::getInstance();
-    //app->datfiles[id].CommitChanges();
-    app->datfiles[id].CloseDatFile();
-    app->helper->setState("free");
-}
-
 const char * Helper::stringToChar(QString val){
-    ba = val.toLocal8Bit();
-    const char * result = ba.data();
-    return result;
-}
-
-void Helper::applyPatch(QString name){
-    App *app = &App::getInstance();
-    app->window->ui->hintLabel->setText("Установка патчей");
-    app->window->ui->exthintLabel->setText("Ожидайте. Идет установка выбранных патчей");
-    qDebug("%s:%i: %s%s", __FILE__, __LINE__, "Начинаем применение патча ", app->helper->stringToChar(name));
-    QLabel* label = app->window->findChild<QLabel*>(name + "Status");
-    QDir dir(QApplication::applicationDirPath() + "/data");
-    if (!dir.exists()) {
-        app->window->ui->hintLabel->setText("Установка патчей завершена с ошибкой");
-        app->window->ui->exthintLabel->setText("Ошибка - не найдена папка data");
-        return;
-    }
-
-    QStringList paths = dir.entryList(QStringList(name + "*"));
-    qDebug() << app->helper->stringToChar("data/" + paths.first());
-    if(!paths.empty()){         
-       app->db->InitDatabase(app->helper->stringToChar("data/" + paths.first()));
-        int indb = app->db->CountRows();
-        qInfo("%s:%i: %s%d", __FILE__, __LINE__, "Файлов в обновлении: ", indb);
-        for(int i = 0; i<=indb; i++){
-            processFile();
-            if (label != nullptr)
-                label->setText(QString("Применение ... ") + QString::fromLatin1("%1").arg(i*100.0/indb, 3, 'f', 1) + QString("%"));
-        }
-        if(label != nullptr)label->setText("Готово");
-        //for (int i = 0; i < 5; i++) app->datfiles[i].CommitChanges();
-        app->config->setValue("Applied", name, paths.first());
-        app->db->CloseDatabase();
-    }
-    app->window->ui->hintLabel->setText("Установка патчей завершена");
-    app->window->ui->exthintLabel->setText("Применение выбранных вами патчей закончено");
-}
-
-void Helper::processFile(){
-    App *app = &App::getInstance();
-    SubfileData subfile;
-    subfile = app->db->GetNextFile();
-    if (subfile.Empty()){
-        qInfo("%s:%i: %s", __FILE__, __LINE__, "Достигнут конец файла.");
-    } else {
-        int dat_id = subfile.options["did"].as<int>();
-        int dat_state = app->datfiles[dat_id].InitDatFile(app->config->getDatPath(dat_id), dat_id);
-        //qDebug("%s:%i: %s%d", __FILE__, __LINE__, "Состояние dat-файла: ", dat_state);
-        if(dat_state > 0) app->datfiles[dat_id].PatchFile(subfile);
-    }
-}
-
-void Helper::applyGlobal(){
-    App *app = &App::getInstance();
-
-    // Применяем патч с заставочными экранами
-    if(app->config->getValue("Editor", "screens") == "true"){
-        app->helper->applyLoadscreens();
-    } else {
-        QString dateline = app->config->getValue("Datetime", "loadscreens");
-        if(dateline != "-1"){
-            QStringList date = dateline.split(" ");
-            app->window->ui->loadscreensStatus->setText(date[0]);
-        }
-    }
-
-    // Применяем остальные патчи
-    QStringList names;
-    QStringList need;
-    QFuture<void> f;
-    f = QtConcurrent::run([=]() {});
-    names  << "fonts" << "sounds" << "texts" << "images" << "videos" << "textures";
-    QDir dir(QApplication::applicationDirPath() + "/data");
-
-    foreach(QString name, names) {
-
-        QStringList list = dir.entryList(QStringList(name + "*"));
-
-        if (list.size() > 0 && list.first() != ""){
-            QString isset = app->config->getValue("Applied", name);
-            if (list.first() != isset && app->config->getValue("Editor", name) == "true") {
-                need.append(name);
-            }
-        }
-    }
-
-    Helper *helper = new Helper();
-    QFutureWatcher<void> * watcher = new QFutureWatcher<void>();
-    connect(watcher, SIGNAL(finished()), helper, SLOT(handleFinisheddd()));
-
-    if(need.size() > 0){
-        watcher->setFuture(QtConcurrent::run([=]() {
-            if(app->helper->openDatFile(0)){
-                foreach(QString name, need){ app->helper->applyPatch(name);}
-                app->helper->closeDatFile(0);
-            }
-        }));
-    } else {
-        app->helper->installMicroPatch();
-    }
-
-}
-
-void Helper::handleFinisheddd(){
-   App *app = &App::getInstance();
-   app->helper->installMicroPatch();
-}
-
-bool Helper::isDatReady(){
-    App *app = &App::getInstance();
-    bool free;
-    QString dir = app->config->getValue("Local", "folder");
-    QString file = app->config->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;
+    return val.toLocal8Bit().toStdString().c_str();
 }
 
 void Helper::replaceSkin(QString name){
@@ -727,35 +367,3 @@ void Helper::replaceSkin(QString name){
     movie->setScaledSize(QSize(app->window->ui->loader->width(), app->window->ui->loader->height()));
     movie->start();
 }
-
-int Helper::checkDatFile(){
-    //bool CheckIfUpdatedByGame(); // Обновлялся ли игрой
-    //bool CheckIfNotPatched(); // Был ли хоть раз пропатчен новым лаунчером
-    //bool CheckIfPatchedByOldLauncher(); // Был ли хоть раз пропатчен старым лаунчером
-
-    App *app = &App::getInstance();
-    app->helper->openDatFile(0);
-    if(app->datfiles[0].CheckIfUpdatedByGame()){
-        return 1;
-        //app->ready = false;
-        //QString text = "Файлы локализации изменены";
-        //QString info = "В процессе последнего запуска игры были установлены обновления игрового клиента. Это могло затронуть файлы локализации. Желаете провести проверку и исправить поврежденные участки перевода? Вы можете в любой момент сделать это самостоятельно, нажав кнопку «Применить патчи заново».";
-        //app->helper->myDialogBox(text, info, "OK", "Отмена", "gandalf.png", "applypaths", "", 400, 220, true, true);
-    }
-
-    if(app->datfiles[0].CheckIfNotPatched() && app->config->getValue("Local", "runfirst") == "1"){
-        return 2;
-        //app->ready = false;
-        //QString text = "Файлы локализации отсутствуют";
-        //QString info = "Текущий файл локализации не содержит патчей. Возможно это первый запуск «Наследия» с данным игровым клиентом, или клиент был обновлён игровым лаунчером. Применить выбранные патчи в данному файлу?";
-        //app->helper->myDialogBox(text, info, "OK", "Отмена", "gandalf.png", "applypaths", "", 420, 200, true, true);
-    }
-
-    if(app->datfiles[0].CheckIfPatchedByOldLauncher()){
-        return 3;
-        //QString text = "Файлы локализации не являются оригинальными";
-        //QString info = "Внимание! Присутствующие в вашем игровом клиенте файлы локализации не являются оригинальными, поскольку были модифицированы другой программой.<br/><strong>Мы настоятельно рекомендуем перекачать оригинальные версии файлов, поскольку правильная работа Наследия с данными файлами не гарантируется!</strong>";
-        //app->helper->myDialogBox(text, info, "Перекачать", "Не надо", "gandalf.png", "loaddatfile", "", 550, 200, true, true);
-    }
-    return 0;
-}

+ 5 - 10
helper.h

@@ -8,16 +8,15 @@
 #include <QPushButton>
 #include <QComboBox>
 #include <QCryptographicHash>
-#include "LotroDat.h"
 
 class Helper:public QObject {
     Q_OBJECT
    public:
     Helper();
-    Helper( const Helper&);
-    Helper& operator=( Helper& );
+    Helper( const Helper&) = delete;
+    Helper& operator=( Helper& ) = delete;
+
     int getVersion(QString string);
-    QMap <QString, QString> getPathsMap();
     QMap <QString, QString> htmlColors;
 
     void checkTab(QString tabname);
@@ -26,26 +25,22 @@ class Helper:public QObject {
     void hideAll();
     void setAbout();
     void findSkins();
-    void saveLocale(int locale, QPushButton *button);
     QString getSkinName();
     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);
+                   QString okAnswer, QString cancelAnswer, int w, int h, bool textshadow = false, bool is_cancel = false, bool prevent_dublicates = true);
     int dateToTimestamp(QString customDateString, QString format);
     void addComboItem(QComboBox* combo, QString itemName, QIcon* icon);
-    bool setGameLocale(QString locale);
 
 
     const char *stringToChar(QString val);
     void replaceSkin(QString name);
 
-    QByteArray ba;
     QString dialog_ok_answer;
     QString dialog_cancel_answer;
 
-private slots:
-    void handleFinisheddd();
+    QString last_message_msg;
 };
 
 

+ 413 - 4
lotromanager.cpp

@@ -2,22 +2,35 @@
 #include "app.h"
 #include "filesystem.h"
 
+#include <QStringList>
+
 LotroManager::LotroManager(QObject *parent) : QObject(parent)
 {
+    dat_files_.resize(5);
+}
 
+void LotroManager::saveDatFiles() {
+    for (auto dat_file : dat_files_)
+        dat_file.CloseDatFile();
+    App *app = &App::getInstance();
+    app->helper->setState("free");
 }
 
 void LotroManager::startGame(){
     App *app = &App::getInstance();
-    app->config->saveAllDatFiles();
+
+    for (auto &dat_file : dat_files_)
+        dat_file.CloseDatFile();
+
     QStringList args;
     args << "-skiprawdownload" << "-nosplash";
-    if (dat_locale == PATCHED)
+    if (dat_locale_ == PATCHED)
         args << "-disablePatch";
 
     QFile f(app->config->getValue("Local", "folder") + "/TurbineLauncher.exe");
     QProcess process;
-    if(FileSystem::fileExists(f.fileName())){
+
+    if (FileSystem::fileExists(f.fileName())) {
         if(f.fileName().contains(" ")) f.setFileName("\"" + f.fileName() + "\"");
         process.startDetached(f.fileName(), args);
         process.waitForFinished(-1);
@@ -25,7 +38,403 @@ void LotroManager::startGame(){
         QApplication::quit();
     } else {
         QString text = "Запуск не удался";
-        QString info = "Не удалось запустить игру. Во время запуска произшла непредвиденная ошибка (возможно, не найден файл TurbineLauncher.exe в папке с игрой. Проверьте в 'Настройках', что у вас указан верный путь к игре, и повторите попытку запуска).";
+        QString info = "Не удалось запустить игру. Не найден файл TurbineLauncher.exe или невозможно получить к нему доступ. "
+                       "Проверьте в 'Настройках', что у вас указан верный путь к игре, закрыт лаунчер игры и повторите попытку запуска.";
         app->helper->myDialogBox(text, info, "OK", "Отмена", "gandalf.png", "", "", 400, 160, true, false);
     }
 }
+
+bool LotroManager::openDatFile(int id) {
+    App *app = &App::getInstance();
+    QStringList dat_files_name_list;
+
+    dat_files_name_list << app->config->getValue("Local", "file")
+                        << "client_general.dat"
+                        << "client_sound.dat"
+                        << "client_surface.dat"
+                        << "client_highres.dat";
+
+    if (dat_files_name_list[id] != nullptr) {
+
+        qDebug() << dat_files_name_list[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%d", __FILE__, __LINE__, "Состояние dat-файла: ", dat_state);
+
+        if(dat_state > 0){
+            app->helper->setState("busy");
+            return true;
+        } else {
+            QString text = "Нет доступа к  файлам игры";
+            QString info = "Возможно в данный момент запущены клиент или лаунчер игры либо попытка доступа блокируется настройкой прав, антивирусом или другими приложениями. Завершите все процессы, использующие файлы игры и повторите попытку.";
+            app->helper->myDialogBox(text, info, "OK", "Отмена", "gandalf.png", "", "", 400, 200, true, false);
+            app->helper->setState("free");
+            return false;
+        }
+    }
+    return true;
+}
+
+void LotroManager::applyPatch(QString name){
+    App *app = &App::getInstance();
+    app->window->ui->hintLabel->setText("Установка патчей");
+    app->window->ui->exthintLabel->setText("Ожидайте. Идет установка выбранных патчей");
+    qDebug("%s:%i: %s%s", __FILE__, __LINE__, "Начинаем применение патча ", app->helper->stringToChar(name));
+    QLabel* label = app->window->findChild<QLabel*>(name + "Status");
+    QDir dir(QApplication::applicationDirPath() + "/data");
+    if (!dir.exists()) {
+        app->window->ui->hintLabel->setText("Установка патчей завершена с ошибкой");
+        app->window->ui->exthintLabel->setText("Ошибка - не найдена папка data");
+        return;
+    }
+
+    QStringList paths = dir.entryList(QStringList(name + "*"));
+    qDebug() << app->helper->stringToChar("data/" + paths.first());
+    if(!paths.empty()){
+       database_.InitDatabase(app->helper->stringToChar("data/" + paths.first()));
+        int indb = database_.CountRows();
+        qInfo("%s:%i: %s%d", __FILE__, __LINE__, "Файлов в обновлении: ", indb);
+        for(int i = 0; i<=indb; i++){
+            processFile();
+            if (label != nullptr)
+                label->setText(QString("Применение ... ") + QString::fromLatin1("%1").arg(i*100.0/indb, 3, 'f', 1) + QString("%"));
+        }
+        if(label != nullptr)label->setText("Готово");
+        //for (int i = 0; i < 5; i++) app->datfiles[i].CommitChanges();
+        app->config->setValue("Applied", name, paths.first());
+        database_.CloseDatabase();
+    }
+    app->window->ui->hintLabel->setText("Установка патчей завершена");
+    app->window->ui->exthintLabel->setText("Применение выбранных вами патчей закончено");
+}
+
+void LotroManager::applyGlobal(){
+    App *app = &App::getInstance();
+
+    // Применяем патч с заставочными экранами
+    if(app->config->getValue("Editor", "screens") == "true"){
+        applyLoadscreens();
+    } else {
+        QString dateline = app->config->getValue("Datetime", "loadscreens");
+        if(dateline != "-1"){
+            QStringList date = dateline.split(" ");
+            app->window->ui->loadscreensStatus->setText(date[0]);
+        }
+    }
+
+    // Применяем остальные патчи
+    QStringList names;
+    QStringList need;
+    QFuture<void> f;
+    f = QtConcurrent::run([=]() {});
+    names  << "fonts" << "sounds" << "texts" << "images" << "videos" << "textures";
+    QDir dir(QApplication::applicationDirPath() + "/data");
+
+    foreach(QString name, names) {
+
+        QStringList list = dir.entryList(QStringList(name + "*"));
+
+        if (list.size() > 0 && list.first() != ""){
+            QString isset = app->config->getValue("Applied", name);
+            if (list.first() != isset && app->config->getValue("Editor", name) == "true") {
+                need.append(name);
+            }
+        }
+    }
+
+    Helper *helper = new Helper();
+    QFutureWatcher<void> * watcher = new QFutureWatcher<void>();
+    connect(watcher, SIGNAL(finished()), helper, SLOT(handleFinisheddd()));
+
+    if(need.size() > 0){
+        watcher->setFuture(QtConcurrent::run([=]() {
+            if(openDatFile(0)){
+                foreach(QString name, need) {
+                    applyPatch(name);
+                }
+                saveDatFiles();
+            }
+        }));
+    } else {
+        installMicroPatch();
+    }
+
+}
+
+bool LotroManager::isDatReady(){
+    App *app = &App::getInstance();
+    bool free;
+    QString dir = app->config->getValue("Local", "folder");
+    QString file = app->config->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;
+}
+
+int LotroManager::checkDatFile(){
+    //bool CheckIfUpdatedByGame(); // Обновлялся ли игрой
+    //bool CheckIfNotPatched(); // Был ли хоть раз пропатчен новым лаунчером
+    //bool CheckIfPatchedByOldLauncher(); // Был ли хоть раз пропатчен старым лаунчером
+
+    App *app = &App::getInstance();
+    if (!openDatFile(0)) {
+        return 0;
+    }
+
+    if(dat_files_[0].CheckIfUpdatedByGame()){
+        return 1;
+        //app->ready = false;
+        //QString text = "Файлы локализации изменены";
+        //QString info = "В процессе последнего запуска игры были установлены обновления игрового клиента. Это могло затронуть файлы локализации. Желаете провести проверку и исправить поврежденные участки перевода? Вы можете в любой момент сделать это самостоятельно, нажав кнопку «Применить патчи заново».";
+        //app->helper->myDialogBox(text, info, "OK", "Отмена", "gandalf.png", "applypaths", "", 400, 220, true, true);
+    }
+
+    if(dat_files_[0].CheckIfNotPatched() && app->config->getValue("Local", "runfirst") == "1"){
+        return 2;
+        //app->ready = false;
+        //QString text = "Файлы локализации отсутствуют";
+        //QString info = "Текущий файл локализации не содержит патчей. Возможно это первый запуск «Наследия» с данным игровым клиентом, или клиент был обновлён игровым лаунчером. Применить выбранные патчи в данному файлу?";
+        //app->helper->myDialogBox(text, info, "OK", "Отмена", "gandalf.png", "applypaths", "", 420, 200, true, true);
+    }
+
+    if(dat_files_[0].CheckIfPatchedByOldLauncher()){
+        return 3;
+        //QString text = "Файлы локализации не являются оригинальными";
+        //QString info = "Внимание! Присутствующие в вашем игровом клиенте файлы локализации не являются оригинальными, поскольку были модифицированы другой программой.<br/><strong>Мы настоятельно рекомендуем перекачать оригинальные версии файлов, поскольку правильная работа Наследия с данными файлами не гарантируется!</strong>";
+        //app->helper->myDialogBox(text, info, "Перекачать", "Не надо", "gandalf.png", "loaddatfile", "", 550, 200, true, true);
+    }
+    return 0;
+}
+
+void LotroManager::applyMicroPatch(){
+    App *app = &App::getInstance();
+    app->logSectionStart("Установка мгновенных обновлений");
+    app->helper->setState("busy");
+    app->window->ui->hintLabel->setText("Установка последних обновлений");
+    app->window->ui->exthintLabel->setText("Подождите пока закончится применение обновлений");
+
+    database_.InitDatabase(app->helper->stringToChar(app->network->micropatch));
+    int indb = database_.CountRows();
+    qInfo("%s:%i: %s%d", __FILE__, __LINE__, "Файлов в обновлении: ", indb);
+    for(int i = 0; i<=indb; i++){ processFile(); }
+    //for (int i = 0; i < 5; i++) app->datfiles[i].CommitChanges();
+    database_.CloseDatabase();
+
+    app->config->setValue("Updates", "update", QDate::currentDate().toString("yyyy-MM-dd"));
+
+    app->helper->setState("free");
+    qInfo("%s:%i: %s", __FILE__, __LINE__, "Выполнено.");
+    app->logSectionEnd();
+}
+
+void LotroManager::applyLoadscreens(){
+    App *app = &App::getInstance();
+    app->logSectionStart("Установка заставочных экранов");
+    app->helper->setState("busy");
+
+    QString datafolder = QApplication::applicationDirPath() + "/data";
+    QDir dir(datafolder);
+    if (!dir.exists())
+        return;
+    QStringList paths = dir.entryList(QStringList("loadscreens*"));
+
+    if(!paths.empty()){
+
+        if(paths.first() == app->config->getValue("Applied", "screens")){
+            app->helper->setState("free");
+            return;
+        }
+
+        QString lang = app->config->getValue("Local", "lang");
+
+        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__, app->helper->stringToChar(folder + filenames[i]));
+                QFile::remove(folder + filenames[i]);
+                subfile.binary_data.WriteToFile((folder + filenames[i]).toStdString());
+            }
+        }
+        database_.CloseDatabase();
+
+    }
+    app->helper->setState("free");
+    app->window->ui->loadscreensStatus->setText("Готово");
+    app->config->setValue("Applied", "screens", paths.first());
+    qInfo("%s:%i: %s", __FILE__, __LINE__, "Выполнено.");
+    app->logSectionEnd();
+}
+
+void LotroManager::processFile(){
+    App *app = &App::getInstance();
+    SubfileData subfile;
+    subfile = database_.GetNextFile();
+    if (subfile.Empty()){
+        qInfo("%s:%i: %s", __FILE__, __LINE__, "Достигнут конец файла.");
+    } else {
+        int dat_id = subfile.options["did"].as<int>();
+        int dat_state = dat_files_[dat_id].InitDatFile(app->config->getDatPath(dat_id), dat_id);
+        //qDebug("%s:%i: %s%d", __FILE__, __LINE__, "Состояние dat-файла: ", dat_state);
+        if(dat_state > 0) dat_files_[dat_id].PatchFile(subfile);
+    }
+}
+
+void LotroManager::installMicroPatch(){
+    App *app = &App::getInstance();
+    if(app->config->getValue("Updates", "micro") != "true") return;
+
+    app->helper->setState("busy");
+    app->window->ui->hintLabel->setText("Установка последних обновлений");
+    app->window->ui->exthintLabel->setText("Идет проверка и установка новых обновлений");
+    QFuture<void> future = QtConcurrent::run([=]() {
+        prepareMicroPatch();
+        applyMicroPatch();
+        QDir dir("/data/micro");
+        FileSystem::clearFolder(dir);
+    });
+    app->window->ui->hintLabel->setText("Установка завершена");
+    app->window->ui->exthintLabel->setText("Обновления успешно установлены");
+    app->helper->setState("free");
+
+}
+
+void LotroManager::prepareMicroPatch(){
+    App *app = &App::getInstance();
+    app->logSectionStart("Автоматическая проверка обновлений");
+    app->helper->setState("busy");
+    app->window->ui->hintLabel->setText("Загрузка последних обновлений");
+    app->window->ui->exthintLabel->setText("Подождите пока загрузятся последние изменения в системе переводов");
+
+    QString date = app->config->getValue("Updates", "update");
+    if (date == QDate::currentDate().toString("yyyy-MM-dd"))
+        return;
+
+    if (date == "false" || date == "-1")
+        date = QDate::currentDate().toString("yyyy-MM-dd");
+
+    //QTime time = QTime::currentTime();
+    //int seconds = QTime(0, 0, 0).secsTo(time);
+    //int timestamp = app->helper->dateToTimestamp(date + " " + time.toString("hh:mm:ss"), "yyyy-MM-dd hh:mm:ss") - seconds - 1209600;
+    int timestamp = app->helper->dateToTimestamp(date, "yyyy-MM-dd") - 1209600;
+
+    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->helper->stringToChar(app->network->micropatch));
+        app->network->micropatch = app->network->getMicroPath(timestamp);
+    }
+    app->window->ui->hintLabel->setText("Загрузка завершена");
+    app->window->ui->exthintLabel->setText("Все обновления были успешно загружены и доступны к установке");
+
+    app->helper->setState("free");
+    qInfo("%s:%i: %s", __FILE__, __LINE__, "Выполнено.");
+    app->logSectionEnd();
+}
+
+void LotroManager::saveLocale(int locale, QPushButton * button){
+    App *app = &App::getInstance();
+    QString file;
+
+    if(locale == 0) file = "client_local_English.dat";
+    if(locale == 1) file = "client_local_DE.dat";
+    if(locale == 2) file = "client_local_FR.dat";
+
+    if(FileSystem::fileExists(app->config->getValue("Local", "folder") + "/" + file)){
+        app->window->ui->enButton->setEnabled(true);
+        app->window->ui->deButton->setEnabled(true);
+        app->window->ui->frButton->setEnabled(true);
+        button->setEnabled(false);
+        app->config->setValue("Local", "file", file);
+    } else {
+        QString text = "Данная локализация отсутствует";
+        QString info = "В настоящий момент вы не можете выбрать данную опцию, поскольку файл " + file + " отсутствует в вашем игровом клиенте. Чтобы скачать его, запустите официальный лаунчер, выберите желаемый язык в верхней правой части окна и дождитесь, когда загрузка необходимых файлов завершится.";
+        app->helper->myDialogBox(text, info, "OK", "Отмена", "gandalf.png", "", "", 400, 220, true, false);
+    }
+}
+
+bool LotroManager::setGameLocale(QString locale){
+    App *app = &App::getInstance();
+    app->window->ui->goHint->show();
+    app->helper->setState("busy");
+    app->window->ui->goLocal->setEnabled(false);
+    app->window->ui->goOriginal->setEnabled(false);
+    app->window->ui->goCancel->setEnabled(false);
+
+    if(openDatFile(0)){
+        LOCALE loc = dat_files_[0].current_locale();
+        dat_locale_ = loc;
+
+        if(loc == PATCHED) qDebug() << "Starting " + locale + " version. Current locale is PATCHED";
+        if(loc == ORIGINAL) qDebug() << "Starting " + locale + " version. Current locale is ORIGINAL";
+        if(loc != ORIGINAL && loc != PATCHED) qDebug() << "Starting " + locale + " version. Current locale is UNKNOWN";
+
+        if(locale == "RU" && loc != PATCHED){ qDebug()<< "Current locale Original"; dat_files_[0].SetLocale(PATCHED); dat_locale_ = PATCHED;}
+        if(locale == "Original" && loc != ORIGINAL){ qDebug()<< "Current locale RU"; dat_files_[0].SetLocale(ORIGINAL); dat_locale_ = ORIGINAL;}
+        saveDatFiles();
+    }
+
+    app->window->ui->goHint->hide();
+    app->window->ui->goProgress->hide();
+    app->window->ui->startbox->hide();
+    app->window->ui->goLocal->setEnabled(true);
+    app->window->ui->goOriginal->setEnabled(true);
+    app->window->ui->goCancel->setEnabled(true);
+    app->helper->setState("free");
+    qDebug() << "Locale changed";
+
+    return true;
+}
+
+void LotroManager::handleFinisheddd(){
+   installMicroPatch();
+}

+ 19 - 8
lotromanager.h

@@ -2,6 +2,10 @@
 #define LOTROMANAGER_H
 
 #include <QObject>
+#include <QPushButton>
+
+#include <queue>
+#include <functional>
 
 #include <LotroDat.h>
 
@@ -13,16 +17,14 @@ private:
 
 public:
     static LotroManager& getInstance() {
-       static LotroManager instance;
-       return instance;
+       static LotroManager lotro_mgr_instance;
+       return lotro_mgr_instance;
     }
 
     void startGame();
 
     bool openDatFile(int id);
 
-    void closeDatFile(int id);
-
     void applyPatch(QString name);
 
     void applyGlobal();
@@ -35,20 +37,29 @@ public:
 
     void applyLoadscreens();
 
-private:
+    bool setGameLocale(QString locale);
+
+    void saveLocale(int locale, QPushButton *button);
+
+    void saveDatFiles();
+
+public:
     void processFile();
 
     void installMicroPatch();
 
     void prepareMicroPatch();
 
-
-private:
+public:
     LOTRO_DAT::LOCALE dat_locale_;
+    std::vector<LOTRO_DAT::DatFile> dat_files_;
+    LOTRO_DAT::Database database_;
 
 signals:
 
-public slots:
+private slots:
+    void handleFinisheddd();
+    //void processQueue();
 };
 
 #endif // LOTROMANAGER_H

+ 36 - 18
mainwindow.cpp

@@ -6,6 +6,7 @@
 #include <QImage>
 
 #include "filesystem.h"
+#include "lotromanager.h"
 
 MainWindow::MainWindow( double scale_factor, QMainWindow* parent) :
     QMainWindow( parent, Qt::Window | Qt::FramelessWindowHint),
@@ -63,23 +64,27 @@ MainWindow::MainWindow( double scale_factor, QMainWindow* parent) :
     movie->start();
 
     app->helper->setState("busy");
-    ui->hintLabel->setText("Проверка .dat файла...");
-    ui->exthintLabel->setText("Выполняется предварительная проверка файлов данных. Пожалуйста, подождите..");
+    ui->hintLabel->setText("Получение данных с сервера");
+    ui->exthintLabel->setText("Скачиваем необходимую информацию с сервера...");
 
     show();
 
     connect(app->window->ui->skinSelect, SIGNAL(currentIndexChanged(int)), this, SLOT(saveSkin()));
     connect(this, SIGNAL(datFileChecked(int)), this, SLOT(PostDatFileCheckTransactions(int)));
 
+
     app->helper->loadNews();
     app->network->getFootMessage();
     app->network->getServers();
     app->network->getCoupon();
 
+    ui->hintLabel->setText("Проверка .dat файла");
+    ui->exthintLabel->setText("Выполняется предварительная проверка файлов данных...");
+
     QFuture<void> future = QtConcurrent::run([=]() {
         qInfo("%s:%i: %s", __FILE__, __LINE__, "Инициализация закончена.");
         // Проверяем файл локализации
-        int result = app->helper->checkDatFile();
+        int result = LotroManager::getInstance().checkDatFile();
         emit(datFileChecked(result));
     });
 }
@@ -277,13 +282,19 @@ void MainWindow::on_goCancel_clicked(){
 void MainWindow::on_goOriginal_clicked(){
     App *app = &App::getInstance();
     app->window->ui->goProgress->show();
-    QtConcurrent::run([=]() { app->helper->setGameLocale("Original"); app->helper->startGame(); });
+    QtConcurrent::run([=]() {
+        LotroManager::getInstance().setGameLocale("Original");
+        LotroManager::getInstance().startGame();
+    });
 }
 
 void MainWindow::on_goLocal_clicked(){
     App *app = &App::getInstance();
     app->window->ui->goProgress->show();
-    QtConcurrent::run([=]() { if(app->helper->setGameLocale("RU")) app->helper->startGame(); });
+    QtConcurrent::run([=]() {
+        if(LotroManager::getInstance().setGameLocale("RU"))
+            LotroManager::getInstance().startGame();
+    });
 }
 
 void MainWindow::on_minimizeButton_clicked(){
@@ -302,19 +313,19 @@ void MainWindow::on_couponButton_clicked(){
 
 void MainWindow::on_enButton_clicked(){
     App *app = &App::getInstance();
-    app->helper->saveLocale(0, this->ui->enButton);
+    LotroManager::getInstance().saveLocale(0, this->ui->enButton);
     app->config->setValue("Local", "lang", "en");
 }
 
 void MainWindow::on_deButton_clicked(){
     App *app = &App::getInstance();
-    app->helper->saveLocale(1, this->ui->deButton);
+    LotroManager::getInstance().saveLocale(1, this->ui->deButton);
     app->config->setValue("Local", "lang", "de");
 }
 
 void MainWindow::on_frButton_clicked(){
     App *app = &App::getInstance();
-    app->helper->saveLocale(2, this->ui->frButton);
+    LotroManager::getInstance().saveLocale(2, this->ui->frButton);
     app->config->setValue("Local", "lang", "fr");
 }
 
@@ -375,8 +386,9 @@ void MainWindow::on_lotropathButton_clicked(){
         app->config->setValue("Local", "folder", path);
     } else {
         QString text = "Выбрана неверная папка";
-        QString info = "<p>Убедитесь, что выбранный вами каталог является папкой игры и содержит такие файлы как TurbineLauncher.exe и client_local_English.dat.</p>";
-        app->helper->myDialogBox(text, info, "OK", "Отмена", "gandalf.png", "", "", 400, 160, true, false);
+        QString info = "<p>Убедитесь, что выбранный вами каталог является папкой игры и содержит такие файлы как, например,"
+                       " TurbineLauncher.exe, lotroclient.exe и т.п.</p>";
+        app->helper->myDialogBox(text, info, "OK", "Выход", "gandalf.png", "choosedatpath", "exit", 400, 160, true, true);
     }
 }
 
@@ -388,7 +400,7 @@ void MainWindow::on_designButton_clicked(){
 void MainWindow::on_repairButton_clicked(){
    App *app = &App::getInstance();
    app->config->deleteSection("Applied");
-   app->helper->applyGlobal();
+   LotroManager::getInstance().applyGlobal();
    app->helper->checkTab("mainbox");
 }
 
@@ -429,10 +441,14 @@ void MainWindow::on_okButton_clicked(){
                 }
 
             }
-
             qDebug() << folders;
         }
 
+        if (command == "choosedatpath") {
+            app->helper->checkTab("optbox");
+            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;
@@ -468,9 +484,10 @@ void MainWindow::on_okButton_clicked(){
             app->config->deleteSection("Applied");
             QString filename = app->config->getDatPath(0);
             qInfo("%s:%i: %s%s", __FILE__, __LINE__, "Удаляем файл: ", app->helper->stringToChar(filename));
-            app->helper->closeDatFile(0);
-            if(QFile::remove(filename)){
-                app->helper->startGame();
+            LotroManager::getInstance().saveDatFiles();
+            QFile::remove(filename);
+            if (!FileSystem::fileExists(filename)) {
+                LotroManager::getInstance().startGame();
                 qApp->exit();
             }
 
@@ -485,10 +502,11 @@ void MainWindow::on_cancelButton_clicked(){
     App *app = &App::getInstance();
     QStringList commands = app->helper->dialog_cancel_answer.split(" ");
     foreach(QString command, commands){
-        if(command == "close") this->ui->dialogbox->hide();
-
-
+        if(command == "close")
+            this->ui->dialogbox->hide();
 
+        if (command == "exit")
+            QApplication::exit(0);
     }
 
 

+ 8 - 8
mainwindow.ui

@@ -6,8 +6,8 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>990</width>
-    <height>986</height>
+    <width>611</width>
+    <height>350</height>
    </rect>
   </property>
   <property name="windowTitle">
@@ -891,7 +891,7 @@
       <cursorShape>PointingHandCursor</cursorShape>
      </property>
      <property name="text">
-      <string/>
+      <string>Новость загружается...</string>
      </property>
      <property name="openExternalLinks">
       <bool>true</bool>
@@ -928,7 +928,7 @@
       <rect>
        <x>70</x>
        <y>60</y>
-       <width>371</width>
+       <width>381</width>
        <height>21</height>
       </rect>
      </property>
@@ -936,7 +936,7 @@
       <cursorShape>PointingHandCursor</cursorShape>
      </property>
      <property name="text">
-      <string/>
+      <string>Новость загружается...</string>
      </property>
      <property name="openExternalLinks">
       <bool>true</bool>
@@ -971,7 +971,7 @@
       <cursorShape>PointingHandCursor</cursorShape>
      </property>
      <property name="text">
-      <string/>
+      <string>Новость загружается...</string>
      </property>
     </widget>
     <widget class="QLabel" name="news4Teaser">
@@ -997,7 +997,7 @@
       </rect>
      </property>
      <property name="text">
-      <string/>
+      <string>Новость загружается...</string>
      </property>
     </widget>
    </widget>
@@ -1746,7 +1746,7 @@
      </rect>
     </property>
     <property name="text">
-     <string>Наследие: v1.0.0</string>
+     <string>Наследие: v2.0.0</string>
     </property>
    </widget>
    <widget class="QPushButton" name="designButton">

+ 7 - 7
network.cpp

@@ -1,5 +1,6 @@
 #include "app.h"
 #include "filesystem.h"
+#include "lotromanager.h"
 
 #include <QtNetwork/QNetworkAccessManager>
 #include <QUrl>
@@ -169,7 +170,6 @@ QString ANetwork::getServers(){
 
 
 void ANetwork::getPaths(){
-
     App *app = &App::getInstance();
     QUrlQuery query;
     QStringList names;
@@ -235,7 +235,7 @@ void ANetwork::getPaths(){
     if(content == "") {
         qInfo("%s:%i: %s", __FILE__, __LINE__, "Все версии патчей соответствуют актуальным.");
         app->helper->setState("busy");
-        app->helper->applyGlobal();
+        LotroManager::getInstance().applyGlobal();
         app->helper->setState("free");
         return;
     }
@@ -295,13 +295,13 @@ QString ANetwork::getMicroPath(int timestamp){
     qInfo("%s:%i: %s", __FILE__, __LINE__, "Загрузка микропатча завершена.");
 
 
-    app->db->InitDatabase(app->helper->stringToChar(filename));
-    int indb = app->db->CountRows();
+    LotroManager::getInstance().database_.InitDatabase(app->helper->stringToChar(filename));
+    int indb = LotroManager::getInstance().database_.CountRows();
     qInfo("%s:%i: %s%i", __FILE__, __LINE__, "Патч содержит строк: ", indb);
-    for(int i = 0; i<=indb; i++) app->helper->processFile();
+    for(int i = 0; i<=indb; i++) LotroManager::getInstance().processFile();
     qInfo("%s:%i: %s", __FILE__, __LINE__, "Выполнено.");
-    app->config->saveAllDatFiles();
-    app->db->CloseDatabase();
+    LotroManager::getInstance().saveDatFiles();
+    LotroManager::getInstance().database_.CloseDatabase();
     app->logSectionEnd();
 
     return filename;

+ 5 - 5
res/styles/lotro/skin.ini

@@ -17,31 +17,31 @@ left=740
 top=72
 
 [mainButton]
-width=136
+width=138
 height=26
 left=597
 top=261
 
 [optButton]
-width=136
+width=138
 height=26
 left=597
 top=300
 
 [newsButton]
-width=136
+width=138
 height=26
 left=597
 top=339
 
 [helpButton]
-width=136
+width=138
 height=26
 left=597
 top=377
 
 [aboutButton]
-width=136
+width=138
 height=26
 left=597
 top=414

+ 7 - 7
ui_mainwindow.h

@@ -151,7 +151,7 @@ public:
     {
         if (MainWindow->objectName().isEmpty())
             MainWindow->setObjectName(QStringLiteral("MainWindow"));
-        MainWindow->resize(990, 986);
+        MainWindow->resize(611, 350);
         MainWindow->setStyleSheet(QStringLiteral(""));
         centralWidget = new QWidget(MainWindow);
         centralWidget->setObjectName(QStringLiteral("centralWidget"));
@@ -375,7 +375,7 @@ public:
         news2Teaser->setGeometry(QRect(70, 80, 351, 16));
         news2Title = new QLabel(newsbox);
         news2Title->setObjectName(QStringLiteral("news2Title"));
-        news2Title->setGeometry(QRect(70, 60, 371, 21));
+        news2Title->setGeometry(QRect(70, 60, 381, 21));
         news2Title->setCursor(QCursor(Qt::PointingHandCursor));
         news2Title->setOpenExternalLinks(true);
         news2Title->setTextInteractionFlags(Qt::LinksAccessibleByMouse);
@@ -681,14 +681,14 @@ public:
         news2Image->setText(QString());
         news3Image->setText(QString());
         news4Image->setText(QString());
-        news1Title->setText(QString());
+        news1Title->setText(QApplication::translate("MainWindow", "\320\235\320\276\320\262\320\276\321\201\321\202\321\214 \320\267\320\260\320\263\321\200\321\203\320\266\320\260\320\265\321\202\321\201\321\217...", Q_NULLPTR));
         news1Teaser->setText(QString());
         news2Teaser->setText(QString());
-        news2Title->setText(QString());
+        news2Title->setText(QApplication::translate("MainWindow", "\320\235\320\276\320\262\320\276\321\201\321\202\321\214 \320\267\320\260\320\263\321\200\321\203\320\266\320\260\320\265\321\202\321\201\321\217...", Q_NULLPTR));
         news3Teaser->setText(QString());
-        news3Title->setText(QString());
+        news3Title->setText(QApplication::translate("MainWindow", "\320\235\320\276\320\262\320\276\321\201\321\202\321\214 \320\267\320\260\320\263\321\200\321\203\320\266\320\260\320\265\321\202\321\201\321\217...", Q_NULLPTR));
         news4Teaser->setText(QString());
-        news4Title->setText(QString());
+        news4Title->setText(QApplication::translate("MainWindow", "\320\235\320\276\320\262\320\276\321\201\321\202\321\214 \320\267\320\260\320\263\321\200\321\203\320\266\320\260\320\265\321\202\321\201\321\217...", Q_NULLPTR));
         helpbox->setTitle(QString());
         aboutbox->setTitle(QString());
         helperslist->setText(QApplication::translate("MainWindow", "TextLabel", Q_NULLPTR));
@@ -735,7 +735,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.0.0", Q_NULLPTR));
+        labelVersion->setText(QApplication::translate("MainWindow", "\320\235\320\260\321\201\320\273\320\265\320\264\320\270\320\265: v2.0.0", 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