using System.Threading.Tasks;
using System.Collections.Generic;
namespace Steamworks.Data
{
public struct LobbyQuery
{
// TODO FILTERS
// AddRequestLobbyListStringFilter
// - WithoutKeyValue
#region Distance Filter
internal LobbyDistanceFilter? distance;
///
/// only lobbies in the same immediate region will be returned
///
public LobbyQuery FilterDistanceClose()
{
distance = LobbyDistanceFilter.Close;
return this;
}
///
/// only lobbies in the same immediate region will be returned
///
public LobbyQuery FilterDistanceFar()
{
distance = LobbyDistanceFilter.Far;
return this;
}
///
/// only lobbies in the same immediate region will be returned
///
public LobbyQuery FilterDistanceWorldwide()
{
distance = LobbyDistanceFilter.Worldwide;
return this;
}
#endregion
#region String key/value filter
internal Dictionary stringFilters;
internal Dictionary> stringFiltersExclude;
///
/// Filter by specified key/value pair; string parameters
///
public LobbyQuery WithKeyValue(string key, string value)
{
if (string.IsNullOrEmpty(key))
throw new System.ArgumentException("Key string provided for LobbyQuery filter is null or empty", nameof(key));
if (key.Length > SteamMatchmaking.MaxLobbyKeyLength)
throw new System.ArgumentException($"Key length is longer than {SteamMatchmaking.MaxLobbyKeyLength}", nameof(key));
if (stringFilters == null)
stringFilters = new Dictionary();
stringFilters.Add(key, value);
return this;
}
public LobbyQuery WithoutKeyValue(string key, string value)
{
if (string.IsNullOrEmpty(key))
throw new System.ArgumentException("Key string provided for LobbyQuery filter is null or empty", nameof(key));
if (key.Length > SteamMatchmaking.MaxLobbyKeyLength)
throw new System.ArgumentException($"Key length is longer than {SteamMatchmaking.MaxLobbyKeyLength}", nameof(key));
if (stringFiltersExclude == null)
stringFiltersExclude = new Dictionary>();
if (!stringFiltersExclude.ContainsKey(key))
{
stringFiltersExclude.Add(key, new List());
}
stringFiltersExclude[key].Add(value);
return this;
}
#endregion
#region Numerical filters
internal List numericalFilters;
///
/// Numerical filter where value is less than the value provided
///
public LobbyQuery WithLower( string key, int value )
{
AddNumericalFilter( key, value, LobbyComparison.LessThan );
return this;
}
///
/// Numerical filter where value is greater than the value provided
///
public LobbyQuery WithHigher( string key, int value )
{
AddNumericalFilter( key, value, LobbyComparison.GreaterThan );
return this;
}
///
/// Numerical filter where value must be equal to the value provided
///
public LobbyQuery WithEqual( string key, int value )
{
AddNumericalFilter( key, value, LobbyComparison.Equal );
return this;
}
///
/// Numerical filter where value must not equal the value provided
///
public LobbyQuery WithNotEqual( string key, int value )
{
AddNumericalFilter( key, value, LobbyComparison.NotEqual );
return this;
}
///
/// Test key, initialize numerical filter list if necessary, then add new numerical filter
///
internal void AddNumericalFilter( string key, int value, LobbyComparison compare )
{
if ( string.IsNullOrEmpty( key ) )
throw new System.ArgumentException( "Key string provided for LobbyQuery filter is null or empty", nameof( key ) );
if ( key.Length > SteamMatchmaking.MaxLobbyKeyLength )
throw new System.ArgumentException( $"Key length is longer than {SteamMatchmaking.MaxLobbyKeyLength}", nameof( key ) );
if ( numericalFilters == null )
numericalFilters = new List();
numericalFilters.Add( new NumericalFilter( key, value, compare ) );
}
#endregion
#region Near value filter
internal Dictionary nearValFilters;
///
/// Order filtered results according to key/values nearest the provided key/value pair.
/// Can specify multiple near value filters; each successive filter is lower priority than the previous.
///
public LobbyQuery OrderByNear( string key, int value )
{
if ( string.IsNullOrEmpty( key ) )
throw new System.ArgumentException( "Key string provided for LobbyQuery filter is null or empty", nameof( key ) );
if ( key.Length > SteamMatchmaking.MaxLobbyKeyLength )
throw new System.ArgumentException( $"Key length is longer than {SteamMatchmaking.MaxLobbyKeyLength}", nameof( key ) );
if ( nearValFilters == null )
nearValFilters = new Dictionary();
nearValFilters.Add( key, value );
return this;
}
#endregion
#region Slots Filter
internal int? slotsAvailable;
///
/// returns only lobbies with the specified number of slots available
///
public LobbyQuery WithSlotsAvailable( int minSlots )
{
slotsAvailable = minSlots;
return this;
}
#endregion
#region Max results filter
internal int? maxResults;
///
/// sets how many results to return, the lower the count the faster it is to download the lobby results
///
public LobbyQuery WithMaxResults( int max )
{
maxResults = max;
return this;
}
#endregion
void ApplyFilters()
{
if (SteamMatchmaking.Internal is null) { return; }
if ( distance.HasValue )
{
SteamMatchmaking.Internal.AddRequestLobbyListDistanceFilter( distance.Value );
}
if ( slotsAvailable.HasValue )
{
SteamMatchmaking.Internal.AddRequestLobbyListFilterSlotsAvailable( slotsAvailable.Value );
}
if (stringFilters != null)
{
foreach (var k in stringFilters)
{
SteamMatchmaking.Internal.AddRequestLobbyListStringFilter(k.Key, k.Value, LobbyComparison.Equal);
}
}
if (stringFiltersExclude != null)
{
foreach (var k in stringFiltersExclude)
{
foreach (var v in k.Value)
{
SteamMatchmaking.Internal.AddRequestLobbyListStringFilter(k.Key, v, LobbyComparison.NotEqual);
}
}
}
if ( numericalFilters != null )
{
foreach ( var n in numericalFilters )
{
SteamMatchmaking.Internal.AddRequestLobbyListNumericalFilter( n.Key, n.Value, n.Comparer );
}
}
if( nearValFilters != null )
{
foreach (var v in nearValFilters )
{
SteamMatchmaking.Internal.AddRequestLobbyListNearValueFilter( v.Key, v.Value );
}
}
if (maxResults.HasValue)
{
SteamMatchmaking.Internal.AddRequestLobbyListResultCountFilter(maxResults.Value);
}
}
///
/// Run the query, get the matching lobbies
///
public async Task RequestAsync()
{
if (SteamMatchmaking.Internal is null) { return null; }
await Task.Yield();
ApplyFilters();
LobbyMatchList_t? list = await SteamMatchmaking.Internal.RequestLobbyList();
if ( !list.HasValue || list.Value.LobbiesMatching == 0 )
{
return null;
}
Lobby[] lobbies = new Lobby[list.Value.LobbiesMatching];
for ( int i = 0; i < list.Value.LobbiesMatching; i++ )
{
lobbies[i] = new Lobby { Id = SteamMatchmaking.Internal.GetLobbyByIndex( i ) };
}
return lobbies;
}
}
}