Files
se-launcher/PluginLoader/SteamAPI.cs
2023-06-13 22:47:03 +07:00

85 lines
2.7 KiB
C#

using System.Reflection;
using System.Text;
using HarmonyLib;
using Sandbox.Engine.Networking;
using Steamworks;
using VRage.Game;
using VRage.GameServices;
using VRage.Utils;
using Parallel = ParallelTasks.Parallel;
namespace PluginLoader;
public static class SteamAPI
{
private static MethodInfo? _downloadModsBlocking;
public static bool IsSubscribed(ulong id)
{
var state = (EItemState)SteamUGC.GetItemState(new(id));
return (state & EItemState.k_EItemStateSubscribed) == EItemState.k_EItemStateSubscribed;
}
public static void SubscribeToItem(ulong id)
{
SteamUGC.SubscribeItem(new(id));
}
public static void Update(IEnumerable<ulong> ids)
{
var enumerable = ids as ulong[] ?? ids.ToArray();
if (!enumerable.Any())
return;
var modItems =
new List<MyObjectBuilder_Checkpoint.ModItem>(
enumerable.Select(x => new MyObjectBuilder_Checkpoint.ModItem(x, "Steam")));
LogFile.WriteLine($"Updating {modItems.Count} workshop items");
// Source: MyWorkshop.DownloadWorldModsBlocking
var result = new MyWorkshop.ResultData();
var task = Parallel.Start(delegate { result = UpdateInternal(modItems); });
while (!task.IsComplete)
{
MyGameService.Update();
Thread.Sleep(10);
}
if (result.Result is not MyGameServiceCallResult.OK)
{
var exceptions = task.Exceptions;
if (exceptions is { Length: > 0 })
{
var sb = new StringBuilder();
sb.AppendLine("An error occurred while updating workshop items:");
foreach (var e in exceptions)
sb.Append(e);
LogFile.WriteLine(sb.ToString());
}
else
{
LogFile.WriteLine("Unable to update workshop items");
}
}
}
public static MyWorkshop.ResultData UpdateInternal(List<MyObjectBuilder_Checkpoint.ModItem> mods)
{
// Source: MyWorkshop.DownloadWorldModsBlockingInternal
MyLog.Default.IncreaseIndent();
var list = new List<WorkshopId>(mods.Select(x => new WorkshopId(x.PublishedFileId, x.PublishedServiceName)));
if (_downloadModsBlocking == null)
_downloadModsBlocking = AccessTools.Method(typeof(MyWorkshop), "DownloadModsBlocking");
var resultData = (MyWorkshop.ResultData)_downloadModsBlocking.Invoke(mods, new object[]
{
mods, new MyWorkshop.ResultData { Result = MyGameServiceCallResult.OK }, list, new MyWorkshop.CancelToken()
})!;
MyLog.Default.DecreaseIndent();
return resultData;
}
}