mirror of
https://github.com/BepInEx/BepInEx.git
synced 2026-10-19 15:51:45 +00:00
78 lines
3.1 KiB
C#
78 lines
3.1 KiB
C#
using System;
|
|
using System.IO;
|
|
using System.IO.Compression;
|
|
using System.Linq;
|
|
using System.Net.Http;
|
|
using System.Threading.Tasks;
|
|
using Nuke.Common.IO;
|
|
using ShellProgressBar;
|
|
|
|
static class DownloadTasks
|
|
{
|
|
public static void DownloadFiles(string name, params (string Name, string Url, AbsolutePath Destination)[] files)
|
|
{
|
|
using var progress = new ProgressBar(files.Length, $"Downloading {name}");
|
|
Task.WaitAll(files.Select(t => DownloadFile(progress, t.Name, t.Url, t.Destination)).ToArray());
|
|
}
|
|
|
|
public static void DownloadZipFiles(string name, params (string Name, string Url, AbsolutePath Destination)[] files)
|
|
{
|
|
using var progress = new ProgressBar(files.Length, $"Downloading {name}");
|
|
Task.WaitAll(files.Select(async t =>
|
|
{
|
|
var zipFilePath = (AbsolutePath) $"{t.Destination}_tmp.zip";
|
|
await DownloadFile(progress, t.Name, t.Url, zipFilePath);
|
|
await UnzipFile(progress, t.Name, zipFilePath, t.Destination);
|
|
File.Delete(zipFilePath!);
|
|
}).ToArray());
|
|
}
|
|
|
|
static async Task DownloadFile(ProgressBarBase bar, string name, string url, AbsolutePath destination)
|
|
{
|
|
using var client = new HttpClient();
|
|
await using var fs = File.Create(destination);
|
|
var response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead);
|
|
if (!response.IsSuccessStatusCode)
|
|
throw new Exception($"Failed to download {name}");
|
|
await using var stream = await response.Content.ReadAsStreamAsync();
|
|
using var childBar = bar.Spawn((int) (response.Content.Headers.ContentLength ?? 1), $"Downloading {name}");
|
|
|
|
var buffer = new byte[4096];
|
|
int read;
|
|
while ((read = await stream.ReadAsync(buffer)) > 0)
|
|
{
|
|
await fs.WriteAsync(buffer.AsMemory(0, read));
|
|
childBar.Tick(childBar.CurrentTick + read);
|
|
}
|
|
}
|
|
|
|
static async Task UnzipFile(ProgressBarBase bar, string name, AbsolutePath zipFile, AbsolutePath destination)
|
|
{
|
|
using var zip = ZipFile.OpenRead(zipFile);
|
|
using var childBar = bar.Spawn((int) zip.Entries.Select(e => e.Length).Sum(), $"Extracting {name}");
|
|
|
|
foreach (var entry in zip.Entries)
|
|
{
|
|
// Use Path.Combine to ensure the trailing slash is preserved.
|
|
var fullPath = Path.Combine(destination, entry.FullName);
|
|
var fileName = Path.GetFileName(fullPath);
|
|
if (string.IsNullOrEmpty(fileName))
|
|
{
|
|
Directory.CreateDirectory(fullPath);
|
|
continue;
|
|
}
|
|
|
|
Directory.CreateDirectory(Path.GetDirectoryName(fullPath) ?? throw new InvalidOperationException());
|
|
await using var fs = File.Create(fullPath);
|
|
await using var stream = entry.Open();
|
|
var buffer = new byte[4096];
|
|
int read;
|
|
while ((read = await stream.ReadAsync(buffer)) > 0)
|
|
{
|
|
await fs.WriteAsync(buffer.AsMemory(0, read));
|
|
childBar.Tick(childBar.CurrentTick + read);
|
|
}
|
|
}
|
|
}
|
|
}
|