- add: Config page fully

This commit is contained in:
2025-06-18 21:36:50 +03:00
parent a7943adb76
commit 73682acbab
10 changed files with 331 additions and 158 deletions

View File

@@ -12,6 +12,7 @@
<entry key="Nebula.Launcher/MessageBox/MessageView.axaml" value="Nebula.Launcher/Nebula.Launcher.csproj" />
<entry key="Nebula.Launcher/MessageBox/MessageWindow.axaml" value="Nebula.Launcher/Nebula.Launcher.csproj" />
<entry key="Nebula.Launcher/ViewModels/Styles1.axaml" value="Nebula.Launcher/Nebula.Launcher.csproj" />
<entry key="Nebula.Launcher/Views/Config/StringConfigurationView.axaml" value="Nebula.Launcher/Nebula.Launcher.csproj" />
<entry key="Nebula.Launcher/Views/Controls/PlayerContainerControl.axaml" value="Nebula.Launcher/Nebula.Launcher.csproj" />
<entry key="Nebula.Launcher/Views/Controls/ServerContainerControl.axaml" value="Nebula.Launcher/Nebula.Launcher.csproj" />
<entry key="Nebula.Launcher/Views/ExceptionView.axaml" value="Nebula.Launcher/Nebula.Launcher.csproj" />
@@ -21,6 +22,7 @@
<entry key="Nebula.Launcher/Views/Pages/AccountInfoPage.axaml" value="Nebula.Launcher/Nebula.Launcher.csproj" />
<entry key="Nebula.Launcher/Views/Pages/AccountInfoView.axaml" value="Nebula.Launcher/Nebula.Launcher.csproj" />
<entry key="Nebula.Launcher/Views/Pages/AddFavoriteView.axaml" value="Nebula.Launcher/Nebula.Launcher.csproj" />
<entry key="Nebula.Launcher/Views/Pages/ConfigurationView.axaml" value="Nebula.Launcher/Nebula.Launcher.csproj" />
<entry key="Nebula.Launcher/Views/Pages/ContentBrowserView.axaml" value="Nebula.Launcher/Nebula.Launcher.csproj" />
<entry key="Nebula.Launcher/Views/Pages/FavoriteServerListView.axaml" value="Nebula.Launcher/Nebula.Launcher.csproj" />
<entry key="Nebula.Launcher/Views/Pages/ServerListPage.axaml" value="Nebula.Launcher/Nebula.Launcher.csproj" />

View File

@@ -26,8 +26,8 @@ public static class LauncherConVar
]);
public static readonly ConVar<ServerHubRecord[]> Hub = ConVarBuilder.Build<ServerHubRecord[]>("launcher.hub.v2", [
new ServerHubRecord("WizDen", "https://harpy.durenko.tatar/hub-api/api/servers", null),
new ServerHubRecord("AltHub","https://web.networkgamez.com/api/servers",null)
new ServerHubRecord("WizDen", "https://harpy.durenko.tatar/hub-api/api/servers"),
new ServerHubRecord("AltHub","https://web.networkgamez.com/api/servers")
]);
public static readonly ConVar<string> CurrentLang = ConVarBuilder.Build<string>("launcher.language", "en-US");

View File

@@ -8,5 +8,4 @@ public record ListItemTemplate(Type ModelType, string IconKey, string Label);
public record ServerListTabTemplate(IServerListProvider ServerListProvider, string TabName);
public record ServerHubRecord(
[property:JsonPropertyName("name")] string Name,
[property:JsonPropertyName("url")] string MainUrl,
[property:JsonPropertyName("fallback")] string? Fallback);
[property:JsonPropertyName("url")] string MainUrl);

View File

@@ -78,4 +78,8 @@
<ItemGroup>
<AdditionalFiles Include="Controls\ServerListView.axaml" />
</ItemGroup>
<ItemGroup>
<Folder Include="Views\Config\" />
</ItemGroup>
</Project>

View File

@@ -262,8 +262,7 @@ public sealed record ProfileAuthCredentials(
string Password,
string AuthServer,
[property: JsonIgnore] ICommand OnSelect = default!,
[property: JsonIgnore] ICommand OnDelete = default!
);
[property: JsonIgnore] ICommand OnDelete = default!);
public sealed record AuthServerCredentials(
string Name,

View File

@@ -1,142 +1,349 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Runtime.CompilerServices;
using CommunityToolkit.Mvvm.ComponentModel;
using Microsoft.Extensions.DependencyInjection;
using Nebula.Launcher.Views.Config;
using System.Reflection;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Layout;
using Nebula.Launcher.Views.Pages;
using Nebula.Shared;
using Nebula.Shared.Services;
using BindingFlags = System.Reflection.BindingFlags;
namespace Nebula.Launcher.ViewModels.Pages;
[ViewModelRegister(typeof(ConfigurationView))]
[ConstructGenerator]
public partial class ConfigurationViewModel : ViewModelBase, IConfigContext
public partial class ConfigurationViewModel : ViewModelBase
{
public ObservableCollection<ViewModelBase> ConfigurationVerbose { get; } = new();
public ObservableCollection<IConfigControl> ConfigurationVerbose { get; } = new();
[GenerateProperty] private ConfigurationService ConfigurationService { get; } = default!;
[GenerateProperty] private IServiceProvider ServiceProvider { get; } = default!;
public List<(object, Type)> ConVarList = new();
public void AddConfiguration<T,T1>(ConVar<T> convar) where T1: ViewModelBase, IConfigurationVerbose<T>
public void AddCvarConf<T>(ConVar<T> cvar)
{
var configurationVerbose = ServiceProvider.GetService<T1>()!;
configurationVerbose.Context = new ConfigContext<T>(convar, this);
configurationVerbose.InitializeConfig();
ConfigurationVerbose.Add(configurationVerbose);
ConfigurationVerbose.Add(
ConfigControlHelper.GetConfigControl(cvar.Name, ConfigurationService.GetConfigValue(cvar)));
ConVarList.Add((cvar, cvar.Type));
}
public void InvokeUpdateConfiguration()
{
foreach (var verbose in ConfigurationVerbose)
for (int i = 0; i < ConfigurationVerbose.Count; i++)
{
if(verbose is not IUpdateInvoker invoker) continue;
invoker.UpdateConfiguration();
var conVarControl = ConfigurationVerbose[i];
if(!conVarControl.Dirty)
continue;
var conVar = ConVarList[i];
var methodInfo = ConfigurationService.GetType().GetMethod("SetConfigValue")!.MakeGenericMethod(conVar.Item2);
methodInfo.Invoke(ConfigurationService, [conVar.Item1, conVarControl.GetValue()]);
}
}
protected override void InitialiseInDesignMode()
{
AddConfiguration<string, StringConfigurationViewModel>(LauncherConVar.ILSpyUrl);
{
AddCvarConf(LauncherConVar.ILSpyUrl);
AddCvarConf(LauncherConVar.Hub);
AddCvarConf(LauncherConVar.AuthServers);
AddCvarConf(CurrentConVar.EngineManifestUrl);
AddCvarConf(CurrentConVar.RobustAssemblyName);
AddCvarConf(CurrentConVar.ManifestDownloadProtocolVersion);
}
protected override void Initialise()
{
InitialiseInDesignMode();
}
}
public void SetValue<T>(ConVar<T> conVar, T value)
public static class ConfigControlHelper{
public static IConfigControl GetConfigControl(string name,object value)
{
ConfigurationService.SetConfigValue(conVar, value);
switch (value)
{
case string stringValue:
return new StringUnitConfigControl(name, stringValue);
case int intValue:
return new IntUnitConfigControl(name, intValue);
case float floatValue:
return new FloatUnitConfigControl(name, floatValue);
}
var valueType = value.GetType();
if (valueType.IsArray)
return new ArrayUnitConfigControl(name, value);
return new ComplexUnitConfigControl(name, value);
}
public T? GetValue<T>(ConVar<T> convar)
public static object? CreateDefaultValue(Type type)
{
return ConfigurationService.GetConfigValue<T>(convar);
if (type == typeof(string))
return string.Empty;
if (type == typeof(int))
return 0;
if (type == typeof(float))
return 0f;
if(type.IsValueType)
return Activator.CreateInstance(type);
var ctor = type.GetConstructors().First();
var parameters = ctor.GetParameters()
.Select(p => CreateDefaultValue(p.ParameterType))
.ToArray();
return ctor.Invoke(parameters);
}
}
public interface IConfigContext
public sealed class ComplexUnitConfigControl : StackPanel, IConfigControl
{
public void SetValue<T>(ConVar<T> conVar, T value);
public T? GetValue<T>(ConVar<T> convar);
}
public class ConfigContext<T> : IConfigContext
{
public ConfigContext(ConVar<T> conVar, IConfigContext parent)
{
ConVar = conVar;
Parent = parent;
}
public ConVar<T> ConVar { get; }
public IConfigContext Parent { get; }
public T? GetValue()
{
return GetValue(ConVar);
}
public void SetValue(T? value)
{
SetValue(ConVar!, value);
}
public void SetValue<T1>(ConVar<T1> conVar, T1 value)
{
Parent.SetValue(conVar, value);
}
public T1? GetValue<T1>(ConVar<T1> convar)
{
return Parent.GetValue(convar);
}
}
public interface IConfigurationVerbose<T>
{
public ConfigContext<T> Context { get; set; }
public void InitializeConfig();
}
public interface IUpdateInvoker
{
public void UpdateConfiguration();
}
[ViewModelRegister(typeof(StringConfigurationView))]
public partial class StringConfigurationViewModel : ViewModelBase , IConfigurationVerbose<string>, IUpdateInvoker
{
[ObservableProperty] private string _configText = string.Empty;
[ObservableProperty] private string? _configName = string.Empty;
private List<(PropertyInfo, IConfigControl)> _units = [];
private string _oldText = string.Empty;
private Type _objectType = typeof(object);
public required ConfigContext<string> Context { get; set; }
public void InitializeConfig()
public string ConfigName { get; }
public bool Dirty => _units.Any(dirty => dirty.Item2.Dirty);
public ComplexUnitConfigControl(string name, object obj)
{
ConfigName = Context.ConVar.Name;
_oldText = Context.GetValue() ?? string.Empty;
ConfigText = _oldText;
Orientation = Orientation.Vertical;
Margin = new Thickness(5);
Spacing = 2f;
ConfigName = name;
SetValue(obj);
}
public void UpdateConfiguration()
public void SetValue(object value)
{
if (_oldText == ConfigText) return;
Context.SetValue(ConfigText);
_units.Clear();
Children.Clear();
_objectType = value.GetType();
Children.Add(new Label()
{
Content = ConfigName
});
foreach (var propInfo in _objectType.GetProperties())
{
if(propInfo.PropertyType.IsInterface)
continue;
var propValue = propInfo.GetValue(value);
var control = ConfigControlHelper.GetConfigControl(propInfo.Name, propValue);
Children.Add(control as Control);
_units.Add((propInfo,control));
}
}
public object GetValue()
{
var obj = ConfigControlHelper.CreateDefaultValue(_objectType);
foreach (var (fieldInfo, configControl) in _units)
{
fieldInfo.SetValue(obj, configControl.GetValue());
}
return obj;
}
}
public sealed class ArrayUnitConfigControl : StackPanel, IConfigControl
{
private readonly List<IConfigControl> _itemControls = [];
private readonly StackPanel _itemsPanel = new StackPanel() { Orientation = Orientation.Vertical };
private readonly Button _addButton = new Button() { Content = "Add Item" };
private int oldCount;
private readonly Type _elementType;
public string ConfigName { get; }
public bool Dirty => _itemControls.Any(dirty => dirty.Dirty) || _itemControls.Count != oldCount;
public ArrayUnitConfigControl(string name, object value)
{
_elementType = value.GetType().GetElementType();
ConfigName = name;
Orientation = Orientation.Vertical;
Margin = new Thickness(5);
Spacing = 2f;
Children.Add(new Label { Content = name });
Children.Add(_itemsPanel);
Children.Add(_addButton);
_addButton.Click += (_, _) => AddItem(ConfigControlHelper.CreateDefaultValue(_elementType));
SetValue(value);
oldCount = _itemControls.Count;
}
private void AddItem(object value)
{
var itemPanel = new StackPanel { Orientation = Orientation.Horizontal, Spacing = 2 };
var control = ConfigControlHelper.GetConfigControl(_itemControls.Count.ToString(), value);
var removeButton = new Button { Content = "Remove" };
removeButton.Click += (_, _) =>
{
_itemControls.Remove(control);
_itemsPanel.Children.Remove(itemPanel);
};
itemPanel.Children.Add((Control)control);
itemPanel.Children.Add(removeButton);
_itemsPanel.Children.Add(itemPanel);
_itemControls.Add(control);
}
public void SetValue(object value)
{
_itemControls.Clear();
_itemsPanel.Children.Clear();
if (value is IEnumerable list)
{
foreach (var item in list)
{
AddItem(item);
}
}
}
public object GetValue()
{
return ConvertArray(_itemControls.Select(c => c.GetValue()).ToArray(), _elementType);
}
protected override void InitialiseInDesignMode()
public static Array ConvertArray(Array sourceArray, Type targetType)
{
int length = sourceArray.Length;
var newArray = Array.CreateInstance(targetType, length);
for (int i = 0; i < length; i++)
{
var value = sourceArray.GetValue(i);
var converted = Convert.ChangeType(value, targetType);
newArray.SetValue(converted, i);
}
return newArray;
}
}
public abstract class UnitConfigControl<T> : StackPanel, IConfigControl where T : notnull
{
private readonly Label _nameLabel = new Label();
private readonly TextBox _valueLabel = new TextBox();
private string _originalValue;
public string ConfigName { get; private set;}
public bool Dirty
{
get
{
return _originalValue != ConfigValue;
}
}
protected override void Initialise()
protected string? ConfigValue
{
get => _valueLabel.Text;
set => _valueLabel.Text = value;
}
public UnitConfigControl(string name, T value)
{
ConfigName = name;
Orientation = Orientation.Horizontal;
Children.Add(_nameLabel);
Children.Add(_valueLabel);
_nameLabel.Content = name;
_nameLabel.VerticalAlignment = VerticalAlignment.Center;
SetConfValue(value);
_originalValue = ConfigValue;
}
public abstract void SetConfValue(T value);
public abstract T GetConfValue();
public void SetValue(object value)
{
SetConfValue((T)value);
}
public object GetValue()
{
return GetConfValue()!;
}
}
public sealed class StringUnitConfigControl(string name, string value) : UnitConfigControl<string>(name, value)
{
public override void SetConfValue(string value)
{
ConfigValue = value;
}
public override string GetConfValue()
{
return ConfigValue ?? string.Empty;
}
}
public sealed class IntUnitConfigControl(string name, int value) : UnitConfigControl<int>(name, value)
{
public override void SetConfValue(int value)
{
ConfigValue = value.ToString();
}
public override int GetConfValue()
{
Debug.Assert(ConfigValue != null, nameof(ConfigValue) + " != null");
return int.Parse(ConfigValue);
}
}
public sealed class FloatUnitConfigControl(string name, float value) : UnitConfigControl<float>(name, value)
{
public CultureInfo CultureInfo = CultureInfo.InvariantCulture;
public override void SetConfValue(float value)
{
ConfigValue = value.ToString(CultureInfo);
}
public override float GetConfValue()
{
Debug.Assert(ConfigValue != null, nameof(ConfigValue) + " != null");
return float.Parse(ConfigValue, CultureInfo);
}
}
public interface IConfigControl
{
public string ConfigName { get; }
public bool Dirty {get;}
public abstract void SetValue(object value);
public abstract object GetValue();
}

View File

@@ -1,17 +0,0 @@
<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:pages="clr-namespace:Nebula.Launcher.ViewModels.Pages"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Nebula.Launcher.Views.Config.StringConfigurationView"
x:DataType="pages:StringConfigurationViewModel">
<Design.DataContext>
<pages:StringConfigurationViewModel />
</Design.DataContext>
<StackPanel Orientation="Horizontal" Spacing="5" Margin="5">
<TextBlock VerticalAlignment="Center" Text="{Binding ConfigName}"/>
<TextBlock VerticalAlignment="Center" Text=":"/>
<TextBox Text="{Binding ConfigText}"/>
</StackPanel>
</UserControl>

View File

@@ -1,20 +0,0 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using Nebula.Launcher.ViewModels.Pages;
namespace Nebula.Launcher.Views.Config;
public partial class StringConfigurationView : UserControl
{
public StringConfigurationView()
{
InitializeComponent();
}
public StringConfigurationView(StringConfigurationViewModel viewModel)
: this()
{
DataContext = viewModel;
}
}

View File

@@ -10,31 +10,25 @@
<pages:ConfigurationViewModel />
</Design.DataContext>
<Panel>
<Border
VerticalAlignment="Top"
Margin="5" Padding="5,2,5,2">
<Border.Background>
<LinearGradientBrush EndPoint="50%,100%" StartPoint="50%,0%">
<GradientStop Color="#222222" Offset="0.0" />
<GradientStop Color="#292222" Offset="1.0" />
</LinearGradientBrush>
</Border.Background>
<ScrollViewer >
<StackPanel>
<ItemsControl
ItemsSource="{Binding ConfigurationVerbose}"
Padding="0" />
</StackPanel>
</ScrollViewer>
</Border>
<Button
VerticalAlignment="Bottom"
HorizontalAlignment="Stretch"
Padding="5"
Margin="5"
Command="{Binding InvokeUpdateConfiguration}"
>Save
</Button>
</Panel>
<ScrollViewer>
<StackPanel Spacing="10" Margin="10">
<ItemsControl
ItemsSource="{Binding ConfigurationVerbose}"
Padding="0" >
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Spacing="10" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
<Button
VerticalAlignment="Bottom"
HorizontalAlignment="Stretch"
Padding="5"
Margin="5"
Command="{Binding InvokeUpdateConfiguration}">
Save
</Button>
</StackPanel>
</ScrollViewer>
</UserControl>

View File

@@ -8,6 +8,7 @@
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AControl_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F57361bc4e5442f644ff63ec7e745da2eb4bbb6c769d1fb683bab5f6f952b1ab_003FControl_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ADecorator_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003Feecfe7fcb95caaf3978fdce4ae36e346b34986d1d844b0dce2fcb67e5952c_003FDecorator_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ADrawingContext_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F7f67edd2b798d6c80b015913cde68b729bfe416b62cf075ea3953ffeff639c_003FDrawingContext_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AEnumerable_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fcae7ff14a5884c649c9045d4ef4f987ea0928_003Fa6_003F6011c781_003FEnumerable_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_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>
@@ -15,6 +16,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_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_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_003AJsonSerializer_002ERead_002EString_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F27c4858128168eda568c1334d70d5241efb9461e2a3209258a04deee5d9c367_003FJsonSerializer_002ERead_002EString_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AListBox_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F3a6cdc26ff4d30986a9a16b6bbc9bb6a7f2657431c82cde5c66dd377cf51e2b_003FListBox_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ANativeLibrary_002ECoreCLR_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F88c2c65e1618f68cb5969f70dfc0986e9571015ac8d487b18d26e89c926264_003FNativeLibrary_002ECoreCLR_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
@@ -23,9 +25,12 @@
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003APanel_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F9b699722324e3615b57977447b25bf953fccb2d6e912ae584f16b7e691ad9d3_003FPanel_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AParallel_002EForEachAsync_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003Fc1d1ed6be2d5d4de542b4af5b36e82f6d1d1a389a35a4e4f9748d137d1c651_003FParallel_002EForEachAsync_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AProcessStartInfo_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003Fc5ffb8c166be164bc221db4c64e826a1e8ff54f2f1c9ee8e7f9cfabce707fa4_003FProcessStartInfo_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003APropertyInfo_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F408236be4b0703755f3ed96daaae245919a792d65ce5eaa672d9fa945b1f_003FPropertyInfo_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AScrollBar_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003Fda7bce95d5f888176a5f93c8965e402ca33cba794ac7e7aa776363c664488d_003FScrollBar_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AServiceCollectionContainerBuilderExtensions_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fa8ceca48b7b645dd875a40ee6d28725416d08_003F1b_003F6cd78dc8_003FServiceCollectionContainerBuilderExtensions_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AServiceProviderServiceExtensions_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F4f1fdec7cbfe4433a7ec3a6d1bd0e54210118_003F04_003Fe2f5322d_003FServiceProviderServiceExtensions_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ASingle_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003Fe27543f11ad92fdb62cde92eebaa1afb3de86a016ad85f76d1554b0389cd3f3_003FSingle_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AString_002EManipulation_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003Fe75a5575ba872c8ea754c015cb363850e6c661f39569712d5b74aaca67263c_003FString_002EManipulation_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AUri_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F6a1fb5a19c4883d19f63515be2d0cce5e0e9929bb30469a912a58ad2e1e6152_003FUri_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AValuePrinter_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F80d1676fb411442983574149e0b6aebc72e00_003F2f_003F26a40f58_003FValuePrinter_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/PencilsConfiguration/ActualSeverity/@EntryValue">INFO</s:String></wpf:ResourceDictionary>