diff --git a/build/CMakeFiles/MCC.dir/src/game/Game.cpp.o b/build/CMakeFiles/MCC.dir/src/game/Game.cpp.o index e037b80dd8d75647d5fa06474789506bc7821dcd..53f796947b10805320716feed18f8053f0275ee1 100644 Binary files a/build/CMakeFiles/MCC.dir/src/game/Game.cpp.o and b/build/CMakeFiles/MCC.dir/src/game/Game.cpp.o differ diff --git a/build/CMakeFiles/MCC.dir/src/game/GameEntities.cpp.o b/build/CMakeFiles/MCC.dir/src/game/GameEntities.cpp.o index b8921f8be15f6cffc96345be54816869062bcc93..437141078590fb5657394a1806307788cdc72050 100644 Binary files a/build/CMakeFiles/MCC.dir/src/game/GameEntities.cpp.o and b/build/CMakeFiles/MCC.dir/src/game/GameEntities.cpp.o differ diff --git a/build/CMakeFiles/MCC.dir/src/manager/MenuManager.cpp.o b/build/CMakeFiles/MCC.dir/src/manager/MenuManager.cpp.o index 7bebee71455c7d8752e557fa8bdb92d6f8635b33..6658d47c84d712263335458db21f0aa3b273aa42 100644 Binary files a/build/CMakeFiles/MCC.dir/src/manager/MenuManager.cpp.o and b/build/CMakeFiles/MCC.dir/src/manager/MenuManager.cpp.o differ diff --git a/build/CMakeFiles/MCC.dir/src/manager/NetworkManager.cpp.o b/build/CMakeFiles/MCC.dir/src/manager/NetworkManager.cpp.o index 40508bfef0af0cf0d78ea56b42614e47b4bc10fa..eaa10dd2179ae013429a8c80c75f8bee14fa59bf 100644 Binary files a/build/CMakeFiles/MCC.dir/src/manager/NetworkManager.cpp.o and b/build/CMakeFiles/MCC.dir/src/manager/NetworkManager.cpp.o differ diff --git a/build/CMakeFiles/MCC.dir/src/manager/WorldManager.cpp.o b/build/CMakeFiles/MCC.dir/src/manager/WorldManager.cpp.o index 65a55d223d8d1938949433f64b5f07507f0b2008..d269e6b1d56096d8bd53ca2671fa127f4ef0b8a8 100644 Binary files a/build/CMakeFiles/MCC.dir/src/manager/WorldManager.cpp.o and b/build/CMakeFiles/MCC.dir/src/manager/WorldManager.cpp.o differ diff --git a/build/MCC b/build/MCC index 7da839514ac9d9fd71ff903e3e36705374914000..c5993ae3ce70c1c423cf31822dd94eb616f61fd0 100755 Binary files a/build/MCC and b/build/MCC differ diff --git a/include/game/GameEntities.hpp b/include/game/GameEntities.hpp index d377664026272dac2d5d29bf250a7352ee9b4edf..4a7dee35ee43964c7ad38fd67dfc8290953af694 100644 --- a/include/game/GameEntities.hpp +++ b/include/game/GameEntities.hpp @@ -146,8 +146,9 @@ class Player : public Being void EndContact(b2Contact* contact,float deltaT) override; void getHit(STypeInstance* instance); void setState(EntityState state){this->state = state;} - void setId(int id){this->id = id;} + void setId(short int id){this->id = id;} + short int getId(){return id;} int getWidthArrow(){return widthArrow;} int getHeightArrow(){return heightArrow;} bool applySkill(const PSkill& skill); @@ -169,7 +170,8 @@ class Player : public Being Texture directionArrow; int widthArrow; int heightArrow; - int id; + // Par défaut à 0. 0 Est aussi l'identifiant du joueur hôte. + short int id = 0; Vec2 vectCollide; float angle = 0; diff --git a/include/manager/NetworkManager.hpp b/include/manager/NetworkManager.hpp index d12a7186133f4858c0d440cd178f1001c887ac30..837bbe0ed80e7c8535b5d95ee184535da75418de 100644 --- a/include/manager/NetworkManager.hpp +++ b/include/manager/NetworkManager.hpp @@ -49,11 +49,11 @@ class NetworkManager void joinServer(); void checkForNewPlayer(); - void Client_SendDatas(char datas[]); - void Server_SendDatas(char datas[]); + void Client_SendDatas(char* datas, size_t dataLength); + void Server_SendDatas(char* datas, size_t dataLength); char* Client_ReceiveDatas(); - vector<char> Server_ReceiveDatas(); + vector<vector<char>> Server_ReceiveDatas(); string generateQrCode(string address,int port); @@ -75,10 +75,13 @@ class NetworkManager } private: + void removePlayers(); + static NetworkManager* instance; int applicationSocket; - int cpt = 0; + // Commence toujours à 1 car le numéro 0 appartient à l'hôte. + int cpt = 1; IPaddress ip; Uint16 PORT = 1234; diff --git a/include/manager/WorldManager.hpp b/include/manager/WorldManager.hpp index 61cf5a2e321e11890f81fed7a3d4cf95e1c9eb72..f39981fc379ac3733f4830741532431aa2863127 100644 --- a/include/manager/WorldManager.hpp +++ b/include/manager/WorldManager.hpp @@ -68,7 +68,7 @@ class WorldManager : public IActor void loadTest(); void loadLobby(); void sendMessage(); - void analyseDatas(char* datas); + void analyseDatas(const char* datas); void fpsCounter(); void changePlayerState(EntityState state); void removeMoveInput(SDL_Keycode key); diff --git a/src/manager/NetworkManager.cpp b/src/manager/NetworkManager.cpp index 08f749abc6817dcc8ab717737a7799786a2fdbec..a57e331da45dc108087b835c974b1dc633defc7e 100644 --- a/src/manager/NetworkManager.cpp +++ b/src/manager/NetworkManager.cpp @@ -61,24 +61,26 @@ void NetworkManager::checkForNewPlayer(){ SDLNet_TCP_AddSocket(setJoueurs, joueur); std::cout << "Un joueur vient de se connecter ! " << std::endl; - char datas[5]; // 4 caractères pour les deux entiers et + 1 pour '\0' la terminaison de chaîne + const int lenDatas = sizeof(short int) * 2 + 1; + char datas[lenDatas]; short int commande = -2; short int id = cpt; std::memcpy(datas, &commande, sizeof(short int)); std::memcpy(datas + sizeof(short int), &id, sizeof(short int)); - datas[4] = '\0'; - if (SDLNet_TCP_Send(joueur, datas, 5) < 5) { + + datas[lenDatas - 1] = '\0'; + if (SDLNet_TCP_Send(joueur, datas, lenDatas) < lenDatas) { std::cerr << "Erreur lors de l'envoi des données au joueur " << cpt << " : " << SDLNet_GetError() << std::endl; } - // On prépare les données à envoyer aux autres joueurs. + // On prépare les données à envoyer aux autres joueurs en modifiant la commande initiale. commande = 0; std::memcpy(datas, &commande, sizeof(short int)); // Notifier les autres joueurs qu'il y a un nouveau joueur avec son ID. for (const auto& joueurExistant : joueurs) { if (joueurExistant.playerSocket != joueur) { - if (SDLNet_TCP_Send(joueurExistant.playerSocket, datas, 3) < 3) { + if (SDLNet_TCP_Send(joueurExistant.playerSocket, datas, lenDatas) < lenDatas) { std::cerr << "Erreur lors de l'envoi des données au joueur " << joueurExistant.id << " : " << SDLNet_GetError() << std::endl; } } @@ -91,8 +93,7 @@ void NetworkManager::checkForNewPlayer(){ /** * @brief Fonction réservée au client : envoie des données au serveur. */ -void NetworkManager::Client_SendDatas(char datas[]){ - size_t dataLength = strlen(datas); +void NetworkManager::Client_SendDatas(char* datas, size_t dataLength){ if (SDLNet_TCP_Send(playerZeroSocket, datas, dataLength) < dataLength) { std::cerr << "Erreur lors de l'envoi des données : " << SDLNet_GetError() << std::endl; } @@ -101,8 +102,7 @@ void NetworkManager::Client_SendDatas(char datas[]){ /** * @brief Fonction réservée au serveur : envoie des données aux clients. */ -void NetworkManager::Server_SendDatas(char datas[]){ - size_t dataLength = strlen(datas); +void NetworkManager::Server_SendDatas(char* datas, size_t dataLength){ for(Splayer joueur : joueurs){ if (SDLNet_TCP_Send(joueur.playerSocket, datas, dataLength) < dataLength) { std::cerr << "Erreur lors de l'envoi des données : " << SDLNet_GetError() << std::endl; @@ -121,7 +121,7 @@ void NetworkManager::Server_SendDatas(char datas[]){ char* NetworkManager::Client_ReceiveDatas() { // Je vérifie d'abord qu'il y a quelque chose à récupérer. if (SDLNet_CheckSockets(playerZeroSetSocket, 0) == 1) { - char* datas = new char[maxlen]; + char datas[maxlen]; if (datas == nullptr) { std::cerr << "Erreur d'allocation mémoire." << std::endl; return nullptr; @@ -130,25 +130,23 @@ char* NetworkManager::Client_ReceiveDatas() { int nb_recus = SDLNet_TCP_Recv(playerZeroSocket, datas, maxlen); if (nb_recus <= 0) { if (nb_recus == 0) { - std::cout << "La connexion a été fermée proprement par le client." << std::endl; + std::cout << "Le serveur s'est fermé" << std::endl; + // Il va falloir throw un truc pour que le client se déconnecte du mode en ligne ici. } else { std::cerr << "Erreur lors de la réception des données : " << SDLNet_GetError() << std::endl; } - delete[] datas; return nullptr; } // Alloue dynamiquement de la mémoire pour le résultat - char* result = new char[nb_recus + 1]; // +1 pour le caractère nul de fin de chaîne + char* result = new char[nb_recus]; if (result == nullptr) { std::cerr << "Erreur d'allocation mémoire pour le résultat." << std::endl; - delete[] datas; return nullptr; } + std::memcpy(result, datas, nb_recus); - result[nb_recus] = '\0'; - delete[] datas; return result; } @@ -162,75 +160,69 @@ char* NetworkManager::Client_ReceiveDatas() { /** * @brief Récupère les données envoyées par un joueur et en même temps les renvoie aux autres. - * */ -vector<char> NetworkManager::Server_ReceiveDatas(){ - // Buffer avec tous les paquets reçus par les joueurs. - vector<char> datasbuffer; +vector<vector<char>> NetworkManager::Server_ReceiveDatas() { + vector<vector<char>> datasbuffer; - char* datas = new char[maxlen]; + char datas[maxlen]; if (datas == nullptr) { - std::cerr << "Erreur d'allocation mémoire." << std::endl; + cerr << "Erreur d'allocation mémoire." << endl; return datasbuffer; } - if(SDLNet_CheckSockets(setJoueurs, 0) > 0){ - for (Splayer player : joueurs){ + if (SDLNet_CheckSockets(setJoueurs, 0) > 0) { + for (Splayer player : joueurs) { const TCPsocket sock = player.playerSocket; - if(SDLNet_SocketReady(sock) != 0){ + if (SDLNet_SocketReady(sock) != 0) { int len = SDLNet_TCP_Recv(sock, datas, maxlen); // Récupère les données à renvoyer aux autres joueurs. if (len > 0) { - char* result = new char[len]; - if (result == nullptr) { - std::cerr << "Erreur d'allocation mémoire pour le résultat." << std::endl; - continue; - } - - std::memcpy(result, datas, len); - result[len] = '\0'; - for (size_t j = 0; j < joueurs.size(); ++j) { - if (sock != joueurs[j].playerSocket) { - SDLNet_TCP_Send(joueurs[j].playerSocket, result, len); + vector<char> result(datas, datas + len); + for (size_t j = 0; j < joueurs.size(); ++j) { + if (sock != joueurs[j].playerSocket) { + SDLNet_TCP_Send(joueurs[j].playerSocket, result.data(), len); } } - datasbuffer.insert(datasbuffer.end(), datas, datas + sizeof(datas)); - delete[] result; - } - else if (len <= 0) { + datasbuffer.push_back(result); + } else if (len <= 0) { joueursASupprimer.push_back(sock); } } } + } + return datasbuffer; +} - if(joueursASupprimer.size() > 0){ - for(TCPsocket sock : joueursASupprimer){ - std::cout << "Joueur déconnecté" << std::endl; - SDLNet_TCP_DelSocket(setJoueurs,sock); - SDLNet_TCP_Close(sock); - - // Application de l'diome erase-remove_if - joueurs.erase( - std::remove_if( - joueurs.begin(), - joueurs.end(), - [&](Splayer p) { - return p.playerSocket == sock; - } - ) - ); +/** + * @brief Parcourt la liste des joueurs à supprimer et les supprime. + * + */ +void NetworkManager::removePlayers(){ + if(joueursASupprimer.size() > 0){ + for(TCPsocket sock : joueursASupprimer){ + std::cout << "Joueur déconnecté" << std::endl; + SDLNet_TCP_DelSocket(setJoueurs,sock); + SDLNet_TCP_Close(sock); + + // Application de l'diome erase-remove_if + joueurs.erase( + std::remove_if( + joueurs.begin(), + joueurs.end(), + [&](Splayer p) { + return p.playerSocket == sock; + } + ) + ); - if(joueurs.size() == 0){ - cout << "Il n'y a plus de joueurs" << endl; - } + if(joueurs.size() == 0){ + cout << "Il n'y a plus de joueurs" << endl; } - joueursASupprimer.clear(); } + joueursASupprimer.clear(); } - delete[] datas; - return datasbuffer; } /** diff --git a/src/manager/WorldManager.cpp b/src/manager/WorldManager.cpp index 758040768ca0cc24f61bd5e39a311f7e7190b194..6962d2f6c645ed408a7c0beb37dda09b918f0078 100644 --- a/src/manager/WorldManager.cpp +++ b/src/manager/WorldManager.cpp @@ -2,7 +2,10 @@ #include <cmath> /* - NB : Rajouter la possiblité de créer un pseudo quand on se connecte en ligne. + NB : + - Rajouter la possiblité de créer un pseudo quand on se connecte en ligne. + - Mettre des throw exception pour gérer les exceptions du networkManager. + - Faire apparaître le joueur qui s'est connecté. */ /** @@ -369,27 +372,23 @@ void WorldManager::updateInputStates(float deltaT){ /** * @brief Fonction qui gère la réception des paquets réseau et leur description. */ -void WorldManager::updateNetwork(){ +void WorldManager::updateNetwork() { // Pour le moment on vérifie tout le temps s'il y a un joueur qui se connecte. - if(game->isOnline()) - { - if(game->isHost())// Rajouter le test du fait que l'on soit dans le lobby (quand je l'aurai créé :) ). - { + if (game->isOnline()) { + if (game->isHost()) { networkManager.checkForNewPlayer(); - for(char datas : networkManager.Server_ReceiveDatas()){ - analyseDatas(&datas); + std::vector<std::vector<char>> vecdatas = networkManager.Server_ReceiveDatas(); + for (const std::vector<char>& datas : vecdatas) { + analyseDatas(datas.data()); // Passe un pointeur vers le tableau de char. } - } - else - { + } else { char* datas = networkManager.Client_ReceiveDatas(); analyseDatas(datas); - delete[] datas; } } } -void WorldManager::analyseDatas(char* datas){ +void WorldManager::analyseDatas(const char* datas){ // On analyse les données reçues. if(datas == nullptr){ // Gérer l'erreur. @@ -399,16 +398,21 @@ void WorldManager::analyseDatas(char* datas){ // On a reçu quelque chose. if(datas[0] != '\0') { + // Dans un premier temps, je récupère la commande. short int commande; - std::memcpy(&commande, datas, sizeof(short int)); - switch(commande) - { + memcpy(&commande, datas, sizeof(short int)); + + // Dans un second temps, en fonction de la commande, je fais ce qu'il faut faire. + switch (commande) { // Donne un id au joueur. - case -2: + case -2: { short int id; - std::memcpy(&id, datas + sizeof(short int), sizeof(short int)); + memcpy(&id, datas + sizeof(short int), sizeof(short int)); playerZero->setId(id); + // En même temps, il faut générer le joueur hôte avec l'id 0. + // Code pour générer le joueur hôte... break; + } // Un joueur a quitté. case -1: // Gérer le cas pour supprimer un joueur. @@ -418,20 +422,21 @@ void WorldManager::analyseDatas(char* datas){ // Gérer le cas pour créer un nouveau joueur. break; // On reçoit le message d'un autre joueur. - case 1: - { - short int senderId; - std::memcpy(&senderId, datas + sizeof(short int), sizeof(short int)); - std::string nomJoueur = "joueur" + std::to_string(senderId) + " : "; - std::string finalMessage = nomJoueur + std::string(datas + sizeof(short int) * 2); - messages.push_back(finalMessage); - } + case 1: { + short int senderId; + memcpy(&senderId, datas + sizeof(short int), sizeof(short int)); + string nomJoueur = "joueur_" + to_string(senderId) + " : "; + string message = nomJoueur + string(datas + 2 * sizeof(short int)); + messages.push_back(message); break; + } // Reçoit la modification de position d'un joueur. case 2: + // Gérer la modification de position. break; // La commande doit être corrompue... default: + // Gérer les commandes inconnues ou corrompues. break; } } @@ -548,14 +553,28 @@ void WorldManager::chatBox(){ * [int][char] */ void WorldManager::sendMessage() { - short int commande = 1; - char datas[sizeof(short int) + sizeof(input_buffer)]; - std::memcpy(datas, &commande, sizeof(short int)); - std::memcpy(datas + sizeof(short int), input_buffer, sizeof(input_buffer)); - if(game->isHost()){ - networkManager.Server_SendDatas(datas); - }else{ - networkManager.Client_SendDatas(datas); + const short int commande = 1; + const short int id = playerZero->getId(); + const short int lenBuffer = strlen(input_buffer); + int lenMessage = sizeof(short int) * 2 + lenBuffer + 1; // +1 c'est pour le caractère nul. + char message[lenMessage]; + + // Je copie la commande dans le message + std::memcpy(message, &commande, sizeof(short int)); + + // Ensuite je mets l'ID du joueur dans le message après la commande + std::memcpy(message + sizeof(short int), &id, sizeof(short int)); + + // Et enfin je rajoute le contenu de input_buffer dans le message après l'ID du joueur + std::memcpy(message + sizeof(short int) * 2, input_buffer, lenBuffer); + + // Je rajoute le caractère nul à la fin. + message[lenMessage - 1] = '\0'; + + if(game->isHost()) { + networkManager.Server_SendDatas(message, lenMessage); + } else { + networkManager.Client_SendDatas(message, lenMessage); } }