diff --git a/Aki.Core/InternalData.cs b/Aki.Core/InternalData.cs
index 690d20a..221ad2a 100644
--- a/Aki.Core/InternalData.cs
+++ b/Aki.Core/InternalData.cs
@@ -1,4 +1,5 @@
-using System.Collections.Generic;
+using SPT_AKI_Installer.Aki.Core.Model;
+using System.Collections.Generic;
using System.IO;
namespace SPT_AKI_Installer.Aki.Core
@@ -43,7 +44,7 @@ namespace SPT_AKI_Installer.Aki.Core
///
/// The release download mirrors for the patcher
///
- public List PatcherReleaseMirrors { get; set; } = null;
+ public List PatcherReleaseMirrors { get; set; } = null;
///
/// Whether or not a patch is needed to downgrade the client files
diff --git a/Aki.Core/Model/DownloadMirror.cs b/Aki.Core/Model/DownloadMirror.cs
new file mode 100644
index 0000000..9756b1f
--- /dev/null
+++ b/Aki.Core/Model/DownloadMirror.cs
@@ -0,0 +1,8 @@
+namespace SPT_AKI_Installer.Aki.Core.Model
+{
+ public class DownloadMirror
+ {
+ public string Link { get; set; }
+ public string Hash { get; set; }
+ }
+}
diff --git a/Aki.Core/SPTInstaller.cs b/Aki.Core/SPTInstaller.cs
index 6dfa6d8..1b7014f 100644
--- a/Aki.Core/SPTInstaller.cs
+++ b/Aki.Core/SPTInstaller.cs
@@ -55,7 +55,7 @@ namespace SPT_AKI_Installer.Aki.Core
#endif
await LiveTableTaskRunner.RunAsync(tasks);
- CloseApp("SPT is Ready to play");
+ CloseApp("");
}
private static IHost ConfigureHost()
diff --git a/Aki.Core/Tasks/DownloadTask.cs b/Aki.Core/Tasks/DownloadTask.cs
index 7b9e52d..c49373f 100644
--- a/Aki.Core/Tasks/DownloadTask.cs
+++ b/Aki.Core/Tasks/DownloadTask.cs
@@ -33,9 +33,9 @@ namespace SPT_AKI_Installer.Aki.Core.Tasks
return downloadResult;
}
- var blah = JsonConvert.DeserializeObject>(File.ReadAllText(mirrorListInfo.FullName));
+ var blah = JsonConvert.DeserializeObject>(File.ReadAllText(mirrorListInfo.FullName));
- if (blah is List mirrors)
+ if (blah is List mirrors)
{
_data.PatcherReleaseMirrors = mirrors;
@@ -47,12 +47,12 @@ namespace SPT_AKI_Installer.Aki.Core.Tasks
private async Task DownloadPatcherFromMirrors(IProgress progress)
{
- foreach (string mirror in _data.PatcherReleaseMirrors)
+ foreach (var mirror in _data.PatcherReleaseMirrors)
{
- SetStatus($"Downloading Patcher: {mirror}", false);
+ SetStatus($"Downloading Patcher: {mirror.Link}", false);
// mega is a little weird since they use encryption, but thankfully there is a great library for their api :)
- if (mirror.StartsWith("https://mega"))
+ if (mirror.Link.StartsWith("https://mega"))
{
var megaClient = new MegaApiClient();
await megaClient.LoginAnonymousAsync();
@@ -62,12 +62,19 @@ namespace SPT_AKI_Installer.Aki.Core.Tasks
try
{
- using var megaDownloadStream = await megaClient.DownloadAsync(new Uri(mirror), progress);
+ using var megaDownloadStream = await megaClient.DownloadAsync(new Uri(mirror.Link), progress);
using var patcherFileStream = _data.PatcherZipInfo.Open(FileMode.Create);
{
await megaDownloadStream.CopyToAsync(patcherFileStream);
}
+ patcherFileStream.Close();
+
+ if(!DownloadHelper.FileHashCheck(_data.PatcherZipInfo, mirror.Hash))
+ {
+ return GenericResult.FromError("Hash mismatch");
+ }
+
return GenericResult.FromSuccess();
}
catch (Exception)
@@ -77,7 +84,7 @@ namespace SPT_AKI_Installer.Aki.Core.Tasks
}
}
- var result = await DownloadHelper.DownloadFile(_data.PatcherZipInfo, mirror, progress);
+ var result = await DownloadHelper.DownloadFile(_data.PatcherZipInfo, mirror.Link, progress, mirror.Hash);
if (result.Succeeded)
{
diff --git a/Aki.Helper/DownloadHelper.cs b/Aki.Helper/DownloadHelper.cs
index ff199dd..6e48c30 100644
--- a/Aki.Helper/DownloadHelper.cs
+++ b/Aki.Helper/DownloadHelper.cs
@@ -2,7 +2,9 @@
using SPT_AKI_Installer.Aki.Core.Model;
using System;
using System.IO;
+using System.Linq;
using System.Net.Http;
+using System.Security.Cryptography;
using System.Threading.Tasks;
namespace SPT_AKI_Installer.Aki.Helper
@@ -11,7 +13,22 @@ namespace SPT_AKI_Installer.Aki.Helper
{
private static HttpClient _httpClient = new HttpClient() { Timeout = TimeSpan.FromHours(1) };
- public static async Task DownloadFile(FileInfo outputFile, string targetLink, IProgress progress)
+ public static bool FileHashCheck(FileInfo file, string expectedHash)
+ {
+ using (MD5 md5Service = MD5.Create())
+ using (var sourceStream = file.OpenRead())
+ {
+ byte[] sourceHash = md5Service.ComputeHash(sourceStream);
+ byte[] expectedHashBytes = Convert.FromBase64String(expectedHash);
+
+ bool matched = Enumerable.SequenceEqual(sourceHash, expectedHashBytes);
+
+ return matched;
+ }
+ }
+
+
+ public static async Task DownloadFile(FileInfo outputFile, string targetLink, IProgress progress, string expectedHash = null)
{
try
{
@@ -30,6 +47,11 @@ namespace SPT_AKI_Installer.Aki.Helper
return GenericResult.FromError($"Failed to download {outputFile.Name}");
}
+ if (expectedHash != null && !FileHashCheck(outputFile, expectedHash))
+ {
+ return GenericResult.FromError("Hash mismatch");
+ }
+
return GenericResult.FromSuccess();
}
catch (Exception ex)
diff --git a/Aki.Helper/HttpClientProgressExtensions.cs b/Aki.Helper/HttpClientProgressExtensions.cs
index 3568717..6b27d96 100644
--- a/Aki.Helper/HttpClientProgressExtensions.cs
+++ b/Aki.Helper/HttpClientProgressExtensions.cs
@@ -12,6 +12,8 @@ namespace HttpClientProgress
{
using (var response = await client.GetAsync(requestUrl, HttpCompletionOption.ResponseHeadersRead))
{
+ var blah = await response.Content.ReadAsStringAsync();
+
var contentLength = response.Content.Headers.ContentLength;
using (var download = await response.Content.ReadAsStreamAsync())
{
diff --git a/Properties/PublishProfiles/FolderProfile.pubxml.user b/Properties/PublishProfiles/FolderProfile.pubxml.user
index b3fad3b..e3a2ecb 100644
--- a/Properties/PublishProfiles/FolderProfile.pubxml.user
+++ b/Properties/PublishProfiles/FolderProfile.pubxml.user
@@ -4,6 +4,6 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
-->
- True|2022-07-09T17:06:26.5751622Z;True|2022-07-09T12:56:17.1018408-04:00;True|2022-07-09T12:38:17.0878078-04:00;True|2022-07-09T12:18:23.6469737-04:00;True|2022-06-21T14:47:38.7532473-04:00;True|2022-06-08T13:26:47.7977621-04:00;True|2022-06-06T10:07:18.8067168-04:00;True|2022-06-05T17:55:20.5192697-04:00;True|2022-05-30T08:11:30.6942032-04:00;True|2022-05-30T08:08:08.4269393-04:00;True|2022-05-16T20:06:33.6758525-04:00;True|2022-05-13T20:56:09.8410037-04:00;True|2022-05-13T19:54:24.0683990-04:00;True|2022-05-13T19:53:04.7105427-04:00;True|2022-05-13T19:51:00.6280767-04:00;True|2022-05-13T19:49:19.4630888-04:00;True|2022-05-13T19:47:59.2166156-04:00;
+ True|2022-07-12T01:15:15.4480498Z;True|2022-07-11T21:11:55.8484217-04:00;True|2022-07-09T13:06:26.5751622-04:00;True|2022-07-09T12:56:17.1018408-04:00;True|2022-07-09T12:38:17.0878078-04:00;True|2022-07-09T12:18:23.6469737-04:00;True|2022-06-21T14:47:38.7532473-04:00;True|2022-06-08T13:26:47.7977621-04:00;True|2022-06-06T10:07:18.8067168-04:00;True|2022-06-05T17:55:20.5192697-04:00;True|2022-05-30T08:11:30.6942032-04:00;True|2022-05-30T08:08:08.4269393-04:00;True|2022-05-16T20:06:33.6758525-04:00;True|2022-05-13T20:56:09.8410037-04:00;True|2022-05-13T19:54:24.0683990-04:00;True|2022-05-13T19:53:04.7105427-04:00;True|2022-05-13T19:51:00.6280767-04:00;True|2022-05-13T19:49:19.4630888-04:00;True|2022-05-13T19:47:59.2166156-04:00;
\ No newline at end of file