Decompiled source of BetterJukebox v1.0.0

Mods/BetterJukebox.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.Tasks;
using BetterJukebox;
using BetterJukebox.Config;
using BetterJukebox.Models;
using BetterJukebox.Patches;
using BetterJukebox.Services;
using BetterJukebox.Utils;
using HarmonyLib;
using MelonLoader;
using MelonLoader.Preferences;
using MelonLoader.Utils;
using Microsoft.CodeAnalysis;
using ScheduleOne.ObjectScripts;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Networking;
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")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("BetterJukebox")]
[assembly: AssemblyTitle("BetterJukebox")]
[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 <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);
		}

		[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;
		}
	}
}
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__7 : 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__7(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_029a: Unknown result type (might be due to invalid IL or missing references)
				//IL_02a4: Expected O, but got Unknown
				//IL_01f2: Unknown result type (might be due to invalid IL or missing references)
				//IL_01fc: Expected O, but got Unknown
				//IL_0225: Unknown result type (might be due to invalid IL or missing references)
				//IL_022f: 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_025d;
				case 2:
					<>1__state = -1;
					goto IL_0245;
				case 3:
					<>1__state = -1;
					goto IL_0245;
				case 4:
					{
						<>1__state = -1;
						<finalScan>5__1 = 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)
						{
							MelonLogger.Msg($"Final scan patched {<finalPatched>5__2} additional jukeboxes");
						}
						return false;
					}
					IL_025d:
					if (<attempt>5__3 < 3)
					{
						<>4__this._config.LogDebug($"Checking for saved jukeboxes (attempt {<attempt>5__3 + 1}/3)...");
						<jukeboxes>5__4 = 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)
						{
							MelonLogger.Msg($"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;
						}
					}
					MelonLogger.Msg($"Finished checking for saved jukeboxes, total patched: {<>4__this._patchedJukeboxIds.Count}");
					<>2__current = (object)new WaitForSeconds(5f);
					<>1__state = 4;
					return true;
					IL_0245:
					<jukeboxes>5__4 = null;
					<attempt>5__3++;
					goto IL_025d;
				}
			}

			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__5 : 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__5(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_022a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0234: 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 = 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)
						{
							MelonLogger.Msg($"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>();

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

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

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

		public void PatchJukebox(Jukebox jukebox)
		{
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Expected O, but got Unknown
			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[] trackList = jukebox.TrackList;
				if (trackList == null)
				{
					MelonLogger.Warning($"Jukebox {instanceID} has null TrackList, skipping");
					return;
				}
				Track[] array = (Track[])(object)new Track[trackList.Length + _trackManager.CustomTracks.Count];
				Array.Copy(trackList, array, trackList.Length);
				for (int i = 0; i < _trackManager.CustomTracks.Count; i++)
				{
					array[trackList.Length + i] = _trackManager.CustomTracks[i];
				}
				jukebox.TrackList = array;
				FieldInfo field = typeof(Jukebox).GetField("_jukeboxState", BindingFlags.Instance | BindingFlags.NonPublic);
				if (field != null)
				{
					JukeboxState val = (JukeboxState)field.GetValue(jukebox);
					if (val != null && val.TrackOrder != null)
					{
						int[] array2 = new int[array.Length];
						for (int j = 0; j < array2.Length; j++)
						{
							array2[j] = j;
						}
						val.TrackOrder = array2;
					}
				}
				_patchedJukeboxIds.Add(instanceID);
				MelonLogger.Msg($"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__7))]
		public IEnumerator CheckForSavedJukeboxes()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <CheckForSavedJukeboxes>d__7(0)
			{
				<>4__this = this
			};
		}
	}
	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_0038: Unknown result type (might be due to invalid IL or missing references)
				//IL_003d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0075: Unknown result type (might be due to invalid IL or missing references)
				//IL_007b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0085: Unknown result type (might be due to invalid IL or missing references)
				//IL_0090: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
				//IL_0109: Unknown result type (might be due to invalid IL or missing references)
				//IL_010f: Unknown result type (might be due to invalid IL or missing references)
				//IL_011a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0168: Unknown result type (might be due to invalid IL or missing references)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<originalScale>5__1 = buttonTransform.localScale;
					<duration>5__2 = 0.1f;
					<elapsed>5__3 = 0f;
					goto IL_00c5;
				case 1:
					<>1__state = -1;
					goto IL_00c5;
				case 2:
					{
						<>1__state = -1;
						break;
					}
					IL_00c5:
					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;
					}
					<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;
				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_032f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0339: Expected O, but got Unknown
				//IL_0294: Unknown result type (might be due to invalid IL or missing references)
				//IL_029e: Expected O, but got Unknown
				//IL_02dd: Unknown result type (might be due to invalid IL or missing references)
				//IL_02e7: 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_0317;
				case 2:
					<>1__state = -1;
					goto IL_02fd;
				case 3:
					<>1__state = -1;
					goto IL_02fd;
				case 4:
					{
						<>1__state = -1;
						<finalInterfaces>5__1 = 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)
						{
							MelonLogger.Msg($"Final scan applied pagination to {<finalCount>5__2} additional interfaces");
						}
						return false;
					}
					IL_0317:
					if (<attempt>5__3 < 3)
					{
						<>4__this._config.LogDebug($"Checking for saved jukebox interfaces (attempt {<attempt>5__3 + 1}/3)...");
						<interfaces>5__4 = 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)
						{
							MelonLogger.Msg($"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_02fd:
					<interfaces>5__4 = null;
					<attempt>5__3++;
					goto IL_0317;
				}
			}

			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_0379: Unknown result type (might be due to invalid IL or missing references)
			//IL_0383: Expected O, but got Unknown
			//IL_03c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ce: Expected O, but got Unknown
			//IL_03fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0429: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_04bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0501: Unknown result type (might be due to invalid IL or missing references)
			//IL_0522: Unknown result type (might be due to invalid IL or missing references)
			//IL_0543: Unknown result type (might be due to invalid IL or missing references)
			//IL_056a: Unknown result type (might be due to invalid IL or missing references)
			//IL_05a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ab: Expected O, but got Unknown
			//IL_05cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_05dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_05e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_063a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0677: Unknown result type (might be due to invalid IL or missing references)
			//IL_067e: Expected O, but got Unknown
			//IL_06a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0704: Unknown result type (might be due to invalid IL or missing references)
			//IL_074f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0759: Expected O, but got Unknown
			//IL_0786: Unknown result type (might be due to invalid IL or missing references)
			//IL_07b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_082d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0832: Unknown result type (might be due to invalid IL or missing references)
			//IL_084a: 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_08f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_092f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0936: Expected O, but got Unknown
			//IL_095a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0967: Unknown result type (might be due to invalid IL or missing references)
			//IL_0974: Unknown result type (might be due to invalid IL or missing references)
			//IL_09c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a06: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a10: Expected O, but got Unknown
			//IL_0a23: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a2d: Expected O, but got Unknown
			//IL_0458: Unknown result type (might be due to invalid IL or missing references)
			//IL_046f: Unknown result type (might be due to invalid IL or missing references)
			//IL_07e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_07fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0218: Unknown result type (might be due to invalid IL or missing references)
			//IL_021f: Expected O, but got Unknown
			//IL_0249: Unknown result type (might be due to invalid IL or missing references)
			//IL_0260: Unknown result type (might be due to invalid IL or missing references)
			//IL_0277: Unknown result type (might be due to invalid IL or missing references)
			//IL_028e: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cf: 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 num = jukeboxInterface.Jukebox.TrackList.Length;
				if (num <= 27)
				{
					_config.LogDebug($"No pagination needed, track count ({num}) <= 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)num / 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", new Type[1] { typeof(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 = val.AddComponent<Image>();
				((Graphic)val2).color = new Color(0.1f, 0.1f, 0.1f, 0.8f);
				try
				{
					Type type = Type.GetType("UnityEngine.UI.Extensions.UICornerCut, Unity.UI.Extensions");
					if (type != null)
					{
						Component obj = val.AddComponent(type);
						MonoBehaviour obj2 = (MonoBehaviour)(object)((obj is MonoBehaviour) ? obj : null);
						FieldInfo field = type.GetField("cornerRadius");
						if (field != null)
						{
							field.SetValue(obj2, 10f);
						}
					}
				}
				catch (Exception)
				{
					_config.LogDebug("Couldn't add rounded corners to pagination UI");
				}
				HorizontalLayoutGroup val3 = val.AddComponent<HorizontalLayoutGroup>();
				((LayoutGroup)val3).childAlignment = (TextAnchor)4;
				((HorizontalOrVerticalLayoutGroup)val3).spacing = 10f;
				((LayoutGroup)val3).padding = new RectOffset(10, 10, 5, 5);
				GameObject prevButton = new GameObject("PrevButton", new Type[4]
				{
					typeof(RectTransform),
					typeof(CanvasRenderer),
					typeof(Image),
					typeof(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 val4 = prevButton.AddComponent<Outline>();
					((Shadow)val4).effectColor = new Color(0.3f, 0.3f, 0.3f, 0.5f);
					((Shadow)val4).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 val5 = new GameObject("Text", new Type[3]
				{
					typeof(RectTransform),
					typeof(CanvasRenderer),
					typeof(TextMeshProUGUI)
				});
				val5.transform.SetParent(prevButton.transform, false);
				RectTransform component5 = val5.GetComponent<RectTransform>();
				component5.anchorMin = Vector2.zero;
				component5.anchorMax = Vector2.one;
				component5.sizeDelta = Vector2.zero;
				TextMeshProUGUI component6 = val5.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 val6 = new GameObject("PageText", new Type[3]
				{
					typeof(RectTransform),
					typeof(CanvasRenderer),
					typeof(TextMeshProUGUI)
				});
				val6.transform.SetParent((Transform)(object)component, false);
				RectTransform component7 = val6.GetComponent<RectTransform>();
				component7.sizeDelta = new Vector2(150f, 40f);
				TextMeshProUGUI component8 = val6.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", new Type[4]
				{
					typeof(RectTransform),
					typeof(CanvasRenderer),
					typeof(Image),
					typeof(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 val7 = nextButton.AddComponent<Outline>();
					((Shadow)val7).effectColor = new Color(0.3f, 0.3f, 0.3f, 0.5f);
					((Shadow)val7).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 val8 = new GameObject("Text", new Type[3]
				{
					typeof(RectTransform),
					typeof(CanvasRenderer),
					typeof(TextMeshProUGUI)
				});
				val8.transform.SetParent(nextButton.transform, false);
				RectTransform component12 = val8.GetComponent<RectTransform>();
				component12.anchorMin = Vector2.zero;
				component12.anchorMax = Vector2.one;
				component12.sizeDelta = Vector2.zero;
				TextMeshProUGUI component13 = val8.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;
				((UnityEvent)paginationData.PrevButton.onClick).AddListener((UnityAction)delegate
				{
					StartButtonAnimation(prevButton.transform);
					ChangePage(jukeboxInterface, -1);
				});
				((UnityEvent)paginationData.NextButton.onClick).AddListener((UnityAction)delegate
				{
					StartButtonAnimation(nextButton.transform);
					ChangePage(jukeboxInterface, 1);
				});
				_paginationData[jukeboxInterface] = paginationData;
				UpdatePaginationUI(jukeboxInterface);
				MelonLogger.Msg($"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)
		{
			if (_paginationData.ContainsKey(jukeboxInterface))
			{
				PaginationData paginationData = _paginationData[jukeboxInterface];
				int num = paginationData.CurrentPage + delta;
				if (num >= 0 && num < paginationData.TotalPages)
				{
					paginationData.CurrentPage = num;
					UpdatePaginationUI(jukeboxInterface);
					RefreshPagination(jukeboxInterface);
				}
			}
		}

		public void UpdatePaginationUI(JukeboxInterface jukeboxInterface)
		{
			if (_paginationData.ContainsKey(jukeboxInterface))
			{
				PaginationData paginationData = _paginationData[jukeboxInterface];
				((TMP_Text)paginationData.PageText).text = $"Page {paginationData.CurrentPage + 1}/{paginationData.TotalPages}";
				((Selectable)paginationData.PrevButton).interactable = paginationData.CurrentPage > 0;
				((Selectable)paginationData.NextButton).interactable = paginationData.CurrentPage < paginationData.TotalPages - 1;
			}
		}

		public void RefreshPagination(JukeboxInterface jukeboxInterface)
		{
			if (!_paginationData.ContainsKey(jukeboxInterface))
			{
				return;
			}
			PaginationData paginationData = _paginationData[jukeboxInterface];
			FieldInfo fieldInfo = AccessTools.Field(typeof(JukeboxInterface), "songEntries");
			if (fieldInfo == null || !(fieldInfo.GetValue(jukeboxInterface) is List<RectTransform> list))
			{
				return;
			}
			Track[] trackList = jukeboxInterface.Jukebox.TrackList;
			int num = paginationData.CurrentPage * 27;
			int num2 = Mathf.Min(num + 27, trackList.Length);
			foreach (RectTransform item in list)
			{
				if ((Object)(object)item != (Object)null)
				{
					((Component)item).gameObject.SetActive(false);
				}
			}
			for (int i = num; i < num2; i++)
			{
				if (i < list.Count && (Object)(object)list[i] != (Object)null)
				{
					((Component)list[i]).gameObject.SetActive(true);
					Track val = trackList[i];
					if (jukeboxInterface.Jukebox.currentTrack == val && jukeboxInterface.Jukebox.IsPlaying)
					{
						((Component)((Transform)list[i]).Find("PlayPause/Icon")).GetComponent<Image>().sprite = jukeboxInterface.SongEntryPauseSprite;
					}
					else
					{
						((Component)((Transform)list[i]).Find("PlayPause/Icon")).GetComponent<Image>().sprite = jukeboxInterface.SongEntryPlaySprite;
					}
				}
			}
		}

		private void StartButtonAnimation(Transform buttonTransform)
		{
			MelonCoroutines.Start(AnimateButtonScale(buttonTransform));
		}

		[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)
		{
			//IL_023d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0247: Expected O, but got Unknown
			if ((Object)(object)jukeboxInterface == (Object)null || (Object)(object)jukeboxInterface.Jukebox == (Object)null || (Object)(object)jukeboxInterface.EntryContainer == (Object)null)
			{
				return;
			}
			try
			{
				FieldInfo fieldInfo = AccessTools.Field(typeof(JukeboxInterface), "songEntries");
				if (fieldInfo == null)
				{
					_config.LogDebug("Cannot access songEntries field");
					return;
				}
				if (!(fieldInfo.GetValue(jukeboxInterface) is List<RectTransform> list))
				{
					_config.LogDebug("Song entries list is null");
					return;
				}
				Track[] trackList = jukeboxInterface.Jukebox.TrackList;
				int count = list.Count;
				int num = trackList.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 i = 0; i < trackList.Length; i++)
				{
					Track val = trackList[i];
					if (val == null)
					{
						continue;
					}
					GameObject entry = Object.Instantiate<GameObject>(jukeboxInterface.SongEntryPrefab, (Transform)(object)jukeboxInterface.EntryContainer);
					((TMP_Text)((Component)entry.transform.Find("Name")).GetComponent<TextMeshProUGUI>()).text = val.TrackName;
					((TMP_Text)((Component)entry.transform.Find("Artist")).GetComponent<TextMeshProUGUI>()).text = val.ArtistName;
					entry.transform.SetAsLastSibling();
					int num2 = i;
					((UnityEvent)((Component)entry.transform.Find("PlayPause")).GetComponent<Button>().onClick).AddListener((UnityAction)delegate
					{
						MethodInfo method = typeof(JukeboxInterface).GetMethod("SongEntryClicked", BindingFlags.Instance | BindingFlags.Public);
						if (method != null)
						{
							method.Invoke(jukeboxInterface, new object[1] { entry.GetComponent<RectTransform>() });
						}
					});
					list.Add(entry.GetComponent<RectTransform>());
				}
				fieldInfo.SetValue(jukeboxInterface, list);
				MelonLogger.Msg($"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 = 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)
			{
				MelonLogger.Msg("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 <LoadAudioFiles>d__16 : 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 <completedFiles>5__3;

			private int <batchSize>5__4;

			private int <batchStart>5__5;

			private int <currentBatchSize>5__6;

			private List<Task<Track>> <batchTasks>5__7;

			private int <i>5__8;

			private int <fileIndex>5__9;

			private string <audioFile>5__10;

			private List<Task<Track>>.Enumerator <>s__11;

			private Task<Track> <task>5__12;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<audioFiles>5__1 = null;
				<batchTasks>5__7 = null;
				<audioFile>5__10 = null;
				<>s__11 = default(List<Task<Track>>.Enumerator);
				<task>5__12 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_035a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0364: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>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 to load");
					<totalFiles>5__2 = <audioFiles>5__1.Length;
					<completedFiles>5__3 = 0;
					<batchSize>5__4 = Mathf.Clamp(<>4__this._config.LoadingBatchSize?.Value ?? 5, 1, 10);
					<batchStart>5__5 = 0;
					goto IL_038f;
				case 1:
					<>1__state = -1;
					goto IL_0266;
				case 2:
					{
						<>1__state = -1;
						<batchTasks>5__7 = null;
						<batchStart>5__5 += <batchSize>5__4;
						goto IL_038f;
					}
					IL_0266:
					if (<batchTasks>5__7.Any((Task<Track> t) => !t.IsCompleted))
					{
						<>2__current = null;
						<>1__state = 1;
						return true;
					}
					<>s__11 = <batchTasks>5__7.GetEnumerator();
					try
					{
						while (<>s__11.MoveNext())
						{
							<task>5__12 = <>s__11.Current;
							if (<task>5__12.Result != null)
							{
								<>4__this.CustomTracks.Add(<task>5__12.Result);
							}
							<completedFiles>5__3++;
							<>4__this.LoadingProgress = (float)<completedFiles>5__3 / (float)<totalFiles>5__2;
							<task>5__12 = null;
						}
					}
					finally
					{
						((IDisposable)<>s__11).Dispose();
					}
					<>s__11 = default(List<Task<Track>>.Enumerator);
					<>2__current = (object)new WaitForSeconds(0.1f);
					<>1__state = 2;
					return true;
					IL_038f:
					if (<batchStart>5__5 < <totalFiles>5__2)
					{
						<currentBatchSize>5__6 = Math.Min(<batchSize>5__4, <totalFiles>5__2 - <batchStart>5__5);
						<batchTasks>5__7 = new List<Task<Track>>();
						<i>5__8 = 0;
						while (<i>5__8 < <currentBatchSize>5__6)
						{
							<fileIndex>5__9 = <batchStart>5__5 + <i>5__8;
							<audioFile>5__10 = <audioFiles>5__1[<fileIndex>5__9];
							<batchTasks>5__7.Add(<>4__this.LoadTrackAsync(<audioFile>5__10));
							<audioFile>5__10 = null;
							<i>5__8++;
						}
						goto IL_0266;
					}
					<>4__this.TracksLoaded = true;
					MelonLogger.Msg($"Successfully loaded {<>4__this.CustomTracks.Count} custom tracks");
					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 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__16))]
		public IEnumerator LoadAudioFiles()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <LoadAudioFiles>d__16(0)
			{
				<>4__this = this
			};
		}

		private async Task<Track> LoadTrackAsync(string audioFile)
		{
			try
			{
				string fileName = Path.GetFileNameWithoutExtension(audioFile);
				UnityWebRequest www = UnityWebRequestMultimedia.GetAudioClip("file://" + audioFile, AudioUtils.GetAudioType(audioFile));
				try
				{
					UnityWebRequestAsyncOperation operation = www.SendWebRequest();
					while (!((AsyncOperation)operation).isDone)
					{
						await Task.Delay(10);
					}
					if ((int)www.result != 1)
					{
						MelonLogger.Error("Failed to load " + fileName + ": " + www.error);
						return null;
					}
					AudioClip clip = DownloadHandlerAudioClip.GetContent(www);
					if ((Object)(object)clip != (Object)null)
					{
						((Object)clip).name = fileName;
						Track track = new Track
						{
							TrackName = fileName,
							ArtistName = "Custom",
							Clip = clip
						};
						MelonLogger.Msg("Loaded track: " + fileName);
						return track;
					}
				}
				finally
				{
					((IDisposable)www)?.Dispose();
				}
			}
			catch (Exception ex2)
			{
				Exception ex = ex2;
				MelonLogger.Error("Error loading track " + Path.GetFileName(audioFile) + ": " + ex.Message);
			}
			return null;
		}
	}
}
namespace BetterJukebox.Patches
{
	public class HarmonyPatches
	{
		private readonly JukeboxPatcher _jukeboxPatcher;

		private readonly PaginationManager _paginationManager;

		public HarmonyPatches(JukeboxPatcher jukeboxPatcher, PaginationManager paginationManager)
		{
			_jukeboxPatcher = jukeboxPatcher;
			_paginationManager = paginationManager;
		}

		public void SetupPatches()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Expected O, but got Unknown
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Expected O, but got Unknown
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Expected O, but got Unknown
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Expected O, but got Unknown
			try
			{
				Harmony val = new Harmony("com.bars.BetterJukebox");
				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)
				{
					val.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)
				{
					val.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)
				{
					val.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)
				{
					val.Patch((MethodBase)methodInfo7, new HarmonyMethod(methodInfo8), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Error("Failed to setup Harmony patches: " + ex.Message);
				MelonLogger.Error(ex.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);
		}
	}
}
namespace BetterJukebox.Models
{
	public class PaginationData
	{
		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;

		public MelonPreferences_Entry<bool> EnableCustomTracks { get; private set; }

		public MelonPreferences_Entry<bool> EnableDebugLogs { get; private set; }

		public MelonPreferences_Entry<bool> ShowLoadingIndicator { get; private set; }

		public MelonPreferences_Entry<int> LoadingBatchSize { get; private set; }

		public void Initialize()
		{
			_category = MelonPreferences.CreateCategory("BetterJukebox");
			EnableCustomTracks = _category.CreateEntry<bool>("EnableCustomTracks", true, "Enable Custom Tracks", "Enable loading custom tracks from the mod folder", false, false, (ValueValidator)null, (string)null);
			EnableDebugLogs = _category.CreateEntry<bool>("EnableDebugLogs", false, "Enable Debug Logs", "Enable detailed debug logs", false, false, (ValueValidator)null, (string)null);
			ShowLoadingIndicator = _category.CreateEntry<bool>("ShowLoadingIndicator", true, "Show Loading Indicator", "Show a progress indicator when loading custom tracks", false, false, (ValueValidator)null, (string)null);
			LoadingBatchSize = _category.CreateEntry<int>("LoadingBatchSize", 5, "Loading Batch Size", "Number of tracks to load simultaneously (1-10, higher values may cause lag)", false, false, (ValueValidator)null, (string)null);
			MelonLogger.Msg("Config initialized");
		}

		public void LogDebug(string message)
		{
			if (EnableDebugLogs.Value)
			{
				MelonLogger.Msg("[Debug] " + message);
			}
		}
	}
}