Skip to content

Commit

Permalink
Fix serverlist query allocating a large amount of memory when a large…
Browse files Browse the repository at this point in the history
… amount of servers are pending
  • Loading branch information
Jake-Rich committed Aug 13, 2024
1 parent 4463739 commit d18086a
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,24 @@ internal gameserveritem_t GetServerDetails( HServerListRequest hRequest, int iSe
var returnValue = _GetServerDetails( Self, hRequest, iServer );
return returnValue.ToType<gameserveritem_t>();
}


/// <summary>
/// Read gameserveritem_t.m_bHadSuccessfulResponse without allocating the struct on the heap
/// </summary>
/// <param name="hRequest"></param>
/// <param name="iServer"></param>
/// <returns></returns>
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 );
Expand Down
5 changes: 4 additions & 1 deletion Facepunch.Steamworks/Generated/SteamStructs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<byte>( GameDir, 0 ) );
Expand Down
16 changes: 11 additions & 5 deletions Facepunch.Steamworks/ServerList/Base.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -194,4 +200,4 @@ private void OnServer( ServerInfo serverInfo, bool responded )
Unresponsive.Add( serverInfo );
}
}
}
}

0 comments on commit d18086a

Please sign in to comment.