using System.Threading.Tasks; using System.Collections.Generic; namespace Facepunch.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; /// /// 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; } #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 ( distance.HasValue ) { SteamMatchmaking.Internal.AddRequestLobbyListDistanceFilter( distance.Value ); } if ( slotsAvailable.HasValue ) { SteamMatchmaking.Internal.AddRequestLobbyListFilterSlotsAvailable( slotsAvailable.Value ); } if ( maxResults.HasValue ) { SteamMatchmaking.Internal.AddRequestLobbyListResultCountFilter( maxResults.Value ); } if ( stringFilters != null ) { foreach ( var k in stringFilters ) { SteamMatchmaking.Internal.AddRequestLobbyListStringFilter( k.Key, k.Value, LobbyComparison.Equal ); } } 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 ); } } } /// /// Run the query, get the matching lobbies /// public async Task RequestAsync() { 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; } } }