mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-09-21 09:05:10 -07:00
Merge cc9cf9ba63 into 6823d54c1e
This commit is contained in:
commit
fd3eb1571f
2 changed files with 80 additions and 60 deletions
|
|
@ -10,6 +10,7 @@
|
||||||
#include <QRegularExpression>
|
#include <QRegularExpression>
|
||||||
#include <QSysInfo>
|
#include <QSysInfo>
|
||||||
#include <QtGlobal>
|
#include <QtGlobal>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
#if defined(Q_OS_MACOS)
|
#if defined(Q_OS_MACOS)
|
||||||
#include <sys/sysctl.h>
|
#include <sys/sysctl.h>
|
||||||
|
|
@ -43,55 +44,90 @@ void ReleaseChannel::checkForUpdates()
|
||||||
connect(response, &QNetworkReply::finished, this, &ReleaseChannel::releaseListFinished);
|
connect(response, &QNetworkReply::finished, this, &ReleaseChannel::releaseListFinished);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Different release channel checking functions for different operating systems
|
// Find assets compatible with host platform (Linux is not supported by in-client updater)
|
||||||
bool ReleaseChannel::downloadMatchesCurrentOS(const QString &fileName)
|
std::optional<int> ReleaseChannel::getTargetVersionForCurrentOS(const QString &fileName)
|
||||||
{
|
{
|
||||||
#if defined(Q_OS_MACOS)
|
const QRegularExpression *regex = nullptr;
|
||||||
static QRegularExpression version_regex("macOS(\\d+)");
|
|
||||||
auto match = version_regex.match(fileName);
|
static const std::optional<int> systemVersion = [] {
|
||||||
if (!match.hasMatch()) {
|
bool ok = false;
|
||||||
return false;
|
const QString versionString = QSysInfo::productVersion();
|
||||||
|
const int version = versionString.split('.').first().toInt(&ok);
|
||||||
|
if (!ok) {
|
||||||
|
qCWarning(ReleaseChannelLog) << "Unable to determine OS version from" << versionString;
|
||||||
|
return std::optional<int>();
|
||||||
|
}
|
||||||
|
return std::optional<int>{version};
|
||||||
|
}();
|
||||||
|
|
||||||
|
if (!systemVersion) {
|
||||||
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto getSystemVersion = [] {
|
#if defined(Q_OS_MACOS)
|
||||||
|
static const bool isIntel = [] {
|
||||||
// QSysInfo does not go through translation layers
|
// QSysInfo does not go through translation layers
|
||||||
// We need to use sysctl to reliably detect the underlying architecture
|
// We need to use sysctl to reliably detect the underlying architecture
|
||||||
char arch[255];
|
char arch[255];
|
||||||
size_t len = sizeof(arch);
|
size_t len = sizeof(arch);
|
||||||
if (sysctlbyname("machdep.cpu.brand_string", arch, &len, nullptr, 0) == 0) {
|
if (sysctlbyname("machdep.cpu.brand_string", arch, &len, nullptr, 0) == 0) {
|
||||||
// Intel mac is only supported on macOS 13 versions
|
return QString::fromUtf8(arch).contains("Intel");
|
||||||
if (QString::fromUtf8(arch).contains("Intel")) {
|
|
||||||
return 13;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
|
}();
|
||||||
|
|
||||||
return QSysInfo::productVersion().split(".")[0].toInt();
|
// Apple (ARM) --> Cockatrice-3.0.0-macOS15.dmg
|
||||||
};
|
// Apple (x86) --> Cockatrice-3.0.0-macOS15_Intel.dmg
|
||||||
|
static const QRegularExpression macIntelRegex(R"(-macOS(\d+)_Intel\.[^.]+$)",
|
||||||
// older(smaller) releases are compatible with a newer or the same system version
|
QRegularExpression::CaseInsensitiveOption);
|
||||||
int sys_maj = getSystemVersion();
|
static const QRegularExpression macRegex(R"(-macOS(\d+)\.[^.]+$)", QRegularExpression::CaseInsensitiveOption);
|
||||||
int rel_maj = match.captured(1).toInt();
|
regex = isIntel ? &macIntelRegex : &macRegex;
|
||||||
return rel_maj == sys_maj;
|
|
||||||
|
|
||||||
#elif defined(Q_OS_WIN)
|
#elif defined(Q_OS_WIN)
|
||||||
#if Q_PROCESSOR_WORDSIZE == 4
|
// Windows (x86) --> Cockatrice-3.0.0-Windows10.exe
|
||||||
return fileName.contains("32bit");
|
static const QRegularExpression winRegex(R"(-(?:Win|Windows)(\d+)\.[^.]+$)",
|
||||||
#elif Q_PROCESSOR_WORDSIZE == 8
|
QRegularExpression::CaseInsensitiveOption);
|
||||||
const QString &version = QSysInfo::productVersion();
|
regex = &winRegex;
|
||||||
if (version.startsWith("7") || version.startsWith("8")) {
|
|
||||||
return fileName.contains("Win7");
|
#else // if the OS doesn't fit one of the above #defines, then it will never match
|
||||||
} else {
|
|
||||||
return fileName.contains("Win10");
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
Q_UNUSED(fileName);
|
Q_UNUSED(fileName);
|
||||||
return false;
|
return std::nullopt;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#else // If the OS doesn't fit one of the above #defines, then it will never match
|
// Any asset targeting an OS version up to the current host version works
|
||||||
Q_UNUSED(fileName);
|
auto match = regex->match(fileName);
|
||||||
return false;
|
if (!match.hasMatch()) {
|
||||||
#endif
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
const int targetVersion = match.captured(1).toInt();
|
||||||
|
if (targetVersion > *systemVersion) {
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
return targetVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pick newest targeted version (highest number) amongst all compatible ones
|
||||||
|
QString ReleaseChannel::findBestDownloadUrl(const QVariantList &assets)
|
||||||
|
{
|
||||||
|
QString bestUrl;
|
||||||
|
int bestVersion = -1;
|
||||||
|
for (const auto &rawAsset : assets) {
|
||||||
|
QVariantMap asset = rawAsset.toMap();
|
||||||
|
QString name = asset["name"].toString();
|
||||||
|
QString url = asset["browser_download_url"].toString();
|
||||||
|
auto version = getTargetVersionForCurrentOS(name);
|
||||||
|
if (!version) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (*version > bestVersion) {
|
||||||
|
bestVersion = *version;
|
||||||
|
bestUrl = url;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!bestUrl.isEmpty()) {
|
||||||
|
qCInfo(ReleaseChannelLog) << "Best compatible asset=" << bestUrl;
|
||||||
|
}
|
||||||
|
return bestUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString StableReleaseChannel::getManualDownloadUrl() const
|
QString StableReleaseChannel::getManualDownloadUrl() const
|
||||||
|
|
@ -138,16 +174,9 @@ void StableReleaseChannel::releaseListFinished()
|
||||||
lastRelease->setPublishDate(resultMap["published_at"].toDate());
|
lastRelease->setPublishDate(resultMap["published_at"].toDate());
|
||||||
|
|
||||||
if (resultMap.contains("assets")) {
|
if (resultMap.contains("assets")) {
|
||||||
auto rawAssets = resultMap["assets"].toList();
|
auto url = findBestDownloadUrl(resultMap["assets"].toList());
|
||||||
for (const auto &rawAsset : rawAssets) {
|
if (!url.isEmpty()) {
|
||||||
QVariantMap asset = rawAsset.toMap();
|
|
||||||
QString name = asset["name"].toString();
|
|
||||||
QString url = asset["browser_download_url"].toString();
|
|
||||||
|
|
||||||
if (downloadMatchesCurrentOS(name)) {
|
|
||||||
lastRelease->setDownloadUrl(url);
|
lastRelease->setDownloadUrl(url);
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -289,21 +318,10 @@ void BetaReleaseChannel::fileListFinished()
|
||||||
bool needToUpdate = (QString::compare(shortHash, myHash, Qt::CaseInsensitive) != 0);
|
bool needToUpdate = (QString::compare(shortHash, myHash, Qt::CaseInsensitive) != 0);
|
||||||
bool compatibleVersion = false;
|
bool compatibleVersion = false;
|
||||||
|
|
||||||
QStringList resultUrlList{};
|
QString downloadUrl = findBestDownloadUrl(resultList);
|
||||||
for (QVariant file : resultList) {
|
if (!downloadUrl.isEmpty()) {
|
||||||
QVariantMap map = file.toMap();
|
|
||||||
resultUrlList << map["browser_download_url"].toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
resultUrlList.sort();
|
|
||||||
// iterate in reverse so the first item is the latest os version
|
|
||||||
for (auto url = resultUrlList.rbegin(); url < resultUrlList.rend(); ++url) {
|
|
||||||
if (downloadMatchesCurrentOS(*url)) {
|
|
||||||
compatibleVersion = true;
|
compatibleVersion = true;
|
||||||
lastRelease->setDownloadUrl(*url);
|
lastRelease->setDownloadUrl(downloadUrl);
|
||||||
qCInfo(ReleaseChannelLog) << "Found compatible version url=" << *url;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
emit finishedCheck(needToUpdate, compatibleVersion, lastRelease);
|
emit finishedCheck(needToUpdate, compatibleVersion, lastRelease);
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QVariantMap>
|
#include <QVariantMap>
|
||||||
|
#include <optional>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
inline Q_LOGGING_CATEGORY(ReleaseChannelLog, "release_channel");
|
inline Q_LOGGING_CATEGORY(ReleaseChannelLog, "release_channel");
|
||||||
|
|
@ -96,7 +97,8 @@ protected:
|
||||||
Release *lastRelease;
|
Release *lastRelease;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static bool downloadMatchesCurrentOS(const QString &fileName);
|
static std::optional<int> getTargetVersionForCurrentOS(const QString &fileName);
|
||||||
|
static QString findBestDownloadUrl(const QVariantList &assets);
|
||||||
[[nodiscard]] virtual QString getReleaseChannelUrl() const = 0;
|
[[nodiscard]] virtual QString getReleaseChannelUrl() const = 0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue