#include "UndefinedTask.hpp" #include "../types.hpp" #include #include #include #include #include #include #include #include "Context.hpp" #include "packets/base/Packet.hpp" #include "packets/base/SecurityMode.hpp" #include "packets/search/SearchPacketData.hpp" namespace drp::task { void UndefinedTask::handle(Context& context) { std::cout << "[Task - Undefined] List of peers: " << std::endl; for (const auto& peer : context.remotePeers) std::cout << "\tPeer(id=" << peer.second->information.id << ", " << "status=" << std::to_string(static_cast(peer.second->information.status)) << ")" << std::endl; // search if a server is available among the peer. const auto& server = std::ranges::find_if( context.remotePeers, [&](const auto& peer) { return peer.second->information.status == TaskType::SERVER; } ); // if a server have been found, use it if (server != context.remotePeers.end()) { // if a server have been found, use it context.server = server->second; context.me.status = TaskType::CLIENT; return; } // wait that no more new peers are being discovered if ( std::chrono::high_resolution_clock::now() - context.latestPeerDiscovery > std::chrono::milliseconds(5000) ) { std::cout << "No more peers discovered." << std::endl; // otherwise, become the server if we have the highest ID. // TODO(Faraphel): should use the machine with the lowest average ping if (context.me.serverEnabled) { // find the remote peer with the highest id that can be a server const auto serverCandidate = std::ranges::max_element( context.remotePeers, [&](auto& remotePeer1, auto& remotePeer2) { return ( (remotePeer1.second->information.serverEnabled ? remotePeer1.first : 0) < (remotePeer2.second->information.serverEnabled ? remotePeer2.first : 0) ); } ); // check if we are this peer if (context.me.id == serverCandidate->first) { std::cout << "[Task - Undefined] Becoming server..." << std::endl; // set ourselves as the server context.server = serverCandidate->second; context.me.status = TaskType::SERVER; return; } } std::this_thread::sleep_for(std::chrono::seconds(1)); } // prepare a search message packet::base::Packet packet {}; packet::search::SearchPacketData packetData {}; // broadcast message packet.channel = 0; packet.securityMode = static_cast(packet::base::SecurityMode::PLAIN); // search message with the time of the message being sent packetData.timestamp = std::chrono::high_resolution_clock::now(); packet.setContent(packetData.toGeneric()); std::cout << "[Task - Undefined] Looking for new peers." << std::endl; // send the search message if (sendto( context.socket, &packet, sizeof(packet), 0, context.broadcastAddressInfo->ai_addr, context.broadcastAddressInfo->ai_addrlen ) == -1) std::cerr << "[Task - Undefined] Could not send search event: " << strerror(errno) << std::endl; std::this_thread::sleep_for(std::chrono::seconds(1)); } }