From 6ed6fc65551f8457d283be15ef16e35d9bd35818 Mon Sep 17 00:00:00 2001 From: EndrII Date: Tue, 25 May 2021 12:11:49 +0300 Subject: [PATCH] ref #30 new structure ("using QuasarApp Cmake Project") --- .gitignore | 79 +- .gitmodules | 10 - CMakeLists.txt | 60 + Deploy/SnakeProject.json | 19 + LICENSE | 165 + QuasarAppLib | 1 - README.md | 16 +- SnakeClient/SnakeApp/SnakeApp.pro | 116 - .../SnakeApp/android/AndroidManifest.xml | 79 - SnakeClient/SnakeApp/android/build.gradle | 57 - .../android/gradle/wrapper/gradle-wrapper.jar | Bin 54329 -> 0 bytes .../gradle/wrapper/gradle-wrapper.properties | 5 - SnakeClient/SnakeApp/android/gradlew | 172 - SnakeClient/SnakeApp/android/gradlew.bat | 84 - .../android/res/drawable-hdpi/icon.png | Bin 2461 -> 0 bytes .../android/res/drawable-ldpi/icon.png | Bin 2461 -> 0 bytes .../android/res/drawable-mdpi/icon.png | Bin 2461 -> 0 bytes .../SnakeApp/android/res/values/libs.xml | 25 - .../back-end/ProfileViewItems/mainclient.cpp | 180 - .../back-end/ProfileViewItems/mainclient.h | 51 - .../ProfileViewItems/mainmenumodel.cpp | 59 - .../back-end/ProfileViewItems/mainmenumodel.h | 51 - .../ProfileViewItems/networkclient.cpp | 23 - .../back-end/ProfileViewItems/networkclient.h | 21 - .../ProfileViewItems/notificationdata.cpp | 38 - .../ProfileViewItems/notificationdata.h | 41 - .../ProfileViewItems/notificationservice.cpp | 38 - .../ProfileViewItems/notificationservice.h | 39 - .../ProfileViewItems/playerclientdata.cpp | 6 - .../ProfileViewItems/playerclientdata.h | 11 - .../ProfileViewItems/settingsviewmodel.cpp | 57 - .../ProfileViewItems/settingsviewmodel.h | 42 - .../back-end/ProfileViewItems/userview.cpp | 78 - .../back-end/ProfileViewItems/userview.h | 52 - .../SnakeApp/back-end/asyncimageresponse.cpp | 23 - .../SnakeApp/back-end/asyncimageresponse.h | 24 - SnakeClient/SnakeApp/back-end/background.cpp | 20 - SnakeClient/SnakeApp/back-end/background.h | 16 - .../SnakeApp/back-end/backgrounditem.cpp | 19 - .../SnakeApp/back-end/backgrounditem.h | 15 - SnakeClient/SnakeApp/back-end/baseclass.cpp | 17 - SnakeClient/SnakeApp/back-end/baseclass.h | 17 - SnakeClient/SnakeApp/back-end/box.cpp | 12 - SnakeClient/SnakeApp/back-end/box.h | 13 - SnakeClient/SnakeApp/back-end/clientapp.cpp | 50 - SnakeClient/SnakeApp/back-end/clientapp.h | 22 - SnakeClient/SnakeApp/back-end/controller.cpp | 154 - SnakeClient/SnakeApp/back-end/controller.h | 88 - SnakeClient/SnakeApp/back-end/diff.cpp | 21 - SnakeClient/SnakeApp/back-end/diff.h | 23 - SnakeClient/SnakeApp/back-end/guiobject.cpp | 116 - SnakeClient/SnakeApp/back-end/guiobject.h | 91 - .../SnakeApp/back-end/guiobjectfactory.cpp | 23 - .../SnakeApp/back-end/guiobjectfactory.h | 27 - SnakeClient/SnakeApp/back-end/head.cpp | 58 - SnakeClient/SnakeApp/back-end/head.h | 32 - .../SnakeApp/back-end/imageprovider.cpp | 37 - SnakeClient/SnakeApp/back-end/imageprovider.h | 19 - SnakeClient/SnakeApp/back-end/itemworld.cpp | 48 - SnakeClient/SnakeApp/back-end/itemworld.h | 26 - SnakeClient/SnakeApp/back-end/main.cpp | 20 - SnakeClient/SnakeApp/back-end/settings.cpp | 1 - SnakeClient/SnakeApp/back-end/settings.h | 17 - SnakeClient/SnakeApp/back-end/snake.cpp | 200 - SnakeClient/SnakeApp/back-end/snake.h | 52 - SnakeClient/SnakeApp/back-end/world.cpp | 173 - SnakeClient/SnakeApp/back-end/world.h | 47 - SnakeClient/SnakeApp/front-end/About.qml | 29 - SnakeClient/SnakeApp/front-end/AboutPage.qml | 72 - SnakeClient/SnakeApp/front-end/BasePopUp.qml | 71 - SnakeClient/SnakeApp/front-end/FrameView.qml | 32 - .../SnakeApp/front-end/GraphicItem.qml | 38 - SnakeClient/SnakeApp/front-end/ImageView.qml | 83 - .../SnakeApp/front-end/LeftBoxSideBar.qml | 13 - .../SnakeApp/front-end/LeftSideBar.qml | 35 - SnakeClient/SnakeApp/front-end/LoginView.qml | 301 -- SnakeClient/SnakeApp/front-end/MainMenu.qml | 196 - .../SnakeApp/front-end/MainMenuButton.qml | 17 - SnakeClient/SnakeApp/front-end/Metrix.qml | 27 - .../SnakeApp/front-end/NotificationForm.qml | 84 - .../front-end/NotificationServiceView.qml | 30 - SnakeClient/SnakeApp/front-end/PagePopUp.qml | 26 - .../SnakeApp/front-end/PropertyView.qml | 124 - SnakeClient/SnakeApp/front-end/Scene.qml | 228 - .../SnakeApp/front-end/SelectLevelScene.qml | 217 - .../SnakeApp/front-end/SettingsView.qml | 122 - SnakeClient/SnakeApp/front-end/SideBar.qml | 103 - SnakeClient/SnakeApp/front-end/SnakeItem.qml | 17 - SnakeClient/SnakeApp/front-end/TextInput.qml | 47 - SnakeClient/SnakeApp/front-end/UserView.qml | 112 - SnakeClient/SnakeApp/front-end/main.qml | 40 - SnakeClient/SnakeApp/img/Settings-icon.png | Bin 28236 -> 0 bytes SnakeClient/SnakeApp/img/asphalt.jpg | Bin 190807 -> 0 bytes SnakeClient/SnakeApp/img/box-texture.png | Bin 80593 -> 0 bytes SnakeClient/SnakeApp/img/cogs-solid.svg | 1 - SnakeClient/SnakeApp/img/defaultSnake.png | Bin 17886 -> 0 bytes SnakeClient/SnakeApp/img/defaultUser.png | Bin 38927 -> 0 bytes SnakeClient/SnakeApp/img/icon.ico | Bin 32490 -> 0 bytes SnakeClient/SnakeApp/img/logo.png | Bin 2461 -> 0 bytes SnakeClient/SnakeApp/img/up.svg | 45 - SnakeClient/SnakeApp/qml.qrc | 39 - SnakeClient/SnakeApp/qtquickcontrols2.conf | 7 - SnakeClient/SnakeClient.pro | 5 - SnakeMain.pro | 20 - SnakeServer/ClientProtocol/ClientProtocol.pri | 24 - SnakeServer/ClientProtocol/ClientProtocol.pro | 91 - .../ClientProtocol/ClientProtocolIncludes.pri | 4 - .../Objects/basenetworkobject.cpp | 98 - .../Objects/basenetworkobject.h | 89 - .../ClientProtocol/Objects/gamedata.cpp | 50 - SnakeServer/ClientProtocol/Objects/gamedata.h | 28 - .../ClientProtocol/Objects/getitem.cpp | 10 - SnakeServer/ClientProtocol/Objects/getitem.h | 17 - SnakeServer/ClientProtocol/Objects/login.cpp | 71 - SnakeServer/ClientProtocol/Objects/login.h | 31 - SnakeServer/ClientProtocol/Objects/map.cpp | 45 - SnakeServer/ClientProtocol/Objects/map.h | 25 - .../ClientProtocol/Objects/objdata.cpp | 24 - SnakeServer/ClientProtocol/Objects/objdata.h | 17 - SnakeServer/ClientProtocol/Objects/player.cpp | 116 - SnakeServer/ClientProtocol/Objects/player.h | 50 - SnakeServer/ClientProtocol/Objects/pubkey.cpp | 62 - SnakeServer/ClientProtocol/Objects/pubkey.h | 30 - SnakeServer/ClientProtocol/Objects/snake.cpp | 68 - SnakeServer/ClientProtocol/Objects/snake.h | 32 - .../Objects/updateplayerdata.cpp | 49 - .../ClientProtocol/Objects/updateplayerdata.h | 26 - .../ClientProtocol/Objects/websocket.cpp | 71 - .../ClientProtocol/Objects/websocket.h | 41 - SnakeServer/ClientProtocol/client.cpp | 438 -- SnakeServer/ClientProtocol/client.h | 156 - SnakeServer/ClientProtocol/clientprotocol.cpp | 214 - SnakeServer/ClientProtocol/clientprotocol.h | 188 - .../ClientProtocol/clientprotocol_global.h | 12 - SnakeServer/ClientProtocol/config.h | 10 - SnakeServer/ClientProtocol/connectioninfo.cpp | 81 - SnakeServer/ClientProtocol/connectioninfo.h | 46 - SnakeServer/ClientProtocol/cp.h | 6 - SnakeServer/ClientProtocol/cpserver.h | 6 - .../ClientProtocol/factorynetobjects.cpp | 40 - .../ClientProtocol/factorynetobjects.h | 40 - .../ClientProtocol/networkclasssize.cpp | 32 - SnakeServer/ClientProtocol/networkclasssize.h | 25 - SnakeServer/ClientProtocol/rsakeyspool.cpp | 27 - SnakeServer/ClientProtocol/rsakeyspool.h | 37 - SnakeServer/ClientProtocol/server.cpp | 415 -- SnakeServer/ClientProtocol/server.h | 80 - SnakeServer/Daemon/Daemon.pro | 36 - SnakeServer/Daemon/SnakeServer.pro | 34 - SnakeServer/Daemon/main.cpp | 51 - SnakeServer/Qt-Secret | 1 - SnakeServer/Server/Server.pri | 23 - SnakeServer/Server/Server.pro | 59 - SnakeServer/Server/item.cpp | 72 - SnakeServer/Server/item.h | 30 - SnakeServer/Server/keysreactor.cpp | 89 - SnakeServer/Server/keysreactor.h | 35 - SnakeServer/Server/mainserver.cpp | 320 -- SnakeServer/Server/mainserver.h | 56 - SnakeServer/Server/playerdbdata.cpp | 39 - SnakeServer/Server/playerdbdata.h | 27 - SnakeServer/Server/server_global.h | 12 - SnakeServer/Server/sql/SnakeDB.sql | 40 - SnakeServer/Server/sqldbcache.cpp | 383 -- SnakeServer/Server/sqldbcache.h | 74 - SnakeServer/Server/sqldbwriter.cpp | 460 -- SnakeServer/Server/sqldbwriter.h | 64 - SnakeServer/Server/sqlres.qrc | 5 - SnakeServer/Server/websocketcontroller.cpp | 57 - SnakeServer/Server/websocketcontroller.h | 40 - SnakeServer/ServerProtocol/ServerProtocol.pri | 23 - SnakeServer/ServerProtocol/ServerProtocol.pro | 52 - SnakeServer/ServerProtocol/client.cpp | 193 - SnakeServer/ServerProtocol/client.h | 45 - SnakeServer/ServerProtocol/server.cpp | 152 - SnakeServer/ServerProtocol/server.h | 35 - SnakeServer/ServerProtocol/serverprotocol.cpp | 88 - SnakeServer/ServerProtocol/serverprotocol.h | 106 - .../ServerProtocol/serverprotocol_global.h | 12 - SnakeServer/ServerProtocol/serverutils.cpp | 75 - SnakeServer/ServerProtocol/serverutils.h | 21 - SnakeServer/ServerProtocol/sp.h | 7 - SnakeServer/ServerProtocol/spserver.h | 6 - SnakeServer/SnakeServer.pro | 12 - SnakeServer/Terminal/Terminal.pro | 31 - SnakeServer/Terminal/main.cpp | 99 - SnakeServer/serverProtocolTests/.gitignore | 73 - .../serverProtocolTests.pro | 39 - SnakeServer/serverProtocolTests/testutils.cpp | 141 - SnakeServer/serverProtocolTests/testutils.h | 25 - .../tst_testsnakeserver.cpp | 621 --- SnakeUtils/SnakeUtils.pri | 23 - SnakeUtils/SnakeUtils.pro | 44 - SnakeUtils/lvls.cpp | 11 - SnakeUtils/lvls.h | 9 - SnakeUtils/snakeutils.cpp | 3 - SnakeUtils/snakeutils.h | 21 - SnakeUtils/snakeutils_global.h | 12 - doc/calassdiagramm.png | Bin 53782 -> 0 bytes doc/calassdiagramm.qmodel | 3829 ----------------- doc/librarymodel.qmodel | 1495 ------- doxygen.conf | 2495 +++++++++++ installer | 1 - plug.pro | 5 + src/CMakeLists.txt | 26 + src/Example/CMakeLists.txt | 44 + src/Example/main.cpp | 10 + src/Library/CMakeLists.txt | 48 + src/Library/SnakeProject.qrc | 6 + src/Library/SnakeProject/SnakeProject.cpp | 19 + src/Library/SnakeProject/SnakeProject.h | 16 + .../SnakeProject/SnakeProject_global.h | 20 + .../SnakeProjectModule/SnakeProject.qml | 12 + src/Library/SnakeProjectModule/qmldir | 3 + src/Library/languages/en.ts | 4 + test.pri | 21 - tests/CMakeLists.txt | 30 + tests/tstMain.cpp | 86 + tests/units/exampletest.cpp | 22 + tests/units/exampletest.h | 26 + tests/units/test.cpp | 9 + tests/units/test.h | 20 + tests/units/testutils.cpp | 53 + tests/units/testutils.h | 32 + 224 files changed, 3276 insertions(+), 17441 deletions(-) delete mode 100644 .gitmodules create mode 100644 CMakeLists.txt create mode 100644 Deploy/SnakeProject.json create mode 100644 LICENSE delete mode 160000 QuasarAppLib delete mode 100644 SnakeClient/SnakeApp/SnakeApp.pro delete mode 100644 SnakeClient/SnakeApp/android/AndroidManifest.xml delete mode 100644 SnakeClient/SnakeApp/android/build.gradle delete mode 100644 SnakeClient/SnakeApp/android/gradle/wrapper/gradle-wrapper.jar delete mode 100644 SnakeClient/SnakeApp/android/gradle/wrapper/gradle-wrapper.properties delete mode 100755 SnakeClient/SnakeApp/android/gradlew delete mode 100644 SnakeClient/SnakeApp/android/gradlew.bat delete mode 100644 SnakeClient/SnakeApp/android/res/drawable-hdpi/icon.png delete mode 100644 SnakeClient/SnakeApp/android/res/drawable-ldpi/icon.png delete mode 100644 SnakeClient/SnakeApp/android/res/drawable-mdpi/icon.png delete mode 100644 SnakeClient/SnakeApp/android/res/values/libs.xml delete mode 100644 SnakeClient/SnakeApp/back-end/ProfileViewItems/mainclient.cpp delete mode 100644 SnakeClient/SnakeApp/back-end/ProfileViewItems/mainclient.h delete mode 100644 SnakeClient/SnakeApp/back-end/ProfileViewItems/mainmenumodel.cpp delete mode 100644 SnakeClient/SnakeApp/back-end/ProfileViewItems/mainmenumodel.h delete mode 100644 SnakeClient/SnakeApp/back-end/ProfileViewItems/networkclient.cpp delete mode 100644 SnakeClient/SnakeApp/back-end/ProfileViewItems/networkclient.h delete mode 100644 SnakeClient/SnakeApp/back-end/ProfileViewItems/notificationdata.cpp delete mode 100644 SnakeClient/SnakeApp/back-end/ProfileViewItems/notificationdata.h delete mode 100644 SnakeClient/SnakeApp/back-end/ProfileViewItems/notificationservice.cpp delete mode 100644 SnakeClient/SnakeApp/back-end/ProfileViewItems/notificationservice.h delete mode 100644 SnakeClient/SnakeApp/back-end/ProfileViewItems/playerclientdata.cpp delete mode 100644 SnakeClient/SnakeApp/back-end/ProfileViewItems/playerclientdata.h delete mode 100644 SnakeClient/SnakeApp/back-end/ProfileViewItems/settingsviewmodel.cpp delete mode 100644 SnakeClient/SnakeApp/back-end/ProfileViewItems/settingsviewmodel.h delete mode 100644 SnakeClient/SnakeApp/back-end/ProfileViewItems/userview.cpp delete mode 100644 SnakeClient/SnakeApp/back-end/ProfileViewItems/userview.h delete mode 100644 SnakeClient/SnakeApp/back-end/asyncimageresponse.cpp delete mode 100644 SnakeClient/SnakeApp/back-end/asyncimageresponse.h delete mode 100644 SnakeClient/SnakeApp/back-end/background.cpp delete mode 100644 SnakeClient/SnakeApp/back-end/background.h delete mode 100644 SnakeClient/SnakeApp/back-end/backgrounditem.cpp delete mode 100644 SnakeClient/SnakeApp/back-end/backgrounditem.h delete mode 100644 SnakeClient/SnakeApp/back-end/baseclass.cpp delete mode 100644 SnakeClient/SnakeApp/back-end/baseclass.h delete mode 100644 SnakeClient/SnakeApp/back-end/box.cpp delete mode 100644 SnakeClient/SnakeApp/back-end/box.h delete mode 100644 SnakeClient/SnakeApp/back-end/clientapp.cpp delete mode 100644 SnakeClient/SnakeApp/back-end/clientapp.h delete mode 100644 SnakeClient/SnakeApp/back-end/controller.cpp delete mode 100644 SnakeClient/SnakeApp/back-end/controller.h delete mode 100644 SnakeClient/SnakeApp/back-end/diff.cpp delete mode 100644 SnakeClient/SnakeApp/back-end/diff.h delete mode 100644 SnakeClient/SnakeApp/back-end/guiobject.cpp delete mode 100644 SnakeClient/SnakeApp/back-end/guiobject.h delete mode 100644 SnakeClient/SnakeApp/back-end/guiobjectfactory.cpp delete mode 100644 SnakeClient/SnakeApp/back-end/guiobjectfactory.h delete mode 100644 SnakeClient/SnakeApp/back-end/head.cpp delete mode 100644 SnakeClient/SnakeApp/back-end/head.h delete mode 100644 SnakeClient/SnakeApp/back-end/imageprovider.cpp delete mode 100644 SnakeClient/SnakeApp/back-end/imageprovider.h delete mode 100644 SnakeClient/SnakeApp/back-end/itemworld.cpp delete mode 100644 SnakeClient/SnakeApp/back-end/itemworld.h delete mode 100644 SnakeClient/SnakeApp/back-end/main.cpp delete mode 100644 SnakeClient/SnakeApp/back-end/settings.cpp delete mode 100644 SnakeClient/SnakeApp/back-end/settings.h delete mode 100644 SnakeClient/SnakeApp/back-end/snake.cpp delete mode 100644 SnakeClient/SnakeApp/back-end/snake.h delete mode 100644 SnakeClient/SnakeApp/back-end/world.cpp delete mode 100644 SnakeClient/SnakeApp/back-end/world.h delete mode 100644 SnakeClient/SnakeApp/front-end/About.qml delete mode 100644 SnakeClient/SnakeApp/front-end/AboutPage.qml delete mode 100644 SnakeClient/SnakeApp/front-end/BasePopUp.qml delete mode 100644 SnakeClient/SnakeApp/front-end/FrameView.qml delete mode 100644 SnakeClient/SnakeApp/front-end/GraphicItem.qml delete mode 100644 SnakeClient/SnakeApp/front-end/ImageView.qml delete mode 100644 SnakeClient/SnakeApp/front-end/LeftBoxSideBar.qml delete mode 100644 SnakeClient/SnakeApp/front-end/LeftSideBar.qml delete mode 100644 SnakeClient/SnakeApp/front-end/LoginView.qml delete mode 100644 SnakeClient/SnakeApp/front-end/MainMenu.qml delete mode 100644 SnakeClient/SnakeApp/front-end/MainMenuButton.qml delete mode 100644 SnakeClient/SnakeApp/front-end/Metrix.qml delete mode 100644 SnakeClient/SnakeApp/front-end/NotificationForm.qml delete mode 100644 SnakeClient/SnakeApp/front-end/NotificationServiceView.qml delete mode 100644 SnakeClient/SnakeApp/front-end/PagePopUp.qml delete mode 100644 SnakeClient/SnakeApp/front-end/PropertyView.qml delete mode 100644 SnakeClient/SnakeApp/front-end/Scene.qml delete mode 100644 SnakeClient/SnakeApp/front-end/SelectLevelScene.qml delete mode 100644 SnakeClient/SnakeApp/front-end/SettingsView.qml delete mode 100644 SnakeClient/SnakeApp/front-end/SideBar.qml delete mode 100644 SnakeClient/SnakeApp/front-end/SnakeItem.qml delete mode 100644 SnakeClient/SnakeApp/front-end/TextInput.qml delete mode 100644 SnakeClient/SnakeApp/front-end/UserView.qml delete mode 100644 SnakeClient/SnakeApp/front-end/main.qml delete mode 100644 SnakeClient/SnakeApp/img/Settings-icon.png delete mode 100644 SnakeClient/SnakeApp/img/asphalt.jpg delete mode 100644 SnakeClient/SnakeApp/img/box-texture.png delete mode 100644 SnakeClient/SnakeApp/img/cogs-solid.svg delete mode 100644 SnakeClient/SnakeApp/img/defaultSnake.png delete mode 100644 SnakeClient/SnakeApp/img/defaultUser.png delete mode 100644 SnakeClient/SnakeApp/img/icon.ico delete mode 100644 SnakeClient/SnakeApp/img/logo.png delete mode 100644 SnakeClient/SnakeApp/img/up.svg delete mode 100644 SnakeClient/SnakeApp/qml.qrc delete mode 100644 SnakeClient/SnakeApp/qtquickcontrols2.conf delete mode 100644 SnakeClient/SnakeClient.pro delete mode 100644 SnakeMain.pro delete mode 100644 SnakeServer/ClientProtocol/ClientProtocol.pri delete mode 100644 SnakeServer/ClientProtocol/ClientProtocol.pro delete mode 100644 SnakeServer/ClientProtocol/ClientProtocolIncludes.pri delete mode 100644 SnakeServer/ClientProtocol/Objects/basenetworkobject.cpp delete mode 100644 SnakeServer/ClientProtocol/Objects/basenetworkobject.h delete mode 100644 SnakeServer/ClientProtocol/Objects/gamedata.cpp delete mode 100644 SnakeServer/ClientProtocol/Objects/gamedata.h delete mode 100644 SnakeServer/ClientProtocol/Objects/getitem.cpp delete mode 100644 SnakeServer/ClientProtocol/Objects/getitem.h delete mode 100644 SnakeServer/ClientProtocol/Objects/login.cpp delete mode 100644 SnakeServer/ClientProtocol/Objects/login.h delete mode 100644 SnakeServer/ClientProtocol/Objects/map.cpp delete mode 100644 SnakeServer/ClientProtocol/Objects/map.h delete mode 100644 SnakeServer/ClientProtocol/Objects/objdata.cpp delete mode 100644 SnakeServer/ClientProtocol/Objects/objdata.h delete mode 100644 SnakeServer/ClientProtocol/Objects/player.cpp delete mode 100644 SnakeServer/ClientProtocol/Objects/player.h delete mode 100644 SnakeServer/ClientProtocol/Objects/pubkey.cpp delete mode 100644 SnakeServer/ClientProtocol/Objects/pubkey.h delete mode 100644 SnakeServer/ClientProtocol/Objects/snake.cpp delete mode 100644 SnakeServer/ClientProtocol/Objects/snake.h delete mode 100644 SnakeServer/ClientProtocol/Objects/updateplayerdata.cpp delete mode 100644 SnakeServer/ClientProtocol/Objects/updateplayerdata.h delete mode 100644 SnakeServer/ClientProtocol/Objects/websocket.cpp delete mode 100644 SnakeServer/ClientProtocol/Objects/websocket.h delete mode 100644 SnakeServer/ClientProtocol/client.cpp delete mode 100644 SnakeServer/ClientProtocol/client.h delete mode 100644 SnakeServer/ClientProtocol/clientprotocol.cpp delete mode 100644 SnakeServer/ClientProtocol/clientprotocol.h delete mode 100644 SnakeServer/ClientProtocol/clientprotocol_global.h delete mode 100644 SnakeServer/ClientProtocol/config.h delete mode 100644 SnakeServer/ClientProtocol/connectioninfo.cpp delete mode 100644 SnakeServer/ClientProtocol/connectioninfo.h delete mode 100644 SnakeServer/ClientProtocol/cp.h delete mode 100644 SnakeServer/ClientProtocol/cpserver.h delete mode 100644 SnakeServer/ClientProtocol/factorynetobjects.cpp delete mode 100644 SnakeServer/ClientProtocol/factorynetobjects.h delete mode 100644 SnakeServer/ClientProtocol/networkclasssize.cpp delete mode 100644 SnakeServer/ClientProtocol/networkclasssize.h delete mode 100644 SnakeServer/ClientProtocol/rsakeyspool.cpp delete mode 100644 SnakeServer/ClientProtocol/rsakeyspool.h delete mode 100644 SnakeServer/ClientProtocol/server.cpp delete mode 100644 SnakeServer/ClientProtocol/server.h delete mode 100644 SnakeServer/Daemon/Daemon.pro delete mode 100644 SnakeServer/Daemon/SnakeServer.pro delete mode 100644 SnakeServer/Daemon/main.cpp delete mode 160000 SnakeServer/Qt-Secret delete mode 100644 SnakeServer/Server/Server.pri delete mode 100644 SnakeServer/Server/Server.pro delete mode 100644 SnakeServer/Server/item.cpp delete mode 100644 SnakeServer/Server/item.h delete mode 100644 SnakeServer/Server/keysreactor.cpp delete mode 100644 SnakeServer/Server/keysreactor.h delete mode 100644 SnakeServer/Server/mainserver.cpp delete mode 100644 SnakeServer/Server/mainserver.h delete mode 100644 SnakeServer/Server/playerdbdata.cpp delete mode 100644 SnakeServer/Server/playerdbdata.h delete mode 100644 SnakeServer/Server/server_global.h delete mode 100644 SnakeServer/Server/sql/SnakeDB.sql delete mode 100644 SnakeServer/Server/sqldbcache.cpp delete mode 100644 SnakeServer/Server/sqldbcache.h delete mode 100644 SnakeServer/Server/sqldbwriter.cpp delete mode 100644 SnakeServer/Server/sqldbwriter.h delete mode 100644 SnakeServer/Server/sqlres.qrc delete mode 100644 SnakeServer/Server/websocketcontroller.cpp delete mode 100644 SnakeServer/Server/websocketcontroller.h delete mode 100644 SnakeServer/ServerProtocol/ServerProtocol.pri delete mode 100644 SnakeServer/ServerProtocol/ServerProtocol.pro delete mode 100644 SnakeServer/ServerProtocol/client.cpp delete mode 100644 SnakeServer/ServerProtocol/client.h delete mode 100644 SnakeServer/ServerProtocol/server.cpp delete mode 100644 SnakeServer/ServerProtocol/server.h delete mode 100644 SnakeServer/ServerProtocol/serverprotocol.cpp delete mode 100644 SnakeServer/ServerProtocol/serverprotocol.h delete mode 100644 SnakeServer/ServerProtocol/serverprotocol_global.h delete mode 100644 SnakeServer/ServerProtocol/serverutils.cpp delete mode 100644 SnakeServer/ServerProtocol/serverutils.h delete mode 100644 SnakeServer/ServerProtocol/sp.h delete mode 100644 SnakeServer/ServerProtocol/spserver.h delete mode 100644 SnakeServer/SnakeServer.pro delete mode 100644 SnakeServer/Terminal/Terminal.pro delete mode 100644 SnakeServer/Terminal/main.cpp delete mode 100644 SnakeServer/serverProtocolTests/.gitignore delete mode 100644 SnakeServer/serverProtocolTests/serverProtocolTests.pro delete mode 100644 SnakeServer/serverProtocolTests/testutils.cpp delete mode 100644 SnakeServer/serverProtocolTests/testutils.h delete mode 100644 SnakeServer/serverProtocolTests/tst_testsnakeserver.cpp delete mode 100644 SnakeUtils/SnakeUtils.pri delete mode 100644 SnakeUtils/SnakeUtils.pro delete mode 100644 SnakeUtils/lvls.cpp delete mode 100644 SnakeUtils/lvls.h delete mode 100644 SnakeUtils/snakeutils.cpp delete mode 100644 SnakeUtils/snakeutils.h delete mode 100644 SnakeUtils/snakeutils_global.h delete mode 100644 doc/calassdiagramm.png delete mode 100644 doc/calassdiagramm.qmodel delete mode 100644 doc/librarymodel.qmodel create mode 100644 doxygen.conf delete mode 160000 installer create mode 100644 plug.pro create mode 100644 src/CMakeLists.txt create mode 100644 src/Example/CMakeLists.txt create mode 100644 src/Example/main.cpp create mode 100644 src/Library/CMakeLists.txt create mode 100644 src/Library/SnakeProject.qrc create mode 100644 src/Library/SnakeProject/SnakeProject.cpp create mode 100644 src/Library/SnakeProject/SnakeProject.h create mode 100644 src/Library/SnakeProject/SnakeProject_global.h create mode 100644 src/Library/SnakeProjectModule/SnakeProject.qml create mode 100644 src/Library/SnakeProjectModule/qmldir create mode 100644 src/Library/languages/en.ts delete mode 100644 test.pri create mode 100644 tests/CMakeLists.txt create mode 100644 tests/tstMain.cpp create mode 100644 tests/units/exampletest.cpp create mode 100644 tests/units/exampletest.h create mode 100644 tests/units/test.cpp create mode 100644 tests/units/test.h create mode 100644 tests/units/testutils.cpp create mode 100644 tests/units/testutils.h diff --git a/.gitignore b/.gitignore index f84e2b3..c3e225f 100644 --- a/.gitignore +++ b/.gitignore @@ -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* diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 6072d35..0000000 --- a/.gitmodules +++ /dev/null @@ -1,10 +0,0 @@ -[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 diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..384b03a --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,60 @@ +# +# 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(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(QT NAMES Qt6 Qt5 COMPONENTS Core Test QUIET) +find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Test QUIET) + +include(submodules/CMake/ccache.cmake) +include(submodules/CMake/QuasarAppCITargets.cmake) + +# Add sub directories +add_subdirectory(src) + +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() + + +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) +addDeployFromCustomFile("SnakeProject" "${CMAKE_CURRENT_SOURCE_DIR}/Deploy/SnakeProject.json") diff --git a/Deploy/SnakeProject.json b/Deploy/SnakeProject.json new file mode 100644 index 0000000..b79b689 --- /dev/null +++ b/Deploy/SnakeProject.json @@ -0,0 +1,19 @@ +{ + "binDir": "./../src/build/Debug/SnakeProjectEaxample", + "clear": true, + "libDir": "./../", + "recursiveDepth": "10", + "deploySystem": false, + "qmlDir": "../", + "ignoreEnv": [ + "./../installer", + "./../Distro", + "./../parts", + "./../snap", + "./../prime", + "./../stage" + ], + "extraLib": "crypto", + "targetDir": "./../DisttibutionKit" +} + diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..65c5ca8 --- /dev/null +++ b/LICENSE @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + 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. diff --git a/QuasarAppLib b/QuasarAppLib deleted file mode 160000 index 553e337..0000000 --- a/QuasarAppLib +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 553e337e6a956534d34dbbfcec42359117aa35d4 diff --git a/README.md b/README.md index 98e10aa..08b0533 100644 --- a/README.md +++ b/README.md @@ -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). | diff --git a/SnakeClient/SnakeApp/SnakeApp.pro b/SnakeClient/SnakeApp/SnakeApp.pro deleted file mode 100644 index 4225c5d..0000000 --- a/SnakeClient/SnakeApp/SnakeApp.pro +++ /dev/null @@ -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 diff --git a/SnakeClient/SnakeApp/android/AndroidManifest.xml b/SnakeClient/SnakeApp/android/AndroidManifest.xml deleted file mode 100644 index 586d919..0000000 --- a/SnakeClient/SnakeApp/android/AndroidManifest.xml +++ /dev/null @@ -1,79 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/SnakeClient/SnakeApp/android/build.gradle b/SnakeClient/SnakeApp/android/build.gradle deleted file mode 100644 index 989d079..0000000 --- a/SnakeClient/SnakeApp/android/build.gradle +++ /dev/null @@ -1,57 +0,0 @@ -buildscript { - repositories { - google() - jcenter() - } - - dependencies { - classpath 'com.android.tools.build:gradle:3.2.0' - } -} - -repositories { - google() - jcenter() -} - -apply plugin: 'com.android.application' - -dependencies { - implementation fileTree(dir: 'libs', include: ['*.jar', '*.aar']) -} - -android { - /******************************************************* - * The following variables: - * - androidBuildToolsVersion, - * - androidCompileSdkVersion - * - qt5AndroidDir - holds the path to qt android files - * needed to build any Qt application - * on Android. - * - * are defined in gradle.properties file. This file is - * updated by QtCreator and androiddeployqt tools. - * Changing them manually might break the compilation! - *******************************************************/ - - compileSdkVersion androidCompileSdkVersion.toInteger() - - buildToolsVersion androidBuildToolsVersion - - sourceSets { - main { - manifest.srcFile 'AndroidManifest.xml' - java.srcDirs = [qt5AndroidDir + '/src', 'src', 'java'] - aidl.srcDirs = [qt5AndroidDir + '/src', 'src', 'aidl'] - res.srcDirs = [qt5AndroidDir + '/res', 'res'] - resources.srcDirs = ['src'] - renderscript.srcDirs = ['src'] - assets.srcDirs = ['assets'] - jniLibs.srcDirs = ['libs'] - } - } - - lintOptions { - abortOnError false - } -} diff --git a/SnakeClient/SnakeApp/android/gradle/wrapper/gradle-wrapper.jar b/SnakeClient/SnakeApp/android/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index f6b961fd5a86aa5fbfe90f707c3138408be7c718..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 54329 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

<5G2M1WZP5 zzqSuO91lJod(SBDDw<*sX(+F6Uq~YAeYV#2A;XQu_p=N5X+#cmu19Qk>QAnV=k!?wbk5I;tDWgFc}0NkvC*G=V+Yh1cyeJVq~9czZiDXe+S=VfL2g`LWo8om z$Y~FQc6MFjV-t1Y`^D9XMwY*U_re2R?&(O~68T&D4S{X`6JYU-pz=}ew-)V0AOUT1 zVOkHAB-8uBcRjLvz<9HS#a@X*Kc@|W)nyiSgi|u5$Md|P()%2(?olGg@ypoJwp6>m z*dnfjjWC>?_1p;%1brqZyDRR;8EntVA92EJ3ByOxj6a+bhPl z;a?m4rQAV1@QU^#M1HX)0+}A<7TCO`ZR_RzF}X9-M>cRLyN4C+lCk2)kT^3gN^`IT zNP~fAm(wyIoR+l^lQDA(e1Yv}&$I!n?&*p6?lZcQ+vGLLd~fM)qt}wsbf3r=tmVYe zl)ntf#E!P7wlakP9MXS7m0nsAmqxZ*)#j;M&0De`oNmFgi$ov#!`6^4)iQyxg5Iuj zjLAhzQ)r`^hf7`*1`Rh`X;LVBtDSz@0T?kkT1o!ijeyTGt5vc^Cd*tmNgiNo^EaWvaC8$e+nb_{W01j3%=1Y&92YacjCi>eNbwk%-gPQ@H-+4xskQ}f_c=jg^S-# zYFBDf)2?@5cy@^@FHK5$YdAK9cI;!?Jgd}25lOW%xbCJ>By3=HiK@1EM+I46A)Lsd zeT|ZH;KlCml=@;5+hfYf>QNOr^XNH%J-lvev)$Omy8MZ`!{`j>(J5cG&ZXXgv)TaF zg;cz99i$4CX_@3MIb?GL0s*8J=3`#P(jXF(_(6DXZjc@(@h&=M&JG)9&Te1?(^XMW zjjC_70|b=9hB6pKQi`S^Ls7JyJw^@P>Ko^&q8F&?>6i;#CbxUiLz1ZH4lNyd@QACd zu>{!sqjB!2Dg}pbAXD>d!3jW}=5aN0b;rw*W>*PAxm7D)aw(c*RX2@bTGEI|RRp}vw7;NR2wa;rXN{L{Q#=Fa z$x@ms6pqb>!8AuV(prv>|aU8oWV={C&$c zMa=p=CDNOC2tISZcd8~18GN5oTbKY+Vrq;3_obJlfSKRMk;Hdp1`y`&LNSOqeauR_ z^j*Ojl3Ohzb5-a49A8s|UnM*NM8tg}BJXdci5%h&;$afbmRpN0&~9rCnBA`#lG!p zc{(9Y?A0Y9yo?wSYn>iigf~KP$0*@bGZ>*YM4&D;@{<%Gg5^uUJGRrV4 z(aZOGB&{_0f*O=Oi0k{@8vN^BU>s3jJRS&CJOl3o|BE{FAA&a#2YYiX3pZz@|Go-F z|Fly;7eX2OTs>R}<`4RwpHFs9nwh)B28*o5qK1Ge=_^w0m`uJOv!=&!tzt#Save(C zgKU=Bsgql|`ui(e1KVxR`?>Dx>(rD1$iWp&m`v)3A!j5(6vBm*z|aKm*T*)mo(W;R zNGo2`KM!^SS7+*9YxTm6YMm_oSrLceqN*nDOAtagULuZl5Q<7mOnB@Hq&P|#9y{5B z!2x+2s<%Cv2Aa0+u{bjZXS);#IFPk(Ph-K7K?3i|4ro> zRbqJoiOEYo(Im^((r}U4b8nvo_>4<`)ut`24?ILnglT;Pd&U}$lV3U$F9#PD(O=yV zgNNA=GW|(E=&m_1;uaNmipQe?pon4{T=zK!N!2_CJL0E*R^XXIKf*wi!>@l}3_P9Z zF~JyMbW!+n-+>!u=A1ESxzkJy$DRuG+$oioG7(@Et|xVbJ#BCt;J43Nvj@MKvTxzy zMmjNuc#LXBxFAwIGZJk~^!q$*`FME}yKE8d1f5Mp}KHNq(@=Z8YxV}0@;YS~|SpGg$_jG7>_8WWYcVx#4SxpzlV9N4aO>K{c z$P?a_fyDzGX$Of3@ykvedGd<@-R;M^Shlj*SswJLD+j@hi_&_>6WZ}#AYLR0iWMK|A zH_NBeu(tMyG=6VO-=Pb>-Q#$F*or}KmEGg*-n?vWQREURdB#+6AvOj*I%!R-4E_2$ zU5n9m>RWs|Wr;h2DaO&mFBdDb-Z{APGQx$(L`if?C|njd*fC=rTS%{o69U|meRvu?N;Z|Y zbT|ojL>j;q*?xXmnHH#3R4O-59NV1j=uapkK7}6@Wo*^Nd#(;$iuGsb;H315xh3pl zHaJ>h-_$hdNl{+|Zb%DZH%ES;*P*v0#}g|vrKm9;j-9e1M4qX@zkl&5OiwnCz=tb6 zz<6HXD+rGIVpGtkb{Q^LIgExOm zz?I|oO9)!BOLW#krLmWvX5(k!h{i>ots*EhpvAE;06K|u_c~y{#b|UxQ*O@Ks=bca z^_F0a@61j3I(Ziv{xLb8AXQj3;R{f_l6a#H5ukg5rxwF9A$?Qp-Mo54`N-SKc}fWp z0T)-L@V$$&my;l#Ha{O@!fK4-FSA)L&3<${Hcwa7ue`=f&YsXY(NgeDU#sRlT3+9J z6;(^(sjSK@3?oMo$%L-nqy*E;3pb0nZLx6 z;h5)T$y8GXK1DS-F@bGun8|J(v-9o=42&nLJy#}M5D0T^5VWBNn$RpC zZzG6Bt66VY4_?W=PX$DMpKAI!d`INr) zkMB{XPQ<52rvWVQqgI0OL_NWxoe`xxw&X8yVftdODPj5|t}S6*VMqN$-h9)1MBe0N zYq?g0+e8fJCoAksr0af1)FYtz?Me!Cxn`gUx&|T;)695GG6HF7!Kg1zzRf_{VWv^bo81v4$?F6u2g|wxHc6eJQAg&V z#%0DnWm2Rmu71rPJ8#xFUNFC*V{+N_qqFH@gYRLZ6C?GAcVRi>^n3zQxORPG)$-B~ z%_oB?-%Zf7d*Fe;cf%tQwcGv2S?rD$Z&>QC2X^vwYjnr5pa5u#38cHCt4G3|efuci z@3z=#A13`+ztmp;%zjXwPY_aq-;isu*hecWWX_=Z8paSqq7;XYnUjK*T>c4~PR4W7 z#C*%_H&tfGx`Y$w7`dXvVhmovDnT>btmy~SLf>>~84jkoQ%cv=MMb+a{JV&t0+1`I z32g_Y@yDhKe|K^PevP~MiiVl{Ou7^Mt9{lOnXEQ`xY^6L8D$705GON{!1?1&YJEl#fTf5Z)da=yiEQ zGgtC-soFGOEBEB~ZF_{7b(76En>d}mI~XIwNw{e>=Fv)sgcw@qOsykWr?+qAOZSVrQfg}TNI ztKNG)1SRrAt6#Q?(me%)>&A_^DM`pL>J{2xu>xa$3d@90xR61TQDl@fu%_85DuUUA za9tn64?At;{`BAW6oykwntxHeDpXsV#{tmt5RqdN7LtcF4vR~_kZNT|wqyR#z^Xcd zFdymVRZvyLfTpBT>w9<)Ozv@;Yk@dOSVWbbtm^y@@C>?flP^EgQPAwsy75bveo=}T zFxl(f)s)j(0#N_>Or(xEuV(n$M+`#;Pc$1@OjXEJZumkaekVqgP_i}p`oTx;terTx zZpT+0dpUya2hqlf`SpXN{}>PfhajNk_J0`H|2<5E;U5Vh4F8er z;RxLSFgpGhkU>W?IwdW~NZTyOBrQ84H7_?gviIf71l`EETodG9a1!8e{jW?DpwjL? zGEM&eCzwoZt^P*8KHZ$B<%{I}>46IT%jJ3AnnB5P%D2E2Z_ z1M!vr#8r}1|KTqWA4%67ZdbMW2YJ81b(KF&SQ2L1Qn(y-=J${p?xLMx3W7*MK;LFQ z6Z`aU;;mTL4XrrE;HY*Rkh6N%?qviUGNAKiCB~!P}Z->IpO6E(gGd7I#eDuT7j|?nZ zK}I(EJ>$Kb&@338M~O+em9(L!+=0zBR;JAQesx|3?Ok90)D1aS9P?yTh6Poh8Cr4X zk3zc=f2rE7jj+aP7nUsr@~?^EGP>Q>h#NHS?F{Cn`g-gD<8F&dqOh-0sa%pfL`b+1 zUsF*4a~)KGb4te&K0}bE>z3yb8% zibb5Q%Sfiv7feb1r0tfmiMv z@^4XYwg@KZI=;`wC)`1jUA9Kv{HKe2t$WmRcR4y8)VAFjRi zaz&O7Y2tDmc5+SX(bj6yGHYk$dBkWc96u3u&F)2yEE~*i0F%t9Kg^L6MJSb&?wrXi zGSc;_rln$!^ybwYBeacEFRsVGq-&4uC{F)*Y;<0y7~USXswMo>j4?~5%Zm!m@i@-> zXzi82sa-vpU{6MFRktJy+E0j#w`f`>Lbog{zP|9~hg(r{RCa!uGe>Yl536cn$;ouH za#@8XMvS-kddc1`!1LVq;h57~zV`7IYR}pp3u!JtE6Q67 zq3H9ZUcWPm2V4IukS}MCHSdF0qg2@~ufNx9+VMjQP&exiG_u9TZAeAEj*jw($G)zL zq9%#v{wVyOAC4A~AF=dPX|M}MZV)s(qI9@aIK?Pe+~ch|>QYb+78lDF*Nxz2-vpRbtQ*F4$0fDbvNM#CCatgQ@z1+EZWrt z2dZfywXkiW=no5jus-92>gXn5rFQ-COvKyegmL=4+NPzw6o@a?wGE-1Bt;pCHe;34K%Z z-FnOb%!nH;)gX+!a3nCk?5(f1HaWZBMmmC@lc({dUah+E;NOros{?ui1zPC-Q0);w zEbJmdE$oU$AVGQPdm{?xxI_0CKNG$LbY*i?YRQ$(&;NiA#h@DCxC(U@AJ$Yt}}^xt-EC_ z4!;QlLkjvSOhdx!bR~W|Ezmuf6A#@T`2tsjkr>TvW*lFCMY>Na_v8+{Y|=MCu1P8y z89vPiH5+CKcG-5lzk0oY>~aJC_0+4rS@c@ZVKLAp`G-sJB$$)^4*A!B zmcf}lIw|VxV9NSoJ8Ag3CwN&d7`|@>&B|l9G8tXT^BDHOUPrtC70NgwN4${$k~d_4 zJ@eo6%YQnOgq$th?0{h`KnqYa$Nz@vlHw<%!C5du6<*j1nwquk=uY}B8r7f|lY+v7 zm|JU$US08ugor8E$h3wH$c&i~;guC|3-tqJy#T;v(g( zBZtPMSyv%jzf->435yM(-UfyHq_D=6;ouL4!ZoD+xI5uCM5ay2m)RPmm$I}h>()hS zO!0gzMxc`BPkUZ)WXaXam%1;)gedA7SM8~8yIy@6TPg!hR0=T>4$Zxd)j&P-pXeSF z9W`lg6@~YDhd19B9ETv(%er^Xp8Yj@AuFVR_8t*KS;6VHkEDKI#!@l!l3v6`W1`1~ zP{C@keuV4Q`Rjc08lx?zmT$e$!3esc9&$XZf4nRL(Z*@keUbk!GZi(2Bmyq*saOD? z3Q$V<*P-X1p2}aQmuMw9nSMbOzuASsxten7DKd6A@ftZ=NhJ(0IM|Jr<91uAul4JR zADqY^AOVT3a(NIxg|U;fyc#ZnSzw2cr}#a5lZ38>nP{05D)7~ad7JPhw!LqOwATXtRhK!w0X4HgS1i<%AxbFmGJx9?sEURV+S{k~g zGYF$IWSlQonq6}e;B(X(sIH|;52+(LYW}v_gBcp|x%rEAVB`5LXg_d5{Q5tMDu0_2 z|LOm$@K2?lrLNF=mr%YP|U-t)~9bqd+wHb4KuPmNK<}PK6e@aosGZK57=Zt+kcszVOSbe;`E^dN! ze7`ha3WUUU7(nS0{?@!}{0+-VO4A{7+nL~UOPW9_P(6^GL0h${SLtqG!} zKl~Ng5#@Sy?65wk9z*3SA`Dpd4b4T^@C8Fhd8O)k_4%0RZL5?#b~jmgU+0|DB%0Z) zql-cPC>A9HPjdOTpPC` zQwvF}uB5kG$Xr4XnaH#ruSjM*xG?_hT7y3G+8Ox`flzU^QIgb_>2&-f+XB6MDr-na zSi#S+c!ToK84<&m6sCiGTd^8pNdXo+$3^l3FL_E`0 z>8it5YIDxtTp2Tm(?}FX^w{fbfgh7>^8mtvN>9fWgFN_*a1P`Gz*dyOZF{OV7BC#j zQV=FQM5m>47xXgapI$WbPM5V`V<7J9tD)oz@d~MDoM`R^Y6-Na(lO~uvZlpu?;zw6 zVO1faor3dg#JEb5Q*gz4<W8tgC3nE2BG2jeIQs1)<{In&7hJ39x=;ih;CJDy)>0S1at*7n?Wr0ahYCpFjZ|@u91Zl7( zv;CSBRC65-6f+*JPf4p1UZ)k=XivKTX6_bWT~7V#rq0Xjas6hMO!HJN8GdpBKg_$B zwDHJF6;z?h<;GXFZan8W{XFNPpOj!(&I1`&kWO86p?Xz`a$`7qV7Xqev|7nn_lQuX ziGpU1MMYt&5dE2A62iX3;*0WzNB9*nSTzI%62A+N?f?;S>N@8M=|ef3gtQTIA*=yq zQAAjOqa!CkHOQo4?TsqrrsJLclXcP?dlAVv?v`}YUjo1Htt;6djP@NPFH+&p1I+f_ z)Y279{7OWomY8baT(4TAOlz1OyD{4P?(DGv3XyJTA2IXe=kqD)^h(@*E3{I~w;ws8 z)ZWv7E)pbEM zd3MOXRH3mQhks9 zv6{s;k0y5vrcjXaVfw8^>YyPo=oIqd5IGI{)+TZq5Z5O&hXAw%ZlL}^6FugH;-%vP zAaKFtt3i^ag226=f0YjzdPn6|4(C2sC5wHFX{7QF!tG1E-JFA`>eZ`}$ymcRJK?0c zN363o{&ir)QySOFY0vcu6)kX#;l??|7o{HBDVJN+17rt|w3;(C_1b>d;g9Gp=8YVl zYTtA52@!7AUEkTm@P&h#eg+F*lR zQ7iotZTcMR1frJ0*V@Hw__~CL>_~2H2cCtuzYIUD24=Cv!1j6s{QS!v=PzwQ(a0HS zBKx04KA}-Ue+%9d`?PG*hIij@54RDSQpA7|>qYVIrK_G6%6;#ZkR}NjUgmGju)2F`>|WJoljo)DJgZr4eo1k1i1+o z1D{>^RlpIY8OUaOEf5EBu%a&~c5aWnqM zxBpJq98f=%M^{4mm~5`CWl%)nFR64U{(chmST&2jp+-r z3675V<;Qi-kJud%oWnCLdaU-)xTnMM%rx%Jw6v@=J|Ir=4n-1Z23r-EVf91CGMGNz zb~wyv4V{H-hkr3j3WbGnComiqmS0vn?n?5v2`Vi>{Ip3OZUEPN7N8XeUtF)Ry6>y> zvn0BTLCiqGroFu|m2zG-;Xb6;W`UyLw)@v}H&(M}XCEVXZQoWF=Ykr5lX3XWwyNyF z#jHv)A*L~2BZ4lX?AlN3X#axMwOC)PoVy^6lCGse9bkGjb=qz%kDa6}MOmSwK`cVO zt(e*MW-x}XtU?GY5}9{MKhRhYOlLhJE5=ca+-RmO04^ z66z{40J=s=ey9OCdc(RCzy zd7Zr1%!y3}MG(D=wM_ebhXnJ@MLi7cImDkhm0y{d-Vm81j`0mbi4lF=eirlr)oW~a zCd?26&j^m4AeXEsIUXiTal)+SPM4)HX%%YWF1?(FV47BaA`h9m67S9x>hWMVHx~Hg z1meUYoLL(p@b3?x|9DgWeI|AJ`Ia84*P{Mb%H$ZRROouR4wZhOPX15=KiBMHl!^JnCt$Az`KiH^_d>cev&f zaG2>cWf$=A@&GP~DubsgYb|L~o)cn5h%2`i^!2)bzOTw2UR!>q5^r&2Vy}JaWFUQE04v>2;Z@ZPwXr?y&G(B^@&y zsd6kC=hHdKV>!NDLIj+3rgZJ|dF`%N$DNd;B)9BbiT9Ju^Wt%%u}SvfM^=|q-nxDG zuWCQG9e#~Q5cyf8@y76#kkR^}{c<_KnZ0QsZcAT|YLRo~&tU|N@BjxOuy`#>`X~Q< z?R?-Gsk$$!oo(BveQLlUrcL#eirhgBLh`qHEMg`+sR1`A=1QX7)ZLMRT+GBy?&mM8 zQG^z-!Oa&J-k7I(3_2#Q6Bg=NX<|@X&+YMIOzfEO2$6Mnh}YV!m!e^__{W@-CTprr zbdh3f=BeCD$gHwCrmwgM3LAv3!Mh$wM)~KWzp^w)Cu6roO7uUG5z*}i0_0j47}pK; ztN530`ScGatLOL06~zO)Qmuv`h!gq5l#wx(EliKe&rz-5qH(hb1*fB#B+q`9=jLp@ zOa2)>JTl7ovxMbrif`Xe9;+fqB1K#l=Dv!iT;xF zdkCvS>C5q|O;}ns3AgoE({Ua-zNT-9_5|P0iANmC6O76Sq_(AN?UeEQJ>#b54fi3k zFmh+P%b1x3^)0M;QxXLP!BZ^h|AhOde*{9A=f3|Xq*JAs^Y{eViF|=EBfS6L%k4ip zk+7M$gEKI3?bQg?H3zaE@;cyv9kv;cqK$VxQbFEsy^iM{XXW0@2|DOu$!-k zSFl}Y=jt-VaT>Cx*KQnHTyXt}f9XswFB9ibYh+k2J!ofO+nD?1iw@mwtrqI4_i?nE zhLkPp41ED62me}J<`3RN80#vjW;wt`pP?%oQ!oqy7`miL>d-35a=qotK$p{IzeSk# ze_$CFYp_zIkrPFVaW^s#U4xT1lI^A0IBe~Y<4uS%zSV=wcuLr%gQT=&5$&K*bwqx| zWzCMiz>7t^Et@9CRUm9E+@hy~sBpm9fri$sE1zgLU((1?Yg{N1Sars=DiW&~Zw=3I zi7y)&oTC?UWD2w97xQ&5vx zRXEBGeJ(I?Y}eR0_O{$~)bMJRTsNUPIfR!xU9PE7A>AMNr_wbrFK>&vVw=Y;RH zO$mlpmMsQ}-FQ2cSj7s7GpC+~^Q~dC?y>M}%!-3kq(F3hGWo9B-Gn02AwUgJ>Z-pKOaj zysJBQx{1>Va=*e@sLb2z&RmQ7ira;aBijM-xQ&cpR>X3wP^foXM~u1>sv9xOjzZpX z0K;EGouSYD~oQ&lAafj3~EaXfFShC+>VsRlEMa9cg9i zFxhCKO}K0ax6g4@DEA?dg{mo>s+~RPI^ybb^u--^nTF>**0l5R9pocwB?_K)BG_)S zyLb&k%XZhBVr7U$wlhMqwL)_r&&n%*N$}~qijbkfM|dIWP{MyLx}X&}ES?}7i;9bW zmTVK@zR)7kE2+L42Q`n4m0VVg5l5(W`SC9HsfrLZ=v%lpef=Gj)W59VTLe+Z$8T8i z4V%5+T0t8LnM&H>Rsm5C%qpWBFqgTwL{=_4mE{S3EnBXknM&u8n}A^IIM4$s3m(Rd z>zq=CP-!9p9es2C*)_hoL@tDYABn+o#*l;6@7;knWIyDrt5EuakO99S$}n((Fj4y} zD!VvuRzghcE{!s;jC*<_H$y6!6QpePo2A3ZbX*ZzRnQq*b%KK^NF^z96CHaWmzU@f z#j;y?X=UP&+YS3kZx7;{ zDA{9(wfz7GF`1A6iB6fnXu0?&d|^p|6)%3$aG0Uor~8o? z*e}u#qz7Ri?8Uxp4m_u{a@%bztvz-BzewR6bh*1Xp+G=tQGpcy|4V_&*aOqu|32CM zz3r*E8o8SNea2hYJpLQ-_}R&M9^%@AMx&`1H8aDx4j%-gE+baf2+9zI*+Pmt+v{39 zDZ3Ix_vPYSc;Y;yn68kW4CG>PE5RoaV0n@#eVmk?p$u&Fy&KDTy!f^Hy6&^-H*)#u zdrSCTJPJw?(hLf56%2;_3n|ujUSJOU8VPOTlDULwt0jS@j^t1WS z!n7dZIoT+|O9hFUUMbID4Ec$!cc($DuQWkocVRcYSikFeM&RZ=?BW)mG4?fh#)KVG zcJ!<=-8{&MdE)+}?C8s{k@l49I|Zwswy^ZN3;E!FKyglY~Aq?4m74P-0)sMTGXqd5(S<-(DjjM z&7dL-Mr8jhUCAG$5^mI<|%`;JI5FVUnNj!VO2?Jiqa|c2;4^n!R z`5KK0hyB*F4w%cJ@Un6GC{mY&r%g`OX|1w2$B7wxu97%<@~9>NlXYd9RMF2UM>(z0 zouu4*+u+1*k;+nFPk%ly!nuMBgH4sL5Z`@Rok&?Ef=JrTmvBAS1h?C0)ty5+yEFRz zY$G=coQtNmT@1O5uk#_MQM1&bPPnspy5#>=_7%WcEL*n$;sSAZcXxMpcXxLe;_mLA z5F_paad+bGZV*oh@8h0(|D2P!q# zTHjmiphJ=AazSeKQPkGOR-D8``LjzToyx{lfK-1CDD6M7?pMZOdLKFtjZaZMPk4}k zW)97Fh(Z+_Fqv(Q_CMH-YYi?fR5fBnz7KOt0*t^cxmDoIokc=+`o# zrud|^h_?KW=Gv%byo~(Ln@({?3gnd?DUf-j2J}|$Mk>mOB+1{ZQ8HgY#SA8END(Zw z3T+W)a&;OO54~m}ffemh^oZ!Vv;!O&yhL0~hs(p^(Yv=(3c+PzPXlS5W79Er8B1o* z`c`NyS{Zj_mKChj+q=w)B}K za*zzPhs?c^`EQ;keH{-OXdXJet1EsQ)7;{3eF!-t^4_Srg4(Ot7M*E~91gwnfhqaM zNR7dFaWm7MlDYWS*m}CH${o?+YgHiPC|4?X?`vV+ws&Hf1ZO-w@OGG^o4|`b{bLZj z&9l=aA-Y(L11!EvRjc3Zpxk7lc@yH1e$a}8$_-r$)5++`_eUr1+dTb@ zU~2P1HM#W8qiNN3b*=f+FfG1!rFxnNlGx{15}BTIHgxO>Cq4 z;#9H9YjH%>Z2frJDJ8=xq>Z@H%GxXosS@Z>cY9ppF+)e~t_hWXYlrO6)0p7NBMa`+ z^L>-#GTh;k_XnE)Cgy|0Dw;(c0* zSzW14ZXozu)|I@5mRFF1eO%JM=f~R1dkNpZM+Jh(?&Zje3NgM{2ezg1N`AQg5%+3Y z64PZ0rPq6;_)Pj-hyIOgH_Gh`1$j1!jhml7ksHA1`CH3FDKiHLz+~=^u@kUM{ilI5 z^FPiJ7mSrzBs9{HXi2{sFhl5AyqwUnU{sPcUD{3+l-ZHAQ)C;c$=g1bdoxeG(5N01 zZy=t8i{*w9m?Y>V;uE&Uy~iY{pY4AV3_N;RL_jT_QtLFx^KjcUy~q9KcLE3$QJ{!)@$@En{UGG7&}lc*5Kuc^780;7Bj;)X?1CSy*^^ zPP^M)Pr5R>mvp3_hmCtS?5;W^e@5BjE>Cs<`lHDxj<|gtOK4De?Sf0YuK5GX9G93i zMYB{8X|hw|T6HqCf7Cv&r8A$S@AcgG1cF&iJ5=%+x;3yB`!lQ}2Hr(DE8=LuNb~Vs z=FO&2pdc16nD$1QL7j+!U^XWTI?2qQKt3H8=beVTdHHa9=MiJ&tM1RRQ-=+vy!~iz zj3O{pyRhCQ+b(>jC*H)J)%Wq}p>;?@W*Eut@P&?VU+Sdw^4kE8lvX|6czf{l*~L;J zFm*V~UC;3oQY(ytD|D*%*uVrBB}BbAfjK&%S;z;7$w68(8PV_whC~yvkZmX)xD^s6 z{$1Q}q;99W?*YkD2*;)tRCS{q2s@JzlO~<8x9}X<0?hCD5vpydvOw#Z$2;$@cZkYrp83J0PsS~!CFtY%BP=yxG?<@#{7%2sy zOc&^FJxsUYN36kSY)d7W=*1-{7ghPAQAXwT7z+NlESlkUH&8ODlpc8iC*iQ^MAe(B z?*xO4i{zFz^G=^G#9MsLKIN64rRJykiuIVX5~0#vAyDWc9-=6BDNT_aggS2G{B>dD ze-B%d3b6iCfc5{@yz$>=@1kdK^tX9qh0=ocv@9$ai``a_ofxT=>X7_Y0`X}a^M?d# z%EG)4@`^Ej_=%0_J-{ga!gFtji_byY&Vk@T1c|ucNAr(JNr@)nCWj?QnCyvXg&?FW;S-VOmNL6^km_dqiVjJuIASVGSFEos@EVF7St$WE&Z%)`Q##+0 zjaZ=JI1G@0!?l|^+-ZrNd$WrHBi)DA0-Eke>dp=_XpV<%CO_Wf5kQx}5e<90dt>8k zAi00d0rQ821nA>B4JHN7U8Zz=0;9&U6LOTKOaC1FC8GgO&kc=_wHIOGycL@c*$`ce703t%>S}mvxEnD-V!;6c`2(p74V7D0No1Xxt`urE66$0(ThaAZ1YVG#QP$ zy~NN%kB*zhZ2Y!kjn826pw4bh)75*e!dse+2Db(;bN34Uq7bLpr47XTX{8UEeC?2i z*{$`3dP}32${8pF$!$2Vq^gY|#w+VA_|o(oWmQX8^iw#n_crb(K3{69*iU?<%C-%H zuKi)3M1BhJ@3VW>JA`M>L~5*_bxH@Euy@niFrI$82C1}fwR$p2E&ZYnu?jlS}u7W9AyfdXh2pM>78bIt3 z)JBh&XE@zA!kyCDfvZ1qN^np20c1u#%P6;6tU&dx0phT1l=(mw7`u!-0e=PxEjDds z9E}{E!7f9>jaCQhw)&2TtG-qiD)lD(4jQ!q{`x|8l&nmtHkdul# zy+CIF8lKbp9_w{;oR+jSLtTfE+B@tOd6h=QePP>rh4@~!8c;Hlg9m%%&?e`*Z?qz5-zLEWfi>`ord5uHF-s{^bexKAoMEV@9nU z^5nA{f{dW&g$)BAGfkq@r5D)jr%!Ven~Q58c!Kr;*Li#`4Bu_?BU0`Y`nVQGhNZk@ z!>Yr$+nB=`z#o2nR0)V3M7-eVLuY`z@6CT#OTUXKnxZn$fNLPv7w1y7eGE=Qv@Hey`n;`U=xEl|q@CCV^#l)s0ZfT+mUf z^(j5r4)L5i2jnHW4+!6Si3q_LdOLQi<^fu?6WdohIkn79=jf%Fs3JkeXwF(?_tcF? z?z#j6iXEd(wJy4|p6v?xNk-)iIf2oX5^^Y3q3ziw16p9C6B;{COXul%)`>nuUoM*q zzmr|NJ5n)+sF$!yH5zwp=iM1#ZR`O%L83tyog-qh1I z0%dcj{NUs?{myT~33H^(%0QOM>-$hGFeP;U$puxoJ>>o-%Lk*8X^rx1>j|LtH$*)>1C!Pv&gd16%`qw5LdOIUbkNhaBBTo}5iuE%K&ZV^ zAr_)kkeNKNYJRgjsR%vexa~&8qMrQYY}+RbZ)egRg9_$vkoyV|Nc&MH@8L)`&rpqd zXnVaI@~A;Z^c3+{x=xgdhnocA&OP6^rr@rTvCnhG6^tMox$ulw2U7NgUtW%|-5VeH z_qyd47}1?IbuKtqNbNx$HR`*+9o=8`%vM8&SIKbkX9&%TS++x z5|&6P<%=F$C?owUI`%uvUq^yW0>`>yz!|WjzsoB9dT;2Dx8iSuK%%_XPgy0dTD4kd zDXF@&O_vBVVKQq(9YTClUPM30Sk7B!v7nOyV`XC!BA;BIVwphh+c)?5VJ^(C;GoQ$ zvBxr7_p*k$T%I1ke}`U&)$uf}I_T~#3XTi53OX)PoXVgxEcLJgZG^i47U&>LY(l%_ z;9vVDEtuMCyu2fqZeez|RbbIE7@)UtJvgAcVwVZNLccswxm+*L&w`&t=ttT=sv6Aq z!HouSc-24Y9;0q$>jX<1DnnGmAsP))- z^F~o99gHZw`S&Aw7e4id6Lg7kMk-e)B~=tZ!kE7sGTOJ)8@q}np@j7&7Sy{2`D^FH zI7aX%06vKsfJ168QnCM2=l|i>{I{%@gcr>ExM0Dw{PX6ozEuqFYEt z087%MKC;wVsMV}kIiuu9Zz9~H!21d!;Cu#b;hMDIP7nw3xSX~#?5#SSjyyg+Y@xh| z%(~fv3`0j#5CA2D8!M2TrG=8{%>YFr(j)I0DYlcz(2~92?G*?DeuoadkcjmZszH5& zKI@Lis%;RPJ8mNsbrxH@?J8Y2LaVjUIhRUiO-oqjy<&{2X~*f|)YxnUc6OU&5iac= z*^0qwD~L%FKiPmlzi&~a*9sk2$u<7Al=_`Ox^o2*kEv?p`#G(p(&i|ot8}T;8KLk- zPVf_4A9R`5^e`Om2LV*cK59EshYXse&IoByj}4WZaBomoHAPKqxRKbPcD`lMBI)g- zeMRY{gFaUuecSD6q!+b5(?vAnf>c`Z(8@RJy%Ulf?W~xB1dFAjw?CjSn$ph>st5bc zUac1aD_m6{l|$#g_v6;=32(mwpveQDWhmjR7{|B=$oBhz`7_g7qNp)n20|^^op3 zSfTdWV#Q>cb{CMKlWk91^;mHap{mk)o?udk$^Q^^u@&jd zfZ;)saW6{e*yoL6#0}oVPb2!}r{pAUYtn4{P~ES9tTfC5hXZnM{HrC8^=Pof{G4%Bh#8 ze~?C9m*|fd8MK;{L^!+wMy>=f^8b&y?yr6KnTq28$pFMBW9Oy7!oV5z|VM$s-cZ{I|Xf@}-)1=$V&x7e;9v81eiTi4O5-vs?^5pCKy2l>q);!MA zS!}M48l$scB~+Umz}7NbwyTn=rqt@`YtuwiQSMvCMFk2$83k50Q>OK5&fe*xCddIm)3D0I6vBU<+!3=6?(OhkO|b4fE_-j zimOzyfBB_*7*p8AmZi~X2bgVhyPy>KyGLAnOpou~sx9)S9%r)5dE%ADs4v%fFybDa_w*0?+>PsEHTbhKK^G=pFz z@IxLTCROWiKy*)cV3y%0FwrDvf53Ob_XuA1#tHbyn%Ko!1D#sdhBo`;VC*e1YlhrC z?*y3rp86m#qI|qeo8)_xH*G4q@70aXN|SP+6MQ!fJQqo1kwO_v7zqvUfU=Gwx`CR@ zRFb*O8+54%_8tS(ADh}-hUJzE`s*8wLI>1c4b@$al)l}^%GuIXjzBK!EWFO8W`>F^ ze7y#qPS0NI7*aU)g$_ziF(1ft;2<}6Hfz10cR8P}67FD=+}MfhrpOkF3hFhQu;Q1y zu%=jJHTr;0;oC94Hi@LAF5quAQ(rJG(uo%BiRQ@8U;nhX)j0i?0SL2g-A*YeAqF>RVCBOTrn{0R27vu}_S zS>tX4!#&U4W;ikTE!eFH+PKw%p+B(MR2I%n#+m0{#?qRP_tR@zpgCb=4rcrL!F=;A zh%EIF8m6%JG+qb&mEfuFTLHSxUAZEvC-+kvZKyX~SA3Umt`k}}c!5dy?-sLIM{h@> z!2=C)@nx>`;c9DdwZ&zeUc(7t<21D7qBj!|1^Mp1eZ6)PuvHx+poKSDCSBMFF{bKy z;9*&EyKitD99N}%mK8431rvbT+^%|O|HV23{;RhmS{$5tf!bIPoH9RKps`-EtoW5h zo6H_!s)Dl}2gCeGF6>aZtah9iLuGd19^z0*OryPNt{70RvJSM<#Ox9?HxGg04}b^f zrVEPceD%)#0)v5$YDE?f`73bQ6TA6wV;b^x*u2Ofe|S}+q{s5gr&m~4qGd!wOu|cZ||#h_u=k*fB;R6&k?FoM+c&J;ISg70h!J7*xGus)ta4veTdW)S^@sU@ z4$OBS=a~@F*V0ECic;ht4@?Jw<9kpjBgHfr2FDPykCCz|v2)`JxTH55?b3IM={@DU z!^|9nVO-R#s{`VHypWyH0%cs;0GO3E;It6W@0gX6wZ%W|Dzz&O%m17pa19db(er}C zUId1a4#I+Ou8E1MU$g=zo%g7K(=0Pn$)Rk z<4T2u<0rD)*j+tcy2XvY+0 z0d2pqm4)4lDewsAGThQi{2Kc3&C=|OQF!vOd#WB_`4gG3@inh-4>BoL!&#ij8bw7? zqjFRDaQz!J-YGitV4}$*$hg`vv%N)@#UdzHFI2E<&_@0Uw@h_ZHf}7)G;_NUD3@18 zH5;EtugNT0*RXVK*by>WS>jaDDfe!A61Da=VpIK?mcp^W?!1S2oah^wowRnrYjl~`lgP-mv$?yb6{{S55CCu{R z$9;`dyf0Y>uM1=XSl_$01Lc1Iy68IosWN8Q9Op=~I(F<0+_kKfgC*JggjxNgK6 z-3gQm6;sm?J&;bYe&(dx4BEjvq}b`OT^RqF$J4enP1YkeBK#>l1@-K`ajbn05`0J?0daOtnzh@l3^=BkedW1EahZlRp;`j*CaT;-21&f2wU z+Nh-gc4I36Cw+;3UAc<%ySb`#+c@5y ze~en&bYV|kn?Cn|@fqmGxgfz}U!98$=drjAkMi`43I4R%&H0GKEgx-=7PF}y`+j>r zg&JF`jomnu2G{%QV~Gf_-1gx<3Ky=Md9Q3VnK=;;u0lyTBCuf^aUi?+1+`4lLE6ZK zT#(Bf`5rmr(tgTbIt?yA@y`(Ar=f>-aZ}T~>G32EM%XyFvhn&@PWCm#-<&ApLDCXT zD#(9m|V(OOo7PmE@`vD4$S5;+9IQm19dd zvMEU`)E1_F+0o0-z>YCWqg0u8ciIknU#{q02{~YX)gc_u;8;i233D66pf(IkTDxeN zL=4z2)?S$TV9=ORVr&AkZMl<4tTh(v;Ix1{`pPVqI3n2ci&4Dg+W|N8TBUfZ*WeLF zqCH_1Q0W&f9T$lx3CFJ$o@Lz$99 zW!G&@zFHxTaP!o#z^~xgF|(vrHz8R_r9eo;TX9}2ZyjslrtH=%6O)?1?cL&BT(Amp zTGFU1%%#xl&6sH-UIJk_PGk_McFn7=%yd6tAjm|lnmr8bE2le3I~L{0(ffo}TQjyo zHZZI{-}{E4ohYTlZaS$blB!h$Jq^Rf#(ch}@S+Ww&$b);8+>g84IJcLU%B-W?+IY& zslcZIR>+U4v3O9RFEW;8NpCM0w1ROG84=WpKxQ^R`{=0MZCubg3st z48AyJNEvyxn-jCPTlTwp4EKvyEwD3e%kpdY?^BH0!3n6Eb57_L%J1=a*3>|k68A}v zaW`*4YitylfD}ua8V)vb79)N_Ixw_mpp}yJGbNu+5YYOP9K-7nf*jA1#<^rb4#AcS zKg%zCI)7cotx}L&J8Bqo8O1b0q;B1J#B5N5Z$Zq=wX~nQFgUfAE{@u0+EnmK{1hg> zC{vMfFLD;L8b4L+B51&LCm|scVLPe6h02rws@kGv@R+#IqE8>Xn8i|vRq_Z`V;x6F zNeot$1Zsu`lLS92QlLWF54za6vOEKGYQMdX($0JN*cjG7HP&qZ#3+bEN$8O_PfeAb z0R5;=zXac2IZ?fxu59?Nka;1lKm|;0)6|#RxkD05P5qz;*AL@ig!+f=lW5^Jbag%2 z%9@iM0ph$WFlxS!`p31t92z~TB}P-*CS+1Oo_g;7`6k(Jyj8m8U|Q3Sh7o-Icp4kV zK}%qri5>?%IPfamXIZ8pXbm-#{ytiam<{a5A+3dVP^xz!Pvirsq7Btv?*d7eYgx7q zWFxrzb3-%^lDgMc=Vl7^={=VDEKabTG?VWqOngE`Kt7hs236QKidsoeeUQ_^FzsXjprCDd@pW25rNx#6x&L6ZEpoX9Ffzv@olnH3rGOSW( zG-D|cV0Q~qJ>-L}NIyT?T-+x+wU%;+_GY{>t(l9dI%Ximm+Kmwhee;FK$%{dnF;C% zFjM2&$W68Sz#d*wtfX?*WIOXwT;P6NUw}IHdk|)fw*YnGa0rHx#paG!m=Y6GkS4VX zX`T$4eW9k1W!=q8!(#8A9h67fw))k_G)Q9~Q1e3f`aV@kbcSv7!priDUN}gX(iXTy zr$|kU0Vn%*ylmyDCO&G0Z3g>%JeEPFAW!5*H2Ydl>39w3W+gEUjL&vrRs(xGP{(ze zy7EMWF14@Qh>X>st8_029||TP0>7SG9on_xxeR2Iam3G~Em$}aGsNt$iES9zFa<3W zxtOF*!G@=PhfHO!=9pVPXMUVi30WmkPoy$02w}&6A7mF)G6-`~EVq5CwD2`9Zu`kd)52``#V zNSb`9dG~8(dooi1*-aSMf!fun7Sc`-C$-E(3BoSC$2kKrVcI!&yC*+ff2+C-@!AT_ zsvlAIV+%bRDfd{R*TMF><1&_a%@yZ0G0lg2K;F>7b+7A6pv3-S7qWIgx+Z?dt8}|S z>Qbb6x(+^aoV7FQ!Ph8|RUA6vXWQH*1$GJC+wXLXizNIc9p2yLzw9 z0=MdQ!{NnOwIICJc8!+Jp!zG}**r#E!<}&Te&}|B4q;U57$+pQI^}{qj669zMMe_I z&z0uUCqG%YwtUc8HVN7?0GHpu=bL7&{C>hcd5d(iFV{I5c~jpX&!(a{yS*4MEoYXh z*X4|Y@RVfn;piRm-C%b@{0R;aXrjBtvx^HO;6(>i*RnoG0Rtcd25BT6edxTNOgUAOjn zJ2)l{ipj8IP$KID2}*#F=M%^n&=bA0tY98@+2I+7~A&T-tw%W#3GV>GTmkHaqftl)#+E zMU*P(Rjo>8%P@_@#UNq(_L{}j(&-@1iY0TRizhiATJrnvwSH0v>lYfCI2ex^><3$q znzZgpW0JlQx?JB#0^^s-Js1}}wKh6f>(e%NrMwS`Q(FhazkZb|uyB@d%_9)_xb$6T zS*#-Bn)9gmobhAtvBmL+9H-+0_0US?g6^TOvE8f3v=z3o%NcPjOaf{5EMRnn(_z8- z$|m0D$FTU zDy;21v-#0i)9%_bZ7eo6B9@Q@&XprR&oKl4m>zIj-fiRy4Dqy@VVVs?rscG| zmzaDQ%>AQTi<^vYCmv#KOTd@l7#2VIpsj?nm_WfRZzJako`^uU%Nt3e;cU*y*|$7W zLm%fX#i_*HoUXu!NI$ey>BA<5HQB=|nRAwK!$L#n-Qz;~`zACig0PhAq#^5QS<8L2 zS3A+8%vbVMa7LOtTEM?55apt(DcWh#L}R^P2AY*c8B}Cx=6OFAdMPj1f>k3#^#+Hk z6uW1WJW&RlBRh*1DLb7mJ+KO>!t^t8hX1#_Wk`gjDio9)9IGbyCAGI4DJ~orK+YRv znjxRMtshZQHc$#Y-<-JOV6g^Cr@odj&Xw5B(FmI)*qJ9NHmIz_r{t)TxyB`L-%q5l ztzHgD;S6cw?7Atg*6E1!c6*gPRCb%t7D%z<(xm+K{%EJNiI2N0l8ud0Ch@_av_RW? zIr!nO4dL5466WslE6MsfMss7<)-S!e)2@r2o=7_W)OO`~CwklRWzHTfpB)_HYwgz=BzLhgZ9S<{nLBOwOIgJU=94uj6r!m>Xyn9>&xP+=5!zG_*yEoRgM0`aYts z^)&8(>z5C-QQ*o_s(8E4*?AX#S^0)aqB)OTyX>4BMy8h(cHjA8ji1PRlox@jB*1n? zDIfyDjzeg91Ao(;Q;KE@zei$}>EnrF6I}q&Xd=~&$WdDsyH0H7fJX|E+O~%LS*7^Q zYzZ4`pBdY{b7u72gZm6^5~O-57HwzwAz{)NvVaowo`X02tL3PpgLjwA`^i9F^vSpN zAqH3mRjG8VeJNHZ(1{%!XqC+)Z%D}58Qel{_weSEHoygT9pN@i zi=G;!Vj6XQk2tuJC>lza%ywz|`f7TIz*EN2Gdt!s199Dr4Tfd_%~fu8gXo~|ogt5Q zlEy_CXEe^BgsYM^o@L?s33WM14}7^T(kqohOX_iN@U?u;$l|rAvn{rwy>!yfZw13U zB@X9)qt&4;(C6dP?yRsoTMI!j-f1KC!<%~i1}u7yLXYn)(#a;Z6~r>hp~kfP));mi zcG%kdaB9H)z9M=H!f>kM->fTjRVOELNwh1amgKQT=I8J66kI)u_?0@$$~5f`u%;zl zC?pkr^p2Fe=J~WK%4ItSzKA+QHqJ@~m|Cduv=Q&-P8I5rQ-#G@bYH}YJr zUS(~(w|vKyU(T(*py}jTUp%I%{2!W!K(i$uvotcPjVddW z8_5HKY!oBCwGZcs-q`4Yt`Zk~>K?mcxg51wkZlX5e#B08I75F7#dgn5yf&Hrp`*%$ zQ;_Qg>TYRzBe$x=T(@WI9SC!ReSas9vDm(yslQjBJZde5z8GDU``r|N(MHcxNopGr z_}u39W_zwWDL*XYYt>#Xo!9kL#97|EAGyGBcRXtLTd59x%m=3i zL^9joWYA)HfL15l9%H?q`$mY27!<9$7GH(kxb%MV>`}hR4a?+*LH6aR{dzrX@?6X4 z3e`9L;cjqYb`cJmophbm(OX0b)!AFG?5`c#zLagzMW~o)?-!@e80lvk!p#&CD8u5_r&wp4O0zQ>y!k5U$h_K;rWGk=U)zX!#@Q%|9g*A zWx)qS1?fq6X<$mQTB$#3g;;5tHOYuAh;YKSBz%il3Ui6fPRv#v62SsrCdMRTav)Sg zTq1WOu&@v$Ey;@^+_!)cf|w_X<@RC>!=~+A1-65O0bOFYiH-)abINwZvFB;hJjL_$ z(9iScmUdMp2O$WW!520Hd0Q^Yj?DK%YgJD^ez$Z^?@9@Ab-=KgW@n8nC&88)TDC+E zlJM)L3r+ZJfZW_T$;Imq*#2<(j+FIk8ls7)WJ6CjUu#r5PoXxQs4b)mZza<8=v{o)VlLRM<9yw^0En#tXAj`Sylxvki{<1DPe^ zhjHwx^;c8tb?Vr$6ZB;$Ff$+3(*oinbwpN-#F)bTsXq@Sm?43MC#jQ~`F|twI=7oC zH4TJtu#;ngRA|Y~w5N=UfMZi?s0%ZmKUFTAye&6Y*y-%c1oD3yQ%IF2q2385Zl+=> zfz=o`Bedy|U;oxbyb^rB9ixG{Gb-{h$U0hVe`J;{ql!s_OJ_>>eoQn(G6h7+b^P48 zG<=Wg2;xGD-+d@UMZ!c;0>#3nws$9kIDkK13IfloGT@s14AY>&>>^#>`PT7GV$2Hp zN<{bN*ztlZu_%W=&3+=#3bE(mka6VoHEs~0BjZ$+=0`a@R$iaW)6>wp2w)=v2@|2d z%?34!+iOc5S@;AAC4hELWLH56RGxo4jw8MDMU0Wk2k_G}=Vo(>eRFo(g3@HjG|`H3 zm8b*dK=moM*oB<)*A$M9!!5o~4U``e)wxavm@O_R(`P|u%9^LGi(_%IF<6o;NLp*0 zKsfZ0#24GT8(G`i4UvoMh$^;kOhl?`0yNiyrC#HJH=tqOH^T_d<2Z+ zeN>Y9Zn!X4*DMCK^o75Zk2621bdmV7Rx@AX^alBG4%~;G_vUoxhfhFRlR&+3WwF^T zaL)8xPq|wCZoNT^>3J0K?e{J-kl+hu2rZI>CUv#-z&u@`hjeb+bBZ>bcciQVZ{SbW zez04s9oFEgc8Z+Kp{XFX`MVf-s&w9*dx7wLen(_@y34}Qz@&`$2+osqfxz4&d}{Ql z*g1ag00Gu+$C`0avds{Q65BfGsu9`_`dML*rX~hyWIe$T>CsPRoLIr%MTk3pJ^2zH1qub1MBzPG}PO;Wmav9w%F7?%l=xIf#LlP`! z_Nw;xBQY9anH5-c8A4mME}?{iewjz(Sq-29r{fV;Fc>fv%0!W@(+{={Xl-sJ6aMoc z)9Q+$bchoTGTyWU_oI19!)bD=IG&OImfy;VxNXoIO2hYEfO~MkE#IXTK(~?Z&!ae! zl8z{D&2PC$Q*OBC(rS~-*-GHNJ6AC$@eve>LB@Iq;jbBZj`wk4|LGogE||Ie=M5g= z9d`uYQ1^Sr_q2wmZE>w2WG)!F%^KiqyaDtIAct?}D~JP4shTJy5Bg+-(EA8aXaxbd~BKMtTf2iQ69jD1o* zZF9*S3!v-TdqwK$%&?91Sh2=e63;X0Lci@n7y3XOu2ofyL9^-I767eHESAq{m+@*r zbVDx!FQ|AjT;!bYsXv8ilQjy~Chiu&HNhFXt3R_6kMC8~ChEFqG@MWu#1Q1#=~#ix zrkHpJre_?#r=N0wv`-7cHHqU`phJX2M_^{H0~{VP79Dv{6YP)oA1&TSfKPEPZn2)G z9o{U1huZBLL;Tp_0OYw@+9z(jkrwIGdUrOhKJUbwy?WBt zlIK)*K0lQCY0qZ!$%1?3A#-S70F#YyUnmJF*`xx?aH5;gE5pe-15w)EB#nuf6B*c~ z8Z25NtY%6Wlb)bUA$w%HKs5$!Z*W?YKV-lE0@w^{4vw;J>=rn?u!rv$&eM+rpU6rc=j9>N2Op+C{D^mospMCjF2ZGhe4eADA#skp2EA26%p3Ex9wHW8l&Y@HX z$Qv)mHM}4*@M*#*ll5^hE9M^=q~eyWEai*P;4z<9ZYy!SlNE5nlc7gm;M&Q zKhKE4d*%A>^m0R?{N}y|i6i^k>^n4(wzKvlQeHq{l&JuFD~sTsdhs`(?lFK@Q{pU~ zb!M3c@*3IwN1RUOVjY5>uT+s-2QLWY z4T2>fiSn>>Fob+%B868-v9D@AfWr#M8eM6w#eAlhc#zk6jkLxGBGk`E3$!A@*am!R zy>29&ptYK6>cvP`b!syNp)Q$0UOW|-O@)8!?94GOYF_}+zlW%fCEl|Tep_zx05g6q z>tp47e-&R*hSNe{6{H!mL?+j$c^TXT{C&@T-xIaesNCl05 z9SLb@q&mSb)I{VXMaiWa3PWj=Ed!>*GwUe;^|uk=Pz$njNnfFY^MM>E?zqhf6^{}0 zx&~~dA5#}1ig~7HvOQ#;d9JZBeEQ+}-~v$at`m!(ai z$w(H&mWCC~;PQ1$%iuz3`>dWeb3_p}X>L2LK%2l59Tyc}4m0>9A!8rhoU3m>i2+hl zx?*qs*c^j}+WPs>&v1%1Ko8_ivAGIn@QK7A`hDz-Emkcgv2@wTbYhkiwX2l=xz*XG zaiNg+j4F-I>9v+LjosI-QECrtKjp&0T@xIMKVr+&)gyb4@b3y?2CA?=ooN zT#;rU86WLh(e@#mF*rk(NV-qSIZyr z$6!ZUmzD)%yO-ot`rw3rp6?*_l*@Z*IB0xn4|BGPWHNc-1ZUnNSMWmDh=EzWJRP`) zl%d%J613oXzh5;VY^XWJi{lB`f#u+ThvtP7 zq(HK<4>tw(=yzSBWtYO}XI`S1pMBe3!jFxBHIuwJ(@%zdQFi1Q_hU2eDuHqXte7Ki zOV55H2D6u#4oTfr7|u*3p75KF&jaLEDpxk!4*bhPc%mpfj)Us3XIG3 zIKMX^s^1wt8YK7Ky^UOG=w!o5e7W-<&c|fw2{;Q11vm@J{)@N3-p1U>!0~sKWHaL= zWV(0}1IIyt1p%=_-Fe5Kfzc71wg}`RDDntVZv;4!=&XXF-$48jS0Sc;eDy@Sg;+{A zFStc{dXT}kcIjMXb4F7MbX~2%i;UrBxm%qmLKb|2=?uPr00-$MEUIGR5+JG2l2Nq` zkM{{1RO_R)+8oQ6x&-^kCj)W8Z}TJjS*Wm4>hf+4#VJP)OBaDF%3pms7DclusBUw} z{ND#!*I6h85g6DzNvdAmnwWY{&+!KZM4DGzeHI?MR@+~|su0{y-5-nICz_MIT_#FE zm<5f3zlaKq!XyvY3H`9s&T};z!cK}G%;~!rpzk9-6L}4Rg7vXtKFsl}@sT#U#7)x- z7UWue5sa$R>N&b{J61&gvKcKlozH*;OjoDR+elkh|4bJ!_3AZNMOu?n9&|L>OTD78 z^i->ah_Mqc|Ev)KNDzfu1P3grBIM#%`QZqj5W{qu(HocQhjyS;UINoP`{J+DvV?|1 z_sw6Yr3z6%e7JKVDY<$P=M)dbk@~Yw9|2!Cw!io3%j92wTD!c^e9Vj+7VqXo3>u#= zv#M{HHJ=e$X5vQ>>ML?E8#UlmvJgTnb73{PSPTf*0)mcj6C z{KsfUbDK|F$E(k;ER%8HMdDi`=BfpZzP3cl5yJHu;v^o2FkHNk;cXc17tL8T!CsYI zfeZ6sw@;8ia|mY_AXjCS?kUfxdjDB28)~Tz1dGE|{VfBS9`0m2!m1yG?hR})er^pl4c@9Aq+|}ZlDaHL)K$O| z%9Jp-imI-Id0|(d5{v~w6mx)tUKfbuVD`xNt04Mry%M+jXzE>4(TBsx#&=@wT2Vh) z1yeEY&~17>0%P(eHP0HB^|7C+WJxQBTG$uyOWY@iDloRIb-Cf!p<{WQHR!422#F34 zG`v|#CJ^G}y9U*7jgTlD{D&y$Iv{6&PYG>{Ixg$pGk?lWrE#PJ8KunQC@}^6OP!|< zS;}p3to{S|uZz%kKe|;A0bL0XxPB&Q{J(9PyX`+Kr`k~r2}yP^ND{8!v7Q1&vtk& z2Y}l@J@{|2`oA%sxvM9i0V+8IXrZ4;tey)d;LZI70Kbim<4=WoTPZy=Yd|34v#$Kh zx|#YJ8s`J>W&jt#GcMpx84w2Z3ur-rK7gf-p5cE)=w1R2*|0mj12hvapuUWM0b~dG zMg9p8FmAZI@i{q~0@QuY44&mMUNXd7z>U58shA3o`p5eVLpq>+{(<3->DWuSFVZwC zxd50Uz(w~LxC4}bgag#q#NNokK@yNc+Q|Ap!u>Ddy+df>v;j@I12CDNN9do+0^n8p zMQs7X#+FVF0C5muGfN{r0|Nkql%BQT|K(DDNdR2pzM=_ea5+GO|J67`05AV92t@4l z0Qno0078PIHdaQGHZ~Scw!dzgqjK~3B7kf>BcP__&lLyU(cu3B^uLo%{j|Mb0NR)tkeT7Hcwp4O# z)yzu>cvG(d9~0a^)eZ;;%3ksk@F&1eEBje~ zW+-_s)&RgiweQc!otF>4%vbXKaOU41{!hw?|2`Ld3I8$&#WOsq>EG)1ANb!{N4z9@ zsU!bPG-~-bqCeIDzo^Q;gnucB{tRzm{ZH^Orphm2U+REA!*<*J6YQV83@&xoDl%#wnl5qcBqCcAF-vX5{30}(oJrnSH z{RY85hylK2dMOh2%oO1J8%)0?8TOL%rS8)+CsDv}aQ>4D)Jv+DLK)9gI^n-T^$)Tc zFPUD75qJm!Y-KBqj;JP4dV4 z`X{lGmn<)1IGz330}s}Jrjtf{(lnuuNHe5(ezA(pYa=1|Ff-LhPFK8 zyJh_b{yzu0yll6ZkpRzRjezyYivjyjW7QwO;@6X`m;2Apn2EK2!~7S}-*=;5*7K$B z`x(=!^?zgj(-`&ApZJXI09aDLXaT@<;CH=?fBOY5d|b~wBA@@p^K#nxr`)?i?SqTupI_PJ(A3cx`z~9mX_*)>L F{|7XC?P&l2 diff --git a/SnakeClient/SnakeApp/android/gradle/wrapper/gradle-wrapper.properties b/SnakeClient/SnakeApp/android/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index bf3de21..0000000 --- a/SnakeClient/SnakeApp/android/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,5 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-bin.zip -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists diff --git a/SnakeClient/SnakeApp/android/gradlew b/SnakeClient/SnakeApp/android/gradlew deleted file mode 100755 index cccdd3d..0000000 --- a/SnakeClient/SnakeApp/android/gradlew +++ /dev/null @@ -1,172 +0,0 @@ -#!/usr/bin/env sh - -############################################################################## -## -## Gradle start up script for UN*X -## -############################################################################## - -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null - -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" - -warn () { - echo "$*" -} - -die () { - echo - echo "$*" - echo - exit 1 -} - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; - NONSTOP* ) - nonstop=true - ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi -fi - -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi - -# For Cygwin, switch paths to Windows format before running java -if $cygwin ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi - # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" - fi - i=$((i+1)) - done - case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac -fi - -# Escape application args -save () { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done - echo " " -} -APP_ARGS=$(save "$@") - -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" - -# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong -if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then - cd "$(dirname "$0")" -fi - -exec "$JAVACMD" "$@" diff --git a/SnakeClient/SnakeApp/android/gradlew.bat b/SnakeClient/SnakeApp/android/gradlew.bat deleted file mode 100644 index f955316..0000000 --- a/SnakeClient/SnakeApp/android/gradlew.bat +++ /dev/null @@ -1,84 +0,0 @@ -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto init - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:init -@rem Get command-line arguments, handling Windows variants - -if not "%OS%" == "Windows_NT" goto win9xME_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/SnakeClient/SnakeApp/android/res/drawable-hdpi/icon.png b/SnakeClient/SnakeApp/android/res/drawable-hdpi/icon.png deleted file mode 100644 index f7120fcf82e1779598959fe545f4434d93b1d49d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2461 zcmV;O31aq%P)8?pCWWFNjR9Mpr`=* zfgb^T$H%PJB1>S|nQXURG*b#1m9WP3?@xxm2LB*7Cg!of5^82A#SFmr)u2A&4C z`dY0lzo8y)vvtlDo=)kQ%#pnz!h!U5;AH^gEc3btc-CS!SXX?m9{*Bj%_>=qA{R3g z{+}s?1UwJi>0c(Xa#I5)tD#nPt4c@qhRDlm82DE)Y$g!hz#fB1=(y(QMp~C$YW-X$ zPdJb!8p;q4=SasDG6{veqEg7Kh(-Z}QNSu0ad=F)>Mhi_+we475e?Ok=)kck;XoST zULa8nuQrDpfjyGXWL~$m1<7YdRaGvYNf0H`MjK&0a09Rg z@EI*4ZCy?}R=RN2Tc)f)I7_;1xf+zsriYqyE(wzgohh=e{$a^m$c z$%qW_2A7t-LUnBdfCqR0cnoOtFO}&2Y&}*-`N8qd?ta37^f0i1alKFt#67?+|5Axn zw>ANAY~LWk<1x@Sp|7E}_FQ#0@U+=xkgna{GHI0y9E)=FwLySefmcfti&JF071-rp zCb4RB6QV(&@56Wzpcidi)&c$m$c7$9pvVsEO0QB zQ0{M7XeV?o$wwbV0k$(mua|@PlhG`!{`8JEEEOi1Xb`Axx6{7Dg`6vxW1;Le;2XdQ zaDBQav{BiA;W?DL>s!L6diIRb>Qt z0(gcB-Cu)oT4q&pDk{@^I70Ab47ET4coO&}vxlil z7^M5A!ab$9qNnx|T{D$8Uw(6rb=#|jsPylRdPW;dhqZ6FT3$J~ZlMHPEO0wPyk z>os;=UstotGYN$=2Zsq9kD;oBfk%Kp)U1F}6?@{F29vOP?Uv?AtI=F!G>bGXcF?-q zNj90cCx&x(0k@;=^5I&QQ-t{Qf|YJ*CX;z4GFuJ!mrB&P+Zeu>X^}I9htXEDgSE)N z*z96)bD2;1T5W8+x1EKn+#>K4@Fw7&Yre&vxPRbmvOXPCFqlMaP9uUaA2tLKMS;eJ z4!nLV;XtY*FRKrsoqW&CHqWu)l$X`W$j8~vzLRlx;8=|L26DJHV?sQfGbKmld(ln` zdzrGTcE)}ik`m>pkxbuXcwoCs!cnST1*6T7-;Qs(ze_=?X9d@B}a0+v-<++m@)!f z51gzf-E5oEkG63=2>9HM7TT|N(Ynlu$uhTnCX-NjXLmn|VR;x>4Fsl3Q;YGi4){KB zhiDYUwk{`&R(o*PnP;70CZX`wOMPVGN*@}?lpA9$XQ>@+xIGCpHZHQ$x!#AjWp)O& zL?p-CFZCg33j2XgQ^l>N(MSdk0Y3$Lk|XlE;E7n>$j2GnO%}|ynH6QW8E`jP=sy)- zIGXpHmEz8qHTkhsQ)AuQGfga})3q6^7M(o9|Ae9WTV8zVya$ zFiqnE`;3nIzBU^dPA8Bvg*Cu$%f-1IHpl|74|pvTSMCg+j9J|c795`HO#Xr(AbHL7 zpNhAm4XJabaW1DJH2^$YP}B|mr{W7t7P0C{@9>xy>Q9r7Da(LoOTS-UYq0jxvlFNr zJfB*hNhmZfvR5@vOcs#~rxR_!b7)UzW4hcBpdIk`02ia7?6zb?rfG>|S`dfVMDS!B zC07VjvQk|Mh@yIc|HOxKJK{q*S~{gEK?Fe{8Oae1Wt)IsjsI4=yXfrnBJhQQ-XzEO zO@CYUY0qd~rQuf^0$?}r$oZpD0-Bw-qI`ZEXm2WQC= zzG9+JVLB$$cOnLwop+M-2Jx8DqCFdr*O^0+qPxX2Ehk{ zaVoeZ=?UTiLBzUfwRDz>hmtxF+}jo;ol@Dk>|K+^I{Y z7l_mu%ul>?OczgE(0eZ^~~+ku;}-qe86ED{;WaOf`=P_l(yU<{q&C z)v6oVcg;-=YTI&W@%Kc}bLEHkjMVLEw!H1EH=hL#17Dd-X7l6JG`+gH^y{r&YUi%~ b$<_Y=*q$)a+E8iP00000NkvXXu0mjfdrX$J diff --git a/SnakeClient/SnakeApp/android/res/drawable-ldpi/icon.png b/SnakeClient/SnakeApp/android/res/drawable-ldpi/icon.png deleted file mode 100644 index f7120fcf82e1779598959fe545f4434d93b1d49d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2461 zcmV;O31aq%P)8?pCWWFNjR9Mpr`=* zfgb^T$H%PJB1>S|nQXURG*b#1m9WP3?@xxm2LB*7Cg!of5^82A#SFmr)u2A&4C z`dY0lzo8y)vvtlDo=)kQ%#pnz!h!U5;AH^gEc3btc-CS!SXX?m9{*Bj%_>=qA{R3g z{+}s?1UwJi>0c(Xa#I5)tD#nPt4c@qhRDlm82DE)Y$g!hz#fB1=(y(QMp~C$YW-X$ zPdJb!8p;q4=SasDG6{veqEg7Kh(-Z}QNSu0ad=F)>Mhi_+we475e?Ok=)kck;XoST zULa8nuQrDpfjyGXWL~$m1<7YdRaGvYNf0H`MjK&0a09Rg z@EI*4ZCy?}R=RN2Tc)f)I7_;1xf+zsriYqyE(wzgohh=e{$a^m$c z$%qW_2A7t-LUnBdfCqR0cnoOtFO}&2Y&}*-`N8qd?ta37^f0i1alKFt#67?+|5Axn zw>ANAY~LWk<1x@Sp|7E}_FQ#0@U+=xkgna{GHI0y9E)=FwLySefmcfti&JF071-rp zCb4RB6QV(&@56Wzpcidi)&c$m$c7$9pvVsEO0QB zQ0{M7XeV?o$wwbV0k$(mua|@PlhG`!{`8JEEEOi1Xb`Axx6{7Dg`6vxW1;Le;2XdQ zaDBQav{BiA;W?DL>s!L6diIRb>Qt z0(gcB-Cu)oT4q&pDk{@^I70Ab47ET4coO&}vxlil z7^M5A!ab$9qNnx|T{D$8Uw(6rb=#|jsPylRdPW;dhqZ6FT3$J~ZlMHPEO0wPyk z>os;=UstotGYN$=2Zsq9kD;oBfk%Kp)U1F}6?@{F29vOP?Uv?AtI=F!G>bGXcF?-q zNj90cCx&x(0k@;=^5I&QQ-t{Qf|YJ*CX;z4GFuJ!mrB&P+Zeu>X^}I9htXEDgSE)N z*z96)bD2;1T5W8+x1EKn+#>K4@Fw7&Yre&vxPRbmvOXPCFqlMaP9uUaA2tLKMS;eJ z4!nLV;XtY*FRKrsoqW&CHqWu)l$X`W$j8~vzLRlx;8=|L26DJHV?sQfGbKmld(ln` zdzrGTcE)}ik`m>pkxbuXcwoCs!cnST1*6T7-;Qs(ze_=?X9d@B}a0+v-<++m@)!f z51gzf-E5oEkG63=2>9HM7TT|N(Ynlu$uhTnCX-NjXLmn|VR;x>4Fsl3Q;YGi4){KB zhiDYUwk{`&R(o*PnP;70CZX`wOMPVGN*@}?lpA9$XQ>@+xIGCpHZHQ$x!#AjWp)O& zL?p-CFZCg33j2XgQ^l>N(MSdk0Y3$Lk|XlE;E7n>$j2GnO%}|ynH6QW8E`jP=sy)- zIGXpHmEz8qHTkhsQ)AuQGfga})3q6^7M(o9|Ae9WTV8zVya$ zFiqnE`;3nIzBU^dPA8Bvg*Cu$%f-1IHpl|74|pvTSMCg+j9J|c795`HO#Xr(AbHL7 zpNhAm4XJabaW1DJH2^$YP}B|mr{W7t7P0C{@9>xy>Q9r7Da(LoOTS-UYq0jxvlFNr zJfB*hNhmZfvR5@vOcs#~rxR_!b7)UzW4hcBpdIk`02ia7?6zb?rfG>|S`dfVMDS!B zC07VjvQk|Mh@yIc|HOxKJK{q*S~{gEK?Fe{8Oae1Wt)IsjsI4=yXfrnBJhQQ-XzEO zO@CYUY0qd~rQuf^0$?}r$oZpD0-Bw-qI`ZEXm2WQC= zzG9+JVLB$$cOnLwop+M-2Jx8DqCFdr*O^0+qPxX2Ehk{ zaVoeZ=?UTiLBzUfwRDz>hmtxF+}jo;ol@Dk>|K+^I{Y z7l_mu%ul>?OczgE(0eZ^~~+ku;}-qe86ED{;WaOf`=P_l(yU<{q&C z)v6oVcg;-=YTI&W@%Kc}bLEHkjMVLEw!H1EH=hL#17Dd-X7l6JG`+gH^y{r&YUi%~ b$<_Y=*q$)a+E8iP00000NkvXXu0mjfdrX$J diff --git a/SnakeClient/SnakeApp/android/res/drawable-mdpi/icon.png b/SnakeClient/SnakeApp/android/res/drawable-mdpi/icon.png deleted file mode 100644 index f7120fcf82e1779598959fe545f4434d93b1d49d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2461 zcmV;O31aq%P)8?pCWWFNjR9Mpr`=* zfgb^T$H%PJB1>S|nQXURG*b#1m9WP3?@xxm2LB*7Cg!of5^82A#SFmr)u2A&4C z`dY0lzo8y)vvtlDo=)kQ%#pnz!h!U5;AH^gEc3btc-CS!SXX?m9{*Bj%_>=qA{R3g z{+}s?1UwJi>0c(Xa#I5)tD#nPt4c@qhRDlm82DE)Y$g!hz#fB1=(y(QMp~C$YW-X$ zPdJb!8p;q4=SasDG6{veqEg7Kh(-Z}QNSu0ad=F)>Mhi_+we475e?Ok=)kck;XoST zULa8nuQrDpfjyGXWL~$m1<7YdRaGvYNf0H`MjK&0a09Rg z@EI*4ZCy?}R=RN2Tc)f)I7_;1xf+zsriYqyE(wzgohh=e{$a^m$c z$%qW_2A7t-LUnBdfCqR0cnoOtFO}&2Y&}*-`N8qd?ta37^f0i1alKFt#67?+|5Axn zw>ANAY~LWk<1x@Sp|7E}_FQ#0@U+=xkgna{GHI0y9E)=FwLySefmcfti&JF071-rp zCb4RB6QV(&@56Wzpcidi)&c$m$c7$9pvVsEO0QB zQ0{M7XeV?o$wwbV0k$(mua|@PlhG`!{`8JEEEOi1Xb`Axx6{7Dg`6vxW1;Le;2XdQ zaDBQav{BiA;W?DL>s!L6diIRb>Qt z0(gcB-Cu)oT4q&pDk{@^I70Ab47ET4coO&}vxlil z7^M5A!ab$9qNnx|T{D$8Uw(6rb=#|jsPylRdPW;dhqZ6FT3$J~ZlMHPEO0wPyk z>os;=UstotGYN$=2Zsq9kD;oBfk%Kp)U1F}6?@{F29vOP?Uv?AtI=F!G>bGXcF?-q zNj90cCx&x(0k@;=^5I&QQ-t{Qf|YJ*CX;z4GFuJ!mrB&P+Zeu>X^}I9htXEDgSE)N z*z96)bD2;1T5W8+x1EKn+#>K4@Fw7&Yre&vxPRbmvOXPCFqlMaP9uUaA2tLKMS;eJ z4!nLV;XtY*FRKrsoqW&CHqWu)l$X`W$j8~vzLRlx;8=|L26DJHV?sQfGbKmld(ln` zdzrGTcE)}ik`m>pkxbuXcwoCs!cnST1*6T7-;Qs(ze_=?X9d@B}a0+v-<++m@)!f z51gzf-E5oEkG63=2>9HM7TT|N(Ynlu$uhTnCX-NjXLmn|VR;x>4Fsl3Q;YGi4){KB zhiDYUwk{`&R(o*PnP;70CZX`wOMPVGN*@}?lpA9$XQ>@+xIGCpHZHQ$x!#AjWp)O& zL?p-CFZCg33j2XgQ^l>N(MSdk0Y3$Lk|XlE;E7n>$j2GnO%}|ynH6QW8E`jP=sy)- zIGXpHmEz8qHTkhsQ)AuQGfga})3q6^7M(o9|Ae9WTV8zVya$ zFiqnE`;3nIzBU^dPA8Bvg*Cu$%f-1IHpl|74|pvTSMCg+j9J|c795`HO#Xr(AbHL7 zpNhAm4XJabaW1DJH2^$YP}B|mr{W7t7P0C{@9>xy>Q9r7Da(LoOTS-UYq0jxvlFNr zJfB*hNhmZfvR5@vOcs#~rxR_!b7)UzW4hcBpdIk`02ia7?6zb?rfG>|S`dfVMDS!B zC07VjvQk|Mh@yIc|HOxKJK{q*S~{gEK?Fe{8Oae1Wt)IsjsI4=yXfrnBJhQQ-XzEO zO@CYUY0qd~rQuf^0$?}r$oZpD0-Bw-qI`ZEXm2WQC= zzG9+JVLB$$cOnLwop+M-2Jx8DqCFdr*O^0+qPxX2Ehk{ zaVoeZ=?UTiLBzUfwRDz>hmtxF+}jo;ol@Dk>|K+^I{Y z7l_mu%ul>?OczgE(0eZ^~~+ku;}-qe86ED{;WaOf`=P_l(yU<{q&C z)v6oVcg;-=YTI&W@%Kc}bLEHkjMVLEw!H1EH=hL#17Dd-X7l6JG`+gH^y{r&YUi%~ b$<_Y=*q$)a+E8iP00000NkvXXu0mjfdrX$J diff --git a/SnakeClient/SnakeApp/android/res/values/libs.xml b/SnakeClient/SnakeApp/android/res/values/libs.xml deleted file mode 100644 index 4009a77..0000000 --- a/SnakeClient/SnakeApp/android/res/values/libs.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - https://download.qt.io/ministro/android/qt5/qt-5.9 - - - - - - - - - - - - - - - - - - - - diff --git a/SnakeClient/SnakeApp/back-end/ProfileViewItems/mainclient.cpp b/SnakeClient/SnakeApp/back-end/ProfileViewItems/mainclient.cpp deleted file mode 100644 index 7420fdd..0000000 --- a/SnakeClient/SnakeApp/back-end/ProfileViewItems/mainclient.cpp +++ /dev/null @@ -1,180 +0,0 @@ -#include "mainclient.h" -#include "notificationservice.h" -#include "playerclientdata.h" - -#include - -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::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(); -} diff --git a/SnakeClient/SnakeApp/back-end/ProfileViewItems/mainclient.h b/SnakeClient/SnakeApp/back-end/ProfileViewItems/mainclient.h deleted file mode 100644 index ec1b842..0000000 --- a/SnakeClient/SnakeApp/back-end/ProfileViewItems/mainclient.h +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef MAINCLIENT_H -#define MAINCLIENT_H -#include - -class PlayerClientData; - -enum OnlineStatus: int { - Success = 0x0, - AuthorizationRequired, - WaitForAnswer, - AuthorizationFail, - ClientIsOffline, - OfflineMode -}; - -class MainClient: public ClientProtocol::Client -{ - Q_OBJECT -private: - QHash> _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); -}; - -#endif // MAINCLIENT_H diff --git a/SnakeClient/SnakeApp/back-end/ProfileViewItems/mainmenumodel.cpp b/SnakeClient/SnakeApp/back-end/ProfileViewItems/mainmenumodel.cpp deleted file mode 100644 index d7edc60..0000000 --- a/SnakeClient/SnakeApp/back-end/ProfileViewItems/mainmenumodel.cpp +++ /dev/null @@ -1,59 +0,0 @@ -#include "mainmenumodel.h" -#include "settingsviewmodel.h" -#include "userview.h" - -#include -#include -#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(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(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()); -} diff --git a/SnakeClient/SnakeApp/back-end/ProfileViewItems/mainmenumodel.h b/SnakeClient/SnakeApp/back-end/ProfileViewItems/mainmenumodel.h deleted file mode 100644 index 85f997b..0000000 --- a/SnakeClient/SnakeApp/back-end/ProfileViewItems/mainmenumodel.h +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef NETWORKPROFILEMAINMODEL_H -#define NETWORKPROFILEMAINMODEL_H - -#include "mainclient.h" - -#include -#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 diff --git a/SnakeClient/SnakeApp/back-end/ProfileViewItems/networkclient.cpp b/SnakeClient/SnakeApp/back-end/ProfileViewItems/networkclient.cpp deleted file mode 100644 index 10b646c..0000000 --- a/SnakeClient/SnakeApp/back-end/ProfileViewItems/networkclient.cpp +++ /dev/null @@ -1,23 +0,0 @@ -#include "networkclient.h" -#include "playerclientdata.h" - -#include - -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() { - -} diff --git a/SnakeClient/SnakeApp/back-end/ProfileViewItems/networkclient.h b/SnakeClient/SnakeApp/back-end/ProfileViewItems/networkclient.h deleted file mode 100644 index 840902b..0000000 --- a/SnakeClient/SnakeApp/back-end/ProfileViewItems/networkclient.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef CLIENT_H -#define CLIENT_H - -#include "playerclientdata.h" - -#include - -class NetworkClient : public ClientProtocol::Client -{ - Q_OBJECT -private: - QHash _playersDats; - int _loginedPlayer; -private slots: - void handleReceiveData(ClientProtocol::Command cmd, const QByteArray& obj); -public: - NetworkClient(); - int loginedPlayer() const; -}; - -#endif // CLIENT_H diff --git a/SnakeClient/SnakeApp/back-end/ProfileViewItems/notificationdata.cpp b/SnakeClient/SnakeApp/back-end/ProfileViewItems/notificationdata.cpp deleted file mode 100644 index 94bbce1..0000000 --- a/SnakeClient/SnakeApp/back-end/ProfileViewItems/notificationdata.cpp +++ /dev/null @@ -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; -} diff --git a/SnakeClient/SnakeApp/back-end/ProfileViewItems/notificationdata.h b/SnakeClient/SnakeApp/back-end/ProfileViewItems/notificationdata.h deleted file mode 100644 index dc9ad1d..0000000 --- a/SnakeClient/SnakeApp/back-end/ProfileViewItems/notificationdata.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef NOTIFICATIONDATA_H -#define NOTIFICATIONDATA_H -#include - -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 diff --git a/SnakeClient/SnakeApp/back-end/ProfileViewItems/notificationservice.cpp b/SnakeClient/SnakeApp/back-end/ProfileViewItems/notificationservice.cpp deleted file mode 100644 index 39caa5f..0000000 --- a/SnakeClient/SnakeApp/back-end/ProfileViewItems/notificationservice.cpp +++ /dev/null @@ -1,38 +0,0 @@ -#include "notificationservice.h" - -NotificationService::NotificationService(QObject * ptr): QObject (ptr) { - qRegisterMetaType("NotificationData"); - qRegisterMetaType> ("QList"); - -} - -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(type))); -} - -NotificationService *NotificationService::getService() { - static auto service = new NotificationService; - return service; -} - -const QList &NotificationService::history() const { - return _history; -} diff --git a/SnakeClient/SnakeApp/back-end/ProfileViewItems/notificationservice.h b/SnakeClient/SnakeApp/back-end/ProfileViewItems/notificationservice.h deleted file mode 100644 index 75dcef9..0000000 --- a/SnakeClient/SnakeApp/back-end/ProfileViewItems/notificationservice.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef NOTIFICATIONSERVICE_H -#define NOTIFICATIONSERVICE_H - -#include "notificationdata.h" - -#include - -class NotificationService: public QObject -{ - Q_OBJECT - - Q_PROPERTY(NotificationData notify READ notify NOTIFY notifyChanged) - Q_PROPERTY(QList history READ history NOTIFY notifyChanged) - -private: - explicit NotificationService(QObject *ptr = nullptr); - - NotificationData _notify; - QList _history; - -public: - NotificationData notify() const; - void setNotify(const NotificationData ¬ify); - Q_INVOKABLE void setNotify(const QString& title = "", - const QString& text = "", - const QString& img = "", - int type = NotificationData::Normal); - - static NotificationService* getService(); - - const QList & history() const; - -signals: - void notifyChanged(); -}; - - - -#endif // NOTIFICATIONSERVICE_H diff --git a/SnakeClient/SnakeApp/back-end/ProfileViewItems/playerclientdata.cpp b/SnakeClient/SnakeApp/back-end/ProfileViewItems/playerclientdata.cpp deleted file mode 100644 index 509ed40..0000000 --- a/SnakeClient/SnakeApp/back-end/ProfileViewItems/playerclientdata.cpp +++ /dev/null @@ -1,6 +0,0 @@ -#include "playerclientdata.h" - -PlayerClientData::PlayerClientData() -{ - -} diff --git a/SnakeClient/SnakeApp/back-end/ProfileViewItems/playerclientdata.h b/SnakeClient/SnakeApp/back-end/ProfileViewItems/playerclientdata.h deleted file mode 100644 index fc5a4c5..0000000 --- a/SnakeClient/SnakeApp/back-end/ProfileViewItems/playerclientdata.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef PLAYERCLIENTDATA_H -#define PLAYERCLIENTDATA_H -#include - -class PlayerClientData: public ClientProtocol::Player -{ -public: - PlayerClientData(); -}; - -#endif // PLAYERCLIENTDATA_H diff --git a/SnakeClient/SnakeApp/back-end/ProfileViewItems/settingsviewmodel.cpp b/SnakeClient/SnakeApp/back-end/ProfileViewItems/settingsviewmodel.cpp deleted file mode 100644 index 2279777..0000000 --- a/SnakeClient/SnakeApp/back-end/ProfileViewItems/settingsviewmodel.cpp +++ /dev/null @@ -1,57 +0,0 @@ -#include "settingsviewmodel.h" -#include -#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); -} diff --git a/SnakeClient/SnakeApp/back-end/ProfileViewItems/settingsviewmodel.h b/SnakeClient/SnakeApp/back-end/ProfileViewItems/settingsviewmodel.h deleted file mode 100644 index 9727844..0000000 --- a/SnakeClient/SnakeApp/back-end/ProfileViewItems/settingsviewmodel.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef SETTINGSVIEWMODEL_H -#define SETTINGSVIEWMODEL_H - -#include -#include "./../settings.h" - - -class SettingsViewModel: public QObject -{ - Q_OBJECT - Q_PROPERTY(int port READ port WRITE setPort NOTIFY portChanged) - Q_PROPERTY(QString host READ host WRITE setHost NOTIFY hostChanged) - Q_PROPERTY(int theme READ theme WRITE setTheme NOTIFY themeChanged) - -private: - Settings *_cfg = nullptr; - -private slots: - void handleValueChanged(QString key, QVariant value); - -public: - SettingsViewModel(QObject* ptr = nullptr); - int port() const; - QString host() const; - int theme() const; - - Q_INVOKABLE void forceUpdate(); - Q_INVOKABLE void toDefault(); - - -public slots: - void setPort(int port); - void setHost(const QString &host); - void setTheme(int theme); - -signals: - void portChanged(int port); - void hostChanged(const QString &host); - void themeChanged(int theme); -}; - -#endif // SETTINGSVIEWMODEL_H diff --git a/SnakeClient/SnakeApp/back-end/ProfileViewItems/userview.cpp b/SnakeClient/SnakeApp/back-end/ProfileViewItems/userview.cpp deleted file mode 100644 index 66867a9..0000000 --- a/SnakeClient/SnakeApp/back-end/ProfileViewItems/userview.cpp +++ /dev/null @@ -1,78 +0,0 @@ -#include "userview.h" - -const PlayerClientData *UserView::getSource() const { - return _source.data(); -} - -void UserView::setSource(QSharedPointer 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(_source->getMany()); -} - -int UserView::record() const { - if (!_source) { - return -1; - } - return static_cast(_source->getRecord()); -} - -int UserView::avgRecord() const { - if (!_source) { - return -1; - } - return static_cast(_source->getAvgRecord()); -} - -int UserView::cureentSnake() const { - if (!_source) { - return -1; - } - return _source->getCureentSnake(); -} - -int UserView::id() const { - if (!_source) { - return -1; - } - return _source->id(); -} diff --git a/SnakeClient/SnakeApp/back-end/ProfileViewItems/userview.h b/SnakeClient/SnakeApp/back-end/ProfileViewItems/userview.h deleted file mode 100644 index 455f294..0000000 --- a/SnakeClient/SnakeApp/back-end/ProfileViewItems/userview.h +++ /dev/null @@ -1,52 +0,0 @@ -#ifndef USERVIEW_H -#define USERVIEW_H - -#include "playerclientdata.h" - -#include - -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 _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 data); - -}; - -#endif // USERVIEW_H diff --git a/SnakeClient/SnakeApp/back-end/asyncimageresponse.cpp b/SnakeClient/SnakeApp/back-end/asyncimageresponse.cpp deleted file mode 100644 index b6d7113..0000000 --- a/SnakeClient/SnakeApp/back-end/asyncimageresponse.cpp +++ /dev/null @@ -1,23 +0,0 @@ -#include "asyncimageresponse.h" - -AsyncImageResponse::AsyncImageResponse() = default; -AsyncImageResponse::~AsyncImageResponse() = default; - -QQuickTextureFactory *AsyncImageResponse::textureFactory() const { - return _texture; -} - -// memory leak ? -void AsyncImageResponse::setResult(const QImage& image) { - _texture = QQuickTextureFactory::textureFactoryForImage(image); - emit finished(); -// deleteLater(); -} - -void AsyncImageResponse::error(const QString &err) { - _errorString = " " + err; -} - -QString AsyncImageResponse::errorString() const { - return QQuickImageResponse::errorString() + _errorString; -} diff --git a/SnakeClient/SnakeApp/back-end/asyncimageresponse.h b/SnakeClient/SnakeApp/back-end/asyncimageresponse.h deleted file mode 100644 index ca04a34..0000000 --- a/SnakeClient/SnakeApp/back-end/asyncimageresponse.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef ASYNCIMAGERESPONSE_H -#define ASYNCIMAGERESPONSE_H - -#include - - -class AsyncImageResponse : public QQuickImageResponse { - -private: - QQuickTextureFactory *_texture = nullptr; - QString _errorString; -public: - - AsyncImageResponse (); - ~AsyncImageResponse () override; - - QQuickTextureFactory *textureFactory() const override; - - void setResult(const QImage &image); - void error(const QString &err); - - QString errorString() const override; -}; -#endif // ASYNCIMAGERESPONSE_H diff --git a/SnakeClient/SnakeApp/back-end/background.cpp b/SnakeClient/SnakeApp/back-end/background.cpp deleted file mode 100644 index 50cd2f2..0000000 --- a/SnakeClient/SnakeApp/back-end/background.cpp +++ /dev/null @@ -1,20 +0,0 @@ -#include "background.h" - -BackGround::BackGround(double x, double y): ItemWorld (x, y) { - this->setSize(200, 400); - this->setTexture("qrc:/texture/asphalt"); - setBeckGroundObject(true); -} - -void BackGround::render() { - auto wPart = w() / 2; - - if (m_x + wPart < 200) { - setX(wPart); - } -} - -void BackGround::reset() { - setX(0 - w()); - render(); -} diff --git a/SnakeClient/SnakeApp/back-end/background.h b/SnakeClient/SnakeApp/back-end/background.h deleted file mode 100644 index 26e4619..0000000 --- a/SnakeClient/SnakeApp/back-end/background.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef BACKGROUND_H -#define BACKGROUND_H - -#include "itemworld.h" - - -class BackGround : public ItemWorld -{ -public: - BackGround(double x, double y); - - void render() override; - void reset() override; -}; - -#endif // BACKGROUND_H diff --git a/SnakeClient/SnakeApp/back-end/backgrounditem.cpp b/SnakeClient/SnakeApp/back-end/backgrounditem.cpp deleted file mode 100644 index dcdfbea..0000000 --- a/SnakeClient/SnakeApp/back-end/backgrounditem.cpp +++ /dev/null @@ -1,19 +0,0 @@ -#include "backgrounditem.h" - -#include - -BackGroundItem::BackGroundItem(double x, double y): - ItemWorld (x, y) { - setBeckGroundObject(true); - reset(); -} - -void BackGroundItem::reset() { - auto tempColor = QColor(rand() % 255, rand() % 255, rand() % 255, 10); - setColor(tempColor.name(QColor::HexArgb)); - auto radius = rand() % 200; - setSize(radius , radius); - - setRadius(radius / 2); - -} diff --git a/SnakeClient/SnakeApp/back-end/backgrounditem.h b/SnakeClient/SnakeApp/back-end/backgrounditem.h deleted file mode 100644 index 6999772..0000000 --- a/SnakeClient/SnakeApp/back-end/backgrounditem.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef BACKGROUNDITEM_H -#define BACKGROUNDITEM_H - -#include "itemworld.h" - - -class BackGroundItem : public ItemWorld -{ -public: - BackGroundItem(double x, double y); - void reset() override; - -}; - -#endif // BACKGROUNDITEM_H diff --git a/SnakeClient/SnakeApp/back-end/baseclass.cpp b/SnakeClient/SnakeApp/back-end/baseclass.cpp deleted file mode 100644 index f635b82..0000000 --- a/SnakeClient/SnakeApp/back-end/baseclass.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include "baseclass.h" - -void BaseClass::setName(const QString &value) { - name = value; -} - -BaseClass::BaseClass() : - name("BaseClass") { -} - -BaseClass::~BaseClass() { - -} - -QString BaseClass::getName() const { - return name; -} diff --git a/SnakeClient/SnakeApp/back-end/baseclass.h b/SnakeClient/SnakeApp/back-end/baseclass.h deleted file mode 100644 index a25ed02..0000000 --- a/SnakeClient/SnakeApp/back-end/baseclass.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef BASECLASS_H -#define BASECLASS_H -#include - -class BaseClass -{ -private: - QString name; -public: - BaseClass(); - virtual void render() = 0; - virtual ~BaseClass(); - QString getName() const; - void setName(const QString &value); -}; - -#endif // BASECLASS_H diff --git a/SnakeClient/SnakeApp/back-end/box.cpp b/SnakeClient/SnakeApp/back-end/box.cpp deleted file mode 100644 index 182bf46..0000000 --- a/SnakeClient/SnakeApp/back-end/box.cpp +++ /dev/null @@ -1,12 +0,0 @@ -#include "box.h" - -#include - -Box::Box(double x, double y): - ItemWorld (x, y) { - - this->setSize(10, 10); - - setColor(QColor(100, 100, 100).name()); -} - diff --git a/SnakeClient/SnakeApp/back-end/box.h b/SnakeClient/SnakeApp/back-end/box.h deleted file mode 100644 index 7fd71a4..0000000 --- a/SnakeClient/SnakeApp/back-end/box.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef BOX_H -#define BOX_H - -#include "itemworld.h" - -class Box: public ItemWorld -{ -public: - Box(double x, double y); - -}; - -#endif // BOX_H diff --git a/SnakeClient/SnakeApp/back-end/clientapp.cpp b/SnakeClient/SnakeApp/back-end/clientapp.cpp deleted file mode 100644 index 2d9e109..0000000 --- a/SnakeClient/SnakeApp/back-end/clientapp.cpp +++ /dev/null @@ -1,50 +0,0 @@ -#include "clientapp.h" -#include "imageprovider.h" -#include "ProfileViewItems/userview.h" -#include -#include - -#include -#include - -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 (); - qmlRegisterType (); - qmlRegisterType (); - qmlRegisterType (); - - 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; -} diff --git a/SnakeClient/SnakeApp/back-end/clientapp.h b/SnakeClient/SnakeApp/back-end/clientapp.h deleted file mode 100644 index 8045ff2..0000000 --- a/SnakeClient/SnakeApp/back-end/clientapp.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef CLIENTAPP_H -#define CLIENTAPP_H - -#include "controller.h" -#include "diff.h" - -class QQmlApplicationEngine; - -class ClientApp -{ -private: - Controller contr; - - QByteArray initTheme(); - -public: - ClientApp(); - ~ClientApp(); - bool init(QQmlApplicationEngine* engine); -}; - -#endif // CLIENTAPP_H diff --git a/SnakeClient/SnakeApp/back-end/controller.cpp b/SnakeClient/SnakeApp/back-end/controller.cpp deleted file mode 100644 index 84473de..0000000 --- a/SnakeClient/SnakeApp/back-end/controller.cpp +++ /dev/null @@ -1,154 +0,0 @@ -#include "controller.h" -#include -#include -#include "diff.h" -#include -#include "ProfileViewItems/mainmenumodel.h" -#include - -Controller::Controller() { - srand(static_cast(time(nullptr))); - timer = new QTimer(); - timer->setInterval(1); - - _networkModel = new MainMenuModel(this); - - connect(timer, SIGNAL(timeout()), this, SLOT(update())); - connect(_networkModel, &MainMenuModel::newGame, this, &Controller::handleNewGame); - -} - -Controller::~Controller() { - -} - -bool Controller::nextLvl() { - if (lvl + 1 >= lvls.size()) { - return true; - } - m_generalLong += static_cast(world.getCurrentLong()); - - generateDiff(world.init(lvls.value(++lvl))); - startTimer(); - - - return false; -} - -void Controller::generateDiff(const QMap& objs) { - - auto removeIds = objectsContainer.keys(); - QList addedIds; - - for (auto i = objs.begin(); i != objs.end(); ++i) { - if (objectsContainer.contains(i.key())) { - removeIds.removeOne(i.key()); - } else { - objectsContainer.insert(i.key(), i.value()); - addedIds.push_back(i.key()); - } - } - - if (removeIds.size() || addedIds.size()) { - Diff diff; - - diff.setRemoveIds(removeIds); - diff.setAddedIds(addedIds); - emit gameObjectsChanged(diff); - } -} - -void Controller::update() { - if (pause) { - return; - } - - world.render(); - - if(world.isDefiat()) { - stopTimer(); - if (!_showMenu) { - setShowMenu(true); - } - handleNewGame(); - } - - if (world.isEnd()) { - stopTimer(); - - if (!_showMenu) { - - NotificationData notify(tr(" Next Lvl!!!"), - tr(" You anblock next lvl (%0)" ).arg(lvl), - "qrc:/texture/up"); - - NotificationService::getService()->setNotify(notify); - } - - nextLvl(); - - } - - long_changed(static_cast(world.getCurrentLong())); - generalLongchanged(generalLong()); - -} - -void Controller::handleNewGame() { - - world.resetPosition(); - - WorldRules newGameRules = lvls.first(); - lvl = 0; - m_generalLong = 0; - generateDiff(world.init(newGameRules)); - startTimer(); -} - -QObject *Controller::getGameObject(int id) { - return objectsContainer.value(id, nullptr); -} - -void Controller::startTimer() { - timer->start(); -} - -void Controller::stopTimer() { - timer->stop(); -} - -int Controller::long_() const { - return static_cast(world.getCurrentLong()); -} - -int Controller::generalLong() const { - return m_generalLong + long_(); -} - -QObject *Controller::mainMenuModel() const { - return _networkModel; -} - -void Controller::buttonPress() { - world.reversClick(); -} - -void Controller::setPause(bool p){ - pause = p; - if (!pause) { - world.unPause(); - } -} - -bool Controller::showMenu() const { - return _showMenu; -} - -void Controller::setShowMenu(bool showMenu) { - if (_showMenu == showMenu) - return; - - _showMenu = showMenu; - emit showMenuChanged(_showMenu); -} - diff --git a/SnakeClient/SnakeApp/back-end/controller.h b/SnakeClient/SnakeApp/back-end/controller.h deleted file mode 100644 index 93c0795..0000000 --- a/SnakeClient/SnakeApp/back-end/controller.h +++ /dev/null @@ -1,88 +0,0 @@ -#ifndef CONTROLLER_H -#define CONTROLLER_H - -#include -#include -#include -#include "diff.h" -#include "snake.h" -#include "world.h" - -class MainMenuModel; - -class Controller : public QObject -{ - Q_OBJECT - - Q_PROPERTY(int long_ READ long_ NOTIFY long_changed) - Q_PROPERTY(int generalLong READ generalLong NOTIFY generalLongchanged) - Q_PROPERTY(QObject* mainMenuModel READ mainMenuModel NOTIFY mainMenuModelchanged) - Q_PROPERTY(bool showMenu READ showMenu WRITE setShowMenu NOTIFY showMenuChanged) - -private: - - World world; - QMap objectsContainer; - QTimer *timer = nullptr; - - int lvl = 0; - int m_generalLong = 0; - bool pause = false; - bool _showMenu = true; - - void generateDiff(const QMap &); - - MainMenuModel* _networkModel = nullptr; - -public: - Controller(); - ~Controller(); - - void startTimer(); - void stopTimer(); - - int long_() const; - int generalLong() const; - bool showMenu() const; - - QObject* mainMenuModel() const; - -public slots: - void buttonPress(); - void setPause(bool); - void update(); - - /** - * @brief nextLvl - switch to next lvl from array lvels - * @return true if all levels are passed - */ - bool nextLvl(); - - /** - * @brief newGame - start game from first lvl - */ - void handleNewGame(); - - /** - * @brief getGameObject - * @param id - id of guiObject; - * @return guiObject if (id is not valid return nullptr) - */ - QObject* getGameObject(int id); - - void setShowMenu(bool showMenu); - -signals: - - /** - * @brief gameObjectsChanged - * @param dif - */ - void gameObjectsChanged(const Diff &dif); - void long_changed(int m_long); - void generalLongchanged(int generalLong); - void mainMenuModelchanged(QObject* mainMenuModel); - void showMenuChanged(bool showMenu); -}; - -#endif // CONTROLLER_H diff --git a/SnakeClient/SnakeApp/back-end/diff.cpp b/SnakeClient/SnakeApp/back-end/diff.cpp deleted file mode 100644 index 489a756..0000000 --- a/SnakeClient/SnakeApp/back-end/diff.cpp +++ /dev/null @@ -1,21 +0,0 @@ -#include "diff.h" - -QList Diff::getRemoveIds() const { - return removeIds; -} - -void Diff::setRemoveIds(const QList &value) { - removeIds = value; -} - -QList Diff::getAddedIds() const { - return addedIds; -} - -void Diff::setAddedIds(const QList &value) { - addedIds = value; -} - -Diff::Diff(){ - -} diff --git a/SnakeClient/SnakeApp/back-end/diff.h b/SnakeClient/SnakeApp/back-end/diff.h deleted file mode 100644 index 7733e7b..0000000 --- a/SnakeClient/SnakeApp/back-end/diff.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef DIFF_H -#define DIFF_H - -#include - -class Diff -{ - Q_GADGET -private: - QList removeIds; - QList addedIds; -public: - explicit Diff(); - - Q_INVOKABLE QList getRemoveIds() const; - void setRemoveIds(const QList &value); - Q_INVOKABLE QList getAddedIds() const; - void setAddedIds(const QList &value); -}; - -Q_DECLARE_METATYPE(Diff) - -#endif // DIFF_H diff --git a/SnakeClient/SnakeApp/back-end/guiobject.cpp b/SnakeClient/SnakeApp/back-end/guiobject.cpp deleted file mode 100644 index 419c576..0000000 --- a/SnakeClient/SnakeApp/back-end/guiobject.cpp +++ /dev/null @@ -1,116 +0,0 @@ -#include "guiobject.h" - -GuiObject::GuiObject(const QString &viewTempalte, QObject *ptr): - QObject (ptr) { - m_viewTemplate = viewTempalte; - generateId(); - -} - -double GuiObject::angle() const { - return m_angle; -} - -QString GuiObject::texture() const { - return m_texture; -} - -void GuiObject::render() { -} - -QRectF GuiObject::rect() const { - return QRectF(m_x - m_w / 2, m_y - m_h / 2, m_w, m_h); -} - -void GuiObject::setAngle(double angle) { - m_angle = angle; - emit angleChanged(m_angle); -} - -int GuiObject::guiId() const { - return m_guiId; -} - -QString GuiObject::color() const { - return m_color; -} - -void GuiObject::setColor(QString color) { - if (m_color == color) - return; - - m_color = color; - emit colorChanged(m_color); -} - -double GuiObject::x() const { - return m_x; -} - -double GuiObject::y() const { - return m_y; -} - -double GuiObject::w() const { - return m_w; -} - -double GuiObject::h() const { - return m_h; -} - -void GuiObject::generateId() { - static int id = 0; - m_guiId = id++; -} - -void GuiObject::setH(double h) { - m_h = h; - emit hChanged(m_h); -} - -void GuiObject::reset() { - setX(-1); - setY(-1); -} - -int GuiObject::radius() const { - return m_radius; -} - -QString GuiObject::viewTemplate() const { - return m_viewTemplate; -} - -void GuiObject::setRadius(int radius) { - if (m_radius == radius) - return; - - m_radius = radius; - emit radiusChanged(m_radius); -} - -void GuiObject::setW(double w) { - m_w = w; - emit wChanged(m_w); - -} - -void GuiObject::setY(double y) { - m_y = y; - emit yChanged(m_y); - -} - -void GuiObject::setX(double x) { - m_x = x; - emit xChanged(m_x); - -} - -void GuiObject::setTexture(const QString &texture) { - m_texture = texture; - emit textureChanged(m_texture); -} - - diff --git a/SnakeClient/SnakeApp/back-end/guiobject.h b/SnakeClient/SnakeApp/back-end/guiobject.h deleted file mode 100644 index dc903ef..0000000 --- a/SnakeClient/SnakeApp/back-end/guiobject.h +++ /dev/null @@ -1,91 +0,0 @@ -#ifndef GUIOBJECT_H -#define GUIOBJECT_H - -#include "baseclass.h" -#include "QObject" - -#include - -class GuiObject:public QObject, public BaseClass -{ - Q_OBJECT -// @todo: add color - Q_PROPERTY(QString color READ color WRITE setColor NOTIFY colorChanged) - Q_PROPERTY(double angle READ angle NOTIFY angleChanged) - Q_PROPERTY(QString texture READ texture NOTIFY textureChanged) - Q_PROPERTY(int guiId READ guiId NOTIFY guiIdChanged) - Q_PROPERTY(QString viewTemplate READ viewTemplate NOTIFY viewTemplateChanged) - Q_PROPERTY(int radius READ radius WRITE setRadius NOTIFY radiusChanged) - - Q_PROPERTY(double x READ x NOTIFY xChanged) - Q_PROPERTY(double y READ y NOTIFY yChanged) - Q_PROPERTY(double w READ w NOTIFY wChanged) - Q_PROPERTY(double h READ h NOTIFY hChanged) - -private: - void generateId(); - QString m_viewTemplate; - -protected: - int m_guiId = -1; - double m_angle = 0; - QString m_texture = ""; - QString m_color = ""; - int m_radius = 0; - - double m_x = 0; - double m_y = 0; - double m_w = 0; - double m_h = 0; - - void setTexture(const QString &texture); - - -public: - GuiObject(const QString& viewTempalte = "GraphicItem", QObject *ptr = nullptr); - - double angle() const; - QString texture() const; - - void render() override; - - QRectF rect() const; - virtual void setAngle(double angle); - int guiId() const; - - QString color() const; - - void setColor(QString color); - - double x() const; - double y() const; - double w() const; - double h() const; - - void setX(double x); - void setY(double y); - void setW(double w); - void setH(double h); - - virtual void reset(); - int radius() const; - QString viewTemplate() const; - -public slots: - - void setRadius(int radius); - -signals: - void angleChanged(double angle); - void textureChanged(QString texture); - void guiIdChanged(int guiId); - void colorChanged(QString color); - void xChanged(double x); - void yChanged(double y); - void wChanged(double w); - void hChanged(double h); - void radiusChanged(int radius); - void viewTemplateChanged(QString viewTemplate); -}; - -#endif // GUIOBJECT_H diff --git a/SnakeClient/SnakeApp/back-end/guiobjectfactory.cpp b/SnakeClient/SnakeApp/back-end/guiobjectfactory.cpp deleted file mode 100644 index 4313c60..0000000 --- a/SnakeClient/SnakeApp/back-end/guiobjectfactory.cpp +++ /dev/null @@ -1,23 +0,0 @@ -#include "guiobjectfactory.h" -#include "box.h" -#include -#include "head.h" -#include "background.h" -#include "backgrounditem.h" - -GuiObjectFactory::GuiObjectFactory() {} - -ItemWorld *GuiObjectFactory::generate(const QString &name) { - ItemWorld *obj = nullptr; - if (name == "Box") { - obj = new Box(rand() % 400, 0); - } - else if (name == "BackGround") { - obj = new BackGround(0, 0); - } - else if (name == "BackGroundItem") { - obj = new BackGroundItem(0, 0); - } - - return obj; -} diff --git a/SnakeClient/SnakeApp/back-end/guiobjectfactory.h b/SnakeClient/SnakeApp/back-end/guiobjectfactory.h deleted file mode 100644 index 1d60fe3..0000000 --- a/SnakeClient/SnakeApp/back-end/guiobjectfactory.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef GUIOBJECTFACTORY_H -#define GUIOBJECTFACTORY_H - -#include - -class ItemWorld; - -/** - * @brief The GuiObjectFactory class - * factory of gui ojects; - */ -class GuiObjectFactory -{ -public: - GuiObjectFactory(); - - /** - * @brief generate - generate the child of GuiObject - * by object name. - * @param name - name of class of genereta object - * @return pointer of generated object. - * If method called with not valid name then return nullptr. - */ - static ItemWorld* generate(const QString& name); -}; - -#endif // GUIOBJECTFACTORY_H diff --git a/SnakeClient/SnakeApp/back-end/head.cpp b/SnakeClient/SnakeApp/back-end/head.cpp deleted file mode 100644 index 3701d32..0000000 --- a/SnakeClient/SnakeApp/back-end/head.cpp +++ /dev/null @@ -1,58 +0,0 @@ -#include "head.h" -#include -#include - -void Head::render() { - - - qint64 tempTime = QDateTime::currentMSecsSinceEpoch() - time; - time = QDateTime::currentMSecsSinceEpoch(); - - double my = (m_y + (*speed * 0.55) * sin(m_angle * TO_RADIAN)); - m_y += (my - m_y) / 1000 * tempTime; - - if (*speed < 1) { - setColor(generalSpeadColor); - setRadius(static_cast(m_w * 0.4)); - - } else if (*speed < normSpead) { - setColor(normSpeadColor); - setRadius(static_cast(m_w * 0.5)); - - } else if (*speed < fastSpead) { - setColor(fastSpeadColor); - setRadius(static_cast(m_w * 0.5)); - - } else if (*speed < megaFastSpead) { - setColor(megaFastSpeadColor); - setRadius(static_cast(m_w * 0.4)); - - } - - emit yChanged(m_y); -} - -void Head::reset() { -} - -void Head::unPause() { - time = QDateTime::currentMSecsSinceEpoch(); -} - -Head::Head(double x, double y, double h, double w, double *spead): - GuiObject ("SnakeItem") { - setX(x); - setY(y); - setW(w); - setH(h); - this->speed = spead; -} - -void Head::setAngle(double angle) { - m_angle = angle; - emit angleChanged(m_angle); -} - -Head::~Head() { - -} diff --git a/SnakeClient/SnakeApp/back-end/head.h b/SnakeClient/SnakeApp/back-end/head.h deleted file mode 100644 index 47fb207..0000000 --- a/SnakeClient/SnakeApp/back-end/head.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef HEAD_H -#define HEAD_H -#define TO_RADIAN 0.017453293 - - -#include "guiobject.h" -#include - -class Head : public GuiObject -{ -private: - qint64 time; - double *speed; - const int megaFastSpead = 200; - const int fastSpead = 100; - const int normSpead = 50; - - const QString generalSpeadColor = "#616a6b"; - const QString normSpeadColor = "#5d6d7e"; - const QString fastSpeadColor = "#eb984e"; - const QString megaFastSpeadColor = "#ec7063"; - -public: - Head(double x , double y, double h, double w, double *speed); - void setAngle(double angle) override; - void render() override; - void reset() override; - void unPause(); - ~Head() override; -}; - -#endif // HEAD_H diff --git a/SnakeClient/SnakeApp/back-end/imageprovider.cpp b/SnakeClient/SnakeApp/back-end/imageprovider.cpp deleted file mode 100644 index 6300532..0000000 --- a/SnakeClient/SnakeApp/back-end/imageprovider.cpp +++ /dev/null @@ -1,37 +0,0 @@ -#include "asyncimageresponse.h" -#include "imageprovider.h" -#include -#include - -ImageProvider::ImageProvider() = default; -ImageProvider::~ImageProvider() = default; - -QQuickImageResponse *ImageProvider::requestImageResponse(const QString &id, - const QSize &requestedSize) { - - AsyncImageResponse* response = new AsyncImageResponse(); - auto readImage = [id, requestedSize, response]() mutable { - Q_UNUSED(requestedSize); - - auto params = id.split("/"); - - if (params.contains("player")) { - response->setResult(QImage(":/img/defaultuser"). - scaled(requestedSize, Qt::KeepAspectRatioByExpanding)); - - } else if (params.contains("item")) { - response->setResult(QImage(":/img/defaultsnake"). - scaled(requestedSize, Qt::KeepAspectRatioByExpanding)); - } else { - response->error("Wrong first parametr example 'first/last'"); - } - - }; - - QtConcurrent::run(readImage); - - return response; -} - - - diff --git a/SnakeClient/SnakeApp/back-end/imageprovider.h b/SnakeClient/SnakeApp/back-end/imageprovider.h deleted file mode 100644 index 188380e..0000000 --- a/SnakeClient/SnakeApp/back-end/imageprovider.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef IMAGEPROVIDER_H -#define IMAGEPROVIDER_H - -#include -#include - -class ImageProvider: public QQuickAsyncImageProvider -{ -private: -public: - explicit ImageProvider(); - ~ImageProvider() override; - - QQuickImageResponse *requestImageResponse(const QString &id, - const QSize &requestedSize) override; -}; - - -#endif // IMAGEPROVIDER_H diff --git a/SnakeClient/SnakeApp/back-end/itemworld.cpp b/SnakeClient/SnakeApp/back-end/itemworld.cpp deleted file mode 100644 index 5a1e24d..0000000 --- a/SnakeClient/SnakeApp/back-end/itemworld.cpp +++ /dev/null @@ -1,48 +0,0 @@ -#include "itemworld.h" -#include "snakeutils.h" -#include -#include -#include - -#define POINT 100 - -ItemWorld::ItemWorld(double x, double y, const QString& guiTemplate): - GuiObject (guiTemplate) { - setLoc(x, y); -} - -void ItemWorld::setBeckGroundObject(bool value) { - beckGroundObject = value; -} - -void ItemWorld::setSize(double h, double w) { - setH(h); - setW(w); -} - -void ItemWorld::setLoc(double x, double y) { - setX(x); - setY(y); -} - -void ItemWorld::render() { - if (m_x + w() < 0) { - m_x = (rand() % 400) + 200; - m_y = rand() % 100; - emit xChanged(m_x); - emit yChanged(m_y); - } -} - -bool ItemWorld::move(const GuiObject *snakeRiger, double dx) { - m_x -= dx; - emit xChanged(m_x); - - return snakeRiger->rect().intersects(rect()) && !beckGroundObject; -} - -bool ItemWorld::isBeckGroundObject() { - return beckGroundObject; -} - -ItemWorld::~ItemWorld() {} diff --git a/SnakeClient/SnakeApp/back-end/itemworld.h b/SnakeClient/SnakeApp/back-end/itemworld.h deleted file mode 100644 index 6159eaf..0000000 --- a/SnakeClient/SnakeApp/back-end/itemworld.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef ITEMWORLD_H -#define ITEMWORLD_H - -#include "guiobject.h" -#include - -class ItemWorld : public GuiObject -{ -private: - bool beckGroundObject = false; -protected: - virtual void setSize(double h, double w); - virtual void setLoc(double x, double y); - void setBeckGroundObject(bool value); - -public: - ItemWorld(double x, double y, const QString& GuiTemplate = "GraphicItem"); - - void render(); - virtual bool move(const GuiObject* snakeRiger, double dx); - bool isBeckGroundObject(); - - ~ItemWorld(); -}; - -#endif // ITEMWORLD_H diff --git a/SnakeClient/SnakeApp/back-end/main.cpp b/SnakeClient/SnakeApp/back-end/main.cpp deleted file mode 100644 index b2301a9..0000000 --- a/SnakeClient/SnakeApp/back-end/main.cpp +++ /dev/null @@ -1,20 +0,0 @@ -#include -#include -#include -#include "clientapp.h" - - -int main(int argc, char *argv[]) -{ - QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); - - QGuiApplication app(argc, argv); - QQmlApplicationEngine engine; - ClientApp client; - - if (!client.init(&engine)) { - return 1; - } - - return app.exec(); -} diff --git a/SnakeClient/SnakeApp/back-end/settings.cpp b/SnakeClient/SnakeApp/back-end/settings.cpp deleted file mode 100644 index d90bd07..0000000 --- a/SnakeClient/SnakeApp/back-end/settings.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "settings.h" diff --git a/SnakeClient/SnakeApp/back-end/settings.h b/SnakeClient/SnakeApp/back-end/settings.h deleted file mode 100644 index f9245d0..0000000 --- a/SnakeClient/SnakeApp/back-end/settings.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef SNAKESETTINGS_H -#define SNAKESETTINGS_H -#include -#include - -#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 diff --git a/SnakeClient/SnakeApp/back-end/snake.cpp b/SnakeClient/SnakeApp/back-end/snake.cpp deleted file mode 100644 index 7b1416e..0000000 --- a/SnakeClient/SnakeApp/back-end/snake.cpp +++ /dev/null @@ -1,200 +0,0 @@ -#include "snake.h" -#include "guiobject.h" - -#include -#include -#include -#include - -Snake::Snake() { -} - -const QVector &Snake::getItems() const { - return items; -} - -void Snake::render() { - - auto centerX = [](const Head* head) { - return head->x()/* + (head->w() / 2)*/; - }; - - auto centerY = [](const Head* head) { - return head->y() /*+ (head->h() / 2)*/; - }; - - for (int i = items.length() - 1; i >= 0; --i) { - - if (dead) { - items[i]->render(); - continue; - } - - if (i == 0) { - if (isClick) { - if (countClick & 1){ - items[i]->setAngle(45); - } else { - items[i]->setAngle(315); - } - isClick = false; - } - } else { - - double _atan2 = atan2(centerY(items[i - 1]) - centerY(items[i]), - centerX(items[i - 1]) - centerX(items[i])) * 90; - - items[i]->setAngle(_atan2); - } - - items[i]->render(); - } -} - -double Snake::checDistance(int i) { - - auto result = (items[i]->rect().y() - - items[i - 1]->rect().y()) / rataticonDistance; - - return result; - -} - -double Snake::getRataticonDistance() const { - return rataticonDistance; -} - -void Snake::setRataticonDistance(double value) { - rataticonDistance = value; -} - -void Snake::unPause() { - for ( int i = 0; i < items.size(); ++i ) { - items[i]->unPause(); - } -} - -double Snake::sizeByLvl(double lvl , int count) const { - double maxSize = 9; - double minSize = 5; - - double pos = (1 - (lvl / count)); - - QList> snakeGradientSize { - {1, 4}, - {0.99, 7}, - {0.8, 5}, - {0.6, 6}, - {0.0, 3} - }; - - double local = 0; - int index = 0; - - while (index + 1 < snakeGradientSize.size() - && pos <= snakeGradientSize[index].first) { - - maxSize = snakeGradientSize[index].second; - minSize = snakeGradientSize[index + 1].second; - - auto range = snakeGradientSize[index].first - - snakeGradientSize[index + 1].first; - - local = ( range - (snakeGradientSize[index].first - pos)) / - range; - - index++; - } - - return local * (maxSize - minSize) + minSize; -} - -void Snake::changeCountObjects(int count) { - if (count > 0) { - double margin = 60.0 / count; - for ( int i = 0; i < count; ++i ) { - - auto size = sizeByLvl(i, count); - auto obj = new Head(margin * (count - i), - 50, size , size, - this->speed); - - obj->setY(50 + obj->h() / 2); - - items.push_back(obj); - } - - } else { - for ( int i = count; i < 0; ++i ) { - auto obj = items.first(); - items.removeFirst(); - delete obj; - } - } -} - -QMap Snake::init(int size, double *speed) { - - QMap res; - - if (size <= 0) { - return res; - } - - this->speed = speed; - - changeCountObjects(size - items.size()); - - for (auto i : items) { - res[i->guiId()] = i; - } - - dead = false; - - return res; -} - -bool Snake::isInited() const { - return items.size(); -} - -void Snake::clearItems() { - for (auto i : items) { - delete i; - } - items.clear(); -} - -void Snake::resetPosotion() { - double margin = 60.0 / items.size(); - - for ( int i = 0; i < items.size(); ++i ) { - items[i]->setX(margin * (items.size() - i)); - items[i]->setY(50 + items[i]->h() / 2); - items[i]->setAngle(0); - } -} - -void Snake::kill() { - dead = true; -} - -bool Snake::isDead() const { - return dead; -} - -Snake::~Snake() { - clearItems(); -} - -void Snake::clear() { - clearItems(); -} - -void Snake::reverse() { - if (isClick) { - return; - } - isClick = true; - countClick++; -} diff --git a/SnakeClient/SnakeApp/back-end/snake.h b/SnakeClient/SnakeApp/back-end/snake.h deleted file mode 100644 index b919028..0000000 --- a/SnakeClient/SnakeApp/back-end/snake.h +++ /dev/null @@ -1,52 +0,0 @@ -#ifndef SNAKE_H -#define SNAKE_H - -#define SPEEDSNAKE 10 - -#include -#include "head.h" -#include "baseclass.h" - -class GuiObject; - - - -class Snake : public BaseClass -{ -private: - double rataticonDistance = 1; - QVector items; - double *speed = nullptr; - bool isClick = false; - int countClick = 0; - bool dead = false; - double sizeByLvl(double lvl, int count) const; - void changeCountObjects(int count); - - double checDistance(int i); - void clearItems(); - - -public: - Snake(); - ~Snake() override; - void clear(); - void resetPosotion(); - - void kill(); - bool isDead() const; - - void reverse(); - void render() override; - QMap init(int size, double *speed); - bool isInited() const; - const QVector& getItems() const; - double getMovedLong() const; - double getRataticonDistance() const; - void setRataticonDistance(double value); - int getDeadTimer() const; - void setDeadTimer(int value); - void unPause(); -}; - -#endif // SNAKE_H diff --git a/SnakeClient/SnakeApp/back-end/world.cpp b/SnakeClient/SnakeApp/back-end/world.cpp deleted file mode 100644 index 62f799c..0000000 --- a/SnakeClient/SnakeApp/back-end/world.cpp +++ /dev/null @@ -1,173 +0,0 @@ -#include "background.h" -#include "world.h" - -#include -#include "guiobject.h" -#include "guiobjectfactory.h" -#include -#include - -World::World() { - currentLong = 0; - endLong = 0; - background = ""; -} - -void World::clear() { - clearItems(); - snake.clear(); -} - -double World::getCurrentLong() const { - return currentLong; -} - -QMultiMap World::getItems() const -{ - return items; -} - -void World::unPause() { - time = QDateTime::currentMSecsSinceEpoch(); - snake.unPause(); -} - -void World::clearItems() { - for (auto i : items) { - delete i; - } - oldRules.clear(); - items.clear(); - spead = 0; - d_spead = 0; -} - -void World::changeCountObjects(const QString &name, int count) { - - if (count > 0) { - - for ( int i = 0; i < count; ++i ) { - auto obj = GuiObjectFactory::generate(name); - - if (!obj) { - qWarning() <<"object not created line:" << Q_FUNC_INFO; - break; - } - - items.insertMulti(name, obj); - } - - } else { - for ( int i = count; i < 0; ++i ) { - auto obj = items.value(name); - if (1 != items.remove(name, obj)) { - qWarning() << "World::changeCountObjects error delete object!"; - } - delete obj; - } - } -} - -QMap World::init(WorldRules rules) { - - QMap res; - -// rules["BackGround"] = 1; - - currentLong = -1; - for (auto i = rules.begin(); i != rules.end(); ++i) { - if (i.key() == "Long") { - endLong = rules["Long"]; - currentLong = 0; - } - else if (i.key() == "Spead") { - d_spead = rules["Spead"]; - } - else { - changeCountObjects(i.key(), i.value() - oldRules.value(i.key())); - } - } - - auto snakeItems = snake.init(20, &spead); - - for (auto i = snakeItems.begin(); i != snakeItems.end(); ++i) { - res.insert(i.key(), i.value()); - } - - for (auto i : items) { - res[i->guiId()] = i; - } - - - oldRules = rules; - time = QDateTime::currentMSecsSinceEpoch(); - defiat = false; - return res; -} - -World::~World() { - clearItems(); -} - -void World::render() { - - qint64 tempTime = QDateTime::currentMSecsSinceEpoch() - time; - time = QDateTime::currentMSecsSinceEpoch(); - double dx = spead / 1000 * tempTime; - - spead -= 0.0310 * tempTime; - - if (spead < 0) - spead = 0; - - snake.render(); - auto rig = snake.getItems().first(); - - for (auto i = items.begin(); i != items.end(); ++i) { - defiat |= (*i)->move(rig, dx); - (*i)->render(); - } - - defiat |= (rig->y()< 0 || rig->y() > 100); - - if (!snake.isDead() && defiat) { - snake.kill(); - } - - currentLong += dx; -} - -void World::resetPosition() { - for (auto i : items) { - i->reset(); - } - spead = 0; - - snake.resetPosotion(); -} - -bool World::move() { - return isEnd(); -} - -bool World::isEnd() { - return currentLong >= endLong; -} - -bool World::isDefiat() const { - return defiat && !static_cast(spead); -} - -WorldRules World::currentRules() const { - return oldRules; -} - -void World::reversClick() { - if (snake.isDead()) { - spead = 0; - return; - } - - snake.reverse(); - spead += d_spead; -} diff --git a/SnakeClient/SnakeApp/back-end/world.h b/SnakeClient/SnakeApp/back-end/world.h deleted file mode 100644 index d786634..0000000 --- a/SnakeClient/SnakeApp/back-end/world.h +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef WORLD_H -#define WORLD_H - -#define SPEEDWORLD 10 - -#include -#include "itemworld.h" -#include "baseclass.h" -#include "snakeutils.h" -#include "snake.h" - -class World : public BaseClass -{ -private: - - Snake snake; - QMultiMap items; - double currentLong = 0; - int endLong; - double spead = 0, d_spead = 0; - QString background; - qint64 time; - bool defiat = false; - WorldRules oldRules; - - void clearItems(); - - void changeCountObjects(const QString &name, int count); - -public: - World(); - void clear(); - QMap init(WorldRules rules); - ~World() override; - void render() override; - void resetPosition(); - bool move(); - bool isEnd(); - bool isDefiat() const; - WorldRules currentRules() const; - void reversClick(); - double getCurrentLong() const; - QMultiMap getItems() const; - void unPause(); -}; - -#endif // WORLD_H diff --git a/SnakeClient/SnakeApp/front-end/About.qml b/SnakeClient/SnakeApp/front-end/About.qml deleted file mode 100644 index 8bcbc05..0000000 --- a/SnakeClient/SnakeApp/front-end/About.qml +++ /dev/null @@ -1,29 +0,0 @@ -import QtQuick 2.9 -import QtQuick.Controls.Material 2.0 -import QtQuick.Controls 2.3 -import QtQuick.Layouts 1.3 - -Page { - - signal close(); - - title: "Page" - header: Rectangle { - height: parent.height * 0.1 - color: "#cccccc" - Label { - id: title - text: qsTr("About") - font.pointSize: 13 - wrapMode: Text.WordWrap - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignHCenter - anchors.fill: parent; - anchors.margins: 5 - } - } - - contentItem: AboutPage{ - } - -} diff --git a/SnakeClient/SnakeApp/front-end/AboutPage.qml b/SnakeClient/SnakeApp/front-end/AboutPage.qml deleted file mode 100644 index ef34917..0000000 --- a/SnakeClient/SnakeApp/front-end/AboutPage.qml +++ /dev/null @@ -1,72 +0,0 @@ -import QtQuick 2.9 -import QtQuick.Controls 2.3 -import QtQuick.Controls.Material 2.0 -import QtQuick.Layouts 1.3 - -Item { - clip: true - ColumnLayout { - id: columnLayout - anchors.fill: parent - spacing: 10 - - Rectangle { - Layout.preferredHeight: parent.width / 4 - Layout.preferredWidth: parent.width / 4 - Layout.alignment: Qt.AlignHCenter | Qt.AlignTop - color: "#00000000" - Image { - id: aboutLogo - fillMode: Image.PreserveAspectFit - - source: "qrc:/logo/logo" - anchors.margins: 10 - anchors.fill: parent - - } - } - - - - Flickable { - id: flickable - clip: true - flickableDirection: Flickable.VerticalFlick - - Layout.preferredHeight: parent.height - parent.height / 2.8 - - - TextArea.flickable: TextArea { - id: textArea - textFormat: Qt.RichText - wrapMode: TextArea.Wrap - readOnly: true - persistentSelection: true - - leftPadding: 6 - rightPadding: 6 - topPadding: 0 - bottomPadding: 0 - background: null - - text: qsTr("Product of QuasarrApp"); - font.family: "Verdana" - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignTop - - onLinkActivated: Qt.openUrlExternally(link) - } - - ScrollBar.vertical: ScrollBar { } - Layout.fillWidth: true - - } - - } - -} - -/*##^## Designer { - D{i:0;autoSize:true;height:480;width:640} -} - ##^##*/ diff --git a/SnakeClient/SnakeApp/front-end/BasePopUp.qml b/SnakeClient/SnakeApp/front-end/BasePopUp.qml deleted file mode 100644 index 62af5a8..0000000 --- a/SnakeClient/SnakeApp/front-end/BasePopUp.qml +++ /dev/null @@ -1,71 +0,0 @@ -import QtQuick 2.11 -import QtQuick.Controls 2.3 -import QtQuick.Controls.Material 2.0 -import QtQuick.Layouts 1.3 -import QtGraphicalEffects 1.12 - -Dialog { - id : basePopup - width: 200 - height: 100 - x: 0 - y: 0 - - transformOrigin: Item.Center - - property bool autoClose: true - property bool clickClose: true - - property int closeInterval: 15000; - property int margin : 0 - property color backgroundColor: Material.background - - background: Item { - id: bacground - - Rectangle{ - anchors.fill: parent - id: backCorner - color: backgroundColor - radius: metrix.mm - } - - DropShadow { - anchors.fill: parent - source: backCorner - color: "#80000000" - verticalOffset: 10 - samples: 30 - } - } - - function _show() { - - if (autoClose) { - timerAutoClose.start(); - } - - open(); - } - - Timer { - id: timerAutoClose; - running: false; - repeat: false; - interval: closeInterval; - - onTriggered: { - close(); - } - } - - onClosed: { - if (autoClose) - opacity = 0; - } - - closePolicy: (!clickClose || autoClose)? Popup.NoAutoClose: Popup.CloseOnReleaseOutside - - onRejected: close() - -} diff --git a/SnakeClient/SnakeApp/front-end/FrameView.qml b/SnakeClient/SnakeApp/front-end/FrameView.qml deleted file mode 100644 index 33cc8e6..0000000 --- a/SnakeClient/SnakeApp/front-end/FrameView.qml +++ /dev/null @@ -1,32 +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 - -Frame { - id: frameVew - property bool translucent: true - property bool showBorder: true - - function _backGroundColor() { - if (translucent) { - if (Material.theme == Material.Dark) { - return "#50000000"; - } - - return "#50ffffff"; - } - - return Material.background; - } - - background: Rectangle { - color: _backGroundColor() - border.color: (Material.theme == Material.Dark)? "#000000": "#cfcfcf" - border.width: (showBorder)? 1 : 0 - radius: metrix.mm - } - - padding: 3 * metrix.mm -} diff --git a/SnakeClient/SnakeApp/front-end/GraphicItem.qml b/SnakeClient/SnakeApp/front-end/GraphicItem.qml deleted file mode 100644 index 3534c99..0000000 --- a/SnakeClient/SnakeApp/front-end/GraphicItem.qml +++ /dev/null @@ -1,38 +0,0 @@ -import QtQuick 2.9 - -Rectangle { - id: graphicItem - property var model: null - property real angle: (model) ? model.angle : 0; - property string texture: (model) ? model.texture : ""; - property int guiId: (model) ? model.guiId : -1; - - z:-1 - property double devX: width / 2 - property double devY: height / 2 - - Image { - id: name - visible: texture.length - source: texture - - anchors.fill: parent; - } - - color: (model) ? model.color : "#11ff32"; - - width: (model) ? model.w * metrix.gamePt: 0; - height: (model) ? model.h * metrix.gamePt: 0; - - x: (model) ? model.x * metrix.gamePt - devX: 0; - y: (model) ? model.y * metrix.gamePt - devY: 0; - - radius: (model) ? model.radius * metrix.gamePt : 0; - - transform: Rotation { - origin.x: devX; - origin.y: devY; - angle: graphicItem.angle; - } - -} diff --git a/SnakeClient/SnakeApp/front-end/ImageView.qml b/SnakeClient/SnakeApp/front-end/ImageView.qml deleted file mode 100644 index 8e492b4..0000000 --- a/SnakeClient/SnakeApp/front-end/ImageView.qml +++ /dev/null @@ -1,83 +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 { - id: imageView - property int size: 50 - property double ratio: 1 - property string drawItem: "" - property bool hovered: false - property bool hold: false - - signal clicked(); - - width: size * ratio - height: size - - Image { - id: img - fillMode: Image.PreserveAspectFit - source: drawItem - sourceSize: Qt.size(width, height) - smooth: true - visible: false - anchors.fill: parent - } - - DropShadow { - anchors.fill: img - horizontalOffset: (hold)? 20: (hovered)? 10: 5 - verticalOffset: (hold)? 20: (hovered)? 10: 5 - radius: 8.0 - samples: 17 - Behavior on horizontalOffset { - - ColorAnimation { - duration: 200 - } - } - - Behavior on verticalOffset { - - ColorAnimation { - duration: 200 - } - } - - - Behavior on color { - - ColorAnimation { - duration: 200 - } - } - color: (hold)? "#80000000": (hovered)? "#60000000": "#40000000" - source: img - } - - MouseArea { - anchors.fill: parent - hoverEnabled: true - - onEntered: { - parent.hovered = true; - } - - onExited: { - parent.hovered = false; - } - - onReleased: { - parent.hold = false; - imageView.clicked(); - } - - onPressed: { - parent.hold = true; - } - } - -} diff --git a/SnakeClient/SnakeApp/front-end/LeftBoxSideBar.qml b/SnakeClient/SnakeApp/front-end/LeftBoxSideBar.qml deleted file mode 100644 index 05e1daa..0000000 --- a/SnakeClient/SnakeApp/front-end/LeftBoxSideBar.qml +++ /dev/null @@ -1,13 +0,0 @@ -import QtQuick 2.0 - -LeftSideBar { - resizeHeight: true; - closedHeight: closedWidth; - openHeight: 10 * metrix.pt; - openWidth: 10 * metrix.pt; - anchors.left: parent.left; - anchors.top: undefined; - anchors.bottom: undefined; - -} - diff --git a/SnakeClient/SnakeApp/front-end/LeftSideBar.qml b/SnakeClient/SnakeApp/front-end/LeftSideBar.qml deleted file mode 100644 index e566da8..0000000 --- a/SnakeClient/SnakeApp/front-end/LeftSideBar.qml +++ /dev/null @@ -1,35 +0,0 @@ -import QtQuick 2.12 -import QtQuick.Controls.Material 2.12 -import QtQuick.Controls 2.12 -import QtQuick.Layouts 1.3 - -SideBar { - id: leftSideBar - anchors.left: parent.left; - anchors.top: parent.top; - anchors.bottom: parent.bottom; - closedWidth: closeButton.width + padding * 2; - openWidth: 10 * metrix.pt; - resizeHeight: false; - - header: - RowLayout { - - Button { - id: closeButton - text: leftSideBar.isOpened? "<" : ">" - - Layout.preferredHeight: metrix.controlPtMaterial; - Layout.preferredWidth: metrix.controlPtMaterial; - - Layout.alignment: Qt.AlignRight | Qt.AlignTop - onClicked: { - if (leftSideBar.isOpened) - leftSideBar.hide(); - else - leftSideBar.show(); - } - - } - } -} diff --git a/SnakeClient/SnakeApp/front-end/LoginView.qml b/SnakeClient/SnakeApp/front-end/LoginView.qml deleted file mode 100644 index e7c1ab8..0000000 --- a/SnakeClient/SnakeApp/front-end/LoginView.qml +++ /dev/null @@ -1,301 +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 { - id: element - - property int loginStatus : 0 - - readonly property int currentView: tabBar.currentIndex - readonly property var resultEnum: [ - qsTr("Success"), // 0 - qsTr("Password must be at least 8 characters"), // 1 - qsTr("Name must be at least 1 characters"), // 2 - qsTr("Passwords must match"), // 3 - - qsTr("The letter must match the pattern 'X@xxxx.xxx'") // 4 - - ] - - signal sigNewUser(var gmail, var password); - signal sigLogin(var gmail, var password); - signal toOffline(); - - - function _checkLogin() { - const pass = loginPass.text; - const email = loginEmail.text; - - if (pass.length < 8) { - return 1; - } - - if (email.search(/[a-z\-A-Z0-9_]+@[a-z\-A-Z0-9_]+\.[a-z\-A-Z0-9_]+/) < 0) { - return 4; - } - - return 0; - - } - - function _checkRegister () { - const pass = registerPassword.text; - const pass2 = registerPassword2.text; - - const email = registerEmail.text; - - if (pass.length < 8) { - return 1; - } - - if (pass !== pass2) { - return 3; - } - - if (email.search(/[a-z\-A-Z0-9_]+@[a-z\-A-Z0-9_]+\.[a-z\-A-Z0-9_]+/) < 0) { - return 4; - } - - return 0; - } - - function checkData(isregisterForm) { - if (isregisterForm) { - return _checkRegister(); - } - - return _checkLogin(); - } - - SwipeView { - id: swipeView - anchors.bottom: bottons.top - anchors.top: tabBar.bottom - anchors.left: parent.left - anchors.right: parent.right - - clip: true - - currentIndex: tabBar.currentIndex - - Item { - id: loginPage - - GridLayout { - id: columnLayout - anchors.fill: parent - columns: 2 - rows: 2 - Label { - text: qsTr("Email") - } - - TextField { - id: loginEmail - placeholderText: "Enter Your Email" - Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter - Layout.fillWidth: true - } - - - Label { - text: qsTr("Passsword") - } - TextField { - id: loginPass - placeholderText: qsTr("Enter Your passsword") - - Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter - - echoMode: TextInput.Password - cursorVisible: true - Layout.fillWidth: true - - } - - } - } - - Item { - id: rigisterPage - GridLayout { - - anchors.fill: parent - - columns: 2 - rows: 3 - - Label { - text: qsTr("Email") - } - TextField { - id: registerEmail; - placeholderText: qsTr("Enter Your Email") - Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter - Layout.fillWidth: true - - } - - Label { - text: qsTr("Password") - } - TextField { - id: registerPassword; - - placeholderText: qsTr("Enter Your passsword") - - Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter - Layout.fillWidth: true - echoMode: TextInput.Password - cursorVisible: true - } - - Label { - text: qsTr("Repeat password") - } - TextField { - id: registerPassword2; - - placeholderText: qsTr("Enter Your passsword again") - - Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter - Layout.fillWidth: true - echoMode: TextInput.Password - cursorVisible: true - } - } - } - } - - TabBar { - id: tabBar - anchors.top: parent.top - anchors.topMargin: 0 - anchors.left: parent.left - anchors.leftMargin: 0 - anchors.right: parent.right - anchors.rightMargin: 0 - - TabButton { - id: login - text: qsTr("Sign in") - checkable: false - } - - TabButton { - id: register - text: qsTr("Sign Up") - } - } - - RowLayout { - id : bottons - Button { - text: qsTr("Cancel") - - onClicked: { - Qt.quit() - } - - } - - Item { - Layout.fillWidth: true - } - - Button { - text: tabBar.currentItem.text - - onClicked: { - - const messageIndex = checkData(tabBar.currentIndex); - if (messageIndex === 0) { - - if (tabBar.currentIndex) { - // register request - sigNewUser(registerEmail.text, registerPassword); - } else { - //login request - sigLogin(loginEmail.text, loginPass.text); - } - } else { - - notificationService.setNotify(qsTr("Error"), - resultEnum[messageIndex], - "", - 2); - } - } - - } - - anchors.bottom: parent.bottom - anchors.left: parent.left - anchors.right: parent.right - } - - onLoginStatusChanged: { - if (loginStatus === 2) - busy._show(); - else { - busy.close(); - } - } - - PagePopUp { - id: busy - modal: true - autoClose: false; - clickClose: false; - BusyIndicator { - running: true - anchors.fill: parent - } - height: 2 * metrix.controlPtMaterial - width: height - - } - - - FrameView { - visible: loginStatus === 4 - anchors.fill: parent - translucent: false - showBorder: false - ColumnLayout { - anchors.fill: parent - - Label { - text: qsTr("You need connect to server"); - font.pixelSize: metrix.controlPtMaterial; - wrapMode: Text.WordWrap - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - - Layout.fillHeight: true - Layout.fillWidth: true - - } - - Button { - text: qsTr("Use OfflineMode"); - Layout.alignment: Qt.AlignHCenter - - onClicked: { - toOffline(); - } - - } - } - - } -} - -/*##^## Designer { - D{i:0;autoSize:true;height:480;width:640}D{i:3;anchors_height:100;anchors_width:100;anchors_x:228;anchors_y:63} -D{i:1;anchors_height:200;anchors_width:200;anchors_x:205;anchors_y:53}D{i:11;anchors_width:240;anchors_x:226;anchors_y:21} -} - ##^##*/ diff --git a/SnakeClient/SnakeApp/front-end/MainMenu.qml b/SnakeClient/SnakeApp/front-end/MainMenu.qml deleted file mode 100644 index 74147e0..0000000 --- a/SnakeClient/SnakeApp/front-end/MainMenu.qml +++ /dev/null @@ -1,196 +0,0 @@ -import QtQuick 2.9 -import QtQuick.Controls.Material 2.0 -import QtQuick.Controls 2.3 -import QtQuick.Layouts 1.3 - -Item { - id: item1 - property var model: null - readonly property int onlineStatus: (model)? model.onlineStatus: false - - visible: true - z: 1 - - signal playGame(); - - onOnlineStatusChanged: { - if (onlineStatus && onlineStatus !== 5) { - loginPopUp._show(); - } else { - loginPopUp.close(); - } - } - - LeftSideBar { - id: userViewSideBar - openWidth: 7 * metrix.pt; - - openHeight: columnLayout.height - source: UserView { - - anchors.fill: parent; - model: (item1.model)? item1.model.userViewModel: null - visible: userViewSideBar.openFinished - onTryConnect: { - if (item1.model) - item1.model.tryConnect(); - } - } - - } - - - GridLayout { - id: columnLayout - anchors.top: parent.top - anchors.bottom: parent.bottom - anchors.left: userViewSideBar.right - anchors.right: parent.right - - anchors.leftMargin: 0 - anchors.rightMargin: 0 - anchors.bottomMargin: 0 - anchors.topMargin: 0 - - columns: 3 - rows: 2 - - - transformOrigin: Item.Center - - - MainMenuButton { - id: play - text: qsTr("Play game") - - onClicked: { - playGame(); - if (model) - model.newGame(); - } - - } - - MainMenuButton { - id: store - text: qsTr("Store") - - } - - MainMenuButton { - id: invitar - text: qsTr("My Items") - } - - MainMenuButton { - id: freands - text: qsTr("My friends") - - } - - MainMenuButton { - id: settings - text: qsTr("My Settings") - - onClicked: { - settingsPopUp._show(); - - } - - } - - MainMenuButton { - id: exit - text: qsTr("Exit") - - onClicked: { - Qt.quit(); - } - } - - } - - PagePopUp { - id: about; - width: parent.width / 2 - height: parent.height / 2; - - source: About {} - } - - PagePopUp { - id: settingsPopUp - source: SettingsView { - id: settingsView - model: item1.model ? item1.model.userSettingsModel: null - } - - standardButtons: Dialog.Save | Dialog.Cancel | Dialog.RestoreDefaults - modal: false; - autoClose: false - clickClose: true - width: 12 * metrix.controlPtMaterial - height: 8 * metrix.controlPtMaterial; - - onAccepted: { - settingsView.save(); - } - - onReset: { - settingsView.reset(); - } - - onOpened: { - settingsView.update(); - } - - } - - - PagePopUp { - id: loginPopUp - source: LoginView { - id: loginView - loginStatus: onlineStatus - - onSigLogin: { - if (!model) { - return; - } - - model.login(gmail, password); - } - onSigNewUser: { - if (!model) { - return; - } - - model.registerNewUser(gmail, password); - - } - - onToOffline: { - if (!model) { - return; - } - - model.playOffline(); - } - } - - visible: true; - modal: true; - autoClose: false - clickClose: false - width: 12 * metrix.controlPtMaterial - height: ((loginView.currentView)? 9 : 7) * metrix.controlPtMaterial; - } - - -} - - -/*##^## Designer { - D{i:0;autoSize:true;height:480;width:640} -} - ##^##*/ diff --git a/SnakeClient/SnakeApp/front-end/MainMenuButton.qml b/SnakeClient/SnakeApp/front-end/MainMenuButton.qml deleted file mode 100644 index 12f6eb0..0000000 --- a/SnakeClient/SnakeApp/front-end/MainMenuButton.qml +++ /dev/null @@ -1,17 +0,0 @@ -import QtQuick 2.12 -import QtQuick.Controls.Material 2.12 -import QtQuick.Controls 2.12 -import QtQuick.Layouts 1.3 - -Button { - id: exit - Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter - font.pixelSize: height * 0.1 - display: AbstractButton.TextBesideIcon - spacing: 4 - focusPolicy: Qt.StrongFocus - - Layout.preferredHeight: parent.height / (parent.rows + 1) - Layout.preferredWidth: parent.width / (parent.columns + 1) - -} diff --git a/SnakeClient/SnakeApp/front-end/Metrix.qml b/SnakeClient/SnakeApp/front-end/Metrix.qml deleted file mode 100644 index f0bacc8..0000000 --- a/SnakeClient/SnakeApp/front-end/Metrix.qml +++ /dev/null @@ -1,27 +0,0 @@ -import QtQuick 2.0 -import QtQuick.Window 2.12 -import QtQuick.Controls.Material 2.0 -import QtQuick.Controls 2.3 - -Item { - readonly property int pointCount: 100; - readonly property real mm: Screen.pixelDensity - readonly property real sm: 10 * mm - readonly property real dsm: Math.sqrt(Math.pow(Screen.desktopAvailableWidth, 2) + Math.pow(Screen.desktopAvailableHeight, 2)) / sm - readonly property real pt: getfactor(dsm) * sm - readonly property real controlPtMaterial: Material.buttonHeight - readonly property real gamePt: (width < height) ? width / pointCount : height / pointCount; - - function getfactor(dsm) { - if (dsm < 30) { - return 0.5 - } else if ( dsm < 70) { - return 1 - } else if (dsm < 140) { - return 2; - } else - return 4; - } - - anchors.fill: parent; -} diff --git a/SnakeClient/SnakeApp/front-end/NotificationForm.qml b/SnakeClient/SnakeApp/front-end/NotificationForm.qml deleted file mode 100644 index 72445bc..0000000 --- a/SnakeClient/SnakeApp/front-end/NotificationForm.qml +++ /dev/null @@ -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 - } - } - } -} diff --git a/SnakeClient/SnakeApp/front-end/NotificationServiceView.qml b/SnakeClient/SnakeApp/front-end/NotificationServiceView.qml deleted file mode 100644 index fb6d18e..0000000 --- a/SnakeClient/SnakeApp/front-end/NotificationServiceView.qml +++ /dev/null @@ -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(); - } -} diff --git a/SnakeClient/SnakeApp/front-end/PagePopUp.qml b/SnakeClient/SnakeApp/front-end/PagePopUp.qml deleted file mode 100644 index 7c35bb4..0000000 --- a/SnakeClient/SnakeApp/front-end/PagePopUp.qml +++ /dev/null @@ -1,26 +0,0 @@ -import QtQuick 2.11 -import QtQuick.Controls 2.3 -import QtQuick.Controls.Material 2.0 -import QtQuick.Layouts 1.3 - -BasePopUp { - id: pagePopUp - property var source: null - autoClose: false - - Item { - id: sourceVal - anchors.fill: parent - } - - onSourceChanged: { - if (!source) - return; - - source.parent = sourceVal; - source.anchors.fill = sourceVal; - } - - x: parent.width / 2 - width / 2 - y: parent.height / 2 - height / 2 -} diff --git a/SnakeClient/SnakeApp/front-end/PropertyView.qml b/SnakeClient/SnakeApp/front-end/PropertyView.qml deleted file mode 100644 index 6870da8..0000000 --- a/SnakeClient/SnakeApp/front-end/PropertyView.qml +++ /dev/null @@ -1,124 +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 { - id: properyView - - height: 1 * metrix.pt - - property string keyImage: ""; - property string keyText: ""; - - property string valueImage: ""; - property string valueText: ""; - - property int lineWidth : 0.5 * metrix.mm - - property bool hovered: false - property bool hold: false - - Rectangle { - id:background - anchors.fill: parent - color: "#00000000" - - Rectangle { - height: lineWidth - color: (hold)? Material.accent: (hovered)? Material.foreground:"#aaa" - anchors.bottom: parent.bottom - anchors.left: parent.left - anchors.right: parent.right - - Behavior on color { - - ColorAnimation { - duration: 100 - } - } - } - } - - DropShadow { - anchors.fill: background - horizontalOffset: 2 - verticalOffset: 2 - radius: 8.0 - samples: 17 - - color: "#80000000"; - source: background - } - - MouseArea { - anchors.fill: parent - hoverEnabled: true - - onEntered: { - parent.hovered = true; - } - - onExited: { - parent.hovered = false; - } - - onReleased: { - parent.hold = false; - } - - onPressed: { - parent.hold = true; - } - } - - RowLayout { - - Label { - text: keyText - visible: keyText - Layout.alignment: Qt.AlignLeft - horizontalAlignment: Text.AlignLeft - - } - - ImageView { - visible: keyImage - drawItem: keyImage - size: parent.height * 0.75 - - Layout.alignment: Qt.AlignLeft - } - - - Label { - text: valueText - visible: valueText - horizontalAlignment: Text.AlignRight - - Layout.fillWidth: true - - Layout.alignment: Qt.AlignRight - - } - - ImageView { - drawItem: valueImage - size: parent.height * 0.75 - visible: valueImage - - Layout.alignment: Qt.AlignRight - - - } - anchors.fill: parent - } - - -} - -/*##^## Designer { - D{i:0;autoSize:true;height:480;width:640} -} - ##^##*/ diff --git a/SnakeClient/SnakeApp/front-end/Scene.qml b/SnakeClient/SnakeApp/front-end/Scene.qml deleted file mode 100644 index 524d48f..0000000 --- a/SnakeClient/SnakeApp/front-end/Scene.qml +++ /dev/null @@ -1,228 +0,0 @@ -import QtQuick 2.11 -import QtQuick.Controls.Material 2.0 -import QtQuick.Controls 2.3 -import QtQuick.Layouts 1.3 - -Item { - id: scene; - z: -2 - - Rectangle { - id: background; - color: "#ffffff" - anchors.fill: parent; - - Behavior on color { - - ColorAnimation { - duration: 5000 - } - } - - z: -3 - - } - - property var model: null; - property var arrayObjects: [] - readonly property bool showMenu: (model)? model.showMenu: false - property bool isPause: false - - function add (cppObjId) { - if (!model) { - console.log("create object fail") - return; - } - var objModel = model.getGameObject(cppObjId); - - if (!objModel) { - console.log("object model not found"); - return; - } - - var viewTemplate = objModel.viewTemplate; - - var temp = Qt.createComponent( viewTemplate + ".qml") - if (temp.status === Component.Ready) { - var obj = temp.createObject(parent) // parent - это обьект на который будет помещен соззданный элемент - obj.model = model.getGameObject(cppObjId); - obj.z = -2; - arrayObjects.push(obj) - } else { - console.log("wrong viewTemplate in model"); - } - } - - function remove(id) { - if (typeof id !== "number" || id < 0) { - console.log("id not found"); - return; - } - - for (var i = 0; i < arrayObjects.length; ++i) { - if (id === arrayObjects[i].guiId) { - arrayObjects.splice(i,1); - } - } - } - - function updateBackgroundColor(lvl) { - switch(lvl % 7) { - case 0: background.color = "#d6eaf8"; break; - case 1: background.color = "#d0ece7"; break; - case 2: background.color = "#d4efdf"; break; - case 3: background.color = "#fcf3cf"; break; - case 4: background.color = "#f6ddcc"; break; - case 5: background.color = "#f2d7d5"; break; - case 6: background.color = "#ebdef0"; break; - case 7: background.color = "#fbfcfc"; break; - - } - } - - Timer { - id: autoTimer; - repeat: true; - running: showMenu; - interval: 1000 - onTriggered: { - interval = Math.random() * 600 - scene.model.buttonPress(); - } - } - - Connections { - target: model; - onGameObjectsChanged: { - if (!dif) { - console.log("dif not found"); - return; - } - - var tempDifRem = []; - tempDifRem = dif.getRemoveIds(); - var tempDifAdd = []; - tempDifAdd = dif.getAddedIds(); - - for (var i = 0; i < tempDifAdd.length; ++i) { - add(tempDifAdd[i]); - } - - for (i = 0; i < tempDifRem.length; ++i) { - remove(tempDifRem[i]); - } - } - } - - Component.onCompleted: { - updateBackgroundColor(0); - model.handleNewGame(); - - } - - MouseArea { - anchors.fill: parent; - - onClicked: { - if (!model || showMenu) { - return; - } - - model.buttonPress(); - } - } - - Button { - id: returnToMenu; - - text: "<<" - - anchors.left: parent.left - anchors.leftMargin: metrix.gamePt - - anchors.top: parent.top - anchors.topMargin: metrix.gamePt - z: 1 - - onClicked: { - if (model) - model.showMenu = true; - } - - visible: !showMenu - } - - Button { - id: pause - - text: (isPause)? "▶" :"||" - - anchors.left: returnToMenu.right - anchors.leftMargin: metrix.gamePt - - anchors.top: parent.top - anchors.topMargin: metrix.gamePt - z: returnToMenu.z - - onClicked: { - isPause = !isPause; - if (model) model.setPause(isPause); - } - - visible: !showMenu - - } - - Button { - id: long_ - Label { - anchors.fill: parent; - - textFormat: Text.AutoText - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignHCenter - wrapMode: Text.WordWrap - - text: qsTr("lvl long: ") + ((model)? model.long_: "0") - } - - width: 35 * metrix.gamePt; - height: pause.height; - - anchors.left: pause.right - anchors.leftMargin: metrix.gamePt - - anchors.top: parent.top - anchors.topMargin: metrix.gamePt - z: returnToMenu.z - - visible: !showMenu - - } - - Button { - Label { - anchors.fill: parent; - - textFormat: Text.AutoText - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignHCenter - wrapMode: Text.WordWrap - - text: qsTr("general long: ") + ((model)? model.generalLong: "0") - } - - width: 35 * metrix.gamePt; - height: long_.height; - - anchors.left: long_.right - anchors.leftMargin: metrix.gamePt - - anchors.top: parent.top - anchors.topMargin: metrix.gamePt - z: returnToMenu.z - - visible: !showMenu - - } -} diff --git a/SnakeClient/SnakeApp/front-end/SelectLevelScene.qml b/SnakeClient/SnakeApp/front-end/SelectLevelScene.qml deleted file mode 100644 index 674424e..0000000 --- a/SnakeClient/SnakeApp/front-end/SelectLevelScene.qml +++ /dev/null @@ -1,217 +0,0 @@ -import QtQuick 2.9 -import QtQuick.Controls 2.3 -import QtQuick.Controls.Material 2.0 -import QtQuick.Layouts 1.3 - -Item { - id: item1 - - GridLayout { - id: gridLayout - rows: 8 - columnSpacing: 5 - rowSpacing: 5 - anchors.rightMargin: 200 - anchors.leftMargin: 200 - anchors.bottomMargin: 100 - anchors.topMargin: 50 - anchors.fill: parent - columns: 8 - - RoundButton { - id: roundButton - width: 10*mainWindow.point - height: 10*mainWindow.point - text: "1" - } - - RoundButton { - id: roundButton1 - width: 10*mainWindow.point - height: 10*mainWindow.point - text: "2" - } - - RoundButton { - id: roundButton2 - width: 10*mainWindow.point - height: 10*mainWindow.point - text: "3" - } - - RoundButton { - id: roundButton3 - width: 10*mainWindow.point - height: 10*mainWindow.point - text: "4" - } - - RoundButton { - id: roundButton4 - width: 10*mainWindow.point - height: 10*mainWindow.point - text: "5" - } - - RoundButton { - id: roundButton5 - width: 10*mainWindow.point - height: 10*mainWindow.point - text: "6" - } - - RoundButton { - id: roundButton6 - width: 10*mainWindow.point - height: 10*mainWindow.point - text: "7" - } - - RoundButton { - id: roundButton7 - width: 10*mainWindow.point - height: 10*mainWindow.point - text: "8" - } - - RoundButton { - id: roundButton8 - width: 10*mainWindow.point - height: 10*mainWindow.point - text: "9" - } - - RoundButton { - id: roundButton9 - width: 10*mainWindow.point - height: 10*mainWindow.point - text: "10" - } - - RoundButton { - id: roundButton10 - width: 10*mainWindow.point - height: 10*mainWindow.point - text: "11" - } - - RoundButton { - id: roundButton11 - width: 10*mainWindow.point - height: 10*mainWindow.point - text: "12" - } - - RoundButton { - id: roundButton12 - width: 10*mainWindow.point - height: 10*mainWindow.point - text: "13" - } - - RoundButton { - id: roundButton13 - width: 10*mainWindow.point - height: 10*mainWindow.point - text: "14" - } - - RoundButton { - id: roundButton14 - width: 10*mainWindow.point - height: 10*mainWindow.point - text: "15" - } - - RoundButton { - id: roundButton15 - width: 10*mainWindow.point - height: 10*mainWindow.point - text: "16" - } - - RoundButton { - id: roundButton16 - width: 10*mainWindow.point - height: 10*mainWindow.point - text: "17" - } - - RoundButton { - id: roundButton17 - width: 10*mainWindow.point - height: 10*mainWindow.point - text: "18" - } - - RoundButton { - id: roundButton18 - width: 10*mainWindow.point - height: 10*mainWindow.point - text: "19" - } - - RoundButton { - id: roundButton19 - width: 10*mainWindow.point - height: 10*mainWindow.point - text: "20" - } - - RoundButton { - id: roundButton20 - width: 10*mainWindow.point - height: 10*mainWindow.point - text: "21" - } - - RoundButton { - id: roundButton21 - width: 10*mainWindow.point - height: 10*mainWindow.point - text: "22" - } - - RoundButton { - id: roundButton22 - width: 10*mainWindow.point - height: 10*mainWindow.point - text: "23" - } - - RoundButton { - id: roundButton23 - width: 10*mainWindow.point - height: 10*mainWindow.point - text: "24" - } - - RoundButton { - id: roundButton24 - width: 10*mainWindow.point - height: 10*mainWindow.point - text: "25" - } - - RoundButton { - id: roundButton25 - width: 10*mainWindow.point - height: 10*mainWindow.point - text: "26" - } - } - - Label { - id: label - x: 187 - color: "#795548" - text: qsTr("Select Level") - font.bold: true - font.pixelSize: 30 - anchors.horizontalCenter: parent.horizontalCenter - anchors.top: parent.top - anchors.topMargin: 30 - } - -} - diff --git a/SnakeClient/SnakeApp/front-end/SettingsView.qml b/SnakeClient/SnakeApp/front-end/SettingsView.qml deleted file mode 100644 index 337b0c9..0000000 --- a/SnakeClient/SnakeApp/front-end/SettingsView.qml +++ /dev/null @@ -1,122 +0,0 @@ -import QtQuick 2.12 -import QtQuick.Controls.Material 2.12 -import QtQuick.Controls 2.12 -import QtQuick.Layouts 1.3 - -Item { - id: settingsView - - property var model: null - - function save() { - if (!model) { - return; - } - - model.setPort(port.value); - model.setHost(host.text); - model.setTheme(themeBox.currentIndex); - - } - - function reset() { - if (!model) { - return; - } - - model.toDefault(); - } - - function update() { - if (!model) { - return; - } - model.forceUpdate(); - } - - GridLayout { - - id: columnLayout - rows: 4 - columns: 2 - anchors.fill: parent - - - Label { - text: qsTr("Game Host") - Layout.fillWidth: true - } - - TextField { - id: host; - text: (model)? model.host: "localhost" - Layout.fillHeight: false - Layout.fillWidth: true - horizontalAlignment: Text.AlignLeft - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - - } - - Label { - text: qsTr("Game Port") - Layout.fillWidth: true - } - - SpinBox { - id: port; - Layout.fillWidth: true - to: 10000 - from: 7000 - antialiasing: false - scale: 1 - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - - value: (model)? model.port: 7777 - - } - - Label { - text: qsTr("Use Them") - Layout.fillWidth: true - } - - ComboBox { - id: themeBox; - Layout.fillWidth: true - focusPolicy: Qt.NoFocus - - model: [qsTr("Light"), qsTr("Dark")]; - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - - currentIndex: (settingsView.model)? settingsView.model.theme: 0 - - onCurrentIndexChanged: { - if (((settingsView.model)? settingsView.model.theme: 0) - !== currentIndex) { - themeWarning.visible = true; - } - } - - } - - Item { - Layout.fillHeight: true - Layout.fillWidth: true - - } - - Label { - id: themeWarning - text: qsTr("In order for the new theme to take effect, you need to reload the game."); - - color: "#FF0000" - - wrapMode: Label.WordWrap - - Layout.maximumWidth: themeBox.width - - visible: false; - } - } - -} diff --git a/SnakeClient/SnakeApp/front-end/SideBar.qml b/SnakeClient/SnakeApp/front-end/SideBar.qml deleted file mode 100644 index 1698007..0000000 --- a/SnakeClient/SnakeApp/front-end/SideBar.qml +++ /dev/null @@ -1,103 +0,0 @@ -import QtQuick 2.12 -import QtQuick.Controls.Material 2.12 -import QtQuick.Controls 2.12 - -FrameView { - id: sideBar - property int openHeight: 10 * metrix.pt - property int closedHeight: 1 * metrix.pt - property int openWidth: 10 * metrix.pt - property int closedWidth: 1 * metrix.pt - property int headerHeight : 1 * metrix.controlPtMaterial - - clip: true; - - property bool resizeWidth: true - property bool resizeHeight: true - - property bool isOpened: true - property bool chainAnimation: true - property var source: null - property var header: null - - readonly property bool openFinished: openHeight === height && openWidth == width; - readonly property bool closeFinished: closedHeight === height && closedWidth == width; - - function show() { - if (resizeWidth && !(chainAnimation && resizeHeight)) - width = openWidth; - if (resizeHeight ) - height = openHeight; - - isOpened = true; - - } - - function hide() { - if (resizeWidth && !(chainAnimation && resizeHeight)) - width = closedWidth; - if (resizeHeight ) - height = closedHeight; - - isOpened = false; - } - - Component.onCompleted: { - show(); - } - - onHeightChanged: { - if (isOpened) { - if (height === openHeight) { - sideBar.width = openWidth - } - } - else { - if (height === closedHeight) { - sideBar.width = closedWidth - } - } - } - - Behavior on width { - PropertyAnimation { - duration: 1000 - easing.type: Easing.OutBounce - } - } - - Behavior on height { - PropertyAnimation { - duration: 1000 - easing.type: Easing.OutBounce - } - } - - Item { - id: headerVal - anchors.left: parent.left - anchors.right: parent.right - anchors.top: parent.top - height: headerHeight - } - - Item { - id: sourceVal - - anchors.left: parent.left - anchors.right: parent.right - anchors.top: headerVal.bottom - anchors.bottom: parent.bottom - - } - - onSourceChanged: { - source.parent = sourceVal; - source.anchors.fill = sourceVal; - } - - onHeaderChanged: { - header.parent = headerVal; - header.anchors.fill = headerVal; - } -} diff --git a/SnakeClient/SnakeApp/front-end/SnakeItem.qml b/SnakeClient/SnakeApp/front-end/SnakeItem.qml deleted file mode 100644 index 6614e09..0000000 --- a/SnakeClient/SnakeApp/front-end/SnakeItem.qml +++ /dev/null @@ -1,17 +0,0 @@ -import QtQuick 2.9 - -GraphicItem { - - Behavior on color { - ColorAnimation { - duration: 2000 - } - } - - Behavior on radius { - NumberAnimation { - duration: 2000 - } - } - -} diff --git a/SnakeClient/SnakeApp/front-end/TextInput.qml b/SnakeClient/SnakeApp/front-end/TextInput.qml deleted file mode 100644 index 17ac7c5..0000000 --- a/SnakeClient/SnakeApp/front-end/TextInput.qml +++ /dev/null @@ -1,47 +0,0 @@ -import QtQuick 2.11 -import QtQuick.Controls 2.3 -import QtQuick.Controls.Material 2.0 -import QtQuick.Layouts 1.3 - - -Item { - - signal close(); - - RowLayout { - anchors.fill: parent - Layout.fillWidth: true - Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom - - Label { - text: qsTr("Write you name "); - - } - - TextField { - - id: input; - - Layout.fillWidth: true - horizontalAlignment: Text.AlignHCenter - - } - - Button { - - id: ok - text: qsTr("Ok") - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - - onClicked: { - if (contr) { - var rec = contr.getRecords() - rec.append(input.text, contr.generalLong); - } - - close(); - - } - } - } -} diff --git a/SnakeClient/SnakeApp/front-end/UserView.qml b/SnakeClient/SnakeApp/front-end/UserView.qml deleted file mode 100644 index 848d3d6..0000000 --- a/SnakeClient/SnakeApp/front-end/UserView.qml +++ /dev/null @@ -1,112 +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 - - -Flickable { - id: userVewFlic - - contentWidth: userVew.width - contentHeight: userVew.height - flickableDirection: Flickable.VerticalFlick; - property var model: null - signal tryConnect(); - - ScrollBar.vertical: ScrollBar { - width: metrix.pt - } - - Item { - id: userVew - - width: userVewFlic.width - - ColumnLayout { - id: columnLayout - anchors.fill: parent - - visible: (model)? !model.offline: false; - - ImageView { - drawItem: "image://userItems/player/" + ((model)? model.id: -1).toString() - Layout.fillWidth: true - Layout.fillHeight: true - - } - - PropertyView { - Layout.fillWidth: true - keyText: qsTr("You "); - valueText : (model)? model.name: -1 - - } - - PropertyView { - valueText : ((model)? model.gmail: -1).toString() - Layout.fillWidth: true - keyText: qsTr("You gmail"); - } - - PropertyView { - keyText: qsTr("Money "); - - valueText : ((model)? model.money: -1).toString() - Layout.fillWidth: true - } - - PropertyView { - keyText: qsTr("Record "); - - valueText : ((model)? model.record: -1).toString() - Layout.fillWidth: true - } - - PropertyView { - keyText: qsTr("AvgRecord "); - - valueText : ((model)? model.avgRecord: -1).toString() - Layout.fillWidth: true - - } - - PropertyView { - keyText: qsTr("Snake "); - - valueImage : "image://userItems/item/" + ((model)? model.cureentSnake: -1).toString() - Layout.fillWidth: true - - } - } - - ColumnLayout { - visible: (model)? model.offline: false; - anchors.fill: parent - - Label { - wrapMode: Text.WordWrap - Layout.fillWidth: true - - text: qsTr("Offline mode. Your statistics will be frozen until you login your profile."); - } - - Button { - text: qsTr("try conect to server "); - - Layout.alignment: Qt.AlignHCenter - - onClicked: { - tryConnect(); - } - } - - Item { - Layout.fillHeight: true - - } - } - - } -} - diff --git a/SnakeClient/SnakeApp/front-end/main.qml b/SnakeClient/SnakeApp/front-end/main.qml deleted file mode 100644 index bd8e027..0000000 --- a/SnakeClient/SnakeApp/front-end/main.qml +++ /dev/null @@ -1,40 +0,0 @@ -import QtQuick 2.12 -import QtQuick.Window 2.12 -import QtQuick.Controls 2.12 - -ApplicationWindow { - id: mainWindow; - visible: true; - width: 640; - height: 480; - title: qsTr("SnakeOnTheRoad"); - -// Component.onCompleted: { -// mainWindow.showFullScreen(); -// } - - - Metrix {id: metrix} - - Scene { - id: scane; - model: contr; - anchors.fill: parent; - } - - MainMenu { - - model: (contr)? contr.mainMenuModel: null; - anchors.fill: parent; - visible: scane.showMenu; - - onPlayGame: { - contr.showMenu = false; - } - - } - - NotificationServiceView { - anchors.fill: parent; - } -} diff --git a/SnakeClient/SnakeApp/img/Settings-icon.png b/SnakeClient/SnakeApp/img/Settings-icon.png deleted file mode 100644 index 4c1359732c7d1d4acc3b128dbcb742093dbe59ef..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 28236 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 UIL;ejJRp!;8n@L;Z`y|a9|ZtjbN~PV diff --git a/SnakeClient/SnakeApp/img/asphalt.jpg b/SnakeClient/SnakeApp/img/asphalt.jpg deleted file mode 100644 index cf566c296dcbc7afd9fb51c90c6ae3da3e86cc50..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 190807 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Ék>HJt3sMvY02k> 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

M9hPplmrsq;HdEPQa|3 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 Jb+7(={y)_TpcMcB diff --git a/SnakeClient/SnakeApp/img/box-texture.png b/SnakeClient/SnakeApp/img/box-texture.png deleted file mode 100644 index 9592e5fd6fdf3756b55f3e6e9443df2c5313e385..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 80593 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ɓKI%M+bH^&{JUZ2S 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

)cukA$@1N`V|Yg?quQB1arjv4D^w<8dDrP~8mk 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 X$%%F$HzUo?00000NkvXXu0mjfa*mZe diff --git a/SnakeClient/SnakeApp/img/cogs-solid.svg b/SnakeClient/SnakeApp/img/cogs-solid.svg deleted file mode 100644 index 9cc62a7..0000000 --- a/SnakeClient/SnakeApp/img/cogs-solid.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/SnakeClient/SnakeApp/img/defaultSnake.png b/SnakeClient/SnakeApp/img/defaultSnake.png deleted file mode 100644 index 93a3a3f3078672c3a96f5df4cfbcccbc30410f1b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17886 zcmV)vK$X9VP)EX>4Tx04R~2kg-a`P!xv0RIws;QUpaIgN_9kGr3fSASlFG!RnMIDHf9$l9b{b z_$K-=9R$G_@C_84{cm(|FpC!s|Ht8+|G)P_%TB_yoZp2ss|wfe4K4>)cKeMsTXfiA zJqXLZ=XobIp3he-qc2_K)jap-S%~5?l+ILHm=_gT`(kHW<%U(P-uC@N@q^fo(kv1` ziMOLPGHiDJG?|1yp5`{4IJ-DEebpu|$DHC}Gi1V;go>^-Q|AbWJ*i7Uz&$0QG$B@R zs+o!#Q7I>v15sb3+ce~D)Ons#hVmH8%Ou>9%G2aw{`Y(BVzu(p{^r`xj;$c`}y6Uohhca%D)Q$(?b96+q5U;AjDktrZ|?#j$uDK_Vf8%ek-as?3NZ zBThtSbys)SBOj5O=Um)=-M&?sk@3ZOe}@<_>Hb^cS361&OtWp;J^R~1i+`$mrG<_%Dv^f-eRstV5><@QG}{#3)j!-^MYK*=ARx7gNw8W_}o0#)Ieqc^$l z87|`q#lV$?6Th_yav3;Mc&ZF6FZnHi5>;!9k{Elw^^+p~#+>0vElVL9yp)1b1_Xx< zZWaYp&3ld@fBeasiHY9^&2Z;mJ!*K6BsT~=V{nq_$Z+2dj1naPPH7?!pakIILAXW8 z#g+@vDylsPl`FozlXE0ADGLJ+15O#lm<}mW&)ldDD`1kx%_vdB16axD_Ie@dSem)n ztMD8u^uYmsF(Y|5@lSWs{Qw@wR?Y{Mhe3Kji(AU^#0R}qz=PmP;i;laoGsu1#tXb5 z-8(8r$us@{ivn9+ik`)!01^kAgcP1C56TO^Mcs-!stga-IizC>eVCnZ4&I=GYXvaw zM`u;~03}3sLNcb732xGwRJCWv%UP!W5VIG3Rp}R+d|;K^Jvh_Mm}=g$Gjo>MGEjrD zLIJ=@Qx)qX_bwg`BkLS8#v2fvti6GijOlk@sPIve;I*j6ipM$Gh4v{C4y(LwN_%F?c?h*O|A4t6OxYJZHl-coF65JsfOsFj%$f zZMju{+qOO0-~<>3g_y6Q=E}mJ@%}9ID_ao1V1?(bCX=ug`5xX!goC5SLIkjA1!&?A^ zRVtFS$;>@9^tKQ0*tS+-gSnj%@Doyt%Qz+hnJvHxIV*UYcGZ8 zkp_lOr)+p)HK4@?7f3fv0u?a@Pmz*FJZ4Mtf$v;;u4vUu6R-JazgOcnQ-5=Nu-IDV z!fl75W9n(kO-W@}g(9&GqJ+Z>{CNaZSGDJ(kNif01u9+3-+bM%Hl|>SmOy8PBJo(R z;PC@CBWO|8o{yf#Dt$>mVV5Q+eW`Ze4;Mwge!@>*|MJHQ&(V$A8vtuK)LK(JA$W$~ zp)Mlnbf{*X0-Sfh^Lsyy zuqi=&%?i&!gxG|-Fvsd}q@BjKQN(3q|t)ZQs z?`heHwKE*MFeM5b>S=7S!V>`SoZlyN!pwN!&|Kk39Ou_yphTFJhHwWX-mV3APJFG# zEr4r&4}&!b7GA~^sZ7VXz2+d28{;86kCz`=v~B`Z8Tl`F16@YsUkv4RGJ zhLDm={^L)&d954V;7SO>Y7CRiuY}8(K`3Ex3xYw3w=f+7bn(XROMVBIqAim;I8}!6 z+Xw}KDv^oQ0AAvUlay=04lyTbQ4OL$!+V(2!rdlKHK;pdTv)jF{KaqH!hpc2rGwMr zMyb69@Z16&45JF%1OOZy41hNvCN9`89W@0z_<$ZIJSxy2#%%>FT!DeoGh{`>6z>{@ zsw2I(aP8S{LzMAEH~KdxToClsssI_BeHce<+l+;yT+ndvP(f z*rK&3u}3+{dRo5sJ;})(CAN=;(7$QXeNqB8}9w? z7(*#m*hxmSt&@le)KM8<_s?dHEpX9H7qeV&u2P0`dW%rDG@RR;Y#Ba!a^!--Iq=8t zeeH?q51&-<;yW1>LjLRphBiUdpqqZm(`6_8@C1YClNt^rn)x{=i~=MbPyPZOxKQm$ z9BVy7VtIYQ&$~`ThXbXzYe-Nu-Q5BZ+VoscAS!0i~mb9=3aC^05%_WjpB zyxCYfdfJm*nD(@Y$&}o+CnUp1*klGy;2A7{Iwe}h-$W$G?ppMFDXEvwU&qPYPKq&V za7VMO(}cV zvVzC;8C6}2(Vl@^I-X+r-*rwS)DN#GrL6Jzsi`i_|9&80@%)S#XA9Au#Bt3%@*J1j z&bS%Gsg?Q4PhXo9Mj7H#4VwHfNvT|1t8RVssDqm#8J`OVRx0{@>J8J-;at&n! z&b4$~x(U!V{PM@K6|Wq?ybU!sHC9+j1u)=Xdo=%hfVCTq-LLwO2!=R@y~;L9bPVh0TZ?KHGNf@6!iLnAGBN zjSmXXDc__yqoO2-bsetiHB?Pml(-#yr3$82+x{_k8&ghvp>MnZDoTNLX09bGtlt& zNm9;oe8pKHW-Cx%aG03+gOeta>GTt2?=%BJGt?$Im{C@WiN%w2N8NKAd5??0xd3<; z;DK76E_?jbT-_CFl!F-2Bptf-NGlb+&rr4dw6kIXR46Y@I?WuO&$yNoFGsCoB$LOJ z<-Ok0Fax7v-1b*rk9DX2_mk*R9=Dr9<9cyC1DwN%2Sx{H z>e)Q{_jjE{C}t}KaE~4;7u~s=4LE=P?GQIoW^kt#$MXD=jG~-^Wip!4Wd^DUJx8uH z&<0a7Z}T|JPH~rP2T7n=YfmrT6gl4Hdo^q)D6xs|nBQ}qz28iil2FM|yev*$09HyQ z=I3?VJB+;ZGi~E_9HToux~WB;Ej+K;3$IWPHA4krO50(DKYTK;wPqst*0h@LkHcLi z$Js5JBLP};qCIEpdlJXQe;!m-1!|$5ynJSIuHGm0HvKanYr`-fxud$c=GkgblJ;53 z0-RQ8r2)(koY8dOXJ?Wt3Cnz;Rtr-8|`;YEPdW z_*^_tg96WHtTRJer36rSx~aG|hcyp*_5h5GX!VBq0r8nX?u#;!F{ zZO-zR?wg#=kit-tdp`Ns0*u@IZpy;VGT(W~=<8!VV_r_dq5Wl~Qpj~W@Nt&LZGI^5 zz|6tfjG=H?VmUD%_)6h95qPT1%1$^4&rk+WU_4iNKBcR2ljpPFv|ic|2y^F7e)a^E z-gc%R)b||9_?f**x6BKuxjnqY2%LQGE@KR{)ShK_SG0sdaL;9sy~i>ogoX$k-8YZP zH($9dAKl#L2MSrrJ~mZub8=!WlaY^%*f3~1G;L>T+&<^`YTAxy^7W%X^IAc}5HPX~ zMydg680_*&XQ(}Ip)#IM0hTb5GL8U_2T?5$<&KY$8N$;kPDX`jA2V$XZhw^1U6uz7 z-9Gw?XBo4wijt9ZN`Jol%Rl9Gr#mufpGD?)!m6`kz8U+TaoD)}p5v^1KfdSXjO$%{ zpLg%n!gc8%D4vNm}KZ$ zuJIwORSdhVvC|Ct=t`ZT_B2o#Px>nA`vAiCpJsFr32$+e`|QJ{pP}}&oL>>Za~<{qpPv!>iLlo4(PwkmrBe7Fjcp|} z8O9&(^&u|L^Iu_0x$Lq&ePLzl8$|qK%v&C0^&P(ZB9EQcZ=h z_ZfZeO2NQ0{Gjlh%S|l-pu`xAN^{)xB<}x+(6WSKbPAS4jy=Sk78xAF{p;^p!gHP7 z6@@;I<@lfdZ`&G#VpImdu9*=Q1J6HyoTEk|0ObMzI)rKK1)_{^z8dR3fBEC(x@jHU zRx`Rj2WsRvly>g^XUTPfX!vM*C1)f2>g!K`I%iLQhGLo1tgL+QFtFIoI|E9*LIoBE z*mg%`r_WbjmwT;vRe1JxTk+)fy|f3PzMUKjgxZ&R1N1J*2NG3tKMq6i>gNj3*+y=8 zurS53zLJLnu%0;&uP3IJ3|(Kr2Jm$LE-Mr$<#idW*#_Na8%zx8@w^7|G^XDCGoWkU z^=!3-)m&pM-@n42XSb>|)}FDs$z-z3B%^YGb#^0tx|c06F)T`;7uI;dqXe)8NmTp| zu2|tY9WyICQ@aME0I&tma4Q|SYpSUN^YyfN#c=93>(fl&Yvo>y#LI>lEg_AQs z8r)ruX4+^FxX)|n^m2;_6&YWeyI!# zg9=M((~k0tZ={&Oz@)maZkz|~z1ke2<1^Nt*RaB*mZ2^|g^&X^3!B&Uo;=-r9H3N- zk$?FnB=JE*^FawjD8kT(YXMruu!aUHsTdzdb(P}yX1^k{SUV%DT z+YOKRd}a+#;-Z(C#T{IkXpN=Ca1T2mmlIc$E?#kKg8?US@qJ$I`F-A<8|CK%Zj7AV{!#Hn>e|ghBdu z3)C>6(X-OChv%Ai6S&H-0nK9C&7P8%e1rO4JT?|G3=!rM4DSFCUBLvFtG5j zC}2Q~4HHFqLlrRpZMb3Y&Mj#s5`c5}-L$o}%wO!Eo-QRr%iHlA_ch>MQG7P~YM0Sh7 zPsA(LqAg)!^3pa~pXq-V;0(cuW#ztO{?lY%7S^sdC5cp8={^j`+y*zQMGr(5&b5v5 zWUN@!@On?NQ7C(j0Ho1DEPovUCk?Q2m_!AmEE;r7A$2wzdlh>aWHND9UP znbOIaWj(?Y+}k+2A!UUM78?+2xM&}uu^q3*3LZ5I)F`CdD2;j$eF?-uhg|*n#T~$w zF$;h;Mp->7Syi60;caqaOly#b5rDQ?adT#sH%ohPc5p(Betc6Sya6=;k3zNRp4<}C z6+DXM9FXYA09c0-KnaiQtVcd9(0#Ey{eHoAa4Q5uf_~7X%f3A4ThWt|siNdQoO7%Abt&inE09M(IoGvrq5rKM7$e4N-z@uCzjb%IQ^S$T9S<< zU;MowiGs6{??3&QzpeljLMP@YvO)`u&ClhwDNQg9Tdt6fjp$)1NDn{tsZg#hHg(o; zlN08*2GKVqu(ovXuMCHyY#IlbS?XgdWu{euIUZ0kId1{{fE5#e|EWR~06a1I$ygN& zE<7P#qmm}v`EkF+lE5O(&|IO`{OIJYpv4N)RwAHtBxYox_y{e_0K!qkmWjXnLN~r@ z&+O#|zncty!f6ux>iyFHyNv+Xc(1xt;hD7u%JoG0KTkJ`;yAs)n;XUy8h8}KquW>! z3Il~_whPe3_}3f(>eFPeNN&CVZumZ-Z&9IOV&ZSUQc$S&%t*fZ>RdjP48~f0Q}sQ^Gv%Cwhny}7;uwhl)Yuk6=@!sbeTSSAuNz;VS;qaPD&xgWuRwk~RwvA!s_rBhrQ%xZ0po9WdjoV>NTn|iw zL%we*L{AnnyDKDNShkCWhZBy5u!$@a8!p)J3q9`@o_)!$zQ*FCwgA$M(HaaAgVspK z)ClEsL#gJa1i}Hhfnj39#IF>nYTR}$-+l3~{(Xp5#`MY@i~fcd?KxF=b|f$PEg%d8 zR&{BIer({o*HMUS++HAWXbpf+!lS}U7pVjBLIQ075L*t7ZN#@f(zQ|Td9qybE#|_B zo0I;$xBaB*x5N%F@q_ABh39Dibtok0p>jDy2@b#tPHME;Och2-AP6?oi6;urjN}>L zBnCW{Zh(1Ti^kLp?@coevVzAN??~aPazI}38wAoYg=jY*4Z1SaB(=*NA~2gu-x9vX z@9wb7(g%%tJR(2PufGl)Jt`OL0U*u$-pVMV=3fHxSd7~OgbEHo0V}RWfl%?gtXVRu zJ)e}4>(;C*XuDY!vJ9pq)t*mEMUi!#VT5-;Wo%vi0mLN}|M4fPJ#{;9)SB&Skt*Y9 z6#`N`ov@l|H>$$(q=kx&Rw}v33XBQ{1~p#Hj@dzt+arak1h55QbumU4D<2JZr~qkq zy8+Ft6koOH3G#~H1F+cXQe@$O@}8b4u@x;koe@V0&#ui4X5}NwKzlj>79^Bq;qx^< z>_K;f8&Y^KOg60kXMWl<1nvsd>F_l0uoItgs=nvR5@LiTEz05R_IEEM2G~+Ta!i zH~~|uigJ{d1oWn5>MA@h2~e;rC7Bx-hx>e2=M@$4p2_p+x0*NR~ zB{yHyfB`rVPem)~PP!PPE9q$|0aUI23zd8%)=V=(F#}*G0a1nL#j>S8d}33xRM4L) z`T3q+czPKg1sE2@Hgkxo@7dMk=L&>SvY;jNIr^TVtv)^~xiC z&mLsM6?`k##%kVX@0-TU;L;iN5*Rz$!Q=AOV~!fv3%+XhF4S@A8V@Yj9{1rmaWAXHVb^{7}`Ny~__& z(~G^uwi1fa<-WPU7YMRX#s#?0hA+ZFx8%e%QfE|@O4!3k}%0TqT?0*Jc+ceHy!I`75{52>*cr%h7Q|&pXhr?P^l&4s@6csR10X9Zeu4>OQJse^J7^N;n zX5yq;dJPhAUcrr^%T#;j;OFQ=$V>{0mMEf9+ISS-TC z=tz%3nk^kjY9OV%cCzLb3<$*Ef2s%fLgg8MxaR{!mR6GbU1*+kG;h?wzz;YaLgAUA z80KVNDQj*%=5CnfvcYb!5ld<(WhkDQDgrz8nkif=qu4WPCi)r`NQ~V6HK@XK0`d{RZ7~-yjFvKtA{*Q$xH5QvzEFkdghU_K zXe*Buw#mV0Q>FH+LG_7G&(LDh*zG6=u1S;V2p)t26$~8p`JO5h6Hktq{_qJ}b6p5c zhBW3z+do6=XOKyxI%?v?bw@2alcgfJ4lwOe!>RV1xRhKANUM8cjCMCnG{;EJe@>>F z*P7o8WEDpK_H@>%_MEs>6l#tffE6qNj};gOMmqm3ingx=LecupfpnVpS>9+k{&pzf z@uH^_PPOOEG6k=* zlFt9QcS_Nf42K$CebBR{0D}NjC;;qG;s$-x;;Qys!b#78XB2 zDjmyn-ll1!4P0aMS{PUBC0WBQgIL?!+7^g~@7ToE(2xp%cN7yeKYh*85N_e&VF54- zI51WMQX>$Kkzd_Jp=H5=;m{>@wQ5h52e(Eb!zxkTGl83Oh7zouG)aGkdaUmBryhJN z4+v9Dj+p-D>uB`0H=;|a1qEl+pW(>rk}^!Sr^=CX%@t}G6xgNGK!^#fvcatciUM_5 zH!)m=r^<;^u!n8wOsiG9Vu*U_2rXeybW%m6@KiZ_>yW@y^QO%T6v>)kg{MjmAk{t8 z?gxtOioSzB7KNuuM<8wIOTBz<8rq7*`KSeeiWHtI*?_dsC512xgu(^dD`_wb0BT6H zIEAN5ejtsclaVru(|2|uGuh&x<;y(K(c$@wKO8(wL(8zk3R~@XnxwI700ANiLvNkF zo4cYO^_u_yAOJ~3K~(k($&~^%*0`m~!Sk@Mg7o-!&lrjn`n3Xea(c7`gtZ|Yx^6Ln zq%gsiFVdd_!?WPO2lSRm3YHOx7osW^rjFzAE}l@9a>hmyb&4sH>eGwknJ z>R6z@0H9_#U=pv{A)KcbEDAVmrRW-9c=(jyt`cAwoPH<7{%&E}uvMpd60#$v4<8%s z(m>lK)R9)GafJ}OHu&RDGS;3eu2O$oG-TsPN`3o{soNYiZEm@?9;Foj>z8FzrCU?i zr11yym-bzrze{_DXQa{S;gwU@VcBsDtV)mm82jYhH0{gfT-?sOz}zxd?l#29_(E}h?Ld*1Hs0iGp$7}Twju0EE#U4cR^Kh-NlCn5!NGHJuJ zqgGsEW`6gX36_rG*^K82ZAJyGOm^ztwB@~Oq!~dGCYA&i`?)4xP6ueG z@FWh=*%CGS<$p5=n9sv#w~#Sq1?Y6lK1MQfiBf`9QF-Tc##8+s;$V>HXM1(p=x2*<ewSn50W}DuWeXFMPyiSx#)?!q z=4TNsDkM^Un%i~pQDw3PXBbmM{8G)_iO7zaSYq-O)+oU6Sj_;OA=q{LeO#zL4RgkI z9wE?hSy8ge&{A@ZHFm9_-#k(+k?7=* z`D)ETja8;*t)y4rTZ7s?O7%h~BQ-IF?YW*siC@5p#cB1oXKBwX-ob-VVwZXk@{&L% z(NIdnI-?aVKBx|zj=#q9@I5WsHR#6^oSXsA6^8<>hIlu}WO6WX!?MJ@Q~axeqUp#L zZ)c!A_uatb%T7-=Zom1efws_pA4xNxNk!))_i~Ffg zaM4aU!**B$Gti#lh*3JR>Bx>s5O#1V=3our6?Y6z;sU@HhKJwaRH+|^b?X5SF^Z}7`Gk< z6?On>RO*FJN{4P{aUTxrBX-@9JJT?v3bLL>M|&6w;ZUO1T>UA5 zvyibhm5wW%(iZ19(8ErUSN=H4x+me;P-8B@WC~?}3ed@zxS`Cio@B7n!avE~XP#OB zhMz?u_$gq9q>%w>9Ctz{ZXlfF2|_dEZ#R6Q@41>iynzS7~OWFAui4{FyMI|L3} zGXglR0I?Z##2C8PcLl&f2m4OKm!rs!QTH}9q+8$fI1A7`WG(=4Vo5zhWX$d9$!Ofh za{T^%;cIw_sxgS4D@3!GYj_Y$ilojZgv z>wtwhl6*pCJeg8uc!=tR9bP_Csdi8iT{Gh<4Tm2CoJOh=Ic6f$&j~buHYZdl;3df5 z;5Ck$y*L6&6qrV)fm1|fcdGV`bYC0Xj(Q7iuJ>Tv`hi%(<2!~XIw$o+8YaqKD={z~ zR(UJT5AGE0`Lo{}(I8>${5U0j*I;twh>7K+rWrz>Ls@48pvH&ewP&M~`jq>X9rR>#&116W9byk%`?X7f=;eqC z0Wt%CV6`hWbNv}8>w?X*%a%={sfc?>DII|4Fp*jU;~F0%659op$cifzAkqFociuOp z&xAj=tyj@ zVk^{}K#4F~NfRv@8@Mo1?`Fiz&F>1S^%Wg!+zvZIB@FoMS`UR=xVERm2juecgGW3a-F)m(pzOrFbpRL}06Rcv!wL|8|EYo^AE~JlcWtWhY#sSS z&QhU~5)$3@1IAw1SeMd}rm2yelX+XD;*`AM`QhWuKRl{Ei`4ls1eecP7QX2uEJe5t z{VRa<$b|JXYUE}mpTDkQCt%z%KK|1a+B0;0^rJ!d=Sb10$^4QzrB*^vr~4)V)u6e^ zG)DD4lx9qd@&)e@2`s6H(*dmlfpMjxzx^^;3t^^89|w|Z(0ugL6u5`@seKfhaGHX( z?oWpZ{5*#A70h5*)V;BaKf^oKp`**~kFNeSk%NRDfv4g7!xFlLC$$Jip5tu>8#i{g zu26TbKSK(~K1$H9GSqXPE<8;eKtYNlS3GM)V*=*;6g-Kjocjk&&gh6 z`l(O6wtej=8f{j~!vOvKwZo>Ddkq}>8pj=9t|wg9mv&G1B2MP&W5ZH<-Mr$OeZ=;H z8E?TLINTh}X{o4r+ukvr9))KNk(50V4;mRpnBUZ|e(3*Wx+c(|=n#l`9l!(oo?-A> zFmw9?CuM481eR{QR|!lo7kc6@xed@E5aVwAdk1HJy7N(w^cTOWAH12amng@5%2a?+ z!?bFF{1Z!e8dOOEI+{EeK1d_aayrwrWzRINWc?8jHVK>!;!45#N&%<>a12+PQ7b zgN*;X1UlDou{yp|D=S;5kvo!pGLiB*L;d*>7jG-?*?h}Ay#0P@Lca2z60v@VR~(F6 zz@vtN;Zh+wuy`3dG_^ye1;|Ja*$+H%XVd4aLCZUA4wqlCLx~!|N@kSSszV2rVoyiq z2vU9wo+OC`kN!)b^52&`TFV3N%D^QV&a{KaDsCCRQiu*D|KqdGME2f6pE)oknAR-n z?p@#bafAQ%*+2Vc3QN<>3H2Sh%G{v zESmhWOs@;E!m(g*qY&-ii({KOZz=V55Qgovn@)7XojzEOzwV&LW`{?RMmJ7LDWoGHj#@~Nw(L;>z$ z93qR0u?2y6tq|?dznhZJkl^{d&*Eh4A@+hpfhlh~rVa^ClGcZF8Pl? zQHWi(q7kMU!|F{3s_n-drU;9Z_3HQxKdCu-fb70Vu+H*%f zMGS{9Hf)a@cW~2*2n7fgO1PA@3|g-0(yCdH#y5E<|Xpcp+XeH0LOud^3>dxi+)aFJU|^)~Zs zo?7#+bxQWJeg^Iyxz$~5$#*{Epyx#`=tf2XzT?w|T|p1V81t6cE@_juH$E^UiOpk` zVCHUg3#bQ4+j>B(Zvc2PyQ1$cJx}*(_Z~|(X>s2&ogW&`$oD=UjuJLMwXLUP#HS5X zgYasi-~?*9C-=YsHM}Nw$)?&JWt0N|UhxOHnc>4Kn4w&8-CE6H($`sDY2$So0W2X} zQUz+PaXaBBlw(_7pv5M*NA~``>mKh$=E@FWn1z6IchCgQ$2V)6w@q@$Pu8SuKY={q zi6=s%2koq4gi8g!`D&i<^z;fI4m%Xs09a*7gB8MgcU42UQ8UES!#1M#AM|u zTK^;dFj6hgX4b7}h z5j_l81Z) z?Ohz$pInYd#{&cFkIHs``#rH+Y+j zK!9+wkfYC_LXIOtZ0qA$+7mEr2J4P%M#6_p8Tt*CaQPL#>E!G;c!oENTg$My%M1zU zLZs#YeDaU~?reBo@$H@)JNyabpi?fRyyUltBwR5gZSEA}nKazcrM7Cf;Pnf+JcJeB`Wb6sB_*{l_h}lK3`H^-sdq^;S=x- z#LDB`VDPYFPq~`7DyP9S>Zv@3Js%epFi%;>U8TiO*Paf*3NfjyL)=wP*!;W(uu9aR z`N`jZcFH01pnSw{Mu6uEyHtVeQKG^Xwrb+4oUA+Z1n034^&^zhczUau_!5YzG!LqB z+@>awu-Z}@O_G;zSMUtKWP#ACJKBl#G&75eO0JI3{-BLxBPmD2vn|6@S+y%a6rd`P z@7DZGS`vV=D7Rzx@KHsz;l+&92$m!8%vEx+CF~4F-mCN}n+%OvmiG4$W-Yt61Fm={ z365f<4uAr6O0sAkROPV^U1mDg`Sc{=(PnxWUm9majF$%ul^~i2RXHRpuCojUnY|HH z$Gc}ocZ@NGfv?3V&|Cnye3%uBosWds;EAD?Cm9E)U*^Rvfr zy{~YCI5vibw3^k(RXJ}n4}Wc`9sZQi<_Z1QoyZvYjYyJiX{shtnh>C(1l6K zuEmNl9(}-53dIctPhicvmf{|RDy%VNI5E~8NA0UJH?ua-y_zh^rdt}6&e`W@$(GjX zzw-!Z6(<9i!HGsPo~F8Km!mn6isc+a04B%C?YSDmT=tec(gY|5;O@lfy!@>}Tqr~r zAlDqC4o&X8Mjp&U&DcjmC^G!rXJ@_6`TIEb)#YgEtC2f@3B=sCmm!N?yI|*bDPN#H znZlfd+a>EeaSom~5Hg4S*7KM!vHH?b+6#`Puq>(W#}9yTkzvE9^3~ z-x`La%P4p*^rHjOW`6pUVPIjf0kN_x%n_U=7zGS=$gzQpWrC*-rSNqAeO`DWYxc-* z{&2frUj5MdfwMp@oE^E+Ovfv`Z1-Iph2Bz)BD#Le0sWJ@^`NAytEs+vu4R>`~ihfjO6JHM1H{y zZqyTZGNA`J1(2kYou4qY#MZ zF1t?Lr_NKBo^qt-a?)E9+Q>aP%?<@>7`CX?(9JPszy)@&a41kA1YFt_Hu=iSj@-pQ zJiQD7S_nkKPmpoxGp3=IEEWMfLjn7{^lzM$!JF<$0?nZ7>#p3+(YL~0f!C#+?fT|tD6{x-t$Dx zzYxid{-}k6(Gg3d_?uB<#*vZJs1mBq9SA^y8!!wA z79O=&G`UM;=ji$nA0$O-cq;q4kO38K?)h*w8W0=`)Oe{(^qtBT-(sK4JZ7iOL@I=$ zwbi|aHAqm*Qz0iKwceC6Y@@CBxO3}tHUb__e)0yyq>5d-Xum5hIi0k){;%5uF&Y z{_X|8Lwio}l;PQc^a?jRyzmTPvqAw6FBQ;JlaPd4W1BQ-KPk9@%VP_6$-^6Gcv9Er zCz6rlG`f4VuW8d<96#yjzlK8%f~UUTV_4sgO!Dv=-*bAqIz|&$puoKlYFxNr;*G|4 zA6_>mt^ha`lYjmmge_{x(ar*%fTKd*G~d}6N8E)xo*h`y(J`n2Y_VoyVx5%MmXDa2 z*u%hKm5yjT;pbmUxYP8=x-m-c*NVB7vY4X(8K<)~VU3s!Xu2#2B`WQL0bsb0P+Aih zG%%9shBD9a)dmi`-k;UTovu5o zXo~^{1q=wG<9z-hPb0*Tki?7&gPQOT#KeXT2krXZ7rEcbFMdN@vSnhALIPw4CRsx? zlc&jhcAdd)0B~l)+7&M%Xw7SUSV-WclpYx?v#i=-rI=4`;LI8MtQ+37LSFHDeM`@f z#Ibo6y0dvQ1Uo=TC@XjZulNIMgc`O&?mL(8af$lZ!*IY3z@Yq7*)c{NW-*?Mi5D)YOj}FtM*?D>)v#?3*>Mzl3ckz= zHA=De3*9d&g9;1tR0Gm5;brKaB+64a878U8TtW_1B}eTU?Y7vF+F#q)gtTX)L!0sQ zE8QV8of-hxXN!*;Y*`>gr#nF;{g$#w;*Oc$E8 zH$-AA9t_GqE=n4@RT;(q3})__#HkY)9>(-a_ln9Wuwd9xS&b*7nwn9pKFv~W=%H0q zF4L4Go+jX6;8R`KxI?feWjV%ytg$k;n8f@ImFf7KPD&#o2mjavsb)$G$n+dxz-cX} zN83wKQ8{0G+62ouQFN05d+`M0E^7{>PMvB_mCoQ9sB|{CMPKt$76MP88LCu(#0OPT zxkO@*P%&UP=gf@TMgepMi~2l;1*}ntFRG$);hw@ZEb0-noU_rM&E>DLQ{Aa@p;$O+ zWE?wII}7a@g()^NtEikW4nPHibynbCDv$Y`wQ$xV!x2`q zP&_+gvO>`m=3WFIyx^0T3Qm;++dj~j#uS~+a=zTG3R+hTAwr3Sjv*H3H36e?PnzkR zV>DVXNP9L~bVp%?xNni|*9uOR1KWNJE6lwA>$6-Zv(B;|BuqdHg$o9?B%4)K+5n9- zW;qW{o@LN;M-{E$P{N}I6r3veq(A}SdFB(%XWdM>;Vssv)VNhS2+;iJuFg7TcuPzc zUh|?V_hdbZp~$n}x$lYT{m1Pw=_DO4R(_@>fpZi}+3(ezt!_YIx}8Lu(}I{n!mX~b zL-Vs&-ep?616awlAN^4w=h5588Y82n#KhH z00aX`L_t(u;>?Qn7H{0%H+5g40>jFv2%m=csLV%VX{QHJgHQq)R@AEYd{8V$2Hj}x zs?14N*kJ{W8^jzZPmok&(JYl44rN`%LS~9C=>B_<{)IAB9?tJqrzz&GNd{ZczmPJi*;kc zLLHqGKdr)ZFbTBR39@N3sEp}*vdlvXpe*1p&VXEnXBP6D--Dz;O!K6<=+9;V7SlZM zQspRlM@*h-7zJk@jt2msgu`<%@l40;C_GORCPx+NwC?eZ+X@AM|MWG}+Zj*5Qsee) z+3*%|pkbi!q{Lqn{@%^aH91sW^+TpAV1>kuTjr}lePBK36rWXi_9$!KJrK(ceG^uK z{&5(((qbRhhXy{aON6OO>5}G%Ggwc&7D(YaxV+$ZK$_EWw}aHQ80!J8J9oL@`B%qAy-IV@BVgeG%g?9&M}^8fK(z*2SQKXCvxsaqGK%j z;VZV1BJnBQbN4zoxKT)|_RK@x5>ri{m})V1jeHJU+)6J--0CGt`Pa~MDhRBU6P8Rbwcfw!^>JVrSdbh{B>;=xea6J3;8g9Iy+&=SWRTMG zQ9D{ttKQeZfLb)5`}(Ng{A&BXOzWsH0=z@UtAR;T?7(kODIgV|)0AtzK@-PpOjb&U zBOfq^qXrwsU);Zj#>C$LS-74e_4-^bHcg`Nobf~2_vfM}-Pfo?2Xst2C>Z+{#?jP{ zp6Uu)1*Q6)a}*|yabIFuOQ59|bFl`2VD_q$hR~bg**+Wl>MV0D|KY#tpAL}zwc&a=iEB3ttG$vNoxK*vF#;wX} zvXi9ELw|nv*$YY3w2jp$MQdAFyu|(g@8q+BQ?;jxifT_46_vc?{{sU*gdKis&qe?M N002ovPDHLkV1nFX7L@=1 diff --git a/SnakeClient/SnakeApp/img/defaultUser.png b/SnakeClient/SnakeApp/img/defaultUser.png deleted file mode 100644 index 178aeecc0a9a8027a1780735e583864026bd1aaf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 38927 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 j&X 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 Eg1wAL5C8xG diff --git a/SnakeClient/SnakeApp/img/icon.ico b/SnakeClient/SnakeApp/img/icon.ico deleted file mode 100644 index 53635b1354905e151458fd65d7b7502a6a3bb787..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32490 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 F@xL$p9H#&P diff --git a/SnakeClient/SnakeApp/img/logo.png b/SnakeClient/SnakeApp/img/logo.png deleted file mode 100644 index f7120fcf82e1779598959fe545f4434d93b1d49d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2461 zcmV;O31aq%P)8?pCWWFNjR9Mpr`=* zfgb^T$H%PJB1>S|nQXURG*b#1m9WP3?@xxm2LB*7Cg!of5^82A#SFmr)u2A&4C z`dY0lzo8y)vvtlDo=)kQ%#pnz!h!U5;AH^gEc3btc-CS!SXX?m9{*Bj%_>=qA{R3g z{+}s?1UwJi>0c(Xa#I5)tD#nPt4c@qhRDlm82DE)Y$g!hz#fB1=(y(QMp~C$YW-X$ zPdJb!8p;q4=SasDG6{veqEg7Kh(-Z}QNSu0ad=F)>Mhi_+we475e?Ok=)kck;XoST zULa8nuQrDpfjyGXWL~$m1<7YdRaGvYNf0H`MjK&0a09Rg z@EI*4ZCy?}R=RN2Tc)f)I7_;1xf+zsriYqyE(wzgohh=e{$a^m$c z$%qW_2A7t-LUnBdfCqR0cnoOtFO}&2Y&}*-`N8qd?ta37^f0i1alKFt#67?+|5Axn zw>ANAY~LWk<1x@Sp|7E}_FQ#0@U+=xkgna{GHI0y9E)=FwLySefmcfti&JF071-rp zCb4RB6QV(&@56Wzpcidi)&c$m$c7$9pvVsEO0QB zQ0{M7XeV?o$wwbV0k$(mua|@PlhG`!{`8JEEEOi1Xb`Axx6{7Dg`6vxW1;Le;2XdQ zaDBQav{BiA;W?DL>s!L6diIRb>Qt z0(gcB-Cu)oT4q&pDk{@^I70Ab47ET4coO&}vxlil z7^M5A!ab$9qNnx|T{D$8Uw(6rb=#|jsPylRdPW;dhqZ6FT3$J~ZlMHPEO0wPyk z>os;=UstotGYN$=2Zsq9kD;oBfk%Kp)U1F}6?@{F29vOP?Uv?AtI=F!G>bGXcF?-q zNj90cCx&x(0k@;=^5I&QQ-t{Qf|YJ*CX;z4GFuJ!mrB&P+Zeu>X^}I9htXEDgSE)N z*z96)bD2;1T5W8+x1EKn+#>K4@Fw7&Yre&vxPRbmvOXPCFqlMaP9uUaA2tLKMS;eJ z4!nLV;XtY*FRKrsoqW&CHqWu)l$X`W$j8~vzLRlx;8=|L26DJHV?sQfGbKmld(ln` zdzrGTcE)}ik`m>pkxbuXcwoCs!cnST1*6T7-;Qs(ze_=?X9d@B}a0+v-<++m@)!f z51gzf-E5oEkG63=2>9HM7TT|N(Ynlu$uhTnCX-NjXLmn|VR;x>4Fsl3Q;YGi4){KB zhiDYUwk{`&R(o*PnP;70CZX`wOMPVGN*@}?lpA9$XQ>@+xIGCpHZHQ$x!#AjWp)O& zL?p-CFZCg33j2XgQ^l>N(MSdk0Y3$Lk|XlE;E7n>$j2GnO%}|ynH6QW8E`jP=sy)- zIGXpHmEz8qHTkhsQ)AuQGfga})3q6^7M(o9|Ae9WTV8zVya$ zFiqnE`;3nIzBU^dPA8Bvg*Cu$%f-1IHpl|74|pvTSMCg+j9J|c795`HO#Xr(AbHL7 zpNhAm4XJabaW1DJH2^$YP}B|mr{W7t7P0C{@9>xy>Q9r7Da(LoOTS-UYq0jxvlFNr zJfB*hNhmZfvR5@vOcs#~rxR_!b7)UzW4hcBpdIk`02ia7?6zb?rfG>|S`dfVMDS!B zC07VjvQk|Mh@yIc|HOxKJK{q*S~{gEK?Fe{8Oae1Wt)IsjsI4=yXfrnBJhQQ-XzEO zO@CYUY0qd~rQuf^0$?}r$oZpD0-Bw-qI`ZEXm2WQC= zzG9+JVLB$$cOnLwop+M-2Jx8DqCFdr*O^0+qPxX2Ehk{ zaVoeZ=?UTiLBzUfwRDz>hmtxF+}jo;ol@Dk>|K+^I{Y z7l_mu%ul>?OczgE(0eZ^~~+ku;}-qe86ED{;WaOf`=P_l(yU<{q&C z)v6oVcg;-=YTI&W@%Kc}bLEHkjMVLEw!H1EH=hL#17Dd-X7l6JG`+gH^y{r&YUi%~ b$<_Y=*q$)a+E8iP00000NkvXXu0mjfdrX$J diff --git a/SnakeClient/SnakeApp/img/up.svg b/SnakeClient/SnakeApp/img/up.svg deleted file mode 100644 index 25413c8..0000000 --- a/SnakeClient/SnakeApp/img/up.svg +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/SnakeClient/SnakeApp/qml.qrc b/SnakeClient/SnakeApp/qml.qrc deleted file mode 100644 index ce92df9..0000000 --- a/SnakeClient/SnakeApp/qml.qrc +++ /dev/null @@ -1,39 +0,0 @@ - - - front-end/main.qml - front-end/GraphicItem.qml - front-end/MainMenu.qml - qtquickcontrols2.conf - front-end/Scene.qml - front-end/NotificationForm.qml - front-end/SnakeItem.qml - front-end/About.qml - front-end/AboutPage.qml - front-end/BasePopUp.qml - front-end/TextInput.qml - front-end/PagePopUp.qml - front-end/UserView.qml - front-end/ImageView.qml - front-end/PropertyView.qml - front-end/Metrix.qml - front-end/LoginView.qml - front-end/FrameView.qml - front-end/MainMenuButton.qml - front-end/SideBar.qml - front-end/LeftSideBar.qml - front-end/LeftBoxSideBar.qml - front-end/SettingsView.qml - front-end/NotificationServiceView.qml - - - img/up.svg - - - img/logo.png - img/icon.ico - - - img/defaultUser.png - img/defaultSnake.png - - diff --git a/SnakeClient/SnakeApp/qtquickcontrols2.conf b/SnakeClient/SnakeApp/qtquickcontrols2.conf deleted file mode 100644 index 49b52e5..0000000 --- a/SnakeClient/SnakeApp/qtquickcontrols2.conf +++ /dev/null @@ -1,7 +0,0 @@ -[Controls] -Style=Material - -[Material] -Accent=Teal -Primary=BlueGrey -;Theme=Light diff --git a/SnakeClient/SnakeClient.pro b/SnakeClient/SnakeClient.pro deleted file mode 100644 index fb9ca15..0000000 --- a/SnakeClient/SnakeClient.pro +++ /dev/null @@ -1,5 +0,0 @@ -TEMPLATE = subdirs -CONFIG += ordered - -SUBDIRS += \ - SnakeApp diff --git a/SnakeMain.pro b/SnakeMain.pro deleted file mode 100644 index 97ff5a1..0000000 --- a/SnakeMain.pro +++ /dev/null @@ -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 diff --git a/SnakeServer/ClientProtocol/ClientProtocol.pri b/SnakeServer/ClientProtocol/ClientProtocol.pri deleted file mode 100644 index dead322..0000000 --- a/SnakeServer/ClientProtocol/ClientProtocol.pri +++ /dev/null @@ -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) - - - diff --git a/SnakeServer/ClientProtocol/ClientProtocol.pro b/SnakeServer/ClientProtocol/ClientProtocol.pro deleted file mode 100644 index f7b8129..0000000 --- a/SnakeServer/ClientProtocol/ClientProtocol.pro +++ /dev/null @@ -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) diff --git a/SnakeServer/ClientProtocol/ClientProtocolIncludes.pri b/SnakeServer/ClientProtocol/ClientProtocolIncludes.pri deleted file mode 100644 index 0617e71..0000000 --- a/SnakeServer/ClientProtocol/ClientProtocolIncludes.pri +++ /dev/null @@ -1,4 +0,0 @@ -INCLUDEPATH += "$$PWD/" -INCLUDEPATH += "$$PWD/Objects" - - diff --git a/SnakeServer/ClientProtocol/Objects/basenetworkobject.cpp b/SnakeServer/ClientProtocol/Objects/basenetworkobject.cpp deleted file mode 100644 index 8587d54..0000000 --- a/SnakeServer/ClientProtocol/Objects/basenetworkobject.cpp +++ /dev/null @@ -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 ¶ms) { - bool isKey = params.alg & Key; - - switch (params.alg & ~Key) { - case RSA: { - - if (isKey) { - - return { - static_cast(sizeof (int) + - QRSAEncryption::getKeyBytesSize(static_cast(params.baseBits))) - }; - } - - auto baseSize = - static_cast(sizeof (int) + - QRSAEncryption::getKeyBytesSize(static_cast(params.encryptBits))) / 2; - - return {baseSize, baseSize * params.baseBytes()}; - } - - case SHA: { - return {static_cast(sizeof (int) + params.baseBytes())}; - } - default: - return sizeof (int) + 10; - } - - -} - -unsigned int EncryptionParams::baseBytes() const { - return baseBits / 8; -} - -} diff --git a/SnakeServer/ClientProtocol/Objects/basenetworkobject.h b/SnakeServer/ClientProtocol/Objects/basenetworkobject.h deleted file mode 100644 index 2584496..0000000 --- a/SnakeServer/ClientProtocol/Objects/basenetworkobject.h +++ /dev/null @@ -1,89 +0,0 @@ -#ifndef BASENETWORKOBJECT_H -#define BASENETWORKOBJECT_H - -#include "networkclasssize.h" - -#include -#include -#include -#include -#include "config.h" -#include -#include "clientprotocol_global.h" -#include - -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 ¶ms); - -template -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).hash_code()) { - - return { sizeof (int), sizeof (int) * MAX_SIZE}; - - } else if (hash == typeid(QList).hash_code()) { - - return { sizeof (float), sizeof (float) * MAX_SIZE}; - - } else if (hash == typeid(QStringList).hash_code()) { - - auto size = getTypeSize(); - return {sizeof (int) , size.max + static_cast(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 -auto cast(const BaseNetworkObject* obj) { - static_assert (!std::is_pointer(), "Cast working only with pointers!"); - return static_cast(obj); -} - -} -#endif // BASENETWORKOBJECT_H diff --git a/SnakeServer/ClientProtocol/Objects/gamedata.cpp b/SnakeServer/ClientProtocol/Objects/gamedata.cpp deleted file mode 100644 index 2bd4f19..0000000 --- a/SnakeServer/ClientProtocol/Objects/gamedata.cpp +++ /dev/null @@ -1,50 +0,0 @@ -#include "gamedata.h" -#include "config.h" -#include "clientprotocol.h" - - -namespace ClientProtocol { - -GameData::GameData() -{ - _class = static_cast(Command::GameData); -} - -QList GameData::getTimeClick() const { - return timeClick; -} - -void GameData::setTimeClick(const QList &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(); -} - -} diff --git a/SnakeServer/ClientProtocol/Objects/gamedata.h b/SnakeServer/ClientProtocol/Objects/gamedata.h deleted file mode 100644 index e3cf80a..0000000 --- a/SnakeServer/ClientProtocol/Objects/gamedata.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef GAMEDATA_H -#define GAMEDATA_H - -#include - -namespace ClientProtocol { - - -class CLIENTPROTOCOLSHARED_EXPORT GameData: public UpdatePlayerData -{ -private: - QList timeClick; -public: - GameData(); - QList getTimeClick() const; - void setTimeClick(const QList &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 diff --git a/SnakeServer/ClientProtocol/Objects/getitem.cpp b/SnakeServer/ClientProtocol/Objects/getitem.cpp deleted file mode 100644 index 352a9cf..0000000 --- a/SnakeServer/ClientProtocol/Objects/getitem.cpp +++ /dev/null @@ -1,10 +0,0 @@ -#include "getitem.h" -#include "clientprotocol.h" - -namespace ClientProtocol { - -GetItem::GetItem() -{ - _class = static_cast(Command::GetItem); -} -} diff --git a/SnakeServer/ClientProtocol/Objects/getitem.h b/SnakeServer/ClientProtocol/Objects/getitem.h deleted file mode 100644 index 06978ae..0000000 --- a/SnakeServer/ClientProtocol/Objects/getitem.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef GETITEM_H -#define GETITEM_H - -#include - -namespace ClientProtocol { - - -class CLIENTPROTOCOLSHARED_EXPORT GetItem : public UpdatePlayerData - -{ -public: - GetItem(); -}; - -} -#endif // GETITEM_H diff --git a/SnakeServer/ClientProtocol/Objects/login.cpp b/SnakeServer/ClientProtocol/Objects/login.cpp deleted file mode 100644 index 078bd8f..0000000 --- a/SnakeServer/ClientProtocol/Objects/login.cpp +++ /dev/null @@ -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(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; -} -} diff --git a/SnakeServer/ClientProtocol/Objects/login.h b/SnakeServer/ClientProtocol/Objects/login.h deleted file mode 100644 index 9061765..0000000 --- a/SnakeServer/ClientProtocol/Objects/login.h +++ /dev/null @@ -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 diff --git a/SnakeServer/ClientProtocol/Objects/map.cpp b/SnakeServer/ClientProtocol/Objects/map.cpp deleted file mode 100644 index 9902551..0000000 --- a/SnakeServer/ClientProtocol/Objects/map.cpp +++ /dev/null @@ -1,45 +0,0 @@ -#include "map.h" -#include - -namespace ClientProtocol { - -Map::Map() -{ - _class = static_cast(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(); -} - -} diff --git a/SnakeServer/ClientProtocol/Objects/map.h b/SnakeServer/ClientProtocol/Objects/map.h deleted file mode 100644 index f8caa60..0000000 --- a/SnakeServer/ClientProtocol/Objects/map.h +++ /dev/null @@ -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 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 diff --git a/SnakeServer/ClientProtocol/Objects/objdata.cpp b/SnakeServer/ClientProtocol/Objects/objdata.cpp deleted file mode 100644 index 9af67e7..0000000 --- a/SnakeServer/ClientProtocol/Objects/objdata.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include "objdata.h" -#include - -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; - -} -} diff --git a/SnakeServer/ClientProtocol/Objects/objdata.h b/SnakeServer/ClientProtocol/Objects/objdata.h deleted file mode 100644 index 530b832..0000000 --- a/SnakeServer/ClientProtocol/Objects/objdata.h +++ /dev/null @@ -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 diff --git a/SnakeServer/ClientProtocol/Objects/player.cpp b/SnakeServer/ClientProtocol/Objects/player.cpp deleted file mode 100644 index ff991de..0000000 --- a/SnakeServer/ClientProtocol/Objects/player.cpp +++ /dev/null @@ -1,116 +0,0 @@ -#include "player.h" -#include "config.h" -#include - -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 Player::getItems() const { - return items; -} - -void Player::setItems(const QList &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(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(); -} -} diff --git a/SnakeServer/ClientProtocol/Objects/player.h b/SnakeServer/ClientProtocol/Objects/player.h deleted file mode 100644 index 88ed364..0000000 --- a/SnakeServer/ClientProtocol/Objects/player.h +++ /dev/null @@ -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 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 getItems() const; - void setItems(const QList &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 diff --git a/SnakeServer/ClientProtocol/Objects/pubkey.cpp b/SnakeServer/ClientProtocol/Objects/pubkey.cpp deleted file mode 100644 index 80cf3e1..0000000 --- a/SnakeServer/ClientProtocol/Objects/pubkey.cpp +++ /dev/null @@ -1,62 +0,0 @@ -#include "pubkey.h" -#include "clientprotocol.h" - -namespace ClientProtocol { - -PubKey::PubKey(): - BaseNetworkObject() { - _class = static_cast(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(_typeKey); - stream >> key; - return stream; -} - -bool PubKey::isValid() const { - return static_cast(key.size()) == QRSAEncryption::getKeyBytesSize(typeKey) - && BaseNetworkObject::isValid(); -} - -} diff --git a/SnakeServer/ClientProtocol/Objects/pubkey.h b/SnakeServer/ClientProtocol/Objects/pubkey.h deleted file mode 100644 index 913db5c..0000000 --- a/SnakeServer/ClientProtocol/Objects/pubkey.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef PUBKEY_H -#define PUBKEY_H -#include - -#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 diff --git a/SnakeServer/ClientProtocol/Objects/snake.cpp b/SnakeServer/ClientProtocol/Objects/snake.cpp deleted file mode 100644 index f804a53..0000000 --- a/SnakeServer/ClientProtocol/Objects/snake.cpp +++ /dev/null @@ -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 Snake::getSkillet() const { - return skillet; -} - -void Snake::setSkillet(const QList &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(Command::Snake); - -} - -} diff --git a/SnakeServer/ClientProtocol/Objects/snake.h b/SnakeServer/ClientProtocol/Objects/snake.h deleted file mode 100644 index 685068e..0000000 --- a/SnakeServer/ClientProtocol/Objects/snake.h +++ /dev/null @@ -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 skillet; - -public: - Snake(); - quint8 getSpeed() const; - void setSpeed(const quint8 &value); - quint8 getSnakeClass() const; - void setSnakeClass(const quint8 &value); - QList getSkillet() const; - void setSkillet(const QList &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 diff --git a/SnakeServer/ClientProtocol/Objects/updateplayerdata.cpp b/SnakeServer/ClientProtocol/Objects/updateplayerdata.cpp deleted file mode 100644 index 08df4e0..0000000 --- a/SnakeServer/ClientProtocol/Objects/updateplayerdata.cpp +++ /dev/null @@ -1,49 +0,0 @@ -#include "updateplayerdata.h" -#include "config.h" -#include "clientprotocol.h" - -namespace ClientProtocol { - -UpdatePlayerData::UpdatePlayerData() { - _class = static_cast(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(); -} - -} diff --git a/SnakeServer/ClientProtocol/Objects/updateplayerdata.h b/SnakeServer/ClientProtocol/Objects/updateplayerdata.h deleted file mode 100644 index 4833c3b..0000000 --- a/SnakeServer/ClientProtocol/Objects/updateplayerdata.h +++ /dev/null @@ -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 diff --git a/SnakeServer/ClientProtocol/Objects/websocket.cpp b/SnakeServer/ClientProtocol/Objects/websocket.cpp deleted file mode 100644 index 10ae941..0000000 --- a/SnakeServer/ClientProtocol/Objects/websocket.cpp +++ /dev/null @@ -1,71 +0,0 @@ -#include "websocket.h" - -namespace ClientProtocol { - -WebSocket::WebSocket() { - _class = static_cast(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(_data.cmd) != Command::Undefined && - UpdatePlayerData::isValid(); - -} - -bool WebSocket::isSubscribe() const { - return _data.subscribe; -} - -Command WebSocket::getCommand() const { - return static_cast(_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(cmd); -} - -void WebSocket::setObjectId(int value) { - _data.objectId = value; -} - -QDataStream &operator<<(QDataStream &stream, WebSocketData data) { - stream.writeRawData(reinterpret_cast(&data), sizeof (data)); - return stream; -} - -QDataStream &operator>>(QDataStream &stream, WebSocketData &data) { - stream.readRawData(reinterpret_cast(&data), sizeof (data)); - return stream; - -} - -} diff --git a/SnakeServer/ClientProtocol/Objects/websocket.h b/SnakeServer/ClientProtocol/Objects/websocket.h deleted file mode 100644 index 4b2d238..0000000 --- a/SnakeServer/ClientProtocol/Objects/websocket.h +++ /dev/null @@ -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 diff --git a/SnakeServer/ClientProtocol/client.cpp b/SnakeServer/ClientProtocol/client.cpp deleted file mode 100644 index 1e5c1a4..0000000 --- a/SnakeServer/ClientProtocol/client.cpp +++ /dev/null @@ -1,438 +0,0 @@ -#include "client.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include "factorynetobjects.h" -#include "gamedata.h" -#include "getitem.h" -#include "login.h" -#include "updateplayerdata.h" -#include -#include - -#define SOLT "SNAKE" -namespace ClientProtocol { - -Command Client::checkCommand(int sig, Command reqCmd, Type type) { - -#define idx static_cast(sig) - - auto expCmd = static_cast( - _requestsMap[idx].value("expected", - static_cast(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(hdr.command); - auto requesCommand = static_cast(hdr.requestCommand); - - auto type = static_cast(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(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(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((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& 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(cmd)] = false; - else { - _subscribe.remove(static_cast(cmd)); - } - - return true; -} - -QHash Client::getSubscribe() const { - return _subscribe; -} - - -} diff --git a/SnakeServer/ClientProtocol/client.h b/SnakeServer/ClientProtocol/client.h deleted file mode 100644 index cff1fd8..0000000 --- a/SnakeServer/ClientProtocol/client.h +++ /dev/null @@ -1,156 +0,0 @@ -#ifndef CLIENT_CP_H -#define CLIENT_CP_H - -#include "clientprotocol_global.h" -#include "clientprotocol.h" -#include -#include - -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 _requestsMap; - QHash _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 &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 getSubscribe() const; - - friend class ::testSankeServer; - - -signals: - void sigIncommingData(Command cmd, const QByteArray& obj); - void onlineChanged(bool); - void loginChanged(bool); - -}; - -} -#endif // CLIENT_CP_H diff --git a/SnakeServer/ClientProtocol/clientprotocol.cpp b/SnakeServer/ClientProtocol/clientprotocol.cpp deleted file mode 100644 index f12ece6..0000000 --- a/SnakeServer/ClientProtocol/clientprotocol.cpp +++ /dev/null @@ -1,214 +0,0 @@ -#include "clientprotocol.h" -#include "gamedata.h" -#include "getitem.h" -#include "login.h" -#include "player.h" -#include "updateplayerdata.h" - -#include -#include -#include -#include -#include -#include -#include - -#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::Undefined) { - return false; - } - - if (static_cast(type) == Type::Undefined) { - return false; - } - - if (static_cast(type) == Type::Responke) { - return static_cast(command) != Command::Undefined; - } - - return isValidSize(command, size); -} - -void Header::reset() { - size = 0; - command = static_cast(Command::Undefined); - type = static_cast(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 (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(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(cmd); - hdr.type = static_cast(type); - hdr.size = static_cast(data.size()); - - if (type == Type::Responke) { - signPackage(old); - } - - return isValid(); -} - -QByteArray Package::toBytes() const { - QByteArray res; - res.append(reinterpret_cast(const_cast(&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( - static_cast(Command::Login))) { - return false; - } - - if (!FactoryNetObjects::regType( - static_cast(Command::UpdatePlayerData))) { - return false; - } - - if (!FactoryNetObjects::regType( - static_cast(Command::GameData))) { - return false; - } - - if (!FactoryNetObjects::regType( - static_cast(Command::GetItem))) { - return false; - } - - if (!FactoryNetObjects::regType( - static_cast(Command::Player))) { - return false; - } - - if (!FactoryNetObjects::regType( - static_cast(Command::Snake))) { - return false; - } - - if (!FactoryNetObjects::regType( - static_cast(Command::Map))) { - return false; - } - - if (!FactoryNetObjects::regType( - static_cast(Command::PubKey))) { - return false; - } - - if (!FactoryNetObjects::regType( - static_cast(Command::WebSocket))) { - return false; - } - - return true; -} - -} diff --git a/SnakeServer/ClientProtocol/clientprotocol.h b/SnakeServer/ClientProtocol/clientprotocol.h deleted file mode 100644 index ad40b51..0000000 --- a/SnakeServer/ClientProtocol/clientprotocol.h +++ /dev/null @@ -1,188 +0,0 @@ -#ifndef CLIENTPROTOCOL_H -#define CLIENTPROTOCOL_H - -#include "clientprotocol_global.h" - -#include -#include -#include "config.h" - -#define BASE_ENCRYPTION_BITS 256 -#define BASE_RSA_BITS static_cast(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 - bool parse(T& res) { - auto obj = static_cast(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 diff --git a/SnakeServer/ClientProtocol/clientprotocol_global.h b/SnakeServer/ClientProtocol/clientprotocol_global.h deleted file mode 100644 index 46b61a7..0000000 --- a/SnakeServer/ClientProtocol/clientprotocol_global.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef CLIENTPROTOCOL_GLOBAL_H -#define CLIENTPROTOCOL_GLOBAL_H - -#include - -#if defined(CLIENTPROTOCOL_LIBRARY) -# define CLIENTPROTOCOLSHARED_EXPORT Q_DECL_EXPORT -#else -# define CLIENTPROTOCOLSHARED_EXPORT Q_DECL_IMPORT -#endif - -#endif // CLIENTPROTOCOL_GLOBAL_H diff --git a/SnakeServer/ClientProtocol/config.h b/SnakeServer/ClientProtocol/config.h deleted file mode 100644 index f9b26f0..0000000 --- a/SnakeServer/ClientProtocol/config.h +++ /dev/null @@ -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 diff --git a/SnakeServer/ClientProtocol/connectioninfo.cpp b/SnakeServer/ClientProtocol/connectioninfo.cpp deleted file mode 100644 index b680592..0000000 --- a/SnakeServer/ClientProtocol/connectioninfo.cpp +++ /dev/null @@ -1,81 +0,0 @@ -#include "connectioninfo.h" -#include - -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(); - } -} -} diff --git a/SnakeServer/ClientProtocol/connectioninfo.h b/SnakeServer/ClientProtocol/connectioninfo.h deleted file mode 100644 index 4bbba2e..0000000 --- a/SnakeServer/ClientProtocol/connectioninfo.h +++ /dev/null @@ -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 diff --git a/SnakeServer/ClientProtocol/cp.h b/SnakeServer/ClientProtocol/cp.h deleted file mode 100644 index 569bc01..0000000 --- a/SnakeServer/ClientProtocol/cp.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef CP_H -#define CP_H -#include "server.h" -#include "client.h" - -#endif // CP_H diff --git a/SnakeServer/ClientProtocol/cpserver.h b/SnakeServer/ClientProtocol/cpserver.h deleted file mode 100644 index 265567c..0000000 --- a/SnakeServer/ClientProtocol/cpserver.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef CPSERVER_H -#define CPSERVER_H - -#include "server.h" - -#endif // CPSERVER_H diff --git a/SnakeServer/ClientProtocol/factorynetobjects.cpp b/SnakeServer/ClientProtocol/factorynetobjects.cpp deleted file mode 100644 index cd2785d..0000000 --- a/SnakeServer/ClientProtocol/factorynetobjects.cpp +++ /dev/null @@ -1,40 +0,0 @@ -#include "factorynetobjects.h" -#include "clientprotocol.h" - -namespace ClientProtocol { - -QMap map; -QMap 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(); -} - -} diff --git a/SnakeServer/ClientProtocol/factorynetobjects.h b/SnakeServer/ClientProtocol/factorynetobjects.h deleted file mode 100644 index d614e64..0000000 --- a/SnakeServer/ClientProtocol/factorynetobjects.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef FACTORYNETOBJECTS_H -#define FACTORYNETOBJECTS_H -#include "clientprotocol_global.h" -#include "basenetworkobject.h" -#include -#include -namespace ClientProtocol { - -extern QMap map; -extern QMap 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 - 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 diff --git a/SnakeServer/ClientProtocol/networkclasssize.cpp b/SnakeServer/ClientProtocol/networkclasssize.cpp deleted file mode 100644 index d790614..0000000 --- a/SnakeServer/ClientProtocol/networkclasssize.cpp +++ /dev/null @@ -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; -} -} diff --git a/SnakeServer/ClientProtocol/networkclasssize.h b/SnakeServer/ClientProtocol/networkclasssize.h deleted file mode 100644 index 3581486..0000000 --- a/SnakeServer/ClientProtocol/networkclasssize.h +++ /dev/null @@ -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 diff --git a/SnakeServer/ClientProtocol/rsakeyspool.cpp b/SnakeServer/ClientProtocol/rsakeyspool.cpp deleted file mode 100644 index 8367cf8..0000000 --- a/SnakeServer/ClientProtocol/rsakeyspool.cpp +++ /dev/null @@ -1,27 +0,0 @@ -#include "rsakeyspool.h" -#include - -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(time(nullptr)), key); -} - -int RSAKeysPool::size(QRSAEncryption::Rsa rsa) const { - return pool.value(rsa).size(); -} - -} diff --git a/SnakeServer/ClientProtocol/rsakeyspool.h b/SnakeServer/ClientProtocol/rsakeyspool.h deleted file mode 100644 index 402f60a..0000000 --- a/SnakeServer/ClientProtocol/rsakeyspool.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef RSAKEYSPOOL_H -#define RSAKEYSPOOL_H -#include -#include -#include -#include -#include -#include "clientprotocol_global.h" - -namespace ClientProtocol { - -struct RSAKeyPair { - QByteArray pub; - QByteArray priv; -}; - -typedef QMap KeysPool; -typedef QHash 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 diff --git a/SnakeServer/ClientProtocol/server.cpp b/SnakeServer/ClientProtocol/server.cpp deleted file mode 100644 index b08d81e..0000000 --- a/SnakeServer/ClientProtocol/server.cpp +++ /dev/null @@ -1,415 +0,0 @@ -#include "server.h" -#include "quasarapp.h" -#include -#include -#include -#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(pkg.hdr.command)) { - case Command::Ping: { - - if (static_cast(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(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(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; -} - - -} diff --git a/SnakeServer/ClientProtocol/server.h b/SnakeServer/ClientProtocol/server.h deleted file mode 100644 index 0221116..0000000 --- a/SnakeServer/ClientProtocol/server.h +++ /dev/null @@ -1,80 +0,0 @@ -#ifndef SERVER_CP_H -#define SERVER_CP_H -#include "clientprotocol_global.h" -#include "clientprotocol.h" - -#include -#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 _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 diff --git a/SnakeServer/Daemon/Daemon.pro b/SnakeServer/Daemon/Daemon.pro deleted file mode 100644 index ee57c0f..0000000 --- a/SnakeServer/Daemon/Daemon.pro +++ /dev/null @@ -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) diff --git a/SnakeServer/Daemon/SnakeServer.pro b/SnakeServer/Daemon/SnakeServer.pro deleted file mode 100644 index 22c203c..0000000 --- a/SnakeServer/Daemon/SnakeServer.pro +++ /dev/null @@ -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 diff --git a/SnakeServer/Daemon/main.cpp b/SnakeServer/Daemon/main.cpp deleted file mode 100644 index 9eeb09e..0000000 --- a/SnakeServer/Daemon/main.cpp +++ /dev/null @@ -1,51 +0,0 @@ -#include -#include -#include -#include -#include - -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(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(); -} diff --git a/SnakeServer/Qt-Secret b/SnakeServer/Qt-Secret deleted file mode 160000 index 29bdfc6..0000000 --- a/SnakeServer/Qt-Secret +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 29bdfc6e8182615b782f2f5abdca6427f718208e diff --git a/SnakeServer/Server/Server.pri b/SnakeServer/Server/Server.pri deleted file mode 100644 index 21b6637..0000000 --- a/SnakeServer/Server/Server.pri +++ /dev/null @@ -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/" - - - diff --git a/SnakeServer/Server/Server.pro b/SnakeServer/Server/Server.pro deleted file mode 100644 index c669b6f..0000000 --- a/SnakeServer/Server/Server.pro +++ /dev/null @@ -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 diff --git a/SnakeServer/Server/item.cpp b/SnakeServer/Server/item.cpp deleted file mode 100644 index c203c3b..0000000 --- a/SnakeServer/Server/item.cpp +++ /dev/null @@ -1,72 +0,0 @@ -#include "item.h" -#include "factorynetobjects.h" -#include -#include - -int Item::getId() const { - return id; -} - -bool Item::setId(int value) { - id = value; - - if (data.size() < static_cast(sizeof (id) + sizeof (ClientProtocol::Command))) { - return false; - } - - int oldSize = data.size(); - - data.replace(sizeof (ClientProtocol::Command), sizeof (id), - reinterpret_cast(&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(hdr.command); -} - -const QByteArray &Item::dataArray() const { - return data; -} - -bool Item::isValid() const { - return ClientProtocol::FactoryNetObjects::isRegisteredType(hdr.type) - && Package::isValid(); -} diff --git a/SnakeServer/Server/item.h b/SnakeServer/Server/item.h deleted file mode 100644 index a8c13c1..0000000 --- a/SnakeServer/Server/item.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef ITEM_H -#define ITEM_H -#include -#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 - bool parse(T& res) { - return ClientProtocol::Package::parse(res); - } -}; - -#endif // ITEM_H diff --git a/SnakeServer/Server/keysreactor.cpp b/SnakeServer/Server/keysreactor.cpp deleted file mode 100644 index f7692ff..0000000 --- a/SnakeServer/Server/keysreactor.cpp +++ /dev/null @@ -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(); - } -} diff --git a/SnakeServer/Server/keysreactor.h b/SnakeServer/Server/keysreactor.h deleted file mode 100644 index 55422cf..0000000 --- a/SnakeServer/Server/keysreactor.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef KEYSREACTOR_H -#define KEYSREACTOR_H - -#include -#include -#include -#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 _mutexs; - QHash> _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 diff --git a/SnakeServer/Server/mainserver.cpp b/SnakeServer/Server/mainserver.cpp deleted file mode 100644 index 9b4afee..0000000 --- a/SnakeServer/Server/mainserver.cpp +++ /dev/null @@ -1,320 +0,0 @@ -#include "keysreactor.h" -#include "mainserver.h" -#include "playerdbdata.h" -#include "sqldbcache.h" -#include "websocketcontroller.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include - -QByteArray MainServer::generateTocket(const QString& gmail) const { - - return QCryptographicHash::hash((gmail + QString::number(rand())).toLatin1(), - QCryptographicHash::Sha256); -} - -QByteArray MainServer::registerPlayer(const ClientProtocol::Login& login, - const ClientProtocol::RSAKeyPair& rsa) const { - - if (!login.isValid()) { - return {}; - } - - 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(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(obj.value("command").toInt()); - QVariantMap res; - - switch (command) { - case ServerProtocol::State: { - res ["Work State"] = _serverDaemon->getWorkState(); - res ["Connections count"] = _serverDaemon->connectionState(); - - auto banedList = _serverDaemon->baned(); - res ["Baned Addresses count"] = banedList.size(); - res ["Baned List"] = banedList; - - break; - } - case ServerProtocol::Ban: { - auto address = obj.value("address").toUInt(); - - _serverDaemon->ban(address); - auto banedList = _serverDaemon->baned(); - res ["Baned List"] = banedList; - - break; - } - - case ServerProtocol::Unban: { - auto address = obj.value("address").toUInt(); - _serverDaemon->unBan(address); - auto banedList = _serverDaemon->baned(); - - res ["Baned List"] = banedList; - break; - } - - case ServerProtocol::Restart: { - auto address = obj.value("address").toString(); - auto port = static_cast(obj.value("port").toInt()); - - if (!restartSrver(address, port)) { - QuasarAppUtils::Params::verboseLog("server restart fail!"); - } - - res ["Work State"] = _serverDaemon->getWorkState(); - res ["Address"] = QString("%0:%1"). - arg(_serverDaemon->serverAddress().toString()). - arg(_serverDaemon->serverPort()); - - - break; - } - - case ServerProtocol::Stop: { - - res ["Res"] = "Server stoped!"; - _terminalPort->sendResponce(res, command); - _serverDaemon->stop(); - QCoreApplication::processEvents(); - QCoreApplication::quit(); - return; - - } - - default: - QuasarAppUtils::Params::verboseLog("server get undefined command!"); - res ["Error"] = "Server get undefined command!"; - break; - } - - _terminalPort->sendResponce(res, command); - return; -} - -MainServer::MainServer(bool forceKeys ,QObject *ptr): - QObject (ptr) { - - _keyReactor = new KeysReactor(forceKeys , this); - _serverDaemon = new ClientProtocol::Server(_keyReactor->getPool(), this); - _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() { -} diff --git a/SnakeServer/Server/mainserver.h b/SnakeServer/Server/mainserver.h deleted file mode 100644 index 0c75e16..0000000 --- a/SnakeServer/Server/mainserver.h +++ /dev/null @@ -1,56 +0,0 @@ -#ifndef SERVER_H -#define SERVER_H -#include -#include "server_global.h" -#include -#include - -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 diff --git a/SnakeServer/Server/playerdbdata.cpp b/SnakeServer/Server/playerdbdata.cpp deleted file mode 100644 index ff0b140..0000000 --- a/SnakeServer/Server/playerdbdata.cpp +++ /dev/null @@ -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() -{ - -} diff --git a/SnakeServer/Server/playerdbdata.h b/SnakeServer/Server/playerdbdata.h deleted file mode 100644 index d765f50..0000000 --- a/SnakeServer/Server/playerdbdata.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef PLAYERDBDATA_H -#define PLAYERDBDATA_H - -#include -#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 diff --git a/SnakeServer/Server/server_global.h b/SnakeServer/Server/server_global.h deleted file mode 100644 index 7ce5a72..0000000 --- a/SnakeServer/Server/server_global.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef SERVER_GLOBAL_H -#define SERVER_GLOBAL_H - -#include - -#if defined(SERVER_LIBRARY) -# define SERVERSHARED_EXPORT Q_DECL_EXPORT -#else -# define SERVERSHARED_EXPORT Q_DECL_IMPORT -#endif - -#endif // SERVER_GLOBAL_H diff --git a/SnakeServer/Server/sql/SnakeDB.sql b/SnakeServer/Server/sql/SnakeDB.sql deleted file mode 100644 index b9468a6..0000000 --- a/SnakeServer/Server/sql/SnakeDB.sql +++ /dev/null @@ -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); diff --git a/SnakeServer/Server/sqldbcache.cpp b/SnakeServer/Server/sqldbcache.cpp deleted file mode 100644 index a9fb3bf..0000000 --- a/SnakeServer/Server/sqldbcache.cpp +++ /dev/null @@ -1,383 +0,0 @@ -#include "sqldbcache.h" -#include "quasarapp.h" -#include "playerdbdata.h" -#include -#include - -#include -#include - -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 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(mode & SqlDBCasheWriteMode::Force)) { - - if (static_cast(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 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 &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; -} diff --git a/SnakeServer/Server/sqldbcache.h b/SnakeServer/Server/sqldbcache.h deleted file mode 100644 index 80bbc37..0000000 --- a/SnakeServer/Server/sqldbcache.h +++ /dev/null @@ -1,74 +0,0 @@ -#ifndef SQLDBCASHE_H -#define SQLDBCASHE_H -#include "sqldbwriter.h" - -#include -#include -#include -#include -#include -#include "item.h" -#include - -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 items; - QMap players; - QHash > owners; - QHash 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& items) override; - - friend class testSankeServer; - -signals: - void sigItemChanged(int id, const Item& newData); - void sigPlayerChanged(int id, const PlayerDBData& newData); - -}; - -#endif // SQLDBCASHE_H diff --git a/SnakeServer/Server/sqldbwriter.cpp b/SnakeServer/Server/sqldbwriter.cpp deleted file mode 100644 index abe0c31..0000000 --- a/SnakeServer/Server/sqldbwriter.cpp +++ /dev/null @@ -1,460 +0,0 @@ -#include "playerdbdata.h" -#include "sqldbwriter.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -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(type)); - } else { - request = QString("INSERT INTO items(id, type, data) VALUES" - "('%0', '%1', :bytes)"). - arg(id). - arg(static_cast(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 &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 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(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; - } -} diff --git a/SnakeServer/Server/sqldbwriter.h b/SnakeServer/Server/sqldbwriter.h deleted file mode 100644 index b87d16e..0000000 --- a/SnakeServer/Server/sqldbwriter.h +++ /dev/null @@ -1,64 +0,0 @@ -#ifndef SQLDBWRITER_H -#define SQLDBWRITER_H -#include "item.h" - -#include -#include -#include -#include - -#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); - - virtual bool getAllItemsOfPalyer(int player, QSet& 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 diff --git a/SnakeServer/Server/sqlres.qrc b/SnakeServer/Server/sqlres.qrc deleted file mode 100644 index 3c2c8cd..0000000 --- a/SnakeServer/Server/sqlres.qrc +++ /dev/null @@ -1,5 +0,0 @@ - - - sql/SnakeDB.sql - - diff --git a/SnakeServer/Server/websocketcontroller.cpp b/SnakeServer/Server/websocketcontroller.cpp deleted file mode 100644 index 0f21ddb..0000000 --- a/SnakeServer/Server/websocketcontroller.cpp +++ /dev/null @@ -1,57 +0,0 @@ -#include "item.h" -#include "playerdbdata.h" -#include "websocketcontroller.h" -#include - -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(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(cmd)].remove(address); - - if (cmd == ClientProtocol::Command::Player || cmd == ClientProtocol::Command::GetItem) { - _subscribsObjIds[id].remove(address); - } -} - -void WebSocketController::foreachSubscribers(const Item &newData, - const QSet &subscribersList) { - for (auto &&subscriber : subscribersList) { - if (_subscribs.value(static_cast(ClientProtocol::Command::GetItem)).contains(subscriber)) { - _serverDaemon->sendResponse(newData, subscriber); - } - } -} - -void WebSocketController::foreachSubscribers(const PlayerDBData &newData, - const QSet &subscribersList){ - for (auto &&subscriber : subscribersList) { - if (_subscribs.value(static_cast(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)); -} diff --git a/SnakeServer/Server/websocketcontroller.h b/SnakeServer/Server/websocketcontroller.h deleted file mode 100644 index e354355..0000000 --- a/SnakeServer/Server/websocketcontroller.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef WEBSOCKETCONTROLLER_H -#define WEBSOCKETCONTROLLER_H -#include -#include -#include -#include - -class Item; -class PlayerDBData; - -namespace ClientProtocol { - class Server; -} - -template -using MultiHash = QHash>; - -class WebSocketController: public QObject -{ - Q_OBJECT -private: - MultiHash _subscribs; - MultiHash _subscribsObjIds; - - ClientProtocol::Server *_serverDaemon = nullptr; - - void foreachSubscribers(const Item &newData, const QSet &subscribersList); - void foreachSubscribers(const PlayerDBData &newData, const QSet &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 diff --git a/SnakeServer/ServerProtocol/ServerProtocol.pri b/SnakeServer/ServerProtocol/ServerProtocol.pri deleted file mode 100644 index e0e8fb6..0000000 --- a/SnakeServer/ServerProtocol/ServerProtocol.pri +++ /dev/null @@ -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/" - - - diff --git a/SnakeServer/ServerProtocol/ServerProtocol.pro b/SnakeServer/ServerProtocol/ServerProtocol.pro deleted file mode 100644 index 1da1053..0000000 --- a/SnakeServer/ServerProtocol/ServerProtocol.pro +++ /dev/null @@ -1,52 +0,0 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2019-01-02T12:44:05 -# -#------------------------------------------------- - -QT -= gui -QT += network -TARGET = ServerProtocol -TEMPLATE = lib - -DEFINES += SERVERPROTOCOL_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) - -DISTFILES += \ - ServerProtocol.pri - -SOURCES += \ - serverutils.cpp \ - serverprotocol.cpp \ - server.cpp \ - client.cpp - -HEADERS += \ - serverprotocol.h \ - serverprotocol_global.h \ - serverutils.h \ - server.h \ - client.h \ - sp.h \ - spserver.h - diff --git a/SnakeServer/ServerProtocol/client.cpp b/SnakeServer/ServerProtocol/client.cpp deleted file mode 100644 index f08124d..0000000 --- a/SnakeServer/ServerProtocol/client.cpp +++ /dev/null @@ -1,193 +0,0 @@ -#include "client.h" -#include "serverprotocol.h" - -#include -#include -#include -#include -#include -#include - -namespace ServerProtocol { - -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()) { - emit sigIncommingData(_downloadPackage.parse()); - _downloadPackage.reset(); - received = true; - return; - } -} - -Client::Client(const QString& server, QObject *ptr): - QObject (ptr) { - - _destination = new QLocalSocket(this); - - _destination->connectToServer(server); - - connect(_destination, &QLocalSocket::readyRead, - this, &Client::incommingData); - -} - -bool Client::sendPackage(const 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 bytes = pkg.toBytes(); - - return bytes.size() == _destination->write(bytes); -} - -bool Client::ping() { - ServerProtocol::Package pkg; - pkg.hdr.command = ServerProtocol::Ping; - pkg.hdr.type = ServerProtocol::Request; - - return sendPackage(pkg); -} - -bool Client::getState() { - - ServerProtocol::Package pkg; - pkg.hdr.command = ServerProtocol::State; - pkg.hdr.type = ServerProtocol::Request; - - return sendPackage(pkg); -} - -bool Client::ban(const QHostAddress &address) { - - ServerProtocol::Package pkg; - pkg.hdr.command = ServerProtocol::Ban; - pkg.hdr.type = ServerProtocol::Request; - - if (address.isNull()) - return false; - - QVariantMap map; - map["address"] = address.toIPv4Address(); - - pkg.fromMap(map); - - return sendPackage(pkg); -} - -bool Client::unBan(const QHostAddress &address) { - - if (address.isNull()) - return false; - - ServerProtocol::Package pkg; - pkg.hdr.command = ServerProtocol::Unban; - pkg.hdr.type = ServerProtocol::Request; - - QVariantMap map; - map["address"] = address.toIPv4Address(); - - pkg.fromMap(map); - - return sendPackage(pkg); -} - -bool Client::restart(const QString &address, unsigned short port) { - - QHostAddress test(address); - - if (test.isNull() || port == 0) { - return false; - } - - ServerProtocol::Package pkg; - pkg.hdr.command = ServerProtocol::Restart; - pkg.hdr.type = ServerProtocol::Request; - - QVariantMap map; - map["address"] = address; - map["port"] = port; - pkg.fromMap(map); - - return sendPackage(pkg); -} - -bool Client::start(const QString &address, unsigned short port) { - QHostAddress test(address); - - QStringList params = {"daemon"}; - - if (!test.isNull()) { - params.push_back("-address"); - params.push_back(address); - - } - - if (port > 0) { - params.push_back("-port"); - params.push_back(QString::number(port)); - } - - QProcess p; - QProcessEnvironment env; - - p.setProcessEnvironment(env); - p.start("snake-d", params); - - if (p.waitForFinished(1000) && p.exitCode() == 0) { - emit sigIncommingData({{"Res", "server started"}}); - } else { - emit sigIncommingData({{"Res", "server started fail " + p.readAll()}}); - } - - return true; -} - -bool Client::stop() { - - ServerProtocol::Package pkg; - pkg.hdr.command = ServerProtocol::Stop; - pkg.hdr.type = ServerProtocol::Request; - - QVariantMap map; - pkg.fromMap(map); - - return sendPackage(pkg); -} - -bool Client::wait(bool & forWait, int msec) { - auto curmsec = QDateTime::currentMSecsSinceEpoch() + msec; - while (curmsec > QDateTime::currentMSecsSinceEpoch() && !forWait) { - QCoreApplication::processEvents(); - } - QCoreApplication::processEvents(); - return forWait; -} - -bool Client::wait(int msec) -{ - received = false; - return wait(received, msec); -} -} diff --git a/SnakeServer/ServerProtocol/client.h b/SnakeServer/ServerProtocol/client.h deleted file mode 100644 index da11278..0000000 --- a/SnakeServer/ServerProtocol/client.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef CLIENT_SP_H -#define CLIENT_SP_H -#include "serverprotocol.h" -#include "serverprotocol_global.h" -#include -#include - -class QLocalSocket; - -namespace ServerProtocol { - -class SERVERPROTOCOLSHARED_EXPORT Client : public QObject -{ - Q_OBJECT -private: - QLocalSocket *_destination; - Package _downloadPackage; - bool received = false; - - bool sendPackage(const Package& pkg); - -private slots: - void incommingData(); - -public: - explicit Client(const QString &server = DEFAULT_SERVER, QObject * ptr = nullptr); - bool ping(); - bool getState(); - bool ban(const QHostAddress& address); - bool unBan(const QHostAddress& address); - bool restart(const QString &address, unsigned short port); - bool start(const QString &address, unsigned short port); - bool stop(); - bool wait(bool &forWait, int msec = 10000); - bool wait(int msec = 10000); - - -signals: - void sigIncommingData(const QVariantMap& map); -}; - -} - - -#endif // CLIENT_SP_H diff --git a/SnakeServer/ServerProtocol/server.cpp b/SnakeServer/ServerProtocol/server.cpp deleted file mode 100644 index d0c582e..0000000 --- a/SnakeServer/ServerProtocol/server.cpp +++ /dev/null @@ -1,152 +0,0 @@ -#include "server.h" -#include -#include -#include -#include -#include -#include - -#include "serverutils.h" -#include "serverprotocol.h" -#include "server.h" - - -namespace ServerProtocol { - -void Server::parsePackage(const Package& pkg) { - if (!pkg.isValid()) { - return; - } - - - switch (pkg.hdr.command) { - case Ping: { - - if (pkg.hdr.type != Request) { - return; - } - - Package resp; - resp.hdr.command = Ping; - resp.hdr.type = Responke; - - QVariantMap data; - data["res"] = "Pong"; - resp.fromMap(data); - - if (!sendPackage(resp)) { - QuasarAppUtils::Params::verboseLog("!responce not sendet!"); - } - - break; - } - - default: { - QVariantMap res; - QDataStream stream(pkg.data); - stream >> res; - res["command"] = pkg.hdr.command; - emit incomingRequest(res); - }; - } -} - -bool Server::sendPackage(Package &pkg) { - if (!pkg.isValid()) { - return false; - } - - if (!_client->isValid()) { - qCritical() << "destination server not valid!"; - return false; - } - - if (!_client->waitForConnected()) { - qCritical() << "no connected to server! " << _client->errorString(); - return false; - } - - auto bytes = pkg.toBytes(); - bool sendet = bytes.size() == _client->write(bytes); - - return sendet; -} - - -void Server::avelableBytes() { - auto array = _client->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()) { - parsePackage(_downloadPackage); - _downloadPackage.reset(); - return; - } -} - -void Server::incomingConnection(quintptr socketDescriptor) { - _client->setSocketDescriptor(static_cast(socketDescriptor)); - - if (!_client->isValid()) { - QuasarAppUtils::Params::verboseLog("incomingConnection not valid!"); - return; - } - - if (!_client->isOpen() && !_client->open()) { - QuasarAppUtils::Params::verboseLog("incomingConnection not opened!"); - return; - } -} - -Server::Server(QObject *ptr): - QLocalServer (ptr) -{ - _client = new QLocalSocket(this); - - connect(_client, &QLocalSocket::readyRead, - this, &Server::avelableBytes); -} - -Server::~Server() { - close(); -} - -bool Server::run(const QString &name, bool force) { - - if (force) { - QFile::remove("/tmp/" + name); - } - - if (!listen(name)) { - QuasarAppUtils::Params::verboseLog("listing fail " + this->errorString()); - return false; - } - - return true; -} - -bool Server::sendResponce(QVariantMap res, Command command) { - - Package pck; - - pck.hdr.type = ServerProtocol::Responke; - pck.hdr.command = static_cast(command); - - if (res.isEmpty()) { - res["Error"] = "command not supported!"; - } - - pck.fromMap(res); - pck.hdr.size = static_cast(pck.data.size()); - - return sendPackage(pck); -} -} diff --git a/SnakeServer/ServerProtocol/server.h b/SnakeServer/ServerProtocol/server.h deleted file mode 100644 index bbe1bd1..0000000 --- a/SnakeServer/ServerProtocol/server.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef SERVER_SP_H -#define SERVER_SP_H -#include "serverprotocol.h" -#include "serverprotocol_global.h" -#include - -class QLocalSocket; -namespace ServerProtocol { - -class SERVERPROTOCOLSHARED_EXPORT Server: public QLocalServer -{ - Q_OBJECT -private: - QLocalSocket *_client; - Package _downloadPackage; - - void parsePackage(const Package &pkg); - -private slots: - void avelableBytes(); - -protected: - void incomingConnection(quintptr socketDescriptor) override; -public: - explicit Server(QObject * ptr = nullptr); - ~Server() override; - bool run(const QString& name, bool force = false); - bool sendResponce(QVariantMap res, Command command); - - bool sendPackage(Package &pkg); -signals: - void incomingRequest(QVariantMap data); -}; -} -#endif // SERVER_SP_H diff --git a/SnakeServer/ServerProtocol/serverprotocol.cpp b/SnakeServer/ServerProtocol/serverprotocol.cpp deleted file mode 100644 index cf69a1b..0000000 --- a/SnakeServer/ServerProtocol/serverprotocol.cpp +++ /dev/null @@ -1,88 +0,0 @@ -#include "serverprotocol.h" - -#include -#include -#include - - -ServerProtocol::Header::Header() { - reset(); -} - -bool ServerProtocol::Header::isValid() const { - - if (sizeof (*this) != 2) { - return false; - } - - if (type == Type::Request) { - return size < 256; - } - - return size >= 5; -} - -void ServerProtocol::Header::reset() { - size = 0; - command = Undefined; - type = Responke; -} - -ServerProtocol::Package::Package() { - reset(); -} - -bool ServerProtocol::Package::isValid() const { - if (!hdr.isValid()) { - return false; - } - - return hdr.size == data.size(); -} - -QVariantMap ServerProtocol::Package::parse() const { - if (!isValid()) - return QVariantMap(); - - QVariantMap res; - QDataStream stream(data); - - res["command"] = hdr.command; - res["type"] = hdr.type; - - if (hdr.type == Responke) { - stream >> res; - } - - return res; -} - -QByteArray ServerProtocol::Package::toBytes() const { - QByteArray res; - res.append(reinterpret_cast(const_cast(&hdr)), - sizeof (hdr)); - - res.append(data); - return res; -} - -void ServerProtocol::Package::reset() { - hdr.reset(); - data.clear(); -} - -bool ServerProtocol::Package::fromMap(const QVariantMap &map) { - QDataStream stream(&data, QIODevice::ReadWrite); - - stream << map; - - if (data.size() > 1024) { - return false; - } - - hdr.size = static_cast(data.size()); - - return true; - -} - diff --git a/SnakeServer/ServerProtocol/serverprotocol.h b/SnakeServer/ServerProtocol/serverprotocol.h deleted file mode 100644 index 2c0db44..0000000 --- a/SnakeServer/ServerProtocol/serverprotocol.h +++ /dev/null @@ -1,106 +0,0 @@ -#ifndef SERVERPROTOCOL_H -#define SERVERPROTOCOL_H - -#include "serverprotocol_global.h" - -#include - -#define DEFAULT_SERVER "SnnakeServer" - -namespace ServerProtocol { - -enum Type: unsigned char { - Responke = 0, - Request = 1 -}; - -enum Command: unsigned char { - Undefined = 0x00, - Ping = 0x01, - State = 0x02, - Stop = 0x03, - Restart = 0x04, - Unban = 0x05, - Ban = 0x06 -}; - -/** - * @brief The Header struct 2 byte - */ -struct SERVERPROTOCOLSHARED_EXPORT Header { - /** - * @brief size - size of package data (not header) - */ - unsigned short size: 10; - /** - * @brief type of package see Type - */ - unsigned char type: 1; - /** - * @brief command of pacage see Command - */ - unsigned char command: 5; - - /** - * @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(); -}; - -/** - * @brief The Package struct - */ -struct SERVERPROTOCOLSHARED_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 - */ - bool isValid() const; - - /** - * @brief parse - * @return Qmap of package (default key if "value") - */ - QVariantMap parse() const; - - /** - * @brief toBytes - * @return bytes array of packag - */ - QByteArray toBytes() const; - - /** - * @brief reset - reset all data and set for package invalid status - */ - void reset(); - - bool fromMap(const QVariantMap& map); - -}; - -} - -#endif // SERVERPROTOCOL_H diff --git a/SnakeServer/ServerProtocol/serverprotocol_global.h b/SnakeServer/ServerProtocol/serverprotocol_global.h deleted file mode 100644 index 2bbe388..0000000 --- a/SnakeServer/ServerProtocol/serverprotocol_global.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef SERVERPROTOCOL_GLOBAL_H -#define SERVERPROTOCOL_GLOBAL_H - -#include - -#if defined(SERVERPROTOCOL_LIBRARY) -# define SERVERPROTOCOLSHARED_EXPORT Q_DECL_EXPORT -#else -# define SERVERPROTOCOLSHARED_EXPORT Q_DECL_IMPORT -#endif - -#endif // SERVERPROTOCOL_GLOBAL_H diff --git a/SnakeServer/ServerProtocol/serverutils.cpp b/SnakeServer/ServerProtocol/serverutils.cpp deleted file mode 100644 index 19ff40f..0000000 --- a/SnakeServer/ServerProtocol/serverutils.cpp +++ /dev/null @@ -1,75 +0,0 @@ -#include "serverutils.h" -#include -#include -#include - -ServerUtils::ServerUtils() { - -} - -void ServerUtils::helpDaemon() { - - QStringList help = - {{ ""}, - { "Usage: SnakeServer-daemon.sh <[params]> "}, - { ""}, - { "Options:"}, - { " help / h : show help."}, - { " daemon / d : start like daemon."}, - { " -port (port) : start with custom port."}, - { " -address (address) : start with custom address."}, - { " -db (path/to/db.file) : start with custom db"}, - { ""}, - { "General Options:"}}; - - help.append(QuasarAppUtils::Params::getparamsHelp()); - QuasarAppUtils::Params::showHelp(help); - -} - -void ServerUtils::helpClient() { - - QStringList help = - {{ ""}, - { "Usage: Terminal.sh <[params]> "}, - { ""}, - { "Options:"}, - { " help / h : show help."}, - { " ping : debug commnad"}, - { " state : show information about deamon"}, - { " stop : stop server deamon"}, - { " -ban (address) : ban user with address"}, - { " -unban (address) : unban user with address"}, - { " -restart (address:port) : restarrt server deamon with new address and port"}, - { " -start (address:port) : start server deamon with custom address"}, - { " start : start server deamon with default address"}, - { ""}, - { "General Options:"},}; - - help.append(QuasarAppUtils::Params::getparamsHelp()); - QuasarAppUtils::Params::showHelp(help); -} - -bool ServerUtils::runDaemon() { - -#ifdef Q_OS_UNIX - if (QuasarAppUtils::Params::isEndable("daemon") || - QuasarAppUtils::Params::isEndable("d")) { - - int pid = fork(); - if (pid != 0) { - return true; - } - } - -#endif - return false; -} - -bool ServerUtils::parseParams(int argc, char *argv[]) { - if ( !QuasarAppUtils::Params::parseParams(argc, const_cast(argv))) { - return false; - } - - return true; -} diff --git a/SnakeServer/ServerProtocol/serverutils.h b/SnakeServer/ServerProtocol/serverutils.h deleted file mode 100644 index 93d56b1..0000000 --- a/SnakeServer/ServerProtocol/serverutils.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef SERVERUTILS_H -#define SERVERUTILS_H -#include "serverprotocol_global.h" - - -class SERVERPROTOCOLSHARED_EXPORT ServerUtils -{ -public: - - ServerUtils(); - static void helpDaemon(); - static void helpClient(); - /** - * @brief runDaemon - * @return true if app running like a daemon - */ - static bool runDaemon(); - static bool parseParams(int argc, char *argv[]); -}; - -#endif // SERVERUTILS_H diff --git a/SnakeServer/ServerProtocol/sp.h b/SnakeServer/ServerProtocol/sp.h deleted file mode 100644 index f01b74d..0000000 --- a/SnakeServer/ServerProtocol/sp.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef SP_H -#define SP_H - -#include "server.h" -#include "client.h" - -#endif // SP_H diff --git a/SnakeServer/ServerProtocol/spserver.h b/SnakeServer/ServerProtocol/spserver.h deleted file mode 100644 index 28fdc19..0000000 --- a/SnakeServer/ServerProtocol/spserver.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef SPSERVER_H -#define SPSERVER_H - -#include "server.h" - -#endif // SPSERVER_H diff --git a/SnakeServer/SnakeServer.pro b/SnakeServer/SnakeServer.pro deleted file mode 100644 index bdc7db7..0000000 --- a/SnakeServer/SnakeServer.pro +++ /dev/null @@ -1,12 +0,0 @@ - -TEMPLATE = subdirs -CONFIG += ordered - -SUBDIRS += \ - ServerProtocol \ - Qt-Secret \ - ClientProtocol \ - Terminal \ - Server \ - Daemon \ - serverProtocolTests \ diff --git a/SnakeServer/Terminal/Terminal.pro b/SnakeServer/Terminal/Terminal.pro deleted file mode 100644 index 37e2b3d..0000000 --- a/SnakeServer/Terminal/Terminal.pro +++ /dev/null @@ -1,31 +0,0 @@ -QT -= gui -QT += network - -CONFIG += c++14 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 - - -CONFIG(release, debug|release): { - DESTDIR = $$PWD/build/release - -} else { - DESTDIR = $$PWD/build/debug -} - -include($$PWD/../../QuasarAppLib/QuasarLib.pri) -include($$PWD/../ServerProtocol/ServerProtocol.pri) - diff --git a/SnakeServer/Terminal/main.cpp b/SnakeServer/Terminal/main.cpp deleted file mode 100644 index 3344fee..0000000 --- a/SnakeServer/Terminal/main.cpp +++ /dev/null @@ -1,99 +0,0 @@ -#include -#include -#include -#include -#include -#include - -void handleResponcke(const QVariantMap &data) { - for(auto iter = data.begin(); iter != data.end(); ++iter) { - qInfo() << QString("%0: %1").arg( iter.key()).arg(iter.value().toString()); - } - - QCoreApplication::exit(0); -} - -int main(int argc, char *argv[]) -{ - QCoreApplication a(argc, argv); - - QuasarAppUtils::Params::parseParams(argc, const_cast(argv)); - - ServerProtocol::Client cli; - - QObject::connect(&cli, &ServerProtocol::Client::sigIncommingData, - &handleResponcke); - - if (QuasarAppUtils::Params::isEndable("ping")) { - - if (!cli.ping()) { - qCritical() << "command not sendet!"; - return 1; - } - - } else if (QuasarAppUtils::Params::isEndable("help") || - QuasarAppUtils::Params::isEndable("h")) { - - ServerUtils::helpClient(); - return 0; - - } else if (QuasarAppUtils::Params::isEndable("state")) { - - if (!cli.getState()) { - qCritical() << "command not sendet!"; - return 1; - }; - - } else if (QuasarAppUtils::Params::isEndable("ban")) { - - auto address = QuasarAppUtils::Params::getStrArg("ban"); - - if (!cli.ban(QHostAddress(address))) { - qCritical() << "command not sendet!"; - return 1; - } - - } else if (QuasarAppUtils::Params::isEndable("unban")) { - - auto address = QuasarAppUtils::Params::getStrArg("unban"); - if (!cli.unBan(QHostAddress(address))) { - qCritical() << "command not sendet!"; - return 1; - } - - } else if (QuasarAppUtils::Params::isEndable("restart")) { - - QStringList address = QuasarAppUtils::Params::getStrArg("restart").split(":"); - if (!cli.restart(address.value(0), address.value(1).toUShort())) { - qCritical() << "command not sendet!"; - return 1; - } - } else if (QuasarAppUtils::Params::isEndable("stop")) { - - if (!cli.stop()) { - qCritical() << "command not sendet!"; - return 1; - } - } else if (QuasarAppUtils::Params::isEndable("start")) { - - QStringList params = QuasarAppUtils::Params::getStrArg("start").split(":"); - - if (!cli.start(params.value(0), params.value(1).toUShort())) { - qCritical() << "Server not started!"; - return 1; - } - - return 0; - } - else { - ServerUtils::helpClient(); - return 0; - } - - QTimer::singleShot(3000, [&a] { - qCritical() << "server not responsed !"; - a.exit(1); - }); - - return a.exec(); -} diff --git a/SnakeServer/serverProtocolTests/.gitignore b/SnakeServer/serverProtocolTests/.gitignore deleted file mode 100644 index fab7372..0000000 --- a/SnakeServer/serverProtocolTests/.gitignore +++ /dev/null @@ -1,73 +0,0 @@ -# This file is used to ignore files which are generated -# ---------------------------------------------------------------------------- - -*~ -*.autosave -*.a -*.core -*.moc -*.o -*.obj -*.orig -*.rej -*.so -*.so.* -*_pch.h.cpp -*_resource.rc -*.qm -.#* -*.*# -core -!core/ -tags -.DS_Store -.directory -*.debug -Makefile* -*.prl -*.app -moc_*.cpp -ui_*.h -qrc_*.cpp -Thumbs.db -*.res -*.rc -/.qmake.cache -/.qmake.stash - -# qtcreator generated files -*.pro.user* - -# xemacs temporary files -*.flc - -# Vim temporary files -.*.swp - -# Visual Studio generated files -*.ib_pdb_index -*.idb -*.ilk -*.pdb -*.sln -*.suo -*.vcproj -*vcproj.*.*.user -*.ncb -*.sdf -*.opensdf -*.vcxproj -*vcxproj.* - -# MinGW generated files -*.Debug -*.Release - -# Python byte code -*.pyc - -# Binaries -# -------- -*.dll -*.exe - diff --git a/SnakeServer/serverProtocolTests/serverProtocolTests.pro b/SnakeServer/serverProtocolTests/serverProtocolTests.pro deleted file mode 100644 index ca46eaa..0000000 --- a/SnakeServer/serverProtocolTests/serverProtocolTests.pro +++ /dev/null @@ -1,39 +0,0 @@ -QT += testlib network sql -QT -= gui - -CONFIG += qt console warn_on depend_includepath testcase -CONFIG -= app_bundle - -TEMPLATE = app - -TARGET = serverTests - -SOURCES += \ - testutils.cpp \ - tst_testsnakeserver.cpp - -CONFIG(release, debug|release): { - DESTDIR = $$PWD/build/release - -} else { - DESTDIR = $$PWD/build/debug -} - -include($$PWD/../../QuasarAppLib/QuasarLib.pri) -include($$PWD/../ServerProtocol/ServerProtocol.pri) -include($$PWD/../ClientProtocol/ClientProtocol.pri) -include($$PWD/../../SnakeUtils/SnakeUtils.pri) -include($$PWD/../../SnakeServer/Server/Server.pri) - - -HEADERS += \ - testutils.h - -deployTest.commands = cqtdeployer -bin $$DESTDIR clear -qmake $$QMAKE_QMAKE -targetDir $$PWD/deployTests -libDir $$PWD/../../ -recursiveDepth 5 - -test.depends = deployTest -test.commands = $$PWD/deployTests/serverTests.sh - -QMAKE_EXTRA_TARGETS += \ - deployTest \ - test diff --git a/SnakeServer/serverProtocolTests/testutils.cpp b/SnakeServer/serverProtocolTests/testutils.cpp deleted file mode 100644 index 060328e..0000000 --- a/SnakeServer/serverProtocolTests/testutils.cpp +++ /dev/null @@ -1,141 +0,0 @@ -#include "testutils.h" - -#include -#include -#include - -auto terminalFuncPrivate(std::function func, - ServerProtocol::Client& cli, QVariantMap* resMap = nullptr) { - bool isWork = false; - bool received = false; - - QMetaObject::Connection m_connection; - - m_connection = QObject::connect(&cli, &ServerProtocol::Client::sigIncommingData, - [&isWork, &received, &m_connection, resMap] (const QVariantMap& map) { - - isWork = !map.contains("Error"); - received = true; - - if (resMap) - *resMap = map; - - QObject::disconnect(m_connection); - }); - - - if (!func()) { - return false; - } - - if (!cli.wait(received, 1000)) { - return false; - } - - return isWork; -} - -bool clientFuncPrivate(std::function requestFunc, - ClientProtocol::Client& cli, - ClientProtocol::Command* responceCmd = nullptr, - QByteArray* responceArray = nullptr) { - - bool received = false; - QMetaObject::Connection m_connection; - m_connection = QObject::connect(&cli, &ClientProtocol::Client::sigIncommingData, - [ &received, &m_connection, responceCmd, responceArray] - (const ClientProtocol::Command cmd, - const QByteArray& data) { - - received = true; - - if (responceCmd) { - *responceCmd = cmd; - } - - if (responceArray) { - *responceArray = data; - } - - QObject::disconnect(m_connection); - - - }); - - if (!requestFunc()) { - return false; - } - - return TestUtils::wait(received, 1000); -} - -TestUtils::TestUtils() -{ - -} - -bool TestUtils::wait(const bool &forWait, int msec) { - auto curmsec = QDateTime::currentMSecsSinceEpoch() + msec; - while (curmsec > QDateTime::currentMSecsSinceEpoch() && !forWait) { - QCoreApplication::processEvents(); - } - QCoreApplication::processEvents(); - return forWait; -} - - -bool TestUtils::loginFunc( - ClientProtocol::Client &cli, - const QString& login, - const QByteArray& pass, - bool sendResult, - bool loginResult) { - - auto wraper = [&cli, login, pass](){return cli.login(login, pass);}; - bool result = clientFuncPrivate(wraper, cli); - - if (!result) { - return !sendResult; - } - - return loginResult == cli.isLogin(); -} - -bool TestUtils::registerFunc( - ClientProtocol::Client &cli, - const QString& login, - const QByteArray& pass, - bool sendResult, - bool loginResult) { - - auto wraper = [&cli, login, pass](){return cli.registration(login, pass);}; - bool result = clientFuncPrivate(wraper, cli); - - if (!result) { - return !sendResult; - } - - return loginResult == cli.isLogin(); -} - - -bool TestUtils::getState( ServerProtocol::Client& cli, QVariantMap &state) { - auto wraper = [&cli](){return cli.getState();}; - return terminalFuncPrivate(wraper, cli, &state); -} - -bool TestUtils::unBanFunc( ServerProtocol::Client& cli, const QHostAddress& address) { - auto wraper = [&cli, address](){return cli.unBan(address);}; - return terminalFuncPrivate(wraper, cli); -} - - -bool TestUtils::banFunc( ServerProtocol::Client& cli, const QHostAddress& address) { - auto wraper = [&cli, address](){return cli.ban(address);}; - return terminalFuncPrivate(wraper, cli); -} - -bool TestUtils::reconnectFunc(ClientProtocol::Client &cli) { - cli.reconnectToHost(); - return wait(cli.isOnline(), 1000); -} diff --git a/SnakeServer/serverProtocolTests/testutils.h b/SnakeServer/serverProtocolTests/testutils.h deleted file mode 100644 index a334a20..0000000 --- a/SnakeServer/serverProtocolTests/testutils.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef TESTUTILS_H -#define TESTUTILS_H - -#include -#include - -class TestUtils -{ -public: - TestUtils(); - static bool wait(const bool &forWait, int msec); - static bool loginFunc(ClientProtocol::Client &cli, - const QString &login, - const QByteArray &pass, - bool sendResult, - bool loginResult); - static bool getState(ServerProtocol::Client &cli, QVariantMap &state); - static bool unBanFunc(ServerProtocol::Client &cli, const QHostAddress &address); - static bool banFunc(ServerProtocol::Client &cli, const QHostAddress &address); - static bool reconnectFunc(ClientProtocol::Client &cli); - static bool registerFunc(ClientProtocol::Client &cli, const QString &login, - const QByteArray &pass, bool sendResult, bool loginResult); -}; - -#endif // TESTUTILS_H diff --git a/SnakeServer/serverProtocolTests/tst_testsnakeserver.cpp b/SnakeServer/serverProtocolTests/tst_testsnakeserver.cpp deleted file mode 100644 index 3096733..0000000 --- a/SnakeServer/serverProtocolTests/tst_testsnakeserver.cpp +++ /dev/null @@ -1,621 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "factorynetobjects.h" -#include "testutils.h" - -// add necessary includes here - -#define TEST_LOCAL_SERVER QString(DEFAULT_SERVER) + "Test" -#define TEST_SERVER_ADDRESS LOCAL_SNAKE_SERVER -#define TEST_SERVER_PORT 27777 - -class testSankeServer : public QObject -{ - Q_OBJECT - -private: - void testPingServerProtockol(ServerProtocol::Client &cli); - void testStateServerProtockol(ServerProtocol::Client &cli); - void testBanServerProtockol(ServerProtocol::Client& cli); - void testUnBanServerProtockol(ServerProtocol::Client& cli); - void testRestartServerProtockol(ServerProtocol::Client& cli); - void testStopServerProtockol(ServerProtocol::Client& cli); - - void testPingClientProtockol(ClientProtocol::Client& cli); - void testLogin(ClientProtocol::Client& cli); - void testUserData(ClientProtocol::Client& cli); - void testGetItem(ClientProtocol::Client& cli); - void testApplyData(ClientProtocol::Client& cli); - void testWebSockets(ClientProtocol::Client& cli); - void testBanLogin(ClientProtocol::Client &cli, ServerProtocol::Client &term); - - void testBaseSql(); - void testSqlCache(); - -public: - testSankeServer(); - - ~testSankeServer(); - -private slots: - void initTestCase(); - void clianupTestCase(); - - void testProtockols(); -// void testClientProtockol(); - void testSql(); - - -}; - -testSankeServer::testSankeServer() { - QuasarAppUtils::Params::setArg("verbose", 3); - -} - -testSankeServer::~testSankeServer() { - -} - -void testSankeServer::initTestCase() { - ClientProtocol::initClientProtockol(); -} - -void testSankeServer::clianupTestCase() { - -} - -void testSankeServer::testPingServerProtockol(ServerProtocol::Client &cli) { - - - bool isWork = false; - bool received = false; - - QMetaObject::Connection m_connection; - - m_connection = QObject::connect(&cli, &ServerProtocol::Client::sigIncommingData, - [&isWork, &received, &m_connection] (const QVariantMap& map) { - - isWork = map["res"].toString() == "Pong"; - disconnect(m_connection); - received = true; - - - }); - - QVERIFY(cli.ping()); - - QVERIFY(cli.wait(received, 1000)); - - QVERIFY(isWork); - -} - -void testSankeServer::testStateServerProtockol(ServerProtocol::Client& cli) { - QVariantMap map; - QVERIFY(TestUtils::getState(cli, map)); - -} - -void testSankeServer::testBanServerProtockol(ServerProtocol::Client& cli) { - - bool isWork = false; - bool received = false; - - QMetaObject::Connection m_connection; - - m_connection = QObject::connect(&cli, &ServerProtocol::Client::sigIncommingData, - [&isWork, &received, &m_connection] (const QVariantMap& map) { - - isWork = !map.contains("Error"); - received = true; - disconnect(m_connection); - }); - - QVERIFY(!cli.ban(QHostAddress())); - - QVERIFY(cli.ban(QHostAddress("192.192.192.192"))); - QVERIFY(cli.wait(received, 1000)); - - QVERIFY(isWork); - -} - -void testSankeServer::testUnBanServerProtockol(ServerProtocol::Client& cli) -{ - - bool isWork = false; - bool received = false; - - QMetaObject::Connection m_connection; - - m_connection = QObject::connect(&cli, &ServerProtocol::Client::sigIncommingData, - [&isWork, &received, &m_connection] (const QVariantMap& map) { - - isWork = !map.contains("Error"); - received = true; - disconnect(m_connection); - - }); - - QVERIFY(!cli.unBan(QHostAddress())); - - QVERIFY(cli.unBan(QHostAddress("192.192.192.192"))); - QVERIFY(cli.wait(received, 1000)); - - QVERIFY(isWork); - -} - -void testSankeServer::testRestartServerProtockol(ServerProtocol::Client& cli) { - - bool isWork = false; - bool received = false; - - QMetaObject::Connection m_connection; - - m_connection = QObject::connect(&cli, &ServerProtocol::Client::sigIncommingData, - [&isWork, &received, &m_connection] (const QVariantMap& map) { - - isWork = !map.contains("Error"); - received = true; - disconnect(m_connection); - - }); - - QVERIFY(!cli.restart("lolo", 0)); - - QVERIFY(!cli.restart("192.168.1.999", 0)); - QVERIFY(!cli.restart("192.168.1.99", 0)); - QVERIFY(!cli.restart("192.168.1.9", 0)); - - QVERIFY(!cli.restart("-1.168.1.999", 77)); - QVERIFY(!cli.restart("192.168.-1.99", 7777)); - - QVERIFY(cli.restart("127.168.1.9", 3456)); - - cli.wait(received, 1000); - QVERIFY(isWork); - - isWork = false; - received = false; - - m_connection = QObject::connect(&cli, &ServerProtocol::Client::sigIncommingData, - [&isWork, &received, &m_connection] (const QVariantMap& map) { - - isWork = map.value("Address") == QString("%0:%1"). - arg(TEST_SERVER_ADDRESS). - arg(TEST_SERVER_PORT) && - !map.contains("Error"); - received = true; - disconnect(m_connection); - - }); - - QVERIFY(cli.restart(TEST_SERVER_ADDRESS, TEST_SERVER_PORT)); - - cli.wait(received, 1000); - QVERIFY(isWork); - -} - -void testSankeServer::testStopServerProtockol(ServerProtocol::Client& cli) { - - bool isWork = false; - bool received = false; - - QMetaObject::Connection m_connection; - - m_connection = QObject::connect(&cli, &ServerProtocol::Client::sigIncommingData, - [&isWork, &received, &m_connection] (const QVariantMap& map) { - - isWork = !map.contains("Error"); - received = true; - disconnect(m_connection); - - }); - - QVERIFY(cli.stop()); - - cli.wait(received, 1000); - - QVERIFY(!received || isWork); -} - -void testSankeServer::testPingClientProtockol(ClientProtocol::Client &cli) { - - bool isWork = false; - bool received = false; - - QMetaObject::Connection m_connection; - - m_connection = QObject::connect(&cli, &ClientProtocol::Client::sigIncommingData, - [&isWork, &received, &m_connection] (const ClientProtocol::Command cmd, - const QByteArray&) { - - isWork = cmd == ClientProtocol::Command::Ping; - received = true; - disconnect(m_connection); - - - }); - - QVERIFY(cli.ping()); - - QVERIFY(TestUtils::wait(received, 1000)); - - QVERIFY(isWork); - -} - -void testSankeServer::testLogin(ClientProtocol::Client &cli) { - - QVERIFY(TestUtils::loginFunc(cli, "Test@gmail.com", "testpass", true, false)); - - QVERIFY(TestUtils::registerFunc(cli, "Test@gmail.com", "testpass", true, true)); - QVERIFY(TestUtils::registerFunc(cli, "Test@gmail.com", "testpass", true, false)); - - QVERIFY(TestUtils::loginFunc(cli, "Test@gmail.com", "testpass", true, true)); - QVERIFY(TestUtils::loginFunc(cli, "Test@gmail.com", "testpass2", true, false)); - QVERIFY(TestUtils::loginFunc(cli, "Test@gmail.com", "testpass", true, true)); - -} - -void testSankeServer::testBanLogin(ClientProtocol::Client &cli, ServerProtocol::Client &term) { - - QVariantMap state; - TestUtils::getState(term, state); - - for (int i = 0; i < 25 && cli.isOnline(); i++) { - QVERIFY(TestUtils::loginFunc(cli, "Test@gmail.com", "testpass2", true, false) == cli.isOnline()); - } - - TestUtils::getState(term, state); - QVERIFY(state.value("Baned List").toStringList().contains("127.0.0.1")); - QVERIFY(TestUtils::loginFunc(cli, "Test@gmail.com", "testpass", false, false)); - QVERIFY(TestUtils::loginFunc(cli, "Test123@gmail.com", "testpass2", false, false)); - - TestUtils::unBanFunc(term, QHostAddress::LocalHost); - - TestUtils::getState(term, state); - QVERIFY(!state.value("Baned List").toStringList().contains("127.0.0.1")); - - TestUtils::banFunc(term, QHostAddress::LocalHost); - - TestUtils::getState(term, state); - QVERIFY(state.value("Baned List").toStringList().contains("127.0.0.1")); - - TestUtils::unBanFunc(term, QHostAddress::LocalHost); - cli.reconnectToHost(); - - TestUtils::reconnectFunc(cli); - QVERIFY(TestUtils::loginFunc(cli, "Test@gmail.com", "testpass", true, true)); - QVERIFY(TestUtils::loginFunc(cli, "Test123@gmail.com", "testpass2", true, false)); - -} - -void testSankeServer::testUserData(ClientProtocol::Client &cli) { - - cli._token = ""; - QVERIFY(!cli.updateData()); - - cli._token = QCryptographicHash::hash("testtoken", QCryptographicHash::Sha256); - QVERIFY(cli.updateData()); -} - -void testSankeServer::testGetItem(ClientProtocol::Client &cli) { - cli._token = ""; - QVERIFY(!cli.getItem(1)); - - cli._token = QCryptographicHash::hash("testtoken", QCryptographicHash::Sha256); - QVERIFY(cli.getItem(1)); -} - -void testSankeServer::testApplyData(ClientProtocol::Client &cli) { - - cli._token = QCryptographicHash::hash("testtoken", QCryptographicHash::Sha256); - - QVERIFY(!cli.savaData(QList())); - - QList listData = {1}; - - QVERIFY(cli.savaData(listData)); - -} - -void testSankeServer::testWebSockets(ClientProtocol::Client &cli) { - - QVERIFY(cli.setSubscribe(ClientProtocol::Command::Player, true)); - QVERIFY(cli.setSubscribe(ClientProtocol::Command::Player, false)); - - -} - -void testSankeServer::testBaseSql() { - SqlDBWriter db; - QFile::remove("./test.db"); - - bool init = db.initDb("./test.db"); - - if (!init) { - QFile::remove("./test.db"); - } - - QVERIFY(init); - - ClientProtocol::Snake snake; - snake.setSpeed(10); - snake.setSkillet(QList() << 1); - snake.setSnakeClass(0); - - - // TEST ITEM - - ClientProtocol::Snake resSnake; - - QVERIFY(db.saveItem(&snake) < 0); - snake.setId(0); - int id = db.saveItem(&snake); - - QVERIFY(id == 0); - - QVERIFY(db.getItem(id).parse(resSnake)); - - QVERIFY(snake.getSpeed() == resSnake.getSpeed()); - QVERIFY(snake.getSkillet() == resSnake.getSkillet()); - QVERIFY(snake.getSnakeClass() == resSnake.getSnakeClass()); - QVERIFY(snake.getClass() == resSnake.getClass()); - QVERIFY(snake.id() == resSnake.id()); - - resSnake.setSnakeClass(10); - QVERIFY(id == db.saveItem(Item(&resSnake))); - - ClientProtocol::Snake temp; - QVERIFY(db.getItem(id).parse(temp)); - - QVERIFY(temp.getSnakeClass() == 10); - - - // TEST PLAYER - - PlayerDBData player = PlayerDBData(); - - player.setMany(10); - player.setLastOnline(1000); - player.setOnlineTime(1001); - player.setName("test"); - player.fromHexPass("FF"); - player.setGmail("test@gmail.com"); - player.setCureentSnake(0); - - QVERIFY(db.savePlayer(player) < 0); - player.setId(0); - - QVERIFY(db.savePlayer(player) < 0); - player.setCureentSnake(-1); - id = db.savePlayer(player); - QVERIFY(id == 0); - - QVERIFY(!db.saveowners(id, QSet() << 1)); - QVERIFY(db.saveowners(id, QSet() << 0)); - - QSet items; - QVERIFY(db.getAllItemsOfPalyer(id, items)); - QVERIFY(items.contains(0)); - QVERIFY(items.size() == 1); - - - player.setCureentSnake(0); - id = db.savePlayer(player); - - auto resPlayer = db.getPlayer(id); - QVERIFY(resPlayer.isValid()); - QVERIFY(player.getLastOnline() == resPlayer.getLastOnline()); - QVERIFY(player.getMany() == resPlayer.getMany()); - QVERIFY(player.getOnlineTime() == resPlayer.getOnlineTime()); - QVERIFY(player.getName() == resPlayer.getName()); - QVERIFY(player.getPass() == resPlayer.getPass()); - QVERIFY(player.getCureentSnake() == resPlayer.getCureentSnake()); - - - player.setCureentSnake(3); - - QVERIFY(db.savePlayer(player) < 0); - player.setCureentSnake(0); - player.setName("new"); - QVERIFY(db.savePlayer(player) == id); - - resPlayer = db.getPlayer(id); - - QVERIFY(resPlayer.getName() == "new"); - -} - -void testSankeServer::testSqlCache() { - SqlDBCache db; - - QFile::remove("./test2.db"); - - bool init = db.initDb("./test2.db"); - - if (!init) { - QFile::remove("./test2.db"); - } - - QVERIFY(init); - - - ClientProtocol::Snake snake; - snake.setSpeed(10); - snake.setSkillet(QList() << 1); - snake.setSnakeClass(0); - - - // TEST ITEM - - ClientProtocol::Snake resSnake; - - int id = db.saveItem(&snake); - - QVERIFY(id == 0); - snake.setId(id); - - QVERIFY(db.getItem(id).parse(resSnake)); - - QVERIFY(snake.getSpeed() == resSnake.getSpeed()); - QVERIFY(snake.getSkillet() == resSnake.getSkillet()); - QVERIFY(snake.getSnakeClass() == resSnake.getSnakeClass()); - QVERIFY(snake.getClass() == resSnake.getClass()); - QVERIFY(snake.id() == resSnake.id()); - - resSnake.setSnakeClass(10); - QVERIFY(id == db.saveItem(Item(&resSnake))); - - ClientProtocol::Snake temp; - QVERIFY(db.getItem(id).parse(temp)); - - QVERIFY(temp.getSnakeClass() == 10); - - - // TEST PLAYER - - PlayerDBData player = PlayerDBData(); - - player.setMany(10); - player.setLastOnline(1000); - player.setOnlineTime(1001); - player.setName("test"); - player.fromHexPass("FF"); - player.setGmail("test@gmail.com"); - player.setCureentSnake(0); - - QVERIFY(db.savePlayer(player) < 0); - player.setId(0); - - QVERIFY(db.savePlayer(player) < 0); - player.setCureentSnake(-1); - id = db.savePlayer(player); - QVERIFY(id == 0); - - QVERIFY(!db.getItem(id, 1)); - QVERIFY(db.getItem(id, 0)); - - player.setCureentSnake(0); - QVERIFY(db.savePlayer(player) == id); - - auto resPlayer = db.getPlayer(id); - QVERIFY(resPlayer.isValid()); - QVERIFY(player.getLastOnline() == resPlayer.getLastOnline()); - QVERIFY(player.getMany() == resPlayer.getMany()); - QVERIFY(player.getOnlineTime() == resPlayer.getOnlineTime()); - QVERIFY(player.getName() == resPlayer.getName()); - QVERIFY(player.getPass() == resPlayer.getPass()); - QVERIFY(player.getCureentSnake() == resPlayer.getCureentSnake()); - - - player.setCureentSnake(3); - - QVERIFY(db.savePlayer(player) < 0); - player.setCureentSnake(0); - player.setName("new"); - QVERIFY(db.savePlayer(player) == id); - - resPlayer = db.getPlayer(id); - - QVERIFY(resPlayer.getName() == "new"); - - - PlayerDBData second_player = PlayerDBData(); - - second_player.setMany(10); - second_player.setLastOnline(1000); - second_player.setOnlineTime(1001); - second_player.setName("test2"); - second_player.setPass("test2"); - second_player.setGmail("test2@gmail.com"); - second_player.setCureentSnake(-1); - second_player.setId(-1); - - QVERIFY(db.savePlayer(second_player) == 1); - - QVERIFY(db.moveItem(0, 1, 0)); - - QSet items; - QVERIFY(db.getAllItemsOfPalyer(1, items)); - QVERIFY(items.contains(0)); - QVERIFY(items.size() == 1); - - db.updateInterval = 0; - - db.globalUpdateDataBasePrivate(0); - -} - -void testSankeServer::testSql() { - testBaseSql(); - testSqlCache(); -} - -void testSankeServer::testProtockols() { - - int argc =0; - char * argv[] = {nullptr}; - - QCoreApplication app(argc, argv); - - auto serv = new MainServer(true, this); - QVERIFY(serv->run(TEST_SERVER_ADDRESS, TEST_SERVER_PORT , "", TEST_LOCAL_SERVER)); - ServerProtocol::Client cliS(TEST_LOCAL_SERVER); - ClientProtocol::Client cliC(TEST_SERVER_ADDRESS, TEST_SERVER_PORT); - - QVERIFY(TestUtils::wait(cliC.isOnline(), 1000)); - - QTimer::singleShot(0, [this, &app, &cliS, &cliC]() { - - // test client protockol - testPingClientProtockol(cliC); - - testLogin(cliC); - testGetItem(cliC); - testUserData(cliC); - testApplyData(cliC); - testWebSockets(cliC); - testBanLogin(cliC, cliS); - - // test server protockiol - testPingServerProtockol(cliS); - testStateServerProtockol(cliS); - testBanServerProtockol(cliS); - testUnBanServerProtockol(cliS); - testRestartServerProtockol(cliS); - testStopServerProtockol(cliS); - app.exit(0); - }); - - app.exec(); - -} - -//void testSankeServer::testClientProtockol() { - -// auto serv = new ClientProtocol::Server(this); -// QVERIFY(serv->run(TEST_SERVER_ADDRESS, TEST_SERVER_PORT)); - - -//} - -QTEST_APPLESS_MAIN(testSankeServer) - -#include "tst_testsnakeserver.moc" diff --git a/SnakeUtils/SnakeUtils.pri b/SnakeUtils/SnakeUtils.pri deleted file mode 100644 index 8d5f78e..0000000 --- a/SnakeUtils/SnakeUtils.pri +++ /dev/null @@ -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(SNAKEUTILS_LIB):error("SnakeUtils.pri already included") -SNAKEUTILS_LIB = 1 - -#DEPENDS -CONFIG(release, debug|release): { - SNAKEUTILS_LIB_OUTPUT_DIR="$$PWD/build/release" -} else { - SNAKEUTILS_LIB_OUTPUT_DIR="$$PWD/build/debug" -} - -LIBS += -L$$SNAKEUTILS_LIB_OUTPUT_DIR -lSnakeUtils - -INCLUDEPATH += "$$PWD/" - - - diff --git a/SnakeUtils/SnakeUtils.pro b/SnakeUtils/SnakeUtils.pro deleted file mode 100644 index 4c5d9e4..0000000 --- a/SnakeUtils/SnakeUtils.pro +++ /dev/null @@ -1,44 +0,0 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2019-02-19T14:37:16 -# -#------------------------------------------------- - -QT -= gui - -TARGET = SnakeUtils -TEMPLATE = lib - -DEFINES += SNAKEUTILS_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 += \ - snakeutils.cpp \ - lvls.cpp - -HEADERS += \ - snakeutils.h \ - snakeutils_global.h \ - lvls.h - -CONFIG(release, debug|release): { - DESTDIR = $$PWD/build/release - -} else { - DESTDIR = $$PWD/build/debug -} - -include($$PWD/../QuasarAppLib/QuasarLib.pri) - -DISTFILES += \ - SnakeUtils.pri diff --git a/SnakeUtils/lvls.cpp b/SnakeUtils/lvls.cpp deleted file mode 100644 index 007b9d5..0000000 --- a/SnakeUtils/lvls.cpp +++ /dev/null @@ -1,11 +0,0 @@ -#include "lvls.h" - -QList lvls { - WorldRules{{"Long", 500}, {"Box", 2}, {"Spead", 10}, {"BackGroundItem", 10}}, - WorldRules{{"Long", 1000}, {"Box", 4}, {"Spead", 10}, {"BackGroundItem", 10}}, - WorldRules{{"Long", 2000}, {"Box", 8}, {"Spead", 10}, {"BackGroundItem", 10}}, - WorldRules{{"Long", 4000}, {"Box", 16}, {"Spead", 10}, {"BackGroundItem", 10}}, - WorldRules{{"Long", 8000}, {"Box", 32}, {"Spead", 10}, {"BackGroundItem", 10}}, - WorldRules{{"Long", 16000}, {"Box", 64}, {"Spead", 10}, {"BackGroundItem", 10}} - -}; diff --git a/SnakeUtils/lvls.h b/SnakeUtils/lvls.h deleted file mode 100644 index dfcebf7..0000000 --- a/SnakeUtils/lvls.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef LVLS_H -#define LVLS_H - -#include -#include "snakeutils.h" - -extern QList lvls; - -#endif // LVLS_H diff --git a/SnakeUtils/snakeutils.cpp b/SnakeUtils/snakeutils.cpp deleted file mode 100644 index 3570290..0000000 --- a/SnakeUtils/snakeutils.cpp +++ /dev/null @@ -1,3 +0,0 @@ -#include "snakeutils.h" - - diff --git a/SnakeUtils/snakeutils.h b/SnakeUtils/snakeutils.h deleted file mode 100644 index b0fcc70..0000000 --- a/SnakeUtils/snakeutils.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef SNAKEUTILS_H -#define SNAKEUTILS_H - -#include "snakeutils_global.h" - -#include -#include -#include - -/** - * @brief WorldRules - * this map conteins: - * 1. list of generated objects and they count. - * 2. long of world (Long), - * 3. spead of world (Spead), - * !!!Note: all object show on map alltime. - */ -typedef QMap WorldRules; - - -#endif // SNAKEUTILS_H diff --git a/SnakeUtils/snakeutils_global.h b/SnakeUtils/snakeutils_global.h deleted file mode 100644 index 2dfb563..0000000 --- a/SnakeUtils/snakeutils_global.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef SNAKEUTILS_GLOBAL_H -#define SNAKEUTILS_GLOBAL_H - -#include - -#if defined(SNAKEUTILS_LIBRARY) -# define SNAKEUTILSSHARED_EXPORT Q_DECL_EXPORT -#else -# define SNAKEUTILSSHARED_EXPORT Q_DECL_IMPORT -#endif - -#endif // SNAKEUTILS_GLOBAL_H diff --git a/doc/calassdiagramm.png b/doc/calassdiagramm.png deleted file mode 100644 index 1d377d112399b905771d58df6282b26dfe06828e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 53782 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¥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 C?8VXm diff --git a/doc/calassdiagramm.qmodel b/doc/calassdiagramm.qmodel deleted file mode 100644 index b1e412f..0000000 --- a/doc/calassdiagramm.qmodel +++ /dev/null @@ -1,3829 +0,0 @@ - - - - {879592ec-be4e-4128-b462-28a6f1792f3d} - - - - - - - - {a8ddc489-bd35-401c-9439-dadd43dd4801} - - - CalassDiagramm - - - - - - - {021eead1-b7d6-402e-b115-138ba08b5627} - - - - - - - - - - {021eead1-b7d6-402e-b115-138ba08b5627} - - - CalassDiagramm - - - - - - - - - - - - {8533065c-faec-4867-be02-303ff882ec8f} - - - {1040fc09-15a3-4397-ace6-f04c394b0156} - - - interface - - - QObject - x:120;y:235 - x:-40;y:-30;w:80;h:60 - false - 0 - - - - - - - - - - - {920672dd-f71c-4125-a1b8-06c898093caa} - - - BackEnd - x:570;y:480 - x:-505;y:-315;w:1010;h:630 - - - - - - - - - - - {119b6d7e-cc59-4ee2-bd10-dd4d5182e0cc} - - - {30cf1880-ec6a-418d-a40f-bc737c45b215} - Back-End - Snake - x:245;y:550 - x:-40;y:-30;w:80;h:60 - 0 - - - - - - - - - - - - - {10f8a631-f809-46d6-b191-619b8cbef3b2} - - - {8b2a4c22-5e2e-4f4e-a556-31ec6a3b5c8c} - - - interface - - - Back-End - BaseClass - x:360;y:225 - x:-20;y:-20;w:40;h:40 - 0 - - - - - - - - - - - - - {04511117-b195-4c0d-a09b-a54fa402d241} - - - {99e50838-a9fb-4d59-b7f1-6756f84c227e} - Back-End - Box - x:580;y:420 - x:-40;y:-30;w:80;h:60 - 0 - - - - - - - - - - - - - {4f1e9064-853b-420c-a6e7-16e67ac57a3f} - - - {5f23ec13-fb38-44b8-9d85-69bd3db54622} - Back-End - Controller - x:415;y:660 - x:-310;y:-35;w:620;h:70 - false - 0 - - - - - - - - - - - - - {562d0631-7314-4b8a-87c7-502cea55e5ad} - - - {aeea301c-41ac-473b-be41-27e1ca908383} - Back-End - GuiObject - x:250;y:330 - x:-40;y:-30;w:80;h:60 - 0 - - - - - - - - - - - - - {546c8f00-0253-4a2c-b2ef-a9fbe54fa45f} - - - {0a047959-18af-49f9-8302-dae955310bf3} - Back-End - Head - x:130;y:425 - x:-40;y:-30;w:80;h:60 - 0 - - - - - - - - - - - - - {bb2c76a5-c625-4ed5-a106-dd8ec51463d3} - - - {200e5924-5aea-4e63-bffb-079d5b19e2ea} - Back-End - ItemWorld - x:365;y:420 - x:-40;y:-30;w:80;h:60 - 0 - - - - - - - - - - - - - {d50a158a-7f99-4ee8-bb58-695e265c0047} - - - {816ce4f8-1346-42a6-b8fe-24410c5375fb} - Back-End - World - x:465;y:555 - x:-40;y:-30;w:80;h:60 - 0 - - - - - - - - - - - - - {1590bdda-2951-4077-b37b-2cc03cd4e8e5} - - - {a9e10139-9334-492d-87b7-6e49c7d4bd57} - {8533065c-faec-4867-be02-303ff882ec8f} - {562d0631-7314-4b8a-87c7-502cea55e5ad} - - - - - - - - - - - - - {19ca12fd-ae84-4bb6-99f4-e55ca9ed22ca} - - - {8979dd4f-44f2-4a99-ab0a-ab35449575de} - {10f8a631-f809-46d6-b191-619b8cbef3b2} - {562d0631-7314-4b8a-87c7-502cea55e5ad} - - - - - - - - - - - - - {67cf62d9-ab1e-40cb-a467-ff68582796ef} - - - {34d9eb76-1aca-4665-b370-da094719f939} - {10f8a631-f809-46d6-b191-619b8cbef3b2} - {119b6d7e-cc59-4ee2-bd10-dd4d5182e0cc} - - - - - - - - - - - - - {f2e337d3-c749-4670-bf4b-2b965eb7191b} - - - {eca89a79-7b49-4ca2-a8f1-06457d355da4} - {10f8a631-f809-46d6-b191-619b8cbef3b2} - {d50a158a-7f99-4ee8-bb58-695e265c0047} - - - - - - - - - - - - - {30cfb213-d828-45e8-9942-f12a6039b210} - - - {93b313cb-9107-400e-9db4-95184e9f1219} - {d50a158a-7f99-4ee8-bb58-695e265c0047} - {bb2c76a5-c625-4ed5-a106-dd8ec51463d3} - - - - - * - true - 1 - - - - - - - - - - - - - {c159d283-9292-49bb-9dfc-f9b1b5f5cd54} - - - {e2d6cc26-33b0-4c70-8285-7d6f384d032c} - {bb2c76a5-c625-4ed5-a106-dd8ec51463d3} - {04511117-b195-4c0d-a09b-a54fa402d241} - - - - - - - - - - - - - {9bca1d89-89ca-4dea-9ad8-a103f10700af} - - - {e39576a4-e9c6-4d61-8021-ea8f1db5f0ed} - {119b6d7e-cc59-4ee2-bd10-dd4d5182e0cc} - {546c8f00-0253-4a2c-b2ef-a9fbe54fa45f} - - - - - * - true - 1 - - - - - - - - - - - - - {1552add6-397c-44c6-a599-2f6f35b2c725} - - - {20301be4-f051-48ab-b29a-62e92bb98ddc} - {562d0631-7314-4b8a-87c7-502cea55e5ad} - {546c8f00-0253-4a2c-b2ef-a9fbe54fa45f} - - - - - - - - - - - - - {714fa5eb-fe3a-4a15-9ee5-853e6888ef36} - - - {bb48e216-f61d-420b-a255-9564ccca4bd1} - {562d0631-7314-4b8a-87c7-502cea55e5ad} - {bb2c76a5-c625-4ed5-a106-dd8ec51463d3} - - - - - - - - - - - - - {7579536a-5ed8-4790-8fe5-069e48a0fe81} - - - {01fc145c-4b60-43f5-812c-5111cd13b3e7} - {4f1e9064-853b-420c-a6e7-16e67ac57a3f} - {d50a158a-7f99-4ee8-bb58-695e265c0047} - - - - - * - true - 2 - - - - - - - - - - - - - {f094a7fa-3567-46ce-a66f-0336da69a0d3} - - - {6dc1a08a-ef6e-460a-8c87-fecc3d96c1be} - {d50a158a-7f99-4ee8-bb58-695e265c0047} - {119b6d7e-cc59-4ee2-bd10-dd4d5182e0cc} - - - - - * - true - 2 - - - - - - - - - - - {09729430-478a-49a8-a6ec-b20e268a4f26} - - - FrontEnd - x:570;y:930 - x:-505;y:-95;w:1010;h:190 - - - - - - - - - - - {ae400e64-6ec3-4b9b-abb5-8a03b4d2c97e} - - - {c856b2e6-83cc-4d3a-a603-7f18d989b064} - {8533065c-faec-4867-be02-303ff882ec8f} - {4f1e9064-853b-420c-a6e7-16e67ac57a3f} - - - - - - - - - - - - - {6019d1e1-0b02-49d6-a487-15add6fc001d} - - - {eb954854-9b5e-4ea7-9237-b590bfe8e8c6} - Back-End - GuiObjectFactory - x:595;y:555 - x:-55;y:-30;w:110;h:60 - 0 - - - - - - - - - - - - - {e82376a9-680e-49b9-968f-77b67468b31e} - - - {3f96cc10-43e2-4aef-96c0-63ce559963d9} - {d50a158a-7f99-4ee8-bb58-695e265c0047} - {6019d1e1-0b02-49d6-a487-15add6fc001d} - - - - - 1 - true - 2 - - - - - - - - - - - - - {3d1f0043-257f-4f06-aaf4-d5096b619766} - - - {eac9ab00-70e1-4346-a40e-a09dfa347d20} - Diff - x:205;y:745 - x:-100;y:-30;w:200;h:60 - false - 6 - - - - - - - - - - - - - {75539dce-7e03-41df-8e75-da9b3f9ed58a} - - - {984ace8f-ae77-4590-aa60-030b60fddefa} - {3d1f0043-257f-4f06-aaf4-d5096b619766} - {4f1e9064-853b-420c-a6e7-16e67ac57a3f} - - - 1 - - - - - - - - - - - {2bde9796-53db-4a67-8944-252d87de8730} - - - {7e3f8bf1-3d3a-44d6-8888-e9cae3473683} - ProfileViewItems - MainMenuModel - x:770;y:555 - x:-100;y:-30;w:200;h:60 - false - 0 - - - - - - - - - - - - - {ccc76006-4713-4d75-a8ad-178e47e4a791} - - - {49cf0ec6-7362-4c19-a129-cfc0bb8179b8} - {4f1e9064-853b-420c-a6e7-16e67ac57a3f} - {2bde9796-53db-4a67-8944-252d87de8730} - - - - - 1 - true - 2 - - - - - - - - - - - - - {3149b367-e4a8-4582-9868-2c08d3059097} - - - {8c05ffe4-0340-4093-88f9-6570795713f9} - ProfileViewItems - UserView - x:975;y:410 - x:-40;y:-30;w:80;h:60 - 0 - - - - - - - - - - - - - {279317e4-324c-41b7-9c26-f4f3c7b9c8ea} - - - {c5334666-c506-46b1-9ae1-e7a29630bd03} - {2bde9796-53db-4a67-8944-252d87de8730} - {3149b367-e4a8-4582-9868-2c08d3059097} - - - - - 1 - true - 2 - - - - - - - - - - - - - {8c5183be-0767-4399-a856-633d562f035a} - - - {eb0b85b6-658d-4eff-a2e6-cd2ae7befd6d} - ClientProtocol - Client - x:770;y:415 - x:-40;y:-35;w:80;h:70 - 0 - - - ClientProtocol - - - - - - - - - - - {a55f34e3-8354-4588-9948-498b3d97b05f} - - - {7a93a742-d00d-4e04-80fd-f1739a191669} - {2bde9796-53db-4a67-8944-252d87de8730} - {8c5183be-0767-4399-a856-633d562f035a} - - - - - 1 - true - 2 - - - - - - - - - - - - - {3c479b36-a43f-46ba-a822-2766c16905f2} - - - {27cb7b78-cb1d-4418-8f91-025824839a1b} - ProfileViewItems - PlayerClientData - x:900;y:320 - x:-55;y:-35;w:110;h:70 - 0 - - - - - - - - - - - - - {ff44016a-db4c-4ec0-9281-f0af1a179097} - - - {2c238bae-21c1-46c4-9468-86d8d0bb9115} - {2bde9796-53db-4a67-8944-252d87de8730} - {3c479b36-a43f-46ba-a822-2766c16905f2} - - - - - * - true - 1 - - - - - - - - - - - - - {7125e61b-fb26-40bf-9ba3-3c365f5cf02e} - - - {38c55945-27ed-4d5c-9d38-761b84e9ae80} - Objects - Player - x:900;y:220 - x:-40;y:-35;w:80;h:70 - 0 - - - ClientProtocol - - - - - - - - - - - {800dddfe-52a2-41bb-be8a-462423cacaa0} - - - {238a4ada-2b3e-4084-8e38-e027f0d6482c} - {7125e61b-fb26-40bf-9ba3-3c365f5cf02e} - {3c479b36-a43f-46ba-a822-2766c16905f2} - - - - - - - - - - - - - {e1b86e20-4573-40e5-8728-aa9bf9f7ce69} - - - {6ae5bde6-f310-4c85-91e1-0176aebad87e} - Front-End - MainMenu - x:770;y:910 - x:-60;y:-30;w:120;h:60 - 0 - - - - - - - - - - - - - {a9d28e34-4f36-46a0-abd2-d3a20c864c13} - - - {13cf44a9-a6cc-4438-9271-a36888be9ec6} - {2bde9796-53db-4a67-8944-252d87de8730} - {e1b86e20-4573-40e5-8728-aa9bf9f7ce69} - - - 2 - - - - - - - - - - - {ccc95b75-32bd-4416-883b-7f599c850d7b} - - - {4b5e2d40-ee29-49f3-8812-f8e1eb741f03} - Front-End - UserView - x:975;y:910 - x:-55;y:-30;w:110;h:60 - 0 - - - - - - - - - - - - - {02890804-fedb-4650-8693-caeef3cc10ce} - - - {dbe663e7-34c5-4076-b664-a19e63ab0d7f} - Front-End - Scene - x:300;y:910 - x:-190;y:-30;w:380;h:60 - false - 0 - - - - - - - - - - - - - {5be1f4f5-c5e6-43c3-b120-3a3017e9a304} - - - {b7f55ebe-6eaf-4c19-8061-cd6d747a25fc} - {ccc95b75-32bd-4416-883b-7f599c850d7b} - {e1b86e20-4573-40e5-8728-aa9bf9f7ce69} - - - - - - - - - - - - - {be64c2a0-ec56-4f58-b99a-dfb538a9a02f} - - - {754eb6af-590d-4f81-b3ea-03a9e02bc96c} - {ccc95b75-32bd-4416-883b-7f599c850d7b} - {3149b367-e4a8-4582-9868-2c08d3059097} - - - 2 - - - - - - - - - - - {05b4a353-86f1-4b5c-923b-1f71c0a0a461} - - - {fb37e45e-7c18-4d56-aa70-be4b9c8f87a3} - {4f1e9064-853b-420c-a6e7-16e67ac57a3f} - {e1b86e20-4573-40e5-8728-aa9bf9f7ce69} - - - - - - - - - - - - - {bd67731c-6f06-40d5-8872-3076980e2dc4} - - - {fa7a0308-4c69-4938-844f-fa3049ef7dd5} - {4f1e9064-853b-420c-a6e7-16e67ac57a3f} - {02890804-fedb-4650-8693-caeef3cc10ce} - - - - - - - - - - - - - {954775d1-547a-4f10-84d9-1e676c9b1e60} - - - {3f014984-cf29-47b1-8dd7-1b10e238a6e2} - {3d1f0043-257f-4f06-aaf4-d5096b619766} - {02890804-fedb-4650-8693-caeef3cc10ce} - - - 2 - - - - - - - - - - - {f6d0ad9b-9f95-4299-8150-9c229fabcf04} - - - {cf29b293-1a04-45da-be97-39265f097b77} - {e1b86e20-4573-40e5-8728-aa9bf9f7ce69} - {02890804-fedb-4650-8693-caeef3cc10ce} - - - - - - - - 1564387986182 - General - - - - - - - - - - {027cbd47-7e34-4f5c-b11e-f063a6775cac} - - - - - - - - {027cbd47-7e34-4f5c-b11e-f063a6775cac} - - - Создать комонент - - - - - - - - - - {1040fc09-15a3-4397-ace6-f04c394b0156} - - - - - - - - {1040fc09-15a3-4397-ace6-f04c394b0156} - - - interface - - - - - QObject - - - - - - - {a9e10139-9334-492d-87b7-6e49c7d4bd57} - - - - - - - - {a9e10139-9334-492d-87b7-6e49c7d4bd57} - - - {1040fc09-15a3-4397-ace6-f04c394b0156} - {aeea301c-41ac-473b-be41-27e1ca908383} - - - - - - - - - - {c856b2e6-83cc-4d3a-a603-7f18d989b064} - - - - - - - - {c856b2e6-83cc-4d3a-a603-7f18d989b064} - - - {1040fc09-15a3-4397-ace6-f04c394b0156} - {5f23ec13-fb38-44b8-9d85-69bd3db54622} - - - - - - - - - - - - - - - - - - - - - {38bd349e-2976-43f4-8230-7c565b17d286} - - - - - - - - {38bd349e-2976-43f4-8230-7c565b17d286} - - - BaseClass - - - - - - - - - - {aa8272fc-6662-4c64-bf33-449dd6c537f7} - - - - - - - - {aa8272fc-6662-4c64-bf33-449dd6c537f7} - - - GuiObject - - - - - - - - - - {f3676e6f-ccb1-496a-b512-b6cd1caf474c} - - - - - - - - {f3676e6f-ccb1-496a-b512-b6cd1caf474c} - - - ItemWorld - - - - - - - - - - {e9bcc6d4-20a9-4ae5-8077-c76bfab556d5} - - - - - - - - {e9bcc6d4-20a9-4ae5-8077-c76bfab556d5} - 1 - - - Back-End - - - - - - - {30cf1880-ec6a-418d-a40f-bc737c45b215} - - - - - - - - {30cf1880-ec6a-418d-a40f-bc737c45b215} - 1 - - - Snake - - - - - - - {e39576a4-e9c6-4d61-8021-ea8f1db5f0ed} - - - - - - - - {e39576a4-e9c6-4d61-8021-ea8f1db5f0ed} - - - {30cf1880-ec6a-418d-a40f-bc737c45b215} - {0a047959-18af-49f9-8302-dae955310bf3} - - - - - * - true - 1 - - - - - - - - - - {6dc1a08a-ef6e-460a-8c87-fecc3d96c1be} - - - - - - - - {6dc1a08a-ef6e-460a-8c87-fecc3d96c1be} - - - {816ce4f8-1346-42a6-b8fe-24410c5375fb} - {30cf1880-ec6a-418d-a40f-bc737c45b215} - - - - - * - true - 2 - - - - - - - - - - - - - - - - - - - - - {7f5efa28-2448-403f-aac1-1daed0a402bd} - - - - - - - - {7f5efa28-2448-403f-aac1-1daed0a402bd} - 1 - - - Baseclass - - - - - - - - - - {8b2a4c22-5e2e-4f4e-a556-31ec6a3b5c8c} - - - - - - - - {8b2a4c22-5e2e-4f4e-a556-31ec6a3b5c8c} - 1 - - - interface - - - - - BaseClass - - - - - - - {8979dd4f-44f2-4a99-ab0a-ab35449575de} - - - - - - - - {8979dd4f-44f2-4a99-ab0a-ab35449575de} - - - {8b2a4c22-5e2e-4f4e-a556-31ec6a3b5c8c} - {aeea301c-41ac-473b-be41-27e1ca908383} - - - - - - - - - - {34d9eb76-1aca-4665-b370-da094719f939} - - - - - - - - {34d9eb76-1aca-4665-b370-da094719f939} - - - {8b2a4c22-5e2e-4f4e-a556-31ec6a3b5c8c} - {30cf1880-ec6a-418d-a40f-bc737c45b215} - - - - - - - - - - {eca89a79-7b49-4ca2-a8f1-06457d355da4} - - - - - - - - {eca89a79-7b49-4ca2-a8f1-06457d355da4} - - - {8b2a4c22-5e2e-4f4e-a556-31ec6a3b5c8c} - {816ce4f8-1346-42a6-b8fe-24410c5375fb} - - - - - - - - - - - - - - - - - - - - - {99e50838-a9fb-4d59-b7f1-6756f84c227e} - - - - - - - - {99e50838-a9fb-4d59-b7f1-6756f84c227e} - 1 - - - Box - - - - - - - - - - {5f23ec13-fb38-44b8-9d85-69bd3db54622} - - - - - - - - {5f23ec13-fb38-44b8-9d85-69bd3db54622} - 1 - - - Controller - - - - - - - {fe475b66-3ea8-4a72-be84-1020884bfb0c} - - - - - - - - {fe475b66-3ea8-4a72-be84-1020884bfb0c} - - - {5f23ec13-fb38-44b8-9d85-69bd3db54622} - {0e9152a2-43b7-4021-b067-51b48d88bf23} - - - 1 - - - - - - - - {60b51413-5ac6-4650-a8e0-ffa3c3d7b0a2} - - - - - - - - {60b51413-5ac6-4650-a8e0-ffa3c3d7b0a2} - - - {5f23ec13-fb38-44b8-9d85-69bd3db54622} - {8d34e552-fa29-4a02-97fe-348f6d12b5cf} - - - - - - - - - - {b4071def-6543-48b9-80a5-73d360a8a00f} - - - - - - - - {b4071def-6543-48b9-80a5-73d360a8a00f} - - - {5f23ec13-fb38-44b8-9d85-69bd3db54622} - {eac9ab00-70e1-4346-a40e-a09dfa347d20} - - - - - - - - - - {49cf0ec6-7362-4c19-a129-cfc0bb8179b8} - - - - - - - - {49cf0ec6-7362-4c19-a129-cfc0bb8179b8} - - - {5f23ec13-fb38-44b8-9d85-69bd3db54622} - {7e3f8bf1-3d3a-44d6-8888-e9cae3473683} - - - - - 1 - true - 2 - - - - - - - - - - {fb37e45e-7c18-4d56-aa70-be4b9c8f87a3} - - - - - - - - {fb37e45e-7c18-4d56-aa70-be4b9c8f87a3} - - - {5f23ec13-fb38-44b8-9d85-69bd3db54622} - {6ae5bde6-f310-4c85-91e1-0176aebad87e} - - - - - - - - - - {fa7a0308-4c69-4938-844f-fa3049ef7dd5} - - - - - - - - {fa7a0308-4c69-4938-844f-fa3049ef7dd5} - - - {5f23ec13-fb38-44b8-9d85-69bd3db54622} - {dbe663e7-34c5-4076-b664-a19e63ab0d7f} - - - - - - - - - - - - - - - - - - - - - {aeea301c-41ac-473b-be41-27e1ca908383} - - - - - - - - {aeea301c-41ac-473b-be41-27e1ca908383} - 1 - - - GuiObject - - - - - - - {20301be4-f051-48ab-b29a-62e92bb98ddc} - - - - - - - - {20301be4-f051-48ab-b29a-62e92bb98ddc} - - - {aeea301c-41ac-473b-be41-27e1ca908383} - {0a047959-18af-49f9-8302-dae955310bf3} - - - - - - - - - - {bb48e216-f61d-420b-a255-9564ccca4bd1} - - - - - - - - {bb48e216-f61d-420b-a255-9564ccca4bd1} - - - {aeea301c-41ac-473b-be41-27e1ca908383} - {200e5924-5aea-4e63-bffb-079d5b19e2ea} - - - - - - - - - - - - - - - - - - {782195a1-d585-4f3b-bab8-45a87b3b2040} - 2 - 1 - double x, y, angle - - - - - {cc592760-598c-435d-a14e-1154f6fc21ee} - 2 - 1 - QString texture - - - - - {eba85116-d6ff-4873-b2a0-33ac89e28005} - 2 - 1 - double sizeX, sizeY, radius - - - - - {5329a2aa-4c85-4b44-be9f-9a302dc6d148} - 1 - 2 - GuiObject(QObject *ptr = nullptr) - - - - - {c8f587b9-7719-4a67-8421-f742a9726789} - 1 - 2 - 4 - double getAngle() - - - - - {746bac64-782f-4f2f-a8b9-7ecb254da556} - 1 - 2 - void setAngle(double angle) - - - - - {9589ed54-f743-4fc5-bdff-964a5e6a964a} - 1 - 2 - 4 - double getY() - - - - - {b49cea07-c98b-41b5-b5a7-5ff4b0b7f49a} - 1 - 2 - void setY(double y) - - - - - {ef6a5043-5b40-4aac-b68a-7894c2412d27} - 1 - 2 - 4 - double getX() - - - - - {4e283c49-d384-45d2-96fa-6207bf1643fe} - 1 - 2 - void setX(double x) - - - - - {e13ab166-d212-4975-8e2a-18d358facf05} - 1 - 2 - 4 - QString getTexture() - - - - - {52935fab-5720-4c11-ace2-5d138847c67e} - 1 - 2 - void setTexture(const QString &texture) - - - - - - - - - - - - {0a047959-18af-49f9-8302-dae955310bf3} - - - - - - - - {0a047959-18af-49f9-8302-dae955310bf3} - 1 - - - Head - - - - - - - - - - {200e5924-5aea-4e63-bffb-079d5b19e2ea} - - - - - - - - {200e5924-5aea-4e63-bffb-079d5b19e2ea} - 1 - - - ItemWorld - - - - - - - {e2d6cc26-33b0-4c70-8285-7d6f384d032c} - - - - - - - - {e2d6cc26-33b0-4c70-8285-7d6f384d032c} - - - {200e5924-5aea-4e63-bffb-079d5b19e2ea} - {99e50838-a9fb-4d59-b7f1-6756f84c227e} - - - - - - - - - - - - - - - - - - - - - {816ce4f8-1346-42a6-b8fe-24410c5375fb} - - - - - - - - {816ce4f8-1346-42a6-b8fe-24410c5375fb} - 1 - - - World - - - - - - - {93b313cb-9107-400e-9db4-95184e9f1219} - - - - - - - - {93b313cb-9107-400e-9db4-95184e9f1219} - - - {816ce4f8-1346-42a6-b8fe-24410c5375fb} - {200e5924-5aea-4e63-bffb-079d5b19e2ea} - - - - - * - true - 1 - - - - - - - - - - {01fc145c-4b60-43f5-812c-5111cd13b3e7} - - - - - - - - {01fc145c-4b60-43f5-812c-5111cd13b3e7} - - - {5f23ec13-fb38-44b8-9d85-69bd3db54622} - {816ce4f8-1346-42a6-b8fe-24410c5375fb} - - - - - * - true - 2 - - - - - - - - - - - - - - - - - - - - - {80ceace3-3861-4a5f-a0f6-429cb8bd6722} - - - - - - - - {80ceace3-3861-4a5f-a0f6-429cb8bd6722} - 1 - - - Box - - - - - - - {843d1d44-a098-4da0-bab2-e2b7dd55e820} - - - - - - - - {843d1d44-a098-4da0-bab2-e2b7dd55e820} - 1 - - - include - - - - - {80ceace3-3861-4a5f-a0f6-429cb8bd6722} - {98ea3b76-86aa-47e5-a88d-b16e641d66bf} - - - - - - - - - - - - - - - - - - - - - {d6363cef-4687-44ee-b116-97b60b423dd8} - - - - - - - - {d6363cef-4687-44ee-b116-97b60b423dd8} - 1 - - - Controller - - - - - - - {cf19fc60-8b43-4bdc-8ec0-7c162cecbfc1} - - - - - - - - {cf19fc60-8b43-4bdc-8ec0-7c162cecbfc1} - 1 - - - include - - - - - {d6363cef-4687-44ee-b116-97b60b423dd8} - {bf9b8bf1-9645-4bc0-ad34-e2118d42f0b9} - - - - - - - - - - {4d9ab9bb-a5f3-4a45-841c-c05ba8a60919} - - - - - - - - {4d9ab9bb-a5f3-4a45-841c-c05ba8a60919} - 1 - - - include - - - - - {d6363cef-4687-44ee-b116-97b60b423dd8} - {387c7293-83b9-467c-91e4-5089c6b49b07} - - - - - - - - - - - - - - - - - - - - - {7eb487d0-f596-4510-a04a-26333cb016f4} - - - - - - - - {7eb487d0-f596-4510-a04a-26333cb016f4} - 1 - - - Guiobject - - - - - - - {ad8540f4-ac3c-44c6-97af-7de88cc7d5be} - - - - - - - - {ad8540f4-ac3c-44c6-97af-7de88cc7d5be} - 1 - - - include - - - - - {7eb487d0-f596-4510-a04a-26333cb016f4} - {7f5efa28-2448-403f-aac1-1daed0a402bd} - - - - - - - - - - - - - - - - - - - - - {21b0be17-d1b8-44cd-9cfb-cc5262418f35} - - - - - - - - {21b0be17-d1b8-44cd-9cfb-cc5262418f35} - 1 - - - Head - - - - - - - {0f966f2d-3828-45bf-8711-816b81eb1016} - - - - - - - - {0f966f2d-3828-45bf-8711-816b81eb1016} - 1 - - - include - - - - - {21b0be17-d1b8-44cd-9cfb-cc5262418f35} - {7eb487d0-f596-4510-a04a-26333cb016f4} - - - - - - - - - - - - - - - - - - - - - {98ea3b76-86aa-47e5-a88d-b16e641d66bf} - - - - - - - - {98ea3b76-86aa-47e5-a88d-b16e641d66bf} - 1 - - - Itemworld - - - - - - - {3d234f89-0492-4abc-bbde-9245ff4f5a3b} - - - - - - - - {3d234f89-0492-4abc-bbde-9245ff4f5a3b} - 1 - - - include - - - - - {98ea3b76-86aa-47e5-a88d-b16e641d66bf} - {7eb487d0-f596-4510-a04a-26333cb016f4} - - - - - - - - - - - - - - - - - - - - - {acee2132-ede7-46b3-9748-8905cddf12dd} - - - - - - - - {acee2132-ede7-46b3-9748-8905cddf12dd} - 1 - - - Main - - - - - - - - - - {bf9b8bf1-9645-4bc0-ad34-e2118d42f0b9} - - - - - - - - {bf9b8bf1-9645-4bc0-ad34-e2118d42f0b9} - 1 - - - Snake - - - - - - - {59123ee8-b20a-46f1-b5ae-67210c3c90dd} - - - - - - - - {59123ee8-b20a-46f1-b5ae-67210c3c90dd} - 1 - - - include - - - - - {bf9b8bf1-9645-4bc0-ad34-e2118d42f0b9} - {21b0be17-d1b8-44cd-9cfb-cc5262418f35} - - - - - - - - - - {1b87ae74-42ed-4c36-8402-da96464aa371} - - - - - - - - {1b87ae74-42ed-4c36-8402-da96464aa371} - 1 - - - include - - - - - {bf9b8bf1-9645-4bc0-ad34-e2118d42f0b9} - {7f5efa28-2448-403f-aac1-1daed0a402bd} - - - - - - - - - - - - - - - - - - - - - {387c7293-83b9-467c-91e4-5089c6b49b07} - - - - - - - - {387c7293-83b9-467c-91e4-5089c6b49b07} - 1 - - - World - - - - - - - {02d14635-6813-446c-85b2-54f63bdb2120} - - - - - - - - {02d14635-6813-446c-85b2-54f63bdb2120} - 1 - - - include - - - - - {387c7293-83b9-467c-91e4-5089c6b49b07} - {98ea3b76-86aa-47e5-a88d-b16e641d66bf} - - - - - - - - - - {70d98a71-8f8e-4b4e-b194-b99a482e96d4} - - - - - - - - {70d98a71-8f8e-4b4e-b194-b99a482e96d4} - 1 - - - include - - - - - {387c7293-83b9-467c-91e4-5089c6b49b07} - {7f5efa28-2448-403f-aac1-1daed0a402bd} - - - - - - - - - - - - - - - - - - - - - {57a0b749-e7e8-4596-81f9-7eedd5f20c23} - - - - - - - - - - {57a0b749-e7e8-4596-81f9-7eedd5f20c23} - - - Back-End - - - - - - - - - - - - {eb954854-9b5e-4ea7-9237-b590bfe8e8c6} - - - - - - - - {eb954854-9b5e-4ea7-9237-b590bfe8e8c6} - 1 - - - GuiObjectFactory - - - - - - - {3f96cc10-43e2-4aef-96c0-63ce559963d9} - - - - - - - - {3f96cc10-43e2-4aef-96c0-63ce559963d9} - - - {816ce4f8-1346-42a6-b8fe-24410c5375fb} - {eb954854-9b5e-4ea7-9237-b590bfe8e8c6} - - - - - 1 - true - 2 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {0e9152a2-43b7-4021-b067-51b48d88bf23} - - - - - - - - {0e9152a2-43b7-4021-b067-51b48d88bf23} - - - QML Scene - - - - - - - {00a89b55-a11c-46f6-ae56-287d63f5637f} - - - - - - - - {00a89b55-a11c-46f6-ae56-287d63f5637f} - - - {0e9152a2-43b7-4021-b067-51b48d88bf23} - {5f23ec13-fb38-44b8-9d85-69bd3db54622} - - - 2 - - - - - - - - {8c064969-3d23-4bfa-9d24-bc405a68c7d2} - - - - - - - - {8c064969-3d23-4bfa-9d24-bc405a68c7d2} - - - {0e9152a2-43b7-4021-b067-51b48d88bf23} - {8d34e552-fa29-4a02-97fe-348f6d12b5cf} - - - - - - - - - - {aec8e97c-51d5-4db3-9925-cbda4dd01452} - - - - - - - - {aec8e97c-51d5-4db3-9925-cbda4dd01452} - - - {0e9152a2-43b7-4021-b067-51b48d88bf23} - {8d34e552-fa29-4a02-97fe-348f6d12b5cf} - - - - - - - - - - {2e5a2e2d-77af-4074-840f-4b8144df7bdb} - - - - - - - - {2e5a2e2d-77af-4074-840f-4b8144df7bdb} - - - {0e9152a2-43b7-4021-b067-51b48d88bf23} - {eac9ab00-70e1-4346-a40e-a09dfa347d20} - - - - - - - - - - - - - - - - - - - - - {1f442098-3083-4de5-9418-cfedcdc4911b} - - - - - - - - {1f442098-3083-4de5-9418-cfedcdc4911b} - 1 - - - Snake - - - - - - - {2f4799a2-3b05-40a6-a50c-261f3d5025be} - - - - - - - - {2f4799a2-3b05-40a6-a50c-261f3d5025be} - 1 - - - Snake - - - - - - - - - - {ac9a95d0-1eb2-4e9d-8d20-af703111003b} - - - - - - - - {ac9a95d0-1eb2-4e9d-8d20-af703111003b} - 1 - - - Qml - - - - - - - - - - - - - - - - - - - - - {d81fb42e-9df7-4d77-bac0-3ec82b3dee41} - - - - - - - - {d81fb42e-9df7-4d77-bac0-3ec82b3dee41} - 1 - - - Doc - - - - - - - {79ed591f-8e74-4fa9-b8b2-83177217dda8} - - - - - - - - {79ed591f-8e74-4fa9-b8b2-83177217dda8} - 1 - - - Calassdiagramm - - - - - - - - - - - - - - - - - - - - - {eb1d4e8c-23be-49af-99ae-16f21c5f4904} - - - - - - - - {eb1d4e8c-23be-49af-99ae-16f21c5f4904} - - - Новый Instance - - - false - instance - - - - - - - - {8d34e552-fa29-4a02-97fe-348f6d12b5cf} - - - - - - - - {8d34e552-fa29-4a02-97fe-348f6d12b5cf} - - - Objects Diff Interface - - - false - instance - - - - - - - - {b163850b-0cb5-4e82-ac9e-381e8701e38b} - - - - - - - - {b163850b-0cb5-4e82-ac9e-381e8701e38b} - - - Новый Intance - - - false - instance - - - - - - - - {eac9ab00-70e1-4346-a40e-a09dfa347d20} - - - - - - - - {eac9ab00-70e1-4346-a40e-a09dfa347d20} - - - Diff - - - - - - - {984ace8f-ae77-4590-aa60-030b60fddefa} - - - - - - - - {984ace8f-ae77-4590-aa60-030b60fddefa} - - - {eac9ab00-70e1-4346-a40e-a09dfa347d20} - {5f23ec13-fb38-44b8-9d85-69bd3db54622} - - - 1 - - - - - - - - {2ec1fd71-06c6-4724-9d09-d846fa1f423f} - - - - - - - - {2ec1fd71-06c6-4724-9d09-d846fa1f423f} - - - {eac9ab00-70e1-4346-a40e-a09dfa347d20} - {0e9152a2-43b7-4021-b067-51b48d88bf23} - - - - - - - - - - {3f014984-cf29-47b1-8dd7-1b10e238a6e2} - - - - - - - - {3f014984-cf29-47b1-8dd7-1b10e238a6e2} - - - {eac9ab00-70e1-4346-a40e-a09dfa347d20} - {dbe663e7-34c5-4076-b664-a19e63ab0d7f} - - - 2 - - - - - - - - - - - - - - - - - - - {283c0360-30a4-45a0-9e31-99610872d9c5} - - - - - - - - {283c0360-30a4-45a0-9e31-99610872d9c5} - 1 - - - SnakeClient - - - - - - - {d669449c-136b-4a00-959d-c0e77dad4c11} - - - - - - - - {d669449c-136b-4a00-959d-c0e77dad4c11} - 1 - - - Client - - - - - - - {b0e2d377-64aa-4416-aa0f-7a7806e7921a} - - - - - - - - {b0e2d377-64aa-4416-aa0f-7a7806e7921a} - 1 - - - Back-End - - - - - - - {796b776f-d4a7-40fc-a1aa-e99dee0e244c} - - - - - - - - {796b776f-d4a7-40fc-a1aa-e99dee0e244c} - 1 - - - ProfileViewItems - - - - - - - {7e3f8bf1-3d3a-44d6-8888-e9cae3473683} - - - - - - - - {7e3f8bf1-3d3a-44d6-8888-e9cae3473683} - 1 - - - MainMenuModel - - - - - - - {c5334666-c506-46b1-9ae1-e7a29630bd03} - - - - - - - - {c5334666-c506-46b1-9ae1-e7a29630bd03} - - - {7e3f8bf1-3d3a-44d6-8888-e9cae3473683} - {8c05ffe4-0340-4093-88f9-6570795713f9} - - - - - 1 - true - 2 - - - - - - - - - - {7a93a742-d00d-4e04-80fd-f1739a191669} - - - - - - - - {7a93a742-d00d-4e04-80fd-f1739a191669} - - - {7e3f8bf1-3d3a-44d6-8888-e9cae3473683} - {eb0b85b6-658d-4eff-a2e6-cd2ae7befd6d} - - - - - 1 - true - 2 - - - - - - - - - - {2c238bae-21c1-46c4-9468-86d8d0bb9115} - - - - - - - - {2c238bae-21c1-46c4-9468-86d8d0bb9115} - - - {7e3f8bf1-3d3a-44d6-8888-e9cae3473683} - {27cb7b78-cb1d-4418-8f91-025824839a1b} - - - - - * - true - 1 - - - - - - - - - - {13cf44a9-a6cc-4438-9271-a36888be9ec6} - - - - - - - - {13cf44a9-a6cc-4438-9271-a36888be9ec6} - - - {7e3f8bf1-3d3a-44d6-8888-e9cae3473683} - {6ae5bde6-f310-4c85-91e1-0176aebad87e} - - - 2 - - - - - - - - - - - - - - - - - - - {8c05ffe4-0340-4093-88f9-6570795713f9} - - - - - - - - {8c05ffe4-0340-4093-88f9-6570795713f9} - 1 - - - UserView - - - - - - - - - - {27cb7b78-cb1d-4418-8f91-025824839a1b} - - - - - - - - {27cb7b78-cb1d-4418-8f91-025824839a1b} - 1 - - - PlayerClientData - - - - - - - {a9667697-7d4c-4757-bf4f-0ab2568873aa} - - - - - - - - {a9667697-7d4c-4757-bf4f-0ab2568873aa} - - - {27cb7b78-cb1d-4418-8f91-025824839a1b} - {38c55945-27ed-4d5c-9d38-761b84e9ae80} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {d2a6e0a9-4e14-4c26-b4c0-f7f239e19dfd} - - - - - - - - {d2a6e0a9-4e14-4c26-b4c0-f7f239e19dfd} - 1 - - - Front-End - - - - - - - {6ae5bde6-f310-4c85-91e1-0176aebad87e} - - - - - - - - {6ae5bde6-f310-4c85-91e1-0176aebad87e} - 1 - - - MainMenu - - - - - - - {cf29b293-1a04-45da-be97-39265f097b77} - - - - - - - - {cf29b293-1a04-45da-be97-39265f097b77} - - - {6ae5bde6-f310-4c85-91e1-0176aebad87e} - {dbe663e7-34c5-4076-b664-a19e63ab0d7f} - - - - - - - - - - - - - - - - - - - - - {4b5e2d40-ee29-49f3-8812-f8e1eb741f03} - - - - - - - - {4b5e2d40-ee29-49f3-8812-f8e1eb741f03} - 1 - - - UserView - - - - - - - {b7f55ebe-6eaf-4c19-8061-cd6d747a25fc} - - - - - - - - {b7f55ebe-6eaf-4c19-8061-cd6d747a25fc} - - - {4b5e2d40-ee29-49f3-8812-f8e1eb741f03} - {6ae5bde6-f310-4c85-91e1-0176aebad87e} - - - - - - - - - - {754eb6af-590d-4f81-b3ea-03a9e02bc96c} - - - - - - - - {754eb6af-590d-4f81-b3ea-03a9e02bc96c} - - - {4b5e2d40-ee29-49f3-8812-f8e1eb741f03} - {8c05ffe4-0340-4093-88f9-6570795713f9} - - - 2 - - - - - - - - - - - - - - - - - - - {dbe663e7-34c5-4076-b664-a19e63ab0d7f} - - - - - - - - {dbe663e7-34c5-4076-b664-a19e63ab0d7f} - 1 - - - Scene - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {59144cd0-4796-4da3-a967-0ae0bacdf5f2} - - - - - - - - {59144cd0-4796-4da3-a967-0ae0bacdf5f2} - - - qmk MainMenu - - - - - - - {79dba8a4-e8b0-4f96-b405-7663076e9785} - - - - - - - - {79dba8a4-e8b0-4f96-b405-7663076e9785} - - - {59144cd0-4796-4da3-a967-0ae0bacdf5f2} - {7e3f8bf1-3d3a-44d6-8888-e9cae3473683} - - - 2 - - - - - - - - {b8530bc1-b5f0-4a9e-acfb-969901f48cb3} - - - - - - - - {b8530bc1-b5f0-4a9e-acfb-969901f48cb3} - - - {59144cd0-4796-4da3-a967-0ae0bacdf5f2} - {5f23ec13-fb38-44b8-9d85-69bd3db54622} - - - 1 - - - - - - - - - - - - - - - - - - - {d90eff49-65d5-4667-bbbc-d034dea875d4} - - - - - - - - {d90eff49-65d5-4667-bbbc-d034dea875d4} - - - UserView - - - - - - - {fddab005-ecbd-4104-8be1-2b157f36ff3c} - - - - - - - - {fddab005-ecbd-4104-8be1-2b157f36ff3c} - - - {d90eff49-65d5-4667-bbbc-d034dea875d4} - {59144cd0-4796-4da3-a967-0ae0bacdf5f2} - - - - - - - - - - {fd446cc7-6634-4476-adbd-580b314f736f} - - - - - - - - {fd446cc7-6634-4476-adbd-580b314f736f} - - - {d90eff49-65d5-4667-bbbc-d034dea875d4} - {8c05ffe4-0340-4093-88f9-6570795713f9} - - - 2 - - - - - - - - {5dcec008-fc55-477f-8188-4c09482d56bb} - - - - - - - - {5dcec008-fc55-477f-8188-4c09482d56bb} - - - {d90eff49-65d5-4667-bbbc-d034dea875d4} - {6ae5bde6-f310-4c85-91e1-0176aebad87e} - - - - - - - - - - - - - - - - - - - - - {06a33c34-d3d3-4407-a9be-f0b48c7d24d7} - - - - - - - - {06a33c34-d3d3-4407-a9be-f0b48c7d24d7} - 1 - - - SnakeServer - - - - - - - {9b53aa1a-bc2a-48cd-809c-9ea7e1668fdb} - - - - - - - - {9b53aa1a-bc2a-48cd-809c-9ea7e1668fdb} - 1 - - - ClientProtocol - - - - - - - {eb0b85b6-658d-4eff-a2e6-cd2ae7befd6d} - - - - - - - - {eb0b85b6-658d-4eff-a2e6-cd2ae7befd6d} - 1 - - - Client - - - ClientProtocol - - - - - - - - {a98b7369-6a0e-4da6-869e-2b8755cfc148} - - - - - - - - {a98b7369-6a0e-4da6-869e-2b8755cfc148} - 1 - - - Objects - - - - - - - {38c55945-27ed-4d5c-9d38-761b84e9ae80} - - - - - - - - {38c55945-27ed-4d5c-9d38-761b84e9ae80} - 1 - - - Player - - - - - - - {238a4ada-2b3e-4084-8e38-e027f0d6482c} - - - - - - - - {238a4ada-2b3e-4084-8e38-e027f0d6482c} - - - {38c55945-27ed-4d5c-9d38-761b84e9ae80} - {27cb7b78-cb1d-4418-8f91-025824839a1b} - - - - - - - - - - - - - - ClientProtocol - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/doc/librarymodel.qmodel b/doc/librarymodel.qmodel deleted file mode 100644 index 4e1084d..0000000 --- a/doc/librarymodel.qmodel +++ /dev/null @@ -1,1495 +0,0 @@ - - - - {dfea0e90-7910-4ae4-937e-8d4de8fe4774} - - - - - - - - {e8a1d78d-d7dc-4904-b888-2187d5cb3f42} - - - LibraryModel - - - - - - - {a04c0ce6-496f-4d26-9ea2-7ec6bb875cb2} - - - - - - - - - - {a04c0ce6-496f-4d26-9ea2-7ec6bb875cb2} - - - LibraryModel - - - - - - - - - - - - {66a23192-a9ad-4663-84d3-42f3cdcd1c08} - - - {d51b5a71-74cc-42da-a35f-20676c490201} - QuasarAppLib - QuasarApp - x:390;y:60 - x:-60;y:-30;w:120;h:60 - 0 - - - - - - - - - - - - - {c04cb3d2-a9a6-485e-bca2-94f39c01e243} - - - {34dd2fbb-3112-4b22-b369-7fd071dff2a7} - Snake - Snake - x:185;y:395 - x:-50;y:-30;w:100;h:60 - 0 - - - - - - - - - - - - - {787259f9-aabe-4c93-be84-23639f7fbcc3} - - - {3eafef02-7a87-4877-8889-72ea7cb240e9} - ClientProtocol - ClientProtocol - x:190;y:145 - x:-70;y:-30;w:140;h:60 - 0 - - - - - - - - - - - - - {04e5587c-ac50-4f4f-b0b2-f826b70daf1b} - - - {d1deca32-81c8-4f70-8671-17076ea8633b} - Client - Terminal - x:635;y:400 - x:-55;y:-30;w:110;h:60 - 0 - - - - - - - - - - - - - {155d97c2-3148-41d5-8783-709e51e52482} - - - {b4ce19d6-e501-4fa6-82c5-791fab5b94eb} - ServerProtocol - ServerProtocol - x:630;y:145 - x:-70;y:-30;w:140;h:60 - 0 - - - - - - - - - - - - - {5bd34991-4aaa-450d-b716-1e07deb5dfab} - - - {32657f3f-5cc1-470b-a557-dd69c7616889} - Daemon - Daemon - x:395;y:400 - x:-55;y:-30;w:110;h:60 - 0 - - - - - - - - - - - - - {719e7768-fe5e-44fd-a159-e6a18258544d} - - - {97f59dd5-871c-49b7-978d-b25f974d6251} - {7456d55f-3559-46e5-b237-d7430adb61d3} - {66a23192-a9ad-4663-84d3-42f3cdcd1c08} - - - - - - - - - - - - - {40dbfa32-650f-4264-bd8a-82859fa04b45} - - - {cc0dbaf1-ad4e-4376-a985-935b482e7ab9} - {04e5587c-ac50-4f4f-b0b2-f826b70daf1b} - {155d97c2-3148-41d5-8783-709e51e52482} - - - - - - - - - - - - - {7ca29923-fa09-4a36-9454-80250e9b8e4c} - - - {bd120e71-435b-4b77-8dbc-4965cfdb5b86} - {787259f9-aabe-4c93-be84-23639f7fbcc3} - {66a23192-a9ad-4663-84d3-42f3cdcd1c08} - - - - - - - - - - - - - {1b46e4ab-aac0-4351-a421-f5ec73ebc681} - - - {3988bb54-f1c2-49f9-84d7-be11c76353e0} - {c04cb3d2-a9a6-485e-bca2-94f39c01e243} - {7456d55f-3559-46e5-b237-d7430adb61d3} - - - - - - - - - - - - - {2485ae7a-c021-45eb-885d-31c6e625c374} - - - {a7c4b36c-f545-48d1-ad2d-7e49f671c835} - {155d97c2-3148-41d5-8783-709e51e52482} - {66a23192-a9ad-4663-84d3-42f3cdcd1c08} - - - - - - - - - - - - - {6e03d6c1-20ae-45a3-9b6a-878b16d74db9} - - - {9636e57a-651b-4c78-bb85-ecfd66d802e1} - {04e5587c-ac50-4f4f-b0b2-f826b70daf1b} - {66a23192-a9ad-4663-84d3-42f3cdcd1c08} - - - - - - - - - - - - - {6e1ecf72-4476-4891-8e43-eef89da71780} - - - {0fe0f577-4b80-4118-b36e-01f6cc55bebd} - {155d97c2-3148-41d5-8783-709e51e52482} - {66a23192-a9ad-4663-84d3-42f3cdcd1c08} - - - - - - - - - - - - - {7456d55f-3559-46e5-b237-d7430adb61d3} - - - {56f5d199-029a-4d7d-a667-63e884b121c9} - Client - x:185;y:265 - x:-50;y:-30;w:100;h:60 - 0 - - - - - - - - - - - - - {06525499-f6e0-4625-ab68-1c382c9320c2} - - - {03379880-0ad4-4eb8-9e06-c81f1c8f9e26} - Server - x:395;y:265 - x:-50;y:-30;w:100;h:60 - 0 - - - - - - - - - - - - - {fb92c04f-f425-4fbe-b98b-a5c32a6db837} - - - {11bfbdaa-13cf-4fd3-9161-b54d2c49e357} - {06525499-f6e0-4625-ab68-1c382c9320c2} - {66a23192-a9ad-4663-84d3-42f3cdcd1c08} - - - - - - - - - - - - - {834668b7-1943-41d6-a488-148063f7eabd} - - - {d1846a67-a2c7-4eb9-89ea-f1d905dbdaf2} - {06525499-f6e0-4625-ab68-1c382c9320c2} - {155d97c2-3148-41d5-8783-709e51e52482} - - - - - - - - - - - - - {3d0b6e33-e8f0-4d93-9877-c098f98d0766} - - - {e66ff8e1-b4e0-44cd-b7c0-48388d23d78e} - {5bd34991-4aaa-450d-b716-1e07deb5dfab} - {06525499-f6e0-4625-ab68-1c382c9320c2} - - - - - - - - - - - - - {93209e6d-b898-4a65-a499-7700182dcf8c} - - - {a16e9f9d-a7f1-4759-9729-c3ae12cd7534} - {06525499-f6e0-4625-ab68-1c382c9320c2} - {787259f9-aabe-4c93-be84-23639f7fbcc3} - - - - - - - - - - - - - {3ffdc7ca-c9ca-4574-bfcb-036c36e765d2} - - - {6415c533-44d8-4da0-acf0-81e5a137ac1b} - {7456d55f-3559-46e5-b237-d7430adb61d3} - {787259f9-aabe-4c93-be84-23639f7fbcc3} - - - - - - - - - - - - - {d9d1345e-7f2b-4795-991b-329acbef5a3a} - - - {179586c1-7898-4183-9bf5-a77ba74f8f0d} - SnakeUtils - SnakeUtils - x:15;y:145 - x:-60;y:-30;w:120;h:60 - 0 - - - - - - - - - - - - - {c22760ec-b51c-49c2-9046-9b143e53f839} - - - {0ded816f-d6d8-4a25-80dc-523dde93cf81} - {d9d1345e-7f2b-4795-991b-329acbef5a3a} - {7456d55f-3559-46e5-b237-d7430adb61d3} - - - - - - - - - - - - - {e26e74b1-8ca5-437e-b6b1-784bfc2f064f} - - - {e9f56c30-0bd7-4728-bede-81a308bfeb87} - Qt-Secret - Qt-Secret - x:390;y:-25 - x:-55;y:-30;w:110;h:60 - 0 - - - - - - - - - - - - - {e8737647-b81d-4ffc-9590-1be3f88f6863} - - - {0448e403-ef91-4ed8-9a92-6cc96e246407} - {e26e74b1-8ca5-437e-b6b1-784bfc2f064f} - {155d97c2-3148-41d5-8783-709e51e52482} - - - - - - - - - - - - - {d46f31e4-5658-411a-ad00-ed49eccd6d19} - - - {1579610b-168b-45b5-8a9f-8b8f79cb3705} - {e26e74b1-8ca5-437e-b6b1-784bfc2f064f} - {787259f9-aabe-4c93-be84-23639f7fbcc3} - - - - - - - - 1564305456003 - General - - - - - - - - - - {2dfe706c-5751-4433-9565-f86835af13bb} - - - - - - - - {2dfe706c-5751-4433-9565-f86835af13bb} - 1 - - - QuasarAppLib - - - - - - - {d51b5a71-74cc-42da-a35f-20676c490201} - - - - - - - - {d51b5a71-74cc-42da-a35f-20676c490201} - 1 - - - QuasarApp - - - - - - - - - - - - - - - - - - - - - {c544a3f6-c5b6-4f4f-9c40-5d5969e93633} - - - - - - - - {c544a3f6-c5b6-4f4f-9c40-5d5969e93633} - 1 - - - Snake - - - - - - - {34dd2fbb-3112-4b22-b369-7fd071dff2a7} - - - - - - - - {34dd2fbb-3112-4b22-b369-7fd071dff2a7} - 1 - - - Snake - - - - - - - {3988bb54-f1c2-49f9-84d7-be11c76353e0} - - - - - - - - {3988bb54-f1c2-49f9-84d7-be11c76353e0} - - - {34dd2fbb-3112-4b22-b369-7fd071dff2a7} - {56f5d199-029a-4d7d-a667-63e884b121c9} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {d2fbf41a-804d-49c3-b362-89a71531fc8d} - - - - - - - - {d2fbf41a-804d-49c3-b362-89a71531fc8d} - 1 - - - ClientProtocol - - - - - - - {3eafef02-7a87-4877-8889-72ea7cb240e9} - - - - - - - - {3eafef02-7a87-4877-8889-72ea7cb240e9} - 1 - - - ClientProtocol - - - - - - - {bd120e71-435b-4b77-8dbc-4965cfdb5b86} - - - - - - - - {bd120e71-435b-4b77-8dbc-4965cfdb5b86} - - - {3eafef02-7a87-4877-8889-72ea7cb240e9} - {d51b5a71-74cc-42da-a35f-20676c490201} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {4a9e7467-b0c4-4f5a-8041-555c514ef17b} - - - - - - - - {4a9e7467-b0c4-4f5a-8041-555c514ef17b} - 1 - - - Client - - - - - - - {d1deca32-81c8-4f70-8671-17076ea8633b} - - - - - - - - {d1deca32-81c8-4f70-8671-17076ea8633b} - 1 - - - Terminal - - - - - - - {cc0dbaf1-ad4e-4376-a985-935b482e7ab9} - - - - - - - - {cc0dbaf1-ad4e-4376-a985-935b482e7ab9} - - - {d1deca32-81c8-4f70-8671-17076ea8633b} - {b4ce19d6-e501-4fa6-82c5-791fab5b94eb} - - - - - - - - - - {9636e57a-651b-4c78-bb85-ecfd66d802e1} - - - - - - - - {9636e57a-651b-4c78-bb85-ecfd66d802e1} - - - {d1deca32-81c8-4f70-8671-17076ea8633b} - {d51b5a71-74cc-42da-a35f-20676c490201} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {5fcda5bd-7958-4eed-a464-ffe2e6681744} - - - - - - - - {5fcda5bd-7958-4eed-a464-ffe2e6681744} - 1 - - - ServerProtocol - - - - - - - {b4ce19d6-e501-4fa6-82c5-791fab5b94eb} - - - - - - - - {b4ce19d6-e501-4fa6-82c5-791fab5b94eb} - 1 - - - ServerProtocol - - - - - - - {a7c4b36c-f545-48d1-ad2d-7e49f671c835} - - - - - - - - {a7c4b36c-f545-48d1-ad2d-7e49f671c835} - - - {b4ce19d6-e501-4fa6-82c5-791fab5b94eb} - {d51b5a71-74cc-42da-a35f-20676c490201} - - - - - - - - - - {0fe0f577-4b80-4118-b36e-01f6cc55bebd} - - - - - - - - {0fe0f577-4b80-4118-b36e-01f6cc55bebd} - - - {b4ce19d6-e501-4fa6-82c5-791fab5b94eb} - {d51b5a71-74cc-42da-a35f-20676c490201} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {5763646f-1ed3-4f15-bc36-6aead88f6cd3} - - - - - - - - {5763646f-1ed3-4f15-bc36-6aead88f6cd3} - 1 - - - Daemon - - - - - - - {32657f3f-5cc1-470b-a557-dd69c7616889} - - - - - - - - {32657f3f-5cc1-470b-a557-dd69c7616889} - 1 - - - Daemon - - - - - - - {50a42ad1-baf5-41a7-b562-5bf02a1a6c3c} - - - - - - - - {50a42ad1-baf5-41a7-b562-5bf02a1a6c3c} - - - {32657f3f-5cc1-470b-a557-dd69c7616889} - {b4ce19d6-e501-4fa6-82c5-791fab5b94eb} - - - - - - - - - - {ecb68506-18c1-41f3-8b98-8c66e91cbc0e} - - - - - - - - {ecb68506-18c1-41f3-8b98-8c66e91cbc0e} - - - {32657f3f-5cc1-470b-a557-dd69c7616889} - {3eafef02-7a87-4877-8889-72ea7cb240e9} - - - - - - - - - - {f45b5326-c235-436b-8298-517cddf84c79} - - - - - - - - {f45b5326-c235-436b-8298-517cddf84c79} - - - {32657f3f-5cc1-470b-a557-dd69c7616889} - {d51b5a71-74cc-42da-a35f-20676c490201} - - - - - - - - - - {e66ff8e1-b4e0-44cd-b7c0-48388d23d78e} - - - - - - - - {e66ff8e1-b4e0-44cd-b7c0-48388d23d78e} - - - {32657f3f-5cc1-470b-a557-dd69c7616889} - {03379880-0ad4-4eb8-9e06-c81f1c8f9e26} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {56f5d199-029a-4d7d-a667-63e884b121c9} - - - - - - - - {56f5d199-029a-4d7d-a667-63e884b121c9} - - - Client - - - - - - - {97f59dd5-871c-49b7-978d-b25f974d6251} - - - - - - - - {97f59dd5-871c-49b7-978d-b25f974d6251} - - - {56f5d199-029a-4d7d-a667-63e884b121c9} - {d51b5a71-74cc-42da-a35f-20676c490201} - - - - - - - - - - {6415c533-44d8-4da0-acf0-81e5a137ac1b} - - - - - - - - {6415c533-44d8-4da0-acf0-81e5a137ac1b} - - - {56f5d199-029a-4d7d-a667-63e884b121c9} - {3eafef02-7a87-4877-8889-72ea7cb240e9} - - - - - - - - - - - - - - - - - - - - - {03379880-0ad4-4eb8-9e06-c81f1c8f9e26} - - - - - - - - {03379880-0ad4-4eb8-9e06-c81f1c8f9e26} - - - Server - - - - - - - {11bfbdaa-13cf-4fd3-9161-b54d2c49e357} - - - - - - - - {11bfbdaa-13cf-4fd3-9161-b54d2c49e357} - - - {03379880-0ad4-4eb8-9e06-c81f1c8f9e26} - {d51b5a71-74cc-42da-a35f-20676c490201} - - - - - - - - - - {d1846a67-a2c7-4eb9-89ea-f1d905dbdaf2} - - - - - - - - {d1846a67-a2c7-4eb9-89ea-f1d905dbdaf2} - - - {03379880-0ad4-4eb8-9e06-c81f1c8f9e26} - {b4ce19d6-e501-4fa6-82c5-791fab5b94eb} - - - - - - - - - - {a16e9f9d-a7f1-4759-9729-c3ae12cd7534} - - - - - - - - {a16e9f9d-a7f1-4759-9729-c3ae12cd7534} - - - {03379880-0ad4-4eb8-9e06-c81f1c8f9e26} - {3eafef02-7a87-4877-8889-72ea7cb240e9} - - - - - - - - - - - - - - - - - - - - - {4f6ef33d-c575-448e-a0da-f31a5f6434f0} - - - - - - - - {4f6ef33d-c575-448e-a0da-f31a5f6434f0} - 1 - - - SnakeUtils - - - - - - - {179586c1-7898-4183-9bf5-a77ba74f8f0d} - - - - - - - - {179586c1-7898-4183-9bf5-a77ba74f8f0d} - 1 - - - SnakeUtils - - - - - - - {0ded816f-d6d8-4a25-80dc-523dde93cf81} - - - - - - - - {0ded816f-d6d8-4a25-80dc-523dde93cf81} - - - {179586c1-7898-4183-9bf5-a77ba74f8f0d} - {56f5d199-029a-4d7d-a667-63e884b121c9} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {e6099df6-b1b3-4db3-b0ee-296006811b8d} - - - - - - - - {e6099df6-b1b3-4db3-b0ee-296006811b8d} - 1 - - - SnakeServer - - - - - - - {2fa91d20-c7ff-4432-9e89-d4c57d9d0953} - - - - - - - - {2fa91d20-c7ff-4432-9e89-d4c57d9d0953} - 1 - - - Qt-Secret - - - - - - - {e9f56c30-0bd7-4728-bede-81a308bfeb87} - - - - - - - - {e9f56c30-0bd7-4728-bede-81a308bfeb87} - 1 - - - Qt-Secret - - - - - - - {0448e403-ef91-4ed8-9a92-6cc96e246407} - - - - - - - - {0448e403-ef91-4ed8-9a92-6cc96e246407} - - - {e9f56c30-0bd7-4728-bede-81a308bfeb87} - {b4ce19d6-e501-4fa6-82c5-791fab5b94eb} - - - - - - - - - - {1579610b-168b-45b5-8a9f-8b8f79cb3705} - - - - - - - - {1579610b-168b-45b5-8a9f-8b8f79cb3705} - - - {e9f56c30-0bd7-4728-bede-81a308bfeb87} - {3eafef02-7a87-4877-8889-72ea7cb240e9} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/doxygen.conf b/doxygen.conf new file mode 100644 index 0000000..b5b1809 --- /dev/null +++ b/doxygen.conf @@ -0,0 +1,2495 @@ +# Doxyfile 1.8.13 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project. +# +# All text after a double hash (##) is considered a comment and is placed in +# front of the TAG it is preceding. +# +# All text after a single hash (#) is considered a comment and will be ignored. +# The format is: +# TAG = value [value, ...] +# For lists, items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (\" \"). + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all text +# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv +# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv +# for the list of possible encodings. +# The default value is: UTF-8. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by +# double-quotes, unless you are using Doxywizard) that should identify the +# project for which the documentation is generated. This name is used in the +# title of most generated pages and in a few other places. +# The default value is: My Project. + +PROJECT_NAME = SnakeProject + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. This +# could be handy for archiving the generated documentation or if some version +# control system is used. + +PROJECT_NUMBER = + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer a +# quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = + +# With the PROJECT_LOGO tag one can specify a logo or an icon that is included +# in the documentation. The maximum height of the logo should not exceed 55 +# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy +# the logo to the output directory. + +PROJECT_LOGO = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path +# into which the generated documentation will be written. If a relative path is +# entered, it will be relative to the location where doxygen was started. If +# left blank the current directory will be used. + +OUTPUT_DIRECTORY = docs + +# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- +# directories (in 2 levels) under the output directory of each output format and +# will distribute the generated files over these directories. Enabling this +# option can be useful when feeding doxygen a huge amount of source files, where +# putting all generated files in the same directory would otherwise causes +# performance problems for the file system. +# The default value is: NO. + +CREATE_SUBDIRS = NO + +# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII +# characters to appear in the names of generated files. If set to NO, non-ASCII +# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode +# U+3044. +# The default value is: NO. + +ALLOW_UNICODE_NAMES = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese, +# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States), +# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian, +# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages), +# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian, +# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian, +# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish, +# Ukrainian and Vietnamese. +# The default value is: English. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member +# descriptions after the members that are listed in the file and class +# documentation (similar to Javadoc). Set to NO to disable this. +# The default value is: YES. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief +# description of a member or function before the detailed description +# +# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. +# The default value is: YES. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator that is +# used to form the text in various listings. Each string in this list, if found +# as the leading text of the brief description, will be stripped from the text +# and the result, after processing the whole list, is used as the annotated +# text. Otherwise, the brief description is used as-is. If left blank, the +# following values are used ($name is automatically replaced with the name of +# the entity):The $name class, The $name widget, The $name file, is, provides, +# specifies, contains, represents, a, an and the. + +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# doxygen will generate a detailed section even if there is only a brief +# description. +# The default value is: NO. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. +# The default value is: NO. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path +# before files name in the file list and in the header files. If set to NO the +# shortest path that makes the file name unique will be used +# The default value is: YES. + +FULL_PATH_NAMES = YES + +# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. +# Stripping is only done if one of the specified strings matches the left-hand +# part of the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the path to +# strip. +# +# Note that you can specify absolute paths here, but also relative paths, which +# will be relative from the directory where doxygen is started. +# This tag requires that the tag FULL_PATH_NAMES is set to YES. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the +# path mentioned in the documentation of a class, which tells the reader which +# header file to include in order to use a class. If left blank only the name of +# the header file containing the class definition is used. Otherwise one should +# specify the list of include paths that are normally passed to the compiler +# using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but +# less readable) file names. This can be useful is your file systems doesn't +# support long names like on DOS, Mac, or CD-ROM. +# The default value is: NO. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the +# first line (until the first dot) of a Javadoc-style comment as the brief +# description. If set to NO, the Javadoc-style will behave just like regular Qt- +# style comments (thus requiring an explicit @brief command for a brief +# description.) +# The default value is: NO. + +JAVADOC_AUTOBRIEF = NO + +# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first +# line (until the first dot) of a Qt-style comment as the brief description. If +# set to NO, the Qt-style will behave just like regular Qt-style comments (thus +# requiring an explicit \brief command for a brief description.) +# The default value is: NO. + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a +# multi-line C++ special comment block (i.e. a block of //! or /// comments) as +# a brief description. This used to be the default behavior. The new default is +# to treat a multi-line C++ comment block as a detailed description. Set this +# tag to YES if you prefer the old behavior instead. +# +# Note that setting this tag to YES also means that rational rose comments are +# not recognized any more. +# The default value is: NO. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the +# documentation from any documented member that it re-implements. +# The default value is: YES. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new +# page for each member. If set to NO, the documentation of a member will be part +# of the file/class/namespace that contains it. +# The default value is: NO. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen +# uses this value to replace tabs by spaces in code fragments. +# Minimum value: 1, maximum value: 16, default value: 4. + +TAB_SIZE = 4 + +# This tag can be used to specify a number of aliases that act as commands in +# the documentation. An alias has the form: +# name=value +# For example adding +# "sideeffect=@par Side Effects:\n" +# will allow you to put the command \sideeffect (or @sideeffect) in the +# documentation, which will result in a user-defined paragraph with heading +# "Side Effects:". You can put \n's in the value part of an alias to insert +# newlines. + +ALIASES = + +# This tag can be used to specify a number of word-keyword mappings (TCL only). +# A mapping has the form "name=value". For example adding "class=itcl::class" +# will allow you to use the command class in the itcl::class meaning. + +TCL_SUBST = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources +# only. Doxygen will then generate output that is more tailored for C. For +# instance, some of the names that are used will be different. The list of all +# members will be omitted, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or +# Python sources only. Doxygen will then generate output that is more tailored +# for that language. For instance, namespaces will be presented as packages, +# qualified scopes will look different, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources. Doxygen will then generate output that is tailored for Fortran. +# The default value is: NO. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for VHDL. +# The default value is: NO. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given +# extension. Doxygen has a built-in mapping, but you can override or extend it +# using this tag. The format is ext=language, where ext is a file extension, and +# language is one of the parsers supported by doxygen: IDL, Java, Javascript, +# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran: +# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran: +# Fortran. In the later case the parser tries to guess whether the code is fixed +# or free formatted code, this is the default for Fortran type files), VHDL. For +# instance to make doxygen treat .inc files as Fortran files (default is PHP), +# and .f files as C (default is Fortran), use: inc=Fortran f=C. +# +# Note: For files without extension you can use no_extension as a placeholder. +# +# Note that for custom extensions you also need to set FILE_PATTERNS otherwise +# the files are not read by doxygen. + +EXTENSION_MAPPING = + +# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments +# according to the Markdown format, which allows for more readable +# documentation. See http://daringfireball.net/projects/markdown/ for details. +# The output of markdown processing is further processed by doxygen, so you can +# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in +# case of backward compatibilities issues. +# The default value is: YES. + +MARKDOWN_SUPPORT = YES + +# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up +# to that level are automatically included in the table of contents, even if +# they do not have an id attribute. +# Note: This feature currently applies only to Markdown headings. +# Minimum value: 0, maximum value: 99, default value: 0. +# This tag requires that the tag MARKDOWN_SUPPORT is set to YES. + +TOC_INCLUDE_HEADINGS = 0 + +# When enabled doxygen tries to link words that correspond to documented +# classes, or namespaces to their corresponding documentation. Such a link can +# be prevented in individual cases by putting a % sign in front of the word or +# globally by setting AUTOLINK_SUPPORT to NO. +# The default value is: YES. + +AUTOLINK_SUPPORT = YES + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should set this +# tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); +# versus func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. +# The default value is: NO. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. +# The default value is: NO. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip (see: +# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen +# will parse them like normal C++ but will assume all classes use public instead +# of private inheritance when no explicit protection keyword is present. +# The default value is: NO. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate +# getter and setter methods for a property. Setting this option to YES will make +# doxygen to replace the get and set methods by a property in the documentation. +# This will only work if the methods are indeed getting or setting a simple +# type. If this is not the case, or you want to show the methods anyway, you +# should set this option to NO. +# The default value is: YES. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. +# The default value is: NO. + +DISTRIBUTE_GROUP_DOC = NO + +# If one adds a struct or class to a group and this option is enabled, then also +# any nested class or struct is added to the same group. By default this option +# is disabled and one has to add nested compounds explicitly via \ingroup. +# The default value is: NO. + +GROUP_NESTED_COMPOUNDS = NO + +# Set the SUBGROUPING tag to YES to allow class member groups of the same type +# (for instance a group of public functions) to be put as a subgroup of that +# type (e.g. under the Public Functions section). Set it to NO to prevent +# subgrouping. Alternatively, this can be done per class using the +# \nosubgrouping command. +# The default value is: YES. + +SUBGROUPING = YES + +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions +# are shown inside the group in which they are included (e.g. using \ingroup) +# instead of on a separate page (for HTML and Man pages) or section (for LaTeX +# and RTF). +# +# Note that this feature does not work in combination with +# SEPARATE_MEMBER_PAGES. +# The default value is: NO. + +INLINE_GROUPED_CLASSES = NO + +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions +# with only public data fields or simple typedef fields will be shown inline in +# the documentation of the scope in which they are defined (i.e. file, +# namespace, or group documentation), provided this scope is documented. If set +# to NO, structs, classes, and unions are shown on a separate page (for HTML and +# Man pages) or section (for LaTeX and RTF). +# The default value is: NO. + +INLINE_SIMPLE_STRUCTS = NO + +# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or +# enum is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically be +# useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. +# The default value is: NO. + +TYPEDEF_HIDES_STRUCT = NO + +# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This +# cache is used to resolve symbols given their name and scope. Since this can be +# an expensive process and often the same symbol appears multiple times in the +# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small +# doxygen will become slower. If the cache is too large, memory is wasted. The +# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range +# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 +# symbols. At the end of a run doxygen will report the cache usage and suggest +# the optimal cache size from a speed point of view. +# Minimum value: 0, maximum value: 9, default value: 0. + +LOOKUP_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in +# documentation are documented, even if no documentation was available. Private +# class members and static file members will be hidden unless the +# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. +# Note: This will also disable the warnings about undocumented members that are +# normally produced when WARNINGS is set to YES. +# The default value is: NO. + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will +# be included in the documentation. +# The default value is: NO. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal +# scope will be included in the documentation. +# The default value is: NO. + +EXTRACT_PACKAGE = NO + +# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be +# included in the documentation. +# The default value is: NO. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined +# locally in source files will be included in the documentation. If set to NO, +# only classes defined in header files are included. Does not have any effect +# for Java sources. +# The default value is: YES. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. If set to YES, local methods, +# which are defined in the implementation section but not in the interface are +# included in the documentation. If set to NO, only methods in the interface are +# included. +# The default value is: NO. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base name of +# the file that contains the anonymous namespace. By default anonymous namespace +# are hidden. +# The default value is: NO. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all +# undocumented members inside documented classes or files. If set to NO these +# members will be included in the various overviews, but no documentation +# section is generated. This option has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. If set +# to NO, these classes will be included in the various overviews. This option +# has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend +# (class|struct|union) declarations. If set to NO, these declarations will be +# included in the documentation. +# The default value is: NO. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any +# documentation blocks found inside the body of a function. If set to NO, these +# blocks will be appended to the function's detailed documentation block. +# The default value is: NO. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation that is typed after a +# \internal command is included. If the tag is set to NO then the documentation +# will be excluded. Set it to YES to include the internal documentation. +# The default value is: NO. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file +# names in lower-case letters. If set to YES, upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. +# The default value is: system dependent. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with +# their full class and namespace scopes in the documentation. If set to YES, the +# scope will be hidden. +# The default value is: NO. + +HIDE_SCOPE_NAMES = NO + +# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will +# append additional text to a page's title, such as Class Reference. If set to +# YES the compound reference will be hidden. +# The default value is: NO. + +HIDE_COMPOUND_REFERENCE= NO + +# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of +# the files that are included by a file in the documentation of that file. +# The default value is: YES. + +SHOW_INCLUDE_FILES = YES + +# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each +# grouped member an include statement to the documentation, telling the reader +# which file to include in order to use the member. +# The default value is: NO. + +SHOW_GROUPED_MEMB_INC = NO + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include +# files with double quotes in the documentation rather than with sharp brackets. +# The default value is: NO. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the +# documentation for inline members. +# The default value is: YES. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the +# (detailed) documentation of file and class members alphabetically by member +# name. If set to NO, the members will appear in declaration order. +# The default value is: YES. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief +# descriptions of file, namespace and class members alphabetically by member +# name. If set to NO, the members will appear in declaration order. Note that +# this will also influence the order of the classes in the class list. +# The default value is: NO. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the +# (brief and detailed) documentation of class members so that constructors and +# destructors are listed first. If set to NO the constructors will appear in the +# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. +# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief +# member documentation. +# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting +# detailed member documentation. +# The default value is: NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy +# of group names into alphabetical order. If set to NO the group names will +# appear in their defined order. +# The default value is: NO. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by +# fully-qualified names, including namespaces. If set to NO, the class list will +# be sorted only by class name, not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the alphabetical +# list. +# The default value is: NO. + +SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper +# type resolution of all parameters of a function it will reject a match between +# the prototype and the implementation of a member function even if there is +# only one candidate or it is obvious which candidate to choose by doing a +# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still +# accept a match between prototype and implementation in such cases. +# The default value is: NO. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo +# list. This list is created by putting \todo commands in the documentation. +# The default value is: YES. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test +# list. This list is created by putting \test commands in the documentation. +# The default value is: YES. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug +# list. This list is created by putting \bug commands in the documentation. +# The default value is: YES. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO) +# the deprecated list. This list is created by putting \deprecated commands in +# the documentation. +# The default value is: YES. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional documentation +# sections, marked by \if ... \endif and \cond +# ... \endcond blocks. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the +# initial value of a variable or macro / define can have for it to appear in the +# documentation. If the initializer consists of more lines than specified here +# it will be hidden. Use a value of 0 to hide initializers completely. The +# appearance of the value of individual variables and macros / defines can be +# controlled using \showinitializer or \hideinitializer command in the +# documentation regardless of this setting. +# Minimum value: 0, maximum value: 10000, default value: 30. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at +# the bottom of the documentation of classes and structs. If set to YES, the +# list will mention the files that were used to generate the documentation. +# The default value is: YES. + +SHOW_USED_FILES = YES + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This +# will remove the Files entry from the Quick Index and from the Folder Tree View +# (if specified). +# The default value is: YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces +# page. This will remove the Namespaces entry from the Quick Index and from the +# Folder Tree View (if specified). +# The default value is: YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command command input-file, where command is the value of the +# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided +# by doxygen. Whatever the program writes to standard output is used as the file +# version. For an example see the documentation. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. To create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. You can +# optionally specify a file name after the option, if omitted DoxygenLayout.xml +# will be used as the name of the layout file. +# +# Note that if you run doxygen from a directory containing a file called +# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE +# tag is left empty. + +LAYOUT_FILE = CMake/DoxyStyle/DoxygenLayout.xml + +# The CITE_BIB_FILES tag can be used to specify one or more bib files containing +# the reference definitions. This must be a list of .bib files. The .bib +# extension is automatically appended if omitted. This requires the bibtex tool +# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info. +# For LaTeX the style of the bibliography can be controlled using +# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the +# search path. See also \cite for info how to create references. + +CITE_BIB_FILES = + +#--------------------------------------------------------------------------- +# Configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated to +# standard output by doxygen. If QUIET is set to YES this implies that the +# messages are off. +# The default value is: NO. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES +# this implies that the warnings are on. +# +# Tip: Turn warnings on while writing the documentation. +# The default value is: YES. + +WARNINGS = YES + +# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate +# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag +# will automatically be disabled. +# The default value is: YES. + +WARN_IF_UNDOCUMENTED = YES + +# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some parameters +# in a documented function, or documenting parameters that don't exist or using +# markup commands wrongly. +# The default value is: YES. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that +# are documented, but have no documentation for their parameters or return +# value. If set to NO, doxygen will only warn about wrong or incomplete +# parameter documentation, but not about the absence of documentation. +# The default value is: NO. + +WARN_NO_PARAMDOC = NO + +# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when +# a warning is encountered. +# The default value is: NO. + +WARN_AS_ERROR = NO + +# The WARN_FORMAT tag determines the format of the warning messages that doxygen +# can produce. The string should contain the $file, $line, and $text tags, which +# will be replaced by the file and line number from which the warning originated +# and the warning text. Optionally the format may contain $version, which will +# be replaced by the version of the file (if it could be obtained via +# FILE_VERSION_FILTER) +# The default value is: $file:$line: $text. + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning and error +# messages should be written. If left blank the output is written to standard +# error (stderr). + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# Configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag is used to specify the files and/or directories that contain +# documented source files. You may enter file names like myfile.cpp or +# directories like /usr/src/myproject. Separate the files or directories with +# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING +# Note: If this tag is empty the current directory is searched. + +INPUT = ./src \ + ./README.md + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses +# libiconv (or the iconv built into libc) for the transcoding. See the libiconv +# documentation (see: http://www.gnu.org/software/libiconv) for the list of +# possible encodings. +# The default value is: UTF-8. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and +# *.h) to filter out the source-files in the directories. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# read by doxygen. +# +# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, +# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, +# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, +# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, +# *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf and *.qsf. + +FILE_PATTERNS = *.c \ + *.cc \ + *.cxx \ + *.cpp \ + *.c++ \ + *.java \ + *.ii \ + *.ixx \ + *.ipp \ + *.i++ \ + *.inl \ + *.idl \ + *.ddl \ + *.odl \ + *.h \ + *.hh \ + *.hxx \ + *.hpp \ + *.h++ \ + *.cs \ + *.d \ + *.php \ + *.php4 \ + *.php5 \ + *.phtml \ + *.inc \ + *.m \ + *.markdown \ + *.md \ + *.mm \ + *.dox \ + *.py \ + *.pyw \ + *.f90 \ + *.f95 \ + *.f03 \ + *.f08 \ + *.f \ + *.for \ + *.tcl \ + *.vhd \ + *.vhdl \ + *.ucf \ + *.qsf + +# The RECURSIVE tag can be used to specify whether or not subdirectories should +# be searched for input files as well. +# The default value is: NO. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should be +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. +# +# Note that relative paths are relative to the directory from which doxygen is +# run. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. +# The default value is: NO. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories use the pattern */test/* + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or directories +# that contain example code fragments that are included (see the \include +# command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and +# *.h) to filter out the source-files in the directories. If left blank all +# files are included. + +EXAMPLE_PATTERNS = * + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude commands +# irrespective of the value of the RECURSIVE tag. +# The default value is: NO. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or directories +# that contain images that are to be included in the documentation (see the +# \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command: +# +# +# +# where is the value of the INPUT_FILTER tag, and is the +# name of an input file. Doxygen will then use the output that the filter +# program writes to standard output. If FILTER_PATTERNS is specified, this tag +# will be ignored. +# +# Note that the filter must not add or remove lines; it is applied before the +# code is scanned, but not when the output code is generated. If lines are added +# or removed, the anchors will not be placed correctly. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by doxygen. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: pattern=filter +# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how +# filters are used. If the FILTER_PATTERNS tag is empty or if none of the +# patterns match the file name, INPUT_FILTER is applied. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by doxygen. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will also be used to filter the input files that are used for +# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). +# The default value is: NO. + +FILTER_SOURCE_FILES = NO + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and +# it is also possible to disable source filtering for a specific pattern using +# *.ext= (so without naming a filter). +# This tag requires that the tag FILTER_SOURCE_FILES is set to YES. + +FILTER_SOURCE_PATTERNS = + +# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that +# is part of the input, its contents will be placed on the main page +# (index.html). This can be useful if you have a project on for instance GitHub +# and want to reuse the introduction page also for the doxygen output. + +USE_MDFILE_AS_MAINPAGE = ./README.md + +#--------------------------------------------------------------------------- +# Configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will be +# generated. Documented entities will be cross-referenced with these sources. +# +# Note: To get rid of all source code in the generated output, make sure that +# also VERBATIM_HEADERS is set to NO. +# The default value is: NO. + +SOURCE_BROWSER = YES + +# Setting the INLINE_SOURCES tag to YES will include the body of functions, +# classes and enums directly into the documentation. +# The default value is: NO. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any +# special comment blocks from generated source code fragments. Normal C, C++ and +# Fortran comments will always remain visible. +# The default value is: YES. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES then for each documented +# function all documented functions referencing it will be listed. +# The default value is: NO. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES then for each documented function +# all documented entities called/used by that function will be listed. +# The default value is: NO. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set +# to YES then the hyperlinks from functions in REFERENCES_RELATION and +# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will +# link to the documentation. +# The default value is: YES. + +REFERENCES_LINK_SOURCE = YES + +# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the +# source code will show a tooltip with additional information such as prototype, +# brief description and links to the definition and documentation. Since this +# will make the HTML file larger and loading of large files a bit slower, you +# can opt to disable this feature. +# The default value is: YES. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +SOURCE_TOOLTIPS = YES + +# If the USE_HTAGS tag is set to YES then the references to source code will +# point to the HTML generated by the htags(1) tool instead of doxygen built-in +# source browser. The htags tool is part of GNU's global source tagging system +# (see http://www.gnu.org/software/global/global.html). You will need version +# 4.8.6 or higher. +# +# To use it do the following: +# - Install the latest version of global +# - Enable SOURCE_BROWSER and USE_HTAGS in the config file +# - Make sure the INPUT points to the root of the source tree +# - Run doxygen as normal +# +# Doxygen will invoke htags (and that will in turn invoke gtags), so these +# tools must be available from the command line (i.e. in the search path). +# +# The result: instead of the source browser generated by doxygen, the links to +# source code will now point to the output of htags. +# The default value is: NO. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a +# verbatim copy of the header file for each class for which an include is +# specified. Set to NO to disable this. +# See also: Section \class. +# The default value is: YES. + +VERBATIM_HEADERS = YES + +# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the +# clang parser (see: http://clang.llvm.org/) for more accurate parsing at the +# cost of reduced performance. This can be particularly helpful with template +# rich C++ code for which doxygen's built-in parser lacks the necessary type +# information. +# Note: The availability of this option depends on whether or not doxygen was +# generated with the -Duse-libclang=ON option for CMake. +# The default value is: NO. + +CLANG_ASSISTED_PARSING = NO + +# If clang assisted parsing is enabled you can provide the compiler with command +# line options that you would normally use when invoking the compiler. Note that +# the include paths will already be set by doxygen for the files and directories +# specified with INPUT and INCLUDE_PATH. +# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES. + +CLANG_OPTIONS = + +#--------------------------------------------------------------------------- +# Configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all +# compounds will be generated. Enable this if the project contains a lot of +# classes, structs, unions or interfaces. +# The default value is: YES. + +ALPHABETICAL_INDEX = YES + +# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in +# which the alphabetical index list will be split. +# Minimum value: 1, maximum value: 20, default value: 5. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all classes will +# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag +# can be used to specify a prefix (or a list of prefixes) that should be ignored +# while generating the index headers. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output +# The default value is: YES. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_OUTPUT = . + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each +# generated HTML page (for example: .htm, .php, .asp). +# The default value is: .html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a user-defined HTML header file for +# each generated HTML page. If the tag is left blank doxygen will generate a +# standard header. +# +# To get valid HTML the header file that includes any scripts and style sheets +# that doxygen needs, which is dependent on the configuration options used (e.g. +# the setting GENERATE_TREEVIEW). It is highly recommended to start with a +# default header using +# doxygen -w html new_header.html new_footer.html new_stylesheet.css +# YourConfigFile +# and then modify the file new_header.html. See also section "Doxygen usage" +# for information on how to generate the default header that doxygen normally +# uses. +# Note: The header is subject to change so you typically have to regenerate the +# default header when upgrading to a newer version of doxygen. For a description +# of the possible markers and block names see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each +# generated HTML page. If the tag is left blank doxygen will generate a standard +# footer. See HTML_HEADER for more information on how to generate a default +# footer and what special commands can be used inside the footer. See also +# section "Doxygen usage" for information on how to generate the default footer +# that doxygen normally uses. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style +# sheet that is used by each HTML page. It can be used to fine-tune the look of +# the HTML output. If left blank doxygen will generate a default style sheet. +# See also section "Doxygen usage" for information on how to generate the style +# sheet that doxygen normally uses. +# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as +# it is more robust and this tag (HTML_STYLESHEET) will in the future become +# obsolete. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_STYLESHEET = + +# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined +# cascading style sheets that are included after the standard style sheets +# created by doxygen. Using this option one can overrule certain style aspects. +# This is preferred over using HTML_STYLESHEET since it does not replace the +# standard style sheet and is therefore more robust against future updates. +# Doxygen will copy the style sheet files to the output directory. +# Note: The order of the extra style sheet files is of importance (e.g. the last +# style sheet in the list overrules the setting of the previous ones in the +# list). For an example see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_STYLESHEET = CMake/DoxyStyle/doxygenStyles.css + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that the +# files will be copied as-is; there are no commands or markers available. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_FILES = + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen +# will adjust the colors in the style sheet and background images according to +# this color. Hue is specified as an angle on a colorwheel, see +# http://en.wikipedia.org/wiki/Hue for more information. For instance the value +# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 +# purple, and 360 is red again. +# Minimum value: 0, maximum value: 359, default value: 220. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors +# in the HTML output. For a value of 0 the output will use grayscales only. A +# value of 255 will produce the most vivid colors. +# Minimum value: 0, maximum value: 255, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the +# luminance component of the colors in the HTML output. Values below 100 +# gradually make the output lighter, whereas values above 100 make the output +# darker. The value divided by 100 is the actual gamma applied, so 80 represents +# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not +# change the gamma. +# Minimum value: 40, maximum value: 240, default value: 80. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting this +# to YES can help to show when doxygen was last run and thus if the +# documentation is up to date. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_TIMESTAMP = NO + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_DYNAMIC_SECTIONS = NO + +# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries +# shown in the various tree structured indices initially; the user can expand +# and collapse entries dynamically later on. Doxygen will expand the tree to +# such a level that at most the specified number of entries are visible (unless +# a fully collapsed tree already exceeds this amount). So setting the number of +# entries 1 will produce a full collapsed tree by default. 0 is a special value +# representing an infinite number of entries and will result in a full expanded +# tree by default. +# Minimum value: 0, maximum value: 9999, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_INDEX_NUM_ENTRIES = 100 + +# If the GENERATE_DOCSET tag is set to YES, additional index files will be +# generated that can be used as input for Apple's Xcode 3 integrated development +# environment (see: http://developer.apple.com/tools/xcode/), introduced with +# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a +# Makefile in the HTML output directory. Running make will produce the docset in +# that directory and running make install will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at +# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# for more information. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_DOCSET = NO + +# This tag determines the name of the docset feed. A documentation feed provides +# an umbrella under which multiple documentation sets from a single provider +# (such as a company or product suite) can be grouped. +# The default value is: Doxygen generated docs. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# This tag specifies a string that should uniquely identify the documentation +# set bundle. This should be a reverse domain-name style string, e.g. +# com.mycompany.MyDocSet. Doxygen will append .docset to the name. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style +# string, e.g. com.mycompany.MyDocSet.documentation. +# The default value is: org.doxygen.Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. +# The default value is: Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three +# additional HTML index files: index.hhp, index.hhc, and index.hhk. The +# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop +# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on +# Windows. +# +# The HTML Help Workshop contains a compiler that can convert all HTML output +# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML +# files are now used as the Windows 98 help format, and will replace the old +# Windows help format (.hlp) on all Windows platforms in the future. Compressed +# HTML files also contain an index, a table of contents, and you can search for +# words in the documentation. The HTML workshop also contains a viewer for +# compressed HTML files. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_HTMLHELP = NO + +# The CHM_FILE tag can be used to specify the file name of the resulting .chm +# file. You can add a path in front of the file if the result should not be +# written to the html output directory. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_FILE = + +# The HHC_LOCATION tag can be used to specify the location (absolute path +# including file name) of the HTML help compiler (hhc.exe). If non-empty, +# doxygen will try to run the HTML help compiler on the generated index.hhp. +# The file has to be specified with full path. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +HHC_LOCATION = + +# The GENERATE_CHI flag controls if a separate .chi index file is generated +# (YES) or that it should be included in the master .chm file (NO). +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +GENERATE_CHI = NO + +# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc) +# and project file content. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_INDEX_ENCODING = + +# The BINARY_TOC flag controls whether a binary table of contents is generated +# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it +# enables the Previous and Next buttons. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members to +# the table of contents of the HTML help documentation and to the tree view. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that +# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help +# (.qch) of the generated HTML documentation. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify +# the file name of the resulting .qch file. The path specified is relative to +# the HTML output folder. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help +# Project output. For more information please see Qt Help Project / Namespace +# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace). +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt +# Help Project output. For more information please see Qt Help Project / Virtual +# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual- +# folders). +# The default value is: doc. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_VIRTUAL_FOLDER = doc + +# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom +# filter to add. For more information please see Qt Help Project / Custom +# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- +# filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see Qt Help Project / Custom +# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- +# filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's filter section matches. Qt Help Project / Filter Attributes (see: +# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_SECT_FILTER_ATTRS = + +# The QHG_LOCATION tag can be used to specify the location of Qt's +# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the +# generated .qhp file. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be +# generated, together with the HTML files, they form an Eclipse help plugin. To +# install this plugin and make it available under the help contents menu in +# Eclipse, the contents of the directory containing the HTML and XML files needs +# to be copied into the plugins directory of eclipse. The name of the directory +# within the plugins directory should be the same as the ECLIPSE_DOC_ID value. +# After copying Eclipse needs to be restarted before the help appears. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the Eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have this +# name. Each documentation set should have its own identifier. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. + +ECLIPSE_DOC_ID = QuasarApp. + +# If you want full control over the layout of the generated HTML pages it might +# be necessary to disable the index and replace it with your own. The +# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top +# of each HTML page. A value of NO enables the index and the value YES disables +# it. Since the tabs in the index contain the same information as the navigation +# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +DISABLE_INDEX = NO + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. If the tag +# value is set to YES, a side panel will be generated containing a tree-like +# index structure (just like the one that is generated for HTML Help). For this +# to work a browser that supports JavaScript, DHTML, CSS and frames is required +# (i.e. any modern browser). Windows users are probably better off using the +# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can +# further fine-tune the look of the index. As an example, the default style +# sheet generated by doxygen has an example that shows how to put an image at +# the root of the tree instead of the PROJECT_NAME. Since the tree basically has +# the same information as the tab index, you could consider setting +# DISABLE_INDEX to YES when enabling this option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_TREEVIEW = YES + +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that +# doxygen will group on one line in the generated HTML documentation. +# +# Note that a value of 0 will completely suppress the enum values from appearing +# in the overview section. +# Minimum value: 0, maximum value: 20, default value: 4. +# This tag requires that the tag GENERATE_HTML is set to YES. + +ENUM_VALUES_PER_LINE = 4 + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used +# to set the initial width (in pixels) of the frame in which the tree is shown. +# Minimum value: 0, maximum value: 1500, default value: 250. +# This tag requires that the tag GENERATE_HTML is set to YES. + +TREEVIEW_WIDTH = 250 + +# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to +# external symbols imported via tag files in a separate window. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +EXT_LINKS_IN_WINDOW = NO + +# Use this tag to change the font size of LaTeX formulas included as images in +# the HTML documentation. When you change the font size after a successful +# doxygen run you need to manually remove any form_*.png images from the HTML +# output directory to force them to be regenerated. +# Minimum value: 8, maximum value: 50, default value: 10. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FORMULA_FONTSIZE = 10 + +# Use the FORMULA_TRANPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are not +# supported properly for IE 6.0, but are supported on all modern browsers. +# +# Note that when changing this option you need to delete any form_*.png files in +# the HTML output directory before the changes have effect. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FORMULA_TRANSPARENT = YES + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see +# http://www.mathjax.org) which uses client side Javascript for the rendering +# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX +# installed or if you want to formulas look prettier in the HTML output. When +# enabled you may also need to install MathJax separately and configure the path +# to it using the MATHJAX_RELPATH option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +USE_MATHJAX = NO + +# When MathJax is enabled you can set the default output format to be used for +# the MathJax output. See the MathJax site (see: +# http://docs.mathjax.org/en/latest/output.html) for more details. +# Possible values are: HTML-CSS (which is slower, but has the best +# compatibility), NativeMML (i.e. MathML) and SVG. +# The default value is: HTML-CSS. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_FORMAT = HTML-CSS + +# When MathJax is enabled you need to specify the location relative to the HTML +# output directory using the MATHJAX_RELPATH option. The destination directory +# should contain the MathJax.js script. For instance, if the mathjax directory +# is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax +# Content Delivery Network so you can quickly see the result without installing +# MathJax. However, it is strongly recommended to install a local copy of +# MathJax from http://www.mathjax.org before deployment. +# The default value is: http://cdn.mathjax.org/mathjax/latest. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest + +# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax +# extension names that should be enabled during MathJax rendering. For example +# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_EXTENSIONS = + +# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces +# of code that will be used on startup of the MathJax code. See the MathJax site +# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an +# example see the documentation. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_CODEFILE = + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box for +# the HTML output. The underlying search engine uses javascript and DHTML and +# should work on any modern browser. Note that when using HTML help +# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) +# there is already a search function so this one should typically be disabled. +# For large projects the javascript based search engine can be slow, then +# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to +# search using the keyboard; to jump to the search box use + S +# (what the is depends on the OS and browser, but it is typically +# , /