Skip to content

Commit

Permalink
Minor UI changes.
Browse files Browse the repository at this point in the history
  • Loading branch information
Aetopia committed Jul 25, 2024
1 parent ec187ee commit d1aa862
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 40 deletions.
2 changes: 1 addition & 1 deletion src/BedrockUpdater.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<ApplicationManifest>Resources/.manifest</ApplicationManifest>
<ApplicationIcon>Resources/.ico</ApplicationIcon>

<AssemblyVersion>1.1.7.4</AssemblyVersion>
<AssemblyVersion>1.1.8.0</AssemblyVersion>
<AssemblyTitle>Bedrock Updater</AssemblyTitle>
<Product>Bedrock Updater</Product>
<Copyright>Copyright (C) 2024</Copyright>
Expand Down
16 changes: 10 additions & 6 deletions src/MainWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ internal MainWindow(bool preview)
{
UseLayoutRounding = true;
Icon = global::Resources.GetImageSource(".ico");
Title = preview ? "Bedrock Updater Preview" : "Bedrock Updater";
Title = $"Bedrock Updater ({(preview ? "Preview" : "Release")})";
Background = new SolidColorBrush(Color.FromRgb(30, 30, 30));
WindowStartupLocation = WindowStartupLocation.CenterScreen;
ResizeMode = ResizeMode.NoResize;
Expand All @@ -35,7 +35,11 @@ internal MainWindow(bool preview)

WindowsFormsHost host = new()
{
Child = new System.Windows.Forms.WebBrowser { ScrollBarsEnabled = false, DocumentText = global::Resources.GetString("Document.html.gz") },
Child = new System.Windows.Forms.WebBrowser
{
ScrollBarsEnabled = false,
DocumentText = global::Resources.GetString("Document.html.gz")
},
IsEnabled = false
};
Grid.SetRow(host, 0);
Expand All @@ -59,7 +63,7 @@ internal MainWindow(bool preview)

TextBlock textBlock1 = new()
{
Text = "Connecting...",
Text = "Preparing...",
VerticalAlignment = VerticalAlignment.Center,
HorizontalAlignment = HorizontalAlignment.Left,
Margin = new(16, 0, 0, 1),
Expand Down Expand Up @@ -119,7 +123,7 @@ internal MainWindow(bool preview)
Dispatcher.Invoke(() =>
{
progressBar.IsIndeterminate = true;
textBlock1.Text = $"Updating {product.Title}...";
textBlock1.Text = $"Preparing {product.Title}...";
textBlock2.Text = default;
});
var updates = Store.GetUpdates(product);
Expand All @@ -130,15 +134,15 @@ internal MainWindow(bool preview)
Dispatcher.Invoke(() =>
{
textBlock1.Text = "Downloading...";
textBlock2.Text = $"{i + 1} of {updates.Count}";
textBlock2.Text = updates.Count != 1 ? $"{i + 1} / {updates.Count}" : null;
progressBar.Value = 0;
});

try
{
client.DownloadFileTaskAsync(Store.GetUrl(updates[i]), (packageUri = new(Path.GetTempFileName())).AbsolutePath).Wait();
operation = Store.PackageManager.AddPackageAsync(packageUri, null, DeploymentOptions.ForceApplicationShutdown);
operation.Progress += (sender, e) => Dispatcher.Invoke(() => { if (progressBar.Value != e.percentage) textBlock1.Text = $"Installing {progressBar.Value = e.percentage}%"; });
operation.Progress += (sender, e) => Dispatcher.Invoke(() => { if (progressBar.Value != e.percentage) progressBar.Value = e.percentage; });
operation.AsTask().Wait();
}
finally { NativeMethods.DeleteFile(packageUri.AbsolutePath); }
Expand Down
77 changes: 44 additions & 33 deletions src/Store.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,25 +54,33 @@ static class Store

static readonly WebClient client = new() { BaseAddress = "https://fe3.delivery.mp.microsoft.com/ClientWebService/client.asmx/" };

static readonly ((string Native, string Compatible) OS, (ProcessorArchitecture Native, ProcessorArchitecture Compatible) Processor) architectures = (
(RuntimeInformation.OSArchitecture.ToString().ToLowerInvariant(), RuntimeInformation.OSArchitecture switch { Architecture.X64 => "x86", Architecture.Arm64 => "arm", _ => null }),
(RuntimeInformation.OSArchitecture switch
{
Architecture.X86 => ProcessorArchitecture.X86,
Architecture.X64 => ProcessorArchitecture.X64,
Architecture.Arm => ProcessorArchitecture.Arm,
Architecture.Arm64 => ProcessorArchitecture.Arm64,
_ => ProcessorArchitecture.Unknown
},
RuntimeInformation.OSArchitecture switch
{
Architecture.X64 => ProcessorArchitecture.X86,
Architecture.Arm64 => ProcessorArchitecture.Arm,
_ => ProcessorArchitecture.Unknown
})
static readonly (
(string String, ProcessorArchitecture Architecture) Native,
(string String, ProcessorArchitecture Architecture) Compatible
) architectures = (
(
RuntimeInformation.OSArchitecture.ToString().ToLowerInvariant(),
RuntimeInformation.OSArchitecture switch
{
Architecture.X86 => ProcessorArchitecture.X86,
Architecture.X64 => ProcessorArchitecture.X64,
Architecture.Arm => ProcessorArchitecture.Arm,
Architecture.Arm64 => ProcessorArchitecture.Arm64,
_ => ProcessorArchitecture.Unknown
}
),
(
RuntimeInformation.OSArchitecture switch { Architecture.X64 => "x86", Architecture.Arm64 => "arm", _ => null },
RuntimeInformation.OSArchitecture switch
{
Architecture.X64 => ProcessorArchitecture.X86,
Architecture.Arm64 => ProcessorArchitecture.Arm,
_ => ProcessorArchitecture.Unknown
}
)
);

internal static IEnumerable<Product> GetProducts(params string[] productIds)
internal static Product[] GetProducts(params string[] productIds)
{
var products = new Product[productIds.Length];

Expand All @@ -86,29 +94,27 @@ internal static IEnumerable<Product> GetProducts(params string[] productIds)
{
Title = string.IsNullOrEmpty(title) ? payload["Title"].InnerText : title,
AppCategoryId = Deserialize(payload.GetElementsByTagName("FulfillmentData")[0].InnerText)["WuCategoryId"].InnerText,
Architecture = (enumerable.FirstOrDefault(item => item.Equals(architectures.OS.Native, StringComparison.OrdinalIgnoreCase)) ??
enumerable.FirstOrDefault(item => item.Equals(architectures.OS.Compatible, StringComparison.OrdinalIgnoreCase)))?.ToLowerInvariant()
Architecture = (enumerable.FirstOrDefault(item => item.Equals(architectures.Native.String, StringComparison.OrdinalIgnoreCase)) ??
enumerable.FirstOrDefault(item => item.Equals(architectures.Compatible.String, StringComparison.OrdinalIgnoreCase)))?.ToLowerInvariant()
};
}

return products;
}

internal static string GetUrl(UpdateIdentity update)
{
return UploadString(string.Format(Resources.GetExtendedUpdateInfo2, update.UpdateID, update.RevisionNumber), true)
.GetElementsByTagName("Url")
.Cast<XmlNode>()
.First(node => node.InnerText.StartsWith("http://tlu.dl.delivery.mp.microsoft.com", StringComparison.Ordinal)).InnerText;
}
internal static string GetUrl(UpdateIdentity update) =>
UploadString(string.Format(Resources.GetExtendedUpdateInfo2, update.UpdateID, update.RevisionNumber), true)
.GetElementsByTagName("Url")
.Cast<XmlNode>()
.First(node => node.InnerText.StartsWith("http://tlu.dl.delivery.mp.microsoft.com", StringComparison.Ordinal)).InnerText;

internal static IList<UpdateIdentity> GetUpdates(Product product)
internal static List<UpdateIdentity> GetUpdates(Product product)
{
if (product.Architecture is null) return [];
var result = (XmlElement)UploadString(
string.Format(
data ??= string.Format(Resources.GetString("SyncUpdates.xml.gz"), UploadString(Resources.GetString("GetCookie.xml.gz")).GetElementsByTagName("EncryptedData")[0].InnerText, "{0}"),
product.AppCategoryId))
product.AppCategoryId), false)
.GetElementsByTagName("SyncUpdatesResult")[0];

ProcessorArchitecture architecture;
Expand All @@ -121,7 +127,7 @@ internal static IList<UpdateIdentity> GetUpdates(Product product)

var identity = file.Attributes["InstallerSpecificIdentifier"].InnerText.Split('_');
var neutral = identity[2] == "neutral";
if (!neutral && identity[2] != architectures.OS.Native && identity[2] != architectures.OS.Compatible) continue;
if (!neutral && identity[2] != architectures.Native.String && identity[2] != architectures.Compatible.String) continue;
architecture = (neutral ? product.Architecture : identity[2]) switch
{
"x86" => ProcessorArchitecture.X86,
Expand Down Expand Up @@ -149,7 +155,10 @@ internal static IList<UpdateIdentity> GetUpdates(Product product)
}

var values = dictionary.Where(item => item.Value.MainPackage).Select(item => item.Value);
architecture = (values.FirstOrDefault(value => value.Architecture == architectures.Processor.Native) ?? values.FirstOrDefault(value => value.Architecture == architectures.Processor.Compatible)).Architecture;
architecture = (
values.FirstOrDefault(value => value.Architecture == architectures.Native.Architecture)
?? values.FirstOrDefault(value => value.Architecture == architectures.Compatible.Architecture)
).Architecture;
var items = dictionary.Select(item => item.Value).Where(item => item.Architecture == architecture);

List<UpdateIdentity> updates = [];
Expand Down Expand Up @@ -182,17 +191,19 @@ internal static IList<UpdateIdentity> GetUpdates(Product product)

static XmlElement Deserialize(string input)
{
using var reader = JsonReaderWriterFactory.CreateJsonReader(Encoding.UTF8.GetBytes(input), XmlDictionaryReaderQuotas.Max);
using var reader = JsonReaderWriterFactory.CreateJsonReader(Encoding.Unicode.GetBytes(input), XmlDictionaryReaderQuotas.Max);
XmlDocument document = new();
document.Load(reader);
return document["root"];
}

static XmlDocument UploadString(string data, bool secured = false)
static XmlDocument UploadString(string data, bool? _ = null)
{
client.Headers["Content-Type"] = "application/soap+xml";
var value = client.UploadString(_.HasValue && _.Value ? "secured" : string.Empty, data);

XmlDocument document = new();
document.LoadXml(client.UploadString(secured ? "secured" : string.Empty, data).Replace("&lt;", "<").Replace("&gt;", ">"));
document.LoadXml(_.HasValue && !_.Value ? WebUtility.HtmlDecode(value) : value);
return document;
}
}

0 comments on commit d1aa862

Please sign in to comment.