mirror of
https://github.com/PrismLauncher/PrismLauncher.git
synced 2025-05-07 01:54:38 +02:00
remove waitForConnected() and waitForReadyRead() and use signals ineatd
Signed-off-by: iTrooz <hey@itrooz.fr>
This commit is contained in:
parent
43376b1c40
commit
fe8f755b43
@ -15,33 +15,21 @@
|
|||||||
|
|
||||||
McClient::McClient(QObject *parent, QString domain, QString ip, short port): QObject(parent), m_domain(domain), m_ip(ip), m_port(port) {}
|
McClient::McClient(QObject *parent, QString domain, QString ip, short port): QObject(parent), m_domain(domain), m_ip(ip), m_port(port) {}
|
||||||
|
|
||||||
QJsonObject McClient::getStatusDataBlocking() {
|
void McClient::getStatusData() {
|
||||||
qDebug() << "Connecting to socket..";
|
qDebug() << "Connecting to socket..";
|
||||||
m_socket.connectToHost(m_ip, m_port);
|
|
||||||
|
|
||||||
if (!m_socket.waitForConnected()) {
|
connect(&m_socket, &QTcpSocket::connected, this, [this]() {
|
||||||
throw Exception("Failed to connect to socket");
|
qDebug() << "Connected to socket successfully";
|
||||||
}
|
sendRequest();
|
||||||
qDebug() << "Connected to socket successfully";
|
|
||||||
sendRequest();
|
|
||||||
|
|
||||||
if (!m_socket.waitForReadyRead()) {
|
connect(&m_socket, &QTcpSocket::readyRead, this, &McClient::readRawResponse);
|
||||||
throw Exception("Socket didn't send anything to read");
|
|
||||||
}
|
|
||||||
return readResponse();
|
|
||||||
}
|
|
||||||
|
|
||||||
QFuture<int> McClient::getOnlinePlayers() {
|
|
||||||
return QtConcurrent::run([this]() {
|
|
||||||
try {
|
|
||||||
auto status = getStatusDataBlocking();
|
|
||||||
auto players = Json::requireObject(status, "players");
|
|
||||||
return Json::requireInteger(players, "online");
|
|
||||||
} catch (const Exception &e) {
|
|
||||||
qDebug() << "Error: " << e.what();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
connect(&m_socket, &QTcpSocket::errorOccurred, this, [this]() {
|
||||||
|
emitFail("Socket disconnected");
|
||||||
|
});
|
||||||
|
|
||||||
|
m_socket.connectToHost(m_ip, m_port);
|
||||||
}
|
}
|
||||||
|
|
||||||
void McClient::sendRequest() {
|
void McClient::sendRequest() {
|
||||||
@ -58,32 +46,25 @@ void McClient::sendRequest() {
|
|||||||
writePacketToSocket(data); // send status packet
|
writePacketToSocket(data); // send status packet
|
||||||
}
|
}
|
||||||
|
|
||||||
void McClient::readBytesExactFromSocket(QByteArray &resp, int bytesToRead) {
|
// Accumulate data until we have a full response, then call parseResponse()
|
||||||
while (bytesToRead > 0) {
|
void McClient::readRawResponse() {
|
||||||
qDebug() << bytesToRead << " bytes left to read";
|
m_resp.append(m_socket.readAll());
|
||||||
if (!m_socket.waitForReadyRead()) {
|
if (m_wantedRespLength == 0 && m_resp.size() >= 5) {
|
||||||
throw Exception("Read timeout or error");
|
m_wantedRespLength = readVarInt(m_resp);
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray chunk = m_socket.read(bytesToRead);
|
if (m_wantedRespLength != 0 && m_resp.size() >= m_wantedRespLength) {
|
||||||
resp.append(chunk);
|
if (m_resp.size() > m_wantedRespLength) {
|
||||||
bytesToRead -= chunk.size();
|
qDebug() << "Warning: Packet length doesn't match actual packet size (" << m_wantedRespLength << " expected vs " << m_resp.size() << " received)";
|
||||||
|
}
|
||||||
|
parseResponse();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QJsonObject McClient::readResponse() {
|
void McClient::parseResponse() {
|
||||||
auto resp = m_socket.readAll();
|
|
||||||
int length = readVarInt(resp);
|
|
||||||
|
|
||||||
// finish ready response
|
|
||||||
readBytesExactFromSocket(resp, length-resp.size());
|
|
||||||
|
|
||||||
if (length != resp.size()) {
|
|
||||||
qDebug() << "Warning: Packet length doesn't match actual packet size (" << length << " expected vs " << resp.size() << " received)";
|
|
||||||
}
|
|
||||||
qDebug() << "Received response successfully";
|
qDebug() << "Received response successfully";
|
||||||
|
|
||||||
int packetID = readVarInt(resp);
|
int packetID = readVarInt(m_resp);
|
||||||
if (packetID != 0x00) {
|
if (packetID != 0x00) {
|
||||||
throw Exception(
|
throw Exception(
|
||||||
QString("Packet ID doesn't match expected value (0x00 vs 0x%1)")
|
QString("Packet ID doesn't match expected value (0x00 vs 0x%1)")
|
||||||
@ -91,11 +72,11 @@ QJsonObject McClient::readResponse() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Q_UNUSED(readVarInt(resp)); // json length
|
Q_UNUSED(readVarInt(m_resp)); // json length
|
||||||
|
|
||||||
// 'resp' should now be the JSON string
|
// 'resp' should now be the JSON string
|
||||||
QJsonDocument doc = QJsonDocument::fromJson(resp);
|
QJsonDocument doc = QJsonDocument::fromJson(m_resp);
|
||||||
return doc.object();
|
emitSucceed(doc.object());
|
||||||
}
|
}
|
||||||
|
|
||||||
// From https://wiki.vg/Protocol#VarInt_and_VarLong
|
// From https://wiki.vg/Protocol#VarInt_and_VarLong
|
||||||
@ -164,3 +145,15 @@ void McClient::writePacketToSocket(QByteArray &data) {
|
|||||||
|
|
||||||
data.clear();
|
data.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void McClient::emitFail(QString error) {
|
||||||
|
qDebug() << "Minecraft server ping for status error:" << error;
|
||||||
|
emit failed();
|
||||||
|
emit finished();
|
||||||
|
}
|
||||||
|
|
||||||
|
void McClient::emitSucceed(QJsonObject data) {
|
||||||
|
emit succeeded(data);
|
||||||
|
emit finished();
|
||||||
|
}
|
||||||
|
@ -15,14 +15,16 @@ class McClient : public QObject {
|
|||||||
short m_port;
|
short m_port;
|
||||||
QTcpSocket m_socket;
|
QTcpSocket m_socket;
|
||||||
|
|
||||||
|
unsigned m_wantedRespLength = 0;
|
||||||
|
QByteArray m_resp;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit McClient(QObject *parent, QString domain, QString ip, short port);
|
explicit McClient(QObject *parent, QString domain, QString ip, short port);
|
||||||
QFuture<int> getOnlinePlayers();
|
void getStatusData();
|
||||||
private:
|
private:
|
||||||
QJsonObject getStatusDataBlocking();
|
|
||||||
void sendRequest();
|
void sendRequest();
|
||||||
QJsonObject readResponse();
|
void readRawResponse();
|
||||||
void readBytesExactFromSocket(QByteArray &resp, int bytesToRead);
|
void parseResponse();
|
||||||
|
|
||||||
void writeVarInt(QByteArray &data, int value);
|
void writeVarInt(QByteArray &data, int value);
|
||||||
int readVarInt(QByteArray &data);
|
int readVarInt(QByteArray &data);
|
||||||
@ -32,4 +34,12 @@ private:
|
|||||||
void writeString(QByteArray &data, const std::string &value);
|
void writeString(QByteArray &data, const std::string &value);
|
||||||
|
|
||||||
void writePacketToSocket(QByteArray &data);
|
void writePacketToSocket(QByteArray &data);
|
||||||
|
|
||||||
|
void emitFail(QString error);
|
||||||
|
void emitSucceed(QJsonObject data);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void succeeded(QJsonObject data);
|
||||||
|
void failed();
|
||||||
|
void finished();
|
||||||
};
|
};
|
||||||
|
@ -3,6 +3,11 @@
|
|||||||
#include "ServerPingTask.h"
|
#include "ServerPingTask.h"
|
||||||
#include "McResolver.h"
|
#include "McResolver.h"
|
||||||
#include "McClient.h"
|
#include "McClient.h"
|
||||||
|
#include <Json.h>
|
||||||
|
|
||||||
|
unsigned getOnlinePlayers(QJsonObject data) {
|
||||||
|
return Json::requireInteger(Json::requireObject(data, "players"), "online");
|
||||||
|
}
|
||||||
|
|
||||||
void ServerPingTask::executeTask() {
|
void ServerPingTask::executeTask() {
|
||||||
qDebug() << "Querying status of " << QString("%1:%2").arg(m_domain).arg(m_port);
|
qDebug() << "Querying status of " << QString("%1:%2").arg(m_domain).arg(m_port);
|
||||||
@ -14,26 +19,21 @@ void ServerPingTask::executeTask() {
|
|||||||
|
|
||||||
// Now that we have the IP and port, query the server
|
// Now that we have the IP and port, query the server
|
||||||
McClient *client = new McClient(nullptr, m_domain, ip, port);
|
McClient *client = new McClient(nullptr, m_domain, ip, port);
|
||||||
auto onlineFuture = client->getOnlinePlayers();
|
|
||||||
|
|
||||||
// Wait for query to finish
|
QObject::connect(client, &McClient::succeeded, this, [this](QJsonObject data) {
|
||||||
QFutureWatcher<int> *watcher = new QFutureWatcher<int>();
|
m_outputOnlinePlayers = getOnlinePlayers(data);
|
||||||
QObject::connect(watcher, &QFutureWatcher<int>::finished, this, [this, client, onlineFuture, watcher]() {
|
qDebug() << "Online players: " << m_outputOnlinePlayers;
|
||||||
client->deleteLater();
|
emitSucceeded();
|
||||||
watcher->deleteLater();
|
|
||||||
|
|
||||||
int online = onlineFuture.result();
|
|
||||||
if (online == -1) {
|
|
||||||
qDebug() << "Failed to get online players";
|
|
||||||
emitFailed();
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
qDebug() << "Online players: " << online;
|
|
||||||
m_outputOnlinePlayers = online;
|
|
||||||
emitSucceeded();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
watcher->setFuture(onlineFuture);
|
QObject::connect(client, &McClient::failed, this, [this]() {
|
||||||
|
emitFailed();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Delete McClient object when done
|
||||||
|
QObject::connect(client, &McClient::finished, this, [this, client]() {
|
||||||
|
client->deleteLater();
|
||||||
|
});
|
||||||
|
client->getStatusData();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Delete McResolver object when done
|
// Delete McResolver object when done
|
||||||
|
Loading…
x
Reference in New Issue
Block a user