From d4df66ead74b94eec4306a325a9e15160b37d037 Mon Sep 17 00:00:00 2001 From: Thomas Date: Mon, 3 Jan 2022 16:26:55 +0100 Subject: [PATCH] =?UTF-8?q?score=20manager=20beta=20(c'est=20sign=C3=A9)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- QUESTIONS.md | 4 +- headers/game.h | 1 + headers/pixelManager.h | 6 ++- headers/scoresManager.h | 26 +++++++++++ scores.kus | 3 ++ src/gameBasics.cpp | 12 ++++- src/pixelManager.cpp | 4 ++ src/scoresManager.cpp | 97 +++++++++++++++++++++++++++++++++++++++++ 8 files changed, 150 insertions(+), 3 deletions(-) create mode 100644 headers/scoresManager.h create mode 100644 scores.kus create mode 100644 src/scoresManager.cpp diff --git a/QUESTIONS.md b/QUESTIONS.md index 140d4f6..704c164 100644 --- a/QUESTIONS.md +++ b/QUESTIONS.md @@ -4,4 +4,6 @@ Questions que je (Thomas Rubini) voudrais poser - Est-ce que vouloir faire des structures optimisées (pas de redondance de mémoire) est une bonne chose, ou pas importa,t ? - Est-ce que traduire les chars A B et C (identifiants des types d'aliens) tirés de la config en valeurs d'enum est une bonne chose, pas important, ou contre-productif ? - Est-ce que mon implémentation du réseau est bonne ? -- Est-on obligé d'utiliser size_t quand on sait que la taille du vecteur ne dépassera jamais concrètement la taille d'un int (cas précis : taille de 100 maximum, est-on obligé d'utiliser size_t de 8 bytes ?) \ No newline at end of file +- Est-on obligé d'utiliser size_t quand on sait que la taille du vecteur ne dépassera jamais concrètement la taille d'un int (cas précis : taille de 100 maximum, est-on obligé d'utiliser size_t de 8 bytes ?) +- Est-ce mon implémentation du multithreading est bonne ? +- Que pensez-vous de la sémantique de déplacement, plutot que la référence constante ? \ No newline at end of file diff --git a/headers/game.h b/headers/game.h index 8a6007a..f25e5f2 100644 --- a/headers/game.h +++ b/headers/game.h @@ -34,6 +34,7 @@ private: // basic methods void display(); void updateColumns(); + void handleScoreSaving(); // managers void managePlayers(); diff --git a/headers/pixelManager.h b/headers/pixelManager.h index f51fcf3..571270b 100644 --- a/headers/pixelManager.h +++ b/headers/pixelManager.h @@ -1,6 +1,7 @@ #ifndef GUARD_PIXELMANAGER_H #define GUARD_PIXELMANAGER_H +#include #include "mingl/mingl.h" #include "mingl/shape/line.h" #include "mingl/shape/triangle.h" @@ -8,6 +9,8 @@ #include "mingl/shape/circle.h" #include "mingl/gui/sprite.h" +using namespace std; + class PixelManager{ public: MinGL& window; @@ -29,7 +32,8 @@ public: unsigned getScreenWidth(); void startFrame(); void endFrame(); - + + void askPlayerNameMenu(string& name); }; diff --git a/headers/scoresManager.h b/headers/scoresManager.h new file mode 100644 index 0000000..f09b043 --- /dev/null +++ b/headers/scoresManager.h @@ -0,0 +1,26 @@ +#ifndef GUARD_SCORESMANAGER_H +#define GUARD_SCORESMANAGER_H + +#include +#include +#include + +using namespace std; + +struct Score{ + string name; + unsigned points; + Score() = default; + Score(const string& name, unsigned points); +}; + +class ScoresManager { +public: + vector scores; + void inputScore(const string& name, unsigned points); + void readFile(); + void writeFile(); +}; + + +#endif diff --git a/scores.kus b/scores.kus new file mode 100644 index 0000000..be45a37 --- /dev/null +++ b/scores.kus @@ -0,0 +1,3 @@ +11083679872916328441 +thomas2,2 +thomas,1 diff --git a/src/gameBasics.cpp b/src/gameBasics.cpp index 7f9d87c..0cb8a8b 100644 --- a/src/gameBasics.cpp +++ b/src/gameBasics.cpp @@ -23,6 +23,16 @@ void Game::updateColumns(){ } } +void Game::handleScoreSaving(){ + cout << players[0].score << endl; // will remove + + string pName; + pm.askPlayerNameMenu(pName); + if(playMode==PlayMode::TWO_LOCAL){ + + } +} + void Game::managedGames() { playMode = PlayMode::NONE; @@ -32,7 +42,7 @@ void Game::managedGames() { playMode = initialMenuHandler(); }else{ playGame(); // will read the playMode - cout << players[0].score << endl; // will remove + handleScoreSaving(); cout << "END OF GAME" << endl; break; // TODO remove if(!deathMenuHandler()) playMode = PlayMode::NONE; // back to the main menu diff --git a/src/pixelManager.cpp b/src/pixelManager.cpp index 0b64f66..b557465 100644 --- a/src/pixelManager.cpp +++ b/src/pixelManager.cpp @@ -44,6 +44,10 @@ void PixelManager::drawPlayer(const nsGraphics::Vec2D& baseVector, unsigned widt window << nsShape::Triangle(nsGraphics::Vec2D(15+width,720-PLAYER_HEIGHT/2)+baseVector, nsGraphics::Vec2D(15+width*2,720-PLAYER_HEIGHT/2)+baseVector, nsGraphics::Vec2D(15+width,720-PLAYER_HEIGHT*0.9)+baseVector, color); } +void PixelManager::askPlayerNameMenu(string& name){ + name = "Thomas"; +} + void PixelManager::drawMissile(const nsGraphics::Vec2D& baseVector, unsigned width, const nsGraphics::RGBAcolor& color){ window << nsShape::Rectangle(baseVector, baseVector + Position(width, width * PROJ_LENGTH_FACTOR), color); } diff --git a/src/scoresManager.cpp b/src/scoresManager.cpp new file mode 100644 index 0000000..ec7de78 --- /dev/null +++ b/src/scoresManager.cpp @@ -0,0 +1,97 @@ +#include +#include +#include +#include +#include +#include "scoresManager.h" + +// Our own format : kustom +#define SCORE_FILE "scores.kus" + +#define SECRET_KEY "WeAreAGroupOf3" + +void readWholeFile(ifstream& ifs, string& str){ + stringstream ss; + ss << ifs.rdbuf(); + str.assign(ss.str()); +} + +static std::hash hasher; + +bool verifyHash(size_t savedHash, string& content){ + // non-cryptographic hash, but it is part of the std, and openssl is REALLY difficult + // to use in C++ while keeping semantic, because there are no wrappers... + int actualHash = hasher(content+SECRET_KEY); + return actualHash==savedHash; +} + +void ScoresManager::readFile() { + ifstream ifs(SCORE_FILE); + if(!ifs.is_open())return; // file can not exist + + /* the first line is the hash sum of (the following content + a secret key) + * We use it to generate a data signature to prevent users + * from tampering with the save file + */ + size_t hash; + ifs >> hash; + + string content; + readWholeFile(ifs, content); + + scores.clear(); + if(verifyHash(hash, content)){ + stringstream ss(content); + + string line; + Score s; + while(true){ + getline(ss, line); + if(ss.eof())break; + + size_t index = line.find(','); + s.name = line.substr(0, index); + s.points = stoi(line.substr(index)); + } + }else{ + cerr << "Integrity check of the save file failed. Has it been tampered ?" << endl; + } +} + +void ScoresManager::writeFile() { + ofstream ofs(SCORE_FILE); + + string str; + cout << scores.size() << endl; + for(Score& sc : scores){ + str.append(sc.name); + str.append(","); + str.append(to_string(sc.points)); + str.append("\n"); + } + + ofs << hasher(str) << endl << str; +} + +/** + * Insertion sort, probably the most efficient here + */ +void ScoresManager::inputScore(const string& name, unsigned points) { + auto ite = scores.begin(); + while(ite!=scores.end()){ + if(points>ite->points) { + scores.emplace(ite, name, points); + break; + } + ++ite; + } + if(ite==scores.end())scores.emplace(ite, name, points); + if(scores.size()==6)scores.resize(5); + +} + +// Not sure if I should use move semantics +Score::Score(const string& name, unsigned int points) { + this->name = name; + this->points = points; +}