Server browser
parent
dfb87e9e0d
commit
cb799ee446
@ -0,0 +1,90 @@
|
|||||||
|
set(CMAKE_CXX_STANDARD 14)
|
||||||
|
|
||||||
|
set(NETLAUNCHER_UI
|
||||||
|
${CMAKE_SOURCE_DIR}/files/ui/Main.ui
|
||||||
|
${CMAKE_SOURCE_DIR}/files/ui/ServerInfo.ui
|
||||||
|
)
|
||||||
|
set(NETLAUNCHER
|
||||||
|
main.cpp
|
||||||
|
Main.cpp
|
||||||
|
ServerModel.cpp
|
||||||
|
NetController.cpp
|
||||||
|
ServerInfoDialog.cpp
|
||||||
|
netutils/HTTPNetwork.cpp
|
||||||
|
netutils/Utils.cpp
|
||||||
|
${CMAKE_SOURCE_DIR}/files/windows/launcher.rc
|
||||||
|
)
|
||||||
|
|
||||||
|
set(NETLAUNCHER_HEADER_MOC
|
||||||
|
Main.hpp
|
||||||
|
ServerModel.hpp
|
||||||
|
ServerInfoDialog.hpp
|
||||||
|
)
|
||||||
|
|
||||||
|
set(NETLAUNCHER_HEADER
|
||||||
|
${NETLAUNCHER_HEADER_MOC}
|
||||||
|
NetController.hpp
|
||||||
|
netutils/HTTPNetwork.hpp
|
||||||
|
netutils/Utils.hpp
|
||||||
|
)
|
||||||
|
|
||||||
|
source_group(netlauncher FILES ${NETLAUNCHER} ${NETLAUNCHER_HEADER})
|
||||||
|
|
||||||
|
set(QT_USE_QTGUI 1)
|
||||||
|
|
||||||
|
# Set some platform specific settings
|
||||||
|
if(WIN32)
|
||||||
|
set(GUI_TYPE WIN32)
|
||||||
|
set(QT_USE_QTMAIN TRUE)
|
||||||
|
endif(WIN32)
|
||||||
|
|
||||||
|
if (DESIRED_QT_VERSION MATCHES 4)
|
||||||
|
message(SEND_ERROR "QT4 is not supported.")
|
||||||
|
#include(${QT_USE_FILE})
|
||||||
|
#QT4_ADD_RESOURCES(RCC_SRCS ${CMAKE_SOURCE_DIR}/files/launcher/launcher.qrc)
|
||||||
|
#QT4_WRAP_CPP(MOC_SRCS ${NETLAUNCHER_HEADER_MOC})
|
||||||
|
#QT4_WRAP_UI(UI_HDRS ${NETLAUNCHER_UI})
|
||||||
|
else()
|
||||||
|
QT5_ADD_RESOURCES(RCC_SRCS ${CMAKE_SOURCE_DIR}/files/launcher/launcher.qrc)
|
||||||
|
QT5_WRAP_CPP(MOC_SRCS ${NETLAUNCHER_HEADER_MOC})
|
||||||
|
QT5_WRAP_UI(UI_HDRS ${NETLAUNCHER_UI})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
||||||
|
if(NOT WIN32)
|
||||||
|
include_directories(${LIBUNSHIELD_INCLUDE_DIR})
|
||||||
|
endif(NOT WIN32)
|
||||||
|
|
||||||
|
# Main executable
|
||||||
|
add_executable(openmw-netlauncher
|
||||||
|
${GUI_TYPE}
|
||||||
|
${NETLAUNCHER}
|
||||||
|
${NETLAUNCHER_HEADER}
|
||||||
|
${RCC_SRCS}
|
||||||
|
${MOC_SRCS}
|
||||||
|
${UI_HDRS}
|
||||||
|
)
|
||||||
|
|
||||||
|
if (WIN32)
|
||||||
|
INSTALL(TARGETS openmw-netlauncher RUNTIME DESTINATION ".")
|
||||||
|
endif (WIN32)
|
||||||
|
|
||||||
|
target_link_libraries(openmw-netlauncher
|
||||||
|
${SDL2_LIBRARY_ONLY}
|
||||||
|
${RakNet_LIBRARY}
|
||||||
|
components
|
||||||
|
)
|
||||||
|
|
||||||
|
if (DESIRED_QT_VERSION MATCHES 4)
|
||||||
|
# target_link_libraries(openmw-netlauncher ${QT_QTGUI_LIBRARY} ${QT_QTCORE_LIBRARY})
|
||||||
|
# if(WIN32)
|
||||||
|
# target_link_libraries(openmw-netlauncher ${QT_QTMAIN_LIBRARY})
|
||||||
|
# endif(WIN32)
|
||||||
|
else()
|
||||||
|
qt5_use_modules(openmw-netlauncher Widgets Core)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (BUILD_WITH_CODE_COVERAGE)
|
||||||
|
add_definitions (--coverage)
|
||||||
|
target_link_libraries(openmw-netlauncher gcov)
|
||||||
|
endif()
|
@ -0,0 +1,137 @@
|
|||||||
|
//
|
||||||
|
// Created by koncord on 06.01.17.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "Main.hpp"
|
||||||
|
#include "NetController.hpp"
|
||||||
|
#include "ServerInfoDialog.hpp"
|
||||||
|
#include <qdebug.h>
|
||||||
|
#include <QInputDialog>
|
||||||
|
|
||||||
|
using namespace Process;
|
||||||
|
|
||||||
|
Main::Main(QWidget *parent)
|
||||||
|
{
|
||||||
|
setupUi(this);
|
||||||
|
|
||||||
|
mGameInvoker = new ProcessInvoker();
|
||||||
|
|
||||||
|
browser = new ServerModel;
|
||||||
|
favorites = new ServerModel;
|
||||||
|
proxyModel = new QSortFilterProxyModel;
|
||||||
|
proxyModel->setSourceModel(browser);
|
||||||
|
tblServerBrowser->setModel(proxyModel);
|
||||||
|
tblFavorites->setModel(proxyModel);
|
||||||
|
|
||||||
|
tblServerBrowser->hideColumn(ServerData::ADDR);
|
||||||
|
tblFavorites->hideColumn(ServerData::ADDR);
|
||||||
|
|
||||||
|
refresh();
|
||||||
|
|
||||||
|
connect(tabWidget, SIGNAL(currentChanged(int)), this, SLOT(tabSwitched(int)));
|
||||||
|
connect(actionAdd, SIGNAL(triggered(bool)), this, SLOT(addServer()));
|
||||||
|
connect(actionAdd_by_IP, SIGNAL(triggered(bool)), this, SLOT(addServerByIP()));
|
||||||
|
connect(actionDelete, SIGNAL(triggered(bool)), this, SLOT(deleteServer()));
|
||||||
|
connect(actionRefresh, SIGNAL(triggered(bool)), this, SLOT(refresh()));
|
||||||
|
connect(actionPlay, SIGNAL(triggered(bool)), this, SLOT(play()));
|
||||||
|
connect(tblServerBrowser, SIGNAL(clicked(QModelIndex)), this, SLOT(serverSelected()));
|
||||||
|
connect(tblFavorites, SIGNAL(clicked(QModelIndex)), this, SLOT(serverSelected()));
|
||||||
|
}
|
||||||
|
|
||||||
|
Main::~Main()
|
||||||
|
{
|
||||||
|
delete mGameInvoker;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Main::addServer()
|
||||||
|
{
|
||||||
|
int id = tblServerBrowser->selectionModel()->currentIndex().row();
|
||||||
|
|
||||||
|
if(id >= 0)
|
||||||
|
{
|
||||||
|
int sourceId = proxyModel->mapToSource(proxyModel->index(id, ServerData::ADDR)).row();
|
||||||
|
favorites->myData.push_back(browser->myData[sourceId]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Main::addServerByIP()
|
||||||
|
{
|
||||||
|
bool ok;
|
||||||
|
QString text = QInputDialog::getText(this, tr("Add Server by address"), tr("Address:"), QLineEdit::Normal, "", &ok);
|
||||||
|
if(ok && !text.isEmpty())
|
||||||
|
{
|
||||||
|
favorites->insertRows(0, 1);
|
||||||
|
QModelIndex mi = favorites->index(0, ServerData::ADDR);
|
||||||
|
favorites->setData(mi, text, Qt::EditRole);
|
||||||
|
NetController::get()->updateInfo(favorites, mi);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Main::deleteServer()
|
||||||
|
{
|
||||||
|
if(tabWidget->currentIndex() != 1)
|
||||||
|
return;
|
||||||
|
int id = tblFavorites->selectionModel()->currentIndex().row();
|
||||||
|
if(id >= 0)
|
||||||
|
{
|
||||||
|
int sourceId = proxyModel->mapToSource(proxyModel->index(id, ServerData::ADDR)).row();
|
||||||
|
favorites->removeRow(sourceId);
|
||||||
|
if(favorites->myData.isEmpty())
|
||||||
|
actionPlay->setEnabled(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Main::refresh()
|
||||||
|
{
|
||||||
|
NetController::get()->updateInfo(proxyModel->sourceModel());
|
||||||
|
/*tblServerBrowser->resizeColumnToContents(ServerData::HOSTNAME);
|
||||||
|
tblServerBrowser->resizeColumnToContents(ServerData::MODNAME);
|
||||||
|
tblFavorites->resizeColumnToContents(ServerData::HOSTNAME);
|
||||||
|
tblFavorites->resizeColumnToContents(ServerData::MODNAME);*/
|
||||||
|
}
|
||||||
|
|
||||||
|
void Main::play()
|
||||||
|
{
|
||||||
|
QTableView *curTable = tabWidget->currentIndex() ? tblFavorites : tblServerBrowser;
|
||||||
|
int id = curTable->selectionModel()->currentIndex().row();
|
||||||
|
if(id < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ServerInfoDialog infoDialog(this);
|
||||||
|
ServerModel *sm = ((ServerModel*)proxyModel->sourceModel());
|
||||||
|
|
||||||
|
int sourceId = proxyModel->mapToSource(proxyModel->index(id, ServerData::ADDR)).row();
|
||||||
|
NetController::get()->selectServer(&sm->myData[sourceId]);
|
||||||
|
infoDialog.refresh();
|
||||||
|
if(!infoDialog.exec())
|
||||||
|
return;
|
||||||
|
|
||||||
|
QStringList arguments;
|
||||||
|
arguments.append(QLatin1String("--connect=") + sm->myData[sourceId].addr.toLatin1());
|
||||||
|
|
||||||
|
if (mGameInvoker->startProcess(QLatin1String("tes3mp"), arguments, true))
|
||||||
|
return qApp->quit();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Main::tabSwitched(int index)
|
||||||
|
{
|
||||||
|
if(index == 0)
|
||||||
|
{
|
||||||
|
proxyModel->setSourceModel(browser);
|
||||||
|
actionDelete->setEnabled(false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
proxyModel->setSourceModel(favorites);
|
||||||
|
actionDelete->setEnabled(true);
|
||||||
|
}
|
||||||
|
actionPlay->setEnabled(false);
|
||||||
|
actionAdd->setEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Main::serverSelected()
|
||||||
|
{
|
||||||
|
actionPlay->setEnabled(true);
|
||||||
|
if(tabWidget->currentIndex() == 0)
|
||||||
|
actionAdd->setEnabled(true);
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
//
|
||||||
|
// Created by koncord on 06.01.17.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef NEWLAUNCHER_MAIN_HPP
|
||||||
|
#define NEWLAUNCHER_MAIN_HPP
|
||||||
|
|
||||||
|
|
||||||
|
#include "ui_Main.h"
|
||||||
|
#include "ServerModel.hpp"
|
||||||
|
#include <QSortFilterProxyModel>
|
||||||
|
#include <components/process/processinvoker.hpp>
|
||||||
|
|
||||||
|
class Main : public QMainWindow, private Ui::MainWindow
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit Main(QWidget *parent = 0);
|
||||||
|
virtual ~Main();
|
||||||
|
protected:
|
||||||
|
protected slots:
|
||||||
|
void tabSwitched(int index);
|
||||||
|
void addServer();
|
||||||
|
void addServerByIP();
|
||||||
|
void deleteServer();
|
||||||
|
void refresh();
|
||||||
|
void play();
|
||||||
|
void serverSelected();
|
||||||
|
private:
|
||||||
|
Process::ProcessInvoker *mGameInvoker;
|
||||||
|
ServerModel *browser, *favorites;
|
||||||
|
QSortFilterProxyModel *proxyModel;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //NEWLAUNCHER_MAIN_HPP
|
@ -0,0 +1,215 @@
|
|||||||
|
//
|
||||||
|
// 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 <memory>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
NetController *NetController::mThis = nullptr;
|
||||||
|
|
||||||
|
NetController *NetController::get()
|
||||||
|
{
|
||||||
|
assert(mThis);
|
||||||
|
return mThis;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetController::Create()
|
||||||
|
{
|
||||||
|
assert(!mThis);
|
||||||
|
mThis = new NetController;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetController::Destroy()
|
||||||
|
{
|
||||||
|
assert(mThis);
|
||||||
|
delete mThis;
|
||||||
|
mThis = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetController::NetController() : httpNetwork("127.0.0.1", 8080)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
NetController::~NetController()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
struct pattern
|
||||||
|
{
|
||||||
|
pattern(QString value): value(value) {}
|
||||||
|
bool operator()(const ServerData &data)
|
||||||
|
{
|
||||||
|
return value == data.addr;
|
||||||
|
}
|
||||||
|
QString value;
|
||||||
|
};
|
||||||
|
|
||||||
|
void NetController::downloadInfo(QAbstractItemModel *pModel, QModelIndex index)
|
||||||
|
{
|
||||||
|
ServerModel *model = ((ServerModel *) pModel);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* download stuff
|
||||||
|
*/
|
||||||
|
|
||||||
|
QString data;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
data = QString::fromStdString(httpNetwork.getData("/api/servers"));
|
||||||
|
if (!data.isEmpty() && data != "NO_CONTENT" && data != "LOST_CONNECTION")
|
||||||
|
break;
|
||||||
|
RakSleep(30);
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug() << "Content: " << data;
|
||||||
|
|
||||||
|
QJsonParseError err;
|
||||||
|
QJsonDocument jsonDocument = QJsonDocument::fromJson(data.toLatin1(), &err);
|
||||||
|
|
||||||
|
QMap<QString, QVariant> map = jsonDocument.toVariant().toMap()["list servers"].toMap();
|
||||||
|
|
||||||
|
for(QMap<QString, QVariant>::Iterator iter = map.begin(); iter != map.end(); iter++)
|
||||||
|
{
|
||||||
|
qDebug() << iter.key();
|
||||||
|
qDebug() << iter.value().toMap()["hostname"].toString();
|
||||||
|
qDebug() << iter.value().toMap()["modname"].toString();
|
||||||
|
qDebug() << iter.value().toMap()["players"].toInt();
|
||||||
|
qDebug() << iter.value().toMap()["max_players"].toInt();
|
||||||
|
|
||||||
|
QVector<ServerData>::Iterator value = std::find_if(model->myData.begin(), model->myData.end(), pattern(iter.key()));
|
||||||
|
if(value == model->myData.end())
|
||||||
|
model->insertRow(0);
|
||||||
|
|
||||||
|
QModelIndex mi = model->index(0, ServerData::ADDR);
|
||||||
|
model->setData(mi, iter.key());
|
||||||
|
|
||||||
|
mi = model->index(0, ServerData::PLAYERS);
|
||||||
|
model->setData(mi, iter.value().toMap()["players"].toInt());
|
||||||
|
|
||||||
|
mi = model->index(0, ServerData::MAX_PLAYERS);
|
||||||
|
model->setData(mi, iter.value().toMap()["max_players"].toInt());
|
||||||
|
|
||||||
|
mi = model->index(0, ServerData::HOSTNAME);
|
||||||
|
model->setData(mi, iter.value().toMap()["hostname"].toString());
|
||||||
|
|
||||||
|
mi = model->index(0, ServerData::MODNAME);
|
||||||
|
model->setData(mi, iter.value().toMap()["modname"].toString());
|
||||||
|
|
||||||
|
mi = model->index(0, ServerData::PING);
|
||||||
|
|
||||||
|
QStringList addr = iter.key().split(":");
|
||||||
|
model->setData(mi, PingRakNetServer(addr[0].toLatin1().data(), addr[1].toUShort()));
|
||||||
|
}
|
||||||
|
|
||||||
|
//qDebug() << data;
|
||||||
|
|
||||||
|
if (model->rowCount() != 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/*model->insertRows(0, 6);
|
||||||
|
model->myData[0] = {"127.0.0.1:25565", 0, 20, 1, "Super Server"};
|
||||||
|
model->myData[1] = {"127.0.0.1:25565", 5, 20, 2, "Koncord's server"};
|
||||||
|
model->myData[2] = {"server.local:8888", 15, 15, 15, "tes3mp server", "custom mode"};
|
||||||
|
model->myData[3] = {"127.0.0.1:25562", 1, 2, 5, "Server"};
|
||||||
|
model->myData[4] = {"tes3mp.com:22222", 8, 9, 1000, "Antoher Server", "super duper mod"};
|
||||||
|
model->myData[5] = {"localhost:24", 1, 5, 5, "Test Server", "Another mod 0.1"};*/
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetController::updateInfo(QAbstractItemModel *pModel, QModelIndex index)
|
||||||
|
{
|
||||||
|
qDebug() << "TODO: \"NetController::updateInfo(QAbstractItemModel *, QModelIndex)\" is not completed";
|
||||||
|
ServerModel *model = ((ServerModel*)pModel);
|
||||||
|
|
||||||
|
if (index.isValid() && index.row() >= 0)
|
||||||
|
{
|
||||||
|
//ServerData &sd = model->myData[index.row()];
|
||||||
|
//qDebug() << sd.addr;
|
||||||
|
downloadInfo(pModel, index);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (QVector<ServerData>::Iterator iter = model->myData.begin(); iter != model->myData.end(); iter++)
|
||||||
|
{
|
||||||
|
qDebug() << iter->addr;
|
||||||
|
}
|
||||||
|
model->removeRows(0, model->rowCount(index));
|
||||||
|
downloadInfo(pModel, index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
|
||||||
|
sd->hostName = map["hostname"].toString();
|
||||||
|
sd->modName = map["modname"].toString();
|
||||||
|
sd->players = map["players"].toInt();
|
||||||
|
sd->maxPlayers = map["max_players"].toInt();
|
||||||
|
|
||||||
|
QStringList addr = sd->addr.split(":");
|
||||||
|
sd->ping = PingRakNetServer(addr[0].toLatin1(), addr[1].toUShort());
|
||||||
|
sed = getExtendedData(addr[0].toLatin1(), addr[1].toUShort());
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList NetController::players()
|
||||||
|
{
|
||||||
|
QStringList listPlayers;
|
||||||
|
for(vector<string>::iterator player = sed.players.begin(); player != sed.players.end(); player++)
|
||||||
|
listPlayers.push_back(player->c_str());
|
||||||
|
return listPlayers;
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList NetController::plugins()
|
||||||
|
{
|
||||||
|
QStringList listPlugins;
|
||||||
|
for(vector<string>::iterator 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;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,41 @@
|
|||||||
|
//
|
||||||
|
// 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();
|
||||||
|
static void Destroy();
|
||||||
|
void updateInfo(QAbstractItemModel *pModel, QModelIndex index= QModelIndex());
|
||||||
|
void updateInfo();
|
||||||
|
QStringList players();
|
||||||
|
QStringList plugins();
|
||||||
|
void selectServer(ServerData *pServerData);
|
||||||
|
ServerData *selectedServer();
|
||||||
|
protected:
|
||||||
|
NetController();
|
||||||
|
~NetController();
|
||||||
|
private:
|
||||||
|
NetController(const NetController &controller);
|
||||||
|
void downloadInfo(QAbstractItemModel *pModel, QModelIndex index);
|
||||||
|
|
||||||
|
static NetController *mThis;
|
||||||
|
ServerData *sd;
|
||||||
|
HTTPNetwork httpNetwork;
|
||||||
|
ServerExtendedData sed;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //NEWLAUNCHER_NETCONTROLLER_HPP
|
@ -0,0 +1,36 @@
|
|||||||
|
//
|
||||||
|
// Created by koncord on 07.01.17.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "qdebug.h"
|
||||||
|
#include "NetController.hpp"
|
||||||
|
|
||||||
|
#include "ServerInfoDialog.hpp"
|
||||||
|
|
||||||
|
ServerInfoDialog::ServerInfoDialog(QWidget *parent): QDialog(parent)
|
||||||
|
{
|
||||||
|
setupUi(this);
|
||||||
|
connect(btnRefresh, SIGNAL(clicked()), this, SLOT(refresh()));
|
||||||
|
}
|
||||||
|
|
||||||
|
ServerInfoDialog::~ServerInfoDialog()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void ServerInfoDialog::refresh()
|
||||||
|
{
|
||||||
|
NetController::get()->updateInfo();
|
||||||
|
ServerData *sd = NetController::get()->selectedServer();
|
||||||
|
leAddr->setText(sd->addr);
|
||||||
|
lblName->setText(sd->hostName);
|
||||||
|
lblPing->setNum(sd->ping);
|
||||||
|
|
||||||
|
listPlayers->clear();
|
||||||
|
QStringList players = NetController::get()->players();
|
||||||
|
listPlayers->addItems(players);
|
||||||
|
listPlugins->clear();
|
||||||
|
listPlugins->addItems(NetController::get()->plugins());
|
||||||
|
|
||||||
|
lblPlayers->setText(QString::number(players.size()) + " / " + QString::number(sd->maxPlayers));
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
//
|
||||||
|
// Created by koncord on 07.01.17.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef NEWLAUNCHER_SERVERINFODIALOG_HPP
|
||||||
|
#define NEWLAUNCHER_SERVERINFODIALOG_HPP
|
||||||
|
|
||||||
|
#include "ui_ServerInfo.h"
|
||||||
|
|
||||||
|
class ServerInfoDialog : public QDialog, public Ui::Dialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit ServerInfoDialog(QWidget *parent = 0);
|
||||||
|
virtual ~ServerInfoDialog();
|
||||||
|
public slots:
|
||||||
|
void refresh();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //NEWLAUNCHER_SERVERINFODIALOG_HPP
|
@ -0,0 +1,178 @@
|
|||||||
|
#include <qmessagebox.h>
|
||||||
|
#include "ServerModel.hpp"
|
||||||
|
#include <qdebug.h>
|
||||||
|
|
||||||
|
ServerModel::ServerModel(QObject *parent) : QAbstractTableModel(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ServerModel::~ServerModel()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*QHash<int, QByteArray> ServerModel::roleNames() const
|
||||||
|
{
|
||||||
|
return roles;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
QVariant ServerModel::data(const QModelIndex &index, int role) const
|
||||||
|
{
|
||||||
|
if (!index.isValid())
|
||||||
|
return QVariant();
|
||||||
|
if (index.row() < 0 || index.row() > myData.size())
|
||||||
|
return QVariant();
|
||||||
|
|
||||||
|
const ServerData &sd = myData.at(index.row());
|
||||||
|
|
||||||
|
if(role == Qt::DisplayRole)
|
||||||
|
{
|
||||||
|
QVariant var;
|
||||||
|
switch (index.column())
|
||||||
|
{
|
||||||
|
case ServerData::ADDR:
|
||||||
|
var = sd.addr;
|
||||||
|
break;
|
||||||
|
case ServerData::PLAYERS:
|
||||||
|
var = sd.players;
|
||||||
|
break;
|
||||||
|
case ServerData::MAX_PLAYERS:
|
||||||
|
var = sd.maxPlayers;
|
||||||
|
break;
|
||||||
|
case ServerData::HOSTNAME:
|
||||||
|
var = sd.hostName;
|
||||||
|
break;
|
||||||
|
case ServerData::PING:
|
||||||
|
var = sd.ping;
|
||||||
|
break;
|
||||||
|
case ServerData::MODNAME:
|
||||||
|
if(sd.modName.isEmpty())
|
||||||
|
var = "default";
|
||||||
|
else
|
||||||
|
var = sd.modName;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return var;
|
||||||
|
}
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant ServerModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||||
|
{
|
||||||
|
QVariant var;
|
||||||
|
if (orientation == Qt::Horizontal)
|
||||||
|
{
|
||||||
|
if (role == Qt::SizeHintRole)
|
||||||
|
{
|
||||||
|
/*if(section == ServerData::HOSTNAME)
|
||||||
|
var = QSize(200, 25);*/
|
||||||
|
}
|
||||||
|
else if (role == Qt::DisplayRole)
|
||||||
|
{
|
||||||
|
|
||||||
|
switch (section)
|
||||||
|
{
|
||||||
|
case ServerData::ADDR:
|
||||||
|
var = "Address";
|
||||||
|
break;
|
||||||
|
case ServerData::HOSTNAME:
|
||||||
|
var = "Host name";
|
||||||
|
break;
|
||||||
|
case ServerData::PLAYERS:
|
||||||
|
var = "Players";
|
||||||
|
break;
|
||||||
|
case ServerData::MAX_PLAYERS:
|
||||||
|
var = "Player Max";
|
||||||
|
break;
|
||||||
|
case ServerData::PING:
|
||||||
|
var = "Ping";
|
||||||
|
break;
|
||||||
|
case ServerData::MODNAME:
|
||||||
|
var = "Game mode";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return var;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ServerModel::rowCount(const QModelIndex &parent) const
|
||||||
|
{
|
||||||
|
return myData.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
int ServerModel::columnCount(const QModelIndex &parent) const
|
||||||
|
{
|
||||||
|
return ServerData::LAST;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ServerModel::setData(const QModelIndex &index, const QVariant &value, int role)
|
||||||
|
{
|
||||||
|
if (index.isValid() && role == Qt::EditRole)
|
||||||
|
{
|
||||||
|
int row = index.row();
|
||||||
|
int col = index.column();
|
||||||
|
|
||||||
|
ServerData &sd = myData[row];
|
||||||
|
bool ok = true;
|
||||||
|
switch(col)
|
||||||
|
{
|
||||||
|
case ServerData::ADDR:
|
||||||
|
sd.addr = value.toString();
|
||||||
|
ok = !sd.addr.isEmpty();
|
||||||
|
break;
|
||||||
|
case ServerData::PLAYERS:
|
||||||
|
sd.players = value.toInt(&ok);
|
||||||
|
break;
|
||||||
|
case ServerData::MAX_PLAYERS:
|
||||||
|
sd.maxPlayers = value.toInt(&ok);
|
||||||
|
break;
|
||||||
|
case ServerData::HOSTNAME:
|
||||||
|
sd.hostName = value.toString();
|
||||||
|
ok = !sd.addr.isEmpty();
|
||||||
|
break;
|
||||||
|
case ServerData::PING:
|
||||||
|
sd.ping = value.toInt(&ok);
|
||||||
|
break;
|
||||||
|
case ServerData::MODNAME:
|
||||||
|
sd.modName = value.toString();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(ok)
|
||||||
|
emit(dataChanged(index, index));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ServerModel::insertRows(int position, int count, const QModelIndex &index)
|
||||||
|
{
|
||||||
|
Q_UNUSED(index);
|
||||||
|
beginInsertRows(QModelIndex(), position, position + count - 1);
|
||||||
|
|
||||||
|
for (int row = 0; row < count; ++row) {
|
||||||
|
ServerData sd {"", -1, -1, -1, ""};
|
||||||
|
myData.insert(position, sd);
|
||||||
|
}
|
||||||
|
|
||||||
|
endInsertRows();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ServerModel::removeRows(int position, int count, const QModelIndex &parent)
|
||||||
|
{
|
||||||
|
beginRemoveRows(parent, position, position + count - 1);
|
||||||
|
myData.erase(myData.begin()+position, myData.begin() + position + count);
|
||||||
|
endRemoveRows();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
QModelIndex ServerModel::index(int row, int column, const QModelIndex &parent) const
|
||||||
|
{
|
||||||
|
|
||||||
|
QModelIndex index = QAbstractTableModel::index(row, column, parent);
|
||||||
|
//qDebug() << "Valid index? " << index.isValid() << " " << row << " " << column;
|
||||||
|
return index;
|
||||||
|
}
|
@ -0,0 +1,52 @@
|
|||||||
|
#ifndef SERVERMODEL_FONTMODEL_HPP
|
||||||
|
#define SERVERMODEL_FONTMODEL_HPP
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <vector>
|
||||||
|
#include <QString>
|
||||||
|
#include <QAbstractTableModel>
|
||||||
|
|
||||||
|
struct ServerData
|
||||||
|
{
|
||||||
|
QString addr;
|
||||||
|
int players, maxPlayers;
|
||||||
|
int ping;
|
||||||
|
QString hostName;
|
||||||
|
QString modName;
|
||||||
|
enum IDS
|
||||||
|
{
|
||||||
|
ADDR,
|
||||||
|
HOSTNAME,
|
||||||
|
PLAYERS,
|
||||||
|
MAX_PLAYERS,
|
||||||
|
MODNAME,
|
||||||
|
PING,
|
||||||
|
LAST
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
class ServerModel: public QAbstractTableModel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit ServerModel(QObject *parent = 0);
|
||||||
|
~ServerModel();
|
||||||
|
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
|
||||||
|
int rowCount(const QModelIndex &parent = QModelIndex()) const;
|
||||||
|
int columnCount(const QModelIndex &parent) const;
|
||||||
|
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
|
||||||
|
|
||||||
|
bool insertRows(int row, int count, const QModelIndex &index = QModelIndex());
|
||||||
|
bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex());
|
||||||
|
|
||||||
|
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
|
||||||
|
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
//QHash<int, QByteArray> roles;
|
||||||
|
QVector<ServerData> myData;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //SERVERMODEL_FONTMODEL_HPP
|
@ -0,0 +1,17 @@
|
|||||||
|
#include <QApplication>
|
||||||
|
#include "Main.hpp"
|
||||||
|
#include "NetController.hpp"
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
// initialize resources, if needed
|
||||||
|
// Q_INIT_RESOURCE(resfile);
|
||||||
|
|
||||||
|
NetController::Create();
|
||||||
|
atexit(NetController::Destroy);
|
||||||
|
QApplication app(argc, argv);
|
||||||
|
Main d;
|
||||||
|
d.show();
|
||||||
|
// create and show your widgets here
|
||||||
|
return app.exec();
|
||||||
|
}
|
@ -0,0 +1,96 @@
|
|||||||
|
//
|
||||||
|
// Created by koncord on 07.01.17.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <RakPeer.h>
|
||||||
|
#include <HTTPConnection2.h>
|
||||||
|
#include <TCPInterface.h>
|
||||||
|
#include <RakSleep.h>
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
#include "HTTPNetwork.hpp"
|
||||||
|
|
||||||
|
using namespace RakNet;
|
||||||
|
|
||||||
|
HTTPNetwork::HTTPNetwork(std::string addr, unsigned short port) : address(addr), port(port)
|
||||||
|
{
|
||||||
|
httpConnection = HTTPConnection2::GetInstance();
|
||||||
|
tcpInterface = new TCPInterface;
|
||||||
|
tcpInterface->Start(0, 64);
|
||||||
|
tcpInterface->AttachPlugin(httpConnection);
|
||||||
|
}
|
||||||
|
|
||||||
|
HTTPNetwork::~HTTPNetwork()
|
||||||
|
{
|
||||||
|
delete tcpInterface;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string HTTPNetwork::answer()
|
||||||
|
{
|
||||||
|
RakNet::SystemAddress sa;
|
||||||
|
RakNet::Packet *packet;
|
||||||
|
RakNet::SystemAddress hostReceived;
|
||||||
|
RakNet::RakString response;
|
||||||
|
RakNet::RakString transmitted, hostTransmitted;
|
||||||
|
int contentOffset = 0;
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
// This is kind of crappy, but for TCP plugins, always do HasCompletedConnectionAttempt,
|
||||||
|
// then Receive(), then HasFailedConnectionAttempt(),HasLostConnection()
|
||||||
|
sa = tcpInterface->HasCompletedConnectionAttempt();
|
||||||
|
if (sa != RakNet::UNASSIGNED_SYSTEM_ADDRESS)
|
||||||
|
printf("Connected to master server: %s\n", sa.ToString());
|
||||||
|
|
||||||
|
sa = tcpInterface->HasFailedConnectionAttempt();
|
||||||
|
if (sa != RakNet::UNASSIGNED_SYSTEM_ADDRESS)
|
||||||
|
{
|
||||||
|
printf("Failed to connect to master server: %s\n", sa.ToString());
|
||||||
|
return "FAIL_CONNECT";
|
||||||
|
}
|
||||||
|
sa = tcpInterface->HasLostConnection();
|
||||||
|
if (sa != RakNet::UNASSIGNED_SYSTEM_ADDRESS)
|
||||||
|
{
|
||||||
|
printf("Lost connection to master server: %s\n", sa.ToString());
|
||||||
|
return "LOST_CONNECTION";
|
||||||
|
}
|
||||||
|
|
||||||
|
for (packet = tcpInterface->Receive(); packet; tcpInterface->DeallocatePacket(
|
||||||
|
packet), packet = tcpInterface->Receive());
|
||||||
|
|
||||||
|
if (httpConnection->GetResponse(transmitted, hostTransmitted, response, hostReceived, contentOffset))
|
||||||
|
{
|
||||||
|
if (contentOffset < 0)
|
||||||
|
return "NO_CONTENT"; // no content
|
||||||
|
tcpInterface->CloseConnection(sa);
|
||||||
|
|
||||||
|
return (response.C_String() + contentOffset);
|
||||||
|
}
|
||||||
|
RakSleep(30);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string HTTPNetwork::getData(const char *uri)
|
||||||
|
{
|
||||||
|
RakNet::RakString createRequest = RakNet::RakString::FormatForGET(uri);
|
||||||
|
|
||||||
|
httpConnection->TransmitRequest(createRequest, address.c_str(), port);
|
||||||
|
return answer();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string HTTPNetwork::getDataPOST(const char *uri, const char* body, const char* contentType)
|
||||||
|
{
|
||||||
|
RakNet::RakString createRequest = RakNet::RakString::FormatForPOST(uri, contentType, body);
|
||||||
|
|
||||||
|
httpConnection->TransmitRequest(createRequest, address.c_str(), port);
|
||||||
|
return answer();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string HTTPNetwork::getDataPUT(const char *uri, const char* body, const char* contentType)
|
||||||
|
{
|
||||||
|
RakNet::RakString createRequest = RakNet::RakString::FormatForPUT(uri, contentType, body);
|
||||||
|
|
||||||
|
httpConnection->TransmitRequest(createRequest, address.c_str(), port);
|
||||||
|
return answer();
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
//
|
||||||
|
// Created by koncord on 07.01.17.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef NEWLAUNCHER_HTTPNETWORK_HPP
|
||||||
|
#define NEWLAUNCHER_HTTPNETWORK_HPP
|
||||||
|
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace RakNet
|
||||||
|
{
|
||||||
|
class TCPInterface;
|
||||||
|
class HTTPConnection2;
|
||||||
|
}
|
||||||
|
|
||||||
|
class HTTPNetwork
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
HTTPNetwork(std::string addr, unsigned short port);
|
||||||
|
~HTTPNetwork();
|
||||||
|
std::string getData(const char *uri);
|
||||||
|
std::string getDataPOST(const char *uri, const char* body, const char* contentType = "application/json");
|
||||||
|
std::string getDataPUT(const char *uri, const char* body, const char* contentType = "application/json");
|
||||||
|
|
||||||
|
protected:
|
||||||
|
RakNet::TCPInterface *tcpInterface;
|
||||||
|
RakNet::HTTPConnection2 *httpConnection;
|
||||||
|
std::string address;
|
||||||
|
unsigned short port;
|
||||||
|
std::string answer();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //NEWLAUNCHER_HTTPNETWORK_HPP
|
@ -0,0 +1,151 @@
|
|||||||
|
//
|
||||||
|
// Created by koncord on 07.01.17.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <RakPeer.h>
|
||||||
|
#include <MessageIdentifiers.h>
|
||||||
|
#include <RakSleep.h>
|
||||||
|
#include <GetTime.h>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <components/openmw-mp/Version.hpp>
|
||||||
|
|
||||||
|
#include "Utils.hpp"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
unsigned int PingRakNetServer(const char *addr, unsigned short port)
|
||||||
|
{
|
||||||
|
RakNet::Packet *packet;
|
||||||
|
bool done = false;
|
||||||
|
int attempts = 0;
|
||||||
|
RakNet::TimeMS time = 999;
|
||||||
|
|
||||||
|
RakNet::SocketDescriptor socketDescriptor = {0, ""};
|
||||||
|
RakNet::RakPeerInterface *peer = RakNet::RakPeerInterface::GetInstance();
|
||||||
|
peer->Startup(1,&socketDescriptor, 1);
|
||||||
|
|
||||||
|
peer->Ping(addr, port, false);
|
||||||
|
while (!done)
|
||||||
|
{
|
||||||
|
for (packet=peer->Receive(); packet; peer->DeallocatePacket(packet), packet=peer->Receive())
|
||||||
|
{
|
||||||
|
if(packet->data[0] == ID_UNCONNECTED_PONG)
|
||||||
|
{
|
||||||
|
RakNet::BitStream bsIn(&packet->data[1], packet->length, false);
|
||||||
|
bsIn.Read(time);
|
||||||
|
time = RakNet::GetTimeMS() - time - 5;
|
||||||
|
done = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attempts >= 60) // wait 300 msec
|
||||||
|
done = true;
|
||||||
|
attempts++;
|
||||||
|
RakSleep(5);
|
||||||
|
}
|
||||||
|
RakNet::RakPeerInterface::DestroyInstance(peer);
|
||||||
|
return time;
|
||||||
|
}
|
||||||
|
|
||||||
|
ServerExtendedData getExtendedData(const char *addr, unsigned short port)
|
||||||
|
{
|
||||||
|
ServerExtendedData data;
|
||||||
|
RakNet::SocketDescriptor socketDescriptor = {0, ""};
|
||||||
|
RakNet::RakPeerInterface *peer = RakNet::RakPeerInterface::GetInstance();
|
||||||
|
peer->Startup(1, &socketDescriptor, 1);
|
||||||
|
|
||||||
|
stringstream sstr(TES3MP_VERSION);
|
||||||
|
sstr << TES3MP_PROTO_VERSION;
|
||||||
|
|
||||||
|
std::string msg = "";
|
||||||
|
|
||||||
|
if (peer->Connect(addr, port, sstr.str().c_str(), (int)(sstr.str().size()), 0, 0, 3, 500, 0) != RakNet::CONNECTION_ATTEMPT_STARTED)
|
||||||
|
msg = "Connection attempt failed.\n";
|
||||||
|
|
||||||
|
|
||||||
|
bool queue = true;
|
||||||
|
while (queue)
|
||||||
|
{
|
||||||
|
for (RakNet::Packet *packet = peer->Receive(); packet; peer->DeallocatePacket(
|
||||||
|
packet), packet = peer->Receive())
|
||||||
|
{
|
||||||
|
switch (packet->data[0])
|
||||||
|
{
|
||||||
|
case ID_CONNECTION_ATTEMPT_FAILED:
|
||||||
|
{
|
||||||
|
msg = "Connection failed.\n"
|
||||||
|
"Either the IP address is wrong or a firewall on either system is blocking\n"
|
||||||
|
"UDP packets on the port you have chosen.";
|
||||||
|
queue = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ID_INVALID_PASSWORD:
|
||||||
|
{
|
||||||
|
msg = "Connection failed.\n"
|
||||||
|
"The client or server is outdated.\n";
|
||||||
|
queue = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ID_CONNECTION_REQUEST_ACCEPTED:
|
||||||
|
{
|
||||||
|
msg = "Connection accepted.\n";
|
||||||
|
queue = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ID_DISCONNECTION_NOTIFICATION:
|
||||||
|
throw runtime_error("ID_DISCONNECTION_NOTIFICATION.\n");
|
||||||
|
case ID_CONNECTION_BANNED:
|
||||||
|
throw runtime_error("ID_CONNECTION_BANNED.\n");
|
||||||
|
case ID_CONNECTION_LOST:
|
||||||
|
throw runtime_error("ID_CONNECTION_LOST.\n");
|
||||||
|
default:
|
||||||
|
printf("Connection message with identifier %i has arrived in initialization.\n", packet->data[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
puts(msg.c_str());
|
||||||
|
|
||||||
|
{
|
||||||
|
RakNet::BitStream bs;
|
||||||
|
bs.Write((unsigned char) (ID_USER_PACKET_ENUM + 1));
|
||||||
|
peer->Send(&bs, HIGH_PRIORITY, RELIABLE_ORDERED, 0, RakNet::UNASSIGNED_SYSTEM_ADDRESS, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
RakNet::Packet *packet;
|
||||||
|
bool done = false;
|
||||||
|
while (!done)
|
||||||
|
{
|
||||||
|
for (packet = peer->Receive(); packet; peer->DeallocatePacket(packet), packet = peer->Receive())
|
||||||
|
{
|
||||||
|
if(packet->data[0] == (ID_USER_PACKET_ENUM+1))
|
||||||
|
{
|
||||||
|
RakNet::BitStream bs(packet->data, packet->length, false);
|
||||||
|
bs.IgnoreBytes(1);
|
||||||
|
size_t length = 0;
|
||||||
|
bs.Read(length);
|
||||||
|
for(int i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
RakNet::RakString str;
|
||||||
|
bs.Read(str);
|
||||||
|
data.players.push_back(str.C_String());
|
||||||
|
}
|
||||||
|
bs.Read(length);
|
||||||
|
for(int i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
RakNet::RakString str;
|
||||||
|
bs.Read(str);
|
||||||
|
data.plugins.push_back(str.C_String());
|
||||||
|
}
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
peer->Shutdown(1);
|
||||||
|
RakSleep(10);
|
||||||
|
RakNet::RakPeerInterface::DestroyInstance(peer);
|
||||||
|
return data;
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
//
|
||||||
|
// Created by koncord on 07.01.17.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef NEWLAUNCHER_PING_HPP
|
||||||
|
#define NEWLAUNCHER_PING_HPP
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
|
||||||
|
unsigned int PingRakNetServer(const char *addr, unsigned short port);
|
||||||
|
|
||||||
|
struct ServerExtendedData
|
||||||
|
{
|
||||||
|
std::vector<std::string> players;
|
||||||
|
std::vector<std::string> plugins;
|
||||||
|
};
|
||||||
|
|
||||||
|
ServerExtendedData getExtendedData(const char *addr, unsigned short port);
|
||||||
|
|
||||||
|
#endif //NEWLAUNCHER_PING_HPP
|
@ -0,0 +1,134 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>MainWindow</class>
|
||||||
|
<widget class="QMainWindow" name="MainWindow">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>800</width>
|
||||||
|
<height>600</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>MainWindow</string>
|
||||||
|
</property>
|
||||||
|
<widget class="QWidget" name="centralwidget">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QTabWidget" name="tabWidget">
|
||||||
|
<property name="currentIndex">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<widget class="QWidget" name="tabBrowser">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>Browser</string>
|
||||||
|
</attribute>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
|
<item>
|
||||||
|
<widget class="QTableView" name="tblServerBrowser">
|
||||||
|
<property name="selectionMode">
|
||||||
|
<enum>QAbstractItemView::SingleSelection</enum>
|
||||||
|
</property>
|
||||||
|
<property name="selectionBehavior">
|
||||||
|
<enum>QAbstractItemView::SelectRows</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sortingEnabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<attribute name="verticalHeaderVisible">
|
||||||
|
<bool>false</bool>
|
||||||
|
</attribute>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<widget class="QWidget" name="tabFavorites">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>Favorites</string>
|
||||||
|
</attribute>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||||
|
<item>
|
||||||
|
<widget class="QTableView" name="tblFavorites">
|
||||||
|
<property name="selectionMode">
|
||||||
|
<enum>QAbstractItemView::SingleSelection</enum>
|
||||||
|
</property>
|
||||||
|
<property name="selectionBehavior">
|
||||||
|
<enum>QAbstractItemView::SelectRows</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sortingEnabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<attribute name="verticalHeaderVisible">
|
||||||
|
<bool>false</bool>
|
||||||
|
</attribute>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<widget class="QToolBar" name="toolBar">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>toolBar</string>
|
||||||
|
</property>
|
||||||
|
<property name="movable">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="floatable">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<attribute name="toolBarArea">
|
||||||
|
<enum>TopToolBarArea</enum>
|
||||||
|
</attribute>
|
||||||
|
<attribute name="toolBarBreak">
|
||||||
|
<bool>false</bool>
|
||||||
|
</attribute>
|
||||||
|
<addaction name="actionPlay"/>
|
||||||
|
<addaction name="separator"/>
|
||||||
|
<addaction name="actionAdd"/>
|
||||||
|
<addaction name="actionAdd_by_IP"/>
|
||||||
|
<addaction name="actionDelete"/>
|
||||||
|
<addaction name="separator"/>
|
||||||
|
<addaction name="actionRefresh"/>
|
||||||
|
</widget>
|
||||||
|
<action name="actionAdd">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Add</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionDelete">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Delete</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionRefresh">
|
||||||
|
<property name="text">
|
||||||
|
<string>Refresh</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionPlay">
|
||||||
|
<property name="text">
|
||||||
|
<string>Play</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionAdd_by_IP">
|
||||||
|
<property name="text">
|
||||||
|
<string>Add by address</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
@ -0,0 +1,240 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>Dialog</class>
|
||||||
|
<widget class="QDialog" name="Dialog">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>430</width>
|
||||||
|
<height>447</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Connect</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_3">
|
||||||
|
<property name="text">
|
||||||
|
<string>Server Name:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="lblName">
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true">TextLabel</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer_2">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_5">
|
||||||
|
<property name="text">
|
||||||
|
<string>Address:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="leAddr">
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true"/>
|
||||||
|
</property>
|
||||||
|
<property name="readOnly">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_7">
|
||||||
|
<property name="text">
|
||||||
|
<string>Players:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="lblPlayers">
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true">0 / 0</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer_3">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_8">
|
||||||
|
<property name="text">
|
||||||
|
<string>Ping:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="lblPing">
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true">-1</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer_4">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Players:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QListWidget" name="listPlayers">
|
||||||
|
<property name="selectionMode">
|
||||||
|
<enum>QAbstractItemView::NoSelection</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_2">
|
||||||
|
<property name="text">
|
||||||
|
<string>Plugins:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QListWidget" name="listPlugins">
|
||||||
|
<property name="selectionMode">
|
||||||
|
<enum>QAbstractItemView::NoSelection</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="btnCancel">
|
||||||
|
<property name="text">
|
||||||
|
<string>Cancel</string>
|
||||||
|
</property>
|
||||||
|
<property name="default">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="btnRefresh">
|
||||||
|
<property name="text">
|
||||||
|
<string>Refresh</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="btnConnect">
|
||||||
|
<property name="text">
|
||||||
|
<string>Connect</string>
|
||||||
|
</property>
|
||||||
|
<property name="default">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>btnCancel</sender>
|
||||||
|
<signal>clicked()</signal>
|
||||||
|
<receiver>Dialog</receiver>
|
||||||
|
<slot>reject()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>489</x>
|
||||||
|
<y>524</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>316</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>btnConnect</sender>
|
||||||
|
<signal>clicked()</signal>
|
||||||
|
<receiver>Dialog</receiver>
|
||||||
|
<slot>accept()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>580</x>
|
||||||
|
<y>524</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>316</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
</ui>
|
Loading…
Reference in New Issue