// // Created by BreizhHardware on 04/12/2024. // #include "networking.h" std::unordered_map> playerPositions; std::unordered_map> lastKeepAlive; bool initServer() { std::cout << "Initializing server..." << std::endl; if (SDLNet_ResolveHost(&ip, NULL, 1234) == -1) { std::cerr << "SDLNet_ResolveHost: " << SDLNet_GetError() << std::endl; return false; } server = SDLNet_TCP_Open(&ip); if (!server) { std::cerr << "SDLNet_TCP_Open: " << SDLNet_GetError() << std::endl; return false; } std::cout << "Server initialized!" << std::endl; return true; } void acceptClients() { while (game_running) { TCPsocket clientSocket = SDLNet_TCP_Accept(server); if (clientSocket) { clients.push_back(clientSocket); int clientId = clients.size() - 1; createNewPlayer(clientId); updateKeepAlive(clientId); Shark shark(0, 0, 0.1, 0.1,0, 150, 150, renderer,players_server); shark.updatePosition(0, 0); std::thread clientThread([clientSocket, clientId, &shark]() { std::thread keepAliveThread(sendKeepAlive, clientSocket); keepAliveThread.detach(); while (running) { std::string message = receiveMessage(clientSocket); if (!message.empty()) { message = processReceivedData(message); std::cout << "Server received: " << message << std::endl; if (message == "keepalive") { updateKeepAlive(clientId); } else if (message.find(";move;") != std::string::npos) { char direction[20]; sscanf(message.c_str(), "%d;move;%s", &clientId, &direction); int newX = 0, newY = 0; std::tie(newX, newY) = updatePlayerPosition(clientId, direction); // Mettre à jour la position du joueur players_server[clientId].updatePosition(newX, newY); std::string updatedMessage = std::to_string(clientId) + ";moved;" + std::to_string(newX) + "," + std::to_string(newY); for (TCPsocket client : clients) { sendMessage(client, updatedMessage); } } else if (message.find(";shark_moved;") != std::string::npos) { int sharkId, x, y; sscanf(message.c_str(), "%d;shark_moved;%d,%d", &sharkId, &x, &y); shark.updatePosition(x, y); std::string updatedMessage = std::to_string(sharkId) + ";shark_moved;" + std::to_string(x) + "," + std::to_string(y); for (TCPsocket client : clients) { sendMessage(client, updatedMessage); } } } SDL_Delay(1); } lastKeepAlive.erase(clientId); SDLNet_TCP_Close(clientSocket); }); clientThread.detach(); } SDL_Delay(100); } } std::vector split(const std::string& str, char delimiter) { std::vector result; std::string temp; for (char ch : str) { if (ch == delimiter) { if (!temp.empty()) { // On évite d'ajouter des chaînes vides si nécessaire result.push_back(temp); } temp.clear(); // Réinitialise pour le prochain segment } else { temp += ch; } } if (!temp.empty()) { // Ajouter le dernier segment s'il existe result.push_back(temp); } return result; } std::pair updatePlayerPosition(int clientId, const std::string& direction) { std::cout << "Updating player position for client " << clientId << " Direction: "<< direction << std::endl; auto& pos = playerPositions[clientId]; int& newX = pos.first; int& newY = pos.second; int speed = 5; std::vector directions = split(direction, '-'); if(directions.size() > 1 ){ speed = 3; } for(const std::string dist : directions){ if (dist == "up") { if (newY-speed < 0) { newY = 0; } else { newY -= speed; } } else if (dist == "down") { if (newY+speed > ENV_HEIGHT - windowHeight) { newY = ENV_HEIGHT - windowHeight; } else { newY += speed; } } else if (dist == "left") { if (newX-speed < 0) { newX = 0; } else { newX -= speed; } } else if (dist == "right") { if (newX+speed > ENV_WIDTH - windowWidth) { newX = ENV_WIDTH - windowWidth; } else { newX += speed; } } } return {newX, newY}; } void createNewPlayer(int clientId) { if (clientId < 0) { std::cerr << "Invalid client ID: " << clientId << std::endl; return; } // Create a new player at a default position (e.g., 0, 0) Player newPlayer(0, 0, 5, renderer, clientId); players_server.push_back(newPlayer); playerPositions[clientId] = {0, 0}; // Initialize player position // Send the list of existing players to the new client std::string playerListMessage = "playerList;"; for (auto& player : players_server) { auto [x, y] = player.getPlayerPos(); playerListMessage += std::to_string(player.getPlayerId()) + "," + std::to_string(x) + "," + std::to_string(y) + ";"; } sendMessage(clients[clientId], playerListMessage); // Broadcast the new player to all clients std::string newPlayerMessage = "newPlayer;" + std::to_string(clientId) + ",0,0;"; for (TCPsocket client : clients) { sendMessage(client, newPlayerMessage); } } void updateKeepAlive(int clientId) { lastKeepAlive[clientId] = std::chrono::steady_clock::now(); } void checkClientAlive() { auto now = std::chrono::steady_clock::now(); for (auto it = lastKeepAlive.begin(); it != lastKeepAlive.end();) { if (std::chrono::duration_cast(now - it->second).count() > 5) { std::cerr << "Client " << it->first << " is not responding. Removing..." << std::endl; SDLNet_TCP_Close(clients[it->first]); clients.erase(clients.begin() + it->first); playerPositions.erase(it->first); // Supprimer la position du joueur it = lastKeepAlive.erase(it); } else { ++it; } } } void closeServer() { std::string quitMessage = "host;quit"; for (TCPsocket client : clients) { sendMessage(client, quitMessage); } // Fermer les sockets et nettoyer les ressources for (TCPsocket client : clients) { SDLNet_TCP_Close(client); } clients.clear(); SDLNet_TCP_Close(server); } void handleServerMessages() { std::string message = receiveMessage(server); if (!message.empty()) { std::cout << "Server received: " << message << std::endl; if (message.find(";moved;") != std::string::npos) { int clientId, x, y; sscanf(message.c_str(), "%d;moved;%d,%d", &clientId, &x, &y); // Mettre à jour la position du joueur dans players_server for (auto& player : players_server) { std::cout << "Player ID: " << player.getPlayerId() << std::endl; std::cout << "Client ID: " << clientId << std::endl; std::cout << "PlayerId == ClientId: " << (player.getPlayerId() == clientId) << std::endl; if (player.getPlayerId() == clientId) { player.updatePosition(x, y); std::cout << "Player " << clientId << " moved to " << player.getUnifiedX() << ", " << player.getUnifiedY() << std::endl; break; } } } } } void sendSharkPosition(TCPsocket socket, int sharkId, int x, int y) { std::string message = std::to_string(sharkId) + ";shark_moved;" + std::to_string(x) + "," + std::to_string(y); sendMessage(socket, message); } std::string processReceivedData(const std::string& data) { std::string filteredData; for (char c : data) { if (std::isalnum(c) || c == ';' || c == '-' || c == '_' || std::isalpha(c)) { filteredData += c; } } return filteredData; }