Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of CarretaFuracao v0.7.9
BepInEx\plugins\CarretaFuracao\CarretaFuracao.dll
Decompiled 2 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.Diagnostics; using System.IO; using System.IO.Compression; using System.Linq; using System.Net.Http; using System.Net.Http.Headers; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using BoomBoxCartMod.Patches; using BoomBoxCartMod.Util; using ExitGames.Client.Photon; using HarmonyLib; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using Photon.Pun; using Photon.Realtime; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; using UnityEngine.Networking; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("CarretaFuracao")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("CarretaFuracao")] [assembly: AssemblyCopyright("Copyright © 2025")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("37e852e0-b511-4315-8182-68c0a54e1ba9")] [assembly: AssemblyFileVersion("0.7.9.0")] [assembly: AssemblyVersion("0.7.9.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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 BoomBoxCartMod { [BepInPlugin("LucasGPT.CarretaFuracao", "CarretaFuracao", "0.7.9")] public class BoomBoxCartMod : BaseUnityPlugin { public enum VisualizerPaused { Show, PausePosition, Hide } public enum CookieUsage { OFF, FILE, BROWSER } public enum BrowserType { chrome, firefox, edge, brave, safari } public const string modGUID = "LucasGPT.CarretaFuracao"; public const string modName = "CarretaFuracao"; public const string modVersion = "0.7.9"; private readonly Harmony harmony = new Harmony("LucasGPT.CarretaFuracao"); public BaseListener baseListener; internal static BoomBoxCartMod instance; internal ManualLogSource logger; public PersistentData data; private bool _modDisabled; private bool resourcesReinstalling; public bool initialized { get; private set; } public bool modDisabled { get { return _modDisabled; } set { if (_modDisabled != value) { logger.LogInfo((object)("Mod " + (value ? "Disabled" : "Enabled"))); } _modDisabled = value; if (!value || data == null) { return; } foreach (Boombox allBoombox in data.GetAllBoomboxes()) { PhotonView photonView = allBoombox.photonView; Object.Destroy((Object)(object)allBoombox); if (photonView != null) { photonView.RefreshRpcMonoBehaviourCache(); } } data.GetAllBoomboxes().Clear(); data.GetBoomboxData().Clear(); } } public ConfigEntry<CookieUsage> CookiePassthrough { get; private set; } public ConfigEntry<string> CookiePath { get; private set; } public ConfigEntry<BrowserType> Browser { get; private set; } public ConfigEntry<int> DownloadSpeed { get; private set; } public ConfigEntry<Key> OpenUIKey { get; private set; } public ConfigEntry<Key> MenuKey { get; private set; } public ConfigEntry<Key> GlobalMuteKey { get; private set; } public ConfigEntry<bool> MasterClientDismissQueue { get; private set; } public ConfigEntry<bool> UseTimeStampOnce { get; private set; } public ConfigEntry<bool> RestoreBoomboxes { get; private set; } public ConfigEntry<bool> AutoResume { get; private set; } public ConfigEntry<float> UnderglowBeatSpeed { get; private set; } public ConfigEntry<float> UnderglowBassBias { get; private set; } public ConfigEntry<VisualizerPaused> VisualizerBehaviourPaused { get; private set; } public ConfigEntry<bool> SyncVisuals { get; private set; } public ConfigEntry<bool> ReinstallResources { get; private set; } private void Update() { Boombox.TickRuntime(); } private void Awake() { //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Expected O, but got Unknown //IL_021d: Unknown result type (might be due to invalid IL or missing references) //IL_0227: Expected O, but got Unknown //IL_025b: Unknown result type (might be due to invalid IL or missing references) //IL_0265: Expected O, but got Unknown if ((Object)(object)instance == (Object)null) { instance = this; } data = new PersistentData(); logger = Logger.CreateLogSource("LucasGPT.CarretaFuracao"); logger.LogInfo((object)"BoomBoxCartMod loaded!"); logger.LogInfo((object)"CarretaFuracao 0.7.9"); AudioSettings.Initialize(((BaseUnityPlugin)this).Config); LocalMusic.Initialize(); harmony.PatchAll(); CookiePassthrough = ((BaseUnityPlugin)this).Config.Bind<CookieUsage>("Downloader", "CookiePassthrough", CookieUsage.OFF, "Pass cookies from either your browser or an exported file. (OFF, FILE, BROWSER)"); CookiePath = ((BaseUnityPlugin)this).Config.Bind<string>("Downloader", "CustomCookiePath", "", "Path to where the browser cookies are located, if the browser selection does not work."); Browser = ((BaseUnityPlugin)this).Config.Bind<BrowserType>("Downloader", "BrowserCookies", BrowserType.firefox, "Select the browser you are using for cookies (chrome, firefox, edge, brave, safari). This is unlikely to work."); DownloadSpeed = ((BaseUnityPlugin)this).Config.Bind<int>("Downloader", "DownloadSpeed", 10, new ConfigDescription("Estimated download speed in Mbps (not MBps). Used for download timeout estimation.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 100), Array.Empty<object>())); OpenUIKey = ((BaseUnityPlugin)this).Config.Bind<Key>("Binds", "OpenUIKey", (Key)19, "Press E to turn CarretaFuracao on/off while grabbing the cart."); MenuKey = ((BaseUnityPlugin)this).Config.Bind<Key>("Binds", "MenuKey", (Key)39, "Press Y to open/close the compact CarretaFuracao controls while grabbing the cart."); GlobalMuteKey = ((BaseUnityPlugin)this).Config.Bind<Key>("Binds", "GlobalMuteKey", (Key)27, "Key to mute all playback."); MasterClientDismissQueue = ((BaseUnityPlugin)this).Config.Bind<bool>("Queue", "MasterClientDismissQueue", true, "Allow only the master client to dismiss the queue."); UseTimeStampOnce = ((BaseUnityPlugin)this).Config.Bind<bool>("Queue", "UseTimeStampOnce", false, "Only use the timestamp provided with a Url the first time the song is played."); RestoreBoomboxes = ((BaseUnityPlugin)this).Config.Bind<bool>("Queue", "RestoreBoomboxes", true, "Restore BoomBoxes and their Queues when you load back into a level."); AutoResume = ((BaseUnityPlugin)this).Config.Bind<bool>("Queue", "AutoResume", false, "Automatically resume playback when entering a new lobby."); UnderglowBeatSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Visual", "UnderglowBeatSpeed", 1.2f, new ConfigDescription("Scales how much detected beat energy speeds up the RGB underglow cycle. 0 = disabled, 6 = more aggressive.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 6f), Array.Empty<object>())); UnderglowBassBias = ((BaseUnityPlugin)this).Config.Bind<float>("Visual", "UnderglowBassBias", 0.8f, new ConfigDescription("Blends between broad beat response and isolated low-band response. 0 = broad response, 1 = strongest bass isolation.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>())); VisualizerBehaviourPaused = ((BaseUnityPlugin)this).Config.Bind<VisualizerPaused>("Visual", "VisualizerOnPaused", VisualizerPaused.Hide, "Visualizer behaviour when music is paused."); SyncVisuals = ((BaseUnityPlugin)this).Config.Bind<bool>("Visual", "SyncVisuals", true, "Sync if underglow/visualizer are enabled with the lobby, or only apply it to yourself."); ReinstallResources = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "ReinstallResources", false, "Reinstall resources on startup."); ReinstallResources.SettingChanged += delegate(object s, EventArgs _) { if (initialized) { ConfigEntry<bool> val = (ConfigEntry<bool>)s; if (resourcesReinstalling) { if (!val.Value) { val.Value = true; } } else if (YoutubeDL.IsUpdatingResources) { logger.LogInfo((object)"Already updating resources..."); val.Value = false; } else { if (val.Value) { logger.LogInfo((object)"Reinstalling resources..."); resourcesReinstalling = true; } Task.Run(async delegate { await YoutubeDL.Reinstall(); logger.LogInfo((object)"Finished reinstalling resources."); ReinstallResources.Value = false; resourcesReinstalling = false; }); } } }; logger.LogInfo((object)"BoomBoxCartMod initialization finished!"); initialized = true; } private void Start() { if (ReinstallResources.Value) { ReinstallResources.Value = true; } else { logger.LogInfo((object)"CarretaFuracao: modo local pronto. Downloader online nao sera inicializado no startup."); } } private void OnDestroy() { YoutubeDL.CleanUp(); } } public class AudioPlayer : MonoBehaviourPunCallbacks { private static BoomBoxCartMod Instance = BoomBoxCartMod.instance; public float minDistance = 3f; public float maxDistanceBase = 15f; public float maxDistanceAddition = 30f; private static int qualityLevel = 4; private AudioLowPassFilter lowPassFilter; private AudioEchoFilter cartDelay; public AudioSource audioSource; public string currentUrl; private static ManualLogSource Logger => Instance.logger; private void Awake() { audioSource = ((Component)this).gameObject.AddComponent<AudioSource>(); audioSource.volume = 0.15f; audioSource.spatialBlend = 1f; audioSource.playOnAwake = false; audioSource.rolloffMode = (AudioRolloffMode)2; audioSource.spread = 90f; audioSource.dopplerLevel = 0f; audioSource.reverbZoneMix = 1f; audioSource.spatialize = true; audioSource.loop = false; audioSource.mute = Instance.baseListener.audioMuted; lowPassFilter = ((Component)this).gameObject.AddComponent<AudioLowPassFilter>(); ((Behaviour)lowPassFilter).enabled = false; UpdateAudioRangeBasedOnVolume(); } private void Update() { if (Instance.baseListener.audioMuted != audioSource.mute) { audioSource.mute = Instance.baseListener.audioMuted; } } public AudioClip GetClip() { if (!((Object)(object)audioSource == (Object)null)) { return audioSource.clip; } return null; } public void SetDelayedOutput(bool delayed) { if ((Object)(object)cartDelay == (Object)null && delayed) { cartDelay = ((Component)this).gameObject.AddComponent<AudioEchoFilter>(); cartDelay.delay = 25f; cartDelay.decayRatio = 0f; cartDelay.dryMix = 0f; cartDelay.wetMix = 1f; } if ((Object)(object)cartDelay != (Object)null) { ((Behaviour)cartDelay).enabled = delayed; } } public void SetVolume(float volume) { audioSource.volume = volume; UpdateAudioRangeBasedOnVolume(); } public void UpdateAudioRangeBasedOnVolume() { UpdateAudioRangeBasedOnVolume(audioSource.volume); } public void UpdateAudioRangeBasedOnVolume(float volume) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Expected O, but got Unknown float num = Mathf.Lerp(maxDistanceBase, maxDistanceBase + maxDistanceAddition, volume); audioSource.minDistance = minDistance; audioSource.maxDistance = num; AnimationCurve val = new AnimationCurve((Keyframe[])(object)new Keyframe[3] { new Keyframe(0f, 1f), new Keyframe(minDistance, 0.9f), new Keyframe(num, 0f) }); audioSource.SetCustomCurve((AudioSourceCurveType)0, val); } public void SetClip(string url) { if (url != null && (!(url == currentUrl) || !((Object)(object)audioSource.clip != (Object)null)) && DownloadHelper.downloadedClips.TryGetValue(url, out var value) && (Object)(object)value != (Object)null) { audioSource.clip = value; currentUrl = url; } } public void SetQuality(int level) { qualityLevel = Mathf.Clamp(level, 0, 4); switch (qualityLevel) { case 0: ((Behaviour)lowPassFilter).enabled = true; lowPassFilter.cutoffFrequency = 1500f; break; case 1: ((Behaviour)lowPassFilter).enabled = true; lowPassFilter.cutoffFrequency = 3000f; break; case 2: ((Behaviour)lowPassFilter).enabled = true; lowPassFilter.cutoffFrequency = 4500f; break; case 3: ((Behaviour)lowPassFilter).enabled = true; lowPassFilter.cutoffFrequency = 6000f; break; case 4: ((Behaviour)lowPassFilter).enabled = false; break; } } public static int GetQuality() { return qualityLevel; } public float GetTime() { return audioSource.time; } public void SetTime(float time) { if ((Object)(object)audioSource.clip != (Object)null && time > audioSource.clip.length) { time = Mathf.Max(0f, audioSource.clip.length - 0.05f); Logger.LogDebug((object)$"SetTime: Clamped time from {audioSource.time} to {time} (clip length: {audioSource.clip.length})"); } audioSource.time = time; } public bool IsPlaying() { return audioSource.isPlaying; } public bool SongReachedEnd() { if ((Object)(object)audioSource.clip != (Object)null) { return audioSource.time >= Math.Max(0f, audioSource.clip.length - 0.05f); } return false; } public void Play() { audioSource.Play(); } public void Pause() { audioSource.Pause(); } public void Stop() { if (!((Object)(object)audioSource == (Object)null)) { audioSource.Stop(); audioSource.clip = null; currentUrl = null; } } private void OnDestroy() { Stop(); Object.Destroy((Object)(object)lowPassFilter); if ((Object)(object)cartDelay != (Object)null) { Object.Destroy((Object)(object)cartDelay); } Object.Destroy((Object)(object)audioSource); } } public class Boombox : MonoBehaviourPunCallbacks { private class SharedAudioEntry { public string title; public string url; public double duration; public int startTime; } public class BoomboxData { public string key = Guid.NewGuid().ToString(); public AudioEntry currentSong; public List<AudioEntry> playbackQueue = new List<AudioEntry>(); public bool isPlaying; public float absVolume = AudioSettings.MasterValue; public float personalVolumePercentage = AudioSettings.PersonalValue; public bool loopQueue; public bool delayedOutput; public bool underglowEnabled; public bool visualizerEnabled = true; public bool pendingPlaybackStart; public int stateVersion; public int playbackTime; public int playbackStartTimestamp; } public class AudioEntry { public string Title; public string Url; public double Duration = -1.0; public int StartTime; public AudioEntry(string url, SongInfo info) { Url = url; Title = info.title; Duration = info.duration; } private int PeekStartTime(Boombox boombox) { if (boombox.data != null && boombox.data.playbackTime != 0) { return boombox.data.playbackTime; } return StartTime; } public int UseStartTime(Boombox boombox) { int result = PeekStartTime(boombox); if (boombox.data != null && boombox.data.playbackTime != 0) { boombox.data.playbackTime = 0; return result; } if (Instance.UseTimeStampOnce.Value) { StartTime = 0; } return result; } public bool ClipLoaded() { if (DownloadHelper.downloadedClips.ContainsKey(Url)) { return (Object)(object)DownloadHelper.downloadedClips[Url] != (Object)null; } return false; } } public PhotonView photonView; public AudioPlayer audioPlayer; public Visualizer visualizer; public VisualEffects visualEffects; public DownloadHelper downloadHelper; private bool syncFinished; public bool startPlayBackOnDownload = true; public BoomboxData data = new BoomboxData(); private static bool mutePressed = false; private bool isApplyingSharedState; private string pendingCurrentSongDownloadUrl; private int lastAppliedSharedStateVersion = -1; private Hashtable lastSharedState; private static readonly List<string> levelPlaylistOrderKeys = new List<string>(); private static int levelPlaylistIndex = 0; private static bool levelHasStartedPlayback = false; private static readonly HashSet<Boombox> liveCarretas = new HashSet<Boombox>(); private static int lastRuntimeFrame = -1; private static int lastGlobalAdvanceServerTimestamp = int.MinValue; private float nextFollowerSyncTime; private bool runtimeStartLogged; private string nextPreparedUrl; private float monsterAttractTimer; private const float monsterAttractInterval = 1f; private static bool applyQualityToDownloads = false; private static bool monstersCanHearMusic = false; private static BoomBoxCartMod Instance => BoomBoxCartMod.instance; private static ManualLogSource Logger => Instance.logger; public static bool ApplyQualityToDownloads { get { return applyQualityToDownloads; } set { applyQualityToDownloads = value; } } public static bool MonstersCanHearMusic { get { return monstersCanHearMusic; } set { monstersCanHearMusic = value; } } public bool LoopQueue { get { return data.loopQueue; } set { data.loopQueue = value; } } private void Awake() { audioPlayer = ((Component)this).gameObject.AddComponent<AudioPlayer>(); downloadHelper = ((Component)this).gameObject.AddComponent<DownloadHelper>(); photonView = ((Component)this).GetComponent<PhotonView>(); if ((Object)(object)photonView == (Object)null) { Logger.LogError((object)"PhotonView not found on Boombox object."); return; } if ((Object)(object)((Component)this).GetComponent<BoomboxController>() == (Object)null) { ((Component)this).gameObject.AddComponent<BoomboxController>(); } if ((Object)(object)((Component)this).GetComponent<Visualizer>() == (Object)null) { visualizer = ((Component)this).gameObject.AddComponent<Visualizer>(); visualizer.audioSource = audioPlayer.audioSource; } if ((Object)(object)((Component)this).GetComponent<VisualEffects>() == (Object)null) { visualEffects = ((Component)this).gameObject.AddComponent<VisualEffects>(); } RegisterRuntimeCart(this); PersistentData.SetBoomboxViewInitialized(photonView.ViewID); Logger.LogInfo((object)$"Boombox initialized on this cart. AudioPlayer: {audioPlayer}, PhotonView: {photonView}"); } private void Start() { audioPlayer.SetVolume(data.absVolume * data.personalVolumePercentage); audioPlayer.SetDelayedOutput(data.delayedOutput); ApplyVisualStateFromData(); LoadSharedStateFromRoom(); } public static void ResetLevelPlaylistSession() { levelPlaylistOrderKeys.Clear(); levelPlaylistIndex = 0; levelHasStartedPlayback = false; lastGlobalAdvanceServerTimestamp = int.MinValue; if (!PhotonNetwork.IsMasterClient) { return; } List<LocalMusic.LocalTrack> list = new List<LocalMusic.LocalTrack>(LocalMusic.Tracks); Random random = new Random(Guid.NewGuid().GetHashCode()); for (int num = list.Count - 1; num > 0; num--) { int index = random.Next(num + 1); LocalMusic.LocalTrack value = list[num]; list[num] = list[index]; list[index] = value; } foreach (LocalMusic.LocalTrack item in list) { if (item != null && !string.IsNullOrWhiteSpace(item.Key)) { levelPlaylistOrderKeys.Add(item.Key); } } BoomBoxCartMod instance = BoomBoxCartMod.instance; if (instance != null) { ManualLogSource logger = instance.logger; if (logger != null) { logger.LogInfo((object)("CarretaFuracao: nova ordem do level criada com " + levelPlaylistOrderKeys.Count + " faixa(s).")); } } int i; for (i = 0; i < levelPlaylistOrderKeys.Count; i++) { LocalMusic.LocalTrack localTrack = LocalMusic.Tracks.FirstOrDefault((LocalMusic.LocalTrack item) => item != null && item.Key == levelPlaylistOrderKeys[i]); BoomBoxCartMod instance2 = BoomBoxCartMod.instance; if (instance2 != null) { ManualLogSource logger2 = instance2.logger; if (logger2 != null) { logger2.LogInfo((object)(" ORDEM " + (i + 1) + ": " + ((localTrack != null) ? localTrack.Title : levelPlaylistOrderKeys[i]))); } } } } private void EnsureLevelPlaylistSession() { if (PhotonNetwork.IsMasterClient && (levelPlaylistOrderKeys.Count != LocalMusic.Tracks.Count || levelPlaylistOrderKeys.Any((string key) => FindLocalTrackByKey(key) == null))) { ResetLevelPlaylistSession(); } } private int GetLevelPlaylistIndexForKey(string key) { if (string.IsNullOrWhiteSpace(key)) { return -1; } return levelPlaylistOrderKeys.IndexOf(key); } public static void RegisterRuntimeCart(Boombox cart) { if (!((Object)(object)cart == (Object)null) && liveCarretas.Add(cart)) { Logger.LogInfo((object)("CarretaFuracao REGISTER cart=" + cart.photonView.ViewID)); } } public static void TickRuntime() { if (Instance == null || Instance.modDisabled || lastRuntimeFrame == Time.frameCount) { return; } lastRuntimeFrame = Time.frameCount; foreach (Boombox activeCarreta in GetActiveCarretas()) { try { activeCarreta.TickPlayback(); } catch (Exception ex) { Logger.LogError((object)("CarretaFuracao runtime cart=" + activeCarreta.photonView.ViewID + ": " + ex)); } } } public static List<Boombox> GetRuntimeCarretas() { return liveCarretas.Where((Boombox cart) => (Object)(object)cart != (Object)null && cart.data != null).ToList(); } private async void PrepareNextTrack() { if (AudioSettings.Preload == null || !AudioSettings.Preload.Value || data.currentSong == null || !data.currentSong.ClipLoaded() || data.playbackQueue.Count < 2) { return; } int currentSongIndex = GetCurrentSongIndex(); if (currentSongIndex < 0) { return; } string url = data.playbackQueue[(currentSongIndex + 1) % data.playbackQueue.Count].Url; if (url == nextPreparedUrl || !LocalMusic.IsLocalUrl(url)) { return; } nextPreparedUrl = url; try { await LocalClipCache.Load(url); } catch (Exception ex) { Logger.LogWarning((object)("CarretaFuracao preload: " + ex.Message)); } } private static List<Boombox> GetActiveCarretas() { return (from cart in liveCarretas where (Object)(object)cart != (Object)null && cart.data != null && cart.data.currentSong != null && cart.data.playbackQueue != null && cart.data.playbackQueue.Count > 0 && (cart.data.isPlaying || cart.data.pendingPlaybackStart) orderby (!((Object)(object)cart.photonView != (Object)null)) ? int.MaxValue : cart.photonView.ViewID select cart).ToList(); } private static Boombox GetActiveLeader() { return GetActiveCarretas().FirstOrDefault(); } private Boombox GetOtherActiveCarreta() { return GetActiveCarretas().FirstOrDefault((Boombox cart) => (Object)(object)cart != (Object)null && (Object)(object)cart != (Object)(object)this); } private bool EnsureQueueUsesLevelOrder() { EnsureLevelPlaylistSession(); bool flag = data.playbackQueue != null && data.playbackQueue.Count == levelPlaylistOrderKeys.Count; if (flag) { for (int i = 0; i < levelPlaylistOrderKeys.Count; i++) { AudioEntry audioEntry = data.playbackQueue[i]; if (audioEntry == null || audioEntry.Url != levelPlaylistOrderKeys[i]) { flag = false; break; } } } if (flag) { return false; } data.playbackQueue.Clear(); foreach (string levelPlaylistOrderKey in levelPlaylistOrderKeys) { SongInfo info = (DownloadHelper.songInfo.ContainsKey(levelPlaylistOrderKey) ? DownloadHelper.songInfo[levelPlaylistOrderKey] : new SongInfo()); data.playbackQueue.Add(new AudioEntry(levelPlaylistOrderKey, info)); } data.currentSong = null; return true; } private void ApplySyncedLevelTrackInternal(int index, int sharedPlaybackStartTimestamp, bool startPlaying) { if (PhotonNetwork.IsMasterClient) { bool updateQueue = EnsureQueueUsesLevelOrder(); if (data.playbackQueue != null && data.playbackQueue.Count != 0) { index = (index % data.playbackQueue.Count + data.playbackQueue.Count) % data.playbackQueue.Count; RegisterRuntimeCart(this); runtimeStartLogged = false; levelHasStartedPlayback = true; levelPlaylistIndex = index; data.currentSong = data.playbackQueue[index]; StopLocalPlayback(updateSharedFlag: true); data.playbackTime = 0; data.pendingPlaybackStart = false; data.isPlaying = startPlaying; data.loopQueue = true; data.playbackStartTimestamp = sharedPlaybackStartTimestamp; startPlayBackOnDownload = true; ApplyNativeCarretaLoopState(); PublishSharedState(updateTime: true, updateQueue, force: true); ApplySharedPlaybackState(); } } } private static void SyncActiveCarretasToIndex(int index, int sharedPlaybackStartTimestamp, Boombox includeIfNone = null) { if (!PhotonNetwork.IsMasterClient) { return; } List<Boombox> activeCarretas = GetActiveCarretas(); if (activeCarretas.Count == 0 && (Object)(object)includeIfNone != (Object)null) { activeCarretas.Add(includeIfNone); } foreach (Boombox item in activeCarretas) { if (!((Object)(object)item == (Object)null)) { item.ApplySyncedLevelTrackInternal(index, sharedPlaybackStartTimestamp, startPlaying: true); } } } private void StartOrJoinSynchronizedPlaybackInternal() { if (!PhotonNetwork.IsMasterClient) { return; } RegisterRuntimeCart(this); EnsureLevelPlaylistSession(); if (levelPlaylistOrderKeys.Count == 0) { Logger.LogWarning((object)(photonView.ViewID + " CarretaFuracao: nenhum arquivo local encontrado.")); return; } Boombox otherActiveCarreta = GetOtherActiveCarreta(); data.delayedOutput = (Object)(object)otherActiveCarreta != (Object)null; int num = (((Object)(object)otherActiveCarreta != (Object)null) ? otherActiveCarreta.GetCurrentSongIndex() : levelPlaylistIndex); if (num < 0) { num = levelPlaylistIndex; } int index = (levelHasStartedPlayback ? ((num + 1) % levelPlaylistOrderKeys.Count) : 0); int sharedPlaybackStartTimestamp = (int)GetCurrentServerTimeMilliseconds(); foreach (Boombox activeCarreta in GetActiveCarretas()) { if ((Object)(object)activeCarreta != (Object)(object)this) { activeCarreta.ApplySyncedLevelTrackInternal(index, sharedPlaybackStartTimestamp, startPlaying: true); } } ApplySyncedLevelTrackInternal(index, sharedPlaybackStartTimestamp, startPlaying: true); Logger.LogInfo((object)(photonView.ViewID + " CarretaFuracao POWER NEXT: index " + index)); } private static void MoveSynchronizedPlaylist(Boombox requester, int direction) { if (PhotonNetwork.IsMasterClient && !((Object)(object)requester == (Object)null) && levelPlaylistOrderKeys.Count != 0) { Boombox activeLeader = GetActiveLeader(); int num = (((Object)(object)activeLeader != (Object)null) ? activeLeader.GetCurrentSongIndex() : levelPlaylistIndex); if (num < 0) { num = levelPlaylistIndex; } int index = ((num + direction) % levelPlaylistOrderKeys.Count + levelPlaylistOrderKeys.Count) % levelPlaylistOrderKeys.Count; int sharedPlaybackStartTimestamp = (int)GetCurrentServerTimeMilliseconds(); levelPlaylistIndex = index; SyncActiveCarretasToIndex(index, sharedPlaybackStartTimestamp, requester); } } private static void AdvanceSynchronizedPlaylistAtEnd(Boombox requester) { if (!PhotonNetwork.IsMasterClient || (Object)(object)requester == (Object)null || levelPlaylistOrderKeys.Count == 0 || (Object)(object)GetActiveLeader() != (Object)(object)requester) { return; } int num = (int)GetCurrentServerTimeMilliseconds(); if (lastGlobalAdvanceServerTimestamp == int.MinValue || (uint)(num - lastGlobalAdvanceServerTimestamp) >= 500u) { lastGlobalAdvanceServerTimestamp = num; int currentSongIndex = requester.GetCurrentSongIndex(); if (currentSongIndex < 0) { currentSongIndex = levelPlaylistIndex; } int num2 = (levelPlaylistIndex = (currentSongIndex + 1) % levelPlaylistOrderKeys.Count); SyncActiveCarretasToIndex(num2, num); Logger.LogInfo((object)(requester.photonView.ViewID + " CarretaFuracao PLAYLIST NEXT: " + (num2 + 1) + "/" + levelPlaylistOrderKeys.Count)); } } private static void SyncActiveCarretasSeek(float playbackSeconds, Boombox requester) { if (!PhotonNetwork.IsMasterClient || (Object)(object)requester == (Object)null) { return; } float num = Math.Max(0f, playbackSeconds); int playbackStartTimestamp = (int)((double)GetCurrentServerTimeMilliseconds() - Math.Round(num * 1000f)); List<Boombox> activeCarretas = GetActiveCarretas(); if (activeCarretas.Count == 0) { activeCarretas.Add(requester); } foreach (Boombox item in activeCarretas) { if (!((Object)(object)item == (Object)null) && item.data != null && item.data.currentSong != null) { item.data.playbackStartTimestamp = playbackStartTimestamp; item.data.playbackTime = 0; item.data.pendingPlaybackStart = false; item.data.isPlaying = true; if ((Object)(object)item.audioPlayer != (Object)null && (Object)(object)item.audioPlayer.GetClip() != (Object)null) { item.audioPlayer.SetTime(num); } item.PublishSharedState(updateTime: true, updateQueue: false, force: true); } } } private void ApplyFollowerCartLocalSync() { if (Time.unscaledTime < nextFollowerSyncTime || !data.isPlaying || data.currentSong == null || (Object)(object)audioPlayer == (Object)null || (Object)(object)audioPlayer.GetClip() == (Object)null) { return; } nextFollowerSyncTime = Time.unscaledTime + 0.25f; float num = PlaybackElapsedSeconds(data.playbackStartTimestamp); if (!(num >= audioPlayer.GetClip().length)) { if (!audioPlayer.IsPlaying()) { audioPlayer.Play(); } if (Math.Abs(audioPlayer.GetTime() - num) > 0.08f) { audioPlayer.SetTime(num); } } } private void TickPlayback() { //IL_0119: Unknown result type (might be due to invalid IL or missing references) if (!runtimeStartLogged) { runtimeStartLogged = true; Logger.LogInfo((object)("CarretaFuracao CLOCK cart=" + photonView.ViewID + " componentEnabled=" + ((Behaviour)this).enabled + " objectActive=" + ((Component)this).gameObject.activeInHierarchy + " host=" + PhotonNetwork.IsMasterClient + " position=" + PlaybackElapsedSeconds(data.playbackStartTimestamp).ToString("0.000") + "s")); } if (PhotonNetwork.IsMasterClient && data.isPlaying && MonstersCanHearMusic && (Object)(object)EnemyDirector.instance != (Object)null) { monsterAttractTimer += Time.deltaTime; if (monsterAttractTimer >= 1f) { EnemyDirector.instance.SetInvestigate(((Component)this).transform.position, 5f, false); monsterAttractTimer = 0f; } } else { monsterAttractTimer = 0f; } ApplyFollowerCartLocalSync(); PrepareNextTrack(); if (PhotonNetwork.IsMasterClient && data.isPlaying && data.currentSong != null && (Object)(object)audioPlayer != (Object)null && (Object)(object)audioPlayer.GetClip() != (Object)null) { float length = audioPlayer.GetClip().length; float val = Math.Max(0f, audioPlayer.GetTime()); float val2 = Math.Max(0f, PlaybackElapsedSeconds(data.playbackStartTimestamp)); float num = Math.Max(val, val2); if (length > 0.05f && num >= length - 0.05f) { AdvanceSynchronizedPlaylistAtEnd(this); } } } public void ToggleRandomJukeboxLocal() { if (ShouldRequestMasterMutation()) { BaseListener.RPC(photonView, "RequestToggleRandomJukebox", (RpcTarget)2, PhotonNetwork.LocalPlayer.ActorNumber); } else if (data != null && (data.isPlaying || data.pendingPlaybackStart)) { StopRandomJukeboxInternal(); } else { StartRandomJukeboxInternal(); } } private void StopRandomJukeboxInternal() { if (PhotonNetwork.IsMasterClient) { string text = data?.currentSong?.Title ?? "(nenhuma)"; Logger.LogInfo((object)(photonView.ViewID + " CarretaFuracao E JUKEBOX: STOP | " + text)); int currentSongIndex = GetCurrentSongIndex(); if (currentSongIndex >= 0) { levelPlaylistIndex = currentSongIndex; } DismissQueueLocal(); } } private LocalMusic.LocalTrack FindLocalTrackByKey(string key) { if (string.IsNullOrWhiteSpace(key)) { return null; } return LocalMusic.Tracks.FirstOrDefault((LocalMusic.LocalTrack track) => track != null && track.Key == key); } private void StartRandomJukeboxInternal() { StartOrJoinSynchronizedPlaybackInternal(); } public void PlayPreviousRandomJukeboxLocal() { if (ShouldRequestMasterMutation()) { BaseListener.RPC(photonView, "RequestPreviousRandomJukebox", (RpcTarget)2, PhotonNetwork.LocalPlayer.ActorNumber); } else { PlayPreviousRandomJukeboxInternal(); } } private void PlayPreviousRandomJukeboxInternal() { if (PhotonNetwork.IsMasterClient) { EnsureLevelPlaylistSession(); MoveSynchronizedPlaylist(this, -1); } } public void PlayNextRandomJukeboxLocal() { if (ShouldRequestMasterMutation()) { BaseListener.RPC(photonView, "RequestNextRandomJukebox", (RpcTarget)2, PhotonNetwork.LocalPlayer.ActorNumber); } else { PlayNextRandomJukeboxInternal(); } } private void PlayNextRandomJukeboxInternal() { if (PhotonNetwork.IsMasterClient) { EnsureLevelPlaylistSession(); MoveSynchronizedPlaylist(this, 1); } } [PunRPC] public void RequestPreviousRandomJukebox(int requesterId) { if (PhotonNetwork.IsMasterClient) { PlayPreviousRandomJukeboxInternal(); } } [PunRPC] public void RequestNextRandomJukebox(int requesterId) { if (PhotonNetwork.IsMasterClient) { PlayNextRandomJukeboxInternal(); } } [PunRPC] public void RequestToggleRandomJukebox(int requesterId) { if (PhotonNetwork.IsMasterClient) { ToggleRandomJukeboxLocal(); } } public void TogglePlaying(bool value) { data.isPlaying = value; } public static long GetCurrentServerTimeMilliseconds() { return PhotonNetwork.ServerTimestamp; } public static float PlaybackElapsedSeconds(int startedAt) { return Math.Max(0f, (float)(PhotonNetwork.ServerTimestamp - startedAt) / 1000f); } public long GetRelativePlaybackMilliseconds() { return GetCurrentServerTimeMilliseconds() - (long)Math.Round(GetTrackedPlaybackSeconds() * 1000f); } public int GetCurrentSongIndex() { if (data.currentSong == null) { return -1; } return data.playbackQueue.IndexOf(data.currentSong); } private string GetPropertyKey(string propertyName) { if ((Object)(object)photonView == (Object)null) { return propertyName; } return $"boombox_{photonView.ViewID}_{propertyName}"; } private Hashtable CreateSharedState(bool includeTime, bool updateQueue) { //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_0026: Expected O, but got Unknown //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected O, but got Unknown //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Expected O, but got Unknown //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Expected O, but got Unknown //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Expected O, but got Unknown //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Expected O, but got Unknown //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Expected O, but got Unknown //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Expected O, but got Unknown //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Expected O, but got Unknown //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Expected O, but got Unknown //IL_0156: Expected O, but got Unknown Hashtable val = new Hashtable(); ((Dictionary<object, object>)val).Add((object)GetPropertyKey("propVersion"), (object)data.stateVersion); ((Dictionary<object, object>)val).Add((object)GetPropertyKey("IDKey"), (object)data.key); ((Dictionary<object, object>)val).Add((object)GetPropertyKey("isPlaying"), (object)(data.currentSong != null && data.isPlaying)); ((Dictionary<object, object>)val).Add((object)GetPropertyKey("pendingPlaybackStart"), (object)data.pendingPlaybackStart); ((Dictionary<object, object>)val).Add((object)GetPropertyKey("absVolume"), (object)data.absVolume); ((Dictionary<object, object>)val).Add((object)GetPropertyKey("loopQueue"), (object)data.loopQueue); ((Dictionary<object, object>)val).Add((object)GetPropertyKey("delayedOutput"), (object)data.delayedOutput); ((Dictionary<object, object>)val).Add((object)GetPropertyKey("underglow"), (object)data.underglowEnabled); ((Dictionary<object, object>)val).Add((object)GetPropertyKey("visualizer"), (object)data.visualizerEnabled); ((Dictionary<object, object>)val).Add((object)GetPropertyKey("currentSongIndex"), (object)GetCurrentSongIndex()); Hashtable val2 = val; if (includeTime) { ((Dictionary<object, object>)(object)val2).Add((object)GetPropertyKey("playbackStartTimestamp"), (object)data.playbackStartTimestamp); } if (updateQueue) { ((Dictionary<object, object>)(object)val2).Add((object)GetPropertyKey("queue"), (object)JsonConvert.SerializeObject((object)data.playbackQueue.Select((AudioEntry entry) => new SharedAudioEntry { title = entry.Title, url = entry.Url, duration = entry.Duration, startTime = entry.StartTime }).ToArray())); Logger.LogDebug((object)(photonView.ViewID + string.Format("Created table with queue size: {0}", JsonConvert.DeserializeObject<SharedAudioEntry[]>((string)val2[(object)GetPropertyKey("queue")]).Count()))); } return val2; } private void LoadSharedStateFromRoom() { if (PhotonNetwork.IsConnected && PhotonNetwork.CurrentRoom != null && !((Object)(object)photonView == (Object)null)) { Hashtable customProperties = ((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties; ApplyChangedValues(customProperties); if (PhotonNetwork.IsMasterClient && ((Dictionary<object, object>)(object)customProperties).Count > 0) { PublishSharedState(updateTime: true, updateQueue: true, force: true); } } } public override void OnRoomPropertiesUpdate(Hashtable propertiesThatChanged) { ((MonoBehaviourPunCallbacks)this).OnRoomPropertiesUpdate(propertiesThatChanged); if (!((Object)(object)photonView == (Object)null) && propertiesThatChanged != null && !PhotonNetwork.IsMasterClient) { ApplyChangedValues(propertiesThatChanged); } } private void ApplyChangedValues(Hashtable propertiesThatChanged) { isApplyingSharedState = true; string propertyKey = GetPropertyKey("propVersion"); if (!((Dictionary<object, object>)(object)propertiesThatChanged).ContainsKey((object)propertyKey)) { isApplyingSharedState = false; return; } int num = (int)propertiesThatChanged[(object)propertyKey]; if (num < data.stateVersion || num <= lastAppliedSharedStateVersion) { isApplyingSharedState = false; return; } int currentSongIndex = GetCurrentSongIndex(); string propertyKey2 = GetPropertyKey("queue"); bool flag = ((Dictionary<object, object>)(object)propertiesThatChanged).ContainsKey((object)propertyKey2); try { if (flag) { SharedAudioEntry[] array = JsonConvert.DeserializeObject<SharedAudioEntry[]>((string)propertiesThatChanged[(object)propertyKey2]); if (array != null) { data.playbackQueue = array.Select(delegate(SharedAudioEntry entry) { string title = (string.IsNullOrWhiteSpace(entry.title) ? "Unknown Title" : entry.title); _ = entry.duration; double duration = entry.duration; string url = entry.url; SongInfo info = new SongInfo(title, duration); return new AudioEntry(url, info) { StartTime = entry.startTime }; }).ToList(); Logger.LogDebug((object)(photonView.ViewID + $"Updated queue to size {data.playbackQueue.Count}.")); } else { data.playbackQueue = new List<AudioEntry>(); } } string propertyKey3 = GetPropertyKey("currentSongIndex"); if (((Dictionary<object, object>)(object)propertiesThatChanged).ContainsKey((object)propertyKey3)) { int num2 = (int)propertiesThatChanged[(object)propertyKey3]; if (num2 >= 0 && num2 < data.playbackQueue.Count) { data.currentSong = data.playbackQueue[num2]; } else { data.currentSong = null; data.pendingPlaybackStart = false; audioPlayer.Stop(); UpdateUIStatus("Ready to play music! Enter a Video URL"); Logger.LogDebug((object)(photonView.ViewID + $"Invalid currentsong index: {num2}.")); } } else if (flag) { data.currentSong = data.playbackQueue[currentSongIndex]; } string propertyKey4 = GetPropertyKey("pendingPlaybackStart"); if (((Dictionary<object, object>)(object)propertiesThatChanged).ContainsKey((object)propertyKey4)) { bool pendingPlaybackStart = (bool)propertiesThatChanged[(object)propertyKey4]; data.pendingPlaybackStart = pendingPlaybackStart; } string propertyKey5 = GetPropertyKey("isPlaying"); if (((Dictionary<object, object>)(object)propertiesThatChanged).ContainsKey((object)propertyKey5)) { bool flag2 = (bool)propertiesThatChanged[(object)propertyKey5]; data.isPlaying = data.currentSong != null && flag2; } string propertyKey6 = GetPropertyKey("absVolume"); if (((Dictionary<object, object>)(object)propertiesThatChanged).ContainsKey((object)propertyKey6)) { float num3 = Mathf.Clamp01(Convert.ToSingle((float)propertiesThatChanged[(object)propertyKey6])); AudioSettings.RememberMaster(num3); if (data.absVolume != num3) { data.absVolume = num3; float volume = num3 * data.personalVolumePercentage; audioPlayer.SetVolume(volume); } } string propertyKey7 = GetPropertyKey("delayedOutput"); if (((Dictionary<object, object>)(object)propertiesThatChanged).ContainsKey((object)propertyKey7)) { data.delayedOutput = (bool)propertiesThatChanged[(object)propertyKey7]; } string propertyKey8 = GetPropertyKey("loopQueue"); if (((Dictionary<object, object>)(object)propertiesThatChanged).ContainsKey((object)propertyKey8)) { bool loopQueue = (bool)propertiesThatChanged[(object)propertyKey8]; data.loopQueue = loopQueue; } string propertyKey9 = GetPropertyKey("underglow"); if (((Dictionary<object, object>)(object)propertiesThatChanged).ContainsKey((object)propertyKey9) && Instance.SyncVisuals.Value) { bool underglowEnabled = (bool)propertiesThatChanged[(object)propertyKey9]; data.underglowEnabled = underglowEnabled; ApplyVisualStateFromData(); ((Component)this).GetComponent<BoomboxUI>()?.UpdateDataFromBoomBox(); } string propertyKey10 = GetPropertyKey("visualizer"); if (((Dictionary<object, object>)(object)propertiesThatChanged).ContainsKey((object)propertyKey10) && Instance.SyncVisuals.Value) { bool visualizerEnabled = (bool)propertiesThatChanged[(object)propertyKey10]; data.visualizerEnabled = visualizerEnabled; ApplyVisualStateFromData(); ((Component)this).GetComponent<BoomboxUI>()?.UpdateDataFromBoomBox(); } string propertyKey11 = GetPropertyKey("playbackStartTimestamp"); if (((Dictionary<object, object>)(object)propertiesThatChanged).ContainsKey((object)propertyKey11)) { int num4 = (int)propertiesThatChanged[(object)propertyKey11]; data.playbackStartTimestamp = num4; SetPlaybackTime(num4); } string propertyKey12 = GetPropertyKey("IDKey"); if (((Dictionary<object, object>)(object)propertiesThatChanged).ContainsKey((object)propertyKey12)) { string text = (string)propertiesThatChanged[(object)propertyKey12]; if (!string.IsNullOrWhiteSpace(text)) { data.key = text; } } } catch (Exception ex) { Logger.LogWarning((object)("Error occured while reading properties: " + ex.Message)); } ApplySharedPlaybackState(); ((Component)this).GetComponent<BoomboxUI>()?.UpdateDataFromBoomBox(); data.stateVersion = num; lastAppliedSharedStateVersion = num; syncFinished = true; isApplyingSharedState = false; } private bool ShouldUseNativeCarretaLoop() { return false; } private void ApplyNativeCarretaLoopState() { if (!((Object)(object)audioPlayer == (Object)null) && !((Object)(object)audioPlayer.audioSource == (Object)null)) { bool flag = ShouldUseNativeCarretaLoop(); if (audioPlayer.audioSource.loop != flag) { audioPlayer.audioSource.loop = flag; Logger.LogInfo((object)(photonView.ViewID + " CarretaFuracao NATIVE LOOP: " + (flag ? "ON" : "OFF"))); } } } private void ApplySharedPlaybackState() { ApplyNativeCarretaLoopState(); audioPlayer.SetVolume(data.absVolume * data.personalVolumePercentage); audioPlayer.SetDelayedOutput(data.delayedOutput); if (data.currentSong?.Url == null) { Logger.LogDebug((object)(photonView.ViewID + "ApplySharedPlaybackState: No current song" + ((data.currentSong == null) ? "" : "URL") + "!")); data.pendingPlaybackStart = false; audioPlayer.Stop(); UpdateUIStatus("Ready to play music! Enter a Video URL"); return; } AudioEntry currentSong = data.currentSong; if (currentSong == null || !currentSong.ClipLoaded()) { audioPlayer.Stop(); startPlayBackOnDownload = data.pendingPlaybackStart; if (data.pendingPlaybackStart) { UpdateUIStatus("Loading: " + data.currentSong.Title); } if (!data.pendingPlaybackStart) { EnsureCurrentSongDownloaded(); } return; } if (data.currentSong.Url != audioPlayer.currentUrl) { audioPlayer.Stop(); audioPlayer.SetClip(data.currentSong.Url); audioPlayer.SetQuality(AudioPlayer.GetQuality()); audioPlayer.UpdateAudioRangeBasedOnVolume(); } ApplyVisualStateFromData(); if (data.pendingPlaybackStart) { if (audioPlayer.IsPlaying()) { audioPlayer.Pause(); } UpdateUIStatus("Loading: " + data.currentSong.Title); } else if (data.isPlaying) { if (!audioPlayer.IsPlaying() && PlaybackElapsedSeconds(data.playbackStartTimestamp) < audioPlayer.GetClip().length) { Logger.LogDebug((object)(photonView.ViewID + $"ApplySharedPlaybackState: Starting playback - timestamp={data.playbackStartTimestamp}")); audioPlayer.Play(); SetPlaybackTime(data.playbackStartTimestamp); Logger.LogDebug((object)(photonView.ViewID + $"ApplySharedPlaybackState: After Play(), audioPlayer.GetTime()={audioPlayer.GetTime()}")); } UpdateUIStatus("Now playing: " + data.currentSong.Title); } else { if (audioPlayer.IsPlaying()) { audioPlayer.Pause(); } UpdateUIStatus("Ready to play: " + data.currentSong.Title); } } public void ApplyVisualStateFromData() { if ((Object)(object)visualEffects == (Object)null) { visualEffects = ((Component)this).gameObject.AddComponent<VisualEffects>(); if ((Object)(object)visualizer != (Object)null) { visualizer.audioSource = audioPlayer.audioSource; } } visualEffects.SetLights(data.underglowEnabled); if (data.visualizerEnabled) { if ((Object)(object)visualizer == (Object)null) { visualizer = ((Component)this).gameObject.AddComponent<Visualizer>(); } visualizer.audioSource = audioPlayer.audioSource; } else if ((Object)(object)visualizer != (Object)null) { Object.Destroy((Object)(object)visualizer); visualizer = null; } } private async void EnsureCurrentSongDownloaded() { string url = data.currentSong?.Url; if (string.IsNullOrWhiteSpace(url) || (Object)(object)downloadHelper == (Object)null || DownloadHelper.downloadedClips.ContainsKey(url) || pendingCurrentSongDownloadUrl == url) { return; } pendingCurrentSongDownloadUrl = url; try { if (await downloadHelper.StartAudioDownload(url)) { BaseListener.RPC(photonView, "ReportDownloadComplete", (RpcTarget)2, url, PhotonNetwork.LocalPlayer.ActorNumber); } } finally { if (pendingCurrentSongDownloadUrl == url) { pendingCurrentSongDownloadUrl = null; } } if (!((Object)(object)this == (Object)null) && !(data.currentSong?.Url != url)) { ApplySharedPlaybackState(); } } private void UpdateStatusFromState() { if (data.currentSong == null) { UpdateUIStatus("Ready to play music! Enter a Video URL"); } else if (data.pendingPlaybackStart) { UpdateUIStatus("Loading: " + data.currentSong.Title); } else if (data.isPlaying) { UpdateUIStatus("Now playing: " + data.currentSong.Title); } else { UpdateUIStatus("Ready to play: " + data.currentSong.Title); } } public bool CanPublish() { if (PhotonNetwork.IsMasterClient && !isApplyingSharedState && PhotonNetwork.IsConnected && PhotonNetwork.CurrentRoom != null) { return (Object)(object)photonView != (Object)null; } return false; } public void PublishSharedState(bool updateTime, bool updateQueue = false, bool force = false) { if (CanPublish()) { if (PhotonNetwork.IsMasterClient) { data.stateVersion++; } Hashtable val = CreateSharedState(updateTime, updateQueue); PhotonNetwork.CurrentRoom.SetCustomProperties(val, (Hashtable)null, (WebFlags)null); lastSharedState = val; syncFinished = true; } } private void StopLocalPlayback(bool updateSharedFlag) { audioPlayer.Stop(); if (updateSharedFlag) { TogglePlaying(value: false); } } private void SetPlaybackReferenceFromSeconds(float totalSeconds) { float num = Math.Max(0f, totalSeconds); data.playbackStartTimestamp = (int)((double)GetCurrentServerTimeMilliseconds() - Math.Round(num * 1000f)); Logger.LogDebug((object)(photonView.ViewID + $"SetPlaybackReferenceFromSeconds: Set to {num}s, timestamp={data.playbackStartTimestamp}")); } private float GetTrackedPlaybackSeconds() { if ((Object)(object)audioPlayer?.GetClip() != (Object)null) { if (!audioPlayer.IsPlaying() && data.playbackTime > 0 && audioPlayer.GetTime() <= 0f) { Logger.LogDebug((object)(photonView.ViewID + $"GetTrackedPlaybackSeconds: Returning cached playbackTime={data.playbackTime} (not playing, time <= 0)")); return data.playbackTime; } float time = audioPlayer.GetTime(); Logger.LogDebug((object)(photonView.ViewID + $"GetTrackedPlaybackSeconds: Returning audioPlayer.GetTime()={time}, isPlaying={audioPlayer.IsPlaying()}")); return time; } if (data.playbackTime > 0) { Logger.LogDebug((object)(photonView.ViewID + $"GetTrackedPlaybackSeconds: Returning cached playbackTime={data.playbackTime} (no clip)")); return data.playbackTime; } float num = Math.Max(0f, PlaybackElapsedSeconds(data.playbackStartTimestamp)); Logger.LogDebug((object)(photonView.ViewID + $"GetTrackedPlaybackSeconds: Calculating from timestamp: {num}s")); return num; } private void CleanupCurrentPlayback() { StopLocalPlayback(updateSharedFlag: true); } private bool ShouldRequestMasterMutation() { if (PhotonNetwork.IsConnected && PhotonNetwork.CurrentRoom != null) { return !PhotonNetwork.IsMasterClient; } return false; } public void SetPlaybackTime(long relativeStartTimeMillis) { float num = Math.Max(0f, PlaybackElapsedSeconds((int)relativeStartTimeMillis)); Logger.LogDebug((object)(photonView.ViewID + $"SetPlaybackTime: Setting audioPlayer time to {num}s (from timestamp {relativeStartTimeMillis})")); audioPlayer.SetTime(num); } public void EnqueueSongLocal(string url, int seconds) { if (string.IsNullOrWhiteSpace(url)) { return; } if (ShouldRequestMasterMutation()) { BaseListener.RPC(photonView, "RequestEnqueueSong", (RpcTarget)2, url, seconds, PhotonNetwork.LocalPlayer.ActorNumber); return; } SongInfo info = (DownloadHelper.songInfo.ContainsKey(url) ? DownloadHelper.songInfo[url] : new SongInfo()); AudioEntry audioEntry = new AudioEntry(url, info) { StartTime = seconds }; data.playbackQueue.Add(audioEntry); bool flag = data.currentSong == null; if (flag) { data.currentSong = audioEntry; data.playbackTime = 0; Logger.LogDebug((object)(photonView.ViewID + $"Set currentsong local {data.currentSong}")); StopLocalPlayback(updateSharedFlag: true); data.pendingPlaybackStart = true; startPlayBackOnDownload = true; SetPlaybackReferenceFromSeconds(audioEntry.UseStartTime(this)); } PublishSharedState(flag, updateQueue: true); if (PhotonNetwork.IsMasterClient) { downloadHelper.EnqueueDownload(url); downloadHelper.StartDownloadJob(); } } public void CommitPlaybackSeek() { if (data.currentSong != null) { if (ShouldRequestMasterMutation()) { BaseListener.RPC(photonView, "RequestCommitPlaybackSeek", (RpcTarget)2, audioPlayer.GetTime(), PhotonNetwork.LocalPlayer.ActorNumber); } else { SyncActiveCarretasSeek(audioPlayer.GetTime(), this); } } } public void SetPlaybackStateLocal(bool startPlaying) { if (data.currentSong != null) { if (ShouldRequestMasterMutation()) { BaseListener.RPC(photonView, "RequestSetPlaybackState", (RpcTarget)2, startPlaying, PhotonNetwork.LocalPlayer.ActorNumber); } else if (!data.currentSong.ClipLoaded()) { startPlayBackOnDownload = startPlaying; data.isPlaying = false; data.pendingPlaybackStart = startPlaying; PublishSharedState(updateTime: true); } else { float trackedPlaybackSeconds = GetTrackedPlaybackSeconds(); Logger.LogDebug((object)(photonView.ViewID + $"SetPlaybackStateLocal: trackedPlaybackSeconds={trackedPlaybackSeconds}, isPlaying={startPlaying}")); SetPlaybackReferenceFromSeconds(trackedPlaybackSeconds); Logger.LogDebug((object)(photonView.ViewID + $"SetPlaybackStateLocal: Final state - isPlaying={startPlaying}, timestamp={data.playbackStartTimestamp}")); data.isPlaying = startPlaying; data.pendingPlaybackStart = false; PublishSharedState(updateTime: true, updateQueue: false, force: true); } } } public void JumpPlaybackBySeconds(float seconds) { if (!data.currentSong.ClipLoaded()) { return; } if (ShouldRequestMasterMutation()) { BaseListener.RPC(photonView, "RequestJumpPlaybackBySeconds", (RpcTarget)2, seconds, PhotonNetwork.LocalPlayer.ActorNumber); return; } float num = Math.Max(0f, GetTrackedPlaybackSeconds() + seconds); if ((Object)(object)audioPlayer?.GetClip() != (Object)null) { num = Math.Min(num, Math.Max(0f, audioPlayer.GetClip().length - 0.5f)); } SetPlaybackReferenceFromSeconds(num); data.pendingPlaybackStart = false; PublishSharedState(updateTime: true); } public void SelectSongIndex(int index) { if (index < 0 || index >= data.playbackQueue.Count) { return; } if (ShouldRequestMasterMutation()) { BaseListener.RPC(photonView, "RequestSelectSongIndex", (RpcTarget)2, index, PhotonNetwork.LocalPlayer.ActorNumber); return; } data.currentSong = data.playbackQueue[index]; StopLocalPlayback(updateSharedFlag: true); data.playbackTime = 0; data.pendingPlaybackStart = true; startPlayBackOnDownload = true; PublishSharedState(updateTime: true); if (PhotonNetwork.IsMasterClient) { string text = data.currentSong?.Url; if (text != null && DownloadHelper.downloadsReady.ContainsKey(text) && DownloadHelper.downloadsReady[text].Count >= Instance.baseListener.GetAllModUsers().Count && data.pendingPlaybackStart) { Logger.LogDebug((object)(photonView.ViewID + "Skipping download queue, as all users are ready to play.")); FinalizePendingPlaybackStart(startPlayBackOnDownload); } else { downloadHelper.DismissDownloadQueue(); downloadHelper.DownloadQueue(index); } } } public void SetVolumeLocal(float volume) { if (ShouldRequestMasterMutation()) { BaseListener.RPC(photonView, "RequestSetVolume", (RpcTarget)2, volume, PhotonNetwork.LocalPlayer.ActorNumber); return; } AudioSettings.RememberMaster(volume); foreach (Boombox runtimeCarreta in GetRuntimeCarretas()) { if (!((Object)(object)runtimeCarreta == (Object)(object)this)) { runtimeCarreta.data.absVolume = Mathf.Clamp01(volume); if ((Object)(object)runtimeCarreta.audioPlayer != (Object)null) { runtimeCarreta.audioPlayer.SetVolume(runtimeCarreta.data.absVolume * runtimeCarreta.data.personalVolumePercentage); } runtimeCarreta.PublishSharedState(updateTime: false); } } data.absVolume = Mathf.Clamp01(volume); float volume2 = data.absVolume * data.personalVolumePercentage; audioPlayer.SetVolume(volume2); PublishSharedState(updateTime: false); } public void SetLoopQueueLocal(bool loop) { if (ShouldRequestMasterMutation()) { BaseListener.RPC(photonView, "RequestSetLoopQueue", (RpcTarget)2, loop, PhotonNetwork.LocalPlayer.ActorNumber); } else { data.loopQueue = loop; ApplyNativeCarretaLoopState(); PublishSharedState(updateTime: false); } } public void SetUnderglowEnabledLocal(bool enabled) { if (Instance.SyncVisuals.Value) { if (ShouldRequestMasterMutation()) { BaseListener.RPC(photonView, "RequestSetUnderglowEnabled", (RpcTarget)2, enabled, PhotonNetwork.LocalPlayer.ActorNumber); } else { data.underglowEnabled = enabled; ApplyVisualStateFromData(); ((Component)this).GetComponent<BoomboxUI>()?.UpdateDataFromBoomBox(); PublishSharedState(updateTime: false); } } else { data.underglowEnabled = enabled; ApplyVisualStateFromData(); ((Component)this).GetComponent<BoomboxUI>()?.UpdateDataFromBoomBox(); } } public void SetVisualizerEnabledLocal(bool enabled) { if (Instance.SyncVisuals.Value) { if (ShouldRequestMasterMutation()) { BaseListener.RPC(photonView, "RequestSetVisualizerEnabled", (RpcTarget)2, enabled, PhotonNetwork.LocalPlayer.ActorNumber); } else { data.visualizerEnabled = enabled; ApplyVisualStateFromData(); ((Component)this).GetComponent<BoomboxUI>()?.UpdateDataFromBoomBox(); PublishSharedState(updateTime: false); } } else { data.visualizerEnabled = enabled; ApplyVisualStateFromData(); ((Component)this).GetComponent<BoomboxUI>()?.UpdateDataFromBoomBox(); } } public void DismissQueueLocal() { if (ShouldRequestMasterMutation()) { BaseListener.RPC(photonView, "RequestDismissQueue", (RpcTarget)2, PhotonNetwork.LocalPlayer.ActorNumber); return; } if ((Object)(object)audioPlayer != (Object)null && (Object)(object)audioPlayer.audioSource != (Object)null) { audioPlayer.audioSource.loop = false; } StopLocalPlayback(updateSharedFlag: true); data.playbackQueue.Clear(); data.currentSong = null; data.pendingPlaybackStart = false; data.playbackTime = 0; SetPlaybackReferenceFromSeconds(0f); PublishSharedState(updateTime: true, updateQueue: true); if (PhotonNetwork.IsMasterClient) { downloadHelper.DismissDownloadQueue(); downloadHelper.ForceCancelDownload(); } UpdateUIStatus("Ready to play music! Enter a Video URL"); } public void MoveQueueItemLocal(int index, int newIndex) { if (index >= 0 && index < data.playbackQueue.Count && newIndex >= 0 && newIndex < data.playbackQueue.Count && index != newIndex) { if (ShouldRequestMasterMutation()) { BaseListener.RPC(photonView, "RequestMoveQueueItem", (RpcTarget)2, index, newIndex, PhotonNetwork.LocalPlayer.ActorNumber); } else { AudioEntry item = data.playbackQueue[index]; data.playbackQueue.RemoveAt(index); data.playbackQueue.Insert(newIndex, item); PublishSharedState(updateTime: false, updateQueue: true); } } } public void RemoveQueueItemLocal(int index) { if (index < 0 || index >= data.playbackQueue.Count) { return; } if (ShouldRequestMasterMutation()) { BaseListener.RPC(photonView, "RequestRemoveQueueItem", (RpcTarget)2, index, PhotonNetwork.LocalPlayer.ActorNumber); return; } bool flag = data.playbackQueue[index] == data.currentSong; data.playbackQueue.RemoveAt(index); if (flag) { if (data.playbackQueue.Count == 0) { data.currentSong = null; data.isPlaying = false; data.playbackTime = 0; data.pendingPlaybackStart = false; SetPlaybackReferenceFromSeconds(0f); } else { int index2 = Math.Min(index, data.playbackQueue.Count - 1); if (index >= data.playbackQueue.Count && LoopQueue) { index2 = 0; } data.currentSong = data.playbackQueue[index2]; data.isPlaying = false; data.playbackTime = 0; data.pendingPlaybackStart = true; startPlayBackOnDownload = true; SetPlaybackReferenceFromSeconds(data.currentSong.UseStartTime(this)); } } if (PhotonNetwork.IsMasterClient && data.currentSong?.Url != null) { downloadHelper.DismissDownloadQueue(); downloadHelper.DownloadQueue(GetCurrentSongIndex()); } PublishSharedState(flag, updateQueue: true); } public void FinalizePendingPlaybackStart(bool startPlaying) { if (data.currentSong != null) { data.pendingPlaybackStart = false; data.isPlaying = startPlaying; SetPlaybackReferenceFromSeconds(data.currentSong.UseStartTime(this)); startPlayBackOnDownload = true; PublishSharedState(updateTime: true, updateQueue: false, force: true); } } [PunRPC] public void RequestEnqueueSong(string url, int seconds, int requesterId) { if (PhotonNetwork.IsMasterClient) { EnqueueSongLocal(url, seconds); } } [PunRPC] public void RequestCommitPlaybackSeek(float playbackSeconds, int requesterId) { if (PhotonNetwork.IsMasterClient && data.currentSong != null) { SyncActiveCarretasSeek(playbackSeconds, this); } } [PunRPC] public void RequestSetPlaybackState(bool startPlaying, int requesterId) { if (PhotonNetwork.IsMasterClient) { SetPlaybackStateLocal(startPlaying); } } [PunRPC] public void RequestJumpPlaybackBySeconds(float seconds, int requesterId) { if (PhotonNetwork.IsMasterClient) { JumpPlaybackBySeconds(seconds); } } [PunRPC] public void RequestSelectSongIndex(int index, int requesterId) { if (PhotonNetwork.IsMasterClient) { SelectSongIndex(index); } } [PunRPC] public void RequestSetVolume(float volume, int requesterId) { if (PhotonNetwork.IsMasterClient) { SetVolumeLocal(volume); } } [PunRPC] public void RequestSetLoopQueue(bool loop, int requesterId) { if (PhotonNetwork.IsMasterClient) { SetLoopQueueLocal(loop); } } [PunRPC] public void RequestSetUnderglowEnabled(bool enabled, int requesterId) { if (PhotonNetwork.IsMasterClient && Instance.SyncVisuals.Value) { SetUnderglowEnabledLocal(enabled); } } [PunRPC] public void RequestSetVisualizerEnabled(bool enabled, int requesterId) { if (PhotonNetwork.IsMasterClient && Instance.SyncVisuals.Value) { SetVisualizerEnabledLocal(enabled); } } [PunRPC] public void RequestDismissQueue(int requesterId) { if (PhotonNetwork.IsMasterClient && (!Instance.MasterClientDismissQueue.Value || PhotonNetwork.MasterClient.ActorNumber == requesterId)) { DismissQueueLocal(); } } [PunRPC] public void RequestMoveQueueItem(int index, int newIndex, int requesterId) { if (PhotonNetwork.IsMasterClient) { MoveQueueItemLocal(index, newIndex); } } [PunRPC] public void RequestRemoveQueueItem(int index, int requesterId) { if (PhotonNetwork.IsMasterClient) { RemoveQueueItemLocal(index); } } public void HandleDownloadedCurrentSong() { AudioEntry currentSong = data.currentSong; if (currentSong != null && currentSong.ClipLoaded()) { ApplySharedPlaybackState(); } } public double EstimateDownloadTimeSeconds(double durationSeconds, int downloadSpeedMbps) { double num = (double)DownloadHelper.GetBitrateKbps(ApplyQualityToDownloads ? 4 : AudioPlayer.GetQuality()) * 1000.0 / 8.0 * durationSeconds; double num2 = (double)Math.Max(1, downloadSpeedMbps) / 8.0 * 1024.0 * 1024.0; double num3 = num / num2 * 2.5; double num4 = durationSeconds * 0.005; return (5.0 + num3 + num4) * 1.3; } public void UpdateUIStatus(string message) { if (!((Object)(object)this == (Object)null)) { BoomboxUI component = ((Component)this).GetComponent<BoomboxUI>(); if ((Object)(object)component != (Object)null && component.IsUIVisible()) { component.UpdateStatus(message); } } } public override void OnPlayerEnteredRoom(Player newPlayer) { ((MonoBehaviourPunCallbacks)this).OnPlayerEnteredRoom(newPlayer); if (PhotonNetwork.IsMasterClient && !Instance.modDisabled) { PhotonView obj = ((MonoBehaviourPun)Instance.baseListener).photonView; if (obj != null) { obj.RPC("BaseListener", newPlayer, new object[2] { "0.7.9", PhotonNetwork.LocalPlayer.ActorNumber }); } } } public override void OnDisable() { ((MonoBehaviourPunCallbacks)this).OnDisable(); PersistentData.RemoveBoomboxViewInitialized(photonView.ViewID); data.playbackTime = (int)Math.Round(audioPlayer.GetTime()); } private void OnDestroy() { liveCarretas.Remove(this); Instance.data.GetAllBoomboxes().Remove(this); Object.Destroy((Object)(object)((Component)this).GetComponent<BoomboxUI>()); if ((Object)(object)visualizer != (Object)null) { Object.Destroy((Object)(object)visualizer); } Object.Destroy((Object)(object)((Component)this).gameObject.GetComponent<VisualEffects>()); Object.Destroy((Object)(object)audioPlayer); Object.Destroy((Object)(object)downloadHelper); Object.Destroy((Object)(object)((Component)this).gameObject.GetComponent<BoomboxController>()); photonView.RefreshRpcMonoBehaviourCache(); } public void ResetData() { if (PhotonNetwork.IsMasterClient) { Logger.LogInfo((object)$"Resetting Boombox {photonView.ViewID}"); startPlayBackOnDownload = true; data.pendingPlaybackStart = false; UpdateUIStatus("Ready to play music! Enter a Video URL"); CleanupCurrentPlayback(); downloadHelper.DismissDownloadQueue(); List<BoomboxData> boomboxData = Instance.data.GetBoomboxData(); int index = boomboxData.Count; if (boomboxData.Contains(data)) { index = boomboxData.IndexOf(data); boomboxData.Remove(data); } int stateVersion = data.stateVersion; data = new BoomboxData(); data.stateVersion = stateVersion + 1; ApplyVisualStateFromData(); if (Instance.RestoreBoomboxes.Value) { boomboxData.Insert(index, data); } PublishSharedState(updateTime: true, updateQueue: true, force: true); } } } public class BoomboxController : MonoBehaviourPun { private static BoomboxController openPanel; private BoomboxUI panel; public void RequestBoomboxControl() { if ((Object)(object)panel != (Object)null && panel.IsUIVisible()) { ReleaseControl(); } else if (PlayerGrabbingTracker.IsLocalPlayerGrabbingCart(((Component)this).gameObject)) { if ((Object)(object)openPanel != (Object)null && (Object)(object)openPanel != (Object)(object)this) { openPanel.ReleaseControl(); } if ((Object)(object)panel == (Object)null) { panel = ((Component)this).GetComponent<BoomboxUI>() ?? ((Component)this).gameObject.AddComponent<BoomboxUI>(); } panel.ShowUI(); openPanel = this; } } public void ReleaseControl() { if ((Object)(object)panel != (Object)null) { panel.HideUI(); } if ((Object)(object)openPanel == (Object)(object)this) { openPanel = null; } } public void LocalPlayerReleasedCart() { ReleaseControl(); } private void OnDisable() { ReleaseControl(); } private void OnDestroy() { ReleaseControl(); } } public class BoomboxUI : MonoBehaviourPun { private static BoomBoxCartMod Instance = BoomBoxCartMod.instance; public PhotonView photonView; public static bool anyUISHown = false; public bool showUI; private string urlInput = ""; private bool isTimeSliderBeingDragged; private int songIndexForTime = -2; private float songTimePerc; private float lastSentSongTimePerc = -1f; private float lastSentVolume = 0.2f; private bool isVolumeSliderBeingDragged; private bool isIndividualVolumeBeingDragged; private int qualityLevel = 3; private string[] qualityLabels = new string[5] { "REALLY Low (You Freak)", "Low", "Medium-Low", "Medium-High", "High" }; private bool isQualitySliderBeingDragged; private int lastSentQualityLevel = 3; private Rect windowRect; private Boombox boombox; private BoomboxController controller; private VisualEffects visualEffects; private Visualizer visualizer; private GUIStyle windowStyle; private GUIStyle headerStyle; private GUIStyle buttonStyle; private GUIStyle smallButtonStyle; private GUIStyle textFieldStyle; private GUIStyle labelStyle; private GUIStyle sliderStyle; private GUIStyle statusStyle; private GUIStyle scrollViewStyle; private GUIStyle queueHeaderStyle; private GUIStyle queueEntryStyle; private GUIStyle currentSongStyle; private Texture2D backgroundTexture; private Texture2D buttonTexture; private Texture2D sliderBackgroundTexture; private Texture2D sliderThumbTexture; private Texture2D textFieldBackgroundTexture; private Vector2 urlScrollPosition = Vector2.zero; private float textFieldVisibleWidth = 350f; private string errorMessage = ""; private float errorMessageTime; public string statusMessage = ""; private CursorLockMode previousLockMode; private bool previousCursorVisible; private bool stylesInitialized; private Vector2 scrollPosition = Vector2.zero; private Vector2 queueScrollPosition = Vector2.zero; private const float refreshHoldTime = 5f; private const int maxRefreshSymbols = 5; private float? refreshObjectStart; private bool refreshObjectSent; private string lastUrl; private static ManualLogSource Logger => Instance.logger; private void Awake() { //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) try { boombox = ((Component)this).GetComponent<Boombox>(); if ((Object)(object)boombox != (Object)null) { photonView = boombox.photonView; } else { Logger.LogError((object)"BoomboxUI: Failed to find Boombox component"); photonView = ((Component)this).GetComponent<PhotonView>(); } controller = ((Component)this).GetComponent<BoomboxController>(); visualEffects = ((Component)this).GetComponent<VisualEffects>(); if ((Object)(object)visualEffects == (Object)null) { visualEffects = ((Component)this).gameObject.AddComponent<VisualEffects>(); } visualizer = ((Component)this).GetComponent<Visualizer>(); boombox?.ApplyVisualStateFromData(); RefreshVisualComponentRefs(); if ((Object)(object)photonView == (Object)null) { Logger.LogError((object)"BoomboxUI: Failed to find PhotonView component"); } windowRect = new Rect((float)(Screen.width / 2 - 230), (float)(Screen.height / 2 - 170), 460f, 340f); } catch (Exception ex) { Logger.LogError((object)("Error in BoomboxUI.Awake: " + ex.Message + "\n" + ex.StackTrace)); } } private void Update() { if (Time.time > errorMessageTime && !string.IsNullOrEmpty(errorMessage)) { errorMessage = ""; } if (showUI && Keyboard.current != null && ((ButtonControl)Keyboard.current.escapeKey).wasPressedThisFrame) { if ((Object)(object)controller != (Object)null) { controller.ReleaseControl(); } else { HideUI(); } } if (isTimeSliderBeingDragged && ((Mouse.current != null && Mouse.current.leftButton.wasReleasedThisFrame) || songIndexForTime != boombox.GetCurrentSongIndex())) { isTimeSliderBeingDragged = false; SendTimeUpdate(); songIndexForTime = -2; songTimePerc = 0f; lastSentSongTimePerc = -1f; } if (isVolumeSliderBeingDragged && Mouse.current != null && Mouse.current.leftButton.wasReleasedThisFrame) { isVolumeSliderBeingDragged = false; SendVolumeUpdate(); } if (isIndividualVolumeBeingDragged && Mouse.current != null && Mouse.current.leftButton.wasReleasedThisFrame) { isIndividualVolumeBeingDragged = false; AudioSettings.SetPersonal(boombox.data.personalVolumePercentage); } if (isQualitySliderBeingDragged && Mouse.current != null && Mouse.current.leftButton.wasReleasedThisFrame) { isQualitySliderBeingDragged = false; SendQualityUpdate(); } if (refreshObjectStart.HasValue && Mouse.current != null && Mouse.current.leftButton.wasReleasedThisFrame) { refreshObjectStart = null; refreshObjectSent = false; } } public void ShowUI() { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) if (!showUI) { if ((Object)(object)boombox == (Object)null || (Object)(object)photonView == (Object)null) { Logger.LogError((object)"Cannot show UI - boombox or photonView is null"); return; } anyUISHown = true; showUI = true; previousLockMode = Cursor.lockState; previousCursorVisible = Cursor.visible; Cursor.visible = true; Cursor.lockState = (CursorLockMode)0; UpdateDataFromBoomBox(); UpdateStatusFromBoombox(); } } public void UpdateDataFromBoomBox() { if ((Object)(object)boombox != (Object)null) { lastSentVolume = boombox.data.absVolume; qualityLevel = AudioPlayer.GetQuality(); lastSentQualityLevel = qualityLevel; RefreshVisualComponentRefs(); } } private void RefreshVisualComponentRefs() { visualEffects = ((Component)this).GetComponent<VisualEffects>(); visualizer = ((Component)this).GetComponent<Visualizer>(); } public void UpdateStatusFromBoombox() { if ((Object)(object)boombox != (Object)null) { if (YoutubeDL.IsUpdatingResources) { statusMessage = YoutubeDL.ResourceUpdateStatus; } else if (boombox.downloadHelper.IsProcessingQueue() && boombox.data.currentSong != null && !boombox.data.currentSong.ClipLoaded()) { statusMessage = "Downloading audio from " + boombox.downloadHelper.GetCurrentDownloadUrl() + "..."; } else if (boombox.data.currentSong != null && boombox.data.pendingPlaybackStart) { statusMessage = "Loading: " + boombox.data.currentSong.Title; } else if (boombox.data.currentSong != null && boombox.data.isPlaying) { statusMessage = "Now playing: " + boombox.data.currentSong.Title; } else if (!string.IsNullOrEmpty(boombox.data.currentSong?.Url)) { statusMessage = "Ready to play: " + boombox.data.currentSong.Title; } else { statusMessage = "Ready to play music! Enter a Video URL"; } } } private void SendTimeUpdate() { if (songTimePerc != lastSentSongTimePerc) { lastSentSongTimePerc = songTimePerc; if (boombox?.GetCurrentSongIndex() == songIndexForTime && songIndexForTime != -1 && (Object)(object)boombox?.audioPlayer?.GetClip() != (Object)null && boombox.audioPlayer.GetClip().length > 0f) { float time = Math.Max(0f, Math.Min(songTimePerc * boombox.audioPlayer.GetClip().length, boombox.audioPlayer.GetClip().length - 0.05f)); boombox.audioPlayer.SetTime(time); boombox.CommitPlaybackSeek(); } else if (songIndexForTime != boombox.GetCurrentSongIndex()) { UpdateDataFromBoomBox(); } } } private void SendVolumeUpdate() { if (boombox.data.absVolume != lastSentVolume) { lastSentVolume = boombox.data.absVolume; boombox.SetVolumeLocal(boombox.data.absVolume); } } private void SendQualityUpdate() { if (qualityLevel != lastSentQualityLevel) { lastSentQualityLevel = qualityLevel; if ((Object)(object)boombox != (Object)null) { boombox.audioPlayer?.SetQuality(qualityLevel); } } } public void HideUI() { //IL_006b: Unknown result type (might be due to invalid IL or missing references) if (showUI) { if ((Object)(object)boombox != (Object)null && isVolumeSliderBeingDragged) { isVolumeSliderBeingDragged = false; SendVolumeUpdate(); } if ((Object)(object)boombox != (Object)null && isIndividualVolumeBeingDragged) { isIndividualVolumeBeingDragged = false; AudioSettings.SetPersonal(boombox.data.personalVolumePercentage); } anyUISHown = false; showUI = false; Cursor.lockState = previousLockMode; Cursor.visible = previousCursorVisible; } } public bool IsUIVisible() { return showUI; } public void UpdateStatus(string message) { statusMessage = message; } private Texture2D CreateColorTexture(Color color) { //IL_0002: 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_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown Texture2D val = new Texture2D(1, 1); val.SetPixel(0, 0, color); val.Apply(); return val; } private void InitializeStyles() { //IL_001f: 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_0069: 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_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Expected O, but got Unknown //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Expected O, but got Unknown //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Expected O, but got Unknown //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Expected O, but got Unknown //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Expected O, but got Unknown //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Expected O, but got Unknown //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_0212: Unknown result type (might be due to invalid IL or missing references) //IL_022c: Unknown result type (might be due to invalid IL or missing references) //IL_0241: Unknown result type (might be due to invalid IL or missing references) //IL_0256: Unknown result type (might be due to invalid IL or missing references) //IL_0279: Unknown result type (might be due to invalid IL or missing references) //IL_0283: Expected O, but got Unknown //IL_028d: Unknown result type (might be due to invalid IL or missing references) //IL_0297: Expected O, but got Unknown //IL_02aa: Unknown result type (might be due to invalid IL or missing references) //IL_02b4: Expected O, but got Unknown //IL_02be: Unknown result type (might be due to invalid IL or missing references) //IL_02c8: Expected O, but got Unknown //IL_02e0: Unknown result type (might be due to invalid IL or missing references) //IL_02ea: Expected O, but got Unknown //IL_031a: Unknown result type (might be due to invalid IL or missing references) //IL_033d: Unknown result type (might be due to invalid IL or missing references) //IL_0347: Expected O, but got Unknown //IL_0352: Unknown result type (might be due to invalid IL or missing references) //IL_035c: Expected O, but got Unknown //IL_037c: Unknown result type (might be due to invalid IL or missing references) //IL_0386: Expected O, but got Unknown //IL_0390: Unknown result type (might be due to invalid IL or missing references) //IL_039a: Expected O, but got Unknown //IL_03a5: Unknown result type (might be due to invalid IL or missing references) //IL_03af: Expected O, but got Unknown //IL_03ba: Unknown result type (might be due to invalid IL or missing references) //IL_03dc: Unknown result type (might be due to invalid IL or missing references) //IL_03e6: Expected O, but got Unknown //IL_03f1: Unknown result type (might be due to invalid IL or missing references) //IL_03fb: Expected O, but got Unknown //IL_0406: Unknown result type (might be due to invalid IL or missing references) //IL_0440: Unknown result type (might be due to invalid IL or missing references) //IL_044a: Expected O, but got Unknown //IL_0467: Unknown result type (might be due to invalid IL or missing references) //IL_0471: Expected O, but got Unknown //IL_0495: Unknown result type (might be due to invalid IL or missing references) //IL_049f: Expected O, but got Unknown //IL_04a6: Unknown result type (might be due to invalid IL or missing references) //IL_04b0: Expected O, but got Unknown //IL_04d0: Unknown result type (might be due to invalid IL or missing references) //IL_04ff: Unknown result type (might be due to invalid IL or missing references) //IL_0521: Unknown result type (might be due to invalid IL or missing references) //IL_052b: Expected O, but got Unknown //IL_054b: Unknown result type (might be due to invalid IL or missing references) //IL_0565: Unknown result type (might be due to invalid IL or missing references) if (!stylesInitialized) { backgroundTexture = CreateColorTexture(new Color(0.1f, 0.1f, 0.1f, 0.9f)); buttonTexture = CreateColorTexture(new Color(0.2f, 0.2f, 0.3f, 1f)); sliderBackgroundTexture = CreateColorTexture(new Color(0.15f, 0.15f, 0.2f, 1f)); sliderThumbTexture = CreateColorTexture(new Color(0.7f, 0.7f, 0.8f, 1f)); textFieldBackgroundTexture = CreateColorTexture(new Color(0.15f, 0.17f, 0.2f, 1f)); windowStyle = new GUIStyle(GUI.skin.window); windowStyle.normal.background = backgroundTexture; windowStyle.onNormal.background = backgroundTexture; windowStyle.border = new RectOffset(10, 10, 10, 10); windowStyle.padding = new RectOffset(15, 15, 20, 15); headerStyle = new GUIStyle(GUI.skin.label); headerStyle.fontSize = 18; headerStyle.fontStyle = (FontStyle)1; headerStyle.normal.textColor = Color.white; headerStyle.alignment = (TextAnchor)4; headerStyle.margin = new RectOffset(0, 0, 10, 20); buttonStyle = new GUIStyle(GUI.skin.button); buttonStyle.normal.background = buttonTexture; buttonStyle.hover.background = CreateColorTexture(new Color(0.3f, 0.3f, 0.4f, 1f)); buttonStyle.active.background = CreateColorTexture(new Color(0.4f, 0.4f, 0.5f, 1f)); buttonStyle.normal.textColor = Color.white; buttonStyle.hover.textColor = Color.white; buttonStyle.active.textColor = Color.white; buttonStyle.fontSize = 14; buttonStyle.padding = new RectOffset(15, 15, 8, 8); buttonStyle.margin = new RectOffset(5, 5, 5, 5); buttonStyle.alignment = (TextAnchor)4; smallButtonStyle = new GUIStyle(buttonStyle); smallButtonStyle.padding = new RectOffset(8, 8, 4, 4); smallButtonStyle.fontSize = 12; textFieldStyle = new GUIStyle(GUI.skin.textField); textFieldStyle.normal.background = textFieldBackgroundTexture; textFieldStyle.normal.textColor = new Color(1f, 1f, 1f); textFieldStyle.fontSize = 14; textFieldStyle.padding = new RectOffset(10, 10, 8, 8); scrollViewStyle = new GUIStyle(GUI.skin.scrollView); scrollViewStyle.normal.background = textFieldBackgroundTexture; scrollViewStyle.border = new RectOffset(2, 2, 2, 2); scrollViewStyle.padding = new RectOffset(0, 0, 0, 0); labelStyle = new GUIStyle(GUI.skin.label); labelStyle.normal.textColor = Color.white; labelStyle.fontSize = 14; labelStyle.margin = new RectOffset(0, 0, 10, 5); statusStyle = new GUIStyle(GUI.skin.label); statusStyle.normal.textColor = Color.cyan; statusStyle.fontSize = 14; statusStyle.wordWrap = true; statusStyle.alignment = (TextAnchor)4; sliderStyle = new GUIStyle(GUI.skin.horizontalSlider); sliderStyle.normal.background = sliderBackgroundTexture; queueHeaderStyle = new GUIStyle(headerStyle); queueHeaderStyle.fontSize = 16; queueHeaderStyle.alignment = (TextAnchor)3; queueHeaderStyle.margin = new RectOffset(5, 0, 10, 5); queueEntryStyle = new GUIStyle(textFieldStyle); queueEntryStyle.normal.background = CreateColorTexture(new Color(0.1f, 0.1f, 0.1f, 0.7f)); queueEntryStyle.hover.background = CreateColorTexture(new Color(0.2f, 0.2f, 0.2f, 0.8f)); queueEntryStyle.alignment = (TextAnchor)3; currentSongStyle = new GUIStyle(queueEntryStyle); currentSongStyle.normal.background = CreateColorTexture(new Color(0.1f, 0.3f, 0.1f, 0.9f)); currentSongStyle.normal.textColor = Color.yellow; currentSongStyle.hover.background = currentSongStyle.normal.background; stylesInitialized = true; } } private void OnGUI() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) if (showUI) { if (!stylesInitialized) { InitializeStyles(); } windowRect = GUILayout.Window(0, windowRect, new WindowFunction(DrawUI), "CarretaFuracao", windowStyle, Array.Empty<GUILayoutOption>()); } } private void DrawUI(int windowID) { if (boombox?.data != null) { DrawCompactPanel(boombox); GUI.DragWindow(); } } private void DrawCompactPanel(Boombox boombox) { GUILayout.Space(6f); float num = 0f; float num2 = 0f; float num3 = 0f; string text = "??"; bool flag = (Object)(object)boombox.audioPlayer?.GetClip() != (Object)null; if (flag) { num = boombox.audioPlayer.audioSource.time; num2 = boombox.audioPlayer.GetClip().length; if (num2 > 0f) { num3 = num / num2; text = PrintTime(num2); } else { flag = false; } } GUILayout.Label(PrintTime(num) + " / " + text, labelStyle, Array.Empty<GUILayoutOption>()); float num4 = GUILayout.HorizontalSlider(num3, 0f, 1f, sliderStyle, GUI.skin.horizontalSliderThumb, Array.Empty<GUILayoutOption>()); int currentSongIndex = boombox.GetCurrentSongIndex(); if (flag && currentSongIndex != -1 && num4 != num3) { isTimeSliderBeingDragged = true; if (songIndexForTime == -2) { songIndexForTime = currentSongIndex; } if (songIndexForTime == currentSongIndex) { float time = Math.Max(0f, Math.Min(num4 * num2, boombox.audioPlayer.GetClip().length - 0.05f)); boombox.audioPlayer.audioSource.time = time; songTimePerc = num4; } } GUILayout.Space(10f); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); if (GUILayout.Button("◀ Anterior", buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(38f) })) { boombox.PlayPreviousRandomJukeboxLocal(); } if (GUILayout.Button("Pular ▶", buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(38f) })) { boombox.PlayNextRandomJukeboxLocal(); } GUILayout.EndHorizontal(); GUILayout.Space(14f); GUILayout.Label($"Volume Master: {Mathf.Round(boombox.data.absVolume * 100f)}%", labelStyle, Array.Empty<GUILayoutOption>()); float num5 = GUILayout.HorizontalSlider(boombox.data.absVolume, 0f, 1f, sliderStyle, GUI.skin.horizontalSliderThumb, Array.Empty<GUILayoutOption>()); if (num5 != boombox.data.absVolume) { isVolumeSliderBeingDragged = true; boombox.data.absVolume = num5; if ((Object)(object)boombox.audioPlayer?.audioSource != (Object)null) { boombox.audioPlayer.SetVolume(boombox.data.absVolume * boombox.data.personalVolumePercentage); } } GUILayout.Space(12f); GUILayout.Label($"Volume Pessoal: {Mathf.Round(boombox.data.personalVolumePercentage * 100f)}%", labelStyle, Array.Empty<GUILayoutOption>()); float num6 = GUILayout.HorizontalSlider(boombox.data.personalVolumePercentage, 0f, 1f, sliderStyle, GUI.skin.horizontalSliderThumb, Array.Empty<GUILayoutOption>()); if (num6 != boombox.data.personalVolumePercentage) { isIndividualVolumeBeingDragged = true; boombox.data.personalVolumePercentage = num6; if ((Object)(object)boombox.audioPlayer?.audioSource != (Object)null) { boombox.audioPlayer.SetVolume(boombox.data.absVolume * boombox.data.personalVolumePercentage); } } GUILayout.Space(10f); GUILayout.Label("E: ligar/desligar", statusStyle, Array.Empty<GUILayoutOption>()); GUILayout.Space(8f); if (GUILayout.Button("Fechar", buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(36f) })) { if ((Object)(object)controller != (Object)null) { controller.ReleaseControl(); } else { HideUI(); } } } private void DrawMainPanel(Boombox boombox) { //IL_0002: 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_001d: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_05ea: Unknown result type (might be due to invalid IL or missing references) //IL_0564: Unknown result type (might be due to invalid IL or missing references) //IL_0584: Unknown result type (might be due to invalid IL or missing references) //IL_05f1: Unknown result type (might be due to invalid IL or missing references) //IL_05f6: Unknown result type (might be due to invalid IL or missing references) //IL_05ff: Unknown result type (might be due to invalid IL or missing references) //IL_0701: Unknown result type (might be due to invalid IL or missing references) //IL_0708: Unknown result type (might be due to invalid IL or missing references) //IL_070d: Unknown result type (might be due to invalid IL or missing references) //IL_0716: Unknown result type (might be due to invalid IL or missing references) //IL_07fe: Unknown result type (might be due to invalid IL or missing references) //IL_0805: Unknown result type (might be due to invalid IL or missing references) //IL_080a: Unknown result type (might be due to invalid IL or missing references) //IL_0813: Unknown result type (might be due to invalid IL or missing references) scrollPosition = GUILayout.BeginScrollView(scrollPosition, false, false, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandHeight(true) }); GUILayout.Space(10f); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.Label("Enter Video URL:", labelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }); if (GUILayout.Button("Clear", smallButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(60f) })) { urlInput = ""; GUI.FocusControl((string)null); } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); urlScrollPosition = GUILayout.BeginScrollView(urlScrollPosition, false, false, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(60f) }); urlInput = GUILayout.TextField(urlInput, textFieldStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(34f) }); urlInput = Regex.Replace(urlInput, "\\s+", ""); GUILayout.EndScrollView(); GUILayout.EndHorizontal(); float num = 0f; float num2 = 0f; float num3 = 0f; string text = "??"; bool flag = (Object)(object)boombox != (Object)null && (Object)(object)boombox.audioPlayer?.GetClip() != (Object)null; if (flag) { num = boombox.audioPlayer.audioSource.time; num2 = boombox.audioPlayer.GetClip().length; if (num2 > 0f) { num3 = num / num2; text = PrintTime(num2); } else { flag = false; } } GUILayout.Label(PrintTime(num) + " / " + text, labelStyle, Array.Empty<GUILayoutOption>()); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); Rect lastRect; if (flag && (int)Event.current.type == 0) { lastRect = GUILayoutUtility.GetLastRect(); if (((Rect)(ref lastRect)).Contains(Event.current.mousePosition)) { isTimeSliderBeingDragged = true; } } float num4 = GUILayout.HorizontalSlider(num3, 0f, 1f, sliderStyle, GUI.skin.horizontalSliderThumb, Array.Empty<GUILayoutOption>()); int currentSongIndex = boombox.GetCurrentSongIndex(); if (flag && currentSongIndex != -1 && num4 != num3) { if (!isTimeSliderBeingDragged) { isTimeSliderBeingDragged = true; } if (songIndexForTime == -2) { songIndexForTime = currentSongIndex; } if (songIndexForTime == currentSongIndex) { float time = Math.Max(0f, Math.Min(num4 * num2, boombox.audioPlayer.GetClip().length - 0.05f)); boombox.audioPlayer.audioSource.time = time; songTimePerc = num4; } } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); if (GUILayout.Button("<<", smallButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(40f), GUILayout.Height(40f) }) && (Object)(object)boombox != (Object)null && boombox.data.currentSong != null) { boombox.JumpPlaybackBySeconds(-10f); } if (GUILayout.Button((boombox?.data != null && boombox.data.playbackQueue.Count > 0) ? "+ ENQUEUE" : "▶ PLAY", buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(40f) })) { var (text2, seconds) = IsValidVideoUrl(urlInput); if (string.IsNullOrEmpty(text2)) { ShowErrorMessage("Invalid Video URL!"); } else if (lastUrl != text2) { lastUrl = text2; boombox.EnqueueSongLocal(text2, seconds); GUI.FocusControl((string)null); } } if (GUILayout.Button((boombox.data.currentSong == null) ? "..." : (boombox.data.isPlaying ? "▌▌ PAUSE" : "▶ RESUME"), buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(40f) }) && boombox.data.currentSong != null) { boombox.SetPlaybackStateLocal(!boombox.data.isPlaying); } if (GUILayout.Button(">>", smallButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(40f), GUILayout.Height(40f) }) && (Object)(object)boombox != (Object)null && boombox.data.currentSong != null) { boombox.JumpPlaybackBySeconds(10f); } GUILayout.EndHorizontal(); if ((Object)(object)boombox != (Object)null && boombox.downloadHelper.IsProcessingQueue()) { Boombox.AudioEntry currentSong = boombox.data.currentSong; if ((currentSong == null || !currentSong.ClipLoaded()) && boombox.downloadHelper.GetCurrentDownloadUrl() != null) { GUILayout.Space(10f); GUILayout.Label("Download in progress...", statusStyle, Array.Empty<GUILayoutOption>()); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.FlexibleSpace(); if (GUILayout.Button("Force Cancel Download", buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(200f), GUILayout.Height(30f) })) { boombox.downloadHelper.ForceCancelDownload(); } GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); } } GUILayout.Space(15f); if (!string.IsNullOrEmpty(statusMessage)) { GUILayout.Label(statusMessage, statusStyle, Array.Empty<GUILayoutOption>()); GUILayout.Space(5f); } if (!string.IsNullOrEmpty(errorMessage)) { GUI.color = Color.red; GUILayout.Label(errorMessage, labelStyle, Array.Empty<GUILayoutOption>()); GUI.color = Color.white; GUILayout.Space(5f); } GUILayout.Space(15f); float num5 = boombox.data.absVolume * 100f; GUILayout.Label($"Volume: {Mathf.Round(num5)}%", labelStyle, Array.Empty<GUILayoutOption>()); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); if ((int)Event.current.type == 0) { lastRect = GUILayoutUtility.GetLastRect(); if (((Rect)(ref lastRect)).Contains(Event.current.mousePosition)) { isVolumeSliderBeingDragged = true; } } float num6 = GUILayout.HorizontalSlider(boombox.data.absVolume, 0f, 1f, sliderStyle, GUI.skin.horizontalSliderThumb, Array.Empty<GUILayoutOption>()); if (num6 != boombox.data.absVolume) { if (!isVolumeSliderBeingDragged) { isVolumeSliderBeingDragged = true; } if ((Object)(object)boombox.audioPlayer?.audioSource != (Object)null) { float volume = boombox.data.absVolume * boombox.data.personalVolumePercentage; boombox.audioPlayer.SetVolume(volume); } boombox.data.absVolume = num6; } GUILayout.EndHorizontal(); GUILayout.Space(15f); GUILayout.Label($"Personal Volume Multiplier: {Mathf.Round(boombox.data.personalVolumePercentage * 100.001f)}%", labelStyle, Array.Empty<GUILayoutOption>()); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); if ((int)Event.current.type == 0) { lastRect = GUILayoutUtility.GetLastRect(); if (((Rect)(ref lastRect)).Contains(Event.current.mousePosition)) { isIndividualVolumeBeingDragged = true; } } float num7 = GUILayout.HorizontalSlider(boombox.data.personalVolumePercentage, 0f, 1f, sliderStyle, GUI.skin.horizontalSliderThumb, Array.Empty<GUILayoutOption>()); if (num7 != boombox.data.personalVolumePercentage) { isIndividualVolumeBeingDragged = true; boombox.data.personalVolumePercentage = num7; if ((Object)(object)boombox.audioPlayer?.audioSource != (Object)null) { boombox.audioPlayer.SetVolume(boombox.data.absVolume * boombox.data.personalVolumePercentage); } } GUILayout.EndHorizontal(); GUILayout.Space(15f); GUILayout.Label("Audio Quality: " + qualityLabels[qualityLevel]