Manually marshal server list filters to fix crashing

This commit is contained in:
Rohan Singh 2024-12-13 19:44:08 -05:00
parent 3b58a3dc92
commit 5783d89634
8 changed files with 90 additions and 50 deletions

View File

@ -23,12 +23,12 @@ internal ISteamMatchmakingServers( bool IsGameServer )
#region FunctionMeta
[DllImport( Platform.LibraryName, EntryPoint = "SteamAPI_ISteamMatchmakingServers_RequestInternetServerList", CallingConvention = Platform.CC)]
private static extern HServerListRequest _RequestInternetServerList( IntPtr self, AppId iApp, [In,Out] ref MatchMakingKeyValuePair[] ppchFilters, uint nFilters, IntPtr pRequestServersResponse );
private static extern HServerListRequest _RequestInternetServerList( IntPtr self, AppId iApp, IntPtr ppchFilters, uint nFilters, IntPtr pRequestServersResponse );
#endregion
internal HServerListRequest RequestInternetServerList( AppId iApp, [In,Out] ref MatchMakingKeyValuePair[] ppchFilters, uint nFilters, IntPtr pRequestServersResponse )
internal HServerListRequest RequestInternetServerList( AppId iApp, IntPtr ppchFilters, uint nFilters, IntPtr pRequestServersResponse )
{
var returnValue = _RequestInternetServerList( Self, iApp, ref ppchFilters, nFilters, pRequestServersResponse );
var returnValue = _RequestInternetServerList( Self, iApp, ppchFilters, nFilters, pRequestServersResponse );
return returnValue;
}
@ -45,45 +45,45 @@ internal HServerListRequest RequestLANServerList( AppId iApp, IntPtr pRequestSer
#region FunctionMeta
[DllImport( Platform.LibraryName, EntryPoint = "SteamAPI_ISteamMatchmakingServers_RequestFriendsServerList", CallingConvention = Platform.CC)]
private static extern HServerListRequest _RequestFriendsServerList( IntPtr self, AppId iApp, [In,Out] ref MatchMakingKeyValuePair[] ppchFilters, uint nFilters, IntPtr pRequestServersResponse );
private static extern HServerListRequest _RequestFriendsServerList( IntPtr self, AppId iApp, IntPtr ppchFilters, uint nFilters, IntPtr pRequestServersResponse );
#endregion
internal HServerListRequest RequestFriendsServerList( AppId iApp, [In,Out] ref MatchMakingKeyValuePair[] ppchFilters, uint nFilters, IntPtr pRequestServersResponse )
internal HServerListRequest RequestFriendsServerList( AppId iApp, IntPtr ppchFilters, uint nFilters, IntPtr pRequestServersResponse )
{
var returnValue = _RequestFriendsServerList( Self, iApp, ref ppchFilters, nFilters, pRequestServersResponse );
var returnValue = _RequestFriendsServerList( Self, iApp, ppchFilters, nFilters, pRequestServersResponse );
return returnValue;
}
#region FunctionMeta
[DllImport( Platform.LibraryName, EntryPoint = "SteamAPI_ISteamMatchmakingServers_RequestFavoritesServerList", CallingConvention = Platform.CC)]
private static extern HServerListRequest _RequestFavoritesServerList( IntPtr self, AppId iApp, [In,Out] ref MatchMakingKeyValuePair[] ppchFilters, uint nFilters, IntPtr pRequestServersResponse );
private static extern HServerListRequest _RequestFavoritesServerList( IntPtr self, AppId iApp, IntPtr ppchFilters, uint nFilters, IntPtr pRequestServersResponse );
#endregion
internal HServerListRequest RequestFavoritesServerList( AppId iApp, [In,Out] ref MatchMakingKeyValuePair[] ppchFilters, uint nFilters, IntPtr pRequestServersResponse )
internal HServerListRequest RequestFavoritesServerList( AppId iApp, IntPtr ppchFilters, uint nFilters, IntPtr pRequestServersResponse )
{
var returnValue = _RequestFavoritesServerList( Self, iApp, ref ppchFilters, nFilters, pRequestServersResponse );
var returnValue = _RequestFavoritesServerList( Self, iApp, ppchFilters, nFilters, pRequestServersResponse );
return returnValue;
}
#region FunctionMeta
[DllImport( Platform.LibraryName, EntryPoint = "SteamAPI_ISteamMatchmakingServers_RequestHistoryServerList", CallingConvention = Platform.CC)]
private static extern HServerListRequest _RequestHistoryServerList( IntPtr self, AppId iApp, [In,Out] ref MatchMakingKeyValuePair[] ppchFilters, uint nFilters, IntPtr pRequestServersResponse );
private static extern HServerListRequest _RequestHistoryServerList( IntPtr self, AppId iApp, IntPtr ppchFilters, uint nFilters, IntPtr pRequestServersResponse );
#endregion
internal HServerListRequest RequestHistoryServerList( AppId iApp, [In,Out] ref MatchMakingKeyValuePair[] ppchFilters, uint nFilters, IntPtr pRequestServersResponse )
internal HServerListRequest RequestHistoryServerList( AppId iApp, IntPtr ppchFilters, uint nFilters, IntPtr pRequestServersResponse )
{
var returnValue = _RequestHistoryServerList( Self, iApp, ref ppchFilters, nFilters, pRequestServersResponse );
var returnValue = _RequestHistoryServerList( Self, iApp, ppchFilters, nFilters, pRequestServersResponse );
return returnValue;
}
#region FunctionMeta
[DllImport( Platform.LibraryName, EntryPoint = "SteamAPI_ISteamMatchmakingServers_RequestSpectatorServerList", CallingConvention = Platform.CC)]
private static extern HServerListRequest _RequestSpectatorServerList( IntPtr self, AppId iApp, [In,Out] ref MatchMakingKeyValuePair[] ppchFilters, uint nFilters, IntPtr pRequestServersResponse );
private static extern HServerListRequest _RequestSpectatorServerList( IntPtr self, AppId iApp, IntPtr ppchFilters, uint nFilters, IntPtr pRequestServersResponse );
#endregion
internal HServerListRequest RequestSpectatorServerList( AppId iApp, [In,Out] ref MatchMakingKeyValuePair[] ppchFilters, uint nFilters, IntPtr pRequestServersResponse )
internal HServerListRequest RequestSpectatorServerList( AppId iApp, IntPtr ppchFilters, uint nFilters, IntPtr pRequestServersResponse )
{
var returnValue = _RequestSpectatorServerList( Self, iApp, ref ppchFilters, nFilters, pRequestServersResponse );
var returnValue = _RequestSpectatorServerList( Self, iApp, ppchFilters, nFilters, pRequestServersResponse );
return returnValue;
}

View File

@ -1,8 +1,4 @@
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace Steamworks.ServerList
{
@ -10,8 +6,8 @@ public class Favourites : Base
{
internal override void LaunchQuery()
{
var filters = GetFilters();
request = Internal.RequestFavoritesServerList( AppId.Value, ref filters, (uint)filters.Length, IntPtr.Zero );
using var filters = new ServerFilterMarshaler( GetFilters() );
request = Internal.RequestFavoritesServerList( AppId.Value, filters.Pointer, (uint)filters.Count, IntPtr.Zero );
}
}
}

View File

@ -1,8 +1,4 @@
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace Steamworks.ServerList
{
@ -10,8 +6,8 @@ public class Friends : Base
{
internal override void LaunchQuery()
{
var filters = GetFilters();
request = Internal.RequestFriendsServerList( AppId.Value, ref filters, (uint)filters.Length, IntPtr.Zero );
using var filters = new ServerFilterMarshaler( GetFilters() );
request = Internal.RequestFriendsServerList( AppId.Value, filters.Pointer, (uint)filters.Count, IntPtr.Zero );
}
}
}

View File

@ -1,8 +1,4 @@
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace Steamworks.ServerList
{
@ -10,8 +6,8 @@ public class History : Base
{
internal override void LaunchQuery()
{
var filters = GetFilters();
request = Internal.RequestHistoryServerList( AppId.Value, ref filters, (uint)filters.Length, IntPtr.Zero );
using var filters = new ServerFilterMarshaler( GetFilters() );
request = Internal.RequestHistoryServerList( AppId.Value, filters.Pointer, (uint)filters.Count, IntPtr.Zero );
}
}
}

View File

@ -1,8 +1,4 @@
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace Steamworks.ServerList
{
@ -10,9 +6,8 @@ public class Internet : Base
{
internal override void LaunchQuery()
{
var filters = GetFilters();
request = Internal.RequestInternetServerList( AppId.Value, ref filters, (uint)filters.Length, IntPtr.Zero );
using var filters = new ServerFilterMarshaler( GetFilters() );
request = Internal.RequestInternetServerList( AppId.Value, filters.Pointer, (uint)filters.Count, IntPtr.Zero );
}
}
}

View File

@ -1,8 +1,4 @@
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace Steamworks.ServerList
{

View File

@ -0,0 +1,58 @@
using System;
using System.Runtime.InteropServices;
using Steamworks.Data;
namespace Steamworks.ServerList;
internal struct ServerFilterMarshaler : IDisposable
{
private static readonly int SizeOfPointer = Marshal.SizeOf<IntPtr>();
private static readonly int SizeOfKeyValuePair = Marshal.SizeOf<MatchMakingKeyValuePair>();
private IntPtr _arrayPtr;
private IntPtr _itemsPtr;
public int Count { get; private set; }
public IntPtr Pointer => _arrayPtr;
public ServerFilterMarshaler( MatchMakingKeyValuePair[] filters )
{
if ( filters == null || filters.Length == 0 )
{
Count = 0;
_arrayPtr = IntPtr.Zero;
_itemsPtr = IntPtr.Zero;
return;
}
Count = filters.Length;
_arrayPtr = Marshal.AllocHGlobal( SizeOfPointer * filters.Length );
_itemsPtr = Marshal.AllocHGlobal( SizeOfKeyValuePair * filters.Length );
var arrayDst = _arrayPtr;
var itemDst = _itemsPtr;
foreach ( var filter in filters )
{
Marshal.WriteIntPtr( arrayDst, itemDst );
arrayDst += SizeOfPointer;
Marshal.StructureToPtr( filter, itemDst, false );
itemDst += SizeOfKeyValuePair;
}
}
public void Dispose()
{
if ( _arrayPtr != IntPtr.Zero )
{
Marshal.FreeHGlobal( _arrayPtr );
_arrayPtr = IntPtr.Zero;
}
if ( _itemsPtr != IntPtr.Zero )
{
Marshal.FreeHGlobal( _itemsPtr );
_itemsPtr = IntPtr.Zero;
}
}
}

View File

@ -17,13 +17,16 @@ public static BaseType Parse( string type, string varname = null, string callres
{
type = Cleanup.ConvertType( type );
var typeNoSpaces = type.Replace( " ", "" );
if ( varname == "ppOutMessages" ) return new PointerType { NativeType = "void *", VarName = varname };
if ( type == "SteamAPIWarningMessageHook_t" ) return new PointerType { NativeType = type, VarName = varname };
if ( typeNoSpaces == "MatchMakingKeyValuePair**") return new PointerType { NativeType = "MatchMakingKeyValuePair_t", VarName = varname };
if ( type == "SteamAPICall_t" ) return new SteamApiCallType { NativeType = type, VarName = varname, CallResult = callresult };
if ( type == "void" ) return new VoidType { NativeType = type, VarName = varname };
if ( type.Replace( " ", "" ).StartsWith( "constchar*" ) ) return new ConstCharType { NativeType = type, VarName = varname };
if ( typeNoSpaces.StartsWith( "constchar*" ) ) return new ConstCharType { NativeType = type, VarName = varname };
if ( type == "char *" ) return new FetchStringType { NativeType = type, VarName = varname, BufferSizeParamName = bufferSizeName };
var basicType = type.Replace( "const ", "" ).Trim( ' ', '*', '&' );