153 lines
3.7 KiB
C++
153 lines
3.7 KiB
C++
#include <QTcpServer>
|
|
#include <vector>
|
|
#include <QTcpSocket>
|
|
#include <QJsonArray>
|
|
|
|
#include "items/item.h"
|
|
#include "service.h"
|
|
#include "tcpserver.h"
|
|
|
|
TcpServer::TcpServer(QObject* parent):
|
|
Service(parent),
|
|
server(this)
|
|
{
|
|
connect(&server, &QTcpServer::newConnection, this, &TcpServer::incomingConnection);
|
|
}
|
|
|
|
void TcpServer::sendJson(const QJsonObject& json)
|
|
{
|
|
for(auto client: clients)
|
|
{
|
|
QByteArray jsonData = QJsonDocument(json).toJson();
|
|
client.socket->write(QString("MSG JSON LEN " + QString::number(jsonData.size()) + "\n").toLatin1() + jsonData);
|
|
}
|
|
}
|
|
|
|
void TcpServer::processIncomeingJson(const QByteArray& jsonbytes)
|
|
{
|
|
QJsonDocument doc = QJsonDocument::fromJson(jsonbytes);
|
|
QJsonObject json = doc.object();
|
|
QString type = json["MessageType"].toString();
|
|
if(type == "ItemUpdate")
|
|
{
|
|
qDebug()<<"Got Items";
|
|
QJsonArray data = json["Data"].toArray();
|
|
bool FullList = json["FullList"].toBool(false);
|
|
std::vector<std::shared_ptr<Item>> items;
|
|
for(QJsonValueRef itemjson : data)
|
|
{
|
|
QJsonObject jsonobject = itemjson.toObject();
|
|
std::shared_ptr<Item> item = Item::loadItem(jsonobject);
|
|
item->setLoaded(FullList);
|
|
if(item)
|
|
items.push_back(item);
|
|
}
|
|
if(FullList && !items.empty())
|
|
{
|
|
requestReplaceItems(items);
|
|
sigRequestSave();
|
|
}
|
|
else if(!items.empty())
|
|
{
|
|
gotItems(items, false);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Service::processIncomeingJson(jsonbytes);
|
|
}
|
|
}
|
|
|
|
bool TcpServer::launch(const QHostAddress &address, quint16 port)
|
|
{
|
|
return server.listen(address, port);
|
|
}
|
|
|
|
void TcpServer::incomingConnection()
|
|
{
|
|
while(server.hasPendingConnections())
|
|
{
|
|
QTcpSocket* client = server.nextPendingConnection();
|
|
qDebug()<<"Got new client from"<<client->peerAddress().toString();
|
|
if(client)
|
|
{
|
|
clients.push_back({client});
|
|
connect(client, &QTcpSocket::errorOccurred, this, &TcpServer::socketError);
|
|
connect(client, &QTcpSocket::disconnected, this, &TcpServer::socketDisconnect);
|
|
connect(client, &QTcpSocket::readyRead, this, &TcpServer::socketReadyRead);
|
|
}
|
|
}
|
|
}
|
|
|
|
void TcpServer::socketError(QAbstractSocket::SocketError socketError)
|
|
{
|
|
(void)socketError;
|
|
for(size_t i = 0; i < clients.size(); i++)
|
|
{
|
|
if(clients[i].socket == TcpServer::sender())
|
|
{
|
|
clients.erase(clients.begin()+i);
|
|
--i;
|
|
}
|
|
}
|
|
}
|
|
void TcpServer::socketDisconnect()
|
|
{
|
|
for(size_t i = 0; i < clients.size(); i++)
|
|
{
|
|
if(clients[i].socket == TcpServer::sender())
|
|
{
|
|
clients.erase(clients.begin()+i);
|
|
--i;
|
|
}
|
|
}
|
|
}
|
|
|
|
void TcpServer::processComand(const QByteArray& command, Client& client)
|
|
{
|
|
if(command.startsWith("MSG JSON LEN "))
|
|
{
|
|
client.state = STATE_RECV_JSON;
|
|
client.recievebytes = command.mid(13).toLongLong();
|
|
qDebug()<<"Got command:"<<QString::fromLatin1(command);
|
|
}
|
|
}
|
|
|
|
void TcpServer::socketReadyRead()
|
|
{
|
|
for(size_t i = 0; i < clients.size(); i++)
|
|
{
|
|
if(clients[i].socket == sender())
|
|
{
|
|
QByteArray newChars = clients[i].socket->readAll();
|
|
clients[i].buffer += newChars;
|
|
|
|
bool remianing = true;
|
|
while(remianing)
|
|
{
|
|
qDebug()<<clients[i].buffer;
|
|
remianing = false;
|
|
while(clients[i].state == STATE_IDLE && clients[i].buffer.contains('\n'))
|
|
{
|
|
size_t newlineIndex = clients[i].buffer.indexOf('\n');
|
|
QByteArray command = clients[i].buffer.left(newlineIndex);
|
|
clients[i].buffer.remove(0, newlineIndex+1);
|
|
processComand(command, clients[i]);
|
|
remianing = true;
|
|
}
|
|
if(clients[i].state == STATE_RECV_JSON)
|
|
{
|
|
if(clients[i].recievebytes <= clients[i].buffer.size())
|
|
{
|
|
QByteArray json = clients[i].buffer.left(clients[i].recievebytes);
|
|
clients[i].buffer.remove(0, clients[i].recievebytes);
|
|
clients[i].recievebytes = 0;
|
|
clients[i].state = STATE_IDLE;
|
|
processIncomeingJson(json);
|
|
remianing = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|