mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/PCK-Studio.git
synced 2026-05-22 05:25:15 +00:00
147 lines
5.4 KiB
C#
147 lines
5.4 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.IO.Compression;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Net;
|
|
using System.Reflection;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using Octokit;
|
|
|
|
namespace PCKStudio_Updater
|
|
{
|
|
public sealed class GithubUpdateDownloader : IUpdateDownloader
|
|
{
|
|
private static readonly Assembly updaterAssembly = Assembly.GetAssembly(typeof(GithubUpdateDownloader));
|
|
|
|
private readonly GithubParams _updateParams;
|
|
private readonly GitHubClient githubClient;
|
|
private Release latestFetchedRelease;
|
|
private Version latestReleaseVersion;
|
|
private DirectoryInfo downloadDirectory;
|
|
|
|
|
|
public GithubUpdateDownloader(GithubParams updateParams)
|
|
{
|
|
_updateParams = updateParams;
|
|
var githubClientProductHeader = new ProductHeaderValue(updaterAssembly.GetName().Name);
|
|
githubClient = new GitHubClient(githubClientProductHeader);
|
|
}
|
|
|
|
public bool IsUpdateAvailable(FileVersionInfo fileVersionInfo)
|
|
{
|
|
return IsUpdateAvailable(fileVersionInfo.ProductVersion);
|
|
}
|
|
|
|
public bool IsUpdateAvailable(Assembly currentAssembly)
|
|
{
|
|
if (!File.Exists(currentAssembly.Location))
|
|
return false;
|
|
FileVersionInfo fileVersionInfo = FileVersionInfo.GetVersionInfo(currentAssembly.Location);
|
|
return IsUpdateAvailable(fileVersionInfo.ProductVersion);
|
|
}
|
|
|
|
public bool IsUpdateAvailable(Version productVersion)
|
|
{
|
|
Debug.WriteLine("Release Product ver.: " + latestReleaseVersion);
|
|
Debug.WriteLine("Current Product ver.: " + productVersion);
|
|
return latestReleaseVersion.CompareTo(productVersion) >= 0;
|
|
}
|
|
|
|
public bool IsUpdateAvailable(string productVersion)
|
|
{
|
|
GetLatestRelease(_updateParams.UsePreRelease);
|
|
if (Version.TryParse(productVersion, out var currentVersion))
|
|
{
|
|
return IsUpdateAvailable(currentVersion);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
private void UnpackZip(string zipFilePath)
|
|
{
|
|
ZipFile.ExtractToDirectory(zipFilePath, Path.GetDirectoryName(zipFilePath));
|
|
}
|
|
|
|
private static void DownloadAsset(ReleaseAsset asset, Stream destination)
|
|
{
|
|
string downloadUrl = asset.BrowserDownloadUrl;
|
|
var client = new WebClient();
|
|
using (var serverStream = client.OpenRead(downloadUrl))
|
|
{
|
|
serverStream.CopyTo(destination);
|
|
}
|
|
}
|
|
|
|
private void GetLatestRelease(bool prerelease)
|
|
{
|
|
Release release;
|
|
if (prerelease)
|
|
{
|
|
var prereleaseTask = githubClient.Repository.Release.GetAll(_updateParams.RepositoryOwnerName, _updateParams.RepositoryName);
|
|
prereleaseTask.Wait();
|
|
var prereleases = prereleaseTask.Result.OrderByDescending(release => release.PublishedAt ?? release.CreatedAt).Where(release => release.Prerelease).ToArray();
|
|
release = latestFetchedRelease = prereleases[0];
|
|
}
|
|
else
|
|
{
|
|
var latestReleaseTask = githubClient.Repository.Release.GetLatest(_updateParams.RepositoryOwnerName, _updateParams.RepositoryName);
|
|
latestReleaseTask.Wait();
|
|
release = latestFetchedRelease = latestReleaseTask.Result;
|
|
}
|
|
var match = _updateParams.VersionMatcher.Match(release.Name);
|
|
if (match.Success)
|
|
{
|
|
string versionString = match.Value;
|
|
Version.TryParse(versionString, out latestReleaseVersion);
|
|
}
|
|
}
|
|
|
|
private void EmptyDirectory(DirectoryInfo directory)
|
|
{
|
|
foreach (FileInfo file in directory.GetFiles())
|
|
{
|
|
if (Path.GetFileNameWithoutExtension(file.Name) != _updateParams.TargetExecutableName && file.Name != "update.zip")
|
|
file.Delete();
|
|
}
|
|
foreach (DirectoryInfo subDirectory in directory.GetDirectories())
|
|
subDirectory.Delete(true);
|
|
}
|
|
|
|
public void DownloadTo(DirectoryInfo directory)
|
|
{
|
|
if (latestFetchedRelease is null)
|
|
GetLatestRelease(_updateParams.UsePreRelease);
|
|
if (latestFetchedRelease.Assets?.Count > 0)
|
|
{
|
|
var asset = latestFetchedRelease.Assets[0];
|
|
string zipFilePath = Path.Combine(directory.FullName, asset.Name);
|
|
using(var zipFileStream = File.OpenWrite(zipFilePath))
|
|
{
|
|
DownloadAsset(asset, zipFileStream);
|
|
}
|
|
Debug.WriteLine("Download Complete", category: nameof(GithubUpdateDownloader));
|
|
EmptyDirectory(directory);
|
|
UnpackZip(zipFilePath);
|
|
downloadDirectory = directory;
|
|
}
|
|
}
|
|
|
|
public void Launch()
|
|
{
|
|
if (downloadDirectory is null)
|
|
{
|
|
throw new ArgumentNullException("Download directory not set.");
|
|
}
|
|
|
|
var files = downloadDirectory.GetFiles(_updateParams.TargetExecutableName + ".exe", SearchOption.TopDirectoryOnly);
|
|
if (files is not null && files.Length > 0)
|
|
{
|
|
Process.Start(files[0].FullName);
|
|
}
|
|
}
|
|
}
|
|
}
|