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 BepInEx; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.Networking; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("SvinoMusic")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("SvinoMusic")] [assembly: AssemblyTitle("SvinoMusic")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace SvinoMusic { public class MusicLoader : MonoBehaviour { [CompilerGenerated] private sealed class d__6 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public string folderPath; public MusicLoader <>4__this; private string[] 5__2; private string[] <>7__wrap2; private int <>7__wrap3; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__6(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { 5__2 = null; <>7__wrap2 = null; <>1__state = -2; } private bool MoveNext() { int num = <>1__state; MusicLoader musicLoader = <>4__this; switch (num) { default: return false; case 0: { <>1__state = -1; LoadedClips.Clear(); IsLoaded = false; if (!Directory.Exists(folderPath)) { Plugin.Log.LogWarning((object)("Music folder not found: " + folderPath)); return false; } string[] files = Directory.GetFiles(folderPath, "*.ogg", SearchOption.TopDirectoryOnly); 5__2 = Directory.GetFiles(folderPath, "*.wav", SearchOption.TopDirectoryOnly); <>7__wrap2 = files; <>7__wrap3 = 0; goto IL_00d6; } case 1: <>1__state = -1; <>7__wrap3++; goto IL_00d6; case 2: { <>1__state = -1; <>7__wrap3++; break; } IL_00d6: if (<>7__wrap3 < <>7__wrap2.Length) { string filePath = <>7__wrap2[<>7__wrap3]; <>2__current = musicLoader.LoadClip(filePath, (AudioType)14); <>1__state = 1; return true; } <>7__wrap2 = null; <>7__wrap2 = 5__2; <>7__wrap3 = 0; break; } if (<>7__wrap3 < <>7__wrap2.Length) { string filePath2 = <>7__wrap2[<>7__wrap3]; <>2__current = musicLoader.LoadClip(filePath2, (AudioType)20); <>1__state = 2; return true; } <>7__wrap2 = null; IsLoaded = true; Plugin.Log.LogInfo((object)$"Loaded custom tracks: {LoadedClips.Count}"); 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__7 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public string filePath; public AudioType audioType; private UnityWebRequest 5__2; 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() { int num = <>1__state; if (num == -3 || num == 1) { try { } finally { <>m__Finally1(); } } 5__2 = null; <>1__state = -2; } private bool MoveNext() { //IL_003f: 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) //IL_0089: Invalid comparison between Unknown and I4 bool result; try { switch (<>1__state) { default: result = false; break; case 0: { <>1__state = -1; string text = "file:///" + filePath.Replace("\\", "/"); 5__2 = UnityWebRequestMultimedia.GetAudioClip(text, audioType); <>1__state = -3; <>2__current = 5__2.SendWebRequest(); <>1__state = 1; result = true; break; } case 1: <>1__state = -3; if ((int)5__2.result != 1) { Plugin.Log.LogError((object)("Failed to load audio: " + filePath + " | " + 5__2.error)); result = false; } else { AudioClip content = DownloadHandlerAudioClip.GetContent(5__2); if ((Object)(object)content == (Object)null) { Plugin.Log.LogError((object)("Loaded clip is null: " + filePath)); result = false; } else { ((Object)content).name = Path.GetFileNameWithoutExtension(filePath); LoadedClips.Add(content); Plugin.Log.LogInfo((object)("Loaded track: " + ((Object)content).name)); result = false; } } <>m__Finally1(); break; } } 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; if (5__2 != null) { ((IDisposable)5__2).Dispose(); } } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public static readonly List LoadedClips = new List(); public static bool IsLoaded { get; private set; } public void BeginLoad(string folderPath) { ((MonoBehaviour)this).StartCoroutine(LoadAll(folderPath)); } [IteratorStateMachine(typeof(d__6))] private IEnumerator LoadAll(string folderPath) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__6(0) { <>4__this = this, folderPath = folderPath }; } [IteratorStateMachine(typeof(d__7))] private IEnumerator LoadClip(string filePath, AudioType audioType) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__7(0) { filePath = filePath, audioType = audioType }; } } [BepInPlugin("svinokryl.svinomusic", "SvinoMusic", "1.0.0")] public class Plugin : BaseUnityPlugin { public const string ModGuid = "svinokryl.svinomusic"; public const string ModName = "SvinoMusic"; public const string ModVersion = "1.0.0"; public static Plugin Instance; public static ManualLogSource Log; public static string MusicFolder; private Harmony _harmony; private void Awake() { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Expected O, but got Unknown //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; Log.LogInfo((object)"SvinoMusic v1.0.0 loaded"); MusicFolder = Path.Combine(Paths.PluginPath, "Svinokryl-SvinoMusic/SvinoMusic", "Music"); Directory.CreateDirectory(MusicFolder); GameObject val = new GameObject("SvinoMusic_Loader"); Object.DontDestroyOnLoad((Object)val); ((Object)val).hideFlags = (HideFlags)61; val.AddComponent().BeginLoad(MusicFolder); _harmony = new Harmony("svinokryl.svinomusic"); _harmony.PatchAll(); Log.LogInfo((object)("Music folder: " + MusicFolder)); } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } } public static class RadioState { public static bool TracksAdded; public static int LastKnownCount = -1; public static void TryAppendCustomTracks(VehicleController vehicle) { if ((Object)(object)vehicle == (Object)null) { return; } if (!MusicLoader.IsLoaded) { Plugin.Log.LogWarning((object)"Music is not loaded yet"); return; } if (MusicLoader.LoadedClips.Count == 0) { Plugin.Log.LogWarning((object)"Svinokryl-SvinoMusic/SvinoMusic"); return; } if (vehicle.radioClips == null) { Plugin.Log.LogWarning((object)"vehicle.radioClips is null"); return; } List list = vehicle.radioClips.ToList(); int num = 0; foreach (AudioClip clip in MusicLoader.LoadedClips) { if (!((Object)(object)clip == (Object)null) && !list.Any((AudioClip x) => (Object)(object)x != (Object)null && ((Object)x).name == ((Object)clip).name)) { list.Add(clip); num++; } } if (num > 0) { vehicle.radioClips = list.ToArray(); Plugin.Log.LogInfo((object)$"Added {num} custom tracks to vehicle radio. Total now: {vehicle.radioClips.Length}"); } LastKnownCount = vehicle.radioClips.Length; TracksAdded = true; } } [HarmonyPatch(typeof(VehicleController), "Start")] public static class Patch_VehicleController_Start { private static void Postfix(VehicleController __instance) { RadioState.TryAppendCustomTracks(__instance); } } [HarmonyPatch(typeof(VehicleController), "SwitchRadio")] public static class Patch_VehicleController_SwitchRadio { private static void Postfix(VehicleController __instance) { RadioState.TryAppendCustomTracks(__instance); } } [HarmonyPatch(typeof(VehicleController), "ChangeRadioStation")] public static class Patch_VehicleController_ChangeRadioStation { private static void Postfix(VehicleController __instance) { RadioState.TryAppendCustomTracks(__instance); } } [HarmonyPatch(typeof(VehicleController), "SetRadioOnLocalClient")] public static class Patch_VehicleController_SetRadioOnLocalClient { private static void Postfix(VehicleController __instance) { RadioState.TryAppendCustomTracks(__instance); } } }