updated SteamWorks library

This commit is contained in:
2026-10-24 11:38:40 +01:00
parent 91cdba0fef
commit c745fb18bd
8 changed files with 1485 additions and 33 deletions
@@ -1,3 +1,7 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using OmegaLeo.HelperLib.Shared.Attributes;
namespace OmegaLeo.HelperLib.Steamworks
@@ -113,6 +117,22 @@ var items = ugc.GetSubscribedItems();
return submitHandle;
}
[Documentation(nameof(UpdateItem), "Starts an item update, applies option fields, submits it, and calls onCompleted with the upload result from SteamManager.Update().", new[]
{
"consumerAppId: Your game AppId.",
"publishedFileId: Existing workshop item ID.",
"options: Options object containing fields to update.",
"changeNote: Changelog note for submission.",
"onCompleted: Called once with the upload result.",
"failedStep: Name of the failed step when the call returns 0."
}, null)]
public ulong UpdateItem(uint consumerAppId, ulong publishedFileId, SteamUgcItemUpdateOptions options, string changeNote, Action<SteamUgcSubmitItemUpdateResult> onCompleted, out string failedStep)
{
var submitHandle = UpdateItem(consumerAppId, publishedFileId, options, changeNote, out failedStep);
RegisterResult(submitHandle, onCompleted, SteamUgcSubmitItemUpdateResult.FromCallResult, nameof(SubmitItemUpdate));
return submitHandle;
}
[Documentation(nameof(CreateItem), "Creates a new Workshop item and returns a Steam API call handle.", new[]
{
"consumerAppId: Your game AppId.",
@@ -123,6 +143,30 @@ var items = ugc.GetSubscribedItems();
return SteamNativeApi.CreateItem(consumerAppId, fileType);
}
[Documentation(nameof(CreateItem), "Creates a new Workshop item and calls onCompleted with the CreateItemResult_t from SteamManager.Update(). Returns the Steam API call handle, or 0 on failure.", new[]
{
"consumerAppId: Your game AppId.",
"fileType: Numeric EWorkshopFileType value.",
"onCompleted: Called once with the new item ID and result."
}, null)]
public ulong CreateItem(uint consumerAppId, uint fileType, Action<SteamUgcCreateItemResult> onCompleted)
{
var apiCall = CreateItem(consumerAppId, fileType);
RegisterResult(apiCall, onCompleted, SteamUgcCreateItemResult.FromCallResult, nameof(CreateItem));
return apiCall;
}
[Documentation(nameof(CreateItemAsync), "Creates a new Workshop item and returns a task with the CreateItemResult_t. Keep calling SteamManager.Update() while waiting.", new[]
{
"consumerAppId: Your game AppId.",
"fileType: Numeric EWorkshopFileType value.",
"cancellationToken: Cancels the wait (the Steam call keeps running)."
}, null)]
public Task<SteamUgcCreateItemResult> CreateItemAsync(uint consumerAppId, uint fileType, CancellationToken cancellationToken = default)
{
return AwaitResult(CreateItem(consumerAppId, fileType), SteamUgcCreateItemResult.FromCallResult, nameof(CreateItem), cancellationToken);
}
[Documentation(nameof(StartItemUpdate), "Starts an update transaction for an existing Workshop item.", new[]
{
"consumerAppId: Your game AppId.",
@@ -181,7 +225,31 @@ var items = ugc.GetSubscribedItems();
return SteamNativeApi.SubmitItemUpdate(updateHandle, changeNote);
}
[Documentation(nameof(GetItemUpdateProgress), "Gets progress state for a pending item update upload.", new[] { "updateHandle: Handle from StartItemUpdate.", "bytesProcessed: Uploaded bytes output.", "bytesTotal: Total bytes output." }, null)]
[Documentation(nameof(SubmitItemUpdate), "Submits a pending workshop item update and calls onCompleted with the SubmitItemUpdateResult_t from SteamManager.Update(). Returns the Steam API call handle, or 0 when submission failed.", new[]
{
"updateHandle: Handle from StartItemUpdate.",
"changeNote: Changelog note for the update.",
"onCompleted: Called once with the upload result."
}, null)]
public ulong SubmitItemUpdate(ulong updateHandle, string changeNote, Action<SteamUgcSubmitItemUpdateResult> onCompleted)
{
var apiCall = SubmitItemUpdate(updateHandle, changeNote);
RegisterResult(apiCall, onCompleted, SteamUgcSubmitItemUpdateResult.FromCallResult, nameof(SubmitItemUpdate));
return apiCall;
}
[Documentation(nameof(SubmitItemUpdateAsync), "Submits a pending workshop item update and returns a task with the SubmitItemUpdateResult_t. Keep calling SteamManager.Update() while waiting.", new[]
{
"updateHandle: Handle from StartItemUpdate.",
"changeNote: Changelog note for the update.",
"cancellationToken: Cancels the wait (the upload keeps running)."
}, null)]
public Task<SteamUgcSubmitItemUpdateResult> SubmitItemUpdateAsync(ulong updateHandle, string changeNote, CancellationToken cancellationToken = default)
{
return AwaitResult(SubmitItemUpdate(updateHandle, changeNote), SteamUgcSubmitItemUpdateResult.FromCallResult, nameof(SubmitItemUpdate), cancellationToken);
}
[Documentation(nameof(GetItemUpdateProgress),"Gets progress state for a pending item update upload.", new[] { "updateHandle: Handle from StartItemUpdate.", "bytesProcessed: Uploaded bytes output.", "bytesTotal: Total bytes output." }, null)]
public uint GetItemUpdateProgress(ulong updateHandle, out ulong bytesProcessed, out ulong bytesTotal)
{
return SteamNativeApi.GetItemUpdateProgress(updateHandle, out bytesProcessed, out bytesTotal);
@@ -206,7 +274,29 @@ var items = ugc.GetSubscribedItems();
return SteamNativeApi.SendQueryUgcRequest(queryHandle);
}
[Documentation(nameof(ReleaseQueryUgcRequest), "Releases a UGC query handle after you are done with query results.", new[] { "queryHandle: UGC query handle to release." }, null)]
[Documentation(nameof(SendQueryUgcRequest), "Submits a UGC query and calls onCompleted with the SteamUGCQueryCompleted_t from SteamManager.Update(). Returns the Steam API call handle, or 0 on failure.", new[]
{
"queryHandle: UGC query handle returned from CreateQueryAllUgcRequest.",
"onCompleted: Called once with the query result."
}, null)]
public ulong SendQueryUgcRequest(ulong queryHandle, Action<SteamUgcQueryCompletedResult> onCompleted)
{
var apiCall = SendQueryUgcRequest(queryHandle);
RegisterResult(apiCall, onCompleted, SteamUgcQueryCompletedResult.FromCallResult, nameof(SendQueryUgcRequest));
return apiCall;
}
[Documentation(nameof(SendQueryUgcRequestAsync), "Submits a UGC query and returns a task with the SteamUGCQueryCompleted_t. Keep calling SteamManager.Update() while waiting.", new[]
{
"queryHandle: UGC query handle returned from CreateQueryAllUgcRequest.",
"cancellationToken: Cancels the wait (the query keeps running)."
}, null)]
public Task<SteamUgcQueryCompletedResult> SendQueryUgcRequestAsync(ulong queryHandle, CancellationToken cancellationToken = default)
{
return AwaitResult(SendQueryUgcRequest(queryHandle), SteamUgcQueryCompletedResult.FromCallResult, nameof(SendQueryUgcRequest), cancellationToken);
}
[Documentation(nameof(ReleaseQueryUgcRequest),"Releases a UGC query handle after you are done with query results.", new[] { "queryHandle: UGC query handle to release." }, null)]
public bool ReleaseQueryUgcRequest(ulong queryHandle)
{
return SteamNativeApi.ReleaseQueryUgcRequest(queryHandle);
@@ -235,6 +325,30 @@ var items = ugc.GetSubscribedItems();
{
return SteamNativeApi.UnsubscribeItem(publishedFileId);
}
private static void RegisterResult<T>(ulong apiCall, Action<T> onCompleted, Func<SteamApiCallResult, T> convert, string operation)
{
if (apiCall == 0 || onCompleted == null)
{
return;
}
if (!SteamManager.Dispatcher.RegisterCallResult(apiCall, result => onCompleted(convert(result))))
{
SteamManager.Logger.LogWarning("{Operation} was submitted but its result will not be delivered because Steam manual callback dispatch is not active.", operation);
}
}
private static async Task<T> AwaitResult<T>(ulong apiCall, Func<SteamApiCallResult, T> convert, string operation, CancellationToken cancellationToken)
{
if (apiCall == 0)
{
throw new InvalidOperationException($"{operation} did not return a Steam API call handle. Ensure Steamworks is initialized.");
}
var result = await SteamManager.Dispatcher.WaitForCallResultAsync(apiCall, cancellationToken).ConfigureAwait(false);
return convert(result);
}
}
}