Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of CustomCruiserRadioLoader v1.1.1
LC_CruiserTunes.dll
Decompiled 2 months agousing 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 }; } }