< Summary

Class:DCL.ABConverter.PathUtils
Assembly:ABConverter
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/ABConverter/Utils.cs
Covered lines:0
Uncovered lines:29
Coverable lines:29
Total lines:412
Line coverage:0% (0 of 29)
Covered branches:0
Total branches:0

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
GetRelativePathTo(...)0%2100%
FullPathToAssetPath(...)0%12300%
FixDirectorySeparator(...)0%2100%
AssetPathToFullPath(...)0%6200%
GetFreeSpace()0%2100%

File(s)

/tmp/workspace/unity-renderer/unity-renderer/Assets/ABConverter/Utils.cs

#LineLine coverage
 1using DCL.Helpers;
 2using GLTF.Schema;
 3using System;
 4using System.Collections.Generic;
 5using System.IO;
 6using System.Linq;
 7using System.Net.Http;
 8using System.Security.Cryptography;
 9using System.Text;
 10using System.Text.RegularExpressions;
 11using UnityEditor;
 12using UnityEngine;
 13using UnityEngine.Assertions;
 14using UnityEngine.Networking;
 15using static DCL.ContentServerUtils;
 16
 17namespace DCL.ABConverter
 18{
 19    public static class MeshUtils
 20    {
 21        public static Bounds BuildMergedBounds(Renderer[] renderers)
 22        {
 23            Bounds bounds = new Bounds();
 24
 25            for (int i = 0; i < renderers.Length; i++)
 26            {
 27                if (renderers[i] == null)
 28                    continue;
 29
 30                if (i == 0)
 31                    bounds = renderers[i].GetSafeBounds();
 32                else
 33                    bounds.Encapsulate(renderers[i].GetSafeBounds());
 34            }
 35
 36            return bounds;
 37        }
 38
 39        /// <summary>
 40        /// This get the renderer bounds with a check to ensure the renderer is at a safe position.
 41        /// If the renderer is too far away from 0,0,0, wasm target ensures a crash.
 42        /// </summary>
 43        /// <param name="renderer"></param>
 44        /// <returns>The bounds value if the value is correct, or a mocked bounds object with clamped values if its too 
 45        public static Bounds GetSafeBounds( this Renderer renderer )
 46        {
 47            // World extents are of 4800 world mts, so this limit far exceeds the world size.
 48            const float POSITION_OVERFLOW_LIMIT = 10000;
 49            const float POSITION_OVERFLOW_LIMIT_SQR = POSITION_OVERFLOW_LIMIT * POSITION_OVERFLOW_LIMIT;
 50
 51            if ( renderer.transform.position.sqrMagnitude > POSITION_OVERFLOW_LIMIT_SQR )
 52                return new Bounds( Vector3.one * POSITION_OVERFLOW_LIMIT, Vector3.one * 0.1f );
 53
 54            return renderer.bounds;
 55        }
 56    }
 57
 58    public static class PathUtils
 59    {
 60        /// <summary>
 61        /// Gets the relative path ("..\..\to_file_or_dir") of another file or directory (to) in relation to the current
 62        /// </summary>
 63        /// <param name="to"></param>
 64        /// <param name="from"></param>
 65        /// <returns></returns>
 66        public static string GetRelativePathTo(string from, string to)
 67        {
 068            var fromPath = Path.GetFullPath(from);
 069            var toPath = Path.GetFullPath(to);
 70
 071            var fromUri = new Uri(fromPath);
 072            var toUri = new Uri(toPath);
 73
 074            var relativeUri = fromUri.MakeRelativeUri(toUri);
 075            var relativePath = Uri.UnescapeDataString(relativeUri.ToString());
 76
 077            string result = FixDirectorySeparator(relativePath);
 78
 079            return result;
 80        }
 81
 82        /// <summary>
 83        /// Converts an absolute path to an Application.dataPath relative path.
 84        /// </summary>
 85        /// <param name="fullPath">the full path.</param>
 86        /// <returns>the Application.dataPath relative path</returns>
 87        public static string FullPathToAssetPath(string fullPath)
 88        {
 089            char ps = Path.DirectorySeparatorChar;
 90
 091            fullPath = fullPath.Replace('/', ps);
 092            fullPath = fullPath.Replace('\\', ps);
 93
 094            string pattern = $".*?\\{ps}(?<assetpath>Assets\\{ps}.*?$)";
 95
 096            var regex = new Regex(pattern);
 97
 098            var match = regex.Match(fullPath);
 99
 0100            if (match.Success && match.Groups["assetpath"] != null)
 0101                return match.Groups["assetpath"].Value;
 102
 0103            return string.Empty;
 104        }
 105
 106        public static string FixDirectorySeparator(string path)
 107        {
 0108            char ps = Path.DirectorySeparatorChar;
 0109            path = path.Replace('/', ps);
 0110            path = path.Replace('\\', ps);
 0111            return path;
 112        }
 113
 114        /// <summary>
 115        /// Convert a path relative to Application.dataPath to an absolute path.
 116        /// </summary>
 117        /// <param name="assetPath">The relative path</param>
 118        /// <param name="overrideDataPath">Convert from an arbitrary path instead of Application.dataPath. Used for test
 119        /// <returns>The full path.</returns>
 120        public static string AssetPathToFullPath(string assetPath, string overrideDataPath = null)
 121        {
 0122            assetPath = FixDirectorySeparator(assetPath);
 123
 0124            string dataPath = overrideDataPath ?? Application.dataPath;
 0125            dataPath = FixDirectorySeparator(dataPath);
 126
 0127            char ps = Path.DirectorySeparatorChar;
 0128            string dataPathWithoutAssets = dataPath.Replace($"{ps}Assets", "");
 0129            return dataPathWithoutAssets + "/" + assetPath;
 130        }
 131
 132        public static long GetFreeSpace()
 133        {
 0134            DriveInfo info = new DriveInfo(new DirectoryInfo(Application.dataPath).Root.FullName);
 0135            return info.AvailableFreeSpace;
 136        }
 137    }
 138
 139    public static class Utils
 140    {
 141        internal static bool ParseOption(string[] fullCmdArgs, string optionName, int argsQty, out string[] foundArgs) {
 142
 143        internal static bool ParseOption(string optionName, int argsQty, out string[] foundArgs) { return ParseOptionExp
 144
 145        internal static bool ParseOptionExplicit(string[] rawArgsList, string optionName, int expectedArgsQty, out strin
 146        {
 147            foundArgs = null;
 148
 149            if (rawArgsList == null || rawArgsList.Length < expectedArgsQty + 1)
 150                return false;
 151
 152            expectedArgsQty = Mathf.Min(expectedArgsQty, 100);
 153
 154            var foundArgsList = new List<string>();
 155            int argState = 0;
 156
 157            for (int i = 0; i < rawArgsList.Length; i++)
 158            {
 159                switch (argState)
 160                {
 161                    case 0:
 162                        if (rawArgsList[i] == "-" + optionName)
 163                        {
 164                            argState++;
 165                        }
 166
 167                        break;
 168                    default:
 169                        foundArgsList.Add(rawArgsList[i]);
 170                        argState++;
 171                        break;
 172                }
 173
 174                if (argState > 0 && foundArgsList.Count == expectedArgsQty)
 175                    break;
 176            }
 177
 178            if (argState == 0 || foundArgsList.Count < expectedArgsQty)
 179                return false;
 180
 181            if (expectedArgsQty > 0)
 182                foundArgs = foundArgsList.ToArray();
 183
 184            return true;
 185        }
 186
 187        internal static void Exit(int errorCode = 0)
 188        {
 189            Debug.Log($"Process finished with code {errorCode}");
 190
 191            if (Application.isBatchMode)
 192                EditorApplication.Exit(errorCode);
 193        }
 194
 195        internal static void MarkFolderForAssetBundleBuild(string fullPath, string abName)
 196        {
 197            string assetPath = PathUtils.GetRelativePathTo(Application.dataPath, fullPath);
 198            assetPath = Path.GetDirectoryName(assetPath);
 199            AssetImporter importer = AssetImporter.GetAtPath(assetPath);
 200            importer.SetAssetBundleNameAndVariant(abName, "");
 201        }
 202
 203        internal static void MarkAssetForAssetBundleBuild(IAssetDatabase assetDb, UnityEngine.Object asset, string abNam
 204        {
 205            string assetPath = PathUtils.GetRelativePathTo(Application.dataPath, assetDb.GetAssetPath(asset));
 206            var importer = AssetImporter.GetAtPath(assetPath);
 207            importer.SetAssetBundleNameAndVariant(abName, "");
 208        }
 209
 210        public static MD5 md5 = new MD5CryptoServiceProvider();
 211
 212        public static string CidToGuid(string cid)
 213        {
 214            byte[] data = md5.ComputeHash(Encoding.UTF8.GetBytes(cid));
 215            StringBuilder sBuilder = new StringBuilder();
 216
 217            for (int i = 0; i < data.Length; i++)
 218            {
 219                sBuilder.Append(data[i].ToString("x2"));
 220            }
 221
 222            return sBuilder.ToString();
 223        }
 224
 225        public static HashSet<string> GetSceneCids(IWebRequest webRequest, ApiTLD tld, Vector2Int coords, Vector2Int siz
 226        {
 227            HashSet<string> sceneCids = new HashSet<string>();
 228
 229            string url = GetScenesAPIUrl(tld, coords.x, coords.y, size.x, size.y);
 230
 231            DownloadHandler downloadHandler = null;
 232
 233            try
 234            {
 235                downloadHandler = webRequest.Get(url);
 236            }
 237            catch (HttpRequestException e)
 238            {
 239                throw new Exception($"Request error! Parcels couldn't be fetched! -- {e.Message}", e);
 240            }
 241
 242            ScenesAPIData scenesApiData = JsonUtility.FromJson<ScenesAPIData>(downloadHandler.text);
 243            downloadHandler.Dispose();
 244
 245            Assert.IsTrue(scenesApiData != null, "Invalid response from ScenesAPI");
 246            Assert.IsTrue(scenesApiData.data != null, "Invalid response from ScenesAPI");
 247
 248            foreach (var data in scenesApiData.data)
 249            {
 250                sceneCids.Add(data.root_cid);
 251            }
 252
 253            return sceneCids;
 254        }
 255
 256        public static HashSet<string> GetScenesCids(IWebRequest webRequest, ApiTLD tld, List<Vector2Int> coords)
 257        {
 258            HashSet<string> sceneCids = new HashSet<string>();
 259
 260            foreach (Vector2Int v in coords)
 261            {
 262                string url = GetScenesAPIUrl(tld, v.x, v.y, 0, 0);
 263
 264                DownloadHandler downloadHandler = null;
 265
 266                try
 267                {
 268                    downloadHandler = webRequest.Get(url);
 269                }
 270                catch (HttpRequestException e)
 271                {
 272                    throw new HttpRequestException($"Request error! Parcels couldn't be fetched! -- {url} -- {e.Message}
 273                }
 274
 275                ScenesAPIData scenesApiData = JsonUtility.FromJson<ScenesAPIData>(downloadHandler.text);
 276                downloadHandler.Dispose();
 277
 278                Assert.IsTrue(scenesApiData != null, "Invalid response from ScenesAPI");
 279                Assert.IsTrue(scenesApiData.data != null, "Invalid response from ScenesAPI");
 280
 281                foreach (var data in scenesApiData.data)
 282                {
 283                    sceneCids.Add(data.root_cid);
 284                }
 285            }
 286
 287            return sceneCids;
 288        }
 289
 290        public static MappingsAPIData GetSceneMappingsData(IWebRequest webRequest, ApiTLD tld, string sceneCid)
 291        {
 292            string url = GetMappingsAPIUrl(tld, sceneCid);
 293
 294            DownloadHandler downloadHandler = null;
 295
 296            try
 297            {
 298                downloadHandler = webRequest.Get(url);
 299            }
 300            catch (HttpRequestException e)
 301            {
 302                throw new Exception($"Request error! mappings couldn't be fetched for scene {sceneCid}! -- {e.Message}")
 303            }
 304
 305            MappingsAPIData parcelInfoApiData = JsonUtility.FromJson<MappingsAPIData>(downloadHandler.text);
 306            downloadHandler.Dispose();
 307
 308            if (parcelInfoApiData.data.Length == 0 || parcelInfoApiData.data == null)
 309            {
 310                throw new Exception("MappingsAPIData is null?");
 311            }
 312
 313            return parcelInfoApiData;
 314        }
 315
 316        /// <summary>
 317        /// Given a MappingPair list, returns a AssetPath list filtered by file extensions
 318        /// </summary>
 319        /// <param name="pairsToSearch">The MappingPair list to be filtered and converted</param>
 320        /// <param name="extensions">An array detailing the extensions to filter them</param>
 321        /// <returns>A dictionary that maps hashes to mapping pairs</returns>
 322        public static List<AssetPath> GetPathsFromPairs(string basePath, MappingPair[] pairsToSearch, string[] extension
 323        {
 324            var tmpResult = new Dictionary<(string, string), AssetPath>();
 325
 326            for (int i = 0; i < pairsToSearch.Length; i++)
 327            {
 328                MappingPair mappingPair = pairsToSearch[i];
 329
 330                bool hasExtension = extensions.Any((x) => mappingPair.file.ToLower().EndsWith(x));
 331
 332                if (hasExtension)
 333                {
 334                    if (!tmpResult.ContainsKey((mappingPair.hash, mappingPair.file)))
 335                        tmpResult.Add((mappingPair.hash, mappingPair.file), new AssetPath(basePath, mappingPair));
 336                }
 337            }
 338
 339            return tmpResult.Values.ToList();
 340        }
 341
 342        public static void FixGltfRootInvalidUriCharacters(GLTFRoot gltfRoot)
 343        {
 344            if (gltfRoot == null)
 345            {
 346                Debug.LogError("FixGltfRootInvalidUriCharacters >>> gltfRoot is null!");
 347                return;
 348            }
 349
 350            GLTFRoot root = gltfRoot;
 351
 352            if (root.Images != null)
 353            {
 354                foreach (GLTFImage image in root.Images)
 355                {
 356                    if (!string.IsNullOrEmpty(image.Uri))
 357                    {
 358                        bool isBase64 = URIHelper.IsBase64Uri(image.Uri);
 359
 360                        if (!isBase64)
 361                        {
 362                            image.Uri = image.Uri.Replace('/', Path.DirectorySeparatorChar);
 363                        }
 364                    }
 365                }
 366            }
 367
 368            if (root.Buffers != null)
 369            {
 370                foreach (GLTFBuffer buffer in root.Buffers)
 371                {
 372                    if (!string.IsNullOrEmpty(buffer.Uri))
 373                    {
 374                        bool isBase64 = URIHelper.IsBase64Uri(buffer.Uri);
 375
 376                        if (!isBase64)
 377                        {
 378                            buffer.Uri = buffer.Uri.Replace('/', Path.DirectorySeparatorChar);
 379                        }
 380                    }
 381                }
 382            }
 383        }
 384
 385        public static void CleanAssetBundleFolder(IFile file, string pathToSearch, string[] assetBundlesList, Dictionary
 386        {
 387            for (int i = 0; i < assetBundlesList.Length; i++)
 388            {
 389                if (string.IsNullOrEmpty(assetBundlesList[i]))
 390                    continue;
 391
 392                try
 393                {
 394                    //NOTE(Brian): This is done for correctness sake, rename files to preserve the hash upper-case
 395                    if (lowerToUpperDictionary.TryGetValue(assetBundlesList[i], out string hashWithUppercase))
 396                    {
 397                        string oldPath = pathToSearch + assetBundlesList[i];
 398                        string path = pathToSearch + hashWithUppercase;
 399                        file.Move(oldPath, path);
 400                    }
 401
 402                    string oldPathMf = pathToSearch + assetBundlesList[i] + ".manifest";
 403                    file.Delete(oldPathMf);
 404                }
 405                catch (Exception e)
 406                {
 407                    Debug.LogWarning("Error! " + e.Message);
 408                }
 409            }
 410        }
 411    }
 412}