From d3ebe4e2f227a8e2a62c1b6065d3977f1ad1a700 Mon Sep 17 00:00:00 2001 From: James King Date: Mon, 15 May 2017 13:23:19 +0100 Subject: [PATCH] Added overload of Leaderboard.FetchScores that takes a callback --- .../Client/Leaderboard.cs | 47 ++++++++++++++ Facepunch.Steamworks/Client/Leaderboard.cs | 65 ++++++++++++++----- 2 files changed, 97 insertions(+), 15 deletions(-) diff --git a/Facepunch.Steamworks.Test/Client/Leaderboard.cs b/Facepunch.Steamworks.Test/Client/Leaderboard.cs index 4e19a10..6de0efc 100644 --- a/Facepunch.Steamworks.Test/Client/Leaderboard.cs +++ b/Facepunch.Steamworks.Test/Client/Leaderboard.cs @@ -51,6 +51,53 @@ namespace Facepunch.Steamworks.Test } } + [TestMethod] + public void GetLeaderboardCallback() + { + using ( var client = new Steamworks.Client( 252490 ) ) + { + var board = client.GetLeaderboard( "TestLeaderboard", Steamworks.Client.LeaderboardSortMethod.Ascending, Steamworks.Client.LeaderboardDisplayType.Numeric ); + + while ( !board.IsValid ) + { + Thread.Sleep( 10 ); + client.Update(); + } + + Assert.IsTrue( board.IsValid ); + Assert.IsFalse( board.IsError ); + Assert.IsNotNull( board.Name ); + + Console.WriteLine( $"Board name is \"{board.Name}\"" ); + Console.WriteLine( $"Board has \"{board.TotalEntries}\" entries" ); + + board.AddScore( true, 86275309, 7, 8, 9 ); + + var done = false; + + board.FetchScores( Steamworks.Leaderboard.RequestType.Global, 0, 20, ( success, results ) => + { + Assert.IsTrue( success ); + + foreach ( var entry in board.Results ) + { + Console.WriteLine( $"{entry.GlobalRank}: {entry.SteamId} ({entry.Name}) with {entry.Score}" ); + + if ( entry.SubScores != null ) + Console.WriteLine( " - " + string.Join( ";", entry.SubScores.Select( x => x.ToString() ).ToArray() ) ); + } + + done = true; + } ); + + while ( !done ) + { + Thread.Sleep( 10 ); + client.Update(); + } + } + } + [TestMethod] public void AddScores() { diff --git a/Facepunch.Steamworks/Client/Leaderboard.cs b/Facepunch.Steamworks/Client/Leaderboard.cs index 326586b..18edbd5 100644 --- a/Facepunch.Steamworks/Client/Leaderboard.cs +++ b/Facepunch.Steamworks/Client/Leaderboard.cs @@ -125,6 +125,55 @@ namespace Facepunch.Steamworks return true; } + private unsafe void ReadScores( LeaderboardScoresDownloaded_t result, List dest ) + { + for ( var i = 0; i < result.CEntryCount; i++ ) + fixed ( int* ptr = subEntriesBuffer ) + { + var entry = new LeaderboardEntry_t(); + if ( client.native.userstats.GetDownloadedLeaderboardEntry( result.SteamLeaderboardEntries, i, ref entry, (IntPtr) ptr, subEntriesBuffer.Length ) ) + dest.Add( new Entry + { + GlobalRank = entry.GlobalRank, + Score = entry.Score, + SteamId = entry.SteamIDUser, + SubScores = entry.CDetails == 0 ? null : subEntriesBuffer.Take( entry.CDetails ).ToArray(), + Name = client.Friends.GetName( entry.SteamIDUser ) + } ); + } + } + + [ThreadStatic] private static List _sEntryBuffer; + + public delegate void FetchScoresCallback( bool success, Entry[] results ); + + /// + /// Fetch a subset of scores. The scores are passed to . + /// + /// Returns true if we have started the query + public bool FetchScores( RequestType RequestType, int start, int end, FetchScoresCallback callback ) + { + if ( !IsValid ) return false; + + client.native.userstats.DownloadLeaderboardEntries( BoardId, (LeaderboardDataRequest) RequestType, start, end, ( result, error ) => + { + if ( error ) + { + callback( false, null ); + } + else + { + if ( _sEntryBuffer == null ) _sEntryBuffer = new List(); + else _sEntryBuffer.Clear(); + + ReadScores( result, _sEntryBuffer ); + callback( true, _sEntryBuffer.ToArray() ); + } + } ); + + return true; + } + private unsafe void OnScores( LeaderboardScoresDownloaded_t result, bool error ) { IsQuerying = false; @@ -135,21 +184,7 @@ namespace Facepunch.Steamworks return; var list = new List(); - - for ( var i = 0; i < result.CEntryCount; i++ ) - fixed ( int* ptr = subEntriesBuffer ) - { - var entry = new LeaderboardEntry_t(); - if ( client.native.userstats.GetDownloadedLeaderboardEntry( result.SteamLeaderboardEntries, i, ref entry, (IntPtr) ptr, subEntriesBuffer.Length ) ) - list.Add( new Entry - { - GlobalRank = entry.GlobalRank, - Score = entry.Score, - SteamId = entry.SteamIDUser, - SubScores = entry.CDetails == 0 ? null : subEntriesBuffer.Take( entry.CDetails ).ToArray(), - Name = client.Friends.GetName( entry.SteamIDUser ) - } ); - } + ReadScores( result, list ); Results = list.ToArray(); }