using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net.Security; using System.Security.Cryptography.X509Certificates; using System.Text.RegularExpressions; using Crosstales.Radio.Model; using Crosstales.Radio.Model.Enum; using UnityEngine; namespace Crosstales.Radio.Util { public static class Helper { private static readonly Regex lineEndingsRegex = new Regex("\\r\\n|\\r|\\n"); private static readonly int[] mp3Bitrates = new int[14] { 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320 }; private static readonly int[] oggBitrates = new int[14] { 32, 45, 48, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 500 }; private const string file_prefix = "file://"; public static bool isInternetAvailable { get { return Application.internetReachability != NetworkReachability.NotReachable; } } public static bool isWindowsPlatform { get { return Application.platform == RuntimePlatform.WindowsPlayer || Application.platform == RuntimePlatform.WindowsEditor; } } public static bool isMacOSPlatform { get { return Application.platform == RuntimePlatform.OSXPlayer || Application.platform == RuntimePlatform.OSXEditor; } } public static bool isLinuxPlatform { get { return Application.platform == RuntimePlatform.LinuxPlayer || Application.platform == RuntimePlatform.LinuxEditor; } } public static bool isStandalonePlatform { get { return isWindowsPlatform || isMacOSPlatform || isLinuxPlatform; } } public static bool isAndroidPlatform { get { return Application.platform == RuntimePlatform.Android; } } public static bool isIOSPlatform { get { return Application.platform == RuntimePlatform.IPhonePlayer || Application.platform == RuntimePlatform.tvOS; } } public static bool isWSAPlatform { get { return Application.platform == RuntimePlatform.MetroPlayerARM || Application.platform == RuntimePlatform.MetroPlayerX86 || Application.platform == RuntimePlatform.MetroPlayerX64 || Application.platform == RuntimePlatform.XboxOne; } } public static bool isWebGLPlatform { get { return Application.platform == RuntimePlatform.WebGLPlayer; } } public static bool isWebPlayerPlatform { get { return false; } } public static bool isWebPlatform { get { return isWebPlayerPlatform || isWebGLPlatform; } } public static bool isWindowsBasedPlatform { get { return isWindowsPlatform || isWSAPlatform; } } public static bool isAppleBasedPlatform { get { return isMacOSPlatform || isIOSPlatform; } } public static bool isEditor { get { return Application.platform == RuntimePlatform.OSXEditor || Application.platform == RuntimePlatform.WindowsEditor || Application.platform == RuntimePlatform.LinuxEditor; } } public static bool isEditorMode { get { return isEditor && !Application.isPlaying; } } public static bool isSupportedPlatform { get { return true; } } public static bool RemoteCertificateValidationCallback(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { bool result = true; if (sslPolicyErrors != SslPolicyErrors.None) { for (int i = 0; i < chain.ChainStatus.Length; i++) { if (chain.ChainStatus[i].Status != X509ChainStatusFlags.RevocationStatusUnknown) { chain.ChainPolicy.RevocationFlag = X509RevocationFlag.EntireChain; chain.ChainPolicy.RevocationMode = X509RevocationMode.Online; chain.ChainPolicy.UrlRetrievalTimeout = new TimeSpan(0, 1, 0); chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllFlags; result = chain.Build((X509Certificate2)certificate); } } } return result; } public static bool isSane(ref RadioStation station) { if (station == null) { Debug.LogError("'Station' is null!" + Environment.NewLine + "Add a valid station to the player."); return false; } if (string.IsNullOrEmpty(station.Url)) { Debug.LogError(string.Concat(station, Environment.NewLine, "'Url' is null or empty!", Environment.NewLine, "Cannot start playback -> please add a valid url of a radio station (see 'Radios.txt' for some examples).")); return false; } if (!isValidURL(station.Url)) { Debug.LogError(string.Concat(station, Environment.NewLine, "'Url' is not valid!", Environment.NewLine, "Cannot start playback -> please add a valid url of a radio station (see 'Radios.txt' for some examples).")); return false; } if (!isValidFormat(station.Format)) { Debug.LogError(string.Concat(station, Environment.NewLine, "'Format' is invalid: '", station.Format, "'", Environment.NewLine, "Cannot start playback -> please add a valid audio format for a radio station (see 'Radios.txt' for some examples).")); return false; } if (!isValidBitrate(station.Bitrate, station.Format)) { Debug.LogWarning(string.Concat(station, Environment.NewLine, "'Bitrate' is invalid: ", station.Bitrate, Environment.NewLine, "Autmatically using ", Config.DEFAULT_BITRATE, " kbit/s for playback.")); station.Bitrate = Config.DEFAULT_BITRATE; } if (station.ChunkSize < 1) { Debug.LogWarning(string.Concat(station, Environment.NewLine, "'ChunkSize' is smaller than 1KB!", Environment.NewLine, "Autmatically using ", Config.DEFAULT_CHUNKSIZE, "KB for playback.")); station.ChunkSize = Config.DEFAULT_CHUNKSIZE; } if (station.Format == AudioFormat.MP3) { if (station.BufferSize < Config.DEFAULT_BUFFERSIZE / 4) { Debug.LogWarning(string.Concat(station, Environment.NewLine, "'BufferSize' is smaller than DEFAULT_BUFFERSIZE/4!", Environment.NewLine, "Autmatically using ", Config.DEFAULT_BUFFERSIZE / 4, "KB for playback.")); station.BufferSize = Config.DEFAULT_BUFFERSIZE / 4; } } else if (station.BufferSize < 64) { station.BufferSize = 64; } if (station.BufferSize < station.ChunkSize) { Debug.LogWarning(string.Concat(station, Environment.NewLine, "'BufferSize' is smaller than 'ChunkSize'!", Environment.NewLine, "Autmatically using ", station.ChunkSize, "KB for playback.")); station.BufferSize = station.ChunkSize; } return true; } public static string ValidatePath(string path) { if (!string.IsNullOrEmpty(path)) { string text = path.Trim(); string text2 = null; if (isWindowsPlatform) { text2 = text.Replace('/', '\\'); if (!text2.EndsWith("\\")) { text2 += "\\"; } } else { text2 = text.Replace('\\', '/'); if (!text2.EndsWith("/")) { text2 += "/"; } } return string.Join("_", text2.Split(Path.GetInvalidPathChars())); } return path; } public static string ValidateFile(string path) { if (!string.IsNullOrEmpty(path)) { string text = ValidatePath(path); if (text.EndsWith("\\") || text.EndsWith("/")) { text = text.Substring(0, text.Length - 1); } string text2 = text.Substring((!isWindowsBasedPlatform) ? (text.LastIndexOf("/") + 1) : (text.LastIndexOf("\\") + 1)); string text3 = string.Join(string.Empty, text2.Split(Path.GetInvalidFileNameChars())); return text.Substring(0, text.Length - text2.Length) + text3; } return path; } public static string CleanUrl(string url, bool removeProtocol = true, bool removeWWW = true, bool removeSlash = true) { string text = url.Trim(); if (!string.IsNullOrEmpty(url)) { if (removeProtocol) { text = text.Substring(text.IndexOf("//") + 2); } if (removeProtocol) { text = text.CTReplace("www.", string.Empty); } if (removeSlash && text.EndsWith("/")) { text = text.Substring(0, text.Length - 1); } } return text; } public static List SplitStringToLines(string text, bool ignoreCommentedLines = true, int skipHeaderLines = 0, int skipFooterLines = 0) { List list = new List(100); if (string.IsNullOrEmpty(text)) { Debug.LogWarning("Parameter 'text' is null or empty!" + Environment.NewLine + "=> 'SplitStringToLines()' will return an empty string list."); } else { string[] array = lineEndingsRegex.Split(text); for (int i = 0; i < array.Length; i++) { if (i + 1 <= skipHeaderLines || i >= array.Length - skipFooterLines || string.IsNullOrEmpty(array[i])) { continue; } if (ignoreCommentedLines) { if (!array[i].StartsWith("#", StringComparison.OrdinalIgnoreCase)) { list.Add(array[i]); } } else { list.Add(array[i]); } } } return list; } public static string FormatBytesToHRF(long bytes) { string[] array = new string[5] { "B", "KB", "MB", "GB", "TB" }; double num = bytes; int num2 = 0; while (num >= 1024.0 && num2 < array.Length - 1) { num2++; num /= 1024.0; } return string.Format("{0:0.##} {1}", num, array[num2]); } public static string FormatSecondsToHourMinSec(double seconds) { int num = (int)seconds; int num2 = num % 60; if (seconds >= 3600.0) { int num3 = num / 3600; int num4 = (num - num3 * 3600) / 60; return num3 + ":" + ((num4 >= 10) ? num4.ToString() : ("0" + num4)) + ":" + ((num2 >= 10) ? num2.ToString() : ("0" + num2)); } int num5 = num / 60; return num5 + ":" + ((num2 >= 10) ? num2.ToString() : ("0" + num2)); } public static float[] ConvertByteArrayToFloatArray(byte[] bytes, int count) { float[] array = new float[count / 2]; int num = 0; for (int i = 0; i < count; i += 2) { array[num] = bytesToFloat(bytes[i], bytes[i + 1]); num++; } return array; } public static byte[] ConvertFloatArrayToByteArray(float[] floats, int count) { byte[] array = new byte[count * 2]; int num = 0; int num2 = 0; while (num < count) { short num3 = (short)(floats[num] * 32767f); array[num2] = (byte)(num3 & 0xFF); array[num2 + 1] = (byte)((num3 >> 8) & 0xFF); num++; num2 += 2; } return array; } public static Color HSVToRGB(float h, float s, float v, float a = 1f) { if (s == 0f) { return new Color(v, v, v, a); } h /= 60f; int num = Mathf.FloorToInt(h); float num2 = h - (float)num; float num3 = v * (1f - s); float num4 = v * (1f - s * num2); float num5 = v * (1f - s * (1f - num2)); switch (num) { case 0: return new Color(v, num5, num3, a); case 1: return new Color(num4, v, num3, a); case 2: return new Color(num3, v, num5, a); case 3: return new Color(num3, num4, v, a); case 4: return new Color(num5, num3, v, a); default: return new Color(v, num3, num4, a); } } public static AudioFormat AudioFormatFromString(string format) { AudioFormat result = AudioFormat.MP3; if (!string.IsNullOrEmpty(format) && format.CTEquals("ogg")) { result = AudioFormat.OGG; } return result; } public static AudioCodec AudioCodecFromString(string codec) { AudioCodec result = AudioCodec.None; if (!string.IsNullOrEmpty(codec)) { if (codec.CTEquals("MP3_NLayer")) { result = AudioCodec.MP3_NLayer; } else if (codec.CTEquals("MP3_NAudio")) { result = AudioCodec.MP3_NAudio; } else if (codec.CTEquals("OGG_NVorbis")) { result = AudioCodec.OGG_NVorbis; } } return result; } public static AudioCodec AudioCodecForAudioFormat(AudioFormat format) { switch (format) { case AudioFormat.MP3: if (isWindowsPlatform) { return Constants.DEFAULT_CODEC_MP3_WINDOWS; } return Constants.DEFAULT_CODEC_MP3; case AudioFormat.OGG: return AudioCodec.OGG_NVorbis; default: return AudioCodec.None; } } public static bool isValidFormat(AudioFormat format) { return format == AudioFormat.MP3 || format == AudioFormat.OGG; } public static int NearestBitrate(int bitrate, AudioFormat format) { int num = 128; if (format == AudioFormat.MP3) { return NearestMP3Bitrate(bitrate); } return NearestOGGBitrate(bitrate); } public static int NearestMP3Bitrate(int bitrate) { return mp3Bitrates.Aggregate((int x, int y) => (Math.Abs(x - bitrate) >= Math.Abs(y - bitrate)) ? y : x); } public static int NearestOGGBitrate(int bitrate) { return oggBitrates.Aggregate((int x, int y) => (Math.Abs(x - bitrate) >= Math.Abs(y - bitrate)) ? y : x); } public static bool isValidBitrate(int bitrate, AudioFormat format) { bool flag = false; if (format == AudioFormat.MP3) { return isValidMP3Bitrate(bitrate); } return isValidOGGBitrate(bitrate); } public static bool isValidMP3Bitrate(int bitrate) { return mp3Bitrates.Contains(bitrate); } public static bool isValidOGGBitrate(int bitrate) { return oggBitrates.Contains(bitrate); } public static bool isValidURL(string url) { return !string.IsNullOrEmpty(url) && (url.StartsWith("file://", StringComparison.OrdinalIgnoreCase) || url.StartsWith(Constants.PREFIX_HTTP, StringComparison.OrdinalIgnoreCase) || url.StartsWith(Constants.PREFIX_HTTPS, StringComparison.OrdinalIgnoreCase)); } private static float bytesToFloat(byte firstByte, byte secondByte) { return (float)(short)((secondByte << 8) | firstByte) / 32768f; } } }