using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using FishNet.Connection; using FishNet.Object; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.Networking; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("HowToFishCustomRadio")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("HowToFishCustomRadio")] [assembly: AssemblyTitle("HowToFishCustomRadio")] [assembly: AssemblyVersion("1.0.0.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 HowToFishCustomRadio { [BepInPlugin("neko.howtofish.customradio", "How To Fish Custom Radio", "1.0.0")] public class Plugin : BaseUnityPlugin { public const string PluginGuid = "neko.howtofish.customradio"; public const string PluginName = "How To Fish Custom Radio"; public const string PluginVersion = "1.0.0"; public ConfigEntry ToggleKey; public ConfigEntry DefaultVolume; public ConfigEntry DefaultBass; public ConfigEntry RememberLastSettings; public ConfigEntry CloseMenuOnEscape; internal static float RememberedVolume = 1f; internal static float RememberedBass = 1f; public static Plugin Instance { get; private set; } public static ManualLogSource Log { get; private set; } private void Awake() { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) Instance = this; Log = ((BaseUnityPlugin)this).Logger; BindConfig(); EnsureEventSystem(); new Harmony("neko.howtofish.customradio").PatchAll(); Log.LogInfo((object)"How To Fish Custom Radio 1.0.0 loading..."); Log.LogInfo((object)string.Format("{0} loaded. Toggle key: {1}", "How To Fish Custom Radio", ToggleKey.Value)); } private void BindConfig() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Expected O, but got Unknown //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Expected O, but got Unknown //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Expected O, but got Unknown //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Expected O, but got Unknown ToggleKey = ((BaseUnityPlugin)this).Config.Bind("General", "ToggleKey", (KeyCode)121, new ConfigDescription("Клавиша открытия/закрытия меню радио. Выберите клавишу, которая не занята другими модами. | Key that opens/closes the radio menu. Pick a key that isn't already used by another mod.", (AcceptableValueBase)null, Array.Empty())); DefaultVolume = ((BaseUnityPlugin)this).Config.Bind("Audio", "DefaultVolume", 1f, new ConfigDescription("Громкость по умолчанию для нового радио, от 0.0 (тихо) до 1.0 (максимум). | Default volume for a freshly opened radio, from 0.0 (silent) to 1.0 (max).", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 1f), Array.Empty())); DefaultBass = ((BaseUnityPlugin)this).Config.Bind("Audio", "DefaultBass", 1f, new ConfigDescription("Уровень баса по умолчанию, от 0.0 до 2.0. Значение 1.0 — без изменений звука, выше — сильнее фильтр низких частот. | Default bass level, from 0.0 to 2.0. 1.0 means unmodified sound, higher values apply a stronger low-pass bass filter.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 2f), Array.Empty())); RememberLastSettings = ((BaseUnityPlugin)this).Config.Bind("Audio", "RememberLastSettings", true, new ConfigDescription("Если включено, громкость и бас, выставленные на одном радио, будут автоматически применяться ко всем следующим радио в этой игровой сессии (значения DefaultVolume/DefaultBass в этом случае используются только при самом первом открытии). | If enabled, the volume and bass you set on one radio carry over to every other radio you open during this game session (DefaultVolume/DefaultBass below are then only used the very first time).", (AcceptableValueBase)null, Array.Empty())); CloseMenuOnEscape = ((BaseUnityPlugin)this).Config.Bind("Menu", "CloseMenuOnEscape", true, new ConfigDescription("Закрывать ли меню радио по нажатию Escape. | Whether pressing Escape closes the radio menu.", (AcceptableValueBase)null, Array.Empty())); } private void EnsureEventSystem() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown if (!((Object)(object)EventSystem.current != (Object)null)) { GameObject val = new GameObject("NK_CustomRadio_EventSystem"); Object.DontDestroyOnLoad((Object)(object)val); val.AddComponent(); val.AddComponent(); } } private void Update() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) if (!IsAnyInputFieldFocused() && Input.GetKeyDown(ToggleKey.Value)) { TryOpenRadio(); } } private void TryOpenRadio() { Radio val = FindHeldRadio(); if (!((Object)(object)val == (Object)null)) { CustomRadioUI customRadioUI = ((Component)val).GetComponent(); if ((Object)(object)customRadioUI == (Object)null) { customRadioUI = ((Component)val).gameObject.AddComponent(); } customRadioUI.Toggle(); } } private Radio FindHeldRadio() { Radio[] array = Object.FindObjectsByType((FindObjectsInactive)0); Radio[] array2 = array; foreach (Radio val in array2) { if ((Object)(object)val == (Object)null) { continue; } try { if ((Object)(object)((Item)val).Holder != (Object)null && ((NetworkBehaviour)((Item)val).Holder).Owner != (NetworkConnection)null && ((NetworkBehaviour)((Item)val).Holder).Owner.IsLocalClient) { return val; } } catch { } } return null; } public static bool IsAnyInputFieldFocused() { if ((Object)(object)EventSystem.current == (Object)null) { return false; } GameObject currentSelectedGameObject = EventSystem.current.currentSelectedGameObject; if ((Object)(object)currentSelectedGameObject == (Object)null) { return false; } InputField component = currentSelectedGameObject.GetComponent(); return (Object)(object)component != (Object)null && component.isFocused; } } [HarmonyPatch] internal static class RadioSpawnPatch { [HarmonyPatch(typeof(Radio), "Awake")] [HarmonyPriority(800)] [HarmonyPrefix] private static void Radio_Awake_Prefix(Radio __instance) { EnsureNetworkComponents(((Component)__instance).gameObject); } internal static void EnsureNetworkComponents(GameObject go) { if ((Object)(object)go.GetComponent() == (Object)null) { go.AddComponent(); } if ((Object)(object)go.GetComponent() == (Object)null) { go.AddComponent(); } } } [RequireComponent(typeof(AudioSource))] public class CustomRadioAudio : MonoBehaviour { private AudioSource audioSource; private AudioLowPassFilter lowPassFilter; private AudioHighPassFilter highPassFilter; private Coroutine loadingCoroutine; private AudioClip currentClip; private float volume = 1f; private float bass = 1f; private float lastKnownPosition; private bool loading; private bool stopped; private void Awake() { audioSource = ((Component)this).GetComponent(); if ((Object)(object)audioSource == (Object)null) { audioSource = ((Component)this).gameObject.AddComponent(); } ConfigureAudioSource(); lowPassFilter = ((Component)this).GetComponent(); if ((Object)(object)lowPassFilter == (Object)null) { lowPassFilter = ((Component)this).gameObject.AddComponent(); } highPassFilter = ((Component)this).GetComponent(); if ((Object)(object)highPassFilter == (Object)null) { highPassFilter = ((Component)this).gameObject.AddComponent(); } ConfigureFilters(); } private void ConfigureAudioSource() { audioSource.playOnAwake = false; audioSource.loop = false; audioSource.spatialBlend = 1f; audioSource.spatialize = true; audioSource.rolloffMode = (AudioRolloffMode)0; audioSource.minDistance = 1.5f; audioSource.maxDistance = 30f; audioSource.dopplerLevel = 0f; audioSource.volume = volume; } private void ConfigureFilters() { ((Behaviour)lowPassFilter).enabled = false; lowPassFilter.cutoffFrequency = 22000f; lowPassFilter.lowpassResonanceQ = 1f; ((Behaviour)highPassFilter).enabled = false; highPassFilter.cutoffFrequency = 10f; highPassFilter.highpassResonanceQ = 1f; } private void Update() { if (!((Object)(object)audioSource == (Object)null)) { if (audioSource.isPlaying) { lastKnownPosition = audioSource.time; } ApplyBassFilter(); } } public void PlayUrl(string url, float position = 0f) { if (!string.IsNullOrWhiteSpace(url)) { StopLoading(); stopped = false; loading = true; loadingCoroutine = ((MonoBehaviour)this).StartCoroutine(LoadAndPlay(url, Mathf.Max(0f, position))); } } private IEnumerator LoadAndPlay(string url, float position) { string requestUrl = NormalizeUrl(url); AudioType audioType = DetectAudioType(requestUrl); UnityWebRequest request = UnityWebRequestMultimedia.GetAudioClip(requestUrl, audioType); try { request.timeout = 20; yield return request.SendWebRequest(); if ((int)request.result != 1) { loading = false; loadingCoroutine = null; Debug.LogWarning((object)("[CustomRadio] Audio loading failed: " + request.error)); yield break; } AudioClip clip = DownloadHandlerAudioClip.GetContent(request); if ((Object)(object)clip == (Object)null) { loading = false; loadingCoroutine = null; Debug.LogWarning((object)"[CustomRadio] Server returned no audio clip."); yield break; } if (stopped) { DestroyClip(clip); loading = false; loadingCoroutine = null; yield break; } ReplaceClip(clip); audioSource.clip = currentClip; float safePosition = Mathf.Clamp(position, 0f, Mathf.Max(0f, currentClip.length - 0.01f)); audioSource.time = safePosition; lastKnownPosition = safePosition; audioSource.volume = volume; ApplyBassFilter(); audioSource.Play(); loading = false; loadingCoroutine = null; } finally { ((IDisposable)request)?.Dispose(); } } public void PauseAt(float position) { if (!((Object)(object)audioSource == (Object)null)) { float num = Mathf.Max(0f, position); if ((Object)(object)audioSource.clip != (Object)null) { num = Mathf.Clamp(num, 0f, Mathf.Max(0f, audioSource.clip.length - 0.01f)); audioSource.time = num; } lastKnownPosition = num; audioSource.Pause(); } } public void ResumeAt(float position) { if (!((Object)(object)audioSource == (Object)null) && !((Object)(object)audioSource.clip == (Object)null)) { float time = Mathf.Clamp(position, 0f, Mathf.Max(0f, audioSource.clip.length - 0.01f)); audioSource.time = time; lastKnownPosition = time; audioSource.UnPause(); if (!audioSource.isPlaying) { audioSource.Play(); } } } public void Seek(float position) { if (!((Object)(object)audioSource == (Object)null)) { if ((Object)(object)audioSource.clip == (Object)null) { lastKnownPosition = Mathf.Max(0f, position); return; } float time = Mathf.Clamp(position, 0f, Mathf.Max(0f, audioSource.clip.length - 0.01f)); audioSource.time = time; lastKnownPosition = time; } } public void Stop() { stopped = true; StopLoading(); if ((Object)(object)audioSource != (Object)null) { audioSource.Stop(); audioSource.time = 0f; } lastKnownPosition = 0f; loading = false; if ((Object)(object)currentClip != (Object)null) { DestroyClip(currentClip); currentClip = null; } if ((Object)(object)audioSource != (Object)null) { audioSource.clip = null; } } public void SetVolume(float value) { volume = Mathf.Clamp01(value); if ((Object)(object)audioSource != (Object)null) { audioSource.volume = volume; } } public void SetBass(float value) { bass = Mathf.Clamp(value, 0f, 2f); ApplyBassFilter(); } private void ApplyBassFilter() { if (!((Object)(object)lowPassFilter == (Object)null) && !((Object)(object)highPassFilter == (Object)null)) { if (bass <= 1f) { ((Behaviour)lowPassFilter).enabled = false; ((Behaviour)highPassFilter).enabled = false; return; } ((Behaviour)lowPassFilter).enabled = true; ((Behaviour)highPassFilter).enabled = false; float num = Mathf.InverseLerp(1f, 2f, bass); lowPassFilter.cutoffFrequency = Mathf.Lerp(22000f, 11000f, num); lowPassFilter.lowpassResonanceQ = Mathf.Lerp(1f, 3f, num); } } public float GetPosition() { if ((Object)(object)audioSource != (Object)null && (Object)(object)audioSource.clip != (Object)null && audioSource.isPlaying) { return audioSource.time; } return lastKnownPosition; } public float GetLength() { if ((Object)(object)audioSource == (Object)null || (Object)(object)audioSource.clip == (Object)null) { return 0f; } return audioSource.clip.length; } public bool IsPlaying() { return (Object)(object)audioSource != (Object)null && audioSource.isPlaying; } public bool IsLoading() { return loading; } public float GetVolume() { return volume; } public float GetBass() { return bass; } public AudioSource GetAudioSource() { return audioSource; } private string NormalizeUrl(string url) { url = url.Trim(); if (url.StartsWith("http://", StringComparison.OrdinalIgnoreCase) || url.StartsWith("https://", StringComparison.OrdinalIgnoreCase)) { return url; } return "https://" + url; } private AudioType DetectAudioType(string url) { //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_009e: 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_00b5: Unknown result type (might be due to invalid IL or missing references) string text = url; int num = text.IndexOf('?'); if (num >= 0) { text = text.Substring(0, num); } int num2 = text.IndexOf('#'); if (num2 >= 0) { text = text.Substring(0, num2); } text = text.ToLowerInvariant(); if (text.EndsWith(".wav")) { return (AudioType)20; } if (text.EndsWith(".ogg")) { return (AudioType)14; } if (text.EndsWith(".mp3")) { return (AudioType)13; } if (text.EndsWith(".aiff")) { return (AudioType)24; } if (text.EndsWith(".aif")) { return (AudioType)24; } return (AudioType)13; } private void StopLoading() { stopped = true; if (loadingCoroutine != null) { ((MonoBehaviour)this).StopCoroutine(loadingCoroutine); loadingCoroutine = null; } loading = false; } private void ReplaceClip(AudioClip clip) { //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) if ((Object)(object)currentClip != (Object)null && (Object)(object)currentClip != (Object)(object)clip) { DestroyClip(currentClip); } currentClip = clip; ((Object)currentClip).name = "CustomRadio_" + ((object)((Object)((Component)this).gameObject).GetEntityId()/*cast due to .constrained prefix*/).ToString(); } private void DestroyClip(AudioClip clip) { if ((Object)(object)clip == (Object)null) { return; } try { Object.Destroy((Object)(object)clip); } catch { } } private void OnDestroy() { StopLoading(); if ((Object)(object)currentClip != (Object)null) { DestroyClip(currentClip); currentClip = null; } } } public class CustomRadioController : MonoBehaviour { private Radio radio; private CustomRadioNetwork network; private CustomRadioAudio audioPlayer; private string currentUrl = string.Empty; private string currentTitle = string.Empty; private bool isPlaying; private bool isPaused; private float currentPosition; private float currentVolume = 1f; private float currentBass = 1f; private void Awake() { radio = ((Component)this).GetComponent(); network = ((Component)this).GetComponent(); audioPlayer = ((Component)this).GetComponent(); if ((Object)(object)audioPlayer == (Object)null) { audioPlayer = ((Component)this).gameObject.AddComponent(); } } public void SetNetwork(CustomRadioNetwork value) { network = value; } private void Update() { if (isPlaying && !isPaused && !((Object)(object)audioPlayer == (Object)null)) { currentPosition = audioPlayer.GetPosition(); } } public void Play(string url, string title = "", float position = 0f) { if (!string.IsNullOrWhiteSpace(url)) { currentUrl = url; currentTitle = title ?? string.Empty; currentPosition = Mathf.Max(0f, position); isPlaying = true; isPaused = false; if ((Object)(object)network != (Object)null) { network.SendPlay(currentUrl, currentTitle, currentPosition, currentVolume, currentBass); } else { ApplyPlay(); } } } public void Pause() { if (isPlaying && !isPaused) { currentPosition = (((Object)(object)audioPlayer != (Object)null) ? audioPlayer.GetPosition() : currentPosition); isPaused = true; if ((Object)(object)network != (Object)null) { network.SendPause(currentPosition); } else { ApplyPause(currentPosition); } } } public void Resume() { if (isPlaying && isPaused) { isPaused = false; if ((Object)(object)network != (Object)null) { network.SendResume(currentPosition); } else { ApplyResume(currentPosition); } } } public void Stop() { isPlaying = false; isPaused = false; currentPosition = 0f; if ((Object)(object)network != (Object)null) { network.SendStop(); } else { ApplyStop(); } } public void SetVolume(float value) { currentVolume = Mathf.Clamp01(value); if ((Object)(object)network != (Object)null) { network.SendVolume(currentVolume); } else { ApplyVolume(); } } public void SetBass(float value) { currentBass = Mathf.Clamp(value, 0f, 2f); if ((Object)(object)network != (Object)null) { network.SendBass(currentBass); } else { ApplyBass(); } } public void Seek(float position) { currentPosition = Mathf.Max(0f, position); if ((Object)(object)network != (Object)null) { network.SendSeek(currentPosition); } else { ApplySeek(); } } public void SetTrack(string url, string title = "") { if (!string.IsNullOrWhiteSpace(url)) { currentUrl = url; currentTitle = title ?? string.Empty; currentPosition = 0f; isPlaying = false; isPaused = false; if ((Object)(object)network != (Object)null) { network.SendTrack(currentUrl, currentTitle); } else { ApplyTrack(); } } } public void ServerSetPlay(string url, string title, float position, float volume, float bass) { currentUrl = url ?? string.Empty; currentTitle = title ?? string.Empty; currentPosition = Mathf.Max(0f, position); currentVolume = Mathf.Clamp01(volume); currentBass = Mathf.Clamp(bass, 0f, 2f); isPlaying = true; isPaused = false; } public void ServerSetPause(float position) { currentPosition = Mathf.Max(0f, position); isPaused = true; } public void ServerSetResume(float position) { currentPosition = Mathf.Max(0f, position); isPaused = false; isPlaying = true; } public void ServerSetStop() { currentPosition = 0f; isPlaying = false; isPaused = false; } public void ServerSetVolume(float value) { currentVolume = Mathf.Clamp01(value); } public void ServerSetBass(float value) { currentBass = Mathf.Clamp(value, 0f, 2f); } public void ServerSetSeek(float position) { currentPosition = Mathf.Max(0f, position); } public void ServerSetTrack(string url, string title) { currentUrl = url ?? string.Empty; currentTitle = title ?? string.Empty; currentPosition = 0f; isPlaying = false; isPaused = false; } public void NetworkPlay(string url, string title, float position, float volume, float bass) { currentUrl = url ?? string.Empty; currentTitle = title ?? string.Empty; currentPosition = Mathf.Max(0f, position); currentVolume = Mathf.Clamp01(volume); currentBass = Mathf.Clamp(bass, 0f, 2f); isPlaying = true; isPaused = false; ApplyPlay(); } public void NetworkPause(float position) { currentPosition = Mathf.Max(0f, position); isPaused = true; ApplyPause(currentPosition); } public void NetworkResume(float position) { currentPosition = Mathf.Max(0f, position); isPaused = false; isPlaying = true; ApplyResume(currentPosition); } public void NetworkStop() { currentPosition = 0f; isPlaying = false; isPaused = false; ApplyStop(); } public void NetworkVolume(float value) { currentVolume = Mathf.Clamp01(value); ApplyVolume(); } public void NetworkBass(float value) { currentBass = Mathf.Clamp(value, 0f, 2f); ApplyBass(); } public void NetworkSeek(float position) { currentPosition = Mathf.Max(0f, position); ApplySeek(); } public void NetworkTrack(string url, string title) { currentUrl = url ?? string.Empty; currentTitle = title ?? string.Empty; currentPosition = 0f; isPlaying = false; isPaused = false; ApplyTrack(); } private void ApplyPlay() { if (!((Object)(object)audioPlayer == (Object)null)) { audioPlayer.SetVolume(currentVolume); audioPlayer.SetBass(currentBass); audioPlayer.PlayUrl(currentUrl, currentPosition); } } private void ApplyPause(float position) { if (!((Object)(object)audioPlayer == (Object)null)) { audioPlayer.PauseAt(position); } } private void ApplyResume(float position) { if (!((Object)(object)audioPlayer == (Object)null)) { audioPlayer.ResumeAt(position); } } private void ApplyStop() { if (!((Object)(object)audioPlayer == (Object)null)) { audioPlayer.Stop(); } } private void ApplyVolume() { if (!((Object)(object)audioPlayer == (Object)null)) { audioPlayer.SetVolume(currentVolume); } } private void ApplyBass() { if (!((Object)(object)audioPlayer == (Object)null)) { audioPlayer.SetBass(currentBass); } } private void ApplySeek() { if (!((Object)(object)audioPlayer == (Object)null)) { audioPlayer.Seek(currentPosition); } } private void ApplyTrack() { if (!((Object)(object)audioPlayer == (Object)null)) { audioPlayer.Stop(); } } public Radio GetRadio() { return radio; } public string GetUrl() { return currentUrl; } public string GetTitle() { return currentTitle; } public bool IsPlaying() { return isPlaying; } public bool IsPaused() { return isPaused; } public float GetPosition() { if ((Object)(object)audioPlayer != (Object)null && isPlaying && !isPaused) { return audioPlayer.GetPosition(); } return currentPosition; } public float GetVolume() { return currentVolume; } public float GetBass() { return currentBass; } } public class CustomRadioNetwork : NetworkBehaviour { private CustomRadioController controller; public override void OnStartClient() { ((NetworkBehaviour)this).OnStartClient(); controller = ((Component)this).GetComponent(); if ((Object)(object)controller != (Object)null) { controller.SetNetwork(this); } } public override void OnStartServer() { ((NetworkBehaviour)this).OnStartServer(); controller = ((Component)this).GetComponent(); if ((Object)(object)controller != (Object)null) { controller.SetNetwork(this); } } public void SendPlay(string url, string title, float position, float volume, float bass) { if (((NetworkBehaviour)this).IsClientInitialized) { RpcRequestPlay(url, title, position, volume, bass); } } public void SendPause(float position) { if (((NetworkBehaviour)this).IsClientInitialized) { RpcRequestPause(position); } } public void SendResume(float position) { if (((NetworkBehaviour)this).IsClientInitialized) { RpcRequestResume(position); } } public void SendStop() { if (((NetworkBehaviour)this).IsClientInitialized) { RpcRequestStop(); } } public void SendVolume(float volume) { if (((NetworkBehaviour)this).IsClientInitialized) { RpcRequestVolume(volume); } } public void SendBass(float bass) { if (((NetworkBehaviour)this).IsClientInitialized) { RpcRequestBass(bass); } } public void SendSeek(float position) { if (((NetworkBehaviour)this).IsClientInitialized) { RpcRequestSeek(position); } } public void SendTrack(string url, string title) { if (((NetworkBehaviour)this).IsClientInitialized) { RpcRequestTrack(url, title); } } [ServerRpc(RequireOwnership = false)] private void RpcRequestPlay(string url, string title, float position, float volume, float bass, NetworkConnection sender = null) { if (((NetworkBehaviour)this).IsServerInitialized) { if ((Object)(object)controller == (Object)null) { controller = ((Component)this).GetComponent(); } if (!((Object)(object)controller == (Object)null)) { controller.ServerSetPlay(url, title, position, volume, bass); RpcPlay(url, title, position, volume, bass); } } } [ServerRpc(RequireOwnership = false)] private void RpcRequestPause(float position, NetworkConnection sender = null) { if (((NetworkBehaviour)this).IsServerInitialized) { if ((Object)(object)controller == (Object)null) { controller = ((Component)this).GetComponent(); } if (!((Object)(object)controller == (Object)null)) { controller.ServerSetPause(position); RpcPause(position); } } } [ServerRpc(RequireOwnership = false)] private void RpcRequestResume(float position, NetworkConnection sender = null) { if (((NetworkBehaviour)this).IsServerInitialized) { if ((Object)(object)controller == (Object)null) { controller = ((Component)this).GetComponent(); } if (!((Object)(object)controller == (Object)null)) { controller.ServerSetResume(position); RpcResume(position); } } } [ServerRpc(RequireOwnership = false)] private void RpcRequestStop(NetworkConnection sender = null) { if (((NetworkBehaviour)this).IsServerInitialized) { if ((Object)(object)controller == (Object)null) { controller = ((Component)this).GetComponent(); } if (!((Object)(object)controller == (Object)null)) { controller.ServerSetStop(); RpcStop(); } } } [ServerRpc(RequireOwnership = false)] private void RpcRequestVolume(float volume, NetworkConnection sender = null) { if (((NetworkBehaviour)this).IsServerInitialized) { volume = Mathf.Clamp01(volume); if ((Object)(object)controller == (Object)null) { controller = ((Component)this).GetComponent(); } if (!((Object)(object)controller == (Object)null)) { controller.ServerSetVolume(volume); RpcVolume(volume); } } } [ServerRpc(RequireOwnership = false)] private void RpcRequestBass(float bass, NetworkConnection sender = null) { if (((NetworkBehaviour)this).IsServerInitialized) { bass = Mathf.Clamp(bass, 0f, 2f); if ((Object)(object)controller == (Object)null) { controller = ((Component)this).GetComponent(); } if (!((Object)(object)controller == (Object)null)) { controller.ServerSetBass(bass); RpcBass(bass); } } } [ServerRpc(RequireOwnership = false)] private void RpcRequestSeek(float position, NetworkConnection sender = null) { if (((NetworkBehaviour)this).IsServerInitialized) { position = Mathf.Max(0f, position); if ((Object)(object)controller == (Object)null) { controller = ((Component)this).GetComponent(); } if (!((Object)(object)controller == (Object)null)) { controller.ServerSetSeek(position); RpcSeek(position); } } } [ServerRpc(RequireOwnership = false)] private void RpcRequestTrack(string url, string title, NetworkConnection sender = null) { if (((NetworkBehaviour)this).IsServerInitialized && !string.IsNullOrWhiteSpace(url) && url.Length <= 2048) { if (title == null) { title = string.Empty; } if (title.Length > 256) { title = title.Substring(0, 256); } if ((Object)(object)controller == (Object)null) { controller = ((Component)this).GetComponent(); } if (!((Object)(object)controller == (Object)null)) { controller.ServerSetTrack(url, title); RpcTrack(url, title); } } } [ObserversRpc(BufferLast = true)] private void RpcPlay(string url, string title, float position, float volume, float bass) { if ((Object)(object)controller == (Object)null) { controller = ((Component)this).GetComponent(); } if (!((Object)(object)controller == (Object)null)) { controller.NetworkPlay(url, title, position, volume, bass); } } [ObserversRpc(BufferLast = true)] private void RpcPause(float position) { if ((Object)(object)controller == (Object)null) { controller = ((Component)this).GetComponent(); } if (!((Object)(object)controller == (Object)null)) { controller.NetworkPause(position); } } [ObserversRpc(BufferLast = true)] private void RpcResume(float position) { if ((Object)(object)controller == (Object)null) { controller = ((Component)this).GetComponent(); } if (!((Object)(object)controller == (Object)null)) { controller.NetworkResume(position); } } [ObserversRpc(BufferLast = true)] private void RpcStop() { if ((Object)(object)controller == (Object)null) { controller = ((Component)this).GetComponent(); } if (!((Object)(object)controller == (Object)null)) { controller.NetworkStop(); } } [ObserversRpc(BufferLast = true)] private void RpcVolume(float volume) { if ((Object)(object)controller == (Object)null) { controller = ((Component)this).GetComponent(); } if (!((Object)(object)controller == (Object)null)) { controller.NetworkVolume(volume); } } [ObserversRpc(BufferLast = true)] private void RpcBass(float bass) { if ((Object)(object)controller == (Object)null) { controller = ((Component)this).GetComponent(); } if (!((Object)(object)controller == (Object)null)) { controller.NetworkBass(bass); } } [ObserversRpc(BufferLast = true)] private void RpcSeek(float position) { if ((Object)(object)controller == (Object)null) { controller = ((Component)this).GetComponent(); } if (!((Object)(object)controller == (Object)null)) { controller.NetworkSeek(position); } } [ObserversRpc(BufferLast = true)] private void RpcTrack(string url, string title) { if ((Object)(object)controller == (Object)null) { controller = ((Component)this).GetComponent(); } if (!((Object)(object)controller == (Object)null)) { controller.NetworkTrack(url, title); } } } public class CustomRadioUI : MonoBehaviour { [Serializable] private class FavoriteTrack { public string title; public string url; } [Serializable] private class FavoriteSaveData { public List tracks = new List(); } private const float WindowWidth = 720f; private const float WindowHeight = 700f; private const float Margin = 24f; private static readonly Color ColorWindowBg = new Color(0.055f, 0.035f, 0.085f, 0.98f); private static readonly Color ColorWindowBorder = new Color(0.55f, 0.35f, 0.85f, 1f); private static readonly Color ColorHeaderBg = new Color(0.09f, 0.06f, 0.15f, 1f); private static readonly Color ColorRowBg = new Color(0.09f, 0.06f, 0.15f, 1f); private static readonly Color ColorRowBorder = new Color(0.45f, 0.28f, 0.68f, 0.9f); private static readonly Color ColorInputBg = new Color(0.07f, 0.045f, 0.11f, 1f); private static readonly Color ColorButtonNormal = new Color(0.15f, 0.09f, 0.23f, 1f); private static readonly Color ColorButtonHighlight = new Color(0.3f, 0.16f, 0.46f, 1f); private static readonly Color ColorButtonPressed = new Color(0.4f, 0.2f, 0.58f, 1f); private static readonly Color ColorTextMain = new Color(0.93f, 0.92f, 0.98f); private static readonly Color ColorTextDim = new Color(0.62f, 0.58f, 0.72f); private CustomRadioController controller; private GameObject canvasObject; private GameObject windowObject; private GameObject favoritesObject; private GameObject favoritesContent; private InputField urlInput; private InputField titleInput; private Text statusText; private Text timeText; private Text volumeText; private Text bassText; private Slider volumeSlider; private Slider bassSlider; private Slider positionSlider; private Button favoriteButton; private bool visible; private bool suppressSliderEvents; private Sprite roundedSprite; private bool cursorStateSaved; private CursorLockMode previousLockState; private bool previousCursorVisible; private readonly List favorites = new List(); private string savePath; private void Awake() { controller = ((Component)this).GetComponent(); if ((Object)(object)controller == (Object)null) { controller = ((Component)this).gameObject.AddComponent(); } savePath = Path.Combine(Application.persistentDataPath, "CustomRadioFavorites.json"); LoadFavorites(); ApplyDefaultAudioSettings(); EnsureEventSystem(); CreateUI(); SetVisible(state: false); } private void Update() { if (visible) { UpdateState(); if (((Object)(object)Plugin.Instance == (Object)null || Plugin.Instance.CloseMenuOnEscape.Value) && Input.GetKeyDown((KeyCode)27)) { SetVisible(state: false); } } } private void LateUpdate() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Invalid comparison between Unknown and I4 if (visible) { if ((int)Cursor.lockState > 0) { Cursor.lockState = (CursorLockMode)0; } if (!Cursor.visible) { Cursor.visible = true; } } } private void EnsureEventSystem() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown if (!((Object)(object)EventSystem.current != (Object)null)) { GameObject val = new GameObject("NK_CustomRadio_EventSystem"); Object.DontDestroyOnLoad((Object)(object)val); val.AddComponent(); val.AddComponent(); } } public void Toggle() { SetVisible(!visible); } public void Open() { SetVisible(state: true); } public void Close() { SetVisible(state: false); } private void SetVisible(bool state) { //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) visible = state; if ((Object)(object)canvasObject != (Object)null) { canvasObject.SetActive(state); } if (state) { if (!cursorStateSaved) { previousLockState = Cursor.lockState; previousCursorVisible = Cursor.visible; cursorStateSaved = true; } Cursor.lockState = (CursorLockMode)0; Cursor.visible = true; RefreshUI(); } else if (cursorStateSaved) { Cursor.lockState = previousLockState; Cursor.visible = previousCursorVisible; cursorStateSaved = false; } } private void CreateUI() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) canvasObject = new GameObject("CustomRadioCanvas"); canvasObject.transform.SetParent((Transform)null, false); Canvas val = canvasObject.AddComponent(); val.renderMode = (RenderMode)0; val.sortingOrder = 5000; CanvasScaler val2 = canvasObject.AddComponent(); val2.uiScaleMode = (ScaleMode)1; val2.referenceResolution = new Vector2(1920f, 1080f); canvasObject.AddComponent(); windowObject = CreateRoundedPanel(canvasObject.transform, "RadioWindow", new Vector2(720f, 700f), Vector2.zero, ColorWindowBg, ColorWindowBorder, 2f); RectTransform component = windowObject.GetComponent(); component.anchorMin = new Vector2(0.5f, 0.5f); component.anchorMax = new Vector2(0.5f, 0.5f); component.pivot = new Vector2(0.5f, 0.5f); AddHeader(); AddUrlSection(); AddControls(); AddSliders(); AddFavorites(); } private void AddHeader() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: 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) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Expected O, but got Unknown GameObject val = CreateRoundedPanel(windowObject.transform, "Header", new Vector2(672f, 56f), Vector2.zero, ColorHeaderBg, ColorRowBorder, 1.5f); SetTopPosition(val, new Vector2(24f, -24f), val.GetComponent().sizeDelta); Text val2 = CreateText(val.transform, "CUSTOM RADIO", 22, (TextAnchor)3); val2.fontStyle = (FontStyle)1; RectTransform component = ((Component)val2).GetComponent(); component.anchorMin = new Vector2(0f, 0f); component.anchorMax = new Vector2(1f, 1f); component.offsetMin = new Vector2(20f, 0f); component.offsetMax = new Vector2(-60f, 0f); Button val3 = CreateButton(val.transform, "X", new Vector2(36f, 36f)); RectTransform component2 = ((Component)val3).GetComponent(); component2.anchorMin = new Vector2(1f, 0.5f); component2.anchorMax = new Vector2(1f, 0.5f); component2.pivot = new Vector2(1f, 0.5f); component2.anchoredPosition = new Vector2(-10f, 0f); ((UnityEvent)val3.onClick).AddListener(new UnityAction(Close)); } private void AddUrlSection() { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) float num = -100f; Text val = CreateText(windowObject.transform, "AUDIO URL", 13, (TextAnchor)3); ((Graphic)val).color = ColorTextDim; SetTopPosition(((Component)val).gameObject, new Vector2(24f, num), new Vector2(300f, 20f)); num -= 24f; urlInput = CreateInput(windowObject.transform, "https://example.com/music.mp3"); SetTopPosition(((Component)urlInput).gameObject, new Vector2(24f, num), new Vector2(672f, 44f)); num -= 66f; Text val2 = CreateText(windowObject.transform, "TRACK NAME", 13, (TextAnchor)3); ((Graphic)val2).color = ColorTextDim; SetTopPosition(((Component)val2).gameObject, new Vector2(24f, num), new Vector2(300f, 20f)); num -= 24f; titleInput = CreateInput(windowObject.transform, "Track name"); SetTopPosition(((Component)titleInput).gameObject, new Vector2(24f, num), new Vector2(672f, 44f)); } private void AddControls() { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Expected O, but got Unknown //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Expected O, but got Unknown //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Expected O, but got Unknown //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Expected O, but got Unknown //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_01fb: Unknown result type (might be due to invalid IL or missing references) float num = -304f; GameObject val = CreateRoundedPanel(windowObject.transform, "ControlsRow", new Vector2(672f, 52f), Vector2.zero, ColorRowBg, ColorRowBorder, 1.5f); SetTopPosition(val, new Vector2(24f, num), val.GetComponent().sizeDelta); float num2 = 660f; float num3 = num2 / 4f - 6f; Button val2 = CreateButton(val.transform, "PLAY", new Vector2(num3, 40f)); SetInnerRowPosition(((Component)val2).gameObject, 0, 4, num2, 40f); ((UnityEvent)val2.onClick).AddListener(new UnityAction(Play)); Button val3 = CreateButton(val.transform, "PAUSE", new Vector2(num3, 40f)); SetInnerRowPosition(((Component)val3).gameObject, 1, 4, num2, 40f); ((UnityEvent)val3.onClick).AddListener(new UnityAction(PauseResume)); Button val4 = CreateButton(val.transform, "STOP", new Vector2(num3, 40f)); SetInnerRowPosition(((Component)val4).gameObject, 2, 4, num2, 40f); ((UnityEvent)val4.onClick).AddListener(new UnityAction(Stop)); favoriteButton = CreateButton(val.transform, "FAVORITE", new Vector2(num3, 40f)); SetInnerRowPosition(((Component)favoriteButton).gameObject, 3, 4, num2, 40f); ((UnityEvent)favoriteButton.onClick).AddListener(new UnityAction(ToggleFavorite)); num -= 68f; statusText = CreateText(windowObject.transform, "Ready", 13, (TextAnchor)3); SetTopPosition(((Component)statusText).gameObject, new Vector2(24f, num), new Vector2(672f, 24f)); } private void AddSliders() { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_020a: Unknown result type (might be due to invalid IL or missing references) //IL_0219: Unknown result type (might be due to invalid IL or missing references) //IL_0255: Unknown result type (might be due to invalid IL or missing references) //IL_0264: Unknown result type (might be due to invalid IL or missing references) float num = -400f; float num2 = 324f; volumeText = CreateText(windowObject.transform, "VOLUME: 100%", 13, (TextAnchor)3); SetTopPosition(((Component)volumeText).gameObject, new Vector2(24f, num), new Vector2(num2, 22f)); bassText = CreateText(windowObject.transform, "BASS: 100%", 13, (TextAnchor)3); SetTopPosition(((Component)bassText).gameObject, new Vector2(24f + num2 + 24f, num), new Vector2(num2, 22f)); num -= 30f; volumeSlider = CreateSlider(windowObject.transform); SetTopPosition(((Component)volumeSlider).gameObject, new Vector2(24f, num), new Vector2(num2, 24f)); volumeSlider.minValue = 0f; volumeSlider.maxValue = 1f; volumeSlider.value = 1f; ((UnityEvent)(object)volumeSlider.onValueChanged).AddListener((UnityAction)OnVolumeChanged); bassSlider = CreateSlider(windowObject.transform); SetTopPosition(((Component)bassSlider).gameObject, new Vector2(24f + num2 + 24f, num), new Vector2(num2, 24f)); bassSlider.minValue = 0f; bassSlider.maxValue = 2f; bassSlider.value = 1f; ((UnityEvent)(object)bassSlider.onValueChanged).AddListener((UnityAction)OnBassChanged); num -= 46f; timeText = CreateText(windowObject.transform, "00:00 / 00:00", 13, (TextAnchor)4); SetTopPosition(((Component)timeText).gameObject, new Vector2(24f, num), new Vector2(672f, 22f)); num -= 28f; positionSlider = CreateSlider(windowObject.transform); SetTopPosition(((Component)positionSlider).gameObject, new Vector2(24f, num), new Vector2(672f, 24f)); positionSlider.minValue = 0f; positionSlider.maxValue = 1f; positionSlider.value = 0f; ((UnityEvent)(object)positionSlider.onValueChanged).AddListener((UnityAction)OnPositionChanged); } private void AddFavorites() { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Expected O, but got Unknown //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Expected O, but got Unknown //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) float num = -546f; Text val = CreateText(windowObject.transform, "FAVORITES", 14, (TextAnchor)3); val.fontStyle = (FontStyle)1; SetTopPosition(((Component)val).gameObject, new Vector2(24f, num), new Vector2(200f, 22f)); num -= 28f; favoritesObject = new GameObject("FavoritesArea"); favoritesObject.transform.SetParent(windowObject.transform, false); float num2 = 700f + num - 24f; SetTopPosition(favoritesObject, new Vector2(24f, num), new Vector2(672f, num2)); favoritesObject.AddComponent(); favoritesContent = new GameObject("FavoritesContent"); favoritesContent.transform.SetParent(favoritesObject.transform, false); RectTransform val2 = favoritesContent.AddComponent(); val2.anchorMin = new Vector2(0f, 1f); val2.anchorMax = new Vector2(1f, 1f); val2.pivot = new Vector2(0f, 1f); val2.anchoredPosition = Vector2.zero; val2.sizeDelta = new Vector2(0f, 0f); RefreshFavorites(); } private void Play() { if ((Object)(object)controller == (Object)null) { return; } string text = (((Object)(object)urlInput != (Object)null) ? urlInput.text.Trim() : string.Empty); if (string.IsNullOrWhiteSpace(text)) { SetStatus("Введите URL аудио."); return; } string text2 = (((Object)(object)titleInput != (Object)null) ? titleInput.text.Trim() : string.Empty); if (string.IsNullOrWhiteSpace(text2)) { text2 = "Custom Radio Track"; } controller.Play(text, text2); SetStatus("Загрузка: " + text2); } private void PauseResume() { if (!((Object)(object)controller == (Object)null)) { if (controller.IsPaused()) { controller.Resume(); SetStatus("Продолжение воспроизведения."); } else { controller.Pause(); SetStatus("Пауза."); } } } private void Stop() { if (!((Object)(object)controller == (Object)null)) { controller.Stop(); SetStatus("Остановлено."); } } private void OnVolumeChanged(float value) { if (!suppressSliderEvents && !((Object)(object)controller == (Object)null)) { controller.SetVolume(value); if ((Object)(object)Plugin.Instance != (Object)null && Plugin.Instance.RememberLastSettings.Value) { Plugin.RememberedVolume = value; } if ((Object)(object)volumeText != (Object)null) { volumeText.text = "VOLUME: " + Mathf.RoundToInt(value * 100f) + "%"; } } } private void OnBassChanged(float value) { if (!suppressSliderEvents && !((Object)(object)controller == (Object)null)) { controller.SetBass(value); if ((Object)(object)Plugin.Instance != (Object)null && Plugin.Instance.RememberLastSettings.Value) { Plugin.RememberedBass = value; } if ((Object)(object)bassText != (Object)null) { bassText.text = "BASS: " + Mathf.RoundToInt(value * 100f) + "%"; } } } private void OnPositionChanged(float value) { if (suppressSliderEvents || (Object)(object)controller == (Object)null || !controller.IsPlaying()) { return; } CustomRadioAudio component = ((Component)controller).GetComponent(); if (!((Object)(object)component == (Object)null)) { float length = component.GetLength(); if (!(length <= 0f)) { controller.Seek(value * length); } } } private void ToggleFavorite() { if ((Object)(object)controller == (Object)null) { return; } string text = (((Object)(object)urlInput != (Object)null) ? urlInput.text.Trim() : controller.GetUrl()); if (string.IsNullOrWhiteSpace(text)) { SetStatus("Нет трека для добавления."); return; } string text2 = (((Object)(object)titleInput != (Object)null) ? titleInput.text.Trim() : controller.GetTitle()); if (string.IsNullOrWhiteSpace(text2)) { text2 = "Custom Radio Track"; } int num = FindFavorite(text); if (num >= 0) { favorites.RemoveAt(num); SetStatus("Удалено из избранного."); } else { favorites.Add(new FavoriteTrack { title = text2, url = text }); SetStatus("Добавлено в избранное."); } SaveFavorites(); RefreshFavorites(); } private int FindFavorite(string url) { for (int i = 0; i < favorites.Count; i++) { if (string.Equals(favorites[i].url, url, StringComparison.OrdinalIgnoreCase)) { return i; } } return -1; } private void LoadFavorite(FavoriteTrack track) { if (track != null) { if ((Object)(object)urlInput != (Object)null) { urlInput.text = track.url ?? string.Empty; } if ((Object)(object)titleInput != (Object)null) { titleInput.text = track.title ?? string.Empty; } if ((Object)(object)controller != (Object)null) { controller.Play(track.url, track.title); } SetStatus("Загрузка: " + track.title); } } private void RemoveFavorite(int index) { if (index >= 0 && index < favorites.Count) { favorites.RemoveAt(index); SaveFavorites(); RefreshFavorites(); } } private void RefreshFavorites() { //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_02e3: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Unknown result type (might be due to invalid IL or missing references) //IL_020a: Expected O, but got Unknown //IL_0222: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_025a: Unknown result type (might be due to invalid IL or missing references) //IL_0271: Unknown result type (might be due to invalid IL or missing references) //IL_0288: Unknown result type (might be due to invalid IL or missing references) //IL_02a2: Unknown result type (might be due to invalid IL or missing references) //IL_02ac: Expected O, but got Unknown if ((Object)(object)favoritesContent == (Object)null) { return; } for (int num = favoritesContent.transform.childCount - 1; num >= 0; num--) { Object.Destroy((Object)(object)((Component)favoritesContent.transform.GetChild(num)).gameObject); } float num2 = 40f; float num3 = 0f; for (int i = 0; i < favorites.Count; i++) { int index = i; FavoriteTrack track = favorites[i]; GameObject val = CreateRoundedPanel(favoritesContent.transform, "FavoriteRow", new Vector2(0f, num2 - 6f), Vector2.zero, ColorRowBg, ColorRowBorder, 1f); RectTransform component = val.GetComponent(); component.anchorMin = new Vector2(0f, 1f); component.anchorMax = new Vector2(1f, 1f); component.pivot = new Vector2(0f, 1f); component.anchoredPosition = new Vector2(0f, 0f - num3); component.sizeDelta = new Vector2(0f, num2 - 6f); Button val2 = CreateButton(val.transform, track.title, new Vector2(0f, 0f)); RectTransform component2 = ((Component)val2).GetComponent(); component2.anchorMin = Vector2.zero; component2.anchorMax = Vector2.one; component2.offsetMin = new Vector2(4f, 4f); component2.offsetMax = new Vector2(-44f, -4f); Text componentInChildren = ((Component)val2).GetComponentInChildren(); if ((Object)(object)componentInChildren != (Object)null) { componentInChildren.alignment = (TextAnchor)3; } ((UnityEvent)val2.onClick).AddListener((UnityAction)delegate { LoadFavorite(track); }); Button val3 = CreateButton(val.transform, "X", new Vector2(32f, 32f)); RectTransform component3 = ((Component)val3).GetComponent(); component3.anchorMin = new Vector2(1f, 0.5f); component3.anchorMax = new Vector2(1f, 0.5f); component3.pivot = new Vector2(1f, 0.5f); component3.anchoredPosition = new Vector2(-6f, 0f); ((UnityEvent)val3.onClick).AddListener((UnityAction)delegate { RemoveFavorite(index); }); num3 += num2; } RectTransform component4 = favoritesContent.GetComponent(); component4.sizeDelta = new Vector2(0f, num3); } private void SaveFavorites() { try { FavoriteSaveData favoriteSaveData = new FavoriteSaveData { tracks = new List(favorites) }; string contents = JsonUtility.ToJson((object)favoriteSaveData, true); File.WriteAllText(savePath, contents); } catch (Exception ex) { Debug.LogWarning((object)("[CustomRadio] Failed to save favorites: " + ex.Message)); } } private void LoadFavorites() { favorites.Clear(); try { if (!File.Exists(savePath)) { return; } string text = File.ReadAllText(savePath); if (!string.IsNullOrWhiteSpace(text)) { FavoriteSaveData favoriteSaveData = JsonUtility.FromJson(text); if (favoriteSaveData != null && favoriteSaveData.tracks != null) { favorites.AddRange(favoriteSaveData.tracks); } } } catch (Exception ex) { Debug.LogWarning((object)("[CustomRadio] Failed to load favorites: " + ex.Message)); } } private void ApplyDefaultAudioSettings() { if (!((Object)(object)Plugin.Instance == (Object)null) && !((Object)(object)controller == (Object)null)) { float volume = (Plugin.Instance.RememberLastSettings.Value ? Plugin.RememberedVolume : Plugin.Instance.DefaultVolume.Value); float bass = (Plugin.Instance.RememberLastSettings.Value ? Plugin.RememberedBass : Plugin.Instance.DefaultBass.Value); controller.SetVolume(volume); controller.SetBass(bass); } } private void UpdateState() { if ((Object)(object)controller == (Object)null) { return; } if ((Object)(object)volumeSlider != (Object)null) { suppressSliderEvents = true; volumeSlider.value = controller.GetVolume(); suppressSliderEvents = false; } if ((Object)(object)bassSlider != (Object)null) { suppressSliderEvents = true; bassSlider.value = controller.GetBass(); suppressSliderEvents = false; } CustomRadioAudio component = ((Component)controller).GetComponent(); if ((Object)(object)component != (Object)null) { float length = component.GetLength(); float position = controller.GetPosition(); if ((Object)(object)positionSlider != (Object)null && length > 0f) { suppressSliderEvents = true; positionSlider.value = Mathf.Clamp01(position / length); suppressSliderEvents = false; } if ((Object)(object)timeText != (Object)null) { timeText.text = FormatTime(position) + " / " + FormatTime(length); } } if ((Object)(object)statusText != (Object)null) { if ((Object)(object)component != (Object)null && component.IsLoading()) { statusText.text = "Загрузка..."; } else if (controller.IsPaused()) { statusText.text = "Пауза: " + controller.GetTitle(); } else if (controller.IsPlaying()) { statusText.text = "Играет: " + controller.GetTitle(); } } UpdateFavoriteButton(); } private void UpdateFavoriteButton() { if (!((Object)(object)favoriteButton == (Object)null) && !((Object)(object)controller == (Object)null)) { string url = controller.GetUrl(); bool flag = !string.IsNullOrWhiteSpace(url) && FindFavorite(url) >= 0; Text componentInChildren = ((Component)favoriteButton).GetComponentInChildren(); if ((Object)(object)componentInChildren != (Object)null) { componentInChildren.text = (flag ? "UNFAVORITE" : "FAVORITE"); } } } private void RefreshUI() { if (!((Object)(object)controller == (Object)null)) { if ((Object)(object)urlInput != (Object)null) { urlInput.text = controller.GetUrl(); } if ((Object)(object)titleInput != (Object)null) { titleInput.text = controller.GetTitle(); } suppressSliderEvents = true; if ((Object)(object)volumeSlider != (Object)null) { volumeSlider.value = controller.GetVolume(); } if ((Object)(object)bassSlider != (Object)null) { bassSlider.value = controller.GetBass(); } suppressSliderEvents = false; RefreshFavorites(); UpdateState(); } } private void SetStatus(string message) { if ((Object)(object)statusText != (Object)null) { statusText.text = message; } } private string FormatTime(float seconds) { seconds = Mathf.Max(0f, seconds); TimeSpan timeSpan = TimeSpan.FromSeconds(seconds); if (timeSpan.TotalHours >= 1.0) { return $"{(int)timeSpan.TotalHours:00}:{timeSpan.Minutes:00}:{timeSpan.Seconds:00}"; } return $"{timeSpan.Minutes:00}:{timeSpan.Seconds:00}"; } private Sprite GetRoundedSprite() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)roundedSprite != (Object)null) { return roundedSprite; } Texture2D val = new Texture2D(64, 64, (TextureFormat)5, false); ((Texture)val).filterMode = (FilterMode)1; ((Texture)val).wrapMode = (TextureWrapMode)1; for (int i = 0; i < 64; i++) { for (int j = 0; j < 64; j++) { float num = RoundedAlpha(j, i, 64, 64, 18); val.SetPixel(j, i, new Color(1f, 1f, 1f, num)); } } val.Apply(); roundedSprite = Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f), 100f, 0u, (SpriteMeshType)0, new Vector4(18f, 18f, 18f, 18f)); return roundedSprite; } private float RoundedAlpha(int x, int y, int width, int height, int radius) { float num = (float)x + 0.5f; float num2 = (float)y + 0.5f; float num3 = radius; float num4 = radius; float num5 = width - radius; float num6 = height - radius; float num7 = Mathf.Clamp(num, num3, num5); float num8 = Mathf.Clamp(num2, num4, num6); float num9 = num - num7; float num10 = num2 - num8; float num11 = Mathf.Sqrt(num9 * num9 + num10 * num10); float num12 = (float)radius - num11; return Mathf.Clamp01(num12 + 0.5f); } private GameObject CreateRoundedPanel(Transform parent, string objectName, Vector2 size, Vector2 anchoredPos, Color bgColor, Color borderColor, float borderWidth) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown //IL_001e: 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_004b: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Expected O, but got Unknown //IL_0081: 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_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(objectName); val.transform.SetParent(parent, false); RectTransform val2 = val.AddComponent(); val2.sizeDelta = size; val2.anchoredPosition = anchoredPos; Image val3 = val.AddComponent(); val3.sprite = GetRoundedSprite(); val3.type = (Type)1; ((Graphic)val3).color = borderColor; GameObject val4 = new GameObject(objectName + "_BG"); val4.transform.SetParent(val.transform, false); RectTransform val5 = val4.AddComponent(); val5.anchorMin = Vector2.zero; val5.anchorMax = Vector2.one; val5.offsetMin = new Vector2(borderWidth, borderWidth); val5.offsetMax = new Vector2(0f - borderWidth, 0f - borderWidth); Image val6 = val4.AddComponent(); val6.sprite = GetRoundedSprite(); val6.type = (Type)1; ((Graphic)val6).color = bgColor; return val; } private Text CreateText(Transform parent, string value, int size, TextAnchor alignment) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Text"); val.transform.SetParent(parent, false); val.AddComponent(); Text val2 = val.AddComponent(); val2.text = value; val2.font = Resources.GetBuiltinResource("Arial.ttf"); val2.fontSize = size; val2.alignment = alignment; ((Graphic)val2).color = ColorTextMain; val2.horizontalOverflow = (HorizontalWrapMode)1; val2.verticalOverflow = (VerticalWrapMode)0; return val2; } private InputField CreateInput(Transform parent, string placeholder) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("InputField"); val.transform.SetParent(parent, false); val.AddComponent(); Image val2 = val.AddComponent(); val2.sprite = GetRoundedSprite(); val2.type = (Type)1; ((Graphic)val2).color = ColorInputBg; InputField val3 = val.AddComponent(); Text val4 = CreateText(val.transform, "", 14, (TextAnchor)3); RectTransform component = ((Component)val4).GetComponent(); component.anchorMin = new Vector2(0f, 0f); component.anchorMax = new Vector2(1f, 1f); component.offsetMin = new Vector2(14f, 0f); component.offsetMax = new Vector2(-14f, 0f); val3.textComponent = val4; Text val5 = CreateText(val.transform, placeholder, 14, (TextAnchor)3); ((Graphic)val5).color = ColorTextDim; RectTransform component2 = ((Component)val5).GetComponent(); component2.anchorMin = new Vector2(0f, 0f); component2.anchorMax = new Vector2(1f, 1f); component2.offsetMin = new Vector2(14f, 0f); component2.offsetMax = new Vector2(-14f, 0f); val3.placeholder = (Graphic)(object)val5; return val3; } private Button CreateButton(Transform parent, string caption, Vector2 size) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_006f: 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_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Button"); val.transform.SetParent(parent, false); RectTransform val2 = val.AddComponent(); val2.sizeDelta = size; Image val3 = val.AddComponent(); val3.sprite = GetRoundedSprite(); val3.type = (Type)1; ((Graphic)val3).color = Color.white; Button val4 = val.AddComponent