ServerList filters wip

This commit is contained in:
Garry Newman 2016-07-18 17:32:09 +01:00
parent 99e1740961
commit 761b9ce70d
4 changed files with 157 additions and 13 deletions

View File

@ -17,13 +17,24 @@ public void InternetList()
{ {
using ( var client = new Facepunch.Steamworks.Client( 252490 ) ) using ( var client = new Facepunch.Steamworks.Client( 252490 ) )
{ {
var query = client.ServerList.Test(); var filter = new Dictionary<string, string>();
filter.Add( "appid", client.AppId.ToString() );
filter.Add( "gamedir", "rust" );
filter.Add( "secure", "1" );
for ( int i = 0; i < 100; i++ ) var query = client.ServerList.Internet( filter );
for ( int i = 0; i < 1000; i++ )
{ {
client.Update(); client.Update();
System.Threading.Thread.Sleep( 10 ); System.Threading.Thread.Sleep( 10 );
foreach ( var s in query.Responded )
{
Assert.AreEqual( s.AppId, client.AppId );
Assert.AreEqual( s.GameDir, "rust" );
}
if ( query.Finished ) if ( query.Finished )
break; break;
} }
@ -48,8 +59,11 @@ public void MultipleInternetList()
{ {
var queries = new List< Facepunch.Steamworks.ServerList.Request >(); var queries = new List< Facepunch.Steamworks.ServerList.Request >();
var filter = new Dictionary<string, string>();
filter.Add( "map", "barren" );
for ( int i = 0; i < 10; i++ ) for ( int i = 0; i < 10; i++ )
queries.Add( client.ServerList.Test() ); queries.Add( client.ServerList.Internet( filter ) );
for ( int i = 0; i < 100; i++ ) for ( int i = 0; i < 100; i++ )
{ {
@ -72,12 +86,47 @@ public void MultipleInternetList()
} }
} }
[TestMethod]
public void Filters()
{
using ( var client = new Facepunch.Steamworks.Client( 252490 ) )
{
var filter = new Dictionary<string, string>();
filter.Add( "map", "barren" );
var query = client.ServerList.Internet( filter );
while ( true )
{
client.Update();
System.Threading.Thread.Sleep( 2 );
if ( query.Finished )
break;
}
foreach ( var x in query.Responded )
{
Assert.AreEqual( x.Map.ToLower(), "barren" );
}
query.Dispose();
for ( int i = 0; i < 100; i++ )
{
client.Update();
System.Threading.Thread.Sleep( 1 );
}
}
}
[TestMethod] [TestMethod]
public void HistoryList() public void HistoryList()
{ {
using ( var client = new Facepunch.Steamworks.Client( 252490 ) ) using ( var client = new Facepunch.Steamworks.Client( 252490 ) )
{ {
var query = client.ServerList.History( new Dictionary<string, string>() ); var query = client.ServerList.History();
while ( true ) while ( true )
{ {
@ -91,6 +140,11 @@ public void HistoryList()
Console.WriteLine( "Responded: " + query.Responded.Count.ToString() ); Console.WriteLine( "Responded: " + query.Responded.Count.ToString() );
Console.WriteLine( "Unresponsive: " + query.Unresponsive.Count.ToString() ); Console.WriteLine( "Unresponsive: " + query.Unresponsive.Count.ToString() );
foreach ( var x in query.Responded )
{
Console.WriteLine( x.Map );
}
query.Dispose(); query.Dispose();
for ( int i = 0; i < 100; i++ ) for ( int i = 0; i < 100; i++ )

View File

@ -14,6 +14,8 @@ public class Request : IDisposable
internal Client client; internal Client client;
internal IntPtr Id; internal IntPtr Id;
public Action OnUpdate;
public struct Server public struct Server
{ {
public string Name { get; set; } public string Name { get; set; }
@ -73,7 +75,7 @@ internal static Server FromSteam( gameserveritem_t item )
Secure = item.m_bSecure, Secure = item.m_bSecure,
LastTimePlayed = item.m_ulTimeLastPlayed, LastTimePlayed = item.m_ulTimeLastPlayed,
Version = item.m_nServerVersion, Version = item.m_nServerVersion,
Tags = item.m_szGameTags.Split( ',' ), Tags = item.m_szGameTags == null ? null : item.m_szGameTags.Split( ',' ),
SteamId = item.m_steamID SteamId = item.m_steamID
}; };
} }
@ -116,6 +118,8 @@ private void Update()
if ( Id == IntPtr.Zero ) if ( Id == IntPtr.Zero )
return; return;
bool changes = false;
// //
// Add any servers we're not watching to our watch list // Add any servers we're not watching to our watch list
// //
@ -139,6 +143,7 @@ private void Update()
if ( info.m_bHadSuccessfulResponse ) if ( info.m_bHadSuccessfulResponse )
{ {
OnServer( info ); OnServer( info );
changes = true;
return true; return true;
} }
@ -164,7 +169,11 @@ private void Update()
client.OnUpdate -= Update; client.OnUpdate -= Update;
client.native.servers.CancelQuery( Id ); client.native.servers.CancelQuery( Id );
Id = IntPtr.Zero; Id = IntPtr.Zero;
changes = true;
} }
if ( changes && OnUpdate != null)
OnUpdate();
} }
private void OnServer( gameserveritem_t info ) private void OnServer( gameserveritem_t info )

View File

@ -40,17 +40,29 @@ private struct MatchPair
public unsafe Request Test() public unsafe Request Test()
{ {
var filters = new List<MatchPair>(); var filters = new Dictionary<string, string>();
filters.Add( new MatchPair() { key = "gamedir", value = "rust" } ); filters.Add("gamedir", "rust" );
var array = filters.ToArray(); var array = filters.ToArray();
//fixed ( void* a = array ) //fixed ( void* a = array )
{ {
var pairs = filters.Select( x => new MatchMakingKeyValuePair_t()
{
m_szKey = x.Key,
m_szValue = x.Value
}).ToArray();
var request = new Request( client ); var request = new Request( client );
request.Id = client.native.servers.RequestInternetServerList( client.AppId, new IntPtr[] { }, IntPtr.Zero ); GCHandle h = GCHandle.Alloc( pairs, GCHandleType.Pinned );
var a = h.AddrOfPinnedObject();
// request.Id = client.native.servers.RequestInternetServerList( client.AppId, h.AddrOfPinnedObject(), pairs.Length, IntPtr.Zero );
h.Free();
return request; return request;
} }
@ -79,7 +91,64 @@ internal override void ServerResponded( uint hRequest, int iServer )
} }
} }
public unsafe Request History( Dictionary< string, string > filter ) private IntPtr m_pNativeArray;
private IntPtr m_pArrayEntries;
internal void FilterStart( Dictionary<string, string> filter )
{
var filters = filter.Select( x =>
{
return new MatchMakingKeyValuePair_t()
{
m_szKey = x.Key,
m_szValue = x.Value
};
} ).ToArray();
int sizeOfMMKVP = Marshal.SizeOf(typeof(MatchMakingKeyValuePair_t));
m_pNativeArray = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( IntPtr ) ) * filters.Length );
m_pArrayEntries = Marshal.AllocHGlobal( sizeOfMMKVP * filters.Length );
for ( int i = 0; i < filters.Length; ++i )
{
Marshal.StructureToPtr( filters[i], new IntPtr( m_pArrayEntries.ToInt64() + ( i * sizeOfMMKVP ) ), false );
}
Marshal.WriteIntPtr( m_pNativeArray, m_pArrayEntries );
}
internal void FilterFree()
{
if ( m_pArrayEntries != IntPtr.Zero )
{
Marshal.FreeHGlobal( m_pArrayEntries );
}
if ( m_pNativeArray != IntPtr.Zero )
{
Marshal.FreeHGlobal( m_pNativeArray );
}
}
public Request Internet( Dictionary< string, string > filter )
{
FilterStart( filter );
var request = new Request( client );
request.Id = client.native.servers.RequestInternetServerList( client.AppId, m_pNativeArray, filter.Count, IntPtr.Zero );
FilterFree();
return request;
}
/// <summary>
/// History filters don't seem to work, so we don't bother.
/// You should apply them post process'dly
/// </summary>
public Request History()
{ {
var request = new Request( client ); var request = new Request( client );
request.Id = client.native.servers.RequestHistoryServerList( client.AppId, new IntPtr[] { }, IntPtr.Zero ); request.Id = client.native.servers.RequestHistoryServerList( client.AppId, new IntPtr[] { }, IntPtr.Zero );
@ -87,6 +156,18 @@ public unsafe Request History( Dictionary< string, string > filter )
return request; return request;
} }
/// <summary>
/// Favourite filters don't seem to work, so we don't bother.
/// You should apply them post process'dly
/// </summary>
public Request Favourites()
{
var request = new Request( client );
request.Id = client.native.servers.RequestFavoritesServerList( client.AppId, new IntPtr[] { }, IntPtr.Zero );
return request;
}
public void AddToHistory( Request.Server server ) public void AddToHistory( Request.Server server )
{ {
// client.native.matchmaking // client.native.matchmaking

View File

@ -426,7 +426,7 @@ internal class NativeEntrypoints
[DllImportAttribute( "FacepunchSteamworksApi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamMatchmakingRulesResponse_RulesRefreshComplete" )] [DllImportAttribute( "FacepunchSteamworksApi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamMatchmakingRulesResponse_RulesRefreshComplete" )]
internal static extern void SteamAPI_ISteamMatchmakingRulesResponse_RulesRefreshComplete( IntPtr instancePtr ); internal static extern void SteamAPI_ISteamMatchmakingRulesResponse_RulesRefreshComplete( IntPtr instancePtr );
[DllImportAttribute( "FacepunchSteamworksApi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamMatchmakingServers_RequestInternetServerList" )] [DllImportAttribute( "FacepunchSteamworksApi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamMatchmakingServers_RequestInternetServerList" )]
internal static extern IntPtr SteamAPI_ISteamMatchmakingServers_RequestInternetServerList( IntPtr instancePtr, uint iApp, [In, Out] IntPtr[] ppchFilters, uint nFilters, IntPtr pRequestServersResponse ); internal static extern IntPtr SteamAPI_ISteamMatchmakingServers_RequestInternetServerList( IntPtr instancePtr, uint iApp, [In, Out] IntPtr ppchFilters, uint nFilters, IntPtr pRequestServersResponse );
[DllImportAttribute( "FacepunchSteamworksApi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamMatchmakingServers_RequestLANServerList" )] [DllImportAttribute( "FacepunchSteamworksApi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamMatchmakingServers_RequestLANServerList" )]
internal static extern IntPtr SteamAPI_ISteamMatchmakingServers_RequestLANServerList( IntPtr instancePtr, uint iApp, IntPtr pRequestServersResponse ); internal static extern IntPtr SteamAPI_ISteamMatchmakingServers_RequestLANServerList( IntPtr instancePtr, uint iApp, IntPtr pRequestServersResponse );
[DllImportAttribute( "FacepunchSteamworksApi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamMatchmakingServers_RequestFriendsServerList" )] [DllImportAttribute( "FacepunchSteamworksApi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SteamAPI_ISteamMatchmakingServers_RequestFriendsServerList" )]
@ -1816,7 +1816,7 @@ internal abstract class ISteamMatchmakingRulesResponse
internal abstract class ISteamMatchmakingServers internal abstract class ISteamMatchmakingServers
{ {
internal abstract IntPtr GetIntPtr(); internal abstract IntPtr GetIntPtr();
internal abstract IntPtr RequestInternetServerList( uint iApp, IntPtr[] ppchFilters, IntPtr pRequestServersResponse ); internal abstract IntPtr RequestInternetServerList( uint iApp, IntPtr ppchFilters, int length, IntPtr pRequestServersResponse );
internal abstract IntPtr RequestLANServerList( uint iApp, IntPtr pRequestServersResponse ); internal abstract IntPtr RequestLANServerList( uint iApp, IntPtr pRequestServersResponse );
internal abstract IntPtr RequestFriendsServerList( uint iApp, IntPtr[] ppchFilters, IntPtr pRequestServersResponse ); internal abstract IntPtr RequestFriendsServerList( uint iApp, IntPtr[] ppchFilters, IntPtr pRequestServersResponse );
internal abstract IntPtr RequestFavoritesServerList( uint iApp, IntPtr[] ppchFilters, IntPtr pRequestServersResponse ); internal abstract IntPtr RequestFavoritesServerList( uint iApp, IntPtr[] ppchFilters, IntPtr pRequestServersResponse );
@ -3775,10 +3775,10 @@ private void CheckIfUsable()
throw new Exception( "Steam Pointer not configured" ); throw new Exception( "Steam Pointer not configured" );
} }
} }
internal override IntPtr RequestInternetServerList( uint iApp, IntPtr[] ppchFilters, IntPtr pRequestServersResponse ) internal override IntPtr RequestInternetServerList( uint iApp, IntPtr ppchFilters, int length, IntPtr pRequestServersResponse )
{ {
CheckIfUsable(); CheckIfUsable();
IntPtr result = NativeEntrypoints.SteamAPI_ISteamMatchmakingServers_RequestInternetServerList(m_pSteamMatchmakingServers,iApp,ppchFilters,(uint) ppchFilters.Length,pRequestServersResponse); IntPtr result = NativeEntrypoints.SteamAPI_ISteamMatchmakingServers_RequestInternetServerList(m_pSteamMatchmakingServers,iApp,ppchFilters,(uint) length,pRequestServersResponse);
return result; return result;
} }
internal override IntPtr RequestLANServerList( uint iApp, IntPtr pRequestServersResponse ) internal override IntPtr RequestLANServerList( uint iApp, IntPtr pRequestServersResponse )