diff --git a/OwlCore.Wpf/AbstractUI/Themes/AbstractDataListStyle.xaml b/OwlCore.Wpf/AbstractUI/Themes/AbstractDataListStyle.xaml
index 01250bd..b24b881 100644
--- a/OwlCore.Wpf/AbstractUI/Themes/AbstractDataListStyle.xaml
+++ b/OwlCore.Wpf/AbstractUI/Themes/AbstractDataListStyle.xaml
@@ -15,6 +15,7 @@
+
@@ -120,6 +121,11 @@
+
+
+
+
+
@@ -136,9 +142,10 @@
-
+
-
+
@@ -173,7 +180,7 @@
+ Visibility="{Binding Path=Subtitle, TargetNullValue=Collapsed, Mode=OneWay, Converter={StaticResource NotNullOrEmptyToVisibilityConverter}}"/>
diff --git a/ZuneModCore/Mods/WebservicesMod.cs b/ZuneModCore/Mods/WebservicesMod.cs
index 76033ba..4430d4b 100644
--- a/ZuneModCore/Mods/WebservicesMod.cs
+++ b/ZuneModCore/Mods/WebservicesMod.cs
@@ -1,4 +1,5 @@
-using OwlCore.AbstractUI.Models;
+using OwlCore;
+using OwlCore.AbstractUI.Models;
using System;
using System.Collections.Generic;
using System.IO;
@@ -11,6 +12,10 @@ namespace ZuneModCore.Mods
{
private const int ZUNESERVICES_ENDPOINTS_BLOCK_OFFSET = 0x14D60;
private const int ZUNESERVICES_ENDPOINTS_BLOCK_LENGTH = 0x884;
+ private const string WEBSERVICE_ICON_TESTING = "\uE72C";
+ private const string WEBSERVICE_ICON_SUCCESS = "\uE73E";
+ private const string WEBSERVICE_ICON_UNREACHABLE = "\uF384";
+ private const string WEBSERVICE_ICON_UNAVAILABLE = "\uE894";
public override string Id => nameof(WebservicesMod);
@@ -32,13 +37,89 @@ namespace ZuneModCore.Mods
{
Title = "Host",
TooltipText = "The host where the replacement servers are located. Must be the same length as \"zune.net\"."
+ },
+ new AbstractDataList("hostsTest", new List()
+ {
+ GetWebserviceAvailabilityUI("Main website", "www"),
+ GetWebserviceAvailabilityUI("Social website", "social"),
+ GetWebserviceAvailabilityUI("Catalog", "catalog"),
+ GetWebserviceAvailabilityUI("Image catalog", "image.catalog"),
+ GetWebserviceAvailabilityUI("Social", "socialapi"),
+ GetWebserviceAvailabilityUI("Social [Comments]", "comments"),
+ GetWebserviceAvailabilityUI("Social [Inbox]", "inbox"),
+ GetWebserviceAvailabilityUI("Commerce [Sign in]", "commerce"),
+ GetWebserviceAvailabilityUI("Mix", "mix"),
+ GetWebserviceAvailabilityUI("Resources [Firmware]", "resources"),
+ GetWebserviceAvailabilityUI("Statistics", "stats"),
+ }
+ )
+ {
+ Title = "Availability",
+ Subtitle = "Tests availability of each known web service on the new host.",
+ IsUserEditingEnabled = false,
+ PreferredDisplayMode = AbstractDataListPreferredDisplayMode.Grid,
}
}
};
}
+ private static AbstractUIMetadata GetWebserviceAvailabilityUI(string name, string subDomain)
+ {
+ return new("serviceTestUI_" + subDomain)
+ {
+ Title = name,
+ IconCode = WEBSERVICE_ICON_TESTING
+ };
+ }
+
public override IReadOnlyList? DependentMods => null;
+ public override Task Init()
+ {
+ Threading.SetPrimarySynchronizationContext(System.Threading.SynchronizationContext.Current!);
+
+ AbstractTextBox newHostBox = (AbstractTextBox)OptionsUI!.Items[0];
+ System.Net.NetworkInformation.Ping ping = new();
+ async void OnHostChanged(object? sender, string newHost)
+ {
+ ping.SendAsyncCancel();
+ AbstractDataList list = (AbstractDataList)OptionsUI!.Items[1];
+ // Reset all statuses
+ foreach (AbstractUIMetadata metadata in list.Items)
+ metadata.IconCode = WEBSERVICE_ICON_TESTING;
+
+ // Update all statuses
+ foreach (AbstractUIMetadata metadata in list.Items)
+ {
+ string url = (metadata.Id.Split('_')[1] + '.' + newHost).Replace("www.", string.Empty);
+ try
+ {
+ var pingResult = await ping.SendPingAsync(url);
+ if (pingResult.Status == System.Net.NetworkInformation.IPStatus.Success)
+ {
+ metadata.IconCode = WEBSERVICE_ICON_SUCCESS;
+ metadata.ImagePath = "http://free.pagepeeker.com/v2/thumbs.php?size=m&url=" + url;
+ }
+ else
+ {
+ metadata.IconCode = WEBSERVICE_ICON_UNAVAILABLE;
+ metadata.Subtitle = pingResult.Status.ToString();
+ }
+ }
+ catch (System.Net.NetworkInformation.PingException ex)
+ {
+ metadata.IconCode = WEBSERVICE_ICON_UNREACHABLE;
+ if (ex.InnerException?.Message != null)
+ metadata.Subtitle = ex.InnerException.Message;
+ }
+ }
+ }
+ OnHostChanged(newHostBox, newHostBox.Value);
+ newHostBox.ValueChanged += OnHostChanged;
+
+ return Task.CompletedTask;
+ }
+
public override async Task Apply()
{
// Verify that ZuneServices.dll exists