From 7163daa6c1e53921d0c0c95b5ab3b4591596baf1 Mon Sep 17 00:00:00 2001 From: Mr_Goldberg Date: Wed, 10 Aug 2022 03:24:29 -0400 Subject: [PATCH] Destroy client, network sockets and other objects on shutdown. --- dll/dll.cpp | 35 +++++++++++++++++---- dll/network.cpp | 26 +++++++++------- dll/network.h | 5 +-- dll/steam_client.cpp | 72 +++++++++++++++++++++++++++++++++++++++----- 4 files changed, 109 insertions(+), 29 deletions(-) diff --git a/dll/dll.cpp b/dll/dll.cpp index cd1b570..70d91dc 100644 --- a/dll/dll.cpp +++ b/dll/dll.cpp @@ -128,13 +128,26 @@ STEAMAPI_API ISteamClient *g_pSteamClientGameServer; ISteamClient *g_pSteamClientGameServer; #endif +static Steam_Client *client; Steam_Client *get_steam_client() { std::lock_guard lock(global_mutex); - static Steam_Client *client = new Steam_Client(); + if (!client) { + client = new Steam_Client(); + } + return client; } +void destroy_client() +{ + std::lock_guard lock(global_mutex); + if (client) { + delete client; + client = NULL; + } +} + Steam_Client *get_steam_client_old() { return get_steam_client(); @@ -298,6 +311,9 @@ STEAMAPI_API void S_CALLTYPE SteamAPI_Shutdown() old_video_instance = NULL; old_parental_instance = NULL; old_unified_instance = NULL; + if (global_counter == 0) { + destroy_client(); + } } // SteamAPI_RestartAppIfNecessary ensures that your executable was launched through Steam. @@ -607,11 +623,14 @@ STEAMAPI_API ISteamClient *SteamGameServerClient(); STEAMAPI_API steam_bool S_CALLTYPE SteamInternal_GameServer_Init( uint32 unIP, uint16 usPort, uint16 usGamePort, uint16 usQueryPort, EServerMode eServerMode, const char *pchVersionString ) { PRINT_DEBUG("SteamInternal_GameServer_Init %u %hu %hu %hu %u %s\n", unIP, usPort, usGamePort, usQueryPort, eServerMode, pchVersionString); - load_old_interface_versions(); - get_steam_client()->CreateLocalUser(&server_steam_pipe, k_EAccountTypeGameServer); - ++global_counter; - //g_pSteamClientGameServer is only used in pre 1.37 (where the interface versions are not provided by the game) - g_pSteamClientGameServer = SteamGameServerClient(); + if (!server_steam_pipe) { + load_old_interface_versions(); + get_steam_client()->CreateLocalUser(&server_steam_pipe, k_EAccountTypeGameServer); + ++global_counter; + //g_pSteamClientGameServer is only used in pre 1.37 (where the interface versions are not provided by the game) + g_pSteamClientGameServer = SteamGameServerClient(); + } + uint32 unFlags = 0; if (eServerMode == eServerModeAuthenticationAndSecure) unFlags = k_unServerFlagSecure; return get_steam_client()->steam_gameserver->InitGameServer(unIP, usGamePort, usQueryPort, unFlags, 0, pchVersionString); @@ -678,6 +697,10 @@ STEAMAPI_API void SteamGameServer_Shutdown() old_gamserver_ugc_instance = NULL; old_gamserver_apps_instance = NULL; old_gamserver_masterupdater_instance = NULL; + + if (global_counter == 0) { + destroy_client(); + } } STEAMAPI_API void SteamGameServer_RunCallbacks() diff --git a/dll/network.cpp b/dll/network.cpp index 2ff35d6..d2acafa 100644 --- a/dll/network.cpp +++ b/dll/network.cpp @@ -751,7 +751,6 @@ Networking::Networking(CSteamID id, uint32 appid, uint16 port, std::set { tcp_port = udp_port = port; own_ip = 0x7F000001; - alive = true; last_run = std::chrono::high_resolution_clock::now(); this->appid = appid; @@ -843,6 +842,21 @@ Networking::Networking(CSteamID id, uint32 appid, uint16 port, std::set reset_last_error(); } +Networking::~Networking() +{ + for (auto &c : connections) { + kill_tcp_socket(c.tcp_socket_incoming); + kill_tcp_socket(c.tcp_socket_outgoing); + } + + for (auto &c : accepted) { + kill_tcp_socket(c); + } + + kill_socket(udp_socket); + kill_socket(tcp_socket); +} + Common_Message Networking::create_announce(bool request) { Announce *announce = new Announce(); @@ -1265,13 +1279,3 @@ uint32 Networking::getOwnIP() { return own_ip; } - -void Networking::shutDown() -{ - alive = false; -} - -bool Networking::isAlive() -{ - return alive; -} diff --git a/dll/network.h b/dll/network.h index 4231055..72e9f39 100644 --- a/dll/network.h +++ b/dll/network.h @@ -90,7 +90,6 @@ struct Connection { class Networking { bool enabled = false; - bool alive; std::chrono::high_resolution_clock::time_point last_run; sock_t udp_socket, tcp_socket; uint16 udp_port, tcp_port; @@ -126,6 +125,7 @@ public: //ex: 127.0.0.1 should be passed as 0x7F000001 static std::set resolve_ip(std::string dns); Networking(CSteamID id, uint32 appid, uint16 port, std::set *custom_broadcasts, bool disable_sockets); + ~Networking(); void addListenId(CSteamID id); void setAppID(uint32 appid); void Run(); @@ -137,9 +137,6 @@ public: bool setCallback(Callback_Ids id, CSteamID steam_id, void (*message_callback)(void *object, Common_Message *msg), void *object); uint32 getIP(CSteamID id); uint32 getOwnIP(); - - void shutDown(); - bool isAlive(); }; #endif diff --git a/dll/steam_client.cpp b/dll/steam_client.cpp index 35ea62b..89bd973 100644 --- a/dll/steam_client.cpp +++ b/dll/steam_client.cpp @@ -18,19 +18,21 @@ #include "steam_client.h" #include "settings_parser.h" +static std::mutex kill_background_thread_mutex; static std::condition_variable kill_background_thread_cv; -static std::atomic_bool kill_background_thread; +static bool kill_background_thread; static void background_thread(Steam_Client *client) { PRINT_DEBUG("background thread starting\n"); - std::mutex mtx; - std::unique_lock lck(mtx); while (1) { - if (kill_background_thread || kill_background_thread_cv.wait_for(lck, std::chrono::seconds(1)) != std::cv_status::timeout) { - if (kill_background_thread) { - PRINT_DEBUG("background thread exit\n"); - return; + { + std::unique_lock lck(kill_background_thread_mutex); + if (kill_background_thread || kill_background_thread_cv.wait_for(lck, std::chrono::seconds(1)) != std::cv_status::timeout) { + if (kill_background_thread) { + PRINT_DEBUG("background thread exit\n"); + return; + } } } @@ -122,7 +124,59 @@ Steam_Client::Steam_Client() Steam_Client::~Steam_Client() { - network->shutDown(); + delete steam_gameserver; + delete steam_gameserver_utils; + delete steam_gameserverstats; + delete steam_gameserver_networking; + delete steam_gameserver_http; + delete steam_gameserver_inventory; + delete steam_gameserver_ugc; + delete steam_gameserver_apps; + delete steam_gameserver_networking_sockets; + delete steam_gameserver_networking_sockets_serialized; + delete steam_gameserver_networking_messages; + delete steam_gameserver_game_coordinator; + delete steam_masterserver_updater; + + delete steam_matchmaking; + delete steam_matchmaking_servers; + delete steam_user_stats; + delete steam_apps; + delete steam_networking; + delete steam_remote_storage; + delete steam_screenshots; + delete steam_http; + delete steam_controller; + delete steam_ugc; + delete steam_applist; + delete steam_music; + delete steam_musicremote; + delete steam_HTMLsurface; + delete steam_inventory; + delete steam_video; + delete steam_parental; + delete steam_networking_sockets; + delete steam_networking_sockets_serialized; + delete steam_networking_messages; + delete steam_game_coordinator; + delete steam_networking_utils; + delete steam_unified_messages; + delete steam_game_search; + delete steam_parties; + delete steam_remoteplay; + delete steam_tv; + + delete steam_utils; + delete steam_friends; + delete steam_user; + delete steam_overlay; + + delete run_every_runcb; + delete callbacks_server; + delete callbacks_client; + delete callback_results_server; + delete callback_results_client; + delete network; } void Steam_Client::userLogIn() @@ -825,7 +879,9 @@ bool Steam_Client::BShutdownIfAllPipesClosed() if (!steam_pipes.size()) { bool joinable = background_keepalive.joinable(); if (joinable) { + kill_background_thread_mutex.lock(); kill_background_thread = true; + kill_background_thread_mutex.unlock(); kill_background_thread_cv.notify_one(); }