3 Commits

Author SHA1 Message Date
f6a15e9c45 - add: multiauth 2025-07-15 18:38:53 +03:00
c148f6ed34 - add: nice error view 2025-07-14 10:06:38 +03:00
a475148543 - tweak: a little bit of repair and tweaks 2025-07-13 10:07:36 +03:00
25 changed files with 294 additions and 92 deletions

View File

@@ -45,6 +45,7 @@
<entry key="Nebula.Launcher/Views/ServerListView.axaml" value="Nebula.Launcher/Nebula.Launcher.csproj" />
<entry key="Nebula.Launcher/Views/Tabs/AccountInfoTab.axaml" value="Nebula.Launcher/Nebula.Launcher.csproj" />
<entry key="Nebula.Launcher/Views/Tabs/ServerListTab.axaml" value="Nebula.Launcher/Nebula.Launcher.csproj" />
<entry key="Nebula.Launcher/Views/VisualErrorView.axaml" value="Nebula.Launcher/Nebula.Launcher.csproj" />
<entry key="Nebula.UpdateResolver/App.axaml" value="Nebula.UpdateResolver/Nebula.UpdateResolver.csproj" />
<entry key="Nebula.UpdateResolver/MainWindow.axaml" value="Nebula.UpdateResolver/Nebula.UpdateResolver.csproj" />
</map>

View File

@@ -28,14 +28,16 @@ public class App : Application
{
case IClassicDesktopStyleApplicationLifetime desktop:
DisableAvaloniaDataAnnotationValidation();
desktop.MainWindow = new MessageWindow(out provider);
desktop.MainWindow = (Window)(provider = new MessageWindow());
break;
case ISingleViewApplicationLifetime singleViewPlatform:
singleViewPlatform.MainView = new MessageView(out provider);
singleViewPlatform.MainView = (Control)(provider = new MessageView());
break;
}
provider?.ShowMessage("Launcher is already running.","hey shithead!");
provider?.ShowMessage(
"Error: An instance of the application is already running. Please close the existing instance before launching a new one.",
"Duplicate instance detected.");
return;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 KiB

View File

@@ -24,8 +24,9 @@ account-auth-server = Authentication Server
account-auth-button = Authenticate
account-auth-save = Save Profile
account-auth-hello = Hello,
account-auth-current-server = Current server auth:
account-auth-logout = Log out
auth-current-login-name = Current login: {$login}
auth-current-login-name = Current login {$auth_server}: {$login}
auth-current-login-no-name = Profile not selected
auth-processing = Processing authentication request...
@@ -37,6 +38,7 @@ auth-name-resolution-error = Failed to resolve server address. Check your networ
auth-secure-error = Failed to cinnect to the server using SSL
auth-config-read = Reading authentication configuration...
auth-try-auth-config = Attempting to authenticate using saved configuration.
auth-try-auth-profile = Attempting to authenticate using profile
config-export-logs = Export logs
config-open-data = Open data path

View File

@@ -24,8 +24,9 @@ account-auth-server = Сервер аутентификации
account-auth-button = Аутентифицировать
account-auth-save = Сохранить профиль
account-auth-hello = Привет,
account-auth-current-server = Текущий сервер авторизации:
account-auth-logout = Выйти
auth-current-login-name = Текущий профиль: {$login}
auth-current-login-name = Текущий профиль {$auth_server}: {$login}
auth-current-login-no-name = Профиль не выбран
auth-processing = Обработка запроса аутентификации...
@@ -37,6 +38,7 @@ auth-name-resolution-error = Не удалось разрешить адрес
auth-secure-error = Не удалось подключиться к серверу по SSL. Проверьте сетевые настройки.
auth-config-read = Чтение конфигурации аутентификации...
auth-try-auth-config = Попытка аутентификации с использованием сохраненной конфигурации.
auth-try-auth-profile = Попытка аутентификации с использованием профиля
config-export-logs = Экспортировать логи
config-open-data = Открыть путь данных

View File

@@ -1,11 +1,11 @@
using Avalonia;
using Avalonia.Controls;
using System;
using Avalonia.Data.Converters;
using Avalonia.Media;
using Avalonia.Platform;
namespace Nebula.Launcher.Converters;
public class TypeConverters
public static class TypeConverters
{
public static FuncValueConverter<string, string?> IconConverter { get; } =
new(iconKey =>
@@ -13,4 +13,11 @@ public class TypeConverters
if (iconKey == null) return null;
return $"/Assets/svg/{iconKey}.svg";
});
public static FuncValueConverter<string, IImage?> ImageConverter { get; } =
new(iconKey =>
{
if (iconKey == null) return null;
return new Avalonia.Media.Imaging.Bitmap(AssetLoader.Open(new Uri($"avares://Nebula.Launcher/Assets/error_presentation/{iconKey}.png")));
});
}

View File

@@ -2,8 +2,8 @@ using System.Collections.Generic;
using System.Globalization;
using Nebula.Launcher.Models;
using Nebula.Launcher.Models.Auth;
using Nebula.Shared.ConfigMigrations;
using Nebula.Shared.Services;
using Nebula.Shared.Services.ConfigMigrations;
namespace Nebula.Launcher;
@@ -34,7 +34,13 @@ public static class LauncherConVar
"WizDen",
[
"https://harpy.durenko.tatar/auth-api/",
"https://auth.spacestation14.com/",
"https://auth.fallback.spacestation14.com/",
]),
new AuthServerCredentials(
"SimpleStation",
[
"https://auth.simplestation.org/",
])
]);

View File

@@ -2,16 +2,9 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:views="clr-namespace:Nebula.Launcher.Views"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
Width="600"
Height="400"
x:Class="Nebula.Launcher.MessageBox.MessageView">
<Grid RowDefinitions="50,*" ColumnDefinitions="*">
<Border Grid.Column="0" Background="#222222" Padding="10" BorderBrush="#444444" BorderThickness="0,0,0,3">
<Label VerticalAlignment="Center" x:Name="Title">Text</Label>
</Border>
<Panel Margin="5" Grid.Row="1">
<Label x:Name="Message">Message</Label>
</Panel>
</Grid>
<views:VisualErrorView x:Name="ErrorView"/>
</UserControl>

View File

@@ -1,21 +1,22 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using Nebula.Launcher.ViewModels;
namespace Nebula.Launcher.MessageBox;
public partial class MessageView : UserControl, IMessageContainerProvider
{
public MessageView(out IMessageContainerProvider provider)
private readonly VisualErrorViewModel _context;
public MessageView()
{
InitializeComponent();
provider = this;
_context = new VisualErrorViewModel();
ErrorView.Content = _context;
}
public void ShowMessage(string message, string title)
{
Title.Content = title;
Message.Content = message;
_context.Title = title;
_context.Description = message;
}
}

View File

@@ -3,10 +3,52 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:messageBox="clr-namespace:Nebula.Launcher.MessageBox"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
SystemDecorations="BorderOnly"
mc:Ignorable="d" d:DesignWidth="600" d:DesignHeight="260"
Width="600"
Height="400"
Height="260"
CanResize="False"
x:Class="Nebula.Launcher.MessageBox.MessageWindow"
Title="MessageWindow">
<Grid ColumnDefinitions="*" RowDefinitions="30,*">
<messageBox:MessageView
Grid.Column="0"
Grid.Row="0"
Grid.RowSpan="2"
x:Name="MessageView" />
<Border
BorderThickness="0,0,0,2"
CornerRadius="0"
Grid.Column="0"
Grid.Row="0">
<Border.BorderBrush>
<LinearGradientBrush EndPoint="100%,50%" StartPoint="0%,50%">
<GradientStop Color="#222222" Offset="0.0" />
<GradientStop Color="#442222" Offset="1.0" />
</LinearGradientBrush>
</Border.BorderBrush>
<Panel
Height="30"
PointerPressed="InputElement_OnPointerPressed">
<TextBlock
FontSize="10"
Foreground="White"
IsVisible="False"
Margin="15,0"
Text="Nebula Launcher"
VerticalAlignment="Center" />
<StackPanel
HorizontalAlignment="Right"
Margin="5,0,5,0"
Orientation="Horizontal"
Spacing="8">
<Button
Click="Close_Click"
Content="🗙"
Foreground="Azure" />
</StackPanel>
</Panel>
</Border>
</Grid>
</Window>

View File

@@ -1,12 +1,28 @@
using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Interactivity;
namespace Nebula.Launcher.MessageBox;
public partial class MessageWindow : Window
public partial class MessageWindow : Window, IMessageContainerProvider
{
public MessageWindow(out IMessageContainerProvider provider)
public MessageWindow()
{
InitializeComponent();
Content = new MessageView(out provider);
}
public void ShowMessage(string message, string title)
{
MessageView.ShowMessage(message, title);
}
private void Close_Click(object? sender, RoutedEventArgs e)
{
Close();
}
private void InputElement_OnPointerPressed(object? sender, PointerPressedEventArgs e)
{
BeginMoveDrag(e);
}
}

View File

@@ -1,10 +1,13 @@
using System.Text.Json.Serialization;
using System.Windows.Input;
using Avalonia.Media;
using Nebula.Shared.Services;
namespace Nebula.Launcher.Models.Auth;
public sealed record ProfileAuthCredentials(
AuthTokenCredentials Credentials,
AuthTokenCredentials Credentials,
string AuthName,
Color Color,
[property: JsonIgnore] ICommand OnSelect = default!,
[property: JsonIgnore] ICommand OnDelete = default!);

View File

@@ -9,7 +9,7 @@ using Nebula.Shared.Services;
namespace Nebula.Launcher.ProcessHelper;
[ServiceRegister]
public sealed class GameRunnerPreparer(IServiceProvider provider, ContentService contentService, EngineService engineService, DebugService debugService)
public sealed class GameRunnerPreparer(IServiceProvider provider, ContentService contentService, EngineService engineService)
{
public async Task<ProcessRunHandler<GameProcessStartInfoProvider>> GetGameProcessStartInfoProvider(RobustUrl address, ILoadingHandler loadingHandler, CancellationToken cancellationToken = default)
{

View File

@@ -14,7 +14,8 @@ namespace Nebula.Launcher.Services;
public partial class LocalisationService
{
[GenerateProperty] private ConfigurationService ConfigurationService { get; }
[GenerateProperty] private DebugService DebugService { get; }
private CultureInfo _currentCultureInfo = CultureInfo.CurrentCulture;
private static MessageContext? _currentMessageContext;
@@ -42,6 +43,7 @@ public partial class LocalisationService
_currentMessageContext = mc;
} catch (Exception e) {
DebugService.GetLogger("localisationService").Error(e);
LoadLanguage(CultureInfo.GetCultureInfo("en-US"));
}
}

View File

@@ -42,12 +42,12 @@ public partial class MainViewModel : ViewModelBase
[ObservableProperty] private ListItemTemplate? _selectedListItem;
public bool IsLoggedIn => AccountInfoViewModel.Credentials is not null;
public string LoginName => AccountInfoViewModel.Credentials?.Login ?? string.Empty;
public string LoginText => LocalisationService.GetString("auth-current-login-name",
new Dictionary<string, object>
{
{ "login", LoginName }
{ "login", AccountInfoViewModel.Credentials?.Login ?? "" },
{ "auth_server", AccountInfoViewModel.CurrentAuthServerName}
});
[GenerateProperty] private LocalisationService LocalisationService { get; } // Не убирать! Без этой хуйни вся локализация идет в пизду!

View File

@@ -3,7 +3,10 @@ using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Net.Http;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using Avalonia.Media;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using Nebula.Launcher.Models.Auth;
@@ -23,20 +26,15 @@ namespace Nebula.Launcher.ViewModels.Pages;
public partial class AccountInfoViewModel : ViewModelBase
{
[ObservableProperty] private bool _authMenuExpand;
[ObservableProperty] private bool _authUrlConfigExpand;
[ObservableProperty] private int _authViewSpan = 1;
[ObservableProperty] private string _currentAuthServer = string.Empty;
[ObservableProperty] private string _currentLogin = string.Empty;
[ObservableProperty] private string _currentPassword = string.Empty;
[ObservableProperty] private bool _isLogged;
[ObservableProperty] private bool _doRetryAuth;
[ObservableProperty] private AuthTokenCredentials? _credentials;
[ObservableProperty] private AuthServerCredentials _authItemSelect;
private bool _isProfilesEmpty;
[GenerateProperty] private PopupMessageService PopupMessageService { get; } = default!;
@@ -47,18 +45,22 @@ public partial class AccountInfoViewModel : ViewModelBase
public ObservableCollection<ProfileAuthCredentials> Accounts { get; } = new();
public ObservableCollection<AuthServerCredentials> AuthUrls { get; } = new();
[ObservableProperty] private AuthServerCredentials _authItemSelect;
public string CurrentAuthServerName => GetServerAuthName(Credentials);
private ILogger _logger;
partial void OnCredentialsChanged(AuthTokenCredentials? value)
{
OnPropertyChanged(nameof(CurrentAuthServerName));
}
//Design think
protected override void InitialiseInDesignMode()
{
AddAccount(new AuthTokenCredentials(Guid.Empty, LoginToken.Empty, "Binka", ""));
AddAccount(new AuthTokenCredentials(Guid.Empty, LoginToken.Empty, "Binka", ""));
AuthUrls.Add(new AuthServerCredentials("Test",["example.com"]));
AddAccount(new AuthTokenCredentials(Guid.Empty, LoginToken.Empty, "Binka", "example.com"));
AddAccount(new AuthTokenCredentials(Guid.Empty, LoginToken.Empty, "Binka", ""));
}
//Real think
@@ -225,6 +227,13 @@ public partial class AccountInfoViewModel : ViewModelBase
{
IsLogged = false;
Credentials = null;
CurrentAuthServer = "";
}
public string GetServerAuthName(AuthTokenCredentials? credentials)
{
if (credentials is null) return "";
return AuthUrls.FirstOrDefault(p => p.Servers.Contains(credentials.AuthServer))?.Name ?? "CustomAuth";
}
private void UpdateAuthMenu()
@@ -239,9 +248,13 @@ public partial class AccountInfoViewModel : ViewModelBase
{
var onDelete = new DelegateCommand<ProfileAuthCredentials>(OnDeleteProfile);
var onSelect = new DelegateCommand<ProfileAuthCredentials>(AuthByProfile);
var serverName = GetServerAuthName(credentials);
var alpm = new ProfileAuthCredentials(
credentials,
serverName,
ColorUtils.GetColorFromString(credentials.AuthServer),
onSelect,
onDelete);
@@ -257,16 +270,18 @@ public partial class AccountInfoViewModel : ViewModelBase
message.InfoText = LocalisationService.GetString("auth-config-read");
message.IsInfoClosable = false;
PopupMessageService.Popup(message);
AuthUrls.Clear();
var authUrls = ConfigurationService.GetConfigValue(LauncherConVar.AuthServers)!;
foreach (var url in authUrls) AuthUrls.Add(url);
if(authUrls.Length > 0) AuthItemSelect = authUrls[0];
foreach (var profile in
ConfigurationService.GetConfigValue(LauncherConVar.AuthProfiles)!)
AddAccount(profile);
if (Accounts.Count == 0) UpdateAuthMenu();
AuthUrls.Clear();
var authUrls = ConfigurationService.GetConfigValue(LauncherConVar.AuthServers)!;
foreach (var url in authUrls) AuthUrls.Add(url);
if(authUrls.Length > 0) AuthItemSelect = authUrls[0];
message.Dispose();
DoCurrentAuth();
@@ -347,4 +362,18 @@ public partial class AccountInfoViewModel : ViewModelBase
ConfigurationService.SetConfigValue(LauncherConVar.AuthProfiles,
Accounts.Select(a => a.Credentials).ToArray());
}
}
public static class ColorUtils
{
public static Color GetColorFromString(string input)
{
var hash = MD5.HashData(Encoding.UTF8.GetBytes(input));
var r = byte.Clamp(hash[0], 10, 200);
var g = byte.Clamp(hash[1], 10, 100);
var b = byte.Clamp(hash[2], 10, 100);
return Color.FromArgb(Byte.MaxValue, r, g, b);
}
}

View File

@@ -7,7 +7,6 @@ using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using Avalonia;
using Avalonia.Controls;
@@ -195,7 +194,7 @@ public sealed class ComplexUnitConfigControl : Border, IConfigControl
var propValue = propInfo.GetValue(value);
var control = ConfigControlHelper.GetConfigControl(propInfo.Name, propValue);
var control = ConfigControlHelper.GetConfigControl(propInfo.Name, propValue!);
((Control)control).Margin = new Thickness(5);
_panel.Children.Add((Control)control);
@@ -211,7 +210,7 @@ public sealed class ComplexUnitConfigControl : Border, IConfigControl
fieldInfo.SetValue(obj, configControl.GetValue());
}
return obj;
return obj!;
}
}

View File

@@ -0,0 +1,22 @@
using CommunityToolkit.Mvvm.ComponentModel;
using Nebula.Launcher.Views;
using Nebula.Shared.ViewHelper;
namespace Nebula.Launcher.ViewModels;
[ViewModelRegister(typeof(VisualErrorView))]
public partial class VisualErrorViewModel : ViewModelBase
{
[ObservableProperty] private string _imgPath = "cinka";
[ObservableProperty] private string _title = "Error";
[ObservableProperty] private string _description = "This is an error.";
protected override void InitialiseInDesignMode()
{
}
protected override void Initialise()
{
}
}

View File

@@ -1,6 +1,6 @@
<UserControl
d:DesignHeight="450"
d:DesignWidth="800"
d:DesignWidth="1000"
mc:Ignorable="d"
x:Class="Nebula.Launcher.Views.Pages.AccountInfoView"
x:DataType="pages:AccountInfoViewModel"
@@ -39,39 +39,56 @@
Padding="0">
<ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type auth:ProfileAuthCredentials}">
<Border
BoxShadow="0 1 15 -2 #121212"
CornerRadius="0,10,0,10"
Margin="5,5,5,0"
VerticalAlignment="Center">
<Border.Background>
<LinearGradientBrush EndPoint="50%,100%" StartPoint="50%,0%">
<GradientStop Color="#292222" Offset="0.0" />
<GradientStop Color="#222222" Offset="1.0" />
</LinearGradientBrush>
</Border.Background>
<Panel>
<StackPanel Margin="10,5,5,5" Orientation="Horizontal">
<Grid ColumnDefinitions="4*,*">
<Border
BoxShadow="0 1 15 -2 #121212"
CornerRadius="0,10,0,10"
Margin="5,5,5,0">
<Border.Background>
<LinearGradientBrush EndPoint="100%,50%" StartPoint="20%,50%">
<GradientStop Color="{Binding Color}" Offset="0.0" />
<GradientStop Color="#222222" Offset="1.0" />
</LinearGradientBrush>
</Border.Background>
<Label>
<TextBlock Text="{Binding AuthName}" Margin="5"/>
</Label>
</Border>
<Border Grid.Column="0"
CornerRadius="0,10,0,10"
Margin="5,5,5,0">
<Border.Background>
<LinearGradientBrush EndPoint="100%,50%" StartPoint="20%,50%">
<GradientStop Color="#aa222222" Offset="0.0" />
<GradientStop Color="#222222" Offset="0.4" />
</LinearGradientBrush>
</Border.Background>
<Button
HorizontalAlignment="Stretch"
Command="{Binding OnSelect}">
<Label>
<TextBlock Text="{Binding Credentials.Login}" />
<TextBlock Text="{Binding Credentials.Login}" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="0,0,5,0"/>
</Label>
</StackPanel>
<StackPanel HorizontalAlignment="Right" Orientation="Horizontal">
<Button
Command="{Binding OnSelect}"
CornerRadius="0,0,0,10"
Padding="5">
<customControls:LocalizedLabel LocalId="account-profile-select"/>
</Button>
<Button
Command="{Binding OnDelete}"
CornerRadius="0,10,0,0"
Padding="5">
<customControls:LocalizedLabel LocalId="account-profile-delete"/>
</Button>
</StackPanel>
</Panel>
</Border>
</Button>
</Border>
<Border
BoxShadow="0 1 15 -2 #121212"
CornerRadius="0,10,0,10"
Margin="0,5,5,0" Grid.Column="1" Padding="0">
<Border.Background>
<LinearGradientBrush EndPoint="100%,50%" StartPoint="20%,50%">
<GradientStop Color="#292222" Offset="1.0" />
<GradientStop Color="#222222" Offset="1.0" />
</LinearGradientBrush>
</Border.Background>
<Button Command="{Binding OnDelete}" CornerRadius="0,10,0,10" HorizontalAlignment="Stretch">
<Svg
Height="15"
Path="/Assets/svg/delete.svg"
Width="15" />
</Button>
</Border>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
@@ -169,9 +186,15 @@
Margin="0,0,0,20"
Path="/Assets/svg/user.svg" />
<Label>
<StackPanel HorizontalAlignment="Center" Orientation="Horizontal">
<customControls:LocalizedLabel LocalId="account-auth-hello"/>
<TextBlock Text="{Binding CurrentLogin}" />
<StackPanel>
<StackPanel HorizontalAlignment="Center" Orientation="Horizontal" Spacing="5">
<customControls:LocalizedLabel LocalId="account-auth-hello"/>
<TextBlock Text="{Binding CurrentLogin}" />
</StackPanel>
<StackPanel HorizontalAlignment="Center" Orientation="Horizontal" Spacing="5">
<customControls:LocalizedLabel LocalId="account-auth-current-server"/>
<TextBlock Text="{Binding CurrentAuthServerName}" />
</StackPanel>
</StackPanel>
</Label>
<StackPanel

View File

@@ -0,0 +1,39 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:viewModels="clr-namespace:Nebula.Launcher.ViewModels"
xmlns:converters="clr-namespace:Nebula.Launcher.Converters"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:DataType="viewModels:VisualErrorViewModel"
x:Class="Nebula.Launcher.Views.VisualErrorView">
<Design.DataContext>
<viewModels:VisualErrorViewModel />
</Design.DataContext>
<Grid RowDefinitions="30,*" ColumnDefinitions="200,*">
<Border Grid.Row="1" Grid.Column="0"
CornerRadius="10,0,0,10"
BorderThickness="0,0,2,0"
BorderBrush="{StaticResource DefaultForeground}">
<Image Source="{Binding ImgPath, Converter={x:Static converters:TypeConverters.ImageConverter}}" Width="200" Height="200"/>
</Border>
<Border Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" CornerRadius="10,10,0,0">
<Border.Background>
<LinearGradientBrush EndPoint="100%,50%" StartPoint="10%,20%">
<GradientStop Color="#FF6B6B" Offset="0.0" />
<GradientStop Color="#FF8E53" Offset="0.3" />
<GradientStop Color="#FF5E3A" Offset="0.6" />
<GradientStop Color="#FF5e5e" Offset="1.0" />
</LinearGradientBrush>
</Border.Background>
<Label HorizontalAlignment="Center"><TextBlock Text="{Binding Title}"/></Label>
</Border>
<TextBlock
Grid.Row="1"
Grid.Column="1"
Margin="15"
HorizontalAlignment="Center"
TextWrapping="Wrap"
Text="{Binding Description}"/>
</Grid>
</UserControl>

View File

@@ -0,0 +1,11 @@
using Avalonia.Controls;
namespace Nebula.Launcher.Views;
public partial class VisualErrorView : UserControl
{
public VisualErrorView()
{
InitializeComponent();
}
}

View File

@@ -1,6 +1,5 @@
using Microsoft.Extensions.DependencyInjection;
using Nebula.Shared;
using Nebula.Shared.Services;
namespace Nebula.Runner;

View File

@@ -1,7 +1,8 @@
using Microsoft.Extensions.DependencyInjection;
using Nebula.Shared.Models;
using Nebula.Shared.Services;
namespace Nebula.Shared.Services.ConfigMigrations;
namespace Nebula.Shared.ConfigMigrations;
public class ProfileMigrationV2(string oldName, string newName)
: BaseConfigurationMigration<ProfileAuthCredentialsV2[], AuthTokenCredentials[]>(oldName, newName)

View File

@@ -20,6 +20,7 @@
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AFileShare_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fa6b7f037ba7b44df80b8d3aa7e58eeb2e8e938_003F54_003Fc3f4f140_003FFileShare_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AFile_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F3f31e7e8aa33de883c2ccfa62a9c81bfc246c36e825b489476f9472032e512_003FFile_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AFrozenDictionary_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F89dff9063ddb01ff8125b579122b88bf4de94526490d77bcbbef7d0ee662a_003FFrozenDictionary_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AFuncValueConverter_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003Fe91c13e7e24d7ba324e0e6eb12a24ea8c7761299d3c4703e55c86dd120835e61_003FFuncValueConverter_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AFuture_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003Fb3575a2f41d7c2dbfaa36e866b8a361e11dd7223ff82bc574c1d5d4b7522f735_003FFuture_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AHttpClient_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003Fc439425da351c75ac7d966a1cc8324b51a9c471865af79d2f2f3fcb65e392_003FHttpClient_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AHttpContent_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F9657cc383c70851dc2bdcf91eff27f21196844abfe552fc9c3243ff36974cd_003FHttpContent_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
@@ -32,6 +33,7 @@
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AHttpResponseMessage_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F4cfeb8b377bc81e1fbb5f7d7a02492cb6ac23e88c8c9d7155944f0716f3d4b_003FHttpResponseMessage_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AIDispatcherImpl_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F22d92db124764b1ab49745245c66f01b1e1a00_003F0f_003F01061787_003FIDispatcherImpl_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AIDisposable_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fa6b7f037ba7b44df80b8d3aa7e58eeb2e8e938_003F98_003Fd1b23281_003FIDisposable_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AImage_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F2b95745d8f2ddf7b8ad6130e01c5b2782e253ff11247a9aeefcef47277b1ab_003FImage_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AIndex_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F2a1a813823579c69832f1304f97761e7be433bd6aa928f351d138050b56a38_003FIndex_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AInt32_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003Fa882d183338544fdbcbdfc7b6d3dcb78916630765551644a221b5be9c45a121b_003FInt32_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AInterop_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fc4d71b51722245ae8cde97bfd996e68386928_003F3a_003F004a1338_003FInterop_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>