Snake/SnakeServer/Server/mainserver.cpp

305 lines
8.3 KiB
C++
Raw Normal View History

2019-06-09 17:15:50 +03:00
#include "keysreactor.h"
2019-03-10 16:56:42 +03:00
#include "mainserver.h"
#include "playerdbdata.h"
2019-05-18 19:05:36 +03:00
#include "sqldbcache.h"
2019-07-06 20:40:08 +03:00
#include "websocketcontroller.h"
2019-03-10 16:56:42 +03:00
#include <spserver.h>
#include <cpserver.h>
2019-03-10 21:20:51 +03:00
#include <quasarapp.h>
2019-04-29 14:39:48 +03:00
#include <basenetworkobject.h>
2019-05-18 19:05:36 +03:00
#include <login.h>
#include <QCoreApplication>
#include <rsakeyspool.h>
2019-07-06 15:55:37 +03:00
#include <getitem.h>
2019-07-06 20:05:41 +03:00
#include <websocket.h>
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());
2019-07-26 16:25:03 +03:00
player.setPass(QRSAEncryption::decode(login.getHashPass(), rsa.priv, BASE_RSA_BITS));
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 {};
}
2019-07-26 16:25:03 +03:00
auto pass = QRSAEncryption::decode(login.getHashPass(), rsa.priv, BASE_RSA_BITS);
if (_db->login(login.getGmail(), pass.toHex())) {
return generateTocket(login.getGmail());
}
return {};
}
2019-03-10 16:56:42 +03:00
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,
2019-05-18 19:05:36 +03:00
const QByteArray& data,
2019-04-29 14:39:48 +03:00
const quint32 &addres) {
2019-03-10 16:56:42 +03:00
2019-03-14 20:10:25 +03:00
Q_UNUSED(addres);
switch (static_cast<ClientProtocol::Command>(hdr.command)) {
2019-04-29 14:39:48 +03:00
case ClientProtocol::Command::Login: {
2019-05-18 19:05:36 +03:00
ClientProtocol::Login loginData;
loginData.fromBytes(data);
ClientProtocol::RSAKeyPair keys;
if (!_serverDaemon->getRSA(addres, keys)) {
_serverDaemon->badRequest(addres, hdr);
return;
2019-05-18 19:05:36 +03:00
}
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;
}
2019-05-18 19:05:36 +03:00
2019-03-14 20:10:25 +03:00
break;
}
2019-04-29 14:39:48 +03:00
case ClientProtocol::Command::GameData: {
2019-03-14 20:10:25 +03:00
break;
}
2019-04-29 14:39:48 +03:00
case ClientProtocol::Command::UpdatePlayerData: {
2019-07-06 15:55:37 +03:00
2019-03-14 20:10:25 +03:00
break;
}
2019-04-29 14:39:48 +03:00
case ClientProtocol::Command::GetItem: {
2019-07-06 15:55:37 +03:00
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);
2019-03-14 20:10:25 +03:00
break;
}
2019-07-06 20:05:41 +03:00
case ClientProtocol::Command::WebSocket: {
ClientProtocol::WebSocket websocket;
websocket.fromBytes(data);
2019-07-06 20:40:08 +03:00
if (websocket.isSubscribe()) {
2019-07-27 17:03:59 +03:00
_websocketctrl->subscribe(addres, websocket.getCommand(),
websocket.getObjectId());
2019-07-06 20:40:08 +03:00
} else {
2019-07-27 17:03:59 +03:00
_websocketctrl->unsubscribe(addres, websocket.getCommand(),
websocket.getObjectId());
2019-07-06 20:40:08 +03:00
}
2019-07-06 20:05:41 +03:00
break;
}
2019-03-14 20:10:25 +03:00
default:
_serverDaemon->badRequest(addres, hdr);
2019-03-14 20:10:25 +03:00
break;
}
2019-03-10 16:56:42 +03:00
}
void MainServer::handleTerminalRequest(QVariantMap obj) {
auto command = static_cast<ServerProtocol::Command>(obj.value("command").toInt());
QVariantMap res;
2019-03-10 21:20:51 +03:00
switch (command) {
case ServerProtocol::State: {
2019-03-10 16:56:42 +03:00
res ["Work State"] = _serverDaemon->getWorkState();
res ["Connections count"] = _serverDaemon->connectionState();
2019-03-10 21:20:51 +03:00
2019-03-10 18:16:43 +03:00
auto banedList = _serverDaemon->baned();
res ["Baned Addresses count"] = banedList.size();
res ["Baned List"] = banedList;
2019-03-10 16:56:42 +03:00
2019-03-10 21:20:51 +03:00
break;
}
case ServerProtocol::Ban: {
2019-05-26 19:10:58 +03:00
auto address = obj.value("address").toUInt();
2019-03-10 21:20:51 +03:00
_serverDaemon->ban(address);
auto banedList = _serverDaemon->baned();
res ["Baned List"] = banedList;
2019-03-10 21:20:51 +03:00
break;
}
case ServerProtocol::Unban: {
2019-05-26 19:10:58 +03:00
auto address = obj.value("address").toUInt();
2019-03-10 21:20:51 +03:00
_serverDaemon->unBan(address);
auto banedList = _serverDaemon->baned();
res ["Baned List"] = banedList;
2019-03-10 21:20:51 +03:00
break;
}
case ServerProtocol::Restart: {
auto address = obj.value("address").toString();
2019-05-26 18:07:04 +03:00
auto port = static_cast<quint16>(obj.value("port").toInt());
2019-03-10 21:20:51 +03:00
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());
2019-03-10 21:20:51 +03:00
break;
}
case ServerProtocol::Stop: {
res ["Res"] = "Server stoped!";
_terminalPort->sendResponce(res, command);
2019-05-26 18:07:04 +03:00
_serverDaemon->stop();
2019-05-26 18:31:31 +03:00
QCoreApplication::processEvents();
QCoreApplication::quit();
return;
}
2019-03-10 21:20:51 +03:00
default:
QuasarAppUtils::Params::verboseLog("server get undefined command!");
res ["Error"] = "Server get undefined command!";
2019-03-10 21:20:51 +03:00
break;
2019-03-10 18:16:43 +03:00
}
2019-03-10 16:56:42 +03:00
_terminalPort->sendResponce(res, command);
return;
}
2019-06-13 12:53:35 +03:00
MainServer::MainServer(bool forceKeys ,QObject *ptr):
2019-03-10 16:56:42 +03:00
QObject (ptr) {
2019-06-09 17:15:50 +03:00
2019-06-13 12:53:35 +03:00
_keyReactor = new KeysReactor(forceKeys , this);
2019-06-09 17:15:50 +03:00
_serverDaemon = new ClientProtocol::Server(_keyReactor->getPool(), this);
2019-07-06 20:40:08 +03:00
_websocketctrl = new WebSocketController(_serverDaemon, this);
2019-03-10 16:56:42 +03:00
_terminalPort = new ServerProtocol::Server(this);
2019-05-18 19:05:36 +03:00
_db = new SqlDBCache();
2019-03-10 16:56:42 +03:00
connect(_serverDaemon, &ClientProtocol::Server::incomingReques,
this, &MainServer::handleRequest);
connect(_terminalPort, &ServerProtocol::Server::incomingRequest,
this, &MainServer::handleTerminalRequest);
2019-07-27 17:03:59 +03:00
connect(_db, &SqlDBCache::sigItemChanged,
_websocketctrl, &WebSocketController::handleItemChanged);
connect(_db, &SqlDBCache::sigPlayerChanged,
_websocketctrl, &WebSocketController::handlePlayerChanged);
2019-08-06 17:03:49 +03:00
if (!ClientProtocol::initClientProtockol()){
QuasarAppUtils::Params::verboseLog("clientProtocol no inited", QuasarAppUtils::Error);
}
2019-03-10 16:56:42 +03:00
}
bool MainServer::run(const QString &ip, unsigned short port, const QString& db,
2019-08-06 17:03:49 +03:00
const QString& terminalServer) {
2019-05-18 19:05:36 +03:00
if (!_db->initDb((db.size())? db: DEFAULT_DB_PATH)) {
QuasarAppUtils::Params::verboseLog("init db fail!", QuasarAppUtils::Error);
return false;
}
2019-03-10 16:56:42 +03:00
2019-08-06 17:03:49 +03:00
if (!_terminalPort->run((terminalServer.isEmpty())? DEFAULT_SERVER : terminalServer, true)) {
2019-05-18 19:05:36 +03:00
QuasarAppUtils::Params::verboseLog("run termonal fail!", QuasarAppUtils::Error);
2019-03-10 16:56:42 +03:00
return false;
}
2019-05-26 13:52:16 +03:00
if (!restartSrver(ip.isEmpty()? LOCAL_SNAKE_SERVER: ip,
2019-05-13 10:13:22 +03:00
port ? port : DEFAULT_SNAKE_PORT)) {
2019-05-18 19:05:36 +03:00
QuasarAppUtils::Params::verboseLog("restart server fail", QuasarAppUtils::Error);
2019-03-10 16:56:42 +03:00
return false;
}
return true;
}
MainServer::~MainServer() {
}