File indexing completed on 2024-05-05 05:40:33
0001 /************************************************************************* 0002 * Copyright (C) 2011 by Joseph Boudou * 0003 * Copyright (C) 2015 by Renaud Guezennec * 0004 * * 0005 * https://rolisteam.org/ * 0006 * * 0007 * Rolisteam is free software; you can redistribute it and/or modify * 0008 * it under the terms of the GNU General Public License as published * 0009 * by the Free Software Foundation; either version 2 of the License, * 0010 * or (at your option) any later version. * 0011 * * 0012 * This program is distributed in the hope that it will be useful, * 0013 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0015 * GNU General Public License for more details. * 0016 * * 0017 * You should have received a copy of the GNU General Public License * 0018 * along with this program; if not, write to the * 0019 * Free Software Foundation, Inc., * 0020 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 0021 *************************************************************************/ 0022 #include "network/serverconnection.h" 0023 #include "network/channel.h" 0024 0025 #include "worker/playermessagehelper.h" 0026 #include <QHostAddress> 0027 #include <QThread> 0028 0029 ServerConnection::ServerConnection(QTcpSocket* socket, QObject* parent) 0030 : TreeItem(parent), m_socket(socket), m_isAdmin(false), m_player(new Player) 0031 { 0032 m_remainingData= 0; 0033 m_headerRead= 0; 0034 qRegisterMetaType<ServerConnection::ConnectionEvent>(); 0035 } 0036 ServerConnection::~ServerConnection() 0037 { 0038 if(nullptr != m_stateMachine) 0039 { 0040 delete m_stateMachine; 0041 m_stateMachine= nullptr; 0042 } 0043 } 0044 0045 void ServerConnection::resetStateMachine() 0046 { 0047 if(nullptr == m_socket) 0048 return; 0049 0050 m_stateMachine= new QStateMachine(); 0051 0052 connect(m_stateMachine, &QStateMachine::started, this, &ServerConnection::isReady); 0053 m_incomingConnection= new QState(); 0054 m_controlConnection= new QState(); 0055 m_authentificationServer= new QState(); 0056 m_disconnected= new QState(); 0057 0058 m_connected= new QStateMachine(); 0059 m_inChannel= new QState(); 0060 m_wantToGoToChannel= new QState(); 0061 0062 m_stateMachine->addState(m_incomingConnection); 0063 m_stateMachine->setInitialState(m_incomingConnection); 0064 m_stateMachine->addState(m_controlConnection); 0065 m_stateMachine->addState(m_authentificationServer); 0066 m_stateMachine->addState(m_connected); 0067 m_stateMachine->addState(m_disconnected); 0068 0069 m_connected->addState(m_inChannel); 0070 m_connected->setInitialState(m_inChannel); 0071 m_connected->addState(m_wantToGoToChannel); 0072 0073 m_stateMachine->start(); 0074 0075 connect(m_incomingConnection, &QState::activeChanged, this, [=](bool b) { 0076 qDebug() << "incomming state" << b; 0077 if(b) 0078 { 0079 m_currentState= m_incomingConnection; 0080 } 0081 }); 0082 connect(m_controlConnection, &QState::activeChanged, this, [=](bool b) { 0083 qDebug() << "control state" << b; 0084 if(b) 0085 { 0086 m_currentState= m_controlConnection; 0087 emit checkServerAcceptClient(this); 0088 } 0089 }); 0090 0091 connect(m_authentificationServer, &QState::activeChanged, this, [=](bool b) { 0092 qDebug() << "authentification state" << b; 0093 if(b) 0094 { 0095 m_currentState= m_authentificationServer; 0096 if(m_knownUser) 0097 { 0098 qDebug() << "checkserver password" << m_knownUser; 0099 emit checkServerPassword(this); 0100 } 0101 else 0102 { 0103 qDebug() << "Waiting for data" << m_knownUser; 0104 m_waitingData= true; 0105 } 0106 } 0107 }); 0108 connect(m_wantToGoToChannel, &QState::activeChanged, this, [=](bool b) { 0109 if(b) 0110 { 0111 m_currentState= m_wantToGoToChannel; 0112 } 0113 }); 0114 0115 connect(m_disconnected, &QState::activeChanged, this, [=](bool b) { 0116 if(b) 0117 { 0118 m_currentState= m_disconnected; 0119 m_forwardMessage= false; 0120 if(nullptr != m_socket) 0121 { 0122 m_socket->close(); 0123 } 0124 } 0125 }); 0126 0127 connect(m_connected, &QState::activeChanged, this, [=](bool b) { 0128 if(b) 0129 { 0130 m_forwardMessage= true; 0131 } 0132 }); 0133 0134 m_incomingConnection->addTransition(this, &ServerConnection::checkSuccess, m_controlConnection); 0135 m_incomingConnection->addTransition(this, &ServerConnection::checkFail, m_disconnected); 0136 m_incomingConnection->addTransition(this, &ServerConnection::protocolViolation, m_disconnected); 0137 0138 m_controlConnection->addTransition(this, &ServerConnection::controlSuccess, m_authentificationServer); 0139 m_controlConnection->addTransition(this, &ServerConnection::controlFail, m_disconnected); 0140 m_controlConnection->addTransition(this, &ServerConnection::protocolViolation, m_disconnected); 0141 0142 m_authentificationServer->addTransition(this, &ServerConnection::serverAuthSuccess, m_connected); 0143 m_authentificationServer->addTransition(this, &ServerConnection::serverAuthFail, m_disconnected); 0144 m_authentificationServer->addTransition(this, &ServerConnection::protocolViolation, m_disconnected); 0145 0146 m_connected->addTransition(this, &ServerConnection::socketDisconnection, m_disconnected); 0147 m_connected->addTransition(this, &ServerConnection::protocolViolation, m_disconnected); 0148 0149 m_wantToGoToChannel->addTransition(this, &ServerConnection::channelAuthFail, m_inChannel); 0150 m_wantToGoToChannel->addTransition(this, &ServerConnection::channelAuthSuccess, m_inChannel); 0151 m_inChannel->addTransition(this, &ServerConnection::moveChannel, m_wantToGoToChannel); 0152 0153 emit socketInitiliazed(); 0154 } 0155 0156 void ServerConnection::startReading() 0157 { 0158 m_socket= new QTcpSocket(); 0159 connect(m_socket, &QTcpSocket::disconnected, this, &ServerConnection::socketDisconnection); 0160 connect(m_socket, &QTcpSocket::connected, this, &ServerConnection::receivingData); 0161 connect(m_socket, &QTcpSocket::readyRead, this, &ServerConnection::receivingData); 0162 connect(m_socket, &QTcpSocket::bytesWritten, this, &ServerConnection::receivingData); 0163 connect(m_socket, &QTcpSocket::stateChanged, this, &ServerConnection::receivingData); 0164 connect(m_socket, QOverload<QAbstractSocket::SocketError>::of(&QTcpSocket::errorOccurred), this, 0165 &ServerConnection::connectionError); 0166 0167 m_socket->setSocketDescriptor(getSocketHandleId()); 0168 resetStateMachine(); 0169 } 0170 0171 qintptr ServerConnection::getSocketHandleId() const 0172 { 0173 return m_socketHandleId; 0174 } 0175 0176 void ServerConnection::setSocketHandleId(const qintptr& socketHandleId) 0177 { 0178 m_socketHandleId= socketHandleId; 0179 } 0180 0181 bool ServerConnection::isAdmin() const 0182 { 0183 return m_isAdmin; 0184 } 0185 0186 void ServerConnection::setIsAdmin(bool isAdmin) 0187 { 0188 m_isAdmin= isAdmin; 0189 } 0190 0191 bool ServerConnection::isGM() const 0192 { 0193 if(m_player == nullptr) 0194 return false; 0195 return m_player->isGM(); 0196 } 0197 0198 QString ServerConnection::playerId() const 0199 { 0200 if(nullptr != m_player) 0201 return m_player->uuid(); 0202 0203 return {}; 0204 } 0205 0206 void ServerConnection::setPlayerId(const QString& id) 0207 { 0208 if(m_player) 0209 m_player->setUuid(id); 0210 } 0211 0212 QString ServerConnection::playerName() const 0213 { 0214 if(m_player) 0215 return m_player->name(); 0216 0217 return {}; 0218 } 0219 0220 void ServerConnection::setInfoPlayer(NetworkMessageReader* msg) 0221 { 0222 if(nullptr == msg && nullptr == m_player) 0223 return; 0224 0225 if(PlayerMessageHelper::readPlayer(*msg, m_player.get())) 0226 { 0227 setName(m_player->name()); 0228 setUuid(m_player->uuid()); 0229 m_knownUser= true; 0230 emit playerInfoDefined(); 0231 } 0232 } 0233 0234 void ServerConnection::fill(NetworkMessageWriter* msg) 0235 { 0236 if(nullptr != m_player) 0237 { 0238 // m_player->fill(*msg); 0239 PlayerMessageHelper::writePlayerIntoMessage(*msg, m_player.get()); 0240 } 0241 } 0242 0243 bool ServerConnection::isFullyDefined() 0244 { 0245 if(nullptr != m_player) 0246 { 0247 return m_player->isFullyDefined(); 0248 } 0249 return false; 0250 } 0251 0252 void ServerConnection::closeConnection() 0253 { 0254 if(nullptr != m_socket) 0255 { 0256 m_socket->disconnectFromHost(); 0257 } 0258 // Notify all others that player has left. 0259 emit clientSaysGoodBye(playerId()); 0260 } 0261 0262 void ServerConnection::receivingData() 0263 { 0264 if(m_socket.isNull()) 0265 { 0266 return; 0267 } 0268 quint32 dataRead= 0; 0269 0270 while(!m_socket.isNull() && m_socket->bytesAvailable()) 0271 { 0272 if(!m_receivingData) 0273 { 0274 qint64 readDataSize= 0; 0275 char* tmp= reinterpret_cast<char*>(&m_header); 0276 0277 // To do only if there is enough data 0278 readDataSize= m_socket->read(tmp + m_headerRead, static_cast<qint64>(sizeof(NetworkMessageHeader)) 0279 - static_cast<qint64>(m_headerRead)); 0280 0281 if(readDataSize != static_cast<qint64>(sizeof(NetworkMessageHeader)) 0282 && readDataSize + static_cast<qint64>(m_headerRead) != static_cast<qint64>(sizeof(NetworkMessageHeader))) 0283 { 0284 m_headerRead+= static_cast<quint64>(readDataSize); 0285 continue; 0286 } 0287 else 0288 { 0289 m_headerRead= 0; 0290 } 0291 m_buffer= new char[m_header.dataSize]; 0292 m_remainingData= m_header.dataSize; 0293 emit readDataReceived(m_header.dataSize, m_header.dataSize); 0294 } 0295 // To do only if there is enough data 0296 dataRead 0297 = m_socket->read(&(m_buffer[static_cast<int>(static_cast<quint64>(m_header.dataSize) - m_remainingData)]), 0298 static_cast<qint64>(m_remainingData)); 0299 m_dataReceivedTotal+= dataRead; 0300 0301 if(dataRead < m_remainingData) 0302 { 0303 m_remainingData-= dataRead; 0304 m_receivingData= true; 0305 emit readDataReceived(m_remainingData, m_header.dataSize); 0306 } 0307 else 0308 { 0309 m_headerRead= 0; 0310 dataRead= 0; 0311 m_dataReceivedTotal= 0; 0312 emit readDataReceived(0, 0); 0313 m_receivingData= false; 0314 m_remainingData= 0; 0315 forwardMessage(); 0316 } 0317 } 0318 } 0319 bool ServerConnection::isCurrentState(QState* state) 0320 { 0321 return state == m_currentState; 0322 } 0323 0324 QString ServerConnection::getChannelPassword() const 0325 { 0326 return m_channelPassword; 0327 } 0328 0329 QString ServerConnection::getAdminPassword() const 0330 { 0331 return m_adminPassword; 0332 } 0333 0334 QString ServerConnection::getServerPassword() const 0335 { 0336 return m_serverPassword; 0337 } 0338 void ServerConnection::forwardMessage() 0339 { 0340 qDebug() << "forward message"; 0341 QByteArray array(reinterpret_cast<char*>(&m_header), sizeof(NetworkMessageHeader)); 0342 array.append(m_buffer, static_cast<int>(m_header.dataSize)); 0343 if(isCurrentState(m_disconnected)) 0344 return; 0345 0346 if(m_header.category == NetMsg::AdministrationCategory) 0347 { 0348 qDebug() << "read admin message"; 0349 NetworkMessageReader msg; 0350 msg.setData(array); 0351 readAdministrationMessages(msg); 0352 emit dataReceived(array); 0353 } 0354 else if(!m_forwardMessage) 0355 { 0356 delete[] m_buffer; 0357 emit protocolViolation(); 0358 } 0359 else 0360 { 0361 emit dataReceived(array); 0362 } 0363 } 0364 0365 void ServerConnection::sendMessage(NetworkMessage* msg, bool deleteMsg) 0366 { 0367 if((nullptr != m_socket) && (m_socket->isWritable())) 0368 { 0369 NetworkMessageHeader* data= msg->buffer(); 0370 qint64 dataSend= m_socket->write(reinterpret_cast<char*>(data), data->dataSize + sizeof(NetworkMessageHeader)); 0371 if(-1 == dataSend) 0372 { 0373 if(m_socket->state() != QAbstractSocket::ConnectedState) 0374 { 0375 emit socketDisconnection(); 0376 } 0377 } 0378 } 0379 if(deleteMsg) 0380 { 0381 delete msg; 0382 } 0383 } 0384 void ServerConnection::connectionError(QAbstractSocket::SocketError error) 0385 { 0386 emit socketError(error); 0387 if(nullptr != m_socket) 0388 { 0389 qWarning() << m_socket->errorString() << error; 0390 } 0391 } 0392 0393 void ServerConnection::sendEvent(ServerConnection::ConnectionEvent event) 0394 { 0395 if(nullptr != m_player) 0396 qDebug() << "server connection to " << m_player->name() << "recieve event:" << event; 0397 switch(event) 0398 { 0399 case CheckSuccessEvent: 0400 emit checkSuccess(); 0401 break; 0402 case CheckFailEvent: 0403 emit checkFail(); 0404 break; 0405 case ControlFailEvent: 0406 emit controlFail(); 0407 break; 0408 case ControlSuccessEvent: 0409 emit controlSuccess(); 0410 break; 0411 case ServerAuthDataReceivedEvent: 0412 emit serverAuthDataReceived(); 0413 break; 0414 case ServerAuthFailEvent: 0415 emit serverAuthFail(); 0416 break; 0417 case ServerAuthSuccessEvent: 0418 emit serverAuthSuccess(); 0419 break; 0420 case AdminAuthSuccessEvent: 0421 emit adminAuthSucceed(); 0422 m_isAdmin= true; 0423 break; 0424 case AdminAuthFailEvent: 0425 emit adminAuthFailed(); 0426 m_isAdmin= false; 0427 break; 0428 case ChannelAuthSuccessEvent: 0429 emit channelAuthSuccess(); 0430 break; 0431 case ChannelAuthFailEvent: 0432 emit channelAuthFail(); 0433 break; 0434 case MoveChanEvent: 0435 emit moveChannel(); 0436 break; 0437 case ChannelChanged: 0438 sendOffChannelChanged(); 0439 break; 0440 default: 0441 break; 0442 } 0443 } 0444 void ServerConnection::sendOffChannelChanged() 0445 { 0446 NetworkMessageWriter msg(NetMsg::AdministrationCategory, NetMsg::MovedIntoChannel); 0447 sendMessage(&msg, false); 0448 } 0449 void ServerConnection::readAdministrationMessages(NetworkMessageReader& msg) 0450 { 0451 qDebug() << "read Admin messages " << msg.action(); 0452 switch(msg.action()) 0453 { 0454 case NetMsg::ConnectionInfo: 0455 m_serverPassword= msg.byteArray32(); 0456 setName(msg.string32()); 0457 setUuid(msg.string32()); 0458 0459 qDebug() << name() << uuid() << " << user"; 0460 m_knownUser= true; 0461 if(m_waitingData) 0462 { 0463 emit checkServerPassword(this); 0464 } 0465 m_waitingData= false; 0466 break; 0467 case NetMsg::ChannelPassword: 0468 if(isAdmin()) 0469 { 0470 auto channelId= msg.string8(); 0471 auto passwd= msg.byteArray32(); 0472 emit channelPassword(channelId, passwd); 0473 } 0474 break; 0475 case NetMsg::MoveChannel: 0476 { 0477 m_wantedChannel= msg.string32(); 0478 auto passwd= msg.byteArray32(); 0479 emit checkChannelPassword(this, m_wantedChannel, passwd); 0480 } 0481 break; 0482 case NetMsg::AdminPassword: 0483 m_adminPassword= msg.byteArray32(); 0484 emit checkAdminPassword(this); 0485 break; 0486 case NetMsg::Goodbye: 0487 closeConnection(); 0488 break; 0489 default: 0490 break; 0491 } 0492 } 0493 0494 Channel* ServerConnection::getParentChannel() const 0495 { 0496 return dynamic_cast<Channel*>(getParentItem()); 0497 } 0498 0499 void ServerConnection::setParentChannel(Channel* parent) 0500 { 0501 setParentItem(parent); 0502 } 0503 QTcpSocket* ServerConnection::getSocket() 0504 { 0505 return m_socket; 0506 } 0507 int ServerConnection::indexOf(TreeItem*) 0508 { 0509 return -1; 0510 } 0511 0512 void ServerConnection::readFromJson(QJsonObject& json) 0513 { 0514 setName(json["name"].toString()); 0515 setUuid(json["id"].toString()); 0516 setIsAdmin(json["admin"].toBool()); 0517 auto playerId= json["idPlayer"].toString(); 0518 if(m_player) 0519 m_player->setUuid(playerId); 0520 } 0521 0522 void ServerConnection::writeIntoJson(QJsonObject& json) 0523 { 0524 json["type"]= "client"; 0525 json["name"]= m_name; 0526 json["gm"]= isGM(); 0527 json["admin"]= m_isAdmin; 0528 json["id"]= m_id; 0529 json["idPlayer"]= playerId(); 0530 } 0531 QString ServerConnection::getIpAddress() 0532 { 0533 if(nullptr != m_socket) 0534 { 0535 return m_socket->peerAddress().toString(); 0536 } 0537 return {}; 0538 } 0539 0540 QString ServerConnection::getWantedChannel() 0541 { 0542 return m_wantedChannel; 0543 } 0544 0545 bool ServerConnection::isConnected() const 0546 { 0547 if(!m_socket.isNull()) 0548 return (m_socket->isValid() && (m_socket->state() == QAbstractSocket::ConnectedState)); 0549 else 0550 return false; 0551 }