Remove TCP entry point (#1007)
* Remove TCP entry point Resolve #987 * Remove TCP entry point * Servers that do not support WebSocket will be marked as `Legacy` * Removal of TCP connection from the master will follow later. * Tweaked error message
This commit is contained in:
parent
662d4781d2
commit
efd2571459
@ -78,12 +78,8 @@ add_executable(Attorney_Online
|
|||||||
src/lobby.cpp
|
src/lobby.cpp
|
||||||
src/lobby.h
|
src/lobby.h
|
||||||
src/main.cpp
|
src/main.cpp
|
||||||
src/net/netconnection.cpp
|
src/network/websocketconnection.cpp
|
||||||
src/net/netconnection.h
|
src/network/websocketconnection.h
|
||||||
src/net/nettcpconnection.cpp
|
|
||||||
src/net/nettcpconnection.h
|
|
||||||
src/net/netwebsocketconnection.cpp
|
|
||||||
src/net/netwebsocketconnection.h
|
|
||||||
src/networkmanager.cpp
|
src/networkmanager.cpp
|
||||||
src/networkmanager.h
|
src/networkmanager.h
|
||||||
src/options.cpp
|
src/options.cpp
|
||||||
@ -103,6 +99,7 @@ add_executable(Attorney_Online
|
|||||||
src/widgets/server_editor_dialog.h
|
src/widgets/server_editor_dialog.h
|
||||||
data.qrc
|
data.qrc
|
||||||
src/screenslidetimer.h src/screenslidetimer.cpp
|
src/screenslidetimer.h src/screenslidetimer.cpp
|
||||||
|
src/network/serverinfo.h src/network/serverinfo.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
set_target_properties(Attorney_Online PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/bin")
|
set_target_properties(Attorney_Online PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/bin")
|
||||||
|
@ -78,34 +78,13 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="3" column="0">
|
<item row="3" column="0">
|
||||||
<widget class="QLabel" name="label_6">
|
|
||||||
<property name="text">
|
|
||||||
<string>Protocol:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="1">
|
|
||||||
<widget class="QComboBox" name="protocol">
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>TCP</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>WEBSOCKET</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="4" column="0">
|
|
||||||
<widget class="QLabel" name="label_2">
|
<widget class="QLabel" name="label_2">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Description:</string>
|
<string>Description:</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="4" column="1">
|
<item row="3" column="1">
|
||||||
<widget class="QPlainTextEdit" name="description">
|
<widget class="QPlainTextEdit" name="description">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
|
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
|
||||||
|
@ -316,8 +316,14 @@ QScrollBar:horizontall {
|
|||||||
<item row="1" column="0">
|
<item row="1" column="0">
|
||||||
<widget class="QTreeWidget" name="serverlist_tree">
|
<widget class="QTreeWidget" name="serverlist_tree">
|
||||||
<property name="styleSheet">
|
<property name="styleSheet">
|
||||||
<string notr="true">background-color: rgba(140, 140, 140, 255);
|
<string notr="true">QHeaderView, QTreeView {
|
||||||
color: rgb(255, 255, 255);</string>
|
background-color: rgba(140, 140, 140, 255);
|
||||||
|
color: rgb(255, 255, 255);
|
||||||
|
}
|
||||||
|
|
||||||
|
QToolTip {
|
||||||
|
color: black;
|
||||||
|
}</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="textElideMode">
|
<property name="textElideMode">
|
||||||
<enum>Qt::ElideNone</enum>
|
<enum>Qt::ElideNone</enum>
|
||||||
@ -330,7 +336,7 @@ color: rgb(255, 255, 255);</string>
|
|||||||
<string>#</string>
|
<string>#</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="textAlignment">
|
<property name="textAlignment">
|
||||||
<set>AlignTrailing|AlignVCenter</set>
|
<set>AlignLeading|AlignVCenter</set>
|
||||||
</property>
|
</property>
|
||||||
</column>
|
</column>
|
||||||
<column>
|
<column>
|
||||||
@ -369,7 +375,11 @@ color: rgb(255, 255, 255);</string>
|
|||||||
</property>
|
</property>
|
||||||
<property name="styleSheet">
|
<property name="styleSheet">
|
||||||
<string notr="true">background-color: rgba(140, 140, 140, 255);
|
<string notr="true">background-color: rgba(140, 140, 140, 255);
|
||||||
color: rgb(255, 255, 255);</string>
|
color: rgb(255, 255, 255);
|
||||||
|
|
||||||
|
QToolTip {
|
||||||
|
color: black;
|
||||||
|
};</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="textElideMode">
|
<property name="textElideMode">
|
||||||
<enum>Qt::ElideNone</enum>
|
<enum>Qt::ElideNone</enum>
|
||||||
|
@ -5,25 +5,6 @@
|
|||||||
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
|
||||||
enum ServerConnectionType
|
|
||||||
{
|
|
||||||
TcpServerConnection,
|
|
||||||
WebSocketServerConnection,
|
|
||||||
};
|
|
||||||
|
|
||||||
static const QMap<QString, ServerConnectionType> SERVER_CONNECTION_TYPE_STRING_MAP = {{"tcp", ServerConnectionType::TcpServerConnection}, {"ws", ServerConnectionType::WebSocketServerConnection}};
|
|
||||||
|
|
||||||
struct ServerInfo
|
|
||||||
{
|
|
||||||
QString name;
|
|
||||||
QString description;
|
|
||||||
QString ip;
|
|
||||||
int port;
|
|
||||||
ServerConnectionType socket_type;
|
|
||||||
|
|
||||||
inline QString toString() { return QString("%1 (<%2>%3:%4)").arg(name, SERVER_CONNECTION_TYPE_STRING_MAP.key(socket_type), ip, QString::number(port)); }
|
|
||||||
};
|
|
||||||
|
|
||||||
struct CharacterSlot
|
struct CharacterSlot
|
||||||
{
|
{
|
||||||
QString name;
|
QString name;
|
||||||
|
@ -9,8 +9,8 @@ DemoServer::DemoServer(QObject *parent)
|
|||||||
timer->setTimerType(Qt::PreciseTimer);
|
timer->setTimerType(Qt::PreciseTimer);
|
||||||
timer->setSingleShot(true);
|
timer->setSingleShot(true);
|
||||||
|
|
||||||
tcp_server = new QTcpServer(this);
|
server = new QWebSocketServer(tr("DemoServer"), QWebSocketServer::NonSecureMode, this);
|
||||||
connect(tcp_server, &QTcpServer::newConnection, this, &DemoServer::accept_connection);
|
connect(server, &QWebSocketServer::newConnection, this, &DemoServer::accept_connection);
|
||||||
connect(timer, &QTimer::timeout, this, &DemoServer::playback);
|
connect(timer, &QTimer::timeout, this, &DemoServer::playback);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,22 +30,22 @@ void DemoServer::start_server()
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!tcp_server->listen(QHostAddress::LocalHost, 0))
|
if (!server->listen(QHostAddress::LocalHost, 0))
|
||||||
{
|
{
|
||||||
qCritical() << "Could not start demo playback server...";
|
qCritical() << "Could not start demo playback server...";
|
||||||
qDebug() << tcp_server->errorString();
|
qDebug() << server->errorString();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this->m_port = tcp_server->serverPort();
|
this->m_port = server->serverPort();
|
||||||
qInfo() << "Demo server started at port" << m_port;
|
qInfo() << "Demo server started at port" << m_port;
|
||||||
m_server_started = true;
|
m_server_started = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DemoServer::destroy_connection()
|
void DemoServer::destroy_connection()
|
||||||
{
|
{
|
||||||
QTcpSocket *temp_socket = tcp_server->nextPendingConnection();
|
QWebSocket *temp_socket = server->nextPendingConnection();
|
||||||
connect(temp_socket, &QAbstractSocket::disconnected, temp_socket, &QObject::deleteLater);
|
temp_socket->close();
|
||||||
temp_socket->disconnectFromHost();
|
temp_socket->deleteLater();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,22 +80,20 @@ void DemoServer::accept_connection()
|
|||||||
{
|
{
|
||||||
// Client is already connected...
|
// Client is already connected...
|
||||||
qWarning() << "Multiple connections to demo server disallowed.";
|
qWarning() << "Multiple connections to demo server disallowed.";
|
||||||
QTcpSocket *temp_socket = tcp_server->nextPendingConnection();
|
QWebSocket *temp_socket = server->nextPendingConnection();
|
||||||
connect(temp_socket, &QAbstractSocket::disconnected, temp_socket, &QObject::deleteLater);
|
temp_socket->close();
|
||||||
temp_socket->disconnectFromHost();
|
temp_socket->deleteLater();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
client_sock = tcp_server->nextPendingConnection();
|
client_sock = server->nextPendingConnection();
|
||||||
connect(client_sock, &QAbstractSocket::disconnected, this, &DemoServer::client_disconnect);
|
connect(client_sock, &QWebSocket::disconnected, this, &DemoServer::client_disconnect);
|
||||||
connect(client_sock, &QAbstractSocket::readyRead, this, &DemoServer::recv_data);
|
connect(client_sock, &QWebSocket::textMessageReceived, this, &DemoServer::recv_data);
|
||||||
client_sock->write("decryptor#NOENCRYPT#%");
|
client_sock->sendTextMessage("decryptor#NOENCRYPT#%");
|
||||||
}
|
}
|
||||||
|
|
||||||
void DemoServer::recv_data()
|
void DemoServer::recv_data(const QString &message)
|
||||||
{
|
{
|
||||||
QString in_data = QString::fromUtf8(client_sock->readAll());
|
const QStringList packet_list = message.split("%", Qt::SkipEmptyParts);
|
||||||
|
|
||||||
const QStringList packet_list = in_data.split("%", Qt::SkipEmptyParts);
|
|
||||||
for (const QString &packet : packet_list)
|
for (const QString &packet : packet_list)
|
||||||
{
|
{
|
||||||
QStringList f_contents;
|
QStringList f_contents;
|
||||||
@ -145,39 +143,35 @@ void DemoServer::handle_packet(AOPacket p_packet)
|
|||||||
|
|
||||||
if (header == "HI")
|
if (header == "HI")
|
||||||
{
|
{
|
||||||
client_sock->write("ID#0#DEMOINTERNAL#0#%");
|
client_sock->sendTextMessage("ID#0#DEMOINTERNAL#0#%");
|
||||||
}
|
}
|
||||||
else if (header == "ID")
|
else if (header == "ID")
|
||||||
{
|
{
|
||||||
QStringList feature_list = {"noencryption", "yellowtext", "prezoom", "flipping", "customobjections", "fastloading", "deskmod", "evidence", "cccc_ic_support", "arup", "casing_alerts", "modcall_reason", "looping_sfx", "additive", "effects", "y_offset", "expanded_desk_mods"};
|
QStringList feature_list = {"noencryption", "yellowtext", "prezoom", "flipping", "customobjections", "fastloading", "deskmod", "evidence", "cccc_ic_support", "arup", "casing_alerts", "modcall_reason", "looping_sfx", "additive", "effects", "y_offset", "expanded_desk_mods"};
|
||||||
client_sock->write("PN#0#1#%");
|
client_sock->sendTextMessage("PN#0#1#%");
|
||||||
client_sock->write("FL#");
|
client_sock->sendTextMessage("FL#" + feature_list.join('#') + "#%");
|
||||||
client_sock->write(feature_list.join('#').toUtf8());
|
|
||||||
client_sock->write("#%");
|
|
||||||
}
|
}
|
||||||
else if (header == "askchaa")
|
else if (header == "askchaa")
|
||||||
{
|
{
|
||||||
client_sock->write("SI#");
|
client_sock->sendTextMessage("SI#" + QString::number(num_chars) + "#0#1#%");
|
||||||
client_sock->write(QString::number(num_chars).toUtf8());
|
|
||||||
client_sock->write("#0#1#%");
|
|
||||||
}
|
}
|
||||||
else if (header == "RC")
|
else if (header == "RC")
|
||||||
{
|
{
|
||||||
client_sock->write(sc_packet.toUtf8());
|
client_sock->sendTextMessage(sc_packet.toUtf8());
|
||||||
}
|
}
|
||||||
else if (header == "RM")
|
else if (header == "RM")
|
||||||
{
|
{
|
||||||
client_sock->write("SM#%");
|
client_sock->sendTextMessage("SM#%");
|
||||||
}
|
}
|
||||||
else if (header == "RD")
|
else if (header == "RD")
|
||||||
{
|
{
|
||||||
client_sock->write("DONE#%");
|
client_sock->sendTextMessage("DONE#%");
|
||||||
}
|
}
|
||||||
else if (header == "CC")
|
else if (header == "CC")
|
||||||
{
|
{
|
||||||
client_sock->write("PV#0#CID#-1#%");
|
client_sock->sendTextMessage("PV#0#CID#-1#%");
|
||||||
QString packet = "CT#DEMO#" + tr("Demo file loaded. Send /play or > in OOC to begin playback.") + "#1#%";
|
QString packet = "CT#DEMO#" + tr("Demo file loaded. Send /play or > in OOC to begin playback.") + "#1#%";
|
||||||
client_sock->write(packet.toUtf8());
|
client_sock->sendTextMessage(packet.toUtf8());
|
||||||
}
|
}
|
||||||
else if (header == "CT")
|
else if (header == "CT")
|
||||||
{
|
{
|
||||||
@ -190,7 +184,7 @@ void DemoServer::handle_packet(AOPacket p_packet)
|
|||||||
}
|
}
|
||||||
load_demo(path);
|
load_demo(path);
|
||||||
QString packet = "CT#DEMO#" + tr("Demo file loaded. Send /play or > in OOC to begin playback.") + "#1#%";
|
QString packet = "CT#DEMO#" + tr("Demo file loaded. Send /play or > in OOC to begin playback.") + "#1#%";
|
||||||
client_sock->write(packet.toUtf8());
|
client_sock->sendTextMessage(packet.toUtf8());
|
||||||
reset_state();
|
reset_state();
|
||||||
}
|
}
|
||||||
else if (contents[1].startsWith("/play") || contents[1] == ">")
|
else if (contents[1].startsWith("/play") || contents[1] == ">")
|
||||||
@ -199,7 +193,7 @@ void DemoServer::handle_packet(AOPacket p_packet)
|
|||||||
{
|
{
|
||||||
timer->start();
|
timer->start();
|
||||||
QString packet = "CT#DEMO#" + tr("Resuming playback.") + "#1#%";
|
QString packet = "CT#DEMO#" + tr("Resuming playback.") + "#1#%";
|
||||||
client_sock->write(packet.toUtf8());
|
client_sock->sendTextMessage(packet.toUtf8());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -216,7 +210,7 @@ void DemoServer::handle_packet(AOPacket p_packet)
|
|||||||
timer->stop();
|
timer->stop();
|
||||||
timer->setInterval(timeleft);
|
timer->setInterval(timeleft);
|
||||||
QString packet = "CT#DEMO#" + tr("Pausing playback.") + "#1#%";
|
QString packet = "CT#DEMO#" + tr("Pausing playback.") + "#1#%";
|
||||||
client_sock->write(packet.toUtf8());
|
client_sock->sendTextMessage(packet.toUtf8());
|
||||||
}
|
}
|
||||||
else if (contents[1].startsWith("/max_wait"))
|
else if (contents[1].startsWith("/max_wait"))
|
||||||
{
|
{
|
||||||
@ -232,38 +226,32 @@ void DemoServer::handle_packet(AOPacket p_packet)
|
|||||||
p_max_wait = -1;
|
p_max_wait = -1;
|
||||||
}
|
}
|
||||||
m_max_wait = p_max_wait;
|
m_max_wait = p_max_wait;
|
||||||
QString packet = "CT#DEMO#" + tr("Setting max_wait to") + " ";
|
QString packet = "CT#DEMO#" + tr("Setting max_wait to") + " " + QString::number(m_max_wait) + " " + tr("milliseconds.") + "#1#%";
|
||||||
client_sock->write(packet.toUtf8());
|
client_sock->sendTextMessage(packet);
|
||||||
client_sock->write(QString::number(m_max_wait).toUtf8());
|
|
||||||
packet = " " + tr("milliseconds.") + "#1#%";
|
|
||||||
client_sock->write(packet.toUtf8());
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
QString packet = "CT#DEMO#" + tr("Not a valid integer!") + "#1#%";
|
QString packet = "CT#DEMO#" + tr("Not a valid integer!") + "#1#%";
|
||||||
client_sock->write(packet.toUtf8());
|
client_sock->sendTextMessage(packet.toUtf8());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
QString packet = "CT#DEMO#" + tr("Current max_wait is") + " ";
|
QString packet = "CT#DEMO#" + tr("Current max_wait is") + " " + QString::number(m_max_wait) + tr("milliseconds.") + "#1#%";
|
||||||
client_sock->write(packet.toUtf8());
|
client_sock->sendTextMessage(packet.toUtf8());
|
||||||
client_sock->write(QString::number(m_max_wait).toUtf8());
|
|
||||||
packet = " " + tr("milliseconds.") + "#1#%";
|
|
||||||
client_sock->write(packet.toUtf8());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (contents[1].startsWith("/reload"))
|
else if (contents[1].startsWith("/reload"))
|
||||||
{
|
{
|
||||||
load_demo(p_path);
|
load_demo(p_path);
|
||||||
QString packet = "CT#DEMO#" + tr("Current demo file reloaded. Send /play or > in OOC to begin playback.") + "#1#%";
|
QString packet = "CT#DEMO#" + tr("Current demo file reloaded. Send /play or > in OOC to begin playback.") + "#1#%";
|
||||||
client_sock->write(packet.toUtf8());
|
client_sock->sendTextMessage(packet.toUtf8());
|
||||||
reset_state();
|
reset_state();
|
||||||
}
|
}
|
||||||
else if (contents[1].startsWith("/min_wait"))
|
else if (contents[1].startsWith("/min_wait"))
|
||||||
{
|
{
|
||||||
QString packet = "CT#DEMO#" + tr("min_wait is deprecated. Use the client Settings for minimum wait instead!") + "#1#%";
|
QString packet = "CT#DEMO#" + tr("min_wait is deprecated. Use the client Settings for minimum wait instead!") + "#1#%";
|
||||||
client_sock->write(packet.toUtf8());
|
client_sock->sendTextMessage(packet.toUtf8());
|
||||||
}
|
}
|
||||||
else if (contents[1].startsWith("/debug"))
|
else if (contents[1].startsWith("/debug"))
|
||||||
{
|
{
|
||||||
@ -276,31 +264,31 @@ void DemoServer::handle_packet(AOPacket p_packet)
|
|||||||
{
|
{
|
||||||
debug_mode = toggle == 1;
|
debug_mode = toggle == 1;
|
||||||
QString packet = "CT#DEMO#" + tr("Setting debug mode to %1").arg(static_cast<int>(debug_mode)) + "#1#%";
|
QString packet = "CT#DEMO#" + tr("Setting debug mode to %1").arg(static_cast<int>(debug_mode)) + "#1#%";
|
||||||
client_sock->write(packet.toUtf8());
|
client_sock->sendTextMessage(packet.toUtf8());
|
||||||
// Debug mode disabled?
|
// Debug mode disabled?
|
||||||
if (!debug_mode)
|
if (!debug_mode)
|
||||||
{
|
{
|
||||||
// Reset the timer
|
// Reset the timer
|
||||||
client_sock->write("TI#4#1#0#%");
|
client_sock->sendTextMessage("TI#4#1#0#%");
|
||||||
client_sock->write("TI#4#3#0#%");
|
client_sock->sendTextMessage("TI#4#3#0#%");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
QString packet = "CT#DEMO#" + tr("Valid values are 1 or 0!") + "#1#%";
|
QString packet = "CT#DEMO#" + tr("Valid values are 1 or 0!") + "#1#%";
|
||||||
client_sock->write(packet.toUtf8());
|
client_sock->sendTextMessage(packet.toUtf8());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
QString packet = "CT#DEMO#" + tr("Set debug mode using /debug 1 to enable, and /debug 0 to disable, which will use the fifth timer (TI#4) to show the remaining time until next demo line.") + "#1#%";
|
QString packet = "CT#DEMO#" + tr("Set debug mode using /debug 1 to enable, and /debug 0 to disable, which will use the fifth timer (TI#4) to show the remaining time until next demo line.") + "#1#%";
|
||||||
client_sock->write(packet.toUtf8());
|
client_sock->sendTextMessage(packet.toUtf8());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (contents[1].startsWith("/help"))
|
else if (contents[1].startsWith("/help"))
|
||||||
{
|
{
|
||||||
QString packet = "CT#DEMO#" + tr("Available commands:\nload, reload, play, pause, max_wait, debug, help") + "#1#%";
|
QString packet = "CT#DEMO#" + tr("Available commands:\nload, reload, play, pause, max_wait, debug, help") + "#1#%";
|
||||||
client_sock->write(packet.toUtf8());
|
client_sock->sendTextMessage(packet.toUtf8());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -395,22 +383,22 @@ void DemoServer::load_demo(QString filename)
|
|||||||
void DemoServer::reset_state()
|
void DemoServer::reset_state()
|
||||||
{
|
{
|
||||||
// Reset evidence list
|
// Reset evidence list
|
||||||
client_sock->write("LE##%");
|
client_sock->sendTextMessage("LE##%");
|
||||||
|
|
||||||
// Reset timers
|
// Reset timers
|
||||||
client_sock->write("TI#0#1#0#%");
|
client_sock->sendTextMessage("TI#0#1#0#%");
|
||||||
client_sock->write("TI#0#3#0#%");
|
client_sock->sendTextMessage("TI#0#3#0#%");
|
||||||
client_sock->write("TI#1#1#0#%");
|
client_sock->sendTextMessage("TI#1#1#0#%");
|
||||||
client_sock->write("TI#1#3#0#%");
|
client_sock->sendTextMessage("TI#1#3#0#%");
|
||||||
client_sock->write("TI#2#1#0#%");
|
client_sock->sendTextMessage("TI#2#1#0#%");
|
||||||
client_sock->write("TI#2#3#0#%");
|
client_sock->sendTextMessage("TI#2#3#0#%");
|
||||||
client_sock->write("TI#3#1#0#%");
|
client_sock->sendTextMessage("TI#3#1#0#%");
|
||||||
client_sock->write("TI#3#3#0#%");
|
client_sock->sendTextMessage("TI#3#3#0#%");
|
||||||
client_sock->write("TI#4#1#0#%");
|
client_sock->sendTextMessage("TI#4#1#0#%");
|
||||||
client_sock->write("TI#4#3#0#%");
|
client_sock->sendTextMessage("TI#4#3#0#%");
|
||||||
|
|
||||||
// Set the BG to default (also breaks up the message queue)
|
// Set the BG to default (also breaks up the message queue)
|
||||||
client_sock->write("BN#default#wit#%");
|
client_sock->sendTextMessage("BN#default#wit#%");
|
||||||
|
|
||||||
// Stop the wait packet timer
|
// Stop the wait packet timer
|
||||||
timer->stop();
|
timer->stop();
|
||||||
@ -432,7 +420,7 @@ void DemoServer::playback()
|
|||||||
|
|
||||||
while (!current_packet.startsWith("wait#"))
|
while (!current_packet.startsWith("wait#"))
|
||||||
{
|
{
|
||||||
client_sock->write(current_packet.toUtf8());
|
client_sock->sendTextMessage(current_packet.toUtf8());
|
||||||
if (demo_data.isEmpty())
|
if (demo_data.isEmpty())
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
@ -478,15 +466,15 @@ void DemoServer::playback()
|
|||||||
timer->start(duration);
|
timer->start(duration);
|
||||||
if (debug_mode)
|
if (debug_mode)
|
||||||
{
|
{
|
||||||
client_sock->write("TI#4#2#%");
|
client_sock->sendTextMessage("TI#4#2#%");
|
||||||
QString debug_timer = "TI#4#0#" + QString::number(duration) + "#%";
|
QString debug_timer = "TI#4#0#" + QString::number(duration) + "#%";
|
||||||
client_sock->write(debug_timer.toUtf8());
|
client_sock->sendTextMessage(debug_timer.toUtf8());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
QString end_packet = "CT#DEMO#" + tr("Reached the end of the demo file. Send /play or > in OOC to restart, or /load to open a new file.") + "#1#%";
|
QString end_packet = "CT#DEMO#" + tr("Reached the end of the demo file. Send /play or > in OOC to restart, or /load to open a new file.") + "#1#%";
|
||||||
client_sock->write(end_packet.toUtf8());
|
client_sock->sendTextMessage(end_packet.toUtf8());
|
||||||
timer->setInterval(0);
|
timer->setInterval(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,9 +7,9 @@
|
|||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QQueue>
|
#include <QQueue>
|
||||||
#include <QTcpServer>
|
|
||||||
#include <QTcpSocket>
|
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
#include <QWebSocket>
|
||||||
|
#include <QWebSocketServer>
|
||||||
|
|
||||||
class DemoServer : public QObject
|
class DemoServer : public QObject
|
||||||
{
|
{
|
||||||
@ -27,8 +27,8 @@ private:
|
|||||||
int m_port = 0;
|
int m_port = 0;
|
||||||
int m_max_wait = -1;
|
int m_max_wait = -1;
|
||||||
|
|
||||||
QTcpServer *tcp_server;
|
QWebSocketServer *server;
|
||||||
QTcpSocket *client_sock = nullptr;
|
QWebSocket *client_sock = nullptr;
|
||||||
bool client_connected = false;
|
bool client_connected = false;
|
||||||
bool partial_packet = false;
|
bool partial_packet = false;
|
||||||
bool debug_mode = false;
|
bool debug_mode = false;
|
||||||
@ -48,7 +48,7 @@ private:
|
|||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
void accept_connection();
|
void accept_connection();
|
||||||
void destroy_connection();
|
void destroy_connection();
|
||||||
void recv_data();
|
void recv_data(const QString &in_data);
|
||||||
void client_disconnect();
|
void client_disconnect();
|
||||||
void playback();
|
void playback();
|
||||||
|
|
||||||
|
@ -238,8 +238,7 @@ void Lobby::on_add_server_to_fave_released()
|
|||||||
void Lobby::on_edit_favorite_released()
|
void Lobby::on_edit_favorite_released()
|
||||||
{
|
{
|
||||||
const int index = get_selected_server();
|
const int index = get_selected_server();
|
||||||
ServerEditorDialog dialog;
|
ServerEditorDialog dialog(Options::getInstance().favorites().at(index));
|
||||||
dialog.loadServerInfo(Options::getInstance().favorites().at(index));
|
|
||||||
if (dialog.exec())
|
if (dialog.exec())
|
||||||
{
|
{
|
||||||
Options::getInstance().updateFavorite(dialog.currentServerInfo(), index);
|
Options::getInstance().updateFavorite(dialog.currentServerInfo(), index);
|
||||||
@ -428,7 +427,7 @@ void Lobby::on_demo_clicked(QTreeWidgetItem *item, int column)
|
|||||||
QString l_filepath = (get_app_path() + "/logs/%1/%2").arg(item->data(0, Qt::DisplayRole).toString(), item->data(1, Qt::DisplayRole).toString());
|
QString l_filepath = (get_app_path() + "/logs/%1/%2").arg(item->data(0, Qt::DisplayRole).toString(), item->data(1, Qt::DisplayRole).toString());
|
||||||
ao_app->demo_server->start_server();
|
ao_app->demo_server->start_server();
|
||||||
ServerInfo demo_server;
|
ServerInfo demo_server;
|
||||||
demo_server.ip = "127.0.0.1";
|
demo_server.address = "127.0.0.1";
|
||||||
demo_server.port = ao_app->demo_server->port();
|
demo_server.port = ao_app->demo_server->port();
|
||||||
ao_app->demo_server->set_demo_file(l_filepath);
|
ao_app->demo_server->set_demo_file(l_filepath);
|
||||||
net_manager->connect_to_server(demo_server);
|
net_manager->connect_to_server(demo_server);
|
||||||
@ -462,7 +461,22 @@ void Lobby::list_servers()
|
|||||||
{
|
{
|
||||||
QTreeWidgetItem *treeItem = new QTreeWidgetItem(ui_serverlist_tree);
|
QTreeWidgetItem *treeItem = new QTreeWidgetItem(ui_serverlist_tree);
|
||||||
treeItem->setData(0, Qt::DisplayRole, i);
|
treeItem->setData(0, Qt::DisplayRole, i);
|
||||||
treeItem->setText(1, i_server.name);
|
|
||||||
|
if (i_server.legacy)
|
||||||
|
{
|
||||||
|
treeItem->setText(1, "(Legacy) " + i_server.name);
|
||||||
|
treeItem->setBackground(0, Qt::darkRed);
|
||||||
|
treeItem->setBackground(1, Qt::darkRed);
|
||||||
|
|
||||||
|
QString tooltip = tr("Unable to connect to server. Server is missing WebSocket support.");
|
||||||
|
treeItem->setToolTip(0, tooltip);
|
||||||
|
treeItem->setToolTip(1, tooltip);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
treeItem->setText(1, i_server.name);
|
||||||
|
}
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
ui_serverlist_tree->setSortingEnabled(true);
|
ui_serverlist_tree->setSortingEnabled(true);
|
||||||
@ -480,7 +494,22 @@ void Lobby::list_favorites()
|
|||||||
{
|
{
|
||||||
QTreeWidgetItem *treeItem = new QTreeWidgetItem(ui_favorites_tree);
|
QTreeWidgetItem *treeItem = new QTreeWidgetItem(ui_favorites_tree);
|
||||||
treeItem->setData(0, Qt::DisplayRole, i);
|
treeItem->setData(0, Qt::DisplayRole, i);
|
||||||
treeItem->setText(1, i_server.name);
|
|
||||||
|
if (i_server.legacy)
|
||||||
|
{
|
||||||
|
treeItem->setText(1, "(Legacy) " + i_server.name);
|
||||||
|
treeItem->setBackground(0, Qt::darkRed);
|
||||||
|
treeItem->setBackground(1, Qt::darkRed);
|
||||||
|
|
||||||
|
QString tooltip = tr("Unable to connect to server. Server is missing WebSocket support.");
|
||||||
|
treeItem->setToolTip(0, tooltip);
|
||||||
|
treeItem->setToolTip(1, tooltip);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
treeItem->setText(1, i_server.name);
|
||||||
|
}
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
ui_favorites_tree->setSortingEnabled(true);
|
ui_favorites_tree->setSortingEnabled(true);
|
||||||
|
@ -1,5 +0,0 @@
|
|||||||
#include "netconnection.h"
|
|
||||||
|
|
||||||
NetConnection::NetConnection(QObject *parent)
|
|
||||||
: QObject(parent)
|
|
||||||
{}
|
|
@ -1,28 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "aopacket.h"
|
|
||||||
#include "datatypes.h"
|
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
|
|
||||||
class NetConnection : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit NetConnection(QObject *parent = nullptr);
|
|
||||||
|
|
||||||
virtual bool isConnected() = 0;
|
|
||||||
|
|
||||||
virtual void connectToServer(ServerInfo &server) = 0;
|
|
||||||
virtual void disconnectFromServer() = 0;
|
|
||||||
|
|
||||||
virtual void sendPacket(AOPacket packet) = 0;
|
|
||||||
|
|
||||||
Q_SIGNALS:
|
|
||||||
void connectedToServer();
|
|
||||||
void disconnectedFromServer();
|
|
||||||
void errorOccurred(QString error);
|
|
||||||
|
|
||||||
void receivedPacket(AOPacket packet);
|
|
||||||
};
|
|
@ -1,102 +0,0 @@
|
|||||||
#include "nettcpconnection.h"
|
|
||||||
|
|
||||||
NetTcpConnection::NetTcpConnection(QObject *parent)
|
|
||||||
: NetConnection(parent)
|
|
||||||
, m_socket(new QTcpSocket(this))
|
|
||||||
, m_last_state(QAbstractSocket::UnconnectedState)
|
|
||||||
{
|
|
||||||
#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
|
|
||||||
connect(m_socket, QOverload<QAbstractSocket::SocketError>::of(&QAbstractSocket::error), this, &NetTcpConnection::onErrorOccurred);
|
|
||||||
#else
|
|
||||||
connect(m_socket, &QTcpSocket::errorOccurred, this, &NetTcpConnection::onErrorOccurred);
|
|
||||||
#endif
|
|
||||||
connect(m_socket, &QTcpSocket::stateChanged, this, &NetTcpConnection::onStateChanged);
|
|
||||||
connect(m_socket, &QTcpSocket::readyRead, this, &NetTcpConnection::onReadyRead);
|
|
||||||
}
|
|
||||||
|
|
||||||
NetTcpConnection::~NetTcpConnection()
|
|
||||||
{
|
|
||||||
m_socket->disconnect(this);
|
|
||||||
disconnectFromServer();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool NetTcpConnection::isConnected()
|
|
||||||
{
|
|
||||||
return m_last_state == QAbstractSocket::ConnectedState;
|
|
||||||
}
|
|
||||||
|
|
||||||
void NetTcpConnection::connectToServer(ServerInfo &server)
|
|
||||||
{
|
|
||||||
disconnectedFromServer();
|
|
||||||
m_socket->connectToHost(server.ip, server.port);
|
|
||||||
}
|
|
||||||
|
|
||||||
void NetTcpConnection::disconnectFromServer()
|
|
||||||
{
|
|
||||||
m_socket->abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
void NetTcpConnection::sendPacket(AOPacket packet)
|
|
||||||
{
|
|
||||||
if (!isConnected())
|
|
||||||
{
|
|
||||||
qWarning().noquote() << QObject::tr("Cannot send packet, not connected to server");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
m_socket->write(packet.toString(true).toUtf8());
|
|
||||||
}
|
|
||||||
|
|
||||||
void NetTcpConnection::onErrorOccurred()
|
|
||||||
{
|
|
||||||
Q_EMIT errorOccurred(m_socket->errorString());
|
|
||||||
}
|
|
||||||
|
|
||||||
void NetTcpConnection::onStateChanged(QAbstractSocket::SocketState state)
|
|
||||||
{
|
|
||||||
m_last_state = state;
|
|
||||||
switch (state)
|
|
||||||
{
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case QAbstractSocket::ConnectedState:
|
|
||||||
m_cached_data.clear();
|
|
||||||
Q_EMIT connectedToServer();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case QAbstractSocket::UnconnectedState:
|
|
||||||
Q_EMIT disconnectFromServer();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void NetTcpConnection::onReadyRead()
|
|
||||||
{
|
|
||||||
m_cached_data += QString::fromUtf8(m_socket->readAll());
|
|
||||||
if (!m_cached_data.endsWith('%'))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList raw_packet_list = m_cached_data.split('%', Qt::SkipEmptyParts);
|
|
||||||
m_cached_data.clear();
|
|
||||||
for (QString raw_packet : raw_packet_list)
|
|
||||||
{
|
|
||||||
if (!raw_packet.endsWith('#'))
|
|
||||||
{
|
|
||||||
Q_EMIT errorOccurred(QObject::tr("Malformed packet received %1").arg(raw_packet));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
raw_packet.chop(1);
|
|
||||||
|
|
||||||
QStringList raw_content = raw_packet.split('#');
|
|
||||||
|
|
||||||
const QString header = raw_content.takeFirst();
|
|
||||||
for (QString &data : raw_content)
|
|
||||||
{
|
|
||||||
data = AOPacket::decode(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
Q_EMIT receivedPacket(AOPacket(header, raw_content));
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,31 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "aopacket.h"
|
|
||||||
#include "datatypes.h"
|
|
||||||
#include "netconnection.h"
|
|
||||||
|
|
||||||
#include <QTcpSocket>
|
|
||||||
|
|
||||||
class NetTcpConnection : public NetConnection
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
NetTcpConnection(QObject *parent = nullptr);
|
|
||||||
virtual ~NetTcpConnection();
|
|
||||||
|
|
||||||
bool isConnected() override;
|
|
||||||
|
|
||||||
void connectToServer(ServerInfo &server) override;
|
|
||||||
void disconnectFromServer() override;
|
|
||||||
|
|
||||||
void sendPacket(AOPacket packet) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
QTcpSocket *m_socket;
|
|
||||||
QAbstractSocket::SocketState m_last_state;
|
|
||||||
QString m_cached_data;
|
|
||||||
|
|
||||||
private Q_SLOTS:
|
|
||||||
void onErrorOccurred();
|
|
||||||
void onStateChanged(QAbstractSocket::SocketState state);
|
|
||||||
void onReadyRead();
|
|
||||||
};
|
|
@ -1,32 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "netconnection.h"
|
|
||||||
|
|
||||||
class NetworkManager;
|
|
||||||
|
|
||||||
#include <QWebSocket>
|
|
||||||
|
|
||||||
class NetWebSocketConnection : public NetConnection
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
NetWebSocketConnection(NetworkManager *networkManager);
|
|
||||||
virtual ~NetWebSocketConnection();
|
|
||||||
|
|
||||||
bool isConnected() override;
|
|
||||||
|
|
||||||
void connectToServer(ServerInfo &server) override;
|
|
||||||
void disconnectFromServer() override;
|
|
||||||
|
|
||||||
void sendPacket(AOPacket packet) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
NetworkManager *m_network_manager;
|
|
||||||
|
|
||||||
QWebSocket *m_socket;
|
|
||||||
QAbstractSocket::SocketState m_last_state;
|
|
||||||
|
|
||||||
private Q_SLOTS:
|
|
||||||
void onError();
|
|
||||||
void onStateChanged(QAbstractSocket::SocketState state);
|
|
||||||
void onTextMessageReceived(QString message);
|
|
||||||
};
|
|
6
src/network/serverinfo.cpp
Normal file
6
src/network/serverinfo.cpp
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#include "serverinfo.h"
|
||||||
|
|
||||||
|
QString ServerInfo::toString() const
|
||||||
|
{
|
||||||
|
return QString("%1 (%2:%3)").arg(name.isEmpty() ? QStringLiteral("Unnamed Server") : name).arg(address).arg(port);
|
||||||
|
}
|
15
src/network/serverinfo.h
Normal file
15
src/network/serverinfo.h
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
class ServerInfo
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QString name;
|
||||||
|
QString description;
|
||||||
|
QString address;
|
||||||
|
quint16 port = 0;
|
||||||
|
bool legacy = false;
|
||||||
|
|
||||||
|
QString toString() const;
|
||||||
|
};
|
@ -1,48 +1,48 @@
|
|||||||
#include "netwebsocketconnection.h"
|
#include "websocketconnection.h"
|
||||||
|
|
||||||
#include "networkmanager.h"
|
#include "aoapplication.h"
|
||||||
|
|
||||||
#include <QNetworkRequest>
|
#include <QNetworkRequest>
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
|
|
||||||
NetWebSocketConnection::NetWebSocketConnection(NetworkManager *networkManager)
|
WebSocketConnection::WebSocketConnection(AOApplication *ao_app, QObject *parent)
|
||||||
: NetConnection(networkManager)
|
: QObject(parent)
|
||||||
, m_network_manager(networkManager)
|
, ao_app(ao_app)
|
||||||
, m_socket(new QWebSocket(QString(), QWebSocketProtocol::VersionLatest, this))
|
, m_socket(new QWebSocket(QString(), QWebSocketProtocol::VersionLatest, this))
|
||||||
, m_last_state(QAbstractSocket::UnconnectedState)
|
, m_last_state(QAbstractSocket::UnconnectedState)
|
||||||
{
|
{
|
||||||
connect(m_socket, QOverload<QAbstractSocket::SocketError>::of(&QWebSocket::error), this, &NetWebSocketConnection::onError);
|
connect(m_socket, QOverload<QAbstractSocket::SocketError>::of(&QWebSocket::error), this, &WebSocketConnection::onError);
|
||||||
connect(m_socket, &QWebSocket::stateChanged, this, &NetWebSocketConnection::onStateChanged);
|
connect(m_socket, &QWebSocket::stateChanged, this, &WebSocketConnection::onStateChanged);
|
||||||
connect(m_socket, &QWebSocket::textMessageReceived, this, &NetWebSocketConnection::onTextMessageReceived);
|
connect(m_socket, &QWebSocket::textMessageReceived, this, &WebSocketConnection::onTextMessageReceived);
|
||||||
}
|
}
|
||||||
|
|
||||||
NetWebSocketConnection::~NetWebSocketConnection()
|
WebSocketConnection::~WebSocketConnection()
|
||||||
{
|
{
|
||||||
m_socket->disconnect(this);
|
m_socket->disconnect(this);
|
||||||
disconnectFromServer();
|
disconnectFromServer();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NetWebSocketConnection::isConnected()
|
bool WebSocketConnection::isConnected()
|
||||||
{
|
{
|
||||||
return m_last_state == QAbstractSocket::ConnectedState;
|
return m_last_state == QAbstractSocket::ConnectedState;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetWebSocketConnection::connectToServer(ServerInfo &server)
|
void WebSocketConnection::connectToServer(const ServerInfo &server)
|
||||||
{
|
{
|
||||||
disconnectFromServer();
|
disconnectFromServer();
|
||||||
|
|
||||||
QUrl url;
|
QUrl url;
|
||||||
url.setScheme("ws");
|
url.setScheme("ws");
|
||||||
url.setHost(server.ip);
|
url.setHost(server.address);
|
||||||
url.setPort(server.port);
|
url.setPort(server.port);
|
||||||
|
|
||||||
QNetworkRequest req(url);
|
QNetworkRequest req(url);
|
||||||
req.setHeader(QNetworkRequest::UserAgentHeader, m_network_manager->get_user_agent());
|
req.setHeader(QNetworkRequest::UserAgentHeader, QStringLiteral("AttorneyOnline/%1 (Desktop)").arg(ao_app->get_version_string()));
|
||||||
|
|
||||||
m_socket->open(req);
|
m_socket->open(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetWebSocketConnection::disconnectFromServer()
|
void WebSocketConnection::disconnectFromServer()
|
||||||
{
|
{
|
||||||
if (isConnected())
|
if (isConnected())
|
||||||
{
|
{
|
||||||
@ -50,17 +50,17 @@ void NetWebSocketConnection::disconnectFromServer()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetWebSocketConnection::sendPacket(AOPacket packet)
|
void WebSocketConnection::sendPacket(AOPacket packet)
|
||||||
{
|
{
|
||||||
m_socket->sendTextMessage(packet.toString(true));
|
m_socket->sendTextMessage(packet.toString(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetWebSocketConnection::onError()
|
void WebSocketConnection::onError()
|
||||||
{
|
{
|
||||||
Q_EMIT errorOccurred(m_socket->errorString());
|
Q_EMIT errorOccurred(m_socket->errorString());
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetWebSocketConnection::onStateChanged(QAbstractSocket::SocketState state)
|
void WebSocketConnection::onStateChanged(QAbstractSocket::SocketState state)
|
||||||
{
|
{
|
||||||
m_last_state = state;
|
m_last_state = state;
|
||||||
switch (state)
|
switch (state)
|
||||||
@ -78,7 +78,7 @@ void NetWebSocketConnection::onStateChanged(QAbstractSocket::SocketState state)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetWebSocketConnection::onTextMessageReceived(QString message)
|
void WebSocketConnection::onTextMessageReceived(QString message)
|
||||||
{
|
{
|
||||||
if (!message.endsWith("#%"))
|
if (!message.endsWith("#%"))
|
||||||
{
|
{
|
43
src/network/websocketconnection.h
Normal file
43
src/network/websocketconnection.h
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "aopacket.h"
|
||||||
|
#include "serverinfo.h"
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QWebSocket>
|
||||||
|
|
||||||
|
class AOApplication;
|
||||||
|
|
||||||
|
class WebSocketConnection : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit WebSocketConnection(AOApplication *ao_app, QObject *parent = nullptr);
|
||||||
|
virtual ~WebSocketConnection();
|
||||||
|
|
||||||
|
bool isConnected();
|
||||||
|
|
||||||
|
void connectToServer(const ServerInfo &server);
|
||||||
|
void disconnectFromServer();
|
||||||
|
|
||||||
|
void sendPacket(AOPacket packet);
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
void connectedToServer();
|
||||||
|
void disconnectedFromServer();
|
||||||
|
void errorOccurred(QString error);
|
||||||
|
|
||||||
|
void receivedPacket(AOPacket packet);
|
||||||
|
|
||||||
|
private:
|
||||||
|
AOApplication *ao_app;
|
||||||
|
|
||||||
|
QWebSocket *m_socket;
|
||||||
|
QAbstractSocket::SocketState m_last_state;
|
||||||
|
|
||||||
|
private Q_SLOTS:
|
||||||
|
void onError();
|
||||||
|
void onStateChanged(QAbstractSocket::SocketState state);
|
||||||
|
void onTextMessageReceived(QString message);
|
||||||
|
};
|
@ -3,8 +3,6 @@
|
|||||||
#include "datatypes.h"
|
#include "datatypes.h"
|
||||||
#include "debug_functions.h"
|
#include "debug_functions.h"
|
||||||
#include "lobby.h"
|
#include "lobby.h"
|
||||||
#include "net/nettcpconnection.h"
|
|
||||||
#include "net/netwebsocketconnection.h"
|
|
||||||
#include "options.h"
|
#include "options.h"
|
||||||
|
|
||||||
#include <QAbstractSocket>
|
#include <QAbstractSocket>
|
||||||
@ -59,19 +57,19 @@ void NetworkManager::ms_request_finished(QNetworkReply *reply)
|
|||||||
{
|
{
|
||||||
const auto entry = entryRef.toObject();
|
const auto entry = entryRef.toObject();
|
||||||
ServerInfo server;
|
ServerInfo server;
|
||||||
server.ip = entry["ip"].toString();
|
server.address = entry["ip"].toString();
|
||||||
server.name = entry["name"].toString();
|
server.name = entry["name"].toString();
|
||||||
server.description = entry["description"].toString(tr("No description provided."));
|
server.description = entry["description"].toString(tr("No description provided."));
|
||||||
if (entry["ws_port"].isDouble())
|
if (entry.contains("ws_port"))
|
||||||
{
|
{
|
||||||
server.socket_type = WebSocketServerConnection;
|
|
||||||
server.port = entry["ws_port"].toInt();
|
server.port = entry["ws_port"].toInt();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
server.socket_type = TcpServerConnection;
|
|
||||||
server.port = entry["port"].toInt();
|
server.port = entry["port"].toInt();
|
||||||
|
server.legacy = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (server.port != 0)
|
if (server.port != 0)
|
||||||
{
|
{
|
||||||
server_list.append(server);
|
server_list.append(server);
|
||||||
@ -149,27 +147,12 @@ void NetworkManager::connect_to_server(ServerInfo server)
|
|||||||
disconnect_from_server();
|
disconnect_from_server();
|
||||||
|
|
||||||
qInfo().noquote() << QObject::tr("Connecting to %1").arg(server.toString());
|
qInfo().noquote() << QObject::tr("Connecting to %1").arg(server.toString());
|
||||||
switch (server.socket_type)
|
m_connection = new WebSocketConnection(ao_app, this);
|
||||||
{
|
|
||||||
default:
|
|
||||||
server.socket_type = TcpServerConnection;
|
|
||||||
[[fallthrough]];
|
|
||||||
|
|
||||||
case TcpServerConnection:
|
connect(m_connection, &WebSocketConnection::connectedToServer, this, [] { qInfo() << "Established connection to server."; });
|
||||||
qInfo() << "Using TCP backend.";
|
connect(m_connection, &WebSocketConnection::disconnectedFromServer, ao_app, &AOApplication::server_disconnected);
|
||||||
m_connection = new NetTcpConnection(this);
|
connect(m_connection, &WebSocketConnection::errorOccurred, this, [](QString error) { qCritical() << "Connection error:" << error; });
|
||||||
break;
|
connect(m_connection, &WebSocketConnection::receivedPacket, this, &NetworkManager::handle_server_packet);
|
||||||
|
|
||||||
case WebSocketServerConnection:
|
|
||||||
qInfo() << "Using WebSockets backend.";
|
|
||||||
m_connection = new NetWebSocketConnection(this);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
connect(m_connection, &NetConnection::connectedToServer, this, [] { qInfo() << "Established connection to server."; });
|
|
||||||
connect(m_connection, &NetConnection::disconnectedFromServer, ao_app, &AOApplication::server_disconnected);
|
|
||||||
connect(m_connection, &NetConnection::errorOccurred, this, [](QString error) { qCritical() << "Connection error:" << error; });
|
|
||||||
connect(m_connection, &NetConnection::receivedPacket, this, &NetworkManager::handle_server_packet);
|
|
||||||
|
|
||||||
m_connection->connectToServer(server);
|
m_connection->connectToServer(server);
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "aoapplication.h"
|
#include "aoapplication.h"
|
||||||
#include "aopacket.h"
|
#include "aopacket.h"
|
||||||
#include "net/netconnection.h"
|
#include "network/websocketconnection.h"
|
||||||
|
|
||||||
#include <QDnsLookup>
|
#include <QDnsLookup>
|
||||||
#include <QNetworkAccessManager>
|
#include <QNetworkAccessManager>
|
||||||
@ -50,7 +50,7 @@ private:
|
|||||||
AOApplication *ao_app;
|
AOApplication *ao_app;
|
||||||
QNetworkAccessManager *http;
|
QNetworkAccessManager *http;
|
||||||
|
|
||||||
NetConnection *m_connection = nullptr;
|
WebSocketConnection *m_connection = nullptr;
|
||||||
|
|
||||||
QTimer *heartbeat_timer;
|
QTimer *heartbeat_timer;
|
||||||
|
|
||||||
|
@ -668,11 +668,19 @@ QVector<ServerInfo> Options::favorites()
|
|||||||
{
|
{
|
||||||
ServerInfo f_server;
|
ServerInfo f_server;
|
||||||
favorite.beginGroup(group);
|
favorite.beginGroup(group);
|
||||||
f_server.ip = favorite.value("address", "127.0.0.1").toString();
|
f_server.address = favorite.value("address", "127.0.0.1").toString();
|
||||||
f_server.port = favorite.value("port", 27016).toInt();
|
f_server.port = favorite.value("port", 27016).toInt();
|
||||||
f_server.name = favorite.value("name", "Missing Name").toString();
|
f_server.name = favorite.value("name", "Missing Name").toString();
|
||||||
f_server.description = favorite.value("desc", "No description").toString();
|
f_server.description = favorite.value("desc", "No description").toString();
|
||||||
f_server.socket_type = SERVER_CONNECTION_TYPE_STRING_MAP.value(favorite.value("protocol", "tcp").toString());
|
if (favorite.contains("protocol"))
|
||||||
|
{
|
||||||
|
f_server.legacy = favorite.value("protocol").toString() == "tcp";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
f_server.legacy = favorite.value("legacy", false).toBool();
|
||||||
|
}
|
||||||
|
|
||||||
serverlist.append(std::move(f_server));
|
serverlist.append(std::move(f_server));
|
||||||
favorite.endGroup();
|
favorite.endGroup();
|
||||||
}
|
}
|
||||||
@ -688,18 +696,10 @@ void Options::setFavorites(QVector<ServerInfo> value)
|
|||||||
auto fav_server = value.at(i);
|
auto fav_server = value.at(i);
|
||||||
favorite.beginGroup(QString::number(i));
|
favorite.beginGroup(QString::number(i));
|
||||||
favorite.setValue("name", fav_server.name);
|
favorite.setValue("name", fav_server.name);
|
||||||
favorite.setValue("address", fav_server.ip);
|
favorite.setValue("address", fav_server.address);
|
||||||
favorite.setValue("port", fav_server.port);
|
favorite.setValue("port", fav_server.port);
|
||||||
favorite.setValue("desc", fav_server.description);
|
favorite.setValue("desc", fav_server.description);
|
||||||
|
favorite.setValue("legacy", fav_server.legacy);
|
||||||
if (fav_server.socket_type == TcpServerConnection)
|
|
||||||
{
|
|
||||||
favorite.setValue("protocol", "tcp");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
favorite.setValue("protocol", "ws");
|
|
||||||
}
|
|
||||||
favorite.endGroup();
|
favorite.endGroup();
|
||||||
}
|
}
|
||||||
favorite.sync();
|
favorite.sync();
|
||||||
@ -717,17 +717,10 @@ void Options::addFavorite(ServerInfo server)
|
|||||||
int index = favorites().size();
|
int index = favorites().size();
|
||||||
favorite.beginGroup(QString::number(index));
|
favorite.beginGroup(QString::number(index));
|
||||||
favorite.setValue("name", server.name);
|
favorite.setValue("name", server.name);
|
||||||
favorite.setValue("address", server.ip);
|
favorite.setValue("address", server.address);
|
||||||
favorite.setValue("port", server.port);
|
favorite.setValue("port", server.port);
|
||||||
favorite.setValue("desc", server.description);
|
favorite.setValue("desc", server.description);
|
||||||
if (server.socket_type == TcpServerConnection)
|
favorite.setValue("legacy", server.legacy);
|
||||||
{
|
|
||||||
favorite.setValue("protocol", "tcp");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
favorite.setValue("protocol", "ws");
|
|
||||||
}
|
|
||||||
favorite.endGroup();
|
favorite.endGroup();
|
||||||
favorite.sync();
|
favorite.sync();
|
||||||
}
|
}
|
||||||
@ -736,17 +729,10 @@ void Options::updateFavorite(ServerInfo server, int index)
|
|||||||
{
|
{
|
||||||
favorite.beginGroup(QString::number(index));
|
favorite.beginGroup(QString::number(index));
|
||||||
favorite.setValue("name", server.name);
|
favorite.setValue("name", server.name);
|
||||||
favorite.setValue("address", server.ip);
|
favorite.setValue("address", server.address);
|
||||||
favorite.setValue("port", server.port);
|
favorite.setValue("port", server.port);
|
||||||
favorite.setValue("desc", server.description);
|
favorite.setValue("desc", server.description);
|
||||||
if (server.socket_type == TcpServerConnection)
|
favorite.setValue("legacy", server.legacy);
|
||||||
{
|
|
||||||
favorite.setValue("protocol", "tcp");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
favorite.setValue("protocol", "ws");
|
|
||||||
}
|
|
||||||
favorite.endGroup();
|
favorite.endGroup();
|
||||||
favorite.sync();
|
favorite.sync();
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "network/serverinfo.h"
|
||||||
|
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
#include <datatypes.h>
|
|
||||||
|
|
||||||
class Options
|
class Options
|
||||||
{
|
{
|
||||||
|
@ -132,7 +132,7 @@ void AOApplication::server_packet_received(AOPacket packet)
|
|||||||
{
|
{
|
||||||
auto info = server_list.at(selected_server);
|
auto info = server_list.at(selected_server);
|
||||||
server_name = info.name;
|
server_name = info.name;
|
||||||
server_address = QString("%1:%2").arg(info.ip, QString::number(info.port));
|
server_address = QString("%1:%2").arg(info.address, QString::number(info.port));
|
||||||
window_title = server_name;
|
window_title = server_name;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -144,7 +144,7 @@ void AOApplication::server_packet_received(AOPacket packet)
|
|||||||
{
|
{
|
||||||
auto info = favorite_list.at(selected_server);
|
auto info = favorite_list.at(selected_server);
|
||||||
server_name = info.name;
|
server_name = info.name;
|
||||||
server_address = QString("%1:%2").arg(info.ip, QString::number(info.port));
|
server_address = QString("%1:%2").arg(info.address, QString::number(info.port));
|
||||||
window_title = server_name;
|
window_title = server_name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,27 +50,29 @@ void DirectConnectDialog::onConnectPressed()
|
|||||||
QString l_hostname = ui_direct_hostname_edit->text();
|
QString l_hostname = ui_direct_hostname_edit->text();
|
||||||
if (!SCHEME_PATTERN.match(l_hostname).hasMatch())
|
if (!SCHEME_PATTERN.match(l_hostname).hasMatch())
|
||||||
{
|
{
|
||||||
l_hostname = "tcp://" % l_hostname;
|
l_hostname = "ws://" % l_hostname;
|
||||||
}
|
}
|
||||||
|
|
||||||
QUrl l_url(l_hostname);
|
QUrl l_url(l_hostname);
|
||||||
if (!l_url.isValid())
|
if (!l_url.isValid())
|
||||||
{
|
{
|
||||||
call_error(tr("Invalid URL."));
|
call_error(tr("Invalid URL."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!SERVER_CONNECTION_TYPE_STRING_MAP.contains(l_url.scheme()))
|
|
||||||
|
if (l_url.scheme() != "ws")
|
||||||
{
|
{
|
||||||
call_error(tr("Scheme not recognized. Must be either of the following: ") % QStringList::fromVector(SERVER_CONNECTION_TYPE_STRING_MAP.keys().toVector()).join(", "));
|
call_error(tr("Invalid URL scheme. Only ws:// is supported."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (l_url.port() == -1)
|
if (l_url.port() == -1)
|
||||||
{
|
{
|
||||||
call_error(tr("Invalid server port."));
|
call_error(tr("Invalid server port."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ServerInfo l_server;
|
ServerInfo l_server;
|
||||||
l_server.socket_type = SERVER_CONNECTION_TYPE_STRING_MAP[l_url.scheme()];
|
l_server.address = l_url.host();
|
||||||
l_server.ip = l_url.host();
|
|
||||||
l_server.port = l_url.port();
|
l_server.port = l_url.port();
|
||||||
l_server.name = "Direct Connection";
|
l_server.name = "Direct Connection";
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#include "server_editor_dialog.h"
|
#include "server_editor_dialog.h"
|
||||||
|
|
||||||
#include "datatypes.h"
|
#include "datatypes.h"
|
||||||
|
#include "debug_functions.h"
|
||||||
#include "gui_utils.h"
|
#include "gui_utils.h"
|
||||||
#include "options.h"
|
#include "options.h"
|
||||||
|
|
||||||
@ -30,7 +31,6 @@ ServerEditorDialog::ServerEditorDialog(QWidget *parent)
|
|||||||
FROM_UI(QLineEdit, name);
|
FROM_UI(QLineEdit, name);
|
||||||
FROM_UI(QLineEdit, hostname);
|
FROM_UI(QLineEdit, hostname);
|
||||||
FROM_UI(QSpinBox, port);
|
FROM_UI(QSpinBox, port);
|
||||||
FROM_UI(QComboBox, protocol);
|
|
||||||
FROM_UI(QPlainTextEdit, description);
|
FROM_UI(QPlainTextEdit, description);
|
||||||
FROM_UI(QDialogButtonBox, button_box);
|
FROM_UI(QDialogButtonBox, button_box);
|
||||||
|
|
||||||
@ -43,52 +43,35 @@ ServerEditorDialog::ServerEditorDialog(QWidget *parent)
|
|||||||
connect(ui_button_box, &QDialogButtonBox::rejected, this, &ServerEditorDialog::reject);
|
connect(ui_button_box, &QDialogButtonBox::rejected, this, &ServerEditorDialog::reject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ServerEditorDialog::ServerEditorDialog(const ServerInfo &server, QWidget *parent)
|
||||||
|
: ServerEditorDialog(parent)
|
||||||
|
{
|
||||||
|
ui_name->setText(server.name);
|
||||||
|
ui_hostname->setText(server.address);
|
||||||
|
ui_port->setValue(server.port);
|
||||||
|
ui_description->setPlainText(server.description);
|
||||||
|
}
|
||||||
|
|
||||||
ServerInfo ServerEditorDialog::currentServerInfo() const
|
ServerInfo ServerEditorDialog::currentServerInfo() const
|
||||||
{
|
{
|
||||||
ServerInfo server;
|
ServerInfo server;
|
||||||
server.name = ui_name->text();
|
server.name = ui_name->text();
|
||||||
server.ip = ui_hostname->text();
|
server.address = ui_hostname->text();
|
||||||
server.port = ui_port->value();
|
server.port = ui_port->value();
|
||||||
server.description = ui_description->toPlainText();
|
server.description = ui_description->toPlainText();
|
||||||
server.socket_type = ServerConnectionType(ui_protocol->currentIndex());
|
|
||||||
return server;
|
return server;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServerEditorDialog::loadServerInfo(ServerInfo server)
|
|
||||||
{
|
|
||||||
ui_name->setText(server.name);
|
|
||||||
ui_hostname->setText(server.ip);
|
|
||||||
ui_port->setValue(server.port);
|
|
||||||
ui_description->setPlainText(server.description);
|
|
||||||
ui_protocol->setCurrentIndex(server.socket_type);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ServerEditorDialog::parseLegacyEntry()
|
void ServerEditorDialog::parseLegacyEntry()
|
||||||
{
|
{
|
||||||
QStringList entry = ui_legacy_edit->text().split(":");
|
QStringList entry = ui_legacy_edit->text().split(":");
|
||||||
ServerInfo l_server_entry;
|
if (entry.size() < 3)
|
||||||
if (entry.isEmpty())
|
|
||||||
{
|
{
|
||||||
qDebug() << "Legacy entry empty.";
|
call_error("Invalid legacy server entry");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int item_count = entry.size();
|
ui_hostname->setText(entry.at(0));
|
||||||
if (item_count >= 3)
|
ui_port->setValue(entry.at(1).toInt());
|
||||||
{
|
ui_name->setText(entry.at(2));
|
||||||
ui_hostname->setText(entry.at(0));
|
|
||||||
ui_port->setValue(entry.at(1).toInt());
|
|
||||||
ui_name->setText(entry.at(2));
|
|
||||||
if (item_count >= 4)
|
|
||||||
{
|
|
||||||
if (entry.at(3) == "ws")
|
|
||||||
{
|
|
||||||
ui_protocol->setCurrentIndex(1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ui_protocol->setCurrentIndex(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "datatypes.h"
|
#include "network/serverinfo.h"
|
||||||
|
|
||||||
#include <QComboBox>
|
#include <QComboBox>
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
@ -21,8 +21,6 @@ public:
|
|||||||
|
|
||||||
ServerInfo currentServerInfo() const;
|
ServerInfo currentServerInfo() const;
|
||||||
|
|
||||||
void loadServerInfo(ServerInfo server);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const QString UI_FILE_PATH;
|
static const QString UI_FILE_PATH;
|
||||||
|
|
||||||
@ -31,7 +29,6 @@ private:
|
|||||||
QLineEdit *ui_name;
|
QLineEdit *ui_name;
|
||||||
QLineEdit *ui_hostname;
|
QLineEdit *ui_hostname;
|
||||||
QSpinBox *ui_port;
|
QSpinBox *ui_port;
|
||||||
QComboBox *ui_protocol;
|
|
||||||
QPlainTextEdit *ui_description;
|
QPlainTextEdit *ui_description;
|
||||||
QDialogButtonBox *ui_button_box;
|
QDialogButtonBox *ui_button_box;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user