#include "keysreactor.h" #include "mainserver.h" #include "playerdbdata.h" #include "sqldbcache.h" #include #include #include #include #include #include #include #include QByteArray MainServer::generateTocket(const QString& gmail) const { return QCryptographicHash::hash((gmail + QString::number(rand())).toLatin1(), QCryptographicHash::Sha256); } QByteArray MainServer::registerPlayer(const ClientProtocol::Login& login, const ClientProtocol::RSAKeyPair& rsa) const { if (!login.isValid()) { return {}; } PlayerDBData player; player.setGmail( login.getGmail()); player.setPass(QRSAEncryption::decodeS(login.getHashPass(), rsa.priv)); int id = _db->savePlayer(player); if (id < 0) { return {}; } player = _db->getPlayer(id); player.setToken(generateTocket(login.getGmail())); player.setName(QString("Palyer %0").arg(id)); if (!player.isValid()) { QuasarAppUtils::Params::verboseLog("register Player fail!", QuasarAppUtils::Warning); return {}; } if (id != _db->savePlayer(player)) { return {}; } return player.getToken(); } QByteArray MainServer::loginPlayer(const ClientProtocol::Login& login, const ClientProtocol::RSAKeyPair& rsa) const { if (!login.isValid()) { return {}; } auto pass = QRSAEncryption::decodeS(login.getHashPass(), rsa.priv); if (_db->login(login.getGmail(), pass.toHex())) { return generateTocket(login.getGmail()); } return {}; } bool MainServer::restartSrver(const QString &ip, unsigned short port) { if (_serverDaemon->isListening()) { _serverDaemon->stop(); } if (!_serverDaemon->run(ip, port)) { return false; } return true; } void MainServer::handleRequest(ClientProtocol::Header hdr, const QByteArray& data, const quint32 &addres) { Q_UNUSED(addres); switch (static_cast(hdr.command)) { case ClientProtocol::Command::Login: { ClientProtocol::Login loginData; loginData.fromBytes(data); ClientProtocol::RSAKeyPair keys; if (!_serverDaemon->getRSA(addres, keys)) { _serverDaemon->badRequest(addres, hdr); return; } QByteArray tocken; if (_db->getPlayerId(loginData.getGmail()) < 0) { tocken = registerPlayer(loginData, keys); if (!tocken.size()) { _serverDaemon->badRequest(addres, hdr); return; } } else { tocken = loginPlayer(loginData, keys); if (!tocken.size()) { _serverDaemon->badRequest(addres, hdr); return; } } ClientProtocol::UpdatePlayerData tockenObj; tockenObj.setToken(tocken); tockenObj.setId(_db->getPlayerId(loginData.getGmail())); if (!_serverDaemon->sendResponse(&tockenObj, addres, hdr)) { QuasarAppUtils::Params::verboseLog("responce not sendet", QuasarAppUtils::Warning); return; } break; } case ClientProtocol::Command::GameData: { break; } case ClientProtocol::Command::UpdatePlayerData: { break; } case ClientProtocol::Command::GetItem: { ClientProtocol::GetItem getRequest; getRequest.fromBytes(data); auto tocken = _serverDaemon->getToken(addres); if (!tocken.isEmpty() && tocken == getRequest.getToken()) { auto item = _db->getItem(getRequest.id()); _serverDaemon->sendResponse(&item, addres, hdr); } _serverDaemon->badRequest(addres, hdr); break; } default: _serverDaemon->badRequest(addres, hdr); break; } } void MainServer::handleTerminalRequest(QVariantMap obj) { auto command = static_cast(obj.value("command").toInt()); QVariantMap res; switch (command) { case ServerProtocol::State: { res ["Work State"] = _serverDaemon->getWorkState(); res ["Connections count"] = _serverDaemon->connectionState(); auto banedList = _serverDaemon->baned(); res ["Baned Addresses count"] = banedList.size(); res ["Baned List"] = banedList; break; } case ServerProtocol::Ban: { auto address = obj.value("address").toUInt(); _serverDaemon->ban(address); auto banedList = _serverDaemon->baned(); res ["Baned List"] = banedList; break; } case ServerProtocol::Unban: { auto address = obj.value("address").toUInt(); _serverDaemon->unBan(address); auto banedList = _serverDaemon->baned(); res ["Baned List"] = banedList; break; } case ServerProtocol::Restart: { auto address = obj.value("address").toString(); auto port = static_cast(obj.value("port").toInt()); if (!restartSrver(address, port)) { QuasarAppUtils::Params::verboseLog("server restart fail!"); } res ["Work State"] = _serverDaemon->getWorkState(); res ["Address"] = QString("%0:%1"). arg(_serverDaemon->serverAddress().toString()). arg(_serverDaemon->serverPort()); break; } case ServerProtocol::Stop: { res ["Res"] = "Server stoped!"; _terminalPort->sendResponce(res, command); _serverDaemon->stop(); QCoreApplication::processEvents(); QCoreApplication::quit(); return; } default: QuasarAppUtils::Params::verboseLog("server get undefined command!"); res ["Error"] = "Server get undefined command!"; break; } _terminalPort->sendResponce(res, command); return; } MainServer::MainServer(bool forceKeys ,QObject *ptr): QObject (ptr) { _keyReactor = new KeysReactor(forceKeys , this); _serverDaemon = new ClientProtocol::Server(_keyReactor->getPool(), this); _terminalPort = new ServerProtocol::Server(this); _db = new SqlDBCache(); connect(_serverDaemon, &ClientProtocol::Server::incomingReques, this, &MainServer::handleRequest); connect(_terminalPort, &ServerProtocol::Server::incomingRequest, this, &MainServer::handleTerminalRequest); } bool MainServer::run(const QString &ip, unsigned short port, const QString& db, const QString& terminalServer, bool terminalForce) { if (!_db->initDb((db.size())? db: DEFAULT_DB_PATH)) { QuasarAppUtils::Params::verboseLog("init db fail!", QuasarAppUtils::Error); return false; } if (!_terminalPort->run((terminalServer.isEmpty())? DEFAULT_SERVER : terminalServer, terminalForce)) { QuasarAppUtils::Params::verboseLog("run termonal fail!", QuasarAppUtils::Error); return false; } if (!restartSrver(ip.isEmpty()? LOCAL_SNAKE_SERVER: ip, port ? port : DEFAULT_SNAKE_PORT)) { QuasarAppUtils::Params::verboseLog("restart server fail", QuasarAppUtils::Error); return false; } return true; } MainServer::~MainServer() { }