[Browser] Update to new protocol

pull/176/merge
Koncord 8 years ago
parent e7a1474e04
commit db2b53c1b8

@ -9,7 +9,6 @@ set(BROWSER
main.cpp main.cpp
MainWindow.cpp MainWindow.cpp
ServerModel.cpp ServerModel.cpp
NetController.cpp
ServerInfoDialog.cpp ServerInfoDialog.cpp
MySortFilterProxyModel.cpp MySortFilterProxyModel.cpp
netutils/HTTPNetwork.cpp netutils/HTTPNetwork.cpp
@ -27,7 +26,6 @@ set(BROWSER_HEADER_MOC
set(BROWSER_HEADER set(BROWSER_HEADER
${BROWSER_HEADER_MOC} ${BROWSER_HEADER_MOC}
NetController.hpp
netutils/HTTPNetwork.hpp netutils/HTTPNetwork.hpp
netutils/Utils.hpp netutils/Utils.hpp
netutils/QueryClient.hpp netutils/QueryClient.hpp

@ -3,7 +3,6 @@
// //
#include "MainWindow.hpp" #include "MainWindow.hpp"
#include "NetController.hpp"
#include "ServerInfoDialog.hpp" #include "ServerInfoDialog.hpp"
#include "components/files/configurationmanager.hpp" #include "components/files/configurationmanager.hpp"
#include <qdebug.h> #include <qdebug.h>
@ -12,8 +11,11 @@
#include <QJsonArray> #include <QJsonArray>
#include <QFile> #include <QFile>
#include <QJsonDocument> #include <QJsonDocument>
#include <apps/browser/netutils/QueryClient.hpp>
#include <apps/browser/netutils/Utils.hpp>
using namespace Process; using namespace Process;
using namespace std;
MainWindow::MainWindow(QWidget *parent) MainWindow::MainWindow(QWidget *parent)
{ {
@ -58,7 +60,12 @@ void MainWindow::addServerAndUpdate(QString addr)
favorites->insertRow(0); favorites->insertRow(0);
QModelIndex mi = favorites->index(0, ServerData::ADDR); QModelIndex mi = favorites->index(0, ServerData::ADDR);
favorites->setData(mi, addr, Qt::EditRole); favorites->setData(mi, addr, Qt::EditRole);
NetController::get()->updateInfo(favorites, mi); //NetController::get()->updateInfo(favorites, mi);
//QueryClient::Update(RakNet::SystemAddress())
/*auto data = QueryClient::Get().Query();
if(data.empty())
return;
transform(data.begin(), data.end(), back_inserter());*/
} }
void MainWindow::addServer() void MainWindow::addServer()
@ -99,11 +106,42 @@ void MainWindow::deleteServer()
bool MainWindow::refresh() bool MainWindow::refresh()
{ {
return NetController::get()->updateInfo(proxyModel->sourceModel()); auto data = QueryClient::Get().Query();
/*tblServerBrowser->resizeColumnToContents(ServerData::HOSTNAME); if(QueryClient::Get().Status() != ID_MASTER_QUERY)
tblServerBrowser->resizeColumnToContents(ServerData::MODNAME); return false;
tblFavorites->resizeColumnToContents(ServerData::HOSTNAME);
tblFavorites->resizeColumnToContents(ServerData::MODNAME);*/ ServerModel *model = ((ServerModel*)proxyModel->sourceModel());
model->removeRows(0, model->rowCount());
for(auto server : data)
{
model->insertRow(0);
QModelIndex mi = model->index(0, ServerData::ADDR);
model->setData(mi, server.first.ToString(true, ':'));
mi = model->index(0, ServerData::PLAYERS);
model->setData(mi, server.second.GetPlayers());
mi = model->index(0, ServerData::MAX_PLAYERS);
model->setData(mi, server.second.GetMaxPlayers());
mi = model->index(0, ServerData::HOSTNAME);
model->setData(mi, server.second.GetName());
mi = model->index(0, ServerData::MODNAME);
model->setData(mi, server.second.GetGameMode());
mi = model->index(0, ServerData::VERSION);
model->setData(mi, server.second.GetVersion());
mi = model->index(0, ServerData::PASSW);
model->setData(mi, server.second.GetPassword() == 1);
mi = model->index(0, ServerData::PING);
model->setData(mi, PingRakNetServer(server.first.ToString(false), server.first.GetPort()));
}
return true;
} }
void MainWindow::play() void MainWindow::play()
@ -117,7 +155,7 @@ void MainWindow::play()
ServerModel *sm = ((ServerModel*)proxyModel->sourceModel()); ServerModel *sm = ((ServerModel*)proxyModel->sourceModel());
int sourceId = proxyModel->mapToSource(proxyModel->index(id, ServerData::ADDR)).row(); int sourceId = proxyModel->mapToSource(proxyModel->index(id, ServerData::ADDR)).row();
NetController::get()->selectServer(&sm->myData[sourceId]); infoDialog.Server(sm->myData[sourceId].addr);
infoDialog.refresh(); infoDialog.refresh();
if(!infoDialog.exec()) if(!infoDialog.exec())
return; return;
@ -125,7 +163,7 @@ void MainWindow::play()
QStringList arguments; QStringList arguments;
arguments.append(QLatin1String("--connect=") + sm->myData[sourceId].addr.toLatin1()); arguments.append(QLatin1String("--connect=") + sm->myData[sourceId].addr.toLatin1());
if(sm->myData[sourceId].needPassw) if(sm->myData[sourceId].GetPassword() == 1)
{ {
bool ok; bool ok;
QString passw = QInputDialog::getText(this, "Connecting to: " + sm->myData[sourceId].addr, "Password: ", QLineEdit::Password, "", &ok); QString passw = QInputDialog::getText(this, "Connecting to: " + sm->myData[sourceId].addr, "Password: ", QLineEdit::Password, "", &ok);

@ -1,266 +0,0 @@
//
// Created by koncord on 07.01.17.
//
#include <cassert>
#include <QtCore/QTime>
#include "NetController.hpp"
#include "qdebug.h"
#include <RakPeer.h>
#include <RakSleep.h>
#include <sstream>
#include <QJsonDocument>
#include <QJsonArray>
#include <QJsonObject>
#include <memory>
#include <QtWidgets/QMessageBox>
using namespace std;
NetController *NetController::mThis = nullptr;
NetController *NetController::get()
{
assert(mThis);
return mThis;
}
void NetController::Create(std::string addr, unsigned short port)
{
assert(!mThis);
mThis = new NetController(addr, port);
}
void NetController::Destroy()
{
assert(mThis);
delete mThis;
mThis = nullptr;
}
NetController::NetController(std::string addr, unsigned short port) : httpNetwork(addr, port)
{
}
NetController::~NetController()
{
}
struct pattern
{
pattern(QString value): value(value) {}
bool operator()(const ServerData &data)
{
return value == data.addr;
}
QString value;
};
void NetController::setData(QString address, QJsonObject server, ServerModel *model)
{
QModelIndex mi = model->index(0, ServerData::ADDR);
model->setData(mi, address);
mi = model->index(0, ServerData::PLAYERS);
model->setData(mi, server["players"].toInt());
mi = model->index(0, ServerData::MAX_PLAYERS);
model->setData(mi, server["max_players"].toInt());
mi = model->index(0, ServerData::HOSTNAME);
model->setData(mi, server["hostname"].toString());
mi = model->index(0, ServerData::MODNAME);
model->setData(mi, server["modname"].toString());
mi = model->index(0, ServerData::VERSION);
model->setData(mi, server["version"].toString());
mi = model->index(0, ServerData::PASSW);
model->setData(mi, server["passw"].toBool());
mi = model->index(0, ServerData::PING);
// This *should* fix a crash when a port isn't returned by data.
if(!address.contains(":"))
address.append(":25565");
QStringList addr = address.split(":");
model->setData(mi, PingRakNetServer(addr[0].toLatin1().data(), addr[1].toUShort()));
}
bool NetController::downloadInfo(QAbstractItemModel *pModel, QModelIndex index)
{
ServerModel *model = ((ServerModel *) pModel);
/*
* download stuff
*/
QString data;
QJsonParseError err;
if(index.isValid() && index.row() >= 0)
{
const ServerData &sd = model->myData[index.row()];
while(true)
{
data = QString::fromStdString(httpNetwork.getData((QString("/api/servers/") + sd.addr).toLatin1()));
if (!data.isEmpty() && data != "NO_CONTENT" && data != "LOST_CONNECTION")
break;
RakSleep(30);
}
qDebug() << "Content for \"" << sd.addr << "\": " << data;
if(data == "bad request" || data == "not found") // TODO: if server is not registered we should download info directly from the server
{
qDebug() << "Server is not registered";
return false;
}
QJsonDocument jsonDocument = QJsonDocument::fromJson(data.toLatin1(), &err);
QJsonObject server = jsonDocument.object()["server"].toObject();
setData(sd.addr, server, model);
return true;
}
while (true)
{
data = QString::fromStdString(httpNetwork.getData("/api/servers"));
if (!data.isEmpty() && data != "NO_CONTENT" && data != "LOST_CONNECTION")
break;
RakSleep(30);
}
if(data == "UNKNOWN_ADDRESS")
{
QMessageBox::critical(0, "Error", "Cannot connect to the master server!");
return false;
}
qDebug() << "Content: " << data;
QJsonDocument jsonDocument = QJsonDocument::fromJson(data.toLatin1(), &err);
QJsonObject listServers = jsonDocument.object()["list servers"].toObject();
for(auto iter = listServers.begin(); iter != listServers.end(); iter++)
{
QJsonObject server = iter->toObject();
qDebug() << iter.key();
qDebug() << server["hostname"].toString();
qDebug() << server["modname"].toString();
qDebug() << server["players"].toInt();
qDebug() << server["max_players"].toInt();
qDebug() << server["version"].toString();
qDebug() << server["passw"].toBool();
QVector<ServerData>::Iterator value = std::find_if(model->myData.begin(), model->myData.end(), pattern(iter.key()));
if(value == model->myData.end())
model->insertRow(0);
setData(iter.key(), server, model);
}
return true;
}
bool NetController::updateInfo(QAbstractItemModel *pModel, QModelIndex index)
{
ServerModel *model = ((ServerModel*)pModel);
bool result;
if (index.isValid() && index.row() >= 0)
result = downloadInfo(pModel, index);
else
{
for (auto iter = model->myData.begin(); iter != model->myData.end(); iter++)
{
qDebug() << iter->addr;
}
model->removeRows(0, model->rowCount(index));
result = downloadInfo(pModel, index);
}
return result;
}
void NetController::updateInfo()
{
QString data;
QString uri = "/api/servers/" + sd->addr;
while (true)
{
data = QString::fromStdString(httpNetwork.getData(uri.toLatin1()));
if (!data.isEmpty() && data != "NO_CONTENT" && data != "LOST_CONNECTION")
break;
RakSleep(30);
}
if(data == "UNKNOWN_ADDRESS")
{
QMessageBox::critical(0, "Error", "Cannot connect to the master server!");
return;
}
qDebug() << "Content: " << data;
QJsonParseError err;
QJsonDocument jsonDocument = QJsonDocument::fromJson(data.toLatin1(), &err);
QMap<QString, QVariant> map = jsonDocument.toVariant().toMap()["server"].toMap();
qDebug() << sd->addr;
qDebug() << map["hostname"].toString();
qDebug() << map["modname"].toString();
qDebug() << map["players"].toInt();
qDebug() << map["max_players"].toInt();
qDebug() << map["version"].toString();
qDebug() << map["passw"].toBool();
sd->hostName = map["hostname"].toString();
sd->modName = map["modname"].toString();
sd->players = map["players"].toInt();
sd->maxPlayers = map["max_players"].toInt();
if(!sd->addr.contains(":"))
sd->addr.append(":25565");
QStringList addr = sd->addr.split(":");
sd->ping = PingRakNetServer(addr[0].toLatin1(), addr[1].toUShort());
if(sd->ping != PING_UNREACHABLE)
sed = getExtendedData(addr[0].toLatin1(), addr[1].toUShort());
else
qDebug() << "Server is unreachable";
}
QStringList NetController::players()
{
QStringList listPlayers;
for(auto player = sed.players.begin(); player != sed.players.end(); player++)
listPlayers.push_back(player->c_str());
return listPlayers;
}
QStringList NetController::plugins()
{
QStringList listPlugins;
for(auto plugin = sed.plugins.begin(); plugin != sed.plugins.end(); plugin++)
listPlugins.push_back(plugin->c_str());
return listPlugins;
}
void NetController::selectServer(ServerData *pServerData)
{
sd = pServerData;
}
ServerData *NetController::selectedServer()
{
return sd;
}

@ -1,42 +0,0 @@
//
// Created by koncord on 07.01.17.
//
#ifndef NEWLAUNCHER_NETCONTROLLER_HPP
#define NEWLAUNCHER_NETCONTROLLER_HPP
#include "ServerModel.hpp"
#include "netutils/HTTPNetwork.hpp"
#include "netutils/Utils.hpp"
struct ServerModel;
class NetController
{
public:
static NetController *get();
static void Create(std::string addr, unsigned short port);
static void Destroy();
bool updateInfo(QAbstractItemModel *pModel, QModelIndex index= QModelIndex());
void updateInfo();
QStringList players();
QStringList plugins();
void selectServer(ServerData *pServerData);
ServerData *selectedServer();
protected:
NetController(std::string addr, unsigned short port);
~NetController();
private:
NetController(const NetController &controller);
bool downloadInfo(QAbstractItemModel *pModel, QModelIndex index);
void setData(QString addr, QJsonObject server, ServerModel *model);
static NetController *mThis;
ServerData *sd;
HTTPNetwork httpNetwork;
ServerExtendedData sed;
};
#endif //NEWLAUNCHER_NETCONTROLLER_HPP

@ -2,10 +2,14 @@
// Created by koncord on 07.01.17. // Created by koncord on 07.01.17.
// //
#include <apps/browser/netutils/QueryClient.hpp>
#include "qdebug.h" #include "qdebug.h"
#include "NetController.hpp"
#include "ServerInfoDialog.hpp" #include "ServerInfoDialog.hpp"
#include <apps/browser/netutils/Utils.hpp>
using namespace std;
using namespace RakNet;
ServerInfoDialog::ServerInfoDialog(QWidget *parent): QDialog(parent) ServerInfoDialog::ServerInfoDialog(QWidget *parent): QDialog(parent)
{ {
@ -18,22 +22,35 @@ ServerInfoDialog::~ServerInfoDialog()
} }
void ServerInfoDialog::Server(QString addr)
{
this->addr = addr;
}
void ServerInfoDialog::refresh() void ServerInfoDialog::refresh()
{ {
NetController::get()->updateInfo(); QStringList list = addr.split(':');
ServerData *sd = NetController::get()->selectedServer(); auto sd = QueryClient::Get().Update(SystemAddress(list[0].toLatin1(), list[1].toUShort()));
if (sd) if (sd.first != UNASSIGNED_SYSTEM_ADDRESS)
{ {
leAddr->setText(sd->addr); leAddr->setText(sd.first.ToString(true, ':'));
lblName->setText(sd->hostName); lblName->setText(sd.second.GetName());
lblPing->setNum(sd->ping); lblPing->setNum((int) PingRakNetServer(sd.first.ToString(false), sd.first.GetPort()));
listPlayers->clear(); listPlayers->clear();
QStringList players = NetController::get()->players();
listPlayers->addItems(players); for(auto player : sd.second.players)
{
listPlayers->addItem(QString::fromStdString(player));
};
listPlugins->clear(); listPlugins->clear();
listPlugins->addItems(NetController::get()->plugins()); for(auto plugin : sd.second.plugins)
{
listPlugins->addItem(QString::fromStdString(plugin.name));
}
lblPlayers->setText(QString::number(players.size()) + " / " + QString::number(sd->maxPlayers)); lblPlayers->setText(QString::number(sd.second.players.size()) + " / " + QString::number(sd.second.GetMaxPlayers()));
} }
} }

@ -13,8 +13,11 @@ class ServerInfoDialog : public QDialog, public Ui::Dialog
public: public:
explicit ServerInfoDialog(QWidget *parent = 0); explicit ServerInfoDialog(QWidget *parent = 0);
virtual ~ServerInfoDialog(); virtual ~ServerInfoDialog();
void Server(QString addr);
public slots: public slots:
void refresh(); void refresh();
private:
QString addr;
}; };

@ -34,28 +34,28 @@ QVariant ServerModel::data(const QModelIndex &index, int role) const
var = sd.addr; var = sd.addr;
break; break;
case ServerData::PASSW: case ServerData::PASSW:
var = sd.needPassw ? "Yes" : "No"; var = (int)(sd.rules.at("passw").val) == 1 ? "Yes" : "No";
break; break;
case ServerData::VERSION: case ServerData::VERSION:
var = sd.version; var = QString(sd.rules.at("version").str.c_str());
break; break;
case ServerData::PLAYERS: case ServerData::PLAYERS:
var = sd.players; var = (int) sd.rules.at("players").val;
break; break;
case ServerData::MAX_PLAYERS: case ServerData::MAX_PLAYERS:
var = sd.maxPlayers; var = (int) sd.rules.at("maxPlayers").val;
break; break;
case ServerData::HOSTNAME: case ServerData::HOSTNAME:
var = sd.hostName; var = QString(sd.rules.at("name").str.c_str());
break; break;
case ServerData::PING: case ServerData::PING:
var = sd.ping; var = sd.ping;
break; break;
case ServerData::MODNAME: case ServerData::MODNAME:
if(sd.modName.isEmpty()) if(sd.rules.at("gamemode").str == "")
var = "default"; var = "default";
else else
var = sd.modName; var = QString(sd.rules.at("gamemode").str.c_str());
break; break;
} }
return var; return var;
@ -133,27 +133,27 @@ bool ServerModel::setData(const QModelIndex &index, const QVariant &value, int r
ok = !sd.addr.isEmpty(); ok = !sd.addr.isEmpty();
break; break;
case ServerData::PASSW: case ServerData::PASSW:
sd.needPassw = value.toBool(); sd.SetPassword(value.toBool());
break; break;
case ServerData::VERSION: case ServerData::VERSION:
sd.version = value.toString(); sd.SetVersion(value.toString().toLatin1());
ok = !sd.addr.isEmpty(); ok = !sd.addr.isEmpty();
break; break;
case ServerData::PLAYERS: case ServerData::PLAYERS:
sd.players = value.toInt(&ok); sd.SetPlayers(value.toInt(&ok));
break; break;
case ServerData::MAX_PLAYERS: case ServerData::MAX_PLAYERS:
sd.maxPlayers = value.toInt(&ok); sd.SetMaxPlayers(value.toInt(&ok));
break; break;
case ServerData::HOSTNAME: case ServerData::HOSTNAME:
sd.hostName = value.toString(); sd.SetName(value.toString().toLatin1());
ok = !sd.addr.isEmpty(); ok = !sd.addr.isEmpty();
break; break;
case ServerData::PING: case ServerData::PING:
sd.ping = value.toInt(&ok); sd.ping = value.toInt(&ok);
break; break;
case ServerData::MODNAME: case ServerData::MODNAME:
sd.modName = value.toString(); sd.SetGameMode(value.toString().toLatin1());
break; break;
default: default:
return false; return false;
@ -171,8 +171,7 @@ bool ServerModel::insertRows(int position, int count, const QModelIndex &index)
beginInsertRows(QModelIndex(), position, position + count - 1); beginInsertRows(QModelIndex(), position, position + count - 1);
for (int row = 0; row < count; ++row) { for (int row = 0; row < count; ++row) {
ServerData sd {"", -1, -1, -1, "", "", false, 0}; myData.insert(position, {});
myData.insert(position, sd);
} }
endInsertRows(); endInsertRows();
@ -195,6 +194,5 @@ QModelIndex ServerModel::index(int row, int column, const QModelIndex &parent) c
{ {
QModelIndex index = QAbstractTableModel::index(row, column, parent); QModelIndex index = QAbstractTableModel::index(row, column, parent);
//qDebug() << "Valid index? " << index.isValid() << " " << row << " " << column;
return index; return index;
} }

@ -5,16 +5,12 @@
#include <vector> #include <vector>
#include <QString> #include <QString>
#include <QAbstractTableModel> #include <QAbstractTableModel>
#include <components/openmw-mp/Master/MasterData.hpp>
struct ServerData struct ServerData : public QueryData
{ {
QString addr; QString addr;
int players, maxPlayers;
int ping; int ping;
QString hostName;
QString modName;
bool needPassw;
QString version;
enum IDS enum IDS
{ {
ADDR, ADDR,

@ -1,8 +1,8 @@
#include <QApplication> #include <QApplication>
#include <components/settings/settings.hpp> #include <components/settings/settings.hpp>
#include <components/files/configurationmanager.hpp> #include <components/files/configurationmanager.hpp>
#include <apps/browser/netutils/QueryClient.hpp>
#include "MainWindow.hpp" #include "MainWindow.hpp"
#include "NetController.hpp"
std::string loadSettings (Settings::Manager & settings) std::string loadSettings (Settings::Manager & settings)
{ {
@ -39,8 +39,7 @@ int main(int argc, char *argv[])
// initialize resources, if needed // initialize resources, if needed
// Q_INIT_RESOURCE(resfile); // Q_INIT_RESOURCE(resfile);
NetController::Create(addr, port); QueryClient::Get().SetServer(addr, port);
atexit(NetController::Destroy);
QApplication app(argc, argv); QApplication app(argc, argv);
MainWindow d; MainWindow d;

Loading…
Cancel
Save