int network_udp_reopen(UDPsocket udp, int port) { if (udp != NULL) { network_udp_close(udp); } udp = network_udp_open(port); return 0; }
/* * network_udp_reopen() - Close and reopen the given UDP socket on the given port * @udp: the socket to recreate * @port: the port to use */ int network_udp_reopen(UDPsocket* udp, int port) { if (*udp != nullptr) { // If the socket needs to be closed network_udp_close(udp); // Close the socket } *udp = network_udp_open(port); // Open the socket on the given port return 0; // Return 0 on success }
/* * BEE::net_session_join() - Attempt to join a session at the given IP address * @ip: the IP address to attempt to connect to * @player_name: the name of the player which will be sent to the host */ int BEE::net_session_join(const std::string& ip, const std::string& player_name) { net->players.clear(); // Clear the previous player map net->udp_recv = network_udp_open(net->id); // Open a UDP listening socket to receive messages from the server if (net->udp_recv == nullptr) { return 1; // Return 1 if the receiving socket failed to open } net->channel = network_udp_bind(&net->udp_send, -1, ip, net->id); // Bind a sending socket to the given server IP address if (net->channel == -1) { network_udp_close(&net->udp_recv); // Close the receiving socket return 2; // Return 2 if the sending socket failed to bind } network_udp_send(net->udp_send, net->channel, 0, 1, 0); // Send a server connection request if (network_packet_realloc(net->udp_data, 8)) { // Attempt to allocate space to receive data network_udp_close(&net->udp_recv); // Close the sockets network_udp_close(&net->udp_send); return 3; // Return 3 if the allocation failed } Uint32 t = get_ticks(); // Get the current time int r = network_udp_recv(net->udp_recv, net->udp_data); // Attempt to receive data while ((r < 1)||(get_ticks() - t < net->timeout)) { // Wait to receive data until we timeout r = network_udp_recv(net->udp_recv, net->udp_data); // Attempt to receive data } if ((r < 1)||(net->udp_data->data[0] != 1)) { // If no data was received or if the data was not a connection response network_udp_close(&net->udp_recv); // Close the sockets network_udp_close(&net->udp_send); messenger_send({"engine", "network"}, BEE_MESSAGE_WARNING, "net_session_join() : Failed to connect to " + ip); return 4; // Return 4 on failed to connect } // Set connection info net->self_id = net->udp_data->data[1]; net->is_connected = true; messenger_send({"engine", "network"}, BEE_MESSAGE_INFO, "net_session_join() : Connected to server with id " + net->udp_data->data[1]); return 0; // Return 0 on success }
/* * BEE::net_session_start() - Begin hosting a network session for others to join over UDP * @session_name: the name that the session will identify as * @max_players: the maximum amount of people connected to the session including the host * @player_name: the name of the player who's hosting */ int BEE::net_session_start(const std::string& session_name, int max_players, const std::string& player_name) { net->players.clear(); // Clear all old player data net->udp_recv = network_udp_open(net->id); // Open a UDP listening socket to receive from all clients if (net->udp_recv == nullptr) { return 1; // Return 1 if the socket failed to open } // Set the session info net->name = session_name; net->max_players = max_players; net->self_id = 0; net->players.insert(std::pair<int,UDPsocket>(net->self_id, nullptr)); // Insert ourself into the player map // Set connection info net->is_connected = true; net->is_host = true; return 0; // Return 0 on success }
/* * BEE::net_session_find() - Query the local network for available sessions */ std::map<std::string,std::string> BEE::net_session_find() { net->servers.clear(); // Clear the previously available servers net->udp_recv = network_udp_open(net->id); // Open a UDP listening socket to receive responses from the servers if (net->udp_recv == nullptr) { messenger_send({"engine", "network"}, BEE_MESSAGE_WARNING, "net_session_find() : UDP listening socket failed to open"); return net->servers; // Return an empty map if the receiving socket failed to open } net->channel = network_udp_bind(&net->udp_send, -1, "255.255.255.255", net->id); // Bind a sending socket to the broadcast IP 255.255.255.255 if (net->channel == -1) { network_udp_close(&net->udp_recv); // Close the receiving socket messenger_send({"engine", "network"}, BEE_MESSAGE_WARNING, "net_session_find() : UDP broadcast socket failed to bind"); return net->servers; // Return an empty map if the sending socket failed to bind } network_udp_send(net->udp_send, net->channel, net->self_id, 3, 0); // Send a server name info request if (network_packet_realloc(net->udp_data, 8)) { // Attempt to allocate space to receive data network_udp_close(&net->udp_recv); // Close the sockets network_udp_close(&net->udp_send); messenger_send({"engine", "network"}, BEE_MESSAGE_WARNING, "net_session_find() : Failed to allocate space to receive data"); return net->servers; // Return an empty map if the allocation failed } Uint32 t = get_ticks(); // Get the current time int r = network_udp_recv(net->udp_recv, net->udp_data); // Attempt to receive data while (get_ticks() - t < net->timeout) { // Continue receiving until we timeout if ((r == 1)&&(net->udp_data->data[2] == 3)) { // If data was received and it is a server name info response std::string name = chra(net->udp_data->data+4); // Get the server name from the data net->servers.insert(std::make_pair(network_get_address(net->udp_data->address.host), name)); // Add the server to the list of available servers } r = network_udp_recv(net->udp_recv, net->udp_data); // Attempt to receive more data } network_udp_close(&net->udp_recv); // Close the receiving socket network_udp_close(&net->udp_send); // Close the sending socket return net->servers; // Return the filled map on success }