diff --git a/Facepunch.Steamworks/SteamUgc.cs b/Facepunch.Steamworks/SteamUgc.cs
index e53ebbe..e3a8654 100644
--- a/Facepunch.Steamworks/SteamUgc.cs
+++ b/Facepunch.Steamworks/SteamUgc.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
+using System.Threading;
using System.Threading.Tasks;
using Steamworks.Data;
@@ -38,11 +39,91 @@ namespace Steamworks
return r?.Result == Result.OK;
}
+ ///
+ /// Start downloading this item. You'll get notified of completion via OnDownloadItemResult.
+ ///
+ /// The ID of the file you want to download
+ /// If true this should go straight to the top of the download list
+ /// true if nothing went wrong and the download is started
public static bool Download( PublishedFileId fileId, bool highPriority = false )
{
return Internal.DownloadItem( fileId, highPriority );
}
+ ///
+ /// Will attempt to download this item asyncronously - allowing you to instantly react to its installation
+ ///
+ /// The ID of the file you want to download
+ /// An optional callback
+ /// Allows you to send a message to cancel the download anywhere during the process
+ /// How often to call the progress function
+ /// true if downloaded and installed correctly
+ public static async Task DownloadAsync( PublishedFileId fileId, Action progress = null, CancellationToken ct = default, int milisecondsUpdateDelay = 60 )
+ {
+ var item = new Steamworks.Ugc.Item( fileId );
+
+ if ( ct == default )
+ ct = new CancellationTokenSource( TimeSpan.FromSeconds( 60 ) ).Token;
+
+ progress?.Invoke( 0.0f );
+
+ if ( Download( fileId, true ) == false )
+ return item.IsInstalled;
+
+ // Steam docs about Download:
+ // If the return value is true then register and wait
+ // for the Callback DownloadItemResult_t before calling
+ // GetItemInstallInfo or accessing the workshop item on disk.
+
+ // Wait for DownloadItemResult_t
+ {
+ Action onDownloadStarted = null;
+
+ try
+ {
+ var downloadStarted = false;
+
+ onDownloadStarted = r => downloadStarted = true;
+ OnDownloadItemResult += onDownloadStarted;
+
+ while ( downloadStarted == false )
+ {
+ if ( ct.IsCancellationRequested )
+ break;
+
+ await Task.Delay( milisecondsUpdateDelay );
+ }
+ }
+ finally
+ {
+ OnDownloadItemResult -= onDownloadStarted;
+ }
+ }
+
+ progress?.Invoke( 0.2f );
+ await Task.Delay( milisecondsUpdateDelay );
+
+ //Wait for downloading completion
+ {
+ while ( true )
+ {
+ if ( ct.IsCancellationRequested )
+ break;
+
+ progress?.Invoke( 0.2f + item.DownloadAmount * 0.8f );
+
+ if ( !item.IsDownloading && item.IsInstalled )
+ break;
+
+ await Task.Delay( milisecondsUpdateDelay );
+ }
+ }
+
+ progress?.Invoke( 1.0f );
+
+ return item.IsInstalled;
+ }
+
///
/// Utility function to fetch a single item. Internally this uses Ugc.FileQuery -
/// which you can use to query multiple items if you need to.
diff --git a/Facepunch.Steamworks/Structs/UgcItem.cs b/Facepunch.Steamworks/Structs/UgcItem.cs
index fe5dd05..a614789 100644
--- a/Facepunch.Steamworks/Structs/UgcItem.cs
+++ b/Facepunch.Steamworks/Structs/UgcItem.cs
@@ -126,11 +126,11 @@ namespace Steamworks.Ugc
///
/// Start downloading this item.
- /// If this returns false the item isn#t getting downloaded.
+ /// If this returns false the item isn't getting downloaded.
///
public bool Download( bool highPriority = false )
{
- return SteamUGC.Internal.DownloadItem( Id, highPriority );
+ return SteamUGC.Download( Id, highPriority );
}
///
@@ -258,79 +258,13 @@ namespace Steamworks.Ugc
}
///
- /// Allows the user to subscribe to this item and wait for it to be downloaded
+ /// Allows the user to subscribe to download this item asyncronously
/// If CancellationToken is default then there is 60 seconds timeout
/// Progress will be set to 0-1
///
- public async Task SubscribeDownloadAsync( Action progress = null, CancellationToken ct = default, int milisecondsUpdateDelay = 60 )
+ public async Task DownloadAsync( Action progress = null, CancellationToken ct = default, int milisecondsUpdateDelay = 60 )
{
- if ( ct == default )
- ct = new CancellationTokenSource( TimeSpan.FromSeconds( 60 ) ).Token;
-
- progress?.Invoke( 0 );
- await Task.Delay( milisecondsUpdateDelay );
-
- //Subscribe
- {
- var subResult = await SteamUGC.Internal.SubscribeItem( _id );
- if ( subResult?.Result != Result.OK )
- return false;
- }
-
- progress?.Invoke( 0.1f );
- await Task.Delay( milisecondsUpdateDelay );
-
- //Try to start downloading
- {
- if ( Download( true ) == false )
- return State.HasFlag( ItemState.Installed );
-
- //Steam docs about Download:
- //If the return value is true then register and wait
- //for the Callback DownloadItemResult_t before calling
- //GetItemInstallInfo or accessing the workshop item on disk.
-
- //Wait for DownloadItemResult_t
- {
- var downloadStarted = false;
- Action onDownloadStarted = null;
- onDownloadStarted = r =>
- {
- SteamUGC.OnDownloadItemResult -= onDownloadStarted;
- downloadStarted = true;
- };
- SteamUGC.OnDownloadItemResult += onDownloadStarted;
-
- while ( downloadStarted == false )
- {
- if ( ct.IsCancellationRequested )
- break;
-
- await Task.Delay( milisecondsUpdateDelay );
- }
- }
- }
-
- progress?.Invoke( 0.2f );
- await Task.Delay( milisecondsUpdateDelay );
-
- //Wait for downloading completion
- {
- while ( true )
- {
- if ( ct.IsCancellationRequested )
- break;
-
- progress?.Invoke( 0.2f + DownloadAmount * 0.8f );
-
- if ( !IsDownloading && State.HasFlag( ItemState.Installed ) )
- break;
-
- await Task.Delay( milisecondsUpdateDelay );
- }
- }
-
- return State.HasFlag( ItemState.Installed );
+ return await SteamUGC.DownloadAsync( Id, progress, ct, milisecondsUpdateDelay );
}
///