The BepInEx console will not appear when launching like it does for other games on Thunderstore (you can turn it back on in your BepInEx.cfg file). If your PEAK crashes on startup, add -dx12 to your launch parameters.
Decompiled source of sPEAKer v1.1.5
plugins/onlystar.sPEAKer.dll
Decompiled 6 hours 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.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Cryptography; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using Microsoft.CodeAnalysis; using PEAKLib.Core; using Photon.Pun; using Photon.Realtime; using TMPro; using UnityEngine; using UnityEngine.Networking; using UnityEngine.SceneManagement; using UnityEngine.UI; using sPEAKer.Scripts; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("onlystar")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyDescription("Some guy had it aboard. Does it still work?")] [assembly: AssemblyFileVersion("1.1.5.0")] [assembly: AssemblyInformationalVersion("1.1.5+459268a459bae0219dfda5650d27b80ea72c1fc9")] [assembly: AssemblyProduct("onlystar.sPEAKer")] [assembly: AssemblyTitle("sPEAKer")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.1.5.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace BepInEx { [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] [Conditional("CodeGeneration")] internal sealed class BepInAutoPluginAttribute : Attribute { public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null) { } } } namespace BepInEx.Preloader.Core.Patching { [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] [Conditional("CodeGeneration")] internal sealed class PatcherAutoPluginAttribute : Attribute { public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null) { } } } namespace sPEAKer { [BepInPlugin("onlystar.sPEAKer", "sPEAKer", "1.1.5")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { [CompilerGenerated] private sealed class <DelayedSpawn>d__53 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; private Player <masterClient>5__1; private List<Character>.Enumerator <>s__2; private Character <character>5__3; private Vector3 <spawnPos>5__4; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <DelayedSpawn>d__53(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <masterClient>5__1 = null; <>s__2 = default(List<Character>.Enumerator); <character>5__3 = null; <>1__state = -2; } private bool MoveNext() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: 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_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: 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_00dd: Unknown result type (might be due to invalid IL or missing references) switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds(2f); <>1__state = 1; return true; case 1: <>1__state = -1; <masterClient>5__1 = PhotonNetwork.MasterClient; <>s__2 = Character.AllCharacters.GetEnumerator(); try { while (<>s__2.MoveNext()) { <character>5__3 = <>s__2.Current; Character obj = <character>5__3; if (!object.Equals((obj != null) ? ((MonoBehaviourPun)obj).photonView.Owner : null, <masterClient>5__1)) { continue; } <spawnPos>5__4 = <character>5__3.Center + Vector3.up + Random.insideUnitSphere * 1.5f; PhotonNetwork.InstantiateItemRoom(((Object)_prefab).name, <spawnPos>5__4, Quaternion.identity); break; } } finally { ((IDisposable)<>s__2).Dispose(); } <>s__2 = default(List<Character>.Enumerator); 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 _prefab = null; public static PeakBundle Bundle = null; private ConfigEntry<bool> debugModeConfig = null; private ConfigEntry<bool> loadDemoSongConfig = null; private ConfigEntry<string> externalAudioFolderPathConfig = null; private ConfigEntry<bool> spawnAtGameStartConfig = null; private ConfigEntry<bool> spawnWithF4Config = null; private ConfigEntry<bool> recallEnabledConfig = null; private ConfigEntry<bool> extendedFormatSupportConfig = null; private static Plugin Instance { get; set; } = null; internal static ManualLogSource Log { get; private set; } = null; public static bool DebugMode { get; private set; } public static bool LoadDemoSong { get; private set; } public static string ExternalAudioFolderPath { get; private set; } = ""; private static bool SpawnAtGameStart { get; set; } private static bool SpawnWithF4 { get; set; } private static bool RecallEnabled { get; set; } public static bool ExtendedFormatSupport { get; private set; } private void Awake() { Instance = this; Log = ((BaseUnityPlugin)this).Logger; SetUserConfigs(); LocalizationFix(); if (DebugMode) { Log.LogInfo((object)"[sPEAKer] Plugin awakening..."); } ModDefinition.GetOrCreate(((BaseUnityPlugin)this).Info.Metadata); AudioMaster.EnsureInitialized(); Netcode.EnsureInitialized(); BundleLoader.LoadBundleWithName((BaseUnityPlugin)(object)this, "ps.peakbundle", (Action<PeakBundle>)InitSpeaker); } private void InitSpeaker(PeakBundle bundle) { if (DebugMode) { Log.LogInfo((object)"[sPEAKer] Initializing sPEAKer with bundle..."); } Bundle = bundle; GameObject val = Bundle.LoadAsset<GameObject>("assets/sPEAKer.prefab"); if ((Object)(object)val == (Object)null) { Log.LogError((object)"[sPEAKer] Failed to load sPEAKer prefab!"); return; } _prefab = val; if (DebugMode) { Log.LogInfo((object)"[sPEAKer] Successfully loaded sPEAKer prefab."); } SceneManager.sceneLoaded += OnSceneLoaded; val.AddComponent<Controller>(); Bundle.Mod.RegisterContent(); Log.LogInfo((object)"[sPEAKer] Plugin sPEAKer is loaded!"); } private void SetUserConfigs() { externalAudioFolderPathConfig = ((BaseUnityPlugin)this).Config.Bind<string>("Audio Loading", "ExternalAudioFolderPath", Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) ?? throw new InvalidOperationException(), "..\\onlystar-sPEAKer Music"), "Folder path where the mod will load mixtapes and external audio from. It's recommended to leave unchanged."); ExternalAudioFolderPath = externalAudioFolderPathConfig.Value; loadDemoSongConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("Audio Loading", "LoadDemoSong", true, "Include a demo song in your track list."); LoadDemoSong = loadDemoSongConfig.Value; extendedFormatSupportConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("Audio Loading", "ExtendedFormatSupport", true, "Enables loading of .mp3 and .wav files. May impact performance."); ExtendedFormatSupport = extendedFormatSupportConfig.Value; spawnAtGameStartConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("Spawning", "SpawnAtGameStart", true, "Automatically spawn a sPEAKer around the crash site when a game starts."); SpawnAtGameStart = spawnAtGameStartConfig.Value; spawnWithF4Config = ((BaseUnityPlugin)this).Config.Bind<bool>("Spawning", "SpawnWithF4", true, "Allows the host to spawn a sPEAKer in their hands when pressing F4.\nNotes:\n - Only one sPEAKer may exist at a time (for now).\n - Only the host can spawn a sPEAKer (for now)."); SpawnWithF4 = spawnWithF4Config.Value; recallEnabledConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("Spawning", "RecallEnabled", true, "Enables recalling existing sPEAKer when pressing F4.\nNotes:\n - Only works if SpawnWithF4 is enabled.\n - sPEAKer will only be recalled if it's in the ground."); RecallEnabled = recallEnabledConfig.Value; debugModeConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("zZzZz", "Debug", false, "Enable debug mode AKA verbose logging. If you want to report a bug, this is the way."); DebugMode = debugModeConfig.Value; } private void Update() { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Invalid comparison between Unknown and I4 if (Input.GetKeyDown((KeyCode)285) && SpawnWithF4 && PhotonNetwork.IsMasterClient) { bool flag = DoesSpeakerExist(); if (RecallEnabled) { if (flag) { Controller controller = Object.FindAnyObjectByType<Controller>(); if ((int)controller.item.itemState == 0) { controller.KillYourself(); Instance.SpawnAtHand(); } } else { Instance.SpawnAtHand(); } } else if (!flag) { Instance.SpawnAtHand(); } else if (DebugMode) { Log.LogInfo((object)"[sPEAKer:AudioMaster] Speaker already exists - not spawning another one"); } } if (Input.GetKeyDown((KeyCode)289) && DebugMode) { Object.FindAnyObjectByType<Controller>().LogAllComponents(); } } private void OnDestroy() { if (DebugMode) { Log.LogInfo((object)"[sPEAKer] Plugin destroying..."); } SceneManager.sceneLoaded -= OnSceneLoaded; Instance = null; Log = null; } private void OnSceneLoaded(Scene scene, LoadSceneMode mode) { if (SpawnAtGameStart && ((Scene)(ref scene)).name.StartsWith("Level_") && PhotonNetwork.IsConnected && PhotonNetwork.IsMasterClient) { ((MonoBehaviour)this).StartCoroutine(DelayedSpawn()); } } private void LocalizationFix() { LocalizedText.mainTable["NAME_SPEAKER"] = new List<string>(13) { "sPEAKer", "sPEAKer", "sPEAKer", "sPEAKer", "sPEAKer", "sPEAKer", "sPEAKer", "sPEAKer", "sPEAKer", "sPEAKer", "sPEAKer", "sPEAKer", "sPEAKer" }; LocalizedText.mainTable["VOLUME"] = new List<string>(14) { "Volume", "Volume", "Volume", "Volume", "Lautstärke", "Volumen", "Volumen", "Volume", "Громкость", "Гучність", "音量", "音量", "音量", "볼륨" }; LocalizedText.mainTable["TURN ON"] = new List<string>(13) { "Turn On", "Allumer", "Accendere", "Einschalten", "Encender", "Encender", "Ligar", "Включить", "Увімкнути", "打开", "打開", "電源を入れる", "켜다" }; LocalizedText.mainTable["PAUSE"] = new List<string>(14) { "Pause", "Pause", "Pausa", "Pause", "Pausa", "Pausa", "Pausa", "Pausa", "Пауза", "Пауза", "暂停", "暫停", "一時停止", "일시정지" }; LocalizedText.mainTable["..."] = new List<string>(1) { "..." }; } private bool DoesSpeakerExist() { if ((Object)(object)Object.FindAnyObjectByType<Controller>() != (Object)null) { return true; } if (AudioMaster.Instance.IsSpeakerActive()) { return true; } return false; } [IteratorStateMachine(typeof(<DelayedSpawn>d__53))] private static IEnumerator DelayedSpawn() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <DelayedSpawn>d__53(0); } public void SpawnAtHand() { //IL_001a: 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) PhotonNetwork.Instantiate("0_Items/" + ((Object)_prefab).name, Character.localCharacter.Center + Vector3.up * 3f, Quaternion.identity, (byte)0, (object[])null).GetComponent<Item>().Interact(Character.localCharacter); } } } namespace sPEAKer.Scripts { public class AudioMaster : MonoBehaviourPun { [CompilerGenerated] private sealed class <>c__DisplayClass64_0 { public string folderPath; internal IEnumerable<string> <ProcessAudioFolder>b__0(string pattern) { return Directory.GetFiles(folderPath, pattern, SearchOption.TopDirectoryOnly); } } [CompilerGenerated] private sealed class <>c__DisplayClass66_0 { public string mixtapePath; internal IEnumerable<string> <LoadMixtape>b__0(string pattern) { return Directory.GetFiles(mixtapePath, pattern, SearchOption.TopDirectoryOnly); } } [CompilerGenerated] private sealed class <InitializeAsync>d__61 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public AudioMaster <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <InitializeAsync>d__61(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; IsLoading = true; if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)"[sPEAKer:AudioMaster] Starting initialization..."); } <>2__current = ((MonoBehaviour)<>4__this).StartCoroutine(<>4__this.LoadFolderAudio()); <>1__state = 1; return true; case 1: <>1__state = -1; <>2__current = ((MonoBehaviour)<>4__this).StartCoroutine(<>4__this.LoadBundleAudio()); <>1__state = 2; return true; case 2: <>1__state = -1; IsInitialized = true; IsLoading = false; if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)("[sPEAKer:AudioMaster] Initialization complete. Total clips loaded: " + LoadedAudioClips.Count + ", Mixtapes loaded: " + AvailableMixtapes.Count)); } return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <LoadAudioClipsFromMixtapes>d__65 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public string basePath; public AudioMaster <>4__this; private int <mixtapeSuccessCount>5__1; private int <mixtapeFailCount>5__2; private string[] <subDirectories>5__3; private string[] <>s__4; private int <>s__5; private string <mixtapeDir>5__6; private MixtapeInfo <lastMixtape>5__7; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <LoadAudioClipsFromMixtapes>d__65(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <subDirectories>5__3 = null; <>s__4 = null; <mixtapeDir>5__6 = null; <lastMixtape>5__7 = null; <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <mixtapeSuccessCount>5__1 = 0; <mixtapeFailCount>5__2 = 0; <subDirectories>5__3 = Directory.GetDirectories(basePath); if (Plugin.DebugMode && <subDirectories>5__3.Length != 0) { Plugin.Log.LogInfo((object)("[sPEAKer:AudioMaster] Found " + <subDirectories>5__3.Length + " potential mixtape folders in " + basePath)); } <>s__4 = <subDirectories>5__3; <>s__5 = 0; break; case 1: <>1__state = -1; <lastMixtape>5__7 = AvailableMixtapes.LastOrDefault(); if (<lastMixtape>5__7 != null && <lastMixtape>5__7.Path == <mixtapeDir>5__6 && <lastMixtape>5__7.SongCount > 0) { <mixtapeSuccessCount>5__1++; } else if (<lastMixtape>5__7 == null || <lastMixtape>5__7.Path != <mixtapeDir>5__6) { <mixtapeFailCount>5__2++; } <lastMixtape>5__7 = null; <mixtapeDir>5__6 = null; <>s__5++; break; } if (<>s__5 < <>s__4.Length) { <mixtapeDir>5__6 = <>s__4[<>s__5]; <>2__current = ((MonoBehaviour)<>4__this).StartCoroutine(<>4__this.LoadMixtape(<mixtapeDir>5__6)); <>1__state = 1; return true; } <>s__4 = null; if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)("[sPEAKer:AudioMaster] All mixtape folder loading complete for " + basePath + ". Success: " + <mixtapeSuccessCount>5__1 + ", Failed: " + <mixtapeFailCount>5__2)); } 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 <LoadBundleAudio>d__62 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public AudioMaster <>4__this; private int <waitCount>5__1; private string[] <allAssets>5__2; private string[] <jblFX>5__3; private string <whiteNoise>5__4; private string[] <>s__5; private int <>s__6; private string <fx>5__7; private AudioClip <clip>5__8; private string <filename>5__9; private AudioClip <whiteNoiseClip>5__10; private AudioClip <demoClip>5__11; private string <songHash>5__12; private int <index>5__13; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <LoadBundleAudio>d__62(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <allAssets>5__2 = null; <jblFX>5__3 = null; <whiteNoise>5__4 = null; <>s__5 = null; <fx>5__7 = null; <clip>5__8 = null; <filename>5__9 = null; <whiteNoiseClip>5__10 = null; <demoClip>5__11 = null; <songHash>5__12 = null; <>1__state = -2; } private bool MoveNext() { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Expected O, but got Unknown //IL_02ae: Unknown result type (might be due to invalid IL or missing references) //IL_02b4: Invalid comparison between Unknown and I4 switch (<>1__state) { default: return false; case 0: <>1__state = -1; if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)"[sPEAKer:AudioMaster] Starting bundle audio loading..."); } <waitCount>5__1 = 0; goto IL_0082; case 1: <>1__state = -1; <waitCount>5__1++; goto IL_0082; case 2: { <>1__state = -1; return false; } IL_0082: if (Plugin.Bundle == null && <waitCount>5__1 < 100) { <>2__current = (object)new WaitForSeconds(0.1f); <>1__state = 1; return true; } if (Plugin.Bundle == null) { Plugin.Log.LogError((object)"[sPEAKer:AudioMaster] Bundle not available after 10 seconds - skipping bundle audio loading"); return false; } if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)"[sPEAKer:AudioMaster] Bundle is now available, proceeding with loading..."); } <allAssets>5__2 = Plugin.Bundle.GetAllAssetNames(); if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)("[sPEAKer:AudioMaster] Total assets in bundle: " + <allAssets>5__2.Length)); } <jblFX>5__3 = <allAssets>5__2.Where((string asset) => asset.Contains("jbl_fx") && asset.EndsWith(".ogg")).ToArray(); <>s__5 = <jblFX>5__3; for (<>s__6 = 0; <>s__6 < <>s__5.Length; <>s__6++) { <fx>5__7 = <>s__5[<>s__6]; <clip>5__8 = Plugin.Bundle.LoadAsset<AudioClip>(<fx>5__7); <filename>5__9 = Path.GetFileNameWithoutExtension(<fx>5__7); SoundEffects.SetClip(<filename>5__9, <clip>5__8); <clip>5__8 = null; <filename>5__9 = null; <fx>5__7 = null; } <>s__5 = null; <whiteNoise>5__4 = <allAssets>5__2.FirstOrDefault((string asset) => asset.Contains("whitenoise")); if (!string.IsNullOrEmpty(<whiteNoise>5__4)) { <whiteNoiseClip>5__10 = Plugin.Bundle.LoadAsset<AudioClip>(<whiteNoise>5__4); SoundEffects.SetClip("whitenoise", <whiteNoiseClip>5__10); <whiteNoiseClip>5__10 = null; } if (Plugin.LoadDemoSong) { <demoClip>5__11 = Plugin.Bundle.LoadAsset<AudioClip>("assets/speaker audio/portal.ogg"); if ((Object)(object)<demoClip>5__11 != (Object)null) { <demoClip>5__11.LoadAudioData(); if ((int)<demoClip>5__11.loadState == 2) { LoadedAudioClips.Add(<demoClip>5__11); <songHash>5__12 = <>4__this.GenerateAudioHash(<demoClip>5__11); <index>5__13 = LoadedAudioClips.Count - 1; SongHashToIndex[<songHash>5__12] = <index>5__13; IndexToSongHash[<index>5__13] = <songHash>5__12; if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)("[sPEAKer:AudioMaster] Successfully loaded demo song: " + ((Object)<demoClip>5__11).name)); } <songHash>5__12 = null; } else { Plugin.Log.LogError((object)"[sPEAKer:AudioMaster] Failed to load demo song audio data"); } } else { Plugin.Log.LogError((object)"[sPEAKer:AudioMaster] Failed to load demo song from bundle"); } <demoClip>5__11 = null; } if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)"[sPEAKer:AudioMaster] Bundle loading complete."); } <>2__current = null; <>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(); } } [CompilerGenerated] private sealed class <LoadFolderAudio>d__63 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public AudioMaster <>4__this; private List<string> <foldersToProcess>5__1; private string <originalFolderPath>5__2; private string <pluginsPath>5__3; private Exception <e>5__4; private string[] <subDirectories>5__5; private string[] <>s__6; private int <>s__7; private string <subDir>5__8; private string <markerFile>5__9; private List<string>.Enumerator <>s__10; private string <folderPath>5__11; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <LoadFolderAudio>d__63(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || (uint)(num - 1) <= 1u) { try { } finally { <>m__Finally1(); } } <foldersToProcess>5__1 = null; <originalFolderPath>5__2 = null; <pluginsPath>5__3 = null; <e>5__4 = null; <subDirectories>5__5 = null; <>s__6 = null; <subDir>5__8 = null; <markerFile>5__9 = null; <>s__10 = default(List<string>.Enumerator); <folderPath>5__11 = null; <>1__state = -2; } private bool MoveNext() { try { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <foldersToProcess>5__1 = new List<string>(); <originalFolderPath>5__2 = Plugin.ExternalAudioFolderPath; if (Directory.Exists(<originalFolderPath>5__2)) { <foldersToProcess>5__1.Add(<originalFolderPath>5__2); if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)("[sPEAKer:AudioMaster] Added original folder: " + <originalFolderPath>5__2)); } } else { if (Plugin.DebugMode) { Plugin.Log.LogWarning((object)("[sPEAKer:AudioMaster] Original external folder not found: " + <originalFolderPath>5__2 + " - Creating it now.")); } try { Directory.CreateDirectory(<originalFolderPath>5__2); <foldersToProcess>5__1.Add(<originalFolderPath>5__2); if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)"[sPEAKer:AudioMaster] Created original Sounds folder successfully."); } } catch (Exception ex) { <e>5__4 = ex; Plugin.Log.LogError((object)("[sPEAKer:AudioMaster] Failed to create original external folder: " + <e>5__4.Message)); } } <pluginsPath>5__3 = Path.GetDirectoryName(<originalFolderPath>5__2) ?? string.Empty; if (Directory.Exists(<pluginsPath>5__3)) { <foldersToProcess>5__1.Add(<pluginsPath>5__3.Substring(0, <pluginsPath>5__3.Length - 3)); if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)("[sPEAKer:AudioMaster] Scanning plugins folder for mixtape mods: " + <pluginsPath>5__3)); } <subDirectories>5__5 = Directory.GetDirectories(<pluginsPath>5__3); <>s__6 = <subDirectories>5__5; for (<>s__7 = 0; <>s__7 < <>s__6.Length; <>s__7++) { <subDir>5__8 = <>s__6[<>s__7]; <markerFile>5__9 = Path.Combine(<subDir>5__8, "sPEAKer.json"); if (File.Exists(<markerFile>5__9) && !<foldersToProcess>5__1.Contains(<subDir>5__8)) { <foldersToProcess>5__1.Add(<subDir>5__8); if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)("[sPEAKer:AudioMaster] Found mixtape mod folder: " + <subDir>5__8)); } } <markerFile>5__9 = null; <subDir>5__8 = null; } <>s__6 = null; <subDirectories>5__5 = null; } else if (Plugin.DebugMode) { Plugin.Log.LogWarning((object)("[sPEAKer:AudioMaster] Plugins folder not found: " + <pluginsPath>5__3)); } if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)("[sPEAKer:AudioMaster] Total folders to process: " + <foldersToProcess>5__1.Count)); } <>s__10 = <foldersToProcess>5__1.GetEnumerator(); <>1__state = -3; break; case 1: <>1__state = -3; <>2__current = ((MonoBehaviour)<>4__this).StartCoroutine(<>4__this.LoadAudioClipsFromMixtapes(<folderPath>5__11)); <>1__state = 2; return true; case 2: <>1__state = -3; <folderPath>5__11 = null; break; } if (<>s__10.MoveNext()) { <folderPath>5__11 = <>s__10.Current; <>2__current = ((MonoBehaviour)<>4__this).StartCoroutine(<>4__this.ProcessAudioFolder(<folderPath>5__11)); <>1__state = 1; return true; } <>m__Finally1(); <>s__10 = default(List<string>.Enumerator); return false; } 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; ((IDisposable)<>s__10).Dispose(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <LoadMixtape>d__66 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public string mixtapePath; public AudioMaster <>4__this; private <>c__DisplayClass66_0 <>8__1; private string <mixtapeName>5__2; private MixtapeInfo <mixtapeInfo>5__3; private string <metadataPath>5__4; private List<string> <searchPatterns>5__5; private List<string> <audioFiles>5__6; private int <songSuccessCount>5__7; private int <songFailCount>5__8; private float <totalDuration>5__9; private string <jsonContent>5__10; private MixtapeMetadata <metadata>5__11; private Exception <e>5__12; private List<string>.Enumerator <>s__13; private string <audioFile>5__14; private string <fileName>5__15; private string <url>5__16; private AudioType <audioType>5__17; private UnityWebRequest <www>5__18; private AudioClip <clip>5__19; private string <songHash>5__20; private int <index>5__21; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <LoadMixtape>d__66(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if ((uint)(num - -4) <= 1u || (uint)(num - 1) <= 1u) { try { if (num == -4 || (uint)(num - 1) <= 1u) { try { } finally { <>m__Finally2(); } } } finally { <>m__Finally1(); } } <>8__1 = null; <mixtapeName>5__2 = null; <mixtapeInfo>5__3 = null; <metadataPath>5__4 = null; <searchPatterns>5__5 = null; <audioFiles>5__6 = null; <jsonContent>5__10 = null; <metadata>5__11 = null; <e>5__12 = null; <>s__13 = default(List<string>.Enumerator); <audioFile>5__14 = null; <fileName>5__15 = null; <url>5__16 = null; <www>5__18 = null; <clip>5__19 = null; <songHash>5__20 = null; <>1__state = -2; } private bool MoveNext() { //IL_0423: Unknown result type (might be due to invalid IL or missing references) //IL_0429: Invalid comparison between Unknown and I4 //IL_0431: Unknown result type (might be due to invalid IL or missing references) //IL_0437: Invalid comparison between Unknown and I4 //IL_04f8: Unknown result type (might be due to invalid IL or missing references) //IL_04fe: Invalid comparison between Unknown and I4 //IL_050c: Unknown result type (might be due to invalid IL or missing references) //IL_0512: Invalid comparison between Unknown and I4 //IL_037a: Unknown result type (might be due to invalid IL or missing references) //IL_037f: Unknown result type (might be due to invalid IL or missing references) //IL_0385: Unknown result type (might be due to invalid IL or missing references) //IL_038b: Invalid comparison between Unknown and I4 //IL_03c7: Unknown result type (might be due to invalid IL or missing references) //IL_03ea: Unknown result type (might be due to invalid IL or missing references) try { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>8__1 = new <>c__DisplayClass66_0(); <>8__1.mixtapePath = mixtapePath; <mixtapeName>5__2 = new DirectoryInfo(<>8__1.mixtapePath).Name; if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)("[sPEAKer:AudioMaster] Loading mixtape from folder: " + <mixtapeName>5__2)); } <mixtapeInfo>5__3 = new MixtapeInfo { Name = <mixtapeName>5__2, Author = "Unknown", FirstSongIndex = LoadedAudioClips.Count, Path = <>8__1.mixtapePath }; <metadataPath>5__4 = Path.Combine(<>8__1.mixtapePath, "mixtape.json"); if (File.Exists(<metadataPath>5__4)) { try { <jsonContent>5__10 = File.ReadAllText(<metadataPath>5__4); <metadata>5__11 = JsonUtility.FromJson<MixtapeMetadata>(<jsonContent>5__10); if (!string.IsNullOrEmpty(<metadata>5__11.name)) { <mixtapeInfo>5__3.Name = <metadata>5__11.name; } if (!string.IsNullOrEmpty(<metadata>5__11.author)) { <mixtapeInfo>5__3.Author = <metadata>5__11.author; } if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)("[sPEAKer:AudioMaster] Loaded mixtape metadata - Name: " + <mixtapeInfo>5__3.Name + ", Author: " + <mixtapeInfo>5__3.Author)); } <jsonContent>5__10 = null; <metadata>5__11 = null; } catch (Exception ex) { <e>5__12 = ex; Plugin.Log.LogWarning((object)("[sPEAKer:AudioMaster] Failed to parse mixtape metadata for " + <mixtapeName>5__2 + ": " + <e>5__12.Message)); } } <searchPatterns>5__5 = new List<string> { "*.ogg" }; if (Plugin.ExtendedFormatSupport) { <searchPatterns>5__5.Add("*.mp3"); <searchPatterns>5__5.Add("*.wav"); } <audioFiles>5__6 = <searchPatterns>5__5.SelectMany((string pattern) => Directory.GetFiles(<>8__1.mixtapePath, pattern, SearchOption.TopDirectoryOnly)).ToList(); if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)("[sPEAKer:AudioMaster] Found " + <audioFiles>5__6.Count + " audio files in mixtape.")); } <songSuccessCount>5__7 = 0; <songFailCount>5__8 = 0; <totalDuration>5__9 = 0f; <>s__13 = <audioFiles>5__6.GetEnumerator(); <>1__state = -3; break; case 1: <>1__state = -4; if ((int)<www>5__18.result == 2 || (int)<www>5__18.result == 3) { Plugin.Log.LogError((object)("[sPEAKer:AudioMaster] Failed to load mixtape audio: " + <fileName>5__15 + " - Error: " + <www>5__18.error)); <songFailCount>5__8++; goto IL_0681; } <clip>5__19 = DownloadHandlerAudioClip.GetContent(<www>5__18); if ((Object)(object)<clip>5__19 != (Object)null) { ((Object)<clip>5__19).name = Path.GetFileNameWithoutExtension(<audioFile>5__14); <clip>5__19.LoadAudioData(); goto IL_04f2; } Plugin.Log.LogError((object)("[sPEAKer:AudioMaster] Failed to get AudioClip content for mixtape song: " + <fileName>5__15)); <songFailCount>5__8++; goto IL_0679; case 2: { <>1__state = -4; goto IL_04f2; } IL_0681: <>m__Finally2(); <www>5__18 = null; <fileName>5__15 = null; <url>5__16 = null; <audioFile>5__14 = null; break; IL_04f2: if ((int)<clip>5__19.loadState == 1) { <>2__current = null; <>1__state = 2; return true; } if ((int)<clip>5__19.loadState == 2) { LoadedAudioClips.Add(<clip>5__19); <songHash>5__20 = <>4__this.GenerateAudioHash(<clip>5__19); <index>5__21 = LoadedAudioClips.Count - 1; SongHashToIndex[<songHash>5__20] = <index>5__21; IndexToSongHash[<index>5__21] = <songHash>5__20; <totalDuration>5__9 += <clip>5__19.length; if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)("[sPEAKer:AudioMaster] Successfully loaded mixtape song: " + ((Object)<clip>5__19).name + " (Length: " + <clip>5__19.length + "s)")); } <songSuccessCount>5__7++; <songHash>5__20 = null; } else { Plugin.Log.LogError((object)("[sPEAKer:AudioMaster] Failed to preload audio data for mixtape song: " + <fileName>5__15)); <songFailCount>5__8++; } goto IL_0679; IL_0679: <clip>5__19 = null; goto IL_0681; } while (<>s__13.MoveNext()) { <audioFile>5__14 = <>s__13.Current; <fileName>5__15 = Path.GetFileName(<audioFile>5__14); if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)("[sPEAKer:AudioMaster] Loading mixtape song: " + <fileName>5__15)); } <url>5__16 = "file://" + <audioFile>5__14.Replace('\\', '/').Replace("+", "%2B").Replace("#", "%23"); <audioType>5__17 = <>4__this.GetAudioTypeFromExtension(<audioFile>5__14); if ((int)<audioType>5__17 == 0) { if (Plugin.DebugMode) { Plugin.Log.LogWarning((object)("[sPEAKer:AudioMaster] Skipping unsupported file type in mixtape: " + <fileName>5__15)); } continue; } <www>5__18 = UnityWebRequestMultimedia.GetAudioClip(<url>5__16, <audioType>5__17); <>1__state = -4; ((DownloadHandlerAudioClip)<www>5__18.downloadHandler).streamAudio = false; <>2__current = <www>5__18.SendWebRequest(); <>1__state = 1; return true; } <>m__Finally1(); <>s__13 = default(List<string>.Enumerator); <mixtapeInfo>5__3.SongCount = <songSuccessCount>5__7; <mixtapeInfo>5__3.LastSongIndex = <mixtapeInfo>5__3.FirstSongIndex + <songSuccessCount>5__7 - 1; <mixtapeInfo>5__3.TotalLength = <>4__this.FormatDuration(<totalDuration>5__9); if (<songSuccessCount>5__7 > 0) { AvailableMixtapes.Add(<mixtapeInfo>5__3); if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)("[sPEAKer:AudioMaster] Successfully loaded mixtape '" + <mixtapeInfo>5__3.Name + "' by " + <mixtapeInfo>5__3.Author + " - " + <songSuccessCount>5__7 + " songs, " + <mixtapeInfo>5__3.TotalLength + " total")); } } else { Plugin.Log.LogWarning((object)("[sPEAKer:AudioMaster] Mixtape folder '" + <mixtapeInfo>5__3.Name + "' contains no valid audio files.")); } return false; } 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; ((IDisposable)<>s__13).Dispose(); } private void <>m__Finally2() { <>1__state = -3; if (<www>5__18 != null) { ((IDisposable)<www>5__18).Dispose(); } } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <ProcessAudioFolder>d__64 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public string folderPath; public AudioMaster <>4__this; private <>c__DisplayClass64_0 <>8__1; private List<string> <searchPatterns>5__2; private List<string> <audioFiles>5__3; private int <successCount>5__4; private int <failCount>5__5; private List<string>.Enumerator <>s__6; private string <file>5__7; private string <fileName>5__8; private string <url>5__9; private AudioType <audioType>5__10; private UnityWebRequest <www>5__11; private AudioClip <clip>5__12; private string <songHash>5__13; private int <index>5__14; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <ProcessAudioFolder>d__64(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if ((uint)(num - -4) <= 1u || (uint)(num - 1) <= 1u) { try { if (num == -4 || (uint)(num - 1) <= 1u) { try { } finally { <>m__Finally2(); } } } finally { <>m__Finally1(); } } <>8__1 = null; <searchPatterns>5__2 = null; <audioFiles>5__3 = null; <>s__6 = default(List<string>.Enumerator); <file>5__7 = null; <fileName>5__8 = null; <url>5__9 = null; <www>5__11 = null; <clip>5__12 = null; <songHash>5__13 = null; <>1__state = -2; } private bool MoveNext() { //IL_02f5: Unknown result type (might be due to invalid IL or missing references) //IL_02fb: Invalid comparison between Unknown and I4 //IL_0303: Unknown result type (might be due to invalid IL or missing references) //IL_0309: Invalid comparison between Unknown and I4 //IL_03ca: Unknown result type (might be due to invalid IL or missing references) //IL_03d0: Invalid comparison between Unknown and I4 //IL_03de: Unknown result type (might be due to invalid IL or missing references) //IL_03e4: Invalid comparison between Unknown and I4 //IL_024c: Unknown result type (might be due to invalid IL or missing references) //IL_0251: Unknown result type (might be due to invalid IL or missing references) //IL_0257: Unknown result type (might be due to invalid IL or missing references) //IL_025d: Invalid comparison between Unknown and I4 //IL_0299: Unknown result type (might be due to invalid IL or missing references) //IL_02bc: Unknown result type (might be due to invalid IL or missing references) try { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>8__1 = new <>c__DisplayClass64_0(); <>8__1.folderPath = folderPath; if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)("[sPEAKer:AudioMaster] Processing loose audio files in: " + <>8__1.folderPath)); } <searchPatterns>5__2 = new List<string> { "*.ogg" }; if (Plugin.ExtendedFormatSupport) { if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)"[sPEAKer:AudioMaster] Extended format support is ON. Searching for .mp3 and .wav files."); } <searchPatterns>5__2.Add("*.mp3"); <searchPatterns>5__2.Add("*.wav"); } <audioFiles>5__3 = <searchPatterns>5__2.SelectMany((string pattern) => Directory.GetFiles(<>8__1.folderPath, pattern, SearchOption.TopDirectoryOnly)).ToList(); if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)("[sPEAKer:AudioMaster] Found " + <audioFiles>5__3.Count + " loose audio files in " + <>8__1.folderPath)); } if (<audioFiles>5__3.Count == 0) { if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)("[sPEAKer:AudioMaster] No loose audio files found, skipping: " + <>8__1.folderPath)); } return false; } <successCount>5__4 = 0; <failCount>5__5 = 0; <>s__6 = <audioFiles>5__3.GetEnumerator(); <>1__state = -3; break; case 1: <>1__state = -4; if ((int)<www>5__11.result == 2 || (int)<www>5__11.result == 3) { Plugin.Log.LogError((object)("[sPEAKer:AudioMaster] Failed to load audio: " + <fileName>5__8 + " - Error: " + <www>5__11.error)); <failCount>5__5++; goto IL_053b; } <clip>5__12 = DownloadHandlerAudioClip.GetContent(<www>5__11); if ((Object)(object)<clip>5__12 != (Object)null) { ((Object)<clip>5__12).name = Path.GetFileNameWithoutExtension(<file>5__7); <clip>5__12.LoadAudioData(); goto IL_03c4; } Plugin.Log.LogError((object)("[sPEAKer:AudioMaster] Failed to get AudioClip content for: " + <fileName>5__8)); <failCount>5__5++; goto IL_0533; case 2: { <>1__state = -4; goto IL_03c4; } IL_053b: <>m__Finally2(); <www>5__11 = null; <fileName>5__8 = null; <url>5__9 = null; <file>5__7 = null; break; IL_03c4: if ((int)<clip>5__12.loadState == 1) { <>2__current = null; <>1__state = 2; return true; } if ((int)<clip>5__12.loadState == 2) { LoadedAudioClips.Add(<clip>5__12); <songHash>5__13 = <>4__this.GenerateAudioHash(<clip>5__12); <index>5__14 = LoadedAudioClips.Count - 1; SongHashToIndex[<songHash>5__13] = <index>5__14; IndexToSongHash[<index>5__14] = <songHash>5__13; if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)("[sPEAKer:AudioMaster] Successfully loaded and preloaded audio: " + ((Object)<clip>5__12).name + " (Length: " + <clip>5__12.length + "s)")); } <successCount>5__4++; <songHash>5__13 = null; } else { Plugin.Log.LogError((object)("[sPEAKer:AudioMaster] Failed to preload audio data for: " + <fileName>5__8)); <failCount>5__5++; } goto IL_0533; IL_0533: <clip>5__12 = null; goto IL_053b; } while (<>s__6.MoveNext()) { <file>5__7 = <>s__6.Current; <fileName>5__8 = Path.GetFileName(<file>5__7); if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)("[sPEAKer:AudioMaster] Loading file: " + <fileName>5__8)); } <url>5__9 = "file://" + <file>5__7.Replace('\\', '/').Replace("+", "%2B").Replace("#", "%23"); <audioType>5__10 = <>4__this.GetAudioTypeFromExtension(<file>5__7); if ((int)<audioType>5__10 == 0) { if (Plugin.DebugMode) { Plugin.Log.LogWarning((object)("[sPEAKer:AudioMaster] Skipping unsupported file type: " + <fileName>5__8)); } continue; } <www>5__11 = UnityWebRequestMultimedia.GetAudioClip(<url>5__9, <audioType>5__10); <>1__state = -4; ((DownloadHandlerAudioClip)<www>5__11.downloadHandler).streamAudio = false; <>2__current = <www>5__11.SendWebRequest(); <>1__state = 1; return true; } <>m__Finally1(); <>s__6 = default(List<string>.Enumerator); if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)("[sPEAKer:AudioMaster] Loose file processing complete for " + <>8__1.folderPath + ". Success: " + <successCount>5__4 + ", Failed: " + <failCount>5__5)); } return false; } 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; ((IDisposable)<>s__6).Dispose(); } private void <>m__Finally2() { <>1__state = -3; if (<www>5__11 != null) { ((IDisposable)<www>5__11).Dispose(); } } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private static AudioMaster _instance; private Transform? _targetTransform = null; private Character? _targetCharacter = null; private bool _isFollowing; public static List<AudioClip> LoadedAudioClips { get; private set; } = new List<AudioClip>(); private static List<MixtapeInfo> AvailableMixtapes { get; set; } = new List<MixtapeInfo>(); public static AudioSource PersistentAudioSource { get; private set; } = null; private static AudioSource EffectsAudioSource { get; set; } = null; public static AudioSource YoutubeAudioSource { get; private set; } = null; public static bool IsInitialized { get; private set; } private static bool IsLoading { get; set; } public static bool IsYoutubeMode { get; private set; } public static Dictionary<string, int> SongHashToIndex { get; private set; } = new Dictionary<string, int>(); public static Dictionary<int, string> IndexToSongHash { get; private set; } = new Dictionary<int, string>(); public static PlaybackState CurrentPlaybackState { get; private set; } = PlaybackState.Stopped; public static int CurrentSongIndex { get; private set; } public static float CurrentPausedTime { get; private set; } public static AudioMaster Instance { get { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown if ((Object)(object)_instance == (Object)null) { _instance = Object.FindAnyObjectByType<AudioMaster>(); if ((Object)(object)_instance == (Object)null) { GameObject val = new GameObject("PersistentSpeakerAudioLoader"); _instance = val.AddComponent<AudioMaster>(); Object.DontDestroyOnLoad((Object)(object)val); if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)"[sPEAKer:AudioMaster] Created new instance and marked as DontDestroyOnLoad."); } } } return _instance; } } public static void EnsureInitialized() { if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)"[sPEAKer:AudioMaster] EnsureInitialized called."); } AudioMaster instance = Instance; if (!IsInitialized && !IsLoading) { if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)"[sPEAKer:AudioMaster] Not initialized, starting initialization..."); } ((MonoBehaviour)instance).StartCoroutine(instance.InitializeAsync()); } } private void Awake() { if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)"[sPEAKer:AudioMaster] Awake called."); } if ((Object)(object)_instance != (Object)null && (Object)(object)_instance != (Object)(object)this) { if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)"[sPEAKer:AudioMaster] Duplicate instance detected, destroying."); } Object.Destroy((Object)(object)((Component)this).gameObject); return; } _instance = this; Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject); if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)"[sPEAKer:AudioMaster] Instance set and marked as DontDestroyOnLoad."); } InitializeAudioSources(); SceneManager.sceneLoaded += OnSceneLoaded; if (!IsInitialized && !IsLoading) { ((MonoBehaviour)this).StartCoroutine(InitializeAsync()); } } private void InitializeAudioSources() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown AnimationCurve val = new AnimationCurve(); val.AddKey(0f, 1f); val.AddKey(0.1f, 0.9f); val.AddKey(0.3f, 0.6f); val.AddKey(0.6f, 0.3f); val.AddKey(1f, 0.05f); if ((Object)(object)PersistentAudioSource == (Object)null) { PersistentAudioSource = ((Component)this).gameObject.AddComponent<AudioSource>(); PersistentAudioSource.loop = false; PersistentAudioSource.playOnAwake = false; PersistentAudioSource.volume = 0.35f; PersistentAudioSource.minDistance = 2f; PersistentAudioSource.maxDistance = 25f; PersistentAudioSource.spatialBlend = 1f; PersistentAudioSource.dopplerLevel = 0.1f; PersistentAudioSource.spatialize = true; PersistentAudioSource.rolloffMode = (AudioRolloffMode)2; PersistentAudioSource.SetCustomCurve((AudioSourceCurveType)0, val); if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)"[sPEAKer:AudioMaster] Created persistent audio source."); } } if ((Object)(object)EffectsAudioSource == (Object)null) { EffectsAudioSource = ((Component)this).gameObject.AddComponent<AudioSource>(); EffectsAudioSource.playOnAwake = false; EffectsAudioSource.loop = false; EffectsAudioSource.spatialBlend = 1f; EffectsAudioSource.volume = 1f; EffectsAudioSource.minDistance = 2f; EffectsAudioSource.maxDistance = 25f; EffectsAudioSource.rolloffMode = (AudioRolloffMode)0; if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)"[sPEAKer:AudioMaster] Created effects audio source."); } } if ((Object)(object)YoutubeAudioSource == (Object)null) { YoutubeAudioSource = ((Component)this).gameObject.AddComponent<AudioSource>(); YoutubeAudioSource.playOnAwake = false; YoutubeAudioSource.loop = false; YoutubeAudioSource.spatialBlend = 1f; YoutubeAudioSource.volume = 0.35f; YoutubeAudioSource.minDistance = 2f; YoutubeAudioSource.maxDistance = 25f; YoutubeAudioSource.dopplerLevel = 0.1f; YoutubeAudioSource.spatialize = true; YoutubeAudioSource.rolloffMode = (AudioRolloffMode)2; YoutubeAudioSource.SetCustomCurve((AudioSourceCurveType)0, val); if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)"[sPEAKer:AudioMaster] Created YouTube audio source."); } } } [IteratorStateMachine(typeof(<InitializeAsync>d__61))] private IEnumerator InitializeAsync() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <InitializeAsync>d__61(0) { <>4__this = this }; } [IteratorStateMachine(typeof(<LoadBundleAudio>d__62))] private IEnumerator LoadBundleAudio() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <LoadBundleAudio>d__62(0) { <>4__this = this }; } [IteratorStateMachine(typeof(<LoadFolderAudio>d__63))] private IEnumerator LoadFolderAudio() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <LoadFolderAudio>d__63(0) { <>4__this = this }; } [IteratorStateMachine(typeof(<ProcessAudioFolder>d__64))] private IEnumerator ProcessAudioFolder(string folderPath) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <ProcessAudioFolder>d__64(0) { <>4__this = this, folderPath = folderPath }; } [IteratorStateMachine(typeof(<LoadAudioClipsFromMixtapes>d__65))] private IEnumerator LoadAudioClipsFromMixtapes(string basePath) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <LoadAudioClipsFromMixtapes>d__65(0) { <>4__this = this, basePath = basePath }; } [IteratorStateMachine(typeof(<LoadMixtape>d__66))] private IEnumerator LoadMixtape(string mixtapePath) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <LoadMixtape>d__66(0) { <>4__this = this, mixtapePath = mixtapePath }; } public void LoadAudioClipsFromBundle() { //IL_02f2: Unknown result type (might be due to invalid IL or missing references) //IL_02f8: Invalid comparison between Unknown and I4 //IL_0318: Unknown result type (might be due to invalid IL or missing references) //IL_031e: Invalid comparison between Unknown and I4 if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)"[sPEAKer:AudioMaster] Starting bundle audio loading..."); } string[] allAssetNames = Plugin.Bundle.GetAllAssetNames(); if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)("[sPEAKer:AudioMaster] Total assets in bundle: " + allAssetNames.Length)); Plugin.Log.LogInfo((object)"--- All Assets in Bundle ---"); string[] array = allAssetNames; foreach (string text in array) { Plugin.Log.LogInfo((object)(" -> " + text)); } Plugin.Log.LogInfo((object)"----------------------------"); } string[] array2 = allAssetNames.Where((string asset) => asset.Contains("jbl_fx") && asset.EndsWith(".ogg")).ToArray(); if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)$"[sPEAKer:AudioMaster] Found {array2.Length} JBL_FX assets:"); string[] array3 = array2; foreach (string text2 in array3) { Plugin.Log.LogInfo((object)(" -> " + text2)); } } string[] array4 = array2; foreach (string text3 in array4) { AudioClip clip2 = Plugin.Bundle.LoadAsset<AudioClip>(text3); string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(text3); SoundEffects.SetClip(fileNameWithoutExtension, clip2); } string text4 = allAssetNames.FirstOrDefault((string asset) => asset.Contains("whitenoise")); if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)("[sPEAKer:AudioMaster] Found whitenoise asset: " + (text4 ?? "NULL"))); } AudioClip clip3 = Plugin.Bundle.LoadAsset<AudioClip>(text4); SoundEffects.SetClip("whitenoise", clip3); string[] array5 = allAssetNames.Where((string asset) => asset.Contains("speaker audio") && asset.EndsWith(".ogg")).ToArray(); if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)("[sPEAKer:AudioMaster] Found " + array5.Length + " demo songs in bundle.")); string[] array6 = array5; foreach (string text5 in array6) { Plugin.Log.LogInfo((object)(" -> " + text5)); } } int num = 0; int num2 = 0; string[] array7 = array5; foreach (string text6 in array7) { if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)("[sPEAKer:AudioMaster] Loading bundle audio: " + text6)); } try { AudioClip clip = Plugin.Bundle.LoadAsset<AudioClip>(text6); if ((Object)(object)clip != (Object)null) { if ((int)clip.loadState == 2) { goto IL_0354; } clip.LoadAudioData(); if ((int)clip.loadState != 3) { goto IL_0354; } Plugin.Log.LogError((object)("[sPEAKer:AudioMaster] Failed to preload audio data for bundle clip: " + ((Object)clip).name)); num2++; } else { Plugin.Log.LogError((object)("[sPEAKer:AudioMaster] Failed to load audio clip from bundle: " + text6)); num2++; } goto end_IL_02b9; IL_0354: if (!LoadedAudioClips.Any((AudioClip c) => ((Object)c).name == ((Object)clip).name)) { LoadedAudioClips.Add(clip); string text7 = GenerateAudioHash(clip); int num3 = LoadedAudioClips.Count - 1; SongHashToIndex[text7] = num3; IndexToSongHash[num3] = text7; if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)("[sPEAKer:AudioMaster] Successfully loaded bundle audio: " + ((Object)clip).name + " (Length: " + clip.length + "s)")); } num++; } else if (Plugin.DebugMode) { Plugin.Log.LogWarning((object)("[sPEAKer:AudioMaster] Audio clip already loaded: " + ((Object)clip).name)); } end_IL_02b9:; } catch (Exception ex) { Plugin.Log.LogError((object)("[sPEAKer:AudioMaster] Exception loading " + text6 + ": " + ex.Message)); num2++; } } if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)("[sPEAKer:AudioMaster] Bundle loading complete. Success: " + num + ", Failed: " + num2 + ", Total clips now: " + LoadedAudioClips.Count)); } if (LoadedAudioClips.Count > 0 && Plugin.DebugMode) { Plugin.Log.LogInfo((object)"[sPEAKer:AudioMaster] All loaded clips:"); for (int n = 0; n < LoadedAudioClips.Count; n++) { Plugin.Log.LogInfo((object)(" [" + (n + 1) + "] " + ((Object)LoadedAudioClips[n]).name)); } } } public static void UpdatePlaybackState(PlaybackState newState, int songIndex = -1, float pausedTime = 0f) { CurrentPlaybackState = newState; if (songIndex >= 0) { CurrentSongIndex = songIndex; } CurrentPausedTime = pausedTime; if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)$"[sPEAKer:AudioMaster] Playback state updated - State: {newState}, Song: {CurrentSongIndex}, PausedTime: {pausedTime}"); } } public static void ResetPlaybackState() { CurrentPlaybackState = PlaybackState.Stopped; CurrentSongIndex = 0; CurrentPausedTime = 0f; if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)"[sPEAKer:AudioMaster] Playback state reset to defaults"); } } private string FormatDuration(float totalSeconds) { int num = Mathf.FloorToInt(totalSeconds / 60f); int num2 = Mathf.FloorToInt(totalSeconds % 60f); return $"{num}:{num2:00}"; } private string GenerateAudioHash(AudioClip clip) { string s = ((Object)clip).name + "|" + clip.length + "|" + clip.frequency; using MD5 mD = MD5.Create(); byte[] inArray = mD.ComputeHash(Encoding.UTF8.GetBytes(s)); return Convert.ToBase64String(inArray).Substring(0, 12); } public static MixtapeInfo GetMixtapeForSongIndex(int songIndex) { return AvailableMixtapes.FirstOrDefault((MixtapeInfo m) => m.ContainsSongIndex(songIndex)) ?? throw new InvalidOperationException(); } private AudioType GetAudioTypeFromExtension(string filePath) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_004d: 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_0046: 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) return (AudioType)(Path.GetExtension(filePath).ToLowerInvariant() switch { ".mp3" => 13, ".wav" => 20, ".ogg" => 14, _ => 0, }); } public static void PlayFX(AudioClip clip) { if (!((Object)(object)EffectsAudioSource == (Object)null) && !((Object)(object)clip == (Object)null)) { EffectsAudioSource.clip = clip; EffectsAudioSource.Play(); if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)("[sPEAKer:AudioMaster] Playing sound effect: " + ((Object)clip).name)); } } } public void SetVolume(float newVolume) { if ((Object)(object)PersistentAudioSource != (Object)null) { PersistentAudioSource.volume = Mathf.Clamp(newVolume, 0f, 1f); if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)("[sPEAKer:AudioMaster] Volume set to " + PersistentAudioSource.volume)); } } } public void SetFollow(Transform? target) { _targetTransform = target; _targetCharacter = null; _isFollowing = (Object)(object)target != (Object)null; if (Plugin.DebugMode) { if (_isFollowing) { Plugin.Log.LogInfo((object)("[sPEAKer:AudioMaster] Set to follow transform: " + ((Object)target).name)); } else { Plugin.Log.LogInfo((object)"[sPEAKer:AudioMaster] Stopped following."); } } } public void SetFollow(Character? target) { _targetCharacter = target; _targetTransform = null; _isFollowing = (Object)(object)target != (Object)null; if (Plugin.DebugMode) { if (_isFollowing) { Plugin.Log.LogInfo((object)("[sPEAKer:AudioMaster] Set to follow character: " + ((target != null) ? ((Object)target).name : null))); } else { Plugin.Log.LogInfo((object)"[sPEAKer:AudioMaster] Stopped following."); } } } public static void SetYoutubeMode(bool enabled) { IsYoutubeMode = enabled; if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)$"[sPEAKer:AudioMaster] YouTube mode set to {enabled}"); } } public static void PauseLocalAudio() { if ((Object)(object)PersistentAudioSource != (Object)null && PersistentAudioSource.isPlaying) { PersistentAudioSource.Pause(); if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)"[sPEAKer:AudioMaster] Local audio paused for YouTube mode"); } } } public static void ResumeLocalAudio() { if ((Object)(object)PersistentAudioSource != (Object)null && (Object)(object)PersistentAudioSource.clip != (Object)null) { PersistentAudioSource.UnPause(); if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)"[sPEAKer:AudioMaster] Local audio resumed from YouTube mode"); } } } public bool IsSpeakerActive() { if (_isFollowing && (Object)(object)_targetCharacter != (Object)null) { return true; } return false; } private void LateUpdate() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) if (_isFollowing) { Vector3 val = Vector3.zero; if ((Object)(object)_targetTransform != (Object)null) { val = _targetTransform.position; } else if ((Object)(object)_targetCharacter != (Object)null) { val = _targetCharacter.Center; } if ((Object)(object)PersistentAudioSource != (Object)null && ((Component)PersistentAudioSource).transform.position != val) { ((Component)PersistentAudioSource).transform.position = val; } if ((Object)(object)EffectsAudioSource != (Object)null && ((Component)EffectsAudioSource).transform.position != val) { ((Component)EffectsAudioSource).transform.position = val; } if ((Object)(object)YoutubeAudioSource != (Object)null && ((Component)YoutubeAudioSource).transform.position != val) { ((Component)YoutubeAudioSource).transform.position = val; } } } private void OnSceneLoaded(Scene scene, LoadSceneMode mode) { if (((Scene)(ref scene)).name == "Airport") { if ((Object)(object)PersistentAudioSource != (Object)null && PersistentAudioSource.isPlaying) { PersistentAudioSource.Stop(); } if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)"[sPEAKer:AudioMaster] Airport scene detected - stopped audio playback"); } } } private void OnDestroy() { if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)"[sPEAKer:AudioMaster] OnDestroy called."); } SceneManager.sceneLoaded -= OnSceneLoaded; if ((Object)(object)_instance == (Object)(object)this) { IsInitialized = false; IsLoading = false; } } } [Serializable] public class MixtapeMetadata { public string name; public string author; } public class MixtapeInfo { public string Name; public string Author; public string TotalLength; public int FirstSongIndex; public int LastSongIndex; public int SongCount; public string Path; public bool ContainsSongIndex(int index) { return index >= FirstSongIndex && index <= LastSongIndex; } } public enum PlaybackState { Stopped, Playing, Paused } public static class SoundEffects { public static AudioClip Connected { get; private set; } public static AudioClip Connecting { get; private set; } public static AudioClip Party { get; private set; } public static AudioClip TurnOn { get; private set; } public static AudioClip VolMax { get; private set; } public static AudioClip WhiteNoise { get; private set; } public static void SetClip(string filename, AudioClip clip) { switch (filename.ToLower().Replace(" ", "")) { case "connected": Connected = clip; break; case "connecting": Connecting = clip; break; case "party": Party = clip; break; case "turnon": TurnOn = clip; break; case "volmax": VolMax = clip; break; case "whitenoise": WhiteNoise = clip; break; } } } public class Controller : MonoBehaviourPun { [CompilerGenerated] private sealed class <DelayedUIUpdate>d__46 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public Controller <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <DelayedUIUpdate>d__46(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = null; <>1__state = 1; return true; case 1: <>1__state = -1; <>4__this._playbackState = AudioMaster.CurrentPlaybackState; <>4__this._currentSongIndex = AudioMaster.CurrentSongIndex; <>4__this._pausedTime = AudioMaster.CurrentPausedTime; <>4__this._isTurnedOn = <>4__this._playbackState != PlaybackState.Stopped; if (<>4__this._playbackState == PlaybackState.Playing) { <>4__this.item.UIData.mainInteractPrompt = "PAUSE"; } else if (<>4__this._playbackState == PlaybackState.Paused) { <>4__this.item.UIData.mainInteractPrompt = "PLAY"; } else { <>4__this.item.UIData.mainInteractPrompt = "TURN ON"; } if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)$"[sPEAKer:Controller] Delayed UI update - Final state: {<>4__this._playbackState}, Prompt: {<>4__this.item.UIData.mainInteractPrompt}"); } 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 <InitializeWhenReady>d__17 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public Controller <>4__this; private int <waitCount>5__1; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <InitializeWhenReady>d__17(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)"[sPEAKer:Controller] Waiting for AudioMaster to initialize..."); } <waitCount>5__1 = 0; break; case 1: <>1__state = -1; <waitCount>5__1++; break; } if (!AudioMaster.IsInitialized && <waitCount>5__1 < 50) { <>2__current = (object)new WaitForSeconds(0.1f); <>1__state = 1; return true; } if (!AudioMaster.IsInitialized) { Plugin.Log.LogError((object)"[sPEAKer:Controller] AudioMaster failed to initialize after 5 seconds!"); return false; } Item item = <>4__this.item; item.OnScrolled = (Action<float>)Delegate.Combine(item.OnScrolled, new Action<float>(<>4__this.HandleScroll)); <>4__this._currentAudioClips = AudioMaster.LoadedAudioClips.ToArray(); if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)("[sPEAKer:Controller] Loaded " + <>4__this._currentAudioClips.Length + " audio clips")); } AudioMaster.Instance.SetFollow(((Component)<>4__this).transform); <>4__this.SyncWithPersistentAudio(); <>4__this._isInitialized = 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 <MonitorPlayback>d__27 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public Controller <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <MonitorPlayback>d__27(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Expected O, but got Unknown //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)"[sPEAKer:Controller] OWNER: Playback monitor started."); } <>2__current = (object)new WaitUntil((Func<bool>)(() => (Object)(object)AudioMaster.PersistentAudioSource != (Object)null && AudioMaster.PersistentAudioSource.isPlaying)); <>1__state = 1; return true; case 1: <>1__state = -1; break; case 2: <>1__state = -1; break; } if (<>4__this._playbackState == PlaybackState.Playing && AudioMaster.PersistentAudioSource.isPlaying) { if (AudioMaster.IsYoutubeMode) { if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)"[sPEAKer:Controller] OWNER: Playback monitor ended - YouTube mode active."); } return false; } <>2__current = (object)new WaitForSeconds(0.5f); <>1__state = 2; return true; } if (<>4__this._playbackState == PlaybackState.Playing && !AudioMaster.IsYoutubeMode) { if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)"[sPEAKer:Controller] OWNER: Song finished. Automatically playing next track."); } <>4__this.NextSong(); } if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)"[sPEAKer:Controller] OWNER: Playback monitor ended."); } 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 <TurnOnSequence>d__22 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public Controller <>4__this; private float <waitTime>5__1; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <TurnOnSequence>d__22(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>4__this._isTurningOn = true; <>4__this.item.UIData.mainInteractPrompt = "..."; ((MonoBehaviourPun)<>4__this).photonView.RPC("RPC_PlayTurnOn", (RpcTarget)0, Array.Empty<object>()); <waitTime>5__1 = (((Object)(object)SoundEffects.TurnOn != (Object)null) ? SoundEffects.TurnOn.length : 0.5f); <>2__current = (object)new WaitForSeconds(<waitTime>5__1); <>1__state = 1; return true; case 1: <>1__state = -1; <>4__this._isTurnedOn = true; <>4__this._isTurningOn = false; <>4__this._playbackState = PlaybackState.Paused; <>4__this.item.UIData.mainInteractPrompt = "PLAY"; 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(); } } public Item item; private bool _isInitialized; private bool _isTurningOn; private bool _isTurnedOn; private bool _wasUsingPrimary; private bool _wasUsingSecondary; private int _currentSongIndex; private float _pausedTime; private PlaybackState _playbackState = PlaybackState.Stopped; private AudioClip[] _currentAudioClips; private Coroutine _monitorCoroutine; private const float VolumeStep = 0.05f; private bool _wasPocketed; private bool _isFollowingCharacter; private Character? _pocketedByCharacter; private int _followTargetPhotonViewID = -1; private void Start() { if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)("[sPEAKer:Controller] Start called for " + ((Object)((Component)this).gameObject).name)); } item = ((Component)this).GetComponent<Item>(); if ((Object)(object)item == (Object)null) { Plugin.Log.LogError((object)("[sPEAKer:Controller] No Item component found on " + ((Object)((Component)this).gameObject).name)); return; } AudioMaster.EnsureInitialized(); ((MonoBehaviour)this).StartCoroutine(InitializeWhenReady()); } [IteratorStateMachine(typeof(<InitializeWhenReady>d__17))] private IEnumerator InitializeWhenReady() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <InitializeWhenReady>d__17(0) { <>4__this = this }; } private void Update() { if (_isInitialized) { bool isUsingPrimary = item.isUsingPrimary; if (isUsingPrimary && !_wasUsingPrimary) { PrimaryUse(); } _wasUsingPrimary = isUsingPrimary; bool isUsingSecondary = item.isUsingSecondary; if (isUsingSecondary && !_wasUsingSecondary) { SecondaryUse(); } _wasUsingSecondary = isUsingSecondary; } } private void PrimaryUse() { if (_isTurningOn) { return; } if (AudioMaster.IsYoutubeMode) { } if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)$"[sPEAKer:Controller] Primary pressed. Current state: {_playbackState}"); } switch (_playbackState) { case PlaybackState.Stopped: if (!_isTurnedOn) { ((MonoBehaviour)this).StartCoroutine(TurnOnSequence()); break; } item.UIData.mainInteractPrompt = "PAUSE"; StartPlayback(); break; case PlaybackState.Playing: item.UIData.mainInteractPrompt = "PLAY"; PausePlayback(); break; case PlaybackState.Paused: item.UIData.mainInteractPrompt = "PAUSE"; ResumePlayback(); break; } } private void SecondaryUse() { if (!_isTurningOn) { NextSong(); } } private void HandleScroll(float scrollAmount) { if (!((Object)(object)AudioMaster.PersistentAudioSource == (Object)null) && ((MonoBehaviourPun)this).photonView.IsMine) { float volume = AudioMaster.PersistentAudioSource.volume; float num = volume; if (scrollAmount > 0f) { num += 0.05f; } else if (scrollAmount < 0f) { num -= 0.05f; } num = Mathf.Clamp(num, 0f, 1f); Netcode.Instance.SendVolumeChange(((MonoBehaviourPun)this).photonView, num); } } [IteratorStateMachine(typeof(<TurnOnSequence>d__22))] private IEnumerator TurnOnSequence() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <TurnOnSequence>d__22(0) { <>4__this = this }; } private void StartPlayback() { if (_currentAudioClips == null || _currentAudioClips.Length == 0 || (Object)(object)AudioMaster.PersistentAudioSource == (Object)null) { Plugin.Log.LogWarning((object)"[sPEAKer:Controller] Cannot start playback: no audio clips available"); return; } if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)"[sPEAKer:Controller] Starting playback..."); } Netcode.Instance.SendStartPlayback(((MonoBehaviourPun)this).photonView, _currentSongIndex); } private void PausePlayback() { if (_playbackState == PlaybackState.Playing) { float num = (((Object)(object)AudioMaster.PersistentAudioSource != (Object)null) ? AudioMaster.PersistentAudioSource.time : 0f); if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)$"[sPEAKer:Controller] Pausing at {num}s"); } Netcode.Instance.SendPausePlayback(((MonoBehaviourPun)this).photonView, num); } } private void ResumePlayback() { if (_playbackState == PlaybackState.Paused) { if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)$"[sPEAKer:Controller] Resuming from {_pausedTime}s"); } Netcode.Instance.SendResumePlayback(((MonoBehaviourPun)this).photonView, _pausedTime); } } private void NextSong() { if (PhotonNetwork.IsMasterClient) { AudioClip[] currentAudioClips = _currentAudioClips; if (currentAudioClips == null || currentAudioClips.Length <= 1) { if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)"[sPEAKer:Controller] Not enough songs to switch"); } return; } _currentSongIndex = (_currentSongIndex + 1) % _currentAudioClips.Length; if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)("[sPEAKer:Controller] Switching to song " + (_currentSongIndex + 1))); } string text = AudioMaster.IndexToSongHash[_currentSongIndex]; string name = ((Object)_currentAudioClips[_currentSongIndex]).name; ((MonoBehaviourPun)this).photonView.RPC("RPC_NextSong", (RpcTarget)0, new object[2] { text, name }); } else { ((MonoBehaviourPun)this).photonView.RPC("RPC_RequestNextSong", PhotonNetwork.MasterClient, Array.Empty<object>()); } } [IteratorStateMachine(typeof(<MonitorPlayback>d__27))] private IEnumerator MonitorPlayback() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <MonitorPlayback>d__27(0) { <>4__this = this }; } private void PlayCurrentSound() { if (_currentSongIndex < 0 || _currentSongIndex >= _currentAudioClips.Length) { Plugin.Log.LogError((object)("[sPEAKer:Controller] Invalid sound index: " + _currentSongIndex)); return; } if ((Object)(object)AudioMaster.PersistentAudioSource == (Object)null) { Plugin.Log.LogError((object)"[sPEAKer:Controller] Persistent audio source is null!"); return; } AudioClip val = _currentAudioClips[_currentSongIndex]; if ((Object)(object)val == (Object)null) { Plugin.Log.LogError((object)("[sPEAKer:Controller] Clip at index " + _currentSongIndex + " is null!")); return; } AudioMaster.PersistentAudioSource.clip = val; AudioMaster.PersistentAudioSource.Play(); if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)("[sPEAKer:Controller] Playing sound " + (_currentSongIndex + 1) + ": " + ((Object)val).name)); } MixtapeInfo mixtapeForSongIndex = AudioMaster.GetMixtapeForSongIndex(_currentSongIndex); if (mixtapeForSongIndex != null) { sPEAKerUI.Instance.ShowTrackName(mixtapeForSongIndex.Name + " - " + ((Object)val).name); } else { sPEAKerUI.Instance.ShowTrackName(((Object)val).name); } } private void HandleNetworkStartPlayback(string songHash, string songName) { if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)("[sPEAKer:Controller] CLIENT RECEIVED: HandleNetworkStartPlayback - songHash=" + songHash)); } _playbackState = PlaybackState.Playing; _pausedTime = 0f; if (AudioMaster.SongHashToIndex.TryGetValue(songHash, out var value)) { _currentSongIndex = value; PlayCurrentSound(); } else { if (Plugin.DebugMode) { Plugin.Log.LogWarning((object)"[sPEAKer:Controller] Song not available locally, playing white noise"); } AudioMaster.PersistentAudioSource.clip = SoundEffects.WhiteNoise; AudioMaster.PersistentAudioSource.Play(); sPEAKerUI.Instance.ShowTrackName(songName); } AudioMaster.UpdatePlaybackState(PlaybackState.Playing, _currentSongIndex); if (((MonoBehaviourPun)this).photonView.IsMine && !AudioMaster.IsYoutubeMode) { if (_monitorCoroutine != null) { ((MonoBehaviour)this).StopCoroutine(_monitorCoroutine); } _monitorCoroutine = ((MonoBehaviour)this).StartCoroutine(MonitorPlayback()); } } private void HandleNetworkPausePlayback(float pauseTime) { if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)$"[sPEAKer:Controller] HandleNetworkPausePlayback at {pauseTime}s"); } _playbackState = PlaybackState.Paused; _pausedTime = pauseTime; AudioMaster.UpdatePlaybackState(PlaybackState.Paused, _currentSongIndex, pauseTime); if ((Object)(object)AudioMaster.PersistentAudioSource != (Object)null && AudioMaster.PersistentAudioSource.isPlaying) { AudioMaster.PersistentAudioSource.Pause(); } if (((MonoBehaviourPun)this).photonView.IsMine && _monitorCoroutine != null) { ((MonoBehaviour)this).StopCoroutine(_monitorCoroutine); _monitorCoroutine = null; } } private void HandleNetworkResumePlayback(float resumeTime) { if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)$"[sPEAKer:Controller] HandleNetworkResumePlayback from {resumeTime}s"); } _playbackState = PlaybackState.Playing; _pausedTime = resumeTime; AudioMaster.UpdatePlaybackState(PlaybackState.Playing, _currentSongIndex, resumeTime); if ((Object)(object)AudioMaster.PersistentAudioSource != (Object)null) { if ((Object)(object)AudioMaster.PersistentAudioSource.clip == (Object)null) { PlayCurrentSound(); } AudioMaster.PersistentAudioSource.time = resumeTime; AudioMaster.PersistentAudioSource.UnPause(); } if (((MonoBehaviourPun)this).photonView.IsMine && !AudioMaster.IsYoutubeMode) { if (_monitorCoroutine != null) { ((MonoBehaviour)this).StopCoroutine(_monitorCoroutine); } _monitorCoroutine = ((MonoBehaviour)this).StartCoroutine(MonitorPlayback()); } } private void HandleNetworkStopPlayback() { if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)"[sPEAKer:Controller] HandleNetworkStopPlayback called"); } _playbackState = PlaybackState.Stopped; _pausedTime = 0f; AudioMaster.UpdatePlaybackState(PlaybackState.Stopped, 0); if ((Object)(object)AudioMaster.PersistentAudioSource != (Object)null && AudioMaster.PersistentAudioSource.isPlaying) { AudioMaster.PersistentAudioSource.Stop(); AudioMaster.PersistentAudioSource.clip = null; } if (((MonoBehaviourPun)this).photonView.IsMine && _monitorCoroutine != null) { ((MonoBehaviour)this).StopCoroutine(_monitorCoroutine); _monitorCoroutine = null; } } private void HandleNetworkNextSong(string songHash, string songName) { if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)("[sPEAKer:Controller] HandleNetworkNextSong called - songHash=" + songHash)); } if (_playbackState != PlaybackState.Playing) { return; } if (AudioMaster.SongHashToIndex.TryGetValue(songHash, out var value)) { _currentSongIndex = value; PlayCurrentSound(); } else { if (Plugin.DebugMode) { Plugin.Log.LogWarning((object)"[sPEAKer:Controller] Song not available for next song, playing white noise"); } AudioMaster.PersistentAudioSource.clip = SoundEffects.WhiteNoise; AudioMaster.PersistentAudioSource.Play(); sPEAKerUI.Instance.ShowTrackName(songName); } AudioMaster.UpdatePlaybackState(PlaybackState.Playing, _currentSongIndex); if (((MonoBehaviourPun)this).photonView.IsMine) { if (_monitorCoroutine != null) { ((MonoBehaviour)this).StopCoroutine(_monitorCoroutine); } _monitorCoroutine = ((MonoBehaviour)this).StartCoroutine(MonitorPlayback()); } } private void HandleNetworkVolumeChange(float newVolume) { if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)("[sPEAKer:Controller] HandleNetworkVolumeChange called with value " + newVolume)); } AudioMaster.Instance.SetVolume(newVolume); } [PunRPC] private void RPC_StartPlayback(string songHash, string songName) { if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)("[sPEAKer:Controller] RPC_StartPlayback called - hash=" + songHash + ", name=" + songName)); } HandleNetworkStartPlayback(songHash, songName); Netcode.Instance.CachedPlaybackState = 1; Netcode.Instance.CachedSongHash = songHash; Netcode.Instance.CachedSongName = songName; } [PunRPC] private void RPC_PausePlayback(float pauseTime) { if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)$"[sPEAKer:Controller] RPC_PausePlayback at {pauseTime}s"); } HandleNetworkPausePlayback(pauseTime); Netcode.Instance.CachedPlaybackState = 2; } [PunRPC] private void RPC_ResumePlayback(float resumeTime) { if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)$"[sPEAKer:Controller] RPC_ResumePlayback from {resumeTime}s"); } HandleNetworkResumePlayback(resumeTime); Netcode.Instance.CachedPlaybackState = 1; } [PunRPC] private void RPC_StopPlayback() { if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)"[sPEAKer:Controller] RPC_StopPlayback called"); } HandleNetworkStopPlayback(); Netcode.Instance.CachedPlaybackState = 0; } [PunRPC] private void RPC_NextSong(string songHash, string songName) { if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)("[sPEAKer:Controller] RPC_NextSong called - hash=" + songHash + ", name=" + songName)); } HandleNetworkNextSong(songHash, songName); Netcode.Instance.CachedSongHash = songHash; Netcode.Instance.CachedSongName = songName; } [PunRPC] private void RPC_RequestNextSong() { if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)"[sPEAKer:Controller] RPC_RequestNextSong called"); } if (PhotonNetwork.IsMasterClient) { SecondaryUse(); } } [PunRPC] private void RPC_SetVolume(float newVolume) { if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)$"[sPEAKer:Controller] RPC_SetVolume called with value {newVolume}"); } HandleNetworkVolumeChange(newVolume); } [PunRPC] private void RPC_PlayTurnOn() { if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)"[sPEAKer:Controller] RPC_PlayTurnOn called"); } AudioMaster.PlayFX(SoundEffects.TurnOn); } private void OnDestroy() { if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)"[sPEAKer:Controller] OnDestroy called"); } if ((Object)(object)item != (Object)null) { Item obj = item; obj.OnScrolled = (Action<float>)Delegate.Remove(obj.OnScrolled, new Action<float>(HandleScroll)); } } private void OnDisable() { if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)"[sPEAKer:Controller] OnDisable called - Speaker being pocketed"); } if (!((Object)(object)item == (Object)null) && !((Object)(object)item.lastHolderCharacter == (Object)null)) { _wasPocketed = true; _pocketedByCharacter = item.lastHolderCharacter; AudioMaster.Instance.SetFollow(_pocketedByCharacter); _followTargetPhotonViewID = ((MonoBehaviourPun)_pocketedByCharacter).photonView.ViewID; _isFollowingCharacter = true; Netcode.Instance.CachedFollowViewID = _followTargetPhotonViewID; Netcode.Instance.CachedIsFollowingCharacter = _isFollowingCharacter; } } private void OnEnable() { if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)$"[sPEAKer:Controller] OnEnable called - Speaker being unpocketed. {_wasPocketed} {(Object)(object)AudioMaster.Instance == (Object)null}"); } Netcode.Instance.CachedFollowViewID = _followTargetPhotonViewID; Netcode.Instance.CachedIsFollowingCharacter = _isFollowingCharacter; ((MonoBehaviour)this).StartCoroutine(DelayedUIUpdate()); } [IteratorStateMachine(typeof(<DelayedUIUpdate>d__46))] private IEnumerator DelayedUIUpdate() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <DelayedUIUpdate>d__46(0) { <>4__this = this }; } private void SyncWithPersistentAudio() { if ((Object)(object)AudioMaster.PersistentAudioSource == (Object)null || !AudioMaster.PersistentAudioSource.isPlaying) { if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)"[sPEAKer:Controller] No active playback to sync with."); } return; } _playbackState = PlaybackState.Playing; _isTurnedOn = true; _currentSongIndex = AudioMaster.CurrentSongIndex; if (_currentSongIndex >= 0 && _currentSongIndex < _currentAudioClips.Length) { AudioClip clip = AudioMaster.PersistentAudioSource.clip; AudioClip val = _currentAudioClips[_currentSongIndex]; if ((Object)(object)clip != (Object)null && (Object)(object)val != (Object)null && ((Object)clip).name == ((Object)val).name) { if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)("[sPEAKer:Controller] Synced with existing playback - song " + (_currentSongIndex + 1) + ": " + ((Object)val).name)); } } else if (Plugin.DebugMode) { Plugin.Log.LogInfo((object)"[sPEAKer:Controller] Song mismatch detected during sync - client might be playing white noise"); } } else { if (Plugin.DebugMode) { Plugin.Log.LogWarning((object)("[sPEAKer:Controller] Invalid song index during sync: " + _currentSongIndex)); } _currentSongIndex = 0; } if (((MonoBehaviourPun)this).photonView.IsMine) { if (_monitorCoroutine != null) { ((MonoBehaviour)this).StopCoroutine(_monitorCoroutine); } _monitorCoroutine = ((MonoBehaviour)this).StartCoroutine(MonitorPlayback()); } } public void LogAllComponents() { Plugin.Log.LogInfo((object)("[sPEAKer:Controller] Starting component discovery for " + ((Object)((Component)this).gameObject).name)); LogComponentsRecursive(((Component)this).gameObject, 0); } private void LogComponentsRecursive(GameObject obj, int depth) { string text = new string(' ', depth * 2); Plugin.Log.LogInfo((object)("[sPEAKer:Controller] " + text + "GameObject: " + ((Object)obj).name)); Component[] components = obj.GetComponents<Component>(); Component[] array = components; foreach (Component val in array) { if ((Object)(object)val == (Object)null) { continue; } string name = ((object)val).GetType().Name; if (name == "Controller" || name == "Netcode") { continue; } Plugin.Log.LogInfo((object)("[sPEAKer:Controller] " + text + " Component: " + name)); PhotonView val2 = (PhotonView)(object)((val is PhotonView) ? val : null); if (val2 != null) { ManualLogSource log = Plugin.Log; object[] obj2 = new object[4] { text, val2.ViewID, val2.IsMine, null }; Player owner = val2.Owner; obj2[3] = ((owner != null) ? owner.NickName : null) ?? "null"; log.LogInfo((object)string.Format("[sPEAKer:Controller] {0} ViewID: {1}, IsMine: {2}, Owner: {3}", obj2)); } Renderer val3 = (Renderer)(object)((val is Renderer) ? val : null); if (val3 != null) { Plugin.Log.LogInfo((object)$"[sPEAKer:Controller] {text} Enabled: {val3.enabled}, Visible: {val3.isVisible}"); } if (!(((object)val).GetType().Name == "Item")) { continue; } Type type = ((object)val).GetType(); FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); PropertyInfo[] properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); Plugin.Log.LogInfo((object)("[sPEAKer:Controller] " + text + " Item Fields:")); FieldInfo[] array2 = fields; foreach (FieldInfo fieldInfo in array2) { try { object value = fieldInfo.GetValue(val); Plugin.Log.LogInfo((object)$"[sPEAKer:Controller] {text} {fieldInfo.Name}: {value}"); } catch { Plugin.Log.LogInfo((object)("[sPEAKer:Controller] " + text + " " + fieldInfo.Name + ": <access error>")); } } Plugin.Log.LogInfo((object)("[sPEAKer:Controller] " + text + " Item Properties:")); PropertyInfo[] array3 = properties; foreach (PropertyInfo propertyInfo in array3) { if (propertyInfo.CanRead) { try { object value2 = propertyInfo.GetValue(val); Plugin.Log.LogInfo((object)$"[sPEAKer:Controller] {text} {propertyInfo.Name}: {value2}"); } catch { Plugin.Log.LogInfo((object)("[sPEAKer:Controller] " + text + " " + propertyInfo.Name + ": <access error>")); } } } } for (int l = 0; l < obj.transform.childCount; l++) { LogComponentsRecursive(((Component)obj.transform.GetChild(l)).gameObject, depth + 1); } } public void KillYourself() { PhotonNetwork.Destroy(((Component)this).gameObject); } } public class Netcode : MonoBehaviourPunCallbacks { [CompilerGenerated] private sealed class <DelayedSyncSend>d__35 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public int targetActorNumber; public Netcode <>4__this; private float <currentTime>5__1; private float <currentVolume>5__2; private NetworkSyncData <syncData>5__3; private Player <targetPlayer>5__4; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <DelayedSyncSend>d__35(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <syncData>5__3 = null; <targetPlayer>5__4 = null; <>1__state = -2; } private bool MoveNext() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds(2f); <>1__state = 1; return true; case 1: <>1__state = -1; <currentTime>5__1 = 0f; <currentVolume>5__2 = 0.35f; if ((Object)(object)AudioMaster.PersistentAudioSource != (Object)null) { <currentTime>5__1 = AudioMaster.PersistentAudioSource.time; <currentVolume>5__2 = AudioMaster.PersistentAudioSource.volume; } <syncData>5__3 = new NetworkSyncData { PlaybackStateInt = (int)AudioMaster.CurrentPlaybackState, SongHash = ((AudioMaster.CurrentPlaybackState != 0) ? AudioMaster.IndexToSongHash.GetValueOrDefault(AudioMaster.CurrentSongIndex, "") : ""), SongName = ((AudioMaster.CurrentPlaybackState != 0 && AudioMaster.CurrentSongIndex < AudioMaster.LoadedAudioClips.Count) ? ((Object)AudioMaster.LoadedAudioClips[AudioMaste