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 }