move client mods updates to actual steam api
All checks were successful
Build / Build Launcher (push) Successful in 2m17s

This commit is contained in:
zznty
2024-05-31 17:56:24 +07:00
parent 43a4e6f62b
commit fbf02ad716
9 changed files with 42 additions and 92 deletions

View File

@@ -1,18 +1,10 @@
using System.Reflection;
using System.Text;
using HarmonyLib;
using Sandbox.Engine.Networking;
using NLog;
using Steamworks;
using VRage.Game;
using VRage.GameServices;
using VRage.Utils;
namespace PluginLoader;
public static class SteamAPI
{
private static MethodInfo? _downloadModsBlocking;
public static bool IsSubscribed(ulong id)
{
var state = (EItemState)SteamUGC.GetItemState(new(id));
@@ -27,52 +19,45 @@ public static class SteamAPI
public static void Update(IEnumerable<ulong> ids)
{
var enumerable = ids as ulong[] ?? ids.ToArray();
if (!enumerable.Any())
return;
LogFile.Log.Info("Updating {Count} workshop items", enumerable.Length);
var modItems =
new List<MyObjectBuilder_Checkpoint.ModItem>(
enumerable.Select(x => new MyObjectBuilder_Checkpoint.ModItem(x, "Steam")));
LogFile.Log.Debug($"Updating {modItems.Count} workshop items");
// Source: MyWorkshop.DownloadWorldModsBlocking
var result = new MyWorkshop.ResultData();
var task = Task.Run(() => result = UpdateInternal(modItems));
while (!task.IsCompleted)
try
{
MyGameService.Update();
UpdateInternal(enumerable);
}
catch (Exception e)
{
LogFile.Log.Error(e, "An error occurred while updating workshop items");
throw;
}
}
private static void UpdateInternal(IEnumerable<ulong> ids)
{
var count = 0;
using var callback = Callback<DownloadItemResult_t>.Create(t =>
{
if (t.m_eResult == EResult.k_EResultOK)
Interlocked.Increment(ref count);
LogFile.Log.Log(t.m_eResult == EResult.k_EResultOK ? LogLevel.Info : LogLevel.Error,
"Download finished for {Id} with {State}", t.m_nPublishedFileId.m_PublishedFileId, t.m_eResult);
});
var toDownload = ids.Where(b =>
(EItemState)SteamUGC.GetItemState(new(b)) != EItemState.k_EItemStateInstalled).ToArray();
foreach (var id in toDownload)
{
LogFile.Log.Info("Updating workshop item {Id}", id);
SteamUGC.DownloadItem(new(id), true);
}
while (count < toDownload.Length)
{
Steamworks.SteamAPI.RunCallbacks();
Thread.Sleep(10);
}
if (result.Result is MyGameServiceCallResult.OK) return;
if (task.Exception is not null)
{
LogFile.Log.Error(task.Exception, "An error occurred while updating workshop items");
}
else
{
LogFile.Log.Error("Unable to update workshop items due to {Result}", result.Result);
}
}
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;
}
}