using System; using System.CodeDom; using System.CodeDom.Compiler; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using Cysharp.Threading.Tasks; using Cysharp.Threading.Tasks.CompilerServices; using DG.Tweening; using DG.Tweening.Core; using DG.Tweening.Plugins.Options; using Extensions.Unity.ImageLoader; using HarmonyLib; using LBoL.Base; using LBoL.Base.Extensions; using LBoL.ConfigData; using LBoL.Core; using LBoL.Core.Adventures; using LBoL.Core.Battle; using LBoL.Core.Battle.BattleActions; using LBoL.Core.Cards; using LBoL.Core.Dialogs; using LBoL.Core.GapOptions; using LBoL.Core.SaveData; using LBoL.Core.Stations; using LBoL.Core.StatusEffects; using LBoL.Core.Units; using LBoL.EntityLib.Adventures; using LBoL.EntityLib.Cards.Character.Reimu; using LBoL.EntityLib.EnemyUnits.Character; using LBoL.Presentation; using LBoL.Presentation.Effect; using LBoL.Presentation.Environments; using LBoL.Presentation.I10N; using LBoL.Presentation.UI; using LBoL.Presentation.UI.ExtraWidgets; using LBoL.Presentation.UI.Panels; using LBoL.Presentation.UI.Widgets; using LBoL.Presentation.Units; using LBoLEntitySideloader; using LBoLEntitySideloader.Attributes; using LBoLEntitySideloader.BattleModifiers.Actions; using LBoLEntitySideloader.BattleModifiers.Args; using LBoLEntitySideloader.CustomHandlers; using LBoLEntitySideloader.Entities; using LBoLEntitySideloader.Entities.DynamicTemplates; using LBoLEntitySideloader.Entities.MockConfigs; using LBoLEntitySideloader.Entities.Patches; using LBoLEntitySideloader.PersistentValues; using LBoLEntitySideloader.ReflectionHelpers; using LBoLEntitySideloader.Resource; using LBoLEntitySideloader.TemplateGen; using LBoLEntitySideloader.UIhelpers; using LBoLEntitySideloader.Utils; using LBoLEntitySideloader.Utils.ArrayExtensions; using Mono.CSharp; using MonoMod.Utils; using ScriptEngine; using Spine.Unity; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.Experimental.Rendering; using UnityEngine.Networking; using UnityEngine.UI; using YamlDotNet.Core; using YamlDotNet.Core.Events; using YamlDotNet.Helpers; using YamlDotNet.RepresentationModel; using YamlDotNet.Serialization; using Yarn; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: IgnoresAccessChecksTo("LBoL.Base")] [assembly: IgnoresAccessChecksTo("LBoL.ConfigData")] [assembly: IgnoresAccessChecksTo("LBoL.Core")] [assembly: IgnoresAccessChecksTo("LBoL.EntityLib")] [assembly: IgnoresAccessChecksTo("LBoL.Presentation")] [assembly: IgnoresAccessChecksTo("Untitled.ConfigDataBuilder.Base")] [assembly: AssemblyCompany("LBoL-Entity-Sideloader")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+fbe97b4a95487af070d4eacf7741bf6ac981110b")] [assembly: AssemblyProduct("LBoL-Entity-Sideloader")] [assembly: AssemblyTitle("LBoL-Entity-Sideloader")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [HarmonyPatch(typeof(Library), "InternalEnumerateDisplayWords")] public static class DuplicateTooltipFix { private static bool Prefix(GameRunController gameRun, Keyword keyword, IEnumerable initEffects, bool verbose, Keyword? exceptKeywords, ref IEnumerable __result) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) __result = EnumerateDisplayFix(gameRun, keyword, initEffects, verbose, exceptKeywords); return false; } private static IEnumerable EnumerateDisplayFix(GameRunController gameRun, Keyword keyword, IEnumerable initEffects, bool verbose, Keyword? exceptKeywords) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) int counter = 0; HashSet seenTypes = new HashSet(); Keyword traveledKeywords = (Keyword)0; Queue queue = new Queue(); foreach (Keyword k in Keywords.EnumerateComponents(keyword)) { KeywordDisplayWord dw = Keywords.GetDisplayWord(k); if (!dw.IsHidden && (!dw.IsVerbose || verbose)) { queue.Enqueue((IDisplayWord)(object)dw); } } if (initEffects != null) { foreach (string text in initEffects.Distinct()) { if (seenTypes.Add(text)) { StatusEffect se = TypeFactory.CreateInstance(text); if (verbose || !se.Config.IsVerbose) { ((GameEntity)se).GameRun = gameRun; queue.Enqueue((IDisplayWord)(object)se); } } } } while (queue.Count > 0) { int num = counter + 1; counter = num; if (num > 99) { throw new OverflowException("Too many references"); } IDisplayWord front = queue.Dequeue(); KeywordDisplayWord keywordDisplay = (KeywordDisplayWord)(object)((front is KeywordDisplayWord) ? front : null); if (keywordDisplay != null) { if (!exceptKeywords.HasValue || !((Enum)exceptKeywords.Value).HasFlag((Enum)(object)keywordDisplay.Keyword)) { traveledKeywords |= keywordDisplay.Keyword; yield return front; } continue; } StatusEffect se2 = (StatusEffect)(object)((front is StatusEffect) ? front : null); if (se2 == null) { continue; } yield return front; foreach (Keyword subkeyword in Keywords.EnumerateComponents(se2.Config.Keywords)) { if (!((Enum)traveledKeywords).HasFlag((Enum)(object)subkeyword)) { traveledKeywords |= subkeyword; KeywordDisplayWord dw2 = Keywords.GetDisplayWord(subkeyword); if (!dw2.IsHidden && (!dw2.IsVerbose || verbose)) { queue.Enqueue((IDisplayWord)(object)dw2); } } } foreach (string text2 in se2.Config.RelativeEffects) { if (seenTypes.Add(text2)) { StatusEffect seChild = TypeFactory.CreateInstance(text2); if (verbose || !seChild.Config.IsVerbose) { ((GameEntity)seChild).GameRun = gameRun; queue.Enqueue((IDisplayWord)(object)seChild); } } } } } } namespace Extensions.Unity.ImageLoader { public static class ImageLoader { [CompilerGenerated] private sealed class <>c__DisplayClass10_0 { public string url; public UnityWebRequest request; public bool ignoreImageNotFoundError; public bool finished; internal bool b__0() { return IsLoading(url); } internal async void b__1() { try { request = UnityWebRequestTexture.GetTexture(url); UnityWebRequestAsyncOperationAwaiter val = UnityAsyncExtensions.GetAwaiter(request.SendWebRequest()); if (!((UnityWebRequestAsyncOperationAwaiter)(ref val)).IsCompleted) { await val; UnityWebRequestAsyncOperationAwaiter val2 = default(UnityWebRequestAsyncOperationAwaiter); val = val2; } ((UnityWebRequestAsyncOperationAwaiter)(ref val)).GetResult(); } catch (Exception ex) { Exception e = ex; if (!ignoreImageNotFoundError && settings.debugLevel <= DebugLevel.Exception) { Debug.LogException(e); } } finally { finished = true; } } internal bool b__2() { return finished; } } [CompilerGenerated] private sealed class <>c__DisplayClass11_0 { public string url; public Rect? rect; public Vector2? pivot; public int ppu; public SpriteMeshType spriteMeshType; public UnityWebRequest request; public bool ignoreImageNotFoundError; public bool finished; internal bool b__0() { return IsLoading(url); } internal Sprite b__1(Texture2D texture) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) if (!rect.HasValue) { rect = new Rect(0f, 0f, (float)((Texture)texture).width, (float)((Texture)texture).height); } if (!pivot.HasValue) { pivot = new Vector2(0.5f, 0.5f); } return Sprite.Create(texture, rect.Value, pivot.Value, (float)ppu, 0u, spriteMeshType); } internal async void b__2() { try { request = new UnityWebRequest(url); request.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer(); UnityWebRequestAsyncOperationAwaiter val = UnityAsyncExtensions.GetAwaiter(request.SendWebRequest()); if (!((UnityWebRequestAsyncOperationAwaiter)(ref val)).IsCompleted) { await val; UnityWebRequestAsyncOperationAwaiter val2 = default(UnityWebRequestAsyncOperationAwaiter); val = val2; } ((UnityWebRequestAsyncOperationAwaiter)(ref val)).GetResult(); } catch (Exception ex) { Exception e = ex; if (!ignoreImageNotFoundError && settings.debugLevel <= DebugLevel.Exception) { Debug.LogException(e); } } finally { finished = true; } } internal bool b__3() { return finished; } } [CompilerGenerated] private sealed class <>c__DisplayClass30_0 { public Image image; } [CompilerGenerated] private sealed class <>c__DisplayClass30_1 { public Sprite sprite; public <>c__DisplayClass30_0 CS$<>8__locals1; internal void b__0() { if ((Object)(object)CS$<>8__locals1.image == (Object)null || ((UIBehaviour)CS$<>8__locals1.image).IsDestroyed() || object.Equals(((Component)CS$<>8__locals1.image).gameObject, null)) { return; } try { CS$<>8__locals1.image.sprite = sprite; } catch (Exception ex) { if (settings.debugLevel <= DebugLevel.Exception) { Debug.LogException(ex); } } } } [CompilerGenerated] private sealed class <>c__DisplayClass35_0 { public Image[] images; public Sprite sprite; internal void b__0() { for (int i = 0; i < images.Length; i++) { try { if (!((Object)(object)images[i] == (Object)null) && !((UIBehaviour)images[i]).IsDestroyed() && !object.Equals(((Component)images[i]).gameObject, null)) { images[i].sprite = sprite; } } catch (Exception ex) { if (settings.debugLevel <= DebugLevel.Exception) { Debug.LogException(ex); } } } } } [CompilerGenerated] private sealed class <>c__DisplayClass37_0 { public SpriteRenderer spriteRenderer; } [CompilerGenerated] private sealed class <>c__DisplayClass37_1 { public Sprite sprite; public <>c__DisplayClass37_0 CS$<>8__locals1; internal void b__0() { if ((Object)(object)CS$<>8__locals1.spriteRenderer == (Object)null || object.Equals(((Component)CS$<>8__locals1.spriteRenderer).gameObject, null)) { return; } try { CS$<>8__locals1.spriteRenderer.sprite = sprite; } catch (Exception ex) { if (settings.debugLevel <= DebugLevel.Exception) { Debug.LogException(ex); } } } } [CompilerGenerated] private sealed class <>c__DisplayClass42_0 { public SpriteRenderer[] spriteRenderers; public Sprite sprite; internal void b__0() { for (int i = 0; i < spriteRenderers.Length; i++) { try { if (!((Object)(object)spriteRenderers[i] == (Object)null) && !object.Equals(((Component)spriteRenderers[i]).gameObject, null)) { spriteRenderers[i].sprite = sprite; } } catch (Exception ex) { if (settings.debugLevel <= DebugLevel.Exception) { Debug.LogException(ex); } } } } } [CompilerGenerated] private sealed class d__10 : IAsyncStateMachine { public int <>1__state; public AsyncUniTaskMethodBuilder <>t__builder; public string url; public Vector2 pivot; public TextureFormat textureFormat; public bool ignoreImageNotFoundError; private <>c__DisplayClass10_0 <>8__1; private Sprite 5__2; private Sprite <>s__3; private byte[] 5__4; private byte[] <>s__5; private Texture2D 5__6; private Sprite 5__7; private Exception 5__8; private string 5__9; private Texture2D 5__10; private Sprite 5__11; private Awaiter <>u__1; private Awaiter <>u__2; private TaskAwaiter <>u__3; private Awaiter <>u__4; private TaskAwaiter <>u__5; private void MoveNext() { //IL_050f: Unknown result type (might be due to invalid IL or missing references) //IL_0514: Unknown result type (might be due to invalid IL or missing references) //IL_0518: Unknown result type (might be due to invalid IL or missing references) //IL_051d: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_022a: Unknown result type (might be due to invalid IL or missing references) //IL_022f: Unknown result type (might be due to invalid IL or missing references) //IL_0237: Unknown result type (might be due to invalid IL or missing references) //IL_0552: Unknown result type (might be due to invalid IL or missing references) //IL_0557: Unknown result type (might be due to invalid IL or missing references) //IL_055f: Unknown result type (might be due to invalid IL or missing references) //IL_0532: Unknown result type (might be due to invalid IL or missing references) //IL_0534: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_061b: Unknown result type (might be due to invalid IL or missing references) //IL_0670: Unknown result type (might be due to invalid IL or missing references) //IL_0683: Unknown result type (might be due to invalid IL or missing references) //IL_020a: Unknown result type (might be due to invalid IL or missing references) //IL_020c: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_03a8: Unknown result type (might be due to invalid IL or missing references) //IL_03ad: Unknown result type (might be due to invalid IL or missing references) //IL_03b5: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_03d0: Unknown result type (might be due to invalid IL or missing references) //IL_03d6: Unknown result type (might be due to invalid IL or missing references) //IL_03e0: Expected O, but got Unknown //IL_0365: Unknown result type (might be due to invalid IL or missing references) //IL_036a: Unknown result type (might be due to invalid IL or missing references) //IL_036e: Unknown result type (might be due to invalid IL or missing references) //IL_0373: Unknown result type (might be due to invalid IL or missing references) //IL_0424: Unknown result type (might be due to invalid IL or missing references) //IL_042a: Unknown result type (might be due to invalid IL or missing references) //IL_0388: Unknown result type (might be due to invalid IL or missing references) //IL_038a: Unknown result type (might be due to invalid IL or missing references) int num = <>1__state; Sprite result; try { Awaiter val3; Awaiter val2; UniTask val4; Awaiter val; TaskAwaiter taskAwaiter; switch (num) { default: <>8__1 = new <>c__DisplayClass10_0(); <>8__1.url = url; <>8__1.ignoreImageNotFoundError = ignoreImageNotFoundError; if (string.IsNullOrEmpty(<>8__1.url)) { if (settings.debugLevel <= DebugLevel.Error) { Debug.LogError((object)"[ImageLoader] Empty url. Image could not be loaded!"); } result = null; } else { if (!MemoryCacheContains(<>8__1.url)) { goto IL_00fc; } 5__2 = LoadFromMemoryCache(<>8__1.url); if (!((Object)(object)5__2 != (Object)null)) { 5__2 = null; goto IL_00fc; } result = 5__2; } goto end_IL_0007; case 0: val3 = <>u__1; <>u__1 = default(Awaiter); num = (<>1__state = -1); goto IL_01c3; case 1: val2 = <>u__2; <>u__2 = default(Awaiter); num = (<>1__state = -1); goto IL_0246; case 2: case 3: try { Awaiter val5; TaskAwaiter taskAwaiter2; if (num != 2) { if (num == 3) { val5 = <>u__4; <>u__4 = default(Awaiter); num = (<>1__state = -1); goto IL_03c4; } taskAwaiter2 = LoadDiskAsync(<>8__1.url).GetAwaiter(); if (!taskAwaiter2.IsCompleted) { num = (<>1__state = 2); <>u__3 = taskAwaiter2; d__10 d__ = this; <>t__builder.AwaitUnsafeOnCompleted, d__10>(ref taskAwaiter2, ref d__); return; } } else { taskAwaiter2 = <>u__3; <>u__3 = default(TaskAwaiter); num = (<>1__state = -1); } <>s__5 = taskAwaiter2.GetResult(); 5__4 = <>s__5; <>s__5 = null; if (5__4 != null && 5__4.Length != 0) { SwitchToMainThreadAwaitable val6 = UniTask.SwitchToMainThread(default(CancellationToken)); val5 = ((SwitchToMainThreadAwaitable)(ref val6)).GetAwaiter(); if (!((Awaiter)(ref val5)).IsCompleted) { num = (<>1__state = 3); <>u__4 = val5; d__10 d__ = this; <>t__builder.AwaitUnsafeOnCompletedd__10>(ref val5, ref d__); return; } goto IL_03c4; } goto IL_0488; IL_0488: 5__4 = null; goto end_IL_02a2; IL_03c4: ((Awaiter)(ref val5)).GetResult(); 5__6 = new Texture2D(2, 2, textureFormat, true); if (!ImageConversion.LoadImage(5__6, 5__4)) { 5__6 = null; goto IL_0488; } 5__7 = Sprite.Create(5__6, new Rect(0f, 0f, (float)((Texture)5__6).width, (float)((Texture)5__6).height), pivot); if ((Object)(object)5__7 != (Object)null) { SaveToMemoryCache(<>8__1.url, 5__7, replace: true); } RemoveLoading(<>8__1.url); result = 5__7; goto end_IL_0007; end_IL_02a2:; } catch (Exception ex) { 5__8 = ex; if (settings.debugLevel <= DebugLevel.Exception) { Debug.LogException(5__8); } } <>8__1.request = null; <>8__1.finished = false; UniTask.Post((Action)async delegate { try { <>8__1.request = UnityWebRequestTexture.GetTexture(<>8__1.url); UnityWebRequestAsyncOperationAwaiter val7 = UnityAsyncExtensions.GetAwaiter(<>8__1.request.SendWebRequest()); if (!((UnityWebRequestAsyncOperationAwaiter)(ref val7)).IsCompleted) { await val7; UnityWebRequestAsyncOperationAwaiter val8 = default(UnityWebRequestAsyncOperationAwaiter); val7 = val8; } ((UnityWebRequestAsyncOperationAwaiter)(ref val7)).GetResult(); } catch (Exception ex2) { Exception e = ex2; if (!<>8__1.ignoreImageNotFoundError && settings.debugLevel <= DebugLevel.Exception) { Debug.LogException(e); } } finally { <>8__1.finished = true; } }, (PlayerLoopTiming)8); val4 = UniTask.WaitUntil((Func)(() => <>8__1.finished), (PlayerLoopTiming)8, default(CancellationToken), false); val = ((UniTask)(ref val4)).GetAwaiter(); if (!((Awaiter)(ref val)).IsCompleted) { num = (<>1__state = 4); <>u__1 = val; d__10 d__ = this; <>t__builder.AwaitUnsafeOnCompletedd__10>(ref val, ref d__); return; } goto IL_056e; case 4: val = <>u__1; <>u__1 = default(Awaiter); num = (<>1__state = -1); goto IL_056e; case 5: { taskAwaiter = <>u__5; <>u__5 = default(TaskAwaiter); num = (<>1__state = -1); break; } IL_0246: <>s__3 = val2.GetResult(); result = <>s__3; goto end_IL_0007; IL_01c3: ((Awaiter)(ref val3)).GetResult(); val2 = LoadSprite(<>8__1.url, textureFormat, <>8__1.ignoreImageNotFoundError).GetAwaiter(); if (!val2.IsCompleted) { num = (<>1__state = 1); <>u__2 = val2; d__10 d__ = this; <>t__builder.AwaitUnsafeOnCompleted, d__10>(ref val2, ref d__); return; } goto IL_0246; IL_00fc: if (IsLoading(<>8__1.url)) { if (settings.debugLevel <= DebugLevel.Log) { Debug.Log((object)("[ImageLoader] Waiting while another task is loading the sprite url=" + <>8__1.url)); } val4 = UniTask.WaitWhile((Func)(() => IsLoading(<>8__1.url)), (PlayerLoopTiming)8, default(CancellationToken), false); val3 = ((UniTask)(ref val4)).GetAwaiter(); if (!((Awaiter)(ref val3)).IsCompleted) { num = (<>1__state = 0); <>u__1 = val3; d__10 d__ = this; <>t__builder.AwaitUnsafeOnCompletedd__10>(ref val3, ref d__); return; } goto IL_01c3; } AddLoading(<>8__1.url); if (settings.debugLevel <= DebugLevel.Log) { Debug.Log((object)("[ImageLoader] Loading new Sprite into memory url=" + <>8__1.url)); } goto case 2; IL_056e: ((Awaiter)(ref val)).GetResult(); RemoveLoading(<>8__1.url); if (string.IsNullOrEmpty(<>8__1.request.error)) { 5__9 = Path.GetFileNameWithoutExtension(<>8__1.url); 5__10 = ((DownloadHandlerTexture)<>8__1.request.downloadHandler).texture; Debug.Log((object)$"LoadSprite: name={5__9}, size={Utils.ToSize(5__10.GetRawTextureData().Length)}, mipmap={((Texture)5__10).mipmapCount}, format={5__10.format}, graphicsFormat={((Texture)5__10).graphicsFormat}, size={((Texture)5__10).width}x{((Texture)5__10).height}"); 5__11 = ToSprite(5__10); taskAwaiter = SaveDiskAsync(<>8__1.url, <>8__1.request.downloadHandler.data).GetAwaiter(); if (!taskAwaiter.IsCompleted) { num = (<>1__state = 5); <>u__5 = taskAwaiter; d__10 d__ = this; <>t__builder.AwaitUnsafeOnCompletedd__10>(ref taskAwaiter, ref d__); return; } break; } if (settings.debugLevel <= DebugLevel.Error) { Debug.LogError((object)("[ImageLoader] " + <>8__1.request.error + ": url=" + <>8__1.url)); } result = null; goto end_IL_0007; } taskAwaiter.GetResult(); SaveToMemoryCache(<>8__1.url, 5__11, replace: true); result = 5__11; end_IL_0007:; } catch (Exception ex) { <>1__state = -2; <>8__1 = null; <>t__builder.SetException(ex); return; } <>1__state = -2; <>8__1 = null; <>t__builder.SetResult(result); } void IAsyncStateMachine.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext this.MoveNext(); } [DebuggerHidden] private void SetStateMachine(IAsyncStateMachine stateMachine) { } void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine stateMachine) { //ILSpy generated this explicit interface implementation from .override directive in SetStateMachine this.SetStateMachine(stateMachine); } } [CompilerGenerated] private sealed class d__11 : IAsyncStateMachine { public int <>1__state; public AsyncUniTaskMethodBuilder <>t__builder; public string url; public int ppu; public GraphicsFormat finalGraphicsFormat; public int anisoLevel; public FilterMode filterMode; public SpriteMeshType spriteMeshType; public Vector2? pivot; public Rect? rect; public TextureFormat textureFormat; public bool ignoreImageNotFoundError; private <>c__DisplayClass11_0 <>8__1; private Func 5__2; private Sprite 5__3; private Sprite <>s__4; private byte[] 5__5; private byte[] <>s__6; private Texture2D 5__7; private Sprite 5__8; private Exception 5__9; private string 5__10; private Texture2D 5__11; private Sprite 5__12; private Awaiter <>u__1; private Awaiter <>u__2; private TaskAwaiter <>u__3; private Awaiter <>u__4; private TaskAwaiter <>u__5; private void MoveNext() { //IL_0540: Unknown result type (might be due to invalid IL or missing references) //IL_0545: Unknown result type (might be due to invalid IL or missing references) //IL_0549: Unknown result type (might be due to invalid IL or missing references) //IL_054e: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_026e: Unknown result type (might be due to invalid IL or missing references) //IL_0273: Unknown result type (might be due to invalid IL or missing references) //IL_027b: Unknown result type (might be due to invalid IL or missing references) //IL_0583: Unknown result type (might be due to invalid IL or missing references) //IL_0588: Unknown result type (might be due to invalid IL or missing references) //IL_0590: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_0563: Unknown result type (might be due to invalid IL or missing references) //IL_0565: Unknown result type (might be due to invalid IL or missing references) //IL_021b: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Unknown result type (might be due to invalid IL or missing references) //IL_0230: Unknown result type (might be due to invalid IL or missing references) //IL_0234: Unknown result type (might be due to invalid IL or missing references) //IL_0239: Unknown result type (might be due to invalid IL or missing references) //IL_0653: Unknown result type (might be due to invalid IL or missing references) //IL_065f: Unknown result type (might be due to invalid IL or missing references) //IL_024e: Unknown result type (might be due to invalid IL or missing references) //IL_0250: Unknown result type (might be due to invalid IL or missing references) //IL_06c8: Unknown result type (might be due to invalid IL or missing references) //IL_06db: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_0403: Unknown result type (might be due to invalid IL or missing references) //IL_0408: Unknown result type (might be due to invalid IL or missing references) //IL_0410: Unknown result type (might be due to invalid IL or missing references) //IL_01cb: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_042b: Unknown result type (might be due to invalid IL or missing references) //IL_0431: Unknown result type (might be due to invalid IL or missing references) //IL_043b: Expected O, but got Unknown //IL_03c0: Unknown result type (might be due to invalid IL or missing references) //IL_03c5: Unknown result type (might be due to invalid IL or missing references) //IL_03c9: Unknown result type (might be due to invalid IL or missing references) //IL_03ce: Unknown result type (might be due to invalid IL or missing references) //IL_03e3: Unknown result type (might be due to invalid IL or missing references) //IL_03e5: Unknown result type (might be due to invalid IL or missing references) int num = <>1__state; Sprite result; try { Awaiter val3; Awaiter val2; UniTask val4; Awaiter val; TaskAwaiter taskAwaiter; switch (num) { default: <>8__1 = new <>c__DisplayClass11_0(); <>8__1.url = url; <>8__1.rect = rect; <>8__1.pivot = pivot; <>8__1.ppu = ppu; <>8__1.spriteMeshType = spriteMeshType; <>8__1.ignoreImageNotFoundError = ignoreImageNotFoundError; if (string.IsNullOrEmpty(<>8__1.url)) { if (settings.debugLevel <= DebugLevel.Error) { Debug.LogError((object)"[ImageLoader] Empty url. Image could not be loaded!"); } result = null; } else { if (!MemoryCacheContains(<>8__1.url)) { goto IL_0140; } 5__3 = LoadFromMemoryCache(<>8__1.url); if (!((Object)(object)5__3 != (Object)null)) { 5__3 = null; goto IL_0140; } result = 5__3; } goto end_IL_0007; case 0: val3 = <>u__1; <>u__1 = default(Awaiter); num = (<>1__state = -1); goto IL_0207; case 1: val2 = <>u__2; <>u__2 = default(Awaiter); num = (<>1__state = -1); goto IL_028a; case 2: case 3: try { Awaiter val5; TaskAwaiter taskAwaiter2; if (num != 2) { if (num == 3) { val5 = <>u__4; <>u__4 = default(Awaiter); num = (<>1__state = -1); goto IL_041f; } taskAwaiter2 = LoadDiskAsync(<>8__1.url).GetAwaiter(); if (!taskAwaiter2.IsCompleted) { num = (<>1__state = 2); <>u__3 = taskAwaiter2; d__11 d__ = this; <>t__builder.AwaitUnsafeOnCompleted, d__11>(ref taskAwaiter2, ref d__); return; } } else { taskAwaiter2 = <>u__3; <>u__3 = default(TaskAwaiter); num = (<>1__state = -1); } <>s__6 = taskAwaiter2.GetResult(); 5__5 = <>s__6; <>s__6 = null; if (5__5 != null && 5__5.Length != 0) { SwitchToMainThreadAwaitable val6 = UniTask.SwitchToMainThread(default(CancellationToken)); val5 = ((SwitchToMainThreadAwaitable)(ref val6)).GetAwaiter(); if (!((Awaiter)(ref val5)).IsCompleted) { num = (<>1__state = 3); <>u__4 = val5; d__11 d__ = this; <>t__builder.AwaitUnsafeOnCompletedd__11>(ref val5, ref d__); return; } goto IL_041f; } goto IL_04b9; IL_04b9: 5__5 = null; goto end_IL_02fd; IL_041f: ((Awaiter)(ref val5)).GetResult(); 5__7 = new Texture2D(2, 2, textureFormat, true); if (!ImageConversion.LoadImage(5__7, 5__5)) { 5__7 = null; goto IL_04b9; } 5__8 = 5__2(5__7); if ((Object)(object)5__8 != (Object)null) { SaveToMemoryCache(<>8__1.url, 5__8, replace: true); } RemoveLoading(<>8__1.url); result = 5__8; goto end_IL_0007; end_IL_02fd:; } catch (Exception ex) { 5__9 = ex; if (settings.debugLevel <= DebugLevel.Exception) { Debug.LogException(5__9); } } <>8__1.request = null; <>8__1.finished = false; UniTask.Post((Action)async delegate { try { <>8__1.request = new UnityWebRequest(<>8__1.url); <>8__1.request.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer(); UnityWebRequestAsyncOperationAwaiter val7 = UnityAsyncExtensions.GetAwaiter(<>8__1.request.SendWebRequest()); if (!((UnityWebRequestAsyncOperationAwaiter)(ref val7)).IsCompleted) { await val7; UnityWebRequestAsyncOperationAwaiter val8 = default(UnityWebRequestAsyncOperationAwaiter); val7 = val8; } ((UnityWebRequestAsyncOperationAwaiter)(ref val7)).GetResult(); } catch (Exception ex2) { Exception e = ex2; if (!<>8__1.ignoreImageNotFoundError && settings.debugLevel <= DebugLevel.Exception) { Debug.LogException(e); } } finally { <>8__1.finished = true; } }, (PlayerLoopTiming)8); val4 = UniTask.WaitUntil((Func)(() => <>8__1.finished), (PlayerLoopTiming)8, default(CancellationToken), false); val = ((UniTask)(ref val4)).GetAwaiter(); if (!((Awaiter)(ref val)).IsCompleted) { num = (<>1__state = 4); <>u__1 = val; d__11 d__ = this; <>t__builder.AwaitUnsafeOnCompletedd__11>(ref val, ref d__); return; } goto IL_059f; case 4: val = <>u__1; <>u__1 = default(Awaiter); num = (<>1__state = -1); goto IL_059f; case 5: { taskAwaiter = <>u__5; <>u__5 = default(TaskAwaiter); num = (<>1__state = -1); break; } IL_028a: <>s__4 = val2.GetResult(); result = <>s__4; goto end_IL_0007; IL_0207: ((Awaiter)(ref val3)).GetResult(); val2 = LoadSprite(<>8__1.url, textureFormat, <>8__1.ignoreImageNotFoundError).GetAwaiter(); if (!val2.IsCompleted) { num = (<>1__state = 1); <>u__2 = val2; d__11 d__ = this; <>t__builder.AwaitUnsafeOnCompleted, d__11>(ref val2, ref d__); return; } goto IL_028a; IL_0140: if (IsLoading(<>8__1.url)) { if (settings.debugLevel <= DebugLevel.Log) { Debug.Log((object)("[ImageLoader] Waiting while another task is loading the sprite url=" + <>8__1.url)); } val4 = UniTask.WaitWhile((Func)(() => IsLoading(<>8__1.url)), (PlayerLoopTiming)8, default(CancellationToken), false); val3 = ((UniTask)(ref val4)).GetAwaiter(); if (!((Awaiter)(ref val3)).IsCompleted) { num = (<>1__state = 0); <>u__1 = val3; d__11 d__ = this; <>t__builder.AwaitUnsafeOnCompletedd__11>(ref val3, ref d__); return; } goto IL_0207; } AddLoading(<>8__1.url); 5__2 = delegate(Texture2D texture) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) if (!<>8__1.rect.HasValue) { <>8__1.rect = new Rect(0f, 0f, (float)((Texture)texture).width, (float)((Texture)texture).height); } if (!<>8__1.pivot.HasValue) { <>8__1.pivot = new Vector2(0.5f, 0.5f); } return Sprite.Create(texture, <>8__1.rect.Value, <>8__1.pivot.Value, (float)<>8__1.ppu, 0u, <>8__1.spriteMeshType); }; if (settings.debugLevel <= DebugLevel.Log) { Debug.Log((object)("[ImageLoader] Loading new Sprite into memory url=" + <>8__1.url)); } goto case 2; IL_059f: ((Awaiter)(ref val)).GetResult(); RemoveLoading(<>8__1.url); if (string.IsNullOrEmpty(<>8__1.request.error)) { 5__10 = Path.GetFileNameWithoutExtension(<>8__1.url); 5__11 = Utils.CreateTexWithMipmaps(<>8__1.request.downloadHandler.data, shouldGenerateMipMaps: true, finalGraphicsFormat, anisoLevel, filterMode, 5__10); ManualLogSource obj = Log.LogDevExtra(); if (obj != null) { obj.LogInfo((object)$"LoadSpriteMemoryOptimized: name={5__10}, size={Utils.ToSize(5__11.GetRawTextureData().Length)}, mipmap={((Texture)5__11).mipmapCount}, format={5__11.format}, graphicsFormat={((Texture)5__11).graphicsFormat}, size={((Texture)5__11).width}x{((Texture)5__11).height}"); } 5__12 = 5__2(5__11); taskAwaiter = SaveDiskAsync(<>8__1.url, <>8__1.request.downloadHandler.data).GetAwaiter(); if (!taskAwaiter.IsCompleted) { num = (<>1__state = 5); <>u__5 = taskAwaiter; d__11 d__ = this; <>t__builder.AwaitUnsafeOnCompletedd__11>(ref taskAwaiter, ref d__); return; } break; } if (settings.debugLevel <= DebugLevel.Error) { Debug.LogError((object)("[ImageLoader] " + <>8__1.request.error + ": url=" + <>8__1.url)); } result = null; goto end_IL_0007; } taskAwaiter.GetResult(); SaveToMemoryCache(<>8__1.url, 5__12, replace: true); result = 5__12; end_IL_0007:; } catch (Exception ex) { <>1__state = -2; <>8__1 = null; 5__2 = null; <>t__builder.SetException(ex); return; } <>1__state = -2; <>8__1 = null; 5__2 = null; <>t__builder.SetResult(result); } void IAsyncStateMachine.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext this.MoveNext(); } [DebuggerHidden] private void SetStateMachine(IAsyncStateMachine stateMachine) { } void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine stateMachine) { //ILSpy generated this explicit interface implementation from .override directive in SetStateMachine this.SetStateMachine(stateMachine); } } [CompilerGenerated] private sealed class d__30 : IAsyncStateMachine { public int <>1__state; public AsyncUniTaskMethodBuilder <>t__builder; public string url; public Image image; public Vector2 pivot; public TextureFormat textureFormat; public bool ignoreImageNotFoundError; private <>c__DisplayClass30_0 <>8__1; private <>c__DisplayClass30_1 <>8__2; private Sprite <>s__3; private Exception 5__4; private Awaiter <>u__1; private void MoveNext() { //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) int num = <>1__state; try { if (num != 0) { <>8__1 = new <>c__DisplayClass30_0(); <>8__1.image = image; } try { Awaiter val; if (num == 0) { val = <>u__1; <>u__1 = default(Awaiter); num = (<>1__state = -1); goto IL_011c; } <>8__2 = new <>c__DisplayClass30_1(); <>8__2.CS$<>8__locals1 = <>8__1; if (!((Object)(object)<>8__2.CS$<>8__locals1.image == (Object)null) && !((UIBehaviour)<>8__2.CS$<>8__locals1.image).IsDestroyed() && !((Object)(object)((Component)<>8__2.CS$<>8__locals1.image).gameObject == (Object)null)) { val = LoadSprite(url, pivot, textureFormat, ignoreImageNotFoundError).GetAwaiter(); if (!val.IsCompleted) { num = (<>1__state = 0); <>u__1 = val; d__30 d__ = this; ((AsyncUniTaskMethodBuilder)(ref <>t__builder)).AwaitUnsafeOnCompleted, d__30>(ref val, ref d__); return; } goto IL_011c; } goto end_IL_002c; IL_011c: <>s__3 = val.GetResult(); <>8__2.sprite = <>s__3; <>s__3 = null; UniTask.Post((Action)delegate { if ((Object)(object)<>8__2.CS$<>8__locals1.image == (Object)null || ((UIBehaviour)<>8__2.CS$<>8__locals1.image).IsDestroyed() || object.Equals(((Component)<>8__2.CS$<>8__locals1.image).gameObject, null)) { return; } try { <>8__2.CS$<>8__locals1.image.sprite = <>8__2.sprite; } catch (Exception ex2) { if (settings.debugLevel <= DebugLevel.Exception) { Debug.LogException(ex2); } } }, (PlayerLoopTiming)8); <>8__2 = null; end_IL_002c:; } catch (Exception ex) { 5__4 = ex; if (settings.debugLevel <= DebugLevel.Exception) { Debug.LogException(5__4); } } } catch (Exception ex) { <>1__state = -2; <>8__1 = null; ((AsyncUniTaskMethodBuilder)(ref <>t__builder)).SetException(ex); return; } <>1__state = -2; <>8__1 = null; ((AsyncUniTaskMethodBuilder)(ref <>t__builder)).SetResult(); } void IAsyncStateMachine.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext this.MoveNext(); } [DebuggerHidden] private void SetStateMachine(IAsyncStateMachine stateMachine) { } void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine stateMachine) { //ILSpy generated this explicit interface implementation from .override directive in SetStateMachine this.SetStateMachine(stateMachine); } } [CompilerGenerated] private sealed class d__35 : IAsyncStateMachine { public int <>1__state; public AsyncUniTaskMethodBuilder <>t__builder; public string url; public Vector2 pivot; public TextureFormat textureFormat; public bool ignoreImageNotFoundError; public Image[] images; private <>c__DisplayClass35_0 <>8__1; private Sprite <>s__2; private Awaiter <>u__1; private void MoveNext() { //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) int num = <>1__state; try { Awaiter val; if (num == 0) { val = <>u__1; <>u__1 = default(Awaiter); num = (<>1__state = -1); goto IL_00b8; } <>8__1 = new <>c__DisplayClass35_0(); <>8__1.images = images; if (<>8__1.images != null) { val = LoadSprite(url, pivot, textureFormat, ignoreImageNotFoundError).GetAwaiter(); if (!val.IsCompleted) { num = (<>1__state = 0); <>u__1 = val; d__35 d__ = this; ((AsyncUniTaskMethodBuilder)(ref <>t__builder)).AwaitUnsafeOnCompleted, d__35>(ref val, ref d__); return; } goto IL_00b8; } goto end_IL_0007; IL_00b8: <>s__2 = val.GetResult(); <>8__1.sprite = <>s__2; <>s__2 = null; UniTask.Post((Action)delegate { for (int i = 0; i < <>8__1.images.Length; i++) { try { if (!((Object)(object)<>8__1.images[i] == (Object)null) && !((UIBehaviour)<>8__1.images[i]).IsDestroyed() && !object.Equals(((Component)<>8__1.images[i]).gameObject, null)) { <>8__1.images[i].sprite = <>8__1.sprite; } } catch (Exception ex) { if (settings.debugLevel <= DebugLevel.Exception) { Debug.LogException(ex); } } } }, (PlayerLoopTiming)8); end_IL_0007:; } catch (Exception exception) { <>1__state = -2; <>8__1 = null; ((AsyncUniTaskMethodBuilder)(ref <>t__builder)).SetException(exception); return; } <>1__state = -2; <>8__1 = null; ((AsyncUniTaskMethodBuilder)(ref <>t__builder)).SetResult(); } void IAsyncStateMachine.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext this.MoveNext(); } [DebuggerHidden] private void SetStateMachine(IAsyncStateMachine stateMachine) { } void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine stateMachine) { //ILSpy generated this explicit interface implementation from .override directive in SetStateMachine this.SetStateMachine(stateMachine); } } [CompilerGenerated] private sealed class d__37 : IAsyncStateMachine { public int <>1__state; public AsyncUniTaskMethodBuilder <>t__builder; public string url; public SpriteRenderer spriteRenderer; public Vector2 pivot; public TextureFormat textureFormat; public bool ignoreImageNotFoundError; private <>c__DisplayClass37_0 <>8__1; private <>c__DisplayClass37_1 <>8__2; private Sprite <>s__3; private Exception 5__4; private Awaiter <>u__1; private void MoveNext() { //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) int num = <>1__state; try { if (num != 0) { <>8__1 = new <>c__DisplayClass37_0(); <>8__1.spriteRenderer = spriteRenderer; } try { Awaiter val; if (num == 0) { val = <>u__1; <>u__1 = default(Awaiter); num = (<>1__state = -1); goto IL_0105; } <>8__2 = new <>c__DisplayClass37_1(); <>8__2.CS$<>8__locals1 = <>8__1; if (!((Object)(object)<>8__2.CS$<>8__locals1.spriteRenderer == (Object)null) && !((Object)(object)((Component)<>8__2.CS$<>8__locals1.spriteRenderer).gameObject == (Object)null)) { val = LoadSprite(url, pivot, textureFormat, ignoreImageNotFoundError).GetAwaiter(); if (!val.IsCompleted) { num = (<>1__state = 0); <>u__1 = val; d__37 d__ = this; ((AsyncUniTaskMethodBuilder)(ref <>t__builder)).AwaitUnsafeOnCompleted, d__37>(ref val, ref d__); return; } goto IL_0105; } goto end_IL_002c; IL_0105: <>s__3 = val.GetResult(); <>8__2.sprite = <>s__3; <>s__3 = null; UniTask.Post((Action)delegate { if ((Object)(object)<>8__2.CS$<>8__locals1.spriteRenderer == (Object)null || object.Equals(((Component)<>8__2.CS$<>8__locals1.spriteRenderer).gameObject, null)) { return; } try { <>8__2.CS$<>8__locals1.spriteRenderer.sprite = <>8__2.sprite; } catch (Exception ex2) { if (settings.debugLevel <= DebugLevel.Exception) { Debug.LogException(ex2); } } }, (PlayerLoopTiming)8); <>8__2 = null; end_IL_002c:; } catch (Exception ex) { 5__4 = ex; if (settings.debugLevel <= DebugLevel.Exception) { Debug.LogException(5__4); } } } catch (Exception ex) { <>1__state = -2; <>8__1 = null; ((AsyncUniTaskMethodBuilder)(ref <>t__builder)).SetException(ex); return; } <>1__state = -2; <>8__1 = null; ((AsyncUniTaskMethodBuilder)(ref <>t__builder)).SetResult(); } void IAsyncStateMachine.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext this.MoveNext(); } [DebuggerHidden] private void SetStateMachine(IAsyncStateMachine stateMachine) { } void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine stateMachine) { //ILSpy generated this explicit interface implementation from .override directive in SetStateMachine this.SetStateMachine(stateMachine); } } [CompilerGenerated] private sealed class d__42 : IAsyncStateMachine { public int <>1__state; public AsyncUniTaskMethodBuilder <>t__builder; public string url; public Vector2 pivot; public TextureFormat textureFormat; public bool ignoreImageNotFoundError; public SpriteRenderer[] spriteRenderers; private <>c__DisplayClass42_0 <>8__1; private Sprite <>s__2; private Awaiter <>u__1; private void MoveNext() { //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) int num = <>1__state; try { Awaiter val; if (num == 0) { val = <>u__1; <>u__1 = default(Awaiter); num = (<>1__state = -1); goto IL_00b8; } <>8__1 = new <>c__DisplayClass42_0(); <>8__1.spriteRenderers = spriteRenderers; if (<>8__1.spriteRenderers != null) { val = LoadSprite(url, pivot, textureFormat, ignoreImageNotFoundError).GetAwaiter(); if (!val.IsCompleted) { num = (<>1__state = 0); <>u__1 = val; d__42 d__ = this; ((AsyncUniTaskMethodBuilder)(ref <>t__builder)).AwaitUnsafeOnCompleted, d__42>(ref val, ref d__); return; } goto IL_00b8; } goto end_IL_0007; IL_00b8: <>s__2 = val.GetResult(); <>8__1.sprite = <>s__2; <>s__2 = null; UniTask.Post((Action)delegate { for (int i = 0; i < <>8__1.spriteRenderers.Length; i++) { try { if (!((Object)(object)<>8__1.spriteRenderers[i] == (Object)null) && !object.Equals(((Component)<>8__1.spriteRenderers[i]).gameObject, null)) { <>8__1.spriteRenderers[i].sprite = <>8__1.sprite; } } catch (Exception ex) { if (settings.debugLevel <= DebugLevel.Exception) { Debug.LogException(ex); } } } }, (PlayerLoopTiming)8); end_IL_0007:; } catch (Exception exception) { <>1__state = -2; <>8__1 = null; ((AsyncUniTaskMethodBuilder)(ref <>t__builder)).SetException(exception); return; } <>1__state = -2; <>8__1 = null; ((AsyncUniTaskMethodBuilder)(ref <>t__builder)).SetResult(); } void IAsyncStateMachine.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext this.MoveNext(); } [DebuggerHidden] private void SetStateMachine(IAsyncStateMachine stateMachine) { } void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine stateMachine) { //ILSpy generated this explicit interface implementation from .override directive in SetStateMachine this.SetStateMachine(stateMachine); } } private static HashSet loadingInProcess = new HashSet(); internal static readonly TaskFactory diskTaskFactory = new TaskFactory(new LimitedConcurrencyLevelTaskScheduler(1)); internal static Dictionary memorySpriteCache = new Dictionary(); public static readonly Settings settings = new Settings(); private static void AddLoading(string url) { loadingInProcess.Add(url); } private static void RemoveLoading(string url) { loadingInProcess.Remove(url); } public static void Init() { string text = settings.diskSaveLocation + settings.diskSaveLocation; } public static bool IsLoading(string url) { return loadingInProcess.Contains(url); } public static Task ClearCache() { ClearMemoryCache(); return ClearDiskCache(); } public static bool CacheContains(string url) { return MemoryCacheContains(url) || DiskCacheContains(url); } public static Sprite ToSprite(Texture2D texture, float pixelDensity = 100f) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) return Sprite.Create(texture, new Rect(0f, 0f, (float)((Texture)texture).width, (float)((Texture)texture).height), new Vector2(0.5f, 0.5f), pixelDensity); } public static Sprite ToSprite(Texture2D texture, Vector2 pivot, float pixelDensity = 100f) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) return Sprite.Create(texture, new Rect(0f, 0f, (float)((Texture)texture).width, (float)((Texture)texture).height), pivot, pixelDensity); } internal static UniTask LoadSprite(string url, TextureFormat textureFormat = (TextureFormat)5, bool ignoreImageNotFoundError = false) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) return LoadSprite(url, Vector2.one * 0.5f, textureFormat, ignoreImageNotFoundError); } [AsyncStateMachine(typeof(d__10))] [DebuggerStepThrough] internal static UniTask LoadSprite(string url, Vector2 pivot, TextureFormat textureFormat = (TextureFormat)5, bool ignoreImageNotFoundError = false) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) d__10 d__ = new d__10(); d__.<>t__builder = AsyncUniTaskMethodBuilder.Create(); d__.url = url; d__.pivot = pivot; d__.textureFormat = textureFormat; d__.ignoreImageNotFoundError = ignoreImageNotFoundError; d__.<>1__state = -1; d__.<>t__builder.Start<d__10>(ref d__); return d__.<>t__builder.Task; } [AsyncStateMachine(typeof(d__11))] [DebuggerStepThrough] internal static UniTask LoadSpriteMemoryOptimized(string url, int ppu = 100, GraphicsFormat finalGraphicsFormat = (GraphicsFormat)4, int anisoLevel = 1, FilterMode filterMode = (FilterMode)1, SpriteMeshType spriteMeshType = (SpriteMeshType)1, Vector2? pivot = null, Rect? rect = null, TextureFormat textureFormat = (TextureFormat)5, bool ignoreImageNotFoundError = false) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) d__11 d__ = new d__11(); d__.<>t__builder = AsyncUniTaskMethodBuilder.Create(); d__.url = url; d__.ppu = ppu; d__.finalGraphicsFormat = finalGraphicsFormat; d__.anisoLevel = anisoLevel; d__.filterMode = filterMode; d__.spriteMeshType = spriteMeshType; d__.pivot = pivot; d__.rect = rect; d__.textureFormat = textureFormat; d__.ignoreImageNotFoundError = ignoreImageNotFoundError; d__.<>1__state = -1; d__.<>t__builder.Start<d__11>(ref d__); return d__.<>t__builder.Task; } private static string DiskCachePath(string url) { return $"{settings.diskSaveLocation}/I_{url.GetHashCode()}"; } private static void SaveDisk(string url, byte[] data) { if (settings.useDiskCache) { Directory.CreateDirectory(settings.diskSaveLocation); Directory.CreateDirectory(Path.GetDirectoryName(DiskCachePath(url))); File.WriteAllBytes(DiskCachePath(url), data); } } private static byte[] LoadDisk(string url) { if (!settings.useDiskCache) { return null; } Directory.CreateDirectory(settings.diskSaveLocation); Directory.CreateDirectory(Path.GetDirectoryName(DiskCachePath(url))); if (!DiskCacheContains(url)) { return null; } return File.ReadAllBytes(DiskCachePath(url)); } private static Task SaveDiskAsync(string url, byte[] data) { if (!settings.useDiskCache) { return Task.CompletedTask; } return diskTaskFactory.StartNew(delegate { SaveDisk(url, data); }); } private static Task LoadDiskAsync(string url) { if (!settings.useDiskCache) { return Task.FromResult(null); } return diskTaskFactory.StartNew(() => LoadDisk(url)); } public static bool DiskCacheContains(string url) { return File.Exists(DiskCachePath(url)); } public static Task DiskCacheExistsAsync(string url) { string path = DiskCachePath(url); return diskTaskFactory.StartNew(() => File.Exists(path)); } public static Task ClearDiskCache() { return diskTaskFactory.StartNew(delegate { if (Directory.Exists(settings.diskSaveLocation)) { Directory.Delete(settings.diskSaveLocation, recursive: true); } }); } public static Task ClearDiskCache(string url) { string diskPath = DiskCachePath(url); return diskTaskFactory.StartNew(delegate { if (File.Exists(diskPath)) { File.Delete(diskPath); } }); } public static bool MemoryCacheContains(string url) { return memorySpriteCache.ContainsKey(url); } public static void SaveToMemoryCache(string url, Sprite sprite, bool replace = false) { if (!settings.useMemoryCache) { return; } if (!replace && memorySpriteCache.ContainsKey(url)) { if (settings.debugLevel <= DebugLevel.Warning) { Debug.LogError((object)("[ImageLoader] Memory cache already contains key: " + url)); } } else { memorySpriteCache[url] = sprite; } } public static Sprite LoadFromMemoryCache(string url) { if (!settings.useMemoryCache) { return null; } return GetValueOrDefault(url); } public static void ClearMemoryCache(string url) { Sprite valueOrDefault = GetValueOrDefault(url); if ((Object)(object)((valueOrDefault != null) ? valueOrDefault.texture : null) != (Object)null) { Object.DestroyImmediate((Object)(object)valueOrDefault.texture); } memorySpriteCache.Remove(url); } public static void ClearMemoryCache() { foreach (Sprite value in memorySpriteCache.Values) { if ((Object)(object)((value != null) ? value.texture : null) != (Object)null) { Object.DestroyImmediate((Object)(object)value.texture); } } memorySpriteCache.Clear(); } private static Sprite GetValueOrDefault(string url) { if (memorySpriteCache.TryGetValue(url, out var value)) { return value; } return null; } public static UniTask SetSprite(string url, Image image, TextureFormat textureFormat = (TextureFormat)5, bool ignoreImageNotFoundError = false) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) return SetSprite(url, image, Vector2.one * 0.5f, textureFormat, ignoreImageNotFoundError); } [AsyncStateMachine(typeof(d__30))] [DebuggerStepThrough] public static UniTask SetSprite(string url, Image image, Vector2 pivot, TextureFormat textureFormat = (TextureFormat)5, bool ignoreImageNotFoundError = false) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) d__30 d__ = new d__30(); d__.<>t__builder = AsyncUniTaskMethodBuilder.Create(); d__.url = url; d__.image = image; d__.pivot = pivot; d__.textureFormat = textureFormat; d__.ignoreImageNotFoundError = ignoreImageNotFoundError; d__.<>1__state = -1; ((AsyncUniTaskMethodBuilder)(ref d__.<>t__builder)).Start<d__30>(ref d__); return ((AsyncUniTaskMethodBuilder)(ref d__.<>t__builder)).Task; } public static UniTask SetSprite(string url, params Image[] images) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) return SetSprite(url, Vector2.one * 0.5f, (TextureFormat)5, ignoreImageNotFoundError: false, images); } public static UniTask SetSprite(string url, TextureFormat textureFormat, params Image[] images) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) return SetSprite(url, Vector2.one * 0.5f, textureFormat, ignoreImageNotFoundError: false, images); } public static UniTask SetSprite(string url, bool ignoreImageNotFoundError, params Image[] images) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) return SetSprite(url, Vector2.one * 0.5f, (TextureFormat)5, ignoreImageNotFoundError, images); } public static UniTask SetSprite(string url, TextureFormat textureFormat, bool ignoreImageNotFoundError, params Image[] images) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) return SetSprite(url, Vector2.one * 0.5f, textureFormat, ignoreImageNotFoundError, images); } [AsyncStateMachine(typeof(d__35))] [DebuggerStepThrough] public static UniTask SetSprite(string url, Vector2 pivot, TextureFormat textureFormat = (TextureFormat)5, bool ignoreImageNotFoundError = false, params Image[] images) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) d__35 d__ = new d__35(); d__.<>t__builder = AsyncUniTaskMethodBuilder.Create(); d__.url = url; d__.pivot = pivot; d__.textureFormat = textureFormat; d__.ignoreImageNotFoundError = ignoreImageNotFoundError; d__.images = images; d__.<>1__state = -1; ((AsyncUniTaskMethodBuilder)(ref d__.<>t__builder)).Start<d__35>(ref d__); return ((AsyncUniTaskMethodBuilder)(ref d__.<>t__builder)).Task; } public static UniTask SetSprite(string url, SpriteRenderer spriteRenderer, TextureFormat textureFormat = (TextureFormat)5, bool ignoreImageNotFoundError = false) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) return SetSprite(url, spriteRenderer, Vector2.one * 0.5f, textureFormat, ignoreImageNotFoundError); } [AsyncStateMachine(typeof(d__37))] [DebuggerStepThrough] public static UniTask SetSprite(string url, SpriteRenderer spriteRenderer, Vector2 pivot, TextureFormat textureFormat = (TextureFormat)5, bool ignoreImageNotFoundError = false) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) d__37 d__ = new d__37(); d__.<>t__builder = AsyncUniTaskMethodBuilder.Create(); d__.url = url; d__.spriteRenderer = spriteRenderer; d__.pivot = pivot; d__.textureFormat = textureFormat; d__.ignoreImageNotFoundError = ignoreImageNotFoundError; d__.<>1__state = -1; ((AsyncUniTaskMethodBuilder)(ref d__.<>t__builder)).Start<d__37>(ref d__); return ((AsyncUniTaskMethodBuilder)(ref d__.<>t__builder)).Task; } public static UniTask SetSprite(string url, params SpriteRenderer[] spriteRenderers) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) return SetSprite(url, Vector2.one * 0.5f, (TextureFormat)5, ignoreImageNotFoundError: false, spriteRenderers); } public static UniTask SetSprite(string url, TextureFormat textureFormat, params SpriteRenderer[] spriteRenderers) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) return SetSprite(url, Vector2.one * 0.5f, textureFormat, ignoreImageNotFoundError: false, spriteRenderers); } public static UniTask SetSprite(string url, bool ignoreImageNotFoundError, params SpriteRenderer[] spriteRenderers) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) return SetSprite(url, Vector2.one * 0.5f, (TextureFormat)5, ignoreImageNotFoundError, spriteRenderers); } public static UniTask SetSprite(string url, TextureFormat textureFormat, bool ignoreImageNotFoundError, params SpriteRenderer[] spriteRenderers) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) return SetSprite(url, Vector2.one * 0.5f, textureFormat, ignoreImageNotFoundError, spriteRenderers); } [AsyncStateMachine(typeof(d__42))] [DebuggerStepThrough] public static UniTask SetSprite(string url, Vector2 pivot, TextureFormat textureFormat = (TextureFormat)5, bool ignoreImageNotFoundError = false, params SpriteRenderer[] spriteRenderers) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) d__42 d__ = new d__42(); d__.<>t__builder = AsyncUniTaskMethodBuilder.Create(); d__.url = url; d__.pivot = pivot; d__.textureFormat = textureFormat; d__.ignoreImageNotFoundError = ignoreImageNotFoundError; d__.spriteRenderers = spriteRenderers; d__.<>1__state = -1; ((AsyncUniTaskMethodBuilder)(ref d__.<>t__builder)).Start<d__42>(ref d__); return ((AsyncUniTaskMethodBuilder)(ref d__.<>t__builder)).Task; } } public class Settings { public DebugLevel debugLevel = DebugLevel.Error; public bool useMemoryCache = true; public bool useDiskCache = false; public bool generateMipMaps = false; public string diskSaveLocation { get; set; } = Application.persistentDataPath + "/imageCache"; } public enum DebugLevel { Log, Warning, Error, Exception, None } public static class Utils { public enum SizeUnits { Byte, KB, MB, GB, TB, PB, EB, ZB, YB } public class SpriteContainer { public Sprite sprite; } public static string ToSize(long value, SizeUnits unit = SizeUnits.MB) { return ((double)value / Math.Pow(1024.0, (double)unit)).ToString("0.00") + unit; } public static bool IsPowerOfTwo(int x) { return x != 0 && (x & (x - 1)) == 0; } public static Texture2D CreateTexWithMipmaps(byte[] data, GraphicsFormat origGraphicsFormat, int height = 4, int width = 4, TextureFormat textureFormat = (TextureFormat)0, string name = "") { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Expected O, but got Unknown //IL_0065: Unknown result type (might be due to invalid IL or missing references) GraphicsFormat val = (GraphicsFormat)100; TextureCreationFlags val2 = (TextureCreationFlags)1; Texture2D val3 = new Texture2D(width, height, val, val2); ((Texture)val3).wrapMode = (TextureWrapMode)1; if (!ImageConversion.LoadImage(val3, data)) { Debug.Log((object)$"CreateTexWithMipmaps: LoadImage failed, using format={val}, trying again with {(object)(GraphicsFormat)4}"); val = (GraphicsFormat)4; val3 = new Texture2D(width, height, val, val2); if (!ImageConversion.LoadImage(val3, data)) { Debug.LogError((object)$"CreateTexWithMipmaps: LoadImage failed, using format={val}, returning null texture"); val3 = null; } } return val3; } public static Texture2D CreateTexWithMipmaps(byte[] data, bool shouldGenerateMipMaps = true, GraphicsFormat finalGraphicsFormat = (GraphicsFormat)4, int anisoLevel = 1, FilterMode filterMode = (FilterMode)1, string name = "DynamicTex") { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Expected O, but got Unknown //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) TextureCreationFlags val = (TextureCreationFlags)0; if (shouldGenerateMipMaps) { val = (TextureCreationFlags)1; } Texture2D val2 = new Texture2D(4, 4, finalGraphicsFormat, val) { name = name + "-" + shouldGenerateMipMaps, wrapMode = (TextureWrapMode)1, anisoLevel = 1, filterMode = (FilterMode)1 }; if (!ImageConversion.LoadImage(val2, data)) { Debug.Log((object)$"CreateTexWithMipmaps: LoadImage failed using format={finalGraphicsFormat}, size={((Texture)val2).width}x{((Texture)val2).height} trying again with {(object)(GraphicsFormat)4}"); } if (((Texture)val2).width % 4 == 0 && ((Texture)val2).height % 4 == 0) { val2.Compress(false); } return val2; } public static IEnumerator GetImageUsingUWRTexture(string url, Image img = null) { UnityWebRequest uwr = UnityWebRequestTexture.GetTexture(url); yield return uwr.SendWebRequest(); string name = Path.GetFileNameWithoutExtension(url); if ((int)uwr.result != 1 || !uwr.isDone) { Debug.Log((object)("GetImageUsingUWRTexture: Download failed : name=" + name + ", error=" + uwr.error)); yield break; } Texture2D uwrTexture = ((DownloadHandlerTexture)uwr.downloadHandler).texture; Sprite downloadedSprite = Sprite.Create(uwrTexture, new Rect(0f, 0f, (float)((Texture)uwrTexture).width, (float)((Texture)uwrTexture).height), Vector2.zero, 100f, 0u, (SpriteMeshType)0); if ((Object)(object)img != (Object)null) { img.overrideSprite = downloadedSprite; } Debug.Log((object)$"GetImageUsingUWRTexture: name={name}, RawSize={ToSize(uwrTexture.GetRawTextureData().Length)}, mipmap={((Texture)uwrTexture).mipmapCount}, format={uwrTexture.format}, graphicsFormat={((Texture)uwrTexture).graphicsFormat}, dimensions={((Texture)uwrTexture).width}x{((Texture)uwrTexture).height}"); uwr.Dispose(); } public static IEnumerator GetImageUsingUWRBufferAndEnableMipmapsAndCompression(string url, SpriteContainer sprite = null) { UnityWebRequest uwr = new UnityWebRequest(url); uwr.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer(); yield return uwr.SendWebRequest(); string name = Path.GetFileNameWithoutExtension(url); if ((int)uwr.result != 1 || !uwr.isDone) { Debug.Log((object)("GetImageUsingUWRBufferAndEnableMipmapsAndCompression: Download failed : name=" + name + ", error=" + uwr.error)); yield break; } GraphicsFormat graphicsFormat = (GraphicsFormat)4; TextureCreationFlags flags = (TextureCreationFlags)1; Texture2D createdTexture = new Texture2D(4, 4, graphicsFormat, flags) { name = name, wrapMode = (TextureWrapMode)1 }; if (!ImageConversion.LoadImage(createdTexture, uwr.downloadHandler.data)) { Debug.LogError((object)$"GetImageUsingUWRBufferAndEnableMipmapsAndCompression: LoadImage failed using format={graphicsFormat}"); } if (((Texture)createdTexture).width % 4 == 0 && ((Texture)createdTexture).height % 4 == 0) { createdTexture.Compress(false); } Sprite downloadedSprite = Sprite.Create(createdTexture, new Rect(0f, 0f, (float)((Texture)createdTexture).width, (float)((Texture)createdTexture).height), Vector2.zero, 100f, 0u, (SpriteMeshType)0); if (sprite != null) { sprite.sprite = downloadedSprite; } Debug.Log((object)$"GetImageUsingUWRBufferAndEnableMipmapsAndCompression: name={name}, RawSize={ToSize(createdTexture.GetRawTextureData().Length)}, mipmap={((Texture)createdTexture).mipmapCount}, format={createdTexture.format}, graphicsFormat={((Texture)createdTexture).graphicsFormat}, dimensions={((Texture)createdTexture).width}x{((Texture)createdTexture).height}"); uwr.Dispose(); } } internal class LimitedConcurrencyLevelTaskScheduler : TaskScheduler { [ThreadStatic] private static bool _currentThreadIsProcessingItems; private readonly LinkedList _tasks = new LinkedList(); private readonly int _maxDegreeOfParallelism; private int _delegatesQueuedOrRunning = 0; public sealed override int MaximumConcurrencyLevel => _maxDegreeOfParallelism; public LimitedConcurrencyLevelTaskScheduler(int maxDegreeOfParallelism) { if (maxDegreeOfParallelism < 1) { throw new ArgumentOutOfRangeException("maxDegreeOfParallelism"); } _maxDegreeOfParallelism = maxDegreeOfParallelism; } protected sealed override void QueueTask(Task task) { lock (_tasks) { _tasks.AddLast(task); if (_delegatesQueuedOrRunning < _maxDegreeOfParallelism) { _delegatesQueuedOrRunning++; NotifyThreadPoolOfPendingWork(); } } } private void NotifyThreadPoolOfPendingWork() { ThreadPool.UnsafeQueueUserWorkItem(delegate { _currentThreadIsProcessingItems = true; try { while (true) { Task value; lock (_tasks) { if (_tasks.Count == 0) { _delegatesQueuedOrRunning--; break; } value = _tasks.First.Value; _tasks.RemoveFirst(); } TryExecuteTask(value); } } catch (Exception ex) { Debug.LogException(ex); } finally { _currentThreadIsProcessingItems = false; } }, null); } protected sealed override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued) { if (!_currentThreadIsProcessingItems) { return false; } if (taskWasPreviouslyQueued) { TryDequeue(task); } return TryExecuteTask(task); } protected sealed override bool TryDequeue(Task task) { lock (_tasks) { return _tasks.Remove(task); } } protected sealed override IEnumerable GetScheduledTasks() { bool lockTaken = false; try { Monitor.TryEnter(_tasks, ref lockTaken); if (lockTaken) { return _tasks.ToArray(); } throw new NotSupportedException(); } catch (Exception ex) { Debug.LogException(ex); return null; } finally { if (lockTaken) { Monitor.Exit(_tasks); } } } } } namespace LBoLEntitySideloader { [BepInPlugin("neo.lbol.frameworks.entitySideloader", "Entity Sideloader", "1.0.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInProcess("LBoL.exe")] public class BepinexPlugin : BaseUnityPlugin { internal static ManualLogSource log; private static Harmony harmony = PluginInfo.harmony; public static ConfigEntry devModeConfig; public static ConfigEntry devExtraLoggingConfig; public static ConfigEntry reloadKeyConfig; public static ConfigEntry hardReloadKeyConfig; public static ConfigEntry autoRestartLevelConfig; public static BepinexPlugin instance; private static SemaphoreSlim maBoi = new SemaphoreSlim(1); internal static int doingMidRunReload = 0; private void Awake() { //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) instance = this; log = ((BaseUnityPlugin)this).Logger; Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject); ((Object)((Component)this).gameObject).hideFlags = (HideFlags)61; devModeConfig = ((BaseUnityPlugin)this).Config.Bind("DevMode", "DevMode", false, "Enables mod developer mode for extra functionality and error feedback."); devExtraLoggingConfig = ((BaseUnityPlugin)this).Config.Bind("DevMode", "ExtraLogging", true, "Enables some additional error feedback when devMode is enabled."); reloadKeyConfig = ((BaseUnityPlugin)this).Config.Bind("DevMode", "ReloadKey", new KeyboardShortcut((KeyCode)287, Array.Empty()), "Reload all entities (requires scriptengine)."); hardReloadKeyConfig = ((BaseUnityPlugin)this).Config.Bind("DevMode", "HardReloadKey", new KeyboardShortcut((KeyCode)0, Array.Empty()), "Hard reload localization and all entities (requires scriptengine)."); autoRestartLevelConfig = ((BaseUnityPlugin)this).Config.Bind("DevMode", "AutoRestart", true, "Restart level after reloading all entities."); ImageLoader.Init(); ImageLoader.settings.useDiskCache = false; ImageLoader.settings.debugLevel = DebugLevel.Error; harmony.PatchAll(); } private void OnDestroy() { instance = null; if (harmony != null) { harmony.UnpatchSelf(); } } private void Update() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) if (!devModeConfig.Value) { return; } KeyboardShortcut value = reloadKeyConfig.Value; if (!((KeyboardShortcut)(ref value)).IsDown()) { value = hardReloadKeyConfig.Value; if (!((KeyboardShortcut)(ref value)).IsDown()) { return; } } if (Chainloader.PluginInfos.TryGetValue("com.bepis.bepinex.scriptengine", out var value2)) { Reload(value2, hardReload: true); } else { log.LogInfo((object)"scriptengine is required for runtime reload"); } } public void Reload(PluginInfo scriptEngineInfo, bool hardReload = false) { if (!hardReload) { log.LogInfo((object)"'Soft' reload is not a thing. Use 'hard' reload instead"); return; } foreach (UserInfo value in EntityManager.Instance.sideloaderUsers.userInfos.Values) { EntityManager.Instance.UnregisterUser(value); } foreach (UserInfo value2 in EntityManager.Instance.secondaryUsers.userInfos.Values) { EntityManager.Instance.UnregisterUser(value2); } EntityManager.Instance.sideloaderUsers.userInfos = new Dictionary(); EntityManager.Instance.secondaryUsers.userInfos = new Dictionary(); UniqueTracker.DestroySelf(); CollectionExtensions.Do((IEnumerable)EntityManager.Instance.loadedFromDiskUsers, (Action)delegate(Assembly a) { EntityManager.RegisterAssembly(a); }); CollectionExtensions.Do((IEnumerable)EntityManager.Instance.loadedFromDiskPostAction, (Action)delegate(Action a) { UniqueTracker.Instance.PostMainLoad += a; }); UniqueTracker.Instance.formationAddActions.AddRange(EnemyGroupTemplate.loadedFromDiskCustomFormations); UniqueTracker.Instance.populateLoadoutInfosActions.AddRange(EntityManager.Instance.loadedFromDiskCharLoadouts); UniqueTracker.Instance.modifyStageListFuncs.AddRange(EntityManager.Instance.loadedFromDiskmodifyStageListFuncs); UniqueTracker.Instance.modifyStageActions.AddRange(EntityManager.Instance.loadedFromModifyStageActions); UniqueTracker.Instance.formationAddActions.AddRange(StageTemplate.loadedFromDiskEnvironments); EntityManager.Instance.addBossIconsActions.Clear(); Extensions.AddRange(UniqueTracker.Instance.customGrSaveData, EntityManager.Instance.loadedFromDsikCustomGrSaveData); ScriptEngineWrapper.ReloadPlugins(scriptEngineInfo.Instance); ((MonoBehaviour)this).StartCoroutine(DoubleDelayAction(async delegate { if (await maBoi.WaitAsync(0)) { try { ConfigDataManager.Reload(); if (hardReload) { EntityManager.Instance.LoadAll(EntityManager.Instance.sideloaderUsers, "All primary Sideloader users registered!", "Finished loading primary user resources", loadLoc: false); await L10nManager.ReloadLocalization(); UniqueTracker.Instance.RaisePostMainLoad(); EntityManager.Instance.LoadAll(EntityManager.Instance.secondaryUsers, "All secondary Sideloader users registered!", "Finished loading secondary user resources", loadLoc: false); } else { EntityManager.Instance.LoadAll(EntityManager.Instance.sideloaderUsers, "All primary Sideloader users registered!", "Finished loading primary user resources"); UniqueTracker.Instance.RaisePostMainLoad(); EntityManager.Instance.LoadAll(EntityManager.Instance.secondaryUsers, "All secondary Sideloader users registered!", "Finished loading secondary user resources"); } EntityManager.Instance.addBossIconsActions.Reload(); EntityManager.Instance.PostAllLoadProcessing(); CollectionExtensions.Do((IEnumerable)UniqueTracker.Instance.populateLoadoutInfosActions, (Action)delegate(Action a) { a(); }); if (Singleton.Instance.CurrentGameRun == null) { UiManager.GetPanel()._jadeBoxToggles.Clear(); UiManager.GetPanel().InitialForJadeBox(); EnemyGroupTemplate.ReloadFormations(); PlayerSpriteLoader.ReloadForMainMenu(); } else { SpellTemplate.LoadAllSpecialLoc(); } StageTemplate.ReloadEnvs(); if (autoRestartLevelConfig.Value && Singleton.Instance.CurrentGameRun != null) { SettingPanel panel = UiManager.GetPanel(); if (panel != null) { panel.UI_RestartBattle(); } doingMidRunReload = 1; } } catch (Exception ex) { Exception ex2 = ex; log.LogError((object)ex2); } finally { maBoi.Release(); } } })); } private IEnumerator DoubleDelayAction(Action action) { yield return null; yield return null; action(); } } public static class CharNames { public const string Reimu = "Reimu"; public const string Marisa = "Marisa"; public const string Sakuya = "Sakuya"; public const string Cirno = "Cirno"; public const string Koishi = "Koishi"; } internal class DeferredActions { internal Dictionary actions = new Dictionary(); internal Dictionary reloadableActions = new Dictionary(); internal void AddAction(IdContainer id, Action action, Assembly callingAssembly) { if (callingAssembly.IsLoadedFromDisk()) { actions.AlwaysAdd(id, action); } else { reloadableActions.Add(id, action); } } internal void DoAll() { CollectionExtensions.Do((IEnumerable)actions.Values, (Action)delegate(Action a) { a(); }); CollectionExtensions.Do((IEnumerable)reloadableActions.Values, (Action)delegate(Action a) { a(); }); } internal void Clear() { reloadableActions.Clear(); } internal void Reload() { CollectionExtensions.Do((IEnumerable)reloadableActions.Values, (Action)delegate(Action a) { a(); }); } } public static class DictionaryExtensions { public static bool AlwaysAdd(this Dictionary dictionary, K key, V value) { if (!dictionary.TryAdd(key, value)) { dictionary[key] = value; return true; } return false; } public static bool AlwaysAdd(this AssociationList associationList, K key, V value) { if (!((IDictionary)associationList).TryAdd(key, value)) { associationList[key] = value; return true; } return false; } public static bool Merge(this Dictionary dictionary, Dictionary otherDic, bool overwrite = true) { bool dupes = false; otherDic.ToList().ForEach(delegate(KeyValuePair x) { dupes = dictionary.AlwaysAdd(x.Key, x.Value) || dupes; }); return dupes; } } public static class AdventureRegistry { internal static readonly Dictionary YarnPrograms = new Dictionary(StringComparer.OrdinalIgnoreCase); internal static readonly Dictionary AdventureTextures = new Dictionary(StringComparer.OrdinalIgnoreCase); public static void RegisterYarnData(string dialogName, YarnData yarnData) { if (yarnData != null) { YarnPrograms[dialogName] = yarnData; if (!dialogName.StartsWith("Adventure/", StringComparison.OrdinalIgnoreCase)) { YarnPrograms["Adventure/" + dialogName] = yarnData; } } } public static void RegisterAdventureImage(string imageName, Texture2D texture) { if ((Object)(object)texture != (Object)null) { AdventureTextures[imageName] = texture; } } } [HarmonyPatch(typeof(DialogRunner), "LoadAsync")] public static class DialogRunnerPatch { private static bool Prefix(string name, IVariableStorage storage, Library library, ref UniTask __result) { //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Expected O, but got Unknown //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) BepinexPlugin.log.LogInfo((object)("[DialogRunnerPatch] Intercepted LoadAsync for dialog name: '" + name + "'")); if (!AdventureRegistry.YarnPrograms.TryGetValue(name, out var value) || value == null) { return true; } if (value.compiledBytes == null) { BepinexPlugin.log.LogError((object)("[DialogRunnerPatch] Dialog '" + name + "' found in registry, but compiledBytes is NULL!")); return true; } BepinexPlugin.log.LogInfo((object)("[DialogRunnerPatch] Found YarnData for '" + name + "'. Getting string table...")); Dictionary stringTableForCurrentLocale = value.GetStringTableForCurrentLocale(); DialogRunner val = new DialogRunner(name, value.compiledBytes, (IDictionary)stringTableForCurrentLocale, storage, library); __result = UniTask.FromResult(val); BepinexPlugin.log.LogInfo((object)$"[DialogRunnerPatch] Successfully created DialogRunner for '{name}' with {stringTableForCurrentLocale.Count} string table entries."); return false; } } [HarmonyPatch(typeof(ResourcesHelper), "LoadAdventureImage")] public static class AdventureImagePatch { private static bool Prefix(string name, ref Texture2D __result) { if (AdventureRegistry.AdventureTextures.TryGetValue(name, out var value) && (Object)(object)value != (Object)null) { __result = value; return false; } return true; } } public class EntityManager { private static EntityManager _instance; private static readonly ManualLogSource log = BepinexPlugin.log; public HashSet loadedFromDiskUsers = new HashSet(); public HashSet loadedFromDiskPostAction = new HashSet(); public SideloaderUsers sideloaderUsers = new SideloaderUsers(); public SideloaderUsers secondaryUsers = new SideloaderUsers(); public List loadedFromDiskCharLoadouts = new List(); public List, List>> loadedFromDiskmodifyStageListFuncs = new List, List>>(); public List loadedFromModifyStageActions = new List(); internal DeferredActions addBossIconsActions = new DeferredActions(); internal Dictionary loadedFromDsikCustomGrSaveData = new Dictionary(); public static EntityManager Instance { get { if (_instance == null) { _instance = new EntityManager(); } return _instance; } } public IEnumerable<(Assembly ass, UserInfo userInfo)> AllUsers => from kv in sideloaderUsers.userInfos.Concat(secondaryUsers.userInfos) select (Key: kv.Key, Value: kv.Value); public static UserInfo ScanAssembly(Assembly assembly, bool lookForFactypes = true) { UserInfo userInfo = new UserInfo(); userInfo.assembly = assembly; if (!assembly.IsDynamic && BepinexPlugin.devModeConfig.Value && !string.IsNullOrEmpty(assembly.Location)) { Instance.loadedFromDiskUsers.Add(assembly); } ManualLogSource obj = Log.LogDev(); if (obj != null) { obj.LogInfo((object)("Scanning " + assembly.GetName().Name + "...")); } Type[] array = ((!assembly.IsDynamic) ? assembly.GetExportedTypes() : assembly.GetTypes()); userInfo.assembly = assembly; HashSet hashSet = new HashSet(); Type[] array2 = array; foreach (Type type in array2) { if (!assembly.IsDynamic && type.IsSubclassOf(typeof(BaseUnityPlugin))) { object[] customAttributes = type.GetCustomAttributes(inherit: false); BepInPlugin val = type.SingularAttribute(customAttributes); if (val != null) { userInfo.GUID = val.GUID; } else { log.LogError((object)$"{assembly.GetName().Name}: {type} does not have {typeof(BepInPlugin).Name} attribute despite extending {typeof(BaseUnityPlugin).Name}"); } IEnumerable enumerable = type.MultiAttribute(customAttributes); if (enumerable == null || !enumerable.Any((BepInDependency bd) => bd.DependencyGUID == "neo.lbol.frameworks.entitySideloader" && (int)bd.Flags == 1)) { log.LogWarning((object)string.Format("{0}: {1} does not have a {2} attribute with {3} as hard dependency.", assembly.GetName().Name, type, typeof(BepInDependency).Name, "neo.lbol.frameworks.entitySideloader")); } continue; } if (type.IsSubclassOf(typeof(EntityDefinition))) { if (type.IsSealed) { EntityDefinition entityDefinition = (EntityDefinition)Activator.CreateInstance(type); userInfo.definitionInstances.Add(type, entityDefinition); entityDefinition.userAssembly = userInfo.assembly; entityDefinition.user = userInfo; OverwriteVanilla customAttribute = type.GetCustomAttribute(inherit: true); if (customAttribute != null) { userInfo.entitiesToOverwrite.Add(type, new ModificationInfo { attribute = customAttribute }); } } else if (BepinexPlugin.devModeConfig.Value && !type.IsSealed) { ManualLogSource obj2 = Log.LogDevExtra(); if (obj2 != null) { obj2.LogWarning((object)$"(Extra logging) {assembly.GetName().Name}: {type} is subtype of {typeof(EntityDefinition).Name} but isn't sealed. Final entity templates need to be sealed."); } } continue; } Type type2 = TypeFactoryReflection.factoryTypes.FirstOrDefault((Type t) => type.IsSubclassOf(t)); if (!(type2 != null)) { continue; } if (type.IsSealed) { userInfo.entityInfos.TryAdd(type2, new List()); EntityLogic customAttribute2 = type.GetCustomAttribute(); if (customAttribute2 != null) { if (hashSet.Contains(customAttribute2.DefinitionType)) { log.LogError((object)$"{assembly.GetName().Name}: {customAttribute2.DefinitionType} already has an entity logic type associated. Entity can only have one type defining its logic. Please remove {typeof(EntityLogic).Name} attribute."); } else if (BepinexPlugin.devModeConfig.Value && !TemplatesReflection.IsTemplateType(customAttribute2.DefinitionType)) { log.LogError((object)(customAttribute2.DefinitionType.Name + " type provided to " + typeof(EntityLogic).Name + " attribute on " + type.Name + " is not an " + typeof(EntityDefinition).Name + ". Entity definition must extend one of the entity templates.")); } else { hashSet.Add(customAttribute2.DefinitionType); EntityInfo entityInfo = new EntityInfo(type2, type, customAttribute2.DefinitionType); userInfo.entityInfos[type2].Add(entityInfo); userInfo.definition2customEntityLogicType.Add(customAttribute2.DefinitionType, entityInfo.entityType); } continue; } ExternalEntityLogicAttribute customAttribute3 = type.GetCustomAttribute(); if (customAttribute3 == null) { ManualLogSource obj3 = Log.LogDevExtra(); if (obj3 != null) { obj3.LogWarning((object)("(Extra logging) " + assembly.GetName().Name + ": " + type.Name + " does not have " + typeof(EntityLogic).Name + " attribute despite having qualities of an entity logic type. Please add " + typeof(EntityLogic).Name + " attribute.")); } } } else if (BepinexPlugin.devModeConfig.Value && !type.IsSealed) { ManualLogSource obj4 = Log.LogDevExtra(); if (obj4 != null) { obj4.LogWarning((object)$"(Extra logging) {assembly.GetName().Name}: {type} is subtype of {type2.Name} but isn't sealed. Final entity logic types need to be sealed"); } } } if (BepinexPlugin.devModeConfig.Value && BepinexPlugin.devExtraLoggingConfig.Value && !assembly.IsDynamic) { foreach (Type item in hashSet) { if (userInfo.definition2customEntityLogicType.TryGetValue(item, out var value) && userInfo.definitionInstances.TryGetValue(item, out var value2) && !value.IsSubclassOf(value2.EntityType())) { throw new InvalidProgramException($"(Extra Logging) {item.Name} expects its entity logic type, {value.Name}, to extend {value2.EntityType()}. Instead {value.Name} extends {value.BaseType} "); } } foreach (KeyValuePair definitionInstance in userInfo.definitionInstances) { Type key = definitionInstance.Key; EntityDefinition value3 = definitionInstance.Value; if (!userInfo.IsForOverwriting(key) && TemplatesReflection.ExpectsEntityLogic(key) && !hashSet.Contains(key)) { log.LogWarning((object)("(Extra logging) " + key.Name + " needs entity logic type extending " + value3.EntityType().Name + " but none was found. Did you define public sealed entity logic class with " + typeof(EntityLogic).Name + " attribute?")); } } } log.LogMessage((object)$"{assembly.GetName().Name} scanned! {userInfo.definitionInstances.Count()} Entity definition(s) found."); if (BepinexPlugin.devModeConfig.Value && BepinexPlugin.devExtraLoggingConfig.Value) { log.LogInfo((object)"(Extra logging) Entity definitions found: "); CollectionExtensions.Do>((IEnumerable>)userInfo.definitionInstances, (Action>)delegate(KeyValuePair kv) { log.LogInfo((object)kv.Key.Name); }); } return userInfo; } public static void AddExternalDefinitionTypePromise(Type entityLogicType, Func defTypePromise, Assembly userAssembly = null) { if (userAssembly == null) { userAssembly = Assembly.GetCallingAssembly(); } UniqueTracker.Instance.typePromiseDic.TryAdd(userAssembly, new Dictionary>()); Type type = TypeFactoryReflection.factoryTypes.FirstOrDefault((Type t) => entityLogicType.IsSubclassOf(t)); if (type == null) { throw new ArgumentException($"{entityLogicType} does not inherit from general entity logic types"); } UniqueTracker.Instance.typePromiseDic[userAssembly].TryAdd(type, new List()); UniqueTracker.Instance.typePromiseDic[userAssembly][type].Add(new UniqueTracker.DefTypePromisePair { entityLogicType = entityLogicType, defTypePromise = defTypePromise }); } public static void AddPostLoadAction(Action action, Assembly callingAssembly = null) { if (callingAssembly == null) { callingAssembly = Assembly.GetCallingAssembly(); } Action action2 = delegate { try { action(); } catch (Exception arg) { log.LogError((object)$"Error during template generation: {arg}"); } }; if (!callingAssembly.IsDynamic && !string.IsNullOrEmpty(callingAssembly.Location)) { Instance.loadedFromDiskPostAction.Add(action2); } UniqueTracker.Instance.PostMainLoad += action2; } public static void RegisterSelf() { Assembly callingAssembly = Assembly.GetCallingAssembly(); RegisterAssembly(callingAssembly); } public static void RegisterAssembly(Assembly assembly) { Instance.sideloaderUsers.AddUser(assembly); } internal bool RegisterId(UserInfo user, EntityDefinition entityDefinition) { ManualLogSource obj = Log.LogDevExtra(); if (obj != null) { obj.LogDebug((object)$"(Extra logging) Registering id: template: {entityDefinition.GetType().Name}, id: {entityDefinition.GetId()}, IsForOverwriting: {user.IsForOverwriting(entityDefinition.GetType())}"); } Type type = entityDefinition.GetType(); try { if (user.entitiesToOverwrite.ContainsKey(type)) { if (!UniqueTracker.Instance.id2ConfigListIndex[entityDefinition.ConfigType()].ContainsKey(entityDefinition.GetId())) { log.LogError((object)$"RegisterId: {entityDefinition.GetId()} was not found among vanilla ids. Overwriting is not supported for non-vanilla entities (for now, maybe)."); UniqueTracker.Instance.invalidRegistrations.Add(type); return false; } return true; } UniqueTracker.AddUniqueId(entityDefinition, user); } catch (Exception ex) { log.LogError((object)ex); UniqueTracker.Instance.invalidRegistrations.Add(type); return false; } return true; } internal void RegisterUser(UserInfo user) { log.LogInfo((object)("Registering assembly: " + user.assembly.GetName().Name)); ManualLogSource obj = Log.LogDev(); if (obj != null) { obj.LogDebug((object)"Adding configs.."); } Stopwatch stopwatch = new Stopwatch(); if (BepinexPlugin.devModeConfig.Value) { stopwatch.Start(); } foreach (KeyValuePair definitionInstance in user.definitionInstances) { Type key = definitionInstance.Key; EntityDefinition value = definitionInstance.Value; if (!RegisterId(user, value)) { continue; } try { if (value is CardTemplate cardTemplate) { CardConfig val = RegisterConfig(cardTemplate, user); if (val == null) { val = CardConfig.FromId((string)cardTemplate.UniqueId); } val.Colors = val.Colors.OrderBy((ManaColor c) => (int)c).ToList(); } else if (value is StatusEffectTemplate configProvider) { RegisterConfig(configProvider, user); } else if (value is ExhibitTemplate configProvider2) { RegisterConfig(configProvider2, user); } else if (value is BgmTemplate bgmTemplate) { BgmConfig val2 = RegisterConfig(bgmTemplate, user); if (val2 == null) { val2 = BgmConfig.FromID((string)bgmTemplate.UniqueId); } if (!user.IsForOverwriting(bgmTemplate.GetType()) || (user.IsForOverwriting(bgmTemplate.GetType()) && TemplatesReflection.DoOverwrite(bgmTemplate.GetType(), "LoadAudioClipAsync"))) { val2.Path = val2.ID; val2.Folder = ""; } UniqueTracker.Instance.AddOnDemandResource(bgmTemplate.TemplateType(), val2.ID, value); } else if (value is SfxTemplate configProvider3) { RegisterConfig(configProvider3, user); } else if (value is UiSoundTemplate configProvider4) { RegisterConfig(configProvider4, user); } else if (value is JadeBoxTemplate configProvider5) { RegisterConfig(configProvider5, user); } else if (value is EnemyUnitTemplate configProvider6) { RegisterConfig(configProvider6, user); } else if (value is UltimateSkillTemplate configProvider7) { RegisterConfig(configProvider7, user); } else if (value is EnemyGroupTemplate configProvider8) { RegisterConfig(configProvider8, user); } else if (value is PlayerUnitTemplate playerUnitTemplate) { PlayerUnitConfig val3 = RegisterConfig(playerUnitTemplate, user); UniqueTracker.Instance.AddOnDemandResource(playerUnitTemplate.TemplateType(), val3.Id, playerUnitTemplate); } else if (value is UnitModelTemplate unitModelTemplate) { UnitModelConfig val4 = RegisterConfig(unitModelTemplate, user); UniqueTracker.Instance.AddOnDemandResource(unitModelTemplate.TemplateType(), val4.Name, unitModelTemplate); } else if (value is StageTemplate configProvider9) { RegisterConfig(configProvider9, user); } else if (value is EffectTemplate effectTemplate) { string text = null; if (user.IsForOverwriting(effectTemplate.GetType()) && TemplatesReflection.DoOverwrite(effectTemplate.GetType(), "MakeConfig")) { text = EffectConfig.FromName((string)value.UniqueId).Path; } EffectConfig val5 = RegisterConfig(effectTemplate, user); if (val5 != null) { if (text != null) { val5.Path = text; } else { val5.Path = val5.Name; } } } else if (value is LaserTemplate configProvider10) { RegisterConfig(configProvider10, user); } else if (value is BulletTemplate configProvider11) { RegisterConfig(configProvider11, user); } else if (value is GunTemplate configProvider12) { RegisterConfig(configProvider12, user); } else if (value is PieceTemplate configProvider13) { RegisterConfig(configProvider13, user); } else if (value is SpellTemplate configProvider14) { RegisterConfig(configProvider14, user); } else if (value is PackTemplate configProvider15) { RegisterConfig(configProvider15, user); } else if (value is AdventureTemplate configProvider16) { RegisterConfig(configProvider16, user); } } catch (Exception arg) { log.LogError((object)$"Exception registering config of {value}: {arg}"); } } ManualLogSource obj2 = Log.LogDev(); if (obj2 != null) { obj2.LogDebug((object)"Adding entity logic types.."); } foreach (KeyValuePair> entityInfo in user.entityInfos) { RegisterTypes(entityInfo.Key, user); } string text2 = "Registering assembly " + user.assembly.GetName().Name + " done!"; if (BepinexPlugin.devModeConfig.Value) { stopwatch.Stop(); text2 += $" Elapsed time: {stopwatch.ElapsedMilliseconds}ms"; } log.LogInfo((object)text2); } internal C RegisterConfig(IConfigProvider configProvider, UserInfo user, EntityDefinition entityDefinition = null) where C : class { if (entityDefinition == null) { entityDefinition = (EntityDefinition)configProvider; } Type type = entityDefinition.ConfigType(); Type type2 = entityDefinition.GetType(); if (type == null) { return null; } if (type.IsSubclassOf(typeof(MockConfig))) { return null; } FieldInfo idField = ConfigReflection.GetIdField(type); ManualLogSource obj = Log.LogDevExtra(); if (obj != null) { obj.LogDebug((object)$"(Extra Logging) Registering config: id: {entityDefinition.UniqueId}, config type:{entityDefinition.ConfigType().Name}"); } FieldInfo arrayField = ConfigReflection.GetArrayField(type); FieldRef val = AccessTools.StaticFieldRefAccess(arrayField); FieldInfo tableField = ConfigReflection.GetTableField(type); C val2 = null; if (!UniqueTracker.Instance.invalidRegistrations.Contains(type2) && (!user.IsForOverwriting(entityDefinition.GetType()) || TemplatesReflection.DoOverwrite(type2, "MakeConfig"))) { val2 = configProvider.MakeConfig(); if (val2 == null) { throw new ArgumentException("MakeConfig must return a non-null value."); } switch (entityDefinition.UniqueId.idType) { case IdContainer.IdType.String: idField.SetValue(val2, (string)entityDefinition.UniqueId); break; case IdContainer.IdType.Int: idField.SetValue(val2, (int)entityDefinition.UniqueId); break; default: log.LogWarning((object)"RegisterConfig: you shouldn't be here"); break; } } if (!user.IsForOverwriting(entityDefinition.GetType())) { FieldInfo fieldInfo = ConfigReflection.HasIndex(type); if (fieldInfo != null) { fieldInfo.SetValue(val2, UniqueTracker.AddUniqueIndex(IdContainer.CastFromObject(fieldInfo.GetValue(val2)), entityDefinition)); } switch (entityDefinition.UniqueId.idType) { case IdContainer.IdType.String: idField.SetValue(val2, (string)entityDefinition.UniqueId); break; case IdContainer.IdType.Int: idField.SetValue(val2, (int)entityDefinition.UniqueId); break; default: log.LogWarning((object)"RegisterConfig: you shouldn't be here"); break; } switch (entityDefinition.UniqueId.idType) { case IdContainer.IdType.String: ((Dictionary)tableField.GetValue(null)).Add(entityDefinition.UniqueId, val2); break; case IdContainer.IdType.Int: ((Dictionary)tableField.GetValue(null)).Add(entityDefinition.UniqueId, val2); break; default: log.LogWarning((object)"RegisterConfig: you shouldn't be here"); break; } val.Invoke() = CollectionExtensions.AddToArray(val.Invoke(), val2).ToArray(); } else if (!UniqueTracker.Instance.invalidRegistrations.Contains(type2) && TemplatesReflection.DoOverwrite(type2, "MakeConfig") && !UniqueTracker.IsOverwriten(entityDefinition.TemplateType(), entityDefinition.UniqueId, "MakeConfig", type2, user)) { int num = UniqueTracker.Instance.id2ConfigListIndex[type][IdContainer.CastFromObject(idField.GetValue(val2))]; switch (entityDefinition.UniqueId.idType) { case IdContainer.IdType.String: ((Dictionary)tableField.GetValue(null)).AlwaysAdd((string)entityDefinition.UniqueId, val2); break; case IdContainer.IdType.Int: ((Dictionary)tableField.GetValue(null)).AlwaysAdd((int)entityDefinition.UniqueId, val2); break; default: log.LogWarning((object)"RegisterConfig: you shouldn't be here"); break; } val.Invoke()[num] = val2; } return val2; } internal static void RegisterTypes(Type facType, UserInfo user) { if (!user.entityInfos.TryGetValue(facType, out var value)) { return; } foreach (EntityInfo item in value) { try { ManualLogSource obj = Log.LogDevExtra(); if (obj != null) { obj.LogDebug((object)("(Extra Logging) Registering entity logic type in TypeFactory<" + facType.Name + ">, typeName: " + item.entityType.Name + ", from template: " + item.definitionType.Name)); } if (UniqueTracker.Instance.invalidRegistrations.Contains(item.definitionType) || !user.definitionInstances.ContainsKey(item.definitionType)) { log.LogError((object)("TypeFactory<" + facType.Name + ">: Cannot register entity logic " + item.entityType.Name + " because template " + item.definitionType.Name + " was not properly loaded.")); continue; } EntityDefinition entityDefinition = user.definitionInstances[item.definitionType]; IdContainer uniqueId = entityDefinition.UniqueId; if (uniqueId != (IdContainer)item.entityType.Name) { log.LogError((object)$"{user.GUID} entity id, {uniqueId}, mismatches entity type name, {item.entityType.Name}"); continue; } if (!user.IsForOverwriting(item.definitionType)) { if (!TypeFactoryReflection.AccessTypeDicts(facType, TypeFactoryReflection.TableFieldName.FullNameTypeDict).Invoke((object)null).TryAdd(item.entityType.FullName, item.entityType)) { log.LogError((object)("RegisterType: " + item.entityType.Name + " matches an already registered type. Please change plugin namespace.")); } } else { IdContainer id = entityDefinition.GetId(); if (!UniqueTracker.IsOverwriten(entityDefinition.TemplateType(), id, "EntityLogic", item.definitionType, user)) { Type type = TypeFactoryReflection.AccessTypeDicts(facType, TypeFactoryReflection.TableFieldName.TypeDict).Invoke((object)null)[uniqueId]; user.typeName2VanillaType.Add(id, type); TypeFactoryReflection.AccessTypeDicts(facType, TypeFactoryReflection.TableFieldName.FullNameTypeDict).Invoke((object)null)[type.FullName] = item.entityType; } } if (!user.IsForOverwriting(item.definitionType)) { TypeFactoryReflection.AccessTypeDicts(facType, TypeFactoryReflection.TableFieldName.TypeDict).Invoke((object)null).Add(uniqueId, item.entityType); } else { TypeFactoryReflection.AccessTypeDicts(facType, TypeFactoryReflection.TableFieldName.TypeDict).Invoke((object)null).AlwaysAdd((string)uniqueId, item.entityType); } ProcessWeighterAttribute(facType, item.entityType); } catch (Exception ex) { log.LogError((object)ex); } } } private static void ProcessWeighterAttribute(Type facType, Type entityType) { //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Expected O, but got Unknown if (facType == typeof(Exhibit)) { ExhibitInfoAttribute customAttribute = ((MemberInfo)entityType).GetCustomAttribute(); IExhibitWeighter val = ((customAttribute != null) ? customAttribute.CreateWeighter() : null); if (val != null) { Library._exhibitWeighterTable.AlwaysAdd(entityType, val); } } else { if (!(facType == typeof(Adventure))) { return; } AdventureInfoAttribute customAttribute2 = ((MemberInfo)entityType).GetCustomAttribute(); if (((customAttribute2 != null) ? customAttribute2.WeighterType : null) != null) { IAdventureWeighter val2 = (IAdventureWeighter)Activator.CreateInstance(customAttribute2.WeighterType); if (val2 != null) { Library._adventureWeighterTable.AlwaysAdd(entityType, val2); } } } } internal static void UnRegisterTypes(Type facType, UserInfo user) { if (!user.entityInfos.TryGetValue(facType, out var value)) { return; } foreach (EntityInfo item in value) { if (UniqueTracker.Instance.invalidRegistrations.Contains(item.definitionType) || !user.definitionInstances.ContainsKey(item.definitionType)) { continue; } EntityDefinition entityDefinition = user.definitionInstances[item.definitionType]; IdContainer uniqueId = entityDefinition.UniqueId; if (!user.IsForOverwriting(item.definitionType)) { TypeFactoryReflection.AccessTypeDicts(facType, TypeFactoryReflection.TableFieldName.FullNameTypeDict).Invoke((object)null).Remove(item.entityType.FullName); TypeFactoryReflection.AccessTypeDicts(facType, TypeFactoryReflection.TableFieldName.TypeDict).Invoke((object)null).Remove(uniqueId); if (facType == typeof(Exhibit)) { Library._exhibitWeighterTable.Remove(item.entityType); } else if (facType == typeof(Adventure)) { Library._adventureWeighterTable.Remove(item.entityType); } } else { Type type = user.typeName2VanillaType[uniqueId]; TypeFactoryReflection.AccessTypeDicts(facType, TypeFactoryReflection.TableFieldName.FullNameTypeDict).Invoke((object)null)[item.entityType.FullName] = type; TypeFactoryReflection.AccessTypeDicts(facType, TypeFactoryReflection.TableFieldName.TypeDict).Invoke((object)null)[uniqueId] = type; ProcessWeighterAttribute(facType, type); } } } internal void UnregisterUser(UserInfo user) { foreach (KeyValuePair> entityInfo in user.entityInfos) { UnRegisterTypes(entityInfo.Key, user); } } internal void RegisterUsers(SideloaderUsers sideloaderUsers, string onCompleteMsg = "All sideloader users registered!") { foreach (KeyValuePair userInfo in sideloaderUsers.userInfos) { UserInfo value = userInfo.Value; RegisterUser(value); } log.LogInfo((object)onCompleteMsg); } internal void LoadAssetsForResourceHelper(SideloaderUsers sideloaderUsers) { foreach (KeyValuePair userInfo in sideloaderUsers.userInfos) { UserInfo value = userInfo.Value; foreach (KeyValuePair definitionInstance in userInfo.Value.definitionInstances) { Type key = definitionInstance.Key; EntityDefinition value2 = definitionInstance.Value; CardTemplate ct = value2 as CardTemplate; if (ct != null) { HandleOverwriteWrap(delegate { ct.Consume(ct.LoadCardImages()); }, value2, "LoadCardImages", value); continue; } StatusEffectTemplate st = value2 as StatusEffectTemplate; if (st != null) { HandleOverwriteWrap(delegate { st.Consume(st.LoadSprite()); }, value2, "LoadSprite", value); continue; } ExhibitTemplate et = value2 as ExhibitTemplate; if (et != null) { HandleOverwriteWrap(delegate { et.Consume(et.LoadSprite()); }, value2, "LoadSprite", value); continue; } UltimateSkillTemplate ust = value2 as UltimateSkillTemplate; if (ust != null) { HandleOverwriteWrap(delegate { ust.Consume(ust.LoadSprite()); }, value2, "LoadSprite", value); continue; } SfxTemplate sfxT = value2 as SfxTemplate; if (sfxT != null) { HandleOverwriteWrap(delegate { sfxT.Consume(sfxT.LoadSfxListAsync()); }, value2, "LoadSfxListAsync", value); continue; } UiSoundTemplate usfxT = value2 as UiSoundTemplate; if (usfxT != null) { HandleOverwriteWrap(delegate { usfxT.Consume(usfxT.LoadSfxListAsync()); }, value2, "LoadSfxListAsync", value); continue; } if (value2 is PlayerUnitTemplate playerUnitTemplate) { playerUnitTemplate.Consume(playerUnitTemplate.LoadPlayerImages()); continue; } EffectTemplate eft = value2 as EffectTemplate; if (eft != null) { HandleOverwriteWrap(delegate { eft.Consume(eft.LoadEffectData()); }, value2, "LoadEffectData", value); continue; } IntentionTemplate it = value2 as IntentionTemplate; if (it != null) { HandleOverwriteWrap(delegate { it.Consume(it.LoadSprites()); }, value2, "LoadSprites", value); continue; } PackTemplate pt = value2 as PackTemplate; if (pt != null) { HandleOverwriteWrap(delegate { pt.Consume(pt.LoadPackIcon()); }, value2, "LoadPackIcon", value); continue; } AdventureTemplate at = value2 as AdventureTemplate; if (at != null) { HandleOverwriteWrap(delegate { at.Consume(at.LoadAdventureImages()); }, value2, "LoadAdventureImages", value); HandleOverwriteWrap(delegate { at.Consume(at.LoadYarnData()); }, value2, "LoadYarnData", value); } } } } internal void LoadLocalization(SideloaderUsers sideloaderUsers) { //IL_0530: Unknown result type (might be due to invalid IL or missing references) //IL_0640: Unknown result type (might be due to invalid IL or missing references) foreach (KeyValuePair userInfo in sideloaderUsers.userInfos) { UserInfo value = userInfo.Value; UniqueTracker.Instance.typesToLocalize[value.assembly] = new Dictionary(); foreach (KeyValuePair definitionInstance in value.definitionInstances) { EntityDefinition value2 = definitionInstance.Value; CardTemplate ct = value2 as CardTemplate; if (ct != null) { HandleOverwriteWrap(delegate { ct.Consume(ct.LoadLocalization()); }, value2, "LoadLocalization", value); continue; } StatusEffectTemplate st = value2 as StatusEffectTemplate; if (st != null) { HandleOverwriteWrap(delegate { st.Consume(st.LoadLocalization()); }, value2, "LoadLocalization", value); continue; } ExhibitTemplate et = value2 as ExhibitTemplate; if (et != null) { HandleOverwriteWrap(delegate { et.Consume(et.LoadLocalization()); }, value2, "LoadLocalization", value); continue; } JadeBoxTemplate jt = value2 as JadeBoxTemplate; if (jt != null) { HandleOverwriteWrap(delegate { jt.Consume(jt.LoadLocalization()); }, value2, "LoadLocalization", value); continue; } EnemyUnitTemplate eut = value2 as EnemyUnitTemplate; if (eut != null) { HandleOverwriteWrap(delegate { eut.Consume(eut.LoadLocalization()); }, value2, "LoadLocalization", value); continue; } UltimateSkillTemplate ust = value2 as UltimateSkillTemplate; if (ust != null) { HandleOverwriteWrap(delegate { ust.Consume(ust.LoadLocalization()); UniqueTracker.Instance.ultimateSkillTemplates.TryAdd(ust.userAssembly, new Dictionary()); UniqueTracker.Instance.ultimateSkillTemplates[ust.userAssembly].AlwaysAdd((string)ust.GetId(), ust); }, value2, "LoadLocalization", value); continue; } UnitModelTemplate umT = value2 as UnitModelTemplate; if (umT != null) { HandleOverwriteWrap(delegate { umT.Consume(umT.LoadLocalization()); }, value2, "LoadLocalization", value); continue; } PlayerUnitTemplate puT = value2 as PlayerUnitTemplate; if (puT != null) { HandleOverwriteWrap(delegate { puT.Consume(puT.LoadLocalization()); }, value2, "LoadLocalization", value); continue; } SpellTemplate spT = value2 as SpellTemplate; if (spT != null) { HandleOverwriteWrap(delegate { spT.Consume(spT.LoadLocalization()); UniqueTracker.Instance.spellTemplates.TryAdd(spT.userAssembly, new Dictionary()); UniqueTracker.Instance.spellTemplates[spT.userAssembly].AlwaysAdd((string)spT.GetId(), spT); }, value2, "LoadLocalization", value); continue; } IntentionTemplate it = value2 as IntentionTemplate; if (it != null) { HandleOverwriteWrap(delegate { it.Consume(it.LoadLocalization()); }, value2, "LoadLocalization", value); continue; } PackTemplate pt = value2 as PackTemplate; if (pt != null) { HandleOverwriteWrap(delegate { pt.Consume(pt.LoadLocalization()); }, value2, "LoadLocalization", value); continue; } AdventureTemplate at = value2 as AdventureTemplate; if (at != null) { HandleOverwriteWrap(delegate { at.Consume(at.LoadLocalization()); }, value2, "LoadLocalization", value); } } if (UniqueTracker.Instance.typesToLocalize.ContainsKey(value.assembly)) { foreach (KeyValuePair item in UniqueTracker.Instance.typesToLocalize[value.assembly]) { try { Type key = item.Key; LocalizationInfo value3 = item.Value; if (value3.locFiles == null) { Log.log.LogError((object)(value.assembly.GetName().Name + ": localization files parameter was never initialized for global localization option of " + key.Name)); continue; } if (CollectionsExtensions.Empty>>((IReadOnlyCollection>>)value3.locFiles.locTable)) { Log.log.LogError((object)(value.GUID + ": no files were given for global localization option of " + key.Name)); continue; } Dictionary> termDic = value3.locFiles.LoadLocTable(key, value3.entityLogicTypes.ToArray()); LocalizationOption.FillLocalizationTables(termDic, key, value3.locFiles.mergeTerms); } catch (Exception ex) { log.LogError((object)ex); } } } if (UniqueTracker.Instance.unitNamesGlobalLocalizationFiles.TryGetValue(value.assembly, out var value4)) { try { LocalizationOption.FillUnitNameTable(value4.Load(Localization.CurrentLocale), value4.mergeTerms, UniqueTracker.Instance.unitIdsToLocalize[value.assembly]); } catch (Exception ex2) { log.LogError((object)ex2); } } if (!UniqueTracker.Instance.batchLocalization.ContainsKey(value.assembly)) { continue; } foreach (KeyValuePair> item2 in UniqueTracker.Instance.batchLocalization[value.assembly]) { if (item2.Key == typeof(SpellTemplate)) { continue; } foreach (BatchLocalization item3 in item2.Value) { try { LocalizationFiles localizationFiles = item3.localizationFiles; if (item3.templateType == typeof(UnitModelTemplate) || item3.IsUnitNameSource) { Log.log.LogDebug((object)"unit model batch loc"); LocalizationOption.FillUnitNameTable(localizationFiles.Load(Localization.CurrentLocale), localizationFiles.mergeTerms, item3.entityIds); } if (item3.templateType == typeof(PackTemplate)) { PackTemplate.FillPacksLocTable(localizationFiles.LoadLocTable(item3.entityIds, addEmptyDic: false), localizationFiles.mergeTerms); } else { LocalizationOption.FillLocalizationTables(localizationFiles.LoadLocTable(item3.entityIds), item3.factoryType, localizationFiles.mergeTerms); } } catch (Exception ex3) { log.LogError((object)ex3); } } } } } internal void LoadAll(SideloaderUsers sideloaderUsers, string onRegistrationCompleteMsg = "All sideloader users registered!", string onCompleteMsg = "Finished loading custom resources.", bool loadLoc = true) { try { Instance.RegisterUsers(sideloaderUsers, onRegistrationCompleteMsg); Instance.LoadAssetsForResourceHelper(sideloaderUsers); if (loadLoc) { Instance.LoadLocalization(sideloaderUsers); } } catch (Exception ex) { log.LogError((object)ex); } log.LogInfo((object)onCompleteMsg); } internal void PostAllLoadProcessing() { foreach (KeyValuePair> ultimateSkillTemplate in UniqueTracker.Instance.ultimateSkillTemplates) { Assembly key = ultimateSkillTemplate.Key; Dictionary value = ultimateSkillTemplate.Value; Dictionary spellTemplates; List list = ((!UniqueTracker.Instance.spellTemplates.TryGetValue(key, out spellTemplates)) ? value.Select((KeyValuePair kv) => kv.Value).ToList() : (from kv in value where !spellTemplates.ContainsKey(kv.Key) select kv.Value).ToList()); foreach (UltimateSkillTemplate item in list) { item.CreateSpellTemplate(); } } } internal void DoForAllUsers(Action action) { CollectionExtensions.Do((IEnumerable)sideloaderUsers.userInfos.Values, (Action)delegate(UserInfo ui) { action(ui); }); CollectionExtensions.Do((IEnumerable)secondaryUsers.userInfos.Values, (Action)delegate(UserInfo ui) { action(ui); }); } internal static bool HandleOverwriteWrap(Action action, EntityDefinition definition, string methodName, UserInfo user) { try { Type type = definition.GetType(); if (!UniqueTracker.Instance.invalidRegistrations.Contains(type)) { if (!user.IsForOverwriting(type)) { action(); return true; } if (TemplatesReflection.DoOverwrite(type, methodName) && !UniqueTracker.IsOverwriten(definition.TemplateType(), definition.UniqueId, methodName, type, user)) { action(); return true; } } } catch (Exception ex) { Log.log.LogError((object)$"Error while processing {definition.TemplateType().Name} {definition.GetType().Name}.{methodName}: {ex}"); } return false; } } internal class HookPoints { [HarmonyPatch(typeof(GameEntry), "InitializeRestAsync")] [HarmonyPriority(800)] private class InitializeRestAsync_Patch { public static async void Postfix(Task __result) { await __result; EntityManager.Instance.LoadAll(EntityManager.Instance.sideloaderUsers, "All primary Sideloader users registered!", "Finished loading primary user resources", loadLoc: false); UniqueTracker.Instance.RaisePostMainLoad(); EntityManager.Instance.LoadAll(EntityManager.Instance.secondaryUsers, "All secondary Sideloader users registered!", "Finished loading secondary user resources"); CollectionExtensions.Do((IEnumerable)UniqueTracker.Instance.populateLoadoutInfosActions, (Action)delegate(Action a) { a(); }); EntityManager.Instance.addBossIconsActions.DoAll(); EntityManager.Instance.PostAllLoadProcessing(); } } [HarmonyPatch(typeof(CrossPlatformHelper), "SetWindowTitle")] [HarmonyPriority(800)] private class Localization_Patch { private static void Postfix() { try { log.LogDebug((object)"loc reload"); EntityManager.Instance.LoadLocalization(EntityManager.Instance.sideloaderUsers); EntityManager.Instance.LoadLocalization(EntityManager.Instance.secondaryUsers); } catch (Exception ex) { log.LogWarning((object)ex); } } } [HarmonyPatch(typeof(GameDirector), "Awake")] [HarmonyPriority(800)] private class AddFormations_Patch { private static void Postfix() { EnemyGroupTemplate.LoadCustomFormations(); } } [HarmonyPatch(typeof(Environment), "Awake")] [HarmonyPriority(800)] private class AddEnvironments_Patch { private static void Postfix() { StageTemplate.LoadCustomEnvironments(); } } [HarmonyPatch(typeof(GameDirector), "InternalClearEnemies")] private class FormationsHotReload_Patch { private static void Postfix() { if (BepinexPlugin.doingMidRunReload > 0) { BepinexPlugin.doingMidRunReload--; EnemyGroupTemplate.ReloadFormations(); } } } [HarmonyPatch] private class SpellPanelSpecialLoc_Patch { private static IEnumerable TargetMethods() { yield return ExtraAccess.InnerMoveNext(typeof(SpellPanel), "CustomLocalizationAsync"); } private static void LoadLoc(SpellPanel spellPanel) { SpellTemplate.LoadAllSpecialLoc(spellPanel); } private static IEnumerable Transpiler(IEnumerable instructions, ILGenerator generator) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Expected O, but got Unknown //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Expected O, but got Unknown //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Expected O, but got Unknown FieldInfo fieldInfo = AccessTools.Field(typeof(SpellPanel), "_l10nTable"); return new CodeMatcher(instructions, generator).End().MatchBack(false, (CodeMatch[])(object)new CodeMatch[1] { CodeMatch.op_Implicit(new CodeInstruction(OpCodes.Stfld, (object)fieldInfo)) }).Advance(-1) .MatchBack(false, (CodeMatch[])(object)new CodeMatch[1] { CodeMatch.op_Implicit(new CodeInstruction(OpCodes.Stfld, (object)fieldInfo)) }) .Advance(1) .Insert((CodeInstruction[])(object)new CodeInstruction[1] { new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(SpellPanelSpecialLoc_Patch), "LoadLoc", (Type[])null, (Type[])null)) }) .Insert((CodeInstruction[])(object)new CodeInstruction[1] { new CodeInstruction(OpCodes.Ldloc_1, (object)null) }) .InstructionEnumeration(); } } private class Loc_IntrusivePatch { private static IEnumerable TargetMethods() { yield return ExtraAccess.InnerMoveNext(typeof(L10nManager), "ReloadAsync"); } private static void LoadLocWrap() { EntityManager.Instance.LoadLocalization(EntityManager.Instance.sideloaderUsers); EntityManager.Instance.LoadLocalization(EntityManager.Instance.secondaryUsers); } private static IEnumerable Transpiler(IEnumerable instructions, ILGenerator generator) { foreach (CodeInstruction ci in instructions) { if (ci.opcode == OpCodes.Call && (MethodInfo)ci.operand == AccessTools.Method(typeof(CrossPlatformHelper), "SetWindowTitle", (Type[])null, (Type[])null)) { yield return ci; yield return new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(Loc_IntrusivePatch), "LoadLocWrap", (Type[])null, (Type[])null)); } else { yield return ci; } } } } [HarmonyPatch] private class ReadVanillaConfigIds_Patch { private static IEnumerable TargetMethods() { foreach (Type t in ConfigReflection.AllConfigTypes()) { yield return AccessTools.Method(t, "Load", (Type[])null, (Type[])null); } } private static IEnumerable Transpiler(IEnumerable instructions, MethodBase original) { foreach (CodeInstruction ci in instructions) { if (CodeInstructionExtensions.Is(ci, OpCodes.Newobj, (MemberInfo)AccessTools.FirstConstructor(original.DeclaringType, (Func)((ConstructorInfo c) => c.GetParameters().Count() > 0)))) { yield return ci; yield return new CodeInstruction(OpCodes.Dup, (object)null); yield return new CodeInstruction(OpCodes.Ldc_I4_1, (object)null); yield return new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(UniqueTracker), "TrackVanillaConfig", (Type[])null, (Type[])null)); } else { yield return ci; } } } } private static readonly ManualLogSource log = BepinexPlugin.log; } public struct IdContainer : IEquatable { public enum IdType { String, Int } private string sId; private int iId; public readonly IdType idType; public string SId { get { return sId; } set { sId = value; } } public int IId { get { return iId; } set { iId = value; } } public static implicit operator string(IdContainer id) { return id.sId; } public static implicit operator int(IdContainer id) { return id.iId; } public static implicit operator IdContainer(string s) { return new IdContainer(s); } public static implicit operator IdContainer(int i) { return new IdContainer(i); } public static IdContainer CastFromObject(object o) { if (o is string s) { return new IdContainer(s); } if (o is int i) { return new IdContainer(i); } throw new ArgumentException($"IdContainer: {o.GetType()} is not a valid type to cast from."); } public IdContainer(string s) { this = default(IdContainer); sId = s; idType = IdType.String; } public IdContainer(int i) { this = default(IdContainer); iId = i; idType = IdType.Int; } public static bool operator ==(IdContainer a, IdContainer b) { if (a.idType != b.idType) { throw new ArgumentException("Can't compare IdContainers of different types"); } switch (a.idType) { case IdType.String: if (a.sId == null) { return false; } return a.sId.Equals(b.sId); case IdType.Int: return a.iId.Equals(b.iId); default: if (a.sId == null) { return false; } return a.sId.Equals(b.sId); } } public static bool operator !=(IdContainer a, IdContainer b) { if (a.idType != b.idType) { throw new ArgumentException("Can't compare IdContainers of different types"); } switch (a.idType) { case IdType.String: if (a.sId == null) { return true; } return !a.sId.Equals(b.sId); case IdType.Int: return !a.iId.Equals(b.iId); default: if (a.sId == null) { return true; } return !a.sId.Equals(b.sId); } } public override bool Equals(object obj) { if ((object)this == obj) { return true; } if (obj == null) { return false; } return idType switch { IdType.String => sId.Equals(obj), IdType.Int => iId.Equals(obj), _ => sId.Equals(obj), }; } public override int GetHashCode() { switch (idType) { case IdType.String: if (sId == null) { return 0; } return sId.GetHashCode(); case IdType.Int: return iId.GetHashCode(); default: if (sId == null) { return 0; } return sId.GetHashCode(); } } public override string ToString() { return idType switch { IdType.String => sId?.ToString(), IdType.Int => iId.ToString(), _ => sId?.ToString(), }; } public bool Equals(IdContainer other) { return this == other; } } internal static class Log { private static readonly ManualLogSource BePinExlogger = BepinexPlugin.log; public static ManualLogSource log => BePinExlogger; public static ManualLogSource LogDev() { if (BepinexPlugin.devModeConfig.Value) { return log; } return null; } public static ManualLogSource LogDevExtra() { if (BepinexPlugin.devModeConfig.Value && BepinexPlugin.devExtraLoggingConfig.Value) { return log; } return null; } } public class PluginInfo { public const string GUID = "neo.lbol.frameworks.entitySideloader"; public const string description = "Entity Sideloader"; public const string version = "1.0.1"; public static readonly Harmony harmony = new Harmony("neo.lbol.frameworks.entitySideloader"); } public class UserInfo { public string GUID; public Assembly assembly; public Dictionary definitionInstances = new Dictionary(); public Dictionary> entityInfos = new Dictionary>(); public Dictionary definition2customEntityLogicType = new Dictionary(); public Dictionary entitiesToOverwrite = new Dictionary(); public Dictionary typeName2VanillaType = new Dictionary(); public bool IsForOverwriting(Type definitionType) { return entitiesToOverwrite.ContainsKey(definitionType); } } public class EntityInfo { public Type factoryType; public Type entityType; public Type definitionType; public Type originalType; public EntityInfo(Type factoryType, Type entityType, Type definitionType) { this.factoryType = factoryType; this.entityType = entityType; this.definitionType = definitionType; } } public class LocalizationInfo { public LocalizationFiles locFiles; public HashSet entityLogicTypes = new HashSet(); } public class ModificationInfo { public OverwriteVanilla attribute; } public class OverwriteInfo { public IdContainer entityId; public string componentName; public Type defType; public UserInfo user; } internal class ScriptEngineWrapper { internal static void ReloadPlugins(BaseUnityPlugin scriptEngineInstance) { ScriptEngine val = (ScriptEngine)(object)((scriptEngineInstance is ScriptEngine) ? scriptEngineInstance : null); if (val != null) { val.ReloadPlugins(); } else { BepinexPlugin.log.LogWarning((object)$"ScriptEngineWrapper: {scriptEngineInstance} is not an instance of scriptengine"); } } } public class Sequence { private int counter = 0; public int Counter => counter; public Sequence(int startingPoint = 0) { counter = startingPoint; } public void SetCounter(int counter) { this.counter = counter; } public int Next() { return counter++; } } public class SideloaderUsers { public Dictionary userInfos = new Dictionary(); public void AddUser(Assembly assembly) { if (userInfos.ContainsKey(assembly)) { throw new Exception(assembly.GetName().Name + " is already registered"); } try { userInfos.Add(assembly, EntityManager.ScanAssembly(assembly)); } catch (Exception arg) { Log.log.LogError((object)$"{assembly.GetName().Name}: {arg}"); } } public UserInfo GetDefinitionUser(EntityDefinition entityDefinition) { if (userInfos.TryGetValue(entityDefinition.userAssembly, out var value)) { return value; } Log.log.LogWarning((object)(entityDefinition.userAssembly.GetName().Name + " was not found among registered users")); return null; } public static Type GetEntityLogicType(Assembly assembly, Type definitionType) { SideloaderUsers[] array = new SideloaderUsers[2] { EntityManager.Instance.sideloaderUsers, EntityManager.Instance.secondaryUsers }; SideloaderUsers[] array2 = array; foreach (SideloaderUsers sideloaderUsers in array2) { if (!sideloaderUsers.userInfos.TryGetValue(assembly, out var value)) { continue; } if (value.definition2customEntityLogicType.TryGetValue(definitionType, out var value2)) { return value2; } if (value.IsForOverwriting(definitionType) && value.definitionInstances.TryGetValue(definitionType, out var value3)) { FieldRef> val = TypeFactoryReflection.AccessTypeDicts(value3.EntityType(), TypeFactoryReflection.TableFieldName.TypeDict); if (val.Invoke((object)null).TryGetValue(value3.UniqueId, out var value4)) { return value4; } } } Log.log.LogError((object)(definitionType.Name + " was not found in " + assembly.GetName().Name + " or " + definitionType.Name + " is not for overwriting")); return null; } } public class TemplateSequenceTable { private static readonly ManualLogSource log = BepinexPlugin.log; private static Dictionary lookUpDic = new Dictionary(); private Dictionary table = new Dictionary(); public TemplateSequenceTable(int startingPoint = 0) { if (CollectionsExtensions.Empty>((IReadOnlyCollection>)lookUpDic)) { foreach (Type item in ConfigReflection.AllConfigTypes()) { lookUpDic.Add(item, item.Name); } foreach (Type item2 in TemplatesReflection.AllTemplateTypes()) { Type? type = item2.GetInterface("IConfigProvider`1"); Type type2 = (((object)type != null) ? type.GenericTypeArguments[0] : null); if (type2 != null) { lookUpDic.Add(item2, type2.Name); } else { lookUpDic.Add(item2, item2.Name); } } } foreach (KeyValuePair item3 in lookUpDic) { table.TryAdd(item3.Value, new Sequence(startingPoint)); } } public Sequence Sequence(Type type) { TestType(type); return table[lookUpDic[type]]; } public int Next(Type type) { TestType(type); return table[lookUpDic[type]].Next(); } private void TestType(Type type) { if (!TemplatesReflection.AllTemplateTypes().Contains(type) && !ConfigReflection.AllConfigTypes().Contains(type)) { throw new ArgumentException($"TemplateSequenceTable: {type} is not a Entity definition template type or a Config type"); } if (!lookUpDic.ContainsKey(type)) { throw new ArgumentException($"TemplateSequenceTable: {type} is not in lookup dictionary. Some templates might not have an associated config type. Try using template type instead."); } } } public class UniqueTracker { public class DefTypePromisePair { public Type entityLogicType; public Func defTypePromise; } public class CharLoadoutInfo { public string ultimateSkill; public string exhibit; public List deck; public int complexity; public string typeSuffix; public string typeName; } public class StageModAction { public string Id; public Func mod; } private static readonly ManualLogSource log = BepinexPlugin.log; private static UniqueTracker _instance; public Dictionary> configIds = new Dictionary>(); public Dictionary> configIndexes = new Dictionary>(); public Dictionary entity2uniqueIds = new Dictionary(); public Dictionary> id2ConfigListIndex = new Dictionary>(); private TemplateSequenceTable tempConfigIndexTable = new TemplateSequenceTable(); public HashSet invalidRegistrations = new HashSet(); public Dictionary>> overwriteTracker = new Dictionary>>(); public Dictionary> generatedAssemblies = new Dictionary>(); public Dictionary gen2User = new Dictionary(); public Dictionary gen2FacType = new Dictionary(); public Dictionary>> typePromiseDic = new Dictionary>>(); public Dictionary> typesToLocalize = new Dictionary>(); public Dictionary>> batchLocalization = new Dictionary>>(); public Dictionary unitNamesGlobalLocalizationFiles = new Dictionary(); public Dictionary> unitIdsToLocalize = new Dictionary>(); public Dictionary> spellEntriesLocFiles = new Dictionary>(); public Dictionary> spellIdsToLocalize = new Dictionary>(); public Dictionary> spellTemplates = new Dictionary>(); public Dictionary> ultimateSkillTemplates = new Dictionary>(); public Dictionary methodCacheDic = new Dictionary(); public List formationAddActions = new List(); public List environmentsAddActions = new List(); public Dictionary> createdEnvObjectCache = new Dictionary>(); public Dictionary> loadoutInfos = new Dictionary>(); public List populateLoadoutInfosActions = new List(); internal Dictionary customGrSaveData = new Dictionary(); public List, List>> modifyStageListFuncs = new List, List>>(); public List modifyStageActions = new List(); public Dictionary> user2PlayerTemplates = new Dictionary>(); public CHandlerManager cHandlerManager = new CHandlerManager(); private Dictionary> intentionSuffixFuncs = null; private Sequence uIdSalt = new Sequence(); private Sequence uIntId = new Sequence(1394); private TemplateSequenceTable indexTable = new TemplateSequenceTable(12000); public Dictionary entity2uniqueIndexes = new Dictionary(); public Dictionary> onDemandResourceTracker = new Dictionary>(); public static UniqueTracker Instance { get { if (_instance == null) { _instance = new UniqueTracker(); _instance.indexTable.Sequence(typeof(BgmConfig)).SetCounter(120); _instance.indexTable.Sequence(typeof(PlayerUnitConfig)).SetCounter(6); _instance.indexTable.Sequence(typeof(ExhibitConfig)).SetCounter(800); } return _instance; } } public Dictionary> IntentionSuffixFuncs { get { if (intentionSuffixFuncs == null) { intentionSuffixFuncs = (from d in EntityManager.Instance.AllUsers.Select(((Assembly ass, UserInfo userInfo) tu) => tu.userInfo).SelectMany((UserInfo ui) => ui.definitionInstances.Values) where d is IntentionTemplate select d).Cast().ToDictionary((Func)((IntentionTemplate it) => it.UniqueId.ToString()), (Func>)((IntentionTemplate it) => it.SelectAltIconsSuffix)); } return intentionSuffixFuncs; } } internal event Action PostMainLoad; internal static void DestroySelf() { _instance = null; } public void RaisePostMainLoad() { if (this.PostMainLoad == null) { ManualLogSource obj = Log.LogDev(); if (obj != null) { obj.LogInfo((object)"No template generation was queued."); } return; } this.PostMainLoad(); generatedAssemblies.Values.ToList().ForEach(delegate(List l) { l.ForEach(delegate(Assembly a) { EntityManager.Instance.secondaryUsers.AddUser(a); }); }); foreach (KeyValuePair item in gen2User) { if (!gen2FacType.TryGetValue(item.Key, out var value) || !typePromiseDic.TryGetValue(item.Value, out var value2)) { continue; } foreach (DefTypePromisePair item2 in value2[value]) { Type type = item2.defTypePromise(); EntityInfo entityInfo = new EntityInfo(value, item2.entityLogicType, type); UserInfo userInfo = EntityManager.Instance.secondaryUsers.userInfos[item.Key]; userInfo.entityInfos.TryAdd(value, new List()); userInfo.entityInfos[value].Add(entityInfo); userInfo.definition2customEntityLogicType.Add(type, entityInfo.entityType); } } } public bool IsLoadedOnDemand(Type templateType, string Id, out EntityDefinition entityDefinition) { entityDefinition = null; onDemandResourceTracker.TryGetValue(templateType, out var value); return value?.TryGetValue(Id, out entityDefinition) ?? false; } public bool AddOnDemandResource(Type templateType, string Id, EntityDefinition definition) { onDemandResourceTracker.TryAdd(templateType, new Dictionary()); return onDemandResourceTracker[templateType].TryAdd(Id, definition); } public static bool IsOverwriten(Type templateType, IdContainer id, string component, Type definitionType, UserInfo user) { Instance.overwriteTracker.TryAdd(templateType, new Dictionary>()); Dictionary> dictionary = Instance.overwriteTracker[templateType]; if (dictionary.TryGetValue(id, out var value)) { if (value.TryGetValue(component, out var value2)) { if (!value2.defType.Equals(definitionType)) { log.LogError((object)$"{user.assembly.GetName().Name} definition {definitionType.Name} is trying to change {component} of {id} but it's already modified by {value2.user.assembly.GetName().Name} definition {value2.defType.Name}."); return true; } return false; } value.Add(component, new OverwriteInfo { defType = definitionType, user = user }); return false; } dictionary.Add(id, new Dictionary()); dictionary[id].Add(component, new OverwriteInfo { defType = definitionType, user = user }); return false; } internal static void TrackVanillaConfig(object config, bool allowDuplicateIndex = false) { Instance.configIds.TryAdd(config.GetType(), new HashSet()); HashSet hashSet = Instance.configIds[config.GetType()]; FieldInfo idField = ConfigReflection.GetIdField(config.GetType()); IdContainer idContainer = IdContainer.CastFromObject(idField.GetValue(config)); if (hashSet.Contains(idContainer)) { log.LogDebug((object)idContainer); log.LogWarning((object)$"duplicate id: {idContainer} in {config.GetType()}"); } else { hashSet.Add(idContainer); } FieldInfo fieldInfo = ConfigReflection.HasIndex(config.GetType()); if (fieldInfo != null) { Instance.configIndexes.TryAdd(config.GetType(), new HashSet()); Instance.configIndexes.TryGetValue(config.GetType(), out var value); int num = (int)fieldInfo.GetValue(config); if (value.Contains(num) && !allowDuplicateIndex) { log.LogDebug((object)$"index: {num}"); log.LogWarning((object)$"duplicate id: {num} in {config.GetType()}"); } else { value.Add(num); } } Instance.id2ConfigListIndex.TryAdd(config.GetType(), new Dictionary()); Instance.id2ConfigListIndex[config.GetType()].Add(idContainer, Instance.tempConfigIndexTable.Next(config.GetType())); } public static IdContainer GetUniqueId(IdContainer id) { throw new NotImplementedException(); } public static IdContainer GetUniqueId(EntityDefinition entityDefinition) { if (Instance.entity2uniqueIds.TryGetValue(entityDefinition.GetType(), out var value)) { return value; } return entityDefinition.GetId(); } internal static void AddUniqueId(EntityDefinition entityDefinition, UserInfo userInfo) { IdContainer id = entityDefinition.GetId(); Type key = entityDefinition.ConfigType(); Instance.configIds.TryAdd(key, new HashSet()); HashSet hashSet = Instance.configIds[key]; if (hashSet.Contains(id)) { throw new NotImplementedException($"Uniquefying ids is not supported yet. {userInfo.GUID} is trying to register {entityDefinition.TemplateType().Name} id {id} which already used by either vanilla entities or other mods."); } hashSet.Add(id); } internal static IdContainer MakeUniqueId(IdContainer id, EntityDefinition entityDefinition, UserInfo userInfo) { if (id.idType == IdContainer.IdType.String) { string text = userInfo.GUID + id; if (Instance.configIds[entityDefinition.ConfigType()].Contains(text)) { text += Instance.uIdSalt.Next(); } return text; } if (id.idType == IdContainer.IdType.Int) { throw new NotImplementedException(); } throw new NotImplementedException(); } internal static int AddUniqueIndex(int index, EntityDefinition entityDefinition) { int num = Instance.indexTable.Sequence(entityDefinition.ConfigType()).Counter; HashSet hashSet = Instance.configIndexes[entityDefinition.ConfigType()]; while (hashSet.Contains(index + num)) { num = Instance.indexTable.Next(entityDefinition.ConfigType()); } hashSet.Add(index + num); return index + num; } } } namespace LBoLEntitySideloader.Utils { public static class AssemblyExtensions { public static bool IsLoadedFromDisk(this Assembly assembly) { return !assembly.IsDynamic && !string.IsNullOrEmpty(assembly.Location); } } public static class GameObjectExtensions { public static IEnumerable IterateHierarchy(this Transform root) { Queue queue = new Queue(); queue.Enqueue(root); while (queue.Count > 0) { Transform current = queue.Dequeue(); yield return ((Component)current).gameObject; foreach (Transform item in current) { Transform child = item; queue.Enqueue(child); } } } public static T JankyCopyComponent(this GameObject destination, T original) where T : Component { Type type = ((object)original).GetType(); Component val = destination.AddComponent(type); BindingFlags bindingAttr = BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; PropertyInfo[] properties = type.GetProperties(bindingAttr); FieldInfo[] fields = type.GetFields(bindingAttr); PropertyInfo[] array = properties; foreach (PropertyInfo propertyInfo in array) { if (!propertyInfo.CanWrite) { continue; } try { propertyInfo.SetValue(val, propertyInfo.GetValue(original, null), null); } catch (Exception ex) { ManualLogSource obj = Log.LogDev(); if (obj != null) { obj.LogWarning((object)$"Exception while copying gameObject {((Object)destination).name}, component {typeof(T)}, property {propertyInfo.Name}: {ex}"); } } } FieldInfo[] array2 = fields; foreach (FieldInfo fieldInfo in array2) { fieldInfo.SetValue(val, fieldInfo.GetValue(original)); } return (T)(object)((val is T) ? val : null); } } public static class Numbers { public static string DecimalToABC(long decimalNumber, int radix = 26) { if (radix < 2 || radix > "ABCDEFGHIJKLMNOPQRSTUVWXYZ".Length) { throw new ArgumentException("The radix must be >= 2 and <= " + "ABCDEFGHIJKLMNOPQRSTUVWXYZ".Length); } if (decimalNumber == 0) { return "0"; } int num = 63; long num2 = Math.Abs(decimalNumber); char[] array = new char[64]; while (num2 != 0) { int index = (int)(num2 % radix); array[num--] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"[index]; num2 /= radix; } string text = new string(array, num + 1, 64 - num - 1); if (decimalNumber < 0) { text = "-" + text; } return text; } } public static class ObjectExtensions { private static readonly MethodInfo CloneMethod = typeof(object).GetMethod("MemberwiseClone", BindingFlags.Instance | BindingFlags.NonPublic); public static bool IsPrimitive(this Type type) { if (type == typeof(string)) { return true; } return type.IsValueType & type.IsPrimitive; } public static object Copy(this object originalObject) { return InternalCopy(originalObject, new Dictionary(new ReferenceEqualityComparer())); } private static object InternalCopy(object originalObject, IDictionary visited) { if (originalObject == null) { return null; } Type type = originalObject.GetType(); if (type.IsPrimitive()) { return originalObject; } if (visited.ContainsKey(originalObject)) { return visited[originalObject]; } if (typeof(Delegate).IsAssignableFrom(type)) { return null; } object obj = CloneMethod.Invoke(originalObject, null); if (type.IsArray) { Type elementType = type.GetElementType(); if (!elementType.IsPrimitive()) { Array clonedArray = (Array)obj; clonedArray.ForEach(delegate(Array array, int[] indices) { array.SetValue(InternalCopy(clonedArray.GetValue(indices), visited), indices); }); } } visited.Add(originalObject, obj); CopyFields(originalObject, visited, obj, type); RecursiveCopyBaseTypePrivateFields(originalObject, visited, obj, type); return obj; } private static void RecursiveCopyBaseTypePrivateFields(object originalObject, IDictionary visited, object cloneObject, Type typeToReflect) { if (typeToReflect.BaseType != null) { RecursiveCopyBaseTypePrivateFields(originalObject, visited, cloneObject, typeToReflect.BaseType); CopyFields(originalObject, visited, cloneObject, typeToReflect.BaseType, BindingFlags.Instance | BindingFlags.NonPublic, (FieldInfo info) => info.IsPrivate); } } private static void CopyFields(object originalObject, IDictionary visited, object cloneObject, Type typeToReflect, BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy, Func filter = null) { FieldInfo[] fields = typeToReflect.GetFields(bindingFlags); foreach (FieldInfo fieldInfo in fields) { if ((filter == null || filter(fieldInfo)) && !fieldInfo.FieldType.IsPrimitive()) { object value = fieldInfo.GetValue(originalObject); object value2 = InternalCopy(value, visited); fieldInfo.SetValue(cloneObject, value2); } } } public static T Copy(this T original) { return (T)((object)original).Copy(); } } public class ReferenceEqualityComparer : EqualityComparer { public override bool Equals(object x, object y) { return x == y; } public override int GetHashCode(object obj) { return obj?.GetHashCode() ?? 0; } } } namespace LBoLEntitySideloader.Utils.ArrayExtensions { public static class ArrayExtensions { public static void ForEach(this Array array, Action action) { if (array.LongLength != 0) { ArrayTraverse arrayTraverse = new ArrayTraverse(array); do { action(array, arrayTraverse.Position); } while (arrayTraverse.Step()); } } } internal class ArrayTraverse { public int[] Position; private int[] maxLengths; public ArrayTraverse(Array array) { maxLengths = new int[array.Rank]; for (int i = 0; i < array.Rank; i++) { maxLengths[i] = array.GetLength(i) - 1; } Position = new int[array.Rank]; } public bool Step() { for (int i = 0; i < Position.Length; i++) { if (Position[i] < maxLengths[i]) { Position[i]++; for (int j = 0; j < i; j++) { Position[j] = 0; } return true; } } return false; } } } namespace LBoLEntitySideloader.Utils.EnumExtender { [HarmonyPatch] internal static class EnumInfoPatch { static EnumInfoPatch() { } private static MethodBase TargetMethod() { return AccessTools.Method(Type.GetType("System.Enum"), "GetCachedValuesAndNames", (Type[])null, (Type[])null); } private static void FixEnum(object type, ref ulong[] oldValues, ref string[] oldNames) { Type enumType = type as Type; if (!EnumPatcher.TryGetRawPatch(enumType, out var patch)) { return; } List> pairs = patch.GetPairs(); List list = new List(oldValues); List list2 = new List(oldNames); foreach (KeyValuePair item in pairs) { list.Add(item.Key); list2.Add(item.Value); } oldValues = list.ToArray(); oldNames = list2.ToArray(); Array.Sort(oldValues, oldNames, Comparer.Default); } private static IEnumerable Transpiler(IEnumerable instructions) { using IEnumerator enumerator = instructions.GetEnumerator(); while (enumerator.MoveNext()) { CodeInstruction v = enumerator.Current; object operand = v.operand; if (operand is MethodInfo me && me.Name == "Sort") { yield return v; enumerator.MoveNext(); v = enumerator.Current; List