public BlobCache(IStorageSystem storage) { Storage = storage; BasePath = "blobs"; if (!Storage.TryGetDirectory(BasePath, out _)) { Storage.TryCreateDirectory(BasePath); } }
public async Task <string> EnsureTargetReleaseAsync(string targetRelease, IProgressReceiver progressReceiver) { var targetVersion = targetRelease; //manifest.Latest.Release; // string assetDirectory = Path.Combine("assets", "java"); string assetsZipSavePath = Path.Combine("assets", $"java-{targetVersion}.zip"); if (TryGetStoredVersion(out string currentVersion)) { if (currentVersion == targetVersion) { if (_storage.Exists(assetsZipSavePath)) { Log.Debug("MCJava Assets Up to date!"); return(assetsZipSavePath); } } } /*if (CheckLocal(targetRelease, out var jarPath)) * { * _storage.TryWriteString(CurrentVersionStorageKey, targetRelease); * return jarPath; * // using(FileStream) * } * else*/ { progressReceiver?.UpdateProgress(0, "Downloading assets..."); var manifest = await GetManifestAsync(); // not latest, update Log.Info($"Downloading MCJava {targetVersion} Assets."); var version = manifest.Versions.FirstOrDefault( v => string.Equals(v.Id, targetVersion, StringComparison.InvariantCultureIgnoreCase)); if (version == null) { Log.Error("Version not found in versions? wut?"); return(assetsZipSavePath); } LauncherMeta launcherMeta; AssetIndex assetIndex; var dirpath = Path.Combine("assets", $"java-{targetVersion}_cache"); if (!_storage.TryGetDirectory(dirpath, out var dir)) { if (_storage.TryCreateDirectory(dirpath)) { if (!_storage.TryGetDirectory(dirpath, out dir)) { return(assetsZipSavePath); } } } // fetch version's json thing using (var httpClient = new HttpClient()) { var launcherMetaJson = await httpClient.GetStringAsync(version.Url); launcherMeta = LauncherMeta.FromJson(launcherMetaJson); // download client, prob usefil? //var clientJar = await httpClient.GetByteArrayAsync(launcherMeta.Downloads.Client.Url); // using (var clientMs = new MemoryStream(clientJar)) using (var clientMs = await httpClient.GetStreamAsync(launcherMeta.Downloads.Client.Url)) { using (ZipArchive clientJarZip = new ZipArchive(clientMs, ZipArchiveMode.Read)) { foreach (var entry in clientJarZip.Entries) { if (!entry.FullName.StartsWith("assets") && entry.FullName != "pack.mcmeta") { continue; } var localpath = Path.Combine(dir.FullName, entry.FullName); if (!_storage.TryGetDirectory(Path.GetDirectoryName(localpath), out _)) { _storage.TryCreateDirectory(Path.GetDirectoryName(localpath)); // Directory.CreateDirectory(Path.GetDirectoryName(localpath)); } entry.ExtractToFile(localpath, true); Log.Debug($"Extracted Asset '{entry.Name}' (Size: {entry.Length})"); } } } // now we only care about asset index soooo... grab that var assetIndexJson = await httpClient.GetStringAsync(launcherMeta.AssetIndex.Url); _storage.TryWriteString("assetIndex", assetIndexJson, Encoding.UTF8); assetIndex = AssetIndex.FromJson(assetIndexJson); int target = assetIndex.Objects.Count; int done = 0; foreach (var assetIndexObject in assetIndex.Objects) { // Skip ogg files if (assetIndexObject.Key.EndsWith(".ogg", StringComparison.InvariantCultureIgnoreCase)) { continue; } var assetUrl = AssetResourceUri .Replace("{hash_sub2}", assetIndexObject.Value.Hash.Substring(0, 2)).Replace( "{hash}", assetIndexObject.Value.Hash); progressReceiver?.UpdateProgress(done, target, "Downloading assets...", assetIndexObject.Key); try { var fileBytes = await httpClient.GetByteArrayAsync(assetUrl); var filename = Path.Combine("assets", assetIndexObject.Key); var localpath = Path.Combine(dir.FullName, filename); if (!_storage.TryGetDirectory(Path.GetDirectoryName(localpath), out _)) { _storage.TryCreateDirectory(Path.GetDirectoryName(localpath)); // Directory.CreateDirectory(Path.GetDirectoryName(localpath)); } // File.WriteAllBytes(localpath, fileBytes); _storage.TryWriteBytes(localpath, fileBytes); Log.Debug( $"Downloaded asset '{assetIndexObject.Key}' (Hash: {assetIndexObject.Value.Hash})"); } catch (Exception ex) { Log.Error( ex, $"Failed to download asset '{assetIndexObject.Key}' (Hash: {assetIndexObject.Value.Hash})"); continue; } done++; } } // make new zip m8 using (var ms = new MemoryStream()) { using (var zip = new ZipArchive(ms, ZipArchiveMode.Create, true)) { foreach (var file in dir.EnumerateFiles("*", SearchOption.AllDirectories)) { zip.CreateEntryFromFile(file.FullName, Path.GetRelativePath(dir.FullName, file.FullName)); } } // saving zip m8 ms.Seek(0, SeekOrigin.Begin); var allBytes = ms.ToArray(); _storage.TryWriteBytes(assetsZipSavePath, allBytes); Log.Info($"Written Archive to '{assetsZipSavePath}' (Size: {allBytes.Length})"); } Thread.Sleep(500); dir.Delete(true); } _storage.TryWriteString(CurrentVersionStorageKey, targetVersion); return(assetsZipSavePath); }