fix loading of bundles

This commit is contained in:
CWX
2025-02-10 19:40:35 +00:00
parent c26169f53a
commit e8acef4e75
5 changed files with 48 additions and 37 deletions
+4
View File
@@ -11,4 +11,8 @@
<ProjectReference Include="..\SptDependencyInjection\SptDependencyInjection.csproj"/>
</ItemGroup>
<ItemGroup>
<PackageReference Include="System.IO.Hashing" Version="9.0.1" />
</ItemGroup>
</Project>
+15 -14
View File
@@ -9,7 +9,12 @@ namespace Core.Loaders
{
public class BundleInfo
{
public string ModPath
public string? ModPath
{
get;
}
public string FileName
{
get;
}
@@ -19,7 +24,7 @@ namespace Core.Loaders
get;
}
public string Crc
public uint Crc
{
get;
}
@@ -32,9 +37,10 @@ namespace Core.Loaders
public BundleInfo(
string modPath,
BundleManifestEntry bundle,
string bundleHash)
uint bundleHash)
{
ModPath = modPath;
FileName = bundle.Key;
Bundle = bundle;
Crc = bundleHash;
Dependencies = bundle?.DependencyKeys ?? [];
@@ -51,7 +57,7 @@ namespace Core.Loaders
private readonly BundleHashCacheService _bundleHashCacheService;
private readonly InMemoryCacheService _inMemoryCacheService;
private readonly ICloner _cloner;
private readonly Dictionary<string, BundleInfo> _bundles;
private readonly Dictionary<string, BundleInfo> _bundles = new Dictionary<string, BundleInfo>();
public BundleLoader(
ISptLogger<BundleLoader> logger,
@@ -84,27 +90,22 @@ namespace Core.Loaders
public BundleInfo? GetBundle(string bundleKey)
{
return _bundles.GetValueOrDefault(bundleKey);
return _cloner.Clone(_bundles.GetValueOrDefault(bundleKey));
}
public void AddBundles(string modPath)
{
// TODO: Implement
// modPath should be relative to the server exe - /user/mods/Mod3/
var modBundlesJson = _fileUtil.ReadFile(Path.Combine(modPath, "bundles.json"));
var modBundlesJson = _fileUtil.ReadFile(Path.Join(Directory.GetCurrentDirectory(), modPath, "bundles.json"));
var modBundles = _jsonUtil.Deserialize<BundleManifest>(modBundlesJson);
var bundleManifestArr = modBundles?.Manifest;
foreach (var bundleManifest in bundleManifestArr)
{
// TODO: complete
// we currently get D:\HomeRepos\SPT-CS-Server\Server\bin\Debug\net9.0/user/mods/Mod3
// we want /user/mods/Mod3
var relativeModPath = modPath.Substring(0, modPath.Length - 1); // /\\/g, "/" - replaces all instances of \\ with /
var relativeModPath = modPath.Replace('\\', '/'); // /\\/g, "/" - replaces all instances of \\ with /
// we currently get D:\HomeRepos\SPT-CS-Server\Server\bin\Debug\net9.0/user/mods/Mod3/bundles\assets/content/weapons/usable_items/item_bottle/textures/client_assets.bundle
// we want /user/mods/Mod3/bundles\assets/content/weapons/usable_items/item_bottle/textures/client_assets.bundle
var bundleLocalPath = Path.Combine(modPath, "bundles", bundleManifest.Key); // /\\/g, "/" - replaces all instances of \\ with /
var bundleLocalPath = Path.Join(relativeModPath, "bundles", bundleManifest.Key);
if (!_bundleHashCacheService.CalculateAndMatchHash(bundleLocalPath))
{
@@ -11,8 +11,10 @@ namespace Core.Services
private readonly JsonUtil _jsonUtil;
private readonly HashUtil _hashUtil;
private readonly FileUtil _fileUtil;
protected readonly Dictionary<string, string> _bundleHashes = new Dictionary<string, string>();
protected const string _bundleHashCachePath = "./user/cache/bundleHashCache.json";
protected readonly Dictionary<string, uint> _bundleHashes = new Dictionary<string, uint>();
protected const string _bundleHashCachePath = "./user/cache/";
protected const string _cacheName = "bundleHashCache.json";
private readonly string _currentDirectory = Directory.GetCurrentDirectory();
public BundleHashCacheService(
ISptLogger<BundleHashCacheService> logger,
@@ -25,44 +27,52 @@ namespace Core.Services
_hashUtil = hashUtil;
_fileUtil = fileUtil;
}
public string GetStoredValue(string key)
public uint GetStoredValue(string key)
{
if (!_bundleHashes.TryGetValue(key, out var value))
{
return string.Empty;
return 0;
}
return value;
}
public void StoreValue(string bundlePath, string hash)
public void StoreValue(string bundlePath, uint hash)
{
_bundleHashes.Add(bundlePath, hash);
_fileUtil.WriteFile(_bundleHashCachePath, _jsonUtil.Serialize(_bundleHashes));
if (!Directory.Exists(_bundleHashCachePath))
{
Directory.CreateDirectory(_bundleHashCachePath);
}
_fileUtil.WriteFile(Path.Join(_bundleHashCachePath, _cacheName), _jsonUtil.Serialize(_bundleHashes));
_logger.Debug($"Bundle: {bundlePath} hash stored in: ${_bundleHashCachePath}");
}
public bool CalculateAndMatchHash(string bundlePath)
public bool CalculateAndMatchHash(string relativeBundlePath)
{
return MatchWithStoredHash(bundlePath, CalculateHash(bundlePath));
var absolutePath = Path.Join(_currentDirectory, relativeBundlePath);
return MatchWithStoredHash(relativeBundlePath, CalculateHash(absolutePath));
}
public void CalculateAndStoreHash(string bundlePath)
public void CalculateAndStoreHash(string relativeBundlePath)
{
StoreValue(bundlePath, CalculateHash(bundlePath));
var absolutePath = Path.Join(_currentDirectory, relativeBundlePath);
StoreValue(relativeBundlePath, CalculateHash(absolutePath));
}
public string CalculateHash(string bundlePath)
public uint CalculateHash(string absoluteBundlePath)
{
var fileData = _fileUtil.ReadFile(bundlePath);
return _hashUtil.GenerateMd5ForData(fileData);
var fileData = _fileUtil.ReadFile(absoluteBundlePath);
return _hashUtil.GenerateCrc32ForData(fileData);
}
public bool MatchWithStoredHash(string bundlePath, string hash)
public bool MatchWithStoredHash(string relativeBundlePath, uint hash)
{
return GetStoredValue(bundlePath) == hash;
return GetStoredValue(relativeBundlePath) == hash;
}
}
}
+3 -5
View File
@@ -1,3 +1,4 @@
using System.IO.Hashing;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
@@ -64,12 +65,9 @@ public class HashUtil
return GenerateHashForData(HashingAlgorithm.SHA1, data);
}
[Obsolete("Use GenerateMd5ForData instead")]
public string GenerateCrc32ForData(string data)
public uint GenerateCrc32ForData(string data)
{
// TODO: Could not find a ms way of doing this.
// May need a custom impl to avoid an external lib. - CJ
throw new NotImplementedException();
return Crc32.HashToUInt32(new ArraySegment<byte>(Encoding.UTF8.GetBytes(data)));
}
/// <summary>
+1 -3
View File
@@ -19,8 +19,6 @@ public class Bundle : IPostDBLoadMod
public void PostDBLoad()
{
var modFolder = Directory.GetCurrentDirectory();
var test = Assembly.GetExecutingAssembly().Location;
_bundleLoader.AddBundles(Path.Join(modFolder, "/user/mods/Mod3/"));
_bundleLoader.AddBundles("/user/mods/Mod3");
}
}