Skip to content
This repository has been archived by the owner on Nov 29, 2023. It is now read-only.

Commit

Permalink
[Tangerine] Add asset bundle loader
Browse files Browse the repository at this point in the history
  • Loading branch information
mosamadeeb committed Sep 10, 2023
1 parent e5985e5 commit 450e468
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 0 deletions.
1 change: 1 addition & 0 deletions Tangerine/Plugin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,6 @@ public override void Load()
_harmony = new Harmony(MyPluginInfo.PLUGIN_GUID);
TangerineDataManager.InitializeHarmony(_harmony);
TangerineTextDataManager.InitializeHarmony(_harmony);
TangerineLoader.InitializeHarmony(_harmony);
}
}
96 changes: 96 additions & 0 deletions Tangerine/TangerineLoader.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
using HarmonyLib;
using System.Collections.Generic;
using System.Reflection;

namespace Tangerine
{
public static class TangerineLoader
{
private static Harmony _harmony;

private static bool _assetsBundleManagerUnpatched = false;

// assetbundleName: id
private static readonly Dictionary<string, AssetbundleId> _assetBundleIds = new();

// id.hash: filePath
private static readonly Dictionary<string, string> _assetBundlePaths = new();

/// <summary>
/// Adds an Asset Bundle to the game's dictionary to allow it to be loaded from a custom path.
/// Asset bundles existing in the game will be overridden if a bundle with the same name is added.
/// </summary>
/// <param name="id">Id entry to add</param>
/// <param name="filePath">The path the file will be loaded from</param>
public static void AddAssetBundleId(AssetbundleId id, string filePath)
{
id.SetKeys();
_assetBundleIds[id.name] = id;
_assetBundlePaths[id.hash] = filePath;

if (_assetsBundleManagerUnpatched)
{
// Update the game's dictionary
AssetsBundleManager.Instance.dictBundleID[id.name] = id;
}
}

/// <param name="idDict"><c>Key: Value</c> mapping for <see cref="AssetbundleId"/></param>
/// <inheritdoc cref="AddAssetBundleId(AssetbundleId, string)"/>
public static void AddAssetBundleId(Dictionary<string, object> idDict, string filePath)
{
AddAssetBundleId(CreateAssetbundleIdFromDict(idDict), filePath);
}

/// <summary>
/// Adds a file hash to be loaded from a custom path when the game asks for the file.
/// This method is for adding files that are not asset bundles, like <c>.acb</c> files.
/// Use <see cref="AddAssetBundleId(AssetbundleId, string)"/> for adding asset bundles.
/// </summary>
/// <param name="hash">MD5 hash of the file name that the game will search for</param>
/// <inheritdoc cref="AddAssetBundleId(AssetbundleId, string)"/>
public static void AddFile(string hash, string filePath)
{
_assetBundlePaths[hash] = filePath;
}

internal static void InitializeHarmony(Harmony harmony)
{
_harmony = harmony;
_harmony.PatchAll(typeof(TangerineLoader));
}

private static AssetbundleId CreateAssetbundleIdFromDict(Dictionary<string, object> dict)
{
return new AssetbundleId((string)dict["name"], (string)dict["hash"], (uint)dict["crc"], (long)dict["size"]);
}

[HarmonyPatch(typeof(AssetsBundleManager), nameof(AssetsBundleManager.OnStartLoadSingleAsset))]
[HarmonyPostfix]
public static void AddAssetbundleIdsPatch(AssetsBundleManager __instance, MethodBase __originalMethod)
{
// This will override existing bundle ids in the manager's dict
foreach (var id in _assetBundleIds.Values)
{
__instance.dictBundleID[id.name] = id;
Plugin.Log.LogWarning($"Added AssetbundleId: [{id.hash}] {id.name}");
}

Plugin.Log.LogWarning($"Unpatching {nameof(AssetsBundleManager)} postfix");
_harmony.Unpatch(__originalMethod, MethodBase.GetCurrentMethod() as MethodInfo);
_assetsBundleManagerUnpatched = true;
}

[HarmonyPatch(typeof(AssetsBundleManager), nameof(AssetsBundleManager.GetPath))]
[HarmonyPostfix]
private static void GetPathPostfix(string file, ref string __result)
{
if (_assetBundlePaths.TryGetValue(file, out var filePath))
{
// Update file path
__result = filePath;
Plugin.Log.LogWarning($"Replaced path for file: ({__result})");
}
}
}
}

0 comments on commit 450e468

Please sign in to comment.