242 lines
5.1 KiB
C++
Raw Normal View History

2019-02-13 13:03:40 +03:00
#include "server.h"
#include "quasarapp.h"
#include <QTcpSocket>
2019-03-05 13:38:20 +03:00
#include <factorynetobjects.h>
2019-02-13 13:03:40 +03:00
namespace ClientProtocol {
bool Server::parsePackage(const Package &pkg, QTcpSocket* sender) {
if (!pkg.isValid()) {
QuasarAppUtils::Params::verboseLog("incomming package is not valid!");
2019-03-10 21:20:51 +03:00
changeKarma(qHash(sender->peerAddress()), CRITICAL_ERROOR);
2019-02-13 13:03:40 +03:00
return false;
}
if (!sender->isValid()) {
QuasarAppUtils::Params::verboseLog("incomming package is not valid!");
2019-03-10 21:20:51 +03:00
changeKarma(qHash(sender->peerAddress()), LOGICK_ERROOR);
2019-02-13 13:03:40 +03:00
return false;
}
switch (pkg.hdr.command) {
2019-03-05 00:48:32 +03:00
case NetworkClasses::Ping: {
2019-02-13 13:03:40 +03:00
2019-03-05 13:38:20 +03:00
if (pkg.hdr.type != Request) {
2019-02-13 13:03:40 +03:00
return false;
}
2019-03-05 13:38:20 +03:00
Package pcg;
2019-02-13 13:03:40 +03:00
2019-04-20 15:22:00 +03:00
QVariantMap map;
if (!(FactoryNetObjects::build(NetworkClasses::Ping, map) && pcg.create(map, Responke))) {
2019-03-05 13:38:20 +03:00
return false;
};
2019-02-13 13:03:40 +03:00
2019-03-05 13:38:20 +03:00
if (!sendPackage(pcg, sender)) {
2019-02-13 13:03:40 +03:00
QuasarAppUtils::Params::verboseLog("!responce not sendet!");
}
break;
}
default: {
QVariantMap data;
pkg.parse(data);
2019-03-14 20:10:25 +03:00
emit incomingReques(data, qHash(sender->peerAddress()));
2019-02-13 13:03:40 +03:00
}
}
return true;
}
2019-03-05 13:38:20 +03:00
bool Server::sendPackage(Package &pkg, QTcpSocket * target) {
if (!pkg.isValid()) {
return false;
}
2019-03-14 20:10:25 +03:00
if (!target || !target->isValid()) {
2019-03-05 13:38:20 +03:00
qCritical() << "destination server not valid!";
return false;
}
if (!target->waitForConnected()) {
qCritical() << "no connected to server! " << target->errorString();
return false;
}
auto bytes = pkg.toBytes();
bool sendet = bytes.size() == target->write(bytes);
return sendet;
}
2019-03-10 21:20:51 +03:00
void Server::ban(quint32 target) {
_connections[target].karma = BANED_KARMA;
}
2019-03-10 21:20:51 +03:00
void Server::unBan(quint32 target) {
_connections[target].karma = RESTORE_KARMA;
}
2019-03-10 21:20:51 +03:00
void Server::registerSocket(QTcpSocket *socket) {
auto address = qHash(socket->peerAddress());
if (!_connections[address].sct) {
_connections[address].karma = DEFAULT_KARMA;
_connections[address].sct = socket;
connect(socket, &QTcpSocket::readyRead, this, &Server::avelableBytes);
}
}
2019-03-10 21:20:51 +03:00
bool Server::changeKarma(quint32 addresss, int diff) {
auto objKarma = _connections.value(addresss).karma;
if (objKarma >= NOT_VALID_CARMA) {
return false;
}
if (objKarma <= BANED_KARMA) {
return false;
}
2019-03-10 21:20:51 +03:00
_connections[addresss].karma += diff;
return true;
}
bool Server::isBaned(const QTcpSocket * adr) const {
2019-03-10 21:20:51 +03:00
return _connections.value(qHash(adr->peerAddress())).karma < 1;
2019-03-10 16:56:42 +03:00
}
void Server::saveKarma() const {
}
bool Server::loadKarma() {
return false;
}
2019-02-13 13:03:40 +03:00
void Server::avelableBytes() {
auto client = dynamic_cast<QTcpSocket*>(sender());
if (!client) {
return;
}
auto array = client->readAll();
if (_downloadPackage.hdr.isValid()) {
_downloadPackage.data.append(array);
} else {
memcpy(&_downloadPackage.hdr,
2019-02-14 14:09:17 +03:00
array.data(), sizeof(Header));
_downloadPackage.data.append(array.mid(sizeof(Header)));
2019-02-13 13:03:40 +03:00
}
if (_downloadPackage.isValid()) {
parsePackage(_downloadPackage, client);
_downloadPackage.reset();
return;
}
}
void Server::handleIncommingConnection() {
while (hasPendingConnections()) {
auto socket = nextPendingConnection();
if (isBaned(socket)) {
socket->abort();
break;
}
registerSocket(socket);
2019-02-13 13:03:40 +03:00
}
}
Server::Server(QObject *ptr) :
QTcpServer (ptr) {
connect(this, &Server::newConnection, this, &Server::handleIncommingConnection);
}
Server::~Server() {
}
bool Server::run(const QString &ip, unsigned short port) {
if (!listen(QHostAddress(ip), port) ) {
QuasarAppUtils::Params::verboseLog("listing fail " + this->errorString());
return false;
}
return true;
}
2019-03-10 16:56:42 +03:00
void Server::stop(bool reset) {
close();
if (reset) {
_connections.clear();
}
}
2019-03-14 20:10:25 +03:00
void Server::badRequest(quint32 address) {
auto client = _connections.value(address);
if (!changeKarma(address, REQUEST_ERROR)) {
return;
}
2019-04-20 15:22:00 +03:00
QVariantMap map;
2019-03-14 20:10:25 +03:00
Package pcg;
2019-04-20 15:22:00 +03:00
if (!(FactoryNetObjects::build(NetworkClasses::BadRequest, map) && pcg.create(map, Request))) {
2019-03-14 20:10:25 +03:00
return;
};
if (!sendPackage(pcg, client.sct)) {
return;
}
}
2019-03-10 16:56:42 +03:00
QString Server::getWorkState() const {
if (isListening()) {
if (hasPendingConnections())
return "Work";
else {
return "overload";
}
}
return "Not running";
}
QString Server::connectionState() const {
return QString("%0 / %1").arg(_connections.size()).arg(maxPendingConnections());
}
2019-03-10 18:16:43 +03:00
QStringList Server::baned() const {
QStringList list = {};
2019-03-10 21:20:51 +03:00
for (auto i : _connections) {
if (i.karma <= 0) {
list.push_back(i.sct->peerAddress().toString());
2019-03-10 16:56:42 +03:00
}
}
2019-03-10 18:16:43 +03:00
return list;
2019-03-10 16:56:42 +03:00
}
2019-03-10 21:20:51 +03:00
Connectioninfo::Connectioninfo(QTcpSocket *tcp, int kar) {
sct = tcp;
karma = kar;
}
Connectioninfo::~Connectioninfo() {
if (sct) {
sct->deleteLater();
}
}
2019-02-13 13:03:40 +03:00
}