From 9c40e448b6077f99a5296edf2cdb1fb86d91016e Mon Sep 17 00:00:00 2001 From: derrod Date: Tue, 12 Apr 2022 10:10:00 +0200 Subject: [PATCH] UI: Add File Integrity Check --- UI/data/locale/en-US.ini | 5 ++++ UI/forms/OBSBasic.ui | 6 ++++ UI/win-update/win-update.cpp | 54 +++++++++++++++++++++++++++--------- UI/win-update/win-update.hpp | 8 +++++- UI/window-basic-main.cpp | 24 +++++++++++++++- UI/window-basic-main.hpp | 1 + 6 files changed, 83 insertions(+), 15 deletions(-) diff --git a/UI/data/locale/en-US.ini b/UI/data/locale/en-US.ini index 141774a1f..06562c37e 100644 --- a/UI/data/locale/en-US.ini +++ b/UI/data/locale/en-US.ini @@ -261,6 +261,10 @@ Updater.Running.Title="Program currently active" Updater.Running.Text="Outputs are currently active, please shut down any active outputs before attempting to update" Updater.NoUpdatesAvailable.Title="No updates available" Updater.NoUpdatesAvailable.Text="No updates are currently available" +Updater.RepairButUpdatesAvailable.Title="Integrity Check Unavailable" +Updater.RepairButUpdatesAvailable.Text="Checking file integrity is only possible for the latest version available. Use Help → Check For Updates to verify and update your OBS installation." +Updater.RepairConfirm.Title="Confirm Integrity Check" +Updater.RepairConfirm.Text="Starting the integrity check will scan your OBS installation for corruption and redownload broken/modified files. This may take a moment.\n\nDo you wish to proceed?" Updater.FailedToLaunch="Failed to launch updater" Updater.GameCaptureActive.Title="Game capture active" Updater.GameCaptureActive.Text="Game capture hook library is currently in use. Please close any games/programs being captured (or restart Windows) and try again." @@ -781,6 +785,7 @@ Basic.MainMenu.Help.Logs.UploadCurrentLog="Upload &Current Log File" Basic.MainMenu.Help.Logs.UploadLastLog="Upload &Previous Log File" Basic.MainMenu.Help.Logs.ViewCurrentLog="&View Current Log" Basic.MainMenu.Help.CheckForUpdates="Check For Updates" +Basic.MainMenu.Help.Repair="Check File Integrity" Basic.MainMenu.Help.CrashLogs="Crash &Reports" Basic.MainMenu.Help.CrashLogs.ShowLogs="&Show Crash Reports" Basic.MainMenu.Help.CrashLogs.UploadLastLog="Upload &Previous Crash Report" diff --git a/UI/forms/OBSBasic.ui b/UI/forms/OBSBasic.ui index 514d07aa3..a73aec550 100644 --- a/UI/forms/OBSBasic.ui +++ b/UI/forms/OBSBasic.ui @@ -532,6 +532,7 @@ + @@ -1913,6 +1914,11 @@ Basic.MainMenu.Help.CheckForUpdates + + + Basic.MainMenu.Help.Repair + + Interact diff --git a/UI/win-update/win-update.cpp b/UI/win-update/win-update.cpp index 56a7134e8..7619aa6ea 100644 --- a/UI/win-update/win-update.cpp +++ b/UI/win-update/win-update.cpp @@ -511,6 +511,25 @@ int AutoUpdateThread::queryUpdate(bool localManualUpdate, const char *text_utf8) return ret; } +bool AutoUpdateThread::queryRepairSlot() +{ + QMessageBox::StandardButton res = OBSMessageBox::question( + App()->GetMainWindow(), QTStr("Updater.RepairConfirm.Title"), + QTStr("Updater.RepairConfirm.Text"), + QMessageBox::Yes | QMessageBox::Cancel); + + return res == QMessageBox::Yes; +} + +bool AutoUpdateThread::queryRepair() +{ + bool ret = false; + QMetaObject::invokeMethod(this, "queryRepairSlot", + Qt::BlockingQueuedConnection, + Q_RETURN_ARG(bool, ret)); + return ret; +} + void AutoUpdateThread::run() try { long responseCode; @@ -615,11 +634,15 @@ try { if (!success) throw string("Failed to parse manifest"); - if (!updatesAvailable) { + if (!updatesAvailable && !repairMode) { if (manualUpdate) info(QTStr("Updater.NoUpdatesAvailable.Title"), QTStr("Updater.NoUpdatesAvailable.Text")); return; + } else if (updatesAvailable && repairMode) { + info(QTStr("Updater.RepairButUpdatesAvailable.Title"), + QTStr("Updater.RepairButUpdatesAvailable.Text")); + return; } /* ----------------------------------- * @@ -627,7 +650,7 @@ try { int skipUpdateVer = config_get_int(GetGlobalConfig(), "General", "SkipUpdateVersion"); - if (!manualUpdate && updateVer == skipUpdateVer) + if (!manualUpdate && updateVer == skipUpdateVer && !repairMode) return; /* ----------------------------------- * @@ -639,20 +662,25 @@ try { /* ----------------------------------- * * query user for update */ - int queryResult = queryUpdate(manualUpdate, notes.c_str()); + if (repairMode) { + if (!queryRepair()) + return; + } else { + int queryResult = queryUpdate(manualUpdate, notes.c_str()); - if (queryResult == OBSUpdate::No) { - if (!manualUpdate) { - long long t = (long long)time(nullptr); + if (queryResult == OBSUpdate::No) { + if (!manualUpdate) { + long long t = (long long)time(nullptr); + config_set_int(GetGlobalConfig(), "General", + "LastUpdateCheck", t); + } + return; + + } else if (queryResult == OBSUpdate::Skip) { config_set_int(GetGlobalConfig(), "General", - "LastUpdateCheck", t); + "SkipUpdateVersion", updateVer); + return; } - return; - - } else if (queryResult == OBSUpdate::Skip) { - config_set_int(GetGlobalConfig(), "General", - "SkipUpdateVersion", updateVer); - return; } /* ----------------------------------- * diff --git a/UI/win-update/win-update.hpp b/UI/win-update/win-update.hpp index 1e450a6ea..a9e944c59 100644 --- a/UI/win-update/win-update.hpp +++ b/UI/win-update/win-update.hpp @@ -7,19 +7,25 @@ class AutoUpdateThread : public QThread { Q_OBJECT bool manualUpdate; + bool repairMode; bool user_confirmed = false; virtual void run() override; void info(const QString &title, const QString &text); int queryUpdate(bool manualUpdate, const char *text_utf8); + bool queryRepair(); private slots: void infoMsg(const QString &title, const QString &text); int queryUpdateSlot(bool manualUpdate, const QString &text); + bool queryRepairSlot(); public: - AutoUpdateThread(bool manualUpdate_) : manualUpdate(manualUpdate_) {} + AutoUpdateThread(bool manualUpdate_, bool repairMode_ = false) + : manualUpdate(manualUpdate_), repairMode(repairMode_) + { + } }; class WhatsNewInfoThread : public QThread { diff --git a/UI/window-basic-main.cpp b/UI/window-basic-main.cpp index b0bd1ea5b..ca01c7403 100644 --- a/UI/window-basic-main.cpp +++ b/UI/window-basic-main.cpp @@ -2025,9 +2025,11 @@ void OBSBasic::OBSInit() delete ui->actionShowCrashLogs; delete ui->actionUploadLastCrashLog; delete ui->menuCrashLogs; + delete ui->actionRepair; ui->actionShowCrashLogs = nullptr; ui->actionUploadLastCrashLog = nullptr; ui->menuCrashLogs = nullptr; + ui->actionRepair = nullptr; #if !defined(__APPLE__) delete ui->actionCheckForUpdates; ui->actionCheckForUpdates = nullptr; @@ -2041,8 +2043,12 @@ void OBSBasic::OBSInit() #endif #if defined(_WIN32) || defined(__APPLE__) - if (App()->IsUpdaterDisabled()) + if (App()->IsUpdaterDisabled()) { ui->actionCheckForUpdates->setEnabled(false); +#if defined(_WIN32) + ui->actionRepair->setEnabled(false); +#endif + } #endif OnFirstLoad(); @@ -3666,6 +3672,7 @@ void OBSBasic::CheckForUpdates(bool manualUpdate) trigger_sparkle_update(); #elif _WIN32 ui->actionCheckForUpdates->setEnabled(false); + ui->actionRepair->setEnabled(false); if (updateCheckThread && updateCheckThread->isRunning()) return; @@ -3680,6 +3687,7 @@ void OBSBasic::CheckForUpdates(bool manualUpdate) void OBSBasic::updateCheckFinished() { ui->actionCheckForUpdates->setEnabled(true); + ui->actionRepair->setEnabled(true); } void OBSBasic::DuplicateSelectedScene() @@ -6112,6 +6120,20 @@ void OBSBasic::on_actionCheckForUpdates_triggered() CheckForUpdates(true); } +void OBSBasic::on_actionRepair_triggered() +{ +#if defined(_WIN32) + ui->actionCheckForUpdates->setEnabled(false); + ui->actionRepair->setEnabled(false); + + if (updateCheckThread && updateCheckThread->isRunning()) + return; + + updateCheckThread.reset(new AutoUpdateThread(false, true)); + updateCheckThread->start(); +#endif +} + void OBSBasic::logUploadFinished(const QString &text, const QString &error) { ui->menuLogFiles->setEnabled(true); diff --git a/UI/window-basic-main.hpp b/UI/window-basic-main.hpp index 0221bcab1..d16dad7cd 100644 --- a/UI/window-basic-main.hpp +++ b/UI/window-basic-main.hpp @@ -985,6 +985,7 @@ private slots: void on_actionUploadLastLog_triggered(); void on_actionViewCurrentLog_triggered(); void on_actionCheckForUpdates_triggered(); + void on_actionRepair_triggered(); void on_actionShowCrashLogs_triggered(); void on_actionUploadLastCrashLog_triggered();