diff --git a/Facepunch.Steamworks.Test/Client/Leaderboard.cs b/Facepunch.Steamworks.Test/Client/Leaderboard.cs
index 6de0efc..1eb6388 100644
--- a/Facepunch.Steamworks.Test/Client/Leaderboard.cs
+++ b/Facepunch.Steamworks.Test/Client/Leaderboard.cs
@@ -68,9 +68,6 @@ namespace Facepunch.Steamworks.Test
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;
@@ -79,7 +76,7 @@ namespace Facepunch.Steamworks.Test
{
Assert.IsTrue( success );
- foreach ( var entry in board.Results )
+ foreach ( var entry in results )
{
Console.WriteLine( $"{entry.GlobalRank}: {entry.SteamId} ({entry.Name}) with {entry.Score}" );
@@ -135,5 +132,40 @@ namespace Facepunch.Steamworks.Test
client.Update();
}
}
+
+ [TestMethod]
+ public void AddScoresCallback()
+ {
+ 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 );
+
+ var done = false;
+
+ const int score = 5678;
+
+ board.AddScore( false, score, null, ( success, result ) =>
+ {
+ Assert.IsTrue( success );
+ Assert.IsTrue( result.ScoreChanged );
+ Assert.AreEqual( result.Score, score );
+ } );
+
+ while ( !done )
+ {
+ Thread.Sleep( 10 );
+ client.Update();
+ }
+ }
+ }
}
}
\ No newline at end of file
diff --git a/Facepunch.Steamworks/Client/Leaderboard.cs b/Facepunch.Steamworks/Client/Leaderboard.cs
index 18edbd5..db4fce7 100644
--- a/Facepunch.Steamworks/Client/Leaderboard.cs
+++ b/Facepunch.Steamworks/Client/Leaderboard.cs
@@ -99,14 +99,66 @@ namespace Facepunch.Steamworks
/// If onlyIfBeatsOldScore is true, the score will only be updated if it beats the existing score, else it will always
/// be updated.
///
- public void AddScore( bool onlyIfBeatsOldScore, int score, params int[] subscores )
+ public bool AddScore( bool onlyIfBeatsOldScore, int score, params int[] subscores )
{
- if ( !IsValid ) return;
+ if ( !IsValid ) return false;
var flags = LeaderboardUploadScoreMethod.ForceUpdate;
if ( onlyIfBeatsOldScore ) flags = LeaderboardUploadScoreMethod.KeepBest;
client.native.userstats.UploadLeaderboardScore( BoardId, flags, score, subscores, subscores.Length );
+
+ return true;
+ }
+
+ ///
+ /// Callback invoked by when score submission
+ /// is complete.
+ ///
+ /// If true, the score was submitted
+ /// If successful, information about the new entry
+ public delegate void AddScoreCallback( bool success, AddScoreResult result );
+
+ ///
+ /// Information about a newly submitted score.
+ ///
+ public struct AddScoreResult
+ {
+ public int Score;
+ public bool ScoreChanged;
+ public int GlobalRankNew;
+ public int GlobalRankPrevious;
+ }
+
+ ///
+ /// Add a score to this leaderboard.
+ /// Subscores are totally optional, and can be used for other game defined data such as laps etc.. although
+ /// they have no bearing on sorting at all
+ /// If onlyIfBeatsOldScore is true, the score will only be updated if it beats the existing score, else it will always
+ /// be updated.
+ /// Information about the newly submitted score is passed to the optional .
+ ///
+ public bool AddScore( bool onlyIfBeatsOldScore, int score, int[] subscores = null, AddScoreCallback callback = null )
+ {
+ if ( !IsValid ) return false;
+
+ if ( subscores == null ) subscores = new int[0];
+
+ var flags = LeaderboardUploadScoreMethod.ForceUpdate;
+ if ( onlyIfBeatsOldScore ) flags = LeaderboardUploadScoreMethod.KeepBest;
+
+ client.native.userstats.UploadLeaderboardScore( BoardId, flags, score, subscores, subscores.Length, callback != null ? (Action) (( result, error ) =>
+ {
+ callback( !error && result.Success != 0, new AddScoreResult
+ {
+ Score = result.Score,
+ ScoreChanged = result.ScoreChanged != 0,
+ GlobalRankNew = result.GlobalRankNew,
+ GlobalRankPrevious = result.GlobalRankPrevious
+ } );
+ }) : null );
+
+ return true;
}
///
@@ -145,6 +197,10 @@ namespace Facepunch.Steamworks
[ThreadStatic] private static List _sEntryBuffer;
+ ///
+ /// Callback invoked by when
+ /// a query is complete.
+ ///
public delegate void FetchScoresCallback( bool success, Entry[] results );
///
@@ -174,14 +230,12 @@ namespace Facepunch.Steamworks
return true;
}
- private unsafe void OnScores( LeaderboardScoresDownloaded_t result, bool error )
+ private void OnScores( LeaderboardScoresDownloaded_t result, bool error )
{
IsQuerying = false;
if ( client == null ) return;
-
- if ( error )
- return;
+ if ( error ) return;
var list = new List();
ReadScores( result, list );