From d18086a1b87491bbb5f5cdbe57b42968bf881748 Mon Sep 17 00:00:00 2001 From: Jake Rich Date: Mon, 12 Aug 2024 20:46:16 -0400 Subject: [PATCH 1/5] Fix serverlist query allocating a large amount of memory when a large amount of servers are pending --- .../Interfaces/ISteamMatchmakingServers.cs | 19 ++++++++++++++++++- .../Generated/SteamStructs.cs | 5 ++++- Facepunch.Steamworks/ServerList/Base.cs | 16 +++++++++++----- 3 files changed, 33 insertions(+), 7 deletions(-) diff --git a/Facepunch.Steamworks/Generated/Interfaces/ISteamMatchmakingServers.cs b/Facepunch.Steamworks/Generated/Interfaces/ISteamMatchmakingServers.cs index 6f9ee8b3..c1ca82c0 100644 --- a/Facepunch.Steamworks/Generated/Interfaces/ISteamMatchmakingServers.cs +++ b/Facepunch.Steamworks/Generated/Interfaces/ISteamMatchmakingServers.cs @@ -106,7 +106,24 @@ internal gameserveritem_t GetServerDetails( HServerListRequest hRequest, int iSe var returnValue = _GetServerDetails( Self, hRequest, iServer ); return returnValue.ToType(); } - + + /// + /// Read gameserveritem_t.m_bHadSuccessfulResponse without allocating the struct on the heap + /// + /// + /// + /// + internal bool HasServerResponded( HServerListRequest hRequest, int iServer ) + { + IntPtr returnValue = _GetServerDetails( Self, hRequest, iServer ); + + // Return false if steam returned null + if ( returnValue == IntPtr.Zero ) return false; + + // first 8 bytes is IPAddress, next 4 bytes is ping, next 1 byte is m_bHadSuccessfulResponse + return Marshal.ReadByte( IntPtr.Add( returnValue, 12 ) ) == 1; + } + #region FunctionMeta [DllImport( Platform.LibraryName, EntryPoint = "SteamAPI_ISteamMatchmakingServers_CancelQuery", CallingConvention = Platform.CC)] private static extern void _CancelQuery( IntPtr self, HServerListRequest hRequest ); diff --git a/Facepunch.Steamworks/Generated/SteamStructs.cs b/Facepunch.Steamworks/Generated/SteamStructs.cs index 8724de68..13e0b4a6 100644 --- a/Facepunch.Steamworks/Generated/SteamStructs.cs +++ b/Facepunch.Steamworks/Generated/SteamStructs.cs @@ -25,14 +25,17 @@ internal partial struct servernetadr_t internal uint IP; // m_unIP uint32 } - + [StructLayout( LayoutKind.Sequential, Pack = Platform.StructPackSize )] internal partial struct gameserveritem_t { internal servernetadr_t NetAdr; // m_NetAdr servernetadr_t internal int Ping; // m_nPing int + + // NOTE: If you add fields above this you must change offset inISteamMatchmakingServers.HasServerResponded() [MarshalAs(UnmanagedType.I1)] internal bool HadSuccessfulResponse; // m_bHadSuccessfulResponse bool + [MarshalAs(UnmanagedType.I1)] internal bool DoNotRefresh; // m_bDoNotRefresh bool internal string GameDirUTF8() => System.Text.Encoding.UTF8.GetString( GameDir, 0, System.Array.IndexOf( GameDir, 0 ) ); diff --git a/Facepunch.Steamworks/ServerList/Base.cs b/Facepunch.Steamworks/ServerList/Base.cs index 41f8624b..2d11cc5c 100644 --- a/Facepunch.Steamworks/ServerList/Base.cs +++ b/Facepunch.Steamworks/ServerList/Base.cs @@ -161,11 +161,17 @@ public void UpdateResponsive() { watchList.RemoveAll( x => { - var info = Internal.GetServerDetails( request, x ); - if ( info.HadSuccessfulResponse ) + // First check if the server has responded without allocating server info + bool hasResponded = Internal.HasServerResponded( request, x ); + if ( hasResponded ) { - OnServer( ServerInfo.From( info ), info.HadSuccessfulResponse ); - return true; + // Now get all server info + var info = Internal.GetServerDetails( request, x ); + if ( info.HadSuccessfulResponse ) + { + OnServer( ServerInfo.From( info ), info.HadSuccessfulResponse ); + return true; + } } return false; @@ -194,4 +200,4 @@ private void OnServer( ServerInfo serverInfo, bool responded ) Unresponsive.Add( serverInfo ); } } -} \ No newline at end of file +} From 6dd32eb5c4e501e3ea58886dc2ca6518919a4235 Mon Sep 17 00:00:00 2001 From: Jake Rich Date: Mon, 12 Aug 2024 21:29:49 -0400 Subject: [PATCH 2/5] Change codegen to make interface classes partial --- Generator/CodeWriter/Interface.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Generator/CodeWriter/Interface.cs b/Generator/CodeWriter/Interface.cs index 790ec4c2..84db168e 100644 --- a/Generator/CodeWriter/Interface.cs +++ b/Generator/CodeWriter/Interface.cs @@ -23,7 +23,7 @@ public void GenerateInterface( SteamApiDefinition.Interface iface, string folder StartBlock( $"namespace Steamworks" ); { - StartBlock( $"internal unsafe class {iface.Name} : SteamInterface" ); + StartBlock( $"internal unsafe partial class {iface.Name} : SteamInterface" ); { WriteLine(); StartBlock( $"internal {iface.Name}( bool IsGameServer )" ); From 09db39d9e356967da0a6f2b8b4d2d3baa4ac7cf2 Mon Sep 17 00:00:00 2001 From: Jake Rich Date: Mon, 12 Aug 2024 21:30:05 -0400 Subject: [PATCH 3/5] Codegen --- .../Generated/Interfaces/ISteamAppList.cs | 2 +- .../Generated/Interfaces/ISteamApps.cs | 2 +- .../Generated/Interfaces/ISteamClient.cs | 2 +- .../Generated/Interfaces/ISteamController.cs | 2 +- .../Generated/Interfaces/ISteamFriends.cs | 2 +- .../Generated/Interfaces/ISteamGameSearch.cs | 2 +- .../Generated/Interfaces/ISteamGameServer.cs | 2 +- .../Interfaces/ISteamGameServerStats.cs | 2 +- .../Generated/Interfaces/ISteamHTMLSurface.cs | 2 +- .../Generated/Interfaces/ISteamHTTP.cs | 2 +- .../Generated/Interfaces/ISteamInput.cs | 2 +- .../Generated/Interfaces/ISteamInventory.cs | 2 +- .../Generated/Interfaces/ISteamMatchmaking.cs | 2 +- .../ISteamMatchmakingPingResponse.cs | 2 +- .../ISteamMatchmakingPlayersResponse.cs | 2 +- .../ISteamMatchmakingRulesResponse.cs | 2 +- .../ISteamMatchmakingServerListResponse.cs | 2 +- .../Interfaces/ISteamMatchmakingServers.cs | 21 ++----------------- .../Generated/Interfaces/ISteamMusic.cs | 2 +- .../Generated/Interfaces/ISteamMusicRemote.cs | 2 +- .../Generated/Interfaces/ISteamNetworking.cs | 2 +- .../Interfaces/ISteamNetworkingFakeUDPPort.cs | 2 +- .../Interfaces/ISteamNetworkingMessages.cs | 2 +- .../Interfaces/ISteamNetworkingSockets.cs | 2 +- .../Interfaces/ISteamNetworkingUtils.cs | 2 +- .../Interfaces/ISteamParentalSettings.cs | 2 +- .../Generated/Interfaces/ISteamParties.cs | 2 +- .../Generated/Interfaces/ISteamRemotePlay.cs | 2 +- .../Interfaces/ISteamRemoteStorage.cs | 2 +- .../Generated/Interfaces/ISteamScreenshots.cs | 2 +- .../Generated/Interfaces/ISteamUGC.cs | 2 +- .../Generated/Interfaces/ISteamUser.cs | 2 +- .../Generated/Interfaces/ISteamUserStats.cs | 2 +- .../Generated/Interfaces/ISteamUtils.cs | 2 +- .../Generated/Interfaces/ISteamVideo.cs | 2 +- .../Generated/SteamStructs.cs | 5 +---- 36 files changed, 37 insertions(+), 57 deletions(-) diff --git a/Facepunch.Steamworks/Generated/Interfaces/ISteamAppList.cs b/Facepunch.Steamworks/Generated/Interfaces/ISteamAppList.cs index b6745756..2b1a7b55 100644 --- a/Facepunch.Steamworks/Generated/Interfaces/ISteamAppList.cs +++ b/Facepunch.Steamworks/Generated/Interfaces/ISteamAppList.cs @@ -7,7 +7,7 @@ namespace Steamworks { - internal unsafe class ISteamAppList : SteamInterface + internal unsafe partial class ISteamAppList : SteamInterface { internal ISteamAppList( bool IsGameServer ) diff --git a/Facepunch.Steamworks/Generated/Interfaces/ISteamApps.cs b/Facepunch.Steamworks/Generated/Interfaces/ISteamApps.cs index 2888c398..8c5c53a9 100644 --- a/Facepunch.Steamworks/Generated/Interfaces/ISteamApps.cs +++ b/Facepunch.Steamworks/Generated/Interfaces/ISteamApps.cs @@ -7,7 +7,7 @@ namespace Steamworks { - internal unsafe class ISteamApps : SteamInterface + internal unsafe partial class ISteamApps : SteamInterface { internal ISteamApps( bool IsGameServer ) diff --git a/Facepunch.Steamworks/Generated/Interfaces/ISteamClient.cs b/Facepunch.Steamworks/Generated/Interfaces/ISteamClient.cs index 418f5dab..dd8cc2e2 100644 --- a/Facepunch.Steamworks/Generated/Interfaces/ISteamClient.cs +++ b/Facepunch.Steamworks/Generated/Interfaces/ISteamClient.cs @@ -7,7 +7,7 @@ namespace Steamworks { - internal unsafe class ISteamClient : SteamInterface + internal unsafe partial class ISteamClient : SteamInterface { internal ISteamClient( bool IsGameServer ) diff --git a/Facepunch.Steamworks/Generated/Interfaces/ISteamController.cs b/Facepunch.Steamworks/Generated/Interfaces/ISteamController.cs index d93dccff..d0fafb9d 100644 --- a/Facepunch.Steamworks/Generated/Interfaces/ISteamController.cs +++ b/Facepunch.Steamworks/Generated/Interfaces/ISteamController.cs @@ -7,7 +7,7 @@ namespace Steamworks { - internal unsafe class ISteamController : SteamInterface + internal unsafe partial class ISteamController : SteamInterface { internal ISteamController( bool IsGameServer ) diff --git a/Facepunch.Steamworks/Generated/Interfaces/ISteamFriends.cs b/Facepunch.Steamworks/Generated/Interfaces/ISteamFriends.cs index b8e5cd44..16a1ff2b 100644 --- a/Facepunch.Steamworks/Generated/Interfaces/ISteamFriends.cs +++ b/Facepunch.Steamworks/Generated/Interfaces/ISteamFriends.cs @@ -7,7 +7,7 @@ namespace Steamworks { - internal unsafe class ISteamFriends : SteamInterface + internal unsafe partial class ISteamFriends : SteamInterface { internal ISteamFriends( bool IsGameServer ) diff --git a/Facepunch.Steamworks/Generated/Interfaces/ISteamGameSearch.cs b/Facepunch.Steamworks/Generated/Interfaces/ISteamGameSearch.cs index 3c70b84f..930c8886 100644 --- a/Facepunch.Steamworks/Generated/Interfaces/ISteamGameSearch.cs +++ b/Facepunch.Steamworks/Generated/Interfaces/ISteamGameSearch.cs @@ -7,7 +7,7 @@ namespace Steamworks { - internal unsafe class ISteamGameSearch : SteamInterface + internal unsafe partial class ISteamGameSearch : SteamInterface { internal ISteamGameSearch( bool IsGameServer ) diff --git a/Facepunch.Steamworks/Generated/Interfaces/ISteamGameServer.cs b/Facepunch.Steamworks/Generated/Interfaces/ISteamGameServer.cs index b80a6953..2e506b2d 100644 --- a/Facepunch.Steamworks/Generated/Interfaces/ISteamGameServer.cs +++ b/Facepunch.Steamworks/Generated/Interfaces/ISteamGameServer.cs @@ -7,7 +7,7 @@ namespace Steamworks { - internal unsafe class ISteamGameServer : SteamInterface + internal unsafe partial class ISteamGameServer : SteamInterface { internal ISteamGameServer( bool IsGameServer ) diff --git a/Facepunch.Steamworks/Generated/Interfaces/ISteamGameServerStats.cs b/Facepunch.Steamworks/Generated/Interfaces/ISteamGameServerStats.cs index de293cbe..3dd98388 100644 --- a/Facepunch.Steamworks/Generated/Interfaces/ISteamGameServerStats.cs +++ b/Facepunch.Steamworks/Generated/Interfaces/ISteamGameServerStats.cs @@ -7,7 +7,7 @@ namespace Steamworks { - internal unsafe class ISteamGameServerStats : SteamInterface + internal unsafe partial class ISteamGameServerStats : SteamInterface { internal ISteamGameServerStats( bool IsGameServer ) diff --git a/Facepunch.Steamworks/Generated/Interfaces/ISteamHTMLSurface.cs b/Facepunch.Steamworks/Generated/Interfaces/ISteamHTMLSurface.cs index 38c6b462..dde249ba 100644 --- a/Facepunch.Steamworks/Generated/Interfaces/ISteamHTMLSurface.cs +++ b/Facepunch.Steamworks/Generated/Interfaces/ISteamHTMLSurface.cs @@ -7,7 +7,7 @@ namespace Steamworks { - internal unsafe class ISteamHTMLSurface : SteamInterface + internal unsafe partial class ISteamHTMLSurface : SteamInterface { internal ISteamHTMLSurface( bool IsGameServer ) diff --git a/Facepunch.Steamworks/Generated/Interfaces/ISteamHTTP.cs b/Facepunch.Steamworks/Generated/Interfaces/ISteamHTTP.cs index 599054b5..3708f7c7 100644 --- a/Facepunch.Steamworks/Generated/Interfaces/ISteamHTTP.cs +++ b/Facepunch.Steamworks/Generated/Interfaces/ISteamHTTP.cs @@ -7,7 +7,7 @@ namespace Steamworks { - internal unsafe class ISteamHTTP : SteamInterface + internal unsafe partial class ISteamHTTP : SteamInterface { internal ISteamHTTP( bool IsGameServer ) diff --git a/Facepunch.Steamworks/Generated/Interfaces/ISteamInput.cs b/Facepunch.Steamworks/Generated/Interfaces/ISteamInput.cs index 3d1ab522..e5c82b89 100644 --- a/Facepunch.Steamworks/Generated/Interfaces/ISteamInput.cs +++ b/Facepunch.Steamworks/Generated/Interfaces/ISteamInput.cs @@ -7,7 +7,7 @@ namespace Steamworks { - internal unsafe class ISteamInput : SteamInterface + internal unsafe partial class ISteamInput : SteamInterface { internal ISteamInput( bool IsGameServer ) diff --git a/Facepunch.Steamworks/Generated/Interfaces/ISteamInventory.cs b/Facepunch.Steamworks/Generated/Interfaces/ISteamInventory.cs index c5ea02c4..19d425bf 100644 --- a/Facepunch.Steamworks/Generated/Interfaces/ISteamInventory.cs +++ b/Facepunch.Steamworks/Generated/Interfaces/ISteamInventory.cs @@ -7,7 +7,7 @@ namespace Steamworks { - internal unsafe class ISteamInventory : SteamInterface + internal unsafe partial class ISteamInventory : SteamInterface { internal ISteamInventory( bool IsGameServer ) diff --git a/Facepunch.Steamworks/Generated/Interfaces/ISteamMatchmaking.cs b/Facepunch.Steamworks/Generated/Interfaces/ISteamMatchmaking.cs index 801d4108..043b4477 100644 --- a/Facepunch.Steamworks/Generated/Interfaces/ISteamMatchmaking.cs +++ b/Facepunch.Steamworks/Generated/Interfaces/ISteamMatchmaking.cs @@ -7,7 +7,7 @@ namespace Steamworks { - internal unsafe class ISteamMatchmaking : SteamInterface + internal unsafe partial class ISteamMatchmaking : SteamInterface { internal ISteamMatchmaking( bool IsGameServer ) diff --git a/Facepunch.Steamworks/Generated/Interfaces/ISteamMatchmakingPingResponse.cs b/Facepunch.Steamworks/Generated/Interfaces/ISteamMatchmakingPingResponse.cs index 0306b76f..9e95435c 100644 --- a/Facepunch.Steamworks/Generated/Interfaces/ISteamMatchmakingPingResponse.cs +++ b/Facepunch.Steamworks/Generated/Interfaces/ISteamMatchmakingPingResponse.cs @@ -7,7 +7,7 @@ namespace Steamworks { - internal unsafe class ISteamMatchmakingPingResponse : SteamInterface + internal unsafe partial class ISteamMatchmakingPingResponse : SteamInterface { internal ISteamMatchmakingPingResponse( bool IsGameServer ) diff --git a/Facepunch.Steamworks/Generated/Interfaces/ISteamMatchmakingPlayersResponse.cs b/Facepunch.Steamworks/Generated/Interfaces/ISteamMatchmakingPlayersResponse.cs index a5ed9269..8d73d6bd 100644 --- a/Facepunch.Steamworks/Generated/Interfaces/ISteamMatchmakingPlayersResponse.cs +++ b/Facepunch.Steamworks/Generated/Interfaces/ISteamMatchmakingPlayersResponse.cs @@ -7,7 +7,7 @@ namespace Steamworks { - internal unsafe class ISteamMatchmakingPlayersResponse : SteamInterface + internal unsafe partial class ISteamMatchmakingPlayersResponse : SteamInterface { internal ISteamMatchmakingPlayersResponse( bool IsGameServer ) diff --git a/Facepunch.Steamworks/Generated/Interfaces/ISteamMatchmakingRulesResponse.cs b/Facepunch.Steamworks/Generated/Interfaces/ISteamMatchmakingRulesResponse.cs index 78507b9e..431e8771 100644 --- a/Facepunch.Steamworks/Generated/Interfaces/ISteamMatchmakingRulesResponse.cs +++ b/Facepunch.Steamworks/Generated/Interfaces/ISteamMatchmakingRulesResponse.cs @@ -7,7 +7,7 @@ namespace Steamworks { - internal unsafe class ISteamMatchmakingRulesResponse : SteamInterface + internal unsafe partial class ISteamMatchmakingRulesResponse : SteamInterface { internal ISteamMatchmakingRulesResponse( bool IsGameServer ) diff --git a/Facepunch.Steamworks/Generated/Interfaces/ISteamMatchmakingServerListResponse.cs b/Facepunch.Steamworks/Generated/Interfaces/ISteamMatchmakingServerListResponse.cs index 8fd0a9e9..e33a65e6 100644 --- a/Facepunch.Steamworks/Generated/Interfaces/ISteamMatchmakingServerListResponse.cs +++ b/Facepunch.Steamworks/Generated/Interfaces/ISteamMatchmakingServerListResponse.cs @@ -7,7 +7,7 @@ namespace Steamworks { - internal unsafe class ISteamMatchmakingServerListResponse : SteamInterface + internal unsafe partial class ISteamMatchmakingServerListResponse : SteamInterface { internal ISteamMatchmakingServerListResponse( bool IsGameServer ) diff --git a/Facepunch.Steamworks/Generated/Interfaces/ISteamMatchmakingServers.cs b/Facepunch.Steamworks/Generated/Interfaces/ISteamMatchmakingServers.cs index c1ca82c0..65c371f7 100644 --- a/Facepunch.Steamworks/Generated/Interfaces/ISteamMatchmakingServers.cs +++ b/Facepunch.Steamworks/Generated/Interfaces/ISteamMatchmakingServers.cs @@ -7,7 +7,7 @@ namespace Steamworks { - internal unsafe class ISteamMatchmakingServers : SteamInterface + internal unsafe partial class ISteamMatchmakingServers : SteamInterface { internal ISteamMatchmakingServers( bool IsGameServer ) @@ -106,24 +106,7 @@ internal gameserveritem_t GetServerDetails( HServerListRequest hRequest, int iSe var returnValue = _GetServerDetails( Self, hRequest, iServer ); return returnValue.ToType(); } - - /// - /// Read gameserveritem_t.m_bHadSuccessfulResponse without allocating the struct on the heap - /// - /// - /// - /// - internal bool HasServerResponded( HServerListRequest hRequest, int iServer ) - { - IntPtr returnValue = _GetServerDetails( Self, hRequest, iServer ); - - // Return false if steam returned null - if ( returnValue == IntPtr.Zero ) return false; - - // first 8 bytes is IPAddress, next 4 bytes is ping, next 1 byte is m_bHadSuccessfulResponse - return Marshal.ReadByte( IntPtr.Add( returnValue, 12 ) ) == 1; - } - + #region FunctionMeta [DllImport( Platform.LibraryName, EntryPoint = "SteamAPI_ISteamMatchmakingServers_CancelQuery", CallingConvention = Platform.CC)] private static extern void _CancelQuery( IntPtr self, HServerListRequest hRequest ); diff --git a/Facepunch.Steamworks/Generated/Interfaces/ISteamMusic.cs b/Facepunch.Steamworks/Generated/Interfaces/ISteamMusic.cs index 6534a83c..41ddceea 100644 --- a/Facepunch.Steamworks/Generated/Interfaces/ISteamMusic.cs +++ b/Facepunch.Steamworks/Generated/Interfaces/ISteamMusic.cs @@ -7,7 +7,7 @@ namespace Steamworks { - internal unsafe class ISteamMusic : SteamInterface + internal unsafe partial class ISteamMusic : SteamInterface { internal ISteamMusic( bool IsGameServer ) diff --git a/Facepunch.Steamworks/Generated/Interfaces/ISteamMusicRemote.cs b/Facepunch.Steamworks/Generated/Interfaces/ISteamMusicRemote.cs index cf735028..ab6826b2 100644 --- a/Facepunch.Steamworks/Generated/Interfaces/ISteamMusicRemote.cs +++ b/Facepunch.Steamworks/Generated/Interfaces/ISteamMusicRemote.cs @@ -7,7 +7,7 @@ namespace Steamworks { - internal unsafe class ISteamMusicRemote : SteamInterface + internal unsafe partial class ISteamMusicRemote : SteamInterface { internal ISteamMusicRemote( bool IsGameServer ) diff --git a/Facepunch.Steamworks/Generated/Interfaces/ISteamNetworking.cs b/Facepunch.Steamworks/Generated/Interfaces/ISteamNetworking.cs index f1495578..3633e6b0 100644 --- a/Facepunch.Steamworks/Generated/Interfaces/ISteamNetworking.cs +++ b/Facepunch.Steamworks/Generated/Interfaces/ISteamNetworking.cs @@ -7,7 +7,7 @@ namespace Steamworks { - internal unsafe class ISteamNetworking : SteamInterface + internal unsafe partial class ISteamNetworking : SteamInterface { internal ISteamNetworking( bool IsGameServer ) diff --git a/Facepunch.Steamworks/Generated/Interfaces/ISteamNetworkingFakeUDPPort.cs b/Facepunch.Steamworks/Generated/Interfaces/ISteamNetworkingFakeUDPPort.cs index 776ab8a6..ebf730b3 100644 --- a/Facepunch.Steamworks/Generated/Interfaces/ISteamNetworkingFakeUDPPort.cs +++ b/Facepunch.Steamworks/Generated/Interfaces/ISteamNetworkingFakeUDPPort.cs @@ -7,7 +7,7 @@ namespace Steamworks { - internal unsafe class ISteamNetworkingFakeUDPPort : SteamInterface + internal unsafe partial class ISteamNetworkingFakeUDPPort : SteamInterface { internal ISteamNetworkingFakeUDPPort( bool IsGameServer ) diff --git a/Facepunch.Steamworks/Generated/Interfaces/ISteamNetworkingMessages.cs b/Facepunch.Steamworks/Generated/Interfaces/ISteamNetworkingMessages.cs index 715c34a1..5c6daedb 100644 --- a/Facepunch.Steamworks/Generated/Interfaces/ISteamNetworkingMessages.cs +++ b/Facepunch.Steamworks/Generated/Interfaces/ISteamNetworkingMessages.cs @@ -7,7 +7,7 @@ namespace Steamworks { - internal unsafe class ISteamNetworkingMessages : SteamInterface + internal unsafe partial class ISteamNetworkingMessages : SteamInterface { internal ISteamNetworkingMessages( bool IsGameServer ) diff --git a/Facepunch.Steamworks/Generated/Interfaces/ISteamNetworkingSockets.cs b/Facepunch.Steamworks/Generated/Interfaces/ISteamNetworkingSockets.cs index 6a0e8588..c3979ca0 100644 --- a/Facepunch.Steamworks/Generated/Interfaces/ISteamNetworkingSockets.cs +++ b/Facepunch.Steamworks/Generated/Interfaces/ISteamNetworkingSockets.cs @@ -7,7 +7,7 @@ namespace Steamworks { - internal unsafe class ISteamNetworkingSockets : SteamInterface + internal unsafe partial class ISteamNetworkingSockets : SteamInterface { internal ISteamNetworkingSockets( bool IsGameServer ) diff --git a/Facepunch.Steamworks/Generated/Interfaces/ISteamNetworkingUtils.cs b/Facepunch.Steamworks/Generated/Interfaces/ISteamNetworkingUtils.cs index 50d6d7d3..22b1e6d6 100644 --- a/Facepunch.Steamworks/Generated/Interfaces/ISteamNetworkingUtils.cs +++ b/Facepunch.Steamworks/Generated/Interfaces/ISteamNetworkingUtils.cs @@ -7,7 +7,7 @@ namespace Steamworks { - internal unsafe class ISteamNetworkingUtils : SteamInterface + internal unsafe partial class ISteamNetworkingUtils : SteamInterface { internal ISteamNetworkingUtils( bool IsGameServer ) diff --git a/Facepunch.Steamworks/Generated/Interfaces/ISteamParentalSettings.cs b/Facepunch.Steamworks/Generated/Interfaces/ISteamParentalSettings.cs index 56bfb1e6..8ec9c09e 100644 --- a/Facepunch.Steamworks/Generated/Interfaces/ISteamParentalSettings.cs +++ b/Facepunch.Steamworks/Generated/Interfaces/ISteamParentalSettings.cs @@ -7,7 +7,7 @@ namespace Steamworks { - internal unsafe class ISteamParentalSettings : SteamInterface + internal unsafe partial class ISteamParentalSettings : SteamInterface { internal ISteamParentalSettings( bool IsGameServer ) diff --git a/Facepunch.Steamworks/Generated/Interfaces/ISteamParties.cs b/Facepunch.Steamworks/Generated/Interfaces/ISteamParties.cs index e9585ec8..d11fd337 100644 --- a/Facepunch.Steamworks/Generated/Interfaces/ISteamParties.cs +++ b/Facepunch.Steamworks/Generated/Interfaces/ISteamParties.cs @@ -7,7 +7,7 @@ namespace Steamworks { - internal unsafe class ISteamParties : SteamInterface + internal unsafe partial class ISteamParties : SteamInterface { internal ISteamParties( bool IsGameServer ) diff --git a/Facepunch.Steamworks/Generated/Interfaces/ISteamRemotePlay.cs b/Facepunch.Steamworks/Generated/Interfaces/ISteamRemotePlay.cs index 6ad42043..2f39931f 100644 --- a/Facepunch.Steamworks/Generated/Interfaces/ISteamRemotePlay.cs +++ b/Facepunch.Steamworks/Generated/Interfaces/ISteamRemotePlay.cs @@ -7,7 +7,7 @@ namespace Steamworks { - internal unsafe class ISteamRemotePlay : SteamInterface + internal unsafe partial class ISteamRemotePlay : SteamInterface { internal ISteamRemotePlay( bool IsGameServer ) diff --git a/Facepunch.Steamworks/Generated/Interfaces/ISteamRemoteStorage.cs b/Facepunch.Steamworks/Generated/Interfaces/ISteamRemoteStorage.cs index c1a87211..2fdda846 100644 --- a/Facepunch.Steamworks/Generated/Interfaces/ISteamRemoteStorage.cs +++ b/Facepunch.Steamworks/Generated/Interfaces/ISteamRemoteStorage.cs @@ -7,7 +7,7 @@ namespace Steamworks { - internal unsafe class ISteamRemoteStorage : SteamInterface + internal unsafe partial class ISteamRemoteStorage : SteamInterface { internal ISteamRemoteStorage( bool IsGameServer ) diff --git a/Facepunch.Steamworks/Generated/Interfaces/ISteamScreenshots.cs b/Facepunch.Steamworks/Generated/Interfaces/ISteamScreenshots.cs index ff9380a3..e1fd7567 100644 --- a/Facepunch.Steamworks/Generated/Interfaces/ISteamScreenshots.cs +++ b/Facepunch.Steamworks/Generated/Interfaces/ISteamScreenshots.cs @@ -7,7 +7,7 @@ namespace Steamworks { - internal unsafe class ISteamScreenshots : SteamInterface + internal unsafe partial class ISteamScreenshots : SteamInterface { internal ISteamScreenshots( bool IsGameServer ) diff --git a/Facepunch.Steamworks/Generated/Interfaces/ISteamUGC.cs b/Facepunch.Steamworks/Generated/Interfaces/ISteamUGC.cs index 758020c6..1c54bc14 100644 --- a/Facepunch.Steamworks/Generated/Interfaces/ISteamUGC.cs +++ b/Facepunch.Steamworks/Generated/Interfaces/ISteamUGC.cs @@ -7,7 +7,7 @@ namespace Steamworks { - internal unsafe class ISteamUGC : SteamInterface + internal unsafe partial class ISteamUGC : SteamInterface { internal ISteamUGC( bool IsGameServer ) diff --git a/Facepunch.Steamworks/Generated/Interfaces/ISteamUser.cs b/Facepunch.Steamworks/Generated/Interfaces/ISteamUser.cs index 18147edf..35eb5f9b 100644 --- a/Facepunch.Steamworks/Generated/Interfaces/ISteamUser.cs +++ b/Facepunch.Steamworks/Generated/Interfaces/ISteamUser.cs @@ -7,7 +7,7 @@ namespace Steamworks { - internal unsafe class ISteamUser : SteamInterface + internal unsafe partial class ISteamUser : SteamInterface { internal ISteamUser( bool IsGameServer ) diff --git a/Facepunch.Steamworks/Generated/Interfaces/ISteamUserStats.cs b/Facepunch.Steamworks/Generated/Interfaces/ISteamUserStats.cs index ab98ca63..ae3f3a50 100644 --- a/Facepunch.Steamworks/Generated/Interfaces/ISteamUserStats.cs +++ b/Facepunch.Steamworks/Generated/Interfaces/ISteamUserStats.cs @@ -7,7 +7,7 @@ namespace Steamworks { - internal unsafe class ISteamUserStats : SteamInterface + internal unsafe partial class ISteamUserStats : SteamInterface { internal ISteamUserStats( bool IsGameServer ) diff --git a/Facepunch.Steamworks/Generated/Interfaces/ISteamUtils.cs b/Facepunch.Steamworks/Generated/Interfaces/ISteamUtils.cs index f0a4cf54..83f1abc4 100644 --- a/Facepunch.Steamworks/Generated/Interfaces/ISteamUtils.cs +++ b/Facepunch.Steamworks/Generated/Interfaces/ISteamUtils.cs @@ -7,7 +7,7 @@ namespace Steamworks { - internal unsafe class ISteamUtils : SteamInterface + internal unsafe partial class ISteamUtils : SteamInterface { internal ISteamUtils( bool IsGameServer ) diff --git a/Facepunch.Steamworks/Generated/Interfaces/ISteamVideo.cs b/Facepunch.Steamworks/Generated/Interfaces/ISteamVideo.cs index bd4d029a..137e2144 100644 --- a/Facepunch.Steamworks/Generated/Interfaces/ISteamVideo.cs +++ b/Facepunch.Steamworks/Generated/Interfaces/ISteamVideo.cs @@ -7,7 +7,7 @@ namespace Steamworks { - internal unsafe class ISteamVideo : SteamInterface + internal unsafe partial class ISteamVideo : SteamInterface { internal ISteamVideo( bool IsGameServer ) diff --git a/Facepunch.Steamworks/Generated/SteamStructs.cs b/Facepunch.Steamworks/Generated/SteamStructs.cs index 13e0b4a6..8724de68 100644 --- a/Facepunch.Steamworks/Generated/SteamStructs.cs +++ b/Facepunch.Steamworks/Generated/SteamStructs.cs @@ -25,17 +25,14 @@ internal partial struct servernetadr_t internal uint IP; // m_unIP uint32 } - + [StructLayout( LayoutKind.Sequential, Pack = Platform.StructPackSize )] internal partial struct gameserveritem_t { internal servernetadr_t NetAdr; // m_NetAdr servernetadr_t internal int Ping; // m_nPing int - - // NOTE: If you add fields above this you must change offset inISteamMatchmakingServers.HasServerResponded() [MarshalAs(UnmanagedType.I1)] internal bool HadSuccessfulResponse; // m_bHadSuccessfulResponse bool - [MarshalAs(UnmanagedType.I1)] internal bool DoNotRefresh; // m_bDoNotRefresh bool internal string GameDirUTF8() => System.Text.Encoding.UTF8.GetString( GameDir, 0, System.Array.IndexOf( GameDir, 0 ) ); From a80e8590d579595970dfde8a22337249db46136a Mon Sep 17 00:00:00 2001 From: Jake Rich Date: Mon, 12 Aug 2024 21:30:28 -0400 Subject: [PATCH 4/5] Add ISteamMatchmakingServers.HasServerResponded() to partial class instead --- .../Interfaces/ISteamMatchmakingServers.cs | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 Facepunch.Steamworks/Interfaces/ISteamMatchmakingServers.cs diff --git a/Facepunch.Steamworks/Interfaces/ISteamMatchmakingServers.cs b/Facepunch.Steamworks/Interfaces/ISteamMatchmakingServers.cs new file mode 100644 index 00000000..3f555e71 --- /dev/null +++ b/Facepunch.Steamworks/Interfaces/ISteamMatchmakingServers.cs @@ -0,0 +1,28 @@ +using Steamworks.Data; +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.Text; + +namespace Steamworks +{ + internal partial class ISteamMatchmakingServers + { + /// + /// Read gameserveritem_t.m_bHadSuccessfulResponse without allocating the struct on the heap + /// + /// + /// + /// + internal bool HasServerResponded( HServerListRequest hRequest, int iServer ) + { + IntPtr returnValue = _GetServerDetails( Self, hRequest, iServer ); + + // Return false if steam returned null + if ( returnValue == IntPtr.Zero ) return false; + + // first 8 bytes is IPAddress, next 4 bytes is ping, next 1 byte is m_bHadSuccessfulResponse + return Marshal.ReadByte( IntPtr.Add( returnValue, 12 ) ) == 1; + } + } +} From 7f747b04688f1ce25cdb7636e8fd2345f9a052fa Mon Sep 17 00:00:00 2001 From: Jake Rich Date: Mon, 12 Aug 2024 21:44:23 -0400 Subject: [PATCH 5/5] Automatically get the field offset of gameserveritem_t.HasSuccessfulResponse instead of hardcoding it --- .../Interfaces/ISteamMatchmakingServers.cs | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/Facepunch.Steamworks/Interfaces/ISteamMatchmakingServers.cs b/Facepunch.Steamworks/Interfaces/ISteamMatchmakingServers.cs index 3f555e71..070ee12e 100644 --- a/Facepunch.Steamworks/Interfaces/ISteamMatchmakingServers.cs +++ b/Facepunch.Steamworks/Interfaces/ISteamMatchmakingServers.cs @@ -8,6 +8,9 @@ namespace Steamworks { internal partial class ISteamMatchmakingServers { + // Cached offset of gameserveritem_t.m_bHadSuccessfulResponse + private static int hasSuccessfulResponseOffset; + /// /// Read gameserveritem_t.m_bHadSuccessfulResponse without allocating the struct on the heap /// @@ -21,8 +24,19 @@ internal bool HasServerResponded( HServerListRequest hRequest, int iServer ) // Return false if steam returned null if ( returnValue == IntPtr.Zero ) return false; - // first 8 bytes is IPAddress, next 4 bytes is ping, next 1 byte is m_bHadSuccessfulResponse - return Marshal.ReadByte( IntPtr.Add( returnValue, 12 ) ) == 1; + // Cache the offset of m_bHadSuccessfulResponse + if ( hasSuccessfulResponseOffset == 0 ) + { + hasSuccessfulResponseOffset = Marshal.OffsetOf( nameof( gameserveritem_t.HadSuccessfulResponse ) ).ToInt32(); + + if ( hasSuccessfulResponseOffset == 0 ) + { + throw new Exception( "Failed to get offset of gameserveritem_t.HadSuccessfulResponse" ); + } + } + + // Read byte m_bHadSuccessfulResponse + return Marshal.ReadByte( IntPtr.Add( returnValue, hasSuccessfulResponseOffset ) ) == 1; } } }