mirror of
https://github.com/Facepunch/Facepunch.Steamworks.git
synced 2025-01-27 05:58:07 +03:00
Added ServerList favourites/history/LAN/friends
This commit is contained in:
parent
aeec6f59ef
commit
01dbec678c
@ -134,7 +134,90 @@ namespace Facepunch.Steamworks.Test
|
|||||||
{
|
{
|
||||||
using ( var client = new Facepunch.Steamworks.Client( 252490 ) )
|
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 )
|
while ( true )
|
||||||
{
|
{
|
||||||
|
@ -20,7 +20,8 @@ namespace Facepunch.Steamworks
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public string BetaName { get; private set; }
|
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 )
|
public Client( uint appId )
|
||||||
{
|
{
|
||||||
@ -45,6 +46,7 @@ namespace Facepunch.Steamworks
|
|||||||
// Client only interfaces
|
// Client only interfaces
|
||||||
//
|
//
|
||||||
Voice = new Voice( this );
|
Voice = new Voice( this );
|
||||||
|
ServerList = new ServerList( this );
|
||||||
|
|
||||||
Workshop.friends = Friends;
|
Workshop.friends = Friends;
|
||||||
|
|
||||||
@ -89,6 +91,12 @@ namespace Facepunch.Steamworks
|
|||||||
Voice = null;
|
Voice = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( ServerList != null )
|
||||||
|
{
|
||||||
|
ServerList.Dispose();
|
||||||
|
ServerList = null;
|
||||||
|
}
|
||||||
|
|
||||||
base.Dispose();
|
base.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,12 +19,19 @@ namespace Facepunch.Steamworks
|
|||||||
internal IntPtr Request;
|
internal IntPtr Request;
|
||||||
internal int Pointer = 0;
|
internal int Pointer = 0;
|
||||||
internal List<int> WatchList = new List<int>();
|
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 )
|
internal bool Update( SteamNative.SteamMatchmakingServers servers, Action<SteamNative.gameserveritem_t> OnServer, Action OnUpdate )
|
||||||
{
|
{
|
||||||
if ( Request == IntPtr.Zero )
|
if ( Request == IntPtr.Zero )
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
if ( Timer.Elapsed.TotalSeconds < 0.5f )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Timer.Reset();
|
||||||
|
Timer.Start();
|
||||||
|
|
||||||
bool changes = false;
|
bool changes = false;
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -114,7 +121,7 @@ namespace Facepunch.Steamworks
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal IEnumerable<string> ServerList { get; set; }
|
internal IEnumerable<string> ServerList { get; set; }
|
||||||
|
internal Filter Filter { get; set; }
|
||||||
|
|
||||||
internal void StartCustomQuery()
|
internal void StartCustomQuery()
|
||||||
{
|
{
|
||||||
@ -181,6 +188,9 @@ namespace Facepunch.Steamworks
|
|||||||
{
|
{
|
||||||
if ( info.HadSuccessfulResponse )
|
if ( info.HadSuccessfulResponse )
|
||||||
{
|
{
|
||||||
|
if ( Filter != null && !Filter.Test( info ) )
|
||||||
|
return;
|
||||||
|
|
||||||
Responded.Add( Server.FromSteam( client, info ) );
|
Responded.Add( Server.FromSteam( client, info ) );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -29,6 +29,17 @@ namespace Facepunch.Steamworks
|
|||||||
public int ConnectionPort { get; set; }
|
public int ConnectionPort { get; set; }
|
||||||
public int QueryPort { 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;
|
internal Client Client;
|
||||||
|
|
||||||
public string AddressString
|
public string AddressString
|
||||||
@ -111,6 +122,47 @@ namespace Facepunch.Steamworks
|
|||||||
if ( OnReceivedRules != null )
|
if ( OnReceivedRules != null )
|
||||||
OnReceivedRules( Success );
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,27 +3,56 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using SteamNative;
|
||||||
|
|
||||||
namespace Facepunch.Steamworks
|
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
|
this.client = client;
|
||||||
{
|
|
||||||
if ( _serverlist == null )
|
|
||||||
_serverlist = new ServerList { client = this };
|
|
||||||
|
|
||||||
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>>
|
public class Filter : List<KeyValuePair<string, string>>
|
||||||
{
|
{
|
||||||
@ -35,16 +64,19 @@ namespace Facepunch.Steamworks
|
|||||||
internal IntPtr NativeArray;
|
internal IntPtr NativeArray;
|
||||||
private IntPtr m_pArrayEntries;
|
private IntPtr m_pArrayEntries;
|
||||||
|
|
||||||
|
private int AppId = 0;
|
||||||
|
|
||||||
internal void Start()
|
internal void Start()
|
||||||
{
|
{
|
||||||
var filters = this.Select( x =>
|
var filters = this.Select( x =>
|
||||||
{
|
{
|
||||||
|
if ( x.Key == "appid" ) AppId = int.Parse( x.Value );
|
||||||
|
|
||||||
return new SteamNative.MatchMakingKeyValuePair_t()
|
return new SteamNative.MatchMakingKeyValuePair_t()
|
||||||
{
|
{
|
||||||
Key = x.Key,
|
Key = x.Key,
|
||||||
Value = x.Value
|
Value = x.Value
|
||||||
};
|
};
|
||||||
|
|
||||||
} ).ToArray();
|
} ).ToArray();
|
||||||
|
|
||||||
int sizeOfMMKVP = Marshal.SizeOf(typeof(SteamNative.MatchMakingKeyValuePair_t));
|
int sizeOfMMKVP = Marshal.SizeOf(typeof(SteamNative.MatchMakingKeyValuePair_t));
|
||||||
@ -71,9 +103,17 @@ namespace Facepunch.Steamworks
|
|||||||
Marshal.FreeHGlobal( NativeArray );
|
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 )]
|
[StructLayout( LayoutKind.Sequential )]
|
||||||
private struct MatchPair
|
private struct MatchPair
|
||||||
@ -84,11 +124,14 @@ namespace Facepunch.Steamworks
|
|||||||
public string value;
|
public string value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public Request Internet( Filter filter )
|
public Request Internet( Filter filter )
|
||||||
{
|
{
|
||||||
filter.Start();
|
filter.Start();
|
||||||
|
|
||||||
var request = new Request( client );
|
var request = new Request( client );
|
||||||
|
request.Filter = filter;
|
||||||
request.AddRequest( client.native.servers.RequestInternetServerList( client.AppId, filter.NativeArray, (uint) filter.Count, IntPtr.Zero ) );
|
request.AddRequest( client.native.servers.RequestInternetServerList( client.AppId, filter.NativeArray, (uint) filter.Count, IntPtr.Zero ) );
|
||||||
|
|
||||||
filter.Free();
|
filter.Free();
|
||||||
@ -96,6 +139,9 @@ namespace Facepunch.Steamworks
|
|||||||
return request;
|
return request;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Query a list of addresses. No filters applied.
|
||||||
|
/// </summary>
|
||||||
public Request Custom( IEnumerable<string> serverList )
|
public Request Custom( IEnumerable<string> serverList )
|
||||||
{
|
{
|
||||||
var request = new Request( client );
|
var request = new Request( client );
|
||||||
@ -105,52 +151,87 @@ namespace Facepunch.Steamworks
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// History filters don't seem to work, so we don't bother.
|
/// Request a list of servers we've been on. History isn't applied automatically
|
||||||
/// You should apply them post process'dly
|
/// You need to call server.AddtoHistoryList() when you join a server etc.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Request History()
|
public Request History( Filter filter )
|
||||||
{
|
{
|
||||||
|
filter.Start();
|
||||||
|
|
||||||
var request = new Request( client );
|
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;
|
return request;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Favourite filters don't seem to work, so we don't bother.
|
/// Request a list of servers we've favourited
|
||||||
/// You should apply them post process'dly
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Request Favourites()
|
public Request Favourites( Filter filter )
|
||||||
{
|
{
|
||||||
|
filter.Start();
|
||||||
|
|
||||||
var request = new Request( client );
|
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;
|
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 HistoryHash.Contains( encoded );
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user