Added ServerList favourites/history/LAN/friends

This commit is contained in:
Garry Newman 2016-11-11 11:09:28 +00:00
parent aeec6f59ef
commit 01dbec678c
5 changed files with 270 additions and 36 deletions

View File

@ -134,7 +134,90 @@ namespace Facepunch.Steamworks.Test
{
using ( var client = new Facepunch.Steamworks.Client( 252490 ) )
{
var query = client.ServerList.History();
var filter = new Facepunch.Steamworks.ServerList.Filter();
filter.Add( "appid", client.AppId.ToString() );
filter.Add( "gamedir", "rust" );
filter.Add( "secure", "1" );
var query = client.ServerList.History( filter );
while ( true )
{
client.Update();
System.Threading.Thread.Sleep( 2 );
if ( query.Finished )
break;
}
Console.WriteLine( "Responded: " + query.Responded.Count.ToString() );
Console.WriteLine( "Unresponsive: " + query.Unresponsive.Count.ToString() );
foreach ( var x in query.Responded )
{
Console.WriteLine( x.Map );
}
query.Dispose();
for ( int i = 0; i < 100; i++ )
{
client.Update();
System.Threading.Thread.Sleep( 1 );
}
}
}
[TestMethod]
public void FavouriteList()
{
using ( var client = new Facepunch.Steamworks.Client( 252490 ) )
{
var filter = new Facepunch.Steamworks.ServerList.Filter();
filter.Add( "appid", client.AppId.ToString() );
filter.Add( "gamedir", "rust" );
filter.Add( "secure", "1" );
var query = client.ServerList.Favourites( filter );
while ( true )
{
client.Update();
System.Threading.Thread.Sleep( 2 );
if ( query.Finished )
break;
}
Console.WriteLine( "Responded: " + query.Responded.Count.ToString() );
Console.WriteLine( "Unresponsive: " + query.Unresponsive.Count.ToString() );
foreach ( var x in query.Responded )
{
Console.WriteLine( x.Map );
}
query.Dispose();
for ( int i = 0; i < 100; i++ )
{
client.Update();
System.Threading.Thread.Sleep( 1 );
}
}
}
[TestMethod]
public void LocalList()
{
using ( var client = new Facepunch.Steamworks.Client( 252490 ) )
{
var filter = new Facepunch.Steamworks.ServerList.Filter();
filter.Add( "appid", client.AppId.ToString() );
filter.Add( "gamedir", "rust" );
filter.Add( "secure", "1" );
var query = client.ServerList.Local( filter );
while ( true )
{

View File

@ -20,7 +20,8 @@ namespace Facepunch.Steamworks
/// </summary>
public string BetaName { get; private set; }
public Voice Voice { get; internal set; }
public Voice Voice { get; private set; }
public ServerList ServerList { get; private set; }
public Client( uint appId )
{
@ -45,6 +46,7 @@ namespace Facepunch.Steamworks
// Client only interfaces
//
Voice = new Voice( this );
ServerList = new ServerList( this );
Workshop.friends = Friends;
@ -89,6 +91,12 @@ namespace Facepunch.Steamworks
Voice = null;
}
if ( ServerList != null )
{
ServerList.Dispose();
ServerList = null;
}
base.Dispose();
}
}

View File

@ -19,12 +19,19 @@ namespace Facepunch.Steamworks
internal IntPtr Request;
internal int Pointer = 0;
internal List<int> WatchList = new List<int>();
internal System.Diagnostics.Stopwatch Timer = System.Diagnostics.Stopwatch.StartNew();
internal bool Update( SteamNative.SteamMatchmakingServers servers, Action<SteamNative.gameserveritem_t> OnServer, Action OnUpdate )
{
if ( Request == IntPtr.Zero )
return true;
if ( Timer.Elapsed.TotalSeconds < 0.5f )
return false;
Timer.Reset();
Timer.Start();
bool changes = false;
//
@ -114,7 +121,7 @@ namespace Facepunch.Steamworks
}
internal IEnumerable<string> ServerList { get; set; }
internal Filter Filter { get; set; }
internal void StartCustomQuery()
{
@ -181,6 +188,9 @@ namespace Facepunch.Steamworks
{
if ( info.HadSuccessfulResponse )
{
if ( Filter != null && !Filter.Test( info ) )
return;
Responded.Add( Server.FromSteam( client, info ) );
}
else

View File

@ -29,6 +29,17 @@ namespace Facepunch.Steamworks
public int ConnectionPort { get; set; }
public int QueryPort { get; set; }
/// <summary>
/// Returns true if this server is in the favourites list
/// </summary>
public bool Favourite
{
get
{
return Client.ServerList.IsFavourite( this );
}
}
internal Client Client;
public string AddressString
@ -111,6 +122,47 @@ namespace Facepunch.Steamworks
if ( OnReceivedRules != null )
OnReceivedRules( Success );
}
internal const uint k_unFavoriteFlagNone = 0x00;
internal const uint k_unFavoriteFlagFavorite = 0x01; // this game favorite entry is for the favorites list
internal const uint k_unFavoriteFlagHistory = 0x02; // this game favorite entry is for the history list
/// <summary>
/// Add this server to our history list
/// If we're already in the history list, weill set the last played time to now
/// </summary>
public void AddToHistory()
{
Client.native.matchmaking.AddFavoriteGame( AppId, Address, (ushort)ConnectionPort, (ushort)QueryPort, k_unFavoriteFlagHistory, (uint)Utility.Epoch.Current );
Client.ServerList.UpdateFavouriteList();
}
/// <summary>
/// Remove this server from our history list
/// </summary>
public void RemoveFromHistory()
{
Client.native.matchmaking.RemoveFavoriteGame( AppId, Address, (ushort)ConnectionPort, (ushort)QueryPort, k_unFavoriteFlagHistory );
Client.ServerList.UpdateFavouriteList();
}
/// <summary>
/// Add this server to our favourite list
/// </summary>
public void AddToFavourites()
{
Client.native.matchmaking.AddFavoriteGame( AppId, Address, (ushort)ConnectionPort, (ushort)QueryPort, k_unFavoriteFlagFavorite, (uint)Utility.Epoch.Current );
Client.ServerList.UpdateFavouriteList();
}
/// <summary>
/// Remove this server from our favourite list
/// </summary>
public void RemoveFromFavourites()
{
Client.native.matchmaking.RemoveFavoriteGame( AppId, Address, (ushort)ConnectionPort, (ushort)QueryPort, k_unFavoriteFlagFavorite );
Client.ServerList.UpdateFavouriteList();
}
}
}
}

View File

@ -3,27 +3,56 @@ using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using SteamNative;
namespace Facepunch.Steamworks
{
public partial class Client : IDisposable
public partial class ServerList : IDisposable
{
private ServerList _serverlist;
internal Client client;
public ServerList ServerList
internal ServerList( Client client )
{
get
{
if ( _serverlist == null )
_serverlist = new ServerList { client = this };
this.client = client;
return _serverlist;
UpdateFavouriteList();
}
HashSet<ulong> FavouriteHash = new HashSet<ulong>();
HashSet<ulong> HistoryHash = new HashSet<ulong>();
internal void UpdateFavouriteList()
{
FavouriteHash.Clear();
HistoryHash.Clear();
for ( int i=0; i< client.native.matchmaking.GetFavoriteGameCount(); i++ )
{
AppId_t appid = 0;
uint ip;
ushort conPort;
ushort queryPort;
uint lastplayed;
uint flags;
client.native.matchmaking.GetFavoriteGame( i, ref appid, out ip, out conPort, out queryPort, out flags, out lastplayed );
ulong encoded = ip;
encoded = encoded << 32;
encoded = encoded | (uint)conPort;
if ( ( flags & Server.k_unFavoriteFlagFavorite ) == Server.k_unFavoriteFlagFavorite )
FavouriteHash.Add( encoded );
if ( ( flags & Server.k_unFavoriteFlagFavorite ) == Server.k_unFavoriteFlagFavorite )
HistoryHash.Add( encoded );
}
}
public partial class ServerList
public void Dispose()
{
client = null;
}
public class Filter : List<KeyValuePair<string, string>>
{
@ -35,16 +64,19 @@ namespace Facepunch.Steamworks
internal IntPtr NativeArray;
private IntPtr m_pArrayEntries;
private int AppId = 0;
internal void Start()
{
var filters = this.Select( x =>
{
if ( x.Key == "appid" ) AppId = int.Parse( x.Value );
return new SteamNative.MatchMakingKeyValuePair_t()
{
Key = x.Key,
Value = x.Value
};
} ).ToArray();
int sizeOfMMKVP = Marshal.SizeOf(typeof(SteamNative.MatchMakingKeyValuePair_t));
@ -71,9 +103,17 @@ namespace Facepunch.Steamworks
Marshal.FreeHGlobal( NativeArray );
}
}
internal bool Test( gameserveritem_t info )
{
if ( AppId != 0 && AppId != info.AppID )
return false;
return true;
}
}
internal Client client;
[StructLayout( LayoutKind.Sequential )]
private struct MatchPair
@ -84,11 +124,14 @@ namespace Facepunch.Steamworks
public string value;
}
public Request Internet( Filter filter )
{
filter.Start();
var request = new Request( client );
request.Filter = filter;
request.AddRequest( client.native.servers.RequestInternetServerList( client.AppId, filter.NativeArray, (uint) filter.Count, IntPtr.Zero ) );
filter.Free();
@ -96,6 +139,9 @@ namespace Facepunch.Steamworks
return request;
}
/// <summary>
/// Query a list of addresses. No filters applied.
/// </summary>
public Request Custom( IEnumerable<string> serverList )
{
var request = new Request( client );
@ -105,52 +151,87 @@ namespace Facepunch.Steamworks
}
/// <summary>
/// History filters don't seem to work, so we don't bother.
/// You should apply them post process'dly
/// Request a list of servers we've been on. History isn't applied automatically
/// You need to call server.AddtoHistoryList() when you join a server etc.
/// </summary>
public Request History()
public Request History( Filter filter )
{
filter.Start();
var request = new Request( client );
request.AddRequest( client.native.servers.RequestHistoryServerList( client.AppId, IntPtr.Zero, 0, IntPtr.Zero ) );
request.Filter = filter;
request.AddRequest( client.native.servers.RequestHistoryServerList( client.AppId, filter.NativeArray, (uint)filter.Count, IntPtr.Zero ) );
filter.Free();
return request;
}
/// <summary>
/// Favourite filters don't seem to work, so we don't bother.
/// You should apply them post process'dly
/// Request a list of servers we've favourited
/// </summary>
public Request Favourites()
public Request Favourites( Filter filter )
{
filter.Start();
var request = new Request( client );
request.AddRequest( client.native.servers.RequestFavoritesServerList( client.AppId, IntPtr.Zero, 0, IntPtr.Zero ) );
request.Filter = filter;
request.AddRequest( client.native.servers.RequestFavoritesServerList( client.AppId, filter.NativeArray, (uint)filter.Count, IntPtr.Zero ) );
filter.Free();
return request;
}
public void AddToHistory( Server server )
/// <summary>
/// Request a list of servers that our friends are on
/// </summary>
public Request Friends( Filter filter )
{
// client.native.matchmaking
filter.Start();
var request = new Request( client );
request.Filter = filter;
request.AddRequest( client.native.servers.RequestFriendsServerList( client.AppId, filter.NativeArray, (uint)filter.Count, IntPtr.Zero ) );
filter.Free();
return request;
}
public void RemoveFromHistory( Server server )
/// <summary>
/// Request a list of servers that are running on our LAN
/// </summary>
public Request Local( Filter filter )
{
//
filter.Start();
var request = new Request( client );
request.Filter = filter;
request.AddRequest( client.native.servers.RequestLANServerList( client.AppId, IntPtr.Zero ) );
filter.Free();
return request;
}
public void AddToFavourite( Server server )
internal bool IsFavourite( Server server )
{
// client.native.matchmaking
ulong encoded = server.Address;
encoded = encoded << 32;
encoded = encoded | (uint)server.ConnectionPort;
return FavouriteHash.Contains( encoded );
}
public void RemoveFromFavourite( Server server )
internal bool IsHistory( Server server )
{
//
}
ulong encoded = server.Address;
encoded = encoded << 32;
encoded = encoded | (uint)server.ConnectionPort;
public bool IsFavourite( Server server )
{
return false;
return HistoryHash.Contains( encoded );
}
}
}