|
@@ -20,6 +20,11 @@ using Avalonia.Threading;
|
|
|
using System.Net;
|
|
|
using System.IO.Compression;
|
|
|
using ReactiveUI.Validation.Extensions;
|
|
|
+using Avalonia.Media;
|
|
|
+using Avalonia.Data;
|
|
|
+using ReactiveUI.Validation.Helpers;
|
|
|
+using System.Collections.Generic;
|
|
|
+using VeloeMinecraftLauncher.Models.Entity;
|
|
|
|
|
|
namespace VeloeMinecraftLauncher.ViewModels
|
|
|
{
|
|
@@ -92,84 +97,90 @@ namespace VeloeMinecraftLauncher.ViewModels
|
|
|
}
|
|
|
try
|
|
|
{
|
|
|
-
|
|
|
- logger.Debug("Connecting to WebSoket");
|
|
|
- //conection to my servers
|
|
|
- connection = new HubConnectionBuilder()
|
|
|
- .WithUrl("https://monitor.veloe.link/hubs/data")
|
|
|
- .WithAutomaticReconnect()
|
|
|
- .Build();
|
|
|
-
|
|
|
- Func<Exception, Task> reconnecting = ex => Task.Run(() =>
|
|
|
+ var changelog = Downloader.DownloadAndDeserializeJsonData<List<Changelog>>("https://files.veloe.link/launcher/changelog.json");
|
|
|
+
|
|
|
+ if (Avalonia.Application.Current.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
|
|
+ {
|
|
|
+ Dispatcher.UIThread.InvokeAsync(() =>
|
|
|
+ {
|
|
|
+ var stackpanel = desktop.MainWindow.GetControl<StackPanel>("ChangeLogStackPanel");
|
|
|
+ foreach (var version in changelog)
|
|
|
+ {
|
|
|
+ if (version.title is not null)
|
|
|
+ {
|
|
|
+ stackpanel.Children.Add(new TextBlock()
|
|
|
+ {
|
|
|
+ Text = version.title,
|
|
|
+ VerticalAlignment = Avalonia.Layout.VerticalAlignment.Stretch,
|
|
|
+ TextWrapping = TextWrapping.Wrap,
|
|
|
+ FontSize = 16
|
|
|
+ });
|
|
|
+ }
|
|
|
+ stackpanel.Children.Add(new TextBlock()
|
|
|
+ {
|
|
|
+ Text = version.text,
|
|
|
+ VerticalAlignment = Avalonia.Layout.VerticalAlignment.Stretch,
|
|
|
+ TextWrapping = TextWrapping.Wrap
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+ catch (Exception ex)
|
|
|
{
|
|
|
- logger.Warning("Reconnecting to WebCoket...");
|
|
|
- });
|
|
|
- Func<string, Task> reconnected = str => Task.Run(() =>
|
|
|
+ OpenErrorWindow(ex);
|
|
|
+ }
|
|
|
+ try
|
|
|
{
|
|
|
- logger.Warning("Reconnected to WebCoket.");
|
|
|
- connection.InvokeAsync("ConnectToGroup", "McTFC");
|
|
|
- connection.InvokeAsync("ConnectToGroup", "McVanilla");
|
|
|
- connection.InvokeAsync("ConnectToGroup", "McTech");
|
|
|
- });
|
|
|
+
|
|
|
+ logger.Debug("Connecting to WebSoket");
|
|
|
+ //conection to my servers
|
|
|
|
|
|
- connection.Reconnecting += reconnecting;
|
|
|
- connection.Reconnected += reconnected;
|
|
|
+ var serverNames = Downloader.DownloadAndDeserializeJsonData<List<string>>("https://files.veloe.link/launcher/servers.json");
|
|
|
|
|
|
- connection.On<string>("UpdateMcTFC", (message) =>
|
|
|
- {
|
|
|
- McStatus status = JsonSerializer.Deserialize<McStatus>(message);
|
|
|
- McTfcBlock = $"McTFC: Online";
|
|
|
- McTfcPlayersBlock = $"{status.NumPlayers}/{status.MaxPlayers}";
|
|
|
- McTfcTip = String.Empty;
|
|
|
- if (UInt16.Parse(status.NumPlayers) > 0)
|
|
|
- foreach (var player in status.Players)
|
|
|
+ connection = new HubConnectionBuilder()
|
|
|
+ .WithUrl("https://monitor.veloe.link/hubs/data")
|
|
|
+ .WithAutomaticReconnect()
|
|
|
+ .Build();
|
|
|
+
|
|
|
+ Func<Exception, Task> reconnecting = ex => Task.Run(() =>
|
|
|
+ {
|
|
|
+ logger.Warning("Reconnecting to WebCoket...");
|
|
|
+ });
|
|
|
+ Func<string, Task> reconnected = str => Task.Run(() =>
|
|
|
+ {
|
|
|
+ logger.Warning("Reconnected to WebCoket.");
|
|
|
+ foreach (var server in serverNames)
|
|
|
{
|
|
|
- McTfcTip += player;
|
|
|
- McTfcTip += "\n";
|
|
|
+ connection.InvokeAsync("ConnectToGroup", server);
|
|
|
}
|
|
|
- else
|
|
|
- McTfcTip = "No players.";
|
|
|
- mcTfcTimer.Stop();
|
|
|
- mcTfcTimer.Start();
|
|
|
+ });
|
|
|
|
|
|
- //ConsoleText += message;
|
|
|
- });
|
|
|
+ connection.Reconnecting += reconnecting;
|
|
|
+ connection.Reconnected += reconnected;
|
|
|
|
|
|
- connection.On<string>("UpdateMcVanilla", (message) =>
|
|
|
- {
|
|
|
- McStatus status = JsonSerializer.Deserialize<McStatus>(message);
|
|
|
- McVanillaBlock = $"McVanilla: Online";
|
|
|
- McVanillaPlayersBlock = $"{status.NumPlayers}/{status.MaxPlayers}";
|
|
|
- mcTechTimer.Stop();
|
|
|
- mcTechTimer.Start();
|
|
|
- //ConsoleText += message;
|
|
|
- });
|
|
|
-
|
|
|
- connection.On<string>("UpdateMcTech", (message) =>
|
|
|
- {
|
|
|
- McStatus status = JsonSerializer.Deserialize<McStatus>(message);
|
|
|
- McTechBlock = $"McTech: Online {status.NumPlayers}/{status.MaxPlayers}";
|
|
|
- McTechPlayersBlock = $"{status.NumPlayers}/{status.MaxPlayers}";
|
|
|
- mcVanillaTimer.Stop();
|
|
|
- mcVanillaTimer.Start();
|
|
|
- //ConsoleText += message;
|
|
|
- });
|
|
|
+ if (Avalonia.Application.Current.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
|
|
+ {
|
|
|
+ Dispatcher.UIThread.InvokeAsync(() =>
|
|
|
+ {
|
|
|
+ var stackpanel = desktop.MainWindow.GetControl<StackPanel>("ServersStackPanel");
|
|
|
+ foreach (var server in serverNames)
|
|
|
+ stackpanel.Children.Add(CreateServerPanel(server));
|
|
|
+ });
|
|
|
|
|
|
- mcTfcTimer.Elapsed += OnTimedEventMcTfc;
|
|
|
- mcTfcTimer.Start();
|
|
|
- mcTechTimer.Elapsed += OnTimedEventMcTech;
|
|
|
- mcTechTimer.Start();
|
|
|
- mcVanillaTimer.Elapsed += OnTimedEventMcVanilla;
|
|
|
- mcVanillaTimer.Start();
|
|
|
+ }
|
|
|
|
|
|
- connection.StartAsync();
|
|
|
+ connection.StartAsync();
|
|
|
|
|
|
- connection.InvokeAsync("ConnectToGroup", "McTFC");
|
|
|
- connection.InvokeAsync("ConnectToGroup", "McVanilla");
|
|
|
- connection.InvokeAsync("ConnectToGroup", "McTech");
|
|
|
+ foreach (var server in serverNames)
|
|
|
+ {
|
|
|
+ connection.InvokeAsync("ConnectToGroup", server);
|
|
|
+ }
|
|
|
+ logger.Debug("Connected to WebSoket");
|
|
|
|
|
|
- consoleOutputTimer.Elapsed += UpdateConsoleOutput;
|
|
|
- consoleOutputTimer.AutoReset = false;
|
|
|
+ consoleOutputTimer.Elapsed += UpdateConsoleOutput;
|
|
|
+ consoleOutputTimer.AutoReset = false;
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
@@ -179,9 +190,6 @@ namespace VeloeMinecraftLauncher.ViewModels
|
|
|
|
|
|
}
|
|
|
|
|
|
- System.Timers.Timer mcTfcTimer = new System.Timers.Timer(30000);
|
|
|
- System.Timers.Timer mcTechTimer = new System.Timers.Timer(30000);
|
|
|
- System.Timers.Timer mcVanillaTimer = new System.Timers.Timer(30000);
|
|
|
System.Timers.Timer consoleOutputTimer = new(250);
|
|
|
|
|
|
private HubConnection connection;
|
|
@@ -195,15 +203,6 @@ namespace VeloeMinecraftLauncher.ViewModels
|
|
|
private bool isUpdateAvailable = false;
|
|
|
private string settingsButton = "Settings";
|
|
|
private string startButtonOutput;
|
|
|
- private string mcTfcBlock = "Wait for update...";
|
|
|
- private string mcTechBlock = "Wait for update...";
|
|
|
- private string mcVanillaBlock = "Wait for update...";
|
|
|
- private string mcTfcPlayersBlock = String.Empty;
|
|
|
- private string mcTechPlayersBlock = String.Empty;
|
|
|
- private string mcVanillaPlayersBlock = String.Empty;
|
|
|
- private string mcTfcTip = "No players.";
|
|
|
- private string mcTechTip = "No players.";
|
|
|
- private string mcVanillaTip = "No players.";
|
|
|
|
|
|
ILogger logger;
|
|
|
|
|
@@ -321,63 +320,9 @@ namespace VeloeMinecraftLauncher.ViewModels
|
|
|
set => this.RaiseAndSetIfChanged(ref isUpdateAvailable, value);
|
|
|
}
|
|
|
|
|
|
- public string McTfcBlock
|
|
|
- {
|
|
|
- get => mcTfcBlock;
|
|
|
- set => this.RaiseAndSetIfChanged(ref mcTfcBlock, value);
|
|
|
- }
|
|
|
-
|
|
|
- public string McTechBlock
|
|
|
- {
|
|
|
- get => mcTechBlock;
|
|
|
- set => this.RaiseAndSetIfChanged(ref mcTechBlock, value);
|
|
|
- }
|
|
|
-
|
|
|
- public string McVanillaBlock
|
|
|
- {
|
|
|
- get => mcVanillaBlock;
|
|
|
- set => this.RaiseAndSetIfChanged(ref mcVanillaBlock, value);
|
|
|
- }
|
|
|
-
|
|
|
- public string McTfcPlayersBlock
|
|
|
- {
|
|
|
- get => mcTfcPlayersBlock;
|
|
|
- set => this.RaiseAndSetIfChanged(ref mcTfcPlayersBlock, value);
|
|
|
- }
|
|
|
-
|
|
|
- public string McTechPlayersBlock
|
|
|
- {
|
|
|
- get => mcTechPlayersBlock;
|
|
|
- set => this.RaiseAndSetIfChanged(ref mcTechPlayersBlock, value);
|
|
|
- }
|
|
|
-
|
|
|
- public string McVanillaPlayersBlock
|
|
|
- {
|
|
|
- get => mcVanillaPlayersBlock;
|
|
|
- set => this.RaiseAndSetIfChanged(ref mcVanillaPlayersBlock, value);
|
|
|
- }
|
|
|
-
|
|
|
- public string McTfcTip
|
|
|
- {
|
|
|
- get => mcTfcTip;
|
|
|
- set => this.RaiseAndSetIfChanged(ref mcTfcTip, value);
|
|
|
- }
|
|
|
-
|
|
|
- public string McTechTip
|
|
|
- {
|
|
|
- get => mcTechTip;
|
|
|
- set => this.RaiseAndSetIfChanged(ref mcTechTip, value);
|
|
|
- }
|
|
|
-
|
|
|
- public string McVanillaTip
|
|
|
- {
|
|
|
- get => mcVanillaTip;
|
|
|
- set => this.RaiseAndSetIfChanged(ref mcVanillaTip, value);
|
|
|
- }
|
|
|
-
|
|
|
public int ConsoleTextCaretIndex
|
|
|
{
|
|
|
- get { return int.MaxValue; }
|
|
|
+ get => int.MaxValue;
|
|
|
set => this.RaisePropertyChanged(nameof(ConsoleTextCaretIndex));
|
|
|
}
|
|
|
|
|
@@ -804,6 +749,70 @@ namespace VeloeMinecraftLauncher.ViewModels
|
|
|
|
|
|
}
|
|
|
|
|
|
+ private Panel CreateServerPanel(string name)
|
|
|
+ {
|
|
|
+ ServerPanelModel serverPanelModel = new() { Name = name , Status = "Wait for update...", Tip = "No players.", Players = string.Empty};
|
|
|
+
|
|
|
+ Panel panel = new Panel()
|
|
|
+ {
|
|
|
+ VerticalAlignment = Avalonia.Layout.VerticalAlignment.Top,
|
|
|
+ HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Stretch,
|
|
|
+ Height = 75,
|
|
|
+ Width = 150,
|
|
|
+ Margin = Avalonia.Thickness.Parse("0 0 10 10")
|
|
|
+ };
|
|
|
+
|
|
|
+ panel.Children.Add(new Border()
|
|
|
+ {
|
|
|
+ Background = Brushes.Black,
|
|
|
+ Opacity = 0.2,
|
|
|
+ CornerRadius = Avalonia.CornerRadius.Parse("15")
|
|
|
+ });
|
|
|
+
|
|
|
+ var tip = new ToolTip()
|
|
|
+ {
|
|
|
+ Content = new TextBlock() {TextWrapping = TextWrapping.Wrap, [!TextBlock.TextProperty] = new Binding { Source = serverPanelModel,Path = nameof(serverPanelModel.Tip) } }
|
|
|
+ };
|
|
|
+
|
|
|
+ ToolTip.SetTip(panel, tip);
|
|
|
+
|
|
|
+ StackPanel textPanel = new() { VerticalAlignment = Avalonia.Layout.VerticalAlignment.Center, HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Center };
|
|
|
+
|
|
|
+ textPanel.Children.Add(new TextBlock() { VerticalAlignment = Avalonia.Layout.VerticalAlignment.Center, HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Center, [!TextBlock.TextProperty] = new Binding { Source = serverPanelModel, Path = nameof(serverPanelModel.Status) } });
|
|
|
+ textPanel.Children.Add(new TextBlock() { FontSize = 20, VerticalAlignment = Avalonia.Layout.VerticalAlignment.Center, HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Center, [!TextBlock.TextProperty] = new Binding { Source = serverPanelModel, Path = nameof(serverPanelModel.Players) } });
|
|
|
+
|
|
|
+ panel.Children.Add(textPanel);
|
|
|
+
|
|
|
+ System.Timers.Timer timeoutTimer = new System.Timers.Timer(30000);
|
|
|
+
|
|
|
+ timeoutTimer.Elapsed += (Object source, ElapsedEventArgs e) =>
|
|
|
+ {
|
|
|
+ serverPanelModel.Status = $"{serverPanelModel.Name}: Offline";
|
|
|
+ serverPanelModel.Players = string.Empty;
|
|
|
+ };
|
|
|
+ timeoutTimer.Start();
|
|
|
+
|
|
|
+ connection.On<string>($"Update{serverPanelModel.Name}", (message) =>
|
|
|
+ {
|
|
|
+ McStatus status = JsonSerializer.Deserialize<McStatus>(message);
|
|
|
+ serverPanelModel.Status = $"{serverPanelModel.Name}: Online";
|
|
|
+ serverPanelModel.Players = $"{status.NumPlayers}/{status.MaxPlayers}";
|
|
|
+ serverPanelModel.Tip = String.Empty;
|
|
|
+ if (UInt16.Parse(status.NumPlayers) > 0)
|
|
|
+ foreach (var player in status.Players)
|
|
|
+ {
|
|
|
+ serverPanelModel.Tip += player;
|
|
|
+ serverPanelModel.Tip += "\n";
|
|
|
+ }
|
|
|
+ else
|
|
|
+ serverPanelModel.Tip = "No players.";
|
|
|
+ timeoutTimer.Stop();
|
|
|
+ timeoutTimer.Start();
|
|
|
+ });
|
|
|
+
|
|
|
+ return panel;
|
|
|
+ }
|
|
|
+
|
|
|
private void OpenErrorWindow(Exception ex)
|
|
|
{
|
|
|
var message = ex.Message;
|
|
@@ -833,19 +842,6 @@ namespace VeloeMinecraftLauncher.ViewModels
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
-
|
|
|
- private void OnTimedEventMcTfc(Object source, ElapsedEventArgs e)
|
|
|
- {
|
|
|
- McTfcBlock = "McTFC: Offline";
|
|
|
- }
|
|
|
- private void OnTimedEventMcTech(Object source, ElapsedEventArgs e)
|
|
|
- {
|
|
|
- McTechBlock = "McTech: Offline";
|
|
|
- }
|
|
|
- private void OnTimedEventMcVanilla(Object source, ElapsedEventArgs e)
|
|
|
- {
|
|
|
- McVanillaBlock = "McVanilla: Offline";
|
|
|
- }
|
|
|
}
|
|
|
|
|
|
public class LatestLauncherVersion
|
|
@@ -865,5 +861,37 @@ namespace VeloeMinecraftLauncher.ViewModels
|
|
|
return version;
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ public class ServerPanelModel: ReactiveValidationObject
|
|
|
+ {
|
|
|
+ private string _name;
|
|
|
+ private string _status;
|
|
|
+ private string _tip;
|
|
|
+ private string _players;
|
|
|
+
|
|
|
+ public string Name
|
|
|
+ {
|
|
|
+ get => _name;
|
|
|
+ set => this.RaiseAndSetIfChanged(ref _name, value);
|
|
|
+ }
|
|
|
+
|
|
|
+ public string Status
|
|
|
+ {
|
|
|
+ get => _status;
|
|
|
+ set => this.RaiseAndSetIfChanged(ref _status, value);
|
|
|
+ }
|
|
|
+
|
|
|
+ public string Tip
|
|
|
+ {
|
|
|
+ get => _tip;
|
|
|
+ set => this.RaiseAndSetIfChanged(ref _tip, value);
|
|
|
+ }
|
|
|
+
|
|
|
+ public string Players
|
|
|
+ {
|
|
|
+ get => _players;
|
|
|
+ set => this.RaiseAndSetIfChanged(ref _players, value);
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
}
|