mirror of
https://github.com/moonlight-stream/moonlight-qt
synced 2024-12-13 21:02:28 +00:00
Work on Computer Manager
This commit is contained in:
parent
cded01187d
commit
5ee52f15c8
4 changed files with 242 additions and 71 deletions
186
app/http/computermanager.cpp
Normal file
186
app/http/computermanager.cpp
Normal file
|
@ -0,0 +1,186 @@
|
|||
#include "computermanager.h"
|
||||
#include "nvhttp.h"
|
||||
|
||||
#include <QThread>
|
||||
|
||||
ComputerManager::ComputerManager()
|
||||
: m_Polling(false)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void ComputerManager::startPolling()
|
||||
{
|
||||
m_Polling = true;
|
||||
|
||||
|
||||
}
|
||||
|
||||
class PcMonitorThread : public QThread
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
#define TRIES_BEFORE_OFFLINING 2
|
||||
#define POLLS_PER_APPLIST_FETCH 10
|
||||
|
||||
PcMonitorThread(NvComputer* computer, IdentityManager im)
|
||||
: m_Im(im),
|
||||
m_Computer(computer)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
#define DECLARE_UPDATE_COMPUTER_FIELD(Type) \
|
||||
bool UpdateComputerField(Type& oldValue, Type newValue) \
|
||||
{ \
|
||||
if (oldValue == newValue) { \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
oldValue = newValue; \
|
||||
return true; \
|
||||
}
|
||||
|
||||
DECLARE_UPDATE_COMPUTER_FIELD(QString)
|
||||
DECLARE_UPDATE_COMPUTER_FIELD(int)
|
||||
DECLARE_UPDATE_COMPUTER_FIELD(QByteArray)
|
||||
DECLARE_UPDATE_COMPUTER_FIELD(NvComputer::ComputerState)
|
||||
DECLARE_UPDATE_COMPUTER_FIELD(NvComputer::PairState)
|
||||
|
||||
bool TryPollComputer(QString& address, bool& changed)
|
||||
{
|
||||
NvHTTP http(address, m_Im);
|
||||
|
||||
QString serverInfo;
|
||||
try {
|
||||
serverInfo = http.getServerInfo();
|
||||
} catch (...) {
|
||||
return false;
|
||||
}
|
||||
|
||||
changed = false;
|
||||
|
||||
QString newName = http.getXmlString(serverInfo, "hostname");
|
||||
if (newName.isNull()) {
|
||||
newName = "UNKNOWN";
|
||||
}
|
||||
changed |= UpdateComputerField(m_Computer->name, newName);
|
||||
changed |= UpdateComputerField(m_Computer->uuid, http.getXmlString(serverInfo, "uniqueid"));
|
||||
|
||||
QString newMacString = http.getXmlString(serverInfo, "mac");
|
||||
QByteArray newMac;
|
||||
if (newMacString != "00:00:00:00:00:00") {
|
||||
QStringList macOctets = newMacString.split(':');
|
||||
for (QString macOctet : macOctets) {
|
||||
newMac.append((char) macOctet.toInt(nullptr, 16));
|
||||
}
|
||||
changed |= UpdateComputerField(m_Computer->macAddress, newMac);
|
||||
}
|
||||
changed |= UpdateComputerField(m_Computer->localAddress, http.getXmlString(serverInfo, "LocalIP"));
|
||||
changed |= UpdateComputerField(m_Computer->remoteAddress, http.getXmlString(serverInfo, "ExternalIP"));
|
||||
changed |= UpdateComputerField(m_Computer->pairState, http.getXmlString(serverInfo, "PairStatus") == "1" ?
|
||||
NvComputer::PS_PAIRED : NvComputer::PS_NOT_PAIRED);
|
||||
changed |= UpdateComputerField(m_Computer->currentGameId, http.getCurrentGame(serverInfo));
|
||||
changed |= UpdateComputerField(m_Computer->activeAddress, address);
|
||||
changed |= UpdateComputerField(m_Computer->state, NvComputer::CS_ONLINE);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool UpdateAppList(bool& changed)
|
||||
{
|
||||
changed = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
void run() override
|
||||
{
|
||||
// Always fetch the applist the first time
|
||||
int pollsSinceLastAppListFetch = POLLS_PER_APPLIST_FETCH;
|
||||
while (!isInterruptionRequested()) {
|
||||
QVector<QString> uniqueAddressList;
|
||||
|
||||
// Start with addresses correctly ordered
|
||||
uniqueAddressList.append(m_Computer->activeAddress);
|
||||
uniqueAddressList.append(m_Computer->localAddress);
|
||||
uniqueAddressList.append(m_Computer->remoteAddress);
|
||||
uniqueAddressList.append(m_Computer->manualAddress);
|
||||
|
||||
// Prune duplicates (always giving precedence to the first)
|
||||
for (int i = 0; i < uniqueAddressList.count(); i++) {
|
||||
if (uniqueAddressList[i].isEmpty() || uniqueAddressList[i].isNull()) {
|
||||
uniqueAddressList.remove(i);
|
||||
i--;
|
||||
continue;
|
||||
}
|
||||
for (int j = i + 1; j < uniqueAddressList.count(); j++) {
|
||||
if (uniqueAddressList[i] == uniqueAddressList[j]) {
|
||||
// Always remove the later occurrence
|
||||
uniqueAddressList.remove(j);
|
||||
j--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// We must have at least 1 address for this host
|
||||
Q_ASSERT(uniqueAddressList.count() != 0);
|
||||
|
||||
|
||||
bool stateChanged = false;
|
||||
for (int i = 0; i < TRIES_BEFORE_OFFLINING; i++) {
|
||||
for (auto& address : uniqueAddressList) {
|
||||
if (isInterruptionRequested()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (TryPollComputer(address, stateChanged)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// No need to continue retrying if we're online
|
||||
if (m_Computer->state == NvComputer::CS_ONLINE) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if we failed after all retry attempts
|
||||
if (m_Computer->state != NvComputer::CS_ONLINE) {
|
||||
if (m_Computer->state != NvComputer::CS_OFFLINE) {
|
||||
m_Computer->state = NvComputer::CS_OFFLINE;
|
||||
stateChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (stateChanged) {
|
||||
// Tell anyone listening that we've changed state
|
||||
emit computerStateChanged(m_Computer);
|
||||
}
|
||||
|
||||
// Grab the applist if it's empty or it's been long enough that we need to refresh
|
||||
pollsSinceLastAppListFetch++;
|
||||
if (m_Computer->state == NvComputer::CS_ONLINE &&
|
||||
(m_Computer->appList.isEmpty() || pollsSinceLastAppListFetch >= POLLS_PER_APPLIST_FETCH)) {
|
||||
stateChanged = false;
|
||||
|
||||
if (UpdateAppList(stateChanged)) {
|
||||
pollsSinceLastAppListFetch = 0;
|
||||
}
|
||||
|
||||
if (stateChanged) {
|
||||
emit computerStateChanged(m_Computer);
|
||||
}
|
||||
}
|
||||
|
||||
// Wait a bit to poll again
|
||||
QThread::sleep(3);
|
||||
}
|
||||
}
|
||||
|
||||
signals:
|
||||
void computerStateChanged(NvComputer* computer);
|
||||
|
||||
private:
|
||||
IdentityManager m_Im;
|
||||
NvComputer* m_Computer;
|
||||
};
|
56
app/http/computermanager.h
Normal file
56
app/http/computermanager.h
Normal file
|
@ -0,0 +1,56 @@
|
|||
#pragma once
|
||||
#include "nvhttp.h"
|
||||
|
||||
|
||||
class ComputerManager
|
||||
{
|
||||
public:
|
||||
ComputerManager();
|
||||
|
||||
void startPolling();
|
||||
|
||||
private:
|
||||
bool m_Polling;
|
||||
};
|
||||
|
||||
class NvApp
|
||||
{
|
||||
public:
|
||||
int id;
|
||||
QString name;
|
||||
bool hdrSupported;
|
||||
};
|
||||
|
||||
class NvComputer
|
||||
{
|
||||
public:
|
||||
enum PairState
|
||||
{
|
||||
PS_UNKNOWN,
|
||||
PS_PAIRED,
|
||||
PS_NOT_PAIRED
|
||||
};
|
||||
|
||||
enum ComputerState
|
||||
{
|
||||
CS_UNKNOWN,
|
||||
CS_ONLINE,
|
||||
CS_OFFLINE
|
||||
};
|
||||
|
||||
// Ephemeral traits
|
||||
ComputerState state;
|
||||
PairState pairState;
|
||||
QString activeAddress;
|
||||
int currentGameId;
|
||||
|
||||
// Persisted traits
|
||||
QString localAddress;
|
||||
QString remoteAddress;
|
||||
QString manualAddress;
|
||||
QByteArray macAddress;
|
||||
QString name;
|
||||
QString uuid;
|
||||
int serverCodecModeSupport;
|
||||
QVector<NvApp> appList;
|
||||
};
|
|
@ -23,45 +23,6 @@ NvHTTP::NvHTTP(QString address, IdentityManager im) :
|
|||
m_BaseUrlHttps.setPort(47984);
|
||||
}
|
||||
|
||||
NvComputer
|
||||
NvHTTP::getComputerInfo()
|
||||
{
|
||||
NvComputer computer;
|
||||
QString serverInfo = getServerInfo();
|
||||
|
||||
computer.m_Name = getXmlString(serverInfo, "hostname");
|
||||
if (computer.m_Name == nullptr)
|
||||
{
|
||||
computer.m_Name = "UNKNOWN";
|
||||
}
|
||||
|
||||
computer.m_Uuid = getXmlString(serverInfo, "uniqueid");
|
||||
computer.m_MacAddress = getXmlString(serverInfo, "mac");
|
||||
|
||||
// If there's no LocalIP field, use the address we hit the server on
|
||||
computer.m_LocalAddress = getXmlString(serverInfo, "LocalIP");
|
||||
if (computer.m_LocalAddress == nullptr)
|
||||
{
|
||||
computer.m_LocalAddress = m_Address;
|
||||
}
|
||||
|
||||
// If there's no ExternalIP field, use the address we hit the server on
|
||||
computer.m_RemoteAddress = getXmlString(serverInfo, "ExternalIP");
|
||||
if (computer.m_RemoteAddress == nullptr)
|
||||
{
|
||||
computer.m_RemoteAddress = m_Address;
|
||||
}
|
||||
|
||||
computer.m_PairState = getXmlString(serverInfo, "PairStatus") == "1" ?
|
||||
NvComputer::PS_PAIRED : NvComputer::PS_NOT_PAIRED;
|
||||
|
||||
computer.m_RunningGameId = getCurrentGame(serverInfo);
|
||||
|
||||
computer.m_State = NvComputer::CS_ONLINE;
|
||||
|
||||
return computer;
|
||||
}
|
||||
|
||||
QVector<int>
|
||||
NvHTTP::getServerVersionQuad(QString serverInfo)
|
||||
{
|
||||
|
|
|
@ -37,43 +37,11 @@ private:
|
|||
QString m_StatusMessage;
|
||||
};
|
||||
|
||||
class NvComputer
|
||||
{
|
||||
public:
|
||||
NvComputer() {}
|
||||
|
||||
enum PairState
|
||||
{
|
||||
PS_UNKNOWN,
|
||||
PS_PAIRED,
|
||||
PS_NOT_PAIRED
|
||||
};
|
||||
|
||||
enum ComputerState
|
||||
{
|
||||
CS_UNKNOWN,
|
||||
CS_ONLINE,
|
||||
CS_OFFLINE
|
||||
};
|
||||
|
||||
QString m_Name;
|
||||
QString m_Uuid;
|
||||
QString m_MacAddress;
|
||||
QString m_LocalAddress;
|
||||
QString m_RemoteAddress;
|
||||
int m_RunningGameId;
|
||||
PairState m_PairState;
|
||||
ComputerState m_State;
|
||||
};
|
||||
|
||||
class NvHTTP
|
||||
{
|
||||
public:
|
||||
NvHTTP(QString address, IdentityManager im);
|
||||
|
||||
NvComputer
|
||||
getComputerInfo();
|
||||
|
||||
int
|
||||
getCurrentGame(QString serverInfo);
|
||||
|
||||
|
|
Loading…
Reference in a new issue