mirror of
https://github.com/moonlight-stream/moonlight-qt
synced 2024-12-14 21:32:27 +00:00
Refuse to stream if Moonlight is known incompatible with the host GFE version
This commit is contained in:
parent
b50e5ed7e6
commit
2fbb320539
11 changed files with 164 additions and 3 deletions
|
@ -131,6 +131,7 @@ SOURCES += \
|
|||
cli/commandlineparser.cpp \
|
||||
cli/quitstream.cpp \
|
||||
cli/startstream.cpp \
|
||||
settings/compatfetcher.cpp \
|
||||
settings/mappingfetcher.cpp \
|
||||
settings/streamingpreferences.cpp \
|
||||
streaming/input/abstouch.cpp \
|
||||
|
@ -156,6 +157,7 @@ SOURCES += \
|
|||
|
||||
HEADERS += \
|
||||
backend/nvapp.h \
|
||||
settings/compatfetcher.h \
|
||||
settings/mappingfetcher.h \
|
||||
utils.h \
|
||||
backend/computerseeker.h \
|
||||
|
|
|
@ -146,7 +146,8 @@ private:
|
|||
ComputerManager::ComputerManager(QObject *parent)
|
||||
: QObject(parent),
|
||||
m_PollingRef(0),
|
||||
m_MdnsBrowser(nullptr)
|
||||
m_MdnsBrowser(nullptr),
|
||||
m_CompatFetcher(nullptr)
|
||||
{
|
||||
QSettings settings;
|
||||
|
||||
|
@ -159,6 +160,9 @@ ComputerManager::ComputerManager(QObject *parent)
|
|||
}
|
||||
settings.endArray();
|
||||
|
||||
// Fetch latest compatibility data asynchronously
|
||||
m_CompatFetcher.start();
|
||||
|
||||
// To quit in a timely manner, we must block additional requests
|
||||
// after we receive the aboutToQuit() signal. This is neccessary
|
||||
// because NvHTTP uses aboutToQuit() to abort requests in progres
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include "nvcomputer.h"
|
||||
#include "nvpairingmanager.h"
|
||||
#include "settings/compatfetcher.h"
|
||||
|
||||
#include <qmdnsengine/server.h>
|
||||
#include <qmdnsengine/cache.h>
|
||||
|
@ -214,4 +215,5 @@ private:
|
|||
QMdnsEngine::Browser* m_MdnsBrowser;
|
||||
QMdnsEngine::Cache m_MdnsCache;
|
||||
QVector<MdnsPendingComputer*> m_PendingResolution;
|
||||
CompatFetcher m_CompatFetcher;
|
||||
};
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "nvcomputer.h"
|
||||
#include "nvapp.h"
|
||||
#include "settings/compatfetcher.h"
|
||||
|
||||
#include <QUdpSocket>
|
||||
#include <QHostInfo>
|
||||
|
@ -50,6 +51,7 @@ NvComputer::NvComputer(QSettings& settings)
|
|||
this->serverCodecModeSupport = 0;
|
||||
this->pendingQuit = false;
|
||||
this->gpuModel = nullptr;
|
||||
this->isSupportedServerVersion = true;
|
||||
}
|
||||
|
||||
void NvComputer::serialize(QSettings& settings) const
|
||||
|
@ -143,6 +145,7 @@ NvComputer::NvComputer(QString address, QString serverInfo, QSslCertificate serv
|
|||
this->activeAddress = address;
|
||||
this->state = NvComputer::CS_ONLINE;
|
||||
this->pendingQuit = false;
|
||||
this->isSupportedServerVersion = CompatFetcher::isGfeVersionSupported(this->gfeVersion);
|
||||
}
|
||||
|
||||
bool NvComputer::wake()
|
||||
|
@ -408,6 +411,7 @@ bool NvComputer::update(NvComputer& that)
|
|||
ASSIGN_IF_CHANGED(state);
|
||||
ASSIGN_IF_CHANGED(gfeVersion);
|
||||
ASSIGN_IF_CHANGED(appVersion);
|
||||
ASSIGN_IF_CHANGED(isSupportedServerVersion);
|
||||
ASSIGN_IF_CHANGED(maxLumaPixelsHEVC);
|
||||
ASSIGN_IF_CHANGED(gpuModel);
|
||||
ASSIGN_IF_CHANGED_AND_NONNULL(serverCert);
|
||||
|
|
|
@ -65,6 +65,7 @@ public:
|
|||
int maxLumaPixelsHEVC;
|
||||
int serverCodecModeSupport;
|
||||
QString gpuModel;
|
||||
bool isSupportedServerVersion;
|
||||
|
||||
// Persisted traits
|
||||
QString localAddress;
|
||||
|
|
|
@ -220,7 +220,12 @@ CenteredGridView {
|
|||
|
||||
onClicked: {
|
||||
if (model.online) {
|
||||
if (model.paired) {
|
||||
if (!model.serverSupported) {
|
||||
errorDialog.text = qsTr("The version of GeForce Experience on %1 is not supported by this build of Moonlight. You must update Moonlight to stream from %1.").arg(model.name)
|
||||
errorDialog.helpText = ""
|
||||
errorDialog.open()
|
||||
}
|
||||
else if (model.paired) {
|
||||
// go to game view
|
||||
var component = Qt.createComponent("AppView.qml")
|
||||
var appView = component.createObject(stackView, {"computerIndex": index, "objectName": model.name})
|
||||
|
|
|
@ -42,6 +42,8 @@ QVariant ComputerModel::data(const QModelIndex& index, int role) const
|
|||
return !computer->macAddress.isEmpty();
|
||||
case StatusUnknownRole:
|
||||
return computer->state == NvComputer::CS_UNKNOWN;
|
||||
case ServerSupportedRole:
|
||||
return computer->isSupportedServerVersion;
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
|
@ -68,6 +70,7 @@ QHash<int, QByteArray> ComputerModel::roleNames() const
|
|||
names[BusyRole] = "busy";
|
||||
names[WakeableRole] = "wakeable";
|
||||
names[StatusUnknownRole] = "statusUnknown";
|
||||
names[ServerSupportedRole] = "serverSupported";
|
||||
|
||||
return names;
|
||||
}
|
||||
|
|
|
@ -14,7 +14,8 @@ class ComputerModel : public QAbstractListModel
|
|||
PairedRole,
|
||||
BusyRole,
|
||||
WakeableRole,
|
||||
StatusUnknownRole
|
||||
StatusUnknownRole,
|
||||
ServerSupportedRole
|
||||
};
|
||||
|
||||
public:
|
||||
|
|
112
app/settings/compatfetcher.cpp
Normal file
112
app/settings/compatfetcher.cpp
Normal file
|
@ -0,0 +1,112 @@
|
|||
#include "compatfetcher.h"
|
||||
#include "path.h"
|
||||
|
||||
#include <QNetworkReply>
|
||||
#include <QSettings>
|
||||
|
||||
#define COMPAT_VERSION "v1"
|
||||
#define COMPAT_KEY "latestsupportedversion-"
|
||||
|
||||
CompatFetcher::CompatFetcher(QObject *parent) :
|
||||
QObject(parent),
|
||||
m_Nam(this)
|
||||
{
|
||||
// Never communicate over HTTP
|
||||
m_Nam.setStrictTransportSecurityEnabled(true);
|
||||
|
||||
// Allow HTTP redirects
|
||||
m_Nam.setRedirectPolicy(QNetworkRequest::NoLessSafeRedirectPolicy);
|
||||
|
||||
connect(&m_Nam, &QNetworkAccessManager::finished,
|
||||
this, &CompatFetcher::handleCompatInfoFetched);
|
||||
}
|
||||
|
||||
void CompatFetcher::start()
|
||||
{
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) && QT_VERSION < QT_VERSION_CHECK(5, 15, 1) && !defined(QT_NO_BEARERMANAGEMENT)
|
||||
// HACK: Set network accessibility to work around QTBUG-80947 (introduced in Qt 5.14.0 and fixed in Qt 5.15.1)
|
||||
QT_WARNING_PUSH
|
||||
QT_WARNING_DISABLE_DEPRECATED
|
||||
m_Nam.setNetworkAccessible(QNetworkAccessManager::Accessible);
|
||||
QT_WARNING_POP
|
||||
#endif
|
||||
|
||||
QUrl url("https://moonlight-stream.org/compatibility/" COMPAT_VERSION);
|
||||
QNetworkRequest request(url);
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
|
||||
request.setAttribute(QNetworkRequest::Http2AllowedAttribute, true);
|
||||
#else
|
||||
request.setAttribute(QNetworkRequest::HTTP2AllowedAttribute, true);
|
||||
#endif
|
||||
|
||||
// We'll get a callback when this is finished
|
||||
m_Nam.get(request);
|
||||
}
|
||||
|
||||
bool CompatFetcher::isGfeVersionSupported(QString gfeVersion)
|
||||
{
|
||||
QSettings settings;
|
||||
|
||||
if (gfeVersion.isEmpty()) {
|
||||
// If we don't have a GFE version, just allow it
|
||||
return true;
|
||||
}
|
||||
|
||||
QString latestSupportedVersion = settings.value(COMPAT_KEY COMPAT_VERSION).toString();
|
||||
if (latestSupportedVersion.isEmpty()) {
|
||||
// We don't have compat data yet, so just assume it's supported
|
||||
return true;
|
||||
}
|
||||
|
||||
QStringList latestSupportedVersionQuad = latestSupportedVersion.split('.');
|
||||
QStringList gfeVersionQuad = gfeVersion.split('.');
|
||||
|
||||
for (int i = 0;; i++) {
|
||||
int actualVerVal = 0;
|
||||
int latestSupportedVal = 0;
|
||||
|
||||
// Treat missing decimal places as 0
|
||||
if (i < gfeVersionQuad.count()) {
|
||||
actualVerVal = gfeVersionQuad[i].toInt();
|
||||
}
|
||||
if (i < latestSupportedVersionQuad.count()) {
|
||||
latestSupportedVal = latestSupportedVersionQuad[i].toInt();
|
||||
}
|
||||
|
||||
if (i >= gfeVersionQuad.count() && i >= latestSupportedVersionQuad.count()) {
|
||||
// Equal versions - this is fine
|
||||
return true;
|
||||
}
|
||||
|
||||
if (actualVerVal < latestSupportedVal) {
|
||||
// Actual version is lower than latest supported - this is fine
|
||||
return true;
|
||||
}
|
||||
else if (actualVerVal > latestSupportedVal) {
|
||||
// Actual version is greater than latest supported - this is bad
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CompatFetcher::handleCompatInfoFetched(QNetworkReply* reply)
|
||||
{
|
||||
Q_ASSERT(reply->isFinished());
|
||||
|
||||
if (reply->error() == QNetworkReply::NoError) {
|
||||
// Queue the reply for deletion
|
||||
reply->deleteLater();
|
||||
|
||||
QString version = QString(reply->readAll()).trimmed();
|
||||
|
||||
QSettings settings;
|
||||
settings.setValue(COMPAT_KEY COMPAT_VERSION, version);
|
||||
|
||||
qInfo() << "Latest supported GFE server:" << version;
|
||||
}
|
||||
else {
|
||||
qWarning() << "Failed to download latest compatibility data:" << reply->error();
|
||||
reply->deleteLater();
|
||||
}
|
||||
}
|
22
app/settings/compatfetcher.h
Normal file
22
app/settings/compatfetcher.h
Normal file
|
@ -0,0 +1,22 @@
|
|||
#pragma once
|
||||
|
||||
#include <QObject>
|
||||
#include <QNetworkAccessManager>
|
||||
|
||||
class CompatFetcher : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit CompatFetcher(QObject *parent = nullptr);
|
||||
|
||||
void start();
|
||||
|
||||
static bool isGfeVersionSupported(QString gfeVersion);
|
||||
|
||||
private slots:
|
||||
void handleCompatInfoFetched(QNetworkReply* reply);
|
||||
|
||||
private:
|
||||
QNetworkAccessManager m_Nam;
|
||||
};
|
|
@ -588,6 +588,11 @@ bool Session::validateLaunch(SDL_Window* testWindow)
|
|||
{
|
||||
QStringList warningList;
|
||||
|
||||
if (!m_Computer->isSupportedServerVersion) {
|
||||
emit displayLaunchError(tr("The version of GeForce Experience on %1 is not supported by this build of Moonlight. You must update Moonlight to stream from %1.").arg(m_Computer->name));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_Preferences->absoluteMouseMode && !m_App.isAppCollectorGame) {
|
||||
emitLaunchWarning(tr("Your selection to enable remote desktop mouse mode may cause problems in games."));
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue