Decompiled source of BetterJukeboxIL2CPP v1.0.1

Mods/BetterJukebox_Il2CPP.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Threading;
using AudioImportLib;
using BetterJukebox;
using BetterJukebox.Config;
using BetterJukebox.Models;
using BetterJukebox.Patches;
using BetterJukebox.Services;
using HarmonyLib;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppScheduleOne.ObjectScripts;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using Il2CppSystem.Reflection;
using Il2CppTMPro;
using MelonLoader;
using MelonLoader.Preferences;
using MelonLoader.Utils;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: MelonInfo(typeof(Core), "BetterJukebox", "1.0.0", "Bars", null)]
[assembly: MelonGame("TVGS", "Schedule I")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("BetterJukebox_Il2CPP")]
[assembly: AssemblyConfiguration("IL2CPP")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("BetterJukebox_Il2CPP")]
[assembly: AssemblyTitle("BetterJukebox_Il2CPP")]
[assembly: NeutralResourcesLanguage("en-US")]
[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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace BetterJukebox
{
	public class Core : MelonMod
	{
		[CompilerGenerated]
		private sealed class <CheckSavedJukeboxes>d__20 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public Core <>4__this;

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

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

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

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

			private bool MoveNext()
			{
				//IL_0050: Unknown result type (might be due to invalid IL or missing references)
				//IL_005a: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>4__this._config.LogDebug("Waiting for scene to stabilize before checking for saved jukeboxes...");
					<>2__current = (object)new WaitForSeconds(0.5f);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					<>4__this._config.LogDebug("Beginning saved jukebox detection process...");
					<>2__current = <>4__this._jukeboxPatcher.CheckForSavedJukeboxes();
					<>1__state = 2;
					return true;
				case 2:
					<>1__state = -1;
					<>2__current = <>4__this._paginationManager.CheckForSavedJukeboxInterfaces();
					<>1__state = 3;
					return true;
				case 3:
					<>1__state = -1;
					MelonCoroutines.Start(<>4__this.FinalJukeboxCheck());
					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 <FinalJukeboxCheck>d__21 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public Core <>4__this;

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

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

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

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

			private bool MoveNext()
			{
				//IL_0031: Unknown result type (might be due to invalid IL or missing references)
				//IL_003b: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(5f);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					<>4__this._config.LogDebug("Performing final jukebox check...");
					<>2__current = <>4__this._jukeboxPatcher.ScanForJukeboxes(repeat: false);
					<>1__state = 2;
					return true;
				case 2:
					<>1__state = -1;
					<>4__this._paginationManager.CheckForUnpatchedInterfaces();
					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 <InitializationSequence>d__15 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public Core <>4__this;

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

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

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

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

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
				{
					<>1__state = -1;
					<>4__this._config.LogDebug("Starting initialization sequence");
					MelonPreferences_Entry<bool> showLoadingIndicator = <>4__this._config.ShowLoadingIndicator;
					if (showLoadingIndicator != null && showLoadingIndicator.Value)
					{
						<>4__this.CreateLoadingIndicator();
					}
					<>2__current = <>4__this._trackManager.LoadAudioFiles();
					<>1__state = 1;
					return true;
				}
				case 1:
					<>1__state = -1;
					if ((Object)(object)<>4__this._loadingIndicator != (Object)null)
					{
						Object.Destroy((Object)(object)<>4__this._loadingIndicator);
						<>4__this._loadingIndicator = null;
						<>4__this._loadingText = null;
					}
					if (<>4__this._trackManager.TracksLoaded)
					{
						<>4__this._harmonyPatches.SetupPatches();
						<>4__this._patchesApplied = true;
						<>4__this._config.LogDebug("Harmony patches applied");
					}
					<>4__this._initialLoadComplete = true;
					<>4__this._config.LogDebug("Initial loading sequence complete");
					<>2__current = <>4__this.ScanCurrentScene();
					<>1__state = 2;
					return true;
				case 2:
					<>1__state = -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();
			}
		}

		[CompilerGenerated]
		private sealed class <LoadAndPlayTrack>d__29 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public Jukebox jukebox;

			public int trackID;

			public Track track;

			public Action<bool> onComplete;

			public Core <>4__this;

			private Exception <ex>5__1;

			private bool <playSuccess>5__2;

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

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

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

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

			private bool MoveNext()
			{
				//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e2: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = <>4__this._trackManager.EnsureTrackLoaded(track);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					if ((Object)(object)track.Clip == (Object)null)
					{
						<>4__this._config.LogDebug("Failed to load track " + track.TrackName);
						onComplete?.Invoke(obj: false);
						return false;
					}
					<>4__this._config.LogDebug("Track loaded successfully, preparing to play: " + track.TrackName);
					<>2__current = (object)new WaitForSeconds(0.1f);
					<>1__state = 2;
					return true;
				case 2:
					<>1__state = -1;
					try
					{
						<>4__this._config.LogDebug($"Calling jukebox.PlayTrack({trackID}) directly");
						jukebox.PlayTrack(trackID);
						<>4__this._config.LogDebug("Successfully played track " + track.TrackName);
						onComplete?.Invoke(obj: true);
					}
					catch (Exception ex)
					{
						<ex>5__1 = ex;
						<>4__this._config.LogDebug("Failed to play via PlayTrack method, attempting fallback: " + <ex>5__1.Message);
						<playSuccess>5__2 = <>4__this._jukeboxPatcher.ForcePlayTrack(jukebox, trackID);
						<>4__this._config.LogDebug($"Fallback attempt to play track {track.TrackName} result: {<playSuccess>5__2}");
						onComplete?.Invoke(<playSuccess>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();
			}
		}

		[CompilerGenerated]
		private sealed class <ScanCurrentScene>d__18 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public Core <>4__this;

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

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

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

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

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					if (<>4__this._trackManager.TracksLoaded)
					{
						<>4__this._config.LogDebug("Scanning current scene for jukeboxes");
						<>2__current = <>4__this._jukeboxPatcher.ScanForJukeboxes(repeat: false);
						<>1__state = 1;
						return true;
					}
					break;
				case 1:
					<>1__state = -1;
					<>4__this._paginationManager.CheckForUnpatchedInterfaces();
					break;
				}
				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 <UpdateLoadingProgress>d__17 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public Core <>4__this;

			private int <percentage>5__1;

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

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

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

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

			private bool MoveNext()
			{
				//IL_0087: Unknown result type (might be due to invalid IL or missing references)
				//IL_0091: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					break;
				case 1:
					<>1__state = -1;
					break;
				}
				if ((Object)(object)<>4__this._loadingIndicator != (Object)null && (Object)(object)<>4__this._loadingText != (Object)null)
				{
					if (<>4__this._trackManager != null)
					{
						<percentage>5__1 = Mathf.RoundToInt(<>4__this._trackManager.LoadingProgress * 100f);
						((TMP_Text)<>4__this._loadingText).text = $"BetterJukebox: Loading songs... {<percentage>5__1}%";
					}
					<>2__current = (object)new WaitForSeconds(0.1f);
					<>1__state = 1;
					return 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();
			}
		}

		private static Core _instance;

		private ModConfig _config;

		private TrackManager _trackManager;

		private JukeboxPatcher _jukeboxPatcher;

		private PaginationManager _paginationManager;

		private HarmonyPatches _harmonyPatches;

		private object _scanCoroutine;

		private bool _patchesApplied;

		private bool _initialLoadComplete;

		private GameObject _loadingIndicator;

		private TextMeshProUGUI _loadingText;

		private string CustomSongsFolder => Path.Combine(MelonEnvironment.ModsDirectory, "BetterJukebox");

		public override void OnInitializeMelon()
		{
			_instance = this;
			InitializeServices();
			MelonCoroutines.Start(InitializationSequence());
		}

		private void InitializeServices()
		{
			_config = new ModConfig();
			_config.Initialize();
			_trackManager = new TrackManager(_config, CustomSongsFolder);
			_jukeboxPatcher = new JukeboxPatcher(_config, _trackManager);
			_paginationManager = new PaginationManager(_config, _jukeboxPatcher);
			_harmonyPatches = new HarmonyPatches(_jukeboxPatcher, _paginationManager, _trackManager);
		}

		[IteratorStateMachine(typeof(<InitializationSequence>d__15))]
		private IEnumerator InitializationSequence()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <InitializationSequence>d__15(0)
			{
				<>4__this = this
			};
		}

		private void CreateLoadingIndicator()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Expected O, but got Unknown
			//IL_008c: 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_00b8: 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_00e4: 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_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Expected O, but got Unknown
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				_loadingIndicator = new GameObject("BetterJukeboxLoadingIndicator");
				Canvas val = _loadingIndicator.AddComponent<Canvas>();
				val.renderMode = (RenderMode)0;
				val.sortingOrder = 9999;
				CanvasScaler val2 = _loadingIndicator.AddComponent<CanvasScaler>();
				val2.uiScaleMode = (ScaleMode)1;
				val2.referenceResolution = new Vector2(1920f, 1080f);
				GameObject val3 = new GameObject("Panel");
				val3.transform.SetParent(((Component)val).transform, false);
				RectTransform val4 = val3.AddComponent<RectTransform>();
				val4.anchorMin = new Vector2(1f, 0f);
				val4.anchorMax = new Vector2(1f, 0f);
				val4.pivot = new Vector2(1f, 0f);
				val4.anchoredPosition = new Vector2(-10f, 10f);
				val4.sizeDelta = new Vector2(300f, 40f);
				Image val5 = val3.AddComponent<Image>();
				((Graphic)val5).color = new Color(0f, 0f, 0f, 0.7f);
				GameObject val6 = new GameObject("LoadingText");
				val6.transform.SetParent(val3.transform, false);
				RectTransform val7 = val6.AddComponent<RectTransform>();
				val7.anchorMin = Vector2.zero;
				val7.anchorMax = Vector2.one;
				val7.offsetMin = new Vector2(10f, 5f);
				val7.offsetMax = new Vector2(-10f, -5f);
				_loadingText = val6.AddComponent<TextMeshProUGUI>();
				((TMP_Text)_loadingText).text = "BetterJukebox: Loading songs...";
				((TMP_Text)_loadingText).fontSize = 14f;
				((TMP_Text)_loadingText).alignment = (TextAlignmentOptions)513;
				((Graphic)_loadingText).color = Color.white;
				MelonCoroutines.Start(UpdateLoadingProgress());
			}
			catch (Exception ex)
			{
				_config.LogDebug("Failed to create loading indicator: " + ex.Message);
			}
		}

		[IteratorStateMachine(typeof(<UpdateLoadingProgress>d__17))]
		private IEnumerator UpdateLoadingProgress()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <UpdateLoadingProgress>d__17(0)
			{
				<>4__this = this
			};
		}

		[IteratorStateMachine(typeof(<ScanCurrentScene>d__18))]
		private IEnumerator ScanCurrentScene()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <ScanCurrentScene>d__18(0)
			{
				<>4__this = this
			};
		}

		public override void OnSceneWasInitialized(int buildIndex, string sceneName)
		{
			_config.LogDebug($"Scene Initialized: {sceneName} (index: {buildIndex}). Scanning for jukeboxes...");
			if (_scanCoroutine != null)
			{
				MelonCoroutines.Stop(_scanCoroutine);
			}
			if (_initialLoadComplete)
			{
				_scanCoroutine = MelonCoroutines.Start(CheckSavedJukeboxes());
			}
		}

		[IteratorStateMachine(typeof(<CheckSavedJukeboxes>d__20))]
		private IEnumerator CheckSavedJukeboxes()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <CheckSavedJukeboxes>d__20(0)
			{
				<>4__this = this
			};
		}

		[IteratorStateMachine(typeof(<FinalJukeboxCheck>d__21))]
		private IEnumerator FinalJukeboxCheck()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <FinalJukeboxCheck>d__21(0)
			{
				<>4__this = this
			};
		}

		public override void OnLevelWasLoaded(int level)
		{
			if (_trackManager.TracksLoaded)
			{
				_config.LogDebug($"Level {level} was loaded. Running additional jukebox scan...");
				MelonCoroutines.Start(_jukeboxPatcher.ScanForJukeboxes(repeat: false));
			}
		}

		public override void OnUpdate()
		{
			if (_trackManager.TracksLoaded && !_patchesApplied)
			{
				_harmonyPatches.SetupPatches();
				_patchesApplied = true;
				_config.LogDebug("Harmony patches applied during update");
				MelonCoroutines.Start(ScanCurrentScene());
			}
			if (_trackManager.TracksLoaded && Input.GetKeyDown((KeyCode)291))
			{
				MelonLogger.Msg("Manually refreshing jukeboxes");
				MelonCoroutines.Start(_jukeboxPatcher.ScanForJukeboxes(repeat: false));
				_paginationManager.CheckForUnpatchedInterfaces();
			}
		}

		public static void OnJukeboxAwake(Jukebox jukebox)
		{
			if (_instance != null && _instance._trackManager.TracksLoaded && (Object)(object)jukebox != (Object)null)
			{
				_instance._config.LogDebug($"Jukebox created/initialized: {((Object)jukebox).GetInstanceID()}");
				_instance._jukeboxPatcher.PatchJukebox(jukebox);
			}
		}

		public static void OnSetupSongEntries(JukeboxInterface jukeboxInterface)
		{
			if (_instance != null && _instance._trackManager.TracksLoaded)
			{
				_instance._paginationManager.SetupPagination(jukeboxInterface);
			}
		}

		public static void OnJukeboxInterfaceOpen(JukeboxInterface jukeboxInterface)
		{
			if (_instance != null && _instance._trackManager.TracksLoaded)
			{
				_instance._paginationManager.UpdatePaginationUI(jukeboxInterface);
			}
		}

		public static bool OnRefreshSongEntries(JukeboxInterface jukeboxInterface)
		{
			if (_instance != null && _instance._trackManager.TracksLoaded)
			{
				_instance._paginationManager.RefreshPagination(jukeboxInterface);
				return false;
			}
			return true;
		}

		public static bool OnPlayTrack(Jukebox jukebox, int trackID)
		{
			if (_instance == null || !_instance._trackManager.TracksLoaded || (Object)(object)jukebox == (Object)null)
			{
				return true;
			}
			int originalTrackCount = _instance._jukeboxPatcher.GetOriginalTrackCount(((Object)jukebox).GetInstanceID());
			if (trackID >= originalTrackCount && trackID < ((Il2CppArrayBase<Track>)(object)jukebox.TrackList).Length)
			{
				Track val = ((Il2CppArrayBase<Track>)(object)jukebox.TrackList)[trackID];
				if (val != null && (Object)(object)val.Clip == (Object)null)
				{
					_instance._config.LogDebug("Lazy loading track " + val.TrackName + " before playing");
					bool loadCompleted = false;
					bool loadSuccess = false;
					MelonCoroutines.Start(_instance.LoadAndPlayTrack(jukebox, trackID, val, delegate(bool success)
					{
						loadSuccess = success;
						loadCompleted = true;
					}));
					return false;
				}
			}
			return true;
		}

		[IteratorStateMachine(typeof(<LoadAndPlayTrack>d__29))]
		private IEnumerator LoadAndPlayTrack(Jukebox jukebox, int trackID, Track track, Action<bool> onComplete)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <LoadAndPlayTrack>d__29(0)
			{
				<>4__this = this,
				jukebox = jukebox,
				trackID = trackID,
				track = track,
				onComplete = onComplete
			};
		}
	}
}
namespace BetterJukebox.Utils
{
	public static class AudioUtils
	{
		public static AudioType GetAudioType(string filePath)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: 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_002f: Unknown result type (might be due to invalid IL or missing references)
			if (filePath.EndsWith(".mp3", StringComparison.OrdinalIgnoreCase))
			{
				return (AudioType)13;
			}
			if (filePath.EndsWith(".wav", StringComparison.OrdinalIgnoreCase))
			{
				return (AudioType)20;
			}
			return (AudioType)0;
		}
	}
}
namespace BetterJukebox.Services
{
	public class JukeboxPatcher
	{
		[CompilerGenerated]
		private sealed class <CheckForSavedJukeboxes>d__9 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public JukeboxPatcher <>4__this;

			private Jukebox[] <finalScan>5__1;

			private int <finalPatched>5__2;

			private int <attempt>5__3;

			private Jukebox[] <jukeboxes>5__4;

			private int <patchedThisAttempt>5__5;

			private Jukebox[] <>s__6;

			private int <>s__7;

			private Jukebox <jukebox>5__8;

			private Jukebox[] <>s__9;

			private int <>s__10;

			private Jukebox <jukebox>5__11;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<finalScan>5__1 = null;
				<jukeboxes>5__4 = null;
				<>s__6 = null;
				<jukebox>5__8 = null;
				<>s__9 = null;
				<jukebox>5__11 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0046: Unknown result type (might be due to invalid IL or missing references)
				//IL_0050: Expected O, but got Unknown
				//IL_02b5: Unknown result type (might be due to invalid IL or missing references)
				//IL_02bf: Expected O, but got Unknown
				//IL_0202: Unknown result type (might be due to invalid IL or missing references)
				//IL_020c: Expected O, but got Unknown
				//IL_0235: Unknown result type (might be due to invalid IL or missing references)
				//IL_023f: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(3f);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					<attempt>5__3 = 0;
					goto IL_026d;
				case 2:
					<>1__state = -1;
					goto IL_0255;
				case 3:
					<>1__state = -1;
					goto IL_0255;
				case 4:
					{
						<>1__state = -1;
						<finalScan>5__1 = Il2CppArrayBase<Jukebox>.op_Implicit(Object.FindObjectsOfType<Jukebox>(true));
						<finalPatched>5__2 = 0;
						<>s__9 = <finalScan>5__1;
						for (<>s__10 = 0; <>s__10 < <>s__9.Length; <>s__10++)
						{
							<jukebox>5__11 = <>s__9[<>s__10];
							if ((Object)(object)<jukebox>5__11 != (Object)null && !<>4__this._patchedJukeboxIds.Contains(((Object)<jukebox>5__11).GetInstanceID()))
							{
								<>4__this.PatchJukebox(<jukebox>5__11);
								<finalPatched>5__2++;
							}
							<jukebox>5__11 = null;
						}
						<>s__9 = null;
						if (<finalPatched>5__2 > 0)
						{
							<>4__this._config.LogDebug($"Final scan patched {<finalPatched>5__2} additional jukeboxes");
						}
						return false;
					}
					IL_026d:
					if (<attempt>5__3 < 3)
					{
						<>4__this._config.LogDebug($"Checking for saved jukeboxes (attempt {<attempt>5__3 + 1}/3)...");
						<jukeboxes>5__4 = Il2CppArrayBase<Jukebox>.op_Implicit(Object.FindObjectsOfType<Jukebox>(true));
						<patchedThisAttempt>5__5 = 0;
						<>4__this._config.LogDebug($"Found {<jukeboxes>5__4.Length} jukeboxes in the scene");
						<>s__6 = <jukeboxes>5__4;
						for (<>s__7 = 0; <>s__7 < <>s__6.Length; <>s__7++)
						{
							<jukebox>5__8 = <>s__6[<>s__7];
							if ((Object)(object)<jukebox>5__8 != (Object)null && !<>4__this._patchedJukeboxIds.Contains(((Object)<jukebox>5__8).GetInstanceID()))
							{
								<>4__this.PatchJukebox(<jukebox>5__8);
								<patchedThisAttempt>5__5++;
							}
							<jukebox>5__8 = null;
						}
						<>s__6 = null;
						if (<patchedThisAttempt>5__5 > 0)
						{
							<>4__this._config.LogDebug($"Patched {<patchedThisAttempt>5__5} saved jukeboxes in attempt {<attempt>5__3 + 1}");
						}
						if (<patchedThisAttempt>5__5 == 0 && <attempt>5__3 < 2)
						{
							<>4__this._config.LogDebug("No new jukeboxes found, waiting to try again...");
							<>2__current = (object)new WaitForSeconds(2f);
							<>1__state = 2;
							return true;
						}
						if (<patchedThisAttempt>5__5 > 0)
						{
							<>2__current = (object)new WaitForSeconds(1f);
							<>1__state = 3;
							return true;
						}
					}
					<>4__this._config.LogDebug($"Finished checking for saved jukeboxes, total patched: {<>4__this._patchedJukeboxIds.Count}");
					<>2__current = (object)new WaitForSeconds(5f);
					<>1__state = 4;
					return true;
					IL_0255:
					<jukeboxes>5__4 = null;
					<attempt>5__3++;
					goto IL_026d;
				}
			}

			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 <LoadTrackForPlaying>d__11 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public Track track;

			public Action<bool> onComplete;

			public JukeboxPatcher <>4__this;

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

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

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

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

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = <>4__this._trackManager.EnsureTrackLoaded(track, onComplete);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -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();
			}
		}

		[CompilerGenerated]
		private sealed class <ScanForJukeboxes>d__7 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public bool repeat;

			public JukeboxPatcher <>4__this;

			private int <scanAttempts>5__1;

			private int <maxScanAttempts>5__2;

			private int <jukeboxesFound>5__3;

			private int <jukeboxesPatched>5__4;

			private Jukebox[] <jukeboxes>5__5;

			private Jukebox[] <>s__6;

			private int <>s__7;

			private Jukebox <jukebox>5__8;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<jukeboxes>5__5 = null;
				<>s__6 = null;
				<jukebox>5__8 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_023a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0244: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					if (<>4__this._trackManager.CustomTracks.Count == 0)
					{
						return false;
					}
					<scanAttempts>5__1 = 0;
					<maxScanAttempts>5__2 = ((!repeat) ? 1 : 10);
					<jukeboxesFound>5__3 = 0;
					<jukeboxesPatched>5__4 = 0;
					break;
				case 1:
					<>1__state = -1;
					<jukeboxes>5__5 = null;
					break;
				}
				if (<scanAttempts>5__1 < <maxScanAttempts>5__2)
				{
					<scanAttempts>5__1++;
					<>4__this._config.LogDebug($"Scanning for jukeboxes (attempt {<scanAttempts>5__1}/{<maxScanAttempts>5__2})...");
					<jukeboxes>5__5 = Il2CppArrayBase<Jukebox>.op_Implicit(Object.FindObjectsOfType<Jukebox>(true));
					<jukeboxesFound>5__3 = <jukeboxes>5__5.Length;
					if (<jukeboxes>5__5.Length != 0)
					{
						<>4__this._config.LogDebug($"Found {<jukeboxes>5__5.Length} jukeboxes");
						<>s__6 = <jukeboxes>5__5;
						for (<>s__7 = 0; <>s__7 < <>s__6.Length; <>s__7++)
						{
							<jukebox>5__8 = <>s__6[<>s__7];
							if ((Object)(object)<jukebox>5__8 != (Object)null && !<>4__this._patchedJukeboxIds.Contains(((Object)<jukebox>5__8).GetInstanceID()))
							{
								<>4__this.PatchJukebox(<jukebox>5__8);
								<jukeboxesPatched>5__4++;
							}
							<jukebox>5__8 = null;
						}
						<>s__6 = null;
						if (<jukeboxesPatched>5__4 > 0)
						{
							<>4__this._config.LogDebug($"Patched {<jukeboxesPatched>5__4} new jukeboxes");
						}
					}
					else
					{
						<>4__this._config.LogDebug("No jukeboxes found in the current scene");
					}
					if (<jukeboxesFound>5__3 <= 0 || <jukeboxesPatched>5__4 != <jukeboxesFound>5__3)
					{
						<>2__current = (object)new WaitForSeconds(5f);
						<>1__state = 1;
						return true;
					}
				}
				if ((<jukeboxesFound>5__3 == 0) & repeat)
				{
					MelonLogger.Warning("No jukeboxes found after multiple attempts. Try pressing F10 when near a jukebox for manual refresh.");
				}
				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 readonly ModConfig _config;

		private readonly TrackManager _trackManager;

		private readonly HashSet<int> _patchedJukeboxIds = new HashSet<int>();

		private readonly Dictionary<int, int> _originalTrackCounts = new Dictionary<int, int>();

		public JukeboxPatcher(ModConfig config, TrackManager trackManager)
		{
			_config = config;
			_trackManager = trackManager;
		}

		public bool IsJukeboxPatched(int jukeboxId)
		{
			return _patchedJukeboxIds.Contains(jukeboxId);
		}

		public int GetOriginalTrackCount(int jukeboxId)
		{
			if (_originalTrackCounts.TryGetValue(jukeboxId, out var value))
			{
				return value;
			}
			return 0;
		}

		[IteratorStateMachine(typeof(<ScanForJukeboxes>d__7))]
		public IEnumerator ScanForJukeboxes(bool repeat = true)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <ScanForJukeboxes>d__7(0)
			{
				<>4__this = this,
				repeat = repeat
			};
		}

		public void PatchJukebox(Jukebox jukebox)
		{
			if ((Object)(object)jukebox == (Object)null || _trackManager.CustomTracks.Count == 0)
			{
				return;
			}
			int instanceID = ((Object)jukebox).GetInstanceID();
			if (_patchedJukeboxIds.Contains(instanceID))
			{
				_config.LogDebug($"Jukebox {instanceID} already patched, skipping");
				return;
			}
			try
			{
				Track[] array = Il2CppArrayBase<Track>.op_Implicit((Il2CppArrayBase<Track>)(object)jukebox.TrackList);
				if (array == null)
				{
					MelonLogger.Warning($"Jukebox {instanceID} has null TrackList, skipping");
					return;
				}
				_originalTrackCounts[instanceID] = array.Length;
				Track[] array2 = (Track[])(object)new Track[array.Length + _trackManager.CustomTracks.Count];
				Array.Copy(array, array2, array.Length);
				for (int i = 0; i < _trackManager.CustomTracks.Count; i++)
				{
					array2[array.Length + i] = _trackManager.CustomTracks[i];
				}
				jukebox.TrackList = Il2CppReferenceArray<Track>.op_Implicit(array2);
				Type il2CppType = ((Object)jukebox).GetIl2CppType();
				FieldInfo field = il2CppType.GetField("_jukeboxState", (BindingFlags)36);
				if (field != (FieldInfo)null)
				{
					_config.LogDebug("Found _jukeboxState field via IL2CPP reflection");
					Object value = field.GetValue((Object)(object)jukebox);
					if (value != null)
					{
						JukeboxState val = ((Il2CppObjectBase)value).Cast<JukeboxState>();
						if (val != null && val.TrackOrder != null)
						{
							_config.LogDebug("Updating TrackOrder in JukeboxState");
							int[] array3 = new int[array2.Length];
							for (int j = 0; j < array3.Length; j++)
							{
								array3[j] = j;
							}
							val.TrackOrder = Il2CppStructArray<int>.op_Implicit(array3);
							_config.LogDebug($"Updated TrackOrder to include {array2.Length} tracks");
						}
						else
						{
							MelonLogger.Warning("JukeboxState or TrackOrder is null");
						}
					}
					else
					{
						MelonLogger.Warning("_jukeboxState field value is null");
					}
				}
				else
				{
					MelonLogger.Warning("Could not find _jukeboxState field via IL2CPP reflection");
				}
				_patchedJukeboxIds.Add(instanceID);
				_config.LogDebug($"Successfully patched jukebox {instanceID} with {_trackManager.CustomTracks.Count} custom tracks");
			}
			catch (Exception ex)
			{
				MelonLogger.Error($"Failed to patch jukebox {instanceID}: {ex.Message}");
				MelonLogger.Error(ex.StackTrace);
			}
		}

		[IteratorStateMachine(typeof(<CheckForSavedJukeboxes>d__9))]
		public IEnumerator CheckForSavedJukeboxes()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <CheckForSavedJukeboxes>d__9(0)
			{
				<>4__this = this
			};
		}

		public bool ForcePlayTrack(Jukebox jukebox, int trackID)
		{
			if ((Object)(object)jukebox == (Object)null || trackID < 0 || trackID >= ((Il2CppArrayBase<Track>)(object)jukebox.TrackList).Length)
			{
				MelonLogger.Error($"Invalid jukebox or track ID: {trackID}");
				return false;
			}
			try
			{
				Track val = ((Il2CppArrayBase<Track>)(object)jukebox.TrackList)[trackID];
				if (val == null)
				{
					MelonLogger.Error("Track is null");
					return false;
				}
				if (trackID >= GetOriginalTrackCount(((Object)jukebox).GetInstanceID()) && (Object)(object)val.Clip == (Object)null)
				{
					_config.LogDebug("Track " + val.TrackName + " has null clip, loading it now...");
					bool loadSuccess = false;
					MelonCoroutines.Start(LoadTrackForPlaying(val, delegate(bool success)
					{
						loadSuccess = success;
					}));
					float realtimeSinceStartup = Time.realtimeSinceStartup;
					while (!loadSuccess && Time.realtimeSinceStartup - realtimeSinceStartup < 2f)
					{
						Thread.Sleep(50);
					}
					if (!loadSuccess || (Object)(object)val.Clip == (Object)null)
					{
						MelonLogger.Error("Failed to load clip for track " + val.TrackName);
						return false;
					}
				}
				if ((Object)(object)val.Clip == (Object)null)
				{
					MelonLogger.Error("Track " + val.TrackName + " has null clip");
					return false;
				}
				_config.LogDebug("Forcing play of track: " + val.TrackName);
				AudioSource val2 = null;
				try
				{
					FieldInfo field = ((Object)jukebox).GetIl2CppType().GetField("AudioSourceController", (BindingFlags)20);
					if (field != (FieldInfo)null)
					{
						Object value = field.GetValue((Object)(object)jukebox);
						if (value != null)
						{
							Component val3 = ((Il2CppObjectBase)value).Cast<Component>();
							_config.LogDebug("Found AudioSourceController, attempting to get AudioSource");
							PropertyInfo property = ((Object)val3).GetIl2CppType().GetProperty("AudioSource", (BindingFlags)20);
							if (property != (PropertyInfo)null)
							{
								Object value2 = property.GetValue((Object)(object)val3);
								if (value2 != null)
								{
									val2 = ((Il2CppObjectBase)value2).Cast<AudioSource>();
									_config.LogDebug("Successfully got AudioSource via AudioSourceController property");
								}
							}
							else
							{
								val2 = val3.GetComponent<AudioSource>();
								if ((Object)(object)val2 != (Object)null)
								{
									_config.LogDebug("Got AudioSource via GetComponent on AudioSourceController");
								}
							}
						}
					}
				}
				catch (Exception ex)
				{
					_config.LogDebug("Error getting AudioSource via AudioSourceController: " + ex.Message);
				}
				if ((Object)(object)val2 == (Object)null)
				{
					try
					{
						FieldInfo field2 = ((Object)jukebox).GetIl2CppType().GetField("_audioSource", (BindingFlags)36);
						if (field2 != (FieldInfo)null)
						{
							Object value3 = field2.GetValue((Object)(object)jukebox);
							if (value3 != null)
							{
								val2 = ((Il2CppObjectBase)value3).Cast<AudioSource>();
								_config.LogDebug("Got AudioSource via _audioSource field");
							}
						}
						else
						{
							_config.LogDebug("Could not find _audioSource field");
						}
					}
					catch (Exception ex2)
					{
						_config.LogDebug("Error getting _audioSource field: " + ex2.Message);
					}
				}
				if ((Object)(object)val2 == (Object)null)
				{
					try
					{
						val2 = ((Component)jukebox).GetComponent<AudioSource>();
						if ((Object)(object)val2 != (Object)null)
						{
							_config.LogDebug("Got AudioSource via GetComponent on Jukebox");
						}
						else
						{
							val2 = ((Component)jukebox).GetComponentInChildren<AudioSource>();
							if ((Object)(object)val2 != (Object)null)
							{
								_config.LogDebug("Got AudioSource via GetComponentInChildren on Jukebox");
							}
						}
					}
					catch (Exception ex3)
					{
						_config.LogDebug("Error getting AudioSource via GetComponent: " + ex3.Message);
					}
				}
				if ((Object)(object)val2 == (Object)null)
				{
					MelonLogger.Error("Could not find AudioSource by any method");
					return false;
				}
				val2.Stop();
				val2.clip = val.Clip;
				val2.time = 0f;
				val2.volume = 1f;
				val2.Play();
				_config.LogDebug($"Forced play of track {val.TrackName} - AudioSource playing: {val2.isPlaying}");
				try
				{
					FieldInfo field3 = ((Object)jukebox).GetIl2CppType().GetField("_currentTrack", (BindingFlags)36);
					if (field3 != (FieldInfo)null)
					{
						field3.SetValue((Object)(object)jukebox, Object.op_Implicit(trackID));
						_config.LogDebug($"Updated _currentTrack to {trackID}");
					}
				}
				catch (Exception ex4)
				{
					MelonLogger.Warning("Error updating _currentTrack field: " + ex4.Message);
				}
				return val2.isPlaying;
			}
			catch (Exception ex5)
			{
				MelonLogger.Error("Error in ForcePlayTrack: " + ex5.Message);
				MelonLogger.Error(ex5.StackTrace);
				return false;
			}
		}

		[IteratorStateMachine(typeof(<LoadTrackForPlaying>d__11))]
		private IEnumerator LoadTrackForPlaying(Track track, Action<bool> onComplete)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <LoadTrackForPlaying>d__11(0)
			{
				<>4__this = this,
				track = track,
				onComplete = onComplete
			};
		}
	}
	public class PaginationManager
	{
		[CompilerGenerated]
		private sealed class <AnimateButtonScale>d__10 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public Transform buttonTransform;

			public PaginationManager <>4__this;

			private Vector3 <originalScale>5__1;

			private float <duration>5__2;

			private float <elapsed>5__3;

			private float <t>5__4;

			private float <t>5__5;

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

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

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

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

			private bool MoveNext()
			{
				//IL_004e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0053: Unknown result type (might be due to invalid IL or missing references)
				//IL_0069: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b1: 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_00c1: 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)
				//IL_0151: Unknown result type (might be due to invalid IL or missing references)
				//IL_015b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0161: Unknown result type (might be due to invalid IL or missing references)
				//IL_016c: Unknown result type (might be due to invalid IL or missing references)
				//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>4__this._config.LogDebug("AnimateButtonScale coroutine started");
					<originalScale>5__1 = buttonTransform.localScale;
					<>4__this._config.LogDebug($"Original scale: {<originalScale>5__1}");
					<duration>5__2 = 0.1f;
					<elapsed>5__3 = 0f;
					goto IL_0101;
				case 1:
					<>1__state = -1;
					goto IL_0101;
				case 2:
					{
						<>1__state = -1;
						break;
					}
					IL_0101:
					if (<elapsed>5__3 < <duration>5__2)
					{
						<t>5__4 = <elapsed>5__3 / <duration>5__2;
						buttonTransform.localScale = Vector3.Lerp(<originalScale>5__1, <originalScale>5__1 * 0.9f, <t>5__4);
						<elapsed>5__3 += Time.deltaTime;
						<>2__current = null;
						<>1__state = 1;
						return true;
					}
					<>4__this._config.LogDebug("Button scale down complete");
					<elapsed>5__3 = 0f;
					break;
				}
				if (<elapsed>5__3 < <duration>5__2)
				{
					<t>5__5 = <elapsed>5__3 / <duration>5__2;
					buttonTransform.localScale = Vector3.Lerp(<originalScale>5__1 * 0.9f, <originalScale>5__1, <t>5__5);
					<elapsed>5__3 += Time.deltaTime;
					<>2__current = null;
					<>1__state = 2;
					return true;
				}
				buttonTransform.localScale = <originalScale>5__1;
				<>4__this._config.LogDebug("Button animation complete");
				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 <CheckForSavedJukeboxInterfaces>d__13 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public PaginationManager <>4__this;

			private JukeboxInterface[] <finalInterfaces>5__1;

			private int <finalCount>5__2;

			private int <attempt>5__3;

			private JukeboxInterface[] <interfaces>5__4;

			private int <patchedCount>5__5;

			private JukeboxInterface[] <>s__6;

			private int <>s__7;

			private JukeboxInterface <jukeboxInterface>5__8;

			private int <jukeboxId>5__9;

			private JukeboxInterface[] <>s__10;

			private int <>s__11;

			private JukeboxInterface <jukeboxInterface>5__12;

			private int <jukeboxId>5__13;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<finalInterfaces>5__1 = null;
				<interfaces>5__4 = null;
				<>s__6 = null;
				<jukeboxInterface>5__8 = null;
				<>s__10 = null;
				<jukeboxInterface>5__12 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0046: Unknown result type (might be due to invalid IL or missing references)
				//IL_0050: Expected O, but got Unknown
				//IL_033f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0349: Expected O, but got Unknown
				//IL_02a4: Unknown result type (might be due to invalid IL or missing references)
				//IL_02ae: Expected O, but got Unknown
				//IL_02ed: Unknown result type (might be due to invalid IL or missing references)
				//IL_02f7: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(2f);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					<attempt>5__3 = 0;
					goto IL_0327;
				case 2:
					<>1__state = -1;
					goto IL_030d;
				case 3:
					<>1__state = -1;
					goto IL_030d;
				case 4:
					{
						<>1__state = -1;
						<finalInterfaces>5__1 = Il2CppArrayBase<JukeboxInterface>.op_Implicit(Object.FindObjectsOfType<JukeboxInterface>(true));
						<finalCount>5__2 = 0;
						<>s__10 = <finalInterfaces>5__1;
						for (<>s__11 = 0; <>s__11 < <>s__10.Length; <>s__11++)
						{
							<jukeboxInterface>5__12 = <>s__10[<>s__11];
							if ((Object)(object)<jukeboxInterface>5__12 != (Object)null && (Object)(object)<jukeboxInterface>5__12.Jukebox != (Object)null && !<>4__this._paginationData.ContainsKey(<jukeboxInterface>5__12))
							{
								<jukeboxId>5__13 = ((Object)<jukeboxInterface>5__12.Jukebox).GetInstanceID();
								if (<>4__this._jukeboxPatcher.IsJukeboxPatched(<jukeboxId>5__13))
								{
									<>4__this.RecreateSongEntries(<jukeboxInterface>5__12);
									<>4__this.SetupPagination(<jukeboxInterface>5__12);
									<finalCount>5__2++;
								}
							}
							<jukeboxInterface>5__12 = null;
						}
						<>s__10 = null;
						if (<finalCount>5__2 > 0)
						{
							<>4__this._config.LogDebug($"Final scan applied pagination to {<finalCount>5__2} additional interfaces");
						}
						return false;
					}
					IL_0327:
					if (<attempt>5__3 < 3)
					{
						<>4__this._config.LogDebug($"Checking for saved jukebox interfaces (attempt {<attempt>5__3 + 1}/3)...");
						<interfaces>5__4 = Il2CppArrayBase<JukeboxInterface>.op_Implicit(Object.FindObjectsOfType<JukeboxInterface>(true));
						<patchedCount>5__5 = 0;
						<>4__this._config.LogDebug($"Found {<interfaces>5__4.Length} jukebox interfaces in the scene");
						<>s__6 = <interfaces>5__4;
						for (<>s__7 = 0; <>s__7 < <>s__6.Length; <>s__7++)
						{
							<jukeboxInterface>5__8 = <>s__6[<>s__7];
							if ((Object)(object)<jukeboxInterface>5__8 != (Object)null && (Object)(object)<jukeboxInterface>5__8.Jukebox != (Object)null)
							{
								<jukeboxId>5__9 = ((Object)<jukeboxInterface>5__8.Jukebox).GetInstanceID();
								if (<>4__this._paginationData.ContainsKey(<jukeboxInterface>5__8))
								{
									<>4__this._config.LogDebug($"Interface for jukebox {<jukeboxId>5__9} already has pagination");
									continue;
								}
								if (<>4__this._jukeboxPatcher.IsJukeboxPatched(<jukeboxId>5__9))
								{
									<>4__this._config.LogDebug($"Setting up pagination for patched jukebox {<jukeboxId>5__9}");
									<>4__this.RecreateSongEntries(<jukeboxInterface>5__8);
									<>4__this.SetupPagination(<jukeboxInterface>5__8);
									<patchedCount>5__5++;
								}
								else
								{
									<>4__this._config.LogDebug($"Found interface for jukebox {<jukeboxId>5__9} but it's not patched yet");
								}
							}
							<jukeboxInterface>5__8 = null;
						}
						<>s__6 = null;
						if (<patchedCount>5__5 > 0)
						{
							<>4__this._config.LogDebug($"Applied pagination to {<patchedCount>5__5} jukebox interfaces in attempt {<attempt>5__3 + 1}");
							<>2__current = (object)new WaitForSeconds(1f);
							<>1__state = 2;
							return true;
						}
						if (<attempt>5__3 < 2)
						{
							<>4__this._config.LogDebug("No interfaces to update, waiting to try again...");
							<>2__current = (object)new WaitForSeconds(2f);
							<>1__state = 3;
							return true;
						}
					}
					<>2__current = (object)new WaitForSeconds(4f);
					<>1__state = 4;
					return true;
					IL_030d:
					<interfaces>5__4 = null;
					<attempt>5__3++;
					goto IL_0327;
				}
			}

			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 const int TRACKS_PER_PAGE = 27;

		private readonly ModConfig _config;

		private readonly JukeboxPatcher _jukeboxPatcher;

		private readonly Dictionary<JukeboxInterface, PaginationData> _paginationData = new Dictionary<JukeboxInterface, PaginationData>();

		public PaginationManager(ModConfig config, JukeboxPatcher jukeboxPatcher)
		{
			_config = config;
			_jukeboxPatcher = jukeboxPatcher;
		}

		public void SetupPagination(JukeboxInterface jukeboxInterface)
		{
			//IL_037e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0388: Expected O, but got Unknown
			//IL_038f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0399: Expected O, but got Unknown
			//IL_040a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0438: Unknown result type (might be due to invalid IL or missing references)
			//IL_04bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_051a: Unknown result type (might be due to invalid IL or missing references)
			//IL_053b: Unknown result type (might be due to invalid IL or missing references)
			//IL_055c: 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_0590: Unknown result type (might be due to invalid IL or missing references)
			//IL_0597: Expected O, but got Unknown
			//IL_05e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_05fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_064d: Unknown result type (might be due to invalid IL or missing references)
			//IL_065d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0664: Expected O, but got Unknown
			//IL_06b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0711: Unknown result type (might be due to invalid IL or missing references)
			//IL_0722: Unknown result type (might be due to invalid IL or missing references)
			//IL_072c: Expected O, but got Unknown
			//IL_079d: Unknown result type (might be due to invalid IL or missing references)
			//IL_07cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_084e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0853: Unknown result type (might be due to invalid IL or missing references)
			//IL_086b: Unknown result type (might be due to invalid IL or missing references)
			//IL_088c: Unknown result type (might be due to invalid IL or missing references)
			//IL_08ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_08ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_08ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0916: Unknown result type (might be due to invalid IL or missing references)
			//IL_0923: Unknown result type (might be due to invalid IL or missing references)
			//IL_092a: Expected O, but got Unknown
			//IL_0975: Unknown result type (might be due to invalid IL or missing references)
			//IL_0982: Unknown result type (might be due to invalid IL or missing references)
			//IL_098f: Unknown result type (might be due to invalid IL or missing references)
			//IL_09e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0471: Unknown result type (might be due to invalid IL or missing references)
			//IL_0488: Unknown result type (might be due to invalid IL or missing references)
			//IL_0804: Unknown result type (might be due to invalid IL or missing references)
			//IL_081b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: Unknown result type (might be due to invalid IL or missing references)
			//IL_020f: Expected O, but got Unknown
			//IL_0246: Unknown result type (might be due to invalid IL or missing references)
			//IL_025d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0274: Unknown result type (might be due to invalid IL or missing references)
			//IL_028b: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d6: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if ((Object)(object)jukeboxInterface == (Object)null || (Object)(object)jukeboxInterface.Jukebox == (Object)null || (Object)(object)jukeboxInterface.EntryContainer == (Object)null)
				{
					_config.LogDebug("Cannot setup pagination, interface or required components are null");
					return;
				}
				int length = ((Il2CppArrayBase<Track>)(object)jukeboxInterface.Jukebox.TrackList).Length;
				if (length <= 27)
				{
					_config.LogDebug($"No pagination needed, track count ({length}) <= tracks per page ({27})");
					return;
				}
				if (_paginationData.ContainsKey(jukeboxInterface))
				{
					if ((Object)(object)_paginationData[jukeboxInterface].PaginationUI != (Object)null)
					{
						Object.Destroy((Object)(object)_paginationData[jukeboxInterface].PaginationUI);
					}
					_paginationData.Remove(jukeboxInterface);
				}
				PaginationData paginationData = new PaginationData
				{
					CurrentPage = 0,
					TotalPages = Mathf.CeilToInt((float)length / 27f),
					OriginalSongEntries = new List<RectTransform>()
				};
				FieldInfo fieldInfo = AccessTools.Field(typeof(JukeboxInterface), "songEntries");
				if (fieldInfo != null)
				{
					paginationData.OriginalSongEntries = new List<RectTransform>(fieldInfo.GetValue(jukeboxInterface) as List<RectTransform>);
				}
				Canvas canvas = jukeboxInterface.Canvas;
				if ((Object)(object)canvas == (Object)null)
				{
					_config.LogDebug("Canvas is null, cannot create pagination UI");
					return;
				}
				GameObject val = new GameObject("PaginationContainer");
				val.AddComponent(Il2CppType.Of<RectTransform>());
				val.transform.SetParent(((Component)canvas).transform, false);
				RectTransform component = val.GetComponent<RectTransform>();
				component.anchorMin = new Vector2(0.5f, 0f);
				component.anchorMax = new Vector2(0.5f, 0f);
				component.pivot = new Vector2(0.5f, 0f);
				component.anchoredPosition = new Vector2(0f, 445f);
				component.sizeDelta = new Vector2(300f, 40f);
				Image val2 = ((Il2CppObjectBase)val.AddComponent(Il2CppType.Of<Image>())).Cast<Image>();
				((Graphic)val2).color = new Color(0.1f, 0.1f, 0.1f, 0.8f);
				try
				{
					Type val3 = Il2CppType.From(Type.GetType("UnityEngine.UI.Extensions.UICornerCut, Unity.UI.Extensions"));
					if (val3 != (Type)null && ((Il2CppObjectBase)val3).Pointer != IntPtr.Zero)
					{
						val.AddComponent(val3);
						_config.LogDebug("Added rounded corners but couldn't set the radius in IL2CPP build");
					}
				}
				catch (Exception)
				{
					_config.LogDebug("Couldn't add rounded corners to pagination UI");
				}
				HorizontalLayoutGroup val4 = ((Il2CppObjectBase)val.AddComponent(Il2CppType.Of<HorizontalLayoutGroup>())).Cast<HorizontalLayoutGroup>();
				((LayoutGroup)val4).childAlignment = (TextAnchor)4;
				((HorizontalOrVerticalLayoutGroup)val4).spacing = 10f;
				((LayoutGroup)val4).padding = new RectOffset(10, 10, 5, 5);
				GameObject prevButton = new GameObject("PrevButton");
				prevButton.AddComponent(Il2CppType.Of<RectTransform>());
				prevButton.AddComponent(Il2CppType.Of<CanvasRenderer>());
				prevButton.AddComponent(Il2CppType.Of<Image>());
				prevButton.AddComponent(Il2CppType.Of<Button>());
				prevButton.transform.SetParent((Transform)(object)component, false);
				RectTransform component2 = prevButton.GetComponent<RectTransform>();
				component2.sizeDelta = new Vector2(40f, 40f);
				Image component3 = prevButton.GetComponent<Image>();
				((Graphic)component3).color = new Color(0.15f, 0.15f, 0.15f, 0.9f);
				try
				{
					Outline val5 = ((Il2CppObjectBase)prevButton.AddComponent(Il2CppType.Of<Outline>())).Cast<Outline>();
					((Shadow)val5).effectColor = new Color(0.3f, 0.3f, 0.3f, 0.5f);
					((Shadow)val5).effectDistance = new Vector2(1f, -1f);
				}
				catch (Exception)
				{
					_config.LogDebug("Couldn't add rounded style to pagination buttons");
				}
				Button component4 = prevButton.GetComponent<Button>();
				ColorBlock colors = ((Selectable)component4).colors;
				((ColorBlock)(ref colors)).normalColor = new Color(0.15f, 0.15f, 0.15f, 0.9f);
				((ColorBlock)(ref colors)).highlightedColor = new Color(0.25f, 0.25f, 0.25f, 1f);
				((ColorBlock)(ref colors)).pressedColor = new Color(0.1f, 0.1f, 0.1f, 1f);
				((ColorBlock)(ref colors)).selectedColor = new Color(0.25f, 0.25f, 0.25f, 1f);
				((ColorBlock)(ref colors)).disabledColor = new Color(0.15f, 0.15f, 0.15f, 0.5f);
				((ColorBlock)(ref colors)).colorMultiplier = 1.2f;
				((ColorBlock)(ref colors)).fadeDuration = 0.1f;
				((Selectable)component4).colors = colors;
				GameObject val6 = new GameObject("Text");
				val6.AddComponent(Il2CppType.Of<RectTransform>());
				val6.AddComponent(Il2CppType.Of<CanvasRenderer>());
				val6.AddComponent(Il2CppType.Of<TextMeshProUGUI>());
				val6.transform.SetParent(prevButton.transform, false);
				RectTransform component5 = val6.GetComponent<RectTransform>();
				component5.anchorMin = Vector2.zero;
				component5.anchorMax = Vector2.one;
				component5.sizeDelta = Vector2.zero;
				TextMeshProUGUI component6 = val6.GetComponent<TextMeshProUGUI>();
				((TMP_Text)component6).text = "<";
				((TMP_Text)component6).fontSize = 24f;
				((TMP_Text)component6).alignment = (TextAlignmentOptions)514;
				((Graphic)component6).color = new Color(0.8f, 0.8f, 0.8f, 1f);
				GameObject val7 = new GameObject("PageText");
				val7.AddComponent(Il2CppType.Of<RectTransform>());
				val7.AddComponent(Il2CppType.Of<CanvasRenderer>());
				val7.AddComponent(Il2CppType.Of<TextMeshProUGUI>());
				val7.transform.SetParent((Transform)(object)component, false);
				RectTransform component7 = val7.GetComponent<RectTransform>();
				component7.sizeDelta = new Vector2(150f, 40f);
				TextMeshProUGUI component8 = val7.GetComponent<TextMeshProUGUI>();
				((TMP_Text)component8).text = $"Page 1/{paginationData.TotalPages}";
				((TMP_Text)component8).fontSize = 18f;
				((TMP_Text)component8).alignment = (TextAlignmentOptions)514;
				((Graphic)component8).color = new Color(0.8f, 0.8f, 0.8f, 1f);
				GameObject nextButton = new GameObject("NextButton");
				nextButton.AddComponent(Il2CppType.Of<RectTransform>());
				nextButton.AddComponent(Il2CppType.Of<CanvasRenderer>());
				nextButton.AddComponent(Il2CppType.Of<Image>());
				nextButton.AddComponent(Il2CppType.Of<Button>());
				nextButton.transform.SetParent((Transform)(object)component, false);
				RectTransform component9 = nextButton.GetComponent<RectTransform>();
				component9.sizeDelta = new Vector2(40f, 40f);
				Image component10 = nextButton.GetComponent<Image>();
				((Graphic)component10).color = new Color(0.15f, 0.15f, 0.15f, 0.9f);
				try
				{
					Outline val8 = ((Il2CppObjectBase)nextButton.AddComponent(Il2CppType.Of<Outline>())).Cast<Outline>();
					((Shadow)val8).effectColor = new Color(0.3f, 0.3f, 0.3f, 0.5f);
					((Shadow)val8).effectDistance = new Vector2(1f, -1f);
				}
				catch (Exception)
				{
					_config.LogDebug("Couldn't add rounded style to next button");
				}
				Button component11 = nextButton.GetComponent<Button>();
				ColorBlock colors2 = ((Selectable)component11).colors;
				((ColorBlock)(ref colors2)).normalColor = new Color(0.15f, 0.15f, 0.15f, 0.9f);
				((ColorBlock)(ref colors2)).highlightedColor = new Color(0.25f, 0.25f, 0.25f, 1f);
				((ColorBlock)(ref colors2)).pressedColor = new Color(0.1f, 0.1f, 0.1f, 1f);
				((ColorBlock)(ref colors2)).selectedColor = new Color(0.25f, 0.25f, 0.25f, 1f);
				((ColorBlock)(ref colors2)).disabledColor = new Color(0.15f, 0.15f, 0.15f, 0.5f);
				((ColorBlock)(ref colors2)).colorMultiplier = 1.2f;
				((ColorBlock)(ref colors2)).fadeDuration = 0.1f;
				((Selectable)component11).colors = colors2;
				GameObject val9 = new GameObject("Text");
				val9.AddComponent(Il2CppType.Of<RectTransform>());
				val9.AddComponent(Il2CppType.Of<CanvasRenderer>());
				val9.AddComponent(Il2CppType.Of<TextMeshProUGUI>());
				val9.transform.SetParent(nextButton.transform, false);
				RectTransform component12 = val9.GetComponent<RectTransform>();
				component12.anchorMin = Vector2.zero;
				component12.anchorMax = Vector2.one;
				component12.sizeDelta = Vector2.zero;
				TextMeshProUGUI component13 = val9.GetComponent<TextMeshProUGUI>();
				((TMP_Text)component13).text = ">";
				((TMP_Text)component13).fontSize = 24f;
				((TMP_Text)component13).alignment = (TextAlignmentOptions)514;
				((Graphic)component13).color = new Color(0.8f, 0.8f, 0.8f, 1f);
				paginationData.PaginationUI = val;
				paginationData.PrevButton = component4;
				paginationData.NextButton = component11;
				paginationData.PageText = component8;
				Action action = delegate
				{
					try
					{
						_config.LogDebug("IL2CPP Prev Button Clicked");
						StartButtonAnimation(prevButton.transform);
						ChangePage(jukeboxInterface, -1);
						_config.LogDebug("IL2CPP Prev Action Completed");
					}
					catch (Exception arg4)
					{
						MelonLogger.Error($"Error in IL2CPP Prev Action: {arg4}");
					}
				};
				Action action2 = delegate
				{
					try
					{
						_config.LogDebug("IL2CPP Next Button Clicked");
						StartButtonAnimation(nextButton.transform);
						ChangePage(jukeboxInterface, 1);
						_config.LogDebug("IL2CPP Next Action Completed");
					}
					catch (Exception arg3)
					{
						MelonLogger.Error($"Error in IL2CPP Next Action: {arg3}");
					}
				};
				_config.LogDebug("Adding IL2CPP button listeners");
				try
				{
					((UnityEvent)paginationData.PrevButton.onClick).AddListener(UnityAction.op_Implicit(action));
					_config.LogDebug("Successfully added IL2CPP prev button listener");
				}
				catch (Exception arg)
				{
					MelonLogger.Error($"Failed to add IL2CPP prev button listener: {arg}");
				}
				try
				{
					((UnityEvent)paginationData.NextButton.onClick).AddListener(UnityAction.op_Implicit(action2));
					_config.LogDebug("Successfully added IL2CPP next button listener");
				}
				catch (Exception arg2)
				{
					MelonLogger.Error($"Failed to add IL2CPP next button listener: {arg2}");
				}
				_paginationData[jukeboxInterface] = paginationData;
				UpdatePaginationUI(jukeboxInterface);
				_config.LogDebug($"Pagination setup completed for jukebox: {((Object)jukeboxInterface.Jukebox).GetInstanceID()} with {paginationData.TotalPages} pages");
			}
			catch (Exception ex4)
			{
				MelonLogger.Error("Failed to setup pagination: " + ex4.Message);
				MelonLogger.Error(ex4.StackTrace);
			}
		}

		public void ChangePage(JukeboxInterface jukeboxInterface, int delta)
		{
			_config.LogDebug($"ChangePage called with delta: {delta}");
			if (!_paginationData.ContainsKey(jukeboxInterface))
			{
				MelonLogger.Error("ChangePage failed: No pagination data for this interface");
				return;
			}
			PaginationData paginationData = _paginationData[jukeboxInterface];
			int num = paginationData.CurrentPage + delta;
			_config.LogDebug($"Current page: {paginationData.CurrentPage}, New page: {num}, Total pages: {paginationData.TotalPages}");
			if (num >= 0 && num < paginationData.TotalPages)
			{
				_config.LogDebug($"Changing to page {num}");
				paginationData.CurrentPage = num;
				UpdatePaginationUI(jukeboxInterface);
				RefreshPagination(jukeboxInterface);
				_config.LogDebug("Page change completed");
			}
			else
			{
				_config.LogDebug($"Invalid page number: {num}, not changing");
			}
		}

		public void UpdatePaginationUI(JukeboxInterface jukeboxInterface)
		{
			_config.LogDebug("UpdatePaginationUI called");
			if (!_paginationData.ContainsKey(jukeboxInterface))
			{
				MelonLogger.Error("UpdatePaginationUI failed: No pagination data for this interface");
				return;
			}
			PaginationData paginationData = _paginationData[jukeboxInterface];
			((TMP_Text)paginationData.PageText).text = $"Page {paginationData.CurrentPage + 1}/{paginationData.TotalPages}";
			_config.LogDebug("Updated page text to: " + ((TMP_Text)paginationData.PageText).text);
			((Selectable)paginationData.PrevButton).interactable = paginationData.CurrentPage > 0;
			((Selectable)paginationData.NextButton).interactable = paginationData.CurrentPage < paginationData.TotalPages - 1;
			_config.LogDebug($"Button states updated - Prev: {((Selectable)paginationData.PrevButton).interactable}, Next: {((Selectable)paginationData.NextButton).interactable}");
		}

		public void RefreshPagination(JukeboxInterface jukeboxInterface)
		{
			_config.LogDebug("RefreshPagination called");
			if (!_paginationData.ContainsKey(jukeboxInterface))
			{
				MelonLogger.Error("RefreshPagination failed: No pagination data for this interface");
				return;
			}
			PaginationData paginationData = _paginationData[jukeboxInterface];
			Type il2CppType = ((Object)jukeboxInterface).GetIl2CppType();
			FieldInfo field = il2CppType.GetField("songEntries", (BindingFlags)52);
			if (field == (FieldInfo)null)
			{
				MelonLogger.Error("RefreshPagination failed: songEntries field not found via IL2CPP reflection");
				return;
			}
			Object value = field.GetValue((Object)(object)jukeboxInterface);
			if (value == null)
			{
				MelonLogger.Error("RefreshPagination failed: songEntries field value is null");
				return;
			}
			List<RectTransform> list = new List<RectTransform>();
			List<RectTransform> val = ((Il2CppObjectBase)value).Cast<List<RectTransform>>();
			if (val == null)
			{
				MelonLogger.Error("RefreshPagination failed: Could not cast to IL2CPP List");
				return;
			}
			for (int i = 0; i < val.Count; i++)
			{
				list.Add(val[i]);
			}
			_config.LogDebug($"Successfully accessed IL2CPP songEntries field with {list.Count} entries");
			if (list == null)
			{
				MelonLogger.Error("RefreshPagination failed: songEntries list is null");
				return;
			}
			Track[] array = Il2CppArrayBase<Track>.op_Implicit((Il2CppArrayBase<Track>)(object)jukeboxInterface.Jukebox.TrackList);
			_config.LogDebug($"Refreshing pagination - Total tracks: {array.Length}, Total entries: {list.Count}");
			int num = paginationData.CurrentPage * 27;
			int num2 = Mathf.Min(num + 27, array.Length);
			_config.LogDebug($"Page range - Start index: {num}, End index: {num2}");
			foreach (RectTransform item in list)
			{
				if ((Object)(object)item != (Object)null)
				{
					((Component)item).gameObject.SetActive(false);
				}
			}
			int num3 = 0;
			for (int j = num; j < num2; j++)
			{
				if (j < list.Count && (Object)(object)list[j] != (Object)null)
				{
					((Component)list[j]).gameObject.SetActive(true);
					num3++;
					Track val2 = array[j];
					if (jukeboxInterface.Jukebox.currentTrack == val2 && jukeboxInterface.Jukebox.IsPlaying)
					{
						((Component)((Transform)list[j]).Find("PlayPause/Icon")).GetComponent<Image>().sprite = jukeboxInterface.SongEntryPauseSprite;
					}
					else
					{
						((Component)((Transform)list[j]).Find("PlayPause/Icon")).GetComponent<Image>().sprite = jukeboxInterface.SongEntryPlaySprite;
					}
				}
			}
			_config.LogDebug($"Refreshed pagination - Showing {num3} entries on page {paginationData.CurrentPage + 1}");
		}

		private void StartButtonAnimation(Transform buttonTransform)
		{
			_config.LogDebug("StartButtonAnimation called");
			if ((Object)(object)buttonTransform == (Object)null)
			{
				MelonLogger.Error("StartButtonAnimation failed: Button transform is null");
				return;
			}
			try
			{
				object obj = MelonCoroutines.Start(AnimateButtonScale(buttonTransform));
				_config.LogDebug("Button animation coroutine started");
			}
			catch (Exception arg)
			{
				MelonLogger.Error($"Failed to start button animation coroutine: {arg}");
			}
		}

		[IteratorStateMachine(typeof(<AnimateButtonScale>d__10))]
		private IEnumerator AnimateButtonScale(Transform buttonTransform)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <AnimateButtonScale>d__10(0)
			{
				<>4__this = this,
				buttonTransform = buttonTransform
			};
		}

		public void RecreateSongEntries(JukeboxInterface jukeboxInterface)
		{
			if ((Object)(object)jukeboxInterface == (Object)null || (Object)(object)jukeboxInterface.Jukebox == (Object)null || (Object)(object)jukeboxInterface.EntryContainer == (Object)null)
			{
				return;
			}
			try
			{
				Type il2CppType = ((Object)jukeboxInterface).GetIl2CppType();
				FieldInfo field = il2CppType.GetField("songEntries", (BindingFlags)52);
				if (field == (FieldInfo)null)
				{
					_config.LogDebug("Cannot access songEntries field via IL2CPP reflection");
					return;
				}
				Object value = field.GetValue((Object)(object)jukeboxInterface);
				if (value == null)
				{
					_config.LogDebug("SongEntries field value is null");
					return;
				}
				List<RectTransform> list = new List<RectTransform>();
				List<RectTransform> val = ((Il2CppObjectBase)value).Cast<List<RectTransform>>();
				if (val == null)
				{
					_config.LogDebug("Could not cast to IL2CPP List");
					return;
				}
				for (int i = 0; i < val.Count; i++)
				{
					list.Add(val[i]);
				}
				_config.LogDebug($"Successfully accessed IL2CPP songEntries field with {list.Count} entries");
				if (list == null)
				{
					_config.LogDebug("Song entries list is null");
					return;
				}
				Track[] array = Il2CppArrayBase<Track>.op_Implicit((Il2CppArrayBase<Track>)(object)jukeboxInterface.Jukebox.TrackList);
				int count = list.Count;
				int num = array.Length;
				_config.LogDebug($"Recreating song entries: Current UI entries: {count}, Total tracks: {num}");
				foreach (RectTransform item in list)
				{
					if ((Object)(object)item != (Object)null)
					{
						Object.Destroy((Object)(object)((Component)item).gameObject);
					}
				}
				list.Clear();
				for (int j = 0; j < array.Length; j++)
				{
					Track val2 = array[j];
					if (val2 == null)
					{
						continue;
					}
					GameObject entry = Object.Instantiate<GameObject>(jukeboxInterface.SongEntryPrefab, (Transform)(object)jukeboxInterface.EntryContainer);
					((TMP_Text)((Component)entry.transform.Find("Name")).GetComponent<TextMeshProUGUI>()).text = val2.TrackName;
					((TMP_Text)((Component)entry.transform.Find("Artist")).GetComponent<TextMeshProUGUI>()).text = val2.ArtistName;
					entry.transform.SetAsLastSibling();
					int trackIndex = j;
					Action action = delegate
					{
						try
						{
							_config.LogDebug($"IL2CPP Song entry clicked at index {trackIndex}");
							if ((Object)(object)jukeboxInterface.Jukebox != (Object)null && trackIndex < ((Il2CppArrayBase<Track>)(object)jukeboxInterface.Jukebox.TrackList).Length)
							{
								Track val4 = ((Il2CppArrayBase<Track>)(object)jukeboxInterface.Jukebox.TrackList)[trackIndex];
								MelonLogger.Msg("Playing track: " + val4.TrackName);
								if ((Object)(object)val4.Clip != (Object)null)
								{
									_config.LogDebug("Track info - Name: " + val4.TrackName + ", ClipName: " + ((Object)val4.Clip).name + ", " + $"Length: {val4.Clip.length}s, " + $"Channels: {val4.Clip.channels}, " + $"Frequency: {val4.Clip.frequency}Hz, " + $"Samples: {val4.Clip.samples}");
								}
								else
								{
									MelonLogger.Warning("Track " + val4.TrackName + " has NULL clip!");
								}
								if (jukeboxInterface.Jukebox.IsPlaying)
								{
									if (jukeboxInterface.Jukebox.currentTrack == val4)
									{
										_config.LogDebug("Pausing current track");
										try
										{
											jukeboxInterface.Jukebox.TogglePlay();
											_config.LogDebug("Successfully toggled play state");
										}
										catch (Exception ex2)
										{
											MelonLogger.Error("Error toggling play: " + ex2.Message);
											MelonLogger.Error(ex2.StackTrace);
										}
									}
									else
									{
										_config.LogDebug("Switching to new track");
										try
										{
											jukeboxInterface.Jukebox.TogglePlay();
											_config.LogDebug("Stopped current track");
											_config.LogDebug($"Playing track at index {trackIndex}");
											jukeboxInterface.Jukebox.PlayTrack(trackIndex);
											_config.LogDebug("PlayTrack called successfully");
											if (jukeboxInterface.Jukebox.currentTrack != val4)
											{
												_config.LogDebug("PlayTrack didn't seem to change current track, trying direct audio source approach");
												if (_jukeboxPatcher.ForcePlayTrack(jukeboxInterface.Jukebox, trackIndex))
												{
													_config.LogDebug("Successfully forced track to play");
												}
												else
												{
													MelonLogger.Warning("Failed to force play track, trying reflection-based approach");
													FieldInfo field2 = ((Object)jukeboxInterface).GetIl2CppType().GetField("songEntries", (BindingFlags)52);
													if (field2 != (FieldInfo)null)
													{
														Object value2 = field2.GetValue((Object)(object)jukeboxInterface);
														if (value2 != null)
														{
															List<RectTransform> val5 = ((Il2CppObjectBase)value2).Cast<List<RectTransform>>();
															if (val5 != null && trackIndex < val5.Count)
															{
																RectTransform val6 = val5[trackIndex];
																MethodInfo method = ((Object)jukeboxInterface).GetIl2CppType().GetMethod("SongEntryClicked", (BindingFlags)20);
																if (method != (MethodInfo)null)
																{
																	Il2CppReferenceArray<Object> val7 = new Il2CppReferenceArray<Object>(1L) { [0] = ((Il2CppObjectBase)val6).Cast<Object>() };
																	((MethodBase)method).Invoke((Object)(object)jukeboxInterface, val7);
																	_config.LogDebug("Called SongEntryClicked via reflection");
																}
															}
														}
													}
												}
											}
										}
										catch (Exception ex3)
										{
											MelonLogger.Error("Error playing track: " + ex3.Message);
											MelonLogger.Error(ex3.StackTrace);
										}
									}
								}
								else
								{
									_config.LogDebug("Starting to play track");
									try
									{
										jukeboxInterface.Jukebox.PlayTrack(trackIndex);
										_config.LogDebug("PlayTrack called successfully");
										if (!jukeboxInterface.Jukebox.IsPlaying)
										{
											_config.LogDebug("Track did not start playing, trying direct audio source approach");
											if (_jukeboxPatcher.ForcePlayTrack(jukeboxInterface.Jukebox, trackIndex))
											{
												_config.LogDebug("Successfully forced track to play");
											}
											else
											{
												MelonLogger.Warning("Failed to force play track");
											}
										}
									}
									catch (Exception ex4)
									{
										MelonLogger.Error("Error playing track: " + ex4.Message);
										MelonLogger.Error(ex4.StackTrace);
									}
								}
								RefreshPagination(jukeboxInterface);
								if (!jukeboxInterface.Jukebox.IsPlaying)
								{
									MelonLogger.Warning("Jukebox is not playing after PlayTrack call!");
									try
									{
										FieldInfo field3 = ((Object)jukeboxInterface.Jukebox).GetIl2CppType().GetField("_audioSource", (BindingFlags)36);
										if (field3 != (FieldInfo)null)
										{
											Object value3 = field3.GetValue((Object)(object)jukeboxInterface.Jukebox);
											if (value3 != null)
											{
												AudioSource val8 = ((Il2CppObjectBase)value3).Cast<AudioSource>();
												_config.LogDebug($"AudioSource state - IsPlaying: {val8.isPlaying}, " + $"Volume: {val8.volume}, " + "Clip: " + (((Object)(object)val8.clip != (Object)null) ? ((Object)val8.clip).name : "NULL"));
											}
											else
											{
												MelonLogger.Warning("AudioSource field is null");
											}
										}
										return;
									}
									catch (Exception ex5)
									{
										MelonLogger.Error("Error checking AudioSource: " + ex5.Message);
										return;
									}
								}
								_config.LogDebug("Jukebox is now playing!");
							}
							else
							{
								MelonLogger.Error("Jukebox is null or track index is out of range");
								MethodInfo method2 = ((Object)jukeboxInterface).GetIl2CppType().GetMethod("SongEntryClicked", (BindingFlags)20);
								if (method2 != (MethodInfo)null)
								{
									Il2CppReferenceArray<Object> val9 = new Il2CppReferenceArray<Object>(1L) { [0] = ((Il2CppObjectBase)entry.GetComponent<RectTransform>()).Cast<Object>() };
									((MethodBase)method2).Invoke((Object)(object)jukeboxInterface, val9);
								}
								else
								{
									MelonLogger.Error("Could not find SongEntryClicked method via IL2CPP reflection");
								}
							}
						}
						catch (Exception ex6)
						{
							MelonLogger.Error("Error in song entry click handler: " + ex6.Message);
							MelonLogger.Error(ex6.StackTrace);
						}
					};
					if (!_paginationData.ContainsKey(jukeboxInterface))
					{
						_paginationData[jukeboxInterface] = new PaginationData();
					}
					RectTransform component = entry.GetComponent<RectTransform>();
					if ((Object)(object)component != (Object)null)
					{
						_paginationData[jukeboxInterface].EntryClickActions[component] = action;
					}
					((UnityEvent)((Component)entry.transform.Find("PlayPause")).GetComponent<Button>().onClick).AddListener(UnityAction.op_Implicit(action));
					list.Add(entry.GetComponent<RectTransform>());
				}
				List<RectTransform> val3 = new List<RectTransform>();
				foreach (RectTransform item2 in list)
				{
					val3.Add(item2);
				}
				field.SetValue((Object)(object)jukeboxInterface, (Object)(object)val3);
				_config.LogDebug($"Successfully recreated {list.Count} song entries for jukebox {((Object)jukeboxInterface.Jukebox).GetInstanceID()}");
			}
			catch (Exception ex)
			{
				MelonLogger.Error("Failed to recreate song entries: " + ex.Message);
				MelonLogger.Error(ex.StackTrace);
			}
		}

		public void CheckForUnpatchedInterfaces()
		{
			JukeboxInterface[] array = Il2CppArrayBase<JukeboxInterface>.op_Implicit(Object.FindObjectsOfType<JukeboxInterface>());
			bool flag = false;
			JukeboxInterface[] array2 = array;
			foreach (JukeboxInterface val in array2)
			{
				if ((Object)(object)val != (Object)null && !_paginationData.ContainsKey(val))
				{
					Jukebox jukebox = val.Jukebox;
					int num = ((jukebox != null) ? ((Object)jukebox).GetInstanceID() : (-1));
					if (num != -1 && _jukeboxPatcher.IsJukeboxPatched(num))
					{
						_config.LogDebug($"Found JukeboxInterface for already patched jukebox {num}, recreating song entries and setting up pagination");
						RecreateSongEntries(val);
						SetupPagination(val);
						flag = true;
					}
				}
			}
			if (flag)
			{
				_config.LogDebug("Applied pagination to newly found jukebox interfaces from saved game");
			}
		}

		[IteratorStateMachine(typeof(<CheckForSavedJukeboxInterfaces>d__13))]
		public IEnumerator CheckForSavedJukeboxInterfaces()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <CheckForSavedJukeboxInterfaces>d__13(0)
			{
				<>4__this = this
			};
		}
	}
	public class TrackManager
	{
		[CompilerGenerated]
		private sealed class <EnsureTrackLoaded>d__18 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public Track track;

			public Action<bool> onComplete;

			public TrackManager <>4__this;

			private string <filePath>5__1;

			private bool <success>5__2;

			private AudioClip <clip>5__3;

			private string <clipInfo>5__4;

			private Exception <ex>5__5;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<filePath>5__1 = null;
				<clip>5__3 = null;
				<clipInfo>5__4 = null;
				<ex>5__5 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0231: 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_0254: Invalid comparison between Unknown and I4
				if (<>1__state != 0)
				{
					return false;
				}
				<>1__state = -1;
				if (track == null)
				{
					<>4__this._config.LogDebug("Cannot load null track");
					onComplete?.Invoke(obj: false);
					return false;
				}
				if ((Object)(object)track.Clip != (Object)null)
				{
					<>4__this._config.LogDebug("Track " + track.TrackName + " is already loaded");
					onComplete?.Invoke(obj: true);
					return false;
				}
				if (!<>4__this._trackPaths.TryGetValue(track.TrackName, out <filePath>5__1))
				{
					MelonLogger.Error("Could not find file path for track " + track.TrackName);
					onComplete?.Invoke(obj: false);
					return false;
				}
				<>4__this._config.LogDebug("Loading audio for track: " + track.TrackName);
				<success>5__2 = false;
				try
				{
					<clip>5__3 = API.LoadAudioClip(<filePath>5__1, true);
					if ((Object)(object)<clip>5__3 == (Object)null)
					{
						MelonLogger.Error("AudioImportLib returned null clip for " + track.TrackName);
						onComplete?.Invoke(obj: false);
						return false;
					}
					<clipInfo>5__4 = "Name: " + ((Object)<clip>5__3).name + ", " + $"Length: {<clip>5__3.length}s, " + $"Channels: {<clip>5__3.channels}, " + $"Frequency: {<clip>5__3.frequency}Hz, " + $"Samples: {<clip>5__3.samples}, " + $"LoadState: {<clip>5__3.loadState}, " + $"Loaded: {(int)<clip>5__3.loadState == 2}";
					<>4__this._config.LogDebug("AudioImportLib Clip info: " + <clipInfo>5__4);
					((Object)<clip>5__3).name = track.TrackName;
					track.Clip = <clip>5__3;
					<>4__this._config.LogDebug("Successfully loaded audio for track: " + track.TrackName);
					<success>5__2 = true;
					<clip>5__3 = null;
					<clipInfo>5__4 = null;
				}
				catch (Exception ex)
				{
					<ex>5__5 = ex;
					MelonLogger.Error("Error loading track with AudioImportLib: " + <ex>5__5.Message);
					MelonLogger.Error(<ex>5__5.StackTrace);
				}
				onComplete?.Invoke(<success>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();
			}
		}

		[CompilerGenerated]
		private sealed class <LoadAudioFiles>d__17 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public TrackManager <>4__this;

			private string[] <audioFiles>5__1;

			private int <totalFiles>5__2;

			private int <i>5__3;

			private string <audioFile>5__4;

			private string <fileName>5__5;

			private Track <track>5__6;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<audioFiles>5__1 = null;
				<audioFile>5__4 = null;
				<fileName>5__5 = null;
				<track>5__6 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
				//IL_01af: Unknown result type (might be due to invalid IL or missing references)
				//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
				//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
				//IL_01d5: Expected O, but got Unknown
				int num = <>1__state;
				if (num != 0)
				{
					if (num != 1)
					{
						return false;
					}
					<>1__state = -1;
					goto IL_0234;
				}
				<>1__state = -1;
				if (!<>4__this._config.EnableCustomTracks.Value)
				{
					MelonLogger.Msg("Custom tracks are disabled in settings");
					<>4__this.TracksLoaded = true;
					return false;
				}
				if (!Directory.Exists(<>4__this._customSongsFolder))
				{
					Directory.CreateDirectory(<>4__this._customSongsFolder);
					MelonLogger.Msg("Created custom songs folder at " + <>4__this._customSongsFolder);
					MelonLogger.Msg("Place your .mp3 or .wav files in this folder");
					<>4__this.TracksLoaded = true;
					return false;
				}
				<audioFiles>5__1 = (from file in Directory.GetFiles(<>4__this._customSongsFolder)
					where file.EndsWith(".mp3", StringComparison.OrdinalIgnoreCase) || file.EndsWith(".wav", StringComparison.OrdinalIgnoreCase)
					select file).ToArray();
				if (<audioFiles>5__1.Length == 0)
				{
					MelonLogger.Msg("No audio files found in " + <>4__this._customSongsFolder);
					<>4__this.TracksLoaded = true;
					return false;
				}
				MelonLogger.Msg($"Found {<audioFiles>5__1.Length} audio files");
				<totalFiles>5__2 = <audioFiles>5__1.Length;
				<i>5__3 = 0;
				goto IL_025c;
				IL_025c:
				if (<i>5__3 < <audioFiles>5__1.Length)
				{
					<audioFile>5__4 = <audioFiles>5__1[<i>5__3];
					<fileName>5__5 = Path.GetFileNameWithoutExtension(<audioFile>5__4);
					<>4__this._trackPaths[<fileName>5__5] = <audioFile>5__4;
					<track>5__6 = new Track
					{
						TrackName = <fileName>5__5,
						ArtistName = "Custom",
						Clip = null
					};
					<>4__this.CustomTracks.Add(<track>5__6);
					<>4__this.LoadingProgress = (float)(<i>5__3 + 1) / (float)<totalFiles>5__2;
					if (<i>5__3 % 10 == 0)
					{
						<>2__current = null;
						<>1__state = 1;
						return true;
					}
					goto IL_0234;
				}
				<>4__this.TracksLoaded = true;
				MelonLogger.Msg($"Successfully indexed {<>4__this.CustomTracks.Count} custom tracks (lazy loading enabled)");
				return false;
				IL_0234:
				<audioFile>5__4 = null;
				<fileName>5__5 = null;
				<track>5__6 = null;
				<i>5__3++;
				goto IL_025c;
			}

			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 <LoadTrackCoroutine>d__19 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public string audioFile;

			public Action<Track> onComplete;

			public TrackManager <>4__this;

			private string <fileName>5__1;

			private string <extension>5__2;

			private AudioClip <clip>5__3;

			private string <clipInfo>5__4;

			private Track <track>5__5;

			private Exception <ex>5__6;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<fileName>5__1 = null;
				<extension>5__2 = null;
				<clip>5__3 = null;
				<clipInfo>5__4 = null;
				<track>5__5 = null;
				<ex>5__6 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0160: Unknown result type (might be due to invalid IL or missing references)
				//IL_017d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0183: Invalid comparison between Unknown and I4
				//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
				//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
				//IL_01e0: 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_01fe: Expected O, but got Unknown
				if (<>1__state != 0)
				{
					return false;
				}
				<>1__state = -1;
				<fileName>5__1 = Path.GetFileNameWithoutExtension(audioFile);
				<extension>5__2 = Path.GetExtension(audioFile).ToLowerInvariant();
				<>4__this._config.LogDebug("Loading " + <fileName>5__1 + " via AudioImportLib");
				try
				{
					<clip>5__3 = API.LoadAudioClip(audioFile, true);
					if ((Object)(object)<clip>5__3 == (Object)null)
					{
						MelonLogger.Error("AudioImportLib returned null clip for " + <fileName>5__1);
						onComplete?.Invoke(null);
						return false;
					}
					<clipInfo>5__4 = "Name: " + ((Object)<clip>5__3).name + ", " + $"Length: {<clip>5__3.length}s, " + $"Channels: {<clip>5__3.channels}, " + $"Frequency: {<clip>5__3.frequency}Hz, " + $"Samples: {<clip>5__3.samples}, " + $"LoadState: {<clip>5__3.loadState}, " + $"Loaded: {(int)<clip>5__3.loadState == 2}";
					<>4__this._config.LogDebug("AudioImportLib Clip info: " + <clipInfo>5__4);
					((Object)<clip>5__3).name = <fileName>5__1;
					<track>5__5 = new Track
					{
						TrackName = <fileName>5__1,
						ArtistName = "Custom",
						Clip = <clip>5__3
					};
					<>4__this._config.LogDebug("Successfully loaded track: " + <fileName>5__1);
					onComplete?.Invoke(<track>5__5);
					<clip>5__3 = null;
					<clipInfo>5__4 = null;
					<track>5__5 = null;
				}
				catch (Exception ex)
				{
					<ex>5__6 = ex;
					MelonLogger.Error("Error loading track with AudioImportLib: " + <ex>5__6.Message);
					MelonLogger.Error(<ex>5__6.StackTrace);
					onComplete?.Invoke(null);
				}
				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 readonly ModConfig _config;

		private readonly string _customSongsFolder;

		private readonly Dictionary<string, string> _trackPaths = new Dictionary<string, string>();

		private const float BATCH_INTERVAL = 0.1f;

		public List<Track> CustomTracks { get; private set; } = new List<Track>();


		public bool TracksLoaded { get; private set; }

		public float LoadingProgress { get; private set; }

		public TrackManager(ModConfig config, string customSongsFolder)
		{
			_config = config;
			_customSongsFolder = customSongsFolder;
		}

		[IteratorStateMachine(typeof(<LoadAudioFiles>d__17))]
		public IEnumerator LoadAudioFiles()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <LoadAudioFiles>d__17(0)
			{
				<>4__this = this
			};
		}

		[IteratorStateMachine(typeof(<EnsureTrackLoaded>d__18))]
		public IEnumerator EnsureTrackLoaded(Track track, Action<bool> onComplete = null)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <EnsureTrackLoaded>d__18(0)
			{
				<>4__this = this,
				track = track,
				onComplete = onComplete
			};
		}

		[IteratorStateMachine(typeof(<LoadTrackCoroutine>d__19))]
		private IEnumerator LoadTrackCoroutine(string audioFile, Action<Track> onComplete)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <LoadTrackCoroutine>d__19(0)
			{
				<>4__this = this,
				audioFile = audioFile,
				onComplete = onComplete
			};
		}
	}
}
namespace BetterJukebox.Patches
{
	public class HarmonyPatches
	{
		private readonly JukeboxPatcher _jukeboxPatcher;

		private readonly PaginationManager _paginationManager;

		private readonly TrackManager _trackManager;

		private Harmony _harmony;

		public HarmonyPatches(JukeboxPatcher jukeboxPatcher, PaginationManager paginationManager, TrackManager trackManager)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			_jukeboxPatcher = jukeboxPatcher;
			_paginationManager = paginationManager;
			_trackManager = trackManager;
			_harmony = new Harmony("com.bars.BetterJukebox");
		}

		public void SetupPatches()
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Expected O, but got Unknown
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Expected O, but got Unknown
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Expected O, but got Unknown
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Expected O, but got Unknown
			//IL_020d: Unknown result type (might be due to invalid IL or missing references)
			//IL_021b: Expected O, but got Unknown
			try
			{
				MethodInfo methodInfo = AccessTools.Method(typeof(Jukebox), "Awake", (Type[])null, (Type[])null);
				MethodInfo methodInfo2 = AccessTools.Method(typeof(HarmonyPatches), "JukeboxAwakePostfix", (Type[])null, (Type[])null);
				if (methodInfo != null && methodInfo2 != null)
				{
					_harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					MelonLogger.Msg("Successfully patched Jukebox.Awake method");
				}
				else
				{
					MelonLogger.Warning("Failed to patch Jukebox.Awake method. Will use fallback scanning instead.");
				}
				MethodInfo methodInfo3 = AccessTools.Method(typeof(JukeboxInterface), "SetupSongEntries", (Type[])null, (Type[])null);
				MethodInfo methodInfo4 = AccessTools.Method(typeof(HarmonyPatches), "SetupSongEntriesPostfix", (Type[])null, (Type[])null);
				if (methodInfo3 != null && methodInfo4 != null)
				{
					_harmony.Patch((MethodBase)methodInfo3, (HarmonyMethod)null, new HarmonyMethod(methodInfo4), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					MelonLogger.Msg("Successfully patched JukeboxInterface.SetupSongEntries method");
				}
				else
				{
					MelonLogger.Warning("Failed to patch JukeboxInterface.SetupSongEntries method");
				}
				MethodInfo methodInfo5 = AccessTools.Method(typeof(JukeboxInterface), "Open", (Type[])null, (Type[])null);
				MethodInfo methodInfo6 = AccessTools.Method(typeof(HarmonyPatches), "OpenPostfix", (Type[])null, (Type[])null);
				if (methodInfo5 != null && methodInfo6 != null)
				{
					_harmony.Patch((MethodBase)methodInfo5, (HarmonyMethod)null, new HarmonyMethod(methodInfo6), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
				MethodInfo methodInfo7 = AccessTools.Method(typeof(JukeboxInterface), "RefreshSongEntries", (Type[])null, (Type[])null);
				MethodInfo methodInfo8 = AccessTools.Method(typeof(HarmonyPatches), "RefreshSongEntriesPrefix", (Type[])null, (Type[])null);
				if (methodInfo7 != null && methodInfo8 != null)
				{
					_harmony.Patch((MethodBase)methodInfo7, new HarmonyMethod(methodInfo8), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
				try
				{
					MethodInfo methodInfo9 = AccessTools.Method(typeof(Jukebox), "PlayTrack", (Type[])null, (Type[])null);
					if (methodInfo9 != null)
					{
						MethodInfo methodInfo10 = AccessTools.Method(typeof(HarmonyPatches), "PlayTrackPrefix", (Type[])null, (Type[])null);
						_harmony.Patch((MethodBase)methodInfo9, new HarmonyMethod(methodInfo10), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
						MelonLogger.Msg("Successfully patched Jukebox.PlayTrack method");
					}
					else
					{
						MelonLogger.Warning("Could not find Jukebox.PlayTrack method");
					}
				}
				catch (Exception ex)
				{
					MelonLogger.Warning("Failed to patch PlayTrack method: " + ex.Message);
				}
			}
			catch (Exception ex2)
			{
				MelonLogger.Error("Failed to setup Harmony patches: " + ex2.Message);
				MelonLogger.Error(ex2.StackTrace);
			}
		}

		public static void JukeboxAwakePostfix(Jukebox __instance)
		{
			Core.OnJukeboxAwake(__instance);
		}

		public static void SetupSongEntriesPostfix(JukeboxInterface __instance)
		{
			Core.OnSetupSongEntries(__instance);
		}

		public static void OpenPostfix(JukeboxInterface __instance)
		{
			Core.OnJukeboxInterfaceOpen(__instance);
		}

		public static bool RefreshSongEntriesPrefix(JukeboxInterface __instance)
		{
			return Core.OnRefreshSongEntries(__instance);
		}

		public static bool PlayTrackPrefix(Jukebox __instance, int trackID)
		{
			return Core.OnPlayTrack(__instance, trackID);
		}
	}
}
namespace BetterJukebox.Models
{
	public class PaginationData
	{
		public Action PrevButtonAction;

		public Action NextButtonAction;

		public Dictionary<RectTransform, Action> EntryClickActions = new Dictionary<RectTransform, Action>();

		public int CurrentPage { get; set; } = 0;


		public int TotalPages { get; set; } = 1;


		public GameObject PaginationUI { get; set; }

		public Button PrevButton { get; set; }

		public Button NextButton { get; set; }

		public TextMeshProUGUI PageText { get; set; }

		public List<RectTransform> OriginalSongEntries { get; set; } = new List<RectTransform>();

	}
}
namespace BetterJukebox.Config
{
	public class ModConfig
	{
		private MelonPreferences_Category _category;