4
1
mirror of https://github.com/QuasarApp/Snake.git synced 2025-05-13 01:49:44 +00:00

Merge pull request from QuasarApp/task_30

Move project to CMake build system
This commit is contained in:
Andrei Yankovich 2021-05-28 16:22:42 +03:00 committed by GitHub
commit fae4343b21
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
235 changed files with 3828 additions and 13686 deletions
.gitignore.gitmodulesCMakeLists.txt
Deploy
LICENSEQuasarAppLibREADME.md
SnakeClient
SnakeMain.pro
SnakeServer

79
.gitignore vendored

@ -1,33 +1,19 @@
# C++ objects and libs
*.slo
*.lo
*.o
*.a
*.la
*.lai
*.so*
*.so
*.so.*
*.dll
*.dylib
*.exe
# Qt-es
/Build*
/build*
SnakeClient/Client/build/
SnakeClient/SnakeApp/build/
SnakeServer/Server/build/
SnakeServer/serverProtocolTests/build/
SnakeServer/Terminal/build
*.stash
/Release*
/parts/*
/prime/*
/snap/.snapcraft/*
/stage/*
/Build-*
/Release-*
*.stash
object_script.*.Release
object_script.*.Debug
*_plugin_import.cpp
/.qmake.cache
/.qmake.stash
*.pro.user
@ -39,46 +25,43 @@ moc_*.cpp
moc_*.h
qrc_*.cpp
ui_*.h
*.qmlc
*.jsc
Makefile*
*build-*
*_qml.cpp
*.snap
tests/build/
src/build/
*.qm
qml_qmlcache.qrc
qmlcache_loader.cpp
snake
SnakeServer/Terminal/build/debug/Terminal
*.prl
# Qt unit tests
target_wrapper.*
# QtCreator
installer/HanoiTowersInstaller
*.autosave
installer/installer
# QtCtreator Qml
# QtCreator Qml
*.qmlproject.user
*.qmlproject.user.*
# QtCtreator CMake
# QtCreator CMake
CMakeLists.txt.user*
installer/packages/Snake/data
\.buildconfig
SnakeServer/Daemon/build/*
# QtCreator 4.8< compilation database
compile_commands.json
SnakeServer/Client/build/*/Client
# QtCreator local machine specific files for imported projects
*creator.user*
SnakeServer/Daemon/build/*/Daemon
SnakeServer/serverProtocolTests/target_wrapper\.sh
SnakeServer/serverProtocolTests/serverProtocolTests
deployTests/
installer/SnakeInstaller
Distro/
android-build/
*.db
CMakeLists.txt.user
CMakeCache.txt
CMakeFiles
CMakeScripts
Testing
Makefile
cmake_install.cmake
install_manifest.txt
compile_commands.json
CTestTestfile.cmake
_deps
*_autogen*

16
.gitmodules vendored

@ -1,10 +1,6 @@
[submodule "QuasarAppLib"]
path = QuasarAppLib
url = https://github.com/QuasarApp/QuasarAppLib.git
[submodule "SnakeServer/Qt-Secret"]
path = SnakeServer/Qt-Secret
url = git@github.com:QuasarApp/Qt-Secret.git
[submodule "installer"]
path = installer
url = git@github.com:QuasarApp/DesktopInstaller.git
[submodule "submodules/QuasarAppLib"]
path = submodules/QuasarAppLib
url = https://github.com/QuasarApp/QuasarAppLib
[submodule "submodules/SimpleQmlNotify"]
path = submodules/SimpleQmlNotify
url = https://github.com/QuasarApp/SimpleQmlNotify.git

76
CMakeLists.txt Normal file

@ -0,0 +1,76 @@
#
# Copyright (C) 2020-2021 QuasarApp.
# Distributed under the lgplv3 software license, see the accompanying
# Everyone is permitted to copy and distribute verbatim copies
# of this license document, but changing it is not allowed.
#
cmake_minimum_required(VERSION 3.14)
project(SnakeProject)
if(TARGET ${PROJECT_NAME})
message("The ${PROJECT_NAME} arledy included in main Project")
return()
endif()
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)
set(BUILD_SHARED_LIBS ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(QT NAMES Qt6 Qt5 COMPONENTS Core Test REQUIRED)
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Test REQUIRED)
include(submodules/QuasarAppLib/CMake/QuasarApp.cmake)
if (DEFINED TARGET_PLATFORM_TOOLCHAIN)
if (${TARGET_PLATFORM_TOOLCHAIN} STREQUAL "wasm32")
initAll()
return()
endif()
endif()
if (NOT DEFINED SNAKEPROJECT_TESTS)
set(SNAKEPROJECT_TESTS ON)
if (DEFINED TARGET_PLATFORM_TOOLCHAIN)
if (${TARGET_PLATFORM_TOOLCHAIN} STREQUAL "wasm32")
set(SNAKEPROJECT_TESTS OFF)
endif()
endif()
if (ANDROID)
set(SNAKEPROJECT_TESTS OFF)
endif()
if (NOT QT_VERSION_MAJOR)
set(SNAKEPROJECT_TESTS OFF)
endif()
endif()
# Add sub directories
if (ANDROID)
set(ANDROID_PACKAGE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src/Client/android")
endif()
add_subdirectory(submodules/QuasarAppLib)
add_subdirectory(submodules/SimpleQmlNotify)
add_subdirectory(src/ClientLib)
add_subdirectory(src/Client)
if (SNAKEPROJECT_TESTS)
add_subdirectory(tests)
else()
message("The ${PROJECT_NAME} tests is disabled.")
endif()
initAll()
addDoc(${PROJECT_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/doxygen.conf)

26
Deploy/SnakeProject.json Normal file

@ -0,0 +1,26 @@
{
"bin": [
"src/Client/SnakeProject",
"src/Client/SnakeProject.exe"
],
"clear": true,
"libDir": "./../",
"recursiveDepth": "10",
"deploySystem": false,
"qif": true,
"qifStyle": "quasar",
"qifLogo": "./../src/ClientLib/res/logo.png",
"deb": true,
"qmlDir": "./../",
"ignoreEnv": [
"./../installer",
"./../Distro",
"./../parts",
"./../snap",
"./../prime",
"./../stage"
],
"extraLib": "crypto",
"targetDir": "./../Distro"
}

165
LICENSE Normal file

@ -0,0 +1,165 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.
0. Additional Definitions.
As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.
"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.
An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.
A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".
The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.
The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.
1. Exception to Section 3 of the GNU GPL.
You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.
2. Conveying Modified Versions.
If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:
a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or
b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.
3. Object Code Incorporating Material from Library Header Files.
The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:
a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license
document.
4. Combined Works.
You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:
a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.
c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.
1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.
e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)
5. Combined Libraries.
You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:
a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.
b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.
6. Revised Versions of the GNU Lesser General Public License.
The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.
If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.

@ -1 +0,0 @@
Subproject commit 7bd0fbeb56695f92af8e7763d4393f224361aca7

@ -1 +1,15 @@
# Snake
# CMakeProject
Template repository for cmake project
Fork me and replase SnakeProject to Name of your new project.
1. Clone this repository
2. Run ./init.sh NewProjectName
# This template supports next build targets:
| Command or make target | Description |
|------|------|
| **make test** | The run tests for a project (dependet of Qt Tests, so you need to add Qt in Cmake using CMAKE_PREFIX_PATH) |
| **make doc** | The generate a documentation for a project (dependet of doxygen) |
| **make deploy** | The generate distribution for a project (dependet of CQtDeployer) |
| **make release** | The prepare Qt Installer framework repository for a project, generate a snap package and APK file for android (dependet of CQtDeployer, snapcraft, AndroidDeployer). |

@ -1,116 +0,0 @@
QT += quick concurrent
CONFIG += c++17
# The following define makes your compiler emit warnings if you use
# any feature of Qt which as been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
back-end/ProfileViewItems/mainclient.cpp \
back-end/ProfileViewItems/mainmenumodel.cpp \
back-end/ProfileViewItems/networkclient.cpp \
back-end/ProfileViewItems/notificationdata.cpp \
back-end/ProfileViewItems/notificationservice.cpp \
back-end/ProfileViewItems/playerclientdata.cpp \
back-end/ProfileViewItems/settingsviewmodel.cpp \
back-end/ProfileViewItems/userview.cpp \
back-end/asyncimageresponse.cpp \
back-end/background.cpp \
back-end/backgrounditem.cpp \
back-end/baseclass.cpp \
back-end/box.cpp \
back-end/clientapp.cpp \
back-end/controller.cpp \
back-end/diff.cpp \
back-end/guiobject.cpp \
back-end/guiobjectfactory.cpp \
back-end/head.cpp \
back-end/imageprovider.cpp \
back-end/itemworld.cpp \
back-end/settings.cpp \
back-end/snake.cpp \
back-end/world.cpp \
back-end/main.cpp
TARGET = Snake
CONFIG(release, debug|release): {
DESTDIR = $$PWD/build/release
} else {
DESTDIR = $$PWD/build/debug
}
# Additional import path used to resolve QML modules in Qt Creator's code model
QML_IMPORT_PATH =
# Additional import path used to resolve QML modules just for Qt Quick Designer
QML_DESIGNER_IMPORT_PATH =
include($$PWD/../../QuasarAppLib/QuasarLib.pri)
include($$PWD/../../SnakeUtils/SnakeUtils.pri)
include($$PWD/../../SnakeServer/ClientProtocol/ClientProtocol.pri)
DISTFILES += \
android/AndroidManifest.xml \
android/AndroidManifest.xml \
android/AndroidManifest.xml \
android/build.gradle \
android/build.gradle \
android/gradle/wrapper/gradle-wrapper.jar \
android/gradle/wrapper/gradle-wrapper.jar \
android/gradle/wrapper/gradle-wrapper.jar \
android/gradle/wrapper/gradle-wrapper.properties \
android/gradle/wrapper/gradle-wrapper.properties \
android/gradlew \
android/gradlew \
android/gradlew \
android/gradlew.bat \
android/gradlew.bat \
android/res/values/libs.xml \
android/res/values/libs.xml \
android/res/values/libs.xml \
android/build.gradle \
android/gradle/wrapper/gradle-wrapper.properties \
android/gradlew.bat \
front-end/PagePopUp.qml
ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android
RESOURCES += \
qml.qrc
HEADERS += \
back-end/ProfileViewItems/mainclient.h \
back-end/ProfileViewItems/mainmenumodel.h \
back-end/ProfileViewItems/networkclient.h \
back-end/ProfileViewItems/notificationdata.h \
back-end/ProfileViewItems/notificationservice.h \
back-end/ProfileViewItems/playerclientdata.h \
back-end/ProfileViewItems/settingsviewmodel.h \
back-end/ProfileViewItems/userview.h \
back-end/asyncimageresponse.h \
back-end/background.h \
back-end/backgrounditem.h \
back-end/baseclass.h \
back-end/box.h \
back-end/clientapp.h \
back-end/controller.h \
back-end/diff.h \
back-end/guiobject.h \
back-end/guiobjectfactory.h \
back-end/head.h \
back-end/imageprovider.h \
back-end/itemworld.h \
back-end/settings.h \
back-end/snake.h \
back-end/world.h

Binary file not shown.

Before

(image error) Size: 2.4 KiB

Binary file not shown.

Before

(image error) Size: 2.4 KiB

Binary file not shown.

Before

(image error) Size: 2.4 KiB

@ -1,180 +0,0 @@
#include "mainclient.h"
#include "notificationservice.h"
#include "playerclientdata.h"
#include <QSharedPointer>
OnlineStatus MainClient::onlineStatus() const {
return _onlineStatus;
}
void MainClient::setOnlineStatus(OnlineStatus onlineStatus) {
if (_onlineStatus == onlineStatus)
return;
emit sigOnlineStatusChanged(_onlineStatus = onlineStatus);
pushNotify(onlineStatus);
}
void MainClient::clientStatusChanged() {
auto status = OnlineStatus::ClientIsOffline;
if (isOnline()) {
status = OnlineStatus::AuthorizationRequired;
}
if (isLogin()) {
status = OnlineStatus::Success;
}
setOnlineStatus(status);
}
void MainClient::pushNotify(OnlineStatus onlineStatus) {
switch (onlineStatus) {
case OnlineStatus::Success: {
NotificationService::getService()->setNotify(
NotificationData(tr("Login status"), tr("Success")));
break;
}
case OnlineStatus::AuthorizationRequired: {
NotificationService::getService()->setNotify(
NotificationData(tr("Login status"), tr("Authorization Required")));
break;
}
case OnlineStatus::WaitForAnswer: {
NotificationService::getService()->setNotify(
NotificationData(tr("Login status"), tr("Wait for answer")));
break;
}
case OnlineStatus::AuthorizationFail: {
NotificationService::getService()->setNotify(
NotificationData(tr("Login result"), tr("Authorization fail") , "", NotificationData::Error));
break;
}
case OnlineStatus::ClientIsOffline: {
NotificationService::getService()->setNotify(
NotificationData(tr("Login result"), tr("Client is offline"), "", NotificationData::Warning));
break;
}
case OnlineStatus::OfflineMode: {
NotificationService::getService()->setNotify(
NotificationData(tr("Login result"), tr("Offline Mode")));
break;
}
default: break;
}
}
void MainClient::handleReceivePackage(ClientProtocol::Command cmd, const QByteArray &obj) {
switch (cmd) {
case ClientProtocol::Command::Player: {
auto playerData = QSharedPointer<PlayerClientData>::create();
playerData->fromBytes(obj);
_users [playerData->id()] = playerData;
if (playerData->id() == _currentUserId) {
emit currentUserDataChanged(_users [playerData->id()]);
}
break;
}
case ClientProtocol::Command::BadRequest: {
NotificationService::getService()->setNotify(
NotificationData(tr("Request"), tr("Bad Request"), "",
NotificationData::Error));
break;
}
default: return;
}
}
void MainClient::handleLoginChanged(bool logined) {
this->setSubscribe(ClientProtocol::Command::Player, logined, _currentUserId);
clientStatusChanged();
}
void MainClient::handleOnlineChanged(bool) {
clientStatusChanged();
}
MainClient::MainClient(const QString &addrress, unsigned short port, QObject *ptr):
ClientProtocol::Client (addrress, port, ptr) {
connect(this, &MainClient::sigIncommingData,
this, &MainClient::handleReceivePackage);
connect(this, &MainClient::onlineChanged,
this, &MainClient::handleOnlineChanged);
connect(this, &MainClient::loginChanged,
this, &MainClient::handleLoginChanged);
}
bool MainClient::login(const QString &gmail, const QByteArray &pass, bool) {
if (!ClientProtocol::Client::login(gmail, pass)) {
setOnlineStatus(OnlineStatus::AuthorizationFail);
return false;
}
return true;
}
bool MainClient::registration(const QString &gmail,
const QByteArray &pass) {
if (!ClientProtocol::Client::registration(gmail, pass)) {
setOnlineStatus(OnlineStatus::AuthorizationFail);
return false;
}
return true;
}
void MainClient::playOffline() {
if (_onlineStatus == OnlineStatus::ClientIsOffline) {
setOnlineStatus(OfflineMode);
}
}
void MainClient::tryConnect(const QString &addrress, unsigned short port) {
setOnlineStatus(ClientIsOffline);
connectToHost(addrress, port);
}
MainClient::~MainClient() {
for (auto &i: _users) {
i.clear();
}
_users.clear();
}

@ -1,51 +0,0 @@
#ifndef MAINCLIENT_H
#define MAINCLIENT_H
#include <client.h>
class PlayerClientData;
enum OnlineStatus: int {
Success = 0x0,
AuthorizationRequired,
WaitForAnswer,
AuthorizationFail,
ClientIsOffline,
OfflineMode
};
class MainClient: public ClientProtocol::Client
{
Q_OBJECT
private:
QHash<int, QSharedPointer<PlayerClientData>> _users;
OnlineStatus _onlineStatus = ClientIsOffline;
void setOnlineStatus(OnlineStatus onlineStatus);
void clientStatusChanged();
void pushNotify(OnlineStatus onlineStatus);
private slots:
void handleReceivePackage(ClientProtocol::Command cmd, const QByteArray& obj);
void handleLoginChanged(bool);
void handleOnlineChanged(bool);
public:
MainClient(const QString& addrress = LOCAL_SNAKE_SERVER,
unsigned short port = DEFAULT_SNAKE_PORT,
QObject * ptr = nullptr);
bool login(const QString& gmail, const QByteArray &pass, bool registerNewUser = false) override;
bool registration(const QString& gmail,
const QByteArray &pass) override;
void playOffline();
void tryConnect(const QString &addrress, unsigned short port);
~MainClient() override;
OnlineStatus onlineStatus() const;
signals:
void sigOnlineStatusChanged(OnlineStatus);
void currentUserDataChanged(QSharedPointer<PlayerClientData>);
};
#endif // MAINCLIENT_H

@ -1,59 +0,0 @@
#include "mainmenumodel.h"
#include "settingsviewmodel.h"
#include "userview.h"
#include <back-end/settings.h>
#include <quasarapp.h>
#include "mainclient.h"
MainMenuModel::MainMenuModel(QObject *ptr): QObject (ptr) {
if(!ClientProtocol::initClientProtockol()) {
QuasarAppUtils::Params::verboseLog("client protockol not inited", QuasarAppUtils::Error);
}
_userViewModel = new UserView (this);
_conf = Settings::get();
_userSettingsModel = new SettingsViewModel(this);
auto adderss = _conf->getValue(SERVER_ADDRESS, SERVER_ADDRESS_DEFAULT).toString();
auto port = _conf->getValue(SERVER_ADDRESS_PORT, SERVER_ADDRESS_DEFAULT_PORT).toInt();
_client = new MainClient(adderss, static_cast<unsigned short>(port), this);
connect(_client, &MainClient::sigOnlineStatusChanged,
this , &MainMenuModel::onlineStatusChanged);
connect(_client, &MainClient::currentUserDataChanged,
_userViewModel , &UserView::setSource);
}
QObject *MainMenuModel::userViewModel() const {
return _userViewModel;
}
int MainMenuModel::onlineStatus() const {
return _client->onlineStatus();
}
void MainMenuModel::playOffline() {
_client->playOffline();
_userViewModel->setOffline(true);
}
void MainMenuModel::tryConnect() {
auto adderss = _conf->getValue(SERVER_ADDRESS, SERVER_ADDRESS_DEFAULT).toString();
auto port = _conf->getValue(SERVER_ADDRESS_PORT, SERVER_ADDRESS_DEFAULT_PORT).toInt();
_client->tryConnect(adderss, static_cast<unsigned short>(port));
}
QObject *MainMenuModel::userSettingsModel() const {
return _userSettingsModel;
}
void MainMenuModel::login(const QString &email, const QString &pass) {
_client->login(email, pass.toUtf8());
}
void MainMenuModel::registerNewUser(const QString &email,
const QString &pass) {
_client->registration(email, pass.toUtf8());
}

@ -1,51 +0,0 @@
#ifndef NETWORKPROFILEMAINMODEL_H
#define NETWORKPROFILEMAINMODEL_H
#include "mainclient.h"
#include <QObject>
#include "./../settings.h"
class UserView;
class MainClient;
class SettingsViewModel;
class MainMenuModel : public QObject
{
Q_OBJECT
Q_PROPERTY(QObject* userViewModel READ userViewModel NOTIFY userViewModelChanged)
Q_PROPERTY(QObject* userSettingsModel READ userSettingsModel NOTIFY userSettingsModelChanged)
Q_PROPERTY(int onlineStatus READ onlineStatus NOTIFY onlineStatusChanged)
private:
UserView* _userViewModel = nullptr;
SettingsViewModel* _userSettingsModel = nullptr;
MainClient *_client = nullptr;
Settings *_conf = nullptr;
public:
MainMenuModel(QObject *ptr = nullptr);
QObject* userViewModel() const;
QObject* userSettingsModel() const;
int onlineStatus() const;
Q_INVOKABLE void playOffline();
Q_INVOKABLE void tryConnect();
public slots:
void login(const QString& email, const QString& pass);
void registerNewUser(const QString& email, const QString& pass);
signals:
void userViewModelChanged(QObject* userViewModel);
void newGame();
void onlinelChanged(bool online);
void loginChanged(bool login);
void onlineStatusChanged();
void userSettingsModelChanged(QObject* userSettingsModel);
};
#endif // NETWORKPROFILEMAINMODEL_H

@ -1,23 +0,0 @@
#include "networkclient.h"
#include "playerclientdata.h"
#include <updateplayerdata.h>
int NetworkClient::loginedPlayer() const {
return _loginedPlayer;
}
void NetworkClient::handleReceiveData(ClientProtocol::Command cmd,
const QByteArray &obj) {
if (cmd == ClientProtocol::Command::Player) {
PlayerClientData data;
data.fromBytes(obj);
_playersDats[data.id()] = data;
}
}
NetworkClient::NetworkClient() {
}

@ -1,21 +0,0 @@
#ifndef CLIENT_H
#define CLIENT_H
#include "playerclientdata.h"
#include <client.h>
class NetworkClient : public ClientProtocol::Client
{
Q_OBJECT
private:
QHash<int, PlayerClientData> _playersDats;
int _loginedPlayer;
private slots:
void handleReceiveData(ClientProtocol::Command cmd, const QByteArray& obj);
public:
NetworkClient();
int loginedPlayer() const;
};
#endif // CLIENT_H

@ -1,38 +0,0 @@
#include "notificationdata.h"
NotificationData::NotificationData(const QString &title,
const QString &text,
const QString &img, Type type) {
_text = text;
_title = title;
_img = img;
_type = type;
}
QString NotificationData::text() const {
return _text;
}
QString NotificationData::img() const {
return _img;
}
QString NotificationData::title() const {
return _title;
}
bool NotificationData::operator ==(const NotificationData &righ) {
return _title == righ._title &&
_text == righ._text &&
_img == righ._img &&
_type == righ._type;
}
bool NotificationData::operator !=(const NotificationData &righ) {
return !operator==(righ);
}
int NotificationData::type() const {
return _type;
}

@ -1,41 +0,0 @@
#ifndef NOTIFICATIONDATA_H
#define NOTIFICATIONDATA_H
#include <QObject>
class NotificationData
{
Q_GADGET
Q_PROPERTY(QString text READ text)
Q_PROPERTY(QString img READ img)
Q_PROPERTY(QString title READ title)
Q_PROPERTY(int type READ type)
QString _text;
QString _img;
QString _title;
int _type;
public:
enum Type {
Normal,
Warning = 1,
Error = 2,
};
explicit NotificationData(const QString& title = "",
const QString& text = "",
const QString& img = "",
Type type = Type::Normal);
Q_INVOKABLE QString text() const;
Q_INVOKABLE QString img() const;
Q_INVOKABLE QString title() const;
Q_INVOKABLE int type() const;
bool operator ==(const NotificationData &righ);
bool operator !=(const NotificationData &righ);
};
#endif // NOTIFICATIONDATA_H

@ -1,38 +0,0 @@
#include "notificationservice.h"
NotificationService::NotificationService(QObject * ptr): QObject (ptr) {
qRegisterMetaType<NotificationData>("NotificationData");
qRegisterMetaType<QList<NotificationData>> ("QList<NotificationData>");
}
NotificationData NotificationService::notify() const {
return _notify;
}
void NotificationService::setNotify(const NotificationData& notify) {
if (_notify != notify)
_history.push_back(_notify);
_notify = notify;
emit notifyChanged();
}
void NotificationService::setNotify(const QString &title,
const QString &text,
const QString &img,
int type) {
setNotify(NotificationData(title, text, img,
static_cast<NotificationData::Type>(type)));
}
NotificationService *NotificationService::getService() {
static auto service = new NotificationService;
return service;
}
const QList<NotificationData> &NotificationService::history() const {
return _history;
}

@ -1,39 +0,0 @@
#ifndef NOTIFICATIONSERVICE_H
#define NOTIFICATIONSERVICE_H
#include "notificationdata.h"
#include <QObject>
class NotificationService: public QObject
{
Q_OBJECT
Q_PROPERTY(NotificationData notify READ notify NOTIFY notifyChanged)
Q_PROPERTY(QList<NotificationData> history READ history NOTIFY notifyChanged)
private:
explicit NotificationService(QObject *ptr = nullptr);
NotificationData _notify;
QList<NotificationData> _history;
public:
NotificationData notify() const;
void setNotify(const NotificationData &notify);
Q_INVOKABLE void setNotify(const QString& title = "",
const QString& text = "",
const QString& img = "",
int type = NotificationData::Normal);
static NotificationService* getService();
const QList<NotificationData> & history() const;
signals:
void notifyChanged();
};
#endif // NOTIFICATIONSERVICE_H

@ -1,6 +0,0 @@
#include "playerclientdata.h"
PlayerClientData::PlayerClientData()
{
}

@ -1,11 +0,0 @@
#ifndef PLAYERCLIENTDATA_H
#define PLAYERCLIENTDATA_H
#include <player.h>
class PlayerClientData: public ClientProtocol::Player
{
public:
PlayerClientData();
};
#endif // PLAYERCLIENTDATA_H

@ -1,57 +0,0 @@
#include "settingsviewmodel.h"
#include <QSettings>
#include "settings.h"
void SettingsViewModel::handleValueChanged(QString key, QVariant value) {
if (key == SERVER_ADDRESS) {
emit hostChanged(value.toString());
} else if (key == SERVER_ADDRESS_PORT) {
emit portChanged(value.toInt());
} else if (key == THEME) {
emit themeChanged(value.toInt());
}
}
SettingsViewModel::SettingsViewModel(QObject *ptr):
QObject (ptr) {
_cfg = Settings::get();
connect(_cfg, &Settings::valueChanged, this , &SettingsViewModel::handleValueChanged);
}
int SettingsViewModel::port() const {
return _cfg->getValue(SERVER_ADDRESS_PORT, SERVER_ADDRESS_DEFAULT_PORT).toInt();
}
QString SettingsViewModel::host() const {
return _cfg->getValue(SERVER_ADDRESS, SERVER_ADDRESS_DEFAULT).toString();
}
int SettingsViewModel::theme() const {
return _cfg->getValue(THEME, THEME_DEFAULT).toInt();
}
void SettingsViewModel::forceUpdate() {
emit hostChanged("");
emit portChanged(0);
emit themeChanged(0);
}
void SettingsViewModel::toDefault() {
setPort(SERVER_ADDRESS_DEFAULT_PORT);
setHost(SERVER_ADDRESS_DEFAULT);
setTheme(THEME_DEFAULT);
}
void SettingsViewModel::setPort(int port) {
_cfg->setValue(SERVER_ADDRESS_PORT, port);
}
void SettingsViewModel::setHost(const QString& host) {
_cfg->setValue(SERVER_ADDRESS, host);
}
void SettingsViewModel::setTheme(int theme) {
_cfg->setValue(THEME, theme);
}

@ -1,78 +0,0 @@
#include "userview.h"
const PlayerClientData *UserView::getSource() const {
return _source.data();
}
void UserView::setSource(QSharedPointer<PlayerClientData> data) {
_offline = data == nullptr;
if (data->id() != _source->id()) {
_source = data;
emit sourceChanged();
}
}
bool UserView::offline() const {
return _offline;
}
void UserView::setOffline(bool offline) {
if (_offline != offline) {
emit offlineChanged(_offline = offline);
}
}
UserView::UserView(QObject *parent) : QObject(parent) {
}
QString UserView::name() const {
if (!_source) {
return tr("Undefined name");
}
return _source->getName();
}
QString UserView::gmail() const {
if (!_source) {
return tr("Undefined gmail");
}
return _source->getGmail();
}
int UserView::money() const {
if (!_source) {
return -1;
}
return static_cast<int>(_source->getMany());
}
int UserView::record() const {
if (!_source) {
return -1;
}
return static_cast<int>(_source->getRecord());
}
int UserView::avgRecord() const {
if (!_source) {
return -1;
}
return static_cast<int>(_source->getAvgRecord());
}
int UserView::cureentSnake() const {
if (!_source) {
return -1;
}
return _source->getCureentSnake();
}
int UserView::id() const {
if (!_source) {
return -1;
}
return _source->id();
}

@ -1,52 +0,0 @@
#ifndef USERVIEW_H
#define USERVIEW_H
#include "playerclientdata.h"
#include <QObject>
class UserView : public QObject
{
Q_OBJECT
Q_PROPERTY(QString name READ name NOTIFY sourceChanged)
Q_PROPERTY(QString gmail READ gmail NOTIFY sourceChanged)
Q_PROPERTY(int money READ money NOTIFY sourceChanged)
Q_PROPERTY(int record READ record NOTIFY sourceChanged)
Q_PROPERTY(int avgRecord READ avgRecord NOTIFY sourceChanged)
Q_PROPERTY(int cureentSnake READ cureentSnake NOTIFY sourceChanged)
Q_PROPERTY(int id READ id NOTIFY sourceChanged)
Q_PROPERTY(bool offline READ offline NOTIFY offlineChanged)
private:
QSharedPointer<PlayerClientData> _source = nullptr;
bool _offline = false;
public:
explicit UserView(QObject *parent = nullptr);
QString name() const;
QString gmail() const;
int money() const;
int record() const;
int avgRecord() const;
int cureentSnake() const;
int id() const;
const PlayerClientData *getSource() const;
bool offline() const;
void setOffline(bool offline);
signals:
void sourceChanged();
void offlineChanged(bool offline);
public slots:
void setSource(QSharedPointer<PlayerClientData> data);
};
#endif // USERVIEW_H

@ -1,50 +0,0 @@
#include "clientapp.h"
#include "imageprovider.h"
#include "ProfileViewItems/userview.h"
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <back-end/ProfileViewItems/mainmenumodel.h>
#include <back-end/ProfileViewItems/notificationservice.h>
QByteArray ClientApp::initTheme() {
int themeIndex = Settings::get()->getValue(THEME, THEME_DEFAULT).toInt();
switch (themeIndex) {
case 1: return "Dark";
default: return "Light";
}
}
ClientApp::ClientApp() {
}
ClientApp::~ClientApp() {
}
bool ClientApp::init(QQmlApplicationEngine *engine) {
qputenv("QT_QUICK_CONTROLS_MATERIAL_THEME", initTheme());
qmlRegisterType <GuiObject> ();
qmlRegisterType <Diff> ();
qmlRegisterType <MainMenuModel> ();
qmlRegisterType <UserView> ();
auto root = engine->rootContext();
if (!root)
return false;
engine->addImageProvider(QLatin1String("userItems"), new ImageProvider());
root->setContextProperty("contr", &contr);
root->setContextProperty("notificationService", NotificationService::getService());
engine->load(QUrl(QStringLiteral("qrc:/front-end/main.qml")));
if (engine->rootObjects().isEmpty())
return false;
return true;
}

@ -1,17 +0,0 @@
#ifndef SNAKESETTINGS_H
#define SNAKESETTINGS_H
#include <config.h>
#include <quasarapp.h>
#define SERVER_ADDRESS "SERVER_ADDRESS"
#define SERVER_ADDRESS_PORT "SERVER_ADDRESS_PORT"
#define THEME "THEME_GUI"
#define SERVER_ADDRESS_DEFAULT "quasarapp.ddns.net"
//#define SERVER_ADDRESS_DEFAULT "127.0.0.1"
#define SERVER_ADDRESS_DEFAULT_PORT DEFAULT_SNAKE_PORT
#define THEME_DEFAULT 0
using Settings = QuasarAppUtils::Settings;
#endif // SNAKESETTINGS_H

@ -1,84 +0,0 @@
import QtQuick 2.11
import QtQuick.Controls 2.3
import QtQuick.Controls.Material 2.0
import QtQuick.Layouts 1.3
BasePopUp {
id : popup
property string text: qsTr("Message")
property string img: ""
property string titleText: qsTr("Message")
property int type: 0
function _getBackGraundColor(type) {
switch(type) {
case 1: return "#FFC107"
case 2: return "#FF5722"
}
return Material.background
}
autoClose: true;
closeInterval: 5000
margins: 0
margin: 0
spacing: 0
backgroundColor: _getBackGraundColor(type);
Page {
id: page
anchors.fill: parent
spacing: 0
background: Rectangle {
color: "#00000000"
}
header: Label {
text: titleText
horizontalAlignment: Text.AlignHCenter
}
contentItem:
RowLayout {
id: rowLayout
spacing: 5
clip: true
Rectangle {
color: "#00000000"
Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter
Layout.preferredWidth: rowLayout.height;
Layout.preferredHeight: rowLayout.height;
Image {
id: image
fillMode: Image.PreserveAspectCrop
clip: true
anchors.fill: parent;
source: img
}
}
Label {
id: message
text: popup.text
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
Layout.fillHeight: true;
Layout.fillWidth: true;
clip: true
wrapMode: Text.WordWrap
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
}
}
}
}

@ -1,30 +0,0 @@
import QtQuick 2.12
import QtQuick.Controls.Material 2.12
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.3
import QtGraphicalEffects 1.12
Item {
readonly property var model: notificationService;
readonly property var msg: model.notify
readonly property var history: model.history
NotificationForm {
id: notyfyView
titleText : msg.title;
text: (msg)? msg.text: "";
img: (msg)? msg.img: "";
type: (msg)? msg.type: 0;
x: parent.width - width - margin;
y: margin;
width: 6 * metrix.controlPtMaterial;
height: width * 0.5
}
onMsgChanged: {
notyfyView._show();
}
}

@ -1,39 +0,0 @@
<RCC>
<qresource prefix="/">
<file>front-end/main.qml</file>
<file>front-end/GraphicItem.qml</file>
<file>front-end/MainMenu.qml</file>
<file>qtquickcontrols2.conf</file>
<file>front-end/Scene.qml</file>
<file>front-end/NotificationForm.qml</file>
<file>front-end/SnakeItem.qml</file>
<file>front-end/About.qml</file>
<file>front-end/AboutPage.qml</file>
<file>front-end/BasePopUp.qml</file>
<file>front-end/TextInput.qml</file>
<file>front-end/PagePopUp.qml</file>
<file>front-end/UserView.qml</file>
<file>front-end/ImageView.qml</file>
<file>front-end/PropertyView.qml</file>
<file>front-end/Metrix.qml</file>
<file>front-end/LoginView.qml</file>
<file>front-end/FrameView.qml</file>
<file>front-end/MainMenuButton.qml</file>
<file>front-end/SideBar.qml</file>
<file>front-end/LeftSideBar.qml</file>
<file>front-end/LeftBoxSideBar.qml</file>
<file>front-end/SettingsView.qml</file>
<file>front-end/NotificationServiceView.qml</file>
</qresource>
<qresource prefix="/texture">
<file alias="up">img/up.svg</file>
</qresource>
<qresource prefix="/logo">
<file alias="logo">img/logo.png</file>
<file alias="icon">img/icon.ico</file>
</qresource>
<qresource prefix="/img">
<file alias="defaultuser">img/defaultUser.png</file>
<file alias="defaultsnake">img/defaultSnake.png</file>
</qresource>
</RCC>

@ -1,5 +0,0 @@
TEMPLATE = subdirs
CONFIG += ordered
SUBDIRS += \
SnakeApp

@ -1,20 +0,0 @@
TEMPLATE = subdirs
CONFIG += ordered
SUBDIRS += \
QuasarAppLib \
SnakeUtils \
SnakeServer \
SnakeClient \
QuasarAppLib.file = QuasarAppLib/QuasarApp.pro
Snake.file = Snake/snake.pro
include($$PWD/installer/installerSnake.pri)
include($$PWD/test.pri)
DISTFILES += \
doc/librarymodel.qmodel \
doc/calassdiagramm.qmodel

@ -1,24 +0,0 @@
#
# Copyright (C) 2018 - 2019 QuasarApp.
# Distributed under the lgplv3 software license, see the accompanying
# Everyone is permitted to copy and distribute verbatim copies
# of this license document, but changing it is not allowed.
#
!isEmpty(CLIENTPROTOCOL_LIB):error("ClientProtocol.pri already included")
CLIENTPROTOCOL_LIB = 1
#DEPENDS
CONFIG(release, debug|release): {
CLIENTPROTOCOL_LIB_OUTPUT_DIR="$$PWD/build/release"
} else {
CLIENTPROTOCOL_LIB_OUTPUT_DIR="$$PWD/build/debug"
}
LIBS += -L$$CLIENTPROTOCOL_LIB_OUTPUT_DIR -lClientProtocol
include($$PWD/ClientProtocolIncludes.pri)
include($$PWD/../Qt-Secret/src/Qt-Secret.pri)

@ -1,91 +0,0 @@
#
# Copyright (C) 2018 - 2019 QuasarApp.
# Distributed under the lgplv3 software license, see the accompanying
# Everyone is permitted to copy and distribute verbatim copies
# of this license document, but changing it is not allowed.
#
#-------------------------------------------------
#
# Project created by QtCreator 2019-02-12T11:08:54
#
#-------------------------------------------------
QT -= gui
QT += network
CONFIG += c++14
TARGET = ClientProtocol
TEMPLATE = lib
DEFINES += CLIENTPROTOCOL_LIBRARY
# The following define makes your compiler emit warnings if you use
# any feature of Qt which has been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
CONFIG(release, debug|release): {
DESTDIR = $$PWD/build/release
} else {
DESTDIR = $$PWD/build/debug
}
include($$PWD/../../QuasarAppLib/QuasarLib.pri)
include($$PWD/../../SnakeUtils/SnakeUtils.pri)
include($$PWD/../Qt-Secret/src/Qt-Secret.pri)
SOURCES += \
Objects/basenetworkobject.cpp \
Objects/map.cpp \
Objects/objdata.cpp \
Objects/pubkey.cpp \
Objects/snake.cpp \
Objects/websocket.cpp \
clientprotocol.cpp \
client.cpp \
Objects/gamedata.cpp \
Objects/getitem.cpp \
Objects/login.cpp \
networkclasssize.cpp \
Objects/player.cpp \
rsakeyspool.cpp \
server.cpp \
factorynetobjects.cpp \
connectioninfo.cpp \
Objects/updateplayerdata.cpp
HEADERS += \
Objects/basenetworkobject.h \
Objects/map.h \
Objects/objdata.h \
Objects/pubkey.h \
Objects/snake.h \
Objects/websocket.h \
clientprotocol.h \
clientprotocol_global.h \
Objects/gamedata.h \
Objects/getitem.h \
Objects/login.h \
networkclasssize.h \
client.h \
Objects/player.h \
rsakeyspool.h \
server.h \
cp.h \
config.h \
factorynetobjects.h \
connectioninfo.h \
cpserver.h \
Objects/updateplayerdata.h
include($$PWD/ClientProtocolIncludes.pri)

@ -1,4 +0,0 @@
INCLUDEPATH += "$$PWD/"
INCLUDEPATH += "$$PWD/Objects"

@ -1,98 +0,0 @@
#include "basenetworkobject.h"
namespace ClientProtocol {
int BaseNetworkObject::id() const {
return _id;
}
void BaseNetworkObject::setId(int id) {
_id = id;
}
quint8 BaseNetworkObject::getClass() const {
return _class;
}
BaseNetworkObject::BaseNetworkObject() {
}
BaseNetworkObject *BaseNetworkObject::create() const {
return new BaseNetworkObject();
}
BaseNetworkObject::~BaseNetworkObject() {
}
NetworkClassSize BaseNetworkObject::classSize() const {
return getTypeSize(_id) + getTypeSize(_class);
}
QDataStream &BaseNetworkObject::writeToStream(QDataStream &stream) const {
stream << _class;
stream << _id;
return stream;
}
QDataStream &BaseNetworkObject::readFromStream(QDataStream &stream) {
stream >> _class;
stream >> _id;
return stream;
}
bool BaseNetworkObject::isValid() const {
return _id >= 0 && _class > 0;
}
void BaseNetworkObject::toBytes(QByteArray &array) const {
QDataStream stream(&array, QIODevice::WriteOnly);
writeToStream(stream);
}
void BaseNetworkObject::fromBytes(const QByteArray &array) {
QDataStream stream(array);
readFromStream(stream);
}
NetworkClassSize getTypeSize(const EncryptionParams &params) {
bool isKey = params.alg & Key;
switch (params.alg & ~Key) {
case RSA: {
if (isKey) {
return {
static_cast<unsigned int>(sizeof (int) +
QRSAEncryption::getKeyBytesSize(static_cast<QRSAEncryption::Rsa>(params.baseBits)))
};
}
auto baseSize =
static_cast<unsigned int>(sizeof (int) +
QRSAEncryption::getKeyBytesSize(static_cast<QRSAEncryption::Rsa>(params.encryptBits))) / 2;
return {baseSize, baseSize * params.baseBytes()};
}
case SHA: {
return {static_cast<unsigned int>(sizeof (int) + params.baseBytes())};
}
default:
return sizeof (int) + 10;
}
}
unsigned int EncryptionParams::baseBytes() const {
return baseBits / 8;
}
}

@ -1,89 +0,0 @@
#ifndef BASENETWORKOBJECT_H
#define BASENETWORKOBJECT_H
#include "networkclasssize.h"
#include <cstdlib>
#include <QDataStream>
#include <QVector>
#include <typeinfo>
#include "config.h"
#include <type_traits>
#include "clientprotocol_global.h"
#include <qrsaencryption.h>
namespace ClientProtocol {
enum cryptoAlghoritms: unsigned int {
RSA = 0x0,
SHA = 0x2,
Key = 0x100
};
struct EncryptionParams {
unsigned int alg = SHA;
unsigned int baseBits = QRSAEncryption::RSA_256;
unsigned int encryptBits = QRSAEncryption::RSA_256;
unsigned int baseBytes() const;
};
NetworkClassSize getTypeSize(const EncryptionParams &params);
template <class T>
NetworkClassSize getTypeSize(const T& type = {}) {
auto hash = typeid(type).hash_code();
if (hash == typeid(QString).hash_code()) {
return { sizeof (int), sizeof (QChar) * MAX_SIZE};
} else if (hash == typeid(QList<int>).hash_code()) {
return { sizeof (int), sizeof (int) * MAX_SIZE};
} else if (hash == typeid(QList<float>).hash_code()) {
return { sizeof (float), sizeof (float) * MAX_SIZE};
} else if (hash == typeid(QStringList).hash_code()) {
auto size = getTypeSize<QString>();
return {sizeof (int) , size.max + static_cast<int>(sizeof (int) * MAX_SIZE)};
}
return sizeof (type);
}
class CLIENTPROTOCOLSHARED_EXPORT BaseNetworkObject
{
private:
int _id = -1;
protected:
quint8 _class = 0;
public:
BaseNetworkObject();
virtual BaseNetworkObject* create() const;
virtual ~BaseNetworkObject();
virtual NetworkClassSize classSize() const;
virtual QDataStream& writeToStream(QDataStream& stream) const;
virtual QDataStream& readFromStream(QDataStream& stream);
virtual bool isValid() const;
void toBytes(QByteArray& array) const;
void fromBytes(const QByteArray& array);
int id() const;
void setId(int id);
quint8 getClass() const;
};
template<class T>
auto cast(const BaseNetworkObject* obj) {
static_assert (!std::is_pointer<T>(), "Cast working only with pointers!");
return static_cast<T>(obj);
}
}
#endif // BASENETWORKOBJECT_H

@ -1,50 +0,0 @@
#include "gamedata.h"
#include "config.h"
#include "clientprotocol.h"
namespace ClientProtocol {
GameData::GameData()
{
_class = static_cast<quint8>(Command::GameData);
}
QList<int> GameData::getTimeClick() const {
return timeClick;
}
void GameData::setTimeClick(const QList<int> &value) {
timeClick = value;
}
int& GameData::operator[](int index) {
return timeClick[index];
}
BaseNetworkObject *GameData::create() const {
return new GameData();
}
NetworkClassSize GameData::classSize() const {
return UpdatePlayerData::classSize() +
getTypeSize(timeClick);
}
QDataStream &GameData::writeToStream(QDataStream &stream) const {
UpdatePlayerData::writeToStream(stream);
stream << timeClick;
return stream;
}
QDataStream &GameData::readFromStream(QDataStream &stream) {
UpdatePlayerData::readFromStream(stream);
stream >> timeClick;
return stream;
}
bool GameData::isValid() const {
return timeClick.size() > 0 && UpdatePlayerData::isValid();
}
}

@ -1,28 +0,0 @@
#ifndef GAMEDATA_H
#define GAMEDATA_H
#include <updateplayerdata.h>
namespace ClientProtocol {
class CLIENTPROTOCOLSHARED_EXPORT GameData: public UpdatePlayerData
{
private:
QList<int> timeClick;
public:
GameData();
QList<int> getTimeClick() const;
void setTimeClick(const QList<int> &value);
int& operator[](int index);
BaseNetworkObject *create() const override;
NetworkClassSize classSize() const override;
QDataStream &writeToStream(QDataStream &stream) const override;
QDataStream &readFromStream(QDataStream &stream) override;
bool isValid() const override;
};
}
#endif // GAMEDATA_H

@ -1,10 +0,0 @@
#include "getitem.h"
#include "clientprotocol.h"
namespace ClientProtocol {
GetItem::GetItem()
{
_class = static_cast<quint8>(Command::GetItem);
}
}

@ -1,17 +0,0 @@
#ifndef GETITEM_H
#define GETITEM_H
#include <updateplayerdata.h>
namespace ClientProtocol {
class CLIENTPROTOCOLSHARED_EXPORT GetItem : public UpdatePlayerData
{
public:
GetItem();
};
}
#endif // GETITEM_H

@ -1,71 +0,0 @@
#include "login.h"
#include "config.h"
#include "clientprotocol.h"
namespace ClientProtocol {
bool Login::getRegisterNewUser() const {
return registerNewUser;
}
void Login::setRegisterNewUser(bool value) {
registerNewUser = value;
}
Login::Login() {
_class = static_cast<quint8>(Command::Login);
}
BaseNetworkObject *Login::create() const {
return new Login();
}
NetworkClassSize Login::classSize() const {
auto size = BaseNetworkObject::classSize();
EncryptionParams param = {
cryptoAlghoritms::RSA | cryptoAlghoritms::Key,
BASE_HASH_BITS,
BASE_ENCRYPTION_BITS
};
return size + getTypeSize(param) + getTypeSize(gmail) + getTypeSize(registerNewUser);
}
QDataStream &Login::writeToStream(QDataStream &stream) const {
BaseNetworkObject::writeToStream(stream);
stream << gmail;
stream << hashRsaPass;
stream << registerNewUser;
return stream;
}
QDataStream &Login::readFromStream(QDataStream &stream) {
BaseNetworkObject::readFromStream(stream);
stream >> gmail;
stream >> hashRsaPass;
stream >> registerNewUser;
return stream;
}
bool Login::isValid() const {
return gmail.size() > 5 &&
hashRsaPass.size() >= 32 &&
hashRsaPass.size() <= 64 &&
BaseNetworkObject::isValid();
}
QString Login::getGmail() const {
return gmail;
}
void Login::setGmail(const QString &value) {
gmail = value;
}
QByteArray Login::getHashPass() const {
return hashRsaPass;
}
void Login::setHashPass(const QByteArray &value) {
hashRsaPass = value;
}
}

@ -1,31 +0,0 @@
#ifndef LOGIN_H
#define LOGIN_H
#include "basenetworkobject.h"
namespace ClientProtocol {
class CLIENTPROTOCOLSHARED_EXPORT Login : public BaseNetworkObject
{
private:
QByteArray hashRsaPass;
QString gmail;
bool registerNewUser = false;
public:
Login();
BaseNetworkObject *create() const override;
NetworkClassSize classSize() const override;
QDataStream &writeToStream(QDataStream &stream) const override;
QDataStream &readFromStream(QDataStream &stream) override;
bool isValid() const override;
QString getGmail() const;
void setGmail(const QString &value);
QByteArray getHashPass() const;
void setHashPass(const QByteArray &value);
bool getRegisterNewUser() const;
void setRegisterNewUser(bool value);
};
}
#endif // LOGIN_H

@ -1,45 +0,0 @@
#include "map.h"
#include <clientprotocol.h>
namespace ClientProtocol {
Map::Map()
{
_class = static_cast<quint8>(Command::Map);
}
BaseNetworkObject *Map::create() const {
return new Map();
}
NetworkClassSize Map::classSize() const {
return BaseNetworkObject::classSize()
+ getTypeSize(lvl)
+ getTypeSize(lenght)
+ getTypeSize(objects);
}
QDataStream &Map::writeToStream(QDataStream &stream) const {
BaseNetworkObject::writeToStream(stream);
stream << lvl;
stream << lenght;
stream << objects;
return stream;
}
QDataStream &Map::readFromStream(QDataStream &stream) {
BaseNetworkObject::readFromStream(stream);
stream >> lvl;
stream >> lenght;
stream >> objects;
return stream;
}
bool Map::isValid() const {
return lenght > 1 && objects.size() > 1 &&
BaseNetworkObject::isValid();
}
}

@ -1,25 +0,0 @@
#ifndef MAP_H
#define MAP_H
#include "basenetworkobject.h"
#include "objdata.h"
namespace ClientProtocol {
class CLIENTPROTOCOLSHARED_EXPORT Map : public BaseNetworkObject
{
private:
quint8 lvl;
quint16 lenght;
QList<ObjData> objects;
public:
Map();
BaseNetworkObject *create() const override;
NetworkClassSize classSize() const override;
QDataStream &writeToStream(QDataStream &stream) const override;
QDataStream &readFromStream(QDataStream &stream) override;
bool isValid() const override;
};
}
#endif // MAP_H

@ -1,24 +0,0 @@
#include "objdata.h"
#include <QDataStream>
namespace ClientProtocol {
QDataStream& operator <<(QDataStream &stream, const ObjData &obj) {
stream << obj.id;
stream << obj.x;
stream << obj.y;
stream << obj.rat;
return stream;
}
QDataStream& operator >>(QDataStream &stream, ObjData &obj) {
stream >> obj.id;
stream >> obj.x;
stream >> obj.y;
stream >> obj.rat;
return stream;
}
}

@ -1,17 +0,0 @@
#ifndef OBJDATA_H
#define OBJDATA_H
#include "clientprotocol_global.h"
namespace ClientProtocol {
struct CLIENTPROTOCOLSHARED_EXPORT ObjData {
int id;
unsigned short x;
unsigned short y;
unsigned short rat;
friend QDataStream& operator << (QDataStream& stream, const ObjData& obj);
friend QDataStream& operator >> (QDataStream& stream, ObjData& obj);
};
}
#endif // OBJDATA_H

@ -1,116 +0,0 @@
#include "player.h"
#include "config.h"
#include <clientprotocol.h>
namespace ClientProtocol {
QString Player::getName() const {
return name;
}
void Player::setName(const QString &value) {
name = value;
}
QString Player::getGmail() const {
return gmail;
}
void Player::setGmail(const QString &value) {
gmail = value;
}
unsigned int Player::getMany() const
{
return money;
}
void Player::setMany(unsigned int value) {
money = value;
}
unsigned int Player::getRecord() const {
return record;
}
void Player::setRecord(unsigned int value) {
record = value;
}
QList<int> Player::getItems() const {
return items;
}
void Player::setItems(const QList<int> &value) {
items = value;
}
int Player::getCureentSnake() const {
return cureentSnake;
}
void Player::setCureentSnake(int value) {
cureentSnake = value;
}
unsigned int Player::getAvgRecord() const {
return avgRecord;
}
void Player::setAvgRecord(unsigned int value) {
avgRecord = value;
}
Player::Player() {
_class = static_cast<quint8>(Command::Player);
}
BaseNetworkObject *Player::create() const {
return new Player();
}
NetworkClassSize Player::classSize() const {
return UpdatePlayerData::classSize()
+ getTypeSize(name)
+ getTypeSize(gmail)
+ getTypeSize(money)
+ getTypeSize(record)
+ getTypeSize(avgRecord)
+ getTypeSize(items)
+ getTypeSize(cureentSnake);
}
QDataStream &Player::writeToStream(QDataStream &stream) const {
UpdatePlayerData::writeToStream(stream);
stream << name;
stream << gmail;
stream << money;
stream << record;
stream << avgRecord;
stream << items;
stream << cureentSnake;
return stream;
}
QDataStream &Player::readFromStream(QDataStream &stream) {
UpdatePlayerData::readFromStream(stream);
stream >> name;
stream >> gmail;
stream >> money;
stream >> record;
stream >> avgRecord;
stream >> items;
stream >> cureentSnake;
return stream;
}
bool Player::isValid() const {
return !name.isNull() && gmail.size() > 5 &&
BaseNetworkObject::isValid();
}
}

@ -1,50 +0,0 @@
#ifndef PLAYER_H
#define PLAYER_H
#include "updateplayerdata.h"
namespace ClientProtocol {
class CLIENTPROTOCOLSHARED_EXPORT Player: public UpdatePlayerData
{
private:
QString name = "user";
QString gmail = "";
unsigned int money = 0;
unsigned int record = 0;
unsigned int avgRecord = 0;
QList<int> items;
int cureentSnake = -1;
public:
Player();
BaseNetworkObject *create() const override;
NetworkClassSize classSize() const override;
QDataStream &writeToStream(QDataStream &stream) const override;
QDataStream &readFromStream(QDataStream &stream) override;
bool isValid() const override;
QString getName() const;
void setName(const QString &value);
QString getGmail() const;
void setGmail(const QString &value);
unsigned int getMany() const;
void setMany(unsigned int value);
unsigned int getRecord() const;
void setRecord(unsigned int value);
QList<int> getItems() const;
void setItems(const QList<int> &value);
int getCureentSnake() const;
void setCureentSnake(int value);
unsigned int getAvgRecord() const;
void setAvgRecord(unsigned int value);
// QString getHexPass() const;
// void fromHexPass(const QString& passHex);
};
}
#endif // PLAYER_H

@ -1,62 +0,0 @@
#include "pubkey.h"
#include "clientprotocol.h"
namespace ClientProtocol {
PubKey::PubKey():
BaseNetworkObject() {
_class = static_cast<quint8>(Command::PubKey);
}
QRSAEncryption::Rsa PubKey::getTypeKey() const {
return typeKey;
}
void PubKey::setTypeKey(const QRSAEncryption::Rsa &value) {
typeKey = value;
}
QByteArray PubKey::getKey() const {
return key;
}
void PubKey::setKey(const QByteArray &value) {
key = value;
}
BaseNetworkObject *PubKey::create() const {
return new PubKey();
}
NetworkClassSize PubKey::classSize() const {
EncryptionParams param = {
cryptoAlghoritms::RSA | cryptoAlghoritms::Key,
BASE_ENCRYPTION_BITS
};
return BaseNetworkObject::classSize() +
getTypeSize(param) +
getTypeSize(int(typeKey));
}
QDataStream &PubKey::writeToStream(QDataStream &stream) const {
BaseNetworkObject::writeToStream(stream);
stream << int(typeKey);
stream << key;
return stream;
}
QDataStream &PubKey::readFromStream(QDataStream &stream) {
BaseNetworkObject::readFromStream(stream);
int _typeKey;
stream >> _typeKey;
typeKey = static_cast<QRSAEncryption::Rsa>(_typeKey);
stream >> key;
return stream;
}
bool PubKey::isValid() const {
return static_cast<quint32>(key.size()) == QRSAEncryption::getKeyBytesSize(typeKey)
&& BaseNetworkObject::isValid();
}
}

@ -1,30 +0,0 @@
#ifndef PUBKEY_H
#define PUBKEY_H
#include <qrsaencryption.h>
#include "basenetworkobject.h"
namespace ClientProtocol {
class CLIENTPROTOCOLSHARED_EXPORT PubKey: public BaseNetworkObject
{
private:
QRSAEncryption::Rsa typeKey;
QByteArray key;
public:
PubKey();
BaseNetworkObject *create() const override;
NetworkClassSize classSize() const override;
QDataStream &writeToStream(QDataStream &stream) const override;
QDataStream &readFromStream(QDataStream &stream) override;
bool isValid() const override;
QRSAEncryption::Rsa getTypeKey() const;
void setTypeKey(const QRSAEncryption::Rsa &value);
QByteArray getKey() const;
void setKey(const QByteArray &value);
};
}
#endif // PUBKEY_H

@ -1,68 +0,0 @@
#include "snake.h"
#include "clientprotocol.h"
namespace ClientProtocol {
quint8 Snake::getSpeed() const {
return speed;
}
void Snake::setSpeed(const quint8 &value) {
speed = value;
}
quint8 Snake::getSnakeClass() const {
return snakeClass;
}
void Snake::setSnakeClass(const quint8 &value) {
snakeClass = value;
}
QList<float> Snake::getSkillet() const {
return skillet;
}
void Snake::setSkillet(const QList<float> &value) {
skillet = value;
}
BaseNetworkObject *Snake::create() const {
return new Snake();
}
NetworkClassSize Snake::classSize() const {
return BaseNetworkObject::classSize() +
getTypeSize(speed) +
getTypeSize(snakeClass) +
getTypeSize(skillet);
}
QDataStream &Snake::writeToStream(QDataStream &stream) const {
BaseNetworkObject::writeToStream(stream);
stream << speed;
stream << snakeClass;
stream << skillet;
return stream;
}
QDataStream &Snake::readFromStream(QDataStream &stream) {
BaseNetworkObject::readFromStream(stream);
stream >> speed;
stream >> snakeClass;
stream >> skillet;
return stream;
}
bool Snake::isValid() const {
return (speed > 0) && skillet.size() && BaseNetworkObject::isValid();
}
Snake::Snake() {
_class = static_cast<quint8>(Command::Snake);
}
}

@ -1,32 +0,0 @@
#ifndef SNAKE_H
#define SNAKE_H
#include "basenetworkobject.h"
namespace ClientProtocol {
class CLIENTPROTOCOLSHARED_EXPORT Snake: public BaseNetworkObject
{
private:
quint8 speed;
quint8 snakeClass;
QList<float> skillet;
public:
Snake();
quint8 getSpeed() const;
void setSpeed(const quint8 &value);
quint8 getSnakeClass() const;
void setSnakeClass(const quint8 &value);
QList<float> getSkillet() const;
void setSkillet(const QList<float> &value);
BaseNetworkObject *create() const override;
NetworkClassSize classSize() const override;
QDataStream &writeToStream(QDataStream &stream) const override;
QDataStream &readFromStream(QDataStream &stream) override;
bool isValid() const override;
};
}
#endif // SNAKE_H

@ -1,49 +0,0 @@
#include "updateplayerdata.h"
#include "config.h"
#include "clientprotocol.h"
namespace ClientProtocol {
UpdatePlayerData::UpdatePlayerData() {
_class = static_cast<quint8>(Command::UpdatePlayerData);
}
QByteArray UpdatePlayerData::getToken() const {
return token;
}
void UpdatePlayerData::setToken(const QByteArray &value) {
token = value;
}
BaseNetworkObject *UpdatePlayerData::create() const {
return new UpdatePlayerData();
}
NetworkClassSize UpdatePlayerData::classSize() const {
EncryptionParams param = {
cryptoAlghoritms::SHA,
BASE_HASH_BITS
};
return BaseNetworkObject::classSize() + getTypeSize(param);
}
QDataStream &UpdatePlayerData::writeToStream(QDataStream &stream) const {
BaseNetworkObject::writeToStream(stream);
stream << token;
return stream;
}
QDataStream &UpdatePlayerData::readFromStream(QDataStream &stream) {
BaseNetworkObject::readFromStream(stream);
stream >> token;
return stream;
}
bool UpdatePlayerData::isValid() const {
return token.size() == 32 && BaseNetworkObject::isValid();
}
}

@ -1,26 +0,0 @@
#ifndef UPDATEPLAYERDATA_H
#define UPDATEPLAYERDATA_H
#include "basenetworkobject.h"
namespace ClientProtocol {
class CLIENTPROTOCOLSHARED_EXPORT UpdatePlayerData : public BaseNetworkObject
{
private:
QByteArray token;
public:
UpdatePlayerData();
QByteArray getToken() const;
void setToken(const QByteArray &value);
BaseNetworkObject *create() const override;
NetworkClassSize classSize() const override;
QDataStream &writeToStream(QDataStream &stream) const override;
QDataStream &readFromStream(QDataStream &stream) override;
bool isValid() const override;
};
}
#endif // UPDATEPLAYERDATA_H

@ -1,71 +0,0 @@
#include "websocket.h"
namespace ClientProtocol {
WebSocket::WebSocket() {
_class = static_cast<quint8>(Command::WebSocket);
}
BaseNetworkObject *ClientProtocol::WebSocket::create() const {
return new WebSocket();
}
NetworkClassSize WebSocket::classSize() const {
return UpdatePlayerData::classSize() + getTypeSize(_data);
}
QDataStream &WebSocket::writeToStream(QDataStream &stream) const {
UpdatePlayerData::writeToStream(stream);
stream << _data;
return stream;
}
QDataStream &WebSocket::readFromStream(QDataStream &stream) {
UpdatePlayerData::readFromStream(stream);
stream >> _data;
return stream;
}
bool WebSocket::isValid() const {
return static_cast<Command>(_data.cmd) != Command::Undefined &&
UpdatePlayerData::isValid();
}
bool WebSocket::isSubscribe() const {
return _data.subscribe;
}
Command WebSocket::getCommand() const {
return static_cast<Command>(_data.cmd);
}
int WebSocket::getObjectId() const {
return _data.objectId;
}
void WebSocket::setSubscribe(bool subscribe){
_data.subscribe = subscribe;
}
void WebSocket::setCommand(Command cmd) {
_data.cmd = static_cast<unsigned char>(cmd);
}
void WebSocket::setObjectId(int value) {
_data.objectId = value;
}
QDataStream &operator<<(QDataStream &stream, WebSocketData data) {
stream.writeRawData(reinterpret_cast<char*>(&data), sizeof (data));
return stream;
}
QDataStream &operator>>(QDataStream &stream, WebSocketData &data) {
stream.readRawData(reinterpret_cast<char*>(&data), sizeof (data));
return stream;
}
}

@ -1,41 +0,0 @@
#ifndef WEBSOCKET_H
#define WEBSOCKET_H
#include "updateplayerdata.h"
#include "clientprotocol.h"
namespace ClientProtocol {
#pragma pack(push, 1)
struct WebSocketData {
unsigned char cmd : 5;
unsigned subscribe : 1;
int objectId : 26; // -1 is all ovjects, or other bumber is number of object
friend QDataStream& operator<< (QDataStream& stream, WebSocketData data);
friend QDataStream& operator>> (QDataStream& stream, WebSocketData& data);
};
#pragma pack(pop)
class CLIENTPROTOCOLSHARED_EXPORT WebSocket : public UpdatePlayerData
{
WebSocketData _data;
public:
WebSocket();
BaseNetworkObject *create() const override;
NetworkClassSize classSize() const override;
QDataStream &writeToStream(QDataStream &stream) const override;
QDataStream &readFromStream(QDataStream &stream) override;
bool isValid() const override;
bool isSubscribe() const;
Command getCommand() const;
int getObjectId() const;
void setSubscribe(bool subscribe);
void setCommand(Command cmd) ;
void setObjectId(int value);
};
}
#endif // WEBSOCKET_H

@ -1,438 +0,0 @@
#include "client.h"
#include <QRegularExpression>
#include <QTcpSocket>
#include <QVariantMap>
#include <QDateTime>
#include <quasarapp.h>
#include <qrsaencryption.h>
#include <pubkey.h>
#include <websocket.h>
#include "factorynetobjects.h"
#include "gamedata.h"
#include "getitem.h"
#include "login.h"
#include "updateplayerdata.h"
#include <QHash>
#include <player.h>
#define SOLT "SNAKE"
namespace ClientProtocol {
Command Client::checkCommand(int sig, Command reqCmd, Type type) {
#define idx static_cast<quint8>(sig)
auto expCmd = static_cast<Command>(
_requestsMap[idx].value("expected",
static_cast<quint8>(Command::Undefined)).toInt());
if (expCmd == Command::Undefined ||
expCmd != reqCmd ||
type != Type::Responke) {
return Command::Undefined;
}
_requestsMap[idx]["time"] = QDateTime::currentMSecsSinceEpoch();
return expCmd;
}
void Client::updateStatuses(Command extCmd, Command cmd, Type type, const QByteArray& obj)
{
setOnlineStatus(extCmd != Command::Undefined && type == Type::Responke);
if (extCmd == Command::Login
&& type == Type::Responke) {
UpdatePlayerData data;
data.fromBytes(obj);
bool validData = data.isValid();
if (validData) {
_token = data.getToken();
}
_currentUserId = data.id();
setLoginStatus(cmd == Command::UpdatePlayerData && validData);
}
}
bool Client::receiveData(const QByteArray &obj, Header hdr) {
auto command = static_cast<Command>(hdr.command);
auto requesCommand = static_cast<Command>(hdr.requestCommand);
auto type = static_cast<Type>(hdr.type);
if (command == Command::PubKey && !_rsaKey.size()) {
PubKey data;
data.fromBytes(obj);
return setRSAKey(data.getKey());;
}
if (type != Type::Stream) {
auto expectedCommand = checkCommand(hdr.sig, requesCommand, type);
if (expectedCommand == Command::Undefined) {
QuasarAppUtils::Params::verboseLog("wrong sig of package");
return false;
}
updateStatuses(expectedCommand, command, type, obj);
} else if (_subscribe.contains(hdr.command)) {
_subscribe[hdr.command] = true;
} else {
return false;
}
emit sigIncommingData(static_cast<Command>(hdr.command), obj);
return true;
}
bool Client::setRSAKey(const QByteArray& key) {
bool newStatus = QRSAEncryption::isValidRsaKey(key);
setOnlineStatus(newStatus);
if (newStatus) {
_rsaKey = key;
}
return newStatus;
}
void Client::setLoginStatus(bool newStatus) {
if (newStatus != _logined) {
_logined = newStatus;
emit loginChanged(_logined);
}
}
void Client::setOnlineStatus(bool newOnline) {
if (newOnline != _online) {
_online = newOnline;
emit onlineChanged(_online);
if (!_online) {
_rsaKey = "";
setLoginStatus(false);
}
}
}
void Client::incommingData() {
auto array = _destination->readAll();
if (_downloadPackage.hdr.isValid()) {
_downloadPackage.data.append(array);
} else {
memcpy(&_downloadPackage.hdr,
array.data(), sizeof(Header));
_downloadPackage.data.append(array.mid(sizeof(Header)));
}
if (_downloadPackage.isValid()) {
if (!receiveData(_downloadPackage.data, _downloadPackage.hdr)) {
// ban
}
_downloadPackage.reset();
return;
}
}
void Client::handleDisconnected() {
setOnlineStatus(false);
}
Client::Client(const QString &addrress, unsigned short port, QObject *ptr):
QObject (ptr) {
_destination = new QTcpSocket(this);
connectToHost(addrress, port);
connect(_destination, &QTcpSocket::readyRead,
this, &Client::incommingData);
connect(_destination, &QTcpSocket::disconnected,
this, &Client::handleDisconnected);
}
bool Client::sendPackage(Package &pkg) {
if (!pkg.isValid()) {
return false;
}
if (!_destination->isValid()) {
qCritical() << "destination server not valid!";
return false;
}
if (!_destination->waitForConnected()) {
qCritical() << "no connected to server! " << _destination->errorString();
return false;
}
auto index = nextIndex();
_requestsMap[index] = {{"expected", static_cast<const unsigned short>(pkg.hdr.command)}};
pkg.hdr.sig = index;
QByteArray bytes = pkg.toBytes();
bool sendet = bytes.size() == _destination->write(bytes);
return sendet;
}
unsigned char Client::nextIndex() {
return static_cast<unsigned char>((currentIndex++) % 256);
}
bool Client::ping() {
Package pcg;
if (!pcg.create(Command::Ping, Type::Request)) {
return false;
};
if (!sendPackage(pcg)) {
return false;
}
return true;
}
/// Do not change the order of this function,
/// as this may lead to the loss of user accounts.
QByteArray Client::generateHash(const QByteArray& pass) const {
auto passHash = QCryptographicHash::hash(pass, QCryptographicHash::Sha256);
return QCryptographicHash::hash(SOLT + passHash, QCryptographicHash::Sha256);
}
bool Client::login(const QString &gmail, const QByteArray &pass, bool newUser) {
if (!pass.size()) {
return false;
}
if (!gmail.size()) {
return false;
}
if (!isOnline()) {
return false;
}
Package pcg;
Login login;
login.setHashPass(QRSAEncryption::encode(generateHash(pass), _rsaKey, QRSAEncryption::RSA_256));
login.setGmail(gmail);
login.setId(0);
login.setRegisterNewUser(newUser);
if (!login.isValid()) {
return false;
}
if (!pcg.create(&login, Type::Request)) {
return false;
};
if (!sendPackage(pcg)) {
return false;
}
return true;
}
bool Client::registration(const QString &gmail,
const QByteArray &pass) {
return login(gmail, pass, true);
}
void Client::loginOut() {
_token = "";
setLoginStatus(false);
}
void Client::dissconnectFromHost() {
loginOut();
_destination->disconnectFromHost();
}
void Client::connectToHost(const QString &address, unsigned short port) {
_destination->connectToHost(_address = address, _port = port);
}
void Client::reconnectToHost() {
_destination->connectToHost(_address, _port);
}
bool Client::updateData() {
if (!isLogin()) {
return false;
}
Package pcg;
UpdatePlayerData rec;
rec.setToken(_token);
rec.setId(0);
if (!rec.isValid()) {
return false;
}
if (!pcg.create(&rec, Type::Request)) {
return false;
};
if (!sendPackage(pcg)) {
return false;
}
return true;
}
bool Client::savaData(const QList<int>& gameData) {
if (!isLogin()) {
return false;
}
Package pcg;
GameData rec;
rec.setToken(_token);
rec.setTimeClick(gameData);
rec.setId(0);
if (!rec.isValid()) {
return false;
}
if (!pcg.create(&rec, Type::Request)) {
return false;
};
if (!sendPackage(pcg)) {
return false;
}
return true;
}
bool Client::getItem(int id) {
if (!isLogin()) {
return false;
}
if (id <= 0) {
return false;
}
Package pcg;
GetItem rec;
rec.setToken(_token);
rec.setId(id);
if (!rec.isValid()) {
return false;
}
if (!pcg.create(&rec, Type::Request)) {
return false;
};
if (!sendPackage(pcg)) {
return false;
}
return true;
}
bool Client::getPlayer(int id){
if (!isLogin()) {
return false;
}
if (id <= 0) {
return false;
}
Package pcg;
UpdatePlayerData rec;
rec.setToken(_token);
rec.setId(id);
if (!rec.isValid()) {
return false;
}
if (!pcg.create(&rec, Type::Request)) {
return false;
};
if (!sendPackage(pcg)) {
return false;
}
return true;
}
const bool& Client::isOnline() const {
return _online;
}
const bool& Client::isLogin() const {
return _logined;
}
bool Client::setSubscribe(Command cmd, bool subscribe, int id) {
if (!isLogin()) {
return false;
}
Package pcg;
WebSocket rec;
rec.setId(0);
rec.setToken(_token);
rec.setCommand(cmd);
rec.setObjectId(id);
rec.setSubscribe(subscribe);
if (!rec.isValid()) {
return false;
}
if (!pcg.create(&rec, Type::Stream)) {
return false;
};
if (!sendPackage(pcg)) {
return false;
}
if (subscribe)
_subscribe[static_cast<quint8>(cmd)] = false;
else {
_subscribe.remove(static_cast<quint8>(cmd));
}
return true;
}
QHash<quint8, bool> Client::getSubscribe() const {
return _subscribe;
}
}

@ -1,156 +0,0 @@
#ifndef CLIENT_CP_H
#define CLIENT_CP_H
#include "clientprotocol_global.h"
#include "clientprotocol.h"
#include <QObject>
#include <QSet>
class QTcpSocket;
class Player;
class BaseItem;
class testSankeServer;
namespace ClientProtocol {
class CLIENTPROTOCOLSHARED_EXPORT Client: public QObject
{
Q_OBJECT
private:
QTcpSocket *_destination;
Package _downloadPackage;
bool _online = false;
bool _logined = false;
QByteArray _token;
QByteArray _rsaKey;
int currentIndex = 0;
QHash<unsigned char, QVariantMap> _requestsMap;
QHash<quint8, bool> _subscribe; // command and data confirmation
QString _address = LOCAL_SNAKE_SERVER;
unsigned short _port = DEFAULT_SNAKE_PORT;
/**
* @brief checkCommand - return old sendet command if commnad not valid return undefined command
* @param sig - sig package
* @param reqCmd - reqCmd of package
* @param type - type of package
* @return if commnad not valid return undefined command
*/
Command checkCommand(int sig, Command reqCmd, Type type);
bool receiveData(const QByteArray &obj, Header hdr);
bool setRSAKey(const QByteArray &key);
void setLoginStatus(bool newStatus);
void setOnlineStatus(bool newStatus);
bool sendPackage(Package &pkg);
inline unsigned char nextIndex();
QByteArray generateHash(const QByteArray &pass) const;
void updateStatuses(Command extCmd, Command cmd, Type type, const QByteArray &obj);
private slots:
void incommingData();
void handleDisconnected();
protected:
int _currentUserId = -1;
public:
explicit Client(const QString& addrress = LOCAL_SNAKE_SERVER,
unsigned short port = DEFAULT_SNAKE_PORT,
QObject * ptr = nullptr);
/**
* @brief login - register or login a user
* @param gmail - gmail of user
* @param pass - hash of pass of user
* @param error - error ( if all good this variable is empty)
* @return true if message sendet
*/
bool virtual login(const QString& gmail, const QByteArray &pass, bool newUser = false);
/**
* @brief registration - it is wraper of login method
* @return true if message sendet
*/
bool virtual registration(const QString& gmail, const QByteArray &pass);
bool ping();
void loginOut();
void dissconnectFromHost();
void connectToHost(const QString &addrress, unsigned short port);
void reconnectToHost();
/**
* @brief updateData
* @return true if refresh seсcessfully completed
*/
bool updateData();
/**
* @brief savedata
* @param gameData - data of lvl
* @return true if all good
*/
bool savaData(const QList<int> &gameData);
/**
* @brief getItem
* @param id of item
* @return item data
*/
bool getItem(int id);
/**
* @brief getPlayer
* @param id of player
* @return player data
*/
bool getPlayer(int id);
/**
* @brief isOnline
* @return true if client is connected to server and get rsapub key
*/
const bool &isOnline() const;
/**
* @brief isLogin
* @return true if player is online
*/
const bool &isLogin() const;
/**
* @brief setSubscribe change subscribe of command "cmd"
* @param cmd - command of subscribe
* @param subscribe - boolean barametr. true is subscribe, false is unsubscribe
* @param id - id of object for commands (Player and Item).
* If this parameter is -1 then subscribe on all changes of objects.
* @return true if all good
*/
bool setSubscribe(Command cmd, bool subscribe, int id = -1);
/**
* @brief getSubscribe
* @return set of current subscribe commands
*/
QHash<quint8, bool> getSubscribe() const;
friend class ::testSankeServer;
signals:
void sigIncommingData(Command cmd, const QByteArray& obj);
void onlineChanged(bool);
void loginChanged(bool);
};
}
#endif // CLIENT_CP_H

@ -1,214 +0,0 @@
#include "clientprotocol.h"
#include "gamedata.h"
#include "getitem.h"
#include "login.h"
#include "player.h"
#include "updateplayerdata.h"
#include <QDataStream>
#include <QVariantMap>
#include <factorynetobjects.h>
#include <map.h>
#include <pubkey.h>
#include <snake.h>
#include <websocket.h>
#define DEFAULT_GAME_PORT 7777
namespace ClientProtocol {
Header::Header() {
reset();
}
bool Header::isValid() const {
if (sizeof (*this) != 4) {
return false;
}
if (static_cast<Command>(command) == Command::Undefined) {
return false;
}
if (static_cast<Type>(type) == Type::Undefined) {
return false;
}
if (static_cast<Type>(type) == Type::Responke) {
return static_cast<Command>(command) != Command::Undefined;
}
return isValidSize(command, size);
}
void Header::reset() {
size = 0;
command = static_cast<quint8>(Command::Undefined);
type = static_cast<quint8>(Type::Responke);
}
Package::Package() {
reset();
}
bool Package::isValid() const {
if (!hdr.isValid()) {
return false;
}
if (data.size() && hdr.command != data.at(0)) {
return false;
}
return hdr.size == static_cast<unsigned int> (data.size());
}
BaseNetworkObject* Package::parse() const {
if (!isValid())
return nullptr;
auto obj = FactoryNetObjects::build(hdr.command);
if (!obj) {
return nullptr;
}
QDataStream stream(data);
obj->readFromStream(stream);
return obj;
}
bool Package::create(const BaseNetworkObject *obj, Type type, const Header *old) {
if (!obj) {
return false;
}
auto command = static_cast<Command>(obj->getClass());
if (command == Command::Undefined) {
return false;
}
QDataStream stream(&data, QIODevice::ReadWrite);
obj->writeToStream(stream);
return create(command, type, old);
}
bool Package::create(Command cmd, Type type, const QByteArray &data, const Header* old) {
this->data = data;
return create(cmd, type, old);
}
bool Package::create(Command cmd, Type type, const Header *old) {
if (cmd == Command::Undefined) {
return false;
}
hdr.command = static_cast<quint8>(cmd);
hdr.type = static_cast<quint8>(type);
hdr.size = static_cast<unsigned short>(data.size());
if (type == Type::Responke) {
signPackage(old);
}
return isValid();
}
QByteArray Package::toBytes() const {
QByteArray res;
res.append(reinterpret_cast<char*>(const_cast<Header*>(&hdr)),
sizeof (hdr));
res.append(data);
return res;
}
void Package::reset() {
hdr.reset();
data.clear();
}
bool Package::signPackage(const Header *oldHeader) {
if (!oldHeader || !oldHeader->isValid()) {
return false;
}
hdr.sig = oldHeader->sig;
hdr.requestCommand = oldHeader->command;
return true;
}
bool isValidSize(quint8 type, unsigned int size) {
if (!FactoryNetObjects::isInited()) {
return false;
}
if (!FactoryNetObjects::isRegisteredType(type)) {
return size == 0;
}
return FactoryNetObjects::getSize(type).isValid(size);
}
bool initClientProtockol() {
if (!FactoryNetObjects::regType<Login>(
static_cast<quint8>(Command::Login))) {
return false;
}
if (!FactoryNetObjects::regType<UpdatePlayerData>(
static_cast<quint8>(Command::UpdatePlayerData))) {
return false;
}
if (!FactoryNetObjects::regType<GameData>(
static_cast<quint8>(Command::GameData))) {
return false;
}
if (!FactoryNetObjects::regType<GetItem>(
static_cast<quint8>(Command::GetItem))) {
return false;
}
if (!FactoryNetObjects::regType<Player>(
static_cast<quint8>(Command::Player))) {
return false;
}
if (!FactoryNetObjects::regType<Snake>(
static_cast<quint8>(Command::Snake))) {
return false;
}
if (!FactoryNetObjects::regType<Map>(
static_cast<quint8>(Command::Map))) {
return false;
}
if (!FactoryNetObjects::regType<PubKey>(
static_cast<quint8>(Command::PubKey))) {
return false;
}
if (!FactoryNetObjects::regType<WebSocket>(
static_cast<quint8>(Command::WebSocket))) {
return false;
}
return true;
}
}

@ -1,188 +0,0 @@
#ifndef CLIENTPROTOCOL_H
#define CLIENTPROTOCOL_H
#include "clientprotocol_global.h"
#include <QVariantMap>
#include <snakeutils.h>
#include "config.h"
#define BASE_ENCRYPTION_BITS 256
#define BASE_RSA_BITS static_cast<QRSAEncryption::Rsa>(BASE_ENCRYPTION_BITS)
#define BASE_HASH_BITS 256
namespace ClientProtocol {
class BaseNetworkObject;
enum class Type: quint8 {
Undefined = 0x00,
Responke = 0x01,
Request = 0x02,
Stream = 0x03,
};
enum class Command: quint8 {
Undefined = 0x00,
Ping = 0x01,
BadRequest = 0x02,
Login = 0x03,
UpdatePlayerData = 0x04,
GameData = 0x05,
GetItem = 0x06,
Player = 0x07,
Snake = 0x08,
Map = 0x09,
PubKey = 0x0a,
WebSocket = 0x0b
};
bool isValidSize(quint8 type, unsigned int size);
bool CLIENTPROTOCOLSHARED_EXPORT initClientProtockol();
auto cast(const BaseNetworkObject *obj);
/**
* @brief The Header struct 4 byte
*/
#pragma pack(push, 1)
struct CLIENTPROTOCOLSHARED_EXPORT Header {
/**
* @brief size - size of package data (not header)
*/
unsigned short size: 12;
/**
* @brief type of package see Type
*/
quint8 type: 2;
/**
* @brief command of pacage see Command
*/
quint8 command: 5;
/**
* @brief command of pacage see Command (rquest from client)
* the server should write to which command it responds
*/
quint8 requestCommand: 5;
/**
* @brief sig
* signed of package (package number)
*/
unsigned char sig : 8;
/**
* @brief Header default constructor
*/
Header();
/**
* @brief isValid
* @return true if header is valid
*/
bool isValid() const;
/**
* @brief reset - reset all data and set for header invalid status
*/
void reset();
};
#pragma pack(pop)
/**
* @brief The Package struct
*/
struct CLIENTPROTOCOLSHARED_EXPORT Package {
/**
* @brief hdr - header of package
*/
Header hdr;
/**
* @brief data - source data of package
*/
QByteArray data;
Package();
/**
* @brief isValid
* @return true if package is valid
*/
virtual bool isValid() const;
/**
* @brief parse
* @return Qmap of package (default key if "value")
*/
BaseNetworkObject * parse() const;
template<class T>
bool parse(T& res) {
auto obj = static_cast<T*>(parse());
if (!obj)
return false;
res = *obj;
delete obj;
return true;
}
/**
* @brief create - fill package
* @param data - data of filled
* @param old header (only for request type)
* @return true if all done
*/
bool create(const BaseNetworkObject *data, Type type, const Header *old = nullptr);
/**
* @brief create
* @param cmd command of package
* @param type type
* @param data - data of filled
* @param old - header (only for request type)
* @return true if all good
*/
bool create(Command cmd, Type type, const QByteArray& data, const Header* old = nullptr);
/**
* @brief create
* @param cmd command of package
* @param type type
* @param old header (only for request type)
* @return true if all good
*/
bool create(Command cmd, Type type, const Header* old = nullptr);
/**
* @brief toBytes
* @return bytes array of packag
*/
QByteArray toBytes() const;
/**
* @brief reset - reset all data and set for package invalid status
*/
void reset();
/**
* @brief signPackage sign package from old data
* @param oldHeader old data header
* @return true if all good
*/
bool signPackage(const Header* oldHeader);
virtual ~Package() = default;
};
}
#endif // CLIENTPROTOCOL_H

@ -1,12 +0,0 @@
#ifndef CLIENTPROTOCOL_GLOBAL_H
#define CLIENTPROTOCOL_GLOBAL_H
#include <QtCore/qglobal.h>
#if defined(CLIENTPROTOCOL_LIBRARY)
# define CLIENTPROTOCOLSHARED_EXPORT Q_DECL_EXPORT
#else
# define CLIENTPROTOCOLSHARED_EXPORT Q_DECL_IMPORT
#endif
#endif // CLIENTPROTOCOL_GLOBAL_H

@ -1,10 +0,0 @@
#ifndef CONFIG_H
#define CONFIG_H
#define LOCAL_SNAKE_SERVER "127.0.0.1"
#define DEFAULT_SNAKE_PORT 7777
#define MAX_SIZE 100
#define MIN_SIZE 1
#endif // CONFIG_H

@ -1,81 +0,0 @@
#include "connectioninfo.h"
#include <QTcpSocket>
namespace ClientProtocol {
int Connectioninfo::getKarma() const {
return karma;
}
void Connectioninfo::setKarma(int value) {
karma = value;
if (isBaned()) {
disconnect();
}
}
RSAKeyPair Connectioninfo::getRSAKey() const {
return RSAKey;
}
void Connectioninfo::setRSAKey(const RSAKeyPair &value) {
RSAKey = value;
}
QTcpSocket *Connectioninfo::getSct() const {
return sct;
}
void Connectioninfo::setSct(QTcpSocket *value) {
sct = value;
}
QByteArray Connectioninfo::getToken() const {
return token;
}
void Connectioninfo::setToken(const QByteArray &value) {
token = value;
}
void Connectioninfo::disconnect() {
if (sct) {
sct->close();
token = "";
sct->deleteLater();
sct = nullptr;
}
}
void Connectioninfo::ban() {
karma = BANED_KARMA;
disconnect();
}
bool Connectioninfo::isBaned() const {
return karma < 1;
}
void Connectioninfo::unBan() {
karma = RESTORE_KARMA;
}
bool Connectioninfo::isValid() const {
return sct && !RSAKey.pub.isEmpty() && !RSAKey.priv.isEmpty();
}
Connectioninfo::Connectioninfo(QTcpSocket *tcp, int kar, RSAKeyPair keys) {
sct = tcp;
karma = kar;
RSAKey = keys;
token = "";
}
Connectioninfo::~Connectioninfo() {
if (sct) {
sct->deleteLater();
}
}
}

@ -1,46 +0,0 @@
#ifndef CONNECTIONINFO_H
#define CONNECTIONINFO_H
#include "rsakeyspool.h"
#include "clientprotocol_global.h"
class QTcpSocket;
namespace ClientProtocol {
#define NOT_VALID_CARMA 0xFF
#define DEFAULT_KARMA 100
#define RESTORE_KARMA 20
#define BANED_KARMA 0
class CLIENTPROTOCOLSHARED_EXPORT Connectioninfo {
QTcpSocket *sct = nullptr;
int karma = DEFAULT_KARMA;
RSAKeyPair RSAKey;
QByteArray token;
public:
void disconnect();
void ban();
bool isBaned() const;
void unBan();
bool isValid() const;
Connectioninfo(QTcpSocket * tcp = nullptr,
int kar = NOT_VALID_CARMA,
RSAKeyPair keys = RSAKeyPair());
~Connectioninfo();
int getKarma() const;
void setKarma(int value);
RSAKeyPair getRSAKey() const;
void setRSAKey(const RSAKeyPair &value);
QTcpSocket *getSct() const;
void setSct(QTcpSocket *value);
QByteArray getToken() const;
void setToken(const QByteArray &value);
};
}
#endif // CONNECTIONINFO_H

@ -1,6 +0,0 @@
#ifndef CP_H
#define CP_H
#include "server.h"
#include "client.h"
#endif // CP_H

@ -1,6 +0,0 @@
#ifndef CPSERVER_H
#define CPSERVER_H
#include "server.h"
#endif // CPSERVER_H

@ -1,40 +0,0 @@
#include "factorynetobjects.h"
#include "clientprotocol.h"
namespace ClientProtocol {
QMap<quint8, BaseNetworkObject*> map;
QMap<quint8, NetworkClassSize> types_sizes;
BaseNetworkObject *FactoryNetObjects::build(quint8 type) {
if (!map.contains(type)) {
return nullptr;
}
return map.value(type)->create();
}
BaseNetworkObject *FactoryNetObjects::build(quint8 type, const QByteArray &array) {
auto temp = build(type);
if (!temp) {
return temp;
}
temp->fromBytes(array);
return temp;
}
NetworkClassSize FactoryNetObjects::getSize(quint8 type) {
return types_sizes.value(type, 0);
}
bool FactoryNetObjects::isRegisteredType(quint8 type) {
return map.contains(type);
}
bool FactoryNetObjects::isInited() {
return map.size();
}
}

@ -1,40 +0,0 @@
#ifndef FACTORYNETOBJECTS_H
#define FACTORYNETOBJECTS_H
#include "clientprotocol_global.h"
#include "basenetworkobject.h"
#include <QMap>
#include <typeinfo>
namespace ClientProtocol {
extern QMap<quint8, BaseNetworkObject*> map;
extern QMap<quint8, NetworkClassSize> types_sizes;
class CLIENTPROTOCOLSHARED_EXPORT FactoryNetObjects {
private:
public:
FactoryNetObjects() = delete;
static BaseNetworkObject *build(quint8 type);
static BaseNetworkObject *build(quint8 type, const QByteArray& array);
static NetworkClassSize getSize(quint8 type);
static bool isRegisteredType(quint8 type);
static bool isInited();
template<typename T>
static bool regType(quint8 id) {
if (map.contains(id)) {
return false;
}
auto tempObj = new T();
map.insert(id, tempObj);
types_sizes.insert(id, tempObj->classSize());
return true;
}
};
}
#endif // FACTORYNETOBJECTS_H

@ -1,32 +0,0 @@
#include "networkclasssize.h"
namespace ClientProtocol {
bool NetworkClassSize::isStaticType() {
return min == max;
}
NetworkClassSize::NetworkClassSize(unsigned int size) {
operator=(size);
}
NetworkClassSize::NetworkClassSize(unsigned int min, unsigned int maxDif) {
operator=(min);
max += maxDif;
}
NetworkClassSize &NetworkClassSize::operator =(unsigned int size) {
min = max = size;
return *this;
}
NetworkClassSize &NetworkClassSize::operator +(const NetworkClassSize & other) {
min += other.min;
max += other.max;
return *this;
}
bool NetworkClassSize::isValid(unsigned int size) const {
return size <= max && size >= min;
}
}

@ -1,25 +0,0 @@
#ifndef NETWORKCLASSSIZE_H
#define NETWORKCLASSSIZE_H
#include "clientprotocol_global.h"
namespace ClientProtocol {
struct CLIENTPROTOCOLSHARED_EXPORT NetworkClassSize {
unsigned int min = 0;
unsigned int max = 0;
bool isStaticType();
NetworkClassSize(unsigned int size);
NetworkClassSize(unsigned int min, unsigned int max);
NetworkClassSize& operator = (unsigned int size);
NetworkClassSize& operator + (const NetworkClassSize& );
bool isValid(unsigned int size) const;
};
}
#endif // NETWORKCLASSSIZE_H

@ -1,27 +0,0 @@
#include "rsakeyspool.h"
#include <QMutexLocker>
namespace ClientProtocol {
bool RSAKeysPool::take(QRSAEncryption::Rsa rsa, RSAKeyPair& res) {
QMutexLocker locker(&multithread);
if (pool.value(rsa).isEmpty()) {
emit sigKeyTaked();
return false;
}
res = pool.value(rsa).begin().value();
return true;
}
void RSAKeysPool::addNewKey(QRSAEncryption::Rsa rsa, const RSAKeyPair& key) {
QMutexLocker locker(&multithread);
pool[rsa].insert(static_cast<int>(time(nullptr)), key);
}
int RSAKeysPool::size(QRSAEncryption::Rsa rsa) const {
return pool.value(rsa).size();
}
}

@ -1,37 +0,0 @@
#ifndef RSAKEYSPOOL_H
#define RSAKEYSPOOL_H
#include <QHash>
#include <QObject>
#include <qrsaencryption.h>
#include <QMutex>
#include <QMap>
#include "clientprotocol_global.h"
namespace ClientProtocol {
struct RSAKeyPair {
QByteArray pub;
QByteArray priv;
};
typedef QMap<int, RSAKeyPair> KeysPool;
typedef QHash<QRSAEncryption::Rsa, KeysPool> PoolData;
class CLIENTPROTOCOLSHARED_EXPORT RSAKeysPool: public QObject {
Q_OBJECT
private:
PoolData pool;
QMutex multithread;
public:
bool take(QRSAEncryption::Rsa rsa, RSAKeyPair &res);
void addNewKey(QRSAEncryption::Rsa rsa, const RSAKeyPair& key);
int size(QRSAEncryption::Rsa rsa) const;
signals:
void sigKeyTaked();
};
}
#endif // RSAKEYSPOOL_H

@ -1,415 +0,0 @@
#include "server.h"
#include "quasarapp.h"
#include <QTcpSocket>
#include <factorynetobjects.h>
#include <pubkey.h>
#include "clientprotocol.h"
namespace ClientProtocol {
bool Server::parsePackage(const Package &pkg, QTcpSocket* sender) {
if (!pkg.isValid()) {
QuasarAppUtils::Params::verboseLog("incomming package is not valid!");
changeKarma(sender->peerAddress().toIPv4Address(), CRITICAL_ERROOR);
return false;
}
if (!sender->isValid()) {
QuasarAppUtils::Params::verboseLog("incomming package is not valid!");
changeKarma(sender->peerAddress().toIPv4Address(), LOGICK_ERROOR);
return false;
}
switch (static_cast<Command>(pkg.hdr.command)) {
case Command::Ping: {
if (static_cast<Type>(pkg.hdr.type) != Type::Request) {
return false;
}
Package pcg;
if (!(pcg.create(Command::Ping, Type::Responke, &pkg.hdr))) {
return false;
};
if (!sendPackage(pcg, sender)) {
QuasarAppUtils::Params::verboseLog("!responce not sendet!");
}
break;
}
default: {
emit incomingReques(pkg.hdr, pkg.data,
sender->peerAddress().toIPv4Address());
}
}
return true;
}
bool Server::sendPackage(const Package &pkg, QTcpSocket * target) {
if (!pkg.isValid()) {
return false;
}
if (!target || !target->isValid()) {
qCritical() << "destination server not valid!";
return false;
}
if (!target->waitForConnected()) {
qCritical() << "no connected to server! " << target->errorString();
return false;
}
auto bytes = pkg.toBytes();
bool sendet = bytes.size() == target->write(bytes);
return sendet;
}
void Server::ban(quint32 target) {
if (!_connections[target]) {
_connections[target] = new Connectioninfo();
}
_connections[target]->ban();
}
void Server::unBan(quint32 target) {
if (!_connections.contains(target)) {
return;
}
_connections[target]->unBan();
}
bool Server::registerSocket(QTcpSocket *socket) {
auto address = socket->peerAddress().toIPv4Address();
if (!_pool) {
QuasarAppUtils::Params::verboseLog("key pool is not inited", QuasarAppUtils::Error);
return false;
}
RSAKeyPair pair;
if (!_pool->take(BASE_RSA_BITS, pair)) {
QuasarAppUtils::Params::verboseLog("key pool is empty", QuasarAppUtils::Error);
return false;
}
_connections[address] = new Connectioninfo(socket, DEFAULT_KARMA,
pair);
connect(socket, &QTcpSocket::readyRead, this, &Server::avelableBytes);
connect(socket, &QTcpSocket::disconnected, this, &Server::handleDisconected);
if (!sendPubKey(socket, pair.pub)) {
QuasarAppUtils::Params::verboseLog("not sendet pub key to client"
"generate new key!", QuasarAppUtils::Error);
return false;
}
return true;
}
bool Server::changeKarma(quint32 addresss, int diff) {
auto ptr = _connections.value(addresss);
if (!ptr) {
return false;
}
auto objKarma = ptr->getKarma();
if (objKarma >= NOT_VALID_CARMA) {
return false;
}
if (objKarma <= BANED_KARMA) {
return false;
}
ptr->setKarma(objKarma + diff);
return true;
}
bool Server::isBaned(const QTcpSocket * adr) const {
auto ptr = _connections.value(adr->peerAddress().toIPv4Address());
if (!ptr) {
return false;
}
return ptr->isBaned();
}
int Server::connectionsCount() const {
int count = 0;
for (auto i : _connections) {
if (i->getSct()) {
if (!i->getSct()->isValid()) {
QuasarAppUtils::Params::verboseLog("connection count, findet not valid socket",
QuasarAppUtils::Warning);
}
count++;
}
}
return count;
}
bool Server::sendPubKey(QTcpSocket * target, const QByteArray &pubKey) {
Package pcg;
PubKey pubkey;
pubkey.setKey(pubKey);
pubkey.setTypeKey(BASE_RSA_BITS);
pubkey.setId(0);
if (!pubkey.isValid()) {
return false;
}
if (!(pcg.create(&pubkey, Type::Request))) {
return false;
};
return sendPackage(pcg, target);
}
void Server::avelableBytes() {
auto client = dynamic_cast<QTcpSocket*>(sender());
if (!client) {
return;
}
auto array = client->readAll();
if (_downloadPackage.hdr.isValid()) {
_downloadPackage.data.append(array);
} else {
_downloadPackage.reset();
memcpy(&_downloadPackage.hdr,
array.data(), sizeof(Header));
_downloadPackage.data.append(array.mid(sizeof(Header)));
}
if (_downloadPackage.isValid()) {
parsePackage(_downloadPackage, client);
}
if (_downloadPackage.data.size() >= _downloadPackage.hdr.size) {
_downloadPackage.reset();
}
}
void Server::handleDisconected() {
auto _sender = dynamic_cast<QTcpSocket*>(sender());
if (_sender) {
// log error
unsigned int address = _sender->peerAddress().toIPv4Address();
auto ptr = _connections.value(address);
if (ptr) {
ptr->disconnect();
} else {
QuasarAppUtils::Params::verboseLog("system error in void Server::handleDisconected()"
" address not valid",
QuasarAppUtils::Error);
}
return;
}
QuasarAppUtils::Params::verboseLog("system error in void Server::handleDisconected()"
"dynamic_cast fail!",
QuasarAppUtils::Error);
}
void Server::handleIncommingConnection() {
while (hasPendingConnections()) {
auto socket = nextPendingConnection();
if (isBaned(socket)) {
socket->abort();
continue;
}
registerSocket(socket);
}
}
Server::Server(RSAKeysPool *pool, QObject *ptr) :
QTcpServer (ptr) {
_pool = pool;
connect(this, &Server::newConnection, this, &Server::handleIncommingConnection);
}
Server::~Server() {
stop();
}
bool Server::run(const QString &ip, unsigned short port) {
if (!listen(QHostAddress(ip), port)) {
QuasarAppUtils::Params::verboseLog("listing fail " + this->errorString(),
QuasarAppUtils::Error);
return false;
}
return true;
}
void Server::stop(bool reset) {
close();
if (reset) {
for (auto &&i : _connections) {
i->disconnect();
}
_connections.clear();
}
}
void Server::badRequest(quint32 address, const Header &req) {
auto client = _connections.value(address);
if (!client) {
QuasarAppUtils::Params::verboseLog("Bad request detected, bud responce command not sendet!"
" because client == null",
QuasarAppUtils::Error);
return;
}
if (!changeKarma(address, REQUEST_ERROR)) {
QuasarAppUtils::Params::verboseLog("Bad request detected, bud responce command not sendet!"
" because karma not changed",
QuasarAppUtils::Error);
return;
}
Package pcg;
if (!(pcg.create(Command::BadRequest, Type::Responke, &req))) {
QuasarAppUtils::Params::verboseLog("Bad request detected, bud responce command not sendet!"
" because package not created",
QuasarAppUtils::Error);
};
if (!sendPackage(pcg, client->getSct())) {
QuasarAppUtils::Params::verboseLog("Bad request detected, bud responce command not sendet!"
" because karma not changed",
QuasarAppUtils::Error);
return;
}
QuasarAppUtils::Params::verboseLog("Bad request sendet to adderess: " +
client->getSct()->peerAddress().toString(),
QuasarAppUtils::Info);
}
bool Server::sendResponse(const BaseNetworkObject *resp, quint32 address, const Header *req) {
Package pcg;
if (!pcg.create(resp, Type::Responke, req)) {
QuasarAppUtils::Params::verboseLog("Response not sent because package not created",
QuasarAppUtils::Error);
}
return sendResponse(&pcg, address, req);
}
bool Server::sendResponse(Package *pcg, quint32 address, const Header *req) {
pcg->signPackage(req);
return sendResponse(*pcg, address);
}
bool Server::sendResponse(const Package &pcg, quint32 address)
{
auto client = _connections.value(address);
if (!client) {
QuasarAppUtils::Params::verboseLog("Response not sent because client == null",
QuasarAppUtils::Error);
return false;
}
if (!sendPackage(pcg, client->getSct())) {
QuasarAppUtils::Params::verboseLog("Response not sent!",
QuasarAppUtils::Error);
return false;
}
return true;
}
QString Server::getWorkState() const {
if (isListening()) {
if (hasPendingConnections())
return "overload";
else {
return "Work";
}
}
return "Not running";
}
QString Server::connectionState() const {
return QString("%0 / %1").arg(connectionsCount()).arg(maxPendingConnections());
}
QStringList Server::baned() const {
QStringList list = {};
for (auto i = _connections.begin(); i != _connections.end(); ++i) {
if (i.value()->isBaned()) {
list.push_back(QHostAddress(i.key()).toString());
}
}
return list;
}
bool Server::getRSA(quint32 key, RSAKeyPair& res) const {
auto sct = _connections.value(key);
if (sct) {
res = sct->getRSAKey();
return true;
}
return false;
}
QByteArray Server::getToken(quint32 address) const {
return _connections.value(address)->getToken();
}
bool Server::setToken(quint32 address, const QByteArray &token) {
if (_connections.contains(address)) {
_connections[address]->setToken(token);
return true;
}
return false;
}
}

@ -1,80 +0,0 @@
#ifndef SERVER_CP_H
#define SERVER_CP_H
#include "clientprotocol_global.h"
#include "clientprotocol.h"
#include <QTcpServer>
#include "rsakeyspool.h"
#include "connectioninfo.h"
namespace ClientProtocol {
#define CRITICAL_ERROOR -50
#define LOGICK_ERROOR -20
#define REQUEST_ERROR -5
class CLIENTPROTOCOLSHARED_EXPORT Server : public QTcpServer
{
Q_OBJECT
private:
Package _downloadPackage;
QHash<quint32, Connectioninfo*> _connections;
RSAKeysPool * _pool = nullptr;
bool parsePackage(const Package &pkg, QTcpSocket * sender);
bool sendPackage(const Package &pkg, QTcpSocket * target);
bool registerSocket(QTcpSocket *socket);
bool changeKarma(quint32 addresss, int diff);
inline bool isBaned(const QTcpSocket *) const;
int connectionsCount() const;
bool sendPubKey(QTcpSocket *target, const QByteArray &pubKey);
private slots:
void avelableBytes();
void handleDisconected();
void handleIncommingConnection();
public:
explicit Server(RSAKeysPool * pool, QObject * ptr = nullptr);
~Server() override;
bool run(const QString& ip, unsigned short port);
void stop(bool reset = false);
void badRequest(quint32 address, const Header &req);
bool sendResponse(const BaseNetworkObject* resp, quint32 address,
const Header *req = nullptr);
bool sendResponse(Package *pcg, quint32 address, const Header *req = nullptr);
bool sendResponse(const Package &pcg, quint32 address);
void ban(quint32 target);
void unBan(quint32 target);
/**
* @brief getWorkState
* @return string of work state
*/
QString getWorkState() const;
/**
* @brief connectionState
* @return string with count users state
*/
QString connectionState() const;
QStringList baned() const;
bool getRSA(quint32, RSAKeyPair & res) const;
QByteArray getToken(quint32 address) const;
bool setToken(quint32 address, const QByteArray &token);
signals:
void incomingReques(Header hdr, const QByteArray &data, const quint32 &sender);
};
}
#endif // SERVER_CP_H

@ -1,36 +0,0 @@
QT -= gui
QT += network
CONFIG += c++17 console
CONFIG -= app_bundle
# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
main.cpp
TARGET = SnakeServer-daemon
CONFIG(release, debug|release): {
DESTDIR = $$PWD/build/release
} else {
DESTDIR = $$PWD/build/debug
}
HEADERS +=
include($$PWD/../../QuasarAppLib/QuasarLib.pri)
include($$PWD/../ServerProtocol/ServerProtocol.pri)
include($$PWD/../ClientProtocol/ClientProtocol.pri)
include($$PWD/../../SnakeUtils/SnakeUtils.pri)
include($$PWD/../Server/Server.pri)

@ -1,34 +0,0 @@
QT -= gui
CONFIG += c++17 console
CONFIG -= app_bundle
# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
main.cpp \
serverutils.cpp
CONFIG(release, debug|release): {
DESTDIR = $$PWD/build/release
} else {
DESTDIR = $$PWD/build/debug
}
include($$PWD/../QuasarAppLib/Etalons/qmake/install_prefix.pri)
include($$PWD/../QuasarAppLib/QuasarLib.pri)
target_dir.files += QUASARAPP_LIB_OUTPUT_DIR
HEADERS += \
serverutils.h

@ -1,51 +0,0 @@
#include <QCoreApplication>
#include <serverutils.h>
#include <quasarapp.h>
#include <serverutils.h>
#include <mainserver.h>
int main(int argc, char *argv[])
{
if (!ServerUtils::parseParams(argc, argv)) {
ServerUtils::helpDaemon();
return 1;
}
if (QuasarAppUtils::Params::isEndable("help") ||
QuasarAppUtils::Params::isEndable("h")) {
ServerUtils::helpDaemon();
return 0;
}
QString address = "";
unsigned short port = 0;
QString db = "";
if(QuasarAppUtils::Params::isEndable("address")) {
address = QuasarAppUtils::Params::getStrArg("address");
}
if(QuasarAppUtils::Params::isEndable("port")) {
port = static_cast<unsigned short>(QuasarAppUtils::Params::getArg("port").toUInt());
}
if(QuasarAppUtils::Params::isEndable("db")) {
db = QuasarAppUtils::Params::getStrArg("db");
}
if(ServerUtils::runDaemon()) {
return 0;
}
QCoreApplication a(argc, argv);
MainServer mainServer(false, nullptr);
if (!mainServer.run(address, port, db)) {
QuasarAppUtils::Params::verboseLog("server is not run!");
ServerUtils::helpDaemon();
return 1;
}
return a.exec();
}

@ -1 +0,0 @@
Subproject commit 29bdfc6e8182615b782f2f5abdca6427f718208e

@ -1,23 +0,0 @@
#
# Copyright (C) 2018 - 2019 QuasarApp.
# Distributed under the lgplv3 software license, see the accompanying
# Everyone is permitted to copy and distribute verbatim copies
# of this license document, but changing it is not allowed.
#
!isEmpty(SERVER_LIB):error("Server.pri already included")
SERVER_LIB = 1
#DEPENDS
CONFIG(release, debug|release): {
SERVER_LIB_OUTPUT_DIR="$$PWD/build/release"
} else {
SERVER_LIB_OUTPUT_DIR="$$PWD/build/debug"
}
LIBS += -L$$SERVER_LIB_OUTPUT_DIR -lServer
INCLUDEPATH += "$$PWD/"

@ -1,59 +0,0 @@
#-------------------------------------------------
#
# Project created by QtCreator 2019-02-16T12:24:27
#
#-------------------------------------------------
QT -= gui
QT += network sql concurrent
TARGET = Server
TEMPLATE = lib
DEFINES += SERVER_LIBRARY
# The following define makes your compiler emit warnings if you use
# any feature of Qt which has been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
item.cpp \
keysreactor.cpp \
mainserver.cpp \
playerdbdata.cpp \
sqldbcache.cpp \
sqldbwriter.cpp \
websocketcontroller.cpp
TARGET = Server
CONFIG(release, debug|release): {
DESTDIR = $$PWD/build/release
} else {
DESTDIR = $$PWD/build/debug
}
HEADERS += \
item.h \
keysreactor.h \
mainserver.h \
playerdbdata.h \
server_global.h \
sqldbcache.h \
sqldbwriter.h \
websocketcontroller.h
include($$PWD/../../QuasarAppLib/QuasarLib.pri)
include($$PWD/../ServerProtocol/ServerProtocol.pri)
include($$PWD/../ClientProtocol/ClientProtocol.pri)
include($$PWD/../../SnakeUtils/SnakeUtils.pri)
RESOURCES += sqlres.qrc

@ -1,72 +0,0 @@
#include "item.h"
#include "factorynetobjects.h"
#include <exception>
#include <quasarapp.h>
int Item::getId() const {
return id;
}
bool Item::setId(int value) {
id = value;
if (data.size() < static_cast<int>(sizeof (id) + sizeof (ClientProtocol::Command))) {
return false;
}
int oldSize = data.size();
data.replace(sizeof (ClientProtocol::Command), sizeof (id),
reinterpret_cast<char*>(&id), sizeof (id));
return data.size() == oldSize;
}
Item::Item() {
}
Item::Item(const ClientProtocol::Package &other) {
hdr = other.hdr;
data = other.data;
ClientProtocol::BaseNetworkObject base;
base.fromBytes(data);
id = base.id();
}
Item::Item(const ClientProtocol::BaseNetworkObject *obj) {
if (!create(obj, ClientProtocol::Type::Stream)) {
QuasarAppUtils::Params::verboseLog("Error create Item from BaseNetworkObject",
QuasarAppUtils::VerboseLvl::Error);
}
id = obj->id();
}
Item::Item(ClientProtocol::Command cmd, const QByteArray &data) {
if (!create(cmd, ClientProtocol::Type::Stream, data)) {
QuasarAppUtils::Params::verboseLog("Error create Item from QByteArray",
QuasarAppUtils::VerboseLvl::Error);
}
ClientProtocol::BaseNetworkObject base;
base.fromBytes(data);
id = base.id();
}
Item::~Item() {
}
ClientProtocol::Command Item::cmd() const {
return static_cast<ClientProtocol::Command>(hdr.command);
}
const QByteArray &Item::dataArray() const {
return data;
}
bool Item::isValid() const {
return ClientProtocol::FactoryNetObjects::isRegisteredType(hdr.type)
&& Package::isValid();
}

@ -1,30 +0,0 @@
#ifndef ITEM_H
#define ITEM_H
#include <clientprotocol.h>
#include "server_global.h"
class SERVERSHARED_EXPORT Item : public ClientProtocol::Package
{
private:
int id = -1;
public:
Item();
Item(const ClientProtocol::Package& other);
Item(const ClientProtocol::BaseNetworkObject* obj);
Item(ClientProtocol::Command cmd, const QByteArray& data);
~Item() override;
ClientProtocol::Command cmd() const;
const QByteArray& dataArray() const;
bool isValid() const override;
int getId() const;
bool setId(int value);
template<class T>
bool parse(T& res) {
return ClientProtocol::Package::parse(res);
}
};
#endif // ITEM_H

@ -1,89 +0,0 @@
#include "keysreactor.h"
ClientProtocol::RSAKeysPool *KeysReactor::getPool() {
return &_pool;
}
int KeysReactor::getPoolSize() const {
return _poolSize;
}
void KeysReactor::setPoolSize(int value) {
if (_poolSize != value) {
_poolSize = value;
handleGenerateNewKeys();
}
}
void KeysReactor::generateKeys(QRSAEncryption::Rsa rsa) {
QByteArray pub, priv;
if (_poolSize > _pool.size(rsa)) {
QRSAEncryption::generatePairKey(pub, priv, rsa);
_pool.addNewKey(rsa, {pub, priv});
}
return;
}
void KeysReactor::handleGenerateNewKeys() {
auto generatorFunc = [this] (QRSAEncryption::Rsa rsa) {
if (_mutexs[rsa]) {
return;
}
_mutexs[rsa] = true;
QByteArray pub, priv;
while (_poolSize > _pool.size(rsa)) {
QRSAEncryption::generatePairKey(pub, priv, rsa);
_pool.addNewKey(rsa, {pub, priv});
}
_mutexs[rsa] = false;
return;
};
_futures.insert(QRSAEncryption::RSA_64,
QtConcurrent::run(generatorFunc, QRSAEncryption::RSA_64));
_futures.insert(QRSAEncryption::RSA_128,
QtConcurrent::run(generatorFunc, QRSAEncryption::RSA_128));
_futures.insert(QRSAEncryption::RSA_256,
QtConcurrent::run(generatorFunc, QRSAEncryption::RSA_256));
_futures.insert(QRSAEncryption::RSA_512,
QtConcurrent::run(generatorFunc, QRSAEncryption::RSA_512));
}
KeysReactor::KeysReactor(bool ForceGenerateKey, QObject *ptr):
QObject (ptr) {
_mutexs[QRSAEncryption::RSA_64] = false;
_mutexs[QRSAEncryption::RSA_128] = false;
_mutexs[QRSAEncryption::RSA_256] = false;
_mutexs[QRSAEncryption::RSA_512] = false;
if (ForceGenerateKey) {
generateKeys(QRSAEncryption::RSA_64);
generateKeys(QRSAEncryption::RSA_128);
generateKeys(QRSAEncryption::RSA_256);
generateKeys(QRSAEncryption::RSA_512);
}
handleGenerateNewKeys();
connect(&_pool, &ClientProtocol::RSAKeysPool::sigKeyTaked,
this, &KeysReactor::handleGenerateNewKeys);
}
KeysReactor::~KeysReactor() {
for (auto && i: _futures) {
i.cancel();
i.waitForFinished();
}
}

@ -1,35 +0,0 @@
#ifndef KEYSREACTOR_H
#define KEYSREACTOR_H
#include <qrsaencryption.h>
#include <QtConcurrent>
#include <rsakeyspool.h>
#include "server_global.h"
#define DEFAULT_KEYPOOL_SIZE 10
class SERVERSHARED_EXPORT KeysReactor: public QObject
{
Q_OBJECT
private:
ClientProtocol::RSAKeysPool _pool;
int _poolSize = DEFAULT_KEYPOOL_SIZE;
QHash<QRSAEncryption::Rsa, bool> _mutexs;
QHash<QRSAEncryption::Rsa, QFuture<void>> _futures;
void generateKeys(QRSAEncryption::Rsa);
private slots:
void handleGenerateNewKeys();
public:
KeysReactor(bool ForceGenerateKey, QObject *ptr = nullptr);
~KeysReactor() override;
ClientProtocol::RSAKeysPool* getPool();
int getPoolSize() const;
void setPoolSize(int value);
};
#endif // KEYSREACTOR_H

@ -1,320 +0,0 @@
#include "keysreactor.h"
#include "mainserver.h"
#include "playerdbdata.h"
#include "sqldbcache.h"
#include "websocketcontroller.h"
#include <spserver.h>
#include <cpserver.h>
#include <quasarapp.h>
#include <basenetworkobject.h>
#include <login.h>
#include <QCoreApplication>
#include <rsakeyspool.h>
#include <getitem.h>
#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 {};
}
if (_db->getPlayerId(login.getGmail()) > -1) {
return {};
}
PlayerDBData player;
player.setGmail( login.getGmail());
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 {};
}
auto pass = QRSAEncryption::decode(login.getHashPass(), rsa.priv, BASE_RSA_BITS);
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<ClientProtocol::Command>(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 (loginData.getRegisterNewUser()) {
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: {
ClientProtocol::UpdatePlayerData request;
request.fromBytes(data);
auto tocken = _serverDaemon->getToken(addres);
if (!tocken.isEmpty() && tocken == request.getToken()) {
auto player = _db->getPlayer(request.id());
_serverDaemon->sendResponse(&player, addres, &hdr);
}
_serverDaemon->badRequest(addres, hdr);
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;
}
case ClientProtocol::Command::WebSocket: {
ClientProtocol::WebSocket websocket;
websocket.fromBytes(data);
if (websocket.isSubscribe()) {
_websocketctrl->subscribe(addres, websocket.getCommand(),
websocket.getObjectId());
} else {
_websocketctrl->unsubscribe(addres, websocket.getCommand(),
websocket.getObjectId());
}
break;
}
default:
_serverDaemon->badRequest(addres, hdr);
break;
}
}
void MainServer::handleTerminalRequest(QVariantMap obj) {
auto command = static_cast<ServerProtocol::Command>(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<quint16>(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);
_websocketctrl = new WebSocketController(_serverDaemon, 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);
connect(_db, &SqlDBCache::sigItemChanged,
_websocketctrl, &WebSocketController::handleItemChanged);
connect(_db, &SqlDBCache::sigPlayerChanged,
_websocketctrl, &WebSocketController::handlePlayerChanged);
if (!ClientProtocol::initClientProtockol()){
QuasarAppUtils::Params::verboseLog("clientProtocol no inited", QuasarAppUtils::Error);
}
}
bool MainServer::run(const QString &ip, unsigned short port, const QString& db,
const QString& terminalServer) {
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, true)) {
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() {
}

@ -1,56 +0,0 @@
#ifndef SERVER_H
#define SERVER_H
#include <serverprotocol.h>
#include "server_global.h"
#include <QHostAddress>
#include <clientprotocol.h>
namespace ServerProtocol {
class Server;
}
namespace ClientProtocol {
class Server;
class BaseNetworkObject;
class Login;
class RSAKeyPair;
}
class KeysReactor;
class SqlDBCache;
class PlayerDBData;
class WebSocketController;
class SERVERSHARED_EXPORT MainServer: public QObject
{
Q_OBJECT
private:
ServerProtocol::Server *_terminalPort = nullptr;
ClientProtocol::Server *_serverDaemon= nullptr;
SqlDBCache *_db = nullptr;
KeysReactor *_keyReactor = nullptr;
WebSocketController* _websocketctrl = nullptr;
bool payItem(int player, int idItem);
bool sellItem(int player, int idItem);
QByteArray generateTocket(const QString& gmail) const;
QByteArray registerPlayer(const ClientProtocol::Login &login,
const ClientProtocol::RSAKeyPair &rsa) const;
QByteArray loginPlayer(const ClientProtocol::Login& login,
const ClientProtocol::RSAKeyPair& rsa) const;
bool restartSrver(const QString& ip, unsigned short port);
private slots:
void handleRequest(ClientProtocol::Header hdr, const QByteArray &data,
const quint32& addres);
void handleTerminalRequest(QVariantMap obj);
public:
MainServer(bool forceKeys, QObject *ptr = nullptr);
bool run(const QString& ip = "", unsigned short port = 0, const QString &db = "",
const QString &terminalServer = "");
virtual ~MainServer();
};
#endif // SERVER_H

@ -1,39 +0,0 @@
#include "playerdbdata.h"
int PlayerDBData::getLastOnline() const {
return lastOnline;
}
void PlayerDBData::setLastOnline(int value) {
lastOnline = value;
}
int PlayerDBData::getOnlineTime() const {
return onlineTime;
}
void PlayerDBData::setOnlineTime(int value) {
onlineTime = value;
}
QByteArray PlayerDBData::getPass() const {
return pass;
}
void PlayerDBData::setPass(const QByteArray &value) {
pass = value;
}
QString PlayerDBData::getHexPass() const {
return getPass().toHex();
}
void PlayerDBData::fromHexPass(const QString &passHex) {
setPass(QByteArray::fromHex(passHex.toLatin1()));
}
PlayerDBData::PlayerDBData()
{
}

@ -1,27 +0,0 @@
#ifndef PLAYERDBDATA_H
#define PLAYERDBDATA_H
#include <player.h>
#include "server_global.h"
class SERVERSHARED_EXPORT PlayerDBData: public ClientProtocol::Player
{
private:
int lastOnline = 0;
int onlineTime = 0;
QByteArray pass = "";
public:
PlayerDBData();
int getLastOnline() const;
void setLastOnline(int value);
int getOnlineTime() const;
void setOnlineTime(int value);
QByteArray getPass() const;
void setPass(const QByteArray &value);
QString getHexPass() const;
void fromHexPass(const QString &passHex);
};
#endif // PLAYERDBDATA_H

@ -1,12 +0,0 @@
#ifndef SERVER_GLOBAL_H
#define SERVER_GLOBAL_H
#include <QtCore/qglobal.h>
#if defined(SERVER_LIBRARY)
# define SERVERSHARED_EXPORT Q_DECL_EXPORT
#else
# define SERVERSHARED_EXPORT Q_DECL_IMPORT
#endif
#endif // SERVER_GLOBAL_H

@ -1,40 +0,0 @@
PRAGMA foreign_keys = ON;
CREATE TABLE IF NOT EXISTS items(
id INTEGER PRIMARY KEY NOT NULL,
type INTEGER NOT NULL,
data BLOB NOT NULL
);
CREATE TABLE IF NOT EXISTS players(
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
name VARCHAR(100) NOT NULL,
pass VARCHAR(32) NOT NULL,
gmail VARCHAR(64) NOT NULL UNIQUE,
money INTEGER NOT NULL DEFAULT 0,
avgrecord INTEGER NOT NULL DEFAULT 0,
record INTEGER NOT NULL DEFAULT 0,
lastOnline date not null DEFAULT 0,
onlinetime INTEGER not null DEFAULT 0,
currentsnake INTEGER DEFAULT NULL,
FOREIGN KEY(currentsnake) REFERENCES items(id)
ON UPDATE CASCADE
ON DELETE SET NULL
);
CREATE TABLE IF NOT EXISTS owners(
player INTEGER NOT NULL,
item INTEGER NOT NULL,
FOREIGN KEY(player) REFERENCES players(id)
ON UPDATE CASCADE
ON DELETE CASCADE
FOREIGN KEY(item) REFERENCES items(id)
ON UPDATE CASCADE
ON DELETE CASCADE
);
CREATE UNIQUE INDEX IF NOT EXISTS iowners ON owners(player,item);

@ -1,383 +0,0 @@
#include "sqldbcache.h"
#include "quasarapp.h"
#include "playerdbdata.h"
#include <qtconcurrentrun.h>
#include <clientprotocol.h>
#include <QDateTime>
#include <basenetworkobject.h>
int SqlDBCache::generateIdForItem() const {
if (items.isEmpty()) {
return 0;
}
return items.lastKey() + 1;
}
int SqlDBCache::generateIdForPalyer() const {
if (players.isEmpty()) {
return 0;
}
return players.lastKey() + 1;
}
bool SqlDBCache::checkPlayer(int id) {
if (players.contains(id)) {
return true;
}
if (SqlDBWriter::checkPlayer(id)) {
if (savePlayer(getPlayer(id)) < 0) {
QuasarAppUtils::Params::verboseLog("not saved data into cache "
" SqlDBCashe::checkPlayer");
}
return true;
}
return false;
}
bool SqlDBCache::checkItem(int idItem, int idOwner) {
if (idOwner >= 0 ) {
if (owners.contains(idOwner)) {
auto items = owners.value(idOwner);
return items.contains(idItem);
}
if (SqlDBWriter::checkItem(idItem)) {
QSet<int> items;
if (!SqlDBWriter::getAllItemsOfPalyer(idOwner, items)) {
QuasarAppUtils::Params::verboseLog("not loaded owners data from cache "
" SqlDBCashe::checkItem");
}
owners.insert(idOwner, items);
return true;
}
return false;
}
if (items.contains(idItem)) {
return true;
}
if (SqlDBWriter::checkItem(idItem)) {
auto item = getItem(idItem);
if (saveItem(item) < 0) {
QuasarAppUtils::Params::verboseLog("not saved data into cache "
" SqlDBCashe::checkItem");
}
return true;
}
return false;
}
void SqlDBCache::globalUpdateDataBasePrivate(qint64 currentTime) {
for (auto item = items.begin(); item != items.end(); ++item) {
if (SqlDBWriter::saveItem(item.value()) < 0) {
QuasarAppUtils::Params::verboseLog("writeUpdateItemIntoDB failed when"
" work globalUpdateDataRelease!!! id=" +
QString::number(item.key()),
QuasarAppUtils::VerboseLvl::Error);
}
}
for (auto player = players.begin(); player != players.end(); ++player) {
if (SqlDBWriter::savePlayer(player.value()) < 0) {
QuasarAppUtils::Params::verboseLog("writeUpdatePlayerIntoDB failed when"
" work globalUpdateDataRelease!!! id=" +
QString::number(player.key()),
QuasarAppUtils::VerboseLvl::Error);
}
}
for (auto owner = owners.begin(); owner != owners.end(); ++owner) {
if (!SqlDBWriter::saveowners(owner.key(), owner.value())) {
QuasarAppUtils::Params::verboseLog("UpdateInfoOfowners failed when"
" work globalUpdateDataRelease!!! id=" +
QString::number(owner.key()),
QuasarAppUtils::VerboseLvl::Error);
}
}
lastUpdateTime = currentTime;
}
void SqlDBCache::globalUpdateDataBase(SqlDBCasheWriteMode mode) {
qint64 currentTime = QDateTime::currentMSecsSinceEpoch();
if (currentTime - lastUpdateTime > updateInterval ||
static_cast<bool>(mode & SqlDBCasheWriteMode::Force)) {
if (static_cast<bool>(mode & SqlDBCasheWriteMode::On_New_Thread)) {
QtConcurrent::run([currentTime, this](){
globalUpdateDataBasePrivate(currentTime);
});
} else {
globalUpdateDataBasePrivate(currentTime);
}
}
}
bool SqlDBCache::itemIsFreeFrom(int item) const {
return SqlDBWriter::itemIsFreeFrom(item);
}
SqlDBCache::SqlDBCache(qint64 updateInterval) {
lastUpdateTime = QDateTime::currentMSecsSinceEpoch();
this->updateInterval = updateInterval;
}
SqlDBCache::~SqlDBCache() {
globalUpdateDataBase(SqlDBCasheWriteMode::Force);
}
bool SqlDBCache::initDb(const QString &pdbath) {
if (!SqlDBWriter::initDb(pdbath)) {
return false;
}
getItem(getLastIdItems());
getPlayer(getLastIdPlayers());
return true;
}
Item SqlDBCache::getItem(int id) {
if (!isValid()) {
return Item();
}
auto item = items.value(id);
if (item.isValid()) {
return item;
}
item = SqlDBWriter::getItem(id);
if (item.isValid()) {
items.insert(id, item);
return item;
}
return Item();
}
int SqlDBCache::saveItem(const Item &saveData) {
if (!isValid()) {
return -1;
}
auto item = saveData;
int id = item.getId();
if (id < 0) {
id = generateIdForItem();
if (!item.setId(id)) {
return -1;
}
}
if (!item.isValid()) {
return -1;
}
items.insert(id, item);
globalUpdateDataBase(SqlDBCasheWriteMode::On_New_Thread);
emit sigItemChanged(id, item);
return id;
}
PlayerDBData SqlDBCache::getPlayer(int id) {
if (!isValid()) {
return PlayerDBData();
}
auto player = players.value(id);
if (player.isValid()) {
return player;
}
player = SqlDBWriter::getPlayer(id);
if (player.isValid()) {
players.insert(id, player);
return player;
}
return PlayerDBData();
}
int SqlDBCache::savePlayer(const PlayerDBData &saveData) {
if (!isValid()) {
return -1;
}
auto player = saveData;
int id = player.id();
if (id < 0) {
id = generateIdForPalyer();
player.setId(id);
}
if (!player.isValid()) {
return -1;
}
int curSnake = player.getCureentSnake();
if (curSnake >= 0 && !checkItem(curSnake, id)) {
return -1;
}
players.insert(id, player);
playersIds.insert(player.getGmail(), id);
globalUpdateDataBase(SqlDBCasheWriteMode::On_New_Thread);
emit sigPlayerChanged(id, player);
return id;
}
bool SqlDBCache::login(const QString &gmail, const QString &pass) {
if (!isValid()) {
return false;
}
int id = getPlayerId(gmail);
if (id < 0) {
return false;
}
auto player = getPlayer(id);
if (!player.isValid()) {
return false;
}
return player.getHexPass() == pass;
}
bool SqlDBCache::giveAwayItem(int player, int item) {
if (!isValid()) {
return false;
}
if (!checkItem(item, player)) {
return false;
}
if (owners.contains(player)) {
auto &owner = owners[player];
owner.remove(item);
auto &p = players[player];
if (p.getCureentSnake() == item) {
p.setCureentSnake(-1);
}
globalUpdateDataBase(SqlDBCasheWriteMode::On_New_Thread);
return true;
}
return false;
}
bool SqlDBCache::getItem(int player, int item, bool check) {
if (!isValid()) {
return false;
}
if (!(checkPlayer(player) && checkItem(item))) {
return false;
}
if (check && !itemIsFreeFrom(item)) {
return false;
}
if (owners.contains(player)) {
auto &owner = owners[player];
owner.insert(item);
globalUpdateDataBase(SqlDBCasheWriteMode::On_New_Thread);
return true;
}
QSet<int> items;
if (!getAllItemsOfPalyer(player, items)) {
return false;
}
if (owners.contains(player)) {
auto &owner = owners[player];
owner.insert(item);
globalUpdateDataBase(SqlDBCasheWriteMode::On_New_Thread);
return true;
}
return false;
}
bool SqlDBCache::moveItem(int owner, int receiver, int item) {
if (!(giveAwayItem(owner, item) && getItem(receiver, item, false))) {
return false;
}
sigItemChanged(item, getItem(item));
return true;
}
int SqlDBCache::getPlayerId(const QString &gmail) {
int id = playersIds.value(gmail, -1);
if (id < 0) {
id = SqlDBWriter::getPlayerId(gmail);
if (id >= 0) {
playersIds[gmail] = id;
}
return id;
}
return id;
}
bool SqlDBCache::getAllItemsOfPalyer(int player, QSet<int> &items) {
if (owners.contains(player)) {
items = owners[player];
return true;
}
if (SqlDBWriter::getAllItemsOfPalyer(player, items) &&
checkPlayer(player)) {
owners.insert(player, items);
return true;
}
return false;
}

@ -1,74 +0,0 @@
#ifndef SQLDBCASHE_H
#define SQLDBCASHE_H
#include "sqldbwriter.h"
#include <QMap>
#include <QHash>
#include <QSet>
#include <QVariantMap>
#include <player.h>
#include "item.h"
#include <clientprotocol.h>
enum class SqlDBCasheWriteMode: int {
Default = 0x0,
On_New_Thread = 0x1,
Force = 0x2,
} ;
namespace ClientProtocol {
class BaseNetworkObject;
}
class SERVERSHARED_EXPORT SqlDBCache: public QObject , private SqlDBWriter
{
Q_OBJECT
private:
qint64 lastUpdateTime = 0;
qint64 updateInterval = DEFAULT_UPDATE_INTERVAL;
QMap <int, Item> items;
QMap <int, PlayerDBData> players;
QHash <int, QSet<int>> owners;
QHash <QString, int> playersIds;
int generateIdForItem() const;
int generateIdForPalyer() const;
bool checkPlayer(int id) override;
bool checkItem(int idItem, int idOwner = -1) override;
void globalUpdateDataBasePrivate(qint64 currentTime);
void globalUpdateDataBase(SqlDBCasheWriteMode mode = SqlDBCasheWriteMode::Default);
bool itemIsFreeFrom(int item) const override ;
public:
SqlDBCache(qint64 updateInterval = DEFAULT_UPDATE_INTERVAL);
~SqlDBCache() override;
bool initDb(const QString &pdbath = DEFAULT_DB_PATH) override;
Item getItem(int id) override;
int saveItem(const Item& saveData) override;
PlayerDBData getPlayer(int id) override;
int savePlayer(const PlayerDBData &player) override;
bool login(const QString& gmail, const QString& pass);
bool giveAwayItem(int player, int item);
bool getItem(int player, int item, bool check = true);
bool moveItem(int owner, int receiver, int item);
int getPlayerId(const QString &gmail) override;
bool getAllItemsOfPalyer(int player, QSet<int>& items) override;
friend class testSankeServer;
signals:
void sigItemChanged(int id, const Item& newData);
void sigPlayerChanged(int id, const PlayerDBData& newData);
};
#endif // SQLDBCASHE_H

@ -1,460 +0,0 @@
#include "playerdbdata.h"
#include "sqldbwriter.h"
#include <QRegularExpression>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QDebug>
#include <QSqlError>
#include <quasarapp.h>
#include <clientprotocol.h>
#include <factorynetobjects.h>
bool SqlDBWriter::exec(QSqlQuery *sq,const QString& sqlFile) {
QFile f(sqlFile);
bool result = true;
if (f.open(QIODevice::ReadOnly)) {
QString temp, delimiter = ";";
QTextStream stream(&f);
stream.setCodec("UTF8");
while(!stream.atEnd()) {
temp += stream.readLine();
if (temp.lastIndexOf("delimiter", -1, Qt::CaseInsensitive) > -1) {
temp.remove("delimiter", Qt::CaseInsensitive);
int last = temp.indexOf(QRegularExpression("[^ \f\n\r\t\v]")) + 1;
int begin = temp.lastIndexOf(QRegularExpression("[^ \f\n\r\t\v]"));
delimiter = temp.mid(begin, last - begin);
temp = "";
} else {
if (temp.lastIndexOf(delimiter) >- 1) {
temp.remove(delimiter);
result = result && sq->exec(temp);
if (!result) {
qCritical() << sq->lastError().text();
f.close();
return false;
}
temp = "";
}
}
}
f.close();
return result;
}
return false;
}
bool SqlDBWriter::enableFK() const {
QString request = QString("PRAGMA foreign_keys = ON");
if (!query->exec(request)) {
QuasarAppUtils::Params::verboseLog("request error : " + query->lastError().text());
return false;
}
return true;
}
bool SqlDBWriter::disableFK() const {
QString request = QString("PRAGMA foreign_keys = OFF");
if (!query->exec(request)) {
QuasarAppUtils::Params::verboseLog("request error : " + query->lastError().text());
return false;
}
return true;
}
int SqlDBWriter::getLastIdItems() {
if (!SqlDBWriter::isValid()) {
return -1;
}
QString request = QString("SELECT MAX(id) FROM items");
if (!query->exec(request)) {
QuasarAppUtils::Params::verboseLog("request error : " + query->lastError().text());
return -1;
}
if (!query->next()) {
return -1;
}
auto res = query->value(0).toInt();
return res;
}
int SqlDBWriter::getLastIdPlayers() {
if (!SqlDBWriter::isValid()) {
return -1;
}
QString request = QString("SELECT MAX(id) FROM players");
if (!query->exec(request)) {
QuasarAppUtils::Params::verboseLog("request error : " + query->lastError().text());
return -1;
}
if (!query->next()) {
return -1;
}
return query->value(0).toInt();
}
int SqlDBWriter::getPlayerId(const QString &gmail) {
if (!SqlDBWriter::isValid()) {
return -1;
}
QString request = QString("SELECT id from players where gmail='%0'").arg(gmail);
if (!query->exec(request)) {
QuasarAppUtils::Params::verboseLog("request error : " + query->lastError().text());
return -1;
}
if (!query->next()) {
return -1;
}
return query->value("id").toInt();
}
bool SqlDBWriter::checkPlayer(int id) {
QString request = QString("SELECT id from players where id='%0'").arg(id);
if (!query->exec(request)) {
QuasarAppUtils::Params::verboseLog("request error : " + query->lastError().text());
return false;
}
if (!query->next()) {
return false;
}
return true;
}
bool SqlDBWriter::checkItem(int idItem, int idOwner) {
if (idOwner >= 0 ) {
if (!SqlDBWriter::checkPlayer(idOwner)) {
return false;
}
QString request = QString("SELECT item from owners where player='%0' and item='%1'").
arg(idOwner).arg(idItem);
if (!query->exec(request)) {
QuasarAppUtils::Params::verboseLog("request error : " + query->lastError().text());
return false;
}
if (!query->next()) {
return false;
}
return true;
}
QString request = QString("SELECT id from items where id='%0'").
arg(idItem);
if (!query->exec(request)) {
QuasarAppUtils::Params::verboseLog("request error : " + query->lastError().text());
return false;
}
if (!query->next()) {
return false;
}
return true;
}
int SqlDBWriter::savePlayer(const PlayerDBData &player) {
if (!SqlDBWriter::isValid()) {
return -1;
}
if (!player.isValid()) {
return -1;
}
QString request;
int id = player.id();
int curSnake = player.getCureentSnake();
if (curSnake >= 0 && !SqlDBWriter::checkItem(curSnake, id)) {
return -1;
}
if (SqlDBWriter::checkPlayer(id)) {
request = QString("UPDATE players SET name='%0', gmail='%1', pass='%2', money='%3',"
" avgrecord='%4', record='%5', lastOnline='%6',"
" onlinetime='%7', currentsnake='%8' WHERE id='%9' ").arg(
player.getName()).arg(
player.getGmail()).arg(
player.getHexPass()).arg(
player.getMany()).arg(
player.getAvgRecord()).arg(
player.getRecord()).arg(
player.getLastOnline()).arg(
player.getOnlineTime()).arg(
(curSnake >= 0)? QString::number(curSnake) : "NULL").arg(
id);
} else {
request = QString("INSERT INTO players(id, name, gmail, pass, money, avgrecord, record,"
" lastOnline, onlinetime, currentsnake) VALUES "
"('%0', '%1', '%2', '%3', '%4', '%5', '%6', '%7', '%8', '%9')").arg(
id).arg(
player.getName()).arg(
player.getGmail()).arg(
player.getHexPass()).arg(
player.getMany()).arg(
player.getAvgRecord()).arg(
player.getRecord()).arg(
player.getLastOnline()).arg(
player.getOnlineTime()).arg(
(curSnake >= 0)? QString::number(curSnake) : "NULL");
}
if (curSnake < 0 && !disableFK()) {
return false;
}
if (!query->exec(request)) {
QuasarAppUtils::Params::verboseLog("request error : " + query->lastError().text());
return -1;
}
if (curSnake < 0 && !enableFK()) {
return -1;
}
return id;
}
int SqlDBWriter::saveItem(const Item &item) {
if (!SqlDBWriter::isValid()) {
return -1;
}
if (!item.isValid()) {
return -1;
}
auto type = item.cmd();
int id = item.getId();
QByteArray bytes = item.dataArray();
QString request;
if (SqlDBWriter::checkItem(id)) {
request = QString("UPDATE items SET type='%1', data = :bytes where id = %0").
arg(id).
arg(static_cast<int>(type));
} else {
request = QString("INSERT INTO items(id, type, data) VALUES"
"('%0', '%1', :bytes)").
arg(id).
arg(static_cast<int>(type));
}
if (!query->prepare(request)) {
QuasarAppUtils::Params::verboseLog("request error : " + query->lastError().text());
return -1;
}
query->bindValue(":bytes", bytes);
if (!query->exec()) {
QuasarAppUtils::Params::verboseLog("request error : " + query->lastError().text());
return -1;
}
return id;
}
bool SqlDBWriter::getAllItemsOfPalyer(int player, QSet<int> &items) {
if (!SqlDBWriter::isValid()) {
return false;
}
QString request = QString("SELECT item from owners where player='%0'").arg(player);
if (!query->exec(request)) {
QuasarAppUtils::Params::verboseLog("request error : " + query->lastError().text());
return false;
}
while (query->next()) {
items.insert(query->value(0).toInt());
}
return true;
}
bool SqlDBWriter::saveowners(int player, const QSet<int> items) {
if (!SqlDBWriter::isValid()) {
return false;
}
QString request = QString("DELETE from owners where player='%0' ").
arg(player);
if (!query->exec(request)) {
QuasarAppUtils::Params::verboseLog("request error : " + query->lastError().text());
return false;
}
if (items.isEmpty()) {
return true;
}
request = QString("INSERT INTO owners(player, item) VALUES ");
for (int item: items) {
request.push_back("(" + QString::number(player) + "," + QString::number(item) + ")");
}
if (!query->exec(request)) {
QuasarAppUtils::Params::verboseLog(request);
QuasarAppUtils::Params::verboseLog("request error : " + query->lastError().text());
return false;
}
return true;
}
PlayerDBData SqlDBWriter::getPlayer(int id) {
if (!SqlDBWriter::isValid()) {
return PlayerDBData();
}
QString request = QString("SELECT * FROM players WHERE id=%0").arg(id);
if (!query->exec(request)) {
QuasarAppUtils::Params::verboseLog("request error : " + query->lastError().text());
return PlayerDBData();
}
if (!query->next()) {
return PlayerDBData();
}
auto player = PlayerDBData();
player.setId(id);
player.setName(query->value("name").toString());
player.setGmail(query->value("gmail").toString());
player.fromHexPass(query->value("pass").toString());
player.setMany(query->value("money").toUInt());
player.setAvgRecord(query->value("avgrecord").toUInt());
player.setRecord(query->value("record").toUInt());
player.setLastOnline(query->value("lastOnline").toInt());
player.setOnlineTime(query->value("onlinetime").toInt());
player.setCureentSnake(query->value("currentsnake").toInt());
return player;
}
Item SqlDBWriter::getItem(int id) {
if (!SqlDBWriter::isValid()) {
return Item();
}
QString request = QString("SELECT type, data FROM items WHERE id=%0").arg(id);
if (!query->exec(request)) {
QuasarAppUtils::Params::verboseLog("request error : " + query->lastError().text());
return Item();
}
if (!query->next()) {
return Item();
}
auto type = static_cast<ClientProtocol::Command>(query->value(0).toUInt());
auto data = query->value(1).toByteArray();
return Item(type, data);
}
bool SqlDBWriter::itemIsFreeFrom(int item) const {
if (!SqlDBWriter::isValid()) {
return false;
}
QString request = QString("SELECT player FROM owners WHERE player=%0").arg(item);
if (!query->exec(request)) {
QuasarAppUtils::Params::verboseLog("request error : " + query->lastError().text());
return false;
}
return !query->next();
}
SqlDBWriter::SqlDBWriter() {
}
bool SqlDBWriter::initDb(const QString &databasePath) {
QStringList drivers = QSqlDatabase::drivers();
db = new QSqlDatabase();
*db = QSqlDatabase::addDatabase("QSQLITE", QFileInfo(databasePath).fileName());
db->setDatabaseName(QFileInfo(databasePath).absoluteFilePath());
query = new QSqlQuery(*db);
if (!QDir("").mkpath(QFileInfo(databasePath).absolutePath())) {
return false;
}
if (!db->open()) {
return false;
}
if (!exec(query, ":/sql/DB")) {
return false;
}
initSuccessful = true;
return initSuccessful;
}
bool SqlDBWriter::isValid() const {
if (!db) {
return false;
}
return db->isValid() && db->isOpen() && initSuccessful;
}
SqlDBWriter::~SqlDBWriter() {
if (db) {
delete db;
}
if (query) {
delete query;
}
}

@ -1,64 +0,0 @@
#ifndef SQLDBWRITER_H
#define SQLDBWRITER_H
#include "item.h"
#include <QObject>
#include <QSqlDatabase>
#include <QDir>
#include <player.h>
#define DEFAULT_DB_NAME "SnakeDatabase.db"
#define DEFAULT_DB_PATH QDir::homePath() + "/SnakeServer/" + DEFAULT_DB_NAME
#define DEFAULT_UPDATE_INTERVAL 3600000 // 1 hour
class QSqlQuery;
class QSqlDatabase;
class QSqlQuery;
class PlayerDBData;
class SERVERSHARED_EXPORT SqlDBWriter
{
private:
bool exec(QSqlQuery *sq, const QString &sqlFile);
QSqlDatabase *db = nullptr;
QSqlQuery *query = nullptr;
bool initSuccessful = false;
bool enableFK() const;
bool disableFK() const;
protected:
int getLastIdItems();
int getLastIdPlayers();
virtual int getPlayerId(const QString &gmail);
virtual bool checkPlayer(int id);
virtual bool checkItem(int idItem, int idOwner = -1);
virtual int savePlayer(const PlayerDBData& player);
virtual int saveItem(const Item &item);
virtual bool saveowners(int player, const QSet<int>);
virtual bool getAllItemsOfPalyer(int player, QSet<int>& items);
virtual PlayerDBData getPlayer(int id);
virtual Item getItem(int id);
virtual bool itemIsFreeFrom(int item) const;
public:
SqlDBWriter();
virtual bool initDb(const QString &path = DEFAULT_DB_PATH);
virtual bool isValid() const;
virtual ~SqlDBWriter();
friend class testSankeServer;
};
#endif // SQLDBWRITER_H

@ -1,5 +0,0 @@
<RCC>
<qresource prefix="/sql">
<file alias="DB">sql/SnakeDB.sql</file>
</qresource>
</RCC>

@ -1,57 +0,0 @@
#include "item.h"
#include "playerdbdata.h"
#include "websocketcontroller.h"
#include <cpserver.h>
WebSocketController::WebSocketController(ClientProtocol::Server *server, QObject* obj):
QObject (obj) {
assert( server );
_serverDaemon = server;
}
void WebSocketController::subscribe(quint32 address, ClientProtocol::Command cmd, int id) {
_subscribs[static_cast<char>(cmd)].insert(address);
if (cmd == ClientProtocol::Command::Player || cmd == ClientProtocol::Command::GetItem) {
_subscribsObjIds[id].insert(address);
}
}
void WebSocketController::unsubscribe(quint32 address, ClientProtocol::Command cmd, int id) {
_subscribs[static_cast<char>(cmd)].remove(address);
if (cmd == ClientProtocol::Command::Player || cmd == ClientProtocol::Command::GetItem) {
_subscribsObjIds[id].remove(address);
}
}
void WebSocketController::foreachSubscribers(const Item &newData,
const QSet<quint32> &subscribersList) {
for (auto &&subscriber : subscribersList) {
if (_subscribs.value(static_cast<char>(ClientProtocol::Command::GetItem)).contains(subscriber)) {
_serverDaemon->sendResponse(newData, subscriber);
}
}
}
void WebSocketController::foreachSubscribers(const PlayerDBData &newData,
const QSet<quint32> &subscribersList){
for (auto &&subscriber : subscribersList) {
if (_subscribs.value(static_cast<char>(ClientProtocol::Command::GetItem)).contains(subscriber)) {
_serverDaemon->sendResponse(&newData, subscriber);
}
}
}
void WebSocketController::handleItemChanged(int id, const Item &newData) {
foreachSubscribers(newData, _subscribsObjIds.value(id));
foreachSubscribers(newData, _subscribsObjIds.value(-1));
}
void WebSocketController::handlePlayerChanged(int id, const PlayerDBData &newData) {
foreachSubscribers(newData, _subscribsObjIds.value(id));
foreachSubscribers(newData, _subscribsObjIds.value(-1));
}

@ -1,40 +0,0 @@
#ifndef WEBSOCKETCONTROLLER_H
#define WEBSOCKETCONTROLLER_H
#include <QObject>
#include <clientprotocol.h>
#include <QSet>
#include <QHash>
class Item;
class PlayerDBData;
namespace ClientProtocol {
class Server;
}
template <class KEY_TYPE, class VALUE_TYPE>
using MultiHash = QHash<KEY_TYPE, QSet<VALUE_TYPE>>;
class WebSocketController: public QObject
{
Q_OBJECT
private:
MultiHash<char, quint32> _subscribs;
MultiHash<int, quint32> _subscribsObjIds;
ClientProtocol::Server *_serverDaemon = nullptr;
void foreachSubscribers(const Item &newData, const QSet<quint32> &subscribersList);
void foreachSubscribers(const PlayerDBData &newData, const QSet<quint32> &subscribersList);
public:
WebSocketController(ClientProtocol::Server * server, QObject* obj = nullptr);
void subscribe(quint32 address, ClientProtocol::Command cmd, int id);
void unsubscribe(quint32 address, ClientProtocol::Command cmd, int id);
public slots:
void handleItemChanged(int id, const Item& newData);
void handlePlayerChanged(int id, const PlayerDBData& newData);
};
#endif // WEBSOCKETCONTROLLER_H

@ -1,23 +0,0 @@
#
# Copyright (C) 2018 - 2019 QuasarApp.
# Distributed under the lgplv3 software license, see the accompanying
# Everyone is permitted to copy and distribute verbatim copies
# of this license document, but changing it is not allowed.
#
!isEmpty(SERVERPROTOCOL_LIB):error("ServerProtocol.pri already included")
SERVERPROTOCOL_LIB = 1
#DEPENDS
CONFIG(release, debug|release): {
SERVERPROTOCOL_LIB_OUTPUT_DIR="$$PWD/build/release"
} else {
SERVERPROTOCOL_LIB_OUTPUT_DIR="$$PWD/build/debug"
}
LIBS += -L$$SERVERPROTOCOL_LIB_OUTPUT_DIR -lServerProtocol
INCLUDEPATH += "$$PWD/"

Some files were not shown because too many files have changed in this diff Show More