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 }