GH-4014 change updater to recognize new Qt 5.15.2 builds

This commit is contained in:
Petr Mrázek 2021-09-04 21:27:09 +02:00
parent cd87029e6f
commit 938f896bfa
13 changed files with 141 additions and 26 deletions

View File

@ -64,7 +64,7 @@ set(MultiMC_VERSION_BUILD -1 CACHE STRING "Build number. -1 for no build number.
set(MultiMC_BUILD_PLATFORM "" CACHE STRING "A short string identifying the platform that this build was built for. Only used by the notification system and to display in the about dialog.") set(MultiMC_BUILD_PLATFORM "" CACHE STRING "A short string identifying the platform that this build was built for. Only used by the notification system and to display in the about dialog.")
# Channel list URL # Channel list URL
set(MultiMC_CHANLIST_URL "" CACHE STRING "URL for the channel list.") set(MultiMC_UPDATER_BASE "" CACHE STRING "Base URL for the updater.")
# Notification URL # Notification URL
set(MultiMC_NOTIFICATION_URL "" CACHE STRING "URL for checking for notifications.") set(MultiMC_NOTIFICATION_URL "" CACHE STRING "URL for checking for notifications.")

View File

@ -12,14 +12,14 @@ Config::Config()
VERSION_BUILD = @MultiMC_VERSION_BUILD@; VERSION_BUILD = @MultiMC_VERSION_BUILD@;
BUILD_PLATFORM = "@MultiMC_BUILD_PLATFORM@"; BUILD_PLATFORM = "@MultiMC_BUILD_PLATFORM@";
CHANLIST_URL = "@MultiMC_CHANLIST_URL@"; UPDATER_BASE = "@MultiMC_UPDATER_BASE@";
ANALYTICS_ID = "@MultiMC_ANALYTICS_ID@"; ANALYTICS_ID = "@MultiMC_ANALYTICS_ID@";
NOTIFICATION_URL = "@MultiMC_NOTIFICATION_URL@"; NOTIFICATION_URL = "@MultiMC_NOTIFICATION_URL@";
FULL_VERSION_STR = "@MultiMC_VERSION_MAJOR@.@MultiMC_VERSION_MINOR@.@MultiMC_VERSION_BUILD@"; FULL_VERSION_STR = "@MultiMC_VERSION_MAJOR@.@MultiMC_VERSION_MINOR@.@MultiMC_VERSION_BUILD@";
GIT_COMMIT = "@MultiMC_GIT_COMMIT@"; GIT_COMMIT = "@MultiMC_GIT_COMMIT@";
GIT_REFSPEC = "@MultiMC_GIT_REFSPEC@"; GIT_REFSPEC = "@MultiMC_GIT_REFSPEC@";
if(GIT_REFSPEC.startsWith("refs/heads/") && !CHANLIST_URL.isEmpty() && VERSION_BUILD >= 0) if(GIT_REFSPEC.startsWith("refs/heads/") && !UPDATER_BASE.isEmpty() && !BUILD_PLATFORM.isEmpty() && VERSION_BUILD >= 0)
{ {
VERSION_CHANNEL = GIT_REFSPEC; VERSION_CHANNEL = GIT_REFSPEC;
VERSION_CHANNEL.remove("refs/heads/"); VERSION_CHANNEL.remove("refs/heads/");

View File

@ -29,7 +29,7 @@ public:
QString BUILD_PLATFORM; QString BUILD_PLATFORM;
/// URL for the updater's channel /// URL for the updater's channel
QString CHANLIST_URL; QString UPDATER_BASE;
/// User-Agent to use. /// User-Agent to use.
QString USER_AGENT = "MultiMC/5.0"; QString USER_AGENT = "MultiMC/5.0";

View File

@ -91,7 +91,8 @@ using namespace Commandline;
"This usually fixes the problem and you can move the application elsewhere afterwards.\n"\ "This usually fixes the problem and you can move the application elsewhere afterwards.\n"\
"\n" "\n"
static void appDebugOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg) namespace {
void appDebugOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{ {
const char *levels = "DWCFIS"; const char *levels = "DWCFIS";
const QString format("%1 %2 %3\n"); const QString format("%1 %2 %3\n");
@ -111,6 +112,43 @@ static void appDebugOutput(QtMsgType type, const QMessageLogContext &context, co
fflush(stderr); fflush(stderr);
} }
QString getIdealPlatform(QString currentPlatform) {
auto info = Sys::getKernelInfo();
switch(info.kernelType) {
case Sys::KernelType::Darwin: {
if(info.kernelMajor >= 17) {
// macOS 10.13 or newer
return "osx64-5.15.2";
}
else {
// macOS 10.12 or older
return "osx64";
}
}
case Sys::KernelType::Windows: {
if(info.kernelMajor == 6 && info.kernelMinor >= 1) {
// Windows 7
return "win32-5.15.2";
}
else if (info.kernelMajor > 6) {
// Above Windows 7
return "win32-5.15.2";
}
else {
// Below Windows 7
return "win32";
}
}
case Sys::KernelType::Undetermined:
case Sys::KernelType::Linux: {
break;
}
}
return currentPlatform;
}
}
MultiMC::MultiMC(int &argc, char **argv) : QApplication(argc, argv) MultiMC::MultiMC(int &argc, char **argv) : QApplication(argc, argv)
{ {
#if defined Q_OS_WIN32 #if defined Q_OS_WIN32
@ -678,7 +716,10 @@ MultiMC::MultiMC(int &argc, char **argv) : QApplication(argc, argv)
// initialize the updater // initialize the updater
if(BuildConfig.UPDATER_ENABLED) if(BuildConfig.UPDATER_ENABLED)
{ {
m_updateChecker.reset(new UpdateChecker(BuildConfig.CHANLIST_URL, BuildConfig.VERSION_CHANNEL, BuildConfig.VERSION_BUILD)); auto platform = getIdealPlatform(BuildConfig.BUILD_PLATFORM);
auto channelUrl = BuildConfig.UPDATER_BASE + platform + "/channels.json";
qDebug() << "Initializing updater with platform: " << platform << " -- " << channelUrl;
m_updateChecker.reset(new UpdateChecker(channelUrl, BuildConfig.VERSION_CHANNEL, BuildConfig.VERSION_BUILD));
qDebug() << "<> Updater started."; qDebug() << "<> Updater started.";
} }

View File

@ -538,7 +538,7 @@ void AuthContext::onSTSAuthGenericDone(
} }
Katabasis::Token temp; Katabasis::Token temp;
if(!parseXTokenResponse(replyData, temp, "STSAuthGaneric")) { if(!parseXTokenResponse(replyData, temp, "STSAuthGeneric")) {
qWarning() << "Could not parse authorization response for access to xbox API..."; qWarning() << "Could not parse authorization response for access to xbox API...";
failResult(m_xboxProfileSucceeded); failResult(m_xboxProfileSucceeded);
return; return;

View File

@ -58,8 +58,7 @@ MultiMCPage::MultiMCPage(QWidget *parent) : QWidget(parent), ui(new Ui::MultiMCP
if(BuildConfig.UPDATER_ENABLED) if(BuildConfig.UPDATER_ENABLED)
{ {
QObject::connect(MMC->updateChecker().get(), &UpdateChecker::channelListLoaded, this, QObject::connect(MMC->updateChecker().get(), &UpdateChecker::channelListLoaded, this, &MultiMCPage::refreshUpdateChannelList);
&MultiMCPage::refreshUpdateChannelList);
if (MMC->updateChecker()->hasChannels()) if (MMC->updateChecker()->hasChannels())
{ {

View File

@ -170,4 +170,4 @@ OperationList DownloadTask::operations()
return m_operations; return m_operations;
} }
} }

View File

@ -23,9 +23,12 @@
#define API_VERSION 0 #define API_VERSION 0
#define CHANLIST_FORMAT 0 #define CHANLIST_FORMAT 0
UpdateChecker::UpdateChecker(QString channelListUrl, QString currentChannel, int currentBuild) #include "BuildConfig.h"
#include "sys.h"
UpdateChecker::UpdateChecker(QString channelUrl, QString currentChannel, int currentBuild)
{ {
m_channelListUrl = channelListUrl; m_channelUrl = channelUrl;
m_currentChannel = currentChannel; m_currentChannel = currentChannel;
m_currentBuild = currentBuild; m_currentBuild = currentBuild;
} }
@ -48,8 +51,7 @@ void UpdateChecker::checkForUpdate(QString updateChannel, bool notifyNoUpdate)
// later. // later.
if (!m_chanListLoaded) if (!m_chanListLoaded)
{ {
qDebug() << "Channel list isn't loaded yet. Loading channel list and deferring " qDebug() << "Channel list isn't loaded yet. Loading channel list and deferring update check.";
"update check.";
m_checkUpdateWaiting = true; m_checkUpdateWaiting = true;
m_deferredUpdateChannel = updateChannel; m_deferredUpdateChannel = updateChannel;
updateChanList(notifyNoUpdate); updateChanList(notifyNoUpdate);
@ -62,29 +64,43 @@ void UpdateChecker::checkForUpdate(QString updateChannel, bool notifyNoUpdate)
return; return;
} }
m_updateChecking = true;
// Find the desired channel within the channel list and get its repo URL. If if cannot be // Find the desired channel within the channel list and get its repo URL. If if cannot be
// found, error. // found, error.
QString stableUrl;
m_newRepoUrl = ""; m_newRepoUrl = "";
for (ChannelListEntry entry : m_channels) for (ChannelListEntry entry : m_channels)
{ {
if (entry.id == updateChannel) qDebug() << "channelEntry = " << entry.id;
if(entry.id == "stable") {
stableUrl = entry.url;
}
if (entry.id == updateChannel) {
m_newRepoUrl = entry.url; m_newRepoUrl = entry.url;
if (entry.id == m_currentChannel) qDebug() << "is intended update channel: " << entry.id;
}
if (entry.id == m_currentChannel) {
m_currentRepoUrl = entry.url; m_currentRepoUrl = entry.url;
qDebug() << "is current update channel: " << entry.id;
}
} }
qDebug() << "m_repoUrl = " << m_newRepoUrl; qDebug() << "m_repoUrl = " << m_newRepoUrl;
// If we didn't find our channel, error. if (m_newRepoUrl.isEmpty()) {
qWarning() << "m_repoUrl was empty. defaulting to 'stable': " << stableUrl;
m_newRepoUrl = stableUrl;
}
// If nothing applies, error
if (m_newRepoUrl.isEmpty()) if (m_newRepoUrl.isEmpty())
{ {
qCritical() << "m_repoUrl is empty!"; qCritical() << "failed to select any update repository for: " << updateChannel;
emit updateCheckFailed(); emit updateCheckFailed();
return; return;
} }
m_updateChecking = true;
QUrl indexUrl = QUrl(m_newRepoUrl).resolved(QUrl("index.json")); QUrl indexUrl = QUrl(m_newRepoUrl).resolved(QUrl("index.json"));
auto job = new NetJob("GoUpdate Repository Index"); auto job = new NetJob("GoUpdate Repository Index");
@ -174,7 +190,7 @@ void UpdateChecker::updateChanList(bool notifyNoUpdate)
return; return;
} }
if (m_channelListUrl.isEmpty()) if (m_channelUrl.isEmpty())
{ {
qCritical() << "Failed to update channel list. No channel list URL set." qCritical() << "Failed to update channel list. No channel list URL set."
<< "If you'd like to use MultiMC's update system, please pass the channel " << "If you'd like to use MultiMC's update system, please pass the channel "
@ -184,7 +200,7 @@ void UpdateChecker::updateChanList(bool notifyNoUpdate)
m_chanListLoading = true; m_chanListLoading = true;
NetJob *job = new NetJob("Update System Channel List"); NetJob *job = new NetJob("Update System Channel List");
job->addNetAction(Net::Download::makeByteArray(QUrl(m_channelListUrl), &chanlistData)); job->addNetAction(Net::Download::makeByteArray(QUrl(m_channelUrl), &chanlistData));
connect(job, &NetJob::succeeded, [this, notifyNoUpdate]() { chanListDownloadFinished(notifyNoUpdate); }); connect(job, &NetJob::succeeded, [this, notifyNoUpdate]() { chanListDownloadFinished(notifyNoUpdate); });
QObject::connect(job, &NetJob::failed, this, &UpdateChecker::chanListDownloadFailed); QObject::connect(job, &NetJob::failed, this, &UpdateChecker::chanListDownloadFailed);
chanListJob.reset(job); chanListJob.reset(job);

View File

@ -23,7 +23,7 @@ class UpdateChecker : public QObject
Q_OBJECT Q_OBJECT
public: public:
UpdateChecker(QString channelListUrl, QString currentChannel, int currentBuild); UpdateChecker(QString channelUrl, QString currentChannel, int currentBuild);
void checkForUpdate(QString updateChannel, bool notifyNoUpdate); void checkForUpdate(QString updateChannel, bool notifyNoUpdate);
/*! /*!
@ -78,7 +78,7 @@ private:
NetJobPtr chanListJob; NetJobPtr chanListJob;
QByteArray chanlistData; QByteArray chanlistData;
QString m_channelListUrl; QString m_channelUrl;
QList<ChannelListEntry> m_channels; QList<ChannelListEntry> m_channels;

View File

@ -4,10 +4,24 @@
namespace Sys namespace Sys
{ {
const uint64_t mebibyte = 1024ull * 1024ull; const uint64_t mebibyte = 1024ull * 1024ull;
enum class KernelType {
Undetermined,
Windows,
Darwin,
Linux
};
struct KernelInfo struct KernelInfo
{ {
QString kernelName; QString kernelName;
QString kernelVersion; QString kernelVersion;
KernelType kernelType = KernelType::Undetermined;
int kernelMajor = 0;
int kernelMinor = 0;
int kernelPatch = 0;
bool isCursed = false;
}; };
KernelInfo getKernelInfo(); KernelInfo getKernelInfo();

View File

@ -2,13 +2,33 @@
#include <sys/utsname.h> #include <sys/utsname.h>
#include <QString>
#include <QStringList>
Sys::KernelInfo Sys::getKernelInfo() Sys::KernelInfo Sys::getKernelInfo()
{ {
Sys::KernelInfo out; Sys::KernelInfo out;
struct utsname buf; struct utsname buf;
uname(&buf); uname(&buf);
out.kernelType = KernelType::Darwin;
out.kernelName = buf.sysname; out.kernelName = buf.sysname;
out.kernelVersion = buf.release; QString release = out.kernelVersion = buf.release;
// TODO: figure out how to detect cursed-ness (macOS emulated on linux via mad hacks and so on)
out.isCursed = false;
out.kernelMajor = 0;
out.kernelMinor = 0;
out.kernelPatch = 0;
auto sections = release.split('-');
if(sections.size() >= 1) {
auto versionParts = sections[0].split('.');
if(sections.size() >= 3) {
out.kernelMajor = sections[0].toInt();
out.kernelMinor = sections[1].toInt();
out.kernelPatch = sections[2].toInt();
}
}
return out; return out;
} }

View File

@ -6,13 +6,34 @@
#include <fstream> #include <fstream>
#include <limits> #include <limits>
#include <QString>
#include <QStringList>
Sys::KernelInfo Sys::getKernelInfo() Sys::KernelInfo Sys::getKernelInfo()
{ {
Sys::KernelInfo out; Sys::KernelInfo out;
struct utsname buf; struct utsname buf;
uname(&buf); uname(&buf);
// NOTE: we assume linux here. this needs further elaboration
out.kernelType = KernelType::Linux;
out.kernelName = buf.sysname; out.kernelName = buf.sysname;
out.kernelVersion = buf.release; QString release = out.kernelVersion = buf.release;
// linux binary running on WSL is cursed.
out.isCursed = release.contains("WSL", Qt::CaseInsensitive) || release.contains("Microsoft", Qt::CaseInsensitive);
out.kernelMajor = 0;
out.kernelMinor = 0;
out.kernelPatch = 0;
auto sections = release.split('-');
if(sections.size() >= 1) {
auto versionParts = sections[0].split('.');
if(sections.size() >= 3) {
out.kernelMajor = sections[0].toInt();
out.kernelMinor = sections[1].toInt();
out.kernelPatch = sections[2].toInt();
}
}
return out; return out;
} }

View File

@ -5,12 +5,16 @@
Sys::KernelInfo Sys::getKernelInfo() Sys::KernelInfo Sys::getKernelInfo()
{ {
Sys::KernelInfo out; Sys::KernelInfo out;
out.kernelType = KernelType::Windows;
out.kernelName = "Windows"; out.kernelName = "Windows";
OSVERSIONINFOW osvi; OSVERSIONINFOW osvi;
ZeroMemory(&osvi, sizeof(OSVERSIONINFOW)); ZeroMemory(&osvi, sizeof(OSVERSIONINFOW));
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW); osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW);
GetVersionExW(&osvi); GetVersionExW(&osvi);
out.kernelVersion = QString("%1.%2").arg(osvi.dwMajorVersion).arg(osvi.dwMinorVersion); out.kernelVersion = QString("%1.%2").arg(osvi.dwMajorVersion).arg(osvi.dwMinorVersion);
out.kernelMajor = osvi.dwMajorVersion;
out.kernelMinor = osvi.dwMinorVersion;
out.kernelPatch = osvi.dwBuildNumber;
return out; return out;
} }