using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using Azerion.BlueStack.MiniJSON; using UnityEngine; using UnityEngine.Networking; using Debug = UnityEngine.Debug; namespace Azerion.BlueStack.Common { internal class NativeUtils { public static string Version { get; private set; } static NativeUtils() { Version version = typeof(NativeUtils).Assembly.GetName().Version; Version = string.Format("{0}.{1}.{2}", version.Major, version.Minor, version.Revision); } public static bool IsRenderedInScreenSpaceOverlayCanvas(GameObject gameObject) { Canvas componentInParent = gameObject.GetComponentInParent(); return !(componentInParent == null) && componentInParent.renderMode == RenderMode.ScreenSpaceOverlay; } // Find the top Canvas in the scene public static Canvas GetTopCanvas() { // Find all Canvas components in the scene #if UNITY_6000_0_OR_NEWER Canvas[] allCanvases = UnityEngine.Object.FindObjectsByType(FindObjectsSortMode.None); #else Canvas[] allCanvases = UnityEngine.Object.FindObjectsOfType(); #endif Canvas topCanvas = null; int highestSortingOrder = int.MinValue; foreach (Canvas canvas in allCanvases) { // Check if the canvas is enabled and is in World Space or Screen Space modes if (canvas.isActiveAndEnabled && (canvas.renderMode == RenderMode.WorldSpace || canvas.renderMode == RenderMode.ScreenSpaceOverlay || canvas.renderMode == RenderMode.ScreenSpaceCamera)) { // Compare sorting orders to find the highest if (canvas.sortingOrder > highestSortingOrder) { highestSortingOrder = canvas.sortingOrder; topCanvas = canvas; } } } return topCanvas; } public static Vector3 GetBoundsMax(GameObject gameObject, Camera cam, Bounds bounds) { if (!IsRenderedInScreenSpaceOverlayCanvas(gameObject)) { return cam.WorldToScreenPoint(bounds.max); } return bounds.max; } public static Vector3 GetBoundsMin(GameObject gameObject, Camera cam, Bounds bounds) { if (!IsRenderedInScreenSpaceOverlayCanvas(gameObject)) { return cam.WorldToScreenPoint(bounds.min); } return bounds.min; } public static Camera GetCamera() { Camera[] array = new Camera[Camera.allCamerasCount]; Camera.GetAllCameras(array); Camera camera = null; foreach (var camera2 in array) { if (camera == null || camera2.depth >= camera.depth) { camera = camera2; } } return camera; } public static bool CheckRayHits3DCollider(Ray ray, Collider collider) { // Perform a 3D raycast and store the results in an array RaycastHit[] rayHits = Physics.RaycastAll(ray); // Loop through the raycast hits foreach (var raycastHit in rayHits) { // Check if the raycast hit is obstructed by the Collider component if (raycastHit.collider == collider) { return true; } } // Return false if no hit is found on the specific collider return false; } public static bool CheckRayHits2DCollider(Ray ray, Collider2D collider) { // Perform a 2D raycast and store the results in an array RaycastHit2D[] rayIntersectionAll = Physics2D.GetRayIntersectionAll(ray); // Loop through the raycast hits foreach (var raycastHit2D in rayIntersectionAll) { // Check if the raycast hit is obstructed by the Collider2D component if (raycastHit2D.collider == collider) { return true; } } // Return false if no hit is found on the specific collider return false; } public static float ConvertPxToDp(float pixels) { float num = 160f; return pixels / (Screen.dpi / num); } public static Dictionary CastAssetIDMappings(string jsonMappings) { Dictionary objDic = Json.Deserialize(jsonMappings) as Dictionary; Dictionary strDic = new Dictionary(); if (objDic != null) foreach (KeyValuePair current in objDic) { strDic.Add(current.Key, (current.Value != null) ? current.Value.ToString() : string.Empty); } return strDic; } [DebuggerHidden] public static IEnumerator LoadImage(string url, Action callback) { // Send the request using UnityWebRequest uwr = UnityWebRequestTexture.GetTexture(url); // Wait for the request to complete yield return uwr.SendWebRequest(); try { // Check for errors if (uwr.result == UnityWebRequest.Result.ConnectionError || uwr.result == UnityWebRequest.Result.ProtocolError) { Debug.LogError("Error downloading texture: "+ url +"\nerror: " + uwr.error); callback?.Invoke(null); } else { // Get the downloaded texture Texture2D texture = DownloadHandlerTexture.GetContent(uwr); // Callback with texture callback?.Invoke(texture); } } catch (Exception ex) { Debug.LogError("Error loading texture: "+ url); Console.WriteLine(ex.Message); callback?.Invoke(null); } } [DebuggerHidden] public static IEnumerator LoadTextureAsync(string url, Action onSuccess, Action onError) { // Validate the URL before even making the request if (string.IsNullOrWhiteSpace(url)) { onError?.Invoke("URL is null or empty."); yield break; } if (!Uri.IsWellFormedUriString(url, UriKind.Absolute)) { onError?.Invoke($"Invalid URL format: {url}"); yield break; } // Use UnityWebRequestTexture safely inside a using block using (UnityWebRequest uwr = UnityWebRequestTexture.GetTexture(url)) { // Optional: Set a timeout or custom headers if needed uwr.timeout = 10; // Send request and wait for completion yield return uwr.SendWebRequest(); // Handle potential error states (Unity 2022–2025 safe) #if UNITY_2020_2_OR_NEWER if (uwr.result != UnityWebRequest.Result.Success) #else if (uwr.isNetworkError || uwr.isHttpError) #endif { onError?.Invoke($"UnityWebRequest error: {uwr.error} | URL: {url}"); yield break; } // Extract texture safely try { Texture2D texture = DownloadHandlerTexture.GetContent(uwr); onSuccess?.Invoke(texture); } catch (Exception e) { onError?.Invoke($"Texture parsing failed: {e.Message}"); } } } public static void CheckInitialization() { if (!AdsEventExecutor.IsActive()) AdsEventExecutor.Initialize(); } public static Texture2D GetTexture2DFromByteArray(byte[] img) { Texture2D tex = new Texture2D(1, 1); return tex.LoadImage(img) ? tex : throw new InvalidOperationException("Could not load custom native template image asset as texture"); } } }