File indexing completed on 2024-05-05 05:40:34

0001 #include <network/serverconnectionmanager.h>
0002 
0003 #include <QJsonDocument>
0004 #include <QJsonObject>
0005 #include <QTimer>
0006 
0007 #include "network/ipbanaccepter.h"
0008 #include "network/iprangeaccepter.h"
0009 #include "network/messagedispatcher.h"
0010 #include "network/networkmessagewriter.h"
0011 #include "network/passwordaccepter.h"
0012 #include "network/serverconnection.h"
0013 #include "qhostaddress.h"
0014 
0015 #include <QReadLocker>
0016 #include <QWriteLocker>
0017 
0018 void sendEventToClient(ServerConnection* client, ServerConnection::ConnectionEvent event)
0019 {
0020     QMetaObject::invokeMethod(client, "sendEvent", Qt::QueuedConnection,
0021                               Q_ARG(ServerConnection::ConnectionEvent, event));
0022 }
0023 
0024 ServerConnectionManager::ServerConnectionManager(const QMap<QString, QVariant>& parameters, QObject* parent)
0025     : QObject(parent), m_model(new ChannelModel), m_parameters(parameters)
0026 {
0027     int chCount= parameters.value("ChannelCount", 1).toInt();
0028     int count= m_model->rowCount(QModelIndex());
0029     for(int i= count; i < chCount; ++i)
0030     {
0031         m_model->addChannel(QStringLiteral("Channel %1").arg(i), {});
0032     }
0033 
0034     qRegisterMetaType<NetworkMessage*>("NetworkMessage*");
0035 
0036     connect(m_model.get(), &ChannelModel::totalSizeChanged, this, &ServerConnectionManager::memoryChannelChanged);
0037 
0038     m_msgDispatcher= new MessageDispatcher(this);
0039     connect(this, &ServerConnectionManager::messageMustBeDispatched, m_msgDispatcher,
0040             &MessageDispatcher::dispatchMessage, Qt::QueuedConnection);
0041 
0042     connect(m_msgDispatcher, &MessageDispatcher::messageForAdmin, this, &ServerConnectionManager::processMessageAdmin);
0043 
0044     m_corEndProcess.reset(new PasswordAccepter());
0045     m_tcpConnectionAccepter.reset(new IpBanAccepter());
0046     m_tcpConnectionAccepter->setNext(new IpRangeAccepter());
0047     m_adminAccepter.reset(new PasswordAccepter(PasswordAccepter::Admin));
0048 }
0049 
0050 ServerConnectionManager::~ServerConnectionManager()
0051 {
0052     // stopListening();
0053 }
0054 
0055 int ServerConnectionManager::countConnection() const
0056 {
0057     QReadLocker locker(&m_lock);
0058     return m_connections.count();
0059 }
0060 
0061 /*bool ServerConnectionManager::startListening()
0062 {
0063     qDebug() << "Start listening:";
0064     if(!m_server)
0065     {
0066         m_server.reset(new RServer(getValue(QStringLiteral("ThreadCount")).toInt()));
0067         connect(m_server.get(), &RServer::accepting, this, &ServerManager::accept, Qt::QueuedConnection);
0068         connect(m_server.get(), &RServer::finished, this, [this]() { setState(Stopped); });
0069     }
0070 
0071     if(m_server->listen(QHostAddress::Any, static_cast<quint16>(getValue(QStringLiteral("port")).toInt())))
0072     {
0073         setState(Listening);
0074         emit eventOccured(tr("Rolisteam Server is on!"), LogController::Info);
0075     }
0076     else
0077     {
0078         setState(Error);
0079         emit eventOccured(m_server->errorString(), LogController::Error);
0080         /*if(m_tryCount < getValue(QStringLiteral("TryCount")).toInt()
0081            || getValue(QStringLiteral("TryCount")).toInt() == 0)
0082         {
0083             emit eventOccured(tr("Retry start server in %1s!").arg(getValue(QStringLiteral("TimeToRetry")).toInt()),
0084                               LogController::Info);
0085             QTimer::singleShot(getValue(QStringLiteral("TimeToRetry")).toInt(), this, SLOT(startListening()));
0086         }
0087         else
0088         {
0089             emit eventOccured(tr("Retry count reached. Server stops trying."), LogController::Info);
0090             setState(Stopped); // on error
0091         }
0092     }
0093     return state() == Listening;
0094 }*/
0095 
0096 void ServerConnectionManager::messageReceived(QByteArray array)
0097 {
0098     ServerConnection* client= qobject_cast<ServerConnection*>(sender());
0099     if(nullptr == client)
0100         return;
0101 
0102     emit messageMustBeDispatched(array, client->getParentChannel(), client);
0103 }
0104 
0105 void ServerConnectionManager::initClient()
0106 {
0107     ServerConnection* client= qobject_cast<ServerConnection*>(sender());
0108     if(nullptr != client)
0109     {
0110         qDebug() << "client insert" << client << client->name();
0111         m_connections.insert(client->getSocket(), client);
0112         sendEventToClient(client, ServerConnection::CheckSuccessEvent);
0113     }
0114     else
0115     {
0116         sendEventToClient(client, ServerConnection::CheckFailEvent);
0117     }
0118 }
0119 
0120 /////////////////////////////////////////////////////////
0121 ///
0122 /// Slot to perform check during connection process.
0123 ///
0124 ////////////////////////////////////////////////////////
0125 void ServerConnectionManager::serverAcceptClient(ServerConnection* client)
0126 {
0127 
0128     if(nullptr == client)
0129     {
0130         qDebug() << "client is null";
0131         return;
0132     }
0133 
0134     QMap<QString, QVariant> data(m_parameters);
0135     data["currentIp"]= client->getIpAddress();
0136     if(m_tcpConnectionAccepter->runAccepter(data))
0137     {
0138         sendEventToClient(client, ServerConnection::ControlSuccessEvent);
0139     }
0140     else
0141     {
0142         sendEventToClient(client, ServerConnection::ControlFailEvent);
0143     }
0144 }
0145 void ServerConnectionManager::checkAuthToServer(ServerConnection* client)
0146 {
0147     qDebug() << "check auth to server";
0148     if(nullptr == client)
0149         return;
0150     qDebug() << "cilent is fully defined" << client->isFullyDefined();
0151 
0152     QMap<QString, QVariant> data(m_parameters);
0153     data["currentIp"]= client->getIpAddress();
0154     data["userpassword"]= client->getServerPassword();
0155 
0156     if(m_corEndProcess->runAccepter(data))
0157     {
0158         m_model->addConnectionToDefaultChannel(client);
0159         sendEventToClient(client, ServerConnection::ServerAuthSuccessEvent);
0160         // sendOffModel(client);
0161         qDebug() << "server auth successed";
0162     }
0163     else
0164     {
0165         sendEventToClient(client, ServerConnection::ServerAuthFailEvent);
0166         qDebug() << "server auth failed";
0167     }
0168 }
0169 void ServerConnectionManager::checkAuthAsAdmin(ServerConnection* client)
0170 {
0171     QMap<QString, QVariant> data(m_parameters);
0172     data["userpassword"]= client->getAdminPassword();
0173     if(m_adminAccepter->runAccepter(data))
0174     {
0175         sendEventToClient(client, ServerConnection::AdminAuthSuccessEvent);
0176     }
0177     else
0178     {
0179         sendEventToClient(client, ServerConnection::AdminAuthFailEvent);
0180     }
0181 }
0182 
0183 void ServerConnectionManager::memoryChannelChanged(quint64 size)
0184 {
0185     if(size > m_parameters["memorySize"].toULongLong())
0186     {
0187         m_model->emptyChannelMemory();
0188     }
0189 }
0190 void ServerConnectionManager::checkAuthToChannel(ServerConnection* client, QString channelId, QByteArray password)
0191 {
0192     QMap<QString, QVariant> data(m_parameters);
0193     auto item= m_model->getItemById(channelId);
0194     auto channel= dynamic_cast<Channel*>(item);
0195 
0196     auto eventToSend= ServerConnection::ChannelAuthSuccessEvent;
0197 
0198     if(nullptr == channel)
0199     {
0200         eventToSend= ServerConnection::ChannelAuthFailEvent;
0201         sendEventToClient(client, eventToSend);
0202         return;
0203     }
0204 
0205     if(channel->password() != password)
0206         eventToSend= ServerConnection::ChannelAuthFailEvent;
0207 
0208     if((m_corEndProcess->runAccepter(data)) && (eventToSend != ServerConnection::ChannelAuthFailEvent))
0209     {
0210         if(!m_model->addConnectionToChannel(channelId, client))
0211         {
0212             m_model->addConnectionToDefaultChannel(client);
0213         }
0214     }
0215     else
0216     {
0217         eventToSend= ServerConnection::ChannelAuthFailEvent;
0218     }
0219     sendEventToClient(client, eventToSend);
0220 }
0221 /////////////////////////////////////////////////////////
0222 ///
0223 /// Slot to perform check during connection process.
0224 ///
0225 ////////////////////////////////////////////////////////
0226 void ServerConnectionManager::sendOffAdminAuthSuccessed()
0227 {
0228     ServerConnection* client= qobject_cast<ServerConnection*>(sender());
0229     if(nullptr != client)
0230     {
0231         NetworkMessageWriter* msg= new NetworkMessageWriter(NetMsg::AdministrationCategory, NetMsg::AdminAuthSucessed);
0232         QMetaObject::invokeMethod(client, "sendMessage", Qt::QueuedConnection,
0233                                   Q_ARG(NetworkMessage*, static_cast<NetworkMessage*>(msg)), Q_ARG(bool, true));
0234         // sendOffModel(client);
0235     }
0236 }
0237 void ServerConnectionManager::sendOffAdminAuthFail()
0238 {
0239     ServerConnection* client= qobject_cast<ServerConnection*>(sender());
0240     if(nullptr != client)
0241     {
0242         NetworkMessageWriter* msg= new NetworkMessageWriter(NetMsg::AdministrationCategory, NetMsg::AdminAuthFail);
0243         QMetaObject::invokeMethod(client, "sendMessage", Qt::QueuedConnection,
0244                                   Q_ARG(NetworkMessage*, static_cast<NetworkMessage*>(msg)), Q_ARG(bool, true));
0245     }
0246     emit eventOccured(
0247         tr("Authentification as Admin fails: %2 - %1, Wrong password.").arg(client->name(), client->getIpAddress()),
0248         LogController::Info);
0249 }
0250 void ServerConnectionManager::sendOffAuthSuccessed()
0251 {
0252     ServerConnection* client= qobject_cast<ServerConnection*>(sender());
0253     if(nullptr != client)
0254     {
0255         NetworkMessageWriter* msg
0256             = new NetworkMessageWriter(NetMsg::AdministrationCategory, NetMsg::AuthentificationSucessed);
0257         QMetaObject::invokeMethod(client, "sendMessage", Qt::QueuedConnection,
0258                                   Q_ARG(NetworkMessage*, static_cast<NetworkMessage*>(msg)), Q_ARG(bool, true));
0259         // sendOffModel(client);
0260     }
0261 }
0262 void ServerConnectionManager::sendOffAuthFail()
0263 {
0264     ServerConnection* client= qobject_cast<ServerConnection*>(sender());
0265     if(nullptr != client)
0266     {
0267         NetworkMessageWriter* msg
0268             = new NetworkMessageWriter(NetMsg::AdministrationCategory, NetMsg::AuthentificationFail);
0269         QMetaObject::invokeMethod(client, "sendMessage", Qt::QueuedConnection,
0270                                   Q_ARG(NetworkMessage*, static_cast<NetworkMessage*>(msg)), Q_ARG(bool, true));
0271     }
0272     emit eventOccured(
0273         tr("Authentification fails: %1 try to connect to the server with wrong password.").arg(client->getIpAddress()),
0274         LogController::Info);
0275 }
0276 void ServerConnectionManager::kickClient(QString id, bool isAdmin, QString senderId)
0277 {
0278     m_model->kick(id, isAdmin, senderId);
0279     // sendOffModelToAll();
0280 
0281     ServerConnection* client= nullptr;
0282     auto keys= m_connections.keys();
0283     for(auto& key : keys)
0284     {
0285         auto value= m_connections[key];
0286         if(value->uuid() == id)
0287         {
0288             client= value;
0289         }
0290     }
0291     emit eventOccured(tr("User has been kick out: %2 - %1.").arg(client->name(), client->getIpAddress()),
0292                       LogController::Info);
0293 
0294     if(nullptr != client)
0295     {
0296         // removeClient(client);
0297     }
0298 }
0299 
0300 void ServerConnectionManager::banClient(QString id, bool isAdmin, QString senderId)
0301 {
0302     // TODO implement this function
0303     Q_UNUSED(id)
0304     Q_UNUSED(isAdmin)
0305     Q_UNUSED(senderId)
0306 }
0307 
0308 void ServerConnectionManager::processMessageAdmin(NetworkMessageReader* msg, Channel* chan, ServerConnection* tcp)
0309 {
0310     if(tcp == nullptr)
0311         return;
0312 
0313     bool isAdmin= tcp->isAdmin();
0314     bool isGM= tcp->isGM();
0315     auto sourceId= tcp->playerId();
0316     switch(msg->action())
0317     {
0318     case NetMsg::Kicked:
0319     {
0320         QString id= msg->string8();
0321         kickClient(id, isAdmin, sourceId);
0322     }
0323     break;
0324     case NetMsg::BanUser:
0325     {
0326         QString id= msg->string8();
0327         banClient(id, isAdmin, sourceId);
0328     }
0329     break;
0330     case NetMsg::RenameChannel:
0331     {
0332         if(isAdmin)
0333         {
0334             QString idChan= msg->string8();
0335             QString newName= msg->string32();
0336             m_model->renameChannel(sourceId, idChan, newName);
0337         }
0338     }
0339     break;
0340     case NetMsg::AddChannel:
0341     {
0342         if(isAdmin)
0343         {
0344             QString idparent= msg->string8();
0345             TreeItem* parentItem= m_model->getItemById(idparent);
0346             Channel* dest= static_cast<Channel*>(parentItem);
0347 
0348             auto channel= new Channel();
0349             // channel->read(*msg);
0350             m_model->addChannelToChannel(channel, dest);
0351         }
0352     }
0353     break;
0354     case NetMsg::JoinChannel:
0355     {
0356         QString id= msg->string8();
0357         QString idClient= msg->string8();
0358         TreeItem* item= m_model->getItemById(id);
0359         Channel* dest= static_cast<Channel*>(item);
0360         if(nullptr != dest && !dest->locked())
0361         {
0362             m_model->moveClient(chan, idClient, dest);
0363             sendEventToClient(tcp, ServerConnection::ChannelChanged);
0364         }
0365     }
0366     break;
0367     case NetMsg::SetChannelList:
0368     {
0369         qDebug() << "Server received channellist";
0370         /*if(isAdmin)
0371         {
0372             QByteArray data= msg->byteArray32();
0373             QJsonDocument doc= QJsonDocument::fromJson(data);
0374             if(!doc.isEmpty())
0375             {
0376                 QJsonObject obj= doc.object();
0377                // m_model->readDataJson(obj);
0378             }
0379         }*/
0380     }
0381     break;
0382     case NetMsg::DeleteChannel:
0383     {
0384         if(isAdmin)
0385         {
0386             QString id= msg->string8();
0387             m_model->removeChild(id);
0388             // sendOffModelToAll();
0389         }
0390     }
0391     break;
0392     case NetMsg::MoveChannel:
0393     case NetMsg::AdminPassword:
0394         break;
0395     case NetMsg::ResetChannel:
0396     {
0397         if(isGM)
0398         {
0399             if(nullptr != chan)
0400                 chan->clearData();
0401         }
0402         else if(isAdmin)
0403         {
0404             QString id= msg->string8();
0405             auto item= m_model->getItemById(id);
0406             if(!item->isLeaf())
0407             {
0408                 auto channel= dynamic_cast<Channel*>(item);
0409                 if(channel)
0410                     channel->clearData();
0411             }
0412         }
0413     }
0414     break;
0415     case NetMsg::LockChannel:
0416     case NetMsg::UnlockChannel:
0417         if(isGM)
0418         {
0419             if(nullptr != chan)
0420                 chan->setLocked(msg->action() == NetMsg::LockChannel ? true : false);
0421         }
0422         break;
0423     default:
0424         break;
0425     }
0426 }
0427 
0428 /*void ServerManager::sendOffModel(ServerConnection* client)
0429 {
0430     if(nullptr == client)
0431         return;
0432 
0433     qDebug() << "ServerManager Send off channel model" << sender();
0434     static QMap<ServerConnection*, QByteArray> model;
0435     QJsonDocument doc;
0436     QJsonObject obj;
0437     m_model->writeDataJson(obj);
0438     doc.setObject(obj);
0439 
0440     auto b= doc.toJson();
0441 
0442     if(b != model[client])
0443     {
0444         model[client]= b;
0445 
0446         NetworkMessageWriter* msg= new NetworkMessageWriter(NetMsg::AdministrationCategory, NetMsg::SetChannelList);
0447         msg->byteArray32(doc.toJson());
0448         QMetaObject::invokeMethod(client, "sendMessage", Qt::QueuedConnection,
0449                                   Q_ARG(NetworkMessage*, static_cast<NetworkMessage*>(msg)), Q_ARG(bool, true));
0450     }
0451 }*/
0452 
0453 ChannelModel* ServerConnectionManager::channelModel() const
0454 {
0455     return m_model.get();
0456 }
0457 
0458 const QHash<QTcpSocket*, ServerConnection*> ServerConnectionManager::connections() const
0459 {
0460     return m_connections;
0461 }
0462 
0463 void ServerConnectionManager::quit()
0464 {
0465     if(!sender())
0466         return;
0467 
0468     auto sockets= m_connections.keys();
0469     std::for_each(sockets.begin(), sockets.end(), [this](QTcpSocket* socket) { removeSocket(socket); });
0470 
0471     m_connections.clear();
0472 
0473     emit finished();
0474 }
0475 
0476 void ServerConnectionManager::accept(qintptr handle, ServerConnection* connection)
0477 {
0478     if(nullptr == connection)
0479         return;
0480 
0481     emit eventOccured(tr("New Incoming Connection!"), LogController::Info);
0482 
0483     connect(connection, &ServerConnection::dataReceived, this, &ServerConnectionManager::messageReceived,
0484             Qt::QueuedConnection); //
0485     connect(connection, &ServerConnection::socketInitiliazed, this, &ServerConnectionManager::initClient,
0486             Qt::QueuedConnection);
0487 
0488     connect(connection, &ServerConnection::serverAuthFail, this, &ServerConnectionManager::sendOffAuthFail,
0489             Qt::QueuedConnection);
0490     connect(connection, &ServerConnection::serverAuthSuccess, this, &ServerConnectionManager::sendOffAuthSuccessed,
0491             Qt::QueuedConnection);
0492 
0493     connect(connection, &ServerConnection::adminAuthFailed, this, &ServerConnectionManager::sendOffAdminAuthFail,
0494             Qt::QueuedConnection);
0495     connect(connection, &ServerConnection::adminAuthSucceed, this, &ServerConnectionManager::sendOffAdminAuthSuccessed,
0496             Qt::QueuedConnection);
0497 
0498     connect(
0499         connection, &ServerConnection::itemChanged, this,
0500         [this]() {
0501             qDebug() << "connection ItemChanged";
0502             // sendOffModelToAll();
0503         },
0504         Qt::QueuedConnection);
0505 
0506     connect(connection, &ServerConnection::checkServerAcceptClient, this, &ServerConnectionManager::serverAcceptClient,
0507             Qt::QueuedConnection);
0508     connect(connection, &ServerConnection::checkServerPassword, this, &ServerConnectionManager::checkAuthToServer,
0509             Qt::QueuedConnection);
0510     connect(connection, &ServerConnection::checkAdminPassword, this, &ServerConnectionManager::checkAuthAsAdmin,
0511             Qt::QueuedConnection);
0512     connect(connection, &ServerConnection::checkChannelPassword, this, &ServerConnectionManager::checkAuthToChannel,
0513             Qt::QueuedConnection);
0514     connect(connection, &ServerConnection::channelPassword, this, &ServerConnectionManager::setChannelPassword,
0515             Qt::QueuedConnection);
0516 
0517     connect(connection, &ServerConnection::socketDisconnection, this, &ServerConnectionManager::disconnectedUser,
0518             Qt::QueuedConnection);
0519     connect(connection, &ServerConnection::socketError, this, &ServerConnectionManager::error, Qt::QueuedConnection);
0520     connection->setSocketHandleId(handle);
0521 
0522     // emit clientAccepted();
0523     QMetaObject::invokeMethod(connection, &ServerConnection::startReading, Qt::QueuedConnection);
0524 }
0525 
0526 void ServerConnectionManager::disconnectedUser()
0527 {
0528     if(!sender())
0529         return;
0530 
0531     ServerConnection* client= qobject_cast<ServerConnection*>(sender());
0532     if(!client)
0533         return;
0534 
0535     emit eventOccured(tr("User %1 has been disconnected!").arg(client->playerName()), LogController::Info);
0536     // removeClient(client);
0537 }
0538 
0539 void ServerConnectionManager::removeSocket(QTcpSocket* socket)
0540 {
0541     if(!socket)
0542         return;
0543     if(!m_connections.contains(socket))
0544         return;
0545 
0546     qDebug() << this << "removing socket = " << socket;
0547 
0548     if(socket->isOpen())
0549     {
0550         qDebug() << this << "socket is open, attempting to close it " << socket;
0551         QMetaObject::invokeMethod(socket, &QTcpSocket::close);
0552     }
0553 
0554     qDebug() << this << "deleting socket" << socket;
0555     auto client= m_connections.value(socket);
0556     m_connections.remove(socket);
0557 
0558     QMetaObject::invokeMethod(socket, &QTcpSocket::deleteLater);
0559     client->deleteLater();
0560 
0561     qDebug() << this << "client count = " << m_connections.count();
0562 }
0563 void ServerConnectionManager::setChannelPassword(QString chanId, QByteArray passwd)
0564 {
0565     auto item= m_model->getItemById(chanId);
0566     if(nullptr == item)
0567         return;
0568 
0569     auto channel= dynamic_cast<Channel*>(item);
0570     if(nullptr == channel)
0571         return;
0572 
0573     channel->setPassword(passwd);
0574     // sendOffModelToAll();
0575 }
0576 
0577 void ServerConnectionManager::error(QAbstractSocket::SocketError socketError)
0578 {
0579     if(QAbstractSocket::RemoteHostClosedError == socketError)
0580         return;
0581     if(!sender())
0582         return;
0583 
0584     ServerConnection* client= qobject_cast<ServerConnection*>(sender());
0585     if(!client)
0586         return;
0587 
0588     auto socket= client->getSocket();
0589 
0590     if(!socket)
0591         return;
0592 
0593     emit eventOccured(socket->errorString(), LogController::Error);
0594 }