massive refactor ty longbyte
This commit is contained in:
parent
676b4cbf56
commit
772e850d37
@ -1,4 +1,4 @@
|
|||||||
QT += core gui network
|
QT += core gui network websockets
|
||||||
|
|
||||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||||
|
|
||||||
|
@ -1,13 +1,19 @@
|
|||||||
#ifndef AOCLIENT_H
|
#ifndef AOCLIENT_H
|
||||||
#define AOCLIENT_H
|
#define AOCLIENT_H
|
||||||
|
|
||||||
|
#include "include/aopacket.h"
|
||||||
|
#include "include/server.h"
|
||||||
|
|
||||||
#include <QCryptographicHash>
|
#include <QCryptographicHash>
|
||||||
#include <QHostAddress>
|
#include <QHostAddress>
|
||||||
#include <QTcpSocket>
|
#include <QTcpSocket>
|
||||||
|
|
||||||
class AOClient {
|
class Server;
|
||||||
|
|
||||||
|
class AOClient : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
AOClient(QHostAddress p_remote_ip);
|
AOClient(Server* p_server, QTcpSocket* p_socket, QObject* parent = nullptr);
|
||||||
~AOClient();
|
~AOClient();
|
||||||
|
|
||||||
QString getHwid();
|
QString getHwid();
|
||||||
@ -21,7 +27,20 @@ class AOClient {
|
|||||||
int current_area;
|
int current_area;
|
||||||
QString current_char;
|
QString current_char;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void clientDisconnected();
|
||||||
|
void clientData();
|
||||||
|
void sendPacket(AOPacket packet);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Server* server;
|
||||||
|
QTcpSocket* socket;
|
||||||
|
|
||||||
|
void handlePacket(AOPacket packet);
|
||||||
|
|
||||||
|
QString partial_packet;
|
||||||
|
bool is_partial;
|
||||||
|
|
||||||
QString hwid;
|
QString hwid;
|
||||||
QString ipid;
|
QString ipid;
|
||||||
};
|
};
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include "include/aoclient.h"
|
#include "include/aoclient.h"
|
||||||
#include "include/aopacket.h"
|
#include "include/aopacket.h"
|
||||||
#include "include/area_data.h"
|
#include "include/area_data.h"
|
||||||
|
#include "include/ws_proxy.h"
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
@ -14,37 +15,35 @@
|
|||||||
#include <QTcpServer>
|
#include <QTcpServer>
|
||||||
#include <QTcpSocket>
|
#include <QTcpSocket>
|
||||||
|
|
||||||
|
class AOClient;
|
||||||
|
|
||||||
class Server : public QObject {
|
class Server : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Server(int p_port, int p_ws_port, QObject* parent = nullptr);
|
Server(int p_port, int p_ws_port, QObject* parent = nullptr);
|
||||||
void start();
|
void start();
|
||||||
|
AOClient* getClient(QString ipid);
|
||||||
|
void updateCharsTaken(AreaData* area);
|
||||||
|
void broadcast(AOPacket packet);
|
||||||
|
|
||||||
|
int player_count;
|
||||||
|
QStringList characters;
|
||||||
|
QVector<AreaData*> areas;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void clientConnected();
|
void clientConnected();
|
||||||
void clientDisconnected();
|
|
||||||
void clientData();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void handlePacket(AOPacket packet, QTcpSocket* socket);
|
WSProxy* proxy;
|
||||||
QTcpSocket* getClient(QString ipid);
|
|
||||||
void broadcast(AOPacket packet);
|
|
||||||
|
|
||||||
QTcpServer* server;
|
QTcpServer* server;
|
||||||
|
|
||||||
int port;
|
int port;
|
||||||
int ws_port;
|
int ws_port;
|
||||||
|
|
||||||
QMap<QTcpSocket*, AOClient*> clients;
|
QVector<AOClient*> clients;
|
||||||
QString partial_packet;
|
|
||||||
bool is_partial;
|
|
||||||
|
|
||||||
int player_count;
|
|
||||||
QStringList characters;
|
|
||||||
QVector<AreaData*> areas;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SERVER_H
|
#endif // SERVER_H
|
||||||
|
22
include/ws_proxy.h
Normal file
22
include/ws_proxy.h
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#ifndef WS_PROXY_H
|
||||||
|
#define WS_PROXY_H
|
||||||
|
|
||||||
|
#include <QMap>
|
||||||
|
#include <QTcpSocket>
|
||||||
|
#include <QtWebSockets/QtWebSockets>
|
||||||
|
|
||||||
|
class WSProxy : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
WSProxy(QObject* parent);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void wsConnected();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QWebSocketServer* server;
|
||||||
|
QMap<QWebSocket*, QTcpSocket*> tcp_sockets;
|
||||||
|
QMap<QTcpSocket*, QWebSocket*> web_sockets;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // WS_PROXY_H
|
162
src/aoclient.cpp
162
src/aoclient.cpp
@ -1,12 +1,170 @@
|
|||||||
#include "include/aoclient.h"
|
#include "include/aoclient.h"
|
||||||
|
|
||||||
AOClient::AOClient(QHostAddress p_remote_ip)
|
AOClient::AOClient(Server* p_server, QTcpSocket* p_socket, QObject* parent)
|
||||||
|
: QObject(parent)
|
||||||
{
|
{
|
||||||
|
socket = p_socket;
|
||||||
|
server = p_server;
|
||||||
joined = false;
|
joined = false;
|
||||||
password = "";
|
password = "";
|
||||||
current_area = 0;
|
current_area = 0;
|
||||||
current_char = "";
|
current_char = "";
|
||||||
remote_ip = p_remote_ip;
|
remote_ip = p_socket->peerAddress();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AOClient::clientData()
|
||||||
|
{
|
||||||
|
QString data = QString::fromUtf8(socket->readAll());
|
||||||
|
// qDebug() << "From" << client->peerAddress() << ":" << data;
|
||||||
|
|
||||||
|
if (is_partial) {
|
||||||
|
data = partial_packet + data;
|
||||||
|
}
|
||||||
|
if (!data.endsWith("%")) {
|
||||||
|
is_partial = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList all_packets = data.split("%");
|
||||||
|
all_packets.removeLast(); // Remove the entry after the last delimiter
|
||||||
|
|
||||||
|
for (QString single_packet : all_packets) {
|
||||||
|
AOPacket packet(single_packet);
|
||||||
|
handlePacket(packet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AOClient::clientDisconnected()
|
||||||
|
{
|
||||||
|
qDebug() << remote_ip << "disconnected";
|
||||||
|
if (joined)
|
||||||
|
server->player_count--;
|
||||||
|
if (current_char != "")
|
||||||
|
server->areas.value(current_area)->characters_taken[current_char] =
|
||||||
|
false;
|
||||||
|
server->updateCharsTaken(server->areas.value(current_area));
|
||||||
|
}
|
||||||
|
|
||||||
|
void AOClient::handlePacket(AOPacket packet)
|
||||||
|
{
|
||||||
|
// TODO: like everything here should send a signal
|
||||||
|
qDebug() << "Received packet:" << packet.header << ":" << packet.contents;
|
||||||
|
AreaData* area = server->areas.value(current_area);
|
||||||
|
// Lord forgive me
|
||||||
|
if (packet.header == "HI") {
|
||||||
|
setHwid(packet.contents[0]);
|
||||||
|
|
||||||
|
AOPacket response(
|
||||||
|
"ID", {"271828", "akashi", QApplication::applicationVersion()});
|
||||||
|
sendPacket(response);
|
||||||
|
}
|
||||||
|
else if (packet.header == "ID") {
|
||||||
|
QSettings config("config.ini", QSettings::IniFormat);
|
||||||
|
config.beginGroup("Options");
|
||||||
|
QString max_players = config.value("max_players").toString();
|
||||||
|
config.endGroup();
|
||||||
|
|
||||||
|
// Full feature list as of AO 2.8.5
|
||||||
|
// The only ones that are critical to ensuring the server works are
|
||||||
|
// "noencryption" and "fastloading"
|
||||||
|
// TODO: make the rest of these user configurable
|
||||||
|
QStringList feature_list = {
|
||||||
|
"noencryption", "yellowtext", "prezoom",
|
||||||
|
"flipping", "customobjections", "fastloading",
|
||||||
|
"deskmod", "evidence", "cccc_ic_support",
|
||||||
|
"arup", "casing_alserts", "modcall_reason",
|
||||||
|
"looping_sfx", "additive", "effects"};
|
||||||
|
AOPacket response_pn(
|
||||||
|
"PN", {QString::number(server->player_count), max_players});
|
||||||
|
AOPacket response_fl("FL", feature_list);
|
||||||
|
sendPacket(response_pn);
|
||||||
|
sendPacket(response_fl);
|
||||||
|
}
|
||||||
|
else if (packet.header == "askchaa") {
|
||||||
|
// TODO: add user configurable content
|
||||||
|
// For testing purposes, we will just send enough to get things working
|
||||||
|
AOPacket response(
|
||||||
|
"SI", {QString::number(server->characters.length()), "0", "1"});
|
||||||
|
sendPacket(response);
|
||||||
|
}
|
||||||
|
else if (packet.header == "RC") {
|
||||||
|
AOPacket response("SC", server->characters);
|
||||||
|
sendPacket(response);
|
||||||
|
}
|
||||||
|
else if (packet.header == "RM") {
|
||||||
|
AOPacket response("SM", {"~stop.mp3"});
|
||||||
|
sendPacket(response);
|
||||||
|
}
|
||||||
|
else if (packet.header == "RD") {
|
||||||
|
server->player_count++;
|
||||||
|
joined = true;
|
||||||
|
|
||||||
|
server->updateCharsTaken(area);
|
||||||
|
AOPacket response_op("OPPASS", {"DEADBEEF"});
|
||||||
|
AOPacket response_done("DONE", {});
|
||||||
|
sendPacket(response_op);
|
||||||
|
sendPacket(response_done);
|
||||||
|
}
|
||||||
|
else if (packet.header == "PW") {
|
||||||
|
password = packet.contents[0];
|
||||||
|
}
|
||||||
|
else if (packet.header == "CC") {
|
||||||
|
bool argument_ok;
|
||||||
|
int char_id = packet.contents[1].toInt(&argument_ok);
|
||||||
|
if (!argument_ok)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (current_char != "") {
|
||||||
|
area->characters_taken[current_char] = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (char_id >= 0) {
|
||||||
|
QString char_selected = server->characters[char_id];
|
||||||
|
bool taken = area->characters_taken.value(char_selected);
|
||||||
|
if (taken || char_selected == "")
|
||||||
|
return;
|
||||||
|
|
||||||
|
area->characters_taken[char_selected] = true;
|
||||||
|
current_char = char_selected;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
current_char = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
server->updateCharsTaken(server->areas.value(current_area));
|
||||||
|
AOPacket response_pv("PV", {"271828", "CID", packet.contents[1]});
|
||||||
|
sendPacket(response_pv);
|
||||||
|
}
|
||||||
|
else if (packet.header == "MS") {
|
||||||
|
// TODO: validate, validate, validate
|
||||||
|
server->broadcast(packet);
|
||||||
|
}
|
||||||
|
else if (packet.header == "CT") {
|
||||||
|
// TODO: commands
|
||||||
|
// TODO: zalgo strip
|
||||||
|
server->broadcast(packet);
|
||||||
|
}
|
||||||
|
else if (packet.header == "CH") {
|
||||||
|
// Why does this packet exist
|
||||||
|
AOPacket response("CHECK", {});
|
||||||
|
sendPacket(response);
|
||||||
|
}
|
||||||
|
else if (packet.header == "whoami") {
|
||||||
|
AOPacket response(
|
||||||
|
"CT", {"Made with love", "by scatterflower and windrammer"});
|
||||||
|
sendPacket(response);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
qDebug() << "Unimplemented packet:" << packet.header;
|
||||||
|
qDebug() << packet.contents;
|
||||||
|
}
|
||||||
|
socket->flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AOClient::sendPacket(AOPacket packet)
|
||||||
|
{
|
||||||
|
qDebug() << "Sent packet:" << packet.header << ":" << packet.contents;
|
||||||
|
socket->write(packet.toUtf8());
|
||||||
|
socket->flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString AOClient::getHwid() { return hwid; }
|
QString AOClient::getHwid() { return hwid; }
|
||||||
|
206
src/server.cpp
206
src/server.cpp
@ -48,206 +48,52 @@ void Server::start()
|
|||||||
|
|
||||||
void Server::clientConnected()
|
void Server::clientConnected()
|
||||||
{
|
{
|
||||||
QTcpSocket* client = server->nextPendingConnection();
|
QTcpSocket* socket = server->nextPendingConnection();
|
||||||
AOClient* ao_client = new AOClient(client->peerAddress());
|
AOClient* client = new AOClient(this, socket, this);
|
||||||
clients.insert(client, ao_client);
|
clients.append(client);
|
||||||
connect(client, SIGNAL(disconnected()), this, SLOT(clientDisconnected()));
|
connect(socket, &QTcpSocket::disconnected, client,
|
||||||
connect(client, SIGNAL(readyRead()), this, SLOT(clientData()));
|
&AOClient::clientDisconnected);
|
||||||
|
connect(socket, &QTcpSocket::disconnected, this, [=] {
|
||||||
|
qDebug() << "removed client" << client->getIpid();
|
||||||
|
clients.removeAll(client);
|
||||||
|
delete client;
|
||||||
|
});
|
||||||
|
connect(socket, &QTcpSocket::readyRead, client, &AOClient::clientData);
|
||||||
|
|
||||||
AOPacket decryptor(
|
AOPacket decryptor(
|
||||||
"decryptor", {"NOENCRYPT"}); // This is the infamous workaround for
|
"decryptor", {"NOENCRYPT"}); // This is the infamous workaround for
|
||||||
// tsuserver4 It should disable fantacrypt
|
// tsuserver4 It should disable fantacrypt
|
||||||
// completely in any client 2.4.3 or newer
|
// completely in any client 2.4.3 or newer
|
||||||
client->write(decryptor.toUtf8());
|
client->sendPacket(decryptor);
|
||||||
|
|
||||||
qDebug() << client->peerAddress().toString() << "connected";
|
qDebug() << client->remote_ip.toString() << "connected";
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::clientDisconnected()
|
void Server::updateCharsTaken(AreaData* area)
|
||||||
{
|
{
|
||||||
if (QTcpSocket* client = dynamic_cast<QTcpSocket*>(sender())) {
|
QStringList chars_taken;
|
||||||
qDebug() << client->peerAddress() << "disconnected";
|
for (QString cur_char : area->characters_taken.keys()) {
|
||||||
AOClient* ao_client = clients.value(client);
|
chars_taken.append(area->characters_taken.value(cur_char)
|
||||||
if (ao_client->joined)
|
? QStringLiteral("-1")
|
||||||
player_count--;
|
: QStringLiteral("0"));
|
||||||
if(ao_client->current_char != "")
|
|
||||||
areas.value(ao_client->current_area)
|
|
||||||
->characters_taken[ao_client->current_char] = false;
|
|
||||||
|
|
||||||
delete ao_client;
|
|
||||||
clients.remove(client);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void Server::clientData()
|
AOPacket response_cc("CharsCheck", chars_taken);
|
||||||
{
|
broadcast(response_cc);
|
||||||
if (QTcpSocket* client = dynamic_cast<QTcpSocket*>(sender())) {
|
|
||||||
QString data = QString::fromUtf8(client->readAll());
|
|
||||||
// qDebug() << "From" << client->peerAddress() << ":" << data;
|
|
||||||
|
|
||||||
if (is_partial) {
|
|
||||||
data = partial_packet + data;
|
|
||||||
}
|
|
||||||
if (!data.endsWith("%")) {
|
|
||||||
is_partial = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList all_packets = data.split("%");
|
|
||||||
all_packets.removeLast(); // Remove the entry after the last delimiter
|
|
||||||
|
|
||||||
for (QString single_packet : all_packets) {
|
|
||||||
AOPacket packet(single_packet);
|
|
||||||
handlePacket(packet, client);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Server::handlePacket(AOPacket packet, QTcpSocket* socket)
|
|
||||||
{
|
|
||||||
// TODO: like everything here should send a signal
|
|
||||||
qDebug() << "Received packet:" << packet.header << ":" << packet.contents;
|
|
||||||
AOClient* client = clients.value(socket);
|
|
||||||
AreaData* area = areas.value(client->current_area);
|
|
||||||
// Lord forgive me
|
|
||||||
if (packet.header == "HI") {
|
|
||||||
AOClient* client = clients.value(socket);
|
|
||||||
client->setHwid(packet.contents[0]);
|
|
||||||
|
|
||||||
AOPacket response(
|
|
||||||
"ID", {"271828", "akashi", QApplication::applicationVersion()});
|
|
||||||
socket->write(response.toUtf8());
|
|
||||||
}
|
|
||||||
else if (packet.header == "ID") {
|
|
||||||
QSettings config("config.ini", QSettings::IniFormat);
|
|
||||||
config.beginGroup("Options");
|
|
||||||
QString max_players = config.value("max_players").toString();
|
|
||||||
config.endGroup();
|
|
||||||
|
|
||||||
// Full feature list as of AO 2.8.5
|
|
||||||
// The only ones that are critical to ensuring the server works are
|
|
||||||
// "noencryption" and "fastloading"
|
|
||||||
// TODO: make the rest of these user configurable
|
|
||||||
QStringList feature_list = {
|
|
||||||
"noencryption", "yellowtext", "prezoom",
|
|
||||||
"flipping", "customobjections", "fastloading",
|
|
||||||
"deskmod", "evidence", "cccc_ic_support",
|
|
||||||
"arup", "casing_alserts", "modcall_reason",
|
|
||||||
"looping_sfx", "additive", "effects"};
|
|
||||||
AOPacket response_pn("PN",
|
|
||||||
{QString::number(player_count), max_players});
|
|
||||||
AOPacket response_fl("FL", feature_list);
|
|
||||||
socket->write(response_pn.toUtf8());
|
|
||||||
socket->write(response_fl.toUtf8());
|
|
||||||
}
|
|
||||||
else if (packet.header == "askchaa") {
|
|
||||||
// TODO: add user configurable content
|
|
||||||
// For testing purposes, we will just send enough to get things working
|
|
||||||
AOPacket response("SI",
|
|
||||||
{QString::number(characters.length()), "0", "1"});
|
|
||||||
qDebug() << response.toString();
|
|
||||||
socket->write(response.toUtf8());
|
|
||||||
}
|
|
||||||
else if (packet.header == "RC") {
|
|
||||||
AOPacket response("SC", characters);
|
|
||||||
socket->write(response.toUtf8());
|
|
||||||
}
|
|
||||||
else if (packet.header == "RM") {
|
|
||||||
AOPacket response("SM", {"~stop.mp3"});
|
|
||||||
socket->write(response.toUtf8());
|
|
||||||
}
|
|
||||||
else if (packet.header == "RD") {
|
|
||||||
player_count++;
|
|
||||||
client->joined = true;
|
|
||||||
|
|
||||||
QStringList chars_taken;
|
|
||||||
for (QString cur_char : area->characters_taken.keys()) {
|
|
||||||
chars_taken.append(area->characters_taken.value(cur_char)
|
|
||||||
? QStringLiteral("-1")
|
|
||||||
: QStringLiteral("0"));
|
|
||||||
}
|
|
||||||
|
|
||||||
AOPacket response_cc("CharsCheck", chars_taken);
|
|
||||||
AOPacket response_op("OPPASS", {"DEADBEEF"});
|
|
||||||
AOPacket response_done("DONE", {});
|
|
||||||
broadcast(response_cc);
|
|
||||||
socket->write(response_op.toUtf8());
|
|
||||||
socket->write(response_done.toUtf8());
|
|
||||||
}
|
|
||||||
else if (packet.header == "PW") {
|
|
||||||
client->password = packet.contents[0];
|
|
||||||
}
|
|
||||||
else if (packet.header == "CC") {
|
|
||||||
bool argument_ok;
|
|
||||||
int char_id = packet.contents[1].toInt(&argument_ok);
|
|
||||||
if (!argument_ok)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (client->current_char != "") {
|
|
||||||
area->characters_taken[client->current_char] = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(char_id >= 0) {
|
|
||||||
QString char_selected = characters[char_id];
|
|
||||||
bool taken = area->characters_taken.value(char_selected);
|
|
||||||
if (taken || char_selected == "")
|
|
||||||
return;
|
|
||||||
|
|
||||||
area->characters_taken[char_selected] = true;
|
|
||||||
client->current_char = char_selected;
|
|
||||||
} else {
|
|
||||||
client->current_char = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList chars_taken;
|
|
||||||
for (QString cur_char : area->characters_taken.keys()) {
|
|
||||||
chars_taken.append(area->characters_taken.value(cur_char)
|
|
||||||
? QStringLiteral("-1")
|
|
||||||
: QStringLiteral("0"));
|
|
||||||
}
|
|
||||||
|
|
||||||
AOPacket response_cc("CharsCheck", chars_taken);
|
|
||||||
AOPacket response_pv("PV", {"271828", "CID", packet.contents[1]});
|
|
||||||
socket->write(response_pv.toUtf8());
|
|
||||||
broadcast(response_cc);
|
|
||||||
}
|
|
||||||
else if (packet.header == "MS") {
|
|
||||||
// TODO: validate, validate, validate
|
|
||||||
broadcast(packet);
|
|
||||||
}
|
|
||||||
else if (packet.header == "CT") {
|
|
||||||
// TODO: commands
|
|
||||||
// TODO: zalgo strip
|
|
||||||
broadcast(packet);
|
|
||||||
}
|
|
||||||
else if (packet.header == "CH") {
|
|
||||||
// Why does this packet exist
|
|
||||||
AOPacket response("CHECK", {});
|
|
||||||
socket->write(response.toUtf8());
|
|
||||||
}
|
|
||||||
else if (packet.header == "what") {
|
|
||||||
AOPacket response(
|
|
||||||
"CT", {"Made with love", "by scatterflower and windrammer"});
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
qDebug() << "Unimplemented packet:" << packet.header;
|
|
||||||
qDebug() << packet.contents;
|
|
||||||
}
|
|
||||||
socket->flush();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::broadcast(AOPacket packet)
|
void Server::broadcast(AOPacket packet)
|
||||||
{
|
{
|
||||||
// TODO: make this selective to the current area only
|
// TODO: make this selective to the current area only
|
||||||
for (QTcpSocket* client : clients.keys()) {
|
for (AOClient* client : clients) {
|
||||||
client->write(packet.toUtf8());
|
client->sendPacket(packet);
|
||||||
client->flush();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QTcpSocket* Server::getClient(QString ipid)
|
AOClient* Server::getClient(QString ipid)
|
||||||
{
|
{
|
||||||
for (QTcpSocket* client : clients.keys()) {
|
for (AOClient* client : clients) {
|
||||||
if (clients.value(client)->getIpid() == ipid)
|
if (client->getIpid() == ipid)
|
||||||
return client;
|
return client;
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
10
src/ws_proxy.cpp
Normal file
10
src/ws_proxy.cpp
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#include "include/ws_proxy.h"
|
||||||
|
|
||||||
|
WSProxy::WSProxy(QObject* parent) : QObject(parent)
|
||||||
|
{
|
||||||
|
server = new QWebSocketServer(QStringLiteral(""),
|
||||||
|
QWebSocketServer::NonSecureMode, this);
|
||||||
|
connect(server, SIGNAL(newConnection()), this, SLOT(wsConnected()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void WSProxy::wsConnected() {}
|
Loading…
Reference in New Issue
Block a user