using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Threading; using System.Threading.Tasks; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using CielaSpike; using HarmonyLib; using IEVO.UI.uGUIDirectedNavigation; using Microsoft.CodeAnalysis; using Steamworks; using Steamworks.Data; using Steamworks.Ugc; using UnityEngine; using UnityEngine.Events; using UnityEngine.Networking; using UnityEngine.UI; using VGFunctions; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("LessRam")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("title")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+b606bc14cb33cf244d90c967169f456fcefc0d82")] [assembly: AssemblyProduct("LessRam")] [assembly: AssemblyTitle("LessRam")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace LessRam { [HarmonyPatch(typeof(GameManager))] public static class GameManagerPatch { [CompilerGenerated] private sealed class d__1 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public VGLevel _level; private VGLevelWrapper 5__2; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__1(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { 5__2 = null; <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; 5__2 = LessRam.Levels.GetValueOrDefault(((Object)_level).name, null); <>2__current = ThreadNinjaMonoBehaviourExtensions.StartCoroutineAsync((MonoBehaviour)(object)DataManager.inst, LevelLoaderHelper.LoadAudio(_level, 5__2.AudioPath)); <>1__state = 1; return true; case 1: <>1__state = -1; <>2__current = ThreadNinjaMonoBehaviourExtensions.StartCoroutineAsync((MonoBehaviour)(object)DataManager.inst, LevelLoaderHelper.LoadImage(_level, 5__2.ImagePath)); <>1__state = 2; return true; case 2: <>1__state = -1; SingletonBase.Inst.LevelAudio = _level.LevelMusic; SingletonBase.Inst.CurLoadingState.Audio = true; return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [HarmonyPatch("LoadAudio")] [HarmonyPrefix] public static bool PreLoadAudio(ref IEnumerator __result, VGLevel _level) { if (!SingletonBase.Inst.IsArcade || Object.op_Implicit((Object)(object)_level.LevelMusic)) { return true; } __result = LoadAudio(SingletonBase.Inst.CurrentArcadeLevel); return false; } [IteratorStateMachine(typeof(d__1))] private static IEnumerator LoadAudio(VGLevel _level) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__1(0) { _level = _level }; } [HarmonyPatch("PlayGame")] [HarmonyPostfix] private static void OnPlayGame() { ArcadeMenuPatch.CleanLevels(); } } public static class LevelLoaderHelper { [CompilerGenerated] private sealed class d__0 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public string path; public VGLevel level; private UnityWebRequest 5__2; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__0(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { 5__2 = null; <>1__state = -2; } private bool MoveNext() { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Expected O, but got Unknown //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Invalid comparison between Unknown and I4 switch (<>1__state) { default: return false; case 0: { <>1__state = -1; DownloadHandlerAudioClip val = new DownloadHandlerAudioClip(path, (AudioType)14); val.streamAudio = true; 5__2 = new UnityWebRequest(path, "GET", (DownloadHandler)(object)val, (UploadHandler)null); <>2__current = 5__2.SendWebRequest(); <>1__state = 1; return true; } case 1: <>1__state = -1; if ((int)5__2.result != 1) { LessRam.Logger.LogError((object)5__2.error); 5__2.Dispose(); return false; } <>2__current = Ninja.JumpToUnity; <>1__state = 2; return true; case 2: { <>1__state = -1; if (!Object.op_Implicit((Object)(object)level)) { 5__2.Dispose(); return false; } AudioClip content = DownloadHandlerAudioClip.GetContent(5__2); 5__2.Dispose(); if (!Object.op_Implicit((Object)(object)content)) { LessRam.Logger.LogError((object)("Remove invalid song from arcade. No audio file. [" + ((Object)level).name + "]")); return false; } ArcadeMenuPatch.activeClips.Add(content); ((Object)content).name = ((Object)level).name; level.LevelMusic = content; return false; } } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class d__1 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public string path; public VGLevel level; private Sprite 5__2; private UnityWebRequest 5__3; private Texture2D 5__4; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__1(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { 5__2 = null; 5__3 = null; 5__4 = null; <>1__state = -2; } private bool MoveNext() { //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Invalid comparison between Unknown and I4 //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) switch (<>1__state) { default: return false; case 0: <>1__state = -1; 5__2 = null; 5__3 = UnityWebRequestTexture.GetTexture(path, false); <>2__current = 5__3.SendWebRequest(); <>1__state = 1; return true; case 1: { <>1__state = -1; if ((int)5__3.result != 1) { LessRam.Logger.LogError((object)5__3.error); 5__3.Dispose(); return false; } 5__4 = DownloadHandlerTexture.GetContent(5__3); int width = ((Texture)5__4).width; int height = ((Texture)5__4).height; if (width <= 512 && height <= 512 && width == height) { 5__2 = Sprite.Create(5__4, new Rect(0f, 0f, (float)width, (float)height), new Vector2(0.5f, 0.5f), 72f, 0u, (SpriteMeshType)0); } 5__3.Dispose(); <>2__current = Ninja.JumpToUnity; <>1__state = 2; return true; } case 2: <>1__state = -1; if (!Object.op_Implicit((Object)(object)level)) { Object.Destroy((Object)(object)5__4); Object.Destroy((Object)(object)5__2); return false; } ArcadeMenuPatch.activeSprites.Add(5__2); level.AlbumArt = 5__2; return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [IteratorStateMachine(typeof(d__0))] public static IEnumerator LoadAudio(VGLevel level, string path) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__0(0) { level = level, path = path }; } [IteratorStateMachine(typeof(d__1))] public static IEnumerator LoadImage(VGLevel level, string path) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__1(0) { level = level, path = path }; } } public static class VGLevelExtension { public static bool InitSteamInfoFix(this VGLevel level, ulong _id, string _folder) { //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) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown //IL_0022: 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_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown if (string.IsNullOrEmpty(_folder)) { return false; } level.SteamInfo = new SteamData { ItemID = PublishedFileId.op_Implicit(_id) }; level.BaseLevelData = new LevelDataBase { LevelID = _id.ToString(), LocalFolder = _folder }; level.LevelData = level.BaseLevelData; return true; } } [BepInPlugin("me.ytarame.LessRam", "LessRam", "1.0.2")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class LessRam : BaseUnityPlugin { private Harmony _harmony; private const string Guid = "me.ytarame.LessRam"; private const string Name = "LessRam"; private const string Version = "1.0.2"; internal static readonly Dictionary Levels = new Dictionary(); internal static ManualLogSource Logger; internal static int SemaphoreCount = 5; private void Awake() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected O, but got Unknown Logger = ((BaseUnityPlugin)this).Logger; _harmony = new Harmony("me.ytarame.LessRam"); _harmony.PatchAll(); SemaphoreCount = ((BaseUnityPlugin)this).Config.Bind(new ConfigDefinition("LessRam", "Semaphore count"), 5, (ConfigDescription)null).Value; Logger.LogInfo((object)"Plugin me.ytarame.LessRam is loaded!"); } } [HarmonyPatch(typeof(SteamWorkshopFacepunch))] public static class SteamWorkshopPatch { private static object _lockObject = new object(); [HarmonyPatch("DownloadLevels")] [HarmonyPrefix] public static bool PreStart(SteamWorkshopFacepunch __instance, ref Task __result) { __result = LoadLevels(__instance); return false; } private static async Task LoadLevels(SteamWorkshopFacepunch facepunch) { SteamWorkshopFacepunch facepunch2 = facepunch; Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); facepunch2.TotalSteamWorkshopSubscriptions = 0; facepunch2.TotalSteamWorkshopSubscriptionsDone = 0; SteamWorkshopFacepunch.inst.isLoadingLevels = true; Query val = Query.ItemsReadyToUse; val = ((Query)(ref val)).WhereUserSubscribed(default(SteamId)); Query q = ((Query)(ref val)).SortByCreationDate(); ResultPage? val2 = await ((Query)(ref q)).GetPageAsync(1); if (!val2.HasValue) { stopWatch.Stop(); LessRam.Logger.LogError((object)$"Level loading failure [{stopWatch.ElapsedMilliseconds}]"); return; } facepunch2.TotalSteamWorkshopSubscriptions = val2.Value.TotalCount; ResultPage value = val2.Value; foreach (Item entry in ((ResultPage)(ref value)).Entries) { Item current = entry; if (SingletonBase.Inst.skippedLoad) { return; } if (((Item)(ref current)).IsInstalled) { (VGLevel, VGLevelWrapper)? tuple = CreateEntry(facepunch2, current); if (tuple.HasValue) { LessRam.Levels.Add(((Object)tuple.Value.Item1).name, tuple.Value.Item2); SingletonBase.Inst.ArcadeLevels.Add(tuple.Value.Item1); SteamWorkshopFacepunch obj = facepunch2; obj.TotalSteamWorkshopSubscriptionsDone++; } } } int totalPages = Mathf.CeilToInt((float)val2.Value.TotalCount / (float)val2.Value.ResultCount); SemaphoreSlim semaphore = new SemaphoreSlim(LessRam.SemaphoreCount); try { List tasks = new List(); for (int i = 2; i < totalPages; i++) { await semaphore.WaitAsync(); LessRam.Logger.LogInfo((object)$"loading page {i}"); int iteration = i; tasks.Add(Task.Run(async delegate { try { ResultPage? val3 = await ((Query)(ref q)).GetPageAsync(iteration); if (!val3.HasValue) { LessRam.Logger.LogError((object)$"{iteration} no value"); return; } List<(VGLevel, VGLevelWrapper)> list = new List<(VGLevel, VGLevelWrapper)>(val3.Value.ResultCount); ResultPage value2 = val3.Value; foreach (Item entry2 in ((ResultPage)(ref value2)).Entries) { Item current2 = entry2; if (SingletonBase.Inst.skippedLoad) { return; } if (((Item)(ref current2)).IsInstalled) { (VGLevel, VGLevelWrapper)? tuple2 = CreateEntry(facepunch2, current2); if (tuple2.HasValue) { list.Add(tuple2.Value); } } } lock (_lockObject) { foreach (var item in list) { LessRam.Levels.Add(((Object)item.Item1).name, item.Item2); SingletonBase.Inst.ArcadeLevels.Add(item.Item1); SteamWorkshopFacepunch obj2 = facepunch2; obj2.TotalSteamWorkshopSubscriptionsDone++; } } } finally { semaphore.Release(); } })); } await Task.WhenAll(tasks); stopWatch.Stop(); SteamWorkshopFacepunch.inst.isLoadingLevels = false; LessRam.Logger.LogInfo((object)$"Time to load levels [{stopWatch.ElapsedMilliseconds}ms]"); } finally { if (semaphore != null) { ((IDisposable)semaphore).Dispose(); } } } private static (VGLevel, VGLevelWrapper)? CreateEntry(SteamWorkshopFacepunch facepunch, Item entry) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: 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_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) PublishedFileId id = ((Item)(ref entry)).Id; VGLevelWrapper vGLevelWrapper = MakeLevelRealmObject(((object)(PublishedFileId)(ref id)).ToString(), ((Item)(ref entry)).Directory); if (vGLevelWrapper == null) { return null; } VGLevel val = ScriptableObject.CreateInstance(); if (val.InitArcadeData(((Item)(ref entry)).Directory) && val.InitSteamInfoFix(PublishedFileId.op_Implicit(((Item)(ref entry)).Id), ((Item)(ref entry)).Directory)) { id = ((Item)(ref entry)).Id; ((Object)val).name = ((object)(PublishedFileId)(ref id)).ToString(); return (val, vGLevelWrapper); } return null; } private static VGLevelWrapper? MakeLevelRealmObject(string id, string directory) { if (string.IsNullOrEmpty(directory)) { return null; } VGLevelWrapper obj = new VGLevelWrapper { LevelPath = directory }; FileTypeDefinition fileTypeInfo = DataManager.inst.GetFileTypeInfo((FileType)5); string text = directory + "\\" + fileTypeInfo.CurrentFile; if (!LSFile.FileExists(text)) { text = directory + "\\" + fileTypeInfo.LegacyFile; } obj.ImagePath = text; FileTypeDefinition fileTypeInfo2 = DataManager.inst.GetFileTypeInfo((FileType)2); string text2 = directory + "\\" + fileTypeInfo2.CurrentFile; if (!LSFile.FileExists(text2)) { text2 = directory + "\\" + fileTypeInfo2.LegacyFile; } obj.AudioPath = text2; return obj; } } [HarmonyPatch(typeof(ArcadeMenu))] public static class ArcadeMenuPatch { [CompilerGenerated] private sealed class <>c__DisplayClass5_0 { public ArcadeButtonRefs button; internal void b__0() { ((UIElement)button.LevelButton).Hide((Action)null); } } [CompilerGenerated] private sealed class <>c__DisplayClass6_0 { public ArcadeMenu arcadeMenu; public ArcadeButtonRefs button; public VGLevel level; public Action <>9__3; public Action <>9__4; internal void b__0() { arcadeMenu.LastSelectedButtonOffset = 0; arcadeMenu.LastSelectedButton = ((Component)button.Button).gameObject; arcadeMenu.selectedLevelGO = ((Component)button.Button).gameObject; arcadeMenu._songPreviewDebounce.Run((Action)delegate { arcadeMenu.PlaySongPreview(level); }, 0.6f, (MonoBehaviour)(object)arcadeMenu); } internal void b__3() { arcadeMenu.PlaySongPreview(level); } internal void b__1() { arcadeMenu.LastSelectedButtonOffset = 0; arcadeMenu.LastSelectedButton = ((Component)button.Button).gameObject; arcadeMenu.selectedLevelGO = ((Component)button.Button).gameObject; arcadeMenu._songPreviewDebounce.Run((Action)delegate { arcadeMenu.PlaySongPreview(level); }, 0.3f, (MonoBehaviour)(object)arcadeMenu); } internal void b__4() { arcadeMenu.PlaySongPreview(level); } internal void b__2() { arcadeMenu.LastSelectedButtonOffset = 0; arcadeMenu.LastSelectedButton = ((Component)button.Button).gameObject; arcadeMenu.selectedLevelGO = ((Component)button.Button).gameObject; if (SingletonBase.Inst.currentSongGroup == level.TrackName) { arcadeMenu._songPreviewDebounce.ResetTime((MonoBehaviour)(object)arcadeMenu); } arcadeMenu.SetupSongMenu(level); ((Selectable)arcadeMenu.LeftPageTrigger).interactable = false; ((Selectable)arcadeMenu.RightPageTrigger).interactable = false; arcadeMenu.SetSelectedGO((GameObject)null); arcadeMenu.ViewManager.SwapPage("Song Menu"); } } [CompilerGenerated] private sealed class d__6 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public ArcadeMenu arcadeMenu; public ArcadeButtonRefs button; public VGLevel level; private <>c__DisplayClass6_0 <>8__1; private Task 5__2; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__6(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>8__1 = null; 5__2 = null; <>1__state = -2; } private bool MoveNext() { //IL_0132: 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_0214: Expected O, but got Unknown //IL_02e0: Unknown result type (might be due to invalid IL or missing references) switch (<>1__state) { default: return false; case 0: { <>1__state = -1; <>8__1 = new <>c__DisplayClass6_0(); <>8__1.arcadeMenu = arcadeMenu; <>8__1.button = button; <>8__1.level = level; VGLevelWrapper valueOrDefault = LessRam.Levels.GetValueOrDefault(((Object)<>8__1.level).name, null); if (valueOrDefault != null) { Task val = default(Task); ThreadNinjaMonoBehaviourExtensions.StartCoroutineAsync((MonoBehaviour)(object)<>8__1.arcadeMenu, LevelLoaderHelper.LoadAudio(<>8__1.level, valueOrDefault.AudioPath), ref val); ThreadNinjaMonoBehaviourExtensions.StartCoroutineAsync((MonoBehaviour)(object)<>8__1.arcadeMenu, LevelLoaderHelper.LoadImage(<>8__1.level, valueOrDefault.ImagePath), ref 5__2); <>2__current = val.Wait(); <>1__state = 1; return true; } break; } case 1: <>1__state = -1; <>2__current = 5__2.Wait(); <>1__state = 2; return true; case 2: <>1__state = -1; 5__2 = null; break; } DifficultySetting difficulty = <>8__1.arcadeMenu.GetDifficulty(<>8__1.level.Difficulty); ((Component)<>8__1.button.Button).GetComponent().Active = false; <>8__1.button.Button.LockButtonState(true); ((UnityEventBase)((Button)<>8__1.button.Button).onClick).RemoveAllListeners(); <>8__1.button.Button.ClearActions(); <>8__1.button.Button.OnSelectButton += delegate { <>8__1.arcadeMenu.LastSelectedButtonOffset = 0; <>8__1.arcadeMenu.LastSelectedButton = ((Component)<>8__1.button.Button).gameObject; <>8__1.arcadeMenu.selectedLevelGO = ((Component)<>8__1.button.Button).gameObject; <>8__1.arcadeMenu._songPreviewDebounce.Run((Action)delegate { <>8__1.arcadeMenu.PlaySongPreview(<>8__1.level); }, 0.6f, (MonoBehaviour)(object)<>8__1.arcadeMenu); }; <>8__1.button.Button.OnHoverEnterButton += delegate { <>8__1.arcadeMenu.LastSelectedButtonOffset = 0; <>8__1.arcadeMenu.LastSelectedButton = ((Component)<>8__1.button.Button).gameObject; <>8__1.arcadeMenu.selectedLevelGO = ((Component)<>8__1.button.Button).gameObject; <>8__1.arcadeMenu._songPreviewDebounce.Run((Action)delegate { <>8__1.arcadeMenu.PlaySongPreview(<>8__1.level); }, 0.3f, (MonoBehaviour)(object)<>8__1.arcadeMenu); }; ((UnityEvent)((Button)<>8__1.button.Button).onClick).AddListener((UnityAction)delegate { <>8__1.arcadeMenu.LastSelectedButtonOffset = 0; <>8__1.arcadeMenu.LastSelectedButton = ((Component)<>8__1.button.Button).gameObject; <>8__1.arcadeMenu.selectedLevelGO = ((Component)<>8__1.button.Button).gameObject; if (SingletonBase.Inst.currentSongGroup == <>8__1.level.TrackName) { <>8__1.arcadeMenu._songPreviewDebounce.ResetTime((MonoBehaviour)(object)<>8__1.arcadeMenu); } <>8__1.arcadeMenu.SetupSongMenu(<>8__1.level); ((Selectable)<>8__1.arcadeMenu.LeftPageTrigger).interactable = false; ((Selectable)<>8__1.arcadeMenu.RightPageTrigger).interactable = false; <>8__1.arcadeMenu.SetSelectedGO((GameObject)null); <>8__1.arcadeMenu.ViewManager.SwapPage("Song Menu"); }); <>8__1.button.LevelButton.UpdateTitle(LSText.ClampString(<>8__1.level.TrackName, 20, " -")); <>8__1.button.LevelButton.UpdateDifficulty(difficulty); <>8__1.button.LevelButton.UpdateAlbumArt(<>8__1.level.AlbumArt); <>8__1.button.LevelButton.UpdateContent(<>8__1.arcadeMenu.getLevelButtonContent(<>8__1.level)); <>8__1.button.LevelButton.UpdateRank(SingletonBase.Inst.FetchArcadeSave(<>8__1.level.LevelData.LevelID, true).LevelRank); ((UIElement)<>8__1.button.LevelButton).Stutter(true, (Action)null); ((UIElement)<>8__1.button.LevelButton).Show(0f, 0.1f); ((Component)<>8__1.button.Button).GetComponent().Active = true; <>8__1.button.Button.LockButtonState(false); return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class d__5 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public ArcadeMenu arcadeMenu; public int _page; public bool _forceButton; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__5(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) if (<>1__state != 0) { return false; } <>1__state = -1; CleanLevels(); if (arcadeMenu.Page != _page) { SingletonBase.Inst.PlaySound("PageSwap", 1f); } if (arcadeMenu.SearchedLevels.Count <= 0) { if (arcadeMenu.SearchedLevels.Count > 0) { arcadeMenu.ShowNoResults(); } else { arcadeMenu.ShowNoLevels(); } } else { if (_page < 0 || (arcadeMenu.SearchedLevels.Count > 0 && _page * 12 >= arcadeMenu.SearchedLevels.Count)) { return false; } if (((UIElement)arcadeMenu.NoResults).IsVisible) { ((UIElement)arcadeMenu.NoResults).Hide((Action)null); } if (((UIElement)arcadeMenu.NoLevels).IsVisible) { ((UIElement)arcadeMenu.NoLevels).Hide((Action)null); } if (((UIElement)arcadeMenu.KeyboardButtons[0].UIButton).IsVisible) { arcadeMenu.HideAllKeyboardButtons(); } arcadeMenu.PageIsChanging = true; ((MonoBehaviour)arcadeMenu).StartCoroutine(arcadeMenu.DelayAnim(_forceButton)); arcadeMenu.Page = _page; int num = _page * 12; int num2 = Mathf.Clamp(num + 12, 0, arcadeMenu.SearchedLevels.Count - 1) - num; arcadeMenu.PageSlider.UpdateValueAndRange((float)_page, new Vector2(0f, Mathf.Ceil((float)((arcadeMenu.SearchedLevels.Count - 1) / 12))), new Vector2(0f, 9f)); arcadeMenu.PageSlider.UpdateValue(false); ((Selectable)arcadeMenu.PageSlider.LeftButton).interactable = !arcadeMenu.IsFirstPage(); ((Selectable)arcadeMenu.PageSlider.RightButton).interactable = !arcadeMenu.IsLastPage(); ((Component)arcadeMenu.LeftPageTrigger).gameObject.SetActive(true); ((Component)arcadeMenu.RightPageTrigger).gameObject.SetActive(true); ((Selectable)arcadeMenu.LeftPageTrigger).interactable = !arcadeMenu.IsFirstPage(); ((Selectable)arcadeMenu.RightPageTrigger).interactable = !arcadeMenu.IsLastPage(); int num3 = 0; using List.Enumerator enumerator = arcadeMenu.LevelButtons.GetEnumerator(); while (enumerator.MoveNext()) { <>c__DisplayClass5_0 CS$<>8__locals0 = new <>c__DisplayClass5_0 { button = enumerator.Current }; if (num3 > num2) { CS$<>8__locals0.button.Button.ClearActions(); CS$<>8__locals0.button.Button.LockButtonState(true); ((UnityEventBase)((Button)CS$<>8__locals0.button.Button).onClick).RemoveAllListeners(); if (((UIElement)CS$<>8__locals0.button.LevelButton).IsVisible) { LSHelpers.Delay(Random.Range(0f, 0.025f), (Action)delegate { ((UIElement)CS$<>8__locals0.button.LevelButton).Hide((Action)null); }); } } else { activeCoroutines.Add(((MonoBehaviour)SingletonBase.Inst).StartCoroutine(CreateButton(CS$<>8__locals0.button, arcadeMenu.SearchedLevels[num + num3], arcadeMenu))); } num3++; } } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private static List activeCoroutines = new List(); public static readonly List activeSprites = new List(); public static readonly List activeClips = new List(); [HarmonyPatch("SelectPage", new Type[] { typeof(int), typeof(bool) })] [HarmonyPrefix] private static bool PreSelectPage(int _page, bool _forceButton, ArcadeMenu __instance) { ((MonoBehaviour)__instance).StartCoroutine(SelectPage(_page, _forceButton, __instance)); return false; } public static void CleanLevels() { foreach (Coroutine activeCoroutine in activeCoroutines) { if (activeCoroutine != null) { ((MonoBehaviour)SingletonBase.Inst).StopCoroutine(activeCoroutine); } } activeCoroutines.Clear(); int num = 0; while (num < activeClips.Count) { if (Object.op_Implicit((Object)(object)activeClips[num]) && (Object)(object)SingletonBase.Inst.CurrentAudioClip != (Object)(object)activeClips[num] && (!Object.op_Implicit((Object)(object)SingletonBase.Inst.CurrentArcadeLevel) || (Object)(object)SingletonBase.Inst.CurrentArcadeLevel.LevelMusic != (Object)(object)activeClips[num])) { Object.Destroy((Object)(object)activeClips[num]); activeClips.RemoveAt(num); } else { num++; } } int num2 = 0; while (num2 < activeSprites.Count) { if (Object.op_Implicit((Object)(object)activeSprites[num2]) && (!Object.op_Implicit((Object)(object)SingletonBase.Inst.CurrentArcadeLevel) || (Object)(object)SingletonBase.Inst.CurrentArcadeLevel.AlbumArt != (Object)(object)activeSprites[num2])) { Object.Destroy((Object)(object)activeSprites[num2].texture); Object.Destroy((Object)(object)activeSprites[num2]); activeSprites.RemoveAt(num2); } else { num2++; } } } [IteratorStateMachine(typeof(d__5))] private static IEnumerator SelectPage(int _page, bool _forceButton, ArcadeMenu arcadeMenu) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__5(0) { _page = _page, _forceButton = _forceButton, arcadeMenu = arcadeMenu }; } [IteratorStateMachine(typeof(d__6))] private static IEnumerator CreateButton(ArcadeButtonRefs button, VGLevel level, ArcadeMenu arcadeMenu) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__6(0) { button = button, level = level, arcadeMenu = arcadeMenu }; } } [HarmonyPatch(typeof(ArcadeLevelDataManager))] public static class ArcadeDataPatch { [HarmonyPatch("GetLocalCustomLevel")] [HarmonyPostfix] private static void preGetLevel(ArcadeLevelDataManager __instance, string _id, ref VGLevel __result) { if (Object.op_Implicit((Object)(object)__result) && !Object.op_Implicit((Object)(object)__result.LevelMusic)) { VGLevelWrapper valueOrDefault = LessRam.Levels.GetValueOrDefault(_id, null); if (valueOrDefault != null) { ThreadNinjaMonoBehaviourExtensions.StartCoroutineAsync((MonoBehaviour)(object)__instance, LevelLoaderHelper.LoadAudio(__result, valueOrDefault.AudioPath)); ThreadNinjaMonoBehaviourExtensions.StartCoroutineAsync((MonoBehaviour)(object)__instance, LevelLoaderHelper.LoadImage(__result, valueOrDefault.ImagePath)); } } } } [HarmonyPatch(typeof(LSText))] public static class LSTextPatch { [HarmonyPatch("ClampString")] [HarmonyPrefix] private static bool PreClamp(ref string __result, string _inputStr, int _maxLength, string _end) { if (!SteamWorkshopFacepunch.inst.isLoadingLevels) { return true; } if (string.IsNullOrEmpty(_inputStr) || _inputStr.Length <= _maxLength) { __result = _inputStr; return false; } StringBuilder stringBuilder = new StringBuilder(); if (_end == null) { stringBuilder.Append(_inputStr.Substring(0, _maxLength)); } else { stringBuilder.Append(_inputStr.Substring(0, _maxLength - (_end.Length - 1))); stringBuilder.Append(_end); } __result = stringBuilder.ToString(); return false; } } public class VGLevelWrapper { public string ImagePath { get; set; } public string AudioPath { get; set; } public string LevelPath { get; set; } } public static class MyPluginInfo { public const string PLUGIN_GUID = "LessRam"; public const string PLUGIN_NAME = "LessRam"; public const string PLUGIN_VERSION = "1.0.0"; } }