Commit 228ee37b authored by Archnoc's avatar Archnoc

refactor

parent 6d4e79e7
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks;
namespace sunrise_launcher namespace sunrise_launcher
{ {
public interface IManifest public interface IManifest
{ {
public ManifestMetadata GetMetadata(); public Task<ManifestMetadata> GetMetadataAsync();
public IEnumerable<ManifestFile> GetFiles(); public Task<IList<ManifestFile>> GetFilesAsync();
public int Count();
} }
} }
...@@ -6,12 +6,18 @@ using System.Text.Json.Serialization; ...@@ -6,12 +6,18 @@ using System.Text.Json.Serialization;
namespace sunrise_launcher namespace sunrise_launcher
{ {
public class Manifest : ManifestMetadata
{
[JsonPropertyName("files")]
public List<ManifestFile> Files { get; set; }
}
public class ManifestMetadata public class ManifestMetadata
{ {
[JsonPropertyName("title")] [JsonPropertyName("title")]
public string Title { get; set; } public string Title { get; set; }
[JsonPropertyName("hash")] [JsonPropertyName("version")]
public string Hash { get; set; } public string Version { get; set; }
[JsonPropertyName("launch_path")] [JsonPropertyName("launch_path")]
public string LaunchPath { get; set; } public string LaunchPath { get; set; }
[JsonPropertyName("launch_env")] [JsonPropertyName("launch_env")]
......
...@@ -4,7 +4,7 @@ namespace sunrise_launcher ...@@ -4,7 +4,7 @@ namespace sunrise_launcher
{ {
public interface IManifestFactory public interface IManifestFactory
{ {
public Task<IManifest> Get(Server server); public IManifest Get(Server server);
} }
public class ManifestFactory : IManifestFactory public class ManifestFactory : IManifestFactory
...@@ -12,15 +12,15 @@ namespace sunrise_launcher ...@@ -12,15 +12,15 @@ namespace sunrise_launcher
const string manifiesta_v1 = "manifiesta-v1"; const string manifiesta_v1 = "manifiesta-v1";
const string tequila_xml = "tequila-xml"; const string tequila_xml = "tequila-xml";
public async Task<IManifest> Get(Server server) public IManifest Get(Server server)
{ {
var schema = getSchema(server.ManifestURL); var schema = getSchema(server.ManifestURL);
switch (schema) switch (schema)
{ {
case manifiesta_v1: case manifiesta_v1:
return await Manifiesta.Get(server); return new Manifiesta(server.ManifestURL);
case tequila_xml: case tequila_xml:
return await TequilaXML.Get(server); return new TequilaXML(server.ManifestURL);
} }
return null; return null;
} }
...@@ -30,7 +30,7 @@ namespace sunrise_launcher ...@@ -30,7 +30,7 @@ namespace sunrise_launcher
if (manifesturl.ToLower().EndsWith(".xml")) if (manifesturl.ToLower().EndsWith(".xml"))
return tequila_xml; return tequila_xml;
else else
return manifiesta_v1; //todo; call endpoint for actual schema return manifiesta_v1;
} }
} }
} }
...@@ -8,41 +8,48 @@ using System.Threading.Tasks; ...@@ -8,41 +8,48 @@ using System.Threading.Tasks;
namespace sunrise_launcher namespace sunrise_launcher
{ {
public class Manifiesta : ManifestMetadata, IManifest public class Manifiesta : IManifest
{ {
[JsonPropertyName("files")] private static HttpClient client = new HttpClient();
public List<ManifestFile> Files { get; set; } private string URL;
public IEnumerable<ManifestFile> GetFiles()
{
return Files;
}
public int Count() public Manifiesta(string url)
{ {
return Files.Count; URL = url;
} }
public ManifestMetadata GetMetadata() public async Task<ManifestMetadata> GetMetadataAsync()
{ {
return this; try
{
var response = await client.GetAsync(URL + "/metadata");
if (response.IsSuccessStatusCode)
{
using (var reader = await response.Content.ReadAsStreamAsync())
{
var manifest = await JsonSerializer.DeserializeAsync<ManifestMetadata>(reader);
return manifest;
}
}
}
catch (Exception ex)
{
Console.WriteLine("exception while retrieving manifest: {0}", ex.Message);
}
return null;
} }
private static HttpClient client = new HttpClient(); public async Task<IList<ManifestFile>> GetFilesAsync()
public static async Task<Manifiesta> Get(Server server)
{ {
try try
{ {
var response = await client.GetAsync(server.ManifestURL); var response = await client.GetAsync(URL);
if (response.IsSuccessStatusCode) if (response.IsSuccessStatusCode)
{ {
var hash = SHA256.Create();
using (var reader = await response.Content.ReadAsStreamAsync()) using (var reader = await response.Content.ReadAsStreamAsync())
using (var hashstream = new CryptoStream(reader, hash, CryptoStreamMode.Read))
{ {
var manifest = await JsonSerializer.DeserializeAsync<Manifiesta>(hashstream); var manifest = await JsonSerializer.DeserializeAsync<Manifest>(reader);
manifest.Hash = Hashing.ByteArrayToHex(hash.Hash); return manifest.Files;
return manifest;
} }
} }
} }
......
...@@ -170,8 +170,17 @@ namespace sunrise_launcher ...@@ -170,8 +170,17 @@ namespace sunrise_launcher
try try
{ {
var manifest = await manifestFactory.Get(server); var manifest = manifestFactory.Get(server);
if (manifest == null) if (manifest == null)
{
Console.WriteLine("Unknown manifest schema at '{0}'", server.ManifestURL);
server.State = State.Error;
server.Error = "Unknown manifest schema";
return;
}
var metadata = await manifest.GetMetadataAsync();
if (metadata == null)
{ {
Console.WriteLine("Could not retrieve manifest from '{0}'", server.ManifestURL); Console.WriteLine("Could not retrieve manifest from '{0}'", server.ManifestURL);
server.State = State.Error; server.State = State.Error;
...@@ -179,7 +188,6 @@ namespace sunrise_launcher ...@@ -179,7 +188,6 @@ namespace sunrise_launcher
return; return;
} }
var metadata = manifest.GetMetadata();
if (!metadata.Verify()) if (!metadata.Verify())
{ {
Console.WriteLine("Manifest metadata failed inspection '{0}'", server.ManifestURL); Console.WriteLine("Manifest metadata failed inspection '{0}'", server.ManifestURL);
...@@ -211,8 +219,18 @@ namespace sunrise_launcher ...@@ -211,8 +219,18 @@ namespace sunrise_launcher
try try
{ {
UpdateProgress(server, "Retrieving Manfiest", 0, 0); UpdateProgress(server, "Retrieving Manfiest", 0, 0);
var manifest = await manifestFactory.Get(server);
var manifest = manifestFactory.Get(server);
if (manifest == null) if (manifest == null)
{
Console.WriteLine("Unknown manifest schema at '{0}'", server.ManifestURL);
server.State = State.Ready;
server.Error = "Unknown manifest schema. You may still attempt to play, but you may be missing updates.";
return;
}
var metadata = await manifest.GetMetadataAsync();
if (metadata == null)
{ {
Console.WriteLine("Could not retrieve manifest from '{0}'", server.ManifestURL); Console.WriteLine("Could not retrieve manifest from '{0}'", server.ManifestURL);
server.State = State.Ready; server.State = State.Ready;
...@@ -220,7 +238,6 @@ namespace sunrise_launcher ...@@ -220,7 +238,6 @@ namespace sunrise_launcher
return; return;
} }
var metadata = manifest.GetMetadata();
if (!metadata.Verify()) if (!metadata.Verify())
{ {
Console.WriteLine("Manifest metadata failed inspection '{0}'", server.ManifestURL); Console.WriteLine("Manifest metadata failed inspection '{0}'", server.ManifestURL);
...@@ -229,7 +246,7 @@ namespace sunrise_launcher ...@@ -229,7 +246,7 @@ namespace sunrise_launcher
return; return;
} }
if (force || metadata.Hash != server.Hash) if (force || metadata.Version != server.Version)
{ {
await updatefiles(server, manifest, server.InstallPath); await updatefiles(server, manifest, server.InstallPath);
} }
...@@ -241,7 +258,7 @@ namespace sunrise_launcher ...@@ -241,7 +258,7 @@ namespace sunrise_launcher
if (server.State == State.Ready) if (server.State == State.Ready)
{ {
server.Title = metadata.Title; server.Title = metadata.Title;
server.Hash = metadata.Hash; server.Version = metadata.Version;
server.LaunchPath = metadata.LaunchPath; server.LaunchPath = metadata.LaunchPath;
server.LaunchEnv = metadata.LaunchEnv; server.LaunchEnv = metadata.LaunchEnv;
server.LaunchArgs = metadata.LaunchArgs; server.LaunchArgs = metadata.LaunchArgs;
...@@ -308,9 +325,17 @@ namespace sunrise_launcher ...@@ -308,9 +325,17 @@ namespace sunrise_launcher
try try
{ {
var i = 0; var i = 0;
foreach (var file in manifest.GetFiles()) var files = await manifest.GetFilesAsync();
if (files == null)
{
server.State = State.Error;
server.Error = "Could not retrieve files from manifest.";
return;
}
foreach (var file in files)
{ {
UpdateProgress(server, "verifying " + file.Path, i++, manifest.Count()); UpdateProgress(server, "verifying " + file.Path, i++, files.Count);
if (!file.Verify()) if (!file.Verify())
{ {
......
...@@ -7,37 +7,38 @@ using System.Xml.Serialization; ...@@ -7,37 +7,38 @@ using System.Xml.Serialization;
namespace sunrise_launcher namespace sunrise_launcher
{ {
[XmlRoot("manifest")]
public class TequilaXML : IManifest public class TequilaXML : IManifest
{ {
[XmlElement("label")] private static HttpClient client = new HttpClient();
public string Label { get; set; }
[XmlArray("profiles")]
[XmlArrayItem("launch")]
public List<TequilaProfile> Profiles { get; set; }
[XmlArray("filelist")]
[XmlArrayItem("file")]
public List<TequilaFile> FileList { get; set; }
[XmlIgnore] private TequilaRoot TequilaRoot;
public string Hash { get; set; }
private static HttpClient client = new HttpClient(); private string Hash;
public static async Task<TequilaXML> Get(Server server)
private string URL;
public TequilaXML(string url)
{ {
URL = url;
}
private async Task FetchManifest()
{
if (TequilaRoot != null)
return;
try try
{ {
var serializer = new XmlSerializer(typeof(TequilaXML)); var serializer = new XmlSerializer(typeof(TequilaRoot));
var response = await client.GetAsync(server.ManifestURL); var response = await client.GetAsync(URL);
if (response.IsSuccessStatusCode) if (response.IsSuccessStatusCode)
{ {
var hash = SHA256.Create(); var hash = SHA256.Create();
using (var reader = await response.Content.ReadAsStreamAsync()) using (var reader = await response.Content.ReadAsStreamAsync())
using (var hashstream = new CryptoStream(reader, hash, CryptoStreamMode.Read)) using (var hashstream = new CryptoStream(reader, hash, CryptoStreamMode.Read))
{ {
var manifest = (TequilaXML)serializer.Deserialize(hashstream); TequilaRoot = (TequilaRoot)serializer.Deserialize(hashstream);
manifest.Hash = Hashing.ByteArrayToHex(hash.Hash); Hash = Hashing.ByteArrayToHex(hash.Hash);
return manifest;
} }
} }
} }
...@@ -45,33 +46,40 @@ namespace sunrise_launcher ...@@ -45,33 +46,40 @@ namespace sunrise_launcher
{ {
Console.WriteLine("exception while retrieving manifest: {0}", ex.Message); Console.WriteLine("exception while retrieving manifest: {0}", ex.Message);
} }
return null;
} }
public ManifestMetadata GetMetadata() public async Task<ManifestMetadata> GetMetadataAsync()
{ {
if (Profiles.Count == 0) await FetchManifest();
if (TequilaRoot == null)
return null;
if (TequilaRoot.Profiles.Count == 0)
return null; return null;
var metadata = new ManifestMetadata(); var metadata = new ManifestMetadata();
metadata.Hash = Hash; metadata.Version = Hash;
metadata.Title = Profiles[0].Value; metadata.Title = TequilaRoot.Profiles[0].Value;
metadata.LaunchPath = Profiles[0].Exec; metadata.LaunchPath = TequilaRoot.Profiles[0].Exec;
metadata.LaunchArgs = Profiles[0].Params; metadata.LaunchArgs = TequilaRoot.Profiles[0].Params;
return metadata; return metadata;
} }
public IEnumerable<ManifestFile> GetFiles() public async Task<IList<ManifestFile>> GetFilesAsync()
{ {
await FetchManifest();
if (TequilaRoot == null)
return null;
var files = new List<ManifestFile>(); var files = new List<ManifestFile>();
foreach(var tequilaFile in FileList) foreach (var tequilaFile in TequilaRoot.FileList)
{ {
var file = new ManifestFile(); var file = new ManifestFile();
file.MD5 = tequilaFile.MD5.ToLower(); file.MD5 = tequilaFile.MD5.ToLower();
file.Path = tequilaFile.Name; file.Path = tequilaFile.Name;
file.Size = tequilaFile.Size; file.Size = tequilaFile.Size;
file.Sources = new List<FileSource>(); file.Sources = new List<FileSource>();
foreach(var url in tequilaFile.URL) foreach (var url in tequilaFile.URL)
{ {
var source = new FileSource(); var source = new FileSource();
source.URL = url; source.URL = url;
...@@ -81,11 +89,19 @@ namespace sunrise_launcher ...@@ -81,11 +89,19 @@ namespace sunrise_launcher
} }
return files; return files;
} }
}
public int Count() [XmlRoot("manifest")]
{ public class TequilaRoot
return FileList.Count; {
} [XmlElement("label")]
public string Label { get; set; }
[XmlArray("profiles")]
[XmlArrayItem("launch")]
public List<TequilaProfile> Profiles { get; set; }
[XmlArray("filelist")]
[XmlArrayItem("file")]
public List<TequilaFile> FileList { get; set; }
} }
public class TequilaProfile public class TequilaProfile
......
...@@ -405,6 +405,7 @@ ApplicationWindow { ...@@ -405,6 +405,7 @@ ApplicationWindow {
placeholderText: "ex: https://example.com/servername/manifest" placeholderText: "ex: https://example.com/servername/manifest"
id: textfield_manifesturl id: textfield_manifesturl
Layout.fillWidth: true Layout.fillWidth: true
selectByMouse: true
} }
Text { Text {
...@@ -417,6 +418,7 @@ ApplicationWindow { ...@@ -417,6 +418,7 @@ ApplicationWindow {
font.family: fontMont.name font.family: fontMont.name
id: textfield_installpath id: textfield_installpath
Layout.fillWidth: true Layout.fillWidth: true
selectByMouse: true
} }
} }
} }
......
...@@ -17,6 +17,16 @@ ...@@ -17,6 +17,16 @@
<AssemblyOriginatorKeyFile>sunrise-launcher.pfx</AssemblyOriginatorKeyFile> <AssemblyOriginatorKeyFile>sunrise-launcher.pfx</AssemblyOriginatorKeyFile>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<None Remove="sunrise.ico" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="sunrise.ico">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</EmbeddedResource>
</ItemGroup>
<ItemGroup> <ItemGroup>
<TrimmerRootAssembly Include="System.Text.Json" /> <TrimmerRootAssembly Include="System.Text.Json" />
</ItemGroup> </ItemGroup>
...@@ -28,10 +38,10 @@ ...@@ -28,10 +38,10 @@
<ItemGroup> <ItemGroup>
<None Update="main.js"> <None Update="main.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
<None Update="main.qml"> <None Update="main.qml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
<None Update="skins\herocity\fonts\FontsFree-Net-mont.ttf"> <None Update="skins\herocity\fonts\FontsFree-Net-mont.ttf">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
......
sunrise.ico

16.6 KB | W: | H:

sunrise.ico

51.7 KB | W: | H:

sunrise.ico
sunrise.ico
sunrise.ico
sunrise.ico
  • 2-up
  • Swipe
  • Onion skin
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment