Decompiled source of CustomCruiserRadioLoader v1.1.1

LC_CruiserTunes.dll

Decompiled 2 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using LethalNetworkAPI;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Networking;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.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;
		}
	}
}
public class CarPatch
{
	[CompilerGenerated]
	private sealed class <AudioSourceListener>d__7 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public AudioSource radio;

		public VehicleController instance;

		private AudioClip <clip>5__1;

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

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

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

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

		private bool MoveNext()
		{
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				break;
			case 1:
				<>1__state = -1;
				if ((Object)(object)<clip>5__1 != (Object)(object)radio.clip)
				{
					if (CruiserTunesMod.GoodQuality.Value)
					{
						radio.volume = 1f;
						instance.radioInterference.volume = 0f;
					}
					if ((Object)(object)CruiserTunesMod.instance != (Object)null)
					{
						((MonoBehaviour)CruiserTunesMod.instance).StartCoroutine(PlayNotification(instance));
					}
				}
				<clip>5__1 = null;
				break;
			}
			if ((Object)(object)radio != (Object)null && (Object)(object)instance != (Object)null)
			{
				<clip>5__1 = radio.clip;
				instance.radioAudio.loop = CruiserTunesMod.DoLoop.Value;
				<>2__current = null;
				<>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();
		}
	}

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

		private object <>2__current;

		public AudioSource audio;

		private float <timeout>5__1;

		private float <start>5__2;

		private float <max>5__3;

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

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

		[DebuggerHidden]
		public <EnsureClipReadyAndPlay>d__10(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;
				<timeout>5__1 = 5f;
				<start>5__2 = Time.time;
				break;
			case 1:
				<>1__state = -1;
				break;
			}
			if (((Object)(object)audio == (Object)null || (Object)(object)audio.clip == (Object)null || audio.clip.length <= 0f || !audio.clip.isReadyToPlay) && !(Time.time - <start>5__2 > <timeout>5__1))
			{
				<>2__current = null;
				<>1__state = 1;
				return true;
			}
			if ((Object)(object)audio == (Object)null || (Object)(object)audio.clip == (Object)null || audio.clip.length <= 0f)
			{
				return false;
			}
			if (!audio.isPlaying)
			{
				audio.Play();
			}
			if (CruiserTunesMod.DoRandomTime != null && CruiserTunesMod.DoRandomTime.Value)
			{
				<max>5__3 = Mathf.Max(0.01f, audio.clip.length - 0.1f);
				audio.time = Random.Range(0.01f, <max>5__3);
			}
			else
			{
				audio.time = 0f;
			}
			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 <PlayNotification>d__8 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public VehicleController instance;

		private AudioClip <clip>5__1;

		private PlayerControllerB <localPlayer>5__2;

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

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

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

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

		private bool MoveNext()
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Expected O, but got Unknown
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				if (CruiserTunesMod.DoMessage.Value)
				{
					<clip>5__1 = instance.radioAudio.clip;
					<>2__current = (object)new WaitForSeconds(2f);
					<>1__state = 1;
					return true;
				}
				break;
			case 1:
				<>1__state = -1;
				if ((Object)(object)<clip>5__1 == (Object)(object)instance.radioAudio.clip)
				{
					<localPlayer>5__2 = StartOfRound.Instance.localPlayerController;
					if ((Object)(object)<localPlayer>5__2 != (Object)null && (Object)(object)instance != (Object)null && Vector3.Distance(((Component)<localPlayer>5__2).transform.position, ((Component)instance).transform.position) < 10f)
					{
						HUDManager.Instance.DisplayTip("Now Playing:", ((Object)<clip>5__1).name.Replace("Radio_", "") + " - " + FormatLength(<clip>5__1.length), false, false, "LC_Tip1");
					}
					<localPlayer>5__2 = null;
				}
				<clip>5__1 = null;
				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();
		}
	}

	[HarmonyPatch(typeof(VehicleController), "Awake")]
	[HarmonyPostfix]
	public static void AwakePatch(VehicleController __instance)
	{
		if (CruiserTunesMod.HasSongs)
		{
			AudioClip[] source = ((!CruiserTunesMod.IncludeOriginal.Value) ? CruiserTunesMod.CustomSongs : __instance.radioClips.Concat(CruiserTunesMod.CustomSongs).ToArray());
			source = source.OrderByDescending((AudioClip str) => GetAsciiSum(((Object)str).name)).ToArray();
			__instance.radioClips = source;
			__instance.radioAudio.loop = CruiserTunesMod.DoLoop.Value;
			if ((Object)(object)CruiserTunesMod.instance != (Object)null)
			{
				((MonoBehaviour)CruiserTunesMod.instance).StartCoroutine(AudioSourceListener(__instance.radioAudio, __instance));
			}
		}
		static int GetAsciiSum(string str)
		{
			return str.Sum((char c) => c);
		}
	}

	public static void UpdateLooping(object sender, EventArgs e)
	{
		Object val = Object.FindObjectOfType(typeof(VehicleController));
		VehicleController val2 = (VehicleController)(object)((val is VehicleController) ? val : null);
		if (val2 != null)
		{
			val2.radioAudio.loop = CruiserTunesMod.DoLoop.Value;
		}
	}

	public static void ChangeVolume(object sender, EventArgs e)
	{
		Object val = Object.FindObjectOfType(typeof(VehicleController));
		VehicleController val2 = (VehicleController)(object)((val is VehicleController) ? val : null);
		if (val2 != null)
		{
			val2.radioAudio.volume = Mathf.Clamp(CruiserTunesMod.Volume.Value, 0f, 1.25f);
		}
	}

	[HarmonyPatch(typeof(VehicleController), "ChangeRadioStation")]
	[HarmonyPostfix]
	public static void ChangeRadioStationPatch(VehicleController __instance)
	{
		float playbackTime = 0f;
		if (CruiserTunesMod.DoRandomTime != null && CruiserTunesMod.DoRandomTime.Value && (Object)(object)__instance.radioAudio != (Object)null && (Object)(object)__instance.radioAudio.clip != (Object)null && __instance.radioAudio.clip.length > 0f)
		{
			float num = Math.Max(0.01f, __instance.radioAudio.clip.length - 0.1f);
			playbackTime = Random.Range(0.01f, num);
		}
		if (CruiserTunesMod.SyncPlaybackTimeMessage != null)
		{
			FieldInfo field = ((object)__instance).GetType().GetField("currentRadioClip", BindingFlags.Instance | BindingFlags.NonPublic);
			int station = ((field != null) ? ((int)field.GetValue(__instance)) : 0);
			CruiserTunesMod.RadioSyncData radioSyncData = default(CruiserTunesMod.RadioSyncData);
			radioSyncData.Station = station;
			radioSyncData.PlaybackTime = playbackTime;
			CruiserTunesMod.RadioSyncData radioSyncData2 = radioSyncData;
			CruiserTunesMod.PendingSyncData = radioSyncData2;
			CruiserTunesMod.SyncPlaybackTimeMessage.SendClients(radioSyncData2);
		}
	}

	[HarmonyPatch(typeof(VehicleController), "SetRadioOnLocalClient")]
	[HarmonyPrefix]
	public static void SetOnClientPatch(VehicleController __instance)
	{
		Type type = ((object)__instance).GetType();
		FieldInfo field = type.GetField("currentRadioClip", BindingFlags.Instance | BindingFlags.NonPublic);
		field.SetValue(__instance, (int)field.GetValue(__instance) % __instance.radioClips.Length);
	}

	[HarmonyPatch(typeof(VehicleController), "SetRadioValues")]
	[HarmonyPrefix]
	public static void SetRadioValuesPatch(VehicleController __instance)
	{
		if (CruiserTunesMod.GoodQuality.Value)
		{
			__instance.radioAudio.volume = 1f;
			__instance.radioInterference.volume = 0f;
		}
	}

	[HarmonyPatch(typeof(VehicleController), "SwitchRadio")]
	[HarmonyPrefix]
	public static void SwitchRadioPatch(VehicleController __instance)
	{
	}

	[IteratorStateMachine(typeof(<AudioSourceListener>d__7))]
	public static IEnumerator AudioSourceListener(AudioSource radio, VehicleController instance)
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <AudioSourceListener>d__7(0)
		{
			radio = radio,
			instance = instance
		};
	}

	[IteratorStateMachine(typeof(<PlayNotification>d__8))]
	public static IEnumerator PlayNotification(VehicleController instance)
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <PlayNotification>d__8(0)
		{
			instance = instance
		};
	}

	public static string FormatLength(float lengthInSeconds)
	{
		int num = Mathf.FloorToInt(lengthInSeconds / 3600f);
		int num2 = Mathf.FloorToInt(lengthInSeconds % 3600f / 60f);
		int num3 = Mathf.FloorToInt(lengthInSeconds % 60f);
		return $"{num:00}:{num2:00}:{num3:00}";
	}

	[IteratorStateMachine(typeof(<EnsureClipReadyAndPlay>d__10))]
	public static IEnumerator EnsureClipReadyAndPlay(AudioSource audio)
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <EnsureClipReadyAndPlay>d__10(0)
		{
			audio = audio
		};
	}

	public static void ChangeRadioStationWithoutServer(VehicleController instance)
	{
		Type type = ((object)instance).GetType();
		FieldInfo field = type.GetField("radioSignalDecreaseThreshold", BindingFlags.Instance | BindingFlags.NonPublic);
		FieldInfo field2 = type.GetField("radioSignalQuality", BindingFlags.Instance | BindingFlags.NonPublic);
		FieldInfo field3 = type.GetField("currentRadioClip", BindingFlags.Instance | BindingFlags.NonPublic);
		int num = ((int)field3.GetValue(instance) + 1) % instance.radioClips.Length;
		field3.SetValue(instance, num);
		instance.radioAudio.clip = instance.radioClips[num];
		if ((Object)(object)CruiserTunesMod.instance != (Object)null)
		{
			((MonoBehaviour)CruiserTunesMod.instance).StartCoroutine(EnsureClipReadyAndPlay(instance.radioAudio));
		}
		else
		{
			if (CruiserTunesMod.DoRandomTime.Value && (Object)(object)instance.radioAudio.clip != (Object)null && instance.radioAudio.clip.length > 0f)
			{
				float num2 = Math.Max(0.01f, instance.radioAudio.clip.length - 0.1f);
				instance.radioAudio.time = Random.Range(0.01f, num2);
			}
			else
			{
				instance.radioAudio.time = 0f;
			}
			instance.radioAudio.Play();
		}
		float num3 = 10f;
		float num4 = (float)field2.GetValue(instance);
		switch ((int)Mathf.Round(num4))
		{
		case 3:
			num4 = 1f;
			num3 = 10f;
			break;
		case 0:
			num4 = 3f;
			num3 = 90f;
			break;
		case 1:
			num4 = 2f;
			num3 = 70f;
			break;
		case 2:
			num4 = 1f;
			num3 = 30f;
			break;
		}
		field2.SetValue(instance, num4);
		field.SetValue(instance, num3);
		ChangeRadioStationPatch(instance);
	}
}
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInPlugin("Mellowdy.CruiserTunes", "CruiserTunes", "1.3.0")]
public class CruiserTunesMod : BaseUnityPlugin
{
	[Serializable]
	public struct RadioSyncData
	{
		public int Station;

		public float PlaybackTime;
	}

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

		private object <>2__current;

		private bool <finishedLoading>5__1;

		private bool[] <array>5__2;

		private int <i>5__3;

		private string <currentDirectory>5__4;

		private string <path>5__5;

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

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

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

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			<array>5__2 = null;
			<currentDirectory>5__4 = null;
			<path>5__5 = null;
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			int num = <>1__state;
			if (num != 0)
			{
				if (num != 1)
				{
					return false;
				}
				<>1__state = -1;
				goto IL_00ea;
			}
			<>1__state = -1;
			mls.LogInfo((object)("Loading " + instance.loadingList.Length + " songs"));
			<finishedLoading>5__1 = false;
			goto IL_00f2;
			IL_00ea:
			<array>5__2 = null;
			goto IL_00f2;
			IL_00f2:
			if (!<finishedLoading>5__1)
			{
				<finishedLoading>5__1 = true;
				<array>5__2 = instance.loadingList;
				<i>5__3 = 0;
				while (<i>5__3 < <array>5__2.Length)
				{
					if (!<array>5__2[<i>5__3])
					{
						<finishedLoading>5__1 = false;
						break;
					}
					<i>5__3++;
				}
				if (!<finishedLoading>5__1)
				{
					<>2__current = null;
					<>1__state = 1;
					return true;
				}
				goto IL_00ea;
			}
			instance.loadingList = null;
			mls.LogInfo((object)("Finished loading songs, final song count at:" + instance.SongList.Count));
			if (instance.SongList.Count == 0)
			{
				<currentDirectory>5__4 = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
				<path>5__5 = Path.Combine(<currentDirectory>5__4, instance.folderName).Replace("\\", "/");
				mls.LogError((object)"No songs found in folder");
				mls.LogError((object)("Make sure to add any .mp3 or .wav or .ogg files you want as songs to: '" + <path>5__5 + "'"));
				<currentDirectory>5__4 = null;
				<path>5__5 = null;
			}
			CustomSongs = instance.SongList.ToArray();
			instance.SongList.Clear();
			HasSongs = CustomSongs.Length != 0 || IncludeOriginal.Value;
			mls.LogInfo((object)"CruiserTunes has been loaded with loleo's fix");
			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 <EnsureClipReadyAndPlay>d__31 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public AudioSource audio;

		private float <timeout>5__1;

		private float <start>5__2;

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

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

		[DebuggerHidden]
		public <EnsureClipReadyAndPlay>d__31(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;
				<timeout>5__1 = 5f;
				<start>5__2 = Time.time;
				break;
			case 1:
				<>1__state = -1;
				break;
			}
			if (((Object)(object)audio == (Object)null || (Object)(object)audio.clip == (Object)null || audio.clip.length <= 0f || !audio.clip.isReadyToPlay) && !(Time.time - <start>5__2 > <timeout>5__1))
			{
				<>2__current = null;
				<>1__state = 1;
				return true;
			}
			if ((Object)(object)audio == (Object)null || (Object)(object)audio.clip == (Object)null || audio.clip.length <= 0f)
			{
				return false;
			}
			if (!audio.isPlaying)
			{
				audio.Play();
			}
			audio.time = Mathf.Clamp(audio.time, 0.01f, audio.clip.length - 0.1f);
			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 <EnsureClipReadyAndPlayAt>d__30 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public AudioSource audio;

		public float timeToSet;

		private float <timeout>5__1;

		private float <start>5__2;

		private float <clampedTime>5__3;

		private float <guardEnd>5__4;

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

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

		[DebuggerHidden]
		public <EnsureClipReadyAndPlayAt>d__30(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;
				<timeout>5__1 = 5f;
				<start>5__2 = Time.time;
				goto IL_0079;
			case 1:
				<>1__state = -1;
				goto IL_0079;
			case 2:
				{
					<>1__state = -1;
					break;
				}
				IL_0079:
				if (((Object)(object)audio == (Object)null || (Object)(object)audio.clip == (Object)null || audio.clip.length <= 0f || !audio.clip.isReadyToPlay) && !(Time.time - <start>5__2 > <timeout>5__1))
				{
					<>2__current = null;
					<>1__state = 1;
					return true;
				}
				if ((Object)(object)audio == (Object)null || (Object)(object)audio.clip == (Object)null || audio.clip.length <= 0f)
				{
					return false;
				}
				<clampedTime>5__3 = Mathf.Clamp(timeToSet, 0.01f, audio.clip.length - 0.1f);
				if (!audio.isPlaying)
				{
					audio.Play();
				}
				audio.time = <clampedTime>5__3;
				<guardEnd>5__4 = Time.time + 0.5f;
				break;
			}
			if (Time.time < <guardEnd>5__4)
			{
				if ((Object)(object)audio == (Object)null || (Object)(object)audio.clip == (Object)null)
				{
					return false;
				}
				if (Mathf.Abs(audio.time - <clampedTime>5__3) > 0.5f)
				{
					audio.time = <clampedTime>5__3;
				}
				<>2__current = null;
				<>1__state = 2;
				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();
		}
	}

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

		private object <>2__current;

		public string filePath;

		public int index;

		public string fileType;

		private float <loadingTime>5__1;

		private float <maxLoading>5__2;

		private string <fileName>5__3;

		private AudioType <audioType>5__4;

		private UnityWebRequest <loader>5__5;

		private AudioClip <content>5__6;

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

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

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

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			int num = <>1__state;
			if (num == -3 || num == 1)
			{
				try
				{
				}
				finally
				{
					<>m__Finally1();
				}
			}
			<fileName>5__3 = null;
			<loader>5__5 = null;
			<content>5__6 = null;
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			bool result;
			try
			{
				switch (<>1__state)
				{
				default:
					result = false;
					goto end_IL_0000;
				case 0:
					<>1__state = -1;
					<loadingTime>5__1 = Time.time;
					<maxLoading>5__2 = 5f;
					<fileName>5__3 = Path.GetFileName(filePath);
					mls.LogInfo((object)("Loading " + <fileName>5__3));
					<audioType>5__4 = GetAudioType(fileType);
					<loader>5__5 = UnityWebRequestMultimedia.GetAudioClip(filePath, <audioType>5__4);
					<>1__state = -3;
					<loader>5__5.SendWebRequest();
					break;
				case 1:
					<>1__state = -3;
					break;
				}
				if (!<loader>5__5.isDone)
				{
					if (<loadingTime>5__1 + <maxLoading>5__2 < Time.time)
					{
						mls.LogError((object)("Error loading clip from path: " + <fileName>5__3));
						instance.loadingList[index] = true;
						result = false;
						goto IL_01c7;
					}
					<>2__current = null;
					<>1__state = 1;
					result = true;
				}
				else
				{
					instance.loadingList[index] = true;
					if (<loader>5__5.error != null)
					{
						mls.LogError((object)("Error loading clip from path: " + <fileName>5__3 + "\n" + <loader>5__5.error));
						result = false;
						goto IL_01c7;
					}
					<content>5__6 = DownloadHandlerAudioClip.GetContent(<loader>5__5);
					((Object)<content>5__6).name = <fileName>5__3;
					instance.SongList.Add(<content>5__6);
					<content>5__6 = null;
					<>m__Finally1();
					result = false;
				}
				goto end_IL_0000;
				IL_01c7:
				<>m__Finally1();
				end_IL_0000:;
			}
			catch
			{
				//try-fault
				((IDisposable)this).Dispose();
				throw;
			}
			return result;
		}

		bool IEnumerator.MoveNext()
		{
			//ILSpy generated this explicit interface implementation from .override directive in MoveNext
			return this.MoveNext();
		}

		private void <>m__Finally1()
		{
			<>1__state = -1;
			((IDisposable)<loader>5__5)?.Dispose();
		}

		[DebuggerHidden]
		void IEnumerator.Reset()
		{
			throw new NotSupportedException();
		}
	}

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

		private object <>2__current;

		public AudioSource audio;

		public int expectedStation;

		private float <timeout>5__1;

		private float <start>5__2;

		private float <timeToApply>5__3;

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

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

		[DebuggerHidden]
		public <WaitForSyncThenPlay>d__29(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;
				<timeout>5__1 = 0.5f;
				<start>5__2 = Time.time;
				goto IL_0082;
			case 1:
				<>1__state = -1;
				goto IL_0082;
			case 2:
				<>1__state = -1;
				break;
			case 3:
				{
					<>1__state = -1;
					break;
				}
				IL_0082:
				if ((!PendingSyncData.HasValue || PendingSyncData.Value.Station != expectedStation) && !(Time.time - <start>5__2 > <timeout>5__1))
				{
					<>2__current = null;
					<>1__state = 1;
					return true;
				}
				if (PendingSyncData.HasValue && PendingSyncData.Value.Station == expectedStation)
				{
					<timeToApply>5__3 = PendingSyncData.Value.PlaybackTime;
					PendingSyncData = null;
					<>2__current = EnsureClipReadyAndPlayAt(audio, <timeToApply>5__3);
					<>1__state = 2;
					return true;
				}
				PendingSyncData = null;
				<>2__current = EnsureClipReadyAndPlay(audio);
				<>1__state = 3;
				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 const string modGUID = "Mellowdy.CruiserTunes";

	private const string modName = "CruiserTunes";

	private const string modVersion = "1.3.0";

	private readonly Harmony harmony = new Harmony("Mellowdy.CruiserTunes");

	public static ManualLogSource mls;

	public static CruiserTunesMod instance;

	public static ConfigEntry<bool> IncludeOriginal;

	public static ConfigEntry<bool> DoMessage;

	public static ConfigEntry<bool> DoLoop;

	public static ConfigEntry<bool> DoRandomTime;

	public static ConfigEntry<bool> GoodQuality;

	public static ConfigEntry<float> Volume;

	public static bool HasSongs;

	public static AudioClip[] CustomSongs;

	public static LNetworkMessage<RadioSyncData> SyncPlaybackTimeMessage;

	public static RadioSyncData? PendingSyncData;

	private const string supportedAudioFileTypes = ".mp3 or .wav or .ogg";

	private string folderName = "CustomSongs";

	private string altFolderName = "Custom Songs";

	private List<AudioClip> SongList = new List<AudioClip>();

	private bool[] loadingList;

	private void Awake()
	{
		if ((Object)(object)instance == (Object)null)
		{
			instance = this;
		}
		mls = ((BaseUnityPlugin)this).Logger;
		mls.LogInfo((object)"Loading...");
		Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
		((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
		IncludeOriginal = ((BaseUnityPlugin)this).Config.Bind<bool>("Settings", "Include Original Songs", true, "The radio is able to play the orignal songs");
		DoMessage = ((BaseUnityPlugin)this).Config.Bind<bool>("Settings", "Notify When New Song", true, "The radio notifies nearby players what song is now playing");
		DoLoop = ((BaseUnityPlugin)this).Config.Bind<bool>("Settings", "Loop", false, "The radio loops songs upon completion");
		DoLoop.SettingChanged += CarPatch.UpdateLooping;
		DoRandomTime = ((BaseUnityPlugin)this).Config.Bind<bool>("Settings", "Random Start Time", false, "The randomly picks a point in the song to start playing when switching channels");
		GoodQuality = ((BaseUnityPlugin)this).Config.Bind<bool>("Settings", "Always have good quality", true, "When switching between channels the quality will remain good");
		Volume = ((BaseUnityPlugin)this).Config.Bind<float>("Settings", "Volume", 0.75f, "Volume of the radio (does not require restart)");
		Volume.SettingChanged += CarPatch.ChangeVolume;
		SyncPlaybackTimeMessage = LNetworkMessage<RadioSyncData>.Connect("CruiserTunes_SyncTime", (Action<RadioSyncData, ulong>)null, (Action<RadioSyncData>)OnSyncDataReceived, (Action<RadioSyncData, ulong>)null);
		string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
		string text = Path.Combine(directoryName, folderName);
		List<string> list = new List<string>();
		List<string> list2 = new List<string>();
		string text2 = Path.Combine(Directory.GetParent(directoryName).FullName, folderName);
		string text3 = Path.Combine(Directory.GetParent(directoryName).FullName, altFolderName);
		if (Directory.Exists(text2))
		{
			list.Add(text2);
		}
		else if (Directory.Exists(text3))
		{
			list.Add(text3);
		}
		string text4 = Path.Combine(Directory.GetParent(directoryName).Parent.FullName, altFolderName);
		if (Directory.Exists(text4))
		{
			list.Add(text4);
		}
		string[] directories = Directory.GetDirectories(Directory.GetParent(directoryName).FullName);
		string[] array = directories;
		foreach (string path in array)
		{
			string text5 = Path.Combine(path, folderName);
			if (Directory.Exists(text5))
			{
				list.Add(text5);
			}
		}
		if (list.Count == 0)
		{
			Directory.CreateDirectory(text);
			mls.LogWarning((object)("Folder not found. One has been created at: '" + text + "'"));
			return;
		}
		foreach (string item in list)
		{
			list2.AddRange(Directory.GetFiles(item));
		}
		list2 = RemoveDuplicateFiles(list2);
		bool flag = false;
		loadingList = new bool[list2.Count];
		for (int j = 0; j < list2.Count; j++)
		{
			string text6 = list2[j];
			loadingList[j] = false;
			string fileName = Path.GetFileName(text6);
			string text7 = Path.GetExtension(text6).ToLower();
			if (text7 == ".mp3" || text7 == ".wav" || text7 == ".ogg")
			{
				((MonoBehaviour)this).StartCoroutine(LoadAudioClip(text6, j, text7));
				continue;
			}
			loadingList[j] = true;
			if (text7 != ".old")
			{
				mls.LogWarning((object)(fileName + " is of invalid extention. Must be a .mp3 or .wav or .ogg file or .old file"));
				if (!flag)
				{
					mls.LogWarning((object)".old files ignore this message being printed.");
				}
				flag = true;
			}
		}
		if (loadingList.Length == 0)
		{
			mls.LogError((object)"No songs found");
		}
		harmony.PatchAll(typeof(CruiserTunesMod));
		harmony.PatchAll(typeof(CarPatch));
		((MonoBehaviour)this).StartCoroutine(EndOfPatch());
	}

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

	[IteratorStateMachine(typeof(<LoadAudioClip>d__24))]
	private static IEnumerator LoadAudioClip(string filePath, int index, string fileType)
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <LoadAudioClip>d__24(0)
		{
			filePath = filePath,
			index = index,
			fileType = fileType
		};
	}

	public static AudioType GetAudioType(string fileType)
	{
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		if (1 == 0)
		{
		}
		int num = fileType switch
		{
			".mp3" => 13, 
			".wav" => 20, 
			".ogg" => 14, 
			_ => 13, 
		};
		if (1 == 0)
		{
		}
		return (AudioType)num;
	}

	public static List<string> RemoveDuplicateFiles(List<string> filePaths)
	{
		HashSet<string> hashSet = new HashSet<string>();
		List<string> list = new List<string>();
		foreach (string filePath in filePaths)
		{
			string fileName = Path.GetFileName(filePath);
			if (!hashSet.Contains(fileName))
			{
				hashSet.Add(fileName);
				list.Add(filePath);
			}
		}
		return list;
	}

	private static void OnSyncDataReceived(RadioSyncData data)
	{
		PendingSyncData = data;
		VehicleController val = Object.FindObjectOfType<VehicleController>();
		if ((Object)(object)val != (Object)null && (Object)(object)val.radioAudio != (Object)null && (Object)(object)val.radioAudio.clip != (Object)null && data.Station >= 0 && data.Station < val.radioClips.Length && (Object)(object)val.radioAudio.clip == (Object)(object)val.radioClips[data.Station] && data.PlaybackTime > 0f)
		{
			val.radioAudio.time = Mathf.Clamp(data.PlaybackTime, 0.01f, val.radioAudio.clip.length - 0.1f);
			PendingSyncData = null;
		}
	}

	[HarmonyPatch(typeof(VehicleController), "SetRadioStationClientRpc")]
	[HarmonyPostfix]
	public static void SetRadioStationPatch(ref int radioStation, VehicleController __instance)
	{
		if (radioStation < 0 || radioStation >= __instance.radioClips.Length)
		{
			return;
		}
		__instance.radioAudio.clip = __instance.radioClips[radioStation];
		if (PendingSyncData.HasValue && PendingSyncData.Value.Station == radioStation)
		{
			float playbackTime = PendingSyncData.Value.PlaybackTime;
			PendingSyncData = null;
			if ((Object)(object)instance != (Object)null)
			{
				((MonoBehaviour)instance).StartCoroutine(EnsureClipReadyAndPlayAt(__instance.radioAudio, playbackTime));
				return;
			}
			if (!__instance.radioAudio.isPlaying)
			{
				__instance.radioAudio.Play();
			}
			__instance.radioAudio.time = playbackTime;
		}
		else if ((Object)(object)instance != (Object)null)
		{
			((MonoBehaviour)instance).StartCoroutine(WaitForSyncThenPlay(__instance.radioAudio, radioStation));
		}
		else
		{
			__instance.radioAudio.Play();
		}
	}

	[IteratorStateMachine(typeof(<WaitForSyncThenPlay>d__29))]
	private static IEnumerator WaitForSyncThenPlay(AudioSource audio, int expectedStation)
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <WaitForSyncThenPlay>d__29(0)
		{
			audio = audio,
			expectedStation = expectedStation
		};
	}

	[IteratorStateMachine(typeof(<EnsureClipReadyAndPlayAt>d__30))]
	public static IEnumerator EnsureClipReadyAndPlayAt(AudioSource audio, float timeToSet)
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <EnsureClipReadyAndPlayAt>d__30(0)
		{
			audio = audio,
			timeToSet = timeToSet
		};
	}

	[IteratorStateMachine(typeof(<EnsureClipReadyAndPlay>d__31))]
	public static IEnumerator EnsureClipReadyAndPlay(AudioSource audio)
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <EnsureClipReadyAndPlay>d__31(0)
		{
			audio = audio
		};
	}
}