changes lobby initialization and makes lobbylist filter easier

This commit is contained in:
Kyle Kukshtel 2017-07-25 10:09:41 -07:00
parent e3f84eac32
commit 7e38750f2e
3 changed files with 116 additions and 60 deletions

View File

@ -0,0 +1,32 @@
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace Facepunch.Steamworks.Test
{
[DeploymentItem("steam_api.dll")]
[DeploymentItem("steam_api64.dll")]
[DeploymentItem("steam_appid.txt")]
[TestClass]
class Lobby
{
[TestMethod]
public void FriendList()
{
/*
using (var client = new Facepunch.Steamworks.Client(252490))
{
Assert.IsTrue(client.IsValid);
client.Friends.Refresh();
Assert.IsNotNull(client.Friends.All);
foreach (var friend in client.Friends.All)
{
Console.WriteLine("{0}: {1} (Friend:{2}) (Blocked:{3})", friend.Id, friend.Name, friend.IsFriend, friend.IsBlocked);
}
}
*/
}
}
}

View File

@ -18,9 +18,18 @@ void OnLobbyJoined(LobbyEnter_t callback, bool error)
//TODO: //TODO:
} }
// Create a lobby, auto joins the created lobby
public Lobby CreateLobby(Lobby.Type lobbyType, int maxMembers)
{
var lobby = new Lobby(this, lobbyType);
native.matchmaking.CreateLobby((SteamNative.LobbyType)lobbyType, maxMembers, lobby.OnLobbyCreatedAPI);
return lobby;
}
}
public class Lobby : IDisposable
{
//The type of lobby you are creating //The type of lobby you are creating
public enum LobbyType : int public enum Type : int
{ {
Private = SteamNative.LobbyType.Private, Private = SteamNative.LobbyType.Private,
FriendsOnly = SteamNative.LobbyType.FriendsOnly, FriendsOnly = SteamNative.LobbyType.FriendsOnly,
@ -28,22 +37,6 @@ public enum LobbyType : int
Invisible = SteamNative.LobbyType.Invisible Invisible = SteamNative.LobbyType.Invisible
} }
// Create a lobby, auto joins the created lobby
public Lobby CreateLobby(LobbyType lobbyType, int maxMembers, string name)
{
var lobby = new Lobby(this);
native.matchmaking.CreateLobby((SteamNative.LobbyType)lobbyType, maxMembers, lobby.OnLobbyCreated);
if (lobby.IsValid)
{
lobby.Name = name;
lobby.MaxMembers = maxMembers;
lobby.LobbyType = lobbyType;
}
return lobby;
}
}
public class Lobby : IDisposable
{
internal Client client; internal Client client;
/// <summary> /// <summary>
@ -68,16 +61,23 @@ public class Lobby : IDisposable
/// </summary> /// </summary>
public string Name public string Name
{ {
get { return LobbyData["name"]; } get { return _name; }
set { SetLobbyData("name", value); } set { if (_name == value) return; SetLobbyData("name", value); }
} }
string _name = "";
public Lobby(Client c) /// <summary>
/// Callback for when lobby is created
/// </summary>
public Action OnLobbyCreated;
public Lobby(Client c, Type type)
{ {
client = c; client = c;
LobbyType = type;
} }
internal void OnLobbyCreated(LobbyCreated_t callback, bool error) internal void OnLobbyCreatedAPI(LobbyCreated_t callback, bool error)
{ {
//from SpaceWarClient.cpp 793 //from SpaceWarClient.cpp 793
if (error || (callback.Result != Result.OK)) if (error || (callback.Result != Result.OK))
@ -88,6 +88,10 @@ internal void OnLobbyCreated(LobbyCreated_t callback, bool error)
Owner = client.SteamId; //this is implicitly set on creation but need to cache it here Owner = client.SteamId; //this is implicitly set on creation but need to cache it here
LobbyID = callback.SteamIDLobby; LobbyID = callback.SteamIDLobby;
MaxMembers = client.native.matchmaking.GetLobbyMemberLimit(LobbyID);
SetLobbyData("appid", client.AppId.ToString());
if (OnLobbyCreated != null) { OnLobbyCreated(); }
} }
Dictionary<string, string> LobbyData = new Dictionary<string, string>(); Dictionary<string, string> LobbyData = new Dictionary<string, string>();
@ -118,12 +122,21 @@ public void RemoveLobbyData(string key)
client.native.matchmaking.DeleteLobbyData(LobbyID, key); client.native.matchmaking.DeleteLobbyData(LobbyID, key);
} }
public Client.LobbyType LobbyType public Type LobbyType
{ {
get { return _lobbyType; } get { return _lobbyType; }
set { if (_lobbyType == value) return; client.native.matchmaking.SetLobbyType(LobbyID, (SteamNative.LobbyType)value); _lobbyType = value; } //returns bool set
{
if (_lobbyType == value) return;
//only call the proper method if the lobby is valid, otherwise cache the value
if(IsValid)
{
client.native.matchmaking.SetLobbyType(LobbyID, (SteamNative.LobbyType)value); //returns bool?
}
_lobbyType = value;
}
} }
Client.LobbyType _lobbyType; Type _lobbyType;
//Must be the owner to change the owner //Must be the owner to change the owner
@ -158,6 +171,13 @@ public int MaxMembers
} }
int _maxMembers = 0; int _maxMembers = 0;
//How many people are currently in the lobby
public int NumMembers
{
get { return client.native.matchmaking.GetNumLobbyMembers(LobbyID);}
}
//leave the current lobby
public void Leave() public void Leave()
{ {
client.native.matchmaking.LeaveLobby(LobbyID); client.native.matchmaking.LeaveLobby(LobbyID);

View File

@ -15,36 +15,42 @@ internal LobbyList(Client client)
this.client = client; this.client = client;
} }
public void Refresh ( LobbyFilter filter = null) public void Refresh ( Filter filter = null)
{ {
if(filter != null) if(filter == null)
{ {
client.native.matchmaking.AddRequestLobbyListDistanceFilter((SteamNative.LobbyDistanceFilter)filter.DistanceFilter); filter = new Filter();
client.native.matchmaking.AddRequestLobbyListFilterSlotsAvailable(filter.SlotsAvailable); filter.StringFilters.Add("appid", client.AppId.ToString());
client.native.matchmaking.AddRequestLobbyListResultCountFilter(filter.MaxResults);
foreach (KeyValuePair<string, string> fil in filter.StringFilters)
{
client.native.matchmaking.AddRequestLobbyListStringFilter(fil.Key, fil.Value, SteamNative.LobbyComparison.Equal);
}
foreach (KeyValuePair<string, int> fil in filter.NearFilters)
{
client.native.matchmaking.AddRequestLobbyListNearValueFilter(fil.Key, fil.Value);
}
foreach (KeyValuePair<string, KeyValuePair<LobbyFilter.Comparison, int>> fil in filter.NumericalFilters)
{
client.native.matchmaking.AddRequestLobbyListNumericalFilter(fil.Key, fil.Value.Value, (SteamNative.LobbyComparison)fil.Value.Key);
}
} }
client.native.matchmaking.AddRequestLobbyListDistanceFilter((SteamNative.LobbyDistanceFilter)filter.DistanceFilter);
if(filter.SlotsAvailable != null)
{
client.native.matchmaking.AddRequestLobbyListFilterSlotsAvailable((int)filter.SlotsAvailable);
}
if (filter.MaxResults != null)
{
client.native.matchmaking.AddRequestLobbyListResultCountFilter((int)filter.MaxResults);
}
foreach (KeyValuePair<string, string> fil in filter.StringFilters)
{
client.native.matchmaking.AddRequestLobbyListStringFilter(fil.Key, fil.Value, SteamNative.LobbyComparison.Equal);
}
foreach (KeyValuePair<string, int> fil in filter.NearFilters)
{
client.native.matchmaking.AddRequestLobbyListNearValueFilter(fil.Key, fil.Value);
}
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);
}
// this will never return lobbies that are full (via the actual api) // this will never return lobbies that are full (via the actual api)
client.native.matchmaking.RequestLobbyList(OnLobbyList); client.native.matchmaking.RequestLobbyList(OnLobbyList);
/*
if (filter == null) may need this if we are getting too many lobbies
{
filter = new Filter();
//filter.Add("appid", client.AppId.ToString());
}*/
} }
@ -69,14 +75,19 @@ void OnLobbyList(LobbyMatchList_t callback, bool error)
} }
} }
if (OnLobbiesRefreshed != null) { OnLobbiesRefreshed(); }
} }
public Action OnLobbiesRefreshed;
public void Dispose() public void Dispose()
{ {
client = null; client = null;
} }
public class LobbyFilter public class Filter
{ {
// Filters that match actual metadata keys exactly // Filters that match actual metadata keys exactly
public Dictionary<string, string> StringFilters = new Dictionary<string, string>(); public Dictionary<string, string> StringFilters = new Dictionary<string, string>();
@ -84,9 +95,9 @@ public class LobbyFilter
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 { get; set; } 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; }
public enum Distance : int public enum Distance : int
{ {
@ -105,13 +116,6 @@ public enum Comparison : int
EqualToOrGreaterThan = SteamNative.LobbyComparison.EqualToOrGreaterThan, EqualToOrGreaterThan = SteamNative.LobbyComparison.EqualToOrGreaterThan,
NotEqual = SteamNative.LobbyComparison.NotEqual NotEqual = SteamNative.LobbyComparison.NotEqual
} }
public LobbyFilter(Distance distanceFilter, int slotsAvailable, int maxResults)
{
DistanceFilter = distanceFilter;
SlotsAvailable = slotsAvailable;
MaxResults = maxResults;
}
} }
} }
} }