示例#1
0
        /// <summary>
        /// Delete downloaded data, checking to only delte expected files.
        /// </summary>
        /// <param name="downloadPath">Where downloads were stored.</param>
        /// <param name="metadata">The Unity version downloaded</param>
        /// <param name="packageIds">Downloaded packages.</param>
        public void CleanUpDownloads(VersionMetadata metadata, string downloadPath, IEnumerable <PackageMetadata> packages)
        {
            if (!Directory.Exists(downloadPath))
            {
                return;
            }

            foreach (var directory in Directory.GetDirectories(downloadPath))
            {
                throw new Exception("Unexpected directory in downloads folder: " + directory);
            }

            var packageFileNames = packages
                                   .Select(p => p.GetFileName())
                                   .ToList();

            foreach (var path in Directory.GetFiles(downloadPath))
            {
                var fileName = Path.GetFileName(path);
                if (fileName == ".DS_Store" || fileName == "thumbs.db" || fileName == "desktop.ini")
                {
                    continue;
                }

                if (!packageFileNames.Contains(fileName))
                {
                    throw new Exception("Unexpected file in downloads folder: " + path);
                }
            }

            Directory.Delete(downloadPath, true);
        }
示例#2
0
        /// <summary>
        /// Get the default package IDs for the given version.
        /// </summary>
        /// <param name="metadata">Unity version</param>
        /// <param name="cachePlatform">Name of platform</param>
        public IEnumerable <string> GetDefaultPackages(VersionMetadata metadata, CachePlatform cachePlatform)
        {
            var platform = metadata.GetPlatform(cachePlatform);

            if (platform.packages == null)
            {
                throw new ArgumentException("Unity version contains no packages.");
            }
            return(platform.packages.Where(p => p.install).Select(p => p.name));
        }
示例#3
0
        /// <summary>
        /// Extract the versions and the base URLs from the html string.
        /// </summary>
        Dictionary <UnityVersion, VersionMetadata> ExtractFromHtml(string html, Dictionary <UnityVersion, VersionMetadata> results = null)
        {
            var matches = UNIT_DOWNLOADS_RE.Matches(html);

            results = results ?? new Dictionary <UnityVersion, VersionMetadata>();
            foreach (Match match in matches)
            {
                var version = new UnityVersion(match.Groups[4].Value);
                version.hash = match.Groups[2].Value;

                var iniUrl        = match.Groups[1].Value;
                var componentName = match.Groups[3].Value;

                CachePlatform cachePlatform;
                if (componentName.Contains("Mac"))
                {
                    cachePlatform = CachePlatform.macOS;
                }
                else if (componentName.Contains("Windows"))
                {
                    cachePlatform = CachePlatform.Windows;
                }
                else if (componentName.Contains("Linux"))
                {
                    cachePlatform = CachePlatform.Linux;
                }
                else
                {
                    Logger.LogDebug("Platform name not found in component name: " + componentName);
                    continue;
                }

                VersionMetadata metadata = default;
                if (!results.TryGetValue(version, out metadata))
                {
                    metadata.version = version;
                }

                var platform = metadata.GetPlatform(cachePlatform);
                platform.iniUrl = iniUrl;

                metadata.SetPlatform(cachePlatform, platform);
                results[version] = metadata;
            }
            return(results);
        }
示例#4
0
        void ParseVersions(CachePlatform cachePlatform, HubUnityVersion[] versions, List <VersionMetadata> results)
        {
            foreach (var version in versions)
            {
                var metadata = new VersionMetadata();
                metadata.version = new UnityVersion(version.version);

                var platform = new VersionPlatformMetadata();
                platform.packages    = new PackageMetadata[version.modules.Length + 1];
                platform.packages[0] = new PackageMetadata()
                {
                    name          = "Unity ",
                    title         = "Unity " + version.version,
                    description   = "Unity Editor",
                    url           = version.downloadUrl,
                    install       = true,
                    mandatory     = false,
                    size          = long.Parse(version.downloadSize),
                    installedsize = long.Parse(version.installedSize),
                    version       = version.version,
                    md5           = version.checksum
                };

                var i = 1;
                foreach (var module in version.modules)
                {
                    platform.packages[i++] = new PackageMetadata()
                    {
                        name          = module.id,
                        title         = module.name,
                        description   = module.description,
                        url           = module.downloadUrl,
                        install       = module.selected,
                        mandatory     = false,
                        size          = long.Parse(module.downloadSize),
                        installedsize = long.Parse(module.installedSize),
                        version       = version.version,
                        md5           = module.checksum
                    };
                }

                Logger.LogDebug($"Found version {metadata.version} with {platform.packages.Length} packages");
                metadata.SetPlatform(cachePlatform, platform);
                results.Add(metadata);
            }
        }
示例#5
0
        /// <summary>
        /// Create a download and install queue from the given version and packages.
        /// </summary>
        /// <param name="metadata">The Unity version</param>
        /// <param name="cachePlatform">Name of platform</param>
        /// <param name="downloadPath">Location of the downloaded the packages</param>
        /// <param name="packageIds">Packages to download and/or install</param>
        /// <returns>The queue list with the created queue items</returns>
        public Queue CreateQueue(VersionMetadata metadata, CachePlatform cachePlatform, string downloadPath, IEnumerable <PackageMetadata> packages)
        {
            if (!metadata.version.IsFullVersion)
            {
                throw new ArgumentException("VersionMetadata.version needs to contain a full Unity version", nameof(metadata));
            }

            var platform = metadata.GetPlatform(cachePlatform);

            if (platform.packages == null || platform.packages.Length == 0)
            {
                throw new ArgumentException("VersionMetadata.packages cannot be null or empty", nameof(metadata));
            }

            var items = new List <QueueItem>();

            foreach (var package in packages)
            {
                var fullUrl = package.url;
                if (platform.iniUrl != null && !fullUrl.StartsWith("http"))
                {
                    fullUrl = platform.iniUrl + package.url;
                }

                var fileName = package.GetFileName();
                Logger.LogDebug($"{package.name}: Using file name '{fileName}' for url '{fullUrl}'");
                var outputPath = Path.Combine(downloadPath, fileName);

                items.Add(new QueueItem()
                {
                    package     = package,
                    downloadUrl = new Uri(fullUrl),
                    filePath    = outputPath,
                    retries     = Configuration.retryCount
                });
            }

            return(new Queue()
            {
                metadata = metadata,
                items = items
            });
        }
示例#6
0
        /// <summary>
        /// Convert a UnityHub URL to a VersionMetadata struct.
        /// </summary>
        /// <remarks>
        /// Conversion is completely offline, no http lookup is made.
        /// </remarks>
        public VersionMetadata UnityHubUrlToVersion(string url)
        {
            var match = UNITYHUB_RE.Match(url);

            if (!match.Success)
            {
                return(default(VersionMetadata));
            }

            var version = new UnityVersion(match.Groups[1].Value);

            version.hash = match.Groups[2].Value;

            var metadata = new VersionMetadata();

            metadata.version = version;
            metadata.baseUrl = GetIniBaseUrl(version.type) + version.hash + "/";

            return(metadata);
        }
示例#7
0
        /// <summary>
        /// Extract the versions and the base URLs from the html string.
        /// </summary>
        Dictionary <UnityVersion, VersionMetadata> ExtractFromHtml(string html, bool prerelease = false, Dictionary <UnityVersion, VersionMetadata> results = null)
        {
            var matches = UNITYHUB_RE.Matches(html);

            results = results ?? new Dictionary <UnityVersion, VersionMetadata>();
            foreach (Match match in matches)
            {
                var version = new UnityVersion(match.Groups[1].Value);
                version.hash = match.Groups[2].Value;

                VersionMetadata metadata = default;
                if (!results.TryGetValue(version, out metadata))
                {
                    metadata.version = version;
                }

                metadata.baseUrl    = GetIniBaseUrl(version.type) + version.hash + "/";
                metadata.prerelease = prerelease;
                results[version]    = metadata;
            }

            matches = UNITY_DOWNLOAD_RE.Matches(html);
            foreach (Match match in matches)
            {
                var version = new UnityVersion(match.Groups[2].Value);
                version.hash = match.Groups[1].Value;

                VersionMetadata metadata = default;
                if (!results.TryGetValue(version, out metadata))
                {
                    metadata.version = version;
                }

                metadata.baseUrl    = GetIniBaseUrl(version.type) + version.hash + "/";
                metadata.prerelease = prerelease;
                results[version]    = metadata;
            }

            return(results);
        }
示例#8
0
        /// <summary>
        /// Resolve package patterns to package metadata.
        /// This method also adds package dependencies.
        /// </summary>
        public IEnumerable <PackageMetadata> ResolvePackages(
            VersionMetadata metadata,
            CachePlatform cachePlatform,
            IEnumerable <string> packages,
            IList <string> notFound = null,
            bool addDependencies    = true
            )
        {
            var platform = metadata.GetPlatform(cachePlatform);
            var metas    = new List <PackageMetadata>();

            foreach (var id in packages)
            {
                PackageMetadata resolved = default;
                if (id.StartsWith('~'))
                {
                    // Contains lookup
                    var str = id.Substring(1);
                    foreach (var package in platform.packages)
                    {
                        if (package.name.Contains(str, StringComparison.OrdinalIgnoreCase))
                        {
                            if (resolved.name == null)
                            {
                                Logger.LogDebug($"Fuzzy lookup '{id}' matched package '{resolved.name}'");
                                resolved = package;
                            }
                            else
                            {
                                throw new Exception($"Fuzzy package match '{id}' is ambiguous between '{package.name}' and '{resolved.name}'");
                            }
                        }
                    }
                }
                else
                {
                    // Exact lookup
                    resolved = platform.GetPackage(id);
                }

                if (resolved.name != null)
                {
                    if (addDependencies)
                    {
                        foreach (var package in platform.packages)
                        {
                            if (package.sync == resolved.name && !metas.Any(p => p.name == package.name))
                            {
                                Logger.LogInformation($"Adding '{package.name}' which '{resolved.name}' is synced with");
                                metas.Add(package);
                            }
                        }
                    }

                    metas.Add(resolved);
                }
                else if (notFound != null)
                {
                    notFound.Add(id);
                }
            }
            return(metas);
        }
示例#9
0
        /// <summary>
        /// Get the path to the download directory (determined by DataPath or platform).
        /// </summary>
        public string GetDownloadDirectory(VersionMetadata metadata)
        {
            var downloadPath = DataPath ?? Platform.GetDownloadDirectory();

            return(Path.Combine(downloadPath, string.Format(Configuration.downloadSubdirectory, metadata.version)));
        }
示例#10
0
        /// <summary>
        /// Resolve package patterns to package metadata.
        /// This method also adds package dependencies.
        /// </summary>
        public IEnumerable <PackageMetadata> ResolvePackages(
            VersionMetadata metadata,
            CachePlatform cachePlatform,
            IEnumerable <string> packages,
            IList <string> notFound = null
            )
        {
            var packageMetadata = metadata.GetPackages(cachePlatform);
            var metas           = new List <PackageMetadata>();

            foreach (var pattern in packages)
            {
                var  id = pattern;
                bool fuzzy = false, addDependencies = true;
                while (id.StartsWith("~") || id.StartsWith("="))
                {
                    if (id.StartsWith("~"))
                    {
                        fuzzy = true;
                        id    = id.Substring(1);
                    }
                    else if (id.StartsWith("="))
                    {
                        addDependencies = false;
                        id = id.Substring(1);
                    }
                }

                PackageMetadata resolved = default;
                if (fuzzy)
                {
                    // Contains lookup
                    foreach (var package in packageMetadata)
                    {
                        if (package.name.IndexOf(id, StringComparison.OrdinalIgnoreCase) >= 0)
                        {
                            if (resolved.name == null)
                            {
                                Logger.LogDebug($"Fuzzy lookup '{pattern}' matched package '{resolved.name}'");
                                resolved = package;
                            }
                            else
                            {
                                throw new Exception($"Fuzzy package match '{pattern}' is ambiguous between '{package.name}' and '{resolved.name}'");
                            }
                        }
                    }
                }
                else
                {
                    // Exact lookup
                    resolved = metadata.GetPackage(cachePlatform, id);
                }

                if (resolved.name != null)
                {
                    AddPackageWithDependencies(packageMetadata, metas, resolved, addDependencies);
                }
                else if (notFound != null)
                {
                    notFound.Add(id);
                }
            }
            return(metas);
        }
示例#11
0
        static IEnumerable <PackageMetadata> Generator(VersionMetadata version, CachePlatform platform)
        {
            var v = version.version;

            // Documentation
            if (v.major >= 2018 && version.GetRawPackage(platform, "Documentation").name == null)
            {
                yield return(new PackageMetadata()
                {
                    name = "Documentation",
                    description = "Offline Documentation",
                    url = $"https://storage.googleapis.com/docscloudstorage/{v.major}.{v.minor}/UnityDocumentation.zip",
                    install = true,
                    destination = "{UNITY_PATH}",
                    size = 350 * 1024 * 1024,          // Conservative estimate based on 2019.2
                    installedsize = 650 * 1024 * 1024, // "
                });
            }

            // Language packs
            if (v.major >= 2018)
            {
                string[] localizations;
                if (v.major == 2018 && v.minor == 1)
                {
                    localizations = Localizations_2018_1;
                }
                else if (v.major == 2018)
                {
                    localizations = Localizations_2018_2;
                }
                else
                {
                    localizations = Localizations_2019_1;
                }

                foreach (var loc in localizations)
                {
                    yield return(new PackageMetadata()
                    {
                        name = LanguageNames[loc],
                        description = $"{LanguageNames[loc]} Language Pack",
                        url = $"https://new-translate.unity3d.jp/v1/live/54/{v.major}.{v.minor}/{loc}",
                        fileName = $"{loc}.po",
                        destination = "{UNITY_PATH}/Unity.app/Contents/Localization",
                        size = 2 * 1024 * 1024,          // Conservative estimate based on 2019.2
                        installedsize = 2 * 1024 * 1024, // "
                    });
                }
            }

            // Android dependencies
            if (v.major >= 2019 && version.GetRawPackage(platform, "Android").name != null)
            {
                // Android SDK & NDK & stuff
                yield return(new PackageMetadata()
                {
                    name = "Android SDK & NDK Tools",
                    description = "Android SDK & NDK Tools 26.1.1",
                    url = $"https://dl.google.com/android/repository/sdk-tools-darwin-4333796.zip",
                    destination = "{UNITY_PATH}/PlaybackEngines/AndroidPlayer/SDK",
                    size = 148 * 1024 * 1024,
                    installedsize = 174 * 1024 * 1024,
                    sync = "Android",
                    eulaurl1 = "https://dl.google.com/dl/android/repository/repository2-1.xml",
                    eulalabel1 = "Android SDK and NDK License Terms from Google",
                    eulamessage = "Please review and accept the license terms before downloading and installing Android\'s SDK and NDK.",
                });

                yield return(new PackageMetadata()
                {
                    name = "Android SDK Platform Tools",
                    description = "Android SDK Platform Tools 28.0.1",
                    url = $"https://dl.google.com/android/repository/platform-tools_r28.0.1-darwin.zip",
                    destination = "{UNITY_PATH}/PlaybackEngines/AndroidPlayer/SDK",
                    size = 5 * 1024 * 1024,
                    installedsize = 16 * 1024 * 1024,
                    hidden = true,
                    sync = "Android SDK & NDK Tools",
                });

                yield return(new PackageMetadata()
                {
                    name = "Android SDK Build Tools",
                    description = "Android SDK Build Tools 28.0.3",
                    url = $"https://dl.google.com/android/repository/build-tools_r28.0.3-macosx.zip",
                    destination = "{UNITY_PATH}/PlaybackEngines/AndroidPlayer/SDK/build-tools",
                    size = 53 * 1024 * 1024,
                    installedsize = 120 * 1024 * 1024,
                    hidden = true,
                    sync = "Android SDK & NDK Tools",
                    renameFrom = "{UNITY_PATH}/PlaybackEngines/AndroidPlayer/SDK/build-tools/android-9",
                    renameTo = "{UNITY_PATH}/PlaybackEngines/AndroidPlayer/SDK/build-tools/28.0.3"
                });

                yield return(new PackageMetadata()
                {
                    name = "Android SDK Platforms",
                    description = "Android SDK Platforms 28 r06",
                    url = $"https://dl.google.com/android/repository/platform-28_r06.zip",
                    destination = "{UNITY_PATH}/PlaybackEngines/AndroidPlayer/SDK/platforms",
                    size = 61 * 1024 * 1024,
                    installedsize = 121 * 1024 * 1024,
                    hidden = true,
                    sync = "Android SDK & NDK Tools",
                    renameFrom = "{UNITY_PATH}/PlaybackEngines/AndroidPlayer/SDK/platforms/android-9",
                    renameTo = "{UNITY_PATH}/PlaybackEngines/AndroidPlayer/SDK/platforms/android-28"
                });

                if (v.major == 2019 && v.minor <= 2)
                {
                    yield return(new PackageMetadata()
                    {
                        name = "Android NDK 16b",
                        description = "Android NDK r16b",
                        url = $"https://dl.google.com/android/repository/android-ndk-r16b-darwin-x86_64.zip",
                        destination = "{UNITY_PATH}/PlaybackEngines/AndroidPlayer",
                        size = 770 * 1024 * 1024,
                        installedsize = 2700L * 1024 * 1024,
                        hidden = true,
                        sync = "Android SDK & NDK Tools",
                        renameFrom = "{UNITY_PATH}/PlaybackEngines/AndroidPlayer/android-ndk-r16b",
                        renameTo = "{UNITY_PATH}/PlaybackEngines/AndroidPlayer/NDK"
                    });
                }
                else
                {
                    yield return(new PackageMetadata()
                    {
                        name = "Android NDK 19",
                        description = "Android NDK r19",
                        url = $"https://dl.google.com/android/repository/android-ndk-r19-darwin-x86_64.zip",
                        destination = "{UNITY_PATH}/PlaybackEngines/AndroidPlayer",
                        size = 770 * 1024 * 1024,
                        installedsize = 2700L * 1024 * 1024,
                        hidden = true,
                        sync = "Android SDK & NDK Tools",
                        renameFrom = "{UNITY_PATH}/PlaybackEngines/AndroidPlayer/android-ndk-r19",
                        renameTo = "{UNITY_PATH}/PlaybackEngines/AndroidPlayer/NDK"
                    });
                }

                // Android JDK
                if (v.major > 2019 || v.minor >= 2)
                {
                    yield return(new PackageMetadata()
                    {
                        name = "OpenJDK",
                        description = "Android Open JDK 8u172-b11",
                        url = $"http://download.unity3d.com/download_unity/open-jdk/open-jdk-mac-x64/jdk8u172-b11_4be8440cc514099cfe1b50cbc74128f6955cd90fd5afe15ea7be60f832de67b4.zip",
                        destination = "{UNITY_PATH}/PlaybackEngines/AndroidPlayer/OpenJDK",
                        size = 73 * 1024 * 1024,
                        installedsize = 165 * 1024 * 1024,
                        sync = "Android",
                    });
                }
            }
        }
示例#12
0
 static IEnumerable <PackageMetadata> GeneratePackages(VersionMetadata version, CachePlatform platform)
 {
     return(Generator(version, platform).ToList());
 }