feat(updater): tie in part 2, let there be UI!
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
This commit is contained in:
parent
b7dd32274c
commit
1f70589deb
@ -122,6 +122,7 @@
|
||||
#include <FileSystem.h>
|
||||
#include <LocalPeer.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <sys.h>
|
||||
|
||||
#ifdef Q_OS_LINUX
|
||||
@ -397,6 +398,7 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv)
|
||||
.arg(dataPath));
|
||||
return;
|
||||
}
|
||||
m_dataPath = dataPath;
|
||||
|
||||
/*
|
||||
* Establish the mechanism for communication with an already running PrismLauncher that uses the same data path.
|
||||
@ -829,7 +831,7 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv)
|
||||
#ifdef Q_OS_MAC
|
||||
m_updater.reset(new MacSparkleUpdater());
|
||||
#else
|
||||
m_updater.reset(new PrismExternalUpdater(m_rootPath, dataPath));
|
||||
m_updater.reset(new PrismExternalUpdater(m_rootPath, m_dataPath));
|
||||
#endif
|
||||
qDebug() << "<> Updater started.";
|
||||
}
|
||||
@ -1024,9 +1026,120 @@ void Application::setupWizardFinished(int status)
|
||||
performMainStartupAction();
|
||||
}
|
||||
|
||||
std::tuple<QDateTime, QString, QString, QString, QString> read_lock_File(const QString& path)
|
||||
{
|
||||
auto contents = QString(FS::read(path));
|
||||
auto lines = contents.split('\n');
|
||||
|
||||
QDateTime timestamp;
|
||||
QString from, to, target, data_path;
|
||||
for (auto line : lines) {
|
||||
auto index = line.indexOf("=");
|
||||
if (index < 0)
|
||||
continue;
|
||||
auto left = line.left(index);
|
||||
auto right = line.mid(index + 1);
|
||||
if (left.toLower() == "timestamp") {
|
||||
timestamp = QDateTime::fromString(right, Qt::ISODate);
|
||||
} else if (left.toLower() == "from") {
|
||||
from = right;
|
||||
} else if (left.toLower() == "to") {
|
||||
to = right;
|
||||
} else if (left.toLower() == "target") {
|
||||
target = right;
|
||||
} else if (left.toLower() == "data_path") {
|
||||
data_path = right;
|
||||
}
|
||||
}
|
||||
return std::make_tuple(timestamp, from, to, target, data_path);
|
||||
}
|
||||
|
||||
void Application::performMainStartupAction()
|
||||
{
|
||||
m_status = Application::Initialized;
|
||||
|
||||
auto update_log_path = FS::PathCombine(m_dataPath, "prism_launcher_update.log");
|
||||
|
||||
auto update_lock = QFileInfo(FS::PathCombine(m_dataPath, ".prism_launcher_update.lock"));
|
||||
if (update_lock.exists()) {
|
||||
auto [timestamp, from, to, target, data_path] = read_lock_File(update_lock.absoluteFilePath());
|
||||
auto infoMsg = tr("This installation has a update lock file present at: %1\n"
|
||||
"\n"
|
||||
"Timestamp: %2\n"
|
||||
"Updating from version %3 to %4\n"
|
||||
"Target install path: %5\n"
|
||||
"Data Path: %6"
|
||||
"\n"
|
||||
"This likely means that a update attempt failed. Please ensure your installation is in working order before "
|
||||
"proceeding.\n"
|
||||
"Check the Prism Launcher updater log at: \n"
|
||||
"%7\n"
|
||||
"for details on the last update attempt.\n"
|
||||
"\n"
|
||||
"To delete this lock and proceed select \"Ignore\" below.")
|
||||
.arg(update_lock.absoluteFilePath())
|
||||
.arg(timestamp.toString(Qt::ISODate), from, to, target, data_path)
|
||||
.arg(update_log_path);
|
||||
auto msgBox = QMessageBox(QMessageBox::Warning, tr("Update In Progress"), infoMsg, QMessageBox::Ignore | QMessageBox::Abort);
|
||||
msgBox.setDefaultButton(QMessageBox::Abort);
|
||||
msgBox.setModal(true);
|
||||
switch (msgBox.exec()) {
|
||||
case QMessageBox::AcceptRole: {
|
||||
FS::deletePath(update_lock.absoluteFilePath());
|
||||
break;
|
||||
}
|
||||
case QMessageBox::RejectRole:
|
||||
[[fallthrough]];
|
||||
default: {
|
||||
qDebug() << "Exiting because update lockfile is present";
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto update_fail_marker = QFileInfo(FS::PathCombine(m_dataPath, ".prism_launcher_update.fail"));
|
||||
if (update_fail_marker.exists()) {
|
||||
auto infoMsg = tr("An update attempt failed\n"
|
||||
"\n"
|
||||
"Please ensure your installation is in working order before "
|
||||
"proceeding.\n"
|
||||
"Check the Prism Launcher updater log at: \n"
|
||||
"%1\n"
|
||||
"for details on the last update attempt.")
|
||||
.arg(update_log_path);
|
||||
auto msgBox = QMessageBox(QMessageBox::Warning, tr("Update Failed"), infoMsg, QMessageBox::Ignore | QMessageBox::Abort);
|
||||
msgBox.setDefaultButton(QMessageBox::Abort);
|
||||
msgBox.setModal(true);
|
||||
switch (msgBox.exec()) {
|
||||
case QMessageBox::AcceptRole: {
|
||||
FS::deletePath(update_fail_marker.absoluteFilePath());
|
||||
break;
|
||||
}
|
||||
case QMessageBox::RejectRole:
|
||||
[[fallthrough]];
|
||||
default: {
|
||||
qDebug() << "Exiting because update lockfile is present";
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto update_success_marker = QFileInfo(FS::PathCombine(m_dataPath, ".prism_launcher_update.success"));
|
||||
if (update_success_marker.exists()) {
|
||||
auto infoMsg = tr("Update succeeded\n"
|
||||
"\n"
|
||||
"You are now running %1 .\n"
|
||||
"Check the Prism Launcher updater log at: \n"
|
||||
"%1\n"
|
||||
"for details.")
|
||||
.arg(BuildConfig.printableVersionString())
|
||||
.arg(update_log_path);
|
||||
auto msgBox = QMessageBox(QMessageBox::Information, tr("Update Succeeded"), infoMsg, QMessageBox::Ok);
|
||||
msgBox.setDefaultButton(QMessageBox::Ok);
|
||||
msgBox.open();
|
||||
FS::deletePath(update_success_marker.absoluteFilePath());
|
||||
}
|
||||
|
||||
if (!m_instanceIdToLaunch.isEmpty()) {
|
||||
auto inst = instances()->getInstanceById(m_instanceIdToLaunch);
|
||||
if (inst) {
|
||||
|
@ -187,6 +187,11 @@ public:
|
||||
return m_rootPath;
|
||||
}
|
||||
|
||||
/// the data path the application is using
|
||||
const QString& dataRoot() {
|
||||
return m_dataPath;
|
||||
}
|
||||
|
||||
bool isPortable() {
|
||||
return m_portable;
|
||||
}
|
||||
@ -277,6 +282,7 @@ private:
|
||||
QMap<QString, std::shared_ptr<BaseProfilerFactory>> m_profilers;
|
||||
|
||||
QString m_rootPath;
|
||||
QString m_dataPath;
|
||||
Status m_status = Application::StartingUp;
|
||||
Capabilities m_capabilities;
|
||||
bool m_portable = false;
|
||||
|
@ -1078,6 +1078,15 @@ SET(LAUNCHER_SOURCES
|
||||
ui/instanceview/VisualGroup.h
|
||||
)
|
||||
|
||||
if (NOT Apple)
|
||||
set(LAUNCHER_SOURCES
|
||||
${LAUNCHER_SOURCES}
|
||||
|
||||
ui/dialogs/UpdateAvailableDialog.h
|
||||
ui/dialogs/UpdateAvailableDialog.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
qt_wrap_ui(LAUNCHER_UI
|
||||
ui/MainWindow.ui
|
||||
ui/setupwizard/PasteWizardPage.ui
|
||||
@ -1138,6 +1147,14 @@ qt_wrap_ui(LAUNCHER_UI
|
||||
ui/dialogs/ChooseProviderDialog.ui
|
||||
)
|
||||
|
||||
qt_wrap_ui(PRISM_UPDATE_UI
|
||||
ui/dialogs/UpdateAvailableDialog.ui
|
||||
)
|
||||
|
||||
if (NOT Apple)
|
||||
set (LAUNCHER_UI ${LAUNCHER_UI} ${PRISM_UPDATE_UI})
|
||||
endif()
|
||||
|
||||
qt_add_resources(LAUNCHER_RESOURCES
|
||||
resources/backgrounds/backgrounds.qrc
|
||||
resources/multimc/multimc.qrc
|
||||
|
@ -199,7 +199,7 @@ void appendSafe(const QString& filename, const QByteArray& data)
|
||||
QByteArray buffer;
|
||||
try {
|
||||
buffer = read(filename);
|
||||
} catch (FileSystemException) {
|
||||
} catch (FileSystemException&) {
|
||||
buffer = QByteArray();
|
||||
}
|
||||
buffer.append(data);
|
||||
|
63
launcher/ui/dialogs/UpdateAvailableDialog.cpp
Normal file
63
launcher/ui/dialogs/UpdateAvailableDialog.cpp
Normal file
@ -0,0 +1,63 @@
|
||||
// SPDX-FileCopyrightText: 2023 Rachel Powers <508861+Ryex@users.noreply.github.com>
|
||||
//
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
/*
|
||||
* Prism Launcher - Minecraft Launcher
|
||||
* Copyright (C) 2023 Rachel Powers <508861+Ryex@users.noreply.github.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "UpdateAvailableDialog.h"
|
||||
#include <QPushButton>
|
||||
#include "Application.h"
|
||||
#include "BuildConfig.h"
|
||||
#include "Markdown.h"
|
||||
#include "ui_UpdateAvailableDialog.h"
|
||||
|
||||
UpdateAvailableDialog::UpdateAvailableDialog(const QString& currentVersion,
|
||||
const QString& availableVersion,
|
||||
const QString& releaseNotes,
|
||||
QWidget* parent)
|
||||
: QDialog(parent), ui(new Ui::UpdateAvailableDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
QString launcherName = BuildConfig.LAUNCHER_DISPLAYNAME;
|
||||
|
||||
ui->headerLabel->setText(tr("A new version of %1 is available!").arg(launcherName));
|
||||
ui->versionAvailableLabel->setText(
|
||||
tr("Version %1 is now available - you have %2 . Would you like to download it now?").arg(availableVersion).arg(currentVersion));
|
||||
ui->icon->setPixmap(APPLICATION->getThemedIcon("checkupdate").pixmap(64));
|
||||
|
||||
auto releaseNotesHtml = markdownToHTML(releaseNotes);
|
||||
ui->releaseNotes->setHtml(releaseNotesHtml);
|
||||
ui->releaseNotes->setOpenExternalLinks(true);
|
||||
|
||||
connect(ui->skipButton, &QPushButton::clicked, this, [this](){
|
||||
this->setResult(DialogCode::Skip);
|
||||
this->close();
|
||||
});
|
||||
|
||||
connect(ui->delayButton, &QPushButton::clicked, this, [this](){
|
||||
this->setResult(DialogCode::DontInstall);
|
||||
this->close();
|
||||
});
|
||||
|
||||
connect(ui->installButton, &QPushButton::clicked, this, [this](){
|
||||
this->setResult(DialogCode::Install);
|
||||
this->close();
|
||||
});
|
||||
}
|
49
launcher/ui/dialogs/UpdateAvailableDialog.h
Normal file
49
launcher/ui/dialogs/UpdateAvailableDialog.h
Normal file
@ -0,0 +1,49 @@
|
||||
// SPDX-FileCopyrightText: 2023 Rachel Powers <508861+Ryex@users.noreply.github.com>
|
||||
//
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
/*
|
||||
* Prism Launcher - Minecraft Launcher
|
||||
* Copyright (C) 2023 Rachel Powers <508861+Ryex@users.noreply.github.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
namespace Ui {
|
||||
class UpdateAvailableDialog;
|
||||
}
|
||||
|
||||
class UpdateAvailableDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
enum DialogCode {
|
||||
Install,
|
||||
DontInstall,
|
||||
Skip,
|
||||
};
|
||||
|
||||
explicit UpdateAvailableDialog(const QString& currentVersion,
|
||||
const QString& availableVersion,
|
||||
const QString& releaseNotes,
|
||||
QWidget* parent = 0);
|
||||
~UpdateAvailableDialog();
|
||||
|
||||
private:
|
||||
Ui::UpdateAvailableDialog* ui;
|
||||
};
|
155
launcher/ui/dialogs/UpdateAvailableDialog.ui
Normal file
155
launcher/ui/dialogs/UpdateAvailableDialog.ui
Normal file
@ -0,0 +1,155 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>UpdateAvailableDialog</class>
|
||||
<widget class="QDialog" name="UpdateAvailableDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>636</width>
|
||||
<height>352</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Update Available</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout" stretch="0,1">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="leftsideLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="icon">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>64</width>
|
||||
<height>64</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="mainLayout">
|
||||
<property name="leftMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="headerLabel">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>11</pointsize>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>A new version is available!</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="versionAvailableLabel">
|
||||
<property name="text">
|
||||
<string>Version %1 is now available - you have %2 . Would you like to download it now?</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="releaseNotesLabel">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Release Notes:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTextBrowser" name="releaseNotes"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QPushButton" name="skipButton">
|
||||
<property name="text">
|
||||
<string>Skip This Version</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="delayButton">
|
||||
<property name="text">
|
||||
<string>Remind Me Later</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="installButton">
|
||||
<property name="text">
|
||||
<string>Install Update</string>
|
||||
</property>
|
||||
<property name="default">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
@ -21,19 +21,22 @@
|
||||
*/
|
||||
|
||||
#include "PrismExternalUpdater.h"
|
||||
#include <memory>
|
||||
#include <QCoreApplication>
|
||||
#include <QDateTime>
|
||||
#include <QProgressDialog>
|
||||
#include <QDir>
|
||||
#include <QProcess>
|
||||
#include <QTimer>
|
||||
#include <QProgressDialog>
|
||||
#include <QSettings>
|
||||
#include <QCoreApplication>
|
||||
#include <QTimer>
|
||||
#include <memory>
|
||||
#include <QDebug>
|
||||
|
||||
#include "StringUtils.h"
|
||||
|
||||
#include "BuildConfig.h"
|
||||
|
||||
#include "ui/dialogs/UpdateAvailableDialog.h"
|
||||
|
||||
class PrismExternalUpdater::Private {
|
||||
public:
|
||||
QDir appDir;
|
||||
@ -78,12 +81,11 @@ PrismExternalUpdater::~PrismExternalUpdater()
|
||||
|
||||
void PrismExternalUpdater::checkForUpdates()
|
||||
{
|
||||
QProgressDialog progress(tr("Checking for updates..."), "", 0, -1);
|
||||
QProgressDialog progress(tr("Checking for updates..."), "", 0, 0);
|
||||
progress.setCancelButton(nullptr);
|
||||
progress.show();
|
||||
QCoreApplication::processEvents();
|
||||
|
||||
|
||||
QProcess proc;
|
||||
auto exe_name = QStringLiteral("%1_updater").arg(BuildConfig.LAUNCHER_APP_BINARY_NAME);
|
||||
#if defined Q_OS_WIN32
|
||||
@ -98,14 +100,16 @@ void PrismExternalUpdater::checkForUpdates()
|
||||
auto result_start = proc.waitForStarted(5000);
|
||||
if (!result_start) {
|
||||
auto err = proc.error();
|
||||
qDebug() << "Failed to start updater after 5 seconds." << "reason:" << err << proc.errorString();
|
||||
qDebug() << "Failed to start updater after 5 seconds."
|
||||
<< "reason:" << err << proc.errorString();
|
||||
}
|
||||
QCoreApplication::processEvents();
|
||||
|
||||
auto result_finished = proc.waitForFinished(60000);
|
||||
if (!result_finished) {
|
||||
auto err = proc.error();
|
||||
qDebug() << "Updater failed to close after 60 seconds." << "reason:" << err << proc.errorString();
|
||||
qDebug() << "Updater failed to close after 60 seconds."
|
||||
<< "reason:" << err << proc.errorString();
|
||||
}
|
||||
|
||||
auto exit_code = proc.exitCode();
|
||||
@ -116,6 +120,9 @@ void PrismExternalUpdater::checkForUpdates()
|
||||
qDebug() << "captured output:" << std_output;
|
||||
qDebug() << "captured error:" << std_error;
|
||||
|
||||
progress.hide();
|
||||
QCoreApplication::processEvents();
|
||||
|
||||
switch (exit_code) {
|
||||
case 0:
|
||||
// no update available
|
||||
@ -134,12 +141,14 @@ void PrismExternalUpdater::checkForUpdates()
|
||||
{
|
||||
auto [first_line, remainder1] = StringUtils::splitFirst(std_output, '\n');
|
||||
auto [second_line, remainder2] = StringUtils::splitFirst(remainder1, '\n');
|
||||
auto [third_line, changelog] = StringUtils::splitFirst(remainder2, '\n');
|
||||
auto [third_line, release_notes] = StringUtils::splitFirst(remainder2, '\n');
|
||||
auto version_name = StringUtils::splitFirst(first_line, ": ").second;
|
||||
auto version_tag = StringUtils::splitFirst(second_line, ": ").second;
|
||||
auto release_timestamp = QDateTime::fromString(StringUtils::splitFirst(third_line, ": ").second, Qt::ISODate);
|
||||
qDebug() << "Update available:" << version_name << version_tag << release_timestamp;
|
||||
qDebug() << "Update changelog:" << changelog;
|
||||
qDebug() << "Update release notes:" << release_notes;
|
||||
|
||||
offerUpdate(version_name, version_tag, release_notes);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@ -153,48 +162,55 @@ void PrismExternalUpdater::checkForUpdates()
|
||||
priv->settings->sync();
|
||||
}
|
||||
|
||||
bool PrismExternalUpdater::getAutomaticallyChecksForUpdates() {
|
||||
bool PrismExternalUpdater::getAutomaticallyChecksForUpdates()
|
||||
{
|
||||
return priv->autoCheck;
|
||||
}
|
||||
|
||||
double PrismExternalUpdater::getUpdateCheckInterval() {
|
||||
double PrismExternalUpdater::getUpdateCheckInterval()
|
||||
{
|
||||
return priv->updateInterval;
|
||||
}
|
||||
|
||||
bool PrismExternalUpdater::getBetaAllowed() {
|
||||
bool PrismExternalUpdater::getBetaAllowed()
|
||||
{
|
||||
return priv->allowBeta;
|
||||
}
|
||||
|
||||
void PrismExternalUpdater::setAutomaticallyChecksForUpdates(bool check) {
|
||||
void PrismExternalUpdater::setAutomaticallyChecksForUpdates(bool check)
|
||||
{
|
||||
priv->autoCheck = check;
|
||||
priv->settings->setValue("auto_check", check);
|
||||
priv->settings->sync();
|
||||
resetAutoCheckTimer();
|
||||
}
|
||||
|
||||
void PrismExternalUpdater::setUpdateCheckInterval(double seconds) {
|
||||
void PrismExternalUpdater::setUpdateCheckInterval(double seconds)
|
||||
{
|
||||
priv->updateInterval = seconds;
|
||||
priv->settings->setValue("update_interval", seconds);
|
||||
priv->settings->sync();
|
||||
resetAutoCheckTimer();
|
||||
}
|
||||
|
||||
void PrismExternalUpdater::setBetaAllowed(bool allowed) {
|
||||
void PrismExternalUpdater::setBetaAllowed(bool allowed)
|
||||
{
|
||||
priv->allowBeta = allowed;
|
||||
priv->settings->setValue("auto_beta", allowed);
|
||||
priv->settings->sync();
|
||||
}
|
||||
|
||||
void PrismExternalUpdater::resetAutoCheckTimer() {
|
||||
void PrismExternalUpdater::resetAutoCheckTimer()
|
||||
{
|
||||
int timeoutDuration = 0;
|
||||
auto now = QDateTime::currentDateTime();
|
||||
if (priv->autoCheck) {
|
||||
if (priv->lastCheck.isValid()) {
|
||||
if (priv->lastCheck.isValid()) {
|
||||
auto diff = priv->lastCheck.secsTo(now);
|
||||
auto secs_left = priv->updateInterval - diff;
|
||||
if (secs_left < 0)
|
||||
secs_left = 0;
|
||||
timeoutDuration = secs_left * 1000; // to msec
|
||||
timeoutDuration = secs_left * 1000; // to msec
|
||||
}
|
||||
qDebug() << "Auto update timer starting," << timeoutDuration / 1000 << "seconds left";
|
||||
priv->updateTimer.start(timeoutDuration);
|
||||
@ -202,18 +218,66 @@ void PrismExternalUpdater::resetAutoCheckTimer() {
|
||||
if (priv->updateTimer.isActive())
|
||||
priv->updateTimer.stop();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void PrismExternalUpdater::connectTimer() {
|
||||
void PrismExternalUpdater::connectTimer()
|
||||
{
|
||||
connect(&priv->updateTimer, &QTimer::timeout, this, &PrismExternalUpdater::autoCheckTimerFired);
|
||||
|
||||
}
|
||||
|
||||
void PrismExternalUpdater::disconnectTimer() {
|
||||
void PrismExternalUpdater::disconnectTimer()
|
||||
{
|
||||
disconnect(&priv->updateTimer, &QTimer::timeout, this, &PrismExternalUpdater::autoCheckTimerFired);
|
||||
}
|
||||
|
||||
void PrismExternalUpdater::autoCheckTimerFired() {
|
||||
void PrismExternalUpdater::autoCheckTimerFired()
|
||||
{
|
||||
checkForUpdates();
|
||||
}
|
||||
|
||||
void PrismExternalUpdater::offerUpdate(const QString& version_name, const QString& version_tag, const QString& release_notes)
|
||||
{
|
||||
priv->settings->beginGroup("skip");
|
||||
auto should_skip = priv->settings->value(version_tag, false).toBool();
|
||||
priv->settings->endGroup();
|
||||
|
||||
if (should_skip)
|
||||
return;
|
||||
|
||||
UpdateAvailableDialog dlg(BuildConfig.printableVersionString(), version_name, release_notes);
|
||||
|
||||
auto result = dlg.exec();
|
||||
switch (result) {
|
||||
case UpdateAvailableDialog::Install: {
|
||||
performUpdate(version_tag);
|
||||
}
|
||||
case UpdateAvailableDialog::Skip: {
|
||||
priv->settings->beginGroup("skip");
|
||||
priv->settings->setValue(version_tag, true);
|
||||
priv->settings->endGroup();
|
||||
priv->settings->sync();
|
||||
return;
|
||||
}
|
||||
case UpdateAvailableDialog::DontInstall: {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PrismExternalUpdater::performUpdate(const QString& version_tag) {
|
||||
QProcess proc;
|
||||
auto exe_name = QStringLiteral("%1_updater").arg(BuildConfig.LAUNCHER_APP_BINARY_NAME);
|
||||
#if defined Q_OS_WIN32
|
||||
exe_name.append(".exe");
|
||||
#endif
|
||||
|
||||
QStringList args = { "--dir", priv->dataDir.absolutePath(), "--install-version", version_tag };
|
||||
if (priv->allowBeta)
|
||||
args.append("--pre-release");
|
||||
|
||||
auto result = proc.startDetached(priv->appDir.absoluteFilePath(exe_name), args);
|
||||
if (!result) {
|
||||
qDebug() << "Failed to start updater:" << proc.error() << proc.errorString();
|
||||
}
|
||||
QCoreApplication::exit();
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ class PrismExternalUpdater : public ExternalUpdater {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
PrismExternalUpdater(const QString& appDir, const QString& dataDir);
|
||||
PrismExternalUpdater(const QString& appDir, const QString& dataDir);
|
||||
~PrismExternalUpdater() override;
|
||||
|
||||
/*!
|
||||
@ -82,7 +82,8 @@ class PrismExternalUpdater : public ExternalUpdater {
|
||||
void disconnectTimer();
|
||||
void connectTimer();
|
||||
|
||||
void performUpdate();
|
||||
void offerUpdate(const QString& version_name, const QString& version_tag, const QString& release_notes);
|
||||
void performUpdate(const QString& version_tag);
|
||||
|
||||
public slots:
|
||||
void autoCheckTimerFired();
|
||||
|
@ -630,7 +630,7 @@ void PrismUpdaterApp::moveAndFinishUpdate(QDir target)
|
||||
for (auto file : files) {
|
||||
file_list.append(file.trimmed());
|
||||
}
|
||||
} catch (FS::FileSystemException) {
|
||||
} catch (FS::FileSystemException&) {
|
||||
}
|
||||
}
|
||||
|
||||
@ -675,15 +675,23 @@ void PrismUpdaterApp::moveAndFinishUpdate(QDir target)
|
||||
if (error) {
|
||||
logUpdate(tr("There were errors installing the update."));
|
||||
auto fail_marker = FS::PathCombine(m_dataPath, ".prism_launcher_update.fail");
|
||||
FS::move(m_updateLogPath, fail_marker);
|
||||
FS::copy(m_updateLogPath, fail_marker)();
|
||||
} else {
|
||||
logUpdate(tr("Update succeed."));
|
||||
auto success_marker = FS::PathCombine(m_dataPath, ".prism_launcher_update.success");
|
||||
FS::move(m_updateLogPath, success_marker);
|
||||
FS::copy(m_updateLogPath, success_marker)();
|
||||
}
|
||||
auto update_lock_path = FS::PathCombine(m_dataPath, ".prism_launcher_update.lock");
|
||||
FS::deletePath(update_lock_path);
|
||||
|
||||
QProcess proc;
|
||||
auto app_exe_name = BuildConfig.LAUNCHER_APP_BINARY_NAME;
|
||||
#if defined Q_OS_WIN32
|
||||
app_exe_name.append(".exe");
|
||||
#endif
|
||||
auto app_exe_path = target.absoluteFilePath(app_exe_name);
|
||||
proc.startDetached(app_exe_path);
|
||||
|
||||
exit(error ? 1 : 0);
|
||||
}
|
||||
|
||||
@ -897,7 +905,7 @@ bool write_lock_file(const QString& path, QDateTime timestamp, QString from, QSt
|
||||
.arg(target)
|
||||
.arg(data_path)
|
||||
.toUtf8());
|
||||
} catch (FS::FileSystemException err) {
|
||||
} catch (FS::FileSystemException& err) {
|
||||
qWarning() << "Error writing lockfile:" << err.what() << "\n" << err.cause();
|
||||
return false;
|
||||
}
|
||||
@ -922,7 +930,7 @@ void PrismUpdaterApp::performInstall(QFileInfo file)
|
||||
"\n"
|
||||
"This likely means that a previous update attempt failed. Please ensure your installation is in working order before "
|
||||
"proceeding.\n"
|
||||
"Check the Prism Launcher updater log at \n"
|
||||
"Check the Prism Launcher updater log at: \n"
|
||||
"%7\n"
|
||||
"for details on the last update attempt.\n"
|
||||
"\n"
|
||||
@ -936,9 +944,9 @@ void PrismUpdaterApp::performInstall(QFileInfo file)
|
||||
msgBox.setStandardButtons(QMessageBox::Ignore | QMessageBox::Cancel);
|
||||
msgBox.setDefaultButton(QMessageBox::Cancel);
|
||||
switch (msgBox.exec()) {
|
||||
case QMessageBox::Ignore:
|
||||
case QMessageBox::AcceptRole:
|
||||
break;
|
||||
case QMessageBox::Cancel:
|
||||
case QMessageBox::RejectRole:
|
||||
[[fallthrough]];
|
||||
default:
|
||||
return showFatalErrorMessage(tr("Update Aborted"), tr("The update attempt was aborted"));
|
||||
@ -1005,7 +1013,7 @@ void PrismUpdaterApp::backupAppDir()
|
||||
for (auto file : files) {
|
||||
file_list.append(file.trimmed());
|
||||
}
|
||||
} catch (FS::FileSystemException) {
|
||||
} catch (FS::FileSystemException&) {
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user