diff --git a/apps/browser/MainWindow.cpp b/apps/browser/MainWindow.cpp index 56f25604b..fd20f19ee 100644 --- a/apps/browser/MainWindow.cpp +++ b/apps/browser/MainWindow.cpp @@ -122,19 +122,16 @@ void MainWindow::play() if (id < 0) return; - ServerInfoDialog infoDialog(this); + ServerModel *sm = ((ServerModel*)proxyModel->sourceModel()); int sourceId = proxyModel->mapToSource(proxyModel->index(id, ServerData::ADDR)).row(); - infoDialog.Server(sm->myData[sourceId].addr); + ServerInfoDialog infoDialog(sm->myData[sourceId].addr, this); - if (!infoDialog.refresh()) - { - queryHelper->refresh(); + if (!infoDialog.exec()) return; - } - if (!infoDialog.exec()) + if (!infoDialog.isUpdated()) return; QStringList arguments; diff --git a/apps/browser/ServerInfoDialog.cpp b/apps/browser/ServerInfoDialog.cpp index 7a3809048..8cfee4bc5 100644 --- a/apps/browser/ServerInfoDialog.cpp +++ b/apps/browser/ServerInfoDialog.cpp @@ -6,28 +6,65 @@ #include "qdebug.h" #include "ServerInfoDialog.hpp" -#include #include #include +#include using namespace std; using namespace RakNet; -ServerInfoDialog::ServerInfoDialog(QWidget *parent): QDialog(parent) +ThrWorker::ThrWorker(ServerInfoDialog *dialog, QString addr, unsigned short port): addr(std::move(addr)), port(port), stopped(false) { - setupUi(this); - connect(btnRefresh, SIGNAL(clicked()), this, SLOT(refresh())); + this->dialog = dialog; } -void ServerInfoDialog::Server(const QString &addr) +void ThrWorker::process() { - this->addr = addr; + stopped = false; + auto newSD = QueryClient::Get().Update(SystemAddress(addr.toUtf8(), port)); + if (dialog != nullptr) + dialog->setData(newSD); + stopped = true; + emit finished(); } -bool ServerInfoDialog::refresh() +ServerInfoDialog::ServerInfoDialog(const QString &addr, QWidget *parent): QDialog(parent) { + setupUi(this); + refreshThread = new QThread; + QStringList list = addr.split(':'); - auto sd = QueryClient::Get().Update(SystemAddress(list[0].toLatin1(), list[1].toUShort())); + worker = new ThrWorker(this, list[0].toLatin1(), list[1].toUShort()); + worker->moveToThread(refreshThread); + connect(refreshThread, SIGNAL(started()), worker, SLOT(process())); + connect(worker, SIGNAL(finished()), refreshThread, SLOT(quit())); + connect(refreshThread, SIGNAL(finished()), this, SLOT(refresh())); + + connect(btnRefresh, &QPushButton::clicked, [this]{ + if (!refreshThread->isRunning()) + refreshThread->start(); + }); +} + +ServerInfoDialog::~ServerInfoDialog() +{ + worker->dialog = nullptr; + if (!refreshThread->isRunning()) + refreshThread->terminate(); +} + +bool ServerInfoDialog::isUpdated() +{ + return sd.first != UNASSIGNED_SYSTEM_ADDRESS; +} + +void ServerInfoDialog::setData(std::pair &newSD) +{ + sd = newSD; +} + +void ServerInfoDialog::refresh() +{ if (sd.first != UNASSIGNED_SYSTEM_ADDRESS) { leAddr->setText(sd.first.ToString(true, ':')); @@ -37,17 +74,16 @@ bool ServerInfoDialog::refresh() btnConnect->setDisabled(ping == PING_UNREACHABLE); listPlayers->clear(); - for (const auto &player : sd.second.players) listPlayers->addItem(QString::fromStdString(player)); listPlugins->clear(); - for (auto plugin : sd.second.plugins) + for (const auto &plugin : sd.second.plugins) listPlugins->addItem(QString::fromStdString(plugin.name)); listRules->clear(); const static vector defaultRules {"gamemode", "maxPlayers", "name", "passw", "players", "version"}; - for (auto rule : sd.second.rules) + for (auto &rule : sd.second.rules) { if (::find(defaultRules.begin(), defaultRules.end(), rule.first) != defaultRules.end()) continue; @@ -60,7 +96,12 @@ bool ServerInfoDialog::refresh() } lblPlayers->setText(QString::number(sd.second.players.size()) + " / " + QString::number(sd.second.GetMaxPlayers())); - return true; } - return false; +} + +int ServerInfoDialog::exec() +{ + if (!refreshThread->isRunning()) + refreshThread->start(); + return QDialog::exec(); } diff --git a/apps/browser/ServerInfoDialog.hpp b/apps/browser/ServerInfoDialog.hpp index e6fedff6f..a1ee62fee 100644 --- a/apps/browser/ServerInfoDialog.hpp +++ b/apps/browser/ServerInfoDialog.hpp @@ -6,17 +6,45 @@ #define NEWLAUNCHER_SERVERINFODIALOG_HPP #include "ui_ServerInfo.h" +#include +#include +#include + +class ThrWorker; class ServerInfoDialog : public QDialog, public Ui::Dialog { Q_OBJECT public: - explicit ServerInfoDialog(QWidget *parent = nullptr); - void Server(const QString &addr); + explicit ServerInfoDialog(const QString &addr, QWidget *parent = nullptr); + ~ServerInfoDialog() override; + bool isUpdated(); + void setData(std::pair &newSD); +public slots: + void refresh(); + int exec() Q_DECL_OVERRIDE; +private: + QThread *refreshThread; + ThrWorker* worker; + std::pair sd; +}; + +class ThrWorker: public QObject +{ + friend class ServerInfoDialog; +Q_OBJECT +public: + ThrWorker(ServerInfoDialog *dialog, QString addr, unsigned short port); + public slots: - bool refresh(); + void process(); +signals: + void finished(); private: QString addr; + unsigned short port; + bool stopped; + ServerInfoDialog *dialog; };