diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..6152e08 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,26 @@ +{ + "version": "0.2.0", + "configurations": [ + { + // Use IntelliSense to find out which attributes exist for C# debugging + // Use hover for the description of the existing attributes + // For further information visit https://github.com/dotnet/vscode-csharp/blob/main/debugger-launchjson.md + "name": ".NET Core Launch (console)", + "type": "coreclr", + "request": "launch", + "preLaunchTask": "build", + // If you have changed target frameworks, make sure to update the program path. + "program": "${workspaceFolder}/Nebula.Launcher/bin/Debug/net9.0/Nebula.Launcher.dll", + "args": [], + "cwd": "${workspaceFolder}/Nebula.Launcher", + // For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console + "console": "internalConsole", + "stopAtEntry": false + }, + { + "name": ".NET Core Attach", + "type": "coreclr", + "request": "attach" + } + ] +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..76f3f25 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,41 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "build", + "command": "dotnet", + "type": "process", + "args": [ + "build", + "${workspaceFolder}/Nebula.Launcher/Nebula.Launcher.csproj", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary;ForceNoAlign" + ], + "problemMatcher": "$msCompile" + }, + { + "label": "publish", + "command": "dotnet", + "type": "process", + "args": [ + "publish", + "${workspaceFolder}/Nebula.Launcher/Nebula.Launcher.csproj", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary;ForceNoAlign" + ], + "problemMatcher": "$msCompile" + }, + { + "label": "watch", + "command": "dotnet", + "type": "process", + "args": [ + "watch", + "run", + "--project", + "${workspaceFolder}/Nebula.Launcher/Nebula.Launcher.csproj" + ], + "problemMatcher": "$msCompile" + } + ] +} \ No newline at end of file diff --git a/Nebula.Launcher/Services/LocalisationService.cs b/Nebula.Launcher/Services/LocalisationService.cs index bf2976a..dbaf6dc 100644 --- a/Nebula.Launcher/Services/LocalisationService.cs +++ b/Nebula.Launcher/Services/LocalisationService.cs @@ -42,4 +42,5 @@ public partial class LocalisationService { Initialise(); } -} \ No newline at end of file +} + diff --git a/Nebula.Launcher/ViewModels/ContentView/ContentViewBase.cs b/Nebula.Launcher/ViewModels/ContentView/ContentViewBase.cs new file mode 100644 index 0000000..f88fde7 --- /dev/null +++ b/Nebula.Launcher/ViewModels/ContentView/ContentViewBase.cs @@ -0,0 +1,14 @@ +using System; +using System.IO; +using Nebula.Launcher.ViewModels.Pages; + +namespace Nebula.Launcher.ViewModels.ContentView; +public abstract class ContentViewBase : ViewModelBase, IDisposable +{ + public virtual void InitialiseWithData(ContentPath path, Stream stream) + { + } + public virtual void Dispose() + { + } +} \ No newline at end of file diff --git a/Nebula.Launcher/ViewModels/Pages/AccountInfoViewModel.cs b/Nebula.Launcher/ViewModels/Pages/AccountInfoViewModel.cs index 74e2279..14e7fce 100644 --- a/Nebula.Launcher/ViewModels/Pages/AccountInfoViewModel.cs +++ b/Nebula.Launcher/ViewModels/Pages/AccountInfoViewModel.cs @@ -53,9 +53,6 @@ public partial class AccountInfoViewModel : ViewModelBase, IViewModelPage } } - - private CurrentAuthInfo? _currAuthTemp; - public string AuthItemSelect { set => CurrentAuthServer = value; @@ -65,6 +62,8 @@ public partial class AccountInfoViewModel : ViewModelBase, IViewModelPage protected override void InitialiseInDesignMode() { AddAccount(new AuthLoginPassword("Binka", "12341", "")); + AddAccount(new AuthLoginPassword("Binka", "12341", "")); + AuthUrls.Add("https://cinka.ru"); AuthUrls.Add("https://cinka.ru"); } @@ -177,6 +176,7 @@ public partial class AccountInfoViewModel : ViewModelBase, IViewModelPage AuthUrls.Clear(); var authUrls = ConfigurationService.GetConfigValue(LauncherConVar.AuthServers)!; foreach (var url in authUrls) AuthUrls.Add(url); + if(authUrls.Length > 0) CurrentAuthServer = authUrls[0]; var currProfile = ConfigurationService.GetConfigValue(LauncherConVar.AuthCurrent); diff --git a/Nebula.Launcher/ViewModels/Pages/ContentBrowserViewModel.cs b/Nebula.Launcher/ViewModels/Pages/ContentBrowserViewModel.cs index f680e81..c4a2439 100644 --- a/Nebula.Launcher/ViewModels/Pages/ContentBrowserViewModel.cs +++ b/Nebula.Launcher/ViewModels/Pages/ContentBrowserViewModel.cs @@ -12,6 +12,7 @@ using Avalonia.Media.Imaging; using Avalonia.Platform; using CommunityToolkit.Mvvm.ComponentModel; using Nebula.Launcher.Services; +using Nebula.Launcher.ViewModels.ContentView; using Nebula.Launcher.ViewModels.Popup; using Nebula.Launcher.Views.Pages; using Nebula.Shared.Models; @@ -33,6 +34,10 @@ public sealed partial class ContentBrowserViewModel : ViewModelBase , IViewModel private ContentEntry? _selectedEntry; [ObservableProperty] private string _serverText = ""; + [ObservableProperty] private ContentViewBase? _contentView; + public bool IsCustomContenView => ContentView != null; + + [GenerateProperty] private ContentService ContentService { get; } = default!; [GenerateProperty] private CancellationService CancellationService { get; } = default!; [GenerateProperty] private FileService FileService { get; } = default!; @@ -43,16 +48,26 @@ public sealed partial class ContentBrowserViewModel : ViewModelBase , IViewModel public ObservableCollection Entries { get; } = new(); + private Dictionary _contentContainers = new(); + public ContentEntry? SelectedEntry { get => _selectedEntry; set { + SearchText = value?.GetPath().ToString() ?? ""; + ContentView = null; + if (value is { Item: not null }) { if (FileService.ContentFileApi.TryOpen(value.Item.Value.Hash, out var stream)) { var ext = Path.GetExtension(value.Item.Value.Path); + if(TryGetContentViewer(ext, out var contentViewBase)){ + contentViewBase.InitialiseWithData(value.GetPath(), stream); + ContentView = contentViewBase; + return; + } var myTempFile = Path.Combine(Path.GetTempPath(), "tempie" + ext); @@ -83,6 +98,17 @@ public sealed partial class ContentBrowserViewModel : ViewModelBase , IViewModel } } + private bool TryGetContentViewer(string type,[NotNullWhen(true)] out ContentViewBase? contentViewBase){ + contentViewBase = null; + if(!_contentContainers.TryGetValue(type, out var contentViewType) || + !contentViewType.IsAssignableTo(typeof(ContentViewBase))) + return false; + + + contentViewBase = (ContentViewBase)Activator.CreateInstance(contentViewType)!; + return true; + } + protected override void InitialiseInDesignMode() { @@ -144,15 +170,10 @@ public sealed partial class ContentBrowserViewModel : ViewModelBase , IViewModel if (SelectedEntry == null || !SelectedEntry.GetRoot().TryGetEntry(path, out var centry)) throw new Exception("Not found! " + oriPath.Path); - if (appendHistory) AppendHistory(SearchText); - SearchText = oriPath.Path; - SelectedEntry = centry; } catch (Exception e) { - Console.WriteLine(e); - SearchText = oriPath.Path; PopupService.Popup(e); } } @@ -170,11 +191,12 @@ public sealed partial class ContentBrowserViewModel : ViewModelBase , IViewModel private async Task CreateEntry(string serverUrl) { - var rurl = serverUrl.ToRobustUrl(); - var info = await ContentService.GetBuildInfo(rurl, CancellationService.Token); var loading = ViewHelperService.GetViewModel(); loading.LoadingName = "Loading entry"; PopupService.Popup(loading); + + var rurl = serverUrl.ToRobustUrl(); + var info = await ContentService.GetBuildInfo(rurl, CancellationService.Token); var items = await ContentService.EnsureItems(info.RobustManifestInfo, loading, CancellationService.Token); diff --git a/Nebula.Launcher/ViewModels/Pages/ServerListViewModel.cs b/Nebula.Launcher/ViewModels/Pages/ServerListViewModel.cs index 99d4a92..97b9c8f 100644 --- a/Nebula.Launcher/ViewModels/Pages/ServerListViewModel.cs +++ b/Nebula.Launcher/ViewModels/Pages/ServerListViewModel.cs @@ -40,14 +40,14 @@ public partial class ServerListViewModel : ViewModelBase, IViewModelPage //Design think protected override void InitialiseInDesignMode() { - ServerViewContainer = new ServerViewContainer(this, RestService, CancellationService, DebugService, ViewHelperService); + ServerViewContainer = new ServerViewContainer(this, ViewHelperService); HubErrors.Add(new Exception("UVI")); } //real think protected override void Initialise() { - ServerViewContainer = new ServerViewContainer(this, RestService, CancellationService, DebugService, ViewHelperService); + ServerViewContainer = new ServerViewContainer(this, ViewHelperService); foreach (var info in HubService.ServerList) UnsortedServers.Add(info); @@ -142,10 +142,7 @@ public partial class ServerListViewModel : ViewModelBase, IViewModelPage } public class ServerViewContainer( - ServerListViewModel serverListViewModel, - RestService restService, - CancellationService cancellationService, - DebugService debugService, + ServerListViewModel serverListViewModel, ViewHelperService viewHelperService ) { @@ -210,13 +207,6 @@ public class ServerComparer : IComparer, IComparer, public int Compare((RobustUrl, ServerStatus) x, (RobustUrl, ServerStatus) y) { - if (ReferenceEquals(x, y)) - return 0; - if (ReferenceEquals(null, y)) - return 1; - if (ReferenceEquals(null, x)) - return -1; - return Compare(x.Item2, y.Item2); } } \ No newline at end of file diff --git a/Nebula.Launcher/ViewModels/Popup/LoadingContextViewModel.cs b/Nebula.Launcher/ViewModels/Popup/LoadingContextViewModel.cs index bde49c7..5cf5bdb 100644 --- a/Nebula.Launcher/ViewModels/Popup/LoadingContextViewModel.cs +++ b/Nebula.Launcher/ViewModels/Popup/LoadingContextViewModel.cs @@ -10,6 +10,7 @@ namespace Nebula.Launcher.ViewModels.Popup; public sealed partial class LoadingContextViewModel : PopupViewModelBase, ILoadingHandler { [GenerateProperty] public override PopupMessageService PopupMessageService { get; } + [GenerateProperty] public CancellationService CancellationService { get; } [ObservableProperty] private int _currJobs; @@ -40,6 +41,11 @@ public sealed partial class LoadingContextViewModel : PopupViewModelBase, ILoadi return ResolvedJobs; } + public void Cancel(){ + CancellationService.Cancel(); + Dispose(); + } + protected override void Initialise() { } diff --git a/Nebula.Launcher/ViewModels/ServerEntryModelView.cs b/Nebula.Launcher/ViewModels/ServerEntryModelView.cs index af5762f..208e566 100644 --- a/Nebula.Launcher/ViewModels/ServerEntryModelView.cs +++ b/Nebula.Launcher/ViewModels/ServerEntryModelView.cs @@ -58,6 +58,8 @@ public partial class ServerEntryModelView : ViewModelBase private ServerInfo? _serverInfo = null; + private string _lastError = ""; + public async Task GetServerInfo() { if (_serverInfo == null) @@ -232,6 +234,9 @@ public partial class ServerEntryModelView : ViewModelBase DebugService.Log("PROCESS EXIT WITH CODE " + Process.ExitCode); + if(Process.ExitCode != 0) + PopupMessageService.Popup($"Game exit with code {Process.ExitCode}.\nReason: {_lastError}"); + Process.Dispose(); Process = null; } @@ -240,6 +245,7 @@ public partial class ServerEntryModelView : ViewModelBase { if (e.Data != null) { + _lastError = e.Data; DebugService.Error(e.Data); CurrLog.Append(e.Data); } diff --git a/Nebula.Launcher/Views/Pages/AccountInfoView.axaml b/Nebula.Launcher/Views/Pages/AccountInfoView.axaml index 2040c39..ece2fdf 100644 --- a/Nebula.Launcher/Views/Pages/AccountInfoView.axaml +++ b/Nebula.Launcher/Views/Pages/AccountInfoView.axaml @@ -13,7 +13,7 @@ @@ -40,7 +40,7 @@ @@ -50,7 +50,6 @@ - @@ -107,19 +106,19 @@ - + - + - + @@ -136,7 +135,7 @@ ItemsSource="{Binding AuthUrls}" Margin="5" SelectedItem="{Binding AuthItemSelect}" - SelectionMode="Toggle"> + SelectionMode="Single"> + + +