Stubbed out bundle loading

This commit is contained in:
Chomp
2025-02-08 15:22:25 +00:00
parent 316714db22
commit 98041ac785
10 changed files with 276 additions and 8 deletions
+4
View File
@@ -26,4 +26,8 @@
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Folder Include="Mods\12Bundle\bundles\assets\" />
</ItemGroup>
</Project>
@@ -5,13 +5,13 @@ using SptCommon.Annotations;
namespace ExampleMods.Mods._11RegisterClassesInDI;
[Injectable]
public class RegisterClassesInDI : IPostDBLoadMod // Run after db has loaded
public class Bundle : IPostDBLoadMod // Run after db has loaded
{
private readonly SingletonClassExample _singletonClassExample;
private readonly TransientClassExample _transientClassExample;
// We inject 2 classes (singleton and transient) we've made below
public RegisterClassesInDI(
public Bundle(
SingletonClassExample singletonClassExample,
TransientClassExample transientClassExample)
{
+19
View File
@@ -0,0 +1,19 @@
using Core.Models.External;
using Core.Models.Utils;
using SptCommon.Annotations;
namespace ExampleMods.Mods._12Bundle;
[Injectable]
public class Bundle : IPostDBLoadMod // Run after db has loaded
{
public Bundle()
{
}
public void PostDBLoad()
{
}
}
+8
View File
@@ -0,0 +1,8 @@
{
"manifest": [
{
"key": "assets/content/weapons/usable_items/item_bottle/textures/client_assets.bundle",
"dependencyKeys": []
}
]
}
+13
View File
@@ -0,0 +1,13 @@
{
"Name": "12Bundle",
"Version": "1.0.0",
"SptVersion": "~4.0",
"LoadBefore": [],
"LoadAfter": [],
"IncompatibileMods": [],
"Url": "https://github.com/sp-tarkov/server-csharp/tree/develop/ExampleMods/Mods",
"IsBundleMod": false,
"Author": "SPT",
"Contributors": [],
"Licence": "MIT"
}
+5 -6
View File
@@ -1,4 +1,5 @@
using Core.Models.Eft.Common;
using Core.Loaders;
using Core.Models.Eft.Common;
using Core.Utils;
using SptCommon.Annotations;
@@ -6,9 +7,8 @@ namespace Core.Callbacks;
[Injectable(InjectableTypeOverride = typeof(BundleCallbacks))]
public class BundleCallbacks(
HttpResponseUtil _httpResponseUtil
// BundleLoader _bundleLoader,
)
HttpResponseUtil _httpResponseUtil,
BundleLoader _bundleLoader)
{
/// <summary>
/// Handle singleplayer/bundles
@@ -19,8 +19,7 @@ public class BundleCallbacks(
/// <returns></returns>
public string GetBundles(string url, EmptyRequestData info, string sessionID)
{
// return _httpResponseUtil.NoBody(_bundleLoader.GetBundles());
return _httpResponseUtil.NoBody(new List<object>());
return _httpResponseUtil.NoBody(_bundleLoader.GetBundles());
}
public string GetBundle(string url, object info, string sessionID)
+145
View File
@@ -0,0 +1,145 @@
using System.Text.Json.Serialization;
using Core.Models.Utils;
using Core.Services;
using Core.Utils;
using Core.Utils.Cloners;
using SptCommon.Annotations;
namespace Core.Loaders
{
public class BundleInfo
{
public string ModPath
{
get;
}
public IBundleManifestEntry Bundle
{
get;
}
public long Crc
{
get;
}
public List<string> Dependencies
{
get;
}
public BundleInfo(
string modPath,
IBundleManifestEntry bundle,
long bundleHash)
{
ModPath = modPath;
Bundle = bundle;
Crc = bundleHash;
Dependencies = bundle?.DependencyKeys ?? [];
}
}
[Injectable(InjectionType.Singleton)]
public class BundleLoader
{
private readonly ISptLogger<BundleLoader> _logger;
private readonly HashUtil _hashUtil;
private readonly JsonUtil _jsonUtil;
private readonly FileUtil _fileUtil;
private readonly BundleHashCacheService _bundleHashCacheService;
private readonly InMemoryCacheService _inMemoryCacheService;
private readonly ICloner _cloner;
private readonly Dictionary<string, BundleInfo> _bundles;
public BundleLoader(
ISptLogger<BundleLoader> logger,
HashUtil hashUtil,
JsonUtil jsonUtil,
FileUtil fileUtil,
BundleHashCacheService bundleHashCacheService,
InMemoryCacheService inMemoryCacheService,
ICloner cloner)
{
_logger = logger;
_hashUtil = hashUtil;
_jsonUtil = jsonUtil;
_fileUtil = fileUtil;
_bundleHashCacheService = bundleHashCacheService;
_inMemoryCacheService = inMemoryCacheService;
_cloner = cloner;
}
public List<BundleInfo> GetBundles()
{
var result = new List<BundleInfo>();
foreach (var bundle in _bundles) {
result.Add(bundle.Value);
}
return result;
}
public BundleInfo GetBundle(string bundleKey)
{
return _cloner.Clone(_bundles[bundleKey]);
}
public void AddBundles(string modPath)
{
//TODO: Implement
var modBundlesJson = _fileUtil.ReadFile(Path.Combine(modPath, "bundles.json"));
var modBundles = _jsonUtil.Deserialize<IBundleManifest>(modBundlesJson);
var bundleManifestArr = modBundles?.Manifest;
foreach (var bundleManifest in bundleManifestArr)
{
// modpath.slice(0, -1).replace(/\\/ g, "/");
// var bundleLocalPath = $"{modpath}bundles/${bundleManifest.key}".replace(/\\/g, "/");
// if (!_bundleHashCacheService.CalculateAndMatchHash(bundleLocalPath))
// {
// _bundleHashCacheService.CalculateAndStoreHash(bundleLocalPath);
// }
// var bundleHash = _bundleHashCacheService.GetStoredValue(bundleLocalPath);
// AddBundle(bundleManifest.key, new BundleInfo(relativeModPath, bundleManifest, bundleHash));
}
}
public void AddBundle(string key, BundleInfo bundle)
{
var success = _bundles.TryAdd(key, bundle);
if (!success)
{
_logger.Error($"Unable to add bundle: {key}");
}
}
}
}
public interface IBundleManifest
{
[JsonPropertyName("manifest")]
public List<IBundleManifestEntry> Manifest { get; set; }
}
public interface IBundleManifestEntry
{
[JsonPropertyName("key")]
public string Key {
get;
set;
}
[JsonPropertyName("dependencyKeys")]
public List<string>? DependencyKeys
{
get;
set;
}
}
@@ -0,0 +1,12 @@
{
"profiles": {
"Core": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "https://localhost:64951;http://localhost:64952"
}
}
}
@@ -0,0 +1,68 @@
using Core.Models.Utils;
using Core.Utils;
using SptCommon.Annotations;
namespace Core.Services
{
[Injectable(InjectionType.Singleton)]
public class BundleHashCacheService
{
private readonly ISptLogger<BundleHashCacheService> _logger;
private readonly JsonUtil _jsonUtil;
private readonly HashUtil _hashUtil;
private readonly FileUtil _fileUtil;
protected readonly Dictionary<string, string> _bundleHashes;
protected const string _bundleHashCachePath = "./user/cache/bundleHashCache.json";
public BundleHashCacheService(
ISptLogger<BundleHashCacheService> logger,
JsonUtil jsonUtil,
HashUtil hashUtil,
FileUtil fileUtil)
{
_logger = logger;
_jsonUtil = jsonUtil;
_hashUtil = hashUtil;
_fileUtil = fileUtil;
}
public string GetStoredValue(string key)
{
if (!_bundleHashes.TryGetValue(key, out var value))
{
return string.Empty;
}
return value;
}
public void StoreValue(string bundlePath, string hash)
{
_bundleHashes.Add(bundlePath, hash);
_fileUtil.WriteFile(_bundleHashCachePath, _jsonUtil.Serialize(_bundleHashes));
_logger.Debug($"Bundle: {bundlePath} hash stored in: ${_bundleHashCachePath}");
}
public bool CalculateAndMatchHash(string bundlePath)
{
return MatchWithStoredHash(bundlePath, CalculateHash(bundlePath));
}
public void CalculateAndStoreHash(string bundlePath)
{
StoreValue(bundlePath, CalculateHash(bundlePath));
}
public string CalculateHash(string bundlePath)
{
var fileData = _fileUtil.ReadFile(bundlePath);
return _hashUtil.GenerateMd5ForData(fileData);
}
public bool MatchWithStoredHash(string bundlePath, string hash)
{
return GetStoredValue(bundlePath) == hash;
}
}
}