Merge pull request 'imp/7z-compression' (#57) from waffle.lord/SPT-AKI-Installer:imp/7z-compression into master
Reviewed-on: CWX/SPT-AKI-Installer#57
This commit is contained in:
commit
defe7053d3
@ -1,5 +1,4 @@
|
|||||||
using Serilog;
|
using Serilog;
|
||||||
using SharpCompress;
|
|
||||||
using SPTInstaller.CustomControls;
|
using SPTInstaller.CustomControls;
|
||||||
using SPTInstaller.Interfaces;
|
using SPTInstaller.Interfaces;
|
||||||
using SPTInstaller.Models;
|
using SPTInstaller.Models;
|
||||||
@ -22,13 +21,18 @@ public class InstallController
|
|||||||
{
|
{
|
||||||
_tasks = tasks;
|
_tasks = tasks;
|
||||||
_preChecks = preChecks;
|
_preChecks = preChecks;
|
||||||
|
|
||||||
_preChecks.ForEach(x => x.ReeevaluationRequested += (s, e) =>
|
foreach (var check in _preChecks)
|
||||||
{
|
{
|
||||||
if (s is IPreCheck preCheck)
|
check.ReeevaluationRequested += (s, _) =>
|
||||||
{
|
{
|
||||||
Log.Information($"{preCheck.Name}: requested re-evaluation");
|
if (s is not IPreCheck preCheck)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.Information($"{preCheck.Name}: requested re-evaluation");
|
||||||
|
|
||||||
if (_installRunning)
|
if (_installRunning)
|
||||||
{
|
{
|
||||||
Log.Warning("Install is running, re-evaluation denied (how did you do this?)");
|
Log.Warning("Install is running, re-evaluation denied (how did you do this?)");
|
||||||
@ -36,8 +40,8 @@ public class InstallController
|
|||||||
}
|
}
|
||||||
|
|
||||||
RecheckRequested?.Invoke(this, null);
|
RecheckRequested?.Invoke(this, null);
|
||||||
}
|
};
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IResult> RunPreChecks()
|
public async Task<IResult> RunPreChecks()
|
||||||
@ -45,7 +49,10 @@ public class InstallController
|
|||||||
Log.Information("-<>--<>- Running PreChecks -<>--<>-");
|
Log.Information("-<>--<>- Running PreChecks -<>--<>-");
|
||||||
var requiredResults = new List<IResult>();
|
var requiredResults = new List<IResult>();
|
||||||
|
|
||||||
_preChecks.ForEach(x => x.State = StatusSpinner.SpinnerState.Pending);
|
foreach (var check in _preChecks)
|
||||||
|
{
|
||||||
|
check.State = StatusSpinner.SpinnerState.Pending;
|
||||||
|
}
|
||||||
|
|
||||||
foreach (var check in _preChecks)
|
foreach (var check in _preChecks)
|
||||||
{
|
{
|
||||||
|
@ -126,28 +126,39 @@ public static class FileHelper
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void StreamAssemblyResourceOut(string resourceName, string outputFilePath)
|
public static bool StreamAssemblyResourceOut(string resourceName, string outputFilePath)
|
||||||
{
|
{
|
||||||
var assembly = Assembly.GetExecutingAssembly();
|
try
|
||||||
|
|
||||||
FileInfo outputFile = new FileInfo(outputFilePath);
|
|
||||||
|
|
||||||
if (outputFile.Exists)
|
|
||||||
{
|
{
|
||||||
outputFile.Delete();
|
var assembly = Assembly.GetExecutingAssembly();
|
||||||
|
|
||||||
|
FileInfo outputFile = new FileInfo(outputFilePath);
|
||||||
|
|
||||||
|
if (outputFile.Exists)
|
||||||
|
{
|
||||||
|
outputFile.Delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!outputFile.Directory.Exists)
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(outputFile.Directory.FullName);
|
||||||
|
}
|
||||||
|
|
||||||
|
var resName = assembly.GetManifestResourceNames().First(x => x.EndsWith(resourceName));
|
||||||
|
|
||||||
|
using (FileStream fs = File.Create(outputFilePath))
|
||||||
|
using (Stream s = assembly.GetManifestResourceStream(resName))
|
||||||
|
{
|
||||||
|
s.CopyTo(fs);
|
||||||
|
}
|
||||||
|
|
||||||
|
outputFile.Refresh();
|
||||||
|
return outputFile.Exists;
|
||||||
}
|
}
|
||||||
|
catch (Exception ex)
|
||||||
if (!outputFile.Directory.Exists)
|
|
||||||
{
|
{
|
||||||
Directory.CreateDirectory(outputFile.Directory.FullName);
|
Log.Fatal(ex, $"Failed to stream resource out: {resourceName}");
|
||||||
}
|
return false;
|
||||||
|
|
||||||
var resName = assembly.GetManifestResourceNames().First(x => x.EndsWith(resourceName));
|
|
||||||
|
|
||||||
using (FileStream fs = File.Create(outputFilePath))
|
|
||||||
using (Stream s = assembly.GetManifestResourceStream(resName))
|
|
||||||
{
|
|
||||||
s.CopyTo(fs);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,46 +1,34 @@
|
|||||||
using System.Linq;
|
using SevenZip;
|
||||||
using SharpCompress.Archives;
|
|
||||||
using SharpCompress.Archives.Zip;
|
|
||||||
using SharpCompress.Common;
|
|
||||||
using SPTInstaller.Models;
|
using SPTInstaller.Models;
|
||||||
|
|
||||||
namespace SPTInstaller.Helpers;
|
namespace SPTInstaller.Helpers;
|
||||||
|
|
||||||
public static class ZipHelper
|
public static class ZipHelper
|
||||||
{
|
{
|
||||||
public static Result Decompress(FileInfo ArchivePath, DirectoryInfo OutputFolderPath, IProgress<double> progress = null)
|
public static Result Decompress(FileInfo archiveFile, DirectoryInfo outputDirectory, IProgress<double> progress = null)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
OutputFolderPath.Refresh();
|
using var archiveStream = archiveFile.OpenRead();
|
||||||
|
|
||||||
if (!OutputFolderPath.Exists) OutputFolderPath.Create();
|
var dllPath = Path.Join(DownloadCacheHelper.CachePath, "7z.dll");
|
||||||
|
|
||||||
|
SevenZipBase.SetLibraryPath(dllPath);
|
||||||
|
|
||||||
using var archive = ZipArchive.Open(ArchivePath);
|
var extractor = new SevenZipExtractor(archiveStream);
|
||||||
var totalEntries = archive.Entries.Where(entry => !entry.IsDirectory);
|
|
||||||
var processedEntries = 0;
|
|
||||||
|
|
||||||
foreach (var entry in totalEntries)
|
extractor.Extracting += (_, args) =>
|
||||||
{
|
{
|
||||||
entry.WriteToDirectory(OutputFolderPath.FullName, new ExtractionOptions()
|
progress.Report(args.PercentDone);
|
||||||
{
|
};
|
||||||
ExtractFullPath = true,
|
|
||||||
Overwrite = true
|
|
||||||
});
|
|
||||||
|
|
||||||
processedEntries++;
|
extractor.ExtractArchive(outputDirectory.FullName);
|
||||||
|
|
||||||
if (progress != null)
|
outputDirectory.Refresh();
|
||||||
{
|
|
||||||
progress.Report(Math.Floor(((double)processedEntries / totalEntries.Count()) * 100));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
OutputFolderPath.Refresh();
|
if (!outputDirectory.Exists)
|
||||||
|
|
||||||
if (!OutputFolderPath.Exists)
|
|
||||||
{
|
{
|
||||||
return Result.FromError($"Failed to extract files: {ArchivePath.Name}");
|
return Result.FromError($"Failed to extract files: {archiveFile.Name}");
|
||||||
}
|
}
|
||||||
|
|
||||||
return Result.FromSuccess();
|
return Result.FromSuccess();
|
||||||
|
@ -35,7 +35,9 @@ public class DownloadTask : InstallerTaskBase
|
|||||||
var mirrorsList = JsonConvert.DeserializeObject<List<DownloadMirror>>(File.ReadAllText(file.FullName));
|
var mirrorsList = JsonConvert.DeserializeObject<List<DownloadMirror>>(File.ReadAllText(file.FullName));
|
||||||
|
|
||||||
if (mirrorsList == null)
|
if (mirrorsList == null)
|
||||||
|
{
|
||||||
return Result.FromError("Failed to deserialize mirrors list");
|
return Result.FromError("Failed to deserialize mirrors list");
|
||||||
|
}
|
||||||
|
|
||||||
foreach (var mirror in mirrorsList)
|
foreach (var mirror in mirrorsList)
|
||||||
{
|
{
|
||||||
@ -59,7 +61,7 @@ public class DownloadTask : InstallerTaskBase
|
|||||||
{
|
{
|
||||||
SetStatus("Downloading Patcher", "Verifying cached patcher ...", progressStyle: ProgressStyle.Indeterminate);
|
SetStatus("Downloading Patcher", "Verifying cached patcher ...", progressStyle: ProgressStyle.Indeterminate);
|
||||||
|
|
||||||
if (DownloadCacheHelper.CheckCache("patcher.zip", _expectedPatcherHash, out var cacheFile))
|
if (DownloadCacheHelper.CheckCache("patcher", _expectedPatcherHash, out var cacheFile))
|
||||||
{
|
{
|
||||||
_data.PatcherZipInfo = cacheFile;
|
_data.PatcherZipInfo = cacheFile;
|
||||||
Log.Information("Using cached file {fileName} - Hash: {hash}", _data.PatcherZipInfo.Name, _expectedPatcherHash);
|
Log.Information("Using cached file {fileName} - Hash: {hash}", _data.PatcherZipInfo.Name, _expectedPatcherHash);
|
||||||
@ -106,7 +108,7 @@ public class DownloadTask : InstallerTaskBase
|
|||||||
|
|
||||||
SetStatus("Downloading SPT-AKI", _data.AkiReleaseDownloadLink, 0);
|
SetStatus("Downloading SPT-AKI", _data.AkiReleaseDownloadLink, 0);
|
||||||
|
|
||||||
_data.AkiZipInfo = await DownloadCacheHelper.GetOrDownloadFileAsync("sptaki.zip", _data.AkiReleaseDownloadLink, progress, _data.AkiReleaseHash);
|
_data.AkiZipInfo = await DownloadCacheHelper.GetOrDownloadFileAsync("sptaki", _data.AkiReleaseDownloadLink, progress, _data.AkiReleaseHash);
|
||||||
|
|
||||||
if (_data.AkiZipInfo == null)
|
if (_data.AkiZipInfo == null)
|
||||||
{
|
{
|
||||||
|
@ -7,18 +7,18 @@ using SPTInstaller.Helpers;
|
|||||||
|
|
||||||
namespace SPTInstaller.Installer_Tasks.PreChecks;
|
namespace SPTInstaller.Installer_Tasks.PreChecks;
|
||||||
|
|
||||||
public class NetCore6PreCheck : PreCheckBase
|
public class Net8PreCheck : PreCheckBase
|
||||||
{
|
{
|
||||||
public NetCore6PreCheck() : base(".Net Core 6 Desktop Runtime", true)
|
public Net8PreCheck() : base(".Net 8 Desktop Runtime", true)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task<PreCheckResult> CheckOperation()
|
public override async Task<PreCheckResult> CheckOperation()
|
||||||
{
|
{
|
||||||
var minRequiredVersion = new Version("6.0.0");
|
var minRequiredVersion = new Version("8.0.0");
|
||||||
string[] output;
|
string[] output;
|
||||||
|
|
||||||
var failedButtonText = "Download .Net Core 6 Desktop Runtime";
|
var failedButtonText = "Download .Net 8 Desktop Runtime";
|
||||||
|
|
||||||
var failedButtonAction = () =>
|
var failedButtonAction = () =>
|
||||||
{
|
{
|
||||||
@ -27,7 +27,7 @@ public class NetCore6PreCheck : PreCheckBase
|
|||||||
FileName = "cmd.exe",
|
FileName = "cmd.exe",
|
||||||
UseShellExecute = true,
|
UseShellExecute = true,
|
||||||
WindowStyle = ProcessWindowStyle.Hidden,
|
WindowStyle = ProcessWindowStyle.Hidden,
|
||||||
ArgumentList = { "/C", "start", "https://dotnet.microsoft.com/en-us/download/dotnet/thank-you/runtime-desktop-6.0.4-windows-x64-installer" }
|
ArgumentList = { "/C", "start", "https://dotnet.microsoft.com/en-us/download/dotnet/thank-you/runtime-desktop-8.0.2-windows-x64-installer" }
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -37,7 +37,7 @@ public class NetCore6PreCheck : PreCheckBase
|
|||||||
|
|
||||||
if (!result.Succeeded)
|
if (!result.Succeeded)
|
||||||
{
|
{
|
||||||
return PreCheckResult.FromError(result.Message + "\n\nYou most likely don't have .net 6 installed", failedButtonText, failedButtonAction);
|
return PreCheckResult.FromError(result.Message + "\n\nYou most likely don't have .net 8 installed", failedButtonText, failedButtonAction);
|
||||||
}
|
}
|
||||||
|
|
||||||
output = result.StdOut.Split("\r\n");
|
output = result.StdOut.Split("\r\n");
|
||||||
@ -63,12 +63,12 @@ public class NetCore6PreCheck : PreCheckBase
|
|||||||
|
|
||||||
if (foundVersion >= minRequiredVersion)
|
if (foundVersion >= minRequiredVersion)
|
||||||
{
|
{
|
||||||
return PreCheckResult.FromSuccess($".Net Core {minRequiredVersion} Desktop Runtime or higher is installed.\n\nInstalled Version: {foundVersion}");
|
return PreCheckResult.FromSuccess($".Net {minRequiredVersion} Desktop Runtime or higher is installed.\n\nInstalled Version: {foundVersion}");
|
||||||
}
|
}
|
||||||
|
|
||||||
highestFoundVersion = foundVersion > highestFoundVersion ? foundVersion : highestFoundVersion;
|
highestFoundVersion = foundVersion > highestFoundVersion ? foundVersion : highestFoundVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
return PreCheckResult.FromError($".Net Core Desktop Runtime version {minRequiredVersion} or higher is required.\n\nHighest Version Found: {(highestFoundVersion > new Version("0.0.0") ? highestFoundVersion : "Not Found")}\n\nThis is required to play SPT, but you can install it later if and shouldn't affect the SPT install process.", failedButtonText, failedButtonAction);
|
return PreCheckResult.FromError($".Net Desktop Runtime version {minRequiredVersion} or higher is required.\n\nHighest Version Found: {(highestFoundVersion > new Version("0.0.0") ? highestFoundVersion : "Not Found")}\n\nThis is required to play SPT", failedButtonText, failedButtonAction);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -28,6 +28,13 @@ public class SetupClientTask : InstallerTaskBase
|
|||||||
|
|
||||||
if (_data.PatchNeeded)
|
if (_data.PatchNeeded)
|
||||||
{
|
{
|
||||||
|
SetStatus("Preparing 7z", "", null, ProgressStyle.Indeterminate);
|
||||||
|
|
||||||
|
if (!FileHelper.StreamAssemblyResourceOut("7z.dll", Path.Join(DownloadCacheHelper.CachePath, "7z.dll")))
|
||||||
|
{
|
||||||
|
return Result.FromError("Failed to prepare 7z");
|
||||||
|
}
|
||||||
|
|
||||||
// extract patcher files
|
// extract patcher files
|
||||||
SetStatus("Extrating Patcher", "", 0);
|
SetStatus("Extrating Patcher", "", 0);
|
||||||
|
|
||||||
|
@ -61,7 +61,12 @@ public class InstallerUpdateInfo : ReactiveObject
|
|||||||
UpdateAvailable = false;
|
UpdateAvailable = false;
|
||||||
|
|
||||||
var updater = new FileInfo(Path.Join(DownloadCacheHelper.CachePath, "update.ps1"));
|
var updater = new FileInfo(Path.Join(DownloadCacheHelper.CachePath, "update.ps1"));
|
||||||
FileHelper.StreamAssemblyResourceOut("update.ps1", updater.FullName);
|
|
||||||
|
if (!FileHelper.StreamAssemblyResourceOut("update.ps1", updater.FullName))
|
||||||
|
{
|
||||||
|
Log.Fatal("Failed to prepare update file");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (!updater.Exists)
|
if (!updater.Exists)
|
||||||
|
@ -10,7 +10,7 @@ public class HttpMirrorDownloader : MirrorDownloaderBase
|
|||||||
|
|
||||||
public override async Task<FileInfo?> Download(IProgress<double> progress)
|
public override async Task<FileInfo?> Download(IProgress<double> progress)
|
||||||
{
|
{
|
||||||
var file = await DownloadCacheHelper.DownloadFileAsync("patcher.zip", MirrorInfo.Link, progress);
|
var file = await DownloadCacheHelper.DownloadFileAsync("patcher", MirrorInfo.Link, progress);
|
||||||
|
|
||||||
if (file == null)
|
if (file == null)
|
||||||
return null;
|
return null;
|
||||||
|
@ -23,7 +23,7 @@ public class MegaMirrorDownloader : MirrorDownloaderBase
|
|||||||
{
|
{
|
||||||
using var megaDownloadStream = await megaClient.DownloadAsync(new Uri(MirrorInfo.Link), progress);
|
using var megaDownloadStream = await megaClient.DownloadAsync(new Uri(MirrorInfo.Link), progress);
|
||||||
|
|
||||||
var file = await DownloadCacheHelper.DownloadFileAsync("patcher.zip", megaDownloadStream);
|
var file = await DownloadCacheHelper.DownloadFileAsync("patcher", megaDownloadStream);
|
||||||
|
|
||||||
if (file == null)
|
if (file == null)
|
||||||
return null;
|
return null;
|
||||||
|
@ -44,7 +44,7 @@ internal class Program
|
|||||||
|
|
||||||
#if !TEST
|
#if !TEST
|
||||||
ServiceHelper.Register<PreCheckBase, NetFramework472PreCheck>();
|
ServiceHelper.Register<PreCheckBase, NetFramework472PreCheck>();
|
||||||
ServiceHelper.Register<PreCheckBase, NetCore6PreCheck>();
|
ServiceHelper.Register<PreCheckBase, Net8PreCheck>();
|
||||||
ServiceHelper.Register<PreCheckBase, FreeSpacePreCheck>();
|
ServiceHelper.Register<PreCheckBase, FreeSpacePreCheck>();
|
||||||
ServiceHelper.Register<PreCheckBase, EftLauncherPreCheck>();
|
ServiceHelper.Register<PreCheckBase, EftLauncherPreCheck>();
|
||||||
|
|
||||||
|
BIN
SPTInstaller/Resources/7z.dll
Normal file
BIN
SPTInstaller/Resources/7z.dll
Normal file
Binary file not shown.
@ -1,7 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>WinExe</OutputType>
|
<OutputType>WinExe</OutputType>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
<IncludeNativeLibrariesForSelfExtract>true</IncludeNativeLibrariesForSelfExtract>
|
<IncludeNativeLibrariesForSelfExtract>true</IncludeNativeLibrariesForSelfExtract>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<BuiltInComInteropSupport>true</BuiltInComInteropSupport>
|
<BuiltInComInteropSupport>true</BuiltInComInteropSupport>
|
||||||
@ -9,8 +9,8 @@
|
|||||||
<PackageIcon>icon.ico</PackageIcon>
|
<PackageIcon>icon.ico</PackageIcon>
|
||||||
<ApplicationIcon>Assets\icon.ico</ApplicationIcon>
|
<ApplicationIcon>Assets\icon.ico</ApplicationIcon>
|
||||||
<Configurations>Debug;Release;TEST</Configurations>
|
<Configurations>Debug;Release;TEST</Configurations>
|
||||||
<AssemblyVersion>2.33</AssemblyVersion>
|
<AssemblyVersion>2.42</AssemblyVersion>
|
||||||
<FileVersion>2.33</FileVersion>
|
<FileVersion>2.42</FileVersion>
|
||||||
<Company>SPT-AKI</Company>
|
<Company>SPT-AKI</Company>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
@ -23,6 +23,8 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<EmbeddedResource Include="Resources\update.ps1" />
|
<EmbeddedResource Include="Resources\update.ps1" />
|
||||||
|
<None Remove="Resources\7z.dll" />
|
||||||
|
<EmbeddedResource Include="Resources\7z.dll" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@ -42,7 +44,7 @@
|
|||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||||
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
|
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
|
||||||
<PackageReference Include="SerilogTraceListener" Version="3.2.0" />
|
<PackageReference Include="SerilogTraceListener" Version="3.2.0" />
|
||||||
<PackageReference Include="SharpCompress" Version="0.34.0" />
|
<PackageReference Include="Squid-Box.SevenZipSharp" Version="1.6.1.23" />
|
||||||
<PackageReference Include="System.Reactive" Version="6.0.0" />
|
<PackageReference Include="System.Reactive" Version="6.0.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user