From cfff531a23884dd0d4a669383389c09912596286 Mon Sep 17 00:00:00 2001 From: Mr_Goldberg Date: Sat, 23 Jan 2021 16:46:44 -0500 Subject: [PATCH 01/20] Put back the if new frame for overlay. --- ImGui/impls/imgui_impl_opengl3.cpp | 5 +++-- ImGui/impls/imgui_impl_opengl3.h | 2 +- ImGui/impls/windows/imgui_impl_dx10.cpp | 6 ++++-- ImGui/impls/windows/imgui_impl_dx10.h | 2 +- ImGui/impls/windows/imgui_impl_dx11.cpp | 5 +++-- ImGui/impls/windows/imgui_impl_dx11.h | 2 +- ImGui/impls/windows/imgui_impl_dx12.cpp | 5 +++-- ImGui/impls/windows/imgui_impl_dx12.h | 2 +- ImGui/impls/windows/imgui_impl_dx9.cpp | 5 +++-- ImGui/impls/windows/imgui_impl_dx9.h | 2 +- overlay_experimental/windows/DX10_Hook.cpp | 3 +-- overlay_experimental/windows/DX11_Hook.cpp | 3 +-- overlay_experimental/windows/DX12_Hook.cpp | 3 +-- overlay_experimental/windows/DX9_Hook.cpp | 3 +-- overlay_experimental/windows/OpenGL_Hook.cpp | 3 +-- 15 files changed, 26 insertions(+), 25 deletions(-) diff --git a/ImGui/impls/imgui_impl_opengl3.cpp b/ImGui/impls/imgui_impl_opengl3.cpp index 77e1a60..c0ff9e2 100644 --- a/ImGui/impls/imgui_impl_opengl3.cpp +++ b/ImGui/impls/imgui_impl_opengl3.cpp @@ -221,10 +221,11 @@ void ImGui_ImplOpenGL3_Shutdown() ImGui_ImplOpenGL3_DestroyDeviceObjects(); } -void ImGui_ImplOpenGL3_NewFrame() +bool ImGui_ImplOpenGL3_NewFrame() { if (!g_ShaderHandle) - ImGui_ImplOpenGL3_CreateDeviceObjects(); + return ImGui_ImplOpenGL3_CreateDeviceObjects(); + return true; } static void ImGui_ImplOpenGL3_SetupRenderState(ImDrawData* draw_data, int fb_width, int fb_height, GLuint vertex_array_object) diff --git a/ImGui/impls/imgui_impl_opengl3.h b/ImGui/impls/imgui_impl_opengl3.h index c4080c5..6b5e925 100644 --- a/ImGui/impls/imgui_impl_opengl3.h +++ b/ImGui/impls/imgui_impl_opengl3.h @@ -27,7 +27,7 @@ // Backend API IMGUI_IMPL_API bool ImGui_ImplOpenGL3_Init(const char* glsl_version = NULL); IMGUI_IMPL_API void ImGui_ImplOpenGL3_Shutdown(); -IMGUI_IMPL_API void ImGui_ImplOpenGL3_NewFrame(); +IMGUI_IMPL_API bool ImGui_ImplOpenGL3_NewFrame(); IMGUI_IMPL_API void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data); // (Optional) Called by Init/NewFrame/Shutdown diff --git a/ImGui/impls/windows/imgui_impl_dx10.cpp b/ImGui/impls/windows/imgui_impl_dx10.cpp index 3ab7c6d..5b0e9bd 100644 --- a/ImGui/impls/windows/imgui_impl_dx10.cpp +++ b/ImGui/impls/windows/imgui_impl_dx10.cpp @@ -467,8 +467,10 @@ void ImGui_ImplDX10_Shutdown() if (g_pd3dDevice) { g_pd3dDevice->Release(); g_pd3dDevice = NULL; } } -void ImGui_ImplDX10_NewFrame() +bool ImGui_ImplDX10_NewFrame() { if (!g_pFontSampler) - ImGui_ImplDX10_CreateDeviceObjects(); + return ImGui_ImplDX10_CreateDeviceObjects(); + + return true; } diff --git a/ImGui/impls/windows/imgui_impl_dx10.h b/ImGui/impls/windows/imgui_impl_dx10.h index 142fa8d..007071a 100644 --- a/ImGui/impls/windows/imgui_impl_dx10.h +++ b/ImGui/impls/windows/imgui_impl_dx10.h @@ -16,7 +16,7 @@ struct ID3D10Device; IMGUI_IMPL_API bool ImGui_ImplDX10_Init(ID3D10Device* device); IMGUI_IMPL_API void ImGui_ImplDX10_Shutdown(); -IMGUI_IMPL_API void ImGui_ImplDX10_NewFrame(); +IMGUI_IMPL_API bool ImGui_ImplDX10_NewFrame(); IMGUI_IMPL_API void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data); // Use if you want to reset your rendering device without losing Dear ImGui state. diff --git a/ImGui/impls/windows/imgui_impl_dx11.cpp b/ImGui/impls/windows/imgui_impl_dx11.cpp index b37cb0f..cff5a8b 100644 --- a/ImGui/impls/windows/imgui_impl_dx11.cpp +++ b/ImGui/impls/windows/imgui_impl_dx11.cpp @@ -595,8 +595,9 @@ void ImGui_ImplDX11_Shutdown() if (g_pd3dDeviceContext) { g_pd3dDeviceContext->Release(); g_pd3dDeviceContext = NULL; } } -void ImGui_ImplDX11_NewFrame() +bool ImGui_ImplDX11_NewFrame() { if (!g_pFontSampler) - ImGui_ImplDX11_CreateDeviceObjects(); + return ImGui_ImplDX11_CreateDeviceObjects(); + return true; } diff --git a/ImGui/impls/windows/imgui_impl_dx11.h b/ImGui/impls/windows/imgui_impl_dx11.h index 509b899..dcdefa3 100644 --- a/ImGui/impls/windows/imgui_impl_dx11.h +++ b/ImGui/impls/windows/imgui_impl_dx11.h @@ -17,7 +17,7 @@ struct ID3D11DeviceContext; IMGUI_IMPL_API bool ImGui_ImplDX11_Init(ID3D11Device* device, ID3D11DeviceContext* device_context); IMGUI_IMPL_API void ImGui_ImplDX11_Shutdown(); -IMGUI_IMPL_API void ImGui_ImplDX11_NewFrame(); +IMGUI_IMPL_API bool ImGui_ImplDX11_NewFrame(); IMGUI_IMPL_API void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data); // Use if you want to reset your rendering device without losing Dear ImGui state. diff --git a/ImGui/impls/windows/imgui_impl_dx12.cpp b/ImGui/impls/windows/imgui_impl_dx12.cpp index c323f02..1eb4356 100644 --- a/ImGui/impls/windows/imgui_impl_dx12.cpp +++ b/ImGui/impls/windows/imgui_impl_dx12.cpp @@ -634,8 +634,9 @@ void ImGui_ImplDX12_Shutdown() g_frameIndex = UINT_MAX; } -void ImGui_ImplDX12_NewFrame() +bool ImGui_ImplDX12_NewFrame() { if (!g_pPipelineState) - ImGui_ImplDX12_CreateDeviceObjects(); + return ImGui_ImplDX12_CreateDeviceObjects(); + return true; } diff --git a/ImGui/impls/windows/imgui_impl_dx12.h b/ImGui/impls/windows/imgui_impl_dx12.h index 88c78dc..d71ac7b 100644 --- a/ImGui/impls/windows/imgui_impl_dx12.h +++ b/ImGui/impls/windows/imgui_impl_dx12.h @@ -35,7 +35,7 @@ struct D3D12_GPU_DESCRIPTOR_HANDLE; IMGUI_IMPL_API bool ImGui_ImplDX12_Init(ID3D12Device* device, int num_frames_in_flight, DXGI_FORMAT rtv_format, ID3D12DescriptorHeap* cbv_srv_heap, D3D12_CPU_DESCRIPTOR_HANDLE font_srv_cpu_desc_handle, D3D12_GPU_DESCRIPTOR_HANDLE font_srv_gpu_desc_handle); IMGUI_IMPL_API void ImGui_ImplDX12_Shutdown(); -IMGUI_IMPL_API void ImGui_ImplDX12_NewFrame(); +IMGUI_IMPL_API bool ImGui_ImplDX12_NewFrame(); IMGUI_IMPL_API void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandList* graphics_command_list); // Use if you want to reset your rendering device without losing Dear ImGui state. diff --git a/ImGui/impls/windows/imgui_impl_dx9.cpp b/ImGui/impls/windows/imgui_impl_dx9.cpp index 159c146..dcb38a9 100644 --- a/ImGui/impls/windows/imgui_impl_dx9.cpp +++ b/ImGui/impls/windows/imgui_impl_dx9.cpp @@ -277,8 +277,9 @@ void ImGui_ImplDX9_InvalidateDeviceObjects() if (g_FontTexture) { g_FontTexture->Release(); g_FontTexture = NULL; ImGui::GetIO().Fonts->TexID = NULL; } // We copied g_pFontTextureView to io.Fonts->TexID so let's clear that as well. } -void ImGui_ImplDX9_NewFrame() +bool ImGui_ImplDX9_NewFrame() { if (!g_FontTexture) - ImGui_ImplDX9_CreateDeviceObjects(); + return ImGui_ImplDX9_CreateDeviceObjects(); + return true; } diff --git a/ImGui/impls/windows/imgui_impl_dx9.h b/ImGui/impls/windows/imgui_impl_dx9.h index b622a64..981f3bb 100644 --- a/ImGui/impls/windows/imgui_impl_dx9.h +++ b/ImGui/impls/windows/imgui_impl_dx9.h @@ -16,7 +16,7 @@ struct IDirect3DDevice9; IMGUI_IMPL_API bool ImGui_ImplDX9_Init(IDirect3DDevice9* device); IMGUI_IMPL_API void ImGui_ImplDX9_Shutdown(); -IMGUI_IMPL_API void ImGui_ImplDX9_NewFrame(); +IMGUI_IMPL_API bool ImGui_ImplDX9_NewFrame(); IMGUI_IMPL_API void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data); // Use if you want to reset your rendering device without losing Dear ImGui state. diff --git a/overlay_experimental/windows/DX10_Hook.cpp b/overlay_experimental/windows/DX10_Hook.cpp index 96b3f66..924cc4d 100644 --- a/overlay_experimental/windows/DX10_Hook.cpp +++ b/overlay_experimental/windows/DX10_Hook.cpp @@ -80,8 +80,7 @@ void DX10_Hook::prepareForOverlay(IDXGISwapChain* pSwapChain) initialized = true; } - ImGui_ImplDX10_NewFrame(); - + if (ImGui_ImplDX10_NewFrame()) { Windows_Hook::Inst()->prepareForOverlay(desc.OutputWindow); diff --git a/overlay_experimental/windows/DX11_Hook.cpp b/overlay_experimental/windows/DX11_Hook.cpp index 88566e4..db9c6e5 100644 --- a/overlay_experimental/windows/DX11_Hook.cpp +++ b/overlay_experimental/windows/DX11_Hook.cpp @@ -121,8 +121,7 @@ void DX11_Hook::prepareForOverlay(IDXGISwapChain* pSwapChain) initialized = true; } - ImGui_ImplDX11_NewFrame(); - + if (ImGui_ImplDX11_NewFrame()) { Windows_Hook::Inst()->prepareForOverlay(desc.OutputWindow); diff --git a/overlay_experimental/windows/DX12_Hook.cpp b/overlay_experimental/windows/DX12_Hook.cpp index 6543466..8081331 100644 --- a/overlay_experimental/windows/DX12_Hook.cpp +++ b/overlay_experimental/windows/DX12_Hook.cpp @@ -176,8 +176,7 @@ void DX12_Hook::prepareForOverlay(IDXGISwapChain* pSwapChain) pDevice->Release(); } - ImGui_ImplDX12_NewFrame(); - + if (ImGui_ImplDX12_NewFrame()) { Windows_Hook::Inst()->prepareForOverlay(sc_desc.OutputWindow); diff --git a/overlay_experimental/windows/DX9_Hook.cpp b/overlay_experimental/windows/DX9_Hook.cpp index 213e1e2..a3a65f4 100644 --- a/overlay_experimental/windows/DX9_Hook.cpp +++ b/overlay_experimental/windows/DX9_Hook.cpp @@ -75,8 +75,7 @@ void DX9_Hook::prepareForOverlay(IDirect3DDevice9 *pDevice) initialized = true; } - ImGui_ImplDX9_NewFrame(); - + if (ImGui_ImplDX9_NewFrame()) { Windows_Hook::Inst()->prepareForOverlay(param.hFocusWindow); diff --git a/overlay_experimental/windows/OpenGL_Hook.cpp b/overlay_experimental/windows/OpenGL_Hook.cpp index a06fded..0b8ac08 100644 --- a/overlay_experimental/windows/OpenGL_Hook.cpp +++ b/overlay_experimental/windows/OpenGL_Hook.cpp @@ -84,8 +84,7 @@ void OpenGL_Hook::prepareForOverlay(HDC hDC) initialized = true; } - ImGui_ImplOpenGL3_NewFrame(); - + if (ImGui_ImplOpenGL3_NewFrame()) { Windows_Hook::Inst()->prepareForOverlay(hWnd); From 58b09d4f11323b809daf9d34941bd8fe1f2efb89 Mon Sep 17 00:00:00 2001 From: Mr_Goldberg Date: Sat, 23 Jan 2021 16:47:22 -0500 Subject: [PATCH 02/20] Fix old steamnetworkingsockets headers. --- sdk_includes/isteamnetworkingsockets002.h | 6 ------ sdk_includes/isteamnetworkingsockets003.h | 6 ------ sdk_includes/isteamnetworkingsockets004.h | 6 ------ sdk_includes/isteamnetworkingsockets006.h | 5 ----- 4 files changed, 23 deletions(-) diff --git a/sdk_includes/isteamnetworkingsockets002.h b/sdk_includes/isteamnetworkingsockets002.h index 0bbbc3d..149827b 100644 --- a/sdk_includes/isteamnetworkingsockets002.h +++ b/sdk_includes/isteamnetworkingsockets002.h @@ -55,7 +55,6 @@ public: /// man-in-the-middle attacks. virtual HSteamNetConnection ConnectByIPAddress( const SteamNetworkingIPAddr &address ) = 0; -#ifdef STEAMNETWORKINGSOCKETS_ENABLE_SDR /// Like CreateListenSocketIP, but clients will connect using ConnectP2P /// /// nVirtualPort specifies how clients can connect to this socket using @@ -80,7 +79,6 @@ public: /// If you use this, you probably want to call ISteamNetworkingUtils::InitializeRelayNetworkAccess() /// when your app initializes virtual HSteamNetConnection ConnectP2P( const SteamNetworkingIdentity &identityRemote, int nVirtualPort ) = 0; -#endif /// Accept an incoming connection that has been received on a listen socket. /// @@ -292,8 +290,6 @@ public: /// even if they are not signed into Steam.) virtual bool GetIdentity( SteamNetworkingIdentity *pIdentity ) = 0; -#ifdef STEAMNETWORKINGSOCKETS_ENABLE_SDR - // // Clients connecting to dedicated servers hosted in a data center, // using central-authority-granted tickets. @@ -365,8 +361,6 @@ public: /// Note that this call MUST be made through the SteamGameServerNetworkingSockets() interface virtual HSteamListenSocket CreateHostedDedicatedServerListenSocket( int nVirtualPort ) = 0; -#endif // #ifndef STEAMNETWORKINGSOCKETS_ENABLE_SDR - // Invoke all callbacks queued for this interface. // On Steam, callbacks are dispatched via the ordinary Steamworks callbacks mechanism. // So if you have code that is also targeting Steam, you should call this at about the diff --git a/sdk_includes/isteamnetworkingsockets003.h b/sdk_includes/isteamnetworkingsockets003.h index dc452d7..3f074ae 100644 --- a/sdk_includes/isteamnetworkingsockets003.h +++ b/sdk_includes/isteamnetworkingsockets003.h @@ -43,7 +43,6 @@ public: /// man-in-the-middle attacks. virtual HSteamNetConnection ConnectByIPAddress( const SteamNetworkingIPAddr &address ) = 0; -#ifdef STEAMNETWORKINGSOCKETS_ENABLE_SDR /// Like CreateListenSocketIP, but clients will connect using ConnectP2P /// /// nVirtualPort specifies how clients can connect to this socket using @@ -68,7 +67,6 @@ public: /// If you use this, you probably want to call ISteamNetworkingUtils::InitRelayNetworkAccess() /// when your app initializes virtual HSteamNetConnection ConnectP2P( const SteamNetworkingIdentity &identityRemote, int nVirtualPort ) = 0; -#endif /// Accept an incoming connection that has been received on a listen socket. /// @@ -331,8 +329,6 @@ public: #endif -#ifdef STEAMNETWORKINGSOCKETS_ENABLE_SDR - // // Clients connecting to dedicated servers hosted in a data center, // using central-authority-granted tickets. @@ -447,8 +443,6 @@ public: /// and don't share it directly with clients. virtual EResult GetGameCoordinatorServerLogin( SteamDatagramGameCoordinatorServerLogin *pLoginInfo, int *pcbSignedBlob, void *pBlob ) = 0; -#endif // #ifndef STEAMNETWORKINGSOCKETS_ENABLE_SDR - // Invoke all callbacks queued for this interface. // On Steam, callbacks are dispatched via the ordinary Steamworks callbacks mechanism. // So if you have code that is also targeting Steam, you should call this at about the diff --git a/sdk_includes/isteamnetworkingsockets004.h b/sdk_includes/isteamnetworkingsockets004.h index bab1478..85765f8 100644 --- a/sdk_includes/isteamnetworkingsockets004.h +++ b/sdk_includes/isteamnetworkingsockets004.h @@ -43,7 +43,6 @@ public: /// man-in-the-middle attacks. virtual HSteamNetConnection ConnectByIPAddress( const SteamNetworkingIPAddr *address ) = 0; -#ifdef STEAMNETWORKINGSOCKETS_ENABLE_SDR /// Like CreateListenSocketIP, but clients will connect using ConnectP2P /// /// nVirtualPort specifies how clients can connect to this socket using @@ -68,7 +67,6 @@ public: /// If you use this, you probably want to call ISteamNetworkingUtils::InitRelayNetworkAccess() /// when your app initializes virtual HSteamNetConnection ConnectP2P( const SteamNetworkingIdentity *identityRemote, int nVirtualPort ) = 0; -#endif /// Accept an incoming connection that has been received on a listen socket. /// @@ -331,8 +329,6 @@ public: #endif -#ifdef STEAMNETWORKINGSOCKETS_ENABLE_SDR - // // Clients connecting to dedicated servers hosted in a data center, // using central-authority-granted tickets. @@ -447,8 +443,6 @@ public: /// and don't share it directly with clients. virtual EResult GetGameCoordinatorServerLogin( SteamDatagramGameCoordinatorServerLogin *pLoginInfo, int *pcbSignedBlob, void *pBlob ) = 0; -#endif // #ifndef STEAMNETWORKINGSOCKETS_ENABLE_SDR - // Invoke all callbacks queued for this interface. // On Steam, callbacks are dispatched via the ordinary Steamworks callbacks mechanism. // So if you have code that is also targeting Steam, you should call this at about the diff --git a/sdk_includes/isteamnetworkingsockets006.h b/sdk_includes/isteamnetworkingsockets006.h index 1d2698e..83fd0a4 100644 --- a/sdk_includes/isteamnetworkingsockets006.h +++ b/sdk_includes/isteamnetworkingsockets006.h @@ -52,7 +52,6 @@ public: /// setting the options "immediately" after creation. virtual HSteamNetConnection ConnectByIPAddress( const SteamNetworkingIPAddr &address, int nOptions, const SteamNetworkingConfigValue_t *pOptions ) = 0; -#ifdef STEAMNETWORKINGSOCKETS_ENABLE_SDR /// Like CreateListenSocketIP, but clients will connect using ConnectP2P /// /// nVirtualPort specifies how clients can connect to this socket using @@ -81,7 +80,6 @@ public: /// SteamNetworkingConfigValue_t for more about why this is preferable to /// setting the options "immediately" after creation. virtual HSteamNetConnection ConnectP2P( const SteamNetworkingIdentity &identityRemote, int nVirtualPort, int nOptions, const SteamNetworkingConfigValue_t *pOptions ) = 0; -#endif /// Accept an incoming connection that has been received on a listen socket. /// @@ -370,8 +368,6 @@ public: /// details, pass non-NULL to receive them. virtual ESteamNetworkingAvailability GetAuthenticationStatus( SteamNetAuthenticationStatus_t *pDetails ) = 0; -#ifdef STEAMNETWORKINGSOCKETS_ENABLE_SDR - // // Clients connecting to dedicated servers hosted in a data center, // using central-authority-granted tickets. @@ -567,7 +563,6 @@ public: /// If you expect to be using relayed connections, then you probably want /// to call ISteamNetworkingUtils::InitRelayNetworkAccess() when your app initializes virtual bool ReceivedP2PCustomSignal( const void *pMsg, int cbMsg, ISteamNetworkingCustomSignalingRecvContext *pContext ) = 0; -#endif // #ifndef STEAMNETWORKINGSOCKETS_ENABLE_SDR /// Certificate provision by the application. (On Steam, Steam will handle all this automatically) #ifndef STEAMNETWORKINGSOCKETS_STEAM From ccc48d83a8103c2f7019b1827dbfdadfec8521ad Mon Sep 17 00:00:00 2001 From: Mr_Goldberg Date: Sat, 23 Jan 2021 16:48:45 -0500 Subject: [PATCH 03/20] Fix dx9 overlay graphics bug with black mesa. --- ImGui/impls/windows/imgui_impl_dx9.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/ImGui/impls/windows/imgui_impl_dx9.cpp b/ImGui/impls/windows/imgui_impl_dx9.cpp index dcb38a9..69150e9 100644 --- a/ImGui/impls/windows/imgui_impl_dx9.cpp +++ b/ImGui/impls/windows/imgui_impl_dx9.cpp @@ -130,6 +130,7 @@ void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data) if (g_pd3dDevice->CreateStateBlock(D3DSBT_ALL, &d3d9_state_block) < 0) return; + d3d9_state_block->Capture(); // Backup the DX9 transform (DX9 documentation suggests that it is included in the StateBlock but it doesn't appear to) D3DMATRIX last_world, last_view, last_projection; g_pd3dDevice->GetTransform(D3DTS_WORLD, &last_world); From 7ea90b03c4637b099ceef36d6ba425055ec20c52 Mon Sep 17 00:00:00 2001 From: Mr_Goldberg Date: Sat, 23 Jan 2021 23:03:10 -0500 Subject: [PATCH 04/20] Fixed some dedicated servers not booting up correctly. --- dll/dll.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dll/dll.cpp b/dll/dll.cpp index b18827e..b022c3b 100644 --- a/dll/dll.cpp +++ b/dll/dll.cpp @@ -187,7 +187,7 @@ static void *create_client_interface(const char *ver) STEAMAPI_API void * S_CALLTYPE SteamInternal_CreateInterface( const char *ver ) { PRINT_DEBUG("SteamInternal_CreateInterface %s\n", ver); - if (!get_steam_client()->user_logged_in) return NULL; + if (!get_steam_client()->user_logged_in && !get_steam_client()->IsServerInit()) return NULL; return create_client_interface(ver); } @@ -509,6 +509,7 @@ STEAMAPI_API bool S_CALLTYPE SteamAPI_InitSafe() STEAMAPI_API ISteamClient *SteamClient() { PRINT_DEBUG("SteamClient()\n"); load_old_interface_versions(); + if (!get_steam_client()->user_logged_in) return NULL; return (ISteamClient *)SteamInternal_CreateInterface(old_client); } From 37b329c9c560c052a2fe5105cdafb5bb7e4e2755 Mon Sep 17 00:00:00 2001 From: Mr_Goldberg Date: Sun, 31 Jan 2021 21:50:11 -0500 Subject: [PATCH 05/20] Implement networking sockets connection status/info functions. --- dll/steam_networking_sockets.h | 38 +++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/dll/steam_networking_sockets.h b/dll/steam_networking_sockets.h index 60ddaf1..3fe0d91 100644 --- a/dll/steam_networking_sockets.h +++ b/dll/steam_networking_sockets.h @@ -833,7 +833,25 @@ int ReceiveMessagesOnListenSocket( HSteamListenSocket hSocket, SteamNetworkingMe bool GetConnectionInfo( HSteamNetConnection hConn, SteamNetConnectionInfo_t *pInfo ) { PRINT_DEBUG("Steam_Networking_Sockets::GetConnectionInfo\n"); - return false; + if (!pInfo) + return false; + + std::lock_guard lock(global_mutex); + auto connect_socket = connect_sockets.find(hConn); + if (connect_socket == connect_sockets.end()) return false; + + memset(pInfo, 0, sizeof(SteamNetConnectionInfo_t)); + pInfo->m_identityRemote = connect_socket->second.remote_identity; + pInfo->m_nUserData = connect_socket->second.user_data; + pInfo->m_hListenSocket = connect_socket->second.listen_socket_id; + //pInfo->m_addrRemote; //TODO + pInfo->m_idPOPRemote = 0; + pInfo->m_idPOPRelay = 0; + pInfo->m_eState = convert_status(connect_socket->second.status); + pInfo->m_eEndReason = 0; //TODO + pInfo->m_szEndDebug[0] = 0; + sprintf(pInfo->m_szConnectionDescription, "%u", hConn); + return true; } @@ -878,7 +896,7 @@ int ReceiveMessagesOnListenSocket( HSteamListenSocket hSocket, SteamNetworkingMe /// Returns information about the specified connection. bool GetConnectionInfo( HSteamNetConnection hConn, SteamNetConnectionInfo001_t *pInfo ) { - PRINT_DEBUG("Steam_Networking_Sockets::GetConnectionInfo\n"); + PRINT_DEBUG("Steam_Networking_Sockets::GetConnectionInfo001\n"); return false; } @@ -888,7 +906,21 @@ bool GetConnectionInfo( HSteamNetConnection hConn, SteamNetConnectionInfo001_t * bool GetQuickConnectionStatus( HSteamNetConnection hConn, SteamNetworkingQuickConnectionStatus *pStats ) { PRINT_DEBUG("Steam_Networking_Sockets::GetQuickConnectionStatus\n"); - return false; + if (!pStats) + return false; + + std::lock_guard lock(global_mutex); + auto connect_socket = connect_sockets.find(hConn); + if (connect_socket == connect_sockets.end()) return false; + memset(pStats, 0, sizeof(SteamNetworkingQuickConnectionStatus)); + + pStats->m_eState = convert_status(connect_socket->second.status); + pStats->m_nPing = 10; //TODO: calculate real numbers? + pStats->m_flConnectionQualityLocal = 1.0; + pStats->m_flConnectionQualityRemote = 1.0; + //TODO: rest + + return true; } From 9a63cf868da4a7740c9470a06dda299b4e1720e0 Mon Sep 17 00:00:00 2001 From: Mr_Goldberg Date: Sun, 31 Jan 2021 21:50:31 -0500 Subject: [PATCH 06/20] Listen socket ids should be different from connection socket ids. --- dll/steam_networking_sockets.h | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/dll/steam_networking_sockets.h b/dll/steam_networking_sockets.h index 3fe0d91..82acd51 100644 --- a/dll/steam_networking_sockets.h +++ b/dll/steam_networking_sockets.h @@ -107,11 +107,16 @@ Steam_Networking_Sockets(class Settings *settings, class Networking *network, cl this->run_every_runcb->remove(&Steam_Networking_Sockets::steam_run_every_runcb, this); } +static unsigned long get_socket_id() +{ + static unsigned long socket_id; + socket_id++; + return socket_id; +} HSteamListenSocket new_listen_socket(int nSteamConnectVirtualPort) { - static HSteamListenSocket socket_id; - ++socket_id; + HSteamListenSocket socket_id = get_socket_id(); if (socket_id == k_HSteamListenSocket_Invalid) ++socket_id; auto conn = std::find_if(listen_sockets.begin(), listen_sockets.end(), [&nSteamConnectVirtualPort](struct Listen_Socket const& conn) { return conn.virtual_port == nSteamConnectVirtualPort;}); @@ -165,8 +170,7 @@ HSteamNetConnection new_connect_socket(SteamNetworkingIdentity remote_identity, socket.user_data = -1; socket.poll_group = k_HSteamNetPollGroup_Invalid; - static HSteamNetConnection socket_id; - ++socket_id; + HSteamNetConnection socket_id = get_socket_id(); if (socket_id == k_HSteamNetConnection_Invalid) ++socket_id; if (connect_sockets.insert(std::make_pair(socket_id, socket)).second == false) { From 587339879024ead9366f767f5163ca0ba70be8b1 Mon Sep 17 00:00:00 2001 From: Mr_Goldberg Date: Thu, 4 Feb 2021 12:49:01 -0500 Subject: [PATCH 07/20] Fix some header issues that broke some interfaces. --- sdk_includes/isteamnetworkingsockets008.h | 5 ----- sdk_includes/isteamnetworkingutils001.h | 2 -- sdk_includes/isteamnetworkingutils002.h | 2 -- 3 files changed, 9 deletions(-) diff --git a/sdk_includes/isteamnetworkingsockets008.h b/sdk_includes/isteamnetworkingsockets008.h index f98e776..bc2914b 100644 --- a/sdk_includes/isteamnetworkingsockets008.h +++ b/sdk_includes/isteamnetworkingsockets008.h @@ -52,7 +52,6 @@ public: /// setting the options "immediately" after creation. virtual HSteamNetConnection ConnectByIPAddress( const SteamNetworkingIPAddr &address, int nOptions, const SteamNetworkingConfigValue_t *pOptions ) = 0; -#ifdef STEAMNETWORKINGSOCKETS_ENABLE_SDR /// Like CreateListenSocketIP, but clients will connect using ConnectP2P /// /// nVirtualPort specifies how clients can connect to this socket using @@ -81,7 +80,6 @@ public: /// SteamNetworkingConfigValue_t for more about why this is preferable to /// setting the options "immediately" after creation. virtual HSteamNetConnection ConnectP2P( const SteamNetworkingIdentity &identityRemote, int nVirtualPort, int nOptions, const SteamNetworkingConfigValue_t *pOptions ) = 0; -#endif /// Accept an incoming connection that has been received on a listen socket. /// @@ -411,8 +409,6 @@ public: /// other connections.) virtual int ReceiveMessagesOnPollGroup( HSteamNetPollGroup hPollGroup, SteamNetworkingMessage_t **ppOutMessages, int nMaxMessages ) = 0; -#ifdef STEAMNETWORKINGSOCKETS_ENABLE_SDR - // // Clients connecting to dedicated servers hosted in a data center, // using central-authority-granted tickets. @@ -608,7 +604,6 @@ public: /// If you expect to be using relayed connections, then you probably want /// to call ISteamNetworkingUtils::InitRelayNetworkAccess() when your app initializes virtual bool ReceivedP2PCustomSignal( const void *pMsg, int cbMsg, ISteamNetworkingCustomSignalingRecvContext *pContext ) = 0; -#endif // #ifndef STEAMNETWORKINGSOCKETS_ENABLE_SDR // // Certificate provision by the application. On Steam, we normally handle all this automatically diff --git a/sdk_includes/isteamnetworkingutils001.h b/sdk_includes/isteamnetworkingutils001.h index ac5e3ab..1a89064 100644 --- a/sdk_includes/isteamnetworkingutils001.h +++ b/sdk_includes/isteamnetworkingutils001.h @@ -8,7 +8,6 @@ class ISteamNetworkingUtils001 { public: -#ifdef STEAMNETWORKINGSOCKETS_ENABLE_SDR // // Initialization @@ -149,7 +148,6 @@ public: /// Get list of all POP IDs. Returns the number of entries that were filled into /// your list. virtual int GetPOPList( SteamNetworkingPOPID *list, int nListSz ) = 0; -#endif // #ifdef STEAMNETWORKINGSOCKETS_ENABLE_SDR // // Misc diff --git a/sdk_includes/isteamnetworkingutils002.h b/sdk_includes/isteamnetworkingutils002.h index fab5b08..dc9c4d4 100644 --- a/sdk_includes/isteamnetworkingutils002.h +++ b/sdk_includes/isteamnetworkingutils002.h @@ -8,7 +8,6 @@ class ISteamNetworkingUtils002 { public: -#ifdef STEAMNETWORKINGSOCKETS_ENABLE_SDR // // Initialization and status check @@ -152,7 +151,6 @@ public: /// Get list of all POP IDs. Returns the number of entries that were filled into /// your list. virtual int GetPOPList( SteamNetworkingPOPID *list, int nListSz ) = 0; -#endif // #ifdef STEAMNETWORKINGSOCKETS_ENABLE_SDR // // Misc From 6dfe11503bbc9ea8bc68b50087f76319bfeafd97 Mon Sep 17 00:00:00 2001 From: Mr_Goldberg Date: Sat, 6 Feb 2021 22:37:59 -0500 Subject: [PATCH 08/20] Dll loading feature now only tries loading .dll files. --- dll/base.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/dll/base.cpp b/dll/base.cpp index a5b3e5f..4e805e5 100644 --- a/dll/base.cpp +++ b/dll/base.cpp @@ -649,6 +649,13 @@ static void load_dlls() std::vector paths = Local_Storage::get_filenames_path(path); for (auto & p: paths) { std::string full_path = path + p; + size_t length = full_path.length(); + if (length < 4) continue; + if (std::toupper(full_path[length - 1]) != 'L') continue; + if (std::toupper(full_path[length - 2]) != 'L') continue; + if (std::toupper(full_path[length - 3]) != 'D') continue; + if (full_path[length - 4] != '.') continue; + PRINT_DEBUG("Trying to load %s\n", full_path.c_str()); if (LoadLibraryA(full_path.c_str())) { PRINT_DEBUG("LOADED %s\n", full_path.c_str()); From 5f8a454e3f45294194ea5f9627df11a75f52af7f Mon Sep 17 00:00:00 2001 From: Mr_Goldberg Date: Sat, 6 Feb 2021 22:38:51 -0500 Subject: [PATCH 09/20] Fixed mouse getting stuck in the middle of the overlay in some games. --- overlay_experimental/windows/Windows_Hook.cpp | 16 +++++++++++++++- overlay_experimental/windows/Windows_Hook.h | 2 ++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/overlay_experimental/windows/Windows_Hook.cpp b/overlay_experimental/windows/Windows_Hook.cpp index f273c5e..4127aec 100644 --- a/overlay_experimental/windows/Windows_Hook.cpp +++ b/overlay_experimental/windows/Windows_Hook.cpp @@ -18,13 +18,15 @@ bool Windows_Hook::start_hook() { GetRawInputBuffer = ::GetRawInputBuffer; GetRawInputData = ::GetRawInputData; + SetCursorPos = ::SetCursorPos; PRINT_DEBUG("Hooked Windows\n"); BeginHook(); HookFuncs( std::make_pair(&(PVOID&)GetRawInputBuffer, &Windows_Hook::MyGetRawInputBuffer), - std::make_pair(&(PVOID&)GetRawInputData , &Windows_Hook::MyGetRawInputData) + std::make_pair(&(PVOID&)GetRawInputData , &Windows_Hook::MyGetRawInputData), + std::make_pair(&(PVOID&)SetCursorPos , &Windows_Hook::MySetCursorPos) ); EndHook(); @@ -169,6 +171,18 @@ UINT WINAPI Windows_Hook::MyGetRawInputData(HRAWINPUT hRawInput, UINT uiCommand, return 0; } + +BOOL WINAPI Windows_Hook::MySetCursorPos(int x, int y) +{ + if (get_steam_client()->steam_overlay->ShowOverlay()) { + POINT p; + GetCursorPos(&p); + x = p.x; + y = p.y; + } + + return Windows_Hook::Inst()->SetCursorPos(x, y); +} ///////////////////////////////////////////////////////////////////////////////////// Windows_Hook::Windows_Hook() : diff --git a/overlay_experimental/windows/Windows_Hook.h b/overlay_experimental/windows/Windows_Hook.h index 631edf3..0547dfc 100644 --- a/overlay_experimental/windows/Windows_Hook.h +++ b/overlay_experimental/windows/Windows_Hook.h @@ -26,11 +26,13 @@ private: // Hook to Windows window messages decltype(GetRawInputBuffer)* GetRawInputBuffer; decltype(GetRawInputData)* GetRawInputData; + decltype(SetCursorPos)* SetCursorPos; static LRESULT CALLBACK HookWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); static UINT WINAPI MyGetRawInputBuffer(PRAWINPUT pData, PUINT pcbSize, UINT cbSizeHeader); static UINT WINAPI MyGetRawInputData(HRAWINPUT hRawInput, UINT uiCommand, LPVOID pData, PUINT pcbSize, UINT cbSizeHeader); + static BOOL WINAPI MySetCursorPos(int x, int y); public: virtual ~Windows_Hook(); From 69d5facf4f0ec2d7742b59d30212e40fe88689d9 Mon Sep 17 00:00:00 2001 From: Mr_Goldberg Date: Sun, 7 Feb 2021 19:05:22 -0500 Subject: [PATCH 10/20] Cleanup steamclient loader a bit. --- steamclient_loader/ColdClientLoader.cpp | 131 +++++++++--------------- 1 file changed, 46 insertions(+), 85 deletions(-) diff --git a/steamclient_loader/ColdClientLoader.cpp b/steamclient_loader/ColdClientLoader.cpp index d7e2f1a..4c364fa 100644 --- a/steamclient_loader/ColdClientLoader.cpp +++ b/steamclient_loader/ColdClientLoader.cpp @@ -45,7 +45,7 @@ int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance } if (GetFileAttributesA(CurrentDirectory) == INVALID_FILE_ATTRIBUTES) { MessageBoxA(NULL, "Couldn't find the configuration file(ColdClientLoader.ini).", "ColdClientLoader", MB_ICONERROR); - ExitProcess(NULL); + return 0; } GetPrivateProfileStringA("SteamClient", "SteamClient64Dll", "", Client64Path, MAX_PATH, CurrentDirectory); @@ -60,27 +60,23 @@ int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance SetEnvironmentVariableA("SteamGameId", AppId); } - CHAR TMP[MAX_PATH] = { 0 }; + CHAR TMP[MAX_PATH] = {}; if (!IsNotRelativePathOrRemoveFileName(Client64Path, false)) { - ZeroMemory(TMP, sizeof(TMP)); lstrcpyA(TMP, Client64Path); ZeroMemory(Client64Path, sizeof(Client64Path)); GetFullPathNameA(TMP, MAX_PATH, Client64Path, NULL); } if (!IsNotRelativePathOrRemoveFileName(ClientPath, false)) { - ZeroMemory(TMP, sizeof(TMP)); lstrcpyA(TMP, ClientPath); ZeroMemory(ClientPath, sizeof(ClientPath)); GetFullPathNameA(TMP, MAX_PATH, ClientPath, NULL); } if (!IsNotRelativePathOrRemoveFileName(ExeFile, false)) { - ZeroMemory(TMP, sizeof(TMP)); lstrcpyA(TMP, ExeFile); ZeroMemory(ExeFile, sizeof(ExeFile)); GetFullPathNameA(TMP, MAX_PATH, ExeFile, NULL); } if (!IsNotRelativePathOrRemoveFileName(ExeRunDir, false)) { - ZeroMemory(TMP, sizeof(TMP)); lstrcpyA(TMP, ExeRunDir); ZeroMemory(ExeRunDir, sizeof(ExeRunDir)); GetFullPathNameA(TMP, MAX_PATH, ExeRunDir, NULL); @@ -88,17 +84,17 @@ int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance if (GetFileAttributesA(Client64Path) == INVALID_FILE_ATTRIBUTES) { MessageBoxA(NULL, "Couldn't find the requested SteamClient64Dll.", "ColdClientLoader", MB_ICONERROR); - ExitProcess(NULL); + return 0; } if (GetFileAttributesA(ClientPath) == INVALID_FILE_ATTRIBUTES) { MessageBoxA(NULL, "Couldn't find the requested SteamClientDll.", "ColdClientLoader", MB_ICONERROR); - ExitProcess(NULL); + return 0; } if (GetFileAttributesA(ExeFile) == INVALID_FILE_ATTRIBUTES) { MessageBoxA(NULL, "Couldn't find the requested Exe file.", "ColdClientLoader", MB_ICONERROR); - ExitProcess(NULL); + return 0; } CHAR CommandLine[8192]; @@ -106,98 +102,65 @@ int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance if (!ExeFile[0] || !CreateProcessA(ExeFile, CommandLine, NULL, NULL, TRUE, CREATE_SUSPENDED, NULL, ExeRunDir, &info, &processInfo)) { MessageBoxA(NULL, "Unable to load the requested EXE file.", "ColdClientLoader", MB_ICONERROR); - ExitProcess(NULL); + return 0; } HKEY Registrykey; // Declare some variables to be used for Steam registry. DWORD UserId = 0x03100004771F810D & 0xffffffff; DWORD ProcessID = GetCurrentProcessId(); - if (RegOpenKeyExA(HKEY_CURRENT_USER, "Software\\Valve\\Steam\\ActiveProcess", 0, KEY_ALL_ACCESS, &Registrykey) != ERROR_SUCCESS) + bool orig_steam = false; + DWORD keyType = REG_SZ; + CHAR OrgSteamCDir[MAX_PATH] = { 0 }; + CHAR OrgSteamCDir64[MAX_PATH] = { 0 }; + DWORD Size1 = MAX_PATH; + DWORD Size2 = MAX_PATH; + if (RegOpenKeyExA(HKEY_CURRENT_USER, "Software\\Valve\\Steam\\ActiveProcess", 0, KEY_ALL_ACCESS, &Registrykey) == ERROR_SUCCESS) { + orig_steam = true; + // Get original values to restore later. + RegQueryValueExA(Registrykey, "SteamClientDll", 0, &keyType, (LPBYTE)& OrgSteamCDir, &Size1); + RegQueryValueExA(Registrykey, "SteamClientDll64", 0, &keyType, (LPBYTE)& OrgSteamCDir64, &Size2); + } else { if (RegCreateKeyExA(HKEY_CURRENT_USER, "Software\\Valve\\Steam\\ActiveProcess", 0, 0, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &Registrykey, NULL) != ERROR_SUCCESS) { MessageBoxA(NULL, "Unable to patch Steam process informations on the Windows registry.", "ColdClientLoader", MB_ICONERROR); TerminateProcess(processInfo.hProcess, NULL); - ExitProcess(NULL); - } - else - { - - // Set values to Windows registry. - RegSetValueExA(Registrykey, "ActiveUser", NULL, REG_DWORD, (LPBYTE)& UserId, sizeof(DWORD)); - RegSetValueExA(Registrykey, "pid", NULL, REG_DWORD, (LPBYTE)& ProcessID, sizeof(DWORD)); - - { - // Before saving to the registry check again if the path was valid and if the file exist - if (GetFileAttributesA(ClientPath) != INVALID_FILE_ATTRIBUTES) { - RegSetValueExA(Registrykey, "SteamClientDll", NULL, REG_SZ, (LPBYTE)ClientPath, (DWORD)lstrlenA(ClientPath) + 1); - } - else { - RegSetValueExA(Registrykey, "SteamClientDll", NULL, REG_SZ, (LPBYTE)"", 0); - } - if (GetFileAttributesA(Client64Path) != INVALID_FILE_ATTRIBUTES) { - RegSetValueExA(Registrykey, "SteamClientDll64", NULL, REG_SZ, (LPBYTE)Client64Path, (DWORD)lstrlenA(Client64Path) + 1); - } - else { - RegSetValueExA(Registrykey, "SteamClientDll64", NULL, REG_SZ, (LPBYTE)"", 0); - } - } - RegSetValueExA(Registrykey, "Universe", NULL, REG_SZ, (LPBYTE)"Public", (DWORD)lstrlenA("Public") + 1); - - // Close the HKEY Handle. - RegCloseKey(Registrykey); - - ResumeThread(processInfo.hThread); - WaitForSingleObject(processInfo.hThread, INFINITE); - CloseHandle(processInfo.hProcess); - CloseHandle(processInfo.hThread); - ExitProcess(NULL); + return 0; } } - else + + // Set values to Windows registry. + RegSetValueExA(Registrykey, "ActiveUser", NULL, REG_DWORD, (LPBYTE)& UserId, sizeof(DWORD)); + RegSetValueExA(Registrykey, "pid", NULL, REG_DWORD, (LPBYTE)& ProcessID, sizeof(DWORD)); + { - DWORD keyType = REG_SZ; - CHAR OrgSteamCDir[MAX_PATH] = { 0 }; - CHAR OrgSteamCDir64[MAX_PATH] = { 0 }; - DWORD Size1 = MAX_PATH; - DWORD Size2 = MAX_PATH; - - // Get original values to restore later. - RegQueryValueExA(Registrykey, "SteamClientDll", 0, &keyType, (LPBYTE)& OrgSteamCDir, &Size1); - RegQueryValueExA(Registrykey, "SteamClientDll64", 0, &keyType, (LPBYTE)& OrgSteamCDir64, &Size2); - - // Set values to Windows registry. - RegSetValueExA(Registrykey, "ActiveUser", NULL, REG_DWORD, (LPBYTE)& UserId, sizeof(DWORD)); - RegSetValueExA(Registrykey, "pid", NULL, REG_DWORD, (LPBYTE)& ProcessID, sizeof(DWORD)); - - - { - // Before saving to the registry check again if the path was valid and if the file exist - if (GetFileAttributesA(ClientPath) != INVALID_FILE_ATTRIBUTES) { - RegSetValueExA(Registrykey, "SteamClientDll", NULL, REG_SZ, (LPBYTE)ClientPath, (DWORD)lstrlenA(ClientPath) + 1); - } - else { - RegSetValueExA(Registrykey, "SteamClientDll", NULL, REG_SZ, (LPBYTE)"", 0); - } - if (GetFileAttributesA(Client64Path) != INVALID_FILE_ATTRIBUTES) { - RegSetValueExA(Registrykey, "SteamClientDll64", NULL, REG_SZ, (LPBYTE)Client64Path, (DWORD)lstrlenA(Client64Path) + 1); - } - else { - RegSetValueExA(Registrykey, "SteamClientDll64", NULL, REG_SZ, (LPBYTE)"", 0); - } + // Before saving to the registry check again if the path was valid and if the file exist + if (GetFileAttributesA(ClientPath) != INVALID_FILE_ATTRIBUTES) { + RegSetValueExA(Registrykey, "SteamClientDll", NULL, REG_SZ, (LPBYTE)ClientPath, (DWORD)lstrlenA(ClientPath) + 1); } - RegSetValueExA(Registrykey, "Universe", NULL, REG_SZ, (LPBYTE)"Public", (DWORD)lstrlenA("Public") + 1); + else { + RegSetValueExA(Registrykey, "SteamClientDll", NULL, REG_SZ, (LPBYTE)"", 0); + } + if (GetFileAttributesA(Client64Path) != INVALID_FILE_ATTRIBUTES) { + RegSetValueExA(Registrykey, "SteamClientDll64", NULL, REG_SZ, (LPBYTE)Client64Path, (DWORD)lstrlenA(Client64Path) + 1); + } + else { + RegSetValueExA(Registrykey, "SteamClientDll64", NULL, REG_SZ, (LPBYTE)"", 0); + } + } + RegSetValueExA(Registrykey, "Universe", NULL, REG_SZ, (LPBYTE)"Public", (DWORD)lstrlenA("Public") + 1); - // Close the HKEY Handle. - RegCloseKey(Registrykey); + // Close the HKEY Handle. + RegCloseKey(Registrykey); - ResumeThread(processInfo.hThread); - WaitForSingleObject(processInfo.hThread, INFINITE); - CloseHandle(processInfo.hProcess); - CloseHandle(processInfo.hThread); + ResumeThread(processInfo.hThread); + WaitForSingleObject(processInfo.hThread, INFINITE); + CloseHandle(processInfo.hProcess); + CloseHandle(processInfo.hThread); + if (orig_steam) { if (RegOpenKeyExA(HKEY_CURRENT_USER, "Software\\Valve\\Steam\\ActiveProcess", 0, KEY_ALL_ACCESS, &Registrykey) == ERROR_SUCCESS) { // Restore the values. @@ -207,9 +170,7 @@ int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance // Close the HKEY Handle. RegCloseKey(Registrykey); } - ExitProcess(NULL); } - - return 1; + return 0; } From bfa1e95f7b93aded0f166731add4118af0a9f236 Mon Sep 17 00:00:00 2001 From: Mr_Goldberg Date: Sun, 7 Feb 2021 19:09:48 -0500 Subject: [PATCH 11/20] Use the same interface for both enabled and disabled controller builds. --- ...d_win_release_experimental_steamclient.bat | 2 +- dll/steam_client.h | 4 - dll/steam_controller.h | 16 +- dll/steam_controller_disabled.h | 375 ------------------ 4 files changed, 15 insertions(+), 382 deletions(-) delete mode 100644 dll/steam_controller_disabled.h diff --git a/build_win_release_experimental_steamclient.bat b/build_win_release_experimental_steamclient.bat index 540a8e1..22566d4 100644 --- a/build_win_release_experimental_steamclient.bat +++ b/build_win_release_experimental_steamclient.bat @@ -8,7 +8,7 @@ call build_env_x86.bat cl dll/rtlgenrandom.c dll/rtlgenrandom.def cl /LD /DEMU_RELEASE_BUILD /DEMU_EXPERIMENTAL_BUILD /DSTEAMCLIENT_DLL /DCONTROLLER_SUPPORT /DEMU_OVERLAY /DGLEW_STATIC /IImGui /Iglew\include /DNDEBUG /I%PROTOBUF_X86_DIRECTORY%\include\ dll/*.cpp dll/*.cc detours/*.cpp controller/gamepad.c ImGui/*.cpp ImGui/impls/*.cpp ImGui/impls/windows/*.cpp overlay_experimental/*.cpp overlay_experimental/windows/*.cpp "%PROTOBUF_X86_LIBRARY%" glew\glew.c opengl32.lib Iphlpapi.lib Ws2_32.lib rtlgenrandom.lib Shell32.lib Winmm.lib /EHsc /MP12 /Ox /link /debug:none /OUT:release\experimental_steamclient\steamclient.dll "%PROTOC_X64_EXE%" -I.\dll\ --cpp_out=.\dll\ .\dll\net.proto -cl steamclient_loader/*.cpp advapi32.lib user32.lib /EHsc /MP12 /Od /link /debug:none /OUT:release\experimental_steamclient\steamclient_loader.exe +cl steamclient_loader/*.cpp advapi32.lib user32.lib /EHsc /MP12 /Ox /link /debug:none /OUT:release\experimental_steamclient\steamclient_loader.exe copy steamclient_loader\ColdClientLoader.ini release\experimental_steamclient\ call build_env_x64.bat cl dll/rtlgenrandom.c dll/rtlgenrandom.def diff --git a/dll/steam_client.h b/dll/steam_client.h index c085709..b46285e 100644 --- a/dll/steam_client.h +++ b/dll/steam_client.h @@ -27,11 +27,7 @@ #include "steam_remote_storage.h" #include "steam_screenshots.h" #include "steam_http.h" -#ifdef CONTROLLER_SUPPORT #include "steam_controller.h" -#else -#include "steam_controller_disabled.h" -#endif #include "steam_ugc.h" #include "steam_applist.h" #include "steam_music.h" diff --git a/dll/steam_controller.h b/dll/steam_controller.h index 7cefb6f..741ce18 100644 --- a/dll/steam_controller.h +++ b/dll/steam_controller.h @@ -16,6 +16,18 @@ . */ #include "base.h" +#ifndef CONTROLLER_SUPPORT +inline void GamepadInit(void) {} +inline void GamepadShutdown(void) {} +inline void GamepadUpdate(void) {} +inline GAMEPAD_BOOL GamepadIsConnected(GAMEPAD_DEVICE device) { return GAMEPAD_FALSE; } +inline GAMEPAD_BOOL GamepadButtonDown(GAMEPAD_DEVICE device, GAMEPAD_BUTTON button) { return GAMEPAD_FALSE; } +inline float GamepadTriggerLength(GAMEPAD_DEVICE device, GAMEPAD_TRIGGER trigger) { return 0.0; } +inline GAMEPAD_STICKDIR GamepadStickDir(GAMEPAD_DEVICE device, GAMEPAD_STICK stick) { return STICKDIR_CENTER; } +inline void GamepadStickNormXY(GAMEPAD_DEVICE device, GAMEPAD_STICK stick, float* outX, float* outY) {} +inline float GamepadStickLength(GAMEPAD_DEVICE device, GAMEPAD_STICK stick) { return 0.0; } +inline void GamepadSetRumble(GAMEPAD_DEVICE device, float left, float right, unsigned int rumble_length_ms) {} +#endif struct Controller_Map { std::map> active_digital; @@ -756,7 +768,7 @@ int GetGamepadIndexForController( ControllerHandle_t ulControllerHandle ) // Returns the associated controller handle for the specified emulated gamepad ControllerHandle_t GetControllerForGamepadIndex( int nIndex ) { - PRINT_DEBUG("Steam_Controller::GetControllerForGamepadIndex\n"); + PRINT_DEBUG("Steam_Controller::GetControllerForGamepadIndex %i\n", nIndex); ControllerHandle_t out = nIndex + 1; auto controller = controllers.find(out); if (controller == controllers.end()) return 0; @@ -890,7 +902,7 @@ const char *GetGlyphForActionOrigin( EInputActionOrigin eOrigin ) // Returns the input type for a particular handle ESteamInputType GetInputTypeForHandle( ControllerHandle_t controllerHandle ) { - PRINT_DEBUG("Steam_Controller::GetInputTypeForHandle\n"); + PRINT_DEBUG("Steam_Controller::GetInputTypeForHandle %llu\n", controllerHandle); auto controller = controllers.find(controllerHandle); if (controller == controllers.end()) return k_ESteamInputType_Unknown; return k_ESteamInputType_XBox360Controller; diff --git a/dll/steam_controller_disabled.h b/dll/steam_controller_disabled.h deleted file mode 100644 index 825ff0b..0000000 --- a/dll/steam_controller_disabled.h +++ /dev/null @@ -1,375 +0,0 @@ -/* Copyright (C) 2019 Mr Goldberg - This file is part of the Goldberg Emulator - - The Goldberg Emulator is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - The Goldberg Emulator is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the Goldberg Emulator; if not, see - . */ - -#include "base.h" - -class Steam_Controller : -public ISteamController001, -public ISteamController003, -public ISteamController004, -public ISteamController005, -public ISteamController006, -public ISteamController, -public ISteamInput -{ -public: - -Steam_Controller(class Settings *settings, class SteamCallResults *callback_results, class SteamCallBacks *callbacks, class RunEveryRunCB *run_every_runcb) -{ -} - -// Init and Shutdown must be called when starting/ending use of this interface -bool Init() -{ - PRINT_DEBUG("Steam_Controller::Init()\n"); - return true; -} - -bool Init( const char *pchAbsolutePathToControllerConfigVDF ) -{ - PRINT_DEBUG("Steam_Controller::Init() old\n"); - return Init(); -} - -bool Shutdown() -{ - PRINT_DEBUG("Steam_Controller::Shutdown()\n"); - return true; -} - -void SetOverrideMode( const char *pchMode ) -{ - PRINT_DEBUG("Steam_Controller::SetOverrideMode\n"); -} - -// Synchronize API state with the latest Steam Controller inputs available. This -// is performed automatically by SteamAPI_RunCallbacks, but for the absolute lowest -// possible latency, you call this directly before reading controller state. -void RunFrame() -{ - PRINT_DEBUG("Steam_Controller::RunFrame()\n"); -} - -bool GetControllerState( uint32 unControllerIndex, SteamControllerState001_t *pState ) -{ - PRINT_DEBUG("Steam_Controller::GetControllerState()\n"); - return false; -} - -// Enumerate currently connected controllers -// handlesOut should point to a STEAM_CONTROLLER_MAX_COUNT sized array of ControllerHandle_t handles -// Returns the number of handles written to handlesOut -int GetConnectedControllers( ControllerHandle_t *handlesOut ) -{ - PRINT_DEBUG("GetConnectedControllers\n"); - return 0; -} - - -// Invokes the Steam overlay and brings up the binding screen -// Returns false is overlay is disabled / unavailable, or the user is not in Big Picture mode -bool ShowBindingPanel( ControllerHandle_t controllerHandle ) -{ - PRINT_DEBUG("ShowBindingPanel\n"); - return false; -} - - -// ACTION SETS -// Lookup the handle for an Action Set. Best to do this once on startup, and store the handles for all future API calls. -ControllerActionSetHandle_t GetActionSetHandle( const char *pszActionSetName ) -{ - PRINT_DEBUG("GetActionSetHandle %s\n", pszActionSetName); - return 124; -} - - -// Reconfigure the controller to use the specified action set (ie 'Menu', 'Walk' or 'Drive') -// This is cheap, and can be safely called repeatedly. It's often easier to repeatedly call it in -// your state loops, instead of trying to place it in all of your state transitions. -void ActivateActionSet( ControllerHandle_t controllerHandle, ControllerActionSetHandle_t actionSetHandle ) -{ - PRINT_DEBUG("ActivateActionSet\n"); -} - -ControllerActionSetHandle_t GetCurrentActionSet( ControllerHandle_t controllerHandle ) -{ - PRINT_DEBUG("GetCurrentActionSet\n"); - return 124; -} - - -void ActivateActionSetLayer( ControllerHandle_t controllerHandle, ControllerActionSetHandle_t actionSetLayerHandle ) -{ - PRINT_DEBUG("ActivateActionSetLayer\n"); -} - -void DeactivateActionSetLayer( ControllerHandle_t controllerHandle, ControllerActionSetHandle_t actionSetLayerHandle ) -{ - PRINT_DEBUG("DeactivateActionSetLayer\n"); -} - -void DeactivateAllActionSetLayers( ControllerHandle_t controllerHandle ) -{ - PRINT_DEBUG("DeactivateAllActionSetLayers\n"); -} - -int GetActiveActionSetLayers( ControllerHandle_t controllerHandle, ControllerActionSetHandle_t *handlesOut ) -{ - PRINT_DEBUG("GetActiveActionSetLayers\n"); - return 0; -} - - - -// ACTIONS -// Lookup the handle for a digital action. Best to do this once on startup, and store the handles for all future API calls. -ControllerDigitalActionHandle_t GetDigitalActionHandle( const char *pszActionName ) -{ - PRINT_DEBUG("GetDigitalActionHandle %s\n", pszActionName); - return 123; -} - - -// Returns the current state of the supplied digital game action -ControllerDigitalActionData_t GetDigitalActionData( ControllerHandle_t controllerHandle, ControllerDigitalActionHandle_t digitalActionHandle ) -{ - PRINT_DEBUG("GetDigitalActionData\n"); - ControllerDigitalActionData_t digitalData; - digitalData.bActive = false; - return digitalData; -} - - -// Get the origin(s) for a digital action within an action set. Returns the number of origins supplied in originsOut. Use this to display the appropriate on-screen prompt for the action. -// originsOut should point to a STEAM_CONTROLLER_MAX_ORIGINS sized array of EControllerActionOrigin handles -int GetDigitalActionOrigins( ControllerHandle_t controllerHandle, ControllerActionSetHandle_t actionSetHandle, ControllerDigitalActionHandle_t digitalActionHandle, EControllerActionOrigin *originsOut ) -{ - PRINT_DEBUG("GetDigitalActionOrigins\n"); - return 0; -} - -int GetDigitalActionOrigins( InputHandle_t inputHandle, InputActionSetHandle_t actionSetHandle, InputDigitalActionHandle_t digitalActionHandle, EInputActionOrigin *originsOut ) -{ - PRINT_DEBUG("GetDigitalActionOrigins steaminput\n"); - return 0; -} - -// Lookup the handle for an analog action. Best to do this once on startup, and store the handles for all future API calls. -ControllerAnalogActionHandle_t GetAnalogActionHandle( const char *pszActionName ) -{ - PRINT_DEBUG("GetAnalogActionHandle %s\n", pszActionName); - return 125; -} - - -// Returns the current state of these supplied analog game action -ControllerAnalogActionData_t GetAnalogActionData( ControllerHandle_t controllerHandle, ControllerAnalogActionHandle_t analogActionHandle ) -{ - PRINT_DEBUG("GetAnalogActionData\n"); - ControllerAnalogActionData_t data; - data.eMode = k_EInputSourceMode_None; - data.x = data.y = 0; - data.bActive = false; - return data; -} - - -// Get the origin(s) for an analog action within an action set. Returns the number of origins supplied in originsOut. Use this to display the appropriate on-screen prompt for the action. -// originsOut should point to a STEAM_CONTROLLER_MAX_ORIGINS sized array of EControllerActionOrigin handles -int GetAnalogActionOrigins( ControllerHandle_t controllerHandle, ControllerActionSetHandle_t actionSetHandle, ControllerAnalogActionHandle_t analogActionHandle, EControllerActionOrigin *originsOut ) -{ - PRINT_DEBUG("GetAnalogActionOrigins\n"); - return 0; -} - -int GetAnalogActionOrigins( InputHandle_t inputHandle, InputActionSetHandle_t actionSetHandle, InputAnalogActionHandle_t analogActionHandle, EInputActionOrigin *originsOut ) -{ - PRINT_DEBUG("GetAnalogActionOrigins steaminput\n"); - return 0; -} - - -void StopAnalogActionMomentum( ControllerHandle_t controllerHandle, ControllerAnalogActionHandle_t eAction ) -{ - PRINT_DEBUG("StopAnalogActionMomentum\n"); -} - - -// Trigger a haptic pulse on a controller -void TriggerHapticPulse( ControllerHandle_t controllerHandle, ESteamControllerPad eTargetPad, unsigned short usDurationMicroSec ) -{ - PRINT_DEBUG("TriggerHapticPulse\n"); -} - -void TriggerHapticPulse( uint32 unControllerIndex, ESteamControllerPad eTargetPad, unsigned short usDurationMicroSec ) -{ - PRINT_DEBUG("TriggerHapticPulse old\n"); - TriggerHapticPulse(unControllerIndex, eTargetPad, usDurationMicroSec ); -} - -// Trigger a pulse with a duty cycle of usDurationMicroSec / usOffMicroSec, unRepeat times. -// nFlags is currently unused and reserved for future use. -void TriggerRepeatedHapticPulse( ControllerHandle_t controllerHandle, ESteamControllerPad eTargetPad, unsigned short usDurationMicroSec, unsigned short usOffMicroSec, unsigned short unRepeat, unsigned int nFlags ) -{ - PRINT_DEBUG("TriggerRepeatedHapticPulse\n"); -} - - -// Tigger a vibration event on supported controllers. -void TriggerVibration( ControllerHandle_t controllerHandle, unsigned short usLeftSpeed, unsigned short usRightSpeed ) -{ - PRINT_DEBUG("TriggerVibration\n"); -} - - -// Set the controller LED color on supported controllers. -void SetLEDColor( ControllerHandle_t controllerHandle, uint8 nColorR, uint8 nColorG, uint8 nColorB, unsigned int nFlags ) -{ - PRINT_DEBUG("SetLEDColor\n"); -} - - -// Returns the associated gamepad index for the specified controller, if emulating a gamepad -int GetGamepadIndexForController( ControllerHandle_t ulControllerHandle ) -{ - PRINT_DEBUG("GetGamepadIndexForController\n"); - return 0; -} - - -// Returns the associated controller handle for the specified emulated gamepad -ControllerHandle_t GetControllerForGamepadIndex( int nIndex ) -{ - PRINT_DEBUG("GetControllerForGamepadIndex\n"); - return 0; -} - - -// Returns raw motion data from the specified controller -ControllerMotionData_t GetMotionData( ControllerHandle_t controllerHandle ) -{ - PRINT_DEBUG("GetMotionData\n"); - ControllerMotionData_t data = {}; - return data; -} - - -// Attempt to display origins of given action in the controller HUD, for the currently active action set -// Returns false is overlay is disabled / unavailable, or the user is not in Big Picture mode -bool ShowDigitalActionOrigins( ControllerHandle_t controllerHandle, ControllerDigitalActionHandle_t digitalActionHandle, float flScale, float flXPosition, float flYPosition ) -{ - PRINT_DEBUG("ShowDigitalActionOrigins\n"); - return true; -} - -bool ShowAnalogActionOrigins( ControllerHandle_t controllerHandle, ControllerAnalogActionHandle_t analogActionHandle, float flScale, float flXPosition, float flYPosition ) -{ - PRINT_DEBUG("ShowAnalogActionOrigins\n"); - return true; -} - - -// Returns a localized string (from Steam's language setting) for the specified origin -const char *GetStringForActionOrigin( EControllerActionOrigin eOrigin ) -{ - PRINT_DEBUG("GetStringForActionOrigin\n"); - return "Button String"; -} - -const char *GetStringForActionOrigin( EInputActionOrigin eOrigin ) -{ - PRINT_DEBUG("GetStringForActionOrigin steaminput\n"); - return "Button String"; -} - - -// Get a local path to art for on-screen glyph for a particular origin -const char *GetGlyphForActionOrigin( EControllerActionOrigin eOrigin ) -{ - PRINT_DEBUG("GetGlyphForActionOrigin\n"); - return ""; -} - -const char *GetGlyphForActionOrigin( EInputActionOrigin eOrigin ) -{ - PRINT_DEBUG("GetGlyphForActionOrigin steaminput\n"); - return ""; -} - -// Returns the input type for a particular handle -ESteamInputType GetInputTypeForHandle( ControllerHandle_t controllerHandle ) -{ - PRINT_DEBUG("GetInputTypeForHandle\n"); - return k_ESteamInputType_Unknown; -} - -const char *GetStringForXboxOrigin( EXboxOrigin eOrigin ) -{ - PRINT_DEBUG("GetStringForXboxOrigin\n"); - return ""; -} - -const char *GetGlyphForXboxOrigin( EXboxOrigin eOrigin ) -{ - PRINT_DEBUG("GetGlyphForXboxOrigin\n"); - return ""; -} - -EControllerActionOrigin GetActionOriginFromXboxOrigin_( ControllerHandle_t controllerHandle, EXboxOrigin eOrigin ) -{ - PRINT_DEBUG("GetActionOriginFromXboxOrigin\n"); - return k_EControllerActionOrigin_None; -} - -EInputActionOrigin GetActionOriginFromXboxOrigin( InputHandle_t inputHandle, EXboxOrigin eOrigin ) -{ - PRINT_DEBUG("GetActionOriginFromXboxOrigin steaminput\n"); - return k_EInputActionOrigin_None; -} - -EControllerActionOrigin TranslateActionOrigin( ESteamInputType eDestinationInputType, EControllerActionOrigin eSourceOrigin ) -{ - PRINT_DEBUG("TranslateActionOrigin\n"); - return k_EControllerActionOrigin_None; -} - -EInputActionOrigin TranslateActionOrigin( ESteamInputType eDestinationInputType, EInputActionOrigin eSourceOrigin ) -{ - PRINT_DEBUG("TranslateActionOrigin steaminput\n"); - return k_EInputActionOrigin_None; -} - -bool GetControllerBindingRevision( ControllerHandle_t controllerHandle, int *pMajor, int *pMinor ) -{ - PRINT_DEBUG("GetControllerBindingRevision\n"); - return false; -} - -bool GetDeviceBindingRevision( InputHandle_t inputHandle, int *pMajor, int *pMinor ) -{ - PRINT_DEBUG("GetDeviceBindingRevision\n"); - return false; -} - -uint32 GetRemotePlaySessionID( InputHandle_t inputHandle ) -{ - PRINT_DEBUG("GetRemotePlaySessionID\n"); - return 0; -} - -}; From 1648c1424304fac7a40e0581773d608e4bb1e446 Mon Sep 17 00:00:00 2001 From: Mr_Goldberg Date: Tue, 16 Feb 2021 12:30:24 -0500 Subject: [PATCH 12/20] Fixed issue with game treating bool return values as an int. --- dll/dll.cpp | 8 ++++---- sdk_includes/steam_api.h | 4 ++-- sdk_includes/steamtypes.h | 6 ++++++ 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/dll/dll.cpp b/dll/dll.cpp index b022c3b..be5587a 100644 --- a/dll/dll.cpp +++ b/dll/dll.cpp @@ -769,7 +769,7 @@ STEAMAPI_API void S_CALLTYPE SteamAPI_ManualDispatch_RunFrame( HSteamPipe hSteam /// Fetch the next pending callback on the given pipe, if any. If a callback is available, true is returned /// and the structure is populated. In this case, you MUST call SteamAPI_ManualDispatch_FreeLastCallback /// (after dispatching the callback) before calling SteamAPI_ManualDispatch_GetNextCallback again. -STEAMAPI_API bool S_CALLTYPE SteamAPI_ManualDispatch_GetNextCallback( HSteamPipe hSteamPipe, CallbackMsg_t *pCallbackMsg ) +STEAMAPI_API steam_bool S_CALLTYPE SteamAPI_ManualDispatch_GetNextCallback( HSteamPipe hSteamPipe, CallbackMsg_t *pCallbackMsg ) { PRINT_DEBUG("%s\n", __FUNCTION__); std::queue *q = NULL; @@ -829,7 +829,7 @@ STEAMAPI_API void S_CALLTYPE SteamAPI_ManualDispatch_FreeLastCallback( HSteamPip /// Return the call result for the specified call on the specified pipe. You really should /// only call this in a handler for SteamAPICallCompleted_t callback. -STEAMAPI_API bool S_CALLTYPE SteamAPI_ManualDispatch_GetAPICallResult( HSteamPipe hSteamPipe, SteamAPICall_t hSteamAPICall, void *pCallback, int cubCallback, int iCallbackExpected, bool *pbFailed ) +STEAMAPI_API steam_bool S_CALLTYPE SteamAPI_ManualDispatch_GetAPICallResult( HSteamPipe hSteamPipe, SteamAPICall_t hSteamAPICall, void *pCallback, int cubCallback, int iCallbackExpected, bool *pbFailed ) { PRINT_DEBUG("SteamAPI_ManualDispatch_GetAPICallResult %i %llu %i %i\n", hSteamPipe, hSteamAPICall, cubCallback, iCallbackExpected); Steam_Client *steam_client = get_steam_client(); @@ -961,7 +961,7 @@ SteamMasterServerUpdater */ -STEAMCLIENT_API bool Steam_BGetCallback( HSteamPipe hSteamPipe, CallbackMsg_t *pCallbackMsg ) +STEAMCLIENT_API steam_bool Steam_BGetCallback( HSteamPipe hSteamPipe, CallbackMsg_t *pCallbackMsg ) { PRINT_DEBUG("%s %i\n", __FUNCTION__, hSteamPipe); SteamAPI_ManualDispatch_Init(); @@ -976,7 +976,7 @@ STEAMCLIENT_API void Steam_FreeLastCallback( HSteamPipe hSteamPipe ) SteamAPI_ManualDispatch_FreeLastCallback( hSteamPipe ); } -STEAMCLIENT_API bool Steam_GetAPICallResult( HSteamPipe hSteamPipe, SteamAPICall_t hSteamAPICall, void* pCallback, int cubCallback, int iCallbackExpected, bool* pbFailed ) +STEAMCLIENT_API steam_bool Steam_GetAPICallResult( HSteamPipe hSteamPipe, SteamAPICall_t hSteamAPICall, void* pCallback, int cubCallback, int iCallbackExpected, bool* pbFailed ) { PRINT_DEBUG("Steam_GetAPICallResult %i %llu %i %i\n", hSteamPipe, hSteamAPICall, cubCallback, iCallbackExpected); return SteamAPI_ManualDispatch_GetAPICallResult(hSteamPipe, hSteamAPICall, pCallback, cubCallback, iCallbackExpected, pbFailed); diff --git a/sdk_includes/steam_api.h b/sdk_includes/steam_api.h index 8829141..380436b 100644 --- a/sdk_includes/steam_api.h +++ b/sdk_includes/steam_api.h @@ -311,14 +311,14 @@ S_API void S_CALLTYPE SteamAPI_ManualDispatch_RunFrame( HSteamPipe hSteamPipe ); /// Fetch the next pending callback on the given pipe, if any. If a callback is available, true is returned /// and the structure is populated. In this case, you MUST call SteamAPI_ManualDispatch_FreeLastCallback /// (after dispatching the callback) before calling SteamAPI_ManualDispatch_GetNextCallback again. -S_API bool S_CALLTYPE SteamAPI_ManualDispatch_GetNextCallback( HSteamPipe hSteamPipe, CallbackMsg_t *pCallbackMsg ); +S_API steam_bool S_CALLTYPE SteamAPI_ManualDispatch_GetNextCallback( HSteamPipe hSteamPipe, CallbackMsg_t *pCallbackMsg ); /// You must call this after dispatching the callback, if SteamAPI_ManualDispatch_GetNextCallback returns true. S_API void S_CALLTYPE SteamAPI_ManualDispatch_FreeLastCallback( HSteamPipe hSteamPipe ); /// Return the call result for the specified call on the specified pipe. You really should /// only call this in a handler for SteamAPICallCompleted_t callback. -S_API bool S_CALLTYPE SteamAPI_ManualDispatch_GetAPICallResult( HSteamPipe hSteamPipe, SteamAPICall_t hSteamAPICall, void *pCallback, int cubCallback, int iCallbackExpected, bool *pbFailed ); +S_API steam_bool S_CALLTYPE SteamAPI_ManualDispatch_GetAPICallResult( HSteamPipe hSteamPipe, SteamAPICall_t hSteamAPICall, void *pCallback, int cubCallback, int iCallbackExpected, bool *pbFailed ); //----------------------------------------------------------------------------------------------------------------------------------------------------------// // diff --git a/sdk_includes/steamtypes.h b/sdk_includes/steamtypes.h index fd2674a..b3440ee 100644 --- a/sdk_includes/steamtypes.h +++ b/sdk_includes/steamtypes.h @@ -10,6 +10,12 @@ #pragma once #endif +/* +for some dumb reason some games like carrion think a bool is an int and use the whole register as a return value +instead of using just al like a normal program. +*/ +typedef unsigned steam_bool; + #define S_CALLTYPE __cdecl // Steam-specific types. Defined here so this header file can be included in other code bases. From 990a0eb71f7d8153001d61112b9fea6d14e18f87 Mon Sep 17 00:00:00 2001 From: Mr_Goldberg Date: Tue, 16 Feb 2021 12:32:22 -0500 Subject: [PATCH 13/20] Steam networking messages implementation. --- dll/net.proto | 15 ++ dll/network.cpp | 5 + dll/network.h | 1 + dll/steam_networking_messages.h | 259 +++++++++++++++++++++++++++++++- 4 files changed, 275 insertions(+), 5 deletions(-) diff --git a/dll/net.proto b/dll/net.proto index 5b0f627..aaa2bef 100644 --- a/dll/net.proto +++ b/dll/net.proto @@ -125,6 +125,20 @@ message Networking_Sockets { bytes data = 5; } +message Networking_Messages { + enum Types { + CONNECTION_NEW = 0; + CONNECTION_ACCEPT = 1; + CONNECTION_END = 2; + DATA = 3; + } + + Types type = 1; + uint32 channel = 2; + uint32 id_from = 3; + bytes data = 5; +} + message Gameserver { uint64 id = 1; bytes game_description = 2; @@ -212,6 +226,7 @@ message Common_Message { Network_Old network_old = 12; Networking_Sockets networking_sockets = 13; Steam_Messages steam_messages = 14; + Networking_Messages networking_messages = 15; } uint32 source_ip = 128; diff --git a/dll/network.cpp b/dll/network.cpp index 2de7de3..e7c5b2d 100644 --- a/dll/network.cpp +++ b/dll/network.cpp @@ -554,6 +554,11 @@ void Networking::do_callbacks_message(Common_Message *msg) PRINT_DEBUG("has_steam_messages\n"); run_callbacks(CALLBACK_ID_STEAM_MESSAGES, msg); } + + if (msg->has_networking_messages()) { + PRINT_DEBUG("has_networking_messages\n"); + run_callbacks(CALLBACK_ID_NETWORKING_MESSAGES, msg); + } } bool Networking::handle_tcp(Common_Message *msg, struct TCP_Socket &socket) diff --git a/dll/network.h b/dll/network.h index 015115c..5bb3e62 100644 --- a/dll/network.h +++ b/dll/network.h @@ -56,6 +56,7 @@ enum Callback_Ids { CALLBACK_ID_FRIEND_MESSAGES, CALLBACK_ID_NETWORKING_SOCKETS, CALLBACK_ID_STEAM_MESSAGES, + CALLBACK_ID_NETWORKING_MESSAGES, CALLBACK_IDS_MAX }; diff --git a/dll/steam_networking_messages.h b/dll/steam_networking_messages.h index deadca5..7d5471b 100644 --- a/dll/steam_networking_messages.h +++ b/dll/steam_networking_messages.h @@ -17,6 +17,22 @@ #include "base.h" +#define NETWORKING_MESSAGES_TIMEOUT 30.0 + +struct Steam_Message_Connection { + SteamNetworkingIdentity remote_identity; + std::map> data; + + std::list channels; + bool accepted = false; + bool dead = false; + + unsigned id; + unsigned remote_id = 0; + + std::chrono::high_resolution_clock::time_point created = std::chrono::high_resolution_clock::now(); +}; + class Steam_Networking_Messages : public ISteamNetworkingMessages { @@ -26,7 +42,13 @@ public ISteamNetworkingMessages class SteamCallBacks *callbacks; class RunEveryRunCB *run_every_runcb; + std::map connections; + std::list incoming_data; + + unsigned id_counter = 0; + std::chrono::steady_clock::time_point created; public: + static void steam_callback(void *object, Common_Message *msg) { PRINT_DEBUG("steam_networking_messages_callback\n"); @@ -48,11 +70,14 @@ Steam_Networking_Messages(class Settings *settings, class Networking *network, c this->settings = settings; this->network = network; this->run_every_runcb = run_every_runcb; + this->network->setCallback(CALLBACK_ID_NETWORKING_MESSAGES, settings->get_local_steam_id(), &Steam_Networking_Messages::steam_callback, this); this->network->setCallback(CALLBACK_ID_USER_STATUS, settings->get_local_steam_id(), &Steam_Networking_Messages::steam_callback, this); this->run_every_runcb->add(&Steam_Networking_Messages::steam_run_every_runcb, this); this->callback_results = callback_results; this->callbacks = callbacks; + + this->created = std::chrono::steady_clock::now(); } ~Steam_Networking_Messages() @@ -61,6 +86,45 @@ Steam_Networking_Messages(class Settings *settings, class Networking *network, c this->run_every_runcb->remove(&Steam_Networking_Messages::steam_run_every_runcb, this); } +std::map::iterator find_or_create_message_connection(SteamNetworkingIdentity identityRemote, bool incoming, bool restartbroken) +{ + auto conn = connections.find(identityRemote.GetSteamID()); + if (conn == connections.end() || (conn->second.dead && restartbroken)) { + ++id_counter; + struct Steam_Message_Connection con; + con.remote_identity = identityRemote; + con.id = id_counter; + connections[identityRemote.GetSteamID()] = con; + + Common_Message msg; + msg.set_source_id(settings->get_local_steam_id().ConvertToUint64()); + msg.set_dest_id(con.remote_identity.GetSteamID64()); + msg.set_allocated_networking_messages(new Networking_Messages); + if (incoming) { + msg.mutable_networking_messages()->set_type(Networking_Messages::CONNECTION_ACCEPT); + } else { + msg.mutable_networking_messages()->set_type(Networking_Messages::CONNECTION_NEW); + } + msg.mutable_networking_messages()->set_channel(0); + msg.mutable_networking_messages()->set_id_from(con.id); + network->sendTo(&msg, true); + + conn = connections.find(identityRemote.GetSteamID()); + + if (incoming) { + SteamNetworkingMessagesSessionRequest_t data; + data.m_identityRemote = con.remote_identity; + callbacks->addCBResult(data.k_iCallback, &data, sizeof(data)); + } + } + + if (!incoming) { + conn->second.accepted = true; + } + + return conn; +} + /// Sends a message to the specified host. If we don't already have a session with that user, /// a session is implicitly created. There might be some handshaking that needs to happen /// before we can actually begin sending message data. If this handshaking fails and we can't @@ -106,7 +170,57 @@ Steam_Networking_Messages(class Settings *settings, class Networking *network, c EResult SendMessageToUser( const SteamNetworkingIdentity &identityRemote, const void *pubData, uint32 cubData, int nSendFlags, int nRemoteChannel ) { PRINT_DEBUG("Steam_Networking_Messages::SendMessageToUser\n"); - return k_EResultNoConnection; + std::lock_guard lock(global_mutex); + const SteamNetworkingIPAddr *ip = identityRemote.GetIPAddr(); + bool reliable = false; + if (nSendFlags & k_nSteamNetworkingSend_Reliable) { + reliable = true; + } + + bool restart_broken = false; + if (nSendFlags & k_nSteamNetworkingSend_AutoRestartBrokenSession) { + restart_broken = true; + } + + if (identityRemote.m_eType == k_ESteamNetworkingIdentityType_SteamID) { + PRINT_DEBUG("Steam_Networking_Messages::SendMessageToUser %llu\n", identityRemote.GetSteamID64()); + //steam id identity + } else if (ip) { + PRINT_DEBUG("Steam_Networking_Messages::SendMessageToUser %u:%u ipv4? %u\n", ip->GetIPv4(), ip->m_port, ip->IsIPv4()); + //ip addr + return k_EResultNoConnection; //TODO + } else { + return k_EResultNoConnection; + } + + auto conn = find_or_create_message_connection(identityRemote, false, restart_broken); + if (conn->second.dead) { + return k_EResultNoConnection; + } + + Common_Message msg; + msg.set_source_id(settings->get_local_steam_id().ConvertToUint64()); + msg.set_dest_id(conn->second.remote_identity.GetSteamID64()); + msg.set_allocated_networking_messages(new Networking_Messages); + msg.mutable_networking_messages()->set_type(Networking_Messages::DATA); + msg.mutable_networking_messages()->set_channel(nRemoteChannel); + msg.mutable_networking_messages()->set_id_from(conn->second.id); + msg.mutable_networking_messages()->set_data(pubData, cubData); + + network->sendTo(&msg, reliable); + return k_EResultOK; +} + +static void free_steam_message_data(SteamNetworkingMessage_t *pMsg) +{ + free(pMsg->m_pData); + pMsg->m_pData = NULL; +} + +static void delete_steam_message(SteamNetworkingMessage_t *pMsg) +{ + if (pMsg->m_pfnFreeData) pMsg->m_pfnFreeData(pMsg); + delete pMsg; } /// Reads the next message that has been sent from another user via SendMessageToUser() on the given channel. @@ -116,7 +230,42 @@ EResult SendMessageToUser( const SteamNetworkingIdentity &identityRemote, const int ReceiveMessagesOnChannel( int nLocalChannel, SteamNetworkingMessage_t **ppOutMessages, int nMaxMessages ) { PRINT_DEBUG("Steam_Networking_Messages::ReceiveMessagesOnChannel\n"); - return 0; + std::lock_guard lock(global_mutex); + int message_counter = 0; + + for (auto & conn : connections) { + auto chan = conn.second.data.find(nLocalChannel); + if (chan != conn.second.data.end()) { + while (!chan->second.empty() && message_counter <= nMaxMessages) { + SteamNetworkingMessage_t *pMsg = new SteamNetworkingMessage_t(); //TODO size is wrong + unsigned long size = chan->second.front().size(); + pMsg->m_pData = malloc(size); + pMsg->m_cbSize = size; + memcpy(pMsg->m_pData, chan->second.front().data(), size); + pMsg->m_conn = conn.second.id; + pMsg->m_identityPeer = conn.second.remote_identity; + pMsg->m_nConnUserData = -1; + pMsg->m_usecTimeReceived = std::chrono::duration_cast(std::chrono::steady_clock::now() - created).count(); + //TODO: messagenumber? + // pMsg->m_nMessageNumber = connect_socket->second.packet_receive_counter; + // ++connect_socket->second.packet_receive_counter; + + pMsg->m_pfnFreeData = &free_steam_message_data; + pMsg->m_pfnRelease = &delete_steam_message; + pMsg->m_nChannel = nLocalChannel; + ppOutMessages[message_counter] = pMsg; + ++message_counter; + chan->second.pop(); + } + } + + if (message_counter >= nMaxMessages) { + break; + } + } + + PRINT_DEBUG("Steam_Networking_Messages::ReceiveMessagesOnChannel got %u\n", message_counter); + return message_counter; } /// AcceptSessionWithUser() should only be called in response to a SteamP2PSessionRequest_t callback @@ -129,7 +278,14 @@ int ReceiveMessagesOnChannel( int nLocalChannel, SteamNetworkingMessage_t **ppOu bool AcceptSessionWithUser( const SteamNetworkingIdentity &identityRemote ) { PRINT_DEBUG("Steam_Networking_Messages::AcceptSessionWithUser\n"); - return false; + std::lock_guard lock(global_mutex); + auto conn = connections.find(identityRemote.GetSteamID()); + if (conn == connections.end()) { + return false; + } + + conn->second.accepted = true; + return true; } /// Call this when you're done talking to a user to immediately free up resources under-the-hood. @@ -140,7 +296,23 @@ bool AcceptSessionWithUser( const SteamNetworkingIdentity &identityRemote ) bool CloseSessionWithUser( const SteamNetworkingIdentity &identityRemote ) { PRINT_DEBUG("Steam_Networking_Messages::CloseSessionWithUser\n"); - return false; + std::lock_guard lock(global_mutex); + auto conn = connections.find(identityRemote.GetSteamID()); + if (conn == connections.end()) { + return false; + } + + Common_Message msg; + msg.set_source_id(settings->get_local_steam_id().ConvertToUint64()); + msg.set_dest_id(conn->second.remote_identity.GetSteamID64()); + msg.set_allocated_networking_messages(new Networking_Messages); + msg.mutable_networking_messages()->set_type(Networking_Messages::CONNECTION_END); + msg.mutable_networking_messages()->set_channel(0); + msg.mutable_networking_messages()->set_id_from(conn->second.id); + network->sendTo(&msg, true); + + connections.erase(conn); + return true; } /// Call this when you're done talking to a user on a specific channel. Once all @@ -150,6 +322,7 @@ bool CloseSessionWithUser( const SteamNetworkingIdentity &identityRemote ) bool CloseChannelWithUser( const SteamNetworkingIdentity &identityRemote, int nLocalChannel ) { PRINT_DEBUG("Steam_Networking_Messages::CloseChannelWithUser\n"); + std::lock_guard lock(global_mutex); return false; } @@ -165,12 +338,62 @@ bool CloseChannelWithUser( const SteamNetworkingIdentity &identityRemote, int nL ESteamNetworkingConnectionState GetSessionConnectionInfo( const SteamNetworkingIdentity &identityRemote, SteamNetConnectionInfo_t *pConnectionInfo, SteamNetworkingQuickConnectionStatus *pQuickStatus ) { PRINT_DEBUG("Steam_Networking_Messages::GetSessionConnectionInfo\n"); - return k_ESteamNetworkingConnectionState_None; + std::lock_guard lock(global_mutex); + auto conn = connections.find(identityRemote.GetSteamID()); + if (conn == connections.end()) { + return k_ESteamNetworkingConnectionState_None; + } + + if (pConnectionInfo) { + //TODO + } + + if (pQuickStatus) { + //TODO + } + + if (conn->second.remote_id == 0 || !conn->second.accepted) { + return k_ESteamNetworkingConnectionState_Connecting; + } + + if (conn->second.dead) { + return k_ESteamNetworkingConnectionState_ClosedByPeer; + } + + return k_ESteamNetworkingConnectionState_Connected; } +void end_connection(CSteamID steam_id) +{ + auto conn = connections.find(steam_id); + if (conn != connections.end()) { + conn->second.dead = true; + } +} void RunCallbacks() { + auto msg = std::begin(incoming_data); + while (msg != std::end(incoming_data)) { + CSteamID source_id((uint64)msg->source_id()); + + auto conn = connections.find(source_id); + if (conn != connections.end()) { + if (conn->second.remote_id == msg->networking_messages().id_from()) + conn->second.data[msg->networking_messages().channel()].push(msg->networking_messages().data()); + } + + msg = incoming_data.erase(msg); + } + + auto conn = std::begin(connections); + while (conn != std::end(connections)) { + if (!conn->second.accepted && check_timedout(conn->second.created, NETWORKING_MESSAGES_TIMEOUT)) { + conn = connections.erase(conn); + } else { + ++conn; + } + } } void Callback(Common_Message *msg) @@ -181,7 +404,33 @@ void Callback(Common_Message *msg) } if (msg->low_level().type() == Low_Level::DISCONNECT) { + end_connection((uint64)msg->source_id()); + } + } + if (msg->has_networking_messages()) { + PRINT_DEBUG("Steam_Networking_Messages: got network socket msg %u\n", msg->networking_messages().type()); + if (msg->networking_messages().type() == Networking_Messages::CONNECTION_NEW) { + SteamNetworkingIdentity identity; + identity.SetSteamID64(msg->source_id()); + auto conn = find_or_create_message_connection(identity, true, false); + conn->second.remote_id = msg->networking_messages().id_from(); + conn->second.dead = false; + } + + if (msg->networking_messages().type() == Networking_Messages::CONNECTION_ACCEPT) { + auto conn = connections.find((uint64)msg->source_id()); + if (conn != connections.end()) { + conn->second.remote_id = msg->networking_messages().id_from(); + } + } + + if (msg->networking_messages().type() == Networking_Messages::CONNECTION_END) { + end_connection((uint64)msg->source_id()); + } + + if (msg->networking_messages().type() == Networking_Messages::DATA) { + incoming_data.push_back(Common_Message(*msg)); } } } From 8e1be658e9c097924a064f40babc7a26a3fc16e5 Mon Sep 17 00:00:00 2001 From: Mr_Goldberg Date: Sun, 21 Feb 2021 11:13:43 -0500 Subject: [PATCH 14/20] Networking messages improvements. --- dll/steam_networking_messages.h | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/dll/steam_networking_messages.h b/dll/steam_networking_messages.h index 7d5471b..d27d396 100644 --- a/dll/steam_networking_messages.h +++ b/dll/steam_networking_messages.h @@ -236,7 +236,7 @@ int ReceiveMessagesOnChannel( int nLocalChannel, SteamNetworkingMessage_t **ppOu for (auto & conn : connections) { auto chan = conn.second.data.find(nLocalChannel); if (chan != conn.second.data.end()) { - while (!chan->second.empty() && message_counter <= nMaxMessages) { + while (!chan->second.empty() && message_counter < nMaxMessages) { SteamNetworkingMessage_t *pMsg = new SteamNetworkingMessage_t(); //TODO size is wrong unsigned long size = chan->second.front().size(); pMsg->m_pData = malloc(size); @@ -323,6 +323,7 @@ bool CloseChannelWithUser( const SteamNetworkingIdentity &identityRemote, int nL { PRINT_DEBUG("Steam_Networking_Messages::CloseChannelWithUser\n"); std::lock_guard lock(global_mutex); + //TODO return false; } @@ -344,22 +345,29 @@ ESteamNetworkingConnectionState GetSessionConnectionInfo( const SteamNetworkingI return k_ESteamNetworkingConnectionState_None; } + ESteamNetworkingConnectionState state = k_ESteamNetworkingConnectionState_Connected; + if (conn->second.remote_id == 0 || !conn->second.accepted) { + state = k_ESteamNetworkingConnectionState_Connecting; + } else if (conn->second.dead) { + state = k_ESteamNetworkingConnectionState_ClosedByPeer; + } + if (pConnectionInfo) { + memset(pConnectionInfo, 0, sizeof(SteamNetConnectionInfo_t)); + pConnectionInfo->m_eState = state; + pConnectionInfo->m_identityRemote = conn->second.remote_identity; //TODO } if (pQuickStatus) { + memset(pQuickStatus, 0, sizeof(SteamNetworkingQuickConnectionStatus)); + pQuickStatus->m_eState = state; + pQuickStatus->m_nPing = 10; //TODO: calculate real numbers? + pQuickStatus->m_flConnectionQualityLocal = 1.0; + pQuickStatus->m_flConnectionQualityRemote = 1.0; //TODO } - if (conn->second.remote_id == 0 || !conn->second.accepted) { - return k_ESteamNetworkingConnectionState_Connecting; - } - - if (conn->second.dead) { - return k_ESteamNetworkingConnectionState_ClosedByPeer; - } - return k_ESteamNetworkingConnectionState_Connected; } From 8e9d3e8f3a482f5524e74895f75a49e2f970beab Mon Sep 17 00:00:00 2001 From: Mr_Goldberg Date: Sat, 27 Feb 2021 16:28:59 -0500 Subject: [PATCH 15/20] Add force_listen_port.txt --- Readme_release.txt | 2 +- dll/settings_parser.cpp | 4 ++++ .../steam_settings.EXAMPLE/force_listen_port.EXAMPLE.txt | 1 + 3 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 files_example/steam_settings.EXAMPLE/force_listen_port.EXAMPLE.txt diff --git a/Readme_release.txt b/Readme_release.txt index 37b6926..6092603 100644 --- a/Readme_release.txt +++ b/Readme_release.txt @@ -29,7 +29,7 @@ Note that these are global so you won't have to change them for each game. For g If you want to change your steam_id on a per game basis, simply create a settings folder in the game unique directory (Full path: C:\Users\\AppData\Roaming\Goldberg SteamEmu Saves\\settings) In that settings folder create a user_steam_id.txt file that contains the valid steam id that you want to use for that game only. -You can also make the emu ignore certain global settings by using a force_account_name.txt, force_language.txt or force_steamid.txt that you put in the \steam_settings\ folder. +You can also make the emu ignore certain global settings by using a force_account_name.txt, force_language.txt, force_listen_port.txt or force_steamid.txt that you put in the \steam_settings\ folder. See the steam_settings.EXAMPLE folder for an example. If for some reason you want it to save in the game directory you can create a file named local_save.txt right beside steam_api(64).dll (libsteam_api.so on linux) diff --git a/dll/settings_parser.cpp b/dll/settings_parser.cpp index 67bfb8a..78df6c6 100644 --- a/dll/settings_parser.cpp +++ b/dll/settings_parser.cpp @@ -286,6 +286,10 @@ uint32 create_localstorage_settings(Settings **settings_client_out, Settings **s } else if (p == "force_account_name.txt") { int len = Local_Storage::get_file_data(steam_settings_path + "force_account_name.txt", name, sizeof(name) - 1); if (len > 0) name[len] = 0; + } else if (p == "force_listen_port.txt") { + char array_port[10] = {}; + int len = Local_Storage::get_file_data(steam_settings_path + "force_listen_port.txt", array_port, sizeof(array_port) - 1); + if (len > 0) port = std::stoi(array_port); } } } diff --git a/files_example/steam_settings.EXAMPLE/force_listen_port.EXAMPLE.txt b/files_example/steam_settings.EXAMPLE/force_listen_port.EXAMPLE.txt new file mode 100644 index 0000000..4c00d53 --- /dev/null +++ b/files_example/steam_settings.EXAMPLE/force_listen_port.EXAMPLE.txt @@ -0,0 +1 @@ +47584 \ No newline at end of file From 58a57cc91b93f1b55e1aa409540604396e057bd9 Mon Sep 17 00:00:00 2001 From: Mr_Goldberg Date: Sat, 27 Feb 2021 16:29:40 -0500 Subject: [PATCH 16/20] Fix coding mistake in networking socket receive functions. --- dll/steam_networking_sockets.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dll/steam_networking_sockets.h b/dll/steam_networking_sockets.h index 82acd51..0ecd271 100644 --- a/dll/steam_networking_sockets.h +++ b/dll/steam_networking_sockets.h @@ -793,7 +793,7 @@ int ReceiveMessagesOnConnection( HSteamNetConnection hConn, SteamNetworkingMessa std::lock_guard lock(global_mutex); SteamNetworkingMessage_t *msg = NULL; int messages = 0; - while ((msg = get_steam_message_connection(hConn)) && messages < nMaxMessages) { + while (messages < nMaxMessages && (msg = get_steam_message_connection(hConn))) { ppOutMessages[messages] = msg; ++messages; } @@ -821,7 +821,7 @@ int ReceiveMessagesOnListenSocket( HSteamListenSocket hSocket, SteamNetworkingMe auto socket_conn = std::begin(connect_sockets); while (socket_conn != std::end(connect_sockets) && messages < nMaxMessages) { if (socket_conn->second.listen_socket_id == hSocket) { - while ((msg = get_steam_message_connection(socket_conn->first)) && messages < nMaxMessages) { + while (messages < nMaxMessages && (msg = get_steam_message_connection(socket_conn->first))) { ppOutMessages[messages] = msg; ++messages; } @@ -1197,7 +1197,7 @@ int ReceiveMessagesOnPollGroup( HSteamNetPollGroup hPollGroup, SteamNetworkingMe int messages = 0; for (auto c : group->second) { - while ((msg = get_steam_message_connection(c)) && messages < nMaxMessages) { + while (messages < nMaxMessages && (msg = get_steam_message_connection(c))) { ppOutMessages[messages] = msg; ++messages; } From 992e5c3faabb2616f3039c4f0301552da89a4fb6 Mon Sep 17 00:00:00 2001 From: Mr_Goldberg Date: Sun, 28 Feb 2021 19:26:29 -0500 Subject: [PATCH 17/20] Properly initialize user_achievements so functions like getachievementandunlocktime work properly. --- dll/steam_user_stats.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/dll/steam_user_stats.h b/dll/steam_user_stats.h index 8766980..ddfb14e 100644 --- a/dll/steam_user_stats.h +++ b/dll/steam_user_stats.h @@ -94,6 +94,16 @@ Steam_User_Stats(Settings *settings, Local_Storage *local_storage, class SteamCa { load_achievements_db(); // achievements db load_achievements(); // achievements per user + + for (auto & it : defined_achievements) { + try { + std::string name = static_cast(it["name"]); + if (user_achievements.find(name) == user_achievements.end()) { + user_achievements[name]["earned"] = false; + user_achievements[name]["earned_time"] = static_cast(0); + } + } catch (...) {} + } } // Ask the server to send down this user's data and achievements for this game From 8785ae568c82680791b391d32d322016c40b3311 Mon Sep 17 00:00:00 2001 From: Mr_Goldberg Date: Sun, 7 Mar 2021 19:03:24 -0500 Subject: [PATCH 18/20] Allow "hidden" achievement property to be an int in the json config. --- dll/steam_user_stats.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dll/steam_user_stats.h b/dll/steam_user_stats.h index ddfb14e..7de7923 100644 --- a/dll/steam_user_stats.h +++ b/dll/steam_user_stats.h @@ -103,6 +103,10 @@ Steam_User_Stats(Settings *settings, Local_Storage *local_storage, class SteamCa user_achievements[name]["earned_time"] = static_cast(0); } } catch (...) {} + + try { + it["hidden"] = std::to_string(it["hidden"].get()); + } catch (...) {} } } From 3f06dd85760ffb4ba4683143aec2ca19a3b54a5e Mon Sep 17 00:00:00 2001 From: Mr_Goldberg Date: Sun, 7 Mar 2021 19:04:01 -0500 Subject: [PATCH 19/20] Call GameLobbyJoinRequested_t if a lobby exists when joining with rich presence. --- overlay_experimental/steam_overlay.cpp | 40 +++++++++++++++++--------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/overlay_experimental/steam_overlay.cpp b/overlay_experimental/steam_overlay.cpp index 2808f7e..93f739e 100644 --- a/overlay_experimental/steam_overlay.cpp +++ b/overlay_experimental/steam_overlay.cpp @@ -787,22 +787,34 @@ void Steam_Overlay::RunCallbacks() callbacks->addCBResult(data.k_iCallback, &data, sizeof(data)); friend_info->second.window_state &= ~window_state_lobby_invite; - } else + } else { // The user got a rich presence invite and accepted it - if (friend_info->second.window_state & window_state_rich_invite) - { - GameRichPresenceJoinRequested_t data = {}; - data.m_steamIDFriend.SetFromUint64(friend_id); - strncpy(data.m_rgchConnect, friend_info->second.connect, k_cchMaxRichPresenceValueLength - 1); - callbacks->addCBResult(data.k_iCallback, &data, sizeof(data)); + if (friend_info->second.window_state & window_state_rich_invite) + { + GameRichPresenceJoinRequested_t data = {}; + data.m_steamIDFriend.SetFromUint64(friend_id); + strncpy(data.m_rgchConnect, friend_info->second.connect, k_cchMaxRichPresenceValueLength - 1); + callbacks->addCBResult(data.k_iCallback, &data, sizeof(data)); - friend_info->second.window_state &= ~window_state_rich_invite; - } else if (connect.length() > 0) - { - GameRichPresenceJoinRequested_t data = {}; - data.m_steamIDFriend.SetFromUint64(friend_id); - strncpy(data.m_rgchConnect, connect.c_str(), k_cchMaxRichPresenceValueLength - 1); - callbacks->addCBResult(data.k_iCallback, &data, sizeof(data)); + friend_info->second.window_state &= ~window_state_rich_invite; + } else if (connect.length() > 0) + { + GameRichPresenceJoinRequested_t data = {}; + data.m_steamIDFriend.SetFromUint64(friend_id); + strncpy(data.m_rgchConnect, connect.c_str(), k_cchMaxRichPresenceValueLength - 1); + callbacks->addCBResult(data.k_iCallback, &data, sizeof(data)); + } + + //Not sure about this but it fixes sonic racing transformed invites + FriendGameInfo_t friend_game_info = {}; + steamFriends->GetFriendGamePlayed(friend_id, &friend_game_info); + uint64 lobby_id = friend_game_info.m_steamIDLobby.ConvertToUint64(); + if (lobby_id) { + GameLobbyJoinRequested_t data; + data.m_steamIDLobby.SetFromUint64(lobby_id); + data.m_steamIDFriend.SetFromUint64(friend_id); + callbacks->addCBResult(data.k_iCallback, &data, sizeof(data)); + } } friend_info->second.window_state &= ~window_state_join; From 44305a0068df6a97cb3db352652f24430f4f27aa Mon Sep 17 00:00:00 2001 From: Mr_Goldberg Date: Sun, 7 Mar 2021 19:06:05 -0500 Subject: [PATCH 20/20] Implement steamnetworkingsockets ip/port connections. Note: clients need to know each other already or it won't work. --- dll/net.proto | 3 +- dll/steam_networking_sockets.h | 96 +++++++++++++++++++++++++--------- 2 files changed, 74 insertions(+), 25 deletions(-) diff --git a/dll/net.proto b/dll/net.proto index aaa2bef..f85fe0a 100644 --- a/dll/net.proto +++ b/dll/net.proto @@ -119,7 +119,8 @@ message Networking_Sockets { } Types type = 1; - uint32 port = 2; + int32 virtual_port = 2; + int32 real_port = 6; uint64 connection_id = 3; uint64 connection_id_from = 4; bytes data = 5; diff --git a/dll/steam_networking_sockets.h b/dll/steam_networking_sockets.h index 0ecd271..bb5ccd6 100644 --- a/dll/steam_networking_sockets.h +++ b/dll/steam_networking_sockets.h @@ -21,6 +21,7 @@ struct Listen_Socket { HSteamListenSocket socket_id; int virtual_port; + int real_port; }; enum connect_socket_status { @@ -34,6 +35,7 @@ enum connect_socket_status { struct Connect_Socket { int virtual_port; + int real_port; SteamNetworkingIdentity remote_identity; HSteamNetConnection remote_id; @@ -69,6 +71,8 @@ public ISteamNetworkingSockets std::map> poll_groups; std::chrono::steady_clock::time_point created; + static const int SNS_DISABLED_PORT = -1; + public: static void steam_callback(void *object, Common_Message *msg) { @@ -114,7 +118,7 @@ static unsigned long get_socket_id() return socket_id; } -HSteamListenSocket new_listen_socket(int nSteamConnectVirtualPort) +HSteamListenSocket new_listen_socket(int nSteamConnectVirtualPort, int real_port) { HSteamListenSocket socket_id = get_socket_id(); if (socket_id == k_HSteamListenSocket_Invalid) ++socket_id; @@ -125,6 +129,7 @@ HSteamListenSocket new_listen_socket(int nSteamConnectVirtualPort) struct Listen_Socket listen_socket; listen_socket.socket_id = socket_id; listen_socket.virtual_port = nSteamConnectVirtualPort; + listen_socket.real_port = real_port; listen_sockets.push_back(listen_socket); return socket_id; } @@ -145,7 +150,6 @@ bool send_packet_new_connection(HSteamNetConnection m_hConn) Common_Message msg; msg.set_source_id(settings->get_local_steam_id().ConvertToUint64()); - msg.set_dest_id(connect_socket->second.remote_identity.GetSteamID64()); msg.set_allocated_networking_sockets(new Networking_Sockets); if (connect_socket->second.status == CONNECT_SOCKET_CONNECTING) { msg.mutable_networking_sockets()->set_type(Networking_Sockets::CONNECTION_REQUEST); @@ -153,17 +157,31 @@ bool send_packet_new_connection(HSteamNetConnection m_hConn) msg.mutable_networking_sockets()->set_type(Networking_Sockets::CONNECTION_ACCEPTED); } - msg.mutable_networking_sockets()->set_port(connect_socket->second.virtual_port); + msg.mutable_networking_sockets()->set_virtual_port(connect_socket->second.virtual_port); + msg.mutable_networking_sockets()->set_real_port(connect_socket->second.real_port); msg.mutable_networking_sockets()->set_connection_id_from(connect_socket->first); msg.mutable_networking_sockets()->set_connection_id(connect_socket->second.remote_id); - return network->sendTo(&msg, true); + + uint64_t steam_id = connect_socket->second.remote_identity.GetSteamID64(); + if (steam_id) { + msg.set_dest_id(steam_id); + return network->sendTo(&msg, true); + } + + const SteamNetworkingIPAddr *ip_addr = connect_socket->second.remote_identity.GetIPAddr(); + if (ip_addr) { + return network->sendToIPPort(&msg, ip_addr->GetIPv4(), ip_addr->m_port, true); + } + + return false; } -HSteamNetConnection new_connect_socket(SteamNetworkingIdentity remote_identity, int virtual_port, enum connect_socket_status status=CONNECT_SOCKET_CONNECTING, HSteamListenSocket listen_socket_id=k_HSteamListenSocket_Invalid, HSteamNetConnection remote_id=k_HSteamNetConnection_Invalid) +HSteamNetConnection new_connect_socket(SteamNetworkingIdentity remote_identity, int virtual_port, int real_port, enum connect_socket_status status=CONNECT_SOCKET_CONNECTING, HSteamListenSocket listen_socket_id=k_HSteamListenSocket_Invalid, HSteamNetConnection remote_id=k_HSteamNetConnection_Invalid) { Connect_Socket socket = {}; socket.remote_identity = remote_identity; socket.virtual_port = virtual_port; + socket.real_port = real_port; socket.listen_socket_id = listen_socket_id; socket.remote_id = remote_id; socket.status = status; @@ -237,7 +255,7 @@ HSteamListenSocket CreateListenSocket( int nSteamConnectVirtualPort, uint32 nIP, { PRINT_DEBUG("Steam_Networking_Sockets::CreateListenSocket %i %u %u\n", nSteamConnectVirtualPort, nIP, nPort); std::lock_guard lock(global_mutex); - return new_listen_socket(nSteamConnectVirtualPort); + return new_listen_socket(nSteamConnectVirtualPort, nPort); } /// Creates a "server" socket that listens for clients to connect to by @@ -257,19 +275,22 @@ HSteamListenSocket CreateListenSocket( int nSteamConnectVirtualPort, uint32 nIP, HSteamListenSocket CreateListenSocketIP( const SteamNetworkingIPAddr &localAddress ) { PRINT_DEBUG("Steam_Networking_Sockets::CreateListenSocketIP old\n"); - return k_HSteamListenSocket_Invalid; + std::lock_guard lock(global_mutex); + return new_listen_socket(SNS_DISABLED_PORT, localAddress.m_port); } HSteamListenSocket CreateListenSocketIP( const SteamNetworkingIPAddr *localAddress ) { PRINT_DEBUG("Steam_Networking_Sockets::CreateListenSocketIP old1\n"); - return k_HSteamListenSocket_Invalid; + std::lock_guard lock(global_mutex); + return new_listen_socket(SNS_DISABLED_PORT, localAddress->m_port); } HSteamListenSocket CreateListenSocketIP( const SteamNetworkingIPAddr &localAddress, int nOptions, const SteamNetworkingConfigValue_t *pOptions ) { PRINT_DEBUG("Steam_Networking_Sockets::CreateListenSocketIP\n"); - return k_HSteamListenSocket_Invalid; + std::lock_guard lock(global_mutex); + return new_listen_socket(SNS_DISABLED_PORT, localAddress.m_port); } /// Creates a connection and begins talking to a "server" over UDP at the @@ -293,19 +314,34 @@ HSteamListenSocket CreateListenSocketIP( const SteamNetworkingIPAddr &localAddre HSteamNetConnection ConnectByIPAddress( const SteamNetworkingIPAddr &address ) { PRINT_DEBUG("Steam_Networking_Sockets::ConnectByIPAddress old\n"); - return k_HSteamNetConnection_Invalid; + std::lock_guard lock(global_mutex); + SteamNetworkingIdentity ip_id; + ip_id.SetIPAddr(address); + HSteamNetConnection socket = new_connect_socket(ip_id, SNS_DISABLED_PORT, address.m_port); + send_packet_new_connection(socket); + return socket; } HSteamNetConnection ConnectByIPAddress( const SteamNetworkingIPAddr *address ) { PRINT_DEBUG("Steam_Networking_Sockets::ConnectByIPAddress old1\n"); - return k_HSteamNetConnection_Invalid; + std::lock_guard lock(global_mutex); + SteamNetworkingIdentity ip_id; + ip_id.SetIPAddr(*address); + HSteamNetConnection socket = new_connect_socket(ip_id, SNS_DISABLED_PORT, address->m_port); + send_packet_new_connection(socket); + return socket; } HSteamNetConnection ConnectByIPAddress( const SteamNetworkingIPAddr &address, int nOptions, const SteamNetworkingConfigValue_t *pOptions ) { PRINT_DEBUG("Steam_Networking_Sockets::ConnectByIPAddress\n"); - return k_HSteamNetConnection_Invalid; + std::lock_guard lock(global_mutex); + SteamNetworkingIdentity ip_id; + ip_id.SetIPAddr(address); + HSteamNetConnection socket = new_connect_socket(ip_id, SNS_DISABLED_PORT, address.m_port); + send_packet_new_connection(socket); + return socket; } /// Like CreateListenSocketIP, but clients will connect using ConnectP2P @@ -322,7 +358,7 @@ HSteamListenSocket CreateListenSocketP2P( int nVirtualPort ) { PRINT_DEBUG("Steam_Networking_Sockets::CreateListenSocketP2P old %i\n", nVirtualPort); std::lock_guard lock(global_mutex); - return new_listen_socket(nVirtualPort); + return new_listen_socket(nVirtualPort, SNS_DISABLED_PORT); } HSteamListenSocket CreateListenSocketP2P( int nVirtualPort, int nOptions, const SteamNetworkingConfigValue_t *pOptions ) @@ -330,7 +366,7 @@ HSteamListenSocket CreateListenSocketP2P( int nVirtualPort, int nOptions, const PRINT_DEBUG("Steam_Networking_Sockets::CreateListenSocketP2P %i\n", nVirtualPort); //TODO config options std::lock_guard lock(global_mutex); - return new_listen_socket(nVirtualPort); + return new_listen_socket(nVirtualPort, SNS_DISABLED_PORT); } /// Begin connecting to a server that is identified using a platform-specific identifier. @@ -361,7 +397,7 @@ HSteamNetConnection ConnectP2P( const SteamNetworkingIdentity &identityRemote, i return k_HSteamNetConnection_Invalid; } - HSteamNetConnection socket = new_connect_socket(identityRemote, nVirtualPort); + HSteamNetConnection socket = new_connect_socket(identityRemote, nVirtualPort, SNS_DISABLED_PORT); send_packet_new_connection(socket); return socket; } @@ -487,7 +523,8 @@ bool CloseConnection( HSteamNetConnection hPeer, int nReason, const char *pszDeb msg.set_dest_id(connect_socket->second.remote_identity.GetSteamID64()); msg.set_allocated_networking_sockets(new Networking_Sockets); msg.mutable_networking_sockets()->set_type(Networking_Sockets::CONNECTION_END); - msg.mutable_networking_sockets()->set_port(connect_socket->second.virtual_port); + msg.mutable_networking_sockets()->set_virtual_port(connect_socket->second.virtual_port); + msg.mutable_networking_sockets()->set_real_port(connect_socket->second.real_port); msg.mutable_networking_sockets()->set_connection_id_from(connect_socket->first); msg.mutable_networking_sockets()->set_connection_id(connect_socket->second.remote_id); network->sendTo(&msg, true); @@ -665,7 +702,8 @@ EResult SendMessageToConnection( HSteamNetConnection hConn, const void *pData, u msg.set_dest_id(connect_socket->second.remote_identity.GetSteamID64()); msg.set_allocated_networking_sockets(new Networking_Sockets); msg.mutable_networking_sockets()->set_type(Networking_Sockets::DATA); - msg.mutable_networking_sockets()->set_port(connect_socket->second.virtual_port); + msg.mutable_networking_sockets()->set_virtual_port(connect_socket->second.virtual_port); + msg.mutable_networking_sockets()->set_real_port(connect_socket->second.real_port); msg.mutable_networking_sockets()->set_connection_id_from(connect_socket->first); msg.mutable_networking_sockets()->set_connection_id(connect_socket->second.remote_id); msg.mutable_networking_sockets()->set_data(pData, cbData); @@ -1021,8 +1059,8 @@ bool CreateSocketPair( HSteamNetConnection *pOutConnection1, HSteamNetConnection SteamNetworkingIdentity remote_identity; remote_identity.SetSteamID(settings->get_local_steam_id()); - HSteamNetConnection con1 = new_connect_socket(remote_identity, 0, CONNECT_SOCKET_CONNECTED, k_HSteamListenSocket_Invalid, k_HSteamNetConnection_Invalid); - HSteamNetConnection con2 = new_connect_socket(remote_identity, 0, CONNECT_SOCKET_CONNECTED, k_HSteamListenSocket_Invalid, con1); + HSteamNetConnection con1 = new_connect_socket(remote_identity, 0, SNS_DISABLED_PORT, CONNECT_SOCKET_CONNECTED, k_HSteamListenSocket_Invalid, k_HSteamNetConnection_Invalid); + HSteamNetConnection con2 = new_connect_socket(remote_identity, 0, SNS_DISABLED_PORT, CONNECT_SOCKET_CONNECTED, k_HSteamListenSocket_Invalid, con1); connect_sockets[con1].remote_id = con2; *pOutConnection1 = con1; *pOutConnection2 = con2; @@ -1383,7 +1421,7 @@ HSteamListenSocket CreateHostedDedicatedServerListenSocket( int nVirtualPort ) { PRINT_DEBUG("Steam_Networking_Sockets::CreateHostedDedicatedServerListenSocket old %i\n", nVirtualPort); std::lock_guard lock(global_mutex); - return new_listen_socket(nVirtualPort); + return new_listen_socket(nVirtualPort, SNS_DISABLED_PORT); } /// Create a listen socket on the specified virtual port. The physical UDP port to use @@ -1400,7 +1438,7 @@ HSteamListenSocket CreateHostedDedicatedServerListenSocket( int nVirtualPort, in PRINT_DEBUG("Steam_Networking_Sockets::CreateHostedDedicatedServerListenSocket old %i\n", nVirtualPort); //TODO config options std::lock_guard lock(global_mutex); - return new_listen_socket(nVirtualPort); + return new_listen_socket(nVirtualPort, SNS_DISABLED_PORT); } @@ -1670,19 +1708,29 @@ void Callback(Common_Message *msg) if (msg->has_networking_sockets()) { PRINT_DEBUG("Steam_Networking_Sockets: got network socket msg %u\n", msg->networking_sockets().type()); if (msg->networking_sockets().type() == Networking_Sockets::CONNECTION_REQUEST) { - int virtual_port = msg->networking_sockets().port(); + int virtual_port = msg->networking_sockets().virtual_port(); + int real_port = msg->networking_sockets().real_port(); + std::vector::iterator conn; + if (virtual_port == SNS_DISABLED_PORT) { + conn = std::find_if(listen_sockets.begin(), listen_sockets.end(), [&real_port](struct Listen_Socket const& conn) { return conn.real_port == real_port;}); + } else { + conn = std::find_if(listen_sockets.begin(), listen_sockets.end(), [&virtual_port](struct Listen_Socket const& conn) { return conn.virtual_port == virtual_port;}); + } - auto conn = std::find_if(listen_sockets.begin(), listen_sockets.end(), [&virtual_port](struct Listen_Socket const& conn) { return conn.virtual_port == virtual_port;}); if (conn != listen_sockets.end()) { SteamNetworkingIdentity identity; identity.SetSteamID64(msg->source_id()); - HSteamNetConnection new_connection = new_connect_socket(identity, virtual_port, CONNECT_SOCKET_NOT_ACCEPTED, conn->socket_id, msg->networking_sockets().connection_id_from()); + HSteamNetConnection new_connection = new_connect_socket(identity, virtual_port, real_port, CONNECT_SOCKET_NOT_ACCEPTED, conn->socket_id, msg->networking_sockets().connection_id_from()); launch_callback(new_connection, CONNECT_SOCKET_NO_CONNECTION); } } else if (msg->networking_sockets().type() == Networking_Sockets::CONNECTION_ACCEPTED) { auto connect_socket = connect_sockets.find(msg->networking_sockets().connection_id()); if (connect_socket != connect_sockets.end()) { + if (connect_socket->second.remote_identity.GetSteamID64() == 0) { + connect_socket->second.remote_identity.SetSteamID64(msg->source_id()); + } + if (connect_socket->second.remote_identity.GetSteamID64() == msg->source_id() && connect_socket->second.status == CONNECT_SOCKET_CONNECTING) { connect_socket->second.remote_id = msg->networking_sockets().connection_id_from(); connect_socket->second.status = CONNECT_SOCKET_CONNECTED;