aboutsummaryrefslogtreecommitdiff
path: root/launcher/updater/UpdateChecker.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'launcher/updater/UpdateChecker.cpp')
-rw-r--r--launcher/updater/UpdateChecker.cpp296
1 files changed, 0 insertions, 296 deletions
diff --git a/launcher/updater/UpdateChecker.cpp b/launcher/updater/UpdateChecker.cpp
deleted file mode 100644
index 78d979ff..00000000
--- a/launcher/updater/UpdateChecker.cpp
+++ /dev/null
@@ -1,296 +0,0 @@
-/* Copyright 2013-2021 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "UpdateChecker.h"
-
-#include <QJsonObject>
-#include <QJsonArray>
-#include <QJsonValue>
-#include <QDebug>
-
-#define API_VERSION 0
-#define CHANLIST_FORMAT 0
-
-#include "BuildConfig.h"
-
-UpdateChecker::UpdateChecker(shared_qobject_ptr<QNetworkAccessManager> nam, QString channelUrl, QString currentChannel)
-{
- m_network = nam;
- m_channelUrl = channelUrl;
- m_currentChannel = currentChannel;
-
-#ifdef Q_OS_MAC
- m_externalUpdater = new MacSparkleUpdater();
-#endif
-}
-
-QList<UpdateChecker::ChannelListEntry> UpdateChecker::getChannelList() const
-{
- return m_channels;
-}
-
-bool UpdateChecker::hasChannels() const
-{
- return !m_channels.isEmpty();
-}
-
-ExternalUpdater* UpdateChecker::getExternalUpdater()
-{
- return m_externalUpdater;
-}
-
-void UpdateChecker::checkForUpdate(const QString& updateChannel, bool notifyNoUpdate)
-{
- if (m_externalUpdater)
- {
- m_externalUpdater->setBetaAllowed(updateChannel == "beta");
- if (notifyNoUpdate)
- {
- qDebug() << "Checking for updates.";
- m_externalUpdater->checkForUpdates();
- } else
- {
- // The updater library already handles automatic update checks.
- return;
- }
- }
- else
- {
- qDebug() << "Checking for updates.";
- // If the channel list hasn't loaded yet, load it and defer checking for updates until
- // later.
- if (!m_chanListLoaded)
- {
- qDebug() << "Channel list isn't loaded yet. Loading channel list and deferring update check.";
- m_checkUpdateWaiting = true;
- m_deferredUpdateChannel = updateChannel;
- updateChanList(notifyNoUpdate);
- return;
- }
-
- if (m_updateChecking)
- {
- qDebug() << "Ignoring update check request. Already checking for updates.";
- return;
- }
-
- // Find the desired channel within the channel list and get its repo URL. If if cannot be
- // found, error.
- QString stableUrl;
- m_newRepoUrl = "";
- for (ChannelListEntry entry: m_channels)
- {
- qDebug() << "channelEntry = " << entry.id;
- if (entry.id == "stable")
- {
- stableUrl = entry.url;
- }
- if (entry.id == updateChannel)
- {
- m_newRepoUrl = entry.url;
- qDebug() << "is intended update channel: " << entry.id;
- }
- if (entry.id == m_currentChannel)
- {
- m_currentRepoUrl = entry.url;
- qDebug() << "is current update channel: " << entry.id;
- }
- }
-
- qDebug() << "m_repoUrl = " << m_newRepoUrl;
-
- if (m_newRepoUrl.isEmpty())
- {
- qWarning() << "m_repoUrl was empty. defaulting to 'stable': " << stableUrl;
- m_newRepoUrl = stableUrl;
- }
-
- // If nothing applies, error
- if (m_newRepoUrl.isEmpty())
- {
- qCritical() << "failed to select any update repository for: " << updateChannel;
- emit updateCheckFailed();
- return;
- }
-
- m_updateChecking = true;
-
- QUrl indexUrl = QUrl(m_newRepoUrl).resolved(QUrl("index.json"));
-
- indexJob = new NetJob("GoUpdate Repository Index", m_network);
- indexJob->addNetAction(Net::Download::makeByteArray(indexUrl, &indexData));
- connect(indexJob.get(), &NetJob::succeeded, [this, notifyNoUpdate]() { updateCheckFinished(notifyNoUpdate); });
- connect(indexJob.get(), &NetJob::failed, this, &UpdateChecker::updateCheckFailed);
- indexJob->start();
- }
-}
-
-void UpdateChecker::updateCheckFinished(bool notifyNoUpdate)
-{
- qDebug() << "Finished downloading repo index. Checking for new versions.";
-
- QJsonParseError jsonError;
- indexJob.reset();
-
- QJsonDocument jsonDoc = QJsonDocument::fromJson(indexData, &jsonError);
- indexData.clear();
- if (jsonError.error != QJsonParseError::NoError || !jsonDoc.isObject())
- {
- qCritical() << "Failed to parse GoUpdate repository index. JSON error"
- << jsonError.errorString() << "at offset" << jsonError.offset;
- m_updateChecking = false;
- return;
- }
-
- QJsonObject object = jsonDoc.object();
-
- bool success = false;
- int apiVersion = object.value("ApiVersion").toVariant().toInt(&success);
- if (apiVersion != API_VERSION || !success)
- {
- qCritical() << "Failed to check for updates. API version mismatch. We're using"
- << API_VERSION << "server has" << apiVersion;
- m_updateChecking = false;
- return;
- }
-
- qDebug() << "Processing repository version list.";
- QJsonObject newestVersion;
- QJsonArray versions = object.value("Versions").toArray();
- for (QJsonValue versionVal : versions)
- {
- QJsonObject version = versionVal.toObject();
- if (newestVersion.value("Id").toVariant().toInt() <
- version.value("Id").toVariant().toInt())
- {
- newestVersion = version;
- }
- }
-
- // We've got the version with the greatest ID number. Now compare it to our current build
- // number and update if they're different.
- int newBuildNumber = newestVersion.value("Id").toVariant().toInt();
- if (newBuildNumber != m_currentBuild)
- {
- qDebug() << "Found newer version with ID" << newBuildNumber;
- // Update!
- GoUpdate::Status updateStatus;
- updateStatus.updateAvailable = true;
- updateStatus.currentVersionId = m_currentBuild;
- updateStatus.currentRepoUrl = m_currentRepoUrl;
- updateStatus.newVersionId = newBuildNumber;
- updateStatus.newRepoUrl = m_newRepoUrl;
- emit updateAvailable(updateStatus);
- }
- else if (notifyNoUpdate)
- {
- emit noUpdateFound();
- }
- m_updateChecking = false;
-}
-
-void UpdateChecker::updateCheckFailed()
-{
- qCritical() << "Update check failed for reasons unknown.";
-}
-
-void UpdateChecker::updateChanList(bool notifyNoUpdate)
-{
- qDebug() << "Loading the channel list.";
-
- if (m_chanListLoading)
- {
- qDebug() << "Ignoring channel list update request. Already grabbing channel list.";
- return;
- }
-
- m_chanListLoading = true;
- chanListJob = new NetJob("Update System Channel List", m_network);
- chanListJob->addNetAction(Net::Download::makeByteArray(QUrl(m_channelUrl), &chanlistData));
- connect(chanListJob.get(), &NetJob::succeeded, [this, notifyNoUpdate]() { chanListDownloadFinished(notifyNoUpdate); });
- connect(chanListJob.get(), &NetJob::failed, this, &UpdateChecker::chanListDownloadFailed);
- chanListJob->start();
-}
-
-void UpdateChecker::chanListDownloadFinished(bool notifyNoUpdate)
-{
- chanListJob.reset();
-
- QJsonParseError jsonError;
- QJsonDocument jsonDoc = QJsonDocument::fromJson(chanlistData, &jsonError);
- chanlistData.clear();
- if (jsonError.error != QJsonParseError::NoError)
- {
- // TODO: Report errors to the user.
- qCritical() << "Failed to parse channel list JSON:" << jsonError.errorString() << "at" << jsonError.offset;
- m_chanListLoading = false;
- return;
- }
-
- QJsonObject object = jsonDoc.object();
-
- bool success = false;
- int formatVersion = object.value("format_version").toVariant().toInt(&success);
- if (formatVersion != CHANLIST_FORMAT || !success)
- {
- qCritical()
- << "Failed to check for updates. Channel list format version mismatch. We're using"
- << CHANLIST_FORMAT << "server has" << formatVersion;
- m_chanListLoading = false;
- return;
- }
-
- // Load channels into a temporary array.
- QList<ChannelListEntry> loadedChannels;
- QJsonArray channelArray = object.value("channels").toArray();
- for (QJsonValue chanVal : channelArray)
- {
- QJsonObject channelObj = chanVal.toObject();
- ChannelListEntry entry {
- channelObj.value("id").toVariant().toString(),
- channelObj.value("name").toVariant().toString(),
- channelObj.value("description").toVariant().toString(),
- channelObj.value("url").toVariant().toString()
- };
- if (entry.id.isEmpty() || entry.name.isEmpty() || entry.url.isEmpty())
- {
- qCritical() << "Channel list entry with empty ID, name, or URL. Skipping.";
- continue;
- }
- loadedChannels.append(entry);
- }
-
- // Swap the channel list we just loaded into the object's channel list.
- m_channels.swap(loadedChannels);
-
- m_chanListLoading = false;
- m_chanListLoaded = true;
- qDebug() << "Successfully loaded UpdateChecker channel list.";
-
- // If we're waiting to check for updates, do that now.
- if (m_checkUpdateWaiting) {
- checkForUpdate(m_deferredUpdateChannel, notifyNoUpdate);
- }
-
- emit channelListLoaded();
-}
-
-void UpdateChecker::chanListDownloadFailed(QString reason)
-{
- m_chanListLoading = false;
- qCritical() << QString("Failed to download channel list: %1").arg(reason);
- emit channelListLoaded();
-}
-