mirror of
https://github.com/moonlight-stream/moonlight-qt.git
synced 2026-06-15 21:22:40 +00:00
Implement pairing via GUI
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
#include <QThread>
|
||||
#include <QUdpSocket>
|
||||
#include <QHostInfo>
|
||||
#include <QThreadPool>
|
||||
|
||||
#define SER_HOSTS "hosts"
|
||||
#define SER_NAME "hostname"
|
||||
@@ -331,27 +332,54 @@ QVector<NvComputer*> ComputerManager::getComputers()
|
||||
return QVector<NvComputer*>::fromList(m_KnownHosts.values());
|
||||
}
|
||||
|
||||
void ComputerManager::deleteHost(NvComputer* computer)
|
||||
class DeferredHostDeletionTask : public QRunnable
|
||||
{
|
||||
QWriteLocker lock(&m_Lock);
|
||||
public:
|
||||
DeferredHostDeletionTask(ComputerManager* cm, NvComputer* computer)
|
||||
: m_Computer(computer),
|
||||
m_ComputerManager(cm) {}
|
||||
|
||||
QThread* pollingThread = m_PollThreads[computer->uuid];
|
||||
if (pollingThread != nullptr) {
|
||||
pollingThread->requestInterruption();
|
||||
void run()
|
||||
{
|
||||
QWriteLocker lock(&m_ComputerManager->m_Lock);
|
||||
|
||||
// We must wait here because we're going to delete computer
|
||||
// and we can't do that out from underneath the poller.
|
||||
pollingThread->wait();
|
||||
QThread* pollingThread = m_ComputerManager->m_PollThreads[m_Computer->uuid];
|
||||
if (pollingThread != nullptr) {
|
||||
pollingThread->requestInterruption();
|
||||
|
||||
// The thread is safe to delete now
|
||||
Q_ASSERT(pollingThread->isFinished());
|
||||
delete pollingThread;
|
||||
// We must wait here because we're going to delete computer
|
||||
// and we can't do that out from underneath the poller.
|
||||
pollingThread->wait();
|
||||
|
||||
// The thread is safe to delete now
|
||||
Q_ASSERT(pollingThread->isFinished());
|
||||
delete pollingThread;
|
||||
}
|
||||
|
||||
m_ComputerManager->m_PollThreads.remove(m_Computer->uuid);
|
||||
m_ComputerManager->m_KnownHosts.remove(m_Computer->uuid);
|
||||
|
||||
delete m_Computer;
|
||||
}
|
||||
|
||||
m_PollThreads.remove(computer->uuid);
|
||||
m_KnownHosts.remove(computer->uuid);
|
||||
private:
|
||||
NvComputer* m_Computer;
|
||||
ComputerManager* m_ComputerManager;
|
||||
};
|
||||
|
||||
delete computer;
|
||||
void ComputerManager::deleteHost(NvComputer* computer)
|
||||
{
|
||||
// Punt to a worker thread to avoid stalling the
|
||||
// UI while waiting for the polling thread to die
|
||||
QThreadPool::globalInstance()->start(new DeferredHostDeletionTask(this, computer));
|
||||
}
|
||||
|
||||
void ComputerManager::pairHost(NvComputer* computer, QString pin)
|
||||
{
|
||||
// Punt to a worker thread to avoid stalling the
|
||||
// UI while waiting for pairing to complete
|
||||
PendingPairingTask* pairing = new PendingPairingTask(this, computer, pin);
|
||||
QThreadPool::globalInstance()->start(pairing);
|
||||
}
|
||||
|
||||
void ComputerManager::stopPollingAsync()
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
#include "nvhttp.h"
|
||||
#include "nvpairingmanager.h"
|
||||
|
||||
#include <qmdnsengine/server.h>
|
||||
#include <qmdnsengine/cache.h>
|
||||
@@ -10,6 +11,7 @@
|
||||
#include <QThread>
|
||||
#include <QReadWriteLock>
|
||||
#include <QSettings>
|
||||
#include <QRunnable>
|
||||
|
||||
class NvComputer
|
||||
{
|
||||
@@ -239,6 +241,8 @@ class ComputerManager : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
friend class DeferredHostDeletionTask;
|
||||
|
||||
public:
|
||||
explicit ComputerManager(QObject *parent = nullptr);
|
||||
|
||||
@@ -248,6 +252,8 @@ public:
|
||||
|
||||
Q_INVOKABLE bool addNewHost(QString address, bool mdns);
|
||||
|
||||
void pairHost(NvComputer* computer, QString pin);
|
||||
|
||||
QVector<NvComputer*> getComputers();
|
||||
|
||||
// computer is deleted inside this call
|
||||
@@ -256,6 +262,8 @@ public:
|
||||
signals:
|
||||
void computerStateChanged(NvComputer* computer);
|
||||
|
||||
void pairingCompleted(NvComputer* computer, QString error);
|
||||
|
||||
private slots:
|
||||
void handleComputerStateChanged(NvComputer* computer);
|
||||
|
||||
@@ -275,3 +283,54 @@ private:
|
||||
QMdnsEngine::Cache m_MdnsCache;
|
||||
QVector<MdnsPendingComputer*> m_PendingResolution;
|
||||
};
|
||||
|
||||
class PendingPairingTask : public QObject, public QRunnable
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
PendingPairingTask(ComputerManager* computerManager, NvComputer* computer, QString pin)
|
||||
: m_ComputerManager(computerManager),
|
||||
m_Computer(computer),
|
||||
m_Pin(pin)
|
||||
{
|
||||
connect(this, &PendingPairingTask::pairingCompleted,
|
||||
computerManager, &ComputerManager::pairingCompleted);
|
||||
}
|
||||
|
||||
signals:
|
||||
void pairingCompleted(NvComputer* computer, QString error);
|
||||
|
||||
private:
|
||||
void run()
|
||||
{
|
||||
NvPairingManager pairingManager(m_Computer->activeAddress);
|
||||
|
||||
try {
|
||||
NvPairingManager::PairState result = pairingManager.pair(m_Computer->appVersion, m_Pin);
|
||||
switch (result)
|
||||
{
|
||||
case NvPairingManager::PairState::PIN_WRONG:
|
||||
emit pairingCompleted(m_Computer, "The PIN from the PC didn't match. Please try again.");
|
||||
break;
|
||||
case NvPairingManager::PairState::FAILED:
|
||||
emit pairingCompleted(m_Computer, "Pairing failed. Please try again.");
|
||||
break;
|
||||
case NvPairingManager::PairState::ALREADY_IN_PROGRESS:
|
||||
emit pairingCompleted(m_Computer, "Another pairing attempt is already in progress.");
|
||||
break;
|
||||
case NvPairingManager::PairState::PAIRED:
|
||||
emit pairingCompleted(m_Computer, nullptr);
|
||||
break;
|
||||
}
|
||||
} catch (const GfeHttpResponseException& e) {
|
||||
emit pairingCompleted(m_Computer,
|
||||
QString::fromLocal8Bit(e.getStatusMessage()) +
|
||||
" (Error " + QString::number(e.getStatusCode()));
|
||||
}
|
||||
}
|
||||
|
||||
ComputerManager* m_ComputerManager;
|
||||
NvComputer* m_Computer;
|
||||
QString m_Pin;
|
||||
};
|
||||
|
||||
@@ -25,9 +25,8 @@ NvHTTP::NvHTTP(QString address) :
|
||||
}
|
||||
|
||||
QVector<int>
|
||||
NvHTTP::getServerVersionQuad(QString serverInfo)
|
||||
NvHTTP::parseQuad(QString quad)
|
||||
{
|
||||
QString quad = getXmlString(serverInfo, "appversion");
|
||||
QStringList parts = quad.split(".");
|
||||
QVector<int> ret;
|
||||
|
||||
|
||||
@@ -91,7 +91,7 @@ public:
|
||||
|
||||
static
|
||||
QVector<int>
|
||||
getServerVersionQuad(QString serverInfo);
|
||||
parseQuad(QString quad);
|
||||
|
||||
void
|
||||
quitApp();
|
||||
|
||||
@@ -42,12 +42,6 @@ NvPairingManager::~NvPairingManager()
|
||||
EVP_PKEY_free(m_PrivateKey);
|
||||
}
|
||||
|
||||
QString
|
||||
NvPairingManager::generatePinString()
|
||||
{
|
||||
return QString::asprintf("%04d", QRandomGenerator::global()->bounded(10000));
|
||||
}
|
||||
|
||||
QByteArray
|
||||
NvPairingManager::generateRandomBytes(int length)
|
||||
{
|
||||
@@ -167,9 +161,9 @@ NvPairingManager::saltPin(QByteArray salt, QString pin)
|
||||
}
|
||||
|
||||
NvPairingManager::PairState
|
||||
NvPairingManager::pair(QString serverInfo, QString pin)
|
||||
NvPairingManager::pair(QString appVersion, QString pin)
|
||||
{
|
||||
int serverMajorVersion = NvHTTP::getServerVersionQuad(serverInfo).at(0);
|
||||
int serverMajorVersion = NvHTTP::parseQuad(appVersion).at(0);
|
||||
qDebug() << "Pairing with server generation: " << serverMajorVersion;
|
||||
|
||||
QCryptographicHash::Algorithm hashAlgo;
|
||||
|
||||
@@ -23,11 +23,8 @@ public:
|
||||
|
||||
~NvPairingManager();
|
||||
|
||||
QString
|
||||
generatePinString();
|
||||
|
||||
PairState
|
||||
pair(QString serverInfo, QString pin);
|
||||
pair(QString appVersion, QString pin);
|
||||
|
||||
private:
|
||||
QByteArray
|
||||
|
||||
Reference in New Issue
Block a user