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 }