Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added src/Launcher/Assets/AltButtons/Discord.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/Launcher/Assets/AltButtons/Discord_Hover.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/Launcher/Assets/AltButtons/New.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/Launcher/Assets/AltButtons/New_Hover.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/Launcher/Assets/AltButtons/Reddit.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/Launcher/Assets/AltButtons/Reddit_Hover.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/Launcher/Assets/AltButtons/Settings.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/Launcher/Assets/AltButtons/Settings_Hover.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/Launcher/Assets/AltButtons/Spacer.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/Launcher/Assets/Backgrounds/Back1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/Launcher/Assets/Backgrounds/Back10.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/Launcher/Assets/Backgrounds/Back11.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/Launcher/Assets/Backgrounds/Back12.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/Launcher/Assets/Backgrounds/Back13.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/Launcher/Assets/Backgrounds/Back14.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/Launcher/Assets/Backgrounds/Back15.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/Launcher/Assets/Backgrounds/Back16.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/Launcher/Assets/Backgrounds/Back17.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/Launcher/Assets/Backgrounds/Back18.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/Launcher/Assets/Backgrounds/Back19.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/Launcher/Assets/Backgrounds/Back2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/Launcher/Assets/Backgrounds/Back20.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/Launcher/Assets/Backgrounds/Back3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/Launcher/Assets/Backgrounds/Back4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/Launcher/Assets/Backgrounds/Back5.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/Launcher/Assets/Backgrounds/Back6.png
Binary file added src/Launcher/Assets/Backgrounds/Back7.png
Binary file added src/Launcher/Assets/Backgrounds/Back8.png
Binary file added src/Launcher/Assets/Backgrounds/Back9.png
Binary file added src/Launcher/Assets/Frame/Offline_Button.png
Binary file added src/Launcher/Assets/Frame/Play_Button.png
Binary file added src/Launcher/Assets/Frame/Play_Button_Hover.png
Binary file added src/Launcher/Assets/Frame/Stop_Button.png
Binary file added src/Launcher/Assets/Frame/Stop_Button_Hover.png
Binary file added src/Launcher/Assets/Hero/OSFRLogo.png
Binary file added src/Launcher/Assets/Hero/sanctuary.jpg
Binary file added src/Launcher/Assets/ServerIcons/Edit.png
Binary file added src/Launcher/Assets/ServerIcons/Edit_Hover.png
Binary file added src/Launcher/Assets/ServerIcons/Online_Status.png
Binary file added src/Launcher/Assets/ServerIcons/Player_Count.png
Binary file added src/Launcher/Assets/ServerIcons/Server_Spacer.png
65 changes: 64 additions & 1 deletion src/Launcher/ViewModels/AddServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Threading.Tasks;

using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;

using Launcher.Extensions;
using Launcher.Helpers;
Expand All @@ -17,12 +18,19 @@ public partial class AddServer : Popup
{
private static readonly Logger _logger = LogManager.GetCurrentClassLogger();

private readonly ServerInfo? _editingInfo;

[Required]
[ObservableProperty]
[NotifyDataErrorInfo]
[CustomValidation(typeof(AddServer), nameof(ValidateServerUrl))]
private string serverUrl = string.Empty;

[ObservableProperty]
private string serverName = string.Empty;

public bool IsEditMode => _editingInfo is not null;

public AddServer()
{
View = new Views.AddServer
Expand All @@ -31,6 +39,42 @@ public AddServer()
};
}

public AddServer(ServerInfo info)
{
_editingInfo = info;

ServerUrl = info.Url;
ServerName = info.Name;

View = new Views.AddServer
{
DataContext = this
};
}

[RelayCommand]
public void Delete()
{
if (_editingInfo is null)
return;

Settings.Instance.ServerInfoList.Remove(_editingInfo);
Settings.Instance.Save();

App.CancelPopup();
App.AddNotification("Server deleted.", false);
}

[RelayCommand]
public void Register()
{
if (_editingInfo is null)
return;

App.CancelPopup();
App.ShowPopup(new Register(_editingInfo));
}

public static ValidationResult? ValidateServerUrl(string serverUrl, ValidationContext context)
{
if (string.IsNullOrWhiteSpace(serverUrl))
Expand All @@ -54,7 +98,26 @@ public override Task<bool> ProcessAsync()
{
ProgressDescription = App.GetText("Text.Add_Server.Loading");

return TryAddServerAsync(ServerUrl);
return IsEditMode ? OnEditServerAsync() : TryAddServerAsync(ServerUrl);
}

private Task<bool> OnEditServerAsync()
{
try
{
_editingInfo!.Url = ServerUrl.Trim();
_editingInfo.Name = ServerName.Trim();

Settings.Instance.Save();

return Task.FromResult(true);
}
catch (Exception ex)
{
_logger.Error(ex, "An exception occurred while updating server.");
App.AddNotification("An error occurred while updating server.", true);
return Task.FromResult(false);
}
}

public static async Task<bool> TryAddServerAsync(string serverUrl)
Expand Down
53 changes: 52 additions & 1 deletion src/Launcher/ViewModels/Main.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ public partial class Main : ObservableObject
[ObservableProperty]
private SemanticVersion version = App.CurrentVersion;

public string DisplayName => Settings.Instance.DisplayName;

public bool IsGameRunning => Servers.Any(x => x.Process is not null);

public AvaloniaList<Server> Servers { get; } = [];
public AvaloniaList<Notification> Notifications { get; } = [];

Expand All @@ -54,6 +58,11 @@ public Main()
// Subscribe to changes in the server list from settings to keep the UI in sync.
Settings.Instance.ServerInfoList.CollectionChanged += ServerInfoList_CollectionChanged;
Settings.Instance.DiscordActivityChanged += (_, _) => UpdateDiscordActivity();
Settings.Instance.PropertyChanged += (_, e) =>
{
if (e.PropertyName == nameof(Settings.DisplayName))
OnPropertyChanged(nameof(DisplayName));
};
}

private void ServerInfoList_CollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
Expand Down Expand Up @@ -85,7 +94,7 @@ public void OnLoad()
_logger.Info("No servers found in settings. Adding default servers.");
foreach (var defaultServerUrl in Constants.DefaultServerUrls)
{
_ = AddServer.TryAddServerAsync(defaultServerUrl);
_ = ViewModels.AddServer.TryAddServerAsync(defaultServerUrl);
}
}

Expand All @@ -107,6 +116,11 @@ public void UpdateDiscordActivity()
DiscordService.UpdateActivity(details, playingOn);
}

public void RefreshRuntimeState()
{
OnPropertyChanged(nameof(IsGameRunning));
}

[RelayCommand]
public Task CheckForUpdates() => App.CheckForUpdatesAsync();

Expand All @@ -122,6 +136,43 @@ public void ShowSettings()
[RelayCommand]
public void ShowAddServer() => App.ShowPopup(new AddServer());

[RelayCommand]
public void AddServer() => App.ShowPopup(new AddServer());

public void EditServer(Server server)
{
var viewModel = new AddServer(server.Info);
App.ShowPopup(viewModel, process: false);
}

[RelayCommand]
public async Task OpenDiscordAsync()
{
try
{
var window = App.GetWindow();
await window.Launcher.LaunchUriAsync(new Uri("https://discord.gg/x7Xfz99Ydv"));
}
catch
{
App.AddNotification("Unable to open Discord link.", true);
}
}

[RelayCommand]
public async Task OpenRedditAsync()
{
try
{
var window = App.GetWindow();
await window.Launcher.LaunchUriAsync(new Uri("https://www.reddit.com/r/freerealms/"));
}
catch
{
App.AddNotification("Unable to open Reddit link.", true);
}
}

[RelayCommand]
public async Task OpenLogsAsync()
{
Expand Down
25 changes: 20 additions & 5 deletions src/Launcher/ViewModels/Register.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ namespace Launcher.ViewModels;

public partial class Register : Popup
{
private readonly Server _server;
private readonly Server? _server;
private readonly ServerInfo? _serverInfo;
private readonly Logger _logger = LogManager.GetCurrentClassLogger();

[ObservableProperty]
Expand Down Expand Up @@ -57,6 +58,20 @@ public Register(Server server)
};
}

public Register(ServerInfo serverInfo)
{
_serverInfo = serverInfo;

AddSecureWarning();

View = new Views.Register
{
DataContext = this
};
}

private ServerInfo Info => _server?.Info ?? _serverInfo!;

public static ValidationResult? ValidateConfirmPassword(string confirmPassword, ValidationContext context)
{
if (context.ObjectInstance is not Register register)
Expand All @@ -82,7 +97,7 @@ public override async Task<bool> ProcessAsync()
Password = Password
};

var baseUri = new Uri(_server.Info.WebApiUrl);
var baseUri = new Uri(Info.WebApiUrl);

var registerUri = new Uri(baseUri, "register");

Expand All @@ -101,7 +116,7 @@ public override async Task<bool> ProcessAsync()
{
App.AddNotification("Registration failed. Please check your username and password and try again", true);

_logger.Warn("Registration failed for server: '{Name}'. API returned {StatusCode}: {Reason}.", _server.Info.Name, httpResponse.StatusCode, httpResponse.ReasonPhrase);
_logger.Warn("Registration failed for server: '{Name}'. API returned {StatusCode}: {Reason}.", Info.Name, httpResponse.StatusCode, httpResponse.ReasonPhrase);

Username = string.Empty;
Password = string.Empty;
Expand All @@ -117,15 +132,15 @@ public override async Task<bool> ProcessAsync()
{
App.AddNotification("Registration failed. Please check your username and password and try again", true);

_logger.Error(ex, "An exception occurred registering on server: '{Name}'.", _server.Info.Name);
_logger.Error(ex, "An exception occurred registering on server: '{Name}'.", Info.Name);

return false;
}
}

private void AddSecureWarning()
{
if (Uri.TryCreate(_server.Info.WebApiUrl, UriKind.Absolute, out var webApiUrl)
if (Uri.TryCreate(Info.WebApiUrl, UriKind.Absolute, out var webApiUrl)
&& webApiUrl.Scheme != Uri.UriSchemeHttps)
{
Warning = App.GetText("Text.Server.SecureApiWarning");
Expand Down
20 changes: 20 additions & 0 deletions src/Launcher/ViewModels/Server.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
using System.Threading.Tasks;

using Avalonia.Media;
using Avalonia.Media.Imaging;
using Avalonia.Platform;
using Avalonia.Platform.Storage;

using CommunityToolkit.Mvvm.ComponentModel;
Expand Down Expand Up @@ -67,6 +69,17 @@ public partial class Server : ObservableObject
[ObservableProperty]
private ObservableStringBuilder markdownBuilder = new();

public bool IsLocalServer => false;

public string ProfileTitle => Info?.Name ?? "Unknown Server";

public string ProfileSubtitle => IsOnline ? "Online" : "Offline";

private static readonly IImage IconGreen = new Bitmap(AssetLoader.Open(new Uri("avares://Launcher/Assets/ServerIcons/Server_Icon_Green.png")));
private static readonly IImage IconRed = new Bitmap(AssetLoader.Open(new Uri("avares://Launcher/Assets/ServerIcons/Server_Icon_Red.png")));

public IImage ServerIconSource => IsOnline ? IconGreen : IconRed;

public Server()
{
#if DEBUG && DESIGNMODE
Expand Down Expand Up @@ -107,6 +120,13 @@ public void ClientProcessExited(object? sender, EventArgs e)
Process = null;
}

[RelayCommand]
private async Task EditAsync()
{
_main.EditServer(this);
await OnShowAsync();
}

[RelayCommand]
private async Task OpenUriAsync(LinkClickedEventArgs args)
{
Expand Down
6 changes: 6 additions & 0 deletions src/Launcher/ViewModels/Settings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ public partial class Settings : ObservableObject
[ObservableProperty]
private LocaleType locale = LocaleType.en_US;

[ObservableProperty]
private string displayName = "User";

[ObservableProperty]
private AvaloniaList<ServerInfo> serverInfoList = [];

Expand Down Expand Up @@ -71,6 +74,9 @@ public void Save()
partial void OnLocaleChanged(LocaleType value)
=> LocaleChanged?.Invoke(this, EventArgs.Empty);

partial void OnDisplayNameChanged(string value)
=> Save();

partial void OnDiscordActivityChanged(bool value)
{
if (value)
Expand Down
Loading