Skip to content

Commit

Permalink
Fix server list being dropped when invalid ip is provided by a single…
Browse files Browse the repository at this point in the history
… server (#185)

* Fix server list being dropped when invalid ip is provided by a single server

* Validate ServerIp for valid IP address or domain name and additional logging for server fetching
  • Loading branch information
CorruptComputer authored Mar 9, 2023
1 parent 571c0f8 commit 69de6c5
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 31 deletions.
5 changes: 5 additions & 0 deletions UnitystationLauncher/Models/Api/Server.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.IO;
using System.Net;
using System.Runtime.InteropServices;
using UnitystationLauncher.Models.ConfigFile;

Expand Down Expand Up @@ -57,6 +58,10 @@ public bool HasTrustedUrlSource
}
}

public bool HasValidDomainName => Uri.CheckHostName(ServerIp) == UriHostNameType.Dns;

public bool HasValidIpAddress => IPAddress.TryParse(ServerIp, out _);

public string InstallationName => ForkName + BuildVersion;

public string InstallationPath => Path.Combine(Config.InstallationsPath, InstallationName);
Expand Down
5 changes: 2 additions & 3 deletions UnitystationLauncher/Models/Installation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
Expand Down Expand Up @@ -55,12 +54,12 @@ public Installation(string folderPath)
return exe;
}

public void Start(IPAddress ip, short port, string? refreshToken, string? uid)
public void LaunchWithArgs(string ip, short port, string? refreshToken, string? uid)
{
Start($"--server {ip} --port {port} --refreshtoken {refreshToken} --uid {uid}");
}

public void Start()
public void LaunchWithoutArgs()
{
Start("");
}
Expand Down
54 changes: 36 additions & 18 deletions UnitystationLauncher/Services/ServerService.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Reactive.Linq;
using System.Threading.Tasks;
Expand All @@ -8,7 +9,6 @@
using Serilog;
using UnitystationLauncher.Constants;
using UnitystationLauncher.Models.Api;
using UnitystationLauncher.Models.ConfigFile;

namespace UnitystationLauncher.Services
{
Expand All @@ -22,7 +22,7 @@ public ServerService(HttpClient http, InstallationService installService)
{
_http = http;
_installService = installService;
Servers = Observable.Timer(TimeSpan.FromSeconds(0), TimeSpan.FromSeconds(10))
Servers = Observable.Timer(TimeSpan.Zero, TimeSpan.FromSeconds(10))
.SelectMany(_ => GetServerListAsync())
.Replay(1)
.RefCount();
Expand All @@ -40,31 +40,49 @@ private async Task<IReadOnlyList<Server>> GetServerListAsync()
{
Refreshing = true;

var data = await _http.GetStringAsync(ApiUrls.ServerListUrl);
var serverData = JsonConvert.DeserializeObject<ServerList>(data)?.Servers;
string data = await _http.GetStringAsync(ApiUrls.ServerListUrl);
List<Server>? serverData = JsonConvert.DeserializeObject<ServerList>(data)?.Servers;
Log.Information("Server list fetched");

var servers = new List<Server>();
if (serverData != null)
List<Server> servers = new();
if (serverData == null)
{
foreach (var server in serverData)
{
if (!server.HasTrustedUrlSource)
{
Log.Warning(
"Server: {ServerName} has untrusted download URL and has been omitted in the server list!",
server.ServerName);
continue;
}

servers.Add(server);
}
Log.Warning("Warning: {Warning}", "Invalid response from hub, server list is null.");
}
else if (serverData.Count == 0)
{
Log.Warning("Warning: {Warning}", "No servers returned by the hub.");
}
else
{
servers.AddRange(serverData.Where(IsValidServer));
}

Refreshing = false;
return servers;
}

private static bool IsValidServer(Server server)
{
if (!server.HasTrustedUrlSource)
{
Log.Warning("Server: {ServerName} has untrusted download URL and has been omitted in the server list!",
server.ServerName);
return false;
}

if (server is { HasValidDomainName: false, HasValidIpAddress: false })
{
Log.Warning("Server: {ServerName} has an invalid IP or domain name: {Domain}",
server.ServerName,
server.ServerIp);

return false;
}

return true;
}

public void Dispose()
{
_installService.Dispose();
Expand Down
2 changes: 1 addition & 1 deletion UnitystationLauncher/ViewModels/InstallationViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ public class InstallationViewModel : ViewModelBase
public InstallationViewModel(Installation installation)
{
Installation = installation;
LaunchCommand = ReactiveCommand.Create(Installation.Start);
LaunchCommand = ReactiveCommand.Create(Installation.LaunchWithoutArgs);
UninstallCommand = ReactiveCommand.CreateFromTask(Installation.DeleteAsync);
}

Expand Down
25 changes: 17 additions & 8 deletions UnitystationLauncher/ViewModels/ServerViewModel.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;
using System.Net;
using System.Net.NetworkInformation;
using System.Reactive.Linq;
using System.Diagnostics;
Expand Down Expand Up @@ -37,13 +36,23 @@ public ServerViewModel(Server server, Installation? installation, Download? down
Download = download;
_authService = authService;
RoundTrip = new();

try
{
#if FLATPAK
Task.Run(FlatpakGetPingTime);
Task.Run(FlatpakGetPingTime);
#else
using Ping ping = new();
ping.PingCompleted += PingCompletedCallback;
ping.SendAsync(Server.ServerIp, null);
using Ping ping = new();
ping.PingCompleted += PingCompletedCallback;
ping.SendAsync(Server.ServerIp, null);
#endif
}
catch (ArgumentException e)
{
Log.Error("Error: {Error}", $"Invalid IP address when trying to ping server: {e.Message}");
RoundTrip.Value = "Error";
}

DownloadedAmount = (
Download?.WhenAnyValue(d => d.Downloaded)
?? Observable.Return(0L)
Expand All @@ -62,17 +71,17 @@ private void PingCompletedCallback(object _, PingCompletedEventArgs eventArgs)
// If an error occurred, display the exception to the user.
if (eventArgs.Error != null)
{
Log.Error(eventArgs.Error, "Ping failed");
Log.Error("Ping failed: {Error}", eventArgs.Error);
return;
}

long? tripTime = eventArgs.Reply?.RoundtripTime;
RoundTrip.Value = tripTime.HasValue ? $"{tripTime.Value}ms" : "null";
}

public void Start()
public void LaunchGame()
{
Installation?.Start(IPAddress.Parse(Server.ServerIp), (short)Server.ServerPort,
Installation?.LaunchWithArgs(Server.ServerIp, (short)Server.ServerPort,
_authService.CurrentRefreshToken, _authService.Uid);
}

Expand Down
2 changes: 1 addition & 1 deletion UnitystationLauncher/Views/ServerView.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
</MultiBinding.Bindings>
</MultiBinding>
</Panel.IsVisible>
<Button Command="{Binding Start}" Content="Start" Background="{StaticResource PrimaryTransparent4}"
<Button Command="{Binding LaunchGame}" Content="Start" Background="{StaticResource PrimaryTransparent4}"
BorderThickness="0" />
</Panel>
<StackPanel IsVisible="{Binding Downloading^}" VerticalAlignment="Center">
Expand Down

0 comments on commit 69de6c5

Please sign in to comment.