Gives LobbyList the ability to be queried for if it is Finished or not.

A lobby refresh will finish when the number of cached lobbies equals the
number of requests.
This commit is contained in:
Kyle Kukshtel 2017-07-31 09:29:53 -07:00
parent c40037784e
commit beccb5e5e9

View File

@ -8,16 +8,36 @@ namespace Facepunch.Steamworks
public partial class LobbyList : IDisposable public partial class LobbyList : IDisposable
{ {
internal Client client; internal Client client;
public List<Lobby> Lobbies = new List<Lobby>();
//The list of retrieved lobbies
public List<Lobby> Lobbies { get; private set; }
//True when all the possible lobbies have had their data updated
//if the number of lobbies is now equal to the initial request number, we've found all lobbies
public bool Finished { get; private set; }
//The number of possible lobbies we can get data from
internal List<ulong> requests;
internal LobbyList(Client client) internal LobbyList(Client client)
{ {
this.client = client; this.client = client;
Lobbies = new List<Lobby>();
requests = new List<ulong>();
} }
/// <summary>
/// Refresh the List of Lobbies. If no filter is passed in, a default one is created that filters based on AppId ("appid").
/// </summary>
/// <param name="filter"></param>
public void Refresh ( Filter filter = null) public void Refresh ( Filter filter = null)
{ {
if(filter == null) //init out values
Lobbies.Clear();
requests.Clear();
Finished = false;
if (filter == null)
{ {
filter = new Filter(); filter = new Filter();
filter.StringFilters.Add("appid", client.AppId.ToString()); filter.StringFilters.Add("appid", client.AppId.ToString());
@ -25,7 +45,7 @@ public void Refresh ( Filter filter = null)
client.native.matchmaking.AddRequestLobbyListDistanceFilter((SteamNative.LobbyDistanceFilter)filter.DistanceFilter); client.native.matchmaking.AddRequestLobbyListDistanceFilter((SteamNative.LobbyDistanceFilter)filter.DistanceFilter);
if(filter.SlotsAvailable != null) if (filter.SlotsAvailable != null)
{ {
client.native.matchmaking.AddRequestLobbyListFilterSlotsAvailable((int)filter.SlotsAvailable); client.native.matchmaking.AddRequestLobbyListFilterSlotsAvailable((int)filter.SlotsAvailable);
} }
@ -43,10 +63,10 @@ public void Refresh ( Filter filter = null)
{ {
client.native.matchmaking.AddRequestLobbyListNearValueFilter(fil.Key, fil.Value); client.native.matchmaking.AddRequestLobbyListNearValueFilter(fil.Key, fil.Value);
} }
foreach (KeyValuePair<string, KeyValuePair<Filter.Comparison, int>> fil in filter.NumericalFilters) //foreach (KeyValuePair<string, KeyValuePair<Filter.Comparison, int>> fil in filter.NumericalFilters)
{ //{
client.native.matchmaking.AddRequestLobbyListNumericalFilter(fil.Key, fil.Value.Value, (SteamNative.LobbyComparison)fil.Value.Key); // client.native.matchmaking.AddRequestLobbyListNumericalFilter(fil.Key, fil.Value.Value, (SteamNative.LobbyComparison)fil.Value.Key);
} //}
// this will never return lobbies that are full (via the actual api) // this will never return lobbies that are full (via the actual api)
@ -54,23 +74,32 @@ public void Refresh ( Filter filter = null)
} }
void OnLobbyList(LobbyMatchList_t callback, bool error) void OnLobbyList(LobbyMatchList_t callback, bool error)
{ {
if (error) return; if (error) return;
Lobbies.Clear();
//how many lobbies matched
uint lobbiesMatching = callback.LobbiesMatching; uint lobbiesMatching = callback.LobbiesMatching;
// lobbies are returned in order of closeness to the user, so add them to the list in that order // lobbies are returned in order of closeness to the user, so add them to the list in that order
for (int i = 0; i < lobbiesMatching; i++) for (int i = 0; i < lobbiesMatching; i++)
{ {
//add the lobby to the list of requests
ulong lobby = client.native.matchmaking.GetLobbyByIndex(i); ulong lobby = client.native.matchmaking.GetLobbyByIndex(i);
requests.Add(lobby);
//cast to a LobbyList.Lobby
Lobby newLobby = Lobby.FromSteam(client, lobby); Lobby newLobby = Lobby.FromSteam(client, lobby);
if (newLobby.Name != "") if (newLobby.Name != "")
{ {
//if the lobby is valid add it to the valid return lobbies
Lobbies.Add(newLobby); Lobbies.Add(newLobby);
checkFinished();
} }
else else
{ {
//need to get the info for the missing lobby //else we need to get the info for the missing lobby
client.native.matchmaking.RequestLobbyData(lobby); client.native.matchmaking.RequestLobbyData(lobby);
SteamNative.LobbyDataUpdate_t.RegisterCallback(client, OnLobbyDataUpdated); SteamNative.LobbyDataUpdate_t.RegisterCallback(client, OnLobbyDataUpdated);
} }
@ -80,19 +109,35 @@ void OnLobbyList(LobbyMatchList_t callback, bool error)
if (OnLobbiesUpdated != null) { OnLobbiesUpdated(); } if (OnLobbiesUpdated != null) { OnLobbiesUpdated(); }
} }
void checkFinished()
{
if (Lobbies.Count == requests.Count)
{
Finished = true;
return;
}
Finished = false;
}
void OnLobbyDataUpdated(LobbyDataUpdate_t callback, bool error) void OnLobbyDataUpdated(LobbyDataUpdate_t callback, bool error)
{ {
if (callback.Success == 1) //1 if success, 0 if failure if (callback.Success == 1) //1 if success, 0 if failure
{ {
//find the lobby that has been updated
Lobby lobby = Lobbies.Find(x => x.LobbyID == callback.SteamIDLobby); Lobby lobby = Lobbies.Find(x => x.LobbyID == callback.SteamIDLobby);
if (lobby == null) //need to add this lobby to the list
//if this lobby isn't yet in the list of lobbies, we know that we should add it
if (lobby == null)
{ {
Lobbies.Add(lobby); Lobbies.Add(lobby);
checkFinished();
} }
//otherwise lobby data in general was updated and you should listen to see what changed //otherwise lobby data in general was updated and you should listen to see what changed
if (OnLobbiesUpdated != null) { OnLobbiesUpdated(); } if (OnLobbiesUpdated != null) { OnLobbiesUpdated(); }
} }
} }
public Action OnLobbiesUpdated; public Action OnLobbiesUpdated;
@ -109,7 +154,7 @@ public class Filter
// Filters that are of string key and int value for that key to be close to // Filters that are of string key and int value for that key to be close to
public Dictionary<string, int> NearFilters = new Dictionary<string, int>(); public Dictionary<string, int> NearFilters = new Dictionary<string, int>();
//Filters that are of string key and int value, with a comparison filter to say how we should relate to the value //Filters that are of string key and int value, with a comparison filter to say how we should relate to the value
public Dictionary<string, KeyValuePair<Comparison, int>> NumericalFilters = new Dictionary<string, KeyValuePair<Comparison, int>>(); //public Dictionary<string, KeyValuePair<Comparison, int>> NumericalFilters = new Dictionary<string, KeyValuePair<Comparison, int>>();
public Distance DistanceFilter = Distance.Worldwide; public Distance DistanceFilter = Distance.Worldwide;
public int? SlotsAvailable { get; set; } public int? SlotsAvailable { get; set; }
public int? MaxResults { get; set; } public int? MaxResults { get; set; }