Compare commits

...

3 Commits

Author SHA1 Message Date
Mr_Goldberg c22b3cd3d3
Fix crash. 2022-08-10 03:24:53 -04:00
Mr_Goldberg 7163daa6c1
Destroy client, network sockets and other objects on shutdown. 2022-08-10 03:24:29 -04:00
Mr_Goldberg 04022c005f
Update nemirtingas overlay to latest. 2022-08-10 03:22:23 -04:00
20 changed files with 298 additions and 124 deletions

View File

@ -128,13 +128,26 @@ STEAMAPI_API ISteamClient *g_pSteamClientGameServer;
ISteamClient *g_pSteamClientGameServer; ISteamClient *g_pSteamClientGameServer;
#endif #endif
static Steam_Client *client;
Steam_Client *get_steam_client() Steam_Client *get_steam_client()
{ {
std::lock_guard<std::recursive_mutex> lock(global_mutex); std::lock_guard<std::recursive_mutex> lock(global_mutex);
static Steam_Client *client = new Steam_Client(); if (!client) {
client = new Steam_Client();
}
return client; return client;
} }
void destroy_client()
{
std::lock_guard<std::recursive_mutex> lock(global_mutex);
if (client) {
delete client;
client = NULL;
}
}
Steam_Client *get_steam_client_old() Steam_Client *get_steam_client_old()
{ {
return get_steam_client(); return get_steam_client();
@ -298,6 +311,9 @@ STEAMAPI_API void S_CALLTYPE SteamAPI_Shutdown()
old_video_instance = NULL; old_video_instance = NULL;
old_parental_instance = NULL; old_parental_instance = NULL;
old_unified_instance = NULL; old_unified_instance = NULL;
if (global_counter == 0) {
destroy_client();
}
} }
// SteamAPI_RestartAppIfNecessary ensures that your executable was launched through Steam. // 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 ) 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); PRINT_DEBUG("SteamInternal_GameServer_Init %u %hu %hu %hu %u %s\n", unIP, usPort, usGamePort, usQueryPort, eServerMode, pchVersionString);
load_old_interface_versions(); if (!server_steam_pipe) {
get_steam_client()->CreateLocalUser(&server_steam_pipe, k_EAccountTypeGameServer); load_old_interface_versions();
++global_counter; get_steam_client()->CreateLocalUser(&server_steam_pipe, k_EAccountTypeGameServer);
//g_pSteamClientGameServer is only used in pre 1.37 (where the interface versions are not provided by the game) ++global_counter;
g_pSteamClientGameServer = SteamGameServerClient(); //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; uint32 unFlags = 0;
if (eServerMode == eServerModeAuthenticationAndSecure) unFlags = k_unServerFlagSecure; if (eServerMode == eServerModeAuthenticationAndSecure) unFlags = k_unServerFlagSecure;
return get_steam_client()->steam_gameserver->InitGameServer(unIP, usGamePort, usQueryPort, unFlags, 0, pchVersionString); 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_ugc_instance = NULL;
old_gamserver_apps_instance = NULL; old_gamserver_apps_instance = NULL;
old_gamserver_masterupdater_instance = NULL; old_gamserver_masterupdater_instance = NULL;
if (global_counter == 0) {
destroy_client();
}
} }
STEAMAPI_API void SteamGameServer_RunCallbacks() STEAMAPI_API void SteamGameServer_RunCallbacks()

View File

@ -751,7 +751,6 @@ Networking::Networking(CSteamID id, uint32 appid, uint16 port, std::set<IP_PORT>
{ {
tcp_port = udp_port = port; tcp_port = udp_port = port;
own_ip = 0x7F000001; own_ip = 0x7F000001;
alive = true;
last_run = std::chrono::high_resolution_clock::now(); last_run = std::chrono::high_resolution_clock::now();
this->appid = appid; this->appid = appid;
@ -843,6 +842,21 @@ Networking::Networking(CSteamID id, uint32 appid, uint16 port, std::set<IP_PORT>
reset_last_error(); 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) Common_Message Networking::create_announce(bool request)
{ {
Announce *announce = new Announce(); Announce *announce = new Announce();
@ -1265,13 +1279,3 @@ uint32 Networking::getOwnIP()
{ {
return own_ip; return own_ip;
} }
void Networking::shutDown()
{
alive = false;
}
bool Networking::isAlive()
{
return alive;
}

View File

@ -90,7 +90,6 @@ struct Connection {
class Networking { class Networking {
bool enabled = false; bool enabled = false;
bool alive;
std::chrono::high_resolution_clock::time_point last_run; std::chrono::high_resolution_clock::time_point last_run;
sock_t udp_socket, tcp_socket; sock_t udp_socket, tcp_socket;
uint16 udp_port, tcp_port; uint16 udp_port, tcp_port;
@ -126,6 +125,7 @@ public:
//ex: 127.0.0.1 should be passed as 0x7F000001 //ex: 127.0.0.1 should be passed as 0x7F000001
static std::set<IP_PORT> resolve_ip(std::string dns); static std::set<IP_PORT> resolve_ip(std::string dns);
Networking(CSteamID id, uint32 appid, uint16 port, std::set<IP_PORT> *custom_broadcasts, bool disable_sockets); Networking(CSteamID id, uint32 appid, uint16 port, std::set<IP_PORT> *custom_broadcasts, bool disable_sockets);
~Networking();
void addListenId(CSteamID id); void addListenId(CSteamID id);
void setAppID(uint32 appid); void setAppID(uint32 appid);
void Run(); 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); bool setCallback(Callback_Ids id, CSteamID steam_id, void (*message_callback)(void *object, Common_Message *msg), void *object);
uint32 getIP(CSteamID id); uint32 getIP(CSteamID id);
uint32 getOwnIP(); uint32 getOwnIP();
void shutDown();
bool isAlive();
}; };
#endif #endif

View File

@ -173,6 +173,8 @@ void Steam_Apps::RequestAppProofOfPurchaseKey( AppId_t nAppID )
bool Steam_Apps::GetCurrentBetaName( char *pchName, int cchNameBufferSize ) bool Steam_Apps::GetCurrentBetaName( char *pchName, int cchNameBufferSize )
{ {
PRINT_DEBUG("GetCurrentBetaName %i\n", cchNameBufferSize); PRINT_DEBUG("GetCurrentBetaName %i\n", cchNameBufferSize);
if (!pchName) return false;
if (sizeof("public") > cchNameBufferSize) { if (sizeof("public") > cchNameBufferSize) {
return false; return false;
} }

View File

@ -18,19 +18,21 @@
#include "steam_client.h" #include "steam_client.h"
#include "settings_parser.h" #include "settings_parser.h"
static std::mutex kill_background_thread_mutex;
static std::condition_variable kill_background_thread_cv; 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) static void background_thread(Steam_Client *client)
{ {
PRINT_DEBUG("background thread starting\n"); PRINT_DEBUG("background thread starting\n");
std::mutex mtx;
std::unique_lock<std::mutex> lck(mtx);
while (1) { 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) { std::unique_lock<std::mutex> lck(kill_background_thread_mutex);
PRINT_DEBUG("background thread exit\n"); if (kill_background_thread || kill_background_thread_cv.wait_for(lck, std::chrono::seconds(1)) != std::cv_status::timeout) {
return; if (kill_background_thread) {
PRINT_DEBUG("background thread exit\n");
return;
}
} }
} }
@ -122,7 +124,59 @@ Steam_Client::Steam_Client()
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() void Steam_Client::userLogIn()
@ -825,7 +879,9 @@ bool Steam_Client::BShutdownIfAllPipesClosed()
if (!steam_pipes.size()) { if (!steam_pipes.size()) {
bool joinable = background_keepalive.joinable(); bool joinable = background_keepalive.joinable();
if (joinable) { if (joinable) {
kill_background_thread_mutex.lock();
kill_background_thread = true; kill_background_thread = true;
kill_background_thread_mutex.unlock();
kill_background_thread_cv.notify_one(); kill_background_thread_cv.notify_one();
} }

View File

@ -25,6 +25,7 @@
#include "System/String.hpp" #include "System/String.hpp"
#include "System/System.h" #include "System/System.h"
#include "System/Library.h" #include "System/Library.h"
#include "System/ScopedLock.hpp"
#if defined(WIN64) || defined(_WIN64) || defined(__MINGW64__) \ #if defined(WIN64) || defined(_WIN64) || defined(__MINGW64__) \
|| defined(WIN32) || defined(_WIN32) || defined(__MINGW32__) || defined(WIN32) || defined(_WIN32) || defined(__MINGW32__)
@ -77,10 +78,6 @@ public:
delete vulkan_hook; delete vulkan_hook;
} }
bool force_stop_detection;
std::condition_variable detect_renderer_thread_cv;
std::mutex destroy_render_thread_mutex;
private: private:
Renderer_Detector(): Renderer_Detector():
dxgi_hooked(false), dxgi_hooked(false),
@ -98,8 +95,7 @@ private:
dx12_hook(nullptr), dx12_hook(nullptr),
opengl_hook(nullptr), opengl_hook(nullptr),
vulkan_hook(nullptr), vulkan_hook(nullptr),
detection_done(false), detection_done(false)
force_stop_detection(false)
{ {
std::wstring tmp(4096, L'\0'); std::wstring tmp(4096, L'\0');
tmp.resize(GetSystemDirectoryW(&tmp[0], tmp.size())); tmp.resize(GetSystemDirectoryW(&tmp[0], tmp.size()));
@ -147,6 +143,8 @@ private:
Vulkan_Hook* vulkan_hook; Vulkan_Hook* vulkan_hook;
bool detection_done; bool detection_done;
std::condition_variable stop_detection_cv;
std::mutex stop_detection_mutex;
HWND dummyWindow = nullptr; HWND dummyWindow = nullptr;
std::wstring _WindowClassName; std::wstring _WindowClassName;
@ -431,14 +429,14 @@ private:
} }
void HookDX9Present(IDirect3DDevice9* pDevice, bool ex, IDirect3DSwapChain9* pSwapChain, void HookDX9Present(IDirect3DDevice9* pDevice, bool ex, IDirect3DSwapChain9* pSwapChain,
decltype(&IDirect3DDevice9::Present)& pfnPresent, void*& pfnPresent,
decltype(&IDirect3DDevice9::Reset)& pfnReset, void*& pfnReset,
decltype(&IDirect3DDevice9Ex::PresentEx)& pfnPresentEx, void*& pfnPresentEx,
decltype(&IDirect3DSwapChain9::Present)& pfnSwapChainPresent) void*& pfnSwapChainPresent)
{ {
void** vTable = *reinterpret_cast<void***>(pDevice); void** vTable = *reinterpret_cast<void***>(pDevice);
(void*&)pfnPresent = vTable[(int)IDirect3DDevice9VTable::Present]; pfnPresent = vTable[(int)IDirect3DDevice9VTable::Present];
(void*&)pfnReset = vTable[(int)IDirect3DDevice9VTable::Reset]; pfnReset = vTable[(int)IDirect3DDevice9VTable::Reset];
(void*&)IDirect3DDevice9Present = vTable[(int)IDirect3DDevice9VTable::Present]; (void*&)IDirect3DDevice9Present = vTable[(int)IDirect3DDevice9VTable::Present];
@ -448,7 +446,7 @@ private:
if (ex) if (ex)
{ {
(void*&)pfnPresentEx = vTable[(int)IDirect3DDevice9VTable::PresentEx]; pfnPresentEx = vTable[(int)IDirect3DDevice9VTable::PresentEx];
(void*&)IDirect3DDevice9ExPresentEx = vTable[(int)IDirect3DDevice9VTable::PresentEx]; (void*&)IDirect3DDevice9ExPresentEx = vTable[(int)IDirect3DDevice9VTable::PresentEx];
detection_hooks.BeginHook(); detection_hooks.BeginHook();
@ -463,9 +461,9 @@ private:
if (pSwapChain != nullptr) if (pSwapChain != nullptr)
{ {
IDirect3DSwapChain9VTable* vTable = *reinterpret_cast<IDirect3DSwapChain9VTable**>(pSwapChain); vTable = *reinterpret_cast<void***>(pSwapChain);
pfnSwapChainPresent = vTable->pPresent; pfnSwapChainPresent = vTable[(int)IDirect3DSwapChain9VTable::Present];
IDirect3DSwapChain9Present = vTable->pPresent; (void*&)IDirect3DSwapChain9Present = vTable[(int)IDirect3DSwapChain9VTable::Present];
detection_hooks.BeginHook(); detection_hooks.BeginHook();
detection_hooks.HookFunc(std::pair<void**, void*>{ (void**)&IDirect3DSwapChain9Present, (void*)&MyDX9SwapChainPresent }); detection_hooks.HookFunc(std::pair<void**, void*>{ (void**)&IDirect3DSwapChain9Present, (void*)&MyDX9SwapChainPresent });
@ -553,7 +551,7 @@ private:
decltype(&IDirect3DDevice9Ex::PresentEx) pfnPresentEx; decltype(&IDirect3DDevice9Ex::PresentEx) pfnPresentEx;
decltype(&IDirect3DSwapChain9::Present) pfnSwapChainPresent; decltype(&IDirect3DSwapChain9::Present) pfnSwapChainPresent;
HookDX9Present(pDevice, Direct3DCreate9Ex != nullptr, pSwapChain, pfnPresent, pfnReset, pfnPresentEx, pfnSwapChainPresent); HookDX9Present(pDevice, Direct3DCreate9Ex != nullptr, pSwapChain, (void*&)pfnPresent, (void*&)pfnReset, (void*&)pfnPresentEx, (void*&)pfnSwapChainPresent);
dx9_hook = DX9_Hook::Inst(); dx9_hook = DX9_Hook::Inst();
dx9_hook->LibraryName = library_path; dx9_hook->LibraryName = library_path;
@ -1045,7 +1043,10 @@ public:
std::lock_guard<std::mutex> lk(renderer_mutex); std::lock_guard<std::mutex> lk(renderer_mutex);
if (detection_done) if (detection_done)
{ {
return renderer_hook; if (renderer_hook != nullptr)
return renderer_hook;
detection_done = false;
} }
if (CreateHWND() == nullptr) if (CreateHWND() == nullptr)
@ -1069,8 +1070,9 @@ public:
auto start_time = std::chrono::steady_clock::now(); auto start_time = std::chrono::steady_clock::now();
do do
{ {
std::unique_lock<std::mutex> lck(destroy_render_thread_mutex); std::unique_lock<std::mutex> lck(stop_detection_mutex);
if (force_stop_detection) break; if (detection_done)
break;
for (auto const& library : libraries) for (auto const& library : libraries)
{ {
@ -1083,9 +1085,7 @@ public:
} }
} }
detect_renderer_thread_cv.wait_for(lck, std::chrono::milliseconds(100)); stop_detection_cv.wait_for(lck, std::chrono::milliseconds{ 100 });
if (force_stop_detection) break;
} while (!detection_done && (timeout.count() == -1 || (std::chrono::steady_clock::now() - start_time) <= timeout)); } while (!detection_done && (timeout.count() == -1 || (std::chrono::steady_clock::now() - start_time) <= timeout));
{ {
@ -1093,19 +1093,38 @@ public:
DestroyHWND(); DestroyHWND();
detection_done = true; detection_done = true;
detection_hooks.UnhookAll();
dxgi_hooked = false;
dxgi1_2_hooked = false;
dx12_hooked = false;
dx11_hooked = false;
dx10_hooked = false;
dx9_hooked = false;
opengl_hooked = false;
vulkan_hooked = false;
delete dx9_hook ; dx9_hook = nullptr; delete dx9_hook ; dx9_hook = nullptr;
delete dx10_hook ; dx10_hook = nullptr; delete dx10_hook ; dx10_hook = nullptr;
delete dx11_hook ; dx11_hook = nullptr; delete dx11_hook ; dx11_hook = nullptr;
delete dx12_hook ; dx12_hook = nullptr; delete dx12_hook ; dx12_hook = nullptr;
delete opengl_hook; opengl_hook = nullptr; delete opengl_hook; opengl_hook = nullptr;
delete vulkan_hook; vulkan_hook = nullptr; delete vulkan_hook; vulkan_hook = nullptr;
detection_hooks.UnhookAll();
} }
SPDLOG_TRACE("Renderer detection done {}.", (void*)renderer_hook); SPDLOG_TRACE("Renderer detection done {}.", (void*)renderer_hook);
return renderer_hook; return renderer_hook;
} }
void stop_detection()
{
{
System::scoped_lock lk(renderer_mutex, stop_detection_mutex);
detection_done = true;
}
stop_detection_cv.notify_all();
}
}; };
Renderer_Detector* Renderer_Detector::instance = nullptr; Renderer_Detector* Renderer_Detector::instance = nullptr;
@ -1158,6 +1177,8 @@ private:
OpenGLX_Hook* openglx_hook; OpenGLX_Hook* openglx_hook;
bool detection_done; bool detection_done;
std::condition_variable stop_detection_cv;
std::mutex stop_detection_mutex;
static void MyglXSwapBuffers(Display* dpy, GLXDrawable drawable) static void MyglXSwapBuffers(Display* dpy, GLXDrawable drawable)
{ {
@ -1231,7 +1252,12 @@ public:
{ {
std::lock_guard<std::mutex> lk(renderer_mutex); std::lock_guard<std::mutex> lk(renderer_mutex);
if (detection_done) if (detection_done)
return renderer_hook; {
if (renderer_hook != nullptr)
return renderer_hook;
detection_done = false;
}
} }
SPDLOG_TRACE("Started renderer detection."); SPDLOG_TRACE("Started renderer detection.");
@ -1239,6 +1265,10 @@ public:
auto start_time = std::chrono::steady_clock::now(); auto start_time = std::chrono::steady_clock::now();
do do
{ {
std::unique_lock<std::mutex> lck(stop_detection_mutex);
if (detection_done)
break;
for (auto const& library : libraries) for (auto const& library : libraries)
{ {
void* lib_handle = System::Library::GetLibraryHandle(library.first); void* lib_handle = System::Library::GetLibraryHandle(library.first);
@ -1249,12 +1279,18 @@ public:
(this->*library.second)(lib_path); (this->*library.second)(lib_path);
} }
} }
std::this_thread::sleep_for(std::chrono::milliseconds{ 100 });
stop_detection_cv.wait_for(lck, std::chrono::milliseconds{ 100 });
} while (!detection_done && (timeout.count() == -1 || (std::chrono::steady_clock::now() - start_time) <= timeout)); } while (!detection_done && (timeout.count() == -1 || (std::chrono::steady_clock::now() - start_time) <= timeout));
{ {
std::lock_guard<std::mutex> lk(renderer_mutex); std::lock_guard<std::mutex> lk(renderer_mutex);
detection_done = true; detection_done = true;
detection_hooks.UnhookAll();
openglx_hooked = false;
delete openglx_hook; openglx_hook = nullptr; delete openglx_hook; openglx_hook = nullptr;
//delete vulkan_hook; vulkan_hook = nullptr; //delete vulkan_hook; vulkan_hook = nullptr;
} }
@ -1263,6 +1299,15 @@ public:
return renderer_hook; return renderer_hook;
} }
void stop_detection()
{
{
System::scoped_lock lk(renderer_mutex, stop_detection_mutex);
detection_done = true;
}
stop_detection_cv.notify_all();
}
}; };
Renderer_Detector* Renderer_Detector::instance = nullptr; Renderer_Detector* Renderer_Detector::instance = nullptr;
@ -1311,6 +1356,8 @@ private:
OpenGL_Hook* opengl_hook; OpenGL_Hook* opengl_hook;
bool detection_done; bool detection_done;
std::condition_variable stop_detection_cv;
std::mutex stop_detection_mutex;
static int64_t MyCGLFlushDrawable(CGLDrawable_t* glDrawable) static int64_t MyCGLFlushDrawable(CGLDrawable_t* glDrawable)
{ {
@ -1384,7 +1431,12 @@ public:
{ {
std::lock_guard<std::mutex> lk(renderer_mutex); std::lock_guard<std::mutex> lk(renderer_mutex);
if (detection_done) if (detection_done)
return renderer_hook; {
if (renderer_hook != nullptr)
return renderer_hook;
detection_done = false;
}
} }
SPDLOG_TRACE("Started renderer detection."); SPDLOG_TRACE("Started renderer detection.");
@ -1392,6 +1444,10 @@ public:
auto start_time = std::chrono::steady_clock::now(); auto start_time = std::chrono::steady_clock::now();
do do
{ {
std::unique_lock<std::mutex> lck(stop_detection_mutex);
if (detection_done)
break;
for (auto const& library : libraries) for (auto const& library : libraries)
{ {
void* lib_handle = System::Library::GetLibraryHandle(library.first); void* lib_handle = System::Library::GetLibraryHandle(library.first);
@ -1402,12 +1458,18 @@ public:
(this->*library.second)(lib_path); (this->*library.second)(lib_path);
} }
} }
std::this_thread::sleep_for(std::chrono::milliseconds{ 100 });
stop_detection_cv.wait_for(lck, std::chrono::milliseconds{ 100 });
} while (!detection_done && (timeout.count() == -1 || (std::chrono::steady_clock::now() - start_time) <= timeout)); } while (!detection_done && (timeout.count() == -1 || (std::chrono::steady_clock::now() - start_time) <= timeout));
{ {
std::lock_guard<std::mutex> lk(renderer_mutex); std::lock_guard<std::mutex> lk(renderer_mutex);
detection_done = true; detection_done = true;
detection_hooks.UnhookAll();
opengl_hooked = false;
delete opengl_hook; opengl_hook = nullptr; delete opengl_hook; opengl_hook = nullptr;
//delete vulkan_hook; vulkan_hook = nullptr; //delete vulkan_hook; vulkan_hook = nullptr;
} }
@ -1416,21 +1478,31 @@ public:
return renderer_hook; return renderer_hook;
} }
void stop_detection()
{
{
System::scoped_lock lk(renderer_mutex, stop_detection_mutex);
detection_done = true;
}
stop_detection_cv.notify_all();
}
}; };
Renderer_Detector* Renderer_Detector::instance = nullptr; Renderer_Detector* Renderer_Detector::instance = nullptr;
#endif #endif
std::future<Renderer_Hook*> detect_renderer(std::chrono::milliseconds timeout) namespace ingame_overlay {
std::future<Renderer_Hook*> DetectRenderer(std::chrono::milliseconds timeout)
{ {
return std::async(std::launch::async, &Renderer_Detector::detect_renderer, Renderer_Detector::Inst(), timeout); return std::async(std::launch::async, &Renderer_Detector::detect_renderer, Renderer_Detector::Inst(), timeout);
} }
void stop_renderer_detector() void StopRendererDetection()
{ {
Renderer_Detector::Inst()->destroy_render_thread_mutex.lock(); Renderer_Detector::Inst()->stop_detection();
Renderer_Detector::Inst()->force_stop_detection = true; }
Renderer_Detector::Inst()->destroy_render_thread_mutex.unlock();
Renderer_Detector::Inst()->detect_renderer_thread_cv.notify_all();
} }

View File

@ -27,5 +27,9 @@
#include "Renderer_Hook.h" #include "Renderer_Hook.h"
std::future<Renderer_Hook*> detect_renderer(std::chrono::milliseconds timeout = std::chrono::milliseconds{-1}); namespace ingame_overlay {
void stop_renderer_detector();
std::future<Renderer_Hook*> DetectRenderer(std::chrono::milliseconds timeout = std::chrono::milliseconds{ -1 });
void StopRendererDetection();
}

View File

@ -110,6 +110,8 @@ void OpenGLX_Hook::_PrepareForOverlay(Display* display, GLXDrawable drawable)
_Display = display; _Display = display;
X11_Hook::Inst()->SetInitialWindowSize(_Display, (Window)drawable);
_Initialized = true; _Initialized = true;
OverlayHookReady(true); OverlayHookReady(true);
} }

View File

@ -83,6 +83,18 @@ void X11_Hook::ResetRenderState()
} }
} }
void X11_Hook::SetInitialWindowSize(Display* display, Window wnd)
{
unsigned int width, height;
Window unused_window;
int unused_int;
unsigned int unused_unsigned_int;
XGetGeometry(display, wnd, &unused_window, &unused_int, &unused_int, &width, &height, &unused_unsigned_int, &unused_unsigned_int);
ImGui::GetIO().DisplaySize = ImVec2((float)width, (float)height);
}
bool X11_Hook::PrepareForOverlay(Display *display, Window wnd) bool X11_Hook::PrepareForOverlay(Display *display, Window wnd)
{ {
if(!_Hooked) if(!_Hooked)

View File

@ -60,6 +60,7 @@ public:
virtual ~X11_Hook(); virtual ~X11_Hook();
void ResetRenderState(); void ResetRenderState();
void SetInitialWindowSize(Display* display, Window wnd);
bool PrepareForOverlay(Display *display, Window wnd); bool PrepareForOverlay(Display *display, Window wnd);
Window GetGameWnd() const{ return _GameWnd; } Window GetGameWnd() const{ return _GameWnd; }

View File

@ -196,14 +196,14 @@ void Steam_Overlay::SetupOverlay()
if (!setup_overlay_called) if (!setup_overlay_called)
{ {
setup_overlay_called = true; setup_overlay_called = true;
future_renderer = detect_renderer(); future_renderer = ingame_overlay::DetectRenderer();
} }
} }
void Steam_Overlay::UnSetupOverlay() void Steam_Overlay::UnSetupOverlay()
{ {
stop_renderer_detector(); ingame_overlay::StopRendererDetection();
if (!Ready() && future_renderer.valid()) { if (!Ready() && future_renderer.valid()) {
if (future_renderer.wait_for(std::chrono::milliseconds{500}) == std::future_status::ready) { if (future_renderer.wait_for(std::chrono::milliseconds{500}) == std::future_status::ready) {
future_renderer.get(); future_renderer.get();

View File

@ -82,7 +82,7 @@ void DX10_Hook::_ResetRenderState()
OverlayHookReady(false); OverlayHookReady(false);
ImGui_ImplDX10_Shutdown(); ImGui_ImplDX10_Shutdown();
Windows_Hook::Inst()->_ResetRenderState(); Windows_Hook::Inst()->ResetRenderState();
ImGui::DestroyContext(); ImGui::DestroyContext();
SafeRelease(mainRenderTargetView); SafeRelease(mainRenderTargetView);
@ -118,11 +118,13 @@ void DX10_Hook::_PrepareForOverlay(IDXGISwapChain* pSwapChain)
ImGui::CreateContext(); ImGui::CreateContext();
ImGui_ImplDX10_Init(pDevice); ImGui_ImplDX10_Init(pDevice);
Windows_Hook::Inst()->SetInitialWindowSize(desc.OutputWindow);
_Initialized = true; _Initialized = true;
OverlayHookReady(true); OverlayHookReady(true);
} }
if (ImGui_ImplDX10_NewFrame() && Windows_Hook::Inst()->_PrepareForOverlay(desc.OutputWindow)) if (ImGui_ImplDX10_NewFrame() && Windows_Hook::Inst()->PrepareForOverlay(desc.OutputWindow))
{ {
ImGui::NewFrame(); ImGui::NewFrame();

View File

@ -92,7 +92,7 @@ void DX11_Hook::_ResetRenderState()
OverlayHookReady(false); OverlayHookReady(false);
ImGui_ImplDX11_Shutdown(); ImGui_ImplDX11_Shutdown();
Windows_Hook::Inst()->_ResetRenderState(); Windows_Hook::Inst()->ResetRenderState();
//ImGui::DestroyContext(); //ImGui::DestroyContext();
SafeRelease(mainRenderTargetView); SafeRelease(mainRenderTargetView);
@ -151,11 +151,13 @@ void DX11_Hook::_PrepareForOverlay(IDXGISwapChain* pSwapChain)
ImGui_ImplDX11_Init(pDevice, pContext); ImGui_ImplDX11_Init(pDevice, pContext);
Windows_Hook::Inst()->SetInitialWindowSize(desc.OutputWindow);
_Initialized = true; _Initialized = true;
OverlayHookReady(true); OverlayHookReady(true);
} }
if (ImGui_ImplDX11_NewFrame() && Windows_Hook::Inst()->_PrepareForOverlay(desc.OutputWindow)) if (ImGui_ImplDX11_NewFrame() && Windows_Hook::Inst()->PrepareForOverlay(desc.OutputWindow))
{ {
ImGui::NewFrame(); ImGui::NewFrame();

View File

@ -137,7 +137,7 @@ void DX12_Hook::_ResetRenderState()
OverlayHookReady(false); OverlayHookReady(false);
ImGui_ImplDX12_Shutdown(); ImGui_ImplDX12_Shutdown();
Windows_Hook::Inst()->_ResetRenderState(); Windows_Hook::Inst()->ResetRenderState();
ImGui::DestroyContext(); ImGui::DestroyContext();
OverlayFrames.clear(); OverlayFrames.clear();
@ -271,11 +271,13 @@ void DX12_Hook::_PrepareForOverlay(IDXGISwapChain* pSwapChain, ID3D12CommandQueu
//heaps.cpu_handle, //heaps.cpu_handle,
//heaps.gpu_handle); //heaps.gpu_handle);
Windows_Hook::Inst()->SetInitialWindowSize(sc_desc.OutputWindow);
_Initialized = true; _Initialized = true;
OverlayHookReady(true); OverlayHookReady(true);
} }
if (ImGui_ImplDX12_NewFrame() && Windows_Hook::Inst()->_PrepareForOverlay(sc_desc.OutputWindow)) if (ImGui_ImplDX12_NewFrame() && Windows_Hook::Inst()->PrepareForOverlay(sc_desc.OutputWindow))
{ {
ImGui::NewFrame(); ImGui::NewFrame();

View File

@ -88,7 +88,7 @@ void DX9_Hook::_ResetRenderState()
OverlayHookReady(false); OverlayHookReady(false);
ImGui_ImplDX9_Shutdown(); ImGui_ImplDX9_Shutdown();
Windows_Hook::Inst()->_ResetRenderState(); Windows_Hook::Inst()->ResetRenderState();
ImGui::DestroyContext(); ImGui::DestroyContext();
SafeRelease(_pDevice); SafeRelease(_pDevice);
@ -137,11 +137,14 @@ void DX9_Hook::_PrepareForOverlay(IDirect3DDevice9 *pDevice, HWND destWindow)
ImGui_ImplDX9_Init(pDevice); ImGui_ImplDX9_Init(pDevice);
_LastWindow = destWindow; _LastWindow = destWindow;
Windows_Hook::Inst()->SetInitialWindowSize(destWindow);
_Initialized = true; _Initialized = true;
OverlayHookReady(true); OverlayHookReady(true);
} }
if (ImGui_ImplDX9_NewFrame() && Windows_Hook::Inst()->_PrepareForOverlay(destWindow)) if (ImGui_ImplDX9_NewFrame() && Windows_Hook::Inst()->PrepareForOverlay(destWindow))
{ {
ImGui::NewFrame(); ImGui::NewFrame();

View File

@ -464,43 +464,24 @@ enum class IDirect3DDevice9VTable
GetDisplayModeEx, GetDisplayModeEx,
}; };
struct IDirect3DSwapChain9VTable enum class IDirect3DSwapChain9VTable
{ {
enum class Index // IUnknown
{ QueryInterface,
// IUnknown AddRef,
QueryInterface, Release,
AddRef,
Release,
// IDirect3DSwapChain9 // IDirect3DSwapChain9
Present, Present,
GetFrontBufferData, GetFrontBufferData,
GetBackBuffer, GetBackBuffer,
GetRasterStatus, GetRasterStatus,
GetDisplayMode, GetDisplayMode,
GetDevice, GetDevice,
GetPresentParameters, GetPresentParameters,
// IDirect3DSwapChain9Ex // IDirect3DSwapChain9Ex
GetLastPresentCount, GetLastPresentCount,
GetPresentStats, GetPresentStats,
GetDisplayModeEx, GetDisplayModeEx,
};
decltype(&IDirect3DSwapChain9::QueryInterface) pQueryInterface;
decltype(&IDirect3DSwapChain9::AddRef) pAddRef;
decltype(&IDirect3DSwapChain9::Release) pRelease;
decltype(&IDirect3DSwapChain9::Present) pPresent;
decltype(&IDirect3DSwapChain9::GetFrontBufferData) pGetFrontBufferData;
decltype(&IDirect3DSwapChain9::GetBackBuffer) pGetBackBuffer;
decltype(&IDirect3DSwapChain9::GetRasterStatus) pGetRasterStatus;
decltype(&IDirect3DSwapChain9::GetDisplayMode) pGetDisplayMode;
decltype(&IDirect3DSwapChain9::GetDevice) pGetDevice;
decltype(&IDirect3DSwapChain9::GetPresentParameters) pGetPresentParameters;
decltype(&IDirect3DSwapChain9Ex::GetLastPresentCount) pGetLastPresentCount;
decltype(&IDirect3DSwapChain9Ex::GetPresentStats) pGetPresentStats;
decltype(&IDirect3DSwapChain9Ex::GetDisplayModeEx) pGetDisplayModeEx;
}; };

View File

@ -68,10 +68,10 @@ void OpenGL_Hook::_ResetRenderState()
OverlayHookReady(false); OverlayHookReady(false);
ImGui_ImplOpenGL3_Shutdown(); ImGui_ImplOpenGL3_Shutdown();
Windows_Hook::Inst()->_ResetRenderState(); Windows_Hook::Inst()->ResetRenderState();
ImGui::DestroyContext(); ImGui::DestroyContext();
last_window = nullptr; _LastWindow = nullptr;
_Initialized = false; _Initialized = false;
} }
} }
@ -81,7 +81,7 @@ void OpenGL_Hook::_PrepareForOverlay(HDC hDC)
{ {
HWND hWnd = WindowFromDC(hDC); HWND hWnd = WindowFromDC(hDC);
if (hWnd != last_window) if (hWnd != _LastWindow)
_ResetRenderState(); _ResetRenderState();
if (!_Initialized) if (!_Initialized)
@ -89,12 +89,15 @@ void OpenGL_Hook::_PrepareForOverlay(HDC hDC)
ImGui::CreateContext(); ImGui::CreateContext();
ImGui_ImplOpenGL3_Init(); ImGui_ImplOpenGL3_Init();
last_window = hWnd; _LastWindow = hWnd;
Windows_Hook::Inst()->SetInitialWindowSize(hWnd);
_Initialized = true; _Initialized = true;
OverlayHookReady(true); OverlayHookReady(true);
} }
if (ImGui_ImplOpenGL3_NewFrame() && Windows_Hook::Inst()->_PrepareForOverlay(hWnd)) if (ImGui_ImplOpenGL3_NewFrame() && Windows_Hook::Inst()->PrepareForOverlay(hWnd))
{ {
ImGui::NewFrame(); ImGui::NewFrame();
@ -117,7 +120,7 @@ OpenGL_Hook::OpenGL_Hook():
_Hooked(false), _Hooked(false),
_WindowsHooked(false), _WindowsHooked(false),
_Initialized(false), _Initialized(false),
last_window(nullptr), _LastWindow(nullptr),
wglSwapBuffers(nullptr) wglSwapBuffers(nullptr)
{ {
} }

View File

@ -37,7 +37,7 @@ private:
bool _Hooked; bool _Hooked;
bool _WindowsHooked; bool _WindowsHooked;
bool _Initialized; bool _Initialized;
HWND last_window; HWND _LastWindow;
std::set<std::shared_ptr<uint64_t>> _ImageResources; std::set<std::shared_ptr<uint64_t>> _ImageResources;
// Functions // Functions

View File

@ -88,7 +88,7 @@ bool Windows_Hook::StartHook(std::function<bool(bool)>& _key_combination_callbac
return true; return true;
} }
void Windows_Hook::_ResetRenderState() void Windows_Hook::ResetRenderState()
{ {
if (_Initialized) if (_Initialized)
{ {
@ -100,10 +100,17 @@ void Windows_Hook::_ResetRenderState()
} }
} }
bool Windows_Hook::_PrepareForOverlay(HWND hWnd) void Windows_Hook::SetInitialWindowSize(HWND hWnd)
{
RECT rect = { 0, 0, 0, 0 };
::GetClientRect(hWnd, &rect);
ImGui::GetIO().DisplaySize = ImVec2((float)(rect.right - rect.left), (float)(rect.bottom - rect.top));
}
bool Windows_Hook::PrepareForOverlay(HWND hWnd)
{ {
if (_GameHwnd != hWnd) if (_GameHwnd != hWnd)
_ResetRenderState(); ResetRenderState();
if (!_Initialized) if (!_Initialized)
{ {
@ -374,7 +381,7 @@ Windows_Hook::~Windows_Hook()
{ {
SPDLOG_INFO("Windows Hook removed"); SPDLOG_INFO("Windows Hook removed");
_ResetRenderState(); ResetRenderState();
_inst = nullptr; _inst = nullptr;
} }

View File

@ -68,8 +68,9 @@ public:
virtual ~Windows_Hook(); virtual ~Windows_Hook();
void _ResetRenderState(); void ResetRenderState();
bool _PrepareForOverlay(HWND hWnd); void SetInitialWindowSize(HWND hWnd);
bool PrepareForOverlay(HWND hWnd);
HWND GetGameHwnd() const; HWND GetGameHwnd() const;
WNDPROC GetGameWndProc() const; WNDPROC GetGameWndProc() const;