Leaderboard.GetGlobalEntriesAsync

This commit is contained in:
Garry Newman 2019-04-17 09:31:28 +01:00
parent e5a89b0550
commit ebcd96326a
7 changed files with 132 additions and 3 deletions

View File

@ -29,6 +29,7 @@
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<PlatformTarget>x64</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>

View File

@ -50,6 +50,31 @@ public async Task StoreStats()
}
[TestMethod]
public async Task CreateLeaderboard()
{
var leaderboard = await SteamUserStats.FindOrCreateLeaderboard( "Testleaderboard", Data.LeaderboardSort.Descending, Data.LeaderboardDisplay.Numeric );
Assert.IsTrue( leaderboard.HasValue );
}
[TestMethod]
public async Task FindLeaderboard()
{
var leaderboard = await SteamUserStats.FindLeaderboard( "Testleaderboard" );
Assert.IsTrue( leaderboard.HasValue );
// Get top 20 global scores
var globalsScores = await leaderboard.Value.GetGlobalEntriesAsync( 20 );
Assert.IsNotNull( globalsScores );
foreach ( var e in globalsScores )
{
Console.WriteLine( $"{e.GlobalRank}: {e.Score} {e.User}" );
}
}
}
}

View File

@ -412,13 +412,13 @@ internal LeaderboardDisplay GetLeaderboardDisplayType( SteamLeaderboard_t hSteam
#region FunctionMeta
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
[return: MarshalAs( UnmanagedType.I1 )]
private delegate bool GetDownloadedLeaderboardEntryDelegate( IntPtr self, SteamLeaderboardEntries_t hSteamLeaderboardEntries, int index, ref LeaderboardEntry_t pLeaderboardEntry, ref int pDetails, int cDetailsMax );
private delegate bool GetDownloadedLeaderboardEntryDelegate( IntPtr self, SteamLeaderboardEntries_t hSteamLeaderboardEntries, int index, ref LeaderboardEntry_t pLeaderboardEntry, [In,Out] int[] pDetails, int cDetailsMax );
private GetDownloadedLeaderboardEntryDelegate GetDownloadedLeaderboardEntryDelegatePointer;
#endregion
internal bool GetDownloadedLeaderboardEntry( SteamLeaderboardEntries_t hSteamLeaderboardEntries, int index, ref LeaderboardEntry_t pLeaderboardEntry, ref int pDetails, int cDetailsMax )
internal bool GetDownloadedLeaderboardEntry( SteamLeaderboardEntries_t hSteamLeaderboardEntries, int index, ref LeaderboardEntry_t pLeaderboardEntry, [In,Out] int[] pDetails, int cDetailsMax )
{
return GetDownloadedLeaderboardEntryDelegatePointer( Self, hSteamLeaderboardEntries, index, ref pLeaderboardEntry, ref pDetails, cDetailsMax );
return GetDownloadedLeaderboardEntryDelegatePointer( Self, hSteamLeaderboardEntries, index, ref pLeaderboardEntry, pDetails, cDetailsMax );
}
#region FunctionMeta

View File

@ -16,6 +16,11 @@ public Friend( SteamId steamid )
Id = steamid;
}
public override string ToString()
{
return $"{Name} ({Id.ToString()})";
}
public bool IsFriend => Relationship == Relationship.Friend;
public bool IsBlocked => Relationship == Relationship.Blocked;
public bool IsPlayingThisGame => GameInfo?.GameID == SteamUtils.AppId;

View File

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
@ -9,5 +10,70 @@ namespace Steamworks.Data
public struct Leaderboard
{
internal SteamLeaderboard_t Id;
/// <summary>
/// the name of a leaderboard
/// </summary>
public string Name => SteamUserStats.Internal.GetLeaderboardName( Id );
public LeaderboardSort Sort => SteamUserStats.Internal.GetLeaderboardSortMethod( Id );
public LeaderboardDisplay Display => SteamUserStats.Internal.GetLeaderboardDisplayType( Id );
static int[] detailsBuffer = new int[64];
/// <summary>
/// Used to query for a sequential range of leaderboard entries by leaderboard Sort.
/// </summary>
public async Task<LeaderboardEntry[]> GetGlobalEntriesAsync( int count, int offset = 1 )
{
if ( offset <= 0 ) throw new System.ArgumentException( "Should be 1+", nameof( offset ) );
var r = await SteamUserStats.Internal.DownloadLeaderboardEntries( Id, LeaderboardDataRequest.Global, offset, offset + count );
if ( !r.HasValue )
return null;
return await LeaderboardResultToEntries( r.Value );
}
#region util
internal async Task<LeaderboardEntry[]> LeaderboardResultToEntries( LeaderboardScoresDownloaded_t r )
{
if ( r.CEntryCount == 0 )
return null;
var output = new LeaderboardEntry[r.CEntryCount];
var e = default( LeaderboardEntry_t );
for ( int i = 0; i < r.CEntryCount; i++ )
{
if ( SteamUserStats.Internal.GetDownloadedLeaderboardEntry( r.SteamLeaderboardEntries, i, ref e, detailsBuffer, detailsBuffer.Length ) )
{
output[i] = LeaderboardEntry.From( e, detailsBuffer );
}
}
await WaitForUserNames( output );
return output;
}
internal async Task WaitForUserNames( LeaderboardEntry[] entries)
{
bool gotAll = false;
while ( !gotAll )
{
gotAll = true;
foreach ( var entry in entries )
{
if ( entry.User.Id == 0 ) continue;
if ( !SteamFriends.Internal.RequestUserInformation( entry.User.Id, true ) ) continue;
gotAll = false;
}
await Task.Delay( 1 );
}
}
#endregion
}
}

View File

@ -0,0 +1,31 @@
using System.Linq;
namespace Steamworks.Data
{
public struct LeaderboardEntry
{
public Friend User;
public int GlobalRank;
public int Score;
public int[] Details;
// UGCHandle_t m_hUGC
internal static LeaderboardEntry From( LeaderboardEntry_t e, int[] detailsBuffer )
{
var r = new LeaderboardEntry
{
User = new Friend( e.SteamIDUser ),
GlobalRank = e.GlobalRank,
Score = e.Score,
Details = null
};
if ( e.CDetails > 0 )
{
r.Details = detailsBuffer.Take( e.CDetails ).ToArray();
}
return r;
}
}
}

View File

@ -62,6 +62,7 @@ public virtual bool IsVector
if ( VarName == "psteamIDClans" ) return true;
if ( VarName == "pScoreDetails" ) return true;
if ( VarName == "prgUsers" ) return true;
if ( VarName == "pDetails" ) return true;
if ( NativeType.EndsWith( "**" ) ) return true;
if ( NativeType.EndsWith( "*" ) )