Sped up ServerList.Custom using multiple queries (16 seconds+ to 2 seconds)

This commit is contained in:
Garry Newman 2016-10-06 12:00:08 +01:00
parent e181bef77b
commit 28baea049c
3 changed files with 119 additions and 97 deletions

View File

@ -273,7 +273,7 @@ public void CustomList()
for ( int i = 0; i < 1000; i++ ) for ( int i = 0; i < 1000; i++ )
{ {
client.Update(); client.Update();
System.Threading.Thread.Sleep( 10 ); System.Threading.Thread.Sleep( 20 );
if ( query.Finished ) if ( query.Finished )
break; break;
@ -284,7 +284,7 @@ public void CustomList()
foreach ( var s in query.Responded ) foreach ( var s in query.Responded )
{ {
Console.WriteLine( s.Name ); Console.WriteLine( "{0} - {1}", s.AddressString, s.Name );
} }
query.Dispose(); query.Dispose();

View File

@ -12,7 +12,77 @@ public partial class ServerList
public class Request : IDisposable public class Request : IDisposable
{ {
internal Client client; internal Client client;
internal IntPtr Id;
internal List<SubRequest> Requests = new List<SubRequest>();
internal class SubRequest
{
internal IntPtr Request;
internal int Pointer = 0;
internal List<int> WatchList = new List<int>();
internal bool Update( ISteamMatchmakingServers servers, Action<gameserveritem_t> OnServer, Action OnUpdate )
{
if ( Request == IntPtr.Zero )
return true;
bool changes = false;
//
// Add any servers we're not watching to our watch list
//
var count = servers.GetServerCount( Request );
if ( count != Pointer )
{
for ( int i = Pointer; i < count; i++ )
{
WatchList.Add( i );
}
}
Pointer = count;
//
// Remove any servers that respond successfully
//
WatchList.RemoveAll( x =>
{
var info = servers.GetServerDetails( Request, x );
if ( info.m_bHadSuccessfulResponse )
{
OnServer( info );
changes = true;
return true;
}
return false;
} );
//
// If we've finished refreshing
//
if ( servers.IsRefreshing( Request ) == false )
{
//
// Put any other servers on the 'no response' list
//
WatchList.RemoveAll( x =>
{
var info = servers.GetServerDetails( Request, x );
OnServer( info );
return true;
} );
servers.CancelQuery( Request );
Request = IntPtr.Zero;
changes = true;
}
if ( changes && OnUpdate != null )
OnUpdate();
return Request == IntPtr.Zero;
}
}
public Action OnUpdate; public Action OnUpdate;
@ -43,118 +113,69 @@ internal Request( Client c )
{ {
Dispose(); Dispose();
} }
int lastCount = 0;
internal List<int> watchlist = new List<int>();
internal IEnumerable<string> ServerList { get; set; } internal IEnumerable<string> ServerList { get; set; }
internal int ServerListPointer = 0;
void UpdateCustomQuery() internal void StartCustomQuery()
{ {
if ( ServerList == null ) if ( ServerList == null )
return; return;
if ( Id != IntPtr.Zero ) int blockSize = 16;
return; int Pointer = 0;
var sublist = ServerList.Skip( ServerListPointer ).Take( 10 ); while ( true )
if ( sublist.Count() == 0 )
{ {
ServerList = null; var sublist = ServerList.Skip( Pointer ).Take( blockSize );
ServerListPointer = 0;
Finished = true; if ( sublist.Count() == 0 )
return; break;
Pointer += sublist.Count();
var filter = new Filter();
filter.Add( "or", sublist.Count().ToString() );
foreach ( var server in sublist )
{
filter.Add( "gameaddr", server );
}
filter.Start();
var id = client.native.servers.RequestInternetServerList( client.AppId, filter.NativeArray, filter.Count, IntPtr.Zero );
filter.Free();
AddRequest( id );
} }
ServerListPointer += sublist.Count(); ServerList = null;
}
var filter = new Filter(); internal void AddRequest( IntPtr id )
filter.Add( "or", sublist.Count().ToString() ); {
Requests.Add( new SubRequest() { Request = id } );
foreach ( var server in sublist )
{
filter.Add( "gameaddr", server );
}
filter.Start();
Id = client.native.servers.RequestInternetServerList( client.AppId, filter.NativeArray, filter.Count, IntPtr.Zero );
filter.Free();
} }
private void Update() private void Update()
{ {
UpdateCustomQuery(); if ( Requests.Count == 0 )
if ( Id == IntPtr.Zero )
return; return;
bool changes = false; for( int i=0; i< Requests.Count(); i++ )
//
// Add any servers we're not watching to our watch list
//
var count = client.native.servers.GetServerCount( Id );
if ( count != lastCount )
{ {
for ( int i = lastCount; i < count; i++ ) if ( Requests[i].Update( client.native.servers, OnServer, OnUpdate ) )
{ {
watchlist.Add( i ); Requests.RemoveAt( i );
i--;
} }
lastCount = count;
} }
// if ( Requests.Count == 0 )
// Remove any servers that respond successfully
//
watchlist.RemoveAll( x =>
{ {
var info = client.native.servers.GetServerDetails( Id, x ); Finished = true;
if ( info.m_bHadSuccessfulResponse ) client.OnUpdate -= Update;
{
OnServer( info );
changes = true;
return true;
}
return false;
} );
//
// If we've finished refreshing
//
if ( client.native.servers.IsRefreshing( Id ) == false )
{
//
// Put any other servers on the 'no response' list
//
watchlist.RemoveAll( x =>
{
var info = client.native.servers.GetServerDetails( Id, x );
OnServer( info );
return true;
} );
//
// We have more to process
//
if ( ServerList == null )
{
Finished = true;
client.OnUpdate -= Update;
}
client.native.servers.CancelQuery( Id );
Id = IntPtr.Zero;
changes = true;
} }
if ( changes && OnUpdate != null)
OnUpdate();
} }
private void OnServer( gameserveritem_t info ) private void OnServer( gameserveritem_t info )
@ -180,13 +201,13 @@ public void Dispose()
// //
// Cancel the query if it's still running // Cancel the query if it's still running
// //
if ( Id != IntPtr.Zero ) foreach( var subRequest in Requests )
{ {
if ( client.IsValid ) if ( client.IsValid )
client.native.servers.CancelQuery( Id ); client.native.servers.CancelQuery( subRequest.Request );
Id = IntPtr.Zero;
} }
Requests.Clear();
} }
} }

View File

@ -90,7 +90,7 @@ public Request Internet( Filter filter )
filter.Start(); filter.Start();
var request = new Request( client ); var request = new Request( client );
request.Id = client.native.servers.RequestInternetServerList( client.AppId, filter.NativeArray, filter.Count, IntPtr.Zero ); request.AddRequest( client.native.servers.RequestInternetServerList( client.AppId, filter.NativeArray, filter.Count, IntPtr.Zero ) );
filter.Free(); filter.Free();
@ -101,6 +101,7 @@ public Request Custom( IEnumerable<string> serverList )
{ {
var request = new Request( client ); var request = new Request( client );
request.ServerList = serverList; request.ServerList = serverList;
request.StartCustomQuery();
return request; return request;
} }
@ -111,7 +112,7 @@ public Request Custom( IEnumerable<string> serverList )
public Request History() 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.AddRequest( client.native.servers.RequestHistoryServerList( client.AppId, new IntPtr[] { }, IntPtr.Zero ) );
return request; return request;
} }
@ -123,7 +124,7 @@ public Request History()
public Request Favourites() public Request Favourites()
{ {
var request = new Request( client ); var request = new Request( client );
request.Id = client.native.servers.RequestFavoritesServerList( client.AppId, new IntPtr[] { }, IntPtr.Zero ); request.AddRequest( client.native.servers.RequestFavoritesServerList( client.AppId, new IntPtr[] { }, IntPtr.Zero ) );
return request; return request;
} }