Compare commits
No commits in common. "1e78942572de7af50a0316c2c7abec3d755fc3bb" and "058c086c51e0ca95817cd80f2ae5af894ef8d49b" have entirely different histories.
1e78942572
...
058c086c51
@ -10,8 +10,6 @@ public static class DownloadCacheHelper
|
||||
private static HttpClient _httpClient = new() { Timeout = TimeSpan.FromHours(1) };
|
||||
|
||||
public static string CachePath = Path.Join(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "spt-installer/cache");
|
||||
public static string ReleaseMirrorUrl = "https://spt-releases.modd.in/release.json";
|
||||
public static string PatchMirrorUrl = "https://slugma.waffle-lord.net/mirrors.json";
|
||||
|
||||
public static string GetCacheSizeText()
|
||||
{
|
||||
|
@ -1,22 +1,24 @@
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text.RegularExpressions;
|
||||
using Gitea.Model;
|
||||
using Serilog;
|
||||
|
||||
namespace SPTInstaller.Helpers;
|
||||
|
||||
public static class FileHashHelper
|
||||
{
|
||||
// public static string? GetGiteaReleaseHash(Release release)
|
||||
// {
|
||||
// var regex = Regex.Match(release.Body, @"Release Hash: (?<hash>\S+)");
|
||||
//
|
||||
// if (regex.Success)
|
||||
// {
|
||||
// return regex.Groups["hash"].Value;
|
||||
// }
|
||||
//
|
||||
// return null;
|
||||
// }
|
||||
public static string? GetGiteaReleaseHash(Release release)
|
||||
{
|
||||
var regex = Regex.Match(release.Body, @"Release Hash: (?<hash>\S+)");
|
||||
|
||||
if (regex.Success)
|
||||
{
|
||||
return regex.Groups["hash"].Value;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static bool CheckHash(FileInfo file, string expectedHash)
|
||||
{
|
||||
|
@ -23,13 +23,29 @@ public class DownloadTask : InstallerTaskBase
|
||||
|
||||
private async Task<IResult> BuildMirrorList()
|
||||
{
|
||||
foreach (var mirror in _data.PatchInfo.Mirrors)
|
||||
var progress = new Progress<double>((d) => { SetStatus("Downloading Mirror List", "", (int)Math.Floor(d), ProgressStyle.Shown);});
|
||||
|
||||
var file = await DownloadCacheHelper.DownloadFileAsync("mirrors.json", _data.PatcherMirrorsLink, progress);
|
||||
|
||||
if (file == null)
|
||||
{
|
||||
return Result.FromError("Failed to download mirror list");
|
||||
}
|
||||
|
||||
var mirrorsList = JsonConvert.DeserializeObject<List<DownloadMirror>>(File.ReadAllText(file.FullName));
|
||||
|
||||
if (mirrorsList == null)
|
||||
{
|
||||
return Result.FromError("Failed to deserialize mirrors list");
|
||||
}
|
||||
|
||||
foreach (var mirror in mirrorsList)
|
||||
{
|
||||
_expectedPatcherHash = mirror.Hash;
|
||||
|
||||
switch (mirror.Link)
|
||||
{
|
||||
case { } l when l.StartsWith("https://mega"):
|
||||
case string l when l.StartsWith("https://mega"):
|
||||
_mirrors.Add(new MegaMirrorDownloader(mirror));
|
||||
break;
|
||||
default:
|
||||
|
@ -1,10 +1,11 @@
|
||||
using SPTInstaller.Interfaces;
|
||||
using Gitea.Api;
|
||||
using Gitea.Client;
|
||||
using SPTInstaller.Interfaces;
|
||||
using SPTInstaller.Models;
|
||||
using System.Threading.Tasks;
|
||||
using SPTInstaller.Helpers;
|
||||
using Newtonsoft.Json;
|
||||
using SPTInstaller.Models.Mirrors;
|
||||
using SPTInstaller.Models.ReleaseInfo;
|
||||
using SPTInstaller.Models.Releases;
|
||||
|
||||
namespace SPTInstaller.Installer_Tasks;
|
||||
|
||||
@ -21,10 +22,12 @@ public class ReleaseCheckTask : InstallerTaskBase
|
||||
{
|
||||
try
|
||||
{
|
||||
var repo = new RepositoryApi(Configuration.Default);
|
||||
|
||||
SetStatus("Checking SPT Releases", "", null, ProgressStyle.Indeterminate);
|
||||
|
||||
var progress = new Progress<double>((d) => { SetStatus(null, null, (int)Math.Floor(d)); });
|
||||
var akiReleaseInfoFile = await DownloadCacheHelper.DownloadFileAsync("release.json", DownloadCacheHelper.ReleaseMirrorUrl, progress);
|
||||
var akiReleaseInfoFile = await DownloadCacheHelper.DownloadFileAsync("release.json", "https://spt-releases.modd.in/release.json", progress);
|
||||
if (akiReleaseInfoFile == null)
|
||||
{
|
||||
return Result.FromError("Failed to download release metadata");
|
||||
@ -34,42 +37,34 @@ public class ReleaseCheckTask : InstallerTaskBase
|
||||
|
||||
SetStatus("Checking for Patches", "", null, ProgressStyle.Indeterminate);
|
||||
|
||||
var akiPatchMirrorsFile =
|
||||
await DownloadCacheHelper.DownloadFileAsync("mirrors.json", DownloadCacheHelper.PatchMirrorUrl,
|
||||
progress);
|
||||
var patchRepoReleases = await repo.RepoListReleasesAsync("SPT-AKI", "Downgrade-Patches");
|
||||
|
||||
if (akiPatchMirrorsFile == null)
|
||||
{
|
||||
return Result.FromError("Failed to download patch mirror data");
|
||||
}
|
||||
|
||||
var patchMirrorInfo = JsonConvert.DeserializeObject<PatchInfo>(File.ReadAllText(akiPatchMirrorsFile.FullName));
|
||||
|
||||
if (akiReleaseInfo == null || patchMirrorInfo == null)
|
||||
{
|
||||
return Result.FromError("An error occurred while deserializing aki or patch data");
|
||||
}
|
||||
var comparePatchToAki = patchRepoReleases?.Find(x => x.Name.Contains(_data.OriginalGameVersion) && x.Name.Contains(akiReleaseInfo.ClientVersion));
|
||||
|
||||
_data.PatcherMirrorsLink = comparePatchToAki?.Assets[0].BrowserDownloadUrl;
|
||||
_data.ReleaseInfo = akiReleaseInfo;
|
||||
_data.PatchInfo = patchMirrorInfo;
|
||||
int intAkiVersion = int.Parse(akiReleaseInfo.ClientVersion);
|
||||
int intGameVersion = int.Parse(_data.OriginalGameVersion);
|
||||
|
||||
// note: it's possible the game version could be lower than the aki version and still need a patch if the major version numbers change
|
||||
// : it's probably a low chance though
|
||||
bool patchNeedCheck = intGameVersion > intAkiVersion;
|
||||
int IntAkiVersion = int.Parse(akiReleaseInfo.ClientVersion);
|
||||
int IntGameVersion = int.Parse(_data.OriginalGameVersion);
|
||||
bool patchNeedCheck = false;
|
||||
|
||||
if (intGameVersion < intAkiVersion)
|
||||
if (IntGameVersion > IntAkiVersion)
|
||||
{
|
||||
patchNeedCheck = true;
|
||||
}
|
||||
|
||||
if (IntGameVersion < IntAkiVersion)
|
||||
{
|
||||
return Result.FromError("Your client is outdated. Please update EFT");
|
||||
|
||||
}
|
||||
|
||||
if (intGameVersion == intAkiVersion)
|
||||
if (IntGameVersion == IntAkiVersion)
|
||||
{
|
||||
patchNeedCheck = false;
|
||||
}
|
||||
|
||||
if ((intGameVersion != patchMirrorInfo.SourceClientVersion || intAkiVersion != patchMirrorInfo.TargetClientVersion) && patchNeedCheck)
|
||||
if (comparePatchToAki == null && patchNeedCheck)
|
||||
{
|
||||
return Result.FromError("No patcher available for your version.\nA patcher is usually created within 24 hours of an EFT update.");
|
||||
}
|
||||
|
@ -4,6 +4,6 @@ using System.Threading.Tasks;
|
||||
namespace SPTInstaller.Interfaces;
|
||||
public interface IMirrorDownloader
|
||||
{
|
||||
public PatchInfoMirror MirrorInfo { get; }
|
||||
public DownloadMirror MirrorInfo { get; }
|
||||
public Task<FileInfo?> Download(IProgress<double> progress);
|
||||
}
|
||||
|
@ -1,4 +1,6 @@
|
||||
using ReactiveUI;
|
||||
using Gitea.Api;
|
||||
using Gitea.Client;
|
||||
using ReactiveUI;
|
||||
using Serilog;
|
||||
using SPTInstaller.Helpers;
|
||||
using System.Diagnostics;
|
||||
@ -115,57 +117,57 @@ public class InstallerUpdateInfo : ReactiveObject
|
||||
UpdateAvailable = updateAvailable;
|
||||
}
|
||||
|
||||
// public async Task CheckForUpdates(Version? currentVersion)
|
||||
// {
|
||||
// if (currentVersion == null)
|
||||
// return;
|
||||
//
|
||||
// UpdateInfoText = "Checking for installer updates";
|
||||
// Show = true;
|
||||
// CheckingForUpdates = true;
|
||||
//
|
||||
// try
|
||||
// {
|
||||
// var repo = new RepositoryApi(Configuration.Default);
|
||||
//
|
||||
// var releases = await repo.RepoListReleasesAsync("CWX", "SPT-AKI-Installer");
|
||||
//
|
||||
// if (releases == null || releases.Count == 0)
|
||||
// {
|
||||
// EndCheck("No releases available", false);
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// var latest = releases.FindAll(x => !x.Prerelease)[0];
|
||||
//
|
||||
// if (latest == null)
|
||||
// {
|
||||
// EndCheck("could not get latest release", false);
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// var latestVersion = new Version(latest.TagName);
|
||||
//
|
||||
// if (latestVersion == null || latestVersion <= currentVersion)
|
||||
// {
|
||||
// EndCheck("No updates available", false);
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// _newVersion = latestVersion;
|
||||
//
|
||||
// NewInstallerUrl = latest.Assets[0].BrowserDownloadUrl;
|
||||
//
|
||||
// EndCheck($"Update available: v{latestVersion}", true);
|
||||
//
|
||||
// return;
|
||||
// }
|
||||
// catch (Exception ex)
|
||||
// {
|
||||
// EndCheck(ex.Message, false, false);
|
||||
// Log.Error(ex, "Failed to check for updates");
|
||||
// }
|
||||
//
|
||||
// return;
|
||||
// }
|
||||
public async Task CheckForUpdates(Version? currentVersion)
|
||||
{
|
||||
if (currentVersion == null)
|
||||
return;
|
||||
|
||||
UpdateInfoText = "Checking for installer updates";
|
||||
Show = true;
|
||||
CheckingForUpdates = true;
|
||||
|
||||
try
|
||||
{
|
||||
var repo = new RepositoryApi(Configuration.Default);
|
||||
|
||||
var releases = await repo.RepoListReleasesAsync("CWX", "SPT-AKI-Installer");
|
||||
|
||||
if (releases == null || releases.Count == 0)
|
||||
{
|
||||
EndCheck("No releases available", false);
|
||||
return;
|
||||
}
|
||||
|
||||
var latest = releases.FindAll(x => !x.Prerelease)[0];
|
||||
|
||||
if (latest == null)
|
||||
{
|
||||
EndCheck("could not get latest release", false);
|
||||
return;
|
||||
}
|
||||
|
||||
var latestVersion = new Version(latest.TagName);
|
||||
|
||||
if (latestVersion == null || latestVersion <= currentVersion)
|
||||
{
|
||||
EndCheck("No updates available", false);
|
||||
return;
|
||||
}
|
||||
|
||||
_newVersion = latestVersion;
|
||||
|
||||
NewInstallerUrl = latest.Assets[0].BrowserDownloadUrl;
|
||||
|
||||
EndCheck($"Update available: v{latestVersion}", true);
|
||||
|
||||
return;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
EndCheck(ex.Message, false, false);
|
||||
Log.Error(ex, "Failed to check for updates");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
using SPTInstaller.Models.Mirrors;
|
||||
using SPTInstaller.Models.ReleaseInfo;
|
||||
using SPTInstaller.Models.Releases;
|
||||
|
||||
namespace SPTInstaller.Models;
|
||||
|
||||
@ -33,14 +32,12 @@ public class InternalData
|
||||
/// <summary>
|
||||
/// The release information from release.json
|
||||
/// </summary>
|
||||
public ReleaseInfo.ReleaseInfo ReleaseInfo { get; set; }
|
||||
|
||||
public PatchInfo PatchInfo { get; set; }
|
||||
public ReleaseInfo ReleaseInfo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The release download link for the patcher mirror list
|
||||
/// </summary>
|
||||
// public string PatcherMirrorsLink { get; set; }
|
||||
public string PatcherMirrorsLink { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not a patch is needed to downgrade the client files
|
||||
|
@ -1,6 +1,6 @@
|
||||
namespace SPTInstaller.Models.Mirrors;
|
||||
|
||||
public class PatchInfoMirror
|
||||
public class DownloadMirror
|
||||
{
|
||||
public string Link { get; set; }
|
||||
public string Hash { get; set; }
|
@ -4,7 +4,7 @@ using System.Threading.Tasks;
|
||||
namespace SPTInstaller.Models.Mirrors.Downloaders;
|
||||
public class HttpMirrorDownloader : MirrorDownloaderBase
|
||||
{
|
||||
public HttpMirrorDownloader(PatchInfoMirror mirror) : base(mirror)
|
||||
public HttpMirrorDownloader(DownloadMirror mirror) : base(mirror)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,7 @@ using Serilog;
|
||||
namespace SPTInstaller.Models.Mirrors.Downloaders;
|
||||
public class MegaMirrorDownloader : MirrorDownloaderBase
|
||||
{
|
||||
public MegaMirrorDownloader(PatchInfoMirror mirrorInfo) : base(mirrorInfo)
|
||||
public MegaMirrorDownloader(DownloadMirror mirrorInfo) : base(mirrorInfo)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -4,9 +4,9 @@ using System.Threading.Tasks;
|
||||
namespace SPTInstaller.Models.Mirrors.Downloaders;
|
||||
public abstract class MirrorDownloaderBase : IMirrorDownloader
|
||||
{
|
||||
public PatchInfoMirror MirrorInfo { get; private set; }
|
||||
public DownloadMirror MirrorInfo { get; private set; }
|
||||
public abstract Task<FileInfo?> Download(IProgress<double> progress);
|
||||
public MirrorDownloaderBase(PatchInfoMirror mirrorInfo)
|
||||
public MirrorDownloaderBase(DownloadMirror mirrorInfo)
|
||||
{
|
||||
MirrorInfo = mirrorInfo;
|
||||
}
|
||||
|
@ -1,10 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace SPTInstaller.Models.Mirrors;
|
||||
|
||||
public class PatchInfo
|
||||
{
|
||||
public int SourceClientVersion { get; set; }
|
||||
public int TargetClientVersion { get; set; }
|
||||
public List<PatchInfoMirror> Mirrors { get; set; }
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace SPTInstaller.Models.ReleaseInfo;
|
||||
public class ReleaseInfo
|
||||
{
|
||||
public string AkiVersion { get; set; }
|
||||
public string ClientVersion { get; set; }
|
||||
public List<ReleaseInfoMirror> Mirrors { get; set; }
|
||||
}
|
||||
|
@ -1,6 +0,0 @@
|
||||
namespace SPTInstaller.Models.ReleaseInfo;
|
||||
public class ReleaseInfoMirror
|
||||
{
|
||||
public string DownloadUrl { get; set; }
|
||||
public string Hash { get; set; }
|
||||
}
|
@ -9,8 +9,8 @@
|
||||
<PackageIcon>icon.ico</PackageIcon>
|
||||
<ApplicationIcon>Assets\icon.ico</ApplicationIcon>
|
||||
<Configurations>Debug;Release;TEST</Configurations>
|
||||
<AssemblyVersion>2.61</AssemblyVersion>
|
||||
<FileVersion>2.61</FileVersion>
|
||||
<AssemblyVersion>2.59</AssemblyVersion>
|
||||
<FileVersion>2.59</FileVersion>
|
||||
<Company>SPT-AKI</Company>
|
||||
</PropertyGroup>
|
||||
|
||||
@ -47,4 +47,10 @@
|
||||
<PackageReference Include="Squid-Box.SevenZipSharp" Version="1.6.1.23" />
|
||||
<PackageReference Include="System.Reactive" Version="6.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="Gitea">
|
||||
<HintPath>Z:\dev_stuff\EftPatchHelper\EftPatchHelper\EftPatchHelper\Resources\Gitea.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
@ -1,4 +1,5 @@
|
||||
using Avalonia;
|
||||
using Gitea.Client;
|
||||
using ReactiveUI;
|
||||
using Serilog;
|
||||
using System.Globalization;
|
||||
@ -20,6 +21,8 @@ public class MainWindowViewModel : ReactiveObject, IActivatableViewModel, IScree
|
||||
|
||||
public MainWindowViewModel(bool debugging)
|
||||
{
|
||||
Configuration.Default.BasePath = "https://dev.sp-tarkov.com/api/v1";
|
||||
|
||||
Title = $"{(debugging ? "-debug-" : "")} SPT Installer {"v" + Assembly.GetExecutingAssembly().GetName()?.Version?.ToString() ?? "--unknown version--"}";
|
||||
|
||||
Log.Information($"========= {Title} Started =========");
|
||||
|
@ -5,7 +5,8 @@ using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
using Avalonia.Threading;
|
||||
using DialogHostAvalonia;
|
||||
using Newtonsoft.Json;
|
||||
using Gitea.Api;
|
||||
using Gitea.Client;
|
||||
using ReactiveUI;
|
||||
using Serilog;
|
||||
using SPTInstaller.Controllers;
|
||||
@ -13,7 +14,6 @@ using SPTInstaller.CustomControls;
|
||||
using SPTInstaller.CustomControls.Dialogs;
|
||||
using SPTInstaller.Helpers;
|
||||
using SPTInstaller.Models;
|
||||
using SPTInstaller.Models.ReleaseInfo;
|
||||
|
||||
namespace SPTInstaller.ViewModels;
|
||||
|
||||
@ -262,30 +262,32 @@ public class PreChecksViewModel : ViewModelBase
|
||||
var result = await installer.RunPreChecks();
|
||||
|
||||
// check for updates
|
||||
//await UpdateInfo.CheckForUpdates(Assembly.GetExecutingAssembly().GetName()?.Version);
|
||||
await UpdateInfo.CheckForUpdates(Assembly.GetExecutingAssembly().GetName()?.Version);
|
||||
|
||||
// get latest spt version
|
||||
InstallButtonText = "Getting latest release ...";
|
||||
InstallButtonCheckState = StatusSpinner.SpinnerState.Running;
|
||||
|
||||
var progress = new Progress<double>((d) => { });
|
||||
var akiReleaseInfoFile = await DownloadCacheHelper.DownloadFileAsync("release.json", DownloadCacheHelper.ReleaseMirrorUrl, progress);
|
||||
if (akiReleaseInfoFile == null)
|
||||
var repo = new RepositoryApi(Configuration.Default);
|
||||
var akiRepoReleases = await repo.RepoListReleasesAsync("SPT-AKI", "Stable-releases");
|
||||
|
||||
if (akiRepoReleases == null || akiRepoReleases.Count == 0)
|
||||
{
|
||||
InstallButtonText = "Could not get SPT release metadata";
|
||||
InstallButtonText = "Could not get SPT releases from repo";
|
||||
InstallButtonCheckState = StatusSpinner.SpinnerState.Error;
|
||||
return;
|
||||
}
|
||||
|
||||
var akiReleaseInfo = JsonConvert.DeserializeObject<ReleaseInfo>(File.ReadAllText(akiReleaseInfoFile.FullName));
|
||||
if (akiReleaseInfo == null)
|
||||
var latestAkiRelease = akiRepoReleases.FindAll(x => !x.Prerelease)[0];
|
||||
|
||||
if (latestAkiRelease == null)
|
||||
{
|
||||
InstallButtonText = "Could not parse latest SPT release";
|
||||
InstallButtonText = "Could not find the latest SPT release";
|
||||
InstallButtonCheckState = StatusSpinner.SpinnerState.Error;
|
||||
return;
|
||||
}
|
||||
|
||||
InstallButtonText = $"Start Install: SPT v{akiReleaseInfo.AkiVersion}";
|
||||
InstallButtonText = $"Start Install: SPT v{latestAkiRelease.TagName}";
|
||||
InstallButtonCheckState = StatusSpinner.SpinnerState.OK;
|
||||
|
||||
AllowDetailsButton = true;
|
||||
|
Loading…
x
Reference in New Issue
Block a user