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

0001 /***************************************************************************
0002  *  Copyright (C) 2019 by Renaud Guezennec                               *
0003  *   http://www.rolisteam.org/contact                                      *
0004  *                                                                         *
0005  *   This software is free software; you can redistribute it and/or modify *
0006  *   it under the terms of the GNU General Public License as published by  *
0007  *   the Free Software Foundation; either version 2 of the License, or     *
0008  *   (at your option) any later version.                                   *
0009  *                                                                         *
0010  *   This program is distributed in the hope that it will be useful,       *
0011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
0012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
0013  *   GNU General Public License for more details.                          *
0014  *                                                                         *
0015  *   You should have received a copy of the GNU General Public License     *
0016  *   along with this program; if not, write to the                         *
0017  *   Free Software Foundation, Inc.,                                       *
0018  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
0019  ***************************************************************************/
0020 #include "controller/networkcontroller.h"
0021 
0022 #include <QLoggingCategory>
0023 #include <QMetaObject>
0024 #include <QThread>
0025 #include <chrono>
0026 #include <iostream>
0027 #include <thread>
0028 
0029 #include "controller/gamecontroller.h"
0030 #include "controller/playercontroller.h"
0031 #include "network/clientmanager.h"
0032 #include "network/networkmessage.h"
0033 #include "network/receiveevent.h"
0034 #include "network/rserver.h"
0035 #include "services/ipchecker.h"
0036 #include "utils/countdownobject.h"
0037 #include "worker/iohelper.h"
0038 #include "worker/messagehelper.h"
0039 #include "worker/modelhelper.h"
0040 #include "worker/networkhelper.h"
0041 #include "worker/playermessagehelper.h"
0042 
0043 QLoggingCategory rNetwork("rolisteam.network");
0044 
0045 void readDataAndSetModel(NetworkMessageReader* msg, ChannelModel* model)
0046 {
0047     auto data= msg->byteArray32();
0048     auto jon= IOHelper::textByteArrayToJsonObj(data);
0049     helper::network::fetchChannelModel(model, jon);
0050 }
0051 
0052 NetworkController::NetworkController(QObject* parent)
0053     : AbstractControllerInterface(parent)
0054     , m_clientManager(new ClientManager)
0055     , m_profileModel(new ProfileModel)
0056     , m_channelModel(new ChannelModel)
0057     , m_countDown(new CountDownObject(5, 10))
0058 {
0059     qRegisterMetaType<RServer::ServerState>();
0060     SettingsHelper::readConnectionProfileModel(m_profileModel.get());
0061 
0062     ReceiveEvent::registerNetworkReceiver(NetMsg::AdministrationCategory, this);
0063 
0064     connect(m_clientManager.get(), &ClientManager::connectionStateChanged, this,
0065             [this](ClientManager::ConnectionState state)
0066             {
0067                 qDebug() << "NETWORKCONTROLLER - ConnectionState" << state;
0068                 setConnected(state == ClientManager::AUTHENTIFIED);
0069                 setConnecting(state == ClientManager::CONNECTING);
0070             });
0071 
0072     connect(m_clientManager.get(), &ClientManager::dataReceived, this, &NetworkController::downloadingData);
0073     connect(m_clientManager.get(), &ClientManager::messageReceived, this, &NetworkController::dispatchMessage);
0074     connect(m_clientManager.get(), &ClientManager::connectedToServer, this, &NetworkController::sendOffConnectionInfo);
0075     connect(m_clientManager.get(), &ClientManager::gameMasterStatusChanged, this, &NetworkController::isGMChanged);
0076     connect(m_clientManager.get(), &ClientManager::moveToAnotherChannel, this, &NetworkController::tableChanged);
0077     connect(m_countDown.get(), &CountDownObject::triggered, this, &NetworkController::startServer);
0078 
0079     // connect(m_clientManager.get(), SIGNAL(clearData()), this, SLOT(cleanUpData()));
0080     // connect(m_clientManager.get(), &ClientManager::notifyUser, m_gameController.get(),
0081     // &GameController::addFeatureLog);
0082     // connect(m_clientManager.get(), &ClientManager::stopConnectionTry, this, &MainWindow::stopReconnection);
0083     // connect(m_clientManager.get(), &ClientManager::errorOccur, m_dialog,
0084     // &SelectConnectionProfileDialog::errorOccurs);
0085     /*connect(m_clientManager.get(), SIGNAL(connectionStateChanged(ClientManager::ConnectionState)), this,
0086             SLOT(updateWindowTitle()));*/
0087 
0088     connect(this, &NetworkController::selectedProfileIndexChanged, this, [this]() { emit isGMChanged(isGM()); });
0089     connect(this, &NetworkController::selectedProfileIndexChanged, this, &NetworkController::hostingChanged);
0090     connect(this, &NetworkController::selectedProfileIndexChanged, this, &NetworkController::askForGMChanged);
0091     connect(this, &NetworkController::selectedProfileIndexChanged, this, &NetworkController::hostChanged);
0092     connect(this, &NetworkController::selectedProfileIndexChanged, this, &NetworkController::portChanged);
0093     connect(this, &NetworkController::selectedProfileIndexChanged, this, &NetworkController::serverPasswordChanged);
0094 }
0095 NetworkController::~NetworkController() {}
0096 
0097 void NetworkController::dispatchMessage(QByteArray array)
0098 {
0099     NetworkMessageReader data;
0100     data.setData(array);
0101     if(ReceiveEvent::hasNetworkReceiverFor(data.category()))
0102     {
0103         QList<NetWorkReceiver*> tmpList= ReceiveEvent::getNetWorkReceiverFor(data.category());
0104         for(NetWorkReceiver* tmp : tmpList)
0105         {
0106             tmp->processMessage(&data);
0107         }
0108     }
0109 }
0110 
0111 ProfileModel* NetworkController::profileModel() const
0112 {
0113     return m_profileModel.get();
0114 }
0115 
0116 ChannelModel* NetworkController::channelModel() const
0117 {
0118     return m_channelModel.get();
0119 }
0120 
0121 void NetworkController::startConnection()
0122 {
0123     if(hosting() && currentProfile())
0124     {
0125         currentProfile()->setAddress(QStringLiteral("localhost"));
0126         m_countDown->start();
0127     }
0128     else
0129         startClient();
0130 }
0131 
0132 void NetworkController::setConnected(bool b)
0133 {
0134     if(b == m_connected)
0135         return;
0136     m_connected= b;
0137     emit connectedChanged(m_connected);
0138 }
0139 
0140 void NetworkController::setConnecting(bool b)
0141 {
0142     if(b == m_connecting)
0143         return;
0144     m_connecting= b;
0145     emit connectingChanged(m_connecting);
0146 }
0147 
0148 void NetworkController::setAdminPassword(const QByteArray& array)
0149 {
0150     if(m_admindPw == array)
0151         return;
0152     m_admindPw= array;
0153     emit adminPasswordChanged();
0154 }
0155 
0156 void NetworkController::removeProfile(int pos)
0157 {
0158     m_profileModel->removeProfile(pos);
0159 }
0160 
0161 void NetworkController::startClient()
0162 {
0163     m_clientManager->connectTo(host(), port());
0164 }
0165 
0166 void NetworkController::stopClient()
0167 {
0168     m_clientManager->disconnectAndClose();
0169 }
0170 
0171 void NetworkController::startServer()
0172 {
0173     m_serverParameters= {{"ServerPassword", serverPassword()}, {"AdminPassword", adminPassword()}};
0174 
0175     if(!m_server)
0176     {
0177         m_server.reset(new RServer(m_serverParameters, true));
0178         m_serverThread.reset(new QThread);
0179     }
0180     m_server->moveToThread(thread());
0181     m_server->setPort(port());
0182 
0183     connect(m_serverThread.get(), &QThread::started, m_server.get(), &RServer::listen);
0184     connect(m_serverThread.get(), &QThread::finished, this,
0185             [this]() { emit infoMessage("server thread has been closed"); });
0186 
0187     connect(m_server.get(), &RServer::finished, this, [this]() { emit infoMessage("server has been closed"); });
0188 
0189     connect(m_server.get(), &RServer::stateChanged, this,
0190             [this]()
0191             {
0192                 switch(m_server->state())
0193                 {
0194                 case RServer::Stopped:
0195                     m_serverThread->quit();
0196                     break;
0197                 case RServer::Listening:
0198                     m_countDown->stop();
0199                     emit infoMessage("server is on");
0200                     startClient();
0201                     break;
0202                 case RServer::Error:
0203                     closeServer();
0204                     break;
0205                 }
0206             });
0207 
0208     m_ipChecker.reset(new IpChecker());
0209     connect(m_ipChecker.get(), &IpChecker::ipAddressChanged, this,
0210             [this](const QString& ip)
0211             {
0212                 m_ipv4Address= ip;
0213                 emit ipv4Changed();
0214             });
0215     m_ipChecker->startCheck();
0216 
0217     m_server->moveToThread(m_serverThread.get());
0218     m_serverThread->start();
0219 }
0220 
0221 void NetworkController::stopConnecting()
0222 {
0223     if(!m_connecting)
0224         return;
0225 
0226     stopConnection();
0227 }
0228 
0229 void NetworkController::stopConnection()
0230 {
0231     if(!m_connected && !m_connecting)
0232         return;
0233 
0234     stopClient();
0235     if(hosting())
0236     {
0237         closeServer();
0238     }
0239 }
0240 
0241 NetWorkReceiver::SendType NetworkController::processMessage(NetworkMessageReader* msg)
0242 {
0243     NetWorkReceiver::SendType type= NetWorkReceiver::NONE;
0244     switch(msg->action())
0245     {
0246     case NetMsg::EndConnectionAction:
0247         break;
0248     case NetMsg::SetChannelList:
0249         readDataAndSetModel(msg, m_channelModel.get());
0250         break;
0251     case NetMsg::AdminAuthSucessed:
0252         break;
0253     case NetMsg::AuthentificationFail:
0254         qDebug() << "Authentification fail";
0255         m_clientManager->setAuthentificationStatus(false);
0256         break;
0257     case NetMsg::AuthentificationSucessed:
0258         qDebug() << "Authentification sucessed";
0259         m_clientManager->setAuthentificationStatus(true);
0260         break;
0261     default:
0262         break;
0263     }
0264 
0265     return type;
0266 }
0267 
0268 bool NetworkController::hosting() const
0269 {
0270     return currentProfile() ? currentProfile()->isServer() : false;
0271 }
0272 
0273 bool NetworkController::askForGM() const
0274 {
0275     return currentProfile() ? currentProfile()->isGM() : false;
0276 }
0277 
0278 QString NetworkController::host() const
0279 {
0280     return currentProfile() ? currentProfile()->address() : QString();
0281 }
0282 
0283 int NetworkController::port() const
0284 {
0285     return currentProfile() ? currentProfile()->port() : 6660;
0286 }
0287 
0288 QString NetworkController::ipv4() const
0289 {
0290     return m_ipv4Address;
0291 }
0292 
0293 QString NetworkController::lastError() const
0294 {
0295     return m_lastError;
0296 }
0297 
0298 bool NetworkController::isGM() const
0299 {
0300     return currentProfile() ? currentProfile()->isGM() : false;
0301 }
0302 
0303 bool NetworkController::connected() const
0304 {
0305     return m_connected;
0306 }
0307 
0308 bool NetworkController::connecting() const
0309 {
0310     return m_connecting;
0311 }
0312 
0313 QByteArray NetworkController::serverPassword() const
0314 {
0315     return currentProfile() ? currentProfile()->password() : QByteArray();
0316 }
0317 
0318 QByteArray NetworkController::adminPassword() const
0319 {
0320     return m_admindPw;
0321 }
0322 
0323 void NetworkController::setGameController(GameController* game)
0324 {
0325     m_gameCtrl= game;
0326 }
0327 
0328 void NetworkController::sendOffConnectionInfo()
0329 {
0330     if(m_gameCtrl.isNull())
0331         return;
0332 
0333     auto playerCtrl= m_gameCtrl->playerController();
0334     if(nullptr == playerCtrl)
0335         return;
0336     PlayerMessageHelper::sendOffConnectionInfo(playerCtrl->localPlayer(), serverPassword());
0337 }
0338 
0339 void NetworkController::setLastError(const QString& error)
0340 {
0341     if(error == m_lastError)
0342         return;
0343     m_lastError= error;
0344     emit lastErrorChanged(m_lastError);
0345 }
0346 void NetworkController::closeServer()
0347 {
0348     if(!m_server)
0349         return;
0350 
0351     QMetaObject::invokeMethod(m_server.get(), &RServer::close, Qt::QueuedConnection);
0352 }
0353 
0354 void NetworkController::saveData()
0355 {
0356     SettingsHelper::writeConnectionProfileModel(m_profileModel.get());
0357 }
0358 
0359 int NetworkController::selectedProfileIndex() const
0360 {
0361     return m_selectedProfileIndex;
0362 }
0363 
0364 void NetworkController::setSelectedProfileIndex(int newSelectedProfileIndex)
0365 {
0366     if(m_selectedProfileIndex == newSelectedProfileIndex)
0367         return;
0368     m_selectedProfileIndex= newSelectedProfileIndex;
0369     emit selectedProfileIndexChanged();
0370 }
0371 
0372 ConnectionProfile* NetworkController::currentProfile() const
0373 {
0374     return m_profileModel->getProfile(m_selectedProfileIndex);
0375 }