AnotherReplayReader/UpdateChecker.cs

91 lines
3.2 KiB
C#

using AnotherReplayReader.Utils;
using System;
using System.Collections.Immutable;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using System.Windows;
namespace AnotherReplayReader
{
internal class UpdateCheckerVersionData
{
public string NewVersion { get; }
public string Description { get; }
public ImmutableArray<string> Urls { get; }
public UpdateCheckerVersionData(string newVersion,
string description,
ImmutableArray<string> urls)
{
NewVersion = newVersion;
Description = description;
Urls = urls;
}
public bool IsNewVersion() => NewVersion != App.Version;
}
internal class UpdateChecker
{
public const string CheckForUpdatesKey = "checkForUpdates";
public const string CachedDataKey = "cachedUpdateData";
private static readonly ImmutableArray<string> _updateSources = new[]
{
"https://lanyi.altervista.org/playertable/file.json"
}.ToImmutableArray();
public static Task<UpdateCheckerVersionData> CheckForUpdates(Cache cache)
{
var taskSource = new TaskCompletionSource<UpdateCheckerVersionData>();
if (cache.GetOrDefault(CheckForUpdatesKey, false) is not true)
{
return taskSource.Task;
}
foreach (var source in _updateSources)
{
Task.Run(async () =>
{
try
{
var data = await DownloadAndVerify(source).ConfigureAwait(false);
if (data.IsNewVersion())
{
cache.Set(CachedDataKey, data);
taskSource.TrySetResult(data);
}
}
catch (Exception e)
{
Debug.Instance.DebugMessage += $"Update check failed: {e}";
}
});
}
return taskSource.Task;
}
private static async Task<UpdateCheckerVersionData> DownloadAndVerify(string url)
{
var payload = await Network.HttpGetJson<VerifierPayload>(url)
?? throw new InvalidDataException(nameof(VerifierPayload) + " is null");
if (!Verifier.Verify(payload))
{
throw new InvalidDataException(nameof(VerifierPayload) + " cannot be verified");
}
return JsonSerializer.Deserialize<UpdateCheckerVersionData>(payload.ByteData.Value, Network.CommonJsonOptions)
?? throw new InvalidDataException(nameof(UpdateCheckerVersionData) + " is null");
}
public static void Sign()
{
var sample = new UpdateCheckerVersionData(App.Version, "Alice Margatroid", _updateSources);
var sampleText = JsonSerializer.Serialize(sample, Network.CommonJsonOptions);
Verifier.Sign(sampleText);
}
}
}