mirror of
https://github.com/sp-tarkov/modules.git
synced 2025-02-13 09:50:43 -05:00
Improve bundle documentation (!101)
Most of this code was (re-)written in 0.12.9, almost 3 years ago. Current understanding of how it worked was limited, so I went back and broke it until I understood it properly. I added comments where I could and slightly altered the logic of `GetManifestJson` to make it easier to read. Regarding removal of `GetManifestBundle`: you can't. While `Windows.json` contains most of the bundle info, some info (like `Doge`) resides outside of this. Removing `GetManifestBundle` results in the game failing to load. Reviewed-on: SPT-AKI/Modules#101 Co-authored-by: Merijn Hendriks <merijn.d.hendriks@gmail.com> Co-committed-by: Merijn Hendriks <merijn.d.hendriks@gmail.com>
This commit is contained in:
parent
f3df1e319c
commit
245f21c3d8
@ -11,6 +11,7 @@ using System.IO;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Aki.Common.Utils;
|
||||||
using Aki.Custom.Models;
|
using Aki.Custom.Models;
|
||||||
using Aki.Custom.Utils;
|
using Aki.Custom.Utils;
|
||||||
using DependencyGraph = DependencyGraph<IEasyBundle>;
|
using DependencyGraph = DependencyGraph<IEasyBundle>;
|
||||||
@ -57,24 +58,29 @@ namespace Aki.Custom.Patches
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task Init(EasyAssets instance, [CanBeNull] IBundleLock bundleLock, string defaultKey, string rootPath,
|
private static async Task Init(EasyAssets instance, [CanBeNull] IBundleLock bundleLock, string defaultKey, string rootPath, string platformName, [CanBeNull] Func<string, bool> shouldExclude, Func<string, Task> bundleCheck)
|
||||||
string platformName, [CanBeNull] Func<string, bool> shouldExclude, Func<string, Task> bundleCheck)
|
|
||||||
{
|
{
|
||||||
// platform manifest
|
// platform manifest
|
||||||
var path = $"{rootPath.Replace("file:///", string.Empty).Replace("file://", string.Empty)}/{platformName}/";
|
var path = $"{rootPath.Replace("file:///", string.Empty).Replace("file://", string.Empty)}/{platformName}/";
|
||||||
var filepath = path + platformName;
|
var filepath = path + platformName;
|
||||||
var jsonPath = filepath + ".json";
|
var jsonfile = filepath + ".json";
|
||||||
var manifest = (File.Exists(jsonPath)) ? await GetManifestJson(filepath) : await GetManifestBundle(filepath);
|
var manifest = File.Exists(jsonfile)
|
||||||
|
? await GetManifestJson(jsonfile)
|
||||||
|
: await GetManifestBundle(filepath);
|
||||||
|
|
||||||
// load bundles
|
// create bundles array from obfuscated type
|
||||||
var bundleNames = manifest.GetAllAssetBundles().Union(BundleManager.Bundles.Keys).ToArray();
|
var bundleNames = manifest.GetAllAssetBundles()
|
||||||
|
.Union(BundleManager.Bundles.Keys)
|
||||||
|
.ToArray();
|
||||||
var bundles = (IEasyBundle[])Array.CreateInstance(EasyBundleHelper.Type, bundleNames.Length);
|
var bundles = (IEasyBundle[])Array.CreateInstance(EasyBundleHelper.Type, bundleNames.Length);
|
||||||
|
|
||||||
|
// create bundle lock
|
||||||
if (bundleLock == null)
|
if (bundleLock == null)
|
||||||
{
|
{
|
||||||
bundleLock = new BundleLock(int.MaxValue);
|
bundleLock = new BundleLock(int.MaxValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// create bundle of obfuscated type
|
||||||
for (var i = 0; i < bundleNames.Length; i++)
|
for (var i = 0; i < bundleNames.Length; i++)
|
||||||
{
|
{
|
||||||
bundles[i] = (IEasyBundle)Activator.CreateInstance(EasyBundleHelper.Type, new object[]
|
bundles[i] = (IEasyBundle)Activator.CreateInstance(EasyBundleHelper.Type, new object[]
|
||||||
@ -89,11 +95,18 @@ namespace Aki.Custom.Patches
|
|||||||
await JobScheduler.Yield(EJobPriority.Immediate);
|
await JobScheduler.Yield(EJobPriority.Immediate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// create dependency graph
|
||||||
instance.Manifest = manifest;
|
instance.Manifest = manifest;
|
||||||
_bundlesField.SetValue(instance, bundles);
|
_bundlesField.SetValue(instance, bundles);
|
||||||
instance.System = new DependencyGraph(bundles, defaultKey, shouldExclude);
|
instance.System = new DependencyGraph(bundles, defaultKey, shouldExclude);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE: used by:
|
||||||
|
// - EscapeFromTarkov_Data/StreamingAssets/Windows/cubemaps
|
||||||
|
// - EscapeFromTarkov_Data/StreamingAssets/Windows/defaultmaterial
|
||||||
|
// - EscapeFromTarkov_Data/StreamingAssets/Windows/dissonancesetup
|
||||||
|
// - EscapeFromTarkov_Data/StreamingAssets/Windows/Doge
|
||||||
|
// - EscapeFromTarkov_Data/StreamingAssets/Windows/shaders
|
||||||
private static async Task<CompatibilityAssetBundleManifest> GetManifestBundle(string filepath)
|
private static async Task<CompatibilityAssetBundleManifest> GetManifestBundle(string filepath)
|
||||||
{
|
{
|
||||||
var manifestLoading = AssetBundle.LoadFromFileAsync(filepath);
|
var manifestLoading = AssetBundle.LoadFromFileAsync(filepath);
|
||||||
@ -108,16 +121,18 @@ namespace Aki.Custom.Patches
|
|||||||
|
|
||||||
private static async Task<CompatibilityAssetBundleManifest> GetManifestJson(string filepath)
|
private static async Task<CompatibilityAssetBundleManifest> GetManifestJson(string filepath)
|
||||||
{
|
{
|
||||||
var text = string.Empty;
|
var text = VFS.ReadTextFile(filepath);
|
||||||
|
|
||||||
using (var reader = File.OpenText($"{filepath}.json"))
|
/* we cannot parse directly as <string, BundleDetails>, because...
|
||||||
{
|
[Error : Unity Log] JsonSerializationException: Expected string when reading UnityEngine.Hash128 type, got 'StartObject' <>. Path '['assets/content/weapons/animations/simple_animations.bundle'].Hash', line 1, position 176.
|
||||||
text = await reader.ReadToEndAsync();
|
...so we need to first convert it to a slimmed-down type (BundleItem), then convert back to BundleDetails.
|
||||||
}
|
*/
|
||||||
|
var raw = JsonConvert.DeserializeObject<Dictionary<string, BundleItem>>(text);
|
||||||
|
var converted = raw.ToDictionary(GetPairKey, GetPairValue);
|
||||||
|
|
||||||
var data = JsonConvert.DeserializeObject<Dictionary<string, BundleItem>>(text).ToDictionary(GetPairKey, GetPairValue);
|
// initialize manifest
|
||||||
var manifest = ScriptableObject.CreateInstance<CompatibilityAssetBundleManifest>();
|
var manifest = ScriptableObject.CreateInstance<CompatibilityAssetBundleManifest>();
|
||||||
manifest.SetResults(data);
|
manifest.SetResults(converted);
|
||||||
|
|
||||||
return manifest;
|
return manifest;
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,12 @@ namespace Aki.Custom.Patches
|
|||||||
|
|
||||||
if (BundleManager.Bundles.TryGetValue(key, out BundleInfo bundle))
|
if (BundleManager.Bundles.TryGetValue(key, out BundleInfo bundle))
|
||||||
{
|
{
|
||||||
dependencyKeys = (dependencyKeys.Length > 0) ? dependencyKeys.Union(bundle.DependencyKeys).ToArray() : bundle.DependencyKeys;
|
// server bundle
|
||||||
|
dependencyKeys = (dependencyKeys.Length > 0)
|
||||||
|
? dependencyKeys.Union(bundle.DependencyKeys).ToArray()
|
||||||
|
: bundle.DependencyKeys;
|
||||||
|
|
||||||
|
// set path to either cachedpath (HTTP) or modpath (local)
|
||||||
path = bundle.Path;
|
path = bundle.Path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user