diff --git a/.gitignore b/.gitignore index 5ba3447..103a206 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,12 @@ -.vscode/* -*.bin -*.o -net.pb.* -*steam_api* \ No newline at end of file +.vscode/* +*.bin +*.o +net.pb.* +*steam_api* +release/* +*.obj +base.exp +base.lib +rtlgenrandom* +steamclient.exp +steamclient.lib \ No newline at end of file diff --git a/Makefile b/Makefile index eb3f9e6..da7ddd8 100644 --- a/Makefile +++ b/Makefile @@ -25,8 +25,8 @@ release: CXX_FLAGS += -DNDEBUG -DEMU_RELEASE_BUILD -Ofast release: LD_FLAGS += -lpthread release32: CXX_FLAGS += -m32 release32: LD_FLAGS += -m32 -debug: CXX_FLAGS += -g3 -fsanitize=address -debug: LD_FLAGS += -lasan +debug: CXX_FLAGS += -g3 +debug: LD_FLAGS += -lpthread release: library release32: release debug: library diff --git a/dll/network.cpp b/dll/network.cpp index 100480c..6d4a5a5 100644 --- a/dll/network.cpp +++ b/dll/network.cpp @@ -280,7 +280,7 @@ static int receive_packet(sock_t sock, IP_PORT *ip_port, char *data, unsigned lo return -1; } -static bool send_broadcasts(sock_t sock, uint16 port, char *data, unsigned long length) +static bool send_broadcasts(sock_t sock, uint16 port, char *data, unsigned long length, uint32_t *custom_broadcasts) { static std::chrono::high_resolution_clock::time_point last_get_broadcast_info; if (number_broadcasts < 0 || check_timedout(last_get_broadcast_info, 60.0)) { @@ -302,6 +302,23 @@ static bool send_broadcasts(sock_t sock, uint16 port, char *data, unsigned long IP_PORT ip_port = broadcasts[i]; } + /** + * Custom targeted clients server broadcaster + * + * Sends to custom IPs the broadcast packet + * This is useful in cases of undetected network interfaces + */ + PRINT_DEBUG("start custom broadcasts\n"); + IP_PORT custom_targeted_broadcast; + custom_targeted_broadcast.port = port; + for(int i = 0; i < MAX_CUSTOM_BROADCASTS; i++) { + if(custom_broadcasts[i] == 0) + break; + custom_targeted_broadcast.ip = custom_broadcasts[i]; + send_packet_to(sock, custom_targeted_broadcast, data, length); + } + PRINT_DEBUG("end custom broadcasts\n"); + return true; } @@ -666,7 +683,7 @@ bool Networking::handle_low_level_udp(Common_Message *msg, IP_PORT ip_port) #define NUM_TCP_WAITING 128 -Networking::Networking(CSteamID id, uint32 appid, uint16 port) +Networking::Networking(CSteamID id, uint32 appid, uint16 port, uint32_t *custom_broadcasts) { run_at_startup(); tcp_port = udp_port = port; @@ -674,6 +691,8 @@ Networking::Networking(CSteamID id, uint32 appid, uint16 port) alive = true; last_run = std::chrono::high_resolution_clock::now(); this->appid = appid; + for(int i = 0; i < MAX_CUSTOM_BROADCASTS; i++) + this->custom_broadcasts[i] = custom_broadcasts[i]; sock_t sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); PRINT_DEBUG("UDP socket: %u\n", sock); @@ -783,9 +802,9 @@ void Networking::send_announce_broadcasts() size_t size = msg.ByteSizeLong(); char *buffer = new char[size]; msg.SerializeToArray(buffer, size); - send_broadcasts(udp_socket, htons(DEFAULT_PORT), buffer, size); + send_broadcasts(udp_socket, htons(DEFAULT_PORT), buffer, size, this->custom_broadcasts); if (udp_port != DEFAULT_PORT) { - send_broadcasts(udp_socket, htons(udp_port), buffer, size); + send_broadcasts(udp_socket, htons(udp_port), buffer, size, this->custom_broadcasts); } delete[] buffer; diff --git a/dll/network.h b/dll/network.h index b7c624e..76c9d3d 100644 --- a/dll/network.h +++ b/dll/network.h @@ -20,6 +20,8 @@ #ifndef NETWORK_INCLUDE #define NETWORK_INCLUDE +#define MAX_CUSTOM_BROADCASTS 128 + #include "net.pb.h" #include @@ -106,6 +108,7 @@ class Networking { std::vector ids; uint32 appid; std::chrono::high_resolution_clock::time_point last_broadcast; + uint32_t custom_broadcasts[MAX_CUSTOM_BROADCASTS]; std::vector accepted; std::recursive_mutex mutex; @@ -120,7 +123,7 @@ class Networking { Common_Message create_announce(bool request); public: - Networking(CSteamID id, uint32 appid, uint16 port); + Networking(CSteamID id, uint32 appid, uint16 port, uint32_t *custom_broadcasts); void addListenId(CSteamID id); void setAppID(uint32 appid); void Run(); diff --git a/dll/steam_client.cpp b/dll/steam_client.cpp index 40b8d05..fa313a9 100644 --- a/dll/steam_client.cpp +++ b/dll/steam_client.cpp @@ -19,6 +19,7 @@ #include + static void network_thread(Networking *network) { PRINT_DEBUG("network thread starting\n"); @@ -112,6 +113,7 @@ Steam_Client::Steam_Client() local_storage = new Local_Storage(save_path); local_storage->setAppId(appid); + // Listen port char array_port[10] = {}; array_port[0] = '0'; local_storage->get_data_settings("listen_port.txt", array_port, sizeof(array_port) - 1); @@ -122,19 +124,68 @@ Steam_Client::Steam_Client() local_storage->store_data_settings("listen_port.txt", array_port, strlen(array_port)); } - char name[32] = {}; + // Custom broadcasts + uint32_t custom_broadcasts[MAX_CUSTOM_BROADCASTS] = {0}; + int readIP = 0; + + std::string broadcasts_filepath = Local_Storage::get_game_settings_path() + "custom_broadcasts.txt"; + + std::ifstream broadcasts_file(broadcasts_filepath); + PRINT_DEBUG("Broadcasts file path: %s\n", broadcasts_filepath.c_str()); + if (broadcasts_file.is_open()) { + std::string line; + while (std::getline(broadcasts_file, line) && readIP < MAX_CUSTOM_BROADCASTS) { + int offset = 0; + size_t pos = 0; + std::string tok; + uint32_t current_ip = 0; + while((pos = line.find(".")) != std::string::npos && offset < 32) + { + tok = line.substr(0, pos); + try + { + current_ip += (std::stoi(tok) << offset); + } + catch(std::invalid_argument ex) + { + offset = -1; + break; + } + line.erase(0, pos+1); + offset += 8; + } + if(pos == std::string::npos && offset != -1) + { + try + { + current_ip += (std::stoi(line) << offset); + custom_broadcasts[readIP++] = current_ip; + } + catch(std::invalid_argument ex) + { + + } + } + } + } + + + // Acount name + char name[32] = {}; if (local_storage->get_data_settings("account_name.txt", name, sizeof(name) - 1) <= 0) { strcpy(name, DEFAULT_NAME); local_storage->store_data_settings("account_name.txt", name, strlen(name)); } + // Language char language[32] = {}; if (local_storage->get_data_settings("language.txt", language, sizeof(language) - 1) <= 0) { strcpy(language, DEFAULT_LANGUAGE); local_storage->store_data_settings("language.txt", language, strlen(language)); } + // Steam ID char array_steam_id[32] = {}; CSteamID user_id; uint64 steam_id = 0; @@ -222,7 +273,7 @@ Steam_Client::Steam_Client() } } - network = new Networking(settings_server->get_local_steam_id(), appid, port); + network = new Networking(settings_server->get_local_steam_id(), appid, port, custom_broadcasts); callback_results_client = new SteamCallResults(); callback_results_server = new SteamCallResults(); @@ -230,7 +281,7 @@ Steam_Client::Steam_Client() callbacks_server = new SteamCallBacks(callback_results_server); run_every_runcb = new RunEveryRunCB(); - PRINT_DEBUG("steam client init: id: %llu server id: %llu appid: %u port: %u \n", user_id.ConvertToUint64(), settings_server->get_local_steam_id().ConvertToUint64(), appid, port); + PRINT_DEBUG("steam client init: id: %llu server id: %llu appid: %u port: %u custom broadcasts: %u\n", user_id.ConvertToUint64(), settings_server->get_local_steam_id().ConvertToUint64(), appid, port, sizeof(custom_broadcasts)); steam_user = new Steam_User(settings_client, local_storage, network, callback_results_client, callbacks_client); steam_friends = new Steam_Friends(settings_client, network, callback_results_client, callbacks_client, run_every_runcb);