H-a-y-K

Untitled

Mar 15th, 2020
214
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include "hichess_server.h"
  2.  
  3. #define UDP_SERVER_PORT 45454
  4. #define UDP_CLIENT_PORT 45455
  5. #define WEB_PORT 54545
  6.  
  7.  
  8. Player::Player(const QString& name, QWebSocket *wsocket)
  9.     : m_wsocket(wsocket)
  10.     , m_name(name)
  11. {}
  12.  
  13. bool Player::operator==(const Player &other) const
  14. {
  15.     return QString::compare(m_name, other.getName(), Qt::CaseInsensitive);
  16. }
  17.  
  18. Game::Game(const PlayerPair &players)
  19.     : m_name(QString("%1 vs %2").arg(players.first.getName(), players.second.getName()))
  20.     , m_players(QRandomGenerator::global()->bounded(1) ?
  21.                     players :
  22.                     qMakePair(players.second, players.first))
  23. {}
  24.  
  25. bool Game::operator==(const Game &other) const
  26. {
  27.     return QString::compare(m_name, other.getName(), Qt::CaseInsensitive);
  28. }
  29.  
  30. HichessServer::HichessServer(QObject *parent)
  31.     : QObject(parent)
  32. {
  33.     m_udpServer = new QUdpSocket(this);
  34.     m_webServer = new QWebSocketServer("HichessServer", QWebSocketServer::NonSecureMode, this);
  35.  
  36.     connect(m_udpServer, &QUdpSocket::readyRead, this, &HichessServer::processPendingDatagrams);
  37.     connect(m_webServer, &QWebSocketServer::newConnection, this, &HichessServer::onNewConnection);
  38.     connect(m_webServer, &QWebSocketServer::serverError, this,
  39.             [](QWebSocketProtocol::CloseCode closeCode) { qDebug() << Q_FUNC_INFO << closeCode; });
  40.  
  41.     QList<QNetworkInterface> interfaces = QNetworkInterface::allInterfaces();
  42.     foreach (QNetworkInterface interface, interfaces)
  43.         if (interface.isValid() &&
  44.             !interface.flags().testFlag(QNetworkInterface::IsLoopBack) &&
  45.             !interface.flags().testFlag(QNetworkInterface::IsPointToPoint) &&
  46.             interface.flags().testFlag(QNetworkInterface::IsUp) &&
  47.             interface.flags().testFlag(QNetworkInterface::IsRunning))
  48.         {
  49.             QList<QNetworkAddressEntry> addresses = interface.addressEntries();
  50.             foreach (QNetworkAddressEntry address, addresses)
  51.                 if (!address.ip().isNull() &&
  52.                     !address.ip().isLoopback() &&
  53.                     address.ip().protocol() == QUdpSocket::IPv4Protocol)
  54.                 {
  55.                     qDebug() << Q_FUNC_INFO << "IP: " << address.ip().toString();
  56.                     qDebug() << Q_FUNC_INFO << "Bound: " << m_udpServer->bind(address.ip(), UDP_SERVER_PORT, QUdpSocket::ShareAddress);
  57.                     qDebug() << Q_FUNC_INFO << "Port: " << m_udpServer->localAddress() << m_udpServer->localPort();
  58.                     qDebug() << Q_FUNC_INFO << "Listening: " << m_webServer->listen(address.ip(), WEB_PORT);
  59.                     return;
  60.                 }
  61.         }
  62. }
  63.  
  64. void HichessServer::processPendingDatagrams()
  65. {
  66.     QUdpSocket *socket = qobject_cast<QUdpSocket*>(sender());
  67.     if (socket && socket->hasPendingDatagrams()) {
  68.         QNetworkDatagram datagram = socket->receiveDatagram();
  69.         qDebug() << Q_FUNC_INFO << "Datagram data: " << datagram.data();
  70.  
  71.         if (datagram.data().startsWith("User = ")) {
  72.             qDebug() << Q_FUNC_INFO << "Datagram data is valid, parsing...";
  73.             QString username = datagram.data().mid(7);
  74.             QRegularExpression rx("[A-Za-z0-9_]{6,15}");
  75.  
  76.             if (rx.match(username).hasMatch()) {
  77.                 qDebug() << Q_FUNC_INFO << "Parsed username is valid...";
  78.                 auto found = std::find_if(m_allPlayers.begin(), m_allPlayers.end(), [username](Player p) {
  79.                     return p.getName() == username;
  80.                 });
  81.  
  82.                 if (found == m_allPlayers.end()) {
  83.                     qDebug() << Q_FUNC_INFO << username << "Username is not occupied";
  84.                     qDebug() << Q_FUNC_INFO << "Url: " << m_webServer->serverUrl().toString().toUtf8();
  85.                     m_usernameQueue.enqueue(username);
  86.                     socket->writeDatagram(m_webServer->serverUrl().toString().toUtf8(), datagram.senderAddress(), UDP_CLIENT_PORT);
  87.                 } else
  88.                     qDebug() << Q_FUNC_INFO << username << " username is already occupied";
  89.             } else
  90.                 qDebug() << Q_FUNC_INFO << username << " is not a valid username";
  91.         }
  92.     }
  93. }
  94.  
  95. void HichessServer::addClient(QWebSocket *client)
  96. {
  97.     if (client == nullptr) {
  98.         qDebug() << Q_FUNC_INFO << " Client is nullptr";
  99.         return;
  100.     }
  101.     qDebug() << Q_FUNC_INFO << "Client: " << client;
  102.  
  103.     connect(client, &QWebSocket::disconnected, this, [this, client]() {
  104.         qDebug() << Q_FUNC_INFO << client << "disconnected";
  105.         removeClient(client);
  106.     });
  107.     connect(client, &QWebSocket::textMessageReceived, this, [](){});
  108.     connect(client, QOverload<QAbstractSocket::SocketError>::of(&QWebSocket::error),
  109.         [=](QAbstractSocket::SocketError error){ qDebug() << Q_FUNC_INFO << error; });
  110.     connect(client, &QObject::destroyed, this, []() {qDebug() << Q_FUNC_INFO << "destroyed"; });
  111.  
  112.     if (!m_usernameQueue.isEmpty()) {
  113.         qDebug() << Q_FUNC_INFO << "There are queued usernames";
  114.  
  115.         QString username = m_usernameQueue.dequeue();
  116.         qDebug() << Q_FUNC_INFO << "Username: " << username;
  117.  
  118.         m_playerQueue.enqueue({username, client});
  119.         m_allPlayers.append({username, client});
  120.  
  121.         if (m_playerQueue.size() > 1) {
  122.             qDebug() << Q_FUNC_INFO << "There are more than 1 queued players. Found pair for a game...";
  123.             PlayerPair players = {m_playerQueue.dequeue(), m_playerQueue.dequeue()};
  124.  
  125.             Game game(players);
  126.             m_games.append(game);
  127.         }
  128.         foreach (auto p, m_allPlayers)
  129.             qDebug() << Q_FUNC_INFO << "Players: " << p.getName();
  130.         foreach (auto g, m_games)
  131.             qDebug() << Q_FUNC_INFO << "Games: " << g.getName();
  132.     } else
  133.         qDebug() << Q_FUNC_INFO << "There are no queued usernames";
  134. }
  135.  
  136. void HichessServer::removeClient(QWebSocket *client)
  137. {
  138.     auto p = std::find_if(m_allPlayers.begin(), m_allPlayers.end(), [client](const Player &p){ return p.getWSocket() == client; });
  139.     if (p != m_allPlayers.end()){
  140.         qDebug() << Q_FUNC_INFO << "Found the client to remove";
  141.         qDebug() << Q_FUNC_INFO << "Username: " << p->getName() << ", socket: " << client;
  142.  
  143.         m_allPlayers.removeAll(*p);
  144.         m_playerQueue.removeAll(*p);
  145.  
  146.         foreach (Game g, m_games) {
  147.             if (g.getWhite() == *p) {
  148.                 qDebug() << Q_FUNC_INFO << "Found game with insufficient players. White player is missing.";
  149.                 m_games.removeAll(g);
  150.                 g.getBlack().getWSocket()->sendTextMessage(p->getName() + " left the game");
  151.                 break;
  152.             } else if (g.getBlack() == *p) {
  153.                 qDebug() << Q_FUNC_INFO << "Found game with insufficient players. Black player is missing.";
  154.                 m_games.removeAll(g);
  155.                 g.getBlack().getWSocket()->sendTextMessage(p->getName() + " left the game");
  156.                 break;
  157.             } else
  158.                 qDebug() << Q_FUNC_INFO << "Client is not inside a game";
  159.         }
  160.         p->getWSocket()->deleteLater();
  161.         qDebug() << Q_FUNC_INFO << p->getName() << " left the game";
  162.     }
  163. }
  164.  
  165. void HichessServer::onNewConnection()
  166. {
  167.     qDebug() << Q_FUNC_INFO;
  168.     auto cli = m_webServer->nextPendingConnection();
  169.     addClient(cli);
  170. }
  171.  
  172. void HichessServer::onTextMessageReceived()
  173. {
  174. }
RAW Paste Data

Adblocker detected! Please consider disabling it...

We've detected AdBlock Plus or some other adblocking software preventing Pastebin.com from fully loading.

We don't have any obnoxious sound, or popup ads, we actively block these annoying types of ads!

Please add Pastebin.com to your ad blocker whitelist or disable your adblocking software.

×