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 d__7 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public AudioSource radio; public VehicleController instance; private AudioClip 5__1; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__7(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { 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)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)); } } 5__1 = null; break; } if ((Object)(object)radio != (Object)null && (Object)(object)instance != (Object)null) { 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 d__10 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public AudioSource audio; private float 5__1; private float 5__2; private float 5__3; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public 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; 5__1 = 5f; 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 - 5__2 > 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) { 5__3 = Mathf.Max(0.01f, audio.clip.length - 0.1f); audio.time = Random.Range(0.01f, 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 d__8 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public VehicleController instance; private AudioClip 5__1; private PlayerControllerB 5__2; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__8(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { 5__1 = null; 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) { 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)5__1 == (Object)(object)instance.radioAudio.clip) { 5__2 = StartOfRound.Instance.localPlayerController; if ((Object)(object)5__2 != (Object)null && (Object)(object)instance != (Object)null && Vector3.Distance(((Component)5__2).transform.position, ((Component)instance).transform.position) < 10f) { HUDManager.Instance.DisplayTip("Now Playing:", ((Object)5__1).name.Replace("Radio_", "") + " - " + FormatLength(5__1.length), false, false, "LC_Tip1"); } 5__2 = null; } 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(d__7))] public static IEnumerator AudioSourceListener(AudioSource radio, VehicleController instance) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__7(0) { radio = radio, instance = instance }; } [IteratorStateMachine(typeof(d__8))] public static IEnumerator PlayNotification(VehicleController instance) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new 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(d__10))] public static IEnumerator EnsureClipReadyAndPlay(AudioSource audio) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new 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 d__23 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; private bool 5__1; private bool[] 5__2; private int 5__3; private string 5__4; private string 5__5; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__23(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { 5__2 = null; 5__4 = null; 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")); 5__1 = false; goto IL_00f2; IL_00ea: 5__2 = null; goto IL_00f2; IL_00f2: if (!5__1) { 5__1 = true; 5__2 = instance.loadingList; 5__3 = 0; while (5__3 < 5__2.Length) { if (!5__2[5__3]) { 5__1 = false; break; } 5__3++; } if (!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) { 5__4 = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); 5__5 = Path.Combine(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: '" + 5__5 + "'")); 5__4 = null; 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 d__31 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public AudioSource audio; private float 5__1; private float 5__2; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public 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; 5__1 = 5f; 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 - 5__2 > 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 d__30 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public AudioSource audio; public float timeToSet; private float 5__1; private float 5__2; private float 5__3; private float 5__4; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public 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; 5__1 = 5f; 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 - 5__2 > 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; } 5__3 = Mathf.Clamp(timeToSet, 0.01f, audio.clip.length - 0.1f); if (!audio.isPlaying) { audio.Play(); } audio.time = 5__3; 5__4 = Time.time + 0.5f; break; } if (Time.time < 5__4) { if ((Object)(object)audio == (Object)null || (Object)(object)audio.clip == (Object)null) { return false; } if (Mathf.Abs(audio.time - 5__3) > 0.5f) { audio.time = 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 d__24 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public string filePath; public int index; public string fileType; private float 5__1; private float 5__2; private string 5__3; private AudioType 5__4; private UnityWebRequest 5__5; private AudioClip 5__6; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public 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(); } } 5__3 = null; 5__5 = null; 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; 5__1 = Time.time; 5__2 = 5f; 5__3 = Path.GetFileName(filePath); mls.LogInfo((object)("Loading " + 5__3)); 5__4 = GetAudioType(fileType); 5__5 = UnityWebRequestMultimedia.GetAudioClip(filePath, 5__4); <>1__state = -3; 5__5.SendWebRequest(); break; case 1: <>1__state = -3; break; } if (!5__5.isDone) { if (5__1 + 5__2 < Time.time) { mls.LogError((object)("Error loading clip from path: " + 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 (5__5.error != null) { mls.LogError((object)("Error loading clip from path: " + 5__3 + "\n" + 5__5.error)); result = false; goto IL_01c7; } 5__6 = DownloadHandlerAudioClip.GetContent(5__5); ((Object)5__6).name = 5__3; instance.SongList.Add(5__6); 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)5__5)?.Dispose(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class d__29 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public AudioSource audio; public int expectedStation; private float 5__1; private float 5__2; private float 5__3; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public 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; 5__1 = 0.5f; 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 - 5__2 > 5__1)) { <>2__current = null; <>1__state = 1; return true; } if (PendingSyncData.HasValue && PendingSyncData.Value.Station == expectedStation) { 5__3 = PendingSyncData.Value.PlaybackTime; PendingSyncData = null; <>2__current = EnsureClipReadyAndPlayAt(audio, 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 IncludeOriginal; public static ConfigEntry DoMessage; public static ConfigEntry DoLoop; public static ConfigEntry DoRandomTime; public static ConfigEntry GoodQuality; public static ConfigEntry Volume; public static bool HasSongs; public static AudioClip[] CustomSongs; public static LNetworkMessage 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 SongList = new List(); 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("Settings", "Include Original Songs", true, "The radio is able to play the orignal songs"); DoMessage = ((BaseUnityPlugin)this).Config.Bind("Settings", "Notify When New Song", true, "The radio notifies nearby players what song is now playing"); DoLoop = ((BaseUnityPlugin)this).Config.Bind("Settings", "Loop", false, "The radio loops songs upon completion"); DoLoop.SettingChanged += CarPatch.UpdateLooping; DoRandomTime = ((BaseUnityPlugin)this).Config.Bind("Settings", "Random Start Time", false, "The randomly picks a point in the song to start playing when switching channels"); GoodQuality = ((BaseUnityPlugin)this).Config.Bind("Settings", "Always have good quality", true, "When switching between channels the quality will remain good"); Volume = ((BaseUnityPlugin)this).Config.Bind("Settings", "Volume", 0.75f, "Volume of the radio (does not require restart)"); Volume.SettingChanged += CarPatch.ChangeVolume; SyncPlaybackTimeMessage = LNetworkMessage.Connect("CruiserTunes_SyncTime", (Action)null, (Action)OnSyncDataReceived, (Action)null); string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); string text = Path.Combine(directoryName, folderName); List list = new List(); List list2 = new List(); 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(d__23))] private static IEnumerator EndOfPatch() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__23(0); } [IteratorStateMachine(typeof(d__24))] private static IEnumerator LoadAudioClip(string filePath, int index, string fileType) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new 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 RemoveDuplicateFiles(List filePaths) { HashSet hashSet = new HashSet(); List list = new List(); 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(); 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(d__29))] private static IEnumerator WaitForSyncThenPlay(AudioSource audio, int expectedStation) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__29(0) { audio = audio, expectedStation = expectedStation }; } [IteratorStateMachine(typeof(d__30))] public static IEnumerator EnsureClipReadyAndPlayAt(AudioSource audio, float timeToSet) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__30(0) { audio = audio, timeToSet = timeToSet }; } [IteratorStateMachine(typeof(d__31))] public static IEnumerator EnsureClipReadyAndPlay(AudioSource audio) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__31(0) { audio = audio }; } }