Skip to content

Commit

Permalink
GitHub Downloading
Browse files Browse the repository at this point in the history
  • Loading branch information
200Tigersbloxed committed May 22, 2024
1 parent b7e2ba3 commit 3edd129
Show file tree
Hide file tree
Showing 3 changed files with 195 additions and 35 deletions.
130 changes: 130 additions & 0 deletions Hypernex.Launcher/Installer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net;
using System.Runtime.InteropServices;
using Avalonia.Threading;
using HypernexSharp;
Expand All @@ -12,6 +13,7 @@ namespace Hypernex.Launcher;
public static class Installer
{
private const string INSTALLING_NAME = "Hypernex.Unity";
public const string GIT_URL = "https://github.com/TigersUniverse/" + INSTALLING_NAME + "/releases/latest";

private static (string, bool, string[]?)[] UnityDirectories =
{
Expand Down Expand Up @@ -45,6 +47,20 @@ private static int ArtifactId
throw new Exception("Unknown Artifact Platform");
}
}

private static string GitHubDownload
{
get
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
return
"https://github.com/TigersUniverse/Hypernex.Unity/releases/latest/download/Hypernex_win-x64.zip";
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
return
"https://github.com/TigersUniverse/Hypernex.Unity/releases/latest/download/Hypernex_linux-x64.zip";
throw new Exception("Unknown Artifact Platform");
}
}

private static void ContinueInstall(Action<bool, string> callback, Action<string, int> progress,
LauncherCache launcherCache, HypernexObject hypernexObject, string latest, string userid = "", string tokenContent = "")
Expand Down Expand Up @@ -72,6 +88,19 @@ private static void ContinueInstall(Action<bool, string> callback, Action<string
callback.Invoke(true, FindExecutable(launcherCache.InstallDirectory));
}, INSTALLING_NAME, latest, ArtifactId, new User{Id=userid}, new Token{content = tokenContent});
}

private static void ContinueInstall(Action<bool, string> callback, Action<string, int> progress,
LauncherCache launcherCache, string buildResult, string latest)
{
progress.Invoke("Removing Old Files", 60);
ClearOld(launcherCache.InstallDirectory);
progress.Invoke("Extracting Files", 80);
ZipFile.ExtractToDirectory(buildResult, launcherCache.InstallDirectory, true);
progress.Invoke("Cleaning Up", 100);
File.WriteAllText(Path.Combine(launcherCache.InstallDirectory, "version.txt"), latest);
File.Delete(buildResult);
callback.Invoke(true, FindExecutable(launcherCache.InstallDirectory));
}

// Returns the path of the Executable
public static void Install(Action<bool, string> callback, Action<string, int> progress, LauncherCache launcherCache)
Expand Down Expand Up @@ -127,6 +156,26 @@ public static void Install(Action<bool, string> callback, Action<string, int> pr
}, INSTALLING_NAME);
}

public static void InstallGithub(Action<bool, string> callback, Action<string, int> progress, LauncherCache launcherCache)
{
progress.Invoke("Getting Latest Version", 20);
string version = GetLatestVersionFromGitHub();
if (IsSameVersion(launcherCache.InstallDirectory, version))
{
callback.Invoke(true, FindExecutable(launcherCache.InstallDirectory));
return;
}
progress.Invoke("Getting Build Artifact", 40);
using WebClient client = new WebClient();
string outputFile = LauncherCache.GetFileSave("build.zip");
client.DownloadFileCompleted += (sender, args) =>
ContinueInstall(callback, progress, launcherCache, outputFile, version);
client.DownloadProgressChanged += (sender, args) =>
progress.Invoke("Downloading latest version... (" + args.ProgressPercentage + "%)",
args.ProgressPercentage);
client.DownloadFileAsync(new Uri(GitHubDownload), outputFile);
}

private static bool IsSameVersion(string installLocation, string version)
{
string file = Path.Combine(installLocation, "version.txt");
Expand All @@ -135,6 +184,87 @@ private static bool IsSameVersion(string installLocation, string version)
string t = File.ReadAllText(file);
return t == version;
}

public static string GetLatestVersionFromGitHub()
{
// Get the URL
string url = GetFinalRedirect(GIT_URL);
if (!string.IsNullOrEmpty(url))
{
// Parse the Url
string[] slashSplit = url.Split('/');
string tag = slashSplit[slashSplit.Length - 1];
return tag;
}
return String.Empty;
}

/// <summary>
/// Method by Marcelo Calbucci and edited by Uwe Keim.
/// No changes to this method were made.
/// https://stackoverflow.com/a/28424940/12968919
/// </summary>
/// <param name="url"></param>
/// <returns></returns>
private static string GetFinalRedirect(string url)
{
if(string.IsNullOrWhiteSpace(url))
return url;

int maxRedirCount = 8; // prevent infinite loops
string newUrl = url;
do
{
HttpWebRequest req = null;
HttpWebResponse resp = null;
try
{
req = (HttpWebRequest) HttpWebRequest.Create(url);
req.Method = "HEAD";
req.AllowAutoRedirect = false;
resp = (HttpWebResponse)req.GetResponse();
switch (resp.StatusCode)
{
case HttpStatusCode.OK:
return newUrl;
case HttpStatusCode.Redirect:
case HttpStatusCode.MovedPermanently:
case HttpStatusCode.RedirectKeepVerb:
case HttpStatusCode.RedirectMethod:
newUrl = resp.Headers["Location"];
if (newUrl == null)
return url;

if (newUrl.IndexOf("://", System.StringComparison.Ordinal) == -1)
{
// Doesn't have a URL Schema, meaning it's a relative or absolute URL
Uri u = new Uri(new Uri(url), newUrl);
newUrl = u.ToString();
}
break;
default:
return newUrl;
}
url = newUrl;
}
catch (WebException)
{
// Return the last known good URL
return newUrl;
}
catch (Exception ex)
{
return null;
}
finally
{
if (resp != null)
resp.Close();
}
}
while (maxRedirCount-- > 0);
return newUrl;
}

private static void ClearOld(string installDirectory)
{
Expand Down
11 changes: 11 additions & 0 deletions Hypernex.Launcher/LauncherCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,15 @@ public class LauncherCache
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Hypernex.Launcher");

private static string ConfigLocation => Path.Combine(CacheDirectory, "launcher.cfg");

public static void DeleteFile(string fileName)
{
if (!Directory.Exists(CacheDirectory))
Directory.CreateDirectory(CacheDirectory);
string path = Path.Combine(CacheDirectory, fileName);
if(!File.Exists(path)) return;
File.Delete(path);
}

public static string SaveFile(byte[] data, string fileName)
{
Expand All @@ -25,6 +34,8 @@ public static string SaveFile(byte[] data, string fileName)
return file;
}

public static string GetFileSave(string fileName) => Path.Combine(CacheDirectory, fileName);

public static LauncherCache Create()
{
if (!Directory.Exists(CacheDirectory))
Expand Down
89 changes: 54 additions & 35 deletions Hypernex.Launcher/MainWindow.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -108,43 +108,22 @@ private void Launch(LauncherCache launcherCache)
{
try
{
Installer.Install((didDownload, executableToLaunch) => Dispatcher.UIThread.InvokeAsync(() =>
if(GetArgs().Contains("--no-github"))
{
ActionText.Text = "Launching";
ProgressBar.Value = 100;
new Thread(() =>
{
ProcessStartInfo processStartInfo = new()
{
FileName = Path.GetFileName(executableToLaunch),
WorkingDirectory = Path.GetDirectoryName(executableToLaunch),
UseShellExecute = true,
Arguments = GetArgs()
};
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
// Make sure the file is executable first
Process chmodProcess = new Process
{
StartInfo = new ProcessStartInfo("chmod", $"+x {executableToLaunch}")
{
CreateNoWindow = true
},
EnableRaisingEvents = true
};
chmodProcess.Exited += (sender, args) => { Process.Start(processStartInfo); };
chmodProcess.Start();
}
else
Process.Start(processStartInfo);
Thread.Sleep(3000);
Environment.Exit(0);
}).Start();
}), (text, progress) => Dispatcher.UIThread.InvokeAsync(() =>
Installer.Install(
(didDownload, executableToLaunch) =>
Dispatcher.UIThread.InvokeAsync(() => OnInstall(didDownload, executableToLaunch)),
(text, progress) => Dispatcher.UIThread.InvokeAsync(() => OnProgress(text, progress)),
launcherCache);
}
else
{
ActionText.Text = text;
ProgressBar.Value = progress;
}), launcherCache);
Installer.InstallGithub(
(didDownload, executableToLaunch) =>
Dispatcher.UIThread.InvokeAsync(() => OnInstall(didDownload, executableToLaunch)),
(text, progress) => Dispatcher.UIThread.InvokeAsync(() => OnProgress(text, progress)),
launcherCache);
}
}
catch (Exception e)
{
Expand All @@ -160,4 +139,44 @@ private void Launch(LauncherCache launcherCache)
Environment.Exit(0);
}
}

private void OnProgress(string text, int progress)
{
ActionText.Text = text;
ProgressBar.Value = progress;
}

private void OnInstall(bool didDownload, string executableToLaunch)
{
ActionText.Text = "Launching";
ProgressBar.Value = 100;
new Thread(() =>
{
ProcessStartInfo processStartInfo = new()
{
FileName = Path.GetFileName(executableToLaunch),
WorkingDirectory = Path.GetDirectoryName(executableToLaunch),
UseShellExecute = true,
Arguments = GetArgs()
};
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
// Make sure the file is executable first
Process chmodProcess = new Process
{
StartInfo = new ProcessStartInfo("chmod", $"+x {executableToLaunch}")
{
CreateNoWindow = true
},
EnableRaisingEvents = true
};
chmodProcess.Exited += (sender, args) => { Process.Start(processStartInfo); };
chmodProcess.Start();
}
else
Process.Start(processStartInfo);
Thread.Sleep(3000);
Environment.Exit(0);
}).Start();
}
}

0 comments on commit 3edd129

Please sign in to comment.