Decompiled source of GDG ScheduleI Traditional Chinese Translation v2.0.4

FontPatcher.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text.RegularExpressions;
using FontPatcher;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem.Collections.Generic;
using Il2CppTMPro;
using MelonLoader;
using MelonLoader.Preferences;
using MelonLoader.Utils;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.TextCore;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(Main), "GDG字體修補dll", "1.0.0", "GDG遊戲聯合公國-午夜的大叔", null)]
[assembly: MelonGame(null, null)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("FontPatcher")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("FontPatcher")]
[assembly: AssemblyTitle("FontPatcher")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace FontPatcher
{
	public class Main : MelonMod
	{
		private static readonly MelonPreferences_Category ConfigCategory = MelonPreferences.CreateCategory("GDG_FontPatcher", "GDG 字體修補設定");

		private static MelonPreferences_Entry<string> _fontRegex;

		internal static Main Instance;

		internal static List<TMP_FontAsset> LoadedFonts = new List<TMP_FontAsset>();

		internal static HashSet<int> PatchedFontIds = new HashSet<int>();

		internal static Regex FontNameRegex;

		private bool _fontsLoaded;

		private static readonly HashSet<string> SkipExtensions = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
		{
			".dll", ".cfg", ".ini", ".txt", ".json", ".xml", ".log", ".md", ".png", ".jpg",
			".jpeg", ".gif", ".bmp", ".pdb", ".mdb", ".cs", ".csproj", ".sln", ".yml", ".yaml",
			".zip", ".7z", ".rar", ".exe", ".bat", ".sh", ".ico", ".svg", ".ttf", ".otf",
			".woff"
		};

		private float _lastPatchTime;

		private int _swapCount;

		private Material _donorMaterial;

		public override void OnInitializeMelon()
		{
			Instance = this;
			_fontRegex = ConfigCategory.CreateEntry<string>("FontNameRegex", ".*", "字體名稱匹配", "正則表達式,匹配要修補的遊戲字體名稱", false, false, (ValueValidator)null, (string)null);
			((MelonBase)this).LoggerInstance.Msg("========================================");
			((MelonBase)this).LoggerInstance.Msg("  GDG 字體修補dll v1.0.0");
			((MelonBase)this).LoggerInstance.Msg("========================================");
			MoveAutoTranslator();
		}

		private void MoveAutoTranslator()
		{
			try
			{
				string text = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "AutoTranslator");
				if (!Directory.Exists(text))
				{
					((MelonBase)this).LoggerInstance.Msg("AutoTranslator 資料夾不存在於模組目錄,可能已搬移過");
					return;
				}
				string text2 = Path.Combine(MelonEnvironment.GameRootDirectory, "AutoTranslator");
				((MelonBase)this).LoggerInstance.Msg("開始進行翻譯文本與設定檔搬移作業...");
				DirectoryCopy(text, text2, copySubDirs: true);
				((MelonBase)this).LoggerInstance.Msg("✅ 已覆蓋 AutoTranslator → " + text2);
				Directory.Delete(text, recursive: true);
				((MelonBase)this).LoggerInstance.Msg("✅ 已刪除模組目錄的 AutoTranslator(搬移完成)");
			}
			catch (Exception ex)
			{
				((MelonBase)this).LoggerInstance.Error("AutoTranslator 搬移失敗: " + ex.Message);
			}
		}

		private void DirectoryCopy(string sourceDirName, string destDirName, bool copySubDirs)
		{
			DirectoryInfo directoryInfo = new DirectoryInfo(sourceDirName);
			DirectoryInfo[] directories = directoryInfo.GetDirectories();
			Directory.CreateDirectory(destDirName);
			FileInfo[] files = directoryInfo.GetFiles();
			foreach (FileInfo fileInfo in files)
			{
				string destFileName = Path.Combine(destDirName, fileInfo.Name);
				fileInfo.CopyTo(destFileName, overwrite: true);
			}
			if (copySubDirs)
			{
				DirectoryInfo[] array = directories;
				foreach (DirectoryInfo directoryInfo2 in array)
				{
					string destDirName2 = Path.Combine(destDirName, directoryInfo2.Name);
					DirectoryCopy(directoryInfo2.FullName, destDirName2, copySubDirs);
				}
			}
		}

		public override void OnSceneWasLoaded(int buildIndex, string sceneName)
		{
			if (!_fontsLoaded)
			{
				_fontsLoaded = true;
				((MelonBase)this).LoggerInstance.Msg("場景 [" + sceneName + "] 觸發字體載入...");
				LoadFontBundles();
				if (LoadedFonts.Count > 0)
				{
					FontNameRegex = new Regex(_fontRegex.Value);
				}
			}
			if (LoadedFonts.Count == 0)
			{
				if (buildIndex <= 1)
				{
					((MelonBase)this).LoggerInstance.Warning("未找到任何字體檔案,字體修補停用");
				}
			}
			else
			{
				PatchAllFonts("場景 [" + sceneName + "]");
				SwapFontsOnTextComponents();
			}
		}

		public override void OnLateUpdate()
		{
			if (LoadedFonts.Count != 0 && _fontsLoaded)
			{
				float time = Time.time;
				float num = ((time < 10f) ? 0.5f : 2f);
				if (!(time - _lastPatchTime < num))
				{
					_lastPatchTime = time;
					PatchAllFonts(null);
					SwapFontsOnTextComponents();
				}
			}
		}

		private void SwapFontsOnTextComponents()
		{
			TMP_FontAsset val = LoadedFonts[0];
			int num = 0;
			Il2CppArrayBase<TextMeshProUGUI> val2 = Resources.FindObjectsOfTypeAll<TextMeshProUGUI>();
			if (val2 == null)
			{
				return;
			}
			foreach (TextMeshProUGUI item in val2)
			{
				if ((Object)(object)item == (Object)null || (Object)(object)((TMP_Text)item).font == (Object)(object)val)
				{
					continue;
				}
				string text = null;
				try
				{
					text = ((TMP_Text)item).text;
				}
				catch
				{
					continue;
				}
				if (string.IsNullOrEmpty(text))
				{
					continue;
				}
				bool flag = false;
				string text2 = text;
				foreach (char c in text2)
				{
					if (c >= '一' && c <= '\u9fff')
					{
						flag = true;
						break;
					}
				}
				if (flag)
				{
					((TMP_Text)item).font = val;
					num++;
				}
			}
			if (num > 0 && _swapCount == 0)
			{
				((MelonBase)this).LoggerInstance.Msg($"直接替換字體: {num} 個含中文的文字元件");
			}
			_swapCount += num;
		}

		private void PatchAllFonts(string source)
		{
			Il2CppArrayBase<TMP_FontAsset> val = Resources.FindObjectsOfTypeAll<TMP_FontAsset>();
			if (val == null)
			{
				return;
			}
			int num = 0;
			foreach (TMP_FontAsset item in val)
			{
				if ((Object)(object)item == (Object)null)
				{
					continue;
				}
				int instanceID = ((Object)item).GetInstanceID();
				if (PatchedFontIds.Contains(instanceID) || LoadedFonts.Contains(item) || (Object)(object)((TMP_Asset)item).material == (Object)null)
				{
					continue;
				}
				string input = ((Object)item).name ?? "";
				if (FontNameRegex != null && !FontNameRegex.IsMatch(input))
				{
					continue;
				}
				if (item.fallbackFontAssetTable == null)
				{
					item.fallbackFontAssetTable = new List<TMP_FontAsset>();
				}
				int num2 = 0;
				foreach (TMP_FontAsset loadedFont in LoadedFonts)
				{
					if ((Object)(object)loadedFont != (Object)null)
					{
						item.fallbackFontAssetTable.Add(loadedFont);
						num2++;
					}
				}
				PatchedFontIds.Add(instanceID);
				if (num2 > 0)
				{
					num++;
				}
			}
			if (num <= 0 || source == null)
			{
				return;
			}
			((MelonBase)this).LoggerInstance.Msg($"{source} 已修補 {num} 個字體(累計 {PatchedFontIds.Count} 個)");
			foreach (TMP_FontAsset item2 in val)
			{
				if (!((Object)(object)item2 == (Object)null) && item2.fallbackFontAssetTable != null && !LoadedFonts.Contains(item2) && item2.fallbackFontAssetTable.Count > 0)
				{
					_ = item2.fallbackFontAssetTable[0];
					bool value = item2.HasCharacter('中', true, true);
					((MelonBase)this).LoggerInstance.Msg($"  驗證 [{((Object)item2).name}]: fallback數={item2.fallbackFontAssetTable.Count}, HasCharacter('中',searchFallbacks)={value}");
					break;
				}
			}
		}

		private void InitFontAsset(TMP_FontAsset font)
		{
			//IL_025d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0262: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if ((Object)(object)((TMP_Asset)font).material == (Object)null && (Object)(object)font.atlasTexture != (Object)null)
				{
					((MelonBase)this).LoggerInstance.Msg("    material 為 null,從遊戲字體複製...");
					if ((Object)(object)_donorMaterial == (Object)null)
					{
						foreach (TMP_FontAsset item in Resources.FindObjectsOfTypeAll<TMP_FontAsset>())
						{
							if ((Object)(object)item != (Object)null && (Object)(object)((TMP_Asset)item).material != (Object)null && !LoadedFonts.Contains(item))
							{
								_donorMaterial = ((TMP_Asset)item).material;
								((MelonBase)this).LoggerInstance.Msg("    donor material: " + ((Object)item).name + " → " + ((Object)_donorMaterial).name);
								break;
							}
						}
					}
					if ((Object)(object)_donorMaterial != (Object)null)
					{
						Material val = Object.Instantiate<Material>(_donorMaterial);
						((Object)val).name = ((Object)font).name + " Material";
						val.mainTexture = (Texture)(object)font.atlasTexture;
						val.SetFloat(Shader.PropertyToID("_TextureWidth"), (float)((Texture)font.atlasTexture).width);
						val.SetFloat(Shader.PropertyToID("_TextureHeight"), (float)((Texture)font.atlasTexture).height);
						val.SetFloat(Shader.PropertyToID("_GradientScale"), (float)(font.atlasPadding + 1));
						((TMP_Asset)font).material = val;
						((MelonBase)this).LoggerInstance.Msg($"    已建立 material: {((Object)val).name} (shader={((Object)val.shader).name})");
					}
					else
					{
						((MelonBase)this).LoggerInstance.Warning("    找不到可用的 donor material!");
					}
				}
				font.ReadFontAssetDefinition();
				Texture2D atlasTexture = font.atlasTexture;
				Material material = ((TMP_Asset)font).material;
				int value = font.characterTable?.Count ?? 0;
				bool value2 = font.HasCharacter('中', false, false);
				string text = "N/A";
				try
				{
					Dictionary<uint, TMP_Character> characterLookupTable = font.characterLookupTable;
					TMP_Character val2 = default(TMP_Character);
					if (characterLookupTable != null && characterLookupTable.TryGetValue(20013u, ref val2) && val2 != null)
					{
						Glyph glyph = ((TMP_TextElement)val2).glyph;
						if (glyph != null)
						{
							GlyphRect glyphRect = glyph.glyphRect;
							text = $"glyphIdx={glyph.index}, rect=({((GlyphRect)(ref glyphRect)).x},{((GlyphRect)(ref glyphRect)).y},{((GlyphRect)(ref glyphRect)).width},{((GlyphRect)(ref glyphRect)).height}), atlasIdx={glyph.atlasIndex}";
						}
						else
						{
							text = "glyph=null!";
						}
					}
				}
				catch (Exception ex)
				{
					text = "error: " + ex.Message;
				}
				((MelonBase)this).LoggerInstance.Msg($"    初始化: atlas={(((Object)(object)atlasTexture != (Object)null) ? $"{((Texture)atlasTexture).width}x{((Texture)atlasTexture).height}" : "null")}, material={(((Object)(object)material != (Object)null) ? ((Object)material).name : "null")}, 字元數={value}, HasChar('中')={value2}");
				((MelonBase)this).LoggerInstance.Msg("    glyph('中'): " + text);
			}
			catch (Exception ex2)
			{
				((MelonBase)this).LoggerInstance.Warning("    InitFontAsset 失敗: " + ex2.Message);
			}
		}

		private void LoadFontBundles()
		{
			string gameRootDirectory = MelonEnvironment.GameRootDirectory;
			string modsDirectory = MelonEnvironment.ModsDirectory;
			string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
			HashSet<string> searchDirs = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
			TryAdd(gameRootDirectory);
			TryAdd(Path.Combine(gameRootDirectory, "FontPatcher"));
			TryAdd(Path.Combine(gameRootDirectory, "AutoTranslator"));
			TryAdd(Path.Combine(gameRootDirectory, "AutoTranslator", "FontPatcher"));
			TryAdd(directoryName);
			TryAdd(Path.Combine(directoryName, "FontPatcher"));
			TryAdd(Path.Combine(directoryName, "AutoTranslator"));
			TryAdd(Path.Combine(directoryName, "AutoTranslator", "FontPatcher"));
			TryAdd(modsDirectory);
			if (Directory.Exists(modsDirectory))
			{
				string[] directories = Directory.GetDirectories(modsDirectory);
				foreach (string obj in directories)
				{
					TryAdd(obj);
					TryAdd(Path.Combine(obj, "FontPatcher"));
					TryAdd(Path.Combine(obj, "AutoTranslator"));
					TryAdd(Path.Combine(obj, "AutoTranslator", "FontPatcher"));
				}
			}
			((MelonBase)this).LoggerInstance.Msg($"掃描 {searchDirs.Count} 個目錄...");
			Dictionary<string, string> dictionary = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
			foreach (string item in searchDirs)
			{
				bool flag = Path.GetFileName(item).Equals("FontPatcher", StringComparison.OrdinalIgnoreCase);
				string[] directories = Directory.GetFiles(item);
				foreach (string path in directories)
				{
					string extension = Path.GetExtension(path);
					if ((string.IsNullOrEmpty(extension) || !SkipExtensions.Contains(extension)) && (flag || string.IsNullOrEmpty(extension)))
					{
						string fileName = Path.GetFileName(path);
						if (!dictionary.ContainsKey(fileName))
						{
							dictionary[fileName] = Path.GetFullPath(path);
						}
					}
				}
			}
			if (dictionary.Count == 0)
			{
				((MelonBase)this).LoggerInstance.Warning("所有目錄中都找不到字體檔案");
				{
					foreach (string item2 in searchDirs.Take(8))
					{
						((MelonBase)this).LoggerInstance.Warning("  已搜尋: " + item2);
					}
					return;
				}
			}
			((MelonBase)this).LoggerInstance.Msg($"找到 {dictionary.Count} 個候選字體檔案");
			int num = 0;
			int num2 = 0;
			foreach (KeyValuePair<string, string> item3 in dictionary)
			{
				string key = item3.Key;
				string value = item3.Value;
				((MelonBase)this).LoggerInstance.Msg("嘗試載入: " + value);
				try
				{
					Il2CppAssetBundle il2CppAssetBundle = Il2CppAssetBundleManager.LoadFromFile(value);
					if (il2CppAssetBundle == null)
					{
						((MelonBase)this).LoggerInstance.Warning("  [" + key + "] LoadFromFile 回傳 null");
						num2++;
						continue;
					}
					((MelonBase)this).LoggerInstance.Msg("  [" + key + "] AssetBundle 已開啟");
					bool flag2 = false;
					string[] array = null;
					try
					{
						Il2CppStringArray allAssetNames = il2CppAssetBundle.GetAllAssetNames();
						if (allAssetNames != null && ((Il2CppArrayBase<string>)(object)allAssetNames).Length > 0)
						{
							array = new string[((Il2CppArrayBase<string>)(object)allAssetNames).Length];
							for (int j = 0; j < ((Il2CppArrayBase<string>)(object)allAssetNames).Length; j++)
							{
								array[j] = ((Il2CppArrayBase<string>)(object)allAssetNames)[j];
								((MelonBase)this).LoggerInstance.Msg($"    asset[{j}]: {array[j]}");
							}
						}
					}
					catch (Exception ex)
					{
						((MelonBase)this).LoggerInstance.Msg("  GetAllAssetNames 失敗: " + ex.Message);
					}
					if (array != null)
					{
						string[] directories = array;
						foreach (string text in directories)
						{
							try
							{
								TMP_FontAsset val = il2CppAssetBundle.LoadAsset<TMP_FontAsset>(text);
								if ((Object)(object)val != (Object)null)
								{
									((MelonBase)this).LoggerInstance.Msg("  LoadAsset(\"" + text + "\") → " + ((Object)val).name);
									((MelonBase)this).LoggerInstance.Msg("    material(載入時)=" + (((Object)(object)((TMP_Asset)val).material != (Object)null) ? ((Object)((TMP_Asset)val).material).name : "null"));
									InitFontAsset(val);
									LoadedFonts.Add(val);
									flag2 = true;
									num++;
								}
							}
							catch
							{
							}
						}
					}
					if (!flag2)
					{
						try
						{
							Il2CppReferenceArray<TMP_FontAsset> val2 = il2CppAssetBundle.LoadAllAssets<TMP_FontAsset>();
							if (val2 != null && ((Il2CppArrayBase<TMP_FontAsset>)(object)val2).Length > 0)
							{
								foreach (TMP_FontAsset item4 in (Il2CppArrayBase<TMP_FontAsset>)(object)val2)
								{
									if ((Object)(object)item4 != (Object)null)
									{
										InitFontAsset(item4);
										((MelonBase)this).LoggerInstance.Msg("  → 字體: " + ((Object)item4).name);
										LoadedFonts.Add(item4);
										flag2 = true;
									}
								}
								if (flag2)
								{
									num++;
								}
							}
						}
						catch (Exception ex2)
						{
							((MelonBase)this).LoggerInstance.Msg("  LoadAllAssets 跳過: " + ex2.Message);
						}
					}
					if (flag2)
					{
						continue;
					}
					try
					{
						Il2CppStringArray allAssetNames2 = il2CppAssetBundle.GetAllAssetNames();
						if (allAssetNames2 != null && ((Il2CppArrayBase<string>)(object)allAssetNames2).Length > 0)
						{
							((MelonBase)this).LoggerInstance.Warning("  [" + key + "] 無 TMP_FontAsset,包含的資產:");
							foreach (string item5 in (Il2CppArrayBase<string>)(object)allAssetNames2)
							{
								((MelonBase)this).LoggerInstance.Warning("    - " + item5);
							}
						}
						else
						{
							((MelonBase)this).LoggerInstance.Warning("  [" + key + "] AssetBundle 為空");
						}
					}
					catch
					{
					}
					il2CppAssetBundle.Unload(unloadAllLoadedObjects: false);
					num2++;
				}
				catch (Exception ex3)
				{
					((MelonBase)this).LoggerInstance.Warning("  [" + key + "] 載入失敗: " + ex3.Message);
					num2++;
				}
			}
			((MelonBase)this).LoggerInstance.Msg($"字體載入完成: {num} 成功, {num2} 失敗, 共 {LoadedFonts.Count} 個字體資產");
			void TryAdd(string p)
			{
				try
				{
					if (Directory.Exists(p))
					{
						searchDirs.Add(Path.GetFullPath(p));
					}
				}
				catch
				{
				}
			}
		}
	}
}
namespace UnityEngine
{
	public class Il2CppAssetBundle
	{
		private delegate bool ContainsDelegate(IntPtr _this, IntPtr name);

		private delegate IntPtr GetAllAssetNamesDelegate(IntPtr _this);

		private delegate IntPtr LoadAsset_InternalDelegate(IntPtr _this, IntPtr name, IntPtr type);

		private delegate IntPtr LoadAssetWithSubAssets_InternalDelegate(IntPtr _this, IntPtr name, IntPtr type);

		private delegate void UnloadDelegate(IntPtr _this, bool unloadAllObjects);

		private IntPtr bundleptr = IntPtr.Zero;

		private static readonly ContainsDelegate ContainsDelegateField;

		private static readonly GetAllAssetNamesDelegate GetAllAssetNamesDelegateField;

		private static readonly LoadAsset_InternalDelegate LoadAsset_InternalDelegateField;

		private static readonly LoadAssetWithSubAssets_InternalDelegate LoadAssetWithSubAssets_InternalDelegateField;

		private static readonly UnloadDelegate UnloadDelegateField;

		public Il2CppAssetBundle(IntPtr ptr)
		{
			bundleptr = ptr;
		}

		static Il2CppAssetBundle()
		{
			ContainsDelegateField = IL2CPP.ResolveICall<ContainsDelegate>("UnityEngine.AssetBundle::Contains");
			GetAllAssetNamesDelegateField = IL2CPP.ResolveICall<GetAllAssetNamesDelegate>("UnityEngine.AssetBundle::GetAllAssetNames");
			LoadAsset_InternalDelegateField = IL2CPP.ResolveICall<LoadAsset_InternalDelegate>("UnityEngine.AssetBundle::LoadAsset_Internal(System.String,System.Type)");
			LoadAssetWithSubAssets_InternalDelegateField = IL2CPP.ResolveICall<LoadAssetWithSubAssets_InternalDelegate>("UnityEngine.AssetBundle::LoadAssetWithSubAssets_Internal");
			UnloadDelegateField = IL2CPP.ResolveICall<UnloadDelegate>("UnityEngine.AssetBundle::Unload");
		}

		public bool Contains(string name)
		{
			if (bundleptr == IntPtr.Zero)
			{
				throw new NullReferenceException("The bundleptr cannot be IntPtr.Zero");
			}
			if (string.IsNullOrEmpty(name))
			{
				throw new ArgumentException("The input asset name cannot be null or empty.");
			}
			if (ContainsDelegateField == null)
			{
				throw new NullReferenceException("The ContainsDelegateField cannot be null.");
			}
			return ContainsDelegateField(bundleptr, IL2CPP.ManagedStringToIl2Cpp(name));
		}

		public Il2CppStringArray GetAllAssetNames()
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Expected O, but got Unknown
			if (bundleptr == IntPtr.Zero)
			{
				throw new NullReferenceException("The bundleptr cannot be IntPtr.Zero");
			}
			if (GetAllAssetNamesDelegateField == null)
			{
				throw new NullReferenceException("The GetAllAssetNamesDelegateField cannot be null.");
			}
			IntPtr intPtr = GetAllAssetNamesDelegateField(bundleptr);
			if (!(intPtr != IntPtr.Zero))
			{
				return null;
			}
			return new Il2CppStringArray(intPtr);
		}

		public T LoadAsset<T>(string name) where T : Il2CppObjectBase
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			IntPtr pointer = ((Il2CppObjectBase)Il2CppType.Of<T>()).Pointer;
			IntPtr intPtr = LoadAssetRaw(name, pointer);
			if (intPtr == IntPtr.Zero)
			{
				return default(T);
			}
			return new Il2CppObjectBase(intPtr).Cast<T>();
		}

		private IntPtr LoadAssetRaw(string name, IntPtr typeptr)
		{
			if (bundleptr == IntPtr.Zero)
			{
				throw new NullReferenceException("The bundleptr cannot be IntPtr.Zero");
			}
			if (string.IsNullOrEmpty(name))
			{
				throw new ArgumentException("The input asset name cannot be null or empty.");
			}
			if (typeptr == IntPtr.Zero)
			{
				throw new NullReferenceException("The input type cannot be IntPtr.Zero");
			}
			if (LoadAsset_InternalDelegateField == null)
			{
				throw new NullReferenceException("The LoadAsset_InternalDelegateField cannot be null.");
			}
			return LoadAsset_InternalDelegateField(bundleptr, IL2CPP.ManagedStringToIl2Cpp(name), typeptr);
		}

		public Il2CppReferenceArray<T> LoadAllAssets<T>() where T : Il2CppObjectBase
		{
			IntPtr pointer = ((Il2CppObjectBase)Il2CppType.Of<T>()).Pointer;
			IntPtr intPtr = LoadAllAssetsRaw(pointer);
			if (!(intPtr != IntPtr.Zero))
			{
				return null;
			}
			return new Il2CppReferenceArray<T>(intPtr);
		}

		private IntPtr LoadAllAssetsRaw(IntPtr typeptr)
		{
			if (typeptr == IntPtr.Zero)
			{
				throw new NullReferenceException("The input type cannot be IntPtr.Zero");
			}
			if (LoadAssetWithSubAssets_InternalDelegateField == null)
			{
				throw new NullReferenceException("The LoadAssetWithSubAssets_InternalDelegateField cannot be null.");
			}
			return LoadAssetWithSubAssets_InternalDelegateField(bundleptr, IL2CPP.ManagedStringToIl2Cpp(string.Empty), typeptr);
		}

		public void Unload(bool unloadAllLoadedObjects)
		{
			if (bundleptr == IntPtr.Zero)
			{
				throw new NullReferenceException("The bundleptr cannot be IntPtr.Zero");
			}
			if (UnloadDelegateField == null)
			{
				throw new NullReferenceException("The UnloadDelegateField cannot be null.");
			}
			UnloadDelegateField(bundleptr, unloadAllLoadedObjects);
		}
	}
	public class Il2CppAssetBundleManager
	{
		private delegate IntPtr LoadFromFile_InternalDelegate(IntPtr path, uint crc, ulong offset);

		private delegate IntPtr UnloadAllAssetBundlesDelegate(bool unloadAllObjects);

		private static readonly LoadFromFile_InternalDelegate LoadFromFile_InternalDelegateField;

		private static readonly UnloadAllAssetBundlesDelegate UnloadAllAssetBundlesDelegateField;

		static Il2CppAssetBundleManager()
		{
			LoadFromFile_InternalDelegateField = IL2CPP.ResolveICall<LoadFromFile_InternalDelegate>("UnityEngine.AssetBundle::LoadFromFile_Internal(System.String,System.UInt32,System.UInt64)");
			UnloadAllAssetBundlesDelegateField = IL2CPP.ResolveICall<UnloadAllAssetBundlesDelegate>("UnityEngine.AssetBundle::UnloadAllAssetBundles");
		}

		public static Il2CppAssetBundle LoadFromFile(string path)
		{
			return LoadFromFile(path, 0u, 0uL);
		}

		public static Il2CppAssetBundle LoadFromFile(string path, uint crc)
		{
			return LoadFromFile(path, crc, 0uL);
		}

		public static Il2CppAssetBundle LoadFromFile(string path, uint crc, ulong offset)
		{
			if (string.IsNullOrEmpty(path))
			{
				throw new ArgumentException("The input asset bundle path cannot be null or empty.");
			}
			if (LoadFromFile_InternalDelegateField == null)
			{
				throw new NullReferenceException("The LoadFromFile_InternalDelegateField cannot be null.");
			}
			IntPtr intPtr = LoadFromFile_InternalDelegateField(IL2CPP.ManagedStringToIl2Cpp(path), crc, offset);
			if (!(intPtr != IntPtr.Zero))
			{
				return null;
			}
			return new Il2CppAssetBundle(intPtr);
		}

		public static void UnloadAllAssetBundles(bool unloadAllObjects)
		{
			if (UnloadAllAssetBundlesDelegateField == null)
			{
				throw new NullReferenceException("The UnloadAllAssetBundlesDelegateField cannot be null.");
			}
			UnloadAllAssetBundlesDelegateField(unloadAllObjects);
		}
	}
}