Decompiled source of CybergrindMusicExplorer v2.2.1
plugins/Jukebox/Jukebox.dll
Decompiled 5 days ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using Discord; using HarmonyLib; using Jukebox.Components; using Jukebox.Input; using Jukebox.UI; using Jukebox.UI.Elements; using Jukebox.UI.Windows; using Jukebox.Utils; using JukeboxCore.Collections; using JukeboxCore.Components; using JukeboxCore.Events; using JukeboxCore.Models.Preferences; using JukeboxCore.Models.Song; using JukeboxCore.Utils; using Newtonsoft.Json; using SettingsMenu.Components; using SettingsMenu.Components.Pages; using Steamworks; using TMPro; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.InputSystem; using UnityEngine.Networking; using UnityEngine.ResourceManagement.AsyncOperations; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("Jukebox")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Jukebox")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("B01B8657-61B6-4BC3-BFAF-F43D4C264B4B")] [assembly: AssemblyFileVersion("2.2.1.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("2.2.1.0")] namespace Jukebox { [BepInProcess("ULTRAKILL.exe")] [BepInPlugin("dev.flazhik.jukebox", "Jukebox", "2.2.1")] public class JukeboxPlugin : BaseUnityPlugin { [CompilerGenerated] private sealed class <>c__DisplayClass11_0 { public InputAction menu; internal string <MotD>b__0(InputBinding binding) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) return InputExtensions.GetBindingDisplayStringWithoutOverride(menu, binding, (DisplayStringOptions)0); } } [CompilerGenerated] private sealed class <MotD>d__11 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; private <>c__DisplayClass11_0 <>8__1; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <MotD>d__11(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>8__1 = null; <>1__state = -2; } private bool MoveNext() { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Expected O, but got Unknown //IL_0062: Unknown result type (might be due to invalid IL or missing references) switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>8__1 = new <>c__DisplayClass11_0(); <>2__current = (object)new WaitForSeconds(1.5f); <>1__state = 1; return true; case 1: { <>1__state = -1; <>8__1.menu = MonoSingleton<JukeboxInputs>.Instance.Menu; string text = GeneralExtensions.Join<InputBinding>((IEnumerable<InputBinding>)(object)<>8__1.menu.bindings, (Func<InputBinding, string>)((InputBinding binding) => InputExtensions.GetBindingDisplayStringWithoutOverride(<>8__1.menu, binding, (DisplayStringOptions)0)), ", "); MonoSingleton<HudMessageReceiver>.Instance.SendHudMessage("CGME menu is available by pressing <color=orange>" + text + "</color>", "", "", 0, false, false, true); _motDShown = true; return false; } } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private static GameObject _bootstrap; public static string catalogDir; private static Harmony _harmony; private static bool _motDShown; private static bool _init; static JukeboxPlugin() { catalogDir = Path.Combine(PathsUtils.AssemblyPath, "Assets"); } private void Awake() { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Expected O, but got Unknown ((Object)((Component)this).gameObject).hideFlags = (HideFlags)61; Addressables.InitializeAsync().WaitForCompletion(); Addressables.LoadContentCatalogAsync(Path.Combine(catalogDir, "catalog.json"), true, (string)null).WaitForCompletion(); _harmony = new Harmony("dev.flazhik.jukebox"); Startup(); } private void Start() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) _bootstrap = Addressables.LoadAssetAsync<GameObject>((object)"Assets/Jukebox/Bootstrap.prefab").WaitForCompletion(); Addressables.LoadAssetAsync<InputActionAsset>((object)"Assets/Jukebox/JukeboxControls.inputactions").WaitForCompletion(); Addressables.LoadAssetAsync<Sprite>((object)"Assets/Jukebox/Textures/music_note.png").WaitForCompletion(); } private void Startup() { _harmony.PatchAll(); FileInfo fileInfo = new FileInfo(Path.Combine(PathsUtils.AssemblyPath, "cookies.txt")); if (fileInfo.Exists) { fileInfo.Delete(); } SceneManager.sceneLoaded += OnSceneLoaded; } private void OnSceneLoaded(Scene scene, LoadSceneMode loadSceneMode) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) if (scene != SceneManager.GetActiveScene()) { return; } switch (SceneHelper.CurrentScene) { case "Bootstrap": SetDefaultPrefsValues(); break; case "Main Menu": if (!_init) { _init = true; } break; case "Endless": Object.Instantiate<GameObject>(_bootstrap); if (!_motDShown) { ((MonoBehaviour)MonoSingleton<JukeboxManager>.Instance).StartCoroutine(MotD()); } break; } } private static void SetDefaultPrefsValues() { foreach (KeyValuePair<string, object> item in new Dictionary<string, object> { { "jukebox.volumeBoost", 0f }, { "jukebox.individualBoostPerTrack", false }, { "jukebox.showTrackPanelIndefinitely", false }, { "jukebox.alwaysPlayIntro", true }, { "jukebox.resumeLastSong", false }, { "jukebox.discordAndSteamIntegration", true }, { "jukebox.enableTracksPreview", true }, { "jukebox.preventDuplicateTracks", false }, { "jukebox.nowPlayingHud", true }, { "jukebox.enableCalmThemes", true }, { "jukebox.songPanelStyle", 0 }, { "jukebox.currentPlaylist", "slot1" }, { "jukebox.calmThemeEnemiesThreshold", 2 }, { "jukebox.effects.parry", null }, { "jukebox.effects.wavecomplete", null }, { "jukebox.effects.gameover", null }, { "jukebox.effects.aww", null }, { "jukebox.effects.terminal-music", null }, { "jukebox.downloader.separateFolderPerPlaylist", true } }) { MonoSingleton<PrefsManager>.Instance.defaultValues.Add(item.Key, item.Value); } } [IteratorStateMachine(typeof(<MotD>d__11))] private static IEnumerator MotD() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <MotD>d__11(0); } } internal static class PluginInfo { public const string Guid = "dev.flazhik.jukebox"; public const string Name = "Jukebox"; public const string Version = "2.2.1"; } } namespace Jukebox.Utils { public static class FloatExtensions { public static string SecondsToHumanReadable(this float value) { int num = (int)value; int num2 = num / 60; int num3 = num - num2 * 60; return $"{num2:00}:{num3:00}"; } } public static class IntExtensions { public static int Mod(this int num, int mod) { return (num % mod + mod) % mod; } } public abstract class ReflectionUtils { private const BindingFlags PrivateFields = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; public static T GetPrivate<T>(object instance, Type classType, string field) { FieldInfo field2 = classType.GetField(field, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); return (T)((field2 != null) ? field2.GetValue(instance) : null); } public static void SetPrivate<T, TV>(T instance, Type classType, string field, TV value) { FieldInfo field2 = classType.GetField(field, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.SetField); if (field2 != null) { field2.SetValue(instance, value); } } public static void CallPrivate(object instance, Type classType, string methodName, params object[] args) { classType.GetMethod(methodName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.Invoke(instance, args); } } public static class ScrollingTextUnscaled { [CompilerGenerated] private sealed class <HideText>d__1 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public TMP_Text text; public float secondsBetweenLetters; private int <currentLetter>5__2; private string <message>5__3; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <HideText>d__1(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <message>5__3 = null; <>1__state = -2; } private bool MoveNext() { //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <currentLetter>5__2 = text.text.Length - 1; <message>5__3 = text.text; break; case 1: <>1__state = -1; break; } if (<currentLetter>5__2 >= 0) { int num; if (text.text[<currentLetter>5__2] == '>') { while (text.text[<currentLetter>5__2] != '<' && <currentLetter>5__2 >= 0) { num = <currentLetter>5__2 - 1; <currentLetter>5__2 = num; } } num = <currentLetter>5__2 - 1; <currentLetter>5__2 = num; text.text = <message>5__3.Substring(0, <currentLetter>5__2 + 1); <>2__current = (object)new WaitForSecondsRealtime(secondsBetweenLetters); <>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 <ShowText>d__0 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public TMP_Text text; public string message; public AudioSource clickAudio; public float secondsBetweenLetters; private int <currentLetter>5__2; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <ShowText>d__0(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <currentLetter>5__2 = 0; text.text = ""; break; case 1: <>1__state = -1; break; } if (<currentLetter>5__2 < message.Length) { int num; if (message[<currentLetter>5__2] == '<') { while (message[<currentLetter>5__2] != '>' && <currentLetter>5__2 <= message.Length) { num = <currentLetter>5__2 + 1; <currentLetter>5__2 = num; } } else if (<currentLetter>5__2 < message.Length - 1) { while (<currentLetter>5__2 < message.Length - 1 && message[<currentLetter>5__2 + 1] == ' ') { num = <currentLetter>5__2 + 1; <currentLetter>5__2 = num; } } num = <currentLetter>5__2 + 1; <currentLetter>5__2 = num; text.text = message.Substring(0, <currentLetter>5__2); if ((Object)(object)clickAudio != (Object)null && message[<currentLetter>5__2 - 1] != '\n' && message[<currentLetter>5__2 - 1] != ' ') { clickAudio.Play(); } <>2__current = (object)new WaitForSecondsRealtime(secondsBetweenLetters); <>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(); } } [IteratorStateMachine(typeof(<ShowText>d__0))] public static IEnumerator ShowText(TMP_Text text, string message, float secondsBetweenLetters = 0.005f, AudioSource clickAudio = null) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <ShowText>d__0(0) { text = text, message = message, secondsBetweenLetters = secondsBetweenLetters, clickAudio = clickAudio }; } [IteratorStateMachine(typeof(<HideText>d__1))] public static IEnumerator HideText(TMP_Text text, float secondsBetweenLetters = 0.005f) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <HideText>d__1(0) { text = text, secondsBetweenLetters = secondsBetweenLetters }; } } } namespace Jukebox.UI { public class JukeboxCredits : MonoBehaviour { [CompilerGenerated] private sealed class <WindowsRoutine>d__8 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public JukeboxCredits <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <WindowsRoutine>d__8(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { int num = <>1__state; JukeboxCredits jukeboxCredits = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; <>2__current = jukeboxCredits.TerminalTextRoutine(0); <>1__state = 1; return true; case 1: <>1__state = -1; jukeboxCredits.firstWindow.SetActive(true); <>2__current = jukeboxCredits.TerminalTextRoutine(1); <>1__state = 2; return true; case 2: <>1__state = -1; <>2__current = jukeboxCredits.TerminalTextRoutine(2); <>1__state = 3; return true; case 3: <>1__state = -1; jukeboxCredits.secondWindow.SetActive(true); <>2__current = jukeboxCredits.TerminalTextRoutine(3); <>1__state = 4; return true; case 4: <>1__state = -1; <>2__current = jukeboxCredits.TerminalTextRoutine(4); <>1__state = 5; return true; case 5: <>1__state = -1; foreach (GameObject lastWindow in jukeboxCredits.lastWindows) { lastWindow.SetActive(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(); } } [SerializeField] private TMP_Text[] terminalText; [SerializeField] private AudioSource click; [SerializeField] private GameObject firstWindow; [SerializeField] private GameObject secondWindow; [SerializeField] private List<GameObject> lastWindows; private string[] originalText; private void Awake() { originalText = terminalText.Select((TMP_Text t) => t.text).ToArray(); } private void OnEnable() { firstWindow.SetActive(false); secondWindow.SetActive(false); foreach (GameObject lastWindow in lastWindows) { lastWindow.SetActive(false); } TMP_Text[] array = terminalText; for (int i = 0; i < array.Length; i++) { array[i].text = string.Empty; } ((MonoBehaviour)this).StartCoroutine(WindowsRoutine()); } [IteratorStateMachine(typeof(<WindowsRoutine>d__8))] private IEnumerator WindowsRoutine() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <WindowsRoutine>d__8(0) { <>4__this = this }; } private IEnumerator TerminalTextRoutine(int index) { return ScrollingTextUnscaled.ShowText(terminalText[index], originalText[index], 0.01f, click); } } public class JukeboxCustomContentButton : CustomContentButton { [SerializeField] public GameObject introAndLoopIcon; [SerializeField] public GameObject calmThemeIcon; } public class JukeboxUI : MonoBehaviour { [CompilerGenerated] private sealed class <WhatIsNewRoutine>d__14 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public JukeboxUI <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <WhatIsNewRoutine>d__14(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown int num = <>1__state; JukeboxUI jukeboxUI = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds(1.4f); <>1__state = 1; return true; case 1: <>1__state = -1; jukeboxUI.whatIsNew.GetComponent<WhatsNew>().Open(); 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(); } } [SerializeField] public GameObject jukeboxMenuTemplate; [SerializeField] public GameObject playbackMenuTemplate; [SerializeField] public GameObject whatIsNewMenuTemplate; [SerializeField] public GameObject nowPlayingHudTemplate; [SerializeField] public GameObject nowPlayingHudClassicTemplate; private GameObject jukeboxMenu; private GameObject playbackMenu; private GameObject whatIsNew; private ReadOnlyCollection<JukeboxWindow> windows; public void OpenDownloader() { JukeboxMenuWindow component = jukeboxMenu.GetComponent<JukeboxMenuWindow>(); component.Open(); component.OpenDownloader(); } protected void Awake() { InstantiateUI(); windows = new ReadOnlyCollection<JukeboxWindow>(new List<JukeboxWindow> { jukeboxMenu.GetComponent<JukeboxWindow>(), playbackMenu.GetComponent<JukeboxPlaybackWindow>(), whatIsNew.GetComponent<WhatsNew>() }); foreach (JukeboxWindow window in windows) { ((Component)window).gameObject.SetActive(false); } ((MonoBehaviour)this).StartCoroutine(WhatIsNewRoutine()); } protected void Update() { ManageWindows(); } private void ManageWindows() { if (GameIsPaused()) { return; } if (MonoSingleton<InputManager>.Instance.InputSource.Pause.WasPerformedThisFrame) { foreach (JukeboxWindow window in windows) { if (window.IsOpened()) { window.Close(); } } return; } JukeboxWindow jukeboxWindow = windows.FirstOrDefault((JukeboxWindow w) => (Object)(object)w.hotkey != (Object)null && w.hotkey.ToInputAction().WasPerformedThisFrame()); if ((Object)(object)jukeboxWindow != (Object)null) { foreach (JukeboxWindow window2 in windows) { if ((Object)(object)window2.hotkey != (Object)null && InputExtensions.IsActionEqual(window2.hotkey.ToInputAction(), jukeboxWindow.hotkey.ToInputAction(), (string)null)) { window2.Toggle(); } else { window2.Close(); } } } if (!windows.Any((JukeboxWindow w) => GameStateManager.Instance.IsStateActive(w.StateKey())) && MonoSingleton<OptionsManager>.Instance.paused) { MonoSingleton<JukeboxPauseManager>.Instance.UnPause(); } } private void InstantiateUI() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject { name = "JukeboxCanvas" }; val.AddComponent<Canvas>(); GameObject val2 = GameObject.Find("/Canvas"); Canvas component = val.GetComponent<Canvas>(); component.renderMode = (RenderMode)1; component.sortingOrder = val2.GetComponent<Canvas>().sortingOrder + 1; val.AddComponent<CanvasScaler>(); val.AddComponent<GraphicRaycaster>(); jukeboxMenu = Object.Instantiate<GameObject>(jukeboxMenuTemplate, val2.transform); playbackMenu = Object.Instantiate<GameObject>(playbackMenuTemplate, val2.transform); whatIsNew = Object.Instantiate<GameObject>(whatIsNewMenuTemplate, val2.transform); Object.Instantiate<GameObject>(nowPlayingHudTemplate, GameObject.Find("/Player/Main Camera/HUD Camera/HUD/GunCanvas").transform, false); Object.Instantiate<GameObject>(nowPlayingHudClassicTemplate, val2.transform.Find("Crosshair Filler"), false); } [IteratorStateMachine(typeof(<WhatIsNewRoutine>d__14))] private IEnumerator WhatIsNewRoutine() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <WhatIsNewRoutine>d__14(0) { <>4__this = this }; } private static bool GameIsPaused() { return GameStateManager.Instance.IsStateActive("pause"); } } public class ScrollUIImageUnscaled : MonoBehaviour { private RawImage img; public float xSpeed; public float ySpeed; private void Start() { img = ((Component)this).GetComponent<RawImage>(); } private void Update() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) Rect uvRect = img.uvRect; Vector2 val = ((Rect)(ref uvRect)).position + new Vector2(xSpeed, ySpeed) * Time.unscaledDeltaTime; while ((double)val.x > 1.0) { val.x -= 1f; } while ((double)val.x < -1.0) { val.x += 1f; } while ((double)val.y > 1.0) { val.y -= 1f; } while ((double)val.y < -1.0) { val.y += 1f; } RawImage obj = img; uvRect = img.uvRect; Vector2 val2 = ((Rect)(ref uvRect)).position + new Vector2(xSpeed, ySpeed) * Time.unscaledDeltaTime; uvRect = img.uvRect; obj.uvRect = new Rect(val2, ((Rect)(ref uvRect)).size); } } } namespace Jukebox.UI.Windows { public class JukeboxMenuWindow : JukeboxWindow { [SerializeField] protected Button[] buttons; [SerializeField] protected GameObject activeBgObject; [SerializeField] protected GameObject generalSettings; [SerializeField] protected Button downloaderButton; [SerializeField] protected GameObject downloaderPage; public override string StateKey() { return "jukeboxMenu"; } protected override void Awake() { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Expected O, but got Unknown base.Awake(); Button[] array = buttons; foreach (Button button in array) { ((UnityEvent)button.onClick).AddListener((UnityAction)delegate { SetActiveButton(button); }); } JukeboxMusicPlayer.OnNextAudioClip += NextAudioClip; } public void NextAudioClip(ClipChangedArgs clip) { if (clip.NewSong && clip.Song.IsCustom) { ReflectionUtils.GetPrivate<Slider>(generalSettings.GetComponentInChildren<SettingsSlider>(true), typeof(SettingsSlider), "slider").value = MonoSingleton<JukeboxManager>.Instance.player.VolumeBoost; } } public void OpenDownloader() { SettingsMenu component = ((Component)this).gameObject.GetComponent<SettingsMenu>(); if (!ReflectionUtils.GetPrivate<bool>(component, typeof(SettingsMenu), "initialized")) { component.Initialize(); } component.SetActivePage(downloaderPage); SetActiveButton(downloaderButton); } protected void OnDestroy() { JukeboxMusicPlayer.OnNextAudioClip -= NextAudioClip; } private void SetActiveButton(Button button) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) activeBgObject.transform.SetParent(((Component)button).transform); activeBgObject.transform.SetSiblingIndex(0); activeBgObject.transform.localPosition = Vector3.zero; } } public class JukeboxPlaybackWindow : JukeboxWindow { public override string StateKey() { return "jukeboxPlayback"; } } public abstract class JukeboxWindow : MonoBehaviour { [SerializeField] public InputActionReference hotkey; public abstract string StateKey(); public void Open() { ((Component)this).gameObject.SetActive(true); MonoSingleton<JukeboxPauseManager>.Instance.Pause(StateKey(), ((Component)this).gameObject); } public void Close() { GameStateManager.Instance.PopState(StateKey()); ((Component)this).gameObject.SetActive(false); } public void Toggle() { if (IsOpened()) { Close(); } else { Open(); } } protected virtual void Awake() { if ((Object)(object)hotkey != (Object)null) { hotkey = InputActionReference.Create(MonoSingleton<InputManager>.Instance.InputSource.Actions.asset.FindAction(hotkey.ToInputAction().id)); } } public bool IsOpened() { return ((Component)this).gameObject.activeSelf; } } public class WhatsNew : JukeboxWindow { private const string PrefsKey = "Jukebox.NewDiscordServer"; public override string StateKey() { return "jukebox.whatisnew"; } private void Start() { if (PlayerPrefs.GetInt("Jukebox.NewDiscordServer") != 1) { PlayerPrefs.SetInt("Jukebox.NewDiscordServer", 1); } else { Close(); } } } } namespace Jukebox.UI.Themes { public class ThemeEnemySettings : MonoBehaviour { [SerializeField] public TMP_Text title; [SerializeField] public Image icon; [SerializeField] public GameObject radianceBg; [SerializeField] public Toggle toggle; [SerializeField] public Counter counter; } public class ThemeSettingsMenu : MonoBehaviour { [SerializeField] private Counter threshold; [SerializeField] private GameObject enemyTemplate; [SerializeField] private GameObject regularEnemies; [SerializeField] private GameObject radiantEnemies; [SerializeField] private Button[] tabButtons; [SerializeField] private GameObject activeTab; [SerializeField] private List<AssetReferenceT<SpawnableObject>> enemies; private void Awake() { //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Expected O, but got Unknown //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Unknown result type (might be due to invalid IL or missing references) JukeboxThemesManager themesManager = MonoSingleton<JukeboxThemesManager>.Instance; threshold.SetDefaultValue(MonoSingleton<PrefsManager>.Instance.GetIntLocal("jukebox.calmThemeEnemiesThreshold", 0)); threshold.OnChanged += OnThresholdChanged; Button[] array = tabButtons; foreach (Button button in array) { ((UnityEvent)button.onClick).AddListener((UnityAction)delegate { //IL_0055: Unknown result type (might be due to invalid IL or missing references) activeTab.transform.SetParent(((Component)button).transform); activeTab.transform.SetSiblingIndex(0); activeTab.transform.localPosition = Vector3.zero; }); } foreach (AssetReferenceT<SpawnableObject> enemy2 in enemies) { AsyncOperationHandle<SpawnableObject> val = enemy2.LoadAssetAsync(); SpawnableObject enemy = val.WaitForCompletion(); Addressables.Release<SpawnableObject>(val); Dictionary<bool, ThemeEnemySettings> respectiveSettings = new Dictionary<bool, ThemeEnemySettings>(); GameObject[] array2 = (GameObject[])(object)new GameObject[2] { regularEnemies, radiantEnemies }; foreach (GameObject val2 in array2) { GameObject val3 = Object.Instantiate<GameObject>(enemyTemplate, val2.transform); bool radiant = (Object)(object)val2 == (Object)(object)radiantEnemies; Sprite gridIcon = enemy.gridIcon; ThemeEnemySettings enemySettings = val3.GetComponent<ThemeEnemySettings>(); enemySettings.icon.sprite = gridIcon; enemySettings.title.text = (radiant ? ("Radiant " + enemy.objectName) : enemy.objectName); enemySettings.radianceBg.SetActive(radiant); int? thresholdFor = themesManager.GetThresholdFor(enemy.enemyType, radiant); if (!thresholdFor.HasValue) { enemySettings.counter.SetDefaultValue(0); } else { enemySettings.counter.SetDefaultValue(thresholdFor.Value); } enemySettings.toggle.isOn = thresholdFor.HasValue; enemySettings.counter.OnChanged += delegate(int value) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) enemySettings.toggle.isOn = true; themesManager.SetThresholdFor(enemy.enemyType, value, radiant); }; ((UnityEvent<bool>)(object)enemySettings.toggle.onValueChanged).AddListener((UnityAction<bool>)delegate(bool on) { //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) if (on) { themesManager.SetThresholdFor(enemy.enemyType, enemySettings.counter.Value, radiant); } else { themesManager.DisableThresholdFor(enemy.enemyType, radiant); } }); respectiveSettings[radiant] = enemySettings; val3.SetActive(true); } respectiveSettings[false].counter.OnChanged += delegate(int value) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) int? thresholdFor2 = themesManager.GetThresholdFor(enemy.enemyType, radiant: true); if (!thresholdFor2.HasValue || thresholdFor2.Value > value) { themesManager.SetThresholdFor(enemy.enemyType, value, radiant: true); respectiveSettings[true].toggle.isOn = true; respectiveSettings[true].counter.Value = value; } }; ((UnityEvent<bool>)(object)respectiveSettings[false].toggle.onValueChanged).AddListener((UnityAction<bool>)delegate(bool on) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) if (on && !themesManager.GetThresholdFor(enemy.enemyType, radiant: true).HasValue) { respectiveSettings[true].toggle.isOn = true; respectiveSettings[true].counter.Value = respectiveSettings[false].counter.Value; } }); } } private void OnDestroy() { threshold.OnChanged -= OnThresholdChanged; } private static void OnThresholdChanged(int value) { MonoSingleton<PrefsManager>.Instance.SetIntLocal("jukebox.calmThemeEnemiesThreshold", value); } } } namespace Jukebox.UI.SongPanel { public class ClassicSongPanel : SongPanel { [CompilerGenerated] private sealed class <Await>d__3 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public ClassicSongPanel <>4__this; private float <time>5__2; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <Await>d__3(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { int num = <>1__state; ClassicSongPanel classicSongPanel = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; <time>5__2 = classicSongPanel.panelStayTime; break; case 1: <>1__state = -1; break; } if ((double)<time>5__2 > 0.0 || classicSongPanel.showIndefinitely) { classicSongPanel.panelGroup.alpha = (classicSongPanel.active ? 1 : 0); if ((double)<time>5__2 > 0.0) { <time>5__2 -= Time.unscaledDeltaTime; } <>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 <FadeIn>d__2 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public ClassicSongPanel <>4__this; private float <time>5__2; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <FadeIn>d__2(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { int num = <>1__state; ClassicSongPanel classicSongPanel = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; <time>5__2 = 0f; break; case 1: <>1__state = -1; break; } if ((double)<time>5__2 < (double)classicSongPanel.panelApproachTime) { <time>5__2 += Time.unscaledDeltaTime; classicSongPanel.panelGroup.alpha = (classicSongPanel.active ? (<time>5__2 / classicSongPanel.panelApproachTime) : 0f); <>2__current = null; <>1__state = 1; return true; } classicSongPanel.panelGroup.alpha = (classicSongPanel.active ? 1 : 0); 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 <FadeOut>d__4 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public ClassicSongPanel <>4__this; private float <time>5__2; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <FadeOut>d__4(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { int num = <>1__state; ClassicSongPanel classicSongPanel = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; <time>5__2 = classicSongPanel.panelApproachTime; break; case 1: <>1__state = -1; break; } if ((double)<time>5__2 > 0.0) { <time>5__2 -= Time.unscaledDeltaTime; classicSongPanel.panelGroup.alpha = (classicSongPanel.active ? (<time>5__2 / classicSongPanel.panelApproachTime) : 0f); <>2__current = null; <>1__state = 1; return true; } classicSongPanel.panelGroup.alpha = 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(); } } protected override SongPanelStyle Style => SongPanelStyle.Classic; [IteratorStateMachine(typeof(<FadeIn>d__2))] protected override IEnumerator FadeIn(JukeboxSongMetadata metadata) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <FadeIn>d__2(0) { <>4__this = this }; } [IteratorStateMachine(typeof(<Await>d__3))] protected override IEnumerator Await() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <Await>d__3(0) { <>4__this = this }; } [IteratorStateMachine(typeof(<FadeOut>d__4))] protected override IEnumerator FadeOut() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <FadeOut>d__4(0) { <>4__this = this }; } } public class JukeboxSongPanel : SongPanel { [CompilerGenerated] private sealed class <Await>d__6 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public JukeboxSongPanel <>4__this; private float <time>5__2; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <Await>d__6(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { int num = <>1__state; JukeboxSongPanel jukeboxSongPanel = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; <time>5__2 = jukeboxSongPanel.panelStayTime; break; case 1: <>1__state = -1; break; } if ((double)<time>5__2 > 0.0 || jukeboxSongPanel.showIndefinitely) { jukeboxSongPanel.panelGroup.alpha = (jukeboxSongPanel.active ? 1 : 0); if ((double)<time>5__2 > 0.0) { <time>5__2 -= Time.unscaledDeltaTime; } <>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 <FadeIn>d__5 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public JukeboxSongPanel <>4__this; public JukeboxSongMetadata metadata; private RectTransform <rect>5__2; private float <time>5__3; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <FadeIn>d__5(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <rect>5__2 = null; <>1__state = -2; } private bool MoveNext() { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) int num = <>1__state; JukeboxSongPanel jukeboxSongPanel = <>4__this; switch (num) { default: return false; case 0: { <>1__state = -1; ((Graphic)jukeboxSongPanel.text).color = new Color(1f, 1f, 1f, 1f); <rect>5__2 = ((Component)jukeboxSongPanel.panelGroup).GetComponent<RectTransform>(); <rect>5__2.sizeDelta = jukeboxSongPanel.startDimensions; string text = ((!string.IsNullOrEmpty(metadata.Artist)) ? ("<color=#999>" + metadata.Artist + "</color>") : string.Empty); if (jukeboxSongPanel.rollingTextRoutine != null) { ((MonoBehaviour)jukeboxSongPanel).StopCoroutine(jukeboxSongPanel.rollingTextRoutine); } jukeboxSongPanel.text.text = string.Empty; jukeboxSongPanel.rollingTextRoutine = ((MonoBehaviour)jukeboxSongPanel).StartCoroutine(ScrollingTextUnscaled.ShowText(jukeboxSongPanel.text, metadata.Title.ToUpper() + " " + text, 0.022f)); <time>5__3 = 0f; break; } case 1: <>1__state = -1; break; } if (<time>5__3 < jukeboxSongPanel.panelApproachTime) { jukeboxSongPanel.panelGroup.alpha = (jukeboxSongPanel.active ? 1 : 0); <time>5__3 += Time.unscaledDeltaTime; if (<time>5__3 > jukeboxSongPanel.panelApproachTime) { <time>5__3 = jukeboxSongPanel.panelApproachTime; } <rect>5__2.sizeDelta = jukeboxSongPanel.startDimensions + (jukeboxSongPanel.targetDimensions - jukeboxSongPanel.startDimensions) * <time>5__3 / jukeboxSongPanel.panelApproachTime; <>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 <FadeOut>d__7 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public JukeboxSongPanel <>4__this; private RectTransform <rect>5__2; private float <time>5__3; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <FadeOut>d__7(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <rect>5__2 = null; <>1__state = -2; } private bool MoveNext() { //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Expected O, but got Unknown //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) int num = <>1__state; JukeboxSongPanel CS$<>8__locals0 = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; CS$<>8__locals0.rollingTextRoutine = ((MonoBehaviour)CS$<>8__locals0).StartCoroutine(ScrollingTextUnscaled.HideText(CS$<>8__locals0.text, 0.022f)); <rect>5__2 = ((Component)CS$<>8__locals0.panelGroup).GetComponent<RectTransform>(); <time>5__3 = CS$<>8__locals0.panelApproachTime; <>2__current = (object)new WaitUntil((Func<bool>)(() => CS$<>8__locals0.text.text.Length <= 20)); <>1__state = 1; return true; case 1: <>1__state = -1; break; case 2: <>1__state = -1; break; } if ((double)<time>5__3 > 0.0) { CS$<>8__locals0.panelGroup.alpha = (CS$<>8__locals0.active ? 1 : 0); <time>5__3 -= Time.unscaledDeltaTime; if (<time>5__3 < 0f) { <time>5__3 = 0f; } <rect>5__2.sizeDelta = CS$<>8__locals0.startDimensions + (CS$<>8__locals0.targetDimensions - CS$<>8__locals0.startDimensions) * <time>5__3 / CS$<>8__locals0.panelApproachTime; <>2__current = null; <>1__state = 2; return true; } CS$<>8__locals0.panelGroup.alpha = 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(); } } [SerializeField] public Vector2 startDimensions; [SerializeField] public Vector2 targetDimensions; private Coroutine rollingTextRoutine; protected override SongPanelStyle Style => SongPanelStyle.Jukebox; [IteratorStateMachine(typeof(<FadeIn>d__5))] protected override IEnumerator FadeIn(JukeboxSongMetadata metadata) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <FadeIn>d__5(0) { <>4__this = this, metadata = metadata }; } [IteratorStateMachine(typeof(<Await>d__6))] protected override IEnumerator Await() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <Await>d__6(0) { <>4__this = this }; } [IteratorStateMachine(typeof(<FadeOut>d__7))] protected override IEnumerator FadeOut() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <FadeOut>d__7(0) { <>4__this = this }; } } public class PlaylistSelectable : DirectoryTreeBrowser<JukeboxSong> { [SerializeField] public GameObject selectPlaylistPanel; [SerializeField] public string playlistName; [SerializeField] public Button button; [SerializeField] public GameObject empty; protected override int maxPageLength => 6; protected override IDirectoryTree<JukeboxSong> baseDirectory { get { JukeboxPlaylist val; using (StreamReader streamReader = new StreamReader(File.Open(JukeboxPlaylist.PathForPlaylist(playlistName), FileMode.OpenOrCreate))) { val = JsonConvert.DeserializeObject<JukeboxPlaylist>(streamReader.ReadToEnd()); } List<SongIdentifier> source = ((val != null) ? ((Playlist)val).ids : new List<SongIdentifier>()); return (IDirectoryTree<JukeboxSong>)(object)new FakeDirectoryTree<JukeboxSong>("Songs", from id in source where (int)id.type != 1 || File.Exists(id.path) select MonoSingleton<JukeboxSongsLoader>.Instance.Load(id), (IEnumerable<IDirectoryTree<JukeboxSong>>)null, (IDirectoryTree<JukeboxSong>)null); } } private void Awake() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown ((UnityEvent)button.onClick).AddListener((UnityAction)delegate { MonoSingleton<PrefsManager>.Instance.SetStringLocal("jukebox.currentPlaylist", playlistName); MonoSingleton<JukeboxManager>.Instance.playlistEditor.ReloadPlaylist(); selectPlaylistPanel.SetActive(false); }); } private void OnEnable() { base.currentDirectory = ((DirectoryTreeBrowser<JukeboxSong>)this).baseDirectory; ((DirectoryTreeBrowser<JukeboxSong>)this).Rebuild(true); } protected override Action BuildLeaf(JukeboxSong item, int indexInPage) { GameObject go = Object.Instantiate<GameObject>(base.itemButtonTemplate, base.itemButtonTemplate.transform.parent); go.SetActive(true); go.GetComponent<Image>().sprite = item.Metadata.Icon; return delegate { Object.Destroy((Object)(object)go); }; } public override void Rebuild(bool setToPageZero = true) { base.Rebuild(setToPageZero); Transform itemParent = base.itemParent; LayoutRebuilder.ForceRebuildLayoutImmediate((RectTransform)(object)((itemParent is RectTransform) ? itemParent : null)); empty.SetActive(!base.currentDirectory.files.Any()); } } public abstract class SongPanel : MonoBehaviour { [CompilerGenerated] private sealed class <ShowPanelRoutine>d__16 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public JukeboxSongMetadata metadata; public SongPanel <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <ShowPanelRoutine>d__16(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { int num = <>1__state; SongPanel songPanel = <>4__this; switch (num) { default: return false; case 0: { <>1__state = -1; string text = ((!string.IsNullOrEmpty(metadata.Artist)) ? ("<color=#999>" + metadata.Artist + "</color>") : string.Empty); songPanel.text.text = metadata.Title.ToUpper() + " " + text; songPanel.icon.sprite = (((Object)(object)metadata.Icon != (Object)null) ? metadata.Icon : songPanel.defaultIcon); <>2__current = songPanel.FadeIn(metadata); <>1__state = 1; return true; } case 1: <>1__state = -1; <>2__current = songPanel.Await(); <>1__state = 2; return true; case 2: <>1__state = -1; <>2__current = songPanel.FadeOut(); <>1__state = 3; return true; case 3: <>1__state = -1; return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [SerializeField] public CanvasGroup panelGroup; [SerializeField] public Sprite defaultIcon; [SerializeField] public float panelApproachTime; [SerializeField] public float panelStayTime; public TMP_Text text; public Image icon; protected bool showIndefinitely; protected bool active; private Coroutine displayRoutine; protected abstract SongPanelStyle Style { get; } protected abstract IEnumerator FadeIn(JukeboxSongMetadata metadata); protected abstract IEnumerator Await(); protected abstract IEnumerator FadeOut(); public void Awake() { PrefsManager.onPrefChanged = (Action<string, object>)Delegate.Combine(PrefsManager.onPrefChanged, new Action<string, object>(OnPrefChanged)); JukeboxMusicPlayer.OnNextAudioClip += NextAudioClip; JukeboxMusicPlayer.OnStop += OnStop; showIndefinitely = MonoSingleton<PrefsManager>.Instance.GetBoolLocal("jukebox.showTrackPanelIndefinitely", false); active = MonoSingleton<PrefsManager>.Instance.GetIntLocal("jukebox.songPanelStyle", 0) == (int)Style; } public void OnDestroy() { PrefsManager.onPrefChanged = (Action<string, object>)Delegate.Remove(PrefsManager.onPrefChanged, new Action<string, object>(OnPrefChanged)); JukeboxMusicPlayer.OnNextAudioClip -= NextAudioClip; JukeboxMusicPlayer.OnStop -= OnStop; } [IteratorStateMachine(typeof(<ShowPanelRoutine>d__16))] private IEnumerator ShowPanelRoutine(JukeboxSongMetadata metadata) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <ShowPanelRoutine>d__16(0) { <>4__this = this, metadata = metadata }; } private void NextAudioClip(ClipChangedArgs clip) { if (clip.NewSong) { active = MonoSingleton<PrefsManager>.Instance.GetIntLocal("jukebox.songPanelStyle", 0) == (int)Style; if (displayRoutine != null) { ((MonoBehaviour)this).StopCoroutine(displayRoutine); } displayRoutine = ((MonoBehaviour)this).StartCoroutine(ShowPanelRoutine(clip.Song.Metadata)); } } private void OnStop() { active = false; } private void OnPrefChanged(string key, object value) { if (key.Equals("jukebox.showTrackPanelIndefinitely")) { showIndefinitely = (bool)value; } if (key.Equals("jukebox.songPanelStyle")) { active = (int)value == (int)Style; } } } public class SongPanelOption : MonoBehaviour { private static readonly Color Active = new Color(0.68f, 0.68f, 0.68f, 0.25f); private static readonly Color Inactive = new Color(0f, 0f, 0f, 0.59f); public SongPanelStyle style; private void Start() { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) ((Graphic)((Component)this).gameObject.GetComponent<Image>()).color = ((MonoSingleton<PrefsManager>.Instance.GetIntLocal("jukebox.songPanelStyle", 0) == (int)style) ? Active : Inactive); } public void Select() { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) Button[] componentsInChildren = ((Component)((Component)this).transform.parent).GetComponentsInChildren<Button>(); foreach (Button val in componentsInChildren) { ((Graphic)((Component)val).gameObject.GetComponent<Image>()).color = (((Object)(object)val == (Object)(object)((Component)this).gameObject.GetComponent<Button>()) ? Active : Inactive); } MonoSingleton<PrefsManager>.Instance.SetIntLocal("jukebox.songPanelStyle", (int)style); } } public enum SongPanelStyle { Jukebox, Classic } } namespace Jukebox.UI.Elements { public class Counter : MonoBehaviour { [CompilerGenerated] private sealed class <ChangeValueRoutine>d__18 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public Action<int> callback; public Counter <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <ChangeValueRoutine>d__18(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected O, but got Unknown //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Expected O, but got Unknown int num = <>1__state; Counter counter = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; callback(counter.tmpValue); <>2__current = (object)new WaitForSecondsRealtime(0.3f); <>1__state = 1; return true; case 1: <>1__state = -1; break; case 2: <>1__state = -1; break; } callback(counter.tmpValue); <>2__current = (object)new WaitForSecondsRealtime(0.1f); <>1__state = 2; return true; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [SerializeField] private TextMeshProUGUI textValue; [SerializeField] private CounterButton increase; [SerializeField] private CounterButton decrease; [SerializeField] private int minValue; [SerializeField] private int maxValue; private int tmpValue; private IEnumerator changeValueRoutine; private int value; public int Value { get { return value; } set { this.value = value; ((TMP_Text)textValue).text = Value.ToString(); this.OnChanged?.Invoke(value); } } public event Action<int> OnChanged; public void Awake() { AddEvents(increase, delegate { tmpValue = ChangeValue((int i) => i + 1); }); AddEvents(decrease, delegate { tmpValue = ChangeValue((int i) => i - 1); }); } public void SetDefaultValue(int defaultValue) { Value = defaultValue; tmpValue = defaultValue; ((TMP_Text)textValue).text = defaultValue.ToString(); } private void AddEvents(CounterButton button, Action<int> callback) { button.OnDown += delegate { changeValueRoutine = ChangeValueRoutine(callback); ((MonoBehaviour)this).StartCoroutine(changeValueRoutine); }; button.OnUp += SaveValue; button.OnExit += SaveValue; } private void SaveValue() { if (changeValueRoutine != null) { ((MonoBehaviour)this).StopCoroutine(changeValueRoutine); } Value = tmpValue; this.OnChanged?.Invoke(Value); } [IteratorStateMachine(typeof(<ChangeValueRoutine>d__18))] private IEnumerator ChangeValueRoutine(Action<int> callback) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <ChangeValueRoutine>d__18(0) { <>4__this = this, callback = callback }; } private int ChangeValue(Func<int, int> operation) { int result = ValidateOperation(operation); ((TMP_Text)textValue).text = result.ToString(); return result; } private int ValidateOperation(Func<int, int> operation) { int num = operation(tmpValue); if (num >= minValue && num <= maxValue) { return num; } return tmpValue; } } public class CounterButton : Button { public bool pressed; public event Action OnDown; public event Action OnUp; public event Action OnExit; public override void OnPointerDown(PointerEventData eventData) { pressed = true; ((Selectable)this).OnPointerDown(eventData); this.OnDown?.Invoke(); } public override void OnPointerUp(PointerEventData eventData) { pressed = false; ((Selectable)this).OnPointerUp(eventData); this.OnUp?.Invoke(); } public override void OnPointerExit(PointerEventData eventData) { ((Selectable)this).OnPointerExit(eventData); if (pressed) { this.OnExit?.Invoke(); } pressed = false; } } public class RewindSlider : MonoBehaviour, IEndDragHandler, IEventSystemHandler, IDragHandler { public bool beingDragged; [SerializeField] public Slider slider; public event Action<float> OnValueChanged; public void OnEndDrag(PointerEventData eventData) { this.OnValueChanged?.Invoke(slider.value); beingDragged = false; } public void OnDrag(PointerEventData eventData) { beingDragged = true; } } } namespace Jukebox.UI.Effects { public class SoundEffectButton : MonoBehaviour { [SerializeField] private string prefsKey; [SerializeField] private TMP_Text title; [SerializeField] private TMP_Text fileNameText; [SerializeField] private TMP_Text browserWindowTitle; protected void Awake() { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Expected O, but got Unknown ChangeFileName(MonoSingleton<PrefsManager>.Instance.GetStringLocal(prefsKey, (string)null)); PrefsManager.onPrefChanged = (Action<string, object>)Delegate.Combine(PrefsManager.onPrefChanged, new Action<string, object>(OnPrefChanged)); ((UnityEvent)((Component)this).GetComponent<Button>().onClick).AddListener((UnityAction)delegate { browserWindowTitle.text = "Select file for " + title.text; }); } protected void OnDestroy() { PrefsManager.onPrefChanged = (Action<string, object>)Delegate.Remove(PrefsManager.onPrefChanged, new Action<string, object>(OnPrefChanged)); } private void OnPrefChanged(string key, object value) { if (key.Equals(prefsKey)) { ChangeFileName((string)value); } } private void ChangeFileName(string fileName) { fileNameText.text = ((fileName != null) ? new FileInfo(fileName).Name : "Default"); } } } namespace Jukebox.UI.Decorators { public class ControlBindDecorator : MonoBehaviour { [SerializeField] public InputActionReference action; protected void Awake() { //IL_0040: Unknown result type (might be due to invalid IL or missing references) InputAction val = MonoSingleton<InputManager>.Instance.InputSource.Actions.asset.FindAction(action.ToInputAction().id); ((Component)this).GetComponentInChildren<ControlsOptionsKey>().RebuildBindings(val, MonoSingleton<InputManager>.Instance.InputSource.Actions.KeyboardMouseScheme); } } public abstract class UIDecorator<T> : MonoBehaviour where T : MonoBehaviour { [SerializeField] public GameObject hint; protected GameObject control; protected abstract GameObject Template(); protected abstract void Init(); public void Start() { //IL_0028: Unknown result type (might be due to invalid IL or missing references) control = Object.Instantiate<GameObject>(Template(), ((Component)this).transform); control.transform.position = ((Component)this).transform.position; Object.Destroy((Object)(object)hint); Init(); Object.Destroy((Object)(object)((Component)this).GetComponent<T>()); } } } namespace Jukebox.Patches { [HarmonyPatch(typeof(AudioMixerController))] public static class AudioMixerControllerPatch { [HarmonyPostfix] [HarmonyPatch(typeof(AudioMixerController), "Update")] public static void AudioMixerController_Update_Postfix(AudioMixerController __instance) { if (!((Object)(object)MonoSingleton<JukeboxManager>.Instance == (Object)null)) { __instance.musicSound.SetFloat("allVolume", __instance.CalculateVolume(__instance.musicVolume) + MonoSingleton<JukeboxManager>.Instance.player.VolumeBoost); } } } [HarmonyPatch(typeof(DiscordController))] public static class DiscordControllerPatch { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static UpdateActivityHandler <>9__0_0; internal void <DiscordController_UpdateWave_Prefix>b__0_0(Result _) { } } [HarmonyPrefix] [HarmonyPatch(typeof(DiscordController), "UpdateWave")] public static bool DiscordController_UpdateWave_Prefix(int wave) { //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Expected O, but got Unknown if (JukeboxMusicPlayer.CurrentSong == null || !MonoSingleton<PrefsManager>.Instance.GetBoolLocal("jukebox.discordAndSteamIntegration", false)) { return true; } if ((Object)(object)DiscordController.Instance == (Object)null) { return false; } Activity @private = ReflectionUtils.GetPrivate<Activity>(DiscordController.Instance, typeof(DiscordController), "cachedActivity"); string details = @private.Details; try { bool private2 = ReflectionUtils.GetPrivate<bool>(DiscordController.Instance, typeof(DiscordController), "disabled"); ActivityManager private3 = ReflectionUtils.GetPrivate<ActivityManager>(DiscordController.Instance, typeof(DiscordController), "activityManager"); Discord private4 = ReflectionUtils.GetPrivate<Discord>(DiscordController.Instance, typeof(DiscordController), "discord"); if (private2) { return false; } @private.Details = $"WAVE: {wave} | \ud83c\udfb5 {JukeboxMusicPlayer.CurrentSong.ArtistAndTrack}"; ReflectionUtils.SetPrivate<DiscordController, Activity>(DiscordController.Instance, typeof(DiscordController), "cachedActivity", @private); if (private4 == null || private3 == null) { return false; } Activity val = @private; object obj = <>c.<>9__0_0; if (obj == null) { UpdateActivityHandler val2 = delegate { }; <>c.<>9__0_0 = val2; obj = (object)val2; } private3.UpdateActivity(val, (UpdateActivityHandler)obj); return false; } catch (Exception) { @private.Details = details; ReflectionUtils.SetPrivate<DiscordController, Activity>(DiscordController.Instance, typeof(DiscordController), "cachedActivity", @private); return true; } } } [HarmonyPatch(typeof(FinalCyberRank))] public static class FinalCyberRankPatch { [HarmonyPrefix] [HarmonyPatch(typeof(FinalCyberRank), "GameOver")] public static bool FinalCyberRank_GameOver_Prefix() { JukeboxMusicPlayer player = MonoSingleton<JukeboxManager>.Instance.player; if ((Object)(object)player != (Object)null) { if (MonoSingleton<PrefsManager>.Instance.GetBoolLocal("jukebox.resumeLastSong", false) && JukeboxMusicPlayer.CurrentSong != null && (Object)(object)player.Source.clip != (Object)null) { JukeboxPreferencesManager instance = MonoSingleton<JukeboxPreferencesManager>.Instance; instance.SetPlaybackPosition(JukeboxMusicPlayer.CurrentSong.Id, JukeboxMusicPlayer.CurrentClipIndex, player.Source.time); instance.ForceSavePreferences(); } player.Stop(); } return true; } } [HarmonyPatch(typeof(InputActions))] public static class InputActionsPatch { [HarmonyPostfix] [HarmonyPatch(/*Could not decode attribute arguments.*/)] public static void InputActions_Constructor_Postfix(InputActions __instance) { if (__instance.asset.FindActionMap("Jukebox", false) == null) { MergeInputActionAssets(__instance); } } private static void MergeInputActionAssets(InputActions ukInputActions) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) if (Resources.FindObjectsOfTypeAll(typeof(InputActionAsset)).Length == 0) { Debug.LogError((object)"Couldn't load InputActionAsset"); return; } InputActionAsset val = Addressables.LoadAssetAsync<InputActionAsset>((object)"Assets/Jukebox/JukeboxControls.inputactions").WaitForCompletion(); if (ukInputActions.asset.FindActionMap("Jukebox", false) == null) { ukInputActions.Disable(); InputActionSetupExtensions.AddActionMap(ukInputActions.asset, InputActionMap.FromJson(val.ToJson())[0]); ukInputActions.Enable(); } } } [HarmonyPatch(typeof(InputManager))] public static class InputManagerPatch { [HarmonyPrefix] [HarmonyPatch(typeof(InputManager), "Rebind")] public static bool InputManager_Rebind_Prefix(InputManager __instance, InputAction action, int? existingIndex, Action onComplete, Action onCancel, InputControlScheme scheme) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) if (action.actionMap.name != "Jukebox") { return true; } __instance.WaitForButton((Action<string>)delegate(string path) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) if (path == "<Mouse>/leftButton") { onComplete?.Invoke(); } else if (((IEnumerable<InputBinding>)(object)action.bindings).Any((InputBinding binding) => InputSystem.FindControl(((InputBinding)(ref binding)).path) == InputSystem.FindControl(path))) { onComplete?.Invoke(); } else { BindingSyntax val = ((!existingIndex.HasValue) ? InputActionSetupExtensions.AddBinding(action, default(InputBinding)) : InputActionSetupExtensions.ChangeBinding(action, existingIndex.GetValueOrDefault())); val = ((BindingSyntax)(ref val)).WithPath(path); ((BindingSyntax)(ref val)).WithGroup(((InputControlScheme)(ref scheme)).bindingGroup); __instance.actionModified?.Invoke(action); if (onComplete != null) { onComplete(); } } }, (Action)delegate { onCancel?.Invoke(); }, ((IEnumerable<DeviceRequirement>)(object)((InputControlScheme)(ref scheme)).deviceRequirements).Select((DeviceRequirement requirement) => ((DeviceRequirement)(ref requirement)).controlPath).ToList()); return false; } } [HarmonyPatch(typeof(ScreenZone))] public static class ScreenZonePatch { private static PreviewHelper _helper; private static ScreenZone _cgTerminal; [HarmonyPostfix] [HarmonyPatch(typeof(ScreenZone), "Awake")] public static void ScreenZone_Awake_Postfix(ScreenZone __instance) { if (!(((Object)__instance).name != "Cybergrind Shop")) { PreviewHelper previewHelper = default(PreviewHelper); if (!((Component)__instance).TryGetComponent<PreviewHelper>(ref previewHelper)) { ((Component)__instance).gameObject.AddComponent<PreviewHelper>(); } _cgTerminal = __instance; } } [HarmonyPrefix] [HarmonyPatch(typeof(ScreenZone), "Update")] public static bool ScreenZone_Update_Prefix(bool ___inZone, ScreenZone __instance) { if ((Object)(object)_cgTerminal != (Object)(object)__instance) { return true; } if ((Object)(object)_helper == (Object)null) { PreviewHelper helper = default(PreviewHelper); if (!((Component)__instance).TryGetComponent<PreviewHelper>(ref helper)) { return true; } _helper = helper; } _helper.inZone = ___inZone; return true; } } [HarmonyPatch(typeof(SteamController))] public static class SteamControllerPatch { [HarmonyPrefix] [HarmonyPatch(typeof(SteamController), "UpdateWave")] public static bool SteamController_UpdateWave_Prefix(int wave) { if (JukeboxMusicPlayer.CurrentSong == null || !MonoSingleton<PrefsManager>.Instance.GetBoolLocal("jukebox.discordAndSteamIntegration", false)) { return true; } if (!SteamClient.IsValid) { return false; } SteamFriends.SetRichPresence("wave", $"WAVE: {wave} | \ud83c\udfb5 {JukeboxMusicPlayer.CurrentSong.ArtistAndTrack}"); return false; } } } namespace Jukebox.Input { [ConfigureSingleton(/*Could not decode attribute arguments.*/)] public class JukeboxInputs : MonoSingleton<JukeboxInputs> { private InputActionMap jukeboxActionMap; public InputAction Menu { get; private set; } public InputAction Playback { get; private set; } public InputAction NextTrack { get; private set; } public InputAction RandomTrack { get; private set; } public InputAction DisablePlayer { get; private set; } public void Awake() { jukeboxActionMap = MonoSingleton<InputManager>.Instance.InputSource.Actions.asset.FindActionMap("Jukebox", false); Menu = jukeboxActionMap.FindAction("Jukebox Menu", false); Playback = jukeboxActionMap.FindAction("Playback Menu", false); NextTrack = jukeboxActionMap.FindAction("Next Track", false); RandomTrack = jukeboxActionMap.FindAction("Random Track", false); DisablePlayer = jukeboxActionMap.FindAction("Disable Player", false); } } } namespace Jukebox.Components { public class CybergrindEffectsChanger : MonoBehaviour { [CompilerGenerated] private sealed class <>c__DisplayClass19_0 { public AudioSource terminalMusic; internal void <PrepareTerminalMusic>b__0(AudioClip clip) { terminalMusic.Stop(); terminalMusic.volume = 1f; terminalMusic.clip = clip; terminalMusic.Play(); } } [CompilerGenerated] private sealed class <Download>d__21 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public FileSystemInfo path; public Action<AudioClip> callback; private DownloadHandlerAudioClip <handler>5__2; private UnityWebRequest <wr>5__3; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <Download>d__21(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(); } } <handler>5__2 = null; <wr>5__3 = null; <>1__state = -2; } private bool MoveNext() { //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Expected O, but got Unknown //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Expected O, but got Unknown bool result; try { switch (<>1__state) { default: result = false; break; case 0: <>1__state = -1; <handler>5__2 = new DownloadHandlerAudioClip(new Uri(path.FullName).AbsoluteUri, CustomMusicFileBrowser.extensionTypeDict[path.Extension.ToLower()]); <wr>5__3 = new UnityWebRequest(new Uri(path.FullName).AbsoluteUri, "GET", (DownloadHandler)(object)<handler>5__2, (UploadHandler)null); <>1__state = -3; <>2__current = <wr>5__3.SendWebRequest(); <>1__state = 1; result = true; break; case 1: <>1__state = -3; if (<wr>5__3.responseCode == 200) { callback(<handler>5__2.audioClip); } 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 (<wr>5__3 != null) { ((IDisposable)<wr>5__3).Dispose(); } } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <PrepareAwwSfx>d__17 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public CybergrindEffectsChanger <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <PrepareAwwSfx>d__17(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { int num = <>1__state; CybergrindEffectsChanger CS$<>8__locals0 = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; <>2__current = CS$<>8__locals0.PrepareClip(CS$<>8__locals0.prefsManager.GetStringLocal("jukebox.effects.aww", (string)null), delegate(AudioClip clip) { CS$<>8__locals0.crowdReactions.aww = clip; }, CS$<>8__locals0.awwDefault); <>1__state = 1; return true; case 1: <>1__state = -1; return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <PrepareClip>d__20 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public string path; public CybergrindEffectsChanger <>4__this; public Action<AudioClip> callback; public AudioClip fallback; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <PrepareClip>d__20(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { int num = <>1__state; CybergrindEffectsChanger cybergrindEffectsChanger = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; if (path != null) { <>2__current = cybergrindEffectsChanger.Download(new FileInfo(path), callback); <>1__state = 1; return true; } callback(fallback); break; case 1: <>1__state = -1; break; } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <PrepareGameOverSfx>d__18 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public CybergrindEffectsChanger <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <PrepareGameOverSfx>d__18(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { int num = <>1__state; CybergrindEffectsChanger cybergrindEffectsChanger = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; <>2__current = cybergrindEffectsChanger.PrepareClip(cybergrindEffectsChanger.prefsManager.GetStringLocal("jukebox.effects.gameover", (string)null), delegate(AudioClip clip) { EndMusicAudioSource.clip = clip; }, cybergrindEffectsChanger.gameOverDefault); <>1__state = 1; return true; case 1: <>1__state = -1; return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <PrepareParrySfx>d__15 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public CybergrindEffectsChanger <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <PrepareParrySfx>d__15(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { int num = <>1__state; CybergrindEffectsChanger CS$<>8__locals0 = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; <>2__current = CS$<>8__locals0.PrepareClip(CS$<>8__locals0.prefsManager.GetStringLocal("jukebox.effects.parry", (string)null), delegate(AudioClip clip) { CS$<>8__locals0.crowdReactions.cheer = clip; }, CS$<>8__locals0.cheerDefault); <>1__state = 1; return true; case 1: <>1__state = -1; return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <PrepareTerminalMusic>d__19 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public CybergrindEffectsChanger <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <PrepareTerminalMusic>d__19(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { int num = <>1__state; CybergrindEffectsChanger cybergrindEffectsChanger = <>4__this; switch (num) { default: return false; case 0: { <>1__state = -1; <>c__DisplayClass19_0 CS$<>8__locals0 = new <>c__DisplayClass19_0 { terminalMusic = MenuMusicAudioSource }; <>2__current = cybergrindEffectsChanger.PrepareClip(cybergrindEffectsChanger.prefsManager.GetStringLocal("jukebox.effects.terminal-music", (string)null), delegate(AudioClip clip) { CS$<>8__locals0.terminalMusic.Stop(); CS$<>8__locals0.terminalMusic.volume = 1f; CS$<>8__locals0.terminalMusic.clip = clip; CS$<>8__locals0.terminalMusic.Play(); }, cybergrindEffectsChanger.terminalMusicDefault); <>1__state = 1; return true; } case 1: <>1__state = -1; return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <PrepareWaveCompleteSfx>d__16 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public CybergrindEffectsChanger <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <PrepareWaveCompleteSfx>d__16(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { int num = <>1__state; CybergrindEffectsChanger CS$<>8__locals0 = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; <>2__current = CS$<>8__locals0.PrepareClip(CS$<>8__locals0.prefsManager.GetStringLocal("jukebox.effects.wavecomplete", (string)null), delegate(AudioClip clip) { CS$<>8__locals0.crowdReactions.cheerLong = clip; }, CS$<>8__locals0.cheerLongDefault); <>1__state = 1; return true; case 1: <>1__state = -1; return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <Setup>d__14 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public CybergrindEffectsChanger <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <Setup>d__14(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { int num = <>1__state; CybergrindEffectsChanger cybergrindEffectsChanger = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; <>2__current = cybergrindEffectsChanger.PrepareParrySfx(); <>1__state = 1; return true; case 1: <>1__state = -1; <>2__current = cybergrindEffectsChanger.PrepareWaveCompleteSfx(); <>1__state = 2; return true; case 2: <>1__state = -1; <>2__current = cybergrindEffectsChanger.PrepareAwwSfx(); <>1__state = 3; return true; case 3: <>1__state = -1; <>2__current = cybergrindEffectsChanger.PrepareGameOverSfx(); <>1__state = 4; return true; case 4: <>1__state = -1; <>2__current = cybergrindEffectsChanger.PrepareTerminalMusic(); <>1__state = 5; return true; case 5: <>1__state = -1; return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private const string TerminalPath = "/FirstRoom/Room/Cybergrind Shop/Music"; private CrowdReactions crowdReactions; private PrefsManager prefsManager; private AudioClip awwDefault; private AudioClip cheerDefault; private AudioClip cheerLongDefault; private AudioClip terminalMusicDefault; private AudioClip gameOverDefault; private static AudioSource EndMusicAudioSource { get { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) Scene activeScene = SceneManager.GetActiveScene(); return ((Scene)(ref activeScene)).GetRootGameObjects().First((GameObject o) => ((Object)o).name == "EndMusic").GetComponent<AudioSource>(); } } private static AudioSource MenuMusicAudioSource => GameObject.Find("/FirstRoom/Room/Cybergrind Shop/Music").GetComponent<AudioSource>(); private void Awake() { crowdReactions = MonoSingleton<CrowdReactions>.Instance; prefsManager = MonoSingleton<PrefsManager>.Instance; awwDefault = Object.Instantiate<AudioClip>(crowdReactions.aww, ((Component)this).gameObject.transform); cheerDefault = Object.Instantiate<AudioClip>(crowdReactions.cheer, ((Component)this).gameObject.transform); cheerLongDefault = Object.Instantiate<AudioClip>(crowdReactions.cheerLong, ((Component)this).gameObject.transform); terminalMusicDefault = Object.Instantiate<AudioClip>(MenuMusicAudioSource.clip, ((Component)this).gameObject.transform); gameOverDefault = Object.Instantiate<AudioClip>(EndMusicAudioSource.clip, ((Component)this).gameObject.transform); ((MonoBehaviour)this).StartCoroutine(Setup()); PrefsManager.onPrefChanged = (Action<string, object>)Delegate.Combine(PrefsManager.onPrefChanged, new Action<string, object>(OnPrefChanged)); } private void OnDestroy() { PrefsManager.onPrefChanged = (Action<string, object>)Delegate.Remove(PrefsManager.onPrefChanged, new Action<string, object>(OnPrefChanged)); } [IteratorStateMachine(typeof(<Setup>d__14))] private IEnumerator Setup() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <Setup>d__14(0) { <>4__this = this }; } [IteratorStateMachine(typeof(<PrepareParrySfx>d__15))] private IEnumerator PrepareParrySfx() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <PrepareParrySfx>d__15(0) { <>4__this = this }; } [IteratorStateMachine(typeof(<PrepareWaveCompleteSfx>d__16))] private IEnumerator PrepareWaveCompleteSfx() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <PrepareWaveCompleteSfx>d__16(0) { <>4__this = this }; } [IteratorStateMachine(typeof(<PrepareAwwSfx>d__17))] private IEnumerator PrepareAwwSfx() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <PrepareAwwSfx>d__17(0) { <>4__this = this }; } [IteratorStateMachine(typeof(<PrepareGameOverSfx>d__18))] private IEnumerator PrepareGameOverSfx() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <PrepareGameOverSfx>d__18(0) { <>4__this = this }; } [IteratorStateMachine(typeof(<PrepareTerminalMusic>d__19))] private IEnumerator PrepareTerminalMusic() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <PrepareTerminalMusic>d__19(0) { <>4__this = this }; } [IteratorStateMachine(typeof(<PrepareClip>d__20))] private IEnumerator PrepareClip(string path, Action<AudioClip> callback, AudioClip fallback) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <PrepareClip>d__20(0) { <>4__this = this, path = path, callback = callback, fallback = fallback }; } [IteratorStateMachine(typeof(<Download>d__21))] private IEnumerator Download(FileSystemInfo path, Action<AudioClip> callback) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <Download>d__21(0) { path = path, callback = callback }; } private void OnPrefChanged(string key, object value) { switch (key) { case "jukebox.effects.wavecomplete": ((MonoBehaviour)this).StartCoroutine(PrepareWaveCompleteSfx()); break; case "jukebox.effects.aww": ((MonoBehaviour)this).StartCoroutine(PrepareAwwSfx()); break; case "jukebox.effects.gameover": ((MonoBehaviour)this).StartCoroutine(PrepareGameOverSfx()); break; case "jukebox.effects.terminal-music": ((MonoBehaviour)this).StartCoroutine(PrepareTerminalMusic()); break; case "jukebox.effects.parry": ReflectionUtils.GetPrivate<AudioSource>(crowdReactions, typeof(CrowdReactions), "aud").Stop(); ((MonoBehaviour)this).StartCoroutine(PrepareParrySfx()); break; } } } public class JukeboxEffectsBrowser : DirectoryTreeBrowser<FileInfo> { private static readonly DirectoryInfo EffectsDirectory = new DirectoryInfo(Path.Combine(PathsUtils.ApplicationPath, "Cybergrind", "Effects")); [SerializeField] private JukeboxTerminalPanel navigator; [SerializeField] private GameObject effectsMenu; private string currentPrefKey; protected override int maxPageLength => 3; protected override IDirectoryTree<FileInfo> baseDirectory => (IDirectoryTree<FileInfo>)new FileDirectoryTree(EffectsDirectory, (IDirectoryTree<FileInfo>)null); public void NextPage() { base.SetPage((base.currentPage != base.maxPages - 1) ? (base.currentPage + 1) : 0); } public void PreviousPage() { base.SetPage((base.currentPage == 0) ? (base.maxPages - 1) : (base.currentPage - 1)); } public void SetCurrentPrefKey(string key) { currentPrefKey = key; } public void ResetToDefault() { MonoSingleton<PrefsManager>.Instance.SetStringLocal(currentPrefKey, (string)null); } protected override Action BuildLeaf(FileInfo item, int indexInPage) { //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Expected O, but got Unknown GameObject go = Object.Instantiate<GameObject>(base.itemButtonTemplate, base.itemParent); CustomContentButton component = go.GetComponent<CustomContentButton>(); component.text.text = item.Name; go.SetActive(true); ((UnityEvent)component.button.onClick).AddListener((UnityAction)delegate { MonoSingleton<PrefsManager>.Instance.SetStringLocal(currentPrefKey, item.FullName); navigator.GoToNoMenu(effectsMenu); }); return delegate { Object.Destroy((Object)(object)go); }; } public void OpenEffectsFolder() { Application.OpenURL(new Uri(EffectsDirectory.FullName).AbsoluteUri); } public override void Rebuild(bool setToPageZero = true) { Transform itemParent = base.itemParent; LayoutRebuilder.ForceRebuildLayoutImmediate((RectTransform)(object)((itemParent is RectTransform) ? itemParent : null)); base.Rebuild(setToPageZero); } } public class JukeboxMusicChanger : MonoBehaviour { private enum ThemeVariation { Battle, Calm } [CompilerGenerated] private sealed class <SlowUpdate>d__12 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public JukeboxMusicChanger <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <SlowUpdate>d__12(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Expected O, but got Unknown int num = <>1__state; JukeboxMusicChanger jukeboxMusicChanger = <>4__this; if (num != 0) { if (num != 1) { return false; } <>1__state = -1; } else { <>1__state = -1; } if (CalmThemesAllowed && jukeboxMusicChanger.themesManager.FewEnemies) { jukeboxMusicChanger.PlayCalmTheme(); } else { jukeboxMusicChanger.PlayBattleTheme(); } <>2__current = (object)new WaitForSecondsRealtime(0.1f); <>1__state = 1; return true; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private const int FadeSpeed = 1; public AudioSource clean; public AudioSource battle; private JukeboxThemesManager themesManager; private Coroutine updateRoutine; private ThemeVariation currentTheme; private static bool CalmThemesAllowed => MonoSingleton<PrefsManager>.Instance.GetBoolLocal("jukebox.enableCalmThemes", false); public void Awake() { themesManager = MonoSingleton<JukeboxThemesManager>.Instance; } private void Update() { if (!((Object)(object)clean.clip == (Object)null)) { if (currentTheme == ThemeVariation.Calm) { clean.volume = Mathf.MoveTowards(clean.volume, 1f, 1f * Time.deltaTime); battle.volume = Mathf.MoveTowards(battle.volume, 0f, 1f * Time.deltaTime); } else { clean.volume = Mathf.MoveTowards(clean.volume, 0f, 1f * Time.deltaTime); battle.volume = Mathf.MoveTowards(battle.volume, 1f, 1f * Time.deltaTime); } } } public void ChangeTo(AudioClip battleTheme, AudioClip calmTheme, float startingFrom = 0f) { if (updateRoutine != null) { ((MonoBehaviour)this).StopCoroutine(updateRoutine); } clean.clip = calmTheme; battle.clip = battleTheme; battle.Play(); battle.time = startingFrom; battle.volume = 1f; if ((Object)(object)clean.clip != (Object)null) { clean.Play(); clean.time = startingFrom; if (CalmThemesAllowed && themesManager.FewEnemies) { clean.volume = 1f; battle.volume = 0f; } } updateRoutine = ((MonoBehaviour)this).StartCoroutine(SlowUpdate()); } public void RewindTo(float position = 0f) { clean.time = Math.Min(position, ((Object)(object)clean.clip != (Object)null) ? clean.clip.length : 0f); battle.time = Math.Min(position, ((Object)(object)battle.clip != (Object)null) ? battle.clip.length : 0f); } [IteratorStateMachine(typeof(<SlowUpdate>d__12))] private IEnumerator SlowUpdate() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <SlowUpdate>d__12(0) { <>4__this = this }; } private void PlayBattleTheme() { if (currentTheme != 0) { currentTheme = ThemeVariation.Battle; if ((Object)(object)clean.clip != (Object)null) { battle.timeSamples = clean.timeSamples; } } } private void PlayCalmTheme() { if (currentTheme != ThemeVariation.Calm) { currentTheme = ThemeVariation.Calm; if ((Object)(object)clean.clip != (Object)null) { clean.timeSamples = battle.timeSamples; } } } } [ConfigureSingleton(/*Could not decode attribute arguments.*/)] public class JukeboxThemesManager : MonoSingleton<
plugins/Jukebox/JukeboxCore.dll
Decompiled 5 days agousing System; using System.CodeDom.Compiler; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Net.Http; using System.Net.Http.Headers; using System.Reflection; using System.Resources; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Text.RegularExpressions; using System.Threading.Tasks; using BepInEx; using BepInEx.Configuration; using JetBrains.Annotations; using JukeboxCore.Components; using JukeboxCore.Exceptions; using JukeboxCore.Models.Song; using JukeboxCore.Themes; using JukeboxCore.Utils; using Newtonsoft.Json; using TagLib; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.Networking; using UnityEngine.ResourceManagement.AsyncOperations; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("JukeboxCore")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("JukeboxCore")] [assembly: AssemblyCopyright("Copyright © 2025")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("AB57436D-F3D9-454E-8F64-33F23AFD6690")] [assembly: AssemblyFileVersion("2.2.1.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("2.2.1.0")] namespace JukeboxCore { [ConfigureSingleton(/*Could not decode attribute arguments.*/)] public class MainThreadDispatcher : MonoSingleton<MainThreadDispatcher> { private static readonly Queue<Action> ExecutionQueue = new Queue<Action>(); public void Enqueue(Action action) { lock (ExecutionQueue) { ExecutionQueue.Enqueue(action); } } private void Update() { lock (ExecutionQueue) { while (ExecutionQueue.Count > 0) { ExecutionQueue.Dequeue()?.Invoke(); } } } } [GeneratedCode("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] [DebuggerNonUserCode] [CompilerGenerated] internal class Resources { private static ResourceManager resourceMan; private static CultureInfo resourceCulture; [EditorBrowsable(EditorBrowsableState.Advanced)] internal static ResourceManager ResourceManager { get { if (resourceMan == null) { resourceMan = new ResourceManager("JukeboxCore.Resources", typeof(Resources).Assembly); } return resourceMan; } } [EditorBrowsable(EditorBrowsableState.Advanced)] internal static CultureInfo Culture { get { return resourceCulture; } set { resourceCulture = value; } } internal static byte[] JukeboxCore => (byte[])ResourceManager.GetObject("JukeboxCore", resourceCulture); internal Resources() { } } public struct UnscaledTimeSince { private float time; public static implicit operator float(UnscaledTimeSince ts) { return Time.unscaledTime - ts.time; } public static implicit operator UnscaledTimeSince(float ts) { UnscaledTimeSince result = default(UnscaledTimeSince); result.time = Time.unscaledTime - ts; return result; } } } namespace JukeboxCore.Utils { public static class CompositeSongsUtils { private static readonly List<string> SpecialPostfixes = new List<string> { "intro", "loop", "calm", "calmloop", "calmintro" }; public static JukeboxSongMetadata.CompositeProperties GetSongComponents(string guid, SoundtrackSong song) { return new JukeboxSongMetadata.CompositeProperties.Builder().GotIntroAndLoop((Object)(object)song.introClip != (Object)null).GotCalmIntro(val: false).GotCalmLoop(MonoSingleton<JukeboxStaticData>.Instance.calmThemes.FindCalmClipsFor(guid) != null) .Build; } public static JukeboxSongMetadata.CompositeProperties GetSongComponents(FileInfo fileInfo) { JukeboxSongMetadata.CompositeProperties.Builder builder = new JukeboxSongMetadata.CompositeProperties.Builder(); List<FileInfo> source = (from file in fileInfo.Directory?.GetFiles() where WithoutPostfix(file).Name.Equals(fileInfo.Name) select file).Select(delegate(FileInfo file) { if (HasSpecialPostfix(file, "calmintro")) { builder.GotCalmIntro(val: true); } if (HasSpecialPostfix(file, "calmloop")) { builder.GotCalmLoop(val: true); } if (HasSpecialPostfix(file, "calm")) { builder.GotCalmTheme(val: true); } return file; }).ToList() ?? new List<FileInfo>(); if (source.Any((FileInfo file) => HasSpecialPostfix(file, "intro")) && source.Any((FileInfo file) => HasSpecialPostfix(file, "loop"))) { builder.GotIntroAndLoop(val: true); } return builder.Build; } public static FileInfo WithPostfix(FileInfo path, string postfix) { return new FileInfo(Path.GetDirectoryName(path.FullName) + "\\" + Path.GetFileNameWithoutExtension(path.FullName) + "_" + postfix + path.Extension); } public static FileInfo WithoutPostfix(FileInfo path) { if (HasAnySpecialPostfix(path)) { return new FileInfo(Regex.Replace(path.FullName, "_[a-zA-Z]+\\.[a-zA-Z0-9]+$", path.Extension)); } return path; } public static bool HasValidExtenstion(FileInfo path) { return CustomMusicFileBrowser.extensionTypeDict.Keys.Any((string extension) => path.Extension.ToLower().Equals(extension)); } private static bool HasAnySpecialPostfix(FileInfo path) { return SpecialPostfixes.Any((string postfix) => HasSpecialPostfix(path, postfix)); } private static bool HasSpecialPostfix(FileInfo path, string postfix) { return Path.GetFileNameWithoutExtension(path.Name).EndsWith("_" + postfix); } } public static class ConfigUtils { public static readonly ConfigFile BepInExConfig = new ConfigFile(PathsUtils.BepInExConfigPath, true); } public static class GenericUtils { public static string FirstNonEmpty(params string[] options) { return options.FirstOrDefault((string option) => !string.IsNullOrEmpty(option)); } } public static class NetworkUtils { private const int RetryAttempts = 3; private static readonly HttpClient Client; static NetworkUtils() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Expected O, but got Unknown //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown Client = new HttpClient(); Client.Timeout = TimeSpan.FromSeconds(5.0); Client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); Client.DefaultRequestHeaders.UserAgent.TryParseAdd("com.google.android.youtube/17.36.4 (Linux; U; Android 12; GB) gzip"); } public static async Task<string> GetRaw(string url) { for (int i = 0; i < 3; i++) { try { string text = await (await Client.GetAsync(url)).Content.ReadAsStringAsync(); if (text == null) { continue; } return text; } catch (Exception) { if (i == 2) { throw; } } } throw new HttpRequestException(); } public static async Task<Texture2D> DownloadImage(string url) { UnityWebRequest request = UnityWebRequestTexture.GetTexture(url); try { await request.SendWebRequest(); if (request.error != null) { throw new ImageDownloadFailedException(url, request.error); } return DownloadHandlerTexture.GetContent(request); } finally { ((IDisposable)request)?.Dispose(); } } } public static class ObjectExtensions { public static bool IsOneOf(this object v, params object[] options) { return options.Any((object o) => o.Equals(v)); } } public static class PathsUtils { private static readonly List<string> ReservedWords = new List<string> { "CON", "PRN", "AUX", "CLOCK$", "NUL", "COM0", "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9", "LPT0", "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9" }; public static readonly string ApplicationPath = Path.Combine(Directory.GetParent(Application.dataPath)?.FullName); public static readonly string AssemblyPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); public static readonly string MusicPath = Path.Combine(ApplicationPath, "CyberGrind", "Music"); public static readonly string BepInExConfigPath = Path.Combine(Paths.ConfigPath, "Jukebox", "config.cfg"); public static string CoerceValidFileName(string filename) { string text = Regex.Escape(new string(Path.GetInvalidFileNameChars())); string pattern = "[" + text + "]+"; string seed = Regex.Replace(filename, pattern, "_"); return ReservedWords.Select((string reservedWord) => "^" + reservedWord + "\\.").Aggregate(seed, (string current, string reservedWordPattern) => Regex.Replace(current, reservedWordPattern, "_reservedWord_.", RegexOptions.IgnoreCase)); } } public class UnityWebRequestAwaiter : INotifyCompletion { private readonly UnityWebRequestAsyncOperation asyncOp; private Action continuation; public bool IsCompleted => ((AsyncOperation)asyncOp).isDone; public UnityWebRequestAwaiter(UnityWebRequestAsyncOperation asyncOp) { this.asyncOp = asyncOp; ((AsyncOperation)asyncOp).completed += OnRequestCompleted; } public void GetResult() { } public void OnCompleted(Action action) { continuation = action; } private void OnRequestCompleted(AsyncOperation obj) { continuation(); } } public static class UnityWebRequestAwaiterExtensions { public static UnityWebRequestAwaiter GetAwaiter(this UnityWebRequestAsyncOperation asyncOp) { return new UnityWebRequestAwaiter(asyncOp); } } } namespace JukeboxCore.Themes { [CreateAssetMenu(menuName = "Jukebox/Calm theme")] public class CalmThemeEntry : ScriptableObject { [SerializeField] public AssetReferenceSoundtrackSong reference; [SerializeField] public List<AssetReferenceT<AudioClip>> calmVariationClips; } [CreateAssetMenu(menuName = "Jukebox/Calm Themes Data")] public class SoundtrackCalmThemes : ScriptableObject { [SerializeField] public CalmThemeEntry[] calmClips; public List<AssetReferenceT<AudioClip>> FindCalmClipsFor(string guid) { CalmThemeEntry calmThemeEntry = calmClips.FirstOrDefault((CalmThemeEntry variation) => ((AssetReference)variation.reference).AssetGUID == guid); if (!((Object)(object)calmThemeEntry != (Object)null)) { return null; } return calmThemeEntry.calmVariationClips; } } } namespace JukeboxCore.Models.Song { public sealed class JukeboxCustomSong : JukeboxSong { [CompilerGenerated] private sealed class <<AcquireInternal>g__Download|9_5>d : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public FileSystemInfo path; public JukeboxCustomSong <>4__this; public Action<AudioClip> downloadCallback; private DownloadHandlerAudioClip <handle>5__2; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <<AcquireInternal>g__Download|9_5>d(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <handle>5__2 = null; <>1__state = -2; } private bool MoveNext() { //IL_004b: Unknown result type (might be due to invalid IL or missing references) int num = <>1__state; JukeboxCustomSong jukeboxCustomSong = <>4__this; switch (num) { default: return false; case 0: { <>1__state = -1; UnityWebRequest audioClip = UnityWebRequestMultimedia.GetAudioClip(new Uri(path.FullName).AbsoluteUri, CustomMusicFileBrowser.extensionTypeDict[path.Extension.ToLower()]); jukeboxCustomSong.requests.Add(audioClip); ref DownloadHandlerAudioClip reference = ref <handle>5__2; DownloadHandler downloadHandler = audioClip.downloadHandler; reference = (DownloadHandlerAudioClip)(object)((downloadHandler is DownloadHandlerAudioClip) ? downloadHandler : null); jukeboxCustomSong.handles.Add(<handle>5__2); if (<handle>5__2 == null) { return false; } <handle>5__2.streamAudio = true; audioClip.SendWebRequest(); <>2__current = audioClip; <>1__state = 1; return true; } case 1: <>1__state = -1; downloadCallback(<handle>5__2.audioClip); 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 <AcquireInternal>d__9 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public JukeboxCustomSong <>4__this; public IEnumerator callback; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <AcquireInternal>d__9(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { int num = <>1__state; JukeboxCustomSong CS$<>8__locals0 = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; CS$<>8__locals0.handles = new List<DownloadHandlerAudioClip>(); if (CS$<>8__locals0.Metadata.Composite.GotIntroAndLoop) { <>2__current = CS$<>8__locals0.<AcquireInternal>g__Download|9_5(CompositeSongsUtils.WithPostfix(new FileInfo(CS$<>8__locals0.Id.path), "intro"), delegate(AudioClip c) { CS$<>8__locals0.IntroClip = c; }); <>1__state = 1; return true; } goto IL_0098; case 1: <>1__state = -1; goto IL_0098; case 2: <>1__state = -1; if (CS$<>8__locals0.Metadata.Composite.GotCalmIntro) { <>2__current = CS$<>8__locals0.<AcquireInternal>g__Download|9_5(CompositeSongsUtils.WithPostfix(new FileInfo(CS$<>8__locals0.Id.path), "calmintro"), delegate(AudioClip c) { CS$<>8__locals0.CalmIntroClip = c; }); <>1__state = 3; return true; } goto IL_0152; case 3: <>1__state = -1; goto IL_0152; case 4: <>1__state = -1; goto IL_01a6; case 5: <>1__state = -1; goto IL_01fa; case 6: { <>1__state = -1; return false; } IL_0152: if (CS$<>8__locals0.Metadata.Composite.GotCalmTheme) { <>2__current = CS$<>8__locals0.<AcquireInternal>g__Download|9_5(CompositeSongsUtils.WithPostfix(new FileInfo(CS$<>8__locals0.Id.path), "calm"), delegate(AudioClip c) { CS$<>8__locals0.CalmClips = new List<AudioClip> { c }; }); <>1__state = 4; return true; } goto IL_01a6; IL_01a6: if (CS$<>8__locals0.Metadata.Composite.GotCalmLoop) { <>2__current = CS$<>8__locals0.<AcquireInternal>g__Download|9_5(CompositeSongsUtils.WithPostfix(new FileInfo(CS$<>8__locals0.Id.path), "calmloop"), delegate(AudioClip c) { CS$<>8__locals0.CalmClips = new List<AudioClip> { c }; }); <>1__state = 5; return true; } goto IL_01fa; IL_0098: <>2__current = CS$<>8__locals0.<AcquireInternal>g__Download|9_5(CS$<>8__locals0.Metadata.Composite.GotIntroAndLoop ? CompositeSongsUtils.WithPostfix(new FileInfo(CS$<>8__locals0.Id.path), "loop") : new FileInfo(CS$<>8__locals0.Id.path), delegate(AudioClip c) { CS$<>8__locals0.Clips = new List<AudioClip> { c }; }); <>1__state = 2; return true; IL_01fa: <>2__current = callback; <>1__state = 6; return true; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private static readonly Sprite DefaultIcon; private readonly List<UnityWebRequest> requests = new List<UnityWebRequest>(); private List<DownloadHandlerAudioClip> handles; protected override Lazy<JukeboxSongMetadata> GetMetadata => new Lazy<JukeboxSongMetadata>(delegate { JukeboxSongMetadata jukeboxSongMetadata = JukeboxSongMetadata.From(new FileInfo(base.Id.path)); if ((Object)(object)jukeboxSongMetadata.Icon == (Object)null) { jukeboxSongMetadata.Icon = DefaultIcon; } return jukeboxSongMetadata; }); static JukeboxCustomSong() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) DefaultIcon = Addressables.LoadAssetAsync<Sprite>((object)"Assets/Jukebox/Textures/music_note.png").WaitForCompletion(); } private JukeboxCustomSong(string path) : base(new SongIdentifier(path, (IdentifierType)1)) { }//IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown ~JukeboxCustomSong() { requests.ForEach(delegate(UnityWebRequest request) { request.Dispose(); }); } public static JukeboxCustomSong Create(string path) { return new JukeboxCustomSong(path); } [IteratorStateMachine(typeof(<AcquireInternal>d__9))] protected override IEnumerator AcquireInternal(IEnumerator callback) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <AcquireInternal>d__9(0) { <>4__this = this, callback = callback }; } protected override void DisposeInternal() { DisposeOfRequests(); DisposeOfHandlers(); handles = null; DestroyClipIfPresent(base.IntroClip); foreach (AudioClip clip in base.Clips) { DestroyClipIfPresent(clip); } } private void DisposeOfRequests() { requests.ForEach(delegate(UnityWebRequest request) { request.Dispose(); }); } private void DisposeOfHandlers() { handles.ForEach(delegate(DownloadHandlerAudioClip request) { ((DownloadHandler)request).Dispose(); }); } private static void DestroyClipIfPresent(AudioClip clip) { if ((Object)(object)clip != (Object)null) { Object.Destroy((Object)(object)clip); } } [IteratorStateMachine(typeof(<<AcquireInternal>g__Download|9_5>d))] [CompilerGenerated] private IEnumerator <AcquireInternal>g__Download|9_5(FileSystemInfo path, Action<AudioClip> downloadCallback) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <<AcquireInternal>g__Download|9_5>d(0) { <>4__this = this, path = path, downloadCallback = downloadCallback }; } } public class JukeboxPlaylist : Playlist { public static string currentPath => Path.Combine(Playlist.directory.FullName, MonoSingleton<PrefsManager>.Instance.GetStringLocal("jukebox.currentPlaylist", (string)null) + ".json"); public JukeboxPlaylist() { } public JukeboxPlaylist(IEnumerable<SongIdentifier> passedIds) : base(MonoSingleton<PrefsManager>.Instance.GetBoolLocal("jukebox.preventDuplicateTracks", false) ? passedIds.Distinct() : passedIds) { } public static string PathForPlaylist(string name) { return Path.Combine(Playlist.directory.FullName, name + ".json"); } public void Add(SongIdentifier id) { if (!MonoSingleton<PrefsManager>.Instance.GetBoolLocal("jukebox.preventDuplicateTracks", false) || !((Playlist)this).ids.Contains(id)) { ((Playlist)this).Add(id); } } public void RemoveDuplicates() { List<SongIdentifier> list = ((Playlist)this).ids.Distinct().ToList(); ((Playlist)this).ids.Clear(); foreach (SongIdentifier item in list) { Add(item); } } public void RemoveNonExisting() { List<SongIdentifier> list = ((Playlist)this).ids.Where((SongIdentifier id) => (int)id.type == 0 || new FileInfo(id.path).Exists).ToList(); ((Playlist)this).ids.Clear(); foreach (SongIdentifier item in list) { Add(item); } } } public abstract class JukeboxSong { [CompilerGenerated] private sealed class <Acquire>d__33 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public JukeboxSong <>4__this; public IEnumerator callback; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <Acquire>d__33(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { int num = <>1__state; JukeboxSong jukeboxSong = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; <>2__current = jukeboxSong.AcquireInternal(callback); <>1__state = 1; return true; case 1: <>1__state = -1; jukeboxSong.Dispose(); return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private readonly Lazy<JukeboxSongMetadata> lazyMetadata; public SongIdentifier Id { get; } public JukeboxSongMetadata Metadata => lazyMetadata.Value; public AudioClip IntroClip { get; protected set; } public AudioClip CalmIntroClip { get; protected set; } public List<AudioClip> Clips { get; protected set; } public List<AudioClip> CalmClips { get; protected set; } public int MaxClipsIfNotRepeating { get; protected set; } public bool IsCustom => (int)Id.type == 1; public string ArtistAndTrack { get { if (Metadata.Artist == null) { return Metadata.Title; } return Metadata.Artist + " — " + Metadata.Title; } } protected abstract Lazy<JukeboxSongMetadata> GetMetadata { get; } protected JukeboxSong(SongIdentifier id) { Id = id; lazyMetadata = GetMetadata; } [IteratorStateMachine(typeof(<Acquire>d__33))] public IEnumerator Acquire(IEnumerator callback) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <Acquire>d__33(0) { <>4__this = this, callback = callback }; } private void Dispose() { DisposeInternal(); IntroClip = null; CalmIntroClip = null; Clips = null; CalmClips = null; MaxClipsIfNotRepeating = -1; } protected abstract IEnumerator AcquireInternal(IEnumerator callback); protected abstract void DisposeInternal(); } public static class JukeboxSongFactory { public static JukeboxSong Create(SongIdentifier id) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Invalid comparison between Unknown and I4 IdentifierType type = id.type; if ((int)type != 0) { if ((int)type == 1) { return JukeboxCustomSong.Create(id.path); } throw new ArgumentOutOfRangeException(); } return JukeboxSoundtrackSong.Create(id.path); } } public class JukeboxSongMetadata { public class CompositeProperties { public class Builder { public CompositeProperties Build { get; } public Builder() { Build = new CompositeProperties(); } public Builder GotIntroAndLoop(bool val) { Build.GotIntroAndLoop = val; return this; } public Builder GotCalmIntro(bool val) { Build.GotCalmIntro = val; return this; } public Builder GotCalmTheme(bool val) { Build.GotCalmTheme = val; return this; } public Builder GotCalmLoop(bool val) { Build.GotCalmLoop = val; return this; } } public bool GotIntroAndLoop { get; private set; } public bool GotCalmIntro { get; private set; } public bool GotCalmTheme { get; private set; } public bool GotCalmLoop { get; private set; } private CompositeProperties() { } } public Sprite Icon { get; set; } public string Title { get; } public string Artist { get; } public CompositeProperties Composite { get; } private JukeboxSongMetadata(Sprite icon, string title, CompositeProperties composite, string artist = null) { Icon = icon; Title = title; Composite = composite; Artist = artist; } public static JukeboxSongMetadata From(FileInfo srcFile) { CompositeProperties songComponents = CompositeSongsUtils.GetSongComponents(srcFile); FileInfo fileInfo = (songComponents.GotIntroAndLoop ? CompositeSongsUtils.WithPostfix(srcFile, "intro") : srcFile); try { Tag tag = File.Create(fileInfo.FullName).Tag; return new JukeboxSongMetadata(LoadCover(tag), (!string.IsNullOrEmpty(tag.Title)) ? tag.Title : Path.GetFileNameWithoutExtension(srcFile.Name), songComponents, GenericUtils.FirstNonEmpty(tag.FirstPerformer, tag.FirstComposer, tag.FirstAlbumArtist)); } catch (Exception) { return new JukeboxSongMetadata(null, fileInfo.Name, songComponents); } } public static JukeboxSongMetadata From(AssetReferenceSoundtrackSong reference) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) AsyncOperationHandle<SoundtrackSong> val = ((AssetReferenceT<SoundtrackSong>)(object)reference).LoadAssetAsync(); val.WaitForCompletion(); SoundtrackSong result = val.Result; return new JukeboxSongMetadata(result.icon, result.songName, CompositeSongsUtils.GetSongComponents(((AssetReference)reference).AssetGUID, result), result.extraLevelBit); } private static Sprite LoadCover(Tag tag) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) if (tag.Pictures.Length == 0) { return null; } using MemoryStream memoryStream = new MemoryStream(tag.Pictures[0].Data.Data); try { memoryStream.Seek(0L, SeekOrigin.Begin); Texture2D val = new Texture2D(2, 2); ImageConversion.LoadImage(val, memoryStream.ToArray()); return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f); } catch (Exception) { return null; } } } public sealed class JukeboxSoundtrackSong : JukeboxSong { [CompilerGenerated] private sealed class <AcquireInternal>d__6 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public JukeboxSoundtrackSong <>4__this; public IEnumerator callback; private SoundtrackSong <addressable>5__2; private IEnumerator<AsyncOperationHandle<AudioClip>> <>7__wrap2; private AsyncOperationHandle<AudioClip> <calmClipHandle>5__4; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <AcquireInternal>d__6(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { //IL_002e: Unknown result type (might be due to invalid IL or missing references) int num = <>1__state; if (num == -3 || num == 2) { try { } finally { <>m__Finally1(); } } <addressable>5__2 = null; <>7__wrap2 = null; <calmClipHandle>5__4 = default(AsyncOperationHandle<AudioClip>); <>1__state = -2; } private bool MoveNext() { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: 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) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) try { int num = <>1__state; JukeboxSoundtrackSong jukeboxSoundtrackSong = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; jukeboxSoundtrackSong.handle = Addressables.LoadAssetAsync<SoundtrackSong>((object)jukeboxSoundtrackSong.Id.path); <>2__current = jukeboxSoundtrackSong.handle; <>1__state = 1; return true; case 1: { <>1__state = -1; <addressable>5__2 = jukeboxSoundtrackSong.handle.Result; jukeboxSoundtrackSong.IntroClip = <addressable>5__2.introClip; jukeboxSoundtrackSong.Clips = <addressable>5__2.clips; List<AssetReferenceT<AudioClip>> list = MonoSingleton<JukeboxStaticData>.Instance.calmThemes.FindCalmClipsFor(jukeboxSoundtrackSong.Id.path); if (list != null) { jukeboxSoundtrackSong.CalmClips = new List<AudioClip>(); <>7__wrap2 = list.Select((AssetReferenceT<AudioClip> clip) => Addressables.LoadAssetAsync<AudioClip>((object)((AssetReference)clip).AssetGUID)).GetEnumerator(); <>1__state = -3; goto IL_016f; } goto IL_0189; } case 2: <>1__state = -3; jukeboxSoundtrackSong.CalmClips.Add(<calmClipHandle>5__4.Result); <calmClipHandle>5__4 = default(AsyncOperationHandle<AudioClip>); goto IL_016f; case 3: { <>1__state = -1; return false; } IL_0189: jukeboxSoundtrackSong.MaxClipsIfNotRepeating = <addressable>5__2.maxClipsIfNotRepeating; <>2__current = callback; <>1__state = 3; return true; IL_016f: if (<>7__wrap2.MoveNext()) { <calmClipHandle>5__4 = <>7__wrap2.Current; jukeboxSoundtrackSong.calmClipsHandles.Add(<calmClipHandle>5__4); <>2__current = <calmClipHandle>5__4; <>1__state = 2; return true; } <>m__Finally1(); <>7__wrap2 = null; goto IL_0189; } } catch { //try-fault ((IDisposable)this).Dispose(); throw; } } 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 (<>7__wrap2 != null) { <>7__wrap2.Dispose(); } } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private AsyncOperationHandle<SoundtrackSong> handle; private readonly List<AsyncOperationHandle<AudioClip>> calmClipsHandles = new List<AsyncOperationHandle<AudioClip>>(); protected override Lazy<JukeboxSongMetadata> GetMetadata => new Lazy<JukeboxSongMetadata>(() => JukeboxSongMetadata.From(new AssetReferenceSoundtrackSong(base.Id.path))); private JukeboxSoundtrackSong(string path) : base(new SongIdentifier(path, (IdentifierType)0)) { }//IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown public static JukeboxSoundtrackSong Create(string path) { return new JukeboxSoundtrackSong(path); } [IteratorStateMachine(typeof(<AcquireInternal>d__6))] protected override IEnumerator AcquireInternal(IEnumerator callback) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <AcquireInternal>d__6(0) { <>4__this = this, callback = callback }; } protected override void DisposeInternal() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) Addressables.Release<SoundtrackSong>(handle); foreach (AsyncOperationHandle<AudioClip> calmClipsHandle in calmClipsHandles) { Addressables.Release<AudioClip>(calmClipsHandle); } calmClipsHandles.Clear(); handle = default(AsyncOperationHandle<SoundtrackSong>); } } } namespace JukeboxCore.Models.Preferences { [JsonObject(/*Could not decode attribute arguments.*/)] public class JukeboxThemesConfig { public class CalmThemeConfig { [JsonProperty(/*Could not decode attribute arguments.*/)] public Dictionary<EnemyType, int> specialEnemies = new Dictionary<EnemyType, int> { { (EnemyType)19, 1 }, { (EnemyType)5, 1 }, { (EnemyType)26, 1 }, { (EnemyType)2, 1 }, { (EnemyType)7, 2 } }; [JsonProperty(/*Could not decode attribute arguments.*/)] public Dictionary<EnemyType, int> specialRadiantEnemies = new Dictionary<EnemyType, int> { { (EnemyType)19, 0 }, { (EnemyType)5, 0 }, { (EnemyType)26, 0 }, { (EnemyType)2, 0 }, { (EnemyType)7, 1 } }; } [JsonProperty("calmThemeConfig")] public CalmThemeConfig calmTheme = new CalmThemeConfig(); public JukeboxThemesConfig Equalize() { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) foreach (KeyValuePair<EnemyType, int> specialEnemy in calmTheme.specialEnemies) { if (!calmTheme.specialRadiantEnemies.ContainsKey(specialEnemy.Key)) { calmTheme.specialRadiantEnemies.Add(specialEnemy.Key, 0); } if (calmTheme.specialRadiantEnemies[specialEnemy.Key] > specialEnemy.Value) { calmTheme.specialRadiantEnemies[specialEnemy.Key] = specialEnemy.Value; } } return this; } } [JsonObject(/*Could not decode attribute arguments.*/)] public class JukeboxPreferences { [JsonObject(/*Could not decode attribute arguments.*/)] public class PlayStartingFrom { [JsonProperty("path")] public string Path { get; private set; } [JsonProperty("type")] public IdentifierType Type { get; private set; } [JsonProperty("clip")] public int Clip { get; private set; } [JsonProperty("startFrom")] public float StartFrom { get; private set; } [JsonConstructor] protected PlayStartingFrom() { } public PlayStartingFrom(SongIdentifier id, int clipIndex, float startFrom) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) Path = id.path; Type = id.type; Clip = clipIndex; StartFrom = startFrom; } } [JsonProperty(/*Could not decode attribute arguments.*/)] public Dictionary<string, float> boostSettings = new Dictionary<string, float>(); [JsonProperty("playStaringFrom")] public PlayStartingFrom playTrackStaringFrom; } } namespace JukeboxCore.Models.Downloader { public enum TrackDownloadingState { None, Enqueued, PreProcessing, Downloading, PostProcessing, Success, Failed } public class DownloadableSongMetadata { public string Id { get; private set; } public string Url { get; private set; } public string ThumbnailUrl { get; private set; } public string Title { get; private set; } public string Artist { get; private set; } [CanBeNull] public string Playlist { get; private set; } public DownloadableSongMetadata(string id, string url, string thumbnailUrl, string title, string artist, string playlist) { Id = id; Url = url; ThumbnailUrl = thumbnailUrl; Title = title; Artist = artist; Playlist = playlist; } } public class DownloadableEntityState { [CanBeNull] public Sprite thumbnail; public TrackDownloadingState? state; public float? progress; [CanBeNull] public string eta; } } namespace JukeboxCore.Exceptions { public class CookiesRequiredException : JukeboxException { public override string Message => "Cookies required"; } public class ImageDownloadFailedException : JukeboxException { private readonly string url; private readonly string reason; public override string Message => "An error has occured while downloading image " + url + ": " + reason; public ImageDownloadFailedException(string url, string reason) { this.url = url; this.reason = reason; } } public class InvalidCookiesFileException : JukeboxException { public override string Message => "Invalid cookies.txt file"; } public class InvalidVideoUrlException : JukeboxException { public override string Message => "Invalid URL or track is not available"; } public abstract class JukeboxException : ArgumentException { } public class PlaylistIsUnviewableException : JukeboxException { public override string Message => "This type of playlist cannot be downloaded"; } } namespace JukeboxCore.Events { public class ClipChangedArgs { public JukeboxSong Song { get; private set; } public bool NewSong { get; private set; } public ClipChangedArgs(JukeboxSong song, bool newSong) { Song = song; NewSong = newSong; } } public abstract class JukeboxEvent<T> : EventArgs { public T newState; public abstract void Mutate(T state); } public class EventStore<T> { private readonly Dictionary<string, Action<JukeboxEvent<T>>> listeners = new Dictionary<string, Action<JukeboxEvent<T>>>(); public void Subscribe(string id, Action<JukeboxEvent<T>> listener) { if (!listeners.ContainsKey(id)) { listeners[id] = delegate { }; } Dictionary<string, Action<JukeboxEvent<T>>> dictionary = listeners; dictionary[id] = (Action<JukeboxEvent<T>>)Delegate.Combine(dictionary[id], listener); } public void Unsubscribe(string id, Action<JukeboxEvent<T>> listener) { if (listeners.ContainsKey(id)) { Dictionary<string, Action<JukeboxEvent<T>>> dictionary = listeners; dictionary[id] = (Action<JukeboxEvent<T>>)Delegate.Remove(dictionary[id], listener); } } public void Invoke(string id, JukeboxEvent<T> arg) { if (listeners.TryGetValue(id, out var value)) { value?.Invoke(arg); } } public void Clear() { listeners.Clear(); } } public abstract class EventManager<T> { private readonly EventStore<T> events = new EventStore<T>(); private readonly Dictionary<string, T> states = new Dictionary<string, T>(); public void Register(string id) { if (!states.ContainsKey(id)) { states.Add(id, DefaultState(id)); } } public T StateOf(string id) { if (!states.TryGetValue(id, out var value)) { return default(T); } return value; } public void Subscribe(string id, Action<JukeboxEvent<T>> action) { events.Subscribe(id, action); } public void Unsubscribe(string id, Action<JukeboxEvent<T>> action) { events.Unsubscribe(id, action); } public void Invoke(string id, JukeboxEvent<T> e) { if (states.TryGetValue(id, out var value)) { e.Mutate(value); } events.Invoke(id, e); } public void Map(Action<KeyValuePair<string, T>> action) { foreach (KeyValuePair<string, T> state in states) { action(state); } } public void Clear() { states.Clear(); events.Clear(); } protected abstract T DefaultState(string id); } } namespace JukeboxCore.Components { [ConfigureSingleton(/*Could not decode attribute arguments.*/)] public class JukeboxStaticData : MonoSingleton<JukeboxStaticData> { [SerializeField] public SoundtrackCalmThemes calmThemes; } [ConfigureSingleton(/*Could not decode attribute arguments.*/)] public class JukeboxSongsLoader : MonoSingleton<JukeboxSongsLoader> { private readonly Dictionary<SongIdentifier, JukeboxSong> cache = new Dictionary<SongIdentifier, JukeboxSong>(); public JukeboxSong Load(SongIdentifier id) { if (cache.TryGetValue(id, out var value)) { return value; } cache.Add(id, JukeboxSongFactory.Create(id)); return cache[id]; } } public class RingPlaceholder : MonoBehaviour { private UnscaledTimeSince sinceEnabled; private void Awake() { Random.Range(0, 1); } private void OnEnable() { sinceEnabled = 0f; } private void Update() { //IL_0021: Unknown result type (might be due to invalid IL or missing references) ((Component)this).transform.localRotation = Quaternion.Euler(0f, 0f, (float)sinceEnabled * -360f); } } } namespace JukeboxCore.Collections { public class JukeboxFileTree : IDirectoryTree<JukeboxSong>, IDirectoryTree { public string name { get; private set; } public IDirectoryTree<JukeboxSong> parent { get; set; } public IEnumerable<IDirectoryTree<JukeboxSong>> children { get; private set; } public IEnumerable<JukeboxSong> files { get; private set; } private DirectoryInfo RealDirectory { get; } public JukeboxFileTree(string path, IDirectoryTree<JukeboxSong> parent = null) { RealDirectory = new DirectoryInfo(path); this.parent = parent; Refresh(); } private JukeboxFileTree(DirectoryInfo realDirectory, IDirectoryTree<JukeboxSong> parent = null) { RealDirectory = realDirectory; this.parent = parent; Refresh(); } public void Refresh() { RealDirectory.Create(); name = RealDirectory.Name; DirectoryInfo[] youTubeFolderOnTop = GetYouTubeFolderOnTop(RealDirectory.GetDirectories()); children = youTubeFolderOnTop.Select((DirectoryInfo dir) => new JukeboxFileTree(dir, this)); files = (from file in RealDirectory.GetFiles().Where(CompositeSongsUtils.HasValidExtenstion) group file by CompositeSongsUtils.WithoutPostfix(file).FullName into @group select MonoSingleton<JukeboxSongsLoader>.Instance.Load(new SongIdentifier(@group.Key, (IdentifierType)1))).ToList(); } public override bool Equals(object obj) { if (obj != null && !(GetType() != obj.GetType())) { return string.Equals(RealDirectory.FullName, (obj as DirectoryInfo)?.FullName, StringComparison.InvariantCultureIgnoreCase); } return false; } public override int GetHashCode() { return RealDirectory.GetHashCode(); } public IEnumerable<JukeboxSong> GetFilesRecursive() { return children.SelectMany((IDirectoryTree<JukeboxSong> child) => child.GetFilesRecursive()).Concat(files); } private DirectoryInfo[] GetYouTubeFolderOnTop(DirectoryInfo[] directories) { if (parent == null && directories.Length > 1) { DirectoryInfo ytFolder = directories.FirstOrDefault((DirectoryInfo folder) => folder.Name.Equals("YouTube")); if (ytFolder != null) { return directories.Where((DirectoryInfo e) => !e.Equals(ytFolder)).Prepend(ytFolder).ToArray(); } } return directories; } } } namespace JukeboxCore.Assets { [AttributeUsage(AttributeTargets.Field)] public class AddressableAsset : Attribute { public string Path { get; } public Type AssetType { get; } public AddressableAsset(string path, Type type) { Path = path; AssetType = type; } } [ConfigureSingleton(/*Could not decode attribute arguments.*/)] public class AssetsManager : MonoSingleton<AssetsManager> { private const BindingFlags Flags = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; private readonly List<AssetBundle> bundles = new List<AssetBundle>(); public void LoadAssets(byte[] raw) { bundles.Add(AssetBundle.LoadFromMemory(raw)); } public void RegisterPrefabs(Assembly assembly) { Type[] types = assembly.GetTypes(); foreach (Type type in types) { CheckType(type); } } private void CheckType(IReflect type) { type.GetFields(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).ToList().ForEach(ProcessField); } private void ProcessField(FieldInfo field) { //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) if (field.FieldType.IsArray || !typeof(Object).IsAssignableFrom(field.FieldType) || !field.IsStatic) { return; } ExternalAsset customAttribute = field.GetCustomAttribute<ExternalAsset>(); AddressableAsset addressableAsset = field.GetCustomAttribute<AddressableAsset>(); if (customAttribute != null) { field.SetValue(null, LoadAsset(customAttribute.Path, customAttribute.Type)); } if (addressableAsset != null) { AsyncOperationHandle<GameObject> val = Addressables.LoadAssetAsync<GameObject>((object)addressableAsset.Path); val.Completed += delegate(AsyncOperationHandle<GameObject> value) { field.SetValue(null, Convert.ChangeType(value.Result, addressableAsset.AssetType)); }; } } private Object LoadAsset(string path, Type type) { return bundles.Select((AssetBundle bundle) => bundle.LoadAsset(path, type)).FirstOrDefault(); } } [AttributeUsage(AttributeTargets.Field)] public class ExternalAsset : Attribute { public string Path { get; } public Type Type { get; } public ExternalAsset(string path, Type type) { Path = path; Type = type; } } }
plugins/Jukebox/TagLibSharp.dll
Decompiled 5 days ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.Globalization; using System.IO; using System.IO.Compression; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Runtime.Versioning; using System.Text; using System.Xml; using Microsoft.CodeAnalysis; using TagLib.Aac; using TagLib.Aiff; using TagLib.Ape; using TagLib.Asf; using TagLib.Audible; using TagLib.Dsf; using TagLib.Flac; using TagLib.Gif; using TagLib.IFD; using TagLib.IFD.Entries; using TagLib.IFD.Makernotes; using TagLib.IFD.Tags; using TagLib.IIM; using TagLib.Id3v1; using TagLib.Id3v2; using TagLib.Image; using TagLib.Image.NoMetadata; using TagLib.Jpeg; using TagLib.Matroska; using TagLib.Mpeg; using TagLib.Mpeg4; using TagLib.MusePack; using TagLib.NonContainer; using TagLib.Ogg; using TagLib.Ogg.Codecs; using TagLib.Png; using TagLib.Riff; using TagLib.Tiff; using TagLib.Tiff.Arw; using TagLib.Tiff.Cr2; using TagLib.Tiff.Dng; using TagLib.Tiff.Nef; using TagLib.Tiff.Pef; using TagLib.Tiff.Rw2; using TagLib.WavPack; using TagLib.Xmp; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")] [assembly: AssemblyCompany("Brian Nickel, Gabriel Burt, Stephen Shaw, etc")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyCopyright("Copyright (c) 2006-2007 Brian Nickel. Copyright (c) 2009-2020 Other contributors")] [assembly: AssemblyDescription("A library for for reading and writing metadata in media files, including video, audio, and photo formats.")] [assembly: AssemblyFileVersion("2.3.0.0")] [assembly: AssemblyInformationalVersion("2.3.0.0")] [assembly: AssemblyProduct("TagLib#")] [assembly: AssemblyTitle("TagLibSharp")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/mono/taglib-sharp")] [assembly: AssemblyVersion("2.3.0.0")] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class IsReadOnlyAttribute : Attribute { } } namespace TagLib { public enum StringType { Latin1, UTF16, UTF16BE, UTF8, UTF16LE } public class ByteVector : IList<byte>, ICollection<byte>, IEnumerable<byte>, IEnumerable, IComparable<ByteVector> { private static readonly uint[] crc_table = new uint[256] { 0u, 79764919u, 159529838u, 222504665u, 319059676u, 398814059u, 445009330u, 507990021u, 638119352u, 583659535u, 797628118u, 726387553u, 890018660u, 835552979u, 1015980042u, 944750013u, 1276238704u, 1221641927u, 1167319070u, 1095957929u, 1595256236u, 1540665371u, 1452775106u, 1381403509u, 1780037320u, 1859660671u, 1671105958u, 1733955601u, 2031960084u, 2111593891u, 1889500026u, 1952343757u, 2552477408u, 2632100695u, 2443283854u, 2506133561u, 2334638140u, 2414271883u, 2191915858u, 2254759653u, 3190512472u, 3135915759u, 3081330742u, 3009969537u, 2905550212u, 2850959411u, 2762807018u, 2691435357u, 3560074640u, 3505614887u, 3719321342u, 3648080713u, 3342211916u, 3287746299u, 3467911202u, 3396681109u, 4063920168u, 4143685023u, 4223187782u, 4286162673u, 3779000052u, 3858754371u, 3904687514u, 3967668269u, 881225847u, 809987520u, 1023691545u, 969234094u, 662832811u, 591600412u, 771767749u, 717299826u, 311336399u, 374308984u, 453813921u, 533576470u, 25881363u, 88864420u, 134795389u, 214552010u, 2023205639u, 2086057648u, 1897238633u, 1976864222u, 1804852699u, 1867694188u, 1645340341u, 1724971778u, 1587496639u, 1516133128u, 1461550545u, 1406951526u, 1302016099u, 1230646740u, 1142491917u, 1087903418u, 2896545431u, 2825181984u, 2770861561u, 2716262478u, 3215044683u, 3143675388u, 3055782693u, 3001194130u, 2326604591u, 2389456536u, 2200899649u, 2280525302u, 2578013683u, 2640855108u, 2418763421u, 2498394922u, 3769900519u, 3832873040u, 3912640137u, 3992402750u, 4088425275u, 4151408268u, 4197601365u, 4277358050u, 3334271071u, 3263032808u, 3476998961u, 3422541446u, 3585640067u, 3514407732u, 3694837229u, 3640369242u, 1762451694u, 1842216281u, 1619975040u, 1682949687u, 2047383090u, 2127137669u, 1938468188u, 2001449195u, 1325665622u, 1271206113u, 1183200824u, 1111960463u, 1543535498u, 1489069629u, 1434599652u, 1363369299u, 622672798u, 568075817u, 748617968u, 677256519u, 907627842u, 853037301u, 1067152940u, 995781531u, 51762726u, 131386257u, 177728840u, 240578815u, 269590778u, 349224269u, 429104020u, 491947555u, 4046411278u, 4126034873u, 4172115296u, 4234965207u, 3794477266u, 3874110821u, 3953728444u, 4016571915u, 3609705398u, 3555108353u, 3735388376u, 3664026991u, 3290680682u, 3236090077u, 3449943556u, 3378572211u, 3174993278u, 3120533705u, 3032266256u, 2961025959u, 2923101090u, 2868635157u, 2813903052u, 2742672763u, 2604032198u, 2683796849u, 2461293480u, 2524268063u, 2284983834u, 2364738477u, 2175806836u, 2238787779u, 1569362073u, 1498123566u, 1409854455u, 1355396672u, 1317987909u, 1246755826u, 1192025387u, 1137557660u, 2072149281u, 2135122070u, 1912620623u, 1992383480u, 1753615357u, 1816598090u, 1627664531u, 1707420964u, 295390185u, 358241886u, 404320391u, 483945776u, 43990325u, 106832002u, 186451547u, 266083308u, 932423249u, 861060070u, 1041341759u, 986742920u, 613929101u, 542559546u, 756411363u, 701822548u, 3316196985u, 3244833742u, 3425377559u, 3370778784u, 3601682597u, 3530312978u, 3744426955u, 3689838204u, 3819031489u, 3881883254u, 3928223919u, 4007849240u, 4037393693u, 4100235434u, 4180117107u, 4259748804u, 2310601993u, 2373574846u, 2151335527u, 2231098320u, 2596047829u, 2659030626u, 2470359227u, 2550115596u, 2947551409u, 2876312838u, 2788305887u, 2733848168u, 3165939309u, 3094707162u, 3040238851u, 2985771188u }; private static bool use_broken_latin1; private static readonly ReadOnlyByteVector td1 = new ReadOnlyByteVector(1); private static readonly ReadOnlyByteVector td2 = new ReadOnlyByteVector(2); private static Encoding last_utf16_encoding = Encoding.Unicode; private readonly List<byte> data = new List<byte>(); public byte[] Data => data.ToArray(); public bool IsEmpty => data.Count == 0; public uint Checksum { get { uint num = 0u; foreach (byte datum in data) { num = (num << 8) ^ crc_table[((num >> 24) & 0xFF) ^ datum]; } return num; } } public static bool UseBrokenLatin1Behavior { get { return use_broken_latin1; } set { use_broken_latin1 = value; } } public int Count => data.Count; public bool IsSynchronized => false; public object SyncRoot => this; public virtual bool IsReadOnly => false; public virtual bool IsFixedSize => false; public byte this[int index] { get { return data[index]; } set { if (IsReadOnly) { throw new NotSupportedException("Cannot edit readonly objects."); } data[index] = value; } } public ByteVector() { } public ByteVector(ByteVector vector) { if (vector != null) { data.AddRange(vector); } } public ByteVector(params byte[] data) { if (data != null) { this.data.AddRange(data); } } public ByteVector(byte[] data, int length) { if (length > data.Length) { throw new ArgumentOutOfRangeException("length", "Length exceeds size of data."); } if (length < 0) { throw new ArgumentOutOfRangeException("length", "Length is less than zero."); } if (length == data.Length) { this.data.AddRange(data); return; } byte[] array = new byte[length]; Array.Copy(data, 0, array, 0, length); this.data.AddRange(array); } public ByteVector(int size) : this(size, 0) { } public ByteVector(int size, byte value) { if (size < 0) { throw new ArgumentOutOfRangeException("size", "Size is less than zero."); } if (size != 0) { byte[] array = new byte[size]; for (int i = 0; i < size; i++) { array[i] = value; } data.AddRange(array); } } public ByteVector Mid(int startIndex, int length) { if (startIndex < 0 || startIndex > Count) { throw new ArgumentOutOfRangeException("startIndex"); } if (length < 0 || startIndex + length > Count) { throw new ArgumentOutOfRangeException("length"); } if (length == 0) { return new ByteVector(); } if (startIndex + length > data.Count) { length = data.Count - startIndex; } byte[] array = new byte[length]; data.CopyTo(startIndex, array, 0, length); return array; } public ByteVector Mid(int index) { return Mid(index, Count - index); } public int Find(ByteVector pattern, int offset, int byteAlign) { if (pattern == null) { throw new ArgumentNullException("pattern"); } if (offset < 0) { throw new ArgumentOutOfRangeException("offset", "offset must be at least 0."); } if (byteAlign < 1) { throw new ArgumentOutOfRangeException("byteAlign", "byteAlign must be at least 1."); } if (pattern.Count > Count - offset) { return -1; } if (pattern.Count == 1) { byte b = pattern[0]; for (int i = offset; i < data.Count; i += byteAlign) { if (data[i] == b) { return i; } } return -1; } int[] array = new int[256]; for (int j = 0; j < 256; j++) { array[j] = pattern.Count; } for (int k = 0; k < pattern.Count - 1; k++) { array[pattern[k]] = pattern.Count - k - 1; } for (int l = pattern.Count - 1 + offset; l < data.Count; l += array[data[l]]) { int num = l; int num2 = pattern.Count - 1; while (num2 >= 0 && data[num] == pattern[num2]) { num--; num2--; } if (-1 == num2 && (num + 1 - offset) % byteAlign == 0) { return num + 1; } } return -1; } public int Find(ByteVector pattern, int offset) { return Find(pattern, offset, 1); } public int Find(ByteVector pattern) { return Find(pattern, 0, 1); } public int RFind(ByteVector pattern, int offset, int byteAlign) { if (pattern == null) { throw new ArgumentNullException("pattern"); } if (offset < 0) { throw new ArgumentOutOfRangeException("offset"); } if (pattern.Count == 0 || pattern.Count > Count - offset) { return -1; } if (pattern.Count == 1) { byte b = pattern[0]; for (int num = Count - offset - 1; num >= 0; num -= byteAlign) { if (data[num] == b) { return num; } } return -1; } int[] array = new int[256]; for (int i = 0; i < 256; i++) { array[i] = pattern.Count; } for (int num2 = pattern.Count - 1; num2 > 0; num2--) { array[pattern[num2]] = num2; } for (int num3 = Count - offset - pattern.Count; num3 >= 0; num3 -= array[data[num3]]) { if ((offset - num3) % byteAlign == 0 && ContainsAt(pattern, num3)) { return num3; } } return -1; } public int RFind(ByteVector pattern, int offset) { return RFind(pattern, offset, 1); } public int RFind(ByteVector pattern) { return RFind(pattern, 0, 1); } public bool ContainsAt(ByteVector pattern, int offset, int patternOffset, int patternLength) { if (pattern == null) { throw new ArgumentNullException("pattern"); } if (pattern.Count < patternLength) { patternLength = pattern.Count; } if (patternLength > data.Count || offset >= data.Count || patternOffset >= pattern.Count || patternLength <= 0 || offset < 0) { return false; } for (int i = 0; i < patternLength - patternOffset; i++) { if (data[i + offset] != pattern[i + patternOffset]) { return false; } } return true; } public bool ContainsAt(ByteVector pattern, int offset, int patternOffset) { return ContainsAt(pattern, offset, patternOffset, int.MaxValue); } public bool ContainsAt(ByteVector pattern, int offset) { return ContainsAt(pattern, offset, 0); } public bool StartsWith(ByteVector pattern) { return ContainsAt(pattern, 0); } public bool EndsWith(ByteVector pattern) { if (pattern == null) { throw new ArgumentNullException("pattern"); } return ContainsAt(pattern, data.Count - pattern.Count); } public int EndsWithPartialMatch(ByteVector pattern) { if (pattern == null) { throw new ArgumentNullException("pattern"); } if (pattern.Count > data.Count) { return -1; } int num = data.Count - pattern.Count; for (int i = 1; i < pattern.Count; i++) { if (ContainsAt(pattern, num + i, 0, pattern.Count - i)) { return num + i; } } return -1; } public void Add(ByteVector data) { if (IsReadOnly) { throw new NotSupportedException("Cannot edit readonly objects."); } if (data != null) { this.data.AddRange(data); } } public void Add(byte[] data) { if (IsReadOnly) { throw new NotSupportedException("Cannot edit readonly objects."); } if (data != null) { this.data.AddRange(data); } } public void Insert(int index, ByteVector data) { if (IsReadOnly) { throw new NotSupportedException("Cannot edit readonly objects."); } if (data != null) { this.data.InsertRange(index, data); } } public void Insert(int index, byte[] data) { if (IsReadOnly) { throw new NotSupportedException("Cannot edit readonly objects."); } if (data != null) { this.data.InsertRange(index, data); } } public ByteVector Resize(int size, byte padding) { if (IsReadOnly) { throw new NotSupportedException("Cannot edit readonly objects."); } if (data.Count > size) { data.RemoveRange(size, data.Count - size); } while (data.Count < size) { data.Add(padding); } return this; } public ByteVector Resize(int size) { return Resize(size, 0); } public void RemoveRange(int index, int count) { if (IsReadOnly) { throw new NotSupportedException("Cannot edit readonly objects."); } data.RemoveRange(index, count); } public int ToInt(bool mostSignificantByteFirst) { int num = 0; int num2 = ((Count > 4) ? 3 : (Count - 1)); for (int i = 0; i <= num2; i++) { int num3 = (mostSignificantByteFirst ? (num2 - i) : i); num |= this[i] << num3 * 8; } return num; } public int ToInt() { return ToInt(mostSignificantByteFirst: true); } public uint ToUInt(bool mostSignificantByteFirst) { uint num = 0u; int num2 = ((Count > 4) ? 3 : (Count - 1)); for (int i = 0; i <= num2; i++) { int num3 = (mostSignificantByteFirst ? (num2 - i) : i); num |= (uint)(this[i] << num3 * 8); } return num; } public uint ToUInt() { return ToUInt(mostSignificantByteFirst: true); } public short ToShort(bool mostSignificantByteFirst) { short num = 0; int num2 = ((Count > 2) ? 1 : (Count - 1)); for (int i = 0; i <= num2; i++) { int num3 = (mostSignificantByteFirst ? (num2 - i) : i); num |= (short)(this[i] << num3 * 8); } return num; } public short ToShort() { return ToShort(mostSignificantByteFirst: true); } public ushort ToUShort(bool mostSignificantByteFirst) { ushort num = 0; int num2 = ((Count > 2) ? 1 : (Count - 1)); for (int i = 0; i <= num2; i++) { int num3 = (mostSignificantByteFirst ? (num2 - i) : i); num |= (ushort)(this[i] << num3 * 8); } return num; } public ushort ToUShort() { return ToUShort(mostSignificantByteFirst: true); } public long ToLong(bool mostSignificantByteFirst) { long num = 0L; int num2 = ((Count > 8) ? 7 : (Count - 1)); for (int i = 0; i <= num2; i++) { int num3 = (mostSignificantByteFirst ? (num2 - i) : i); num |= (long)((ulong)this[i] << num3 * 8); } return num; } public long ToLong() { return ToLong(mostSignificantByteFirst: true); } public ulong ToULong(bool mostSignificantByteFirst) { ulong num = 0uL; int num2 = ((Count > 8) ? 7 : (Count - 1)); for (int i = 0; i <= num2; i++) { int num3 = (mostSignificantByteFirst ? (num2 - i) : i); num |= (ulong)this[i] << num3 * 8; } return num; } public ulong ToULong() { return ToULong(mostSignificantByteFirst: true); } public float ToFloat(bool mostSignificantByteFirst) { byte[] array = (byte[])Data.Clone(); if (mostSignificantByteFirst) { Array.Reverse((Array)array); } return BitConverter.ToSingle(array, 0); } public float ToFloat() { return ToFloat(mostSignificantByteFirst: true); } public double ToDouble(bool mostSignificantByteFirst) { byte[] array = (byte[])Data.Clone(); if (mostSignificantByteFirst) { Array.Reverse((Array)array); } return BitConverter.ToDouble(array, 0); } public double ToDouble() { return ToDouble(mostSignificantByteFirst: true); } public double ToExtendedPrecision() { int num = ((this[0] & 0x7F) << 8) | this[1]; ulong num2 = ((ulong)this[2] << 24) | ((ulong)this[3] << 16) | ((ulong)this[4] << 8) | this[5]; ulong num3 = ((ulong)this[6] << 24) | ((ulong)this[7] << 16) | ((ulong)this[8] << 8) | this[9]; double num4; if (num == 0 && num2 == 0L && num3 == 0L) { num4 = 0.0; } else if (num == 32767) { num4 = double.PositiveInfinity; } else { num -= 16383; num4 = (double)num2 * Math.Pow(2.0, num -= 31); num4 += (double)num3 * Math.Pow(2.0, num -= 32); } if ((this[0] & 0x80) == 0) { return num4; } return 0.0 - num4; } public string ToString(StringType type, int offset, int count) { if (offset < 0 || offset > Count) { throw new ArgumentOutOfRangeException("offset"); } if (count < 0 || count + offset > Count) { throw new ArgumentOutOfRangeException("count"); } ByteVector bom = ((type == StringType.UTF16 && data.Count - offset > 1) ? Mid(offset, 2) : null); string @string = StringTypeToEncoding(type, bom).GetString(Data, offset, count); if (@string.Length != 0 && (@string[0] == '\ufffe' || @string[0] == '\ufeff')) { return @string.Substring(1); } return @string; } [Obsolete("Use ToString(StringType,int,int)")] public string ToString(StringType type, int offset) { return ToString(type, offset, Count - offset); } public string ToString(StringType type) { return ToString(type, 0, Count); } public override string ToString() { return ToString(StringType.UTF8, 0, Count); } public string[] ToStrings(StringType type, int offset) { return ToStrings(type, offset, int.MaxValue); } public string[] ToStrings(StringType type, int offset, int count) { int num = 0; int num2 = offset; List<string> list = new List<string>(); ByteVector byteVector = TextDelimiter(type); int count2 = byteVector.Count; while (num < count && num2 < Count) { int num3 = num2; if (num + 1 == count) { num2 = offset + count; } else { num2 = Find(byteVector, num3, count2); if (num2 < 0) { num2 = Count; } } int num4 = num2 - num3; if (num4 == 0) { list.Add(string.Empty); } else { string text = ToString(type, num3, num4); if (text.Length != 0 && (text[0] == '\ufffe' || text[0] == '\ufeff')) { text = text.Substring(1); } list.Add(text); } num2 += count2; } return list.ToArray(); } public static bool operator ==(ByteVector first, ByteVector second) { bool flag = (object)first == null; bool flag2 = (object)second == null; if (flag && flag2) { return true; } if (flag || flag2) { return false; } return first.Equals(second); } public static bool operator !=(ByteVector first, ByteVector second) { return !(first == second); } public static bool operator <(ByteVector first, ByteVector second) { if (first == null) { throw new ArgumentNullException("first"); } if (second == null) { throw new ArgumentNullException("second"); } return first.CompareTo(second) < 0; } public static bool operator <=(ByteVector first, ByteVector second) { if (first == null) { throw new ArgumentNullException("first"); } if (second == null) { throw new ArgumentNullException("second"); } return first.CompareTo(second) <= 0; } public static bool operator >(ByteVector first, ByteVector second) { if (first == null) { throw new ArgumentNullException("first"); } if (second == null) { throw new ArgumentNullException("second"); } return first.CompareTo(second) > 0; } public static bool operator >=(ByteVector first, ByteVector second) { if (first == null) { throw new ArgumentNullException("first"); } if (second == null) { throw new ArgumentNullException("second"); } return first.CompareTo(second) >= 0; } public static ByteVector operator +(ByteVector first, ByteVector second) { return new ByteVector(first) { second }; } public static implicit operator ByteVector(byte value) { return new ByteVector(value); } public static implicit operator ByteVector(byte[] value) { return new ByteVector(value); } public static implicit operator ByteVector(string value) { return FromString(value, StringType.UTF8); } public static ByteVector FromInt(int value, bool mostSignificantByteFirst) { ByteVector byteVector = new ByteVector(); for (int i = 0; i < 4; i++) { int num = (mostSignificantByteFirst ? (3 - i) : i); byteVector.Add((byte)((uint)(value >> num * 8) & 0xFFu)); } return byteVector; } public static ByteVector FromInt(int value) { return FromInt(value, mostSignificantByteFirst: true); } public static ByteVector FromUInt(uint value, bool mostSignificantByteFirst) { ByteVector byteVector = new ByteVector(); for (int i = 0; i < 4; i++) { int num = (mostSignificantByteFirst ? (3 - i) : i); byteVector.Add((byte)((value >> num * 8) & 0xFFu)); } return byteVector; } public static ByteVector FromUInt(uint value) { return FromUInt(value, mostSignificantByteFirst: true); } public static ByteVector FromShort(short value, bool mostSignificantByteFirst) { ByteVector byteVector = new ByteVector(); for (int i = 0; i < 2; i++) { int num = (mostSignificantByteFirst ? (1 - i) : i); byteVector.Add((byte)((uint)(value >> num * 8) & 0xFFu)); } return byteVector; } public static ByteVector FromShort(short value) { return FromShort(value, mostSignificantByteFirst: true); } public static ByteVector FromUShort(ushort value, bool mostSignificantByteFirst) { ByteVector byteVector = new ByteVector(); for (int i = 0; i < 2; i++) { int num = (mostSignificantByteFirst ? (1 - i) : i); byteVector.Add((byte)((uint)(value >> num * 8) & 0xFFu)); } return byteVector; } public static ByteVector FromUShort(ushort value) { return FromUShort(value, mostSignificantByteFirst: true); } public static ByteVector FromLong(long value, bool mostSignificantByteFirst) { ByteVector byteVector = new ByteVector(); for (int i = 0; i < 8; i++) { int num = (mostSignificantByteFirst ? (7 - i) : i); byteVector.Add((byte)((value >> num * 8) & 0xFF)); } return byteVector; } public static ByteVector FromLong(long value) { return FromLong(value, mostSignificantByteFirst: true); } public static ByteVector FromULong(ulong value, bool mostSignificantByteFirst) { ByteVector byteVector = new ByteVector(); for (int i = 0; i < 8; i++) { int num = (mostSignificantByteFirst ? (7 - i) : i); byteVector.Add((byte)((value >> num * 8) & 0xFF)); } return byteVector; } public static ByteVector FromULong(ulong value) { return FromULong(value, mostSignificantByteFirst: true); } public static ByteVector FromString(string text, StringType type, int length) { ByteVector byteVector = new ByteVector(); if (type == StringType.UTF16) { byteVector.Add(new byte[2] { 255, 254 }); } if (text == null || text.Length == 0) { return byteVector; } if (text.Length > length) { text = text.Substring(0, length); } byteVector.Add(StringTypeToEncoding(type, byteVector).GetBytes(text)); return byteVector; } public static ByteVector FromString(string text, StringType type) { return FromString(text, type, int.MaxValue); } public static ByteVector FromString(string text, int length) { return FromString(text, StringType.UTF8, length); } [Obsolete("Use FromString(string,StringType)")] public static ByteVector FromString(string text) { return FromString(text, StringType.UTF8); } public static ByteVector FromPath(string path) { byte[] firstChunk; return FromPath(path, out firstChunk, copyFirstChunk: false); } internal static ByteVector FromPath(string path, out byte[] firstChunk, bool copyFirstChunk) { if (path == null) { throw new ArgumentNullException("path"); } return FromFile(new File.LocalFileAbstraction(path), out firstChunk, copyFirstChunk); } public static ByteVector FromFile(File.IFileAbstraction abstraction) { byte[] firstChunk; return FromFile(abstraction, out firstChunk, copyFirstChunk: false); } internal static ByteVector FromFile(File.IFileAbstraction abstraction, out byte[] firstChunk, bool copyFirstChunk) { if (abstraction == null) { throw new ArgumentNullException("abstraction"); } Stream readStream = abstraction.ReadStream; ByteVector result = FromStream(readStream, out firstChunk, copyFirstChunk); abstraction.CloseStream(readStream); return result; } public static ByteVector FromStream(Stream stream) { byte[] firstChunk; return FromStream(stream, out firstChunk, copyFirstChunk: false); } internal static ByteVector FromStream(Stream stream, out byte[] firstChunk, bool copyFirstChunk) { ByteVector byteVector = new ByteVector(); byte[] array = new byte[4096]; int num = array.Length; int num2 = 0; bool flag = false; firstChunk = null; int num3; do { Array.Clear(array, 0, array.Length); num3 = stream.Read(array, 0, num); byteVector.Add(array); num2 += num3; if (flag) { continue; } if (copyFirstChunk) { if (firstChunk == null || firstChunk.Length != num) { firstChunk = new byte[num]; } Array.Copy(array, 0, firstChunk, 0, num3); } flag = true; } while ((num2 != stream.Length || stream.Length <= 0) && (num3 >= num || stream.Length > 0)); if (stream.Length > 0 && byteVector.Count != stream.Length) { byteVector.Resize((int)stream.Length); } return byteVector; } public static ByteVector TextDelimiter(StringType type) { if (type != StringType.UTF16 && type != StringType.UTF16BE && type != StringType.UTF16LE) { return td1; } return td2; } private static Encoding StringTypeToEncoding(StringType type, ByteVector bom) { switch (type) { case StringType.UTF16: if (bom == null) { return last_utf16_encoding; } if (bom[0] == byte.MaxValue && bom[1] == 254) { return last_utf16_encoding = Encoding.Unicode; } if (bom[1] == byte.MaxValue && bom[0] == 254) { return last_utf16_encoding = Encoding.BigEndianUnicode; } return last_utf16_encoding; case StringType.UTF16BE: return Encoding.BigEndianUnicode; case StringType.UTF8: return Encoding.UTF8; case StringType.UTF16LE: return Encoding.Unicode; default: if (use_broken_latin1) { return Encoding.Default; } try { return Encoding.GetEncoding("latin1"); } catch (ArgumentException) { return Encoding.UTF8; } } } public override bool Equals(object other) { if (!(other is ByteVector)) { return false; } return Equals((ByteVector)other); } public bool Equals(ByteVector other) { return CompareTo(other) == 0; } public override int GetHashCode() { return (int)Checksum; } public int CompareTo(ByteVector other) { if ((object)other == null) { throw new ArgumentNullException("other"); } int num = Count - other.Count; int num2 = 0; while (num == 0 && num2 < Count) { num = this[num2] - other[num2]; num2++; } return num; } public IEnumerator<byte> GetEnumerator() { return data.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return data.GetEnumerator(); } public void Clear() { if (IsReadOnly) { throw new NotSupportedException("Cannot edit readonly objects."); } data.Clear(); } public void Add(byte item) { if (IsReadOnly) { throw new NotSupportedException("Cannot edit readonly objects."); } data.Add(item); } public bool Remove(byte item) { if (IsReadOnly) { throw new NotSupportedException("Cannot edit readonly objects."); } return data.Remove(item); } public void CopyTo(byte[] array, int arrayIndex) { data.CopyTo(array, arrayIndex); } public bool Contains(byte item) { return data.Contains(item); } public void RemoveAt(int index) { if (IsReadOnly) { throw new NotSupportedException("Cannot edit readonly objects."); } data.RemoveAt(index); } public void Insert(int index, byte item) { if (IsReadOnly) { throw new NotSupportedException("Cannot edit readonly objects."); } data.Insert(index, item); } public int IndexOf(byte item) { return data.IndexOf(item); } } [ComVisible(false)] public class ByteVectorCollection : ListBase<ByteVector> { public ByteVectorCollection() { } public ByteVectorCollection(IEnumerable<ByteVector> list) { if (list != null) { Add(list); } } public ByteVectorCollection(params ByteVector[] list) { if (list != null) { Add(list); } } public override void SortedInsert(ByteVector item, bool unique) { if (item == null) { throw new ArgumentNullException("item"); } int i; for (i = 0; i < base.Count; i++) { if (item == base[i] && unique) { return; } if (item >= base[i]) { break; } } Insert(i + 1, item); } public ByteVector ToByteVector(ByteVector separator) { if (separator == null) { throw new ArgumentNullException("separator"); } ByteVector byteVector = new ByteVector(); for (int i = 0; i < base.Count; i++) { if (i != 0 && separator.Count > 0) { byteVector.Add(separator); } byteVector.Add(base[i]); } return byteVector; } public static ByteVectorCollection Split(ByteVector vector, ByteVector pattern, int byteAlign, int max) { if (vector == null) { throw new ArgumentNullException("vector"); } if (pattern == null) { throw new ArgumentNullException("pattern"); } if (byteAlign < 1) { throw new ArgumentOutOfRangeException("byteAlign", "byteAlign must be at least 1."); } ByteVectorCollection byteVectorCollection = new ByteVectorCollection(); int num = 0; int num2 = vector.Find(pattern, 0, byteAlign); while (num2 != -1 && (max < 1 || max > byteVectorCollection.Count + 1)) { byteVectorCollection.Add(vector.Mid(num, num2 - num)); num = num2 + pattern.Count; num2 = vector.Find(pattern, num2 + pattern.Count, byteAlign); } if (num < vector.Count) { byteVectorCollection.Add(vector.Mid(num, vector.Count - num)); } return byteVectorCollection; } public static ByteVectorCollection Split(ByteVector vector, ByteVector pattern, int byteAlign) { return Split(vector, pattern, byteAlign, 0); } public static ByteVectorCollection Split(ByteVector vector, ByteVector pattern) { return Split(vector, pattern, 1); } } public class CombinedTag : Tag { private readonly List<Tag> tags; public virtual Tag[] Tags => tags.ToArray(); public override TagTypes TagTypes { get { TagTypes tagTypes = TagTypes.None; foreach (Tag tag in tags) { if (tag != null) { tagTypes |= tag.TagTypes; } } return tagTypes; } } public override string Title { get { foreach (Tag tag in tags) { if (tag != null) { string title = tag.Title; if (title != null) { return title; } } } return null; } set { foreach (Tag tag in tags) { if (tag != null) { tag.Title = value; } } } } public override string Subtitle { get { foreach (Tag tag in tags) { if (tag != null) { string subtitle = tag.Subtitle; if (subtitle != null) { return subtitle; } } } return null; } set { foreach (Tag tag in tags) { if (tag != null) { tag.Subtitle = value; } } } } public override string Description { get { foreach (Tag tag in tags) { if (tag != null) { string description = tag.Description; if (description != null) { return description; } } } return null; } set { foreach (Tag tag in tags) { if (tag != null) { tag.Description = value; } } } } public override string[] Performers { get { foreach (Tag tag in tags) { if (tag != null) { string[] performers = tag.Performers; if (performers != null && performers.Length != 0) { return performers; } } } return new string[0]; } set { foreach (Tag tag in tags) { if (tag != null) { tag.Performers = value; } } } } public override string[] PerformersSort { get { foreach (Tag tag in tags) { if (tag != null) { string[] performersSort = tag.PerformersSort; if (performersSort != null && performersSort.Length != 0) { return performersSort; } } } return new string[0]; } set { foreach (Tag tag in tags) { if (tag != null) { tag.PerformersSort = value; } } } } public override string[] PerformersRole { get { foreach (Tag tag in tags) { if (tag != null) { string[] performersRole = tag.PerformersRole; if (performersRole != null && performersRole.Length != 0) { return performersRole; } } } return new string[0]; } set { foreach (Tag tag in tags) { if (tag != null) { tag.PerformersRole = value; } } } } public override string[] AlbumArtistsSort { get { foreach (Tag tag in tags) { if (tag != null) { string[] albumArtistsSort = tag.AlbumArtistsSort; if (albumArtistsSort != null && albumArtistsSort.Length != 0) { return albumArtistsSort; } } } return new string[0]; } set { foreach (Tag tag in tags) { if (tag != null) { tag.AlbumArtistsSort = value; } } } } public override string[] AlbumArtists { get { foreach (Tag tag in tags) { if (tag != null) { string[] albumArtists = tag.AlbumArtists; if (albumArtists != null && albumArtists.Length != 0) { return albumArtists; } } } return new string[0]; } set { foreach (Tag tag in tags) { if (tag != null) { tag.AlbumArtists = value; } } } } public override string[] Composers { get { foreach (Tag tag in tags) { if (tag != null) { string[] composers = tag.Composers; if (composers != null && composers.Length != 0) { return composers; } } } return new string[0]; } set { foreach (Tag tag in tags) { if (tag != null) { tag.Composers = value; } } } } public override string[] ComposersSort { get { foreach (Tag tag in tags) { if (tag != null) { string[] composersSort = tag.ComposersSort; if (composersSort != null && composersSort.Length != 0) { return composersSort; } } } return new string[0]; } set { foreach (Tag tag in tags) { if (tag != null) { tag.ComposersSort = value; } } } } public override string TitleSort { get { foreach (Tag tag in tags) { if (tag != null) { string titleSort = tag.TitleSort; if (titleSort != null && titleSort.Length > 0) { return titleSort; } } } return null; } set { foreach (Tag tag in tags) { if (tag != null) { tag.TitleSort = value; } } } } public override string AlbumSort { get { foreach (Tag tag in tags) { if (tag != null) { string albumSort = tag.AlbumSort; if (albumSort != null && albumSort.Length > 0) { return albumSort; } } } return null; } set { foreach (Tag tag in tags) { if (tag != null) { tag.AlbumSort = value; } } } } public override string Album { get { foreach (Tag tag in tags) { if (tag != null) { string album = tag.Album; if (album != null) { return album; } } } return null; } set { foreach (Tag tag in tags) { if (tag != null) { tag.Album = value; } } } } public override string Comment { get { foreach (Tag tag in tags) { if (tag != null) { string comment = tag.Comment; if (comment != null) { return comment; } } } return null; } set { foreach (Tag tag in tags) { if (tag != null) { tag.Comment = value; } } } } public override string[] Genres { get { foreach (Tag tag in tags) { if (tag != null) { string[] genres = tag.Genres; if (genres != null && genres.Length != 0) { return genres; } } } return new string[0]; } set { foreach (Tag tag in tags) { if (tag != null) { tag.Genres = value; } } } } public override uint Year { get { foreach (Tag tag in tags) { if (tag != null) { uint year = tag.Year; if (year != 0) { return year; } } } return 0u; } set { foreach (Tag tag in tags) { if (tag != null) { tag.Year = value; } } } } public override uint Track { get { foreach (Tag tag in tags) { if (tag != null) { uint track = tag.Track; if (track != 0) { return track; } } } return 0u; } set { foreach (Tag tag in tags) { if (tag != null) { tag.Track = value; } } } } public override uint TrackCount { get { foreach (Tag tag in tags) { if (tag != null) { uint trackCount = tag.TrackCount; if (trackCount != 0) { return trackCount; } } } return 0u; } set { foreach (Tag tag in tags) { if (tag != null) { tag.TrackCount = value; } } } } public override uint Disc { get { foreach (Tag tag in tags) { if (tag != null) { uint disc = tag.Disc; if (disc != 0) { return disc; } } } return 0u; } set { foreach (Tag tag in tags) { if (tag != null) { tag.Disc = value; } } } } public override uint DiscCount { get { foreach (Tag tag in tags) { if (tag != null) { uint discCount = tag.DiscCount; if (discCount != 0) { return discCount; } } } return 0u; } set { foreach (Tag tag in tags) { if (tag != null) { tag.DiscCount = value; } } } } public override string Lyrics { get { foreach (Tag tag in tags) { if (tag != null) { string lyrics = tag.Lyrics; if (lyrics != null) { return lyrics; } } } return null; } set { foreach (Tag tag in tags) { if (tag != null) { tag.Lyrics = value; } } } } public override string Grouping { get { foreach (Tag tag in tags) { if (tag != null) { string grouping = tag.Grouping; if (grouping != null) { return grouping; } } } return null; } set { foreach (Tag tag in tags) { if (tag != null) { tag.Grouping = value; } } } } public override uint BeatsPerMinute { get { foreach (Tag tag in tags) { if (tag != null) { uint beatsPerMinute = tag.BeatsPerMinute; if (beatsPerMinute != 0) { return beatsPerMinute; } } } return 0u; } set { foreach (Tag tag in tags) { if (tag != null) { tag.BeatsPerMinute = value; } } } } public override string Conductor { get { foreach (Tag tag in tags) { if (tag != null) { string conductor = tag.Conductor; if (conductor != null) { return conductor; } } } return null; } set { foreach (Tag tag in tags) { if (tag != null) { tag.Conductor = value; } } } } public override string Copyright { get { foreach (Tag tag in tags) { if (tag != null) { string copyright = tag.Copyright; if (copyright != null) { return copyright; } } } return null; } set { foreach (Tag tag in tags) { if (tag != null) { tag.Copyright = value; } } } } public override DateTime? DateTagged { get { foreach (Tag tag in tags) { if (tag != null) { DateTime? dateTagged = tag.DateTagged; if (dateTagged.HasValue) { return dateTagged; } } } return null; } set { foreach (Tag tag in tags) { if (tag != null) { tag.DateTagged = value; } } } } public override string MusicBrainzArtistId { get { foreach (Tag tag in tags) { if (tag != null) { string musicBrainzArtistId = tag.MusicBrainzArtistId; if (musicBrainzArtistId != null) { return musicBrainzArtistId; } } } return null; } set { foreach (Tag tag in tags) { if (tag != null) { tag.MusicBrainzArtistId = value; } } } } public override string MusicBrainzReleaseGroupId { get { foreach (Tag tag in tags) { if (tag != null) { string musicBrainzReleaseGroupId = tag.MusicBrainzReleaseGroupId; if (musicBrainzReleaseGroupId != null) { return musicBrainzReleaseGroupId; } } } return null; } set { foreach (Tag tag in tags) { if (tag != null) { tag.MusicBrainzReleaseGroupId = value; } } } } public override string MusicBrainzReleaseId { get { foreach (Tag tag in tags) { if (tag != null) { string musicBrainzReleaseId = tag.MusicBrainzReleaseId; if (musicBrainzReleaseId != null) { return musicBrainzReleaseId; } } } return null; } set { foreach (Tag tag in tags) { if (tag != null) { tag.MusicBrainzReleaseId = value; } } } } public override string MusicBrainzReleaseArtistId { get { foreach (Tag tag in tags) { if (tag != null) { string musicBrainzReleaseArtistId = tag.MusicBrainzReleaseArtistId; if (musicBrainzReleaseArtistId != null) { return musicBrainzReleaseArtistId; } } } return null; } set { foreach (Tag tag in tags) { if (tag != null) { tag.MusicBrainzReleaseArtistId = value; } } } } public override string MusicBrainzTrackId { get { foreach (Tag tag in tags) { if (tag != null) { string musicBrainzTrackId = tag.MusicBrainzTrackId; if (musicBrainzTrackId != null) { return musicBrainzTrackId; } } } return null; } set { foreach (Tag tag in tags) { if (tag != null) { tag.MusicBrainzTrackId = value; } } } } public override string MusicBrainzDiscId { get { foreach (Tag tag in tags) { if (tag != null) { string musicBrainzDiscId = tag.MusicBrainzDiscId; if (musicBrainzDiscId != null) { return musicBrainzDiscId; } } } return null; } set { foreach (Tag tag in tags) { if (tag != null) { tag.MusicBrainzDiscId = value; } } } } public override string MusicIpId { get { foreach (Tag tag in tags) { if (tag != null) { string musicIpId = tag.MusicIpId; if (musicIpId != null) { return musicIpId; } } } return null; } set { foreach (Tag tag in tags) { if (tag != null) { tag.MusicIpId = value; } } } } public override string AmazonId { get { foreach (Tag tag in tags) { if (tag != null) { string amazonId = tag.AmazonId; if (amazonId != null) { return amazonId; } } } return null; } set { foreach (Tag tag in tags) { if (tag != null) { tag.AmazonId = value; } } } } public override string MusicBrainzReleaseStatus { get { foreach (Tag tag in tags) { if (tag != null) { string musicBrainzReleaseStatus = tag.MusicBrainzReleaseStatus; if (musicBrainzReleaseStatus != null) { return musicBrainzReleaseStatus; } } } return null; } set { foreach (Tag tag in tags) { if (tag != null) { tag.MusicBrainzReleaseStatus = value; } } } } public override string MusicBrainzReleaseType { get { foreach (Tag tag in tags) { if (tag != null) { string musicBrainzReleaseType = tag.MusicBrainzReleaseType; if (musicBrainzReleaseType != null) { return musicBrainzReleaseType; } } } return null; } set { foreach (Tag tag in tags) { if (tag != null) { tag.MusicBrainzReleaseType = value; } } } } public override string MusicBrainzReleaseCountry { get { foreach (Tag tag in tags) { if (tag != null) { string musicBrainzReleaseCountry = tag.MusicBrainzReleaseCountry; if (musicBrainzReleaseCountry != null) { return musicBrainzReleaseCountry; } } } return null; } set { foreach (Tag tag in tags) { if (tag != null) { tag.MusicBrainzReleaseCountry = value; } } } } public override IPicture[] Pictures { get { foreach (Tag tag in tags) { if (tag != null) { IPicture[] pictures = tag.Pictures; if (pictures != null && pictures.Length != 0) { return pictures; } } } return base.Pictures; } set { foreach (Tag tag in tags) { if (tag != null) { tag.Pictures = value; } } } } public override double ReplayGainTrackGain { get { foreach (Tag tag in tags) { if (tag != null) { double replayGainTrackGain = tag.ReplayGainTrackGain; if (!double.IsNaN(replayGainTrackGain)) { return replayGainTrackGain; } } } return double.NaN; } set { foreach (Tag tag in tags) { if (tag != null) { tag.ReplayGainTrackGain = value; } } } } public override double ReplayGainTrackPeak { get { foreach (Tag tag in tags) { if (tag != null) { double replayGainTrackPeak = tag.ReplayGainTrackPeak; if (!double.IsNaN(replayGainTrackPeak)) { return replayGainTrackPeak; } } } return double.NaN; } set { foreach (Tag tag in tags) { if (tag != null) { tag.ReplayGainTrackPeak = value; } } } } public override double ReplayGainAlbumGain { get { foreach (Tag tag in tags) { if (tag != null) { double replayGainAlbumGain = tag.ReplayGainAlbumGain; if (!double.IsNaN(replayGainAlbumGain)) { return replayGainAlbumGain; } } } return double.NaN; } set { foreach (Tag tag in tags) { if (tag != null) { tag.ReplayGainAlbumGain = value; } } } } public override double ReplayGainAlbumPeak { get { foreach (Tag tag in tags) { if (tag != null) { double replayGainAlbumPeak = tag.ReplayGainAlbumPeak; if (!double.IsNaN(replayGainAlbumPeak)) { return replayGainAlbumPeak; } } } return double.NaN; } set { foreach (Tag tag in tags) { if (tag != null) { tag.ReplayGainAlbumPeak = value; } } } } public override string InitialKey { get { foreach (Tag tag in tags) { if (tag != null) { string initialKey = tag.InitialKey; if (initialKey != null) { return initialKey; } } } return null; } set { foreach (Tag tag in tags) { if (tag != null) { tag.InitialKey = value; } } } } public override string RemixedBy { get { foreach (Tag tag in tags) { if (tag != null) { string remixedBy = tag.RemixedBy; if (remixedBy != null) { return remixedBy; } } } return null; } set { foreach (Tag tag in tags) { if (tag != null) { tag.RemixedBy = value; } } } } public override string Publisher { get { foreach (Tag tag in tags) { if (tag != null) { string publisher = tag.Publisher; if (publisher != null) { return publisher; } } } return null; } set { foreach (Tag tag in tags) { if (tag != null) { tag.Publisher = value; } } } } public override string ISRC { get { foreach (Tag tag in tags) { if (tag != null) { string iSRC = tag.ISRC; if (iSRC != null) { return iSRC; } } } return null; } set { foreach (Tag tag in tags) { if (tag != null) { tag.ISRC = value; } } } } public override string Length { get { foreach (Tag tag in tags) { if (tag != null) { string length = tag.Length; if (length != null) { return length; } } } return null; } set { foreach (Tag tag in tags) { if (tag != null) { tag.Length = value; } } } } public override bool IsEmpty { get { foreach (Tag tag in tags) { if (tag.IsEmpty) { return true; } } return false; } } public CombinedTag() { tags = new List<Tag>(); } public CombinedTag(params Tag[] tags) { this.tags = new List<Tag>(tags); } public void SetTags(params Tag[] tags) { this.tags.Clear(); this.tags.AddRange(tags); } protected void InsertTag(int index, Tag tag) { tags.Insert(index, tag); } protected void AddTag(Tag tag) { tags.Add(tag); } protected void RemoveTag(Tag tag) { tags.Remove(tag); } protected void ClearTags() { tags.Clear(); } public override void Clear() { foreach (Tag tag in tags) { tag.Clear(); } } } [Serializable] public class CorruptFileException : Exception { public CorruptFileException(string message) : base(message) { } public CorruptFileException() { } public CorruptFileException(string message, Exception innerException) : base(message, innerException) { } protected CorruptFileException(SerializationInfo info, StreamingContext context) : base(info, context) { } } internal static class Debugger { public delegate void DebugMessageSentHandler(string message); private struct DebugTimeData { public TimeSpan time; public long occurances; public DebugTimeData(TimeSpan time, int occurances) { this.time = time; this.occurances = occurances; } } private static readonly string allowed = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ`~!@#$%^&*()_+-={}[];:'\",.<>?/\\|"; private static readonly Dictionary<object, Dictionary<object, DebugTimeData>> debug_times = new Dictionary<object, Dictionary<object, DebugTimeData>>(); public static event DebugMessageSentHandler DebugMessageSent; public static void Debug(string message) { Debugger.DebugMessageSent?.Invoke(message); } public static void DumpHex(ByteVector data) { DumpHex(data.Data); } public static void DumpHex(byte[] data) { int num = 16; int num2 = data.Length / num + ((data.Length % num != 0) ? 1 : 0); for (int i = 0; i < num2; i++) { for (int j = 0; j < num; j++) { if (i == num2 - 1 && data.Length % num != 0 && j >= data.Length % num) { Console.Write(" "); } else { Console.Write(" {0:x2}", data[i * num + j]); } } Console.Write(" | "); for (int k = 0; k < num; k++) { if (i == num2 - 1 && data.Length % num != 0 && k >= data.Length % num) { Console.Write(" "); } else { WriteByte2(data[i * num + k]); } } Console.WriteLine(); } Console.WriteLine(); } private static void WriteByte2(byte data) { string text = allowed; foreach (char c in text) { if (c == data) { Console.Write(c); return; } } Console.Write("."); } public static void AddDebugTime(object o1, object o2, DateTime start) { DebugTimeData value = new DebugTimeData(DateTime.Now - start, 1); if (debug_times.ContainsKey(o1) && debug_times[o1].ContainsKey(o2)) { value.time += debug_times[o1][o2].time; value.occurances += debug_times[o1][o2].occurances; } if (!debug_times.ContainsKey(o1)) { debug_times.Add(o1, new Dictionary<object, DebugTimeData>()); } if (!debug_times[o1].ContainsKey(o2)) { debug_times[o1].Add(o2, value); } else { debug_times[o1][o2] = value; } } public static void DumpDebugTime(object o1) { Console.WriteLine(o1.ToString()); if (!debug_times.ContainsKey(o1)) { return; } foreach (KeyValuePair<object, DebugTimeData> item in debug_times[o1]) { Console.WriteLine(" {0}", item.Key); Console.WriteLine(" Objects: {0}", item.Value.time); Console.WriteLine(" Total: {0}", item.Value.occurances); Console.WriteLine(" Average: {0}", new TimeSpan(item.Value.time.Ticks / item.Value.occurances)); Console.WriteLine(); } debug_times.Remove(o1); } } [Flags] public enum ReadStyle { None = 0, Average = 2, PictureLazy = 4 } public abstract class File : IDisposable { public enum AccessMode { Read, Write, Closed } public delegate File FileTypeResolver(IFileAbstraction abstraction, string mimetype, ReadStyle style); public class LocalFileAbstraction : IFileAbstraction { private readonly string name; public string Name => name; public Stream ReadStream => System.IO.File.Open(Name, FileMode.Open, FileAccess.Read, FileShare.Read); public Stream WriteStream => System.IO.File.Open(Name, FileMode.Open, FileAccess.ReadWrite); public LocalFileAbstraction(string path) { if (path == null) { throw new ArgumentNullException("path"); } name = path; } public void CloseStream(Stream stream) { if (stream == null) { throw new ArgumentNullException("stream"); } stream.Close(); } } public interface IFileAbstraction { string Name { get; } Stream ReadStream { get; } Stream WriteStream { get; } void CloseStream(Stream stream); } private Stream file_stream; protected IFileAbstraction file_abstraction; private static readonly int buffer_size = 1024; private static readonly List<FileTypeResolver> file_type_resolvers = new List<FileTypeResolver>(); private List<string> corruption_reasons; public static uint BufferSize => (uint)buffer_size; public abstract Tag Tag { get; } public abstract Properties Properties { get; } public TagTypes TagTypesOnDisk { get; protected set; } public TagTypes TagTypes => Tag?.TagTypes ?? TagTypes.None; public string Name => file_abstraction.Name; public string MimeType { get; internal set; } public long Tell { get { if (Mode != AccessMode.Closed) { return file_stream.Position; } return 0L; } } public long Length { get { if (Mode != AccessMode.Closed) { return file_stream.Length; } return 0L; } } public long InvariantStartPosition { get; protected set; } = -1L; public long InvariantEndPosition { get; protected set; } = -1L; public AccessMode Mode { get { if (file_stream == null) { return AccessMode.Closed; } if (file_stream.CanWrite) { return AccessMode.Write; } return AccessMode.Read; } set { if (Mode != value && (Mode != AccessMode.Write || value != 0)) { if (file_stream != null) { file_abstraction.CloseStream(file_stream); } file_stream = null; switch (value) { case AccessMode.Read: file_stream = file_abstraction.ReadStream; break; case AccessMode.Write: file_stream = file_abstraction.WriteStream; break; } Mode = value; } } } public IFileAbstraction FileAbstraction => file_abstraction; public virtual bool Writeable => !PossiblyCorrupt; public bool PossiblyCorrupt => corruption_reasons != null; public IEnumerable<string> CorruptionReasons => corruption_reasons; protected File(string path) { if (path == null) { throw new ArgumentNullException("path"); } file_abstraction = new LocalFileAbstraction(path); } protected File(IFileAbstraction abstraction) { if (abstraction == null) { throw new ArgumentNullException("abstraction"); } file_abstraction = abstraction; } internal void MarkAsCorrupt(string reason) { if (corruption_reasons == null) { corruption_reasons = new List<string>(); } corruption_reasons.Add(reason); } public void Dispose() { Mode = AccessMode.Closed; } public abstract void Save(); public abstract void RemoveTags(TagTypes types); public abstract Tag GetTag(TagTypes type, bool create); public Tag GetTag(TagTypes type) { return GetTag(type, create: false); } public ByteVector ReadBlock(int length) { if (length < 0) { throw new ArgumentException("Length must be non-negative", "length"); } if (length == 0) { return new ByteVector(); } Mode = AccessMode.Read; byte[] array = new byte[length]; int num = 0; int num2 = 0; int num3 = length; do { num = file_stream.Read(array, num2, num3); num2 += num; num3 -= num; } while (num3 > 0 && num != 0); return new ByteVector(array, num2); } public void WriteBlock(ByteVector data) { if (data == null) { throw new ArgumentNullException("data"); } Mode = AccessMode.Write; file_stream.Write(data.Data, 0, data.Count); } public long Find(ByteVector pattern, long startPosition, ByteVector before) { if (pattern == null) { throw new ArgumentNullException("pattern"); } Mode = AccessMode.Read; if (pattern.Count > buffer_size) { return -1L; } long num = startPosition; long position = file_stream.Position; try { file_stream.Position = startPosition; ByteVector byteVector = ReadBlock(buffer_size); while (byteVector.Count > 0) { int num2 = byteVector.Find(pattern); if (before != null && byteVector.Find(before) < num2) { return -1L; } if (num2 >= 0) { return num + num2; } num += buffer_size - pattern.Count; if (before != null && before.Count > pattern.Count) { num -= before.Count - pattern.Count; } file_stream.Position = num; byteVector = ReadBlock(buffer_size); } return -1L; } finally { file_stream.Position = position; } } public long Find(ByteVector pattern, long startPosition) { return Find(pattern, startPosition, null); } public long Find(ByteVector pattern) { return Find(pattern, 0L); } private long RFind(ByteVector pattern, long startPosition, ByteVector after) { if (pattern == null) { throw new ArgumentNullException("pattern"); } Mode = AccessMode.Read; if (pattern.Count > buffer_size) { return -1L; } long position = file_stream.Position; long num = Length - startPosition; int num2 = buffer_size; num2 = (int)Math.Min(num, buffer_size); num -= num2; file_stream.Position = num; ByteVector byteVector = ReadBlock(num2); while (byteVector.Count > 0) { long num3 = byteVector.RFind(pattern); if (num3 >= 0) { file_stream.Position = position; return num + num3; } if (after != null && byteVector.RFind(after) >= 0) { file_stream.Position = position; return -1L; } num2 = (int)Math.Min(num, buffer_size); num -= num2; if (num2 + pattern.Count > buffer_size) { num += pattern.Count; } file_stream.Position = num; byteVector = ReadBlock(num2); } file_stream.Position = position; return -1L; } public long RFind(ByteVector pattern, long startPosition) { return RFind(pattern, startPosition, null); } public long RFind(ByteVector pattern) { return RFind(pattern, 0L); } public void Insert(ByteVector data, long start, long replace) { if (data == null) { throw new ArgumentNullException("data"); } Insert(data, data.Count, start, replace); } public void Insert(ByteVector data, long start) { Insert(data, start, 0L); } public void Insert(long size, long start) { Insert(null, size, start, 0L); } public void RemoveBlock(long start, long length) { if (length > 0) { Mode = AccessMode.Write; int length2 = buffer_size; long num = start + length; long num2 = start; ByteVector byteVector = (byte)1; while (byteVector.Count != 0) { file_stream.Position = num; byteVector = ReadBlock(length2); num += byteVector.Count; file_stream.Position = num2; WriteBlock(byteVector); num2 += byteVector.Count; } Truncate(num2); } } public void Seek(long offset, SeekOrigin origin) { if (Mode != AccessMode.Closed) { file_stream.Seek(offset, origin); } } public void Seek(long offset) { Seek(offset, SeekOrigin.Begin); } public static File Create(string path) { return Create(path, null, ReadStyle.Average); } public static File Create(IFileAbstraction abstraction) { return Create(abstraction, null, ReadStyle.Average); } public static File Create(string path, ReadStyle propertiesStyle) { return Create(path, null, propertiesStyle); } public static File Create(IFileAbstraction abstraction, ReadStyle propertiesStyle) { return Create(abstraction, null, propertiesStyle); } public static File Create(string path, string mimetype, ReadStyle propertiesStyle) { return Create(new LocalFileAbstraction(path), mimetype, propertiesStyle); } public static File Create(IFileAbstraction abstraction, string mimetype, ReadStyle propertiesStyle) { if (mimetype == null) { string text = string.Empty; int num = abstraction.Name.LastIndexOf(".") + 1; if (num >= 1 && num < abstraction.Name.Length) { text = abstraction.Name.Substring(num, abstraction.Name.Length - num); } mimetype = "taglib/" + text.ToLower(CultureInfo.InvariantCulture); } foreach (FileTypeResolver file_type_resolver in file_type_resolvers) { File file = file_type_resolver(abstraction, mimetype, propertiesStyle); if (file != null) { return file; } } if (!FileTypes.AvailableTypes.ContainsKey(mimetype)) { throw new UnsupportedFormatException(string.Format(CultureInfo.InvariantCulture, "{0} ({1})", abstraction.Name, mimetype)); } Type type = FileTypes.AvailableTypes[mimetype]; try { File obj = (File)Activator.CreateInstance(type, abstraction, propertiesStyle); obj.MimeType = mimetype; return obj; } catch (TargetInvocationException ex) { PrepareExceptionForRethrow(ex.InnerException); throw ex.InnerException; } } public static void AddFileTypeResolver(FileTypeResolver resolver) { if (resolver != null) { file_type_resolvers.Insert(0, resolver); } } protected void PreSave() { if (!Writeable) { throw new InvalidOperationException("File not writeable."); } if (PossiblyCorrupt) { throw new CorruptFileException("Corrupted file cannot be saved."); } if (Tag?.Pictures == null) { return; } IPicture[] pictures = Tag.Pictures; for (int i = 0; i < pictures.Length; i++) { if (pictures[i] is ILazy lazy) { lazy.Load(); } } } private void Insert(ByteVector data, long size, long start, long replace) { Mode = AccessMode.Write; if (size == replace) { if (data != null) { file_stream.Position = start; WriteBlock(data); } return; } if (size < replace) { if (data != null) { file_stream.Position = start; WriteBlock(data); } RemoveBlock(start + size, replace - size); return; } int num = (int)(size - replace); int num2 = num % buffer_size; if (num2 != 0) { num += buffer_size - num2; } long num3 = start + replace; long num4 = start; file_stream.Position = num3; byte[] data2 = ReadBlock(num).Data; num3 += num; if (data != null) { file_stream.Position = num4; WriteBlock(data); } else if (start + size > Length) { file_stream.SetLength(start + size); } num4 += size; byte[] array = new byte[data2.Length]; Array.Copy(data2, 0, array, 0, data2.Length); while (num != 0) { file_stream.Position = num3; int num5 = file_stream.Read(data2, 0, (num < data2.Length) ? num : data2.Length); num3 += num; file_stream.Position = num4; file_stream.Write(array, 0, (num < array.Length) ? num : array.Length); num4 += num; Array.Copy(data2, 0, array, 0, num5); num = num5; } } protected void Truncate(long length) { AccessMode mode = Mode; Mode = AccessMode.Write; file_stream.SetLength(length); Mode = mode; } private static void PrepareExceptionForRethrow(Exception ex) { StreamingContext context = new StreamingContext(StreamingContextStates.CrossAppDomain); ObjectManager objectManager = new ObjectManager(null, context); SerializationInfo info = new SerializationInfo(ex.GetType(), new FormatterConverter()); ex.GetObjectData(info, context); objectManager.RegisterObject(ex, 1L, info); objectManager.DoFixups(); } } public static class FileTypes { private static Dictionary<string, Type> file_types; private static readonly Type[] static_file_types; public static IDictionary<string, Type> AvailableTypes => file_types; static FileTypes() { static_file_types = new Type[26] { typeof(TagLib.Aac.File), typeof(TagLib.Aiff.File), typeof(TagLib.Ape.File), typeof(TagLib.Asf.File), typeof(TagLib.Audible.File), typeof(TagLib.Dsf.File), typeof(TagLib.Flac.File), typeof(TagLib.Matroska.File), typeof(TagLib.Gif.File), typeof(TagLib.Image.NoMetadata.File), typeof(TagLib.Jpeg.File), typeof(TagLib.Mpeg4.File), typeof(AudioFile), typeof(TagLib.Mpeg.File), typeof(TagLib.MusePack.File), typeof(TagLib.Ogg.File), typeof(TagLib.Png.File), typeof(TagLib.Riff.File), typeof(TagLib.Tiff.Arw.File), typeof(TagLib.Tiff.Cr2.File), typeof(TagLib.Tiff.Dng.File), typeof(TagLib.Tiff.File), typeof(TagLib.Tiff.Nef.File), typeof(TagLib.Tiff.Pef.File), typeof(TagLib.Tiff.Rw2.File), typeof(TagLib.WavPack.File) }; Init(); } internal static void Init() { if (file_types == null) { file_types = new Dictionary<string, Type>(); Type[] array = static_file_types; for (int i = 0; i < array.Length; i++) { Register(array[i]); } } } public static void Register(Type type) { Attribute[] customAttributes = Attribute.GetCustomAttributes(type, typeof(SupportedMimeType), inherit: false); if (customAttributes.Length != 0) { Attribute[] array = customAttributes; for (int i = 0; i < array.Length; i++) { SupportedMimeType supportedMimeType = (SupportedMimeType)array[i]; file_types.Add(supportedMimeType.MimeType, type); } } } } public static class Genres { private static readonly string[] audio = new string[148] { "Blues", "Classic Rock", "Country", "Dance", "Disco", "Funk", "Grunge", "Hip-Hop", "Jazz", "Metal", "New Age", "Oldies", "Other", "Pop", "R&B", "Rap", "Reggae", "Rock", "Techno", "Industrial", "Alternative", "Ska", "Death Metal", "Pranks", "Soundtrack", "Euro-Techno", "Ambient", "Trip-Hop", "Vocal", "Jazz+Funk", "Fusion", "Trance", "Classical", "Instrumental", "Acid", "House", "Game", "Sound Clip", "Gospel", "Noise", "Alternative Rock", "Bass", "Soul", "Punk", "Space", "Meditative", "Instrumental Pop", "Instrumental Rock", "Ethnic", "Gothic", "Darkwave", "Techno-Industrial", "Electronic", "Pop-Folk", "Eurodance", "Dream", "Southern Rock", "Comedy", "Cult", "Gangsta", "Top 40", "Christian Rap", "Pop/Funk", "Jungle", "Native American", "Cabaret", "New Wave", "Psychedelic", "Rave", "Showtunes", "Trailer", "Lo-Fi", "Tribal", "Acid Punk", "Acid Jazz", "Polka", "Retro", "Musical", "Rock & Roll", "Hard Rock", "Folk", "Folk/Rock", "National Folk", "Swing", "Fusion", "Bebob", "Latin", "Revival", "Celtic", "Bluegrass", "Avantgarde", "Gothic Rock", "Progressive Rock", "Psychedelic Rock", "Symphonic Rock", "Slow Rock", "Big Band", "Chorus", "Easy Listening", "Acoustic", "Humour", "Speech", "Chanson", "Opera", "Chamber Music", "Sonata", "Symphony", "Booty Bass", "Primus", "Porn Groove", "Satire", "Slow Jam", "Club", "Tango", "Samba", "Folklore", "Ballad", "Power Ballad", "Rhythmic Soul", "Freestyle", "Duet", "Punk Rock", "Drum Solo", "A Cappella", "Euro-House", "Dance Hall", "Goa", "Drum & Bass", "Club-House", "Hardcore", "Terror", "Indie", "BritPop", "Negerpunk", "Polsk Punk", "Beat", "Christian Gangsta Rap", "Heavy Metal", "Black Metal", "Crossover", "Contemporary Christian", "Christian Rock", "Merengue", "Salsa", "Thrash Metal", "Anime", "Jpop", "Synthpop" }; private static readonly string[] video = new string[40] { "Action", "Action/Adventure", "Adult", "Adventure", "Catastrophe", "Child's", "Claymation", "Comedy", "Concert", "Documentary", "Drama", "Eastern", "Entertaining", "Erotic", "Extremal Sport", "Fantasy", "Fashion", "Historical", "Horror", "Horror/Mystic", "Humor", "Indian", "Informercial", "Melodrama", "Military & War", "Music Video", "Musical", "Mystery", "Nature", "Political Satire", "Popular Science", "Psychological Thriller", "Religion", "Science Fiction", "Scifi Action", "Slapstick", "Splatter", "Sports", "Thriller", "Western" }; public static string[] Audio => (string[])audio.Clone(); public static string[] Video => (string[])video.Clone(); public static byte AudioToIndex(string name) { for (byte b = 0; b < audio.Length; b++) { if (name == audio[b]) { return b; } } return byte.MaxValue; } public static byte VideoToIndex(string name) { for (byte b = 0; b < video.Length; b++) { if (name == video[b]) { return b; } } return byte.MaxValue; } public static string IndexToAudio(byte index) { if (index >= audio.Length) { return null; } return audio[index]; } public static string IndexToVideo(byte index) { if (index >= video.Length) { return null; } return video[index]; } public static string IndexToAudio(string text) { return IndexToAudio(StringToByte(text)); } public static string IndexToVideo(string text) { return IndexToVideo(StringToByte(text)); } private static byte StringToByte(string text) { int num; if (text != null && text.Length > 2 && text[0] == '(' && (num = text.IndexOf(')')) != -1 && byte.TryParse(text.Substring(1, num - 1), out var result)) { return result; } if (text != null && byte.TryParse(text, out result)) { return result; } return byte.MaxValue; } } [Flags] public enum MediaTypes { None = 0, Audio = 1, Video = 2, Photo = 4, Text = 8 } public interface ICodec { TimeSpan Duration { get; } MediaTypes MediaTypes { get; } string Description { get; } } public interface IAudioCodec : ICodec { int AudioBitrate { get; } int AudioSampleRate { get; } int AudioChannels { get; } } public interface ILosslessAudioCodec { int BitsPerSample { get; } } public interface IVideoCodec : ICodec { int VideoWidth { get; } int VideoHeight { get; } } public interface IPhotoCodec : ICodec { int PhotoWidth { get; } int PhotoHeight { get; } int PhotoQuality { get; } } public interface ILazy { bool IsLoaded { get; } void Load(); } public class ListBase<T> : IList<T>, ICollection<T>, IEnumerable<T>, IEnumerable where T : IComparable<T> { private readonly List<T> data = new List<T>(); public bool IsEmpty => Count == 0; public bool IsReadOnly => false; public bool IsFixedSize => false; public T this[int index] { get { return data[index]; } set { data[index] = value; } } public int Count => data.Count; public bool IsSynchronized => false; public object SyncRoot => this; public ListBase() { } public ListBase(ListBase<T> list) { if (list != null) { Add(list); } } public ListBase(params T[] list) { if (list != null) { Add(list); } } public void Add(ListBase<T> list) { if (list != null) { data.AddRange(list); } } public void Add(IEnumerable<T> list) { if (list != null) { data.AddRange(list); } } public void Add(T[] list) { if (list != null) { data.AddRange(list); } } public virtual void SortedInsert(T item, bool unique) { if (item == null) { throw new ArgumentNullException("item"); } int i; for (i = 0; i < data.Count; i++) { if (item.CompareTo(data[i]) == 0 && unique) { return; } if (item.CompareTo(data[i]) <= 0) { break; } } Insert(i, item); } public void SortedInsert(T item) { if (item == null) { throw new ArgumentNullException("item"); } SortedInsert(item, unique: false); } public T[] ToArray() { return data.ToArray(); } public void Add(T item) { data.Add(item); } public void Clear() { data.Clear(); } public bool Contains(T item) { return data.Contains(item); } public int IndexOf(T item) { return data.IndexOf(item); } public void Insert(int index, T item) { data.Insert(index, item); } public bool Remove(T item) { return data.Remove(item); } public void RemoveAt(int index) { data.RemoveAt(index); } public string ToString(string separator) { StringBuilder stringBuilder = new StringBuilder(); for (int i = 0; i < Count; i++) { if (i != 0) { stringBuilder.Append(separator); } stringBuilder.Append(this[i]); } return stringBuilder.ToString(); } public override string ToString() { return ToString(", "); } public void CopyTo(T[] array, int arrayIndex) { data.CopyTo(array, arrayIndex); } public IEnumerator<T> GetEnumerator() { return data.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return data.GetEnumerator(); } } public class TextBox : Box { private ByteVector data; public override ByteVector Data { get { return data; } set { data = value; } } public TextBox(BoxHeader header, File file, IsoHandlerBox handler) : base(header, handler) { if (file == null) { throw new ArgumentNullException("file"); } data = LoadData(file); } } public class UrlBox : Box { private ByteVector data; public override ByteVector Data { get { return data; } set { data = value; } } public UrlBox(BoxHeader header, File file, IsoHandlerBox handler) : base(header, handler) { if (file == null) { throw new ArgumentNullException("file"); } data = LoadData(file); } } public enum PictureType { Other = 0, FileIcon = 1, OtherFileIcon = 2, FrontCover = 3, BackCover = 4, LeafletPage = 5, Media = 6, LeadArtist = 7, Artist = 8, Conductor = 9, Band = 10, Composer = 11, Lyricist = 12, RecordingLocation = 13, DuringRecording = 14, DuringPerformance = 15, MovieScreenCapture = 16, ColoredFish = 17, Illustration = 18, BandLogo = 19, PublisherLogo = 20, NotAPicture = 255 } public interface IPicture { string MimeType { get; set; } PictureType Type { get; set; } string Filename { get; set; } string Description { get; set; } ByteVector Data { get; set; } } public class Picture : IPicture { private static readonly string[] lutExtensionMime = new string[150] { "aac", "audio/aac", "abw", "application/x-abiword", "arc", "application/octet-stream", "avi", "video/x-msvideo", "azw", "application/vnd.amazon.ebook", "bin", "application/octet-stream", "bmp", "image/bmp", "bmp", "image/x-windows-bmp", "bm", "image/bmp", "bz", "application/x-bzip", "bz2", "application/x-bzip2", "csh", "application/x-csh", "css", "text/css", "csv", "text/csv", "doc", "application/msword", "eot", "application/vnd.ms-fontobject", "epub", "application/epub+zip", "gif", "image/gif", "htm", "text/html", "html", "text/html", "ico", "image/x-icon", "ics", "text/calendar", "jar", "application/java-archive", "jpg", "image/jpeg", "jpeg", "image/jpeg", "js", "application/javascript", "json", "application/json", "mid", "audio/midi", "midi", "audio/midi", "mp3", "audio/mpeg", "mp1", "audio/mpeg", "mp2", "audio/mpeg", "mpg", "video/mpeg", "mpeg", "video/mpeg", "m4a", "audio/mp4", "mp4", "video/mp4", "m4v", "video/mp4", "mpkg", "application/vnd.apple.installer+xml", "odp", "application/vnd.oasis.opendocument.presentation", "ods", "application/vnd.oasis.opendocument.spreadsheet", "odt", "application/vnd.oasis.opendocument.text", "oga", "audio/ogg", "ogg", "audio/ogg", "ogx", "application/ogg", "ogv", "video/ogg", "otf", "font/otf", "png", "image/png", "pdf", "application/pdf", "ppt", "application/vnd.ms-powerpoint", "rar", "application/x-rar-compressed", "rtf", "application/rtf", "sh", "application/x-sh", "svg", "image/svg+xml", "swf", "application/x-shockwave-flash", "tar", "application/x-tar", "tif", "image/tiff", "tiff", "image/tiff", "ts", "video/vnd.dlna.mpeg-tts", "ttf", "font/ttf", "vsd", "application/vnd.visio", "wav", "audio/x-wav", "weba", "audio/webm", "webm", "video/webm", "webp", "image/webp", "woff", "font/woff", "woff2", "font/woff2", "xhtml", "application/xhtml+xml", "xls", "application/vnd.ms", "xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "xml", "application/xml", "xul", "application/vnd.mozilla.xul+xml", "zip", "application/zip", "3gp", "video/3gpp", "3g2", "video/3gpp2", "7z", "application/x-7z-compressed" }; public string MimeType { get; set; } public PictureType Type { get; set; } public string Filename { get; set; } public string Description { get; set; } public ByteVector Data { get; set; } public Picture() { } public Picture(string path) { if (path == null) { throw new ArgumentNullException("path"); } Data = ByteVector.FromPath(path); Filename = Path.GetFileName(path); Description = Filename; MimeType = GetMimeFromExtension(Filename); Type = (MimeType.StartsWith("image/") ? PictureType.FrontCover : PictureType.NotAPicture); } public Picture(File.IFileAbstraction abstraction) { if (abstraction == null) { throw new ArgumentNullException("abstraction"); } Data = ByteVector.FromFile(abstraction); Filename = abstraction.Name; Description = abstraction.Name; if (!string.IsNullOrEmpty(Filename) && Filename.Contains(".")) { MimeType = GetMimeFromExtension(Filename); Type = (MimeType.StartsWith("image/") ? PictureType.FrontCover : PictureType.NotAPicture); return; } string extensionFromData = GetExtensionFromData(Data); MimeType = GetMimeFromExtension(extensionFromData); if (extensionFromData != null) { Type = PictureType.FrontCover; Filename = (Description = "cover" + extensionFromData); } else { Type = PictureType.NotAPicture; Filename = "UnknownType"; } } public Picture(ByteVector data) { if (data == null) { throw new ArgumentNullException("data"); } Data = new ByteVector(data); string extensionFromData = GetExtensionFromData(data); MimeType = GetMimeFromExtension(extensionFromData); if (extensionFromData != null) { Type = PictureType.FrontCover; Filename = (Description = "cover" + extensionFromData); } else { Type = PictureType.NotAPicture; Filename = "UnknownType"; } } public Picture(IPicture picture) { MimeType = picture.MimeType; Type = picture.Type; Filename = picture.Filename; Description = picture.Description; Data = picture.Data; } [Obsolete("Use Picture(string filename) constructor instead.")] public static Picture CreateFromPath(string filename) { return new Picture(filename); } [Obsolete("Use Picture(File.IFileAbstraction abstraction) constructor instead.")] public static Picture CreateFromFile(File.IFileAbstraction abstraction) { return new Picture(abstraction); } public static string GetExtensionFromData(ByteVector data) { string result = null; if (data.Count >= 4) { if (data[1] == 80 && data[2] == 78 && data[3] == 71) { result = ".png"; } else if (data[0] == 71 && data[1] == 73 && data[2] == 70) { result = ".gif"; } else if (data[0] == 66 && data[1] == 77) { result = ".bmp"; } else if (data[0] == byte.MaxValue && data[1] == 216 && data[data.Count - 2] == byte.MaxValue && data[data.Count - 1] == 217) { result = ".jpg"; } } return result; } public static string GetExtensionFromMime(string mime) { string result = null; for (int i = 1; i < lutExtensionMime.Length; i += 2) { if (lutExtensionMime[i] == mime) { result = lutExtensionMime[i - 1]; break; } } return result; } public static string GetMimeFromExtension(string name) { string result = "application/octet-stream"; if (string.IsNullOrEmpty(name)) { return result; } string extension = Path.GetExtension(name); extension = ((!string.IsNullOrEmpty(extension)) ? extension.Substring(1) : name); extension = extension.ToLower(); for (int i = 0; i < lutExtensionMime.Length; i += 2) { if (lutExtensionMime[i] == extension) { result = lutExtensionMime[i + 1]; break; } } return result; } } public class PictureLazy : IPicture, ILazy { private string mime_type; private PictureType type; private string filename; private ByteVector data; private File.IFileAbstraction file; private readonly long stream_offset; private readonly long stream_size = -1L; public string MimeType { get { if (mime_type == null) { Load(); } return mime_type; } set { mime_type = value; } } public PictureType Type { get { if (type == PictureType.Other && mime_type == null) { Load(); } return type; } set { type = value; } } public string Filename { get { if (filename == null) { Load(); } return filename; } set { filename = value; } } public string Description { get; set; } public ByteVector Data { get { if (data == null) { Load(); } return data; } set { data = value; } } public bool IsLoaded => data != null; public PictureLazy() { } public PictureLazy(string path) { if (path == null) { throw new ArgumentNullException("path"); } file = new File.LocalFileAbstraction(path); filename = Path.GetFileName(path); Description = filename; mime_type = Picture.GetMimeFromExtension(filename); type = (mime_type.StartsWith("image/") ? PictureType.FrontCover : PictureType.NotAPicture); } public PictureLazy(File.IFileAbstraction abstraction, long offset = 0L, long size = -1L) { if (abstraction == null) { throw new ArgumentNullException("abstraction"); } file = abstraction; stream_offset = offset; stream_size = size; filename = abstraction.Name; Description = abstraction.Name; if (!string.IsNullOrEmpty(filename) && filename.Contains(".")) { mime_type = Picture.GetMimeFromExtension(filename); type = (mime_type.StartsWith("image/") ? PictureType.FrontCover : PictureType.NotAPicture); } } public PictureLazy(ByteVector data) { if (data == null) { throw new ArgumentNullException("data"); } Data = new ByteVector(data); string extensionFromData = Picture.GetExtensionFromData(data); MimeType = Picture.GetMimeFromExtension(extensionFromData); if (extensionFromData != null) { type = PictureType.FrontCover; filename = (Description = "cover" + extensionFromData); } else { type = PictureType.NotAPicture; filename = "UnknownType"; } } public PictureLazy(IPicture picture) { mime_type = picture.MimeType; type = picture.Type; filename = picture.Filename; Description = picture.Description; data = picture.Data; } public void Load() { if (data != null) { return; } Stream stream = null; try { if (stream_size == 0L) { data = new ByteVector(); } else if (stream_size > 0) { stream = file.ReadStream; stream.Seek(stream_offset, SeekOrigin.Begin); int num = 0; int num2 = 0; int num3 = (int)stream_size; byte[] buffer = new byte[num3]; do { num = stream.Read(buffer, num2, num3); num2 += num; num3 -= num; } while (num3 > 0 && num != 0); data = new ByteVector(buffer, num2); } else { stream = file.ReadStream; stream.Seek(stream_offset, SeekOrigin.Begin); data = ByteVector.FromStream(stream); } } finally { if (stream != null && file != null) { file.CloseStream(stream); } file = null; } if (mime_type != null) { return; } string extensionFromData = Picture.GetExtensionFromData(data); MimeType = Picture.GetMimeFromExtension(extensionFromData); if (extensionFromData != null) { type = PictureType.FrontCover; if (filename == null) { string text2 = (Description = "cover" + extensionFromData); filename = text2; } } else { type = PictureType.NotAPicture; if (filename == null) { filename = "UnknownType"; } } } } public class Properties : IAudioCodec, ICodec, IVideoCodec, IPhotoCodec { private readonly ICodec[] codecs = new ICodec[0]; private TimeSpan duration = TimeSpan.Zero; public IEnumerable<ICodec> Codecs => codecs; public TimeSpan Duration { get { TimeSpan timeSpan = duration; if (timeSpan != TimeSpan.Zero) { return timeSpan; } ICodec[] array = codecs; foreach (ICodec codec in array) { if (codec != null && codec.Duration > timeSpan) { timeSpan = codec.Duration; } } return timeSpan; } } public MediaTypes MediaTypes { get { MediaTypes mediaTypes = MediaTypes.None; ICodec[] array = codecs; foreach (ICodec codec in array) { if (codec != null) { mediaTypes |= codec.MediaTypes; } } return mediaTypes; } } public string Description { get { StringBuilder stringBuilder = new StringBuilder(); ICodec[] array = codecs; foreach (ICodec codec in array) { if (codec != null) { if (stringBuilder.Length != 0) { stringBuilder.Append("; "); } stringBuilder.Append(codec.Description); } } return stringBuilder.ToString(); } } public int AudioBitrate { get { ICodec[] array = codecs; foreach (ICodec codec in array) { if (codec != null && (codec.MediaTypes & MediaTypes.Audio) != 0 && codec is IAudioCodec audioCodec && audioCodec.AudioBitrate != 0) { return audioCodec.AudioBitrate; } } return 0; } } public int AudioSampleRate { get { ICodec[] array = codecs; foreach (ICodec codec in array) { if (codec != null && (codec.MediaTypes & MediaTypes.Audio) != 0 && codec is IAudioCodec audioCodec && audioCodec.AudioSampleRate != 0) { return audioCodec.AudioSampleRate; } } return 0; } } public int BitsPerSample { get { ICodec[] array = codecs; foreach (ICodec codec in array) { if (codec != null && (codec.MediaTypes & MediaTypes.Audio) != 0 && codec is ILosslessAudioCodec losslessAudioCodec && losslessAudioCodec.BitsPerSample != 0) { return losslessAudioCodec.BitsPerSample; } } return 0; } } public int AudioChannels { get { ICodec[] array = codecs; foreach (ICodec codec in array) { if (codec != null && (codec.MediaTypes & MediaTypes.Audio) != 0 && codec is IAudioCodec audioCodec && audioCodec.AudioChannels != 0) { return audioCodec.AudioChannels; } } return 0; } } public int VideoWidth { get { ICodec[] array = codecs; foreach (ICodec codec in array) { if (codec != null && (codec.MediaTypes & MediaTypes.Video) != 0 && codec is IVideoCodec videoCodec && videoCodec.VideoWidth != 0) { return videoCodec.VideoWidth; } } return 0; } } public int VideoHeight { get { ICodec[] array = codecs; foreach (ICodec codec in array) { if (codec != null && (codec.MediaTypes & MediaTypes.Video) != 0 && codec is IVideoCodec videoCodec && videoCodec.VideoHeight != 0) { return videoCodec.VideoHeight; } } return 0; } } public int PhotoWidth { get { ICodec[] array = codecs; foreach (ICodec codec in array) { if (codec != null && (codec.MediaTypes & MediaTypes.Photo) != 0 && codec is IPhotoCodec photoCodec && photoCodec.PhotoWidth != 0) { return photoCodec.PhotoWidth; } } return 0; } } public int PhotoHeight { get { ICodec[] array = codecs; foreach (ICodec codec in array) { if (codec != null && (codec.MediaTypes & MediaTypes.Photo) != 0 && codec is IPhotoCodec photoCodec && photoCodec.PhotoHeight != 0) { return photoCodec.PhotoHeight; } } return 0; } } public int PhotoQuality { get { ICodec[] array = codecs; foreach (ICodec codec in array) { if (codec != null && (codec.MediaTypes & MediaTypes.Photo) != 0 && codec is IPhotoCodec photoCodec && photoCodec.PhotoQuality != 0) { return photoCodec.PhotoQuality; } } return 0; } } public Properties() { } public Properties(TimeSpan duration, params ICodec[] codecs) { this.duration = duration; if (codecs != null) { this.codecs = codecs; } } public Properties(TimeSpan duration, IEnumerable<ICodec> codecs) { this.duration = duration; if (codecs != null) { this.codecs = new List<ICodec>(codecs).ToArray(); } } } public sealed class ReadOnlyByteVector : ByteVector { public override bool IsReadOnly => true; public override bool IsFixedSize => true; public ReadOnlyByteVector() { } public ReadOnlyByteVector(int size, byte value) : base(size, value) { } public ReadOnlyByteVector(int size) : this(size, 0) { } public ReadOnlyByteVector(ByteVector vector) : base(vector) { } public ReadOnlyByteVector(byte[] data, int length) : base(data, length) { } public ReadOnlyByteVector(params byte[] data) : base(data) { } public static implicit operator ReadOnlyByteVector(byte value) { return new ReadOnlyByteVector(value); } public static implicit operator ReadOnlyByteVector(byte[] value) { return new ReadOnlyByteVector(value); } public static implicit operator ReadOnlyByteVector(string value) { return new ReadOnlyByteVector(ByteVector.FromString(value, StringType.UTF8)); } } [ComVisible(false)] public class StringCollection : ListBase<string> { public StringCollection() { } public StringCollection(StringCollection values) { Add(values); } public StringCollection(params string[] values) { Add(values); } public StringCollection(ByteVectorCollection vectorList, StringType type) { foreach (ByteVector vector in vectorList) { Add(vector.ToString(type)); } } public StringCollection(ByteVectorCollection vectorList) : this(vectorList, StringType.UTF8) { } public static StringCollection Split(string value, string pattern) { if (value == null) { throw new ArgumentNullException("value"); } if (pattern == null) { throw new ArgumentNullException("pattern"); } StringCollection stringCollection = new StringCollection(); int num = 0; int num2 = value.IndexOf(pattern, 0); int length = pattern.Length; while (num2 != -1) { stringCollection.Add(value.Substring(num, num2 - num)); num = num2 + length; num2 = value.IndexOf(pattern, num); } stringCollection.Add(value.Substring(num)); return stringCollection; } } [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] public sealed class SupportedMimeType : Attribute { private static readonly List<SupportedMimeType> mimetypes; public string MimeType { get; private set; } public string Extension { get; private set; } public static IEnumerable<string> AllMimeTypes { get { foreach (SupportedMimeType mimetype in mimetypes) { yield return mimetype.MimeType; } } } public static IEnumerable<string> AllExtensions { get { foreach (SupportedMimeType mimetype in mimetypes) { if (mimetype.Extension != null) { yield return mimetype.Extension; } } } } static SupportedMimeType() { mimetypes = new List<SupportedMimeType>(); FileTypes.Init(); } public SupportedMimeType(string mimetype) { MimeType = mimetype; mimetypes.Add(this); } public SupportedMimeType(string mimetype, string extension) : this(mimetype) { Extension = extension; } } [Flags] public enum TagTypes : uint { None = 0u, Xiph = 1u, Id3v1 = 2u, Id3v2 = 4u, Ape = 8u, Apple = 0x10u, Asf = 0x20u, RiffInfo = 0x40u, MovieId = 0x80u, DivX = 0x100u, FlacMetadata = 0x200u, TiffIFD = 0x400u, XMP = 0x800u, JpegComment = 0x1000u, GifComment = 0x2000u, Png = 0x4000u, IPTCIIM = 0x8000u, AudibleMetadata = 0x10000u, Matroska = 0x20000u, AllTags = uint.MaxValue } public abstract class Tag { public abstract TagTypes TagTypes { get; } public virtual string Title { get { return null; } set { } } public virtual string TitleSort { get { return null; } set { } } public virtual string Subtitle { get { return null; } set { } } public virtual string Description { get { return null; } set { } } public virtual string[] Performers { get { return new string[0]; } set { } } public virtual string[] PerformersSort { get { return new string[0]; } set { } } public virtual string[] PerformersRole { get { return new string[0]; } set { } } public virtual string[] AlbumArtists { get { return new string[0]; } set { } } public virtual string[] AlbumArtistsSort { get { return new string[0]; } set { } } public virtual string[] Composers { get { return new string[0]; } set { } } public virtual string[] ComposersSort { get { return new string[0]; } set { } } public virtual string Album { get { return null; } set { } } public virtual string AlbumSort { get { return null; } set { } } public virtual string Comment { get { return null; } set { } } public virtual string[] Genres { get { return new string[0]; } set { } } public virtual uint Year { get { return 0u; } set { } } public virtual uint Track { get { return 0u; } set { } } public virtual uint TrackCount { get { return 0u; } set { } } public virtual uint Disc { get { return 0u; } set { } } public virtual uint DiscCount { get { return 0u; } set { } } public virtual string Lyrics { get { return null; } set { } } public virtual string Grouping { get { return null; } set { } } public virtual uint BeatsPerMinute { get { return 0u; } set { } } public virtual string Conductor { get { return null; } set { } } public virtual string Copyright { get { return null; } set { } } public virtual DateTime? DateTagged { get { return null; } set { } } public virtual string MusicBrainzArtistId { get { return null; } set { } } public virtual string MusicBrainzReleaseGroupId { get { return null; } set { } } public virtual string MusicBrainzReleaseId { get { return null; } set { } } public virtual string MusicBrainzReleaseArtistId { get { return null; } set { } } public virtual string MusicBrainzTrackId { get { return null; } set { } } public virtual string MusicBrainzDiscId { get { return null; } set { } } public virtual string MusicIpId { get { return null; } set { } } public virtual string AmazonId { get { return null; } set { } } public virtual string MusicBrainzReleaseStatus { get { return null; } set { } } public virtual string MusicBrainzReleaseType { get { return null; } set { } } public virtual string MusicBrainzReleaseCountry { get { return null; } set { } } public virtual double ReplayGainTrackGain { get { return double.NaN; } set { } } public virtual double ReplayGainTrackPeak { get { return double.NaN; } set { } } public virtual double ReplayGainAlbumGain { get { return double.NaN; } set { } } public virtual double ReplayGainAlbumPeak { get { return double.NaN; } set { } } public virtual string InitialKey { get { return null; } set { } } public virtual string RemixedBy { get { return null; } set { } } public virtual string Publisher { get