diff --git a/Facepunch.Steamworks/Interfaces/Workshop.cs b/Facepunch.Steamworks/Interfaces/Workshop.cs index 64ae67e..c61413c 100644 --- a/Facepunch.Steamworks/Interfaces/Workshop.cs +++ b/Facepunch.Steamworks/Interfaces/Workshop.cs @@ -1,5 +1,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics; +using System.Runtime.InteropServices; using SteamNative; namespace Facepunch.Steamworks @@ -20,6 +22,12 @@ namespace Facepunch.Steamworks /// public partial class Workshop : IDisposable { + static Workshop() + { + Debug.Assert( Marshal.SizeOf( typeof(PublishedFileId_t) ) == Marshal.SizeOf( typeof(ulong) ), + $"sizeof({nameof(PublishedFileId_t)}) != sizeof({nameof(UInt64)})" ); + } + internal const ulong InvalidHandle = 0xffffffffffffffff; internal SteamNative.SteamUGC ugc; @@ -76,6 +84,60 @@ private void onDownloadResult( SteamNative.DownloadItemResult_t obj ) OnFileDownloaded( obj.PublishedFileId, (Callbacks.Result) obj.Result ); } + /// + /// Get the IDs of all subscribed workshop items. Not all items may be currently installed. + /// + public unsafe ulong[] GetSubscribedItemIds() + { + var count = ugc.GetNumSubscribedItems(); + var array = new ulong[count]; + + fixed ( ulong* ptr = array ) + { + ugc.GetSubscribedItems( (PublishedFileId_t*) ptr, count ); + } + + return array; + } + + [ThreadStatic] + private static ulong[] _sSubscribedItemBuffer; + + /// + /// Get the IDs of all subscribed workshop items, avoiding repeated allocations. + /// Not all items may be currently installed. + /// + public unsafe int GetSubscribedItemIds( List destList ) + { + const int bufferSize = 1024; + + var count = ugc.GetNumSubscribedItems(); + + if ( count >= bufferSize ) + { + // Fallback for exceptional cases + destList.AddRange( GetSubscribedItemIds() ); + return (int) count; + } + + if ( _sSubscribedItemBuffer == null ) + { + _sSubscribedItemBuffer = new ulong[bufferSize]; + } + + fixed ( ulong* ptr = _sSubscribedItemBuffer) + { + count = ugc.GetSubscribedItems( (PublishedFileId_t*) ptr, bufferSize ); + } + + for ( var i = 0; i < count; ++i ) + { + destList.Add( _sSubscribedItemBuffer[i] ); + } + + return (int) count; + } + /// /// Creates a query object, which is used to get a list of items. ///