瀏覽代碼

Added Patch Downloader class model

Ivan Arkhipov 4 年之前
父節點
當前提交
aacd2b4ca3

+ 2 - 0
src/Legacy/Legacy.pro

@@ -17,6 +17,7 @@ SOURCES += \
     main.cpp \
     models/downloader.cpp \
     models/lotrodatmanager.cpp \
+    models/patchdownloader.cpp \
     models/selfupdater.cpp \
     utils.cpp \
     widgets/helpwidget.cpp \
@@ -47,6 +48,7 @@ HEADERS += \
     models/downloader.h \
     models/filesystem.h \
     models/lotrodatmanager.h \
+    models/patchdownloader.h \
     models/selfupdater.h \
     utils.h \
     widgets/helpwidget.h \

+ 21 - 14
src/Legacy/legacyapplication.cpp

@@ -10,6 +10,7 @@
 #include <QMessageLogContext>
 
 #include "utils.h"
+#include "models/patchdownloader.h"
 
 extern Q_CORE_EXPORT int qt_ntfs_permission_lookup;
 
@@ -55,21 +56,25 @@ bool LegacyApplication::init()
     QFontDatabase::addApplicationFont(":/fonts/EBGaramond.ttf");
     QFontDatabase::addApplicationFont(":/fonts/aniron.ttf");
 
-    qDebug() << "Starting Lotro Manager initialization...";
+//    qDebug() << "Starting Lotro Manager initialization...";
 
-    lotro_dat_manager = new LotroDatManager();
-    lotro_dat_manager_thread = new QThread();
-    connect(lotro_dat_manager_thread, &QThread::finished, lotro_dat_manager, &LotroDatManager::deleteLater);
-    lotro_dat_manager->moveToThread(lotro_dat_manager_thread);
-    lotro_dat_manager_thread->start();
+//    lotro_dat_manager = new LotroDatManager();
+//    lotro_dat_manager_thread = new QThread();
+//    connect(lotro_dat_manager_thread, &QThread::finished, lotro_dat_manager, &LotroDatManager::deleteLater);
+//    lotro_dat_manager->moveToThread(lotro_dat_manager_thread);
+//    lotro_dat_manager_thread->start();
 
-    qDebug() << "Starting Patch list initialisation...";
+//    qDebug() << "Starting Patch list initialisation...";
 
-    patch_list = new PatchList(lotro_dat_manager);
+//    patch_list = new PatchList(lotro_dat_manager);
 
-    qDebug() << "Starting GUI initialisation...";
+    patch_downloader_thread_ = new QThread();
+    PatchDownloader::instance().init();
+    PatchDownloader::instance().moveToThread(patch_downloader_thread_);
+    patch_downloader_thread_->start();
 
-    gui = new MainWindow(patch_list);
+    qDebug() << "Starting GUI initialisation...";
+    gui = new MainWindow(nullptr);
     connect(this, &LegacyApplication::ErrorStatusChanged, gui, &MainWindow::onErrorStatusChanged);
     connect(this, &LegacyApplication::SecondsToNextTryToInitChanged, gui, &MainWindow::onSecondsToNextTryToInitChanged);
 
@@ -93,11 +98,13 @@ void LegacyApplication::InitModules()
     AppErrorStatus status = CheckAppPrerequesities();
     emit ErrorStatusChanged(status);
 
+    QMetaObject::invokeMethod(&PatchDownloader::instance(), &PatchDownloader::startPatchDownloaderChain, Qt::QueuedConnection);
     if (status == E_NO_ERRORS) {
-        patch_list->initialize();
-        patch_list->startAutoUpdate();
+//        patch_list->initialize();
+//        patch_list->startAutoUpdate();
     } else {
-        qWarning() << "LegacyApplication: Couldnt init functional modules!";
-        modules_init_timer_.start();
+//        qWarning() << "LegacyApplication: Couldnt init functional modules!";
+//        modules_init_timer_.start();
     }
+
 }

+ 5 - 3
src/Legacy/legacyapplication.h

@@ -35,11 +35,13 @@ private slots:
     void InitModules();
 
 private:
-    LotroDatManager *lotro_dat_manager = nullptr;
-    QThread *lotro_dat_manager_thread = nullptr;
-    PatchList *patch_list = nullptr;
+//    LotroDatManager *lotro_dat_manager = nullptr;
+//    QThread *lotro_dat_manager_thread = nullptr;
+//    PatchList *patch_list = nullptr;
     MainWindow *gui = nullptr;
 
+    QThread* patch_downloader_thread_;
+
     QTimer modules_init_timer_;
     size_t seconds_after_previous_try_to_init_ = 10; // init value should be equal to try_to_init_timeout_
     const size_t try_to_init_timeout_ = 10;

+ 1 - 1
src/Legacy/models/downloader.cpp

@@ -4,7 +4,7 @@
 #include <QDebug>
 #include <QTime>
 
-Downloader::Downloader(QObject *parent) :QObject(parent), busy_(false)
+Downloader::Downloader(QObject *parent) : QObject(parent), busy_(false), m_WebCtrl(this)
 {
     qRegisterMetaType<Downloader::Status>();
     connect(&m_WebCtrl, SIGNAL(finished(QNetworkReply*)), this, SLOT(onDownloadFinished(QNetworkReply*)));

+ 114 - 0
src/Legacy/models/patchdownloader.cpp

@@ -0,0 +1,114 @@
+#include "models/patchdownloader.h"
+#include "models/settings.h"
+#include "models/filesystem.h"
+
+#include <QUrlQuery>
+
+void PatchDownloader::init() {
+    for (const QString& patch: patches_) {
+        patch_downloaders_[patch] = new Downloader(this);
+    }
+}
+
+PatchDownloader::~PatchDownloader()
+{
+    for (const QString& patch: patches_) {
+        patch_downloaders_[patch]->deleteLater();
+    }
+}
+
+PatchDownloader::PatchDownloader() {
+    // Does nothing
+}
+
+void PatchDownloader::startPatchDownloaderChain() {
+    checkForUpdates();
+    download();
+}
+
+void PatchDownloader::checkForUpdates() {
+    qDebug() << "CHECKING FOR UPDATES!";
+    QUrlQuery query; // query for building GET-request aka patch-version
+
+    for (const QString& patch: patches_) {
+        query.addQueryItem(patch, "100");
+    }
+
+    QUrl target_url;
+    target_url.setUrl(Settings::getValue("Network/patch_updates_url").toString());
+    target_url.setQuery(query);
+
+    QByteArray target_array;
+    Downloader downloader;
+    downloader.setUrl(target_url);
+    downloader.targetBytearray = &target_array;
+    downloader.start();
+    downloader.waitForDownloaded();
+
+    if (target_array.isEmpty()) {
+        qWarning() << "PatchDwnlder: Cannot check for updates, target_array is empty!";
+        return;
+    }
+    qDebug() << "CHECK FOR UPDATES RESULT: " << target_array;
+
+    QStringList patch_info = QString(target_array).split('|');
+    if (patch_info.size() != patches_.size()) {
+        qCritical() << __FUNCTION__ << "Incorrect patches number! Data: " << patch_info;
+        return;
+    }
+
+    for (int i = 0; i < patches_.size(); ++i) {
+        const QString patch = patches_[i];
+        const QStringList patch_data = patch_info[i].split(":::");
+        if (patch_data.size() != 3) {
+            qCritical() << __FUNCTION__ << "Incorrect patch entry size! Entry: " << patch_data;
+            return;
+        }
+
+        QString patch_filename = Settings::getValue("General/PatchDownloadDir").toString() + "/" + patch;
+
+        Settings::setValue("PatchDatabases/" + patch + "/url", patch_data[0]);
+        Settings::setValue("PatchDatabases/" + patch + "/hashsum", patch_data[1]);
+        Settings::setValue("PatchDatabases/" + patch + "/datetime", patch_data[2]);
+        Settings::setValue("PatchDatabases/" + patch + "/path", patch_filename);
+    }
+}
+
+void PatchDownloader::download() {
+    qDebug() << "STARTING PATCH DOWNLOAD";
+    for (const QString& patch: patches_) {
+        QString target_filename = Settings::getValue("PatchDatabases/" + patch + "/path").toString();
+
+        qDebug() << patch << ": Checking if there's need to download patch";
+        if (!needDownloadDatabase(patch)) {
+            qInfo() << patch << ": file " << target_filename << " is up-to-date, no need to download";
+            continue;
+        }
+
+        FileSystem::createFilePath(target_filename);
+        QFile* target_file = new QFile(target_filename);
+        if (!target_file->open(QIODevice::ReadWrite | QIODevice::Truncate)) {
+            qWarning() << "PatchDwnlder" << patch << "Cannot open file " << target_filename;
+            continue;
+        }
+
+        qInfo() << "PatchDwnlder" << patch << ": beginning download of file " << target_filename;
+
+        patch_downloaders_[patch]->setUrl(Settings::getValue("PatchDatabases/" + patch + "/url").toUrl());
+        patch_downloaders_[patch]->targetFile = target_file;
+        patch_downloaders_[patch]->start();
+        patch_downloaders_[patch]->waitForDownloaded();
+        target_file->close();
+        target_file->deleteLater();
+        Settings::setValue("DatabaseNeedInstall/" + patch, true);
+    }
+    qDebug() << "FINISHED PATCH DOWNLOAD";
+}
+
+bool PatchDownloader::needDownloadDatabase(QString db_name)
+{
+    QString patch_filename = Settings::getValue("PatchDatabases/" + db_name + "/path").toString();
+    QString current_file_hash = FileSystem::fileHash(patch_filename);
+    QString required_file_hash = Settings::getValue("PatchDatabases/" + db_name + "/hashsum").toString();
+    return Settings::getValue("DatabaseDownload/" + db_name).toBool() && (current_file_hash != required_file_hash);
+}

+ 38 - 0
src/Legacy/models/patchdownloader.h

@@ -0,0 +1,38 @@
+#ifndef PATCHDOWNLOADER_H
+#define PATCHDOWNLOADER_H
+
+#include <QObject>
+#include <QList>
+#include <QString>
+#include <QMap>
+
+#include "models/downloader.h"
+
+class PatchDownloader : public QObject
+{
+    Q_OBJECT
+
+public:
+    static PatchDownloader& instance() {
+        static PatchDownloader instance_;
+        return instance_;
+    }
+
+    void init();
+    ~PatchDownloader();
+
+private:
+    PatchDownloader();
+    void checkForUpdates();  // Checks for updates. Returns true, if there are new patch updates
+    void download();         // Downloads all necessary patches.
+    static bool needDownloadDatabase(QString db_name); // Checks if database needs to be downloaded (by checksum comparing)
+
+public slots:
+    void startPatchDownloaderChain();
+
+private:
+    const QList<QString> patches_ = {"text", "font", "image", "texture", "loadscreen", "sound", "video"};
+    QMap<QString, Downloader*> patch_downloaders_;
+};
+
+#endif // PATCHDOWNLOADER_H

+ 4 - 12
src/Legacy/models/settings.cpp

@@ -24,6 +24,7 @@ QMap<QString, QVariant> defaults = {
     {"Backup/creation_time", "none"},
 
     // Databases download settings
+
     {"DatabaseDownload/text", false},          // TextsPatch
     {"DatabaseDownload/font", false},          // TextsPatch
     {"DatabaseDownload/image", false},         // GraphicsPatch
@@ -44,18 +45,8 @@ QMap<QString, QVariant> defaults = {
     {"DatabaseNeedInstall/video", false},          // VideosPatch
     {"DatabaseNeedInstall/micro", false},          // MircoPatch
 
-    // Flags, meaning that database was installed and needs to be activated
-
-    {"DatabaseNeedActivate/text", false},           // TextsPatch
-    {"DatabaseNeedActivate/font", false},           // TextsPatch
-    {"DatabaseNeedActivate/image", false},          // GraphicsPatch
-    {"DatabaseNeedActivate/loadscreen", false},     // GraphicsPatch
-    {"DatabaseNeedActivate/texture", false},        // GraphicsPatch
-    {"DatabaseNeedActivate/sound", false},          // SoundsPatch
-    {"DatabaseNeedActivate/video", false},          // VideosPatch
-    {"DatabaseNeedActivate/micro", false},          // MircoPatch
+    // Localisation components, showed and edited by user in GUI
 
-    // Localisation components
     {"Components/texts_main", false},          // TextsPatch
     {"Components/texts_items", false},         // TextsPatch
     {"Components/texts_emotes", false},        // TextsPatch
@@ -66,7 +57,8 @@ QMap<QString, QVariant> defaults = {
     {"Components/videos", false},              // VideosPatch
     {"Components/micropatch", false},          // PatchList
 
-    // Network
+    // Network settings
+
     {"Network/site_url", "http://translate.lotros.ru/"},
     {"Network/forum_url", "http://lotros.ru/"},
     {"Network/discord_url", "https://discord.gg/j25MdKR"},

+ 12 - 12
src/Legacy/widgets/mainwindow.cpp

@@ -59,9 +59,9 @@ MainWindow::MainWindow(PatchList *legacy_patches, QWidget *parent)
     ui->content_layout->addWidget(about_widget_);
 
     // Adding patch update triggers on settings state changes
-    connect(settings_widget_, &SettingsWidget::SettingsChanged, legacy_patches_, &PatchList::stopAutoUpdate);
-    connect(settings_widget_, &SettingsWidget::SettingsReset, legacy_patches_, &PatchList::startAutoUpdate);
-    connect(settings_widget_, &SettingsWidget::SettingsApplied, legacy_patches_, &PatchList::initialize);
+//    connect(settings_widget_, &SettingsWidget::SettingsChanged, legacy_patches_, &PatchList::stopAutoUpdate);
+//    connect(settings_widget_, &SettingsWidget::SettingsReset, legacy_patches_, &PatchList::startAutoUpdate);
+//    connect(settings_widget_, &SettingsWidget::SettingsApplied, legacy_patches_, &PatchList::initialize);
 
 
     hideAllContentWidgets();
@@ -69,10 +69,10 @@ MainWindow::MainWindow(PatchList *legacy_patches, QWidget *parent)
 
     qDebug() << __FUNCTION__ << "Initialising additional frames...";
 
-    choose_locale_dialog_ = new ChooseVersionDialog(legacy_patches_->getManager(), this);
-    choose_locale_dialog_->resize(size());
-    choose_locale_dialog_->hide();
-    connect(choose_locale_dialog_, &ChooseVersionDialog::cancelled, choose_locale_dialog_, &ChooseVersionDialog::hide);
+//    choose_locale_dialog_ = new ChooseVersionDialog(legacy_patches_->getManager(), this);
+//    choose_locale_dialog_->resize(size());
+//    choose_locale_dialog_->hide();
+//    connect(choose_locale_dialog_, &ChooseVersionDialog::cancelled, choose_locale_dialog_, &ChooseVersionDialog::hide);
 
     dialog_window_ = new DialogWindow(this);
     dialog_window_->resize(size());
@@ -143,13 +143,13 @@ void MainWindow::resizeEvent(QResizeEvent * event)
     ui->content_area->move(0, height * 110 / default_window_height);
     ui->content_area->resize(width * 1000 / default_window_width, height * 530 / default_window_height);
     setupWindowBackgroundAndMask(current_bg_);
-    choose_locale_dialog_->resize(event->size());
+//    choose_locale_dialog_->resize(event->size());
 
     ui->closeButton->setMinimumSize(width * 20 / default_window_width, height * 20 / default_window_height);
     ui->minimizeButton->setMinimumSize(width * 20 / default_window_width, height * 20 / default_window_height);
 
-    choose_locale_dialog_->move({0, 0});
-    choose_locale_dialog_->resize(event->size());
+//    choose_locale_dialog_->move({0, 0});
+//    choose_locale_dialog_->resize(event->size());
 
     dialog_window_->move({0, 0});
     dialog_window_->resize(size());
@@ -382,13 +382,13 @@ void MainWindow::showChooseVersionDialog()
 //    effect->setBlurRadius(10);
 //    effect->setBlurHints(QGraphicsBlurEffect::QualityHint);
 //    ui->content_area->setGraphicsEffect(effect);
-    choose_locale_dialog_->show();
+//    choose_locale_dialog_->show();
 }
 
 void MainWindow::hideChooseVersionDialog()
 {
 //    ui->content_area->setGraphicsEffect(nullptr);
-    choose_locale_dialog_->hide();
+//    choose_locale_dialog_->hide();
 }
 
 void MainWindow::onErrorStatusChanged(AppErrorStatus status)

+ 1 - 1
src/Legacy/widgets/serverstatuswidget.cpp

@@ -49,7 +49,7 @@ void ServerStatusWidget::updateFontsSizes()
     }
 }
 
-void ServerStatusWidget::resizeEvent(QResizeEvent *event)
+void ServerStatusWidget::resizeEvent(QResizeEvent*)
 {
     updateFontsSizes();
 }

+ 4 - 4
src/Legacy/widgets/settingswidget.cpp

@@ -38,10 +38,10 @@ SettingsWidget::SettingsWidget(PatchList *legacy_patches, QWidget *parent)
 //    ui->content_scroll_area->verticalScrollBar()->installEventFilter(scroller);
 
     ui->patch_installing_label->hide();
-    connect(legacy_patches, &PatchList::patchOperationsStarted, this, &SettingsWidget::onPatchTotalOperationsStarted);
-    connect(legacy_patches, &PatchList::patchOperationsFinished, this, &SettingsWidget::onPatchTotalOperationsFinished);
-    connect(legacy_patches, &PatchList::backupSettingsInfoChanged, this, &SettingsWidget::onBackupSettingsInfoChanged);
-    connect(legacy_patches->getManager(), &LotroDatManager::statusChanged, this, &SettingsWidget::onLotroManagerProcessChanged);
+//    connect(legacy_patches, &PatchList::patchOperationsStarted, this, &SettingsWidget::onPatchTotalOperationsStarted);
+//    connect(legacy_patches, &PatchList::patchOperationsFinished, this, &SettingsWidget::onPatchTotalOperationsFinished);
+//    connect(legacy_patches, &PatchList::backupSettingsInfoChanged, this, &SettingsWidget::onBackupSettingsInfoChanged);
+//    connect(legacy_patches->getManager(), &LotroDatManager::statusChanged, this, &SettingsWidget::onLotroManagerProcessChanged);
 
     ui->apply_changes_button->hide();
     ui->apply_changes_label->hide();

+ 3 - 3
src/Legacy/widgets/statuswidget.cpp

@@ -32,9 +32,9 @@ StatusWidget::StatusWidget(PatchList *legacy_patches, QWidget *parent)
     connect(ui->server_status_widget, &ServerStatusWidget::showServersTooltip, this, [this](QString message){setToolTipMessage(message, E_INFO);});
     connect(ui->server_status_widget, &ServerStatusWidget::showNoTooltip, this, [this](){unsetToolTipMessage(E_INFO);});
 
-    connect(legacy_patches_, &PatchList::patchOperationsStarted, this, &StatusWidget::onPatchTotalOperationsStarted);
-    connect(legacy_patches_, &PatchList::patchOperationsFinished, this, &StatusWidget::onPatchTotalOperationsFinished);
-    connect(legacy_patches_, &PatchList::progressChanged, this, &StatusWidget::updatePatchProgressStatus);
+//    connect(legacy_patches_, &PatchList::patchOperationsStarted, this, &StatusWidget::onPatchTotalOperationsStarted);
+//    connect(legacy_patches_, &PatchList::patchOperationsFinished, this, &StatusWidget::onPatchTotalOperationsFinished);
+//    connect(legacy_patches_, &PatchList::progressChanged, this, &StatusWidget::updatePatchProgressStatus);
 
     generateRandomTooltipMessage();
     random_tooltip_generator_timer_.setInterval(5 * 1000);