mirror of
https://github.com/moonlight-stream/moonlight-qt.git
synced 2025-08-17 00:46:11 +00:00
Fetch updated gamepad mappings each launch
This commit is contained in:
parent
aa4684077d
commit
e224a7f0c7
@ -132,6 +132,7 @@ SOURCES += \
|
|||||||
cli/commandlineparser.cpp \
|
cli/commandlineparser.cpp \
|
||||||
cli/quitstream.cpp \
|
cli/quitstream.cpp \
|
||||||
cli/startstream.cpp \
|
cli/startstream.cpp \
|
||||||
|
settings/mappingfetcher.cpp \
|
||||||
settings/streamingpreferences.cpp \
|
settings/streamingpreferences.cpp \
|
||||||
streaming/input/abstouch.cpp \
|
streaming/input/abstouch.cpp \
|
||||||
streaming/input/gamepad.cpp \
|
streaming/input/gamepad.cpp \
|
||||||
@ -155,6 +156,7 @@ SOURCES += \
|
|||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
backend/nvapp.h \
|
backend/nvapp.h \
|
||||||
|
settings/mappingfetcher.h \
|
||||||
utils.h \
|
utils.h \
|
||||||
backend/computerseeker.h \
|
backend/computerseeker.h \
|
||||||
backend/identitymanager.h \
|
backend/identitymanager.h \
|
||||||
|
19
app/path.cpp
19
app/path.cpp
@ -6,6 +6,7 @@
|
|||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
|
|
||||||
|
QString Path::s_CacheDir;
|
||||||
QString Path::s_LogDir;
|
QString Path::s_LogDir;
|
||||||
QString Path::s_BoxArtCacheDir;
|
QString Path::s_BoxArtCacheDir;
|
||||||
|
|
||||||
@ -28,11 +29,25 @@ QByteArray Path::readDataFile(QString fileName)
|
|||||||
return dataFile.readAll();
|
return dataFile.readAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Path::writeDataFile(QString fileName, QByteArray data)
|
||||||
|
{
|
||||||
|
QFile dataFile(QDir(s_CacheDir).absoluteFilePath(fileName));
|
||||||
|
dataFile.open(QIODevice::WriteOnly);
|
||||||
|
dataFile.write(data);
|
||||||
|
}
|
||||||
|
|
||||||
QString Path::getDataFilePath(QString fileName)
|
QString Path::getDataFilePath(QString fileName)
|
||||||
{
|
{
|
||||||
QString candidatePath;
|
QString candidatePath;
|
||||||
|
|
||||||
// Check the current directory first
|
// Check the cache location first (used by Path::writeDataFile())
|
||||||
|
candidatePath = QDir(s_CacheDir).absoluteFilePath(fileName);
|
||||||
|
if (QFile::exists(candidatePath)) {
|
||||||
|
qInfo() << "Found" << fileName << "at" << candidatePath;
|
||||||
|
return candidatePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check the current directory
|
||||||
candidatePath = QDir(QDir::currentPath()).absoluteFilePath(fileName);
|
candidatePath = QDir(QDir::currentPath()).absoluteFilePath(fileName);
|
||||||
if (QFile::exists(candidatePath)) {
|
if (QFile::exists(candidatePath)) {
|
||||||
qInfo() << "Found" << fileName << "at" << candidatePath;
|
qInfo() << "Found" << fileName << "at" << candidatePath;
|
||||||
@ -64,6 +79,7 @@ void Path::initialize(bool portable)
|
|||||||
if (portable) {
|
if (portable) {
|
||||||
s_LogDir = QDir::currentPath();
|
s_LogDir = QDir::currentPath();
|
||||||
s_BoxArtCacheDir = QDir::currentPath() + "/boxart";
|
s_BoxArtCacheDir = QDir::currentPath() + "/boxart";
|
||||||
|
s_CacheDir = QDir::currentPath();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
#ifdef Q_OS_DARWIN
|
#ifdef Q_OS_DARWIN
|
||||||
@ -73,6 +89,7 @@ void Path::initialize(bool portable)
|
|||||||
#else
|
#else
|
||||||
s_LogDir = QDir::tempPath();
|
s_LogDir = QDir::tempPath();
|
||||||
#endif
|
#endif
|
||||||
|
s_CacheDir = QStandardPaths::writableLocation(QStandardPaths::CacheLocation);
|
||||||
s_BoxArtCacheDir = QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + "/boxart";
|
s_BoxArtCacheDir = QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + "/boxart";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ public:
|
|||||||
static QString getBoxArtCacheDir();
|
static QString getBoxArtCacheDir();
|
||||||
|
|
||||||
static QByteArray readDataFile(QString fileName);
|
static QByteArray readDataFile(QString fileName);
|
||||||
|
static void writeDataFile(QString fileName, QByteArray data);
|
||||||
|
|
||||||
// Only safe to use directly for Qt classes
|
// Only safe to use directly for Qt classes
|
||||||
static QString getDataFilePath(QString fileName);
|
static QString getDataFilePath(QString fileName);
|
||||||
@ -17,6 +18,7 @@ public:
|
|||||||
static void initialize(bool portable);
|
static void initialize(bool portable);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
static QString s_CacheDir;
|
||||||
static QString s_LogDir;
|
static QString s_LogDir;
|
||||||
static QString s_BoxArtCacheDir;
|
static QString s_BoxArtCacheDir;
|
||||||
};
|
};
|
||||||
|
52
app/settings/mappingfetcher.cpp
Normal file
52
app/settings/mappingfetcher.cpp
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
#include "mappingfetcher.h"
|
||||||
|
#include "path.h"
|
||||||
|
|
||||||
|
#include <QNetworkReply>
|
||||||
|
|
||||||
|
MappingFetcher::MappingFetcher(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, SIGNAL(finished(QNetworkReply*)),
|
||||||
|
this, SLOT(handleMappingListFetched(QNetworkReply*)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void MappingFetcher::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
|
||||||
|
|
||||||
|
// We'll get a callback when this is finished
|
||||||
|
QUrl url("https://moonlight-stream.org/SDL_GameControllerDB/gamecontrollerdb.txt");
|
||||||
|
m_Nam.get(QNetworkRequest(url));
|
||||||
|
}
|
||||||
|
|
||||||
|
void MappingFetcher::handleMappingListFetched(QNetworkReply* reply)
|
||||||
|
{
|
||||||
|
Q_ASSERT(reply->isFinished());
|
||||||
|
|
||||||
|
if (reply->error() == QNetworkReply::NoError) {
|
||||||
|
// Queue the reply for deletion
|
||||||
|
reply->deleteLater();
|
||||||
|
|
||||||
|
// Update the cached data on disk for next call to applyMappings()
|
||||||
|
Path::writeDataFile("gamecontrollerdb.txt", reply->readAll());
|
||||||
|
|
||||||
|
qInfo() << "Downloaded updated gamepad mappings";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
qWarning() << "Failed to download updated gamepad mappings:" << reply->error();
|
||||||
|
reply->deleteLater();
|
||||||
|
}
|
||||||
|
}
|
20
app/settings/mappingfetcher.h
Normal file
20
app/settings/mappingfetcher.h
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QNetworkAccessManager>
|
||||||
|
|
||||||
|
class MappingFetcher : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit MappingFetcher(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
void start();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void handleMappingListFetched(QNetworkReply* reply);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QNetworkAccessManager m_Nam;
|
||||||
|
};
|
@ -10,10 +10,18 @@
|
|||||||
#define SER_GUID "guid"
|
#define SER_GUID "guid"
|
||||||
#define SER_MAPPING "mapping"
|
#define SER_MAPPING "mapping"
|
||||||
|
|
||||||
|
MappingFetcher* MappingManager::s_MappingFetcher;
|
||||||
|
|
||||||
MappingManager::MappingManager()
|
MappingManager::MappingManager()
|
||||||
{
|
{
|
||||||
QSettings settings;
|
QSettings settings;
|
||||||
|
|
||||||
|
// Load updated mappings from the Internet once per Moonlight launch
|
||||||
|
if (s_MappingFetcher == nullptr) {
|
||||||
|
s_MappingFetcher = new MappingFetcher();
|
||||||
|
s_MappingFetcher->start();
|
||||||
|
}
|
||||||
|
|
||||||
// First load existing saved mappings. This ensures the user's
|
// First load existing saved mappings. This ensures the user's
|
||||||
// hints can always override the old data.
|
// hints can always override the old data.
|
||||||
int mappingCount = settings.beginReadArray(SER_GAMEPADMAPPING);
|
int mappingCount = settings.beginReadArray(SER_GAMEPADMAPPING);
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "mappingfetcher.h"
|
||||||
|
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
|
|
||||||
class SdlGamepadMapping
|
class SdlGamepadMapping
|
||||||
@ -70,5 +72,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
QMap<QString, SdlGamepadMapping> m_Mappings;
|
QMap<QString, SdlGamepadMapping> m_Mappings;
|
||||||
|
|
||||||
|
static MappingFetcher* s_MappingFetcher;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user