mirror of
https://github.com/Facepunch/Facepunch.Steamworks.git
synced 2025-01-24 04:28:00 +03:00
Create/Publish/Delete workshop files
This commit is contained in:
parent
3ff2b304a5
commit
d4eb325606
@ -38,7 +38,7 @@ namespace Facepunch.Steamworks.Test
|
||||
Console.WriteLine( "Searching" );
|
||||
|
||||
Query.Order = Workshop.Order.RankedByTextSearch;
|
||||
Query.QueryType = Workshop.QueryType.Items_Mtx;
|
||||
Query.QueryType = Workshop.QueryType.MicrotransactionItems;
|
||||
Query.SearchText = "shit";
|
||||
Query.RequireTags.Add( "LongTShirt Skin" );
|
||||
Query.Run();
|
||||
@ -237,5 +237,34 @@ namespace Facepunch.Steamworks.Test
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[TestCategory( "Run Manually" )]
|
||||
public void CreatePublish()
|
||||
{
|
||||
using ( var client = new Facepunch.Steamworks.Client( 252490 ) )
|
||||
{
|
||||
Assert.IsTrue( client.IsValid );
|
||||
|
||||
var item = client.Workshop.CreateItem( Workshop.ItemType.Microtransaction );
|
||||
|
||||
item.Title = "Facepunch.Steamworks Unit test";
|
||||
|
||||
item.Publish();
|
||||
|
||||
while ( item.Publishing )
|
||||
{
|
||||
client.Update();
|
||||
Thread.Sleep( 100 );
|
||||
}
|
||||
|
||||
Assert.IsFalse( item.Publishing );
|
||||
Assert.AreNotEqual( 0, item.Id );
|
||||
|
||||
Console.WriteLine( "item.Id: {0}", item.Id );
|
||||
|
||||
item.Delete();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ namespace Facepunch.Steamworks
|
||||
{
|
||||
Networking = new Steamworks.Networking( this, native.networking );
|
||||
Inventory = new Steamworks.Inventory( native.inventory, IsGameServer );
|
||||
Workshop = new Steamworks.Workshop( this, native.ugc );
|
||||
Workshop = new Steamworks.Workshop( this, native.ugc, native.remoteStorage );
|
||||
}
|
||||
|
||||
public bool IsValid
|
||||
@ -88,12 +88,14 @@ namespace Facepunch.Steamworks
|
||||
/// <summary>
|
||||
/// Call results are results to specific actions
|
||||
/// </summary>
|
||||
internal void AddCallResult( CallResult c )
|
||||
internal void AddCallResult( CallResult call )
|
||||
{
|
||||
if ( FinishCallback( c ) )
|
||||
if ( call == null ) throw new ArgumentNullException( "call" );
|
||||
|
||||
if ( FinishCallback( call ) )
|
||||
return;
|
||||
|
||||
Callbacks.Add( c );
|
||||
Callbacks.Add( call );
|
||||
}
|
||||
|
||||
void RunCallbackQueue()
|
||||
|
@ -1,8 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Runtime.InteropServices;
|
||||
using Facepunch.Steamworks.Interop;
|
||||
|
||||
namespace Facepunch.Steamworks.Callbacks.Workshop
|
||||
@ -32,8 +28,6 @@ namespace Facepunch.Steamworks.Callbacks.Workshop
|
||||
public const int CallbackId = Index.UGC + 6;
|
||||
};
|
||||
|
||||
|
||||
|
||||
internal class QueryCompleted : CallResult<QueryCompleted.Data>
|
||||
{
|
||||
public override int CallbackId { get { return Index.UGC + 1; } }
|
||||
@ -50,5 +44,30 @@ namespace Facepunch.Steamworks.Callbacks.Workshop
|
||||
};
|
||||
}
|
||||
|
||||
internal class CreateItem : CallResult<CreateItem.Data>
|
||||
{
|
||||
public override int CallbackId { get { return Index.UGC + 3; } }
|
||||
|
||||
[StructLayout( LayoutKind.Sequential )]
|
||||
internal struct Data
|
||||
{
|
||||
internal Result Result;
|
||||
internal ulong FileId;
|
||||
[MarshalAs(UnmanagedType.I1)]
|
||||
internal bool NeedsLegalAgreement;
|
||||
};
|
||||
}
|
||||
|
||||
internal class SubmitItemUpdate : CallResult<SubmitItemUpdate.Data>
|
||||
{
|
||||
public override int CallbackId { get { return Index.UGC + 4; } }
|
||||
|
||||
[StructLayout( LayoutKind.Sequential )]
|
||||
internal struct Data
|
||||
{
|
||||
internal Result Result;
|
||||
[MarshalAs(UnmanagedType.I1)]
|
||||
internal bool NeedsLegalAgreement;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -137,7 +137,9 @@
|
||||
<Compile Include="Config.cs" />
|
||||
<Compile Include="Callbacks\Networking.cs" />
|
||||
<Compile Include="Interfaces\Workshop.cs" />
|
||||
<Compile Include="Interfaces\Workshop.Editor.cs" />
|
||||
<Compile Include="Interfaces\Workshop.Item.cs" />
|
||||
<Compile Include="Interfaces\Workshop.Query.cs" />
|
||||
<Compile Include="Interop\Callback.cs" />
|
||||
<Compile Include="Interop\CallResult.cs" />
|
||||
<Compile Include="Interop\Native.cs" />
|
||||
|
@ -98,10 +98,7 @@ namespace Facepunch.Steamworks
|
||||
|
||||
int[] ids;
|
||||
if ( !inventory.GetItemDefinitionIDs( out ids ) )
|
||||
{
|
||||
Console.WriteLine( "Couldn't load definitions" );
|
||||
return;
|
||||
}
|
||||
|
||||
Definitions = ids.Select( x =>
|
||||
{
|
||||
|
120
Facepunch.Steamworks/Interfaces/Workshop.Editor.cs
Normal file
120
Facepunch.Steamworks/Interfaces/Workshop.Editor.cs
Normal file
@ -0,0 +1,120 @@
|
||||
using System;
|
||||
using Facepunch.Steamworks.Callbacks.Workshop;
|
||||
|
||||
namespace Facepunch.Steamworks
|
||||
{
|
||||
public partial class Workshop
|
||||
{
|
||||
public class Editor
|
||||
{
|
||||
internal Workshop workshop;
|
||||
|
||||
internal CreateItem CreateItem;
|
||||
internal SubmitItemUpdate SubmitItemUpdate;
|
||||
|
||||
public ulong Id { get; internal set; }
|
||||
public string Title { get; set; }
|
||||
public string Description { get; set; }
|
||||
public bool Publishing { get; internal set; }
|
||||
public ItemType? Type { get; set; }
|
||||
|
||||
public string ChangeNote { get; set; } = "";
|
||||
|
||||
public bool NeedToAgreeToWorkshopLegal { get; internal set; }
|
||||
|
||||
public void Publish()
|
||||
{
|
||||
Publishing = true;
|
||||
|
||||
if ( Id == 0 )
|
||||
{
|
||||
StartCreatingItem();
|
||||
return;
|
||||
}
|
||||
|
||||
PublishChanges();
|
||||
}
|
||||
|
||||
private void StartCreatingItem()
|
||||
{
|
||||
if ( !Type.HasValue )
|
||||
throw new System.Exception( "Editor.Type must be set when creating a new item!" );
|
||||
|
||||
CreateItem = new CreateItem();
|
||||
CreateItem.Handle = workshop.ugc.CreateItem( workshop.steamworks.AppId, (uint)Type );
|
||||
CreateItem.OnResult = OnItemCreated;
|
||||
workshop.steamworks.AddCallResult( CreateItem );
|
||||
}
|
||||
|
||||
private void OnItemCreated( CreateItem.Data obj )
|
||||
{
|
||||
NeedToAgreeToWorkshopLegal = obj.NeedsLegalAgreement;
|
||||
CreateItem = null;
|
||||
|
||||
if ( obj.Result == Callbacks.Result.OK )
|
||||
{
|
||||
Id = obj.FileId;
|
||||
PublishChanges();
|
||||
return;
|
||||
}
|
||||
|
||||
Console.WriteLine( "File publish error: " + obj );
|
||||
Publishing = false;
|
||||
}
|
||||
|
||||
private void PublishChanges()
|
||||
{
|
||||
Publishing = false;
|
||||
|
||||
ulong UpdateId = workshop.ugc.StartItemUpdate( workshop.steamworks.AppId, Id );
|
||||
|
||||
if ( Title != null )
|
||||
workshop.ugc.SetItemTitle( UpdateId, Title );
|
||||
|
||||
if ( Description != null )
|
||||
workshop.ugc.SetItemDescription( UpdateId, Description );
|
||||
|
||||
/*
|
||||
workshop.ugc.SetItemUpdateLanguage( UpdateId, const char *pchLanguage ) = 0; // specify the language of the title or description that will be set
|
||||
workshop.ugc.SetItemMetadata( UpdateId, const char *pchMetaData ) = 0; // change the metadata of an UGC item (max = k_cchDeveloperMetadataMax)
|
||||
workshop.ugc.SetItemVisibility( UpdateId, ERemoteStoragePublishedFileVisibility eVisibility ) = 0; // change the visibility of an UGC item
|
||||
workshop.ugc.SetItemTags( UpdateId, const SteamParamStringArray_t *pTags ) = 0; // change the tags of an UGC item
|
||||
workshop.ugc.SetItemContent( UpdateId, const char *pszContentFolder ) = 0; // update item content from this local folder
|
||||
workshop.ugc.SetItemPreview( UpdateId, const char *pszPreviewFile ) = 0; // change preview image file for this item. pszPreviewFile points to local image file, which must be under 1MB in size
|
||||
workshop.ugc.RemoveItemKeyValueTags( UpdateId, const char *pchKey ) = 0; // remove any existing key-value tags with the specified key
|
||||
workshop.ugc.AddItemKeyValueTag( UpdateId, const char *pchKey, const char *pchValue ) = 0; // add new key-value tags for the item. Note that there can be multiple values for a tag.
|
||||
workshop.ugc.AddItemPreviewFile( UpdateId, const char *pszPreviewFile, EItemPreviewType type ) = 0; // add preview file for this item. pszPreviewFile points to local file, which must be under 1MB in size
|
||||
workshop.ugc.AddItemPreviewVideo( UpdateId, const char *pszVideoID ) = 0; // add preview video for this item
|
||||
workshop.ugc.UpdateItemPreviewFile( UpdateId, uint32 index, const char *pszPreviewFile ) = 0; // updates an existing preview file for this item. pszPreviewFile points to local file, which must be under 1MB in size
|
||||
workshop.ugc.UpdateItemPreviewVideo( UpdateId, uint32 index, const char *pszVideoID ) = 0; // updates an existing preview video for this item
|
||||
workshop.ugc.RemoveItemPreview( UpdateId, uint32 index ) = 0; // remove a preview by index starting at 0 (previews are sorted)
|
||||
|
||||
*/
|
||||
|
||||
SubmitItemUpdate = new SubmitItemUpdate();
|
||||
SubmitItemUpdate.Handle = workshop.ugc.SubmitItemUpdate( UpdateId, ChangeNote );
|
||||
SubmitItemUpdate.OnResult = OnChangesSubmitted;
|
||||
workshop.steamworks.AddCallResult( SubmitItemUpdate );
|
||||
}
|
||||
|
||||
private void OnChangesSubmitted( SubmitItemUpdate.Data obj )
|
||||
{
|
||||
SubmitItemUpdate = null;
|
||||
|
||||
NeedToAgreeToWorkshopLegal = obj.NeedsLegalAgreement;
|
||||
|
||||
if ( obj.Result == Callbacks.Result.OK )
|
||||
{
|
||||
Publishing = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public void Delete()
|
||||
{
|
||||
workshop.remoteStorage.DeletePublishedFile( Id );
|
||||
Id = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
150
Facepunch.Steamworks/Interfaces/Workshop.Query.cs
Normal file
150
Facepunch.Steamworks/Interfaces/Workshop.Query.cs
Normal file
@ -0,0 +1,150 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using Facepunch.Steamworks.Callbacks.Networking;
|
||||
using Facepunch.Steamworks.Callbacks.Workshop;
|
||||
using Facepunch.Steamworks.Interop;
|
||||
using Valve.Steamworks;
|
||||
|
||||
namespace Facepunch.Steamworks
|
||||
{
|
||||
public partial class Workshop
|
||||
{
|
||||
public class Query : IDisposable
|
||||
{
|
||||
internal ulong Handle;
|
||||
internal QueryCompleted Callback;
|
||||
|
||||
/// <summary>
|
||||
/// The AppId you're querying. This defaults to this appid.
|
||||
/// </summary>
|
||||
public uint AppId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The AppId of the app used to upload the item. This defaults to 0
|
||||
/// which means all/any.
|
||||
/// </summary>
|
||||
public uint UploaderAppId { get; set; }
|
||||
|
||||
public QueryType QueryType { get; set; } = QueryType.Items;
|
||||
public Order Order { get; set; } = Order.RankedByVote;
|
||||
|
||||
public string SearchText { get; set; }
|
||||
|
||||
public Item[] Items { get; set; }
|
||||
|
||||
public int TotalResults { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Page starts at 1 !!
|
||||
/// </summary>
|
||||
public int Page { get; set; } = 1;
|
||||
internal Workshop workshop;
|
||||
|
||||
public unsafe void Run()
|
||||
{
|
||||
if ( Callback != null )
|
||||
return;
|
||||
|
||||
if ( Page <= 0 )
|
||||
throw new System.Exception( "Page should be 1 or above" );
|
||||
|
||||
if ( FileId.Count != 0 )
|
||||
{
|
||||
var fileArray = FileId.ToArray();
|
||||
|
||||
fixed ( ulong* array = fileArray )
|
||||
{
|
||||
Handle = workshop.ugc.CreateQueryUGCDetailsRequest( (IntPtr)array, (uint)fileArray.Length );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Handle = workshop.ugc.CreateQueryAllUGCRequest( (uint)Order, (uint)QueryType, UploaderAppId, AppId, (uint)Page );
|
||||
}
|
||||
|
||||
if ( !string.IsNullOrEmpty( SearchText ) )
|
||||
workshop.ugc.SetSearchText( Handle, SearchText );
|
||||
|
||||
foreach ( var tag in RequireTags )
|
||||
workshop.ugc.AddRequiredTag( Handle, tag );
|
||||
|
||||
if ( RequireTags.Count > 0 )
|
||||
workshop.ugc.SetMatchAnyTag( Handle, RequireAllTags );
|
||||
|
||||
foreach ( var tag in ExcludeTags )
|
||||
workshop.ugc.AddExcludedTag( Handle, tag );
|
||||
|
||||
Callback = new QueryCompleted();
|
||||
Callback.Handle = workshop.ugc.SendQueryUGCRequest( Handle );
|
||||
Callback.OnResult = OnResult;
|
||||
workshop.steamworks.AddCallResult( Callback );
|
||||
}
|
||||
|
||||
void OnResult( QueryCompleted.Data data )
|
||||
{
|
||||
Items = new Item[data.m_unNumResultsReturned];
|
||||
for ( int i = 0; i < data.m_unNumResultsReturned; i++ )
|
||||
{
|
||||
SteamUGCDetails_t details = new SteamUGCDetails_t();
|
||||
workshop.ugc.GetQueryUGCResult( data.Handle, (uint)i, ref details );
|
||||
|
||||
Items[i] = Item.From( details, workshop );
|
||||
}
|
||||
|
||||
TotalResults = (int)data.m_unTotalMatchingResults;
|
||||
|
||||
Callback.Dispose();
|
||||
Callback = null;
|
||||
}
|
||||
|
||||
public bool IsRunning
|
||||
{
|
||||
get { return Callback != null; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Only return items with these tags
|
||||
/// </summary>
|
||||
public List<string> RequireTags { get; set; } = new List<string>();
|
||||
|
||||
/// <summary>
|
||||
/// If true, return items that have all RequireTags
|
||||
/// If false, return items that have any tags in RequireTags
|
||||
/// </summary>
|
||||
public bool RequireAllTags { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Don't return any items with this tag
|
||||
/// </summary>
|
||||
public List<string> ExcludeTags { get; set; } = new List<string>();
|
||||
|
||||
/// <summary>
|
||||
/// If you're querying for a particular file or files, add them to this.
|
||||
/// </summary>
|
||||
public List<ulong> FileId { get; set; } = new List<ulong>();
|
||||
|
||||
/// <summary>
|
||||
/// Don't call this in production!
|
||||
/// </summary>
|
||||
public void Block()
|
||||
{
|
||||
workshop.steamworks.Update();
|
||||
|
||||
while ( IsRunning )
|
||||
{
|
||||
System.Threading.Thread.Sleep( 10 );
|
||||
workshop.steamworks.Update();
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
// ReleaseQueryUGCRequest
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,11 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using Facepunch.Steamworks.Callbacks.Workshop;
|
||||
using Facepunch.Steamworks.Interop;
|
||||
using Valve.Steamworks;
|
||||
|
||||
namespace Facepunch.Steamworks
|
||||
@ -16,35 +11,47 @@ namespace Facepunch.Steamworks
|
||||
|
||||
internal ISteamUGC ugc;
|
||||
internal BaseSteamworks steamworks;
|
||||
internal ISteamRemoteStorage remoteStorage;
|
||||
|
||||
internal event Action<ulong, Callbacks.Result> OnFileDownloaded;
|
||||
internal event Action<ulong> OnItemInstalled;
|
||||
|
||||
internal Workshop( BaseSteamworks sw, ISteamUGC ugc )
|
||||
internal Workshop( BaseSteamworks steamworks, ISteamUGC ugc, ISteamRemoteStorage remoteStorage )
|
||||
{
|
||||
this.ugc = ugc;
|
||||
this.steamworks = sw;
|
||||
this.steamworks = steamworks;
|
||||
this.remoteStorage = remoteStorage;
|
||||
|
||||
sw.AddCallback<DownloadResult>( onDownloadResult, DownloadResult.CallbackId );
|
||||
sw.AddCallback<ItemInstalled>( onItemInstalled, ItemInstalled.CallbackId );
|
||||
steamworks.AddCallback<DownloadResult>( onDownloadResult, DownloadResult.CallbackId );
|
||||
steamworks.AddCallback<ItemInstalled>( onItemInstalled, ItemInstalled.CallbackId );
|
||||
}
|
||||
|
||||
private void onItemInstalled( ItemInstalled obj )
|
||||
{
|
||||
Console.WriteLine( "OnItemInstalled" );
|
||||
|
||||
if ( OnItemInstalled != null )
|
||||
OnItemInstalled( obj.FileId );
|
||||
}
|
||||
|
||||
private void onDownloadResult( DownloadResult obj )
|
||||
{
|
||||
Console.WriteLine( "onDownloadResult" );
|
||||
|
||||
if ( OnFileDownloaded != null )
|
||||
OnFileDownloaded( obj.FileId, obj.Result );
|
||||
}
|
||||
|
||||
public Query CreateQuery()
|
||||
{
|
||||
return new Query()
|
||||
{
|
||||
AppId = steamworks.AppId,
|
||||
workshop = this
|
||||
};
|
||||
}
|
||||
|
||||
public Editor CreateItem( ItemType type )
|
||||
{
|
||||
return new Editor() { workshop = this, Type = type };
|
||||
}
|
||||
|
||||
public enum Order
|
||||
{
|
||||
RankedByVote = 0,
|
||||
@ -64,9 +71,18 @@ namespace Facepunch.Steamworks
|
||||
|
||||
public enum QueryType
|
||||
{
|
||||
Items = 0, // both mtx items and ready-to-use items
|
||||
Items_Mtx = 1,
|
||||
Items_ReadyToUse = 2,
|
||||
/// <summary>
|
||||
/// Both MicrotransactionItems and subscriptionItems
|
||||
/// </summary>
|
||||
Items = 0,
|
||||
/// <summary>
|
||||
/// Workshop item that is meant to be voted on for the purpose of selling in-game
|
||||
/// </summary>
|
||||
MicrotransactionItems = 1,
|
||||
/// <summary>
|
||||
/// normal Workshop item that can be subscribed to
|
||||
/// </summary>
|
||||
subscriptionItems = 2,
|
||||
Collections = 3,
|
||||
Artwork = 4,
|
||||
Videos = 5,
|
||||
@ -79,146 +95,27 @@ namespace Facepunch.Steamworks
|
||||
GameManagedItems = 12, // game managed items (not managed by users)
|
||||
};
|
||||
|
||||
public WorkshopQuery CreateQuery()
|
||||
public enum ItemType
|
||||
{
|
||||
var q = new WorkshopQuery();
|
||||
q.AppId = steamworks.AppId;
|
||||
q.workshop = this;
|
||||
return q;
|
||||
}
|
||||
Community = 0, // normal Workshop item that can be subscribed to
|
||||
Microtransaction = 1, // Workshop item that is meant to be voted on for the purpose of selling in-game
|
||||
Collection = 2, // a collection of Workshop or Greenlight items
|
||||
Art = 3, // artwork
|
||||
Video = 4, // external video
|
||||
Screenshot = 5, // screenshot
|
||||
Game = 6, // Greenlight game entry
|
||||
Software = 7, // Greenlight software entry
|
||||
Concept = 8, // Greenlight concept
|
||||
WebGuide = 9, // Steam web guide
|
||||
IntegratedGuide = 10, // application integrated guide
|
||||
Merch = 11, // Workshop merchandise meant to be voted on for the purpose of being sold
|
||||
ControllerBinding = 12, // Steam Controller bindings
|
||||
SteamworksAccessInvite = 13, // internal
|
||||
SteamVideo = 14, // Steam video
|
||||
GameManagedItem = 15, // managed completely by the game, not the user, and not shown on the web
|
||||
};
|
||||
|
||||
public class WorkshopQuery : IDisposable
|
||||
{
|
||||
internal ulong Handle;
|
||||
internal QueryCompleted Callback;
|
||||
|
||||
/// <summary>
|
||||
/// The AppId you're querying. This defaults to this appid.
|
||||
/// </summary>
|
||||
public uint AppId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The AppId of the app used to upload the item. This defaults to 0
|
||||
/// which means all/any.
|
||||
/// </summary>
|
||||
public uint UploaderAppId { get; set; }
|
||||
|
||||
public QueryType QueryType { get; set; } = QueryType.Items;
|
||||
public Order Order { get; set; } = Order.RankedByVote;
|
||||
|
||||
public string SearchText { get; set; }
|
||||
|
||||
public Item[] Items { get; set; }
|
||||
|
||||
public int TotalResults { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Page starts at 1 !!
|
||||
/// </summary>
|
||||
public int Page { get; set; } = 1;
|
||||
internal Workshop workshop;
|
||||
|
||||
public unsafe void Run()
|
||||
{
|
||||
if ( Callback != null )
|
||||
return;
|
||||
|
||||
if ( Page <= 0 )
|
||||
throw new System.Exception( "Page should be 1 or above" );
|
||||
|
||||
if ( FileId.Count != 0 )
|
||||
{
|
||||
var fileArray = FileId.ToArray();
|
||||
|
||||
fixed ( ulong* array = fileArray )
|
||||
{
|
||||
Handle = workshop.ugc.CreateQueryUGCDetailsRequest( (IntPtr) array, (uint)fileArray.Length );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Handle = workshop.ugc.CreateQueryAllUGCRequest( (uint)Order, (uint)QueryType, UploaderAppId, AppId, (uint)Page );
|
||||
}
|
||||
|
||||
if ( !string.IsNullOrEmpty( SearchText ) )
|
||||
workshop.ugc.SetSearchText( Handle, SearchText );
|
||||
|
||||
foreach ( var tag in RequireTags )
|
||||
workshop.ugc.AddRequiredTag( Handle, tag );
|
||||
|
||||
if ( RequireTags.Count > 0 )
|
||||
workshop.ugc.SetMatchAnyTag( Handle, RequireAllTags );
|
||||
|
||||
foreach ( var tag in ExcludeTags )
|
||||
workshop.ugc.AddExcludedTag( Handle, tag );
|
||||
|
||||
Callback = new QueryCompleted();
|
||||
Callback.Handle = workshop.ugc.SendQueryUGCRequest( Handle );
|
||||
Callback.OnResult = OnResult;
|
||||
workshop.steamworks.AddCallResult( Callback );
|
||||
}
|
||||
|
||||
void OnResult( QueryCompleted.Data data )
|
||||
{
|
||||
Items = new Item[data.m_unNumResultsReturned];
|
||||
for ( int i = 0; i < data.m_unNumResultsReturned; i++ )
|
||||
{
|
||||
SteamUGCDetails_t details = new SteamUGCDetails_t();
|
||||
workshop.ugc.GetQueryUGCResult( data.Handle, (uint) i, ref details );
|
||||
|
||||
Items[i] = Item.From( details, workshop );
|
||||
}
|
||||
|
||||
TotalResults = (int) data.m_unTotalMatchingResults;
|
||||
|
||||
Callback.Dispose();
|
||||
Callback = null;
|
||||
}
|
||||
|
||||
public bool IsRunning
|
||||
{
|
||||
get { return Callback != null; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Only return items with these tags
|
||||
/// </summary>
|
||||
public List<string> RequireTags { get; set; } = new List<string>();
|
||||
|
||||
/// <summary>
|
||||
/// If true, return items that have all RequireTags
|
||||
/// If false, return items that have any tags in RequireTags
|
||||
/// </summary>
|
||||
public bool RequireAllTags { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Don't return any items with this tag
|
||||
/// </summary>
|
||||
public List<string> ExcludeTags { get; set; } = new List<string>();
|
||||
|
||||
/// <summary>
|
||||
/// If you're querying for a particular file or files, add them to this.
|
||||
/// </summary>
|
||||
public List<ulong> FileId { get; set; } = new List<ulong>();
|
||||
|
||||
/// <summary>
|
||||
/// Don't call this in production!
|
||||
/// </summary>
|
||||
public void Block()
|
||||
{
|
||||
workshop.steamworks.Update();
|
||||
|
||||
while ( IsRunning )
|
||||
{
|
||||
System.Threading.Thread.Sleep( 10 );
|
||||
workshop.steamworks.Update();
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
// ReleaseQueryUGCRequest
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ namespace Facepunch.Steamworks.Interop
|
||||
internal Valve.Steamworks.ISteamUGC ugc;
|
||||
internal Valve.Steamworks.ISteamGameServer gameServer;
|
||||
internal Valve.Steamworks.ISteamGameServerStats gameServerStats;
|
||||
internal Valve.Steamworks.ISteamRemoteStorage remoteStorage;
|
||||
|
||||
internal bool InitClient()
|
||||
{
|
||||
@ -75,6 +76,7 @@ namespace Facepunch.Steamworks.Interop
|
||||
servers = client.GetISteamMatchmakingServers( huser, hpipe, "SteamMatchMakingServers002" );
|
||||
userstats = client.GetISteamUserStats( huser, hpipe, "STEAMUSERSTATS_INTERFACE_VERSION011" );
|
||||
screenshots = client.GetISteamScreenshots( huser, hpipe, "STEAMSCREENSHOTS_INTERFACE_VERSION002" );
|
||||
remoteStorage = client.GetISteamRemoteStorage( huser, hpipe, "STEAMREMOTESTORAGE_INTERFACE_VERSION013" );
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
|
@ -2513,7 +2513,7 @@ namespace Valve.Steamworks
|
||||
{
|
||||
CheckIfUsable();
|
||||
IntPtr result = NativeEntrypoints.SteamAPI_ISteamClient_GetISteamRemoteStorage(m_pSteamClient,hSteamUser,hSteamPipe,pchVersion);
|
||||
return (ISteamRemoteStorage)Marshal.PtrToStructure( result, typeof( ISteamRemoteStorage ) );
|
||||
return new CSteamRemoteStorage( result );
|
||||
}
|
||||
internal override ISteamScreenshots GetISteamScreenshots( int hSteamUser, int hSteamPipe, string pchVersion )
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user