mirror of
https://github.com/Facepunch/Facepunch.Steamworks.git
synced 2024-12-25 06:05:46 +03:00
Fixed downloading leaderboard file attachments
This commit is contained in:
parent
836f6e285c
commit
7e3527799a
@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
@ -169,5 +170,72 @@ public void AddScoresCallback()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void AddFileAttachment()
|
||||
{
|
||||
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;
|
||||
const string attachment = "Hello world!";
|
||||
|
||||
var file = client.RemoteStorage.CreateFile( "score/example.txt" );
|
||||
file.WriteAllText( attachment );
|
||||
|
||||
Assert.IsTrue( board.AddScore( false, score, null, ( success, result ) =>
|
||||
{
|
||||
Assert.IsTrue( success );
|
||||
Assert.IsTrue( result.ScoreChanged );
|
||||
|
||||
Assert.IsTrue( board.AttachRemoteFile( file, attached =>
|
||||
{
|
||||
Assert.IsTrue( attached );
|
||||
|
||||
done = true;
|
||||
} ) );
|
||||
} ) );
|
||||
|
||||
while ( !done )
|
||||
{
|
||||
Thread.Sleep( 10 );
|
||||
client.Update();
|
||||
}
|
||||
|
||||
done = false;
|
||||
|
||||
Assert.IsTrue( board.FetchScores( Steamworks.Leaderboard.RequestType.GlobalAroundUser, 0, 0, ( success, entries ) =>
|
||||
{
|
||||
Assert.AreEqual( 1, entries.Length );
|
||||
Assert.IsNotNull( entries[0].AttachedFile );
|
||||
|
||||
Assert.IsTrue( entries[0].AttachedFile.Download( downloaded =>
|
||||
{
|
||||
Assert.IsTrue( downloaded );
|
||||
Assert.AreEqual( attachment, entries[0].AttachedFile.ReadAllText() );
|
||||
|
||||
done = true;
|
||||
} ) );
|
||||
} ) );
|
||||
|
||||
while ( !done )
|
||||
{
|
||||
Thread.Sleep( 10 );
|
||||
client.Update();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -177,22 +177,20 @@ public bool AttachRemoteFile( RemoteFile file, AttachRemoteFileCallback callback
|
||||
|
||||
if ( file.IsShared )
|
||||
{
|
||||
client.native.userstats.AttachLeaderboardUGC( BoardId, file.UGCHandle, ( result, error ) =>
|
||||
var handle = client.native.userstats.AttachLeaderboardUGC( BoardId, file.UGCHandle, ( result, error ) =>
|
||||
{
|
||||
callback?.Invoke( !error && result.Result == Result.OK );
|
||||
} );
|
||||
return true;
|
||||
|
||||
return handle.CallResultHandle != 0;
|
||||
}
|
||||
|
||||
file.Share( success =>
|
||||
{
|
||||
if ( !success || !file.IsShared )
|
||||
if ( !success || !file.IsShared || !AttachRemoteFile( file, callback ) )
|
||||
{
|
||||
callback?.Invoke( false );
|
||||
return;
|
||||
}
|
||||
|
||||
AttachRemoteFile( file, callback );
|
||||
} );
|
||||
return true;
|
||||
}
|
||||
@ -226,7 +224,8 @@ private unsafe void ReadScores( LeaderboardScoresDownloaded_t result, List<Entry
|
||||
Score = entry.Score,
|
||||
SteamId = entry.SteamIDUser,
|
||||
SubScores = entry.CDetails == 0 ? null : subEntriesBuffer.Take( entry.CDetails ).ToArray(),
|
||||
Name = client.Friends.GetName( entry.SteamIDUser )
|
||||
Name = client.Friends.GetName( entry.SteamIDUser ),
|
||||
AttachedFile = (entry.UGC >> 32) == 0xffffffff ? null : new RemoteFile( client.RemoteStorage, entry.UGC )
|
||||
} );
|
||||
}
|
||||
}
|
||||
@ -288,7 +287,7 @@ public struct Entry
|
||||
public int Score;
|
||||
public int[] SubScores;
|
||||
public int GlobalRank;
|
||||
|
||||
public RemoteFile AttachedFile;
|
||||
|
||||
/// <summary>
|
||||
/// Note that the player's name might not be immediately available.
|
||||
|
@ -125,11 +125,18 @@ public class RemoteFile
|
||||
private UGCHandle_t _handle;
|
||||
private ulong _ownerId;
|
||||
|
||||
private bool _isDownloading;
|
||||
private byte[] _downloadedData;
|
||||
|
||||
/// <summary>
|
||||
/// Check if the file exists.
|
||||
/// </summary>
|
||||
public bool Exists { get; internal set; }
|
||||
|
||||
public bool IsDownloading { get { return _isUgc && _isDownloading && _downloadedData == null; } }
|
||||
|
||||
public bool IsDownloaded { get { return !_isUgc || _downloadedData != null; } }
|
||||
|
||||
/// <summary>
|
||||
/// If true, the file is available for other users to download.
|
||||
/// </summary>
|
||||
@ -137,6 +144,8 @@ public class RemoteFile
|
||||
|
||||
internal UGCHandle_t UGCHandle { get { return _handle; } }
|
||||
|
||||
public ulong SharingId { get { return UGCHandle.Value; } }
|
||||
|
||||
/// <summary>
|
||||
/// Name and path of the file.
|
||||
/// </summary>
|
||||
@ -201,7 +210,6 @@ internal RemoteFile( RemoteStorage r, string name, ulong ownerId, int sizeInByte
|
||||
/// <summary>
|
||||
/// Creates a <see cref="RemoteFileWriteStream"/> used to write to this file.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public RemoteFileWriteStream OpenWrite()
|
||||
{
|
||||
return new RemoteFileWriteStream( remoteStorage, this );
|
||||
@ -227,6 +235,62 @@ public void WriteAllText( string text, Encoding encoding = null )
|
||||
WriteAllBytes( encoding.GetBytes( text ) );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Callback invoked by <see cref="RemoteFile.Download"/> when a file download is complete.
|
||||
/// </summary>
|
||||
public delegate void DownloadCallback( bool success );
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of bytes downloaded and the total number of bytes expected while
|
||||
/// this file is downloading.
|
||||
/// </summary>
|
||||
/// <returns>True if the file is downloading</returns>
|
||||
public bool GetDownloadProgress( out int bytesDownloaded, out int bytesExpected )
|
||||
{
|
||||
return remoteStorage.native.GetUGCDownloadProgress( _handle, out bytesDownloaded, out bytesExpected );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to start downloading a shared file.
|
||||
/// </summary>
|
||||
/// <returns>True if the download has successfully started</returns>
|
||||
public bool Download( DownloadCallback callback = null )
|
||||
{
|
||||
if ( !_isUgc ) return false;
|
||||
if ( _isDownloading ) return false;
|
||||
if ( IsDownloaded ) return false;
|
||||
|
||||
_isDownloading = true;
|
||||
|
||||
remoteStorage.native.UGCDownload( _handle, 1000, ( result, error ) =>
|
||||
{
|
||||
_isDownloading = false;
|
||||
|
||||
if ( error || result.Result != Result.OK )
|
||||
{
|
||||
callback?.Invoke( false );
|
||||
return;
|
||||
}
|
||||
|
||||
_ownerId = result.SteamIDOwner;
|
||||
_sizeInBytes = result.SizeInBytes;
|
||||
_fileName = result.PchFileName;
|
||||
|
||||
unsafe
|
||||
{
|
||||
_downloadedData = new byte[_sizeInBytes];
|
||||
fixed ( byte* bufferPtr = _downloadedData )
|
||||
{
|
||||
remoteStorage.native.UGCRead( _handle, (IntPtr) bufferPtr, _sizeInBytes, 0, UGCReadAction.ontinueReading );
|
||||
}
|
||||
}
|
||||
|
||||
callback?.Invoke( true );
|
||||
} );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Opens a stream used to read from this file.
|
||||
/// </summary>
|
||||
@ -243,8 +307,8 @@ public unsafe byte[] ReadAllBytes()
|
||||
{
|
||||
if ( _isUgc )
|
||||
{
|
||||
// Need to download
|
||||
throw new NotImplementedException();
|
||||
if ( !IsDownloaded ) throw new Exception( "Cannot read a file that hasn't been downloaded." );
|
||||
return _downloadedData;
|
||||
}
|
||||
|
||||
var size = SizeInBytes;
|
||||
|
@ -14929,7 +14929,7 @@ public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamwo
|
||||
}
|
||||
}
|
||||
|
||||
[StructLayout( LayoutKind.Sequential, Pack = 4 )]
|
||||
[StructLayout( LayoutKind.Sequential, Pack = 8 )]
|
||||
internal struct LeaderboardEntry_t
|
||||
{
|
||||
public ulong SteamIDUser; // m_steamIDUser class CSteamID
|
||||
|
@ -30,6 +30,11 @@ public class TypeDef
|
||||
"CCallbackBase"
|
||||
};
|
||||
|
||||
public readonly static string[] ForceLargePackStructs = new string[]
|
||||
{
|
||||
"LeaderboardEntry_t"
|
||||
};
|
||||
|
||||
void Structs()
|
||||
{
|
||||
foreach ( var c in def.structs )
|
||||
@ -42,7 +47,7 @@ void Structs()
|
||||
|
||||
int defaultPack = 8;
|
||||
|
||||
if ( c.Fields.Any( x => x.Type.Contains( "class CSteamID" ) ) )
|
||||
if ( c.Fields.Any( x => x.Type.Contains( "class CSteamID" ) ) && !ForceLargePackStructs.Contains( c.Name ) )
|
||||
defaultPack = 4;
|
||||
|
||||
//
|
||||
|
Loading…
Reference in New Issue
Block a user