0
0
mirror of https://github.com/sp-tarkov/modules.git synced 2025-02-13 09:50:43 -05:00
modules/project/Aki.Custom/Utils/BundleManager.cs
Dev 64296e3e62 Revert "Improve async bundles (!123)"
This reverts commit 9e65e68c81f47b05b29244f08d3cb2b9edc8616d.
2024-05-12 23:03:30 +01:00

110 lines
3.4 KiB
C#

using System.Collections.Concurrent;
using System.Threading.Tasks;
using BepInEx.Logging;
using Newtonsoft.Json;
using Aki.Common.Http;
using Aki.Common.Utils;
using Aki.Custom.Models;
namespace Aki.Custom.Utils
{
public static class BundleManager
{
private static readonly ManualLogSource _logger;
public static readonly ConcurrentDictionary<string, BundleItem> Bundles;
public static string CachePath;
static BundleManager()
{
_logger = Logger.CreateLogSource(nameof(BundleManager));
Bundles = new ConcurrentDictionary<string, BundleItem>();
CachePath = "user/cache/bundles/";
}
public static string GetBundlePath(BundleItem bundle)
{
return RequestHandler.IsLocal
? $"{bundle.ModPath}/bundles/{bundle.FileName}"
: CachePath + bundle.FileName;
}
public static async Task GetBundles()
{
// get bundles
var json = RequestHandler.GetJson("/singleplayer/bundles");
var bundles = JsonConvert.DeserializeObject<BundleItem[]>(json);
// register bundles
var toDownload = new ConcurrentBag<BundleItem>();
foreach (var bundle in bundles)
{
Bundles.TryAdd(bundle.FileName, bundle);
if (await ShouldReaquire(bundle))
{
// mark for download
toDownload.Add(bundle);
}
}
if (RequestHandler.IsLocal)
{
// loading from local mods
_logger.LogInfo("CACHE: Loading all bundles from mods on disk.");
return;
}
else
{
// download bundles
// NOTE: assumes bundle keys to be unique
foreach (var bundle in toDownload)
{
// download bundle
var filepath = GetBundlePath(bundle);
var data = await RequestHandler.GetDataAsync($"/files/bundle/{bundle.FileName}");
await VFS.WriteFileAsync(filepath, data);
}
}
}
private static async Task<bool> ShouldReaquire(BundleItem bundle)
{
if (RequestHandler.IsLocal)
{
// only handle remote bundles
return false;
}
// read cache
var filepath = CachePath + bundle.FileName;
if (VFS.Exists(filepath))
{
// calculate hash
var data = await VFS.ReadFileAsync(filepath);
var crc = Crc32.Compute(data);
if (crc == bundle.Crc)
{
// file is up-to-date
_logger.LogInfo($"CACHE: Loading locally {bundle.FileName}");
return false;
}
else
{
// crc doesn't match, reaquire the file
_logger.LogInfo($"CACHE: Bundle is invalid, (re-)acquiring {bundle.FileName}");
return true;
}
}
else
{
// file doesn't exist in cache
_logger.LogInfo($"CACHE: Bundle is missing, (re-)acquiring {bundle.FileName}");
return true;
}
}
}
}