From f83c795c68b70017d10215bd3a2cdcd4a879f646 Mon Sep 17 00:00:00 2001 From: js6pak Date: Wed, 31 Jul 2024 00:16:11 +0200 Subject: [PATCH] Add support for asset bundles without an architecture suffix Unity requires specifying the architecture when building asset bundles as part of BuildTarget. While compatibility between targets isn't guaranteed, in practice there are no differences between architectures. --- Reactor.Assets/Assets/Build.cs | 8 +- ...ault-win-x86.bundle => default-win.bundle} | Bin Reactor/Utilities/AssetBundleManager.cs | 92 ++++++++++++------ 3 files changed, 66 insertions(+), 34 deletions(-) rename Reactor/Assets/{default-win-x86.bundle => default-win.bundle} (100%) diff --git a/Reactor.Assets/Assets/Build.cs b/Reactor.Assets/Assets/Build.cs index 7d47946..f214338 100644 --- a/Reactor.Assets/Assets/Build.cs +++ b/Reactor.Assets/Assets/Build.cs @@ -69,14 +69,14 @@ public static void BuildAssetBundles() } } - private static string GetTargetName(BuildTarget target) + private static string GetTargetName(BuildTarget target, bool includeArchitecture = false) { return target switch { - BuildTarget.StandaloneWindows => "win-x86", - BuildTarget.StandaloneWindows64 => "win-x64", + BuildTarget.StandaloneWindows => includeArchitecture ? "win-x86" : "win", + BuildTarget.StandaloneWindows64 => includeArchitecture ? "win-x64" : "win", BuildTarget.Android => "android", - BuildTarget.StandaloneLinux64 => "linux-x64", + BuildTarget.StandaloneLinux64 => includeArchitecture ? "linux-x64" : "linux", _ => throw new ArgumentOutOfRangeException(nameof(target), target, null), }; } diff --git a/Reactor/Assets/default-win-x86.bundle b/Reactor/Assets/default-win.bundle similarity index 100% rename from Reactor/Assets/default-win-x86.bundle rename to Reactor/Assets/default-win.bundle diff --git a/Reactor/Utilities/AssetBundleManager.cs b/Reactor/Utilities/AssetBundleManager.cs index 6645864..afc86cd 100644 --- a/Reactor/Utilities/AssetBundleManager.cs +++ b/Reactor/Utilities/AssetBundleManager.cs @@ -3,8 +3,8 @@ using System.IO; using System.Linq; using System.Reflection; +using System.Runtime.InteropServices; using Il2CppInterop.Runtime.InteropTypes.Arrays; -using MonoMod.Utils; using Reactor.Utilities.Extensions; using UnityEngine; @@ -23,38 +23,48 @@ public static class AssetBundleManager /// /// Gets the target name of the current system. /// - public static string TargetName { get; } + [Obsolete("Use AssetBundleManager#GetTargetName instead")] + public static string TargetName { get; } = GetTargetName(true); - static AssetBundleManager() + /// + /// Gets the target name of the current system. + /// + /// A value indicating whether to include the process architecture. + /// Target name of the current system. + public static string GetTargetName(bool includeArchitecture) { - if (PlatformHelper.Is(Platform.Android)) + string operatingSystem; + + if (OperatingSystem.IsWindows()) { - TargetName = "android"; + operatingSystem = "win"; + } + else if (OperatingSystem.IsLinux()) + { + operatingSystem = "linux"; + } + else if (OperatingSystem.IsAndroid()) + { + operatingSystem = "android"; } else { - if (PlatformHelper.Is(Platform.Windows)) - { - TargetName = "win"; - } - else if (PlatformHelper.Is(Platform.Linux)) - { - TargetName = "linux"; - } - else - { - throw new PlatformNotSupportedException(); - } + throw new PlatformNotSupportedException(); + } - if (PlatformHelper.Is(Platform.ARM)) - { - TargetName += Environment.Is64BitProcess ? "-arm64" : "-arm"; - } - else - { - TargetName += Environment.Is64BitProcess ? "-x64" : "-x86"; - } + if (!includeArchitecture) + { + return operatingSystem; } + + return $"{operatingSystem}-{RuntimeInformation.ProcessArchitecture switch + { + Architecture.X86 => "x86", + Architecture.X64 => "x64", + Architecture.Arm => "arm", + Architecture.Arm64 => "arm64", + _ => throw new PlatformNotSupportedException(), + }}"; } /// @@ -62,7 +72,16 @@ static AssetBundleManager() /// /// The name of the asset bundle. /// File name of the asset bundle. - public static string GetFileName(string assetBundleName) => $"{assetBundleName}-{TargetName}{BundleExtension}"; + [Obsolete("Use the overload with includeArchitecture instead")] + public static string GetFileName(string assetBundleName) => GetFileName(assetBundleName, true); + + /// + /// Gets the file name for an asset bundle named . + /// + /// The name of the asset bundle. + /// A value indicating whether to include the process architecture. + /// File name of the asset bundle. + public static string GetFileName(string assetBundleName, bool includeArchitecture) => $"{assetBundleName}-{GetTargetName(includeArchitecture)}{BundleExtension}"; private static bool TryFindFile(Assembly assembly, string fileName, [NotNullWhen(true)] out string? path) { @@ -72,6 +91,7 @@ private static bool TryFindFile(Assembly assembly, string fileName, [NotNullWhen var filePath = Path.Combine(pluginDirectoryPath, fileName); if (File.Exists(filePath)) { + Debug($"Loading an asset bundle from {filePath}"); path = filePath; return true; } @@ -86,6 +106,8 @@ private static bool TryLoadResource(Assembly assembly, string fileName, [NotNull var resourceName = assembly.GetManifestResourceNames().SingleOrDefault(n => n.EndsWith(fileName, StringComparison.Ordinal)); if (resourceName != null) { + Debug($"Loading an asset bundle from {resourceName}"); + using var stream = assembly.GetManifestResourceStream(resourceName) ?? throw new InvalidOperationException("Resource stream was null"); var length = (int) stream.Length; @@ -119,8 +141,13 @@ public static AssetBundle Load(string name) /// Couldn't find an assetbundle named . public static AssetBundle Load(Assembly assembly, string name) { - var fileName = GetFileName(name); + return TryLoad(assembly, GetFileName(name, includeArchitecture: true)) + ?? TryLoad(assembly, GetFileName(name, includeArchitecture: false)) + ?? throw new AssetBundleNotFoundException(name); + } + private static AssetBundle? TryLoad(Assembly assembly, string fileName) + { if (TryFindFile(assembly, fileName, out var filePath)) { return AssetBundle.LoadFromFile(filePath); @@ -131,7 +158,7 @@ public static AssetBundle Load(Assembly assembly, string name) return AssetBundle.LoadFromMemory(data); } - throw new AssetBundleNotFoundException(name); + return null; } /// @@ -154,8 +181,13 @@ public static AssetBundleCreateRequest LoadAsync(string name) /// Couldn't find an assetbundle named . public static AssetBundleCreateRequest LoadAsync(Assembly assembly, string name) { - var fileName = GetFileName(name); + return TryLoadAsync(assembly, GetFileName(name, includeArchitecture: true)) + ?? TryLoadAsync(assembly, GetFileName(name, includeArchitecture: false)) + ?? throw new AssetBundleNotFoundException(name); + } + private static AssetBundleCreateRequest? TryLoadAsync(Assembly assembly, string fileName) + { if (TryFindFile(assembly, fileName, out var filePath)) { return AssetBundle.LoadFromFileAsync(filePath); @@ -166,7 +198,7 @@ public static AssetBundleCreateRequest LoadAsync(Assembly assembly, string name) return AssetBundle.LoadFromMemoryAsync(data); } - throw new AssetBundleNotFoundException(name); + return null; } }