Decompiled source of LessRam v1.0.0

plugins/LessRam.dll

Decompiled a day ago
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.Threading.Tasks;
using BepInEx;
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.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("LessRam")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("title")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+7d71697ca382adf5af0d40e7ade6ee4587cf1667")]
[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 <LoadAudio>d__2 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public VGLevel _level;

			private VGLevelWrapper <levelRealm>5__1;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <LoadAudio>d__2(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<levelRealm>5__1 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_00db: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e5: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					audioLoading = 1;
					<levelRealm>5__1 = LessRam.Levels.GetValueOrDefault(((Object)_level).name, null);
					<>2__current = ThreadNinjaMonoBehaviourExtensions.StartCoroutineAsync((MonoBehaviour)(object)DataManager.inst, LevelLoaderHelper.LoadAudio(_level, <levelRealm>5__1.AudioPath));
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					<>2__current = ThreadNinjaMonoBehaviourExtensions.StartCoroutineAsync((MonoBehaviour)(object)DataManager.inst, LevelLoaderHelper.LoadImage(_level, <levelRealm>5__1.ImagePath));
					<>1__state = 2;
					return true;
				case 2:
					<>1__state = -1;
					SingletonBase<GameManager>.Inst.LevelAudio = _level.LevelMusic;
					<>2__current = (object)new WaitForEndOfFrame();
					<>1__state = 3;
					return true;
				case 3:
					<>1__state = -1;
					SingletonBase<GameManager>.Inst.CurLoadingState.Audio = true;
					audioLoading = 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();
			}
		}

		private static int audioLoading;

		[HarmonyPrefix]
		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		public static bool PreLoadAudio(ref bool __result)
		{
			if (!SingletonBase<GameManager>.Inst.IsArcade || Object.op_Implicit((Object)(object)SingletonBase<ArcadeManager>.Inst.CurrentArcadeLevel.LevelMusic))
			{
				return true;
			}
			if (audioLoading == 0)
			{
				((MonoBehaviour)DataManager.inst).StartCoroutine(LoadAudio(SingletonBase<ArcadeManager>.Inst.CurrentArcadeLevel));
			}
			if (audioLoading == 2)
			{
				audioLoading = 0;
			}
			__result = audioLoading == 1;
			return false;
		}

		[IteratorStateMachine(typeof(<LoadAudio>d__2))]
		private static IEnumerator LoadAudio(VGLevel _level)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <LoadAudio>d__2(0)
			{
				_level = _level
			};
		}

		[HarmonyPatch("PlayGame")]
		[HarmonyPostfix]
		private static void OnPlayGame()
		{
			ArcadeMenuPatch.CleanLevels();
		}
	}
	public static class LevelLoaderHelper
	{
		[CompilerGenerated]
		private sealed class <LoadAudio>d__0 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public VGLevel level;

			public string path;

			private DownloadHandlerAudioClip <handler>5__1;

			private UnityWebRequest <audioUwr>5__2;

			private AudioClip <audioClip>5__3;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <LoadAudio>d__0(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<handler>5__1 = null;
				<audioUwr>5__2 = null;
				<audioClip>5__3 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0037: Unknown result type (might be due to invalid IL or missing references)
				//IL_0041: Expected O, but got Unknown
				//IL_0061: Unknown result type (might be due to invalid IL or missing references)
				//IL_006b: Expected O, but got Unknown
				//IL_0092: Unknown result type (might be due to invalid IL or missing references)
				//IL_0098: Invalid comparison between Unknown and I4
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<handler>5__1 = new DownloadHandlerAudioClip(path, (AudioType)14);
					<handler>5__1.streamAudio = true;
					<audioUwr>5__2 = new UnityWebRequest(path, "GET", (DownloadHandler)(object)<handler>5__1, (UploadHandler)null);
					<>2__current = <audioUwr>5__2.SendWebRequest();
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					if ((int)<audioUwr>5__2.result != 1)
					{
						LessRam.Logger.LogError((object)<audioUwr>5__2.error);
						<audioUwr>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))
					{
						<audioUwr>5__2.Dispose();
						return false;
					}
					<audioClip>5__3 = DownloadHandlerAudioClip.GetContent(<audioUwr>5__2);
					<audioUwr>5__2.Dispose();
					if (!Object.op_Implicit((Object)(object)<audioClip>5__3))
					{
						LessRam.Logger.LogError((object)("Remove invalid song from arcade. No audio file. [" + ((Object)level).name + "]"));
						return false;
					}
					ArcadeMenuPatch.activeClips.Add(<audioClip>5__3);
					((Object)<audioClip>5__3).name = ((Object)level).name;
					level.LevelMusic = <audioClip>5__3;
					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 <LoadImage>d__1 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public VGLevel level;

			public string path;

			private Sprite <albumArt>5__1;

			private UnityWebRequest <uwr>5__2;

			private Texture2D <texture>5__3;

			private int <width>5__4;

			private int <height>5__5;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <LoadImage>d__1(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<albumArt>5__1 = null;
				<uwr>5__2 = null;
				<texture>5__3 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_006e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0074: Invalid comparison between Unknown and I4
				//IL_0124: Unknown result type (might be due to invalid IL or missing references)
				//IL_0133: Unknown result type (might be due to invalid IL or missing references)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<albumArt>5__1 = null;
					<uwr>5__2 = UnityWebRequestTexture.GetTexture(path, false);
					<>2__current = <uwr>5__2.SendWebRequest();
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					if ((int)<uwr>5__2.result != 1)
					{
						LessRam.Logger.LogError((object)<uwr>5__2.error);
						<uwr>5__2.Dispose();
						return false;
					}
					<texture>5__3 = DownloadHandlerTexture.GetContent(<uwr>5__2);
					<width>5__4 = ((Texture)<texture>5__3).width;
					<height>5__5 = ((Texture)<texture>5__3).height;
					if (<width>5__4 <= 512 && <height>5__5 <= 512 && <width>5__4 == <height>5__5)
					{
						<albumArt>5__1 = Sprite.Create(<texture>5__3, new Rect(0f, 0f, (float)<width>5__4, (float)<height>5__5), new Vector2(0.5f, 0.5f), 72f, 0u, (SpriteMeshType)0);
					}
					<uwr>5__2.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)<texture>5__3);
						Object.Destroy((Object)(object)<albumArt>5__1);
						return false;
					}
					ArcadeMenuPatch.activeSprites.Add(<albumArt>5__1);
					level.AlbumArt = <albumArt>5__1;
					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(<LoadAudio>d__0))]
		public static IEnumerator LoadAudio(VGLevel level, string path)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <LoadAudio>d__0(0)
			{
				level = level,
				path = path
			};
		}

		[IteratorStateMachine(typeof(<LoadImage>d__1))]
		public static IEnumerator LoadImage(VGLevel level, string path)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <LoadImage>d__1(0)
			{
				level = level,
				path = path
			};
		}
	}
	public static class VGLevelExtension
	{
		public static bool InitSteamInfoFix(this VGLevel level, ulong _id, string _folder)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected O, but got Unknown
			//IL_0028: 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_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: 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.0")]
	[BepInProcess("Project Arrhythmia.exe")]
	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.0";

		internal static readonly Dictionary<string, VGLevelWrapper> Levels = new Dictionary<string, VGLevelWrapper>();

		internal static ManualLogSource Logger;

		private void Awake()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			Logger = ((BaseUnityPlugin)this).Logger;
			_harmony = new Harmony("me.ytarame.LessRam");
			_harmony.PatchAll();
			Logger.LogError((object)"Plugin me.ytarame.LessRam is loaded!");
		}
	}
	[HarmonyPatch(typeof(SteamWorkshopFacepunch))]
	public static class SteamWorkshopPatch
	{
		[HarmonyPatch("DownloadLevels")]
		[HarmonyPrefix]
		public static bool PreStart(SteamWorkshopFacepunch __instance, ref Task __result)
		{
			__result = LoadLevels(__instance);
			return false;
		}

		private static async Task LoadLevels(SteamWorkshopFacepunch facepunch)
		{
			Stopwatch stopWatch = new Stopwatch();
			stopWatch.Start();
			facepunch.TotalSteamWorkshopSubscriptions = 0;
			facepunch.TotalSteamWorkshopSubscriptionsDone = 0;
			Query val = Query.ItemsReadyToUse;
			val = ((Query)(ref val)).WhereUserSubscribed(default(SteamId));
			Query q = ((Query)(ref val)).SortByCreationDate();
			int pageNum = 1;
			ResultPage? resultPage = await ((Query)(ref q)).GetPageAsync(pageNum);
			if (!resultPage.HasValue)
			{
				stopWatch.Stop();
				LessRam.Logger.LogError((object)$"Level loading failure [{stopWatch.ElapsedMilliseconds}]");
				return;
			}
			facepunch.TotalSteamWorkshopSubscriptions = resultPage.Value.TotalCount;
			while (resultPage.HasValue && resultPage.Value.ResultCount > 0 && !SingletonBase<ArcadeManager>.Inst.skippedLoad)
			{
				SteamWorkshopFacepunch.inst.isLoadingLevels = true;
				ResultPage value = resultPage.Value;
				foreach (Item entry2 in ((ResultPage)(ref value)).Entries)
				{
					Item entry = entry2;
					if (SingletonBase<ArcadeManager>.Inst.skippedLoad)
					{
						return;
					}
					if (((Item)(ref entry)).IsInstalled)
					{
						CreateEntry(facepunch, entry);
					}
					entry = default(Item);
				}
				pageNum++;
				resultPage = await ((Query)(ref q)).GetPageAsync(pageNum);
			}
			stopWatch.Stop();
			SteamWorkshopFacepunch.inst.isLoadingLevels = false;
			LessRam.Logger.LogInfo((object)$"Time to load levels [{stopWatch.ElapsedMilliseconds}ms]");
		}

		private static void CreateEntry(SteamWorkshopFacepunch facepunch, Item entry)
		{
			//IL_0003: 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_0038: 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_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: 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)
			{
				Dictionary<string, VGLevelWrapper> levels = LessRam.Levels;
				id = ((Item)(ref entry)).Id;
				levels.Add(((object)(PublishedFileId)(ref id)).ToString(), vGLevelWrapper);
				VGLevel val = ScriptableObject.CreateInstance<VGLevel>();
				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();
					SingletonBase<ArcadeLevelDataManager>.Inst.ArcadeLevels.Add(val);
					facepunch.TotalSteamWorkshopSubscriptionsDone++;
				}
			}
		}

		private static VGLevelWrapper? MakeLevelRealmObject(string id, string directory)
		{
			if (string.IsNullOrEmpty(directory))
			{
				return null;
			}
			VGLevelWrapper vGLevelWrapper = new VGLevelWrapper
			{
				LevelPath = directory
			};
			FileTypeDefinition fileTypeInfo = DataManager.inst.GetFileTypeInfo((FileType)5);
			string text = directory + "\\" + fileTypeInfo.CurrentFile;
			if (!LSFile.FileExists(text))
			{
				text = directory + "\\" + fileTypeInfo.LegacyFile;
			}
			vGLevelWrapper.ImagePath = text;
			FileTypeDefinition fileTypeInfo2 = DataManager.inst.GetFileTypeInfo((FileType)2);
			string text2 = directory + "\\" + fileTypeInfo2.CurrentFile;
			if (!LSFile.FileExists(text2))
			{
				text2 = directory + "\\" + fileTypeInfo2.LegacyFile;
			}
			vGLevelWrapper.AudioPath = text2;
			return vGLevelWrapper;
		}
	}
	[HarmonyPatch(typeof(ArcadeMenu))]
	public static class ArcadeMenuPatch
	{
		[CompilerGenerated]
		private sealed class <>c__DisplayClass5_0
		{
			public ArcadeButtonRefs button;

			internal void <SelectPage>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 <CreateButton>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 <CreateButton>b__3()
			{
				arcadeMenu.PlaySongPreview(level);
			}

			internal void <CreateButton>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 <CreateButton>b__4()
			{
				arcadeMenu.PlaySongPreview(level);
			}

			internal void <CreateButton>b__2()
			{
				arcadeMenu.LastSelectedButtonOffset = 0;
				arcadeMenu.LastSelectedButton = ((Component)button.Button).gameObject;
				arcadeMenu.selectedLevelGO = ((Component)button.Button).gameObject;
				if (SingletonBase<AudioManager>.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 <CreateButton>d__6 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public ArcadeButtonRefs button;

			public VGLevel level;

			public ArcadeMenu arcadeMenu;

			private <>c__DisplayClass6_0 <>8__1;

			private VGLevelWrapper <levelRealm>5__2;

			private DifficultySetting <difficulty>5__3;

			private Task <task1>5__4;

			private Task <task2>5__5;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <CreateButton>d__6(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>8__1 = null;
				<levelRealm>5__2 = null;
				<difficulty>5__3 = null;
				<task1>5__4 = null;
				<task2>5__5 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_016d: Unknown result type (might be due to invalid IL or missing references)
				//IL_024f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0259: Expected O, but got Unknown
				//IL_032f: 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;
					<levelRealm>5__2 = LessRam.Levels.GetValueOrDefault(((Object)<>8__1.level).name, null);
					if (<levelRealm>5__2 != null)
					{
						ThreadNinjaMonoBehaviourExtensions.StartCoroutineAsync((MonoBehaviour)(object)<>8__1.arcadeMenu, LevelLoaderHelper.LoadAudio(<>8__1.level, <levelRealm>5__2.AudioPath), ref <task1>5__4);
						ThreadNinjaMonoBehaviourExtensions.StartCoroutineAsync((MonoBehaviour)(object)<>8__1.arcadeMenu, LevelLoaderHelper.LoadImage(<>8__1.level, <levelRealm>5__2.ImagePath), ref <task2>5__5);
						<>2__current = <task1>5__4.Wait();
						<>1__state = 1;
						return true;
					}
					break;
				case 1:
					<>1__state = -1;
					<>2__current = <task2>5__5.Wait();
					<>1__state = 2;
					return true;
				case 2:
					<>1__state = -1;
					<task1>5__4 = null;
					<task2>5__5 = null;
					break;
				}
				<difficulty>5__3 = <>8__1.arcadeMenu.GetDifficulty(<>8__1.level.Difficulty);
				((Component)<>8__1.button.Button).GetComponent<DirectedNavigation>().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<AudioManager>.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>5__3);
				<>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<SavesManager>.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<DirectedNavigation>().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 <SelectPage>d__5 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public int _page;

			public bool _forceButton;

			public ArcadeMenu arcadeMenu;

			private int <startIndex>5__1;

			private int <endIndex>5__2;

			private int <buttonIndex>5__3;

			private List<ArcadeButtonRefs>.Enumerator <>s__4;

			private <>c__DisplayClass5_0 <>8__5;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <SelectPage>d__5(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>s__4 = default(List<ArcadeButtonRefs>.Enumerator);
				<>8__5 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_021b: 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)
				if (<>1__state != 0)
				{
					return false;
				}
				<>1__state = -1;
				CleanLevels();
				if (arcadeMenu.Page != _page)
				{
					SingletonBase<AudioManager>.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;
					<startIndex>5__1 = _page * 12;
					<endIndex>5__2 = Mathf.Clamp(<startIndex>5__1 + 12, 0, arcadeMenu.SearchedLevels.Count - 1) - <startIndex>5__1;
					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();
					<buttonIndex>5__3 = 0;
					<>s__4 = arcadeMenu.LevelButtons.GetEnumerator();
					try
					{
						while (<>s__4.MoveNext())
						{
							<>8__5 = new <>c__DisplayClass5_0();
							<>8__5.button = <>s__4.Current;
							if (<buttonIndex>5__3 > <endIndex>5__2)
							{
								<>8__5.button.Button.ClearActions();
								<>8__5.button.Button.LockButtonState(true);
								((UnityEventBase)((Button)<>8__5.button.Button).onClick).RemoveAllListeners();
								if (((UIElement)<>8__5.button.LevelButton).IsVisible)
								{
									LSHelpers.Delay(Random.Range(0f, 0.025f), (Action)delegate
									{
										((UIElement)<>8__5.button.LevelButton).Hide((Action)null);
									});
								}
							}
							else
							{
								activeCoroutines.Add(((MonoBehaviour)SingletonBase<ArcadeLevelDataManager>.Inst).StartCoroutine(CreateButton(<>8__5.button, arcadeMenu.SearchedLevels[<startIndex>5__1 + <buttonIndex>5__3], arcadeMenu)));
							}
							<buttonIndex>5__3++;
							<>8__5 = null;
						}
					}
					finally
					{
						((IDisposable)<>s__4).Dispose();
					}
					<>s__4 = default(List<ArcadeButtonRefs>.Enumerator);
				}
				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<Coroutine> activeCoroutines = new List<Coroutine>();

		public static readonly List<Sprite> activeSprites = new List<Sprite>();

		public static readonly List<AudioClip> activeClips = new List<AudioClip>();

		[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<ArcadeLevelDataManager>.Inst).StopCoroutine(activeCoroutine);
				}
			}
			activeCoroutines.Clear();
			int num = 0;
			while (num < activeClips.Count)
			{
				if (Object.op_Implicit((Object)(object)activeClips[num]) && (Object)(object)SingletonBase<AudioManager>.Inst.CurrentAudioClip != (Object)(object)activeClips[num] && (!Object.op_Implicit((Object)(object)SingletonBase<ArcadeManager>.Inst.CurrentArcadeLevel) || (Object)(object)SingletonBase<ArcadeManager>.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<ArcadeManager>.Inst.CurrentArcadeLevel) || (Object)(object)SingletonBase<ArcadeManager>.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(<SelectPage>d__5))]
		private static IEnumerator SelectPage(int _page, bool _forceButton, ArcadeMenu arcadeMenu)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <SelectPage>d__5(0)
			{
				_page = _page,
				_forceButton = _forceButton,
				arcadeMenu = arcadeMenu
			};
		}

		[IteratorStateMachine(typeof(<CreateButton>d__6))]
		private static IEnumerator CreateButton(ArcadeButtonRefs button, VGLevel level, ArcadeMenu arcadeMenu)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <CreateButton>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));
				}
			}
		}
	}
	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";
	}
}