This commit is contained in:
Timerix 2024-09-27 02:12:07 +05:00
parent d24dbea501
commit 45c3f90da0
15 changed files with 238 additions and 115 deletions

View File

@ -1,13 +0,0 @@
namespace Млаумчерб.Клиент;
public class LauncherLogger : FileLogger
{
public static readonly IOPath LogsDirectory = "launcher_logs";
public LauncherLogger() : base(LogsDirectory, "млаумчерб")
{
#if DEBUG
DebugLogEnabled = true;
#endif
}
}

View File

@ -19,10 +19,6 @@ namespace Млаумчерб.Клиент;
public class Главне public class Главне
{ {
public static readonly LauncherLogger Логгер = new();
public static Настройки Настройки = new();
[STAThread] [STAThread]
public static void Main(string[] args) public static void Main(string[] args)
{ {
@ -34,7 +30,7 @@ public class Главне
} }
catch (Exception ex) catch (Exception ex)
{ {
Логгер.LogError(nameof(Главне), ex); Приложение.Логгер.LogError(nameof(Главне), ex);
} }
} }

View File

@ -2,7 +2,7 @@
using DTLib.Extensions; using DTLib.Extensions;
using Млаумчерб.Клиент.видимое; using Млаумчерб.Клиент.видимое;
using Млаумчерб.Клиент.классы; using Млаумчерб.Клиент.классы;
using static Млаумчерб.Клиент.классы.Пролетариат; using static Млаумчерб.Клиент.классы.Пути;
namespace Млаумчерб.Клиент; namespace Млаумчерб.Клиент;
@ -49,13 +49,13 @@ public class GameVersionDescriptor
private GameVersionDescriptor(GameVersionProps props) private GameVersionDescriptor(GameVersionProps props)
{ {
_props = props; _props = props;
WorkingDirectory = Path.Concat(Главне.Настройки.путь_к_кубачу, Name); WorkingDirectory = Path.Concat(Приложение.Настройки.путь_к_кубачу, Name);
string descriptorText = File.ReadAllText(props.LocalDescriptorPath); string descriptorText = File.ReadAllText(props.LocalDescriptorPath);
descriptor = JsonConvert.DeserializeObject<MinecraftVersionDescriptor>(descriptorText) descriptor = JsonConvert.DeserializeObject<MinecraftVersionDescriptor>(descriptorText)
?? throw new Exception($"can't parse descriptor file '{props.LocalDescriptorPath}'"); ?? throw new Exception($"can't parse descriptor file '{props.LocalDescriptorPath}'");
javaArgs = new JavaArguments(descriptor); javaArgs = new JavaArguments(descriptor);
gameArgs = new GameArguments(descriptor); gameArgs = new GameArguments(descriptor);
JavaExecutableFilePath = Path.Concat(Главне.Настройки.путь_к_жабе, "bin", JavaExecutableFilePath = Path.Concat(Приложение.Настройки.путь_к_жабе, "bin",
OperatingSystem.IsWindows() ? "javaw.exe" : "javaw"); OperatingSystem.IsWindows() ? "javaw.exe" : "javaw");
} }
@ -64,8 +64,8 @@ public class GameVersionDescriptor
try try
{ {
downloadCts = new CancellationTokenSource(); downloadCts = new CancellationTokenSource();
if(Главне.Настройки.скачатьабу) if(Приложение.Настройки.скачатьабу)
await Сеть.DownloadJava(descriptor.javaVersion, Главне.Настройки.путь_к_жабе, force); await Сеть.DownloadJava(descriptor.javaVersion, Приложение.Настройки.путь_к_жабе, force);
await Сеть.DownloadAssets(descriptor.assetIndex, downloadCts.Token, force); await Сеть.DownloadAssets(descriptor.assetIndex, downloadCts.Token, force);
await Сеть.DownloadVersionFile(descriptor.downloads.client.url, GetVersionJarFilePath(Name), force); await Сеть.DownloadVersionFile(descriptor.downloads.client.url, GetVersionJarFilePath(Name), force);
await Сеть.DownloadLibraries(descriptor.libraries, GetLibrariesDir(), force); await Сеть.DownloadLibraries(descriptor.libraries, GetLibrariesDir(), force);
@ -91,7 +91,7 @@ public class GameVersionDescriptor
.WithWorkingDirectory(WorkingDirectory.ToString()) .WithWorkingDirectory(WorkingDirectory.ToString())
.WithArguments(javaArgsList) .WithArguments(javaArgsList)
.WithArguments(gameArgsList); .WithArguments(gameArgsList);
Главне.Логгер.LogInfo(nameof(GameVersionDescriptor), Приложение.Логгер.LogInfo(nameof(GameVersionDescriptor),
$"launching the game" + $"launching the game" +
"\njava: " + command.TargetFilePath + "\njava: " + command.TargetFilePath +
"\nworking_dir: " + command.WorkingDirPath + "\nworking_dir: " + command.WorkingDirPath +
@ -100,7 +100,7 @@ public class GameVersionDescriptor
gameCts = new(); gameCts = new();
commandTask = command.ExecuteAsync(gameCts.Token); commandTask = command.ExecuteAsync(gameCts.Token);
var result = await commandTask; var result = await commandTask;
Главне.Логгер.LogInfo(nameof(GameVersionDescriptor), $"game exited with code {result.ExitCode}"); Приложение.Логгер.LogInfo(nameof(GameVersionDescriptor), $"game exited with code {result.ExitCode}");
} }
public void Close() public void Close()

View File

@ -0,0 +1,79 @@
namespace Млаумчерб.Клиент;
public class LauncherLogger : ILogger
{
private CompositeLogger _compositeLogger;
private FileLogger _fileLogger;
public static readonly IOPath LogsDirectory = "launcher_logs";
public IOPath LogfileName => _fileLogger.LogfileName;
public LauncherLogger()
{
_fileLogger = new FileLogger(LogsDirectory, "млаумчерб");
ILogger[] loggers =
[
_fileLogger,
#if DEBUG
new ConsoleLogger(),
#endif
];
_compositeLogger = new CompositeLogger(loggers);
#if DEBUG
DebugLogEnabled = true;
#endif
}
public delegate void LogHandler(string context, LogSeverity severity, object message, ILogFormat format);
public event LogHandler? OnLogMessage;
public void Log(string context, LogSeverity severity, object message, ILogFormat format)
{
_compositeLogger.Log(context, severity, message, format);
bool isEnabled = severity switch
{
LogSeverity.Debug => DebugLogEnabled,
LogSeverity.Info => InfoLogEnabled,
LogSeverity.Warn => WarnLogEnabled,
LogSeverity.Error => ErrorLogEnabled,
_ => throw new ArgumentOutOfRangeException(nameof(severity), severity, null)
};
if(isEnabled)
OnLogMessage?.Invoke(context, severity, message, format);
}
public void Dispose()
{
_compositeLogger.Dispose();
}
public ILogFormat Format
{
get => _compositeLogger.Format;
set => _compositeLogger.Format = value;
}
public bool DebugLogEnabled
{
get => _compositeLogger.DebugLogEnabled;
set => _compositeLogger.DebugLogEnabled = value;
}
public bool InfoLogEnabled
{
get => _compositeLogger.InfoLogEnabled;
set => _compositeLogger.InfoLogEnabled = value;
}
public bool WarnLogEnabled
{
get => _compositeLogger.WarnLogEnabled;
set => _compositeLogger.WarnLogEnabled = value;
}
public bool ErrorLogEnabled
{
get => _compositeLogger.ErrorLogEnabled;
set => _compositeLogger.ErrorLogEnabled = value;
}
}

View File

@ -1,6 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<OutputType>WinExe</OutputType> <OutputType Condition="'$(Configuration)' == 'Debug'">Exe</OutputType>
<OutputType Condition="'$(Configuration)' != 'Debug'">WinExe</OutputType>
<TargetFramework>net8.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
<LangVersion>latest</LangVersion> <LangVersion>latest</LangVersion>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
@ -21,7 +22,7 @@
<PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" Version="11.*" /> <PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" Version="11.*" />
<PackageReference Include="Avalonia.Labs.Gif" Version="11.2.999-cibuild-00051673"/> <PackageReference Include="Avalonia.Labs.Gif" Version="11.2.999-cibuild-00051673"/>
<PackageReference Include="CliWrap" Version="3.6.*" /> <PackageReference Include="CliWrap" Version="3.6.*" />
<PackageReference Include="DTLib" Version="1.4.1" /> <PackageReference Include="DTLib" Version="1.4.2" />
<PackageReference Include="MessageBox.Avalonia" Version="3.1.*" /> <PackageReference Include="MessageBox.Avalonia" Version="3.1.*" />
<PackageReference Include="Newtonsoft.Json" Version="13.*" /> <PackageReference Include="Newtonsoft.Json" Version="13.*" />
</ItemGroup> </ItemGroup>

View File

@ -14,10 +14,10 @@ public record Настройки
public static Настройки ЗагрузитьИзФайла(string имяайла = "млаумчерб.настройки") public static Настройки ЗагрузитьИзФайла(string имяайла = "млаумчерб.настройки")
{ {
Главне.Логгер.LogInfo(nameof(Настройки), $"попытка загрузить настройки из файла '{имя_файла}'"); Приложение.Логгер.LogInfo(nameof(Настройки), $"попытка загрузить настройки из файла '{имя_файла}'");
if(!File.Exists(имяайла)) if(!File.Exists(имяайла))
{ {
Главне.Логгер.LogInfo(nameof(Настройки), "файл не существует"); Приложение.Логгер.LogInfo(nameof(Настройки), "файл не существует");
return new Настройки(); return new Настройки();
} }
@ -33,15 +33,15 @@ public record Настройки
$"Создан новый файл '{имя_файла}'."); $"Создан новый файл '{имя_файла}'.");
} }
Главне.Логгер.LogInfo(nameof(Настройки), $"настройки загружены: {н}"); Приложение.Логгер.LogInfo(nameof(Настройки), $"настройки загружены: {н}");
return н; return н;
} }
public void СохранитьВФайл(string имяайла = "млаумчерб.настройки") public void СохранитьВФайл(string имяайла = "млаумчерб.настройки")
{ {
Главне.Логгер.LogInfo(nameof(Настройки), $"попытка сохранить настройки в файл '{имя_файла}'"); Приложение.Логгер.LogInfo(nameof(Настройки), $"попытка сохранить настройки в файл '{имя_файла}'");
var текст = JsonConvert.SerializeObject(this, Formatting.Indented); var текст = JsonConvert.SerializeObject(this, Formatting.Indented);
File.WriteAllText(имяайла, текст); File.WriteAllText(имяайла, текст);
Главне.Логгер.LogInfo(nameof(Настройки), $"настройки сохранены: {текст}"); Приложение.Логгер.LogInfo(nameof(Настройки), $"настройки сохранены: {текст}");
} }
} }

View File

@ -15,7 +15,7 @@ public static class Ошибки
internal static async void ПоказатьСообщение(string context, string err) internal static async void ПоказатьСообщение(string context, string err)
{ {
Главне.Логгер.LogError(nameof(Ошибки), err); Приложение.Логгер.LogError(nameof(Ошибки), err);
var box = MessageBoxManager.GetMessageBoxCustom(new MessageBoxCustomParams var box = MessageBoxManager.GetMessageBoxCustom(new MessageBoxCustomParams
{ {
ButtonDefinitions = new List<ButtonDefinition> { new() { Name = "пон" } }, ButtonDefinitions = new List<ButtonDefinition> { new() { Name = "пон" } },

View File

@ -55,7 +55,7 @@ public static class Сеть
public static async Task DownloadAssets(AssetIndexProperties assetIndexProperties, CancellationToken ct, bool force) public static async Task DownloadAssets(AssetIndexProperties assetIndexProperties, CancellationToken ct, bool force)
{ {
IOPath indexFilePath = Пролетариат.GetAssetIndexFilePath(assetIndexProperties.id); IOPath indexFilePath = Пути.GetAssetIndexFilePath(assetIndexProperties.id);
if (File.Exists(indexFilePath) && !force) if (File.Exists(indexFilePath) && !force)
return; return;
@ -64,9 +64,9 @@ public static class Сеть
File.Delete(indexFilePathTmp); File.Delete(indexFilePathTmp);
// TODO: add something to Downloads ScrollList // TODO: add something to Downloads ScrollList
Главне.Логгер.LogInfo(nameof(DownloadAssets), $"started downloading asset index to '{indexFilePathTmp}'"); Приложение.Логгер.LogInfo(nameof(DownloadAssets), $"started downloading asset index to '{indexFilePathTmp}'");
await DownloadFileHTTP(assetIndexProperties.url, indexFilePathTmp, null, ct); await DownloadFileHTTP(assetIndexProperties.url, indexFilePathTmp, null, ct);
Главне.Логгер.LogInfo(nameof(DownloadAssets), "finished downloading asset index"); Приложение.Логгер.LogInfo(nameof(DownloadAssets), "finished downloading asset index");
string indexFileText = File.ReadAllText(indexFilePathTmp); string indexFileText = File.ReadAllText(indexFilePathTmp);
AssetIndex assetIndex = JsonConvert.DeserializeObject<AssetIndex>(indexFileText) AssetIndex assetIndex = JsonConvert.DeserializeObject<AssetIndex>(indexFileText)
@ -102,13 +102,13 @@ public static class Сеть
long bytesPerSec = (currentSize - prevSize) / (timerDelay / 1000); long bytesPerSec = (currentSize - prevSize) / (timerDelay / 1000);
float KbytesPerSec = bytesPerSec / 1024f; float KbytesPerSec = bytesPerSec / 1024f;
prevSize = currentSize; prevSize = currentSize;
Главне.Логгер.LogDebug(nameof(DownloadAssets), Приложение.Логгер.LogDebug(nameof(DownloadAssets),
$"download progress {currentSizeM}Mb/{totalSizeM}Mb ({KbytesPerSec}Kb/s)"); $"download progress {currentSizeM}Mb/{totalSizeM}Mb ({KbytesPerSec}Kb/s)");
} }
using Timer timer = new Timer(true, timerDelay, ReportProgress); using Timer timer = new Timer(true, timerDelay, ReportProgress);
timer.Start(); timer.Start();
Главне.Логгер.LogInfo(nameof(DownloadAssets), "started downloading assets"); Приложение.Логгер.LogInfo(nameof(DownloadAssets), "started downloading assets");
int parallelDownloads = 32; int parallelDownloads = 32;
var tasks = new Task[parallelDownloads]; var tasks = new Task[parallelDownloads];
var currentlyDownloadingFileHashes = new string[parallelDownloads]; var currentlyDownloadingFileHashes = new string[parallelDownloads];
@ -119,7 +119,7 @@ public static class Сеть
string hashStart = hash.Substring(0, 2); string hashStart = hash.Substring(0, 2);
var assetUrl = $"{ASSET_SERVER_URL}/{hashStart}/{hash}"; var assetUrl = $"{ASSET_SERVER_URL}/{hashStart}/{hash}";
IOPath assetFilePath = Path.Concat("assets", "objects", hashStart, hash); IOPath assetFilePath = Path.Concat("assets", "objects", hashStart, hash);
Главне.Логгер.LogDebug(nameof(DownloadAssets), $"downloading asset '{a.Key}' {hash}"); Приложение.Логгер.LogDebug(nameof(DownloadAssets), $"downloading asset '{a.Key}' {hash}");
tasks[i] = DownloadFileHTTP(assetUrl, assetFilePath, AddBytesCountAtomic, ct); tasks[i] = DownloadFileHTTP(assetUrl, assetFilePath, AddBytesCountAtomic, ct);
currentlyDownloadingFileHashes[i] = hash; currentlyDownloadingFileHashes[i] = hash;
if (++i == parallelDownloads) if (++i == parallelDownloads)
@ -133,7 +133,7 @@ public static class Сеть
timer.Stop(); timer.Stop();
timer.InvokeAction(); timer.InvokeAction();
File.Move(indexFilePathTmp, indexFilePath, true); File.Move(indexFilePathTmp, indexFilePath, true);
Главне.Логгер.LogInfo(nameof(DownloadAssets), "finished downloading assets"); Приложение.Логгер.LogInfo(nameof(DownloadAssets), "finished downloading assets");
} }
private static async Task<List<RemoteVersionDescriptorProps>> GetRemoteVersionDescriptorsAsync() private static async Task<List<RemoteVersionDescriptorProps>> GetRemoteVersionDescriptorsAsync()
@ -150,7 +150,7 @@ public static class Сеть
} }
catch (Exception ex) catch (Exception ex)
{ {
Главне.Логгер.LogWarn(nameof(Сеть), ex); Приложение.Логгер.LogWarn(nameof(Сеть), ex);
} }
} }
return descriptors; return descriptors;

View File

@ -6,7 +6,7 @@
Name="window" Name="window"
Title="млаумчерб" Title="млаумчерб"
Icon="avares://млаумчерб/капитал/кубе.ico" Icon="avares://млаумчерб/капитал/кубе.ico"
FontFamily="{StaticResource PlexMono}" FontSize="18" FontFamily="{StaticResource MonospaceFont}" FontSize="18"
MinWidth="800" MinHeight="500" MinWidth="800" MinHeight="500"
Width="800" Height="500" Width="800" Height="500"
WindowStartupLocation="CenterScreen"> WindowStartupLocation="CenterScreen">
@ -25,9 +25,18 @@
<TextBlock FontWeight="Bold" <TextBlock FontWeight="Bold"
HorizontalAlignment="Center" HorizontalAlignment="Center"
VerticalAlignment="Center"> VerticalAlignment="Center">
News Лог
</TextBlock> </TextBlock>
</Border> </Border>
<ScrollViewer Name="LogScrollViewer" Grid.Row="1"
HorizontalScrollBarVisibility="Disabled"
VerticalScrollBarVisibility="Visible"
Background="Transparent">
<TextBox Name="LogTextBox"
FontSize="12"
IsReadOnly="True" TextWrapping="Wrap"
Background="Transparent" BorderThickness="0"/>
</ScrollViewer>
</Grid> </Grid>
</Border> </Border>
<Border Grid.Column="1" <Border Grid.Column="1"
@ -36,40 +45,39 @@
<Grid> <Grid>
<Grid.RowDefinitions>* 60</Grid.RowDefinitions> <Grid.RowDefinitions>* 60</Grid.RowDefinitions>
<StackPanel Orientation="Vertical" Margin="10" Spacing="10"> <StackPanel Orientation="Vertical" Margin="10" Spacing="10">
<TextBlock>Version:</TextBlock> <TextBlock>Версия:</TextBlock>
<ComboBox Name="VersionComboBox"> <ComboBox Name="VersionComboBox"/>
</ComboBox>
<TextBlock>Username:</TextBlock> <TextBlock>Ник:</TextBlock>
<TextBox Text="{Binding #window.Username}"></TextBox> <TextBox Background="Transparent"
Text="{Binding #window.Username}"/>
<TextBlock> <TextBlock>
<Run>Memory limit:</Run> <Run>Выделенная память:</Run>
<TextBox Background="Transparent" Padding="0" <TextBox Background="Transparent" Padding="0"
BorderThickness="1" BorderThickness="1"
BorderBrush="#777777" BorderBrush="#777777"
Text="{Binding #window.MemoryLimit}"> Text="{Binding #window.MemoryLimit}">
</TextBox> </TextBox>
<Run>Mb</Run> <Run>Мб</Run>
</TextBlock> </TextBlock>
<Slider Minimum="2048" Maximum="8192" <Slider Minimum="2048" Maximum="8192"
Value="{Binding #window.MemoryLimit}"> Value="{Binding #window.MemoryLimit}">
</Slider> </Slider>
<CheckBox IsChecked="{Binding #window.Fullscreen}"> <CheckBox IsChecked="{Binding #window.Fullscreen}">
Fullscreen Запустить полноэкранное
</CheckBox> </CheckBox>
<CheckBox IsChecked="{Binding #window.ForceUpdateGameFiles}"> <CheckBox IsChecked="{Binding #window.CheckGameFiles}">
Force update game files Проверить файлы игры
</CheckBox> </CheckBox>
</StackPanel> </StackPanel>
<Button Grid.Row="1" Margin="10" Padding="0 0 0 4" <Button Grid.Row="1" Margin="10" Padding="0 0 0 4"
Classes="button_no_border" Classes="button_no_border"
Background="#BBFF5900" Background="#BBfd7300"
Click="LaunchButtonHandler"> Click="Запуск">
Launch Запуск
</Button> </Button>
</Grid> </Grid>
</Border> </Border>
@ -81,21 +89,25 @@
<TextBlock FontWeight="Bold" <TextBlock FontWeight="Bold"
HorizontalAlignment="Center" HorizontalAlignment="Center"
VerticalAlignment="Center"> VerticalAlignment="Center">
Downloads Загрузки
</TextBlock> </TextBlock>
</Border> </Border>
<ScrollViewer Name="DownloadsScrollViewer" Grid.Row="1"
HorizontalScrollBarVisibility="Disabled"
VerticalScrollBarVisibility="Visible"
Background="Transparent"/>
</Grid> </Grid>
</Border> </Border>
</Grid> </Grid>
<Border Grid.Row="1" Background="#954808B0"> <Border Grid.Row="1" Background="#954808B0">
<Grid> <Grid>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left"> <StackPanel Orientation="Horizontal" HorizontalAlignment="Left">
<Button Classes="menu_button button_no_border" Click="OpenLogsDirectory">logs directory</Button> <Button Classes="menu_button button_no_border" Click="ОткрытьПапкуЛаунчера">директория лаунчера</Button>
<Border Classes="menu_separator"></Border> <Border Classes="menu_separator"/>
<Button Classes="menu_button button_no_border" Click="OpenLogFile">log file</Button> <Button Classes="menu_button button_no_border" Click="ОткрытьФайлЛогов">лог-файл</Button>
</StackPanel> </StackPanel>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right"> <StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
<Button Classes="menu_button button_no_border" Click="OpenSourceRepository">source code</Button> <Button Classes="menu_button button_no_border" Click="ОткрытьРепозиторий">исходный код</Button>
<gif:GifImage <gif:GifImage
Width="30" Height="30" Stretch="Uniform" Width="30" Height="30" Stretch="Uniform"
Source="avares://млаумчерб/капитал/лисик.gif"/> Source="avares://млаумчерб/капитал/лисик.gif"/>

View File

@ -1,9 +1,11 @@
using Avalonia; using Avalonia;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Controls.Presenters;
using Avalonia.Data; using Avalonia.Data;
using Avalonia.Interactivity; using Avalonia.Interactivity;
using Avalonia.Platform.Storage; using Avalonia.Platform.Storage;
using Avalonia.Threading; using Avalonia.Threading;
using Avalonia.VisualTree;
using Млаумчерб.Клиент.классы; using Млаумчерб.Клиент.классы;
namespace Млаумчерб.Клиент.видимое; namespace Млаумчерб.Клиент.видимое;
@ -37,13 +39,13 @@ public partial class Окне : Window
set => SetValue(FullscreenProperty, value); set => SetValue(FullscreenProperty, value);
} }
public static readonly StyledProperty<bool> ForceUpdateGameFilesProperty = public static readonly StyledProperty<bool> CheckGameFilesProperty =
AvaloniaProperty.Register<Окне, bool>(nameof(ForceUpdateGameFiles), AvaloniaProperty.Register<Окне, bool>(nameof(CheckGameFiles),
defaultBindingMode: BindingMode.TwoWay, defaultValue: false); defaultBindingMode: BindingMode.TwoWay, defaultValue: false);
public bool ForceUpdateGameFiles public bool CheckGameFiles
{ {
get => GetValue(ForceUpdateGameFilesProperty); get => GetValue(CheckGameFilesProperty);
set => SetValue(ForceUpdateGameFilesProperty, value); set => SetValue(CheckGameFilesProperty, value);
} }
public Окне() public Окне()
@ -55,12 +57,28 @@ public partial class Окне : Window
{ {
try try
{ {
Главне.Настройки = Настройки.ЗагрузитьИзФайла(); Приложение.Логгер.OnLogMessage += (context, severity, message, format) =>
Username = Главне.Настройки.имя_пользователя; {
MemoryLimit = Главне.Настройки.выделенная_память_мб; StringBuilder b = new();
Fullscreen = Главне.Настройки.открыватьаесь_экран; b.Append(DateTime.Now.ToString("[HH:mm:ss]["));
b.Append(severity);
b.Append("]: ");
b.Append(message);
b.Append('\n');
double offsetFromBottom = LogScrollViewer.Extent.Height
- LogScrollViewer.Offset.Y
- LogScrollViewer.Viewport.Height;
bool is_scrolled_to_end = offsetFromBottom < 20.0; // scrolled less then one line up
LogTextBox.Text += b.ToString();
if(is_scrolled_to_end)
LogScrollViewer.ScrollToEnd();
};
Directory.Create(Пролетариат.GetVersionDescriptorDir()); Username = Приложение.Настройки.имя_пользователя;
MemoryLimit = Приложение.Настройки.выделенная_память_мб;
Fullscreen = Приложение.Настройки.открыватьаесь_экран;
Directory.Create(Пути.GetVersionDescriptorDir());
VersionComboBox.SelectedIndex = 0; VersionComboBox.SelectedIndex = 0;
VersionComboBox.IsEnabled = false; VersionComboBox.IsEnabled = false;
var versions = await GameVersionDescriptor.GetAllVersionsAsync(); var versions = await GameVersionDescriptor.GetAllVersionsAsync();
@ -69,8 +87,8 @@ public partial class Окне : Window
foreach (var p in versions) foreach (var p in versions)
{ {
VersionComboBox.Items.Add(new VersionItemView(p)); VersionComboBox.Items.Add(new VersionItemView(p));
if (Главне.Настройки.последняяапущенная_версия != null && if (Приложение.Настройки.последняяапущенная_версия != null &&
p.Name == Главне.Настройки.последняяапущенная_версия) p.Name == Приложение.Настройки.последняяапущенная_версия)
VersionComboBox.SelectedIndex = VersionComboBox.Items.Count - 1; VersionComboBox.SelectedIndex = VersionComboBox.Items.Count - 1;
} }
VersionComboBox.IsEnabled = true; VersionComboBox.IsEnabled = true;
@ -82,24 +100,23 @@ public partial class Окне : Window
} }
} }
private async void LaunchButtonHandler(object? sender, RoutedEventArgs e) private async void Запуск(object? sender, RoutedEventArgs e)
{ {
try try
{ {
var selectedVersionView = (VersionItemView?)VersionComboBox.SelectedItem; var selectedVersionView = (VersionItemView?)VersionComboBox.SelectedItem;
var selectedVersion = selectedVersionView?.Props; var selectedVersion = selectedVersionView?.Props;
Главне.Настройки.последняяапущенная_версия = selectedVersion?.Name; Приложение.Настройки.последняяапущенная_версия = selectedVersion?.Name;
Главне.Настройки.имя_пользователя = Username; Приложение.Настройки.имя_пользователя = Username;
Главне.Настройки.выделенная_память_мб = MemoryLimit; Приложение.Настройки.выделенная_память_мб = MemoryLimit;
Главне.Настройки.открыватьаесь_экран = Fullscreen; Приложение.Настройки.открыватьаесь_экран = Fullscreen;
Главне.Настройки.СохранитьВФайл(); Приложение.Настройки.СохранитьВФайл();
if (selectedVersion == null) if (selectedVersion == null)
return; return;
var v = await GameVersionDescriptor.CreateFromPropsAsync(selectedVersion); var v = await GameVersionDescriptor.CreateFromPropsAsync(selectedVersion);
v.BeginUpdate(ForceUpdateGameFiles); v.BeginUpdate(CheckGameFiles);
Dispatcher.UIThread.Invoke(() => ForceUpdateGameFiles = false); Dispatcher.UIThread.Invoke(() => CheckGameFiles = false);
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -107,11 +124,11 @@ public partial class Окне : Window
} }
} }
private void OpenLogsDirectory(object? s, RoutedEventArgs e) private void ОткрытьПапкуЛаунчера(object? s, RoutedEventArgs e)
{ {
try try
{ {
Launcher.LaunchDirectoryInfoAsync(new DirectoryInfo(LauncherLogger.LogsDirectory.ToString())) Launcher.LaunchDirectoryInfoAsync(new DirectoryInfo(Directory.GetCurrent().ToString()))
.ConfigureAwait(false); .ConfigureAwait(false);
} }
catch (Exception ex) catch (Exception ex)
@ -120,11 +137,11 @@ public partial class Окне : Window
} }
} }
private void OpenLogFile(object? sender, RoutedEventArgs e) private void ОткрытьФайлЛогов(object? sender, RoutedEventArgs e)
{ {
try try
{ {
Launcher.LaunchFileInfoAsync(new FileInfo(Главне.Логгер.LogfileName.ToString())) Launcher.LaunchFileInfoAsync(new FileInfo(Приложение.Логгер.LogfileName.ToString()))
.ConfigureAwait(false); .ConfigureAwait(false);
} }
catch (Exception ex) catch (Exception ex)
@ -133,7 +150,7 @@ public partial class Окне : Window
} }
} }
private void OpenSourceRepository(object? sender, RoutedEventArgs e) private void ОткрытьРепозиторий(object? sender, RoutedEventArgs e)
{ {
try try
{ {

View File

@ -30,9 +30,30 @@
<Setter Property="Width" Value="1"/> <Setter Property="Width" Value="1"/>
<Setter Property="Margin" Value="4"/> <Setter Property="Margin" Value="4"/>
</Style> </Style>
<Style Selector="ScrollBar /template/ Border">
<Setter Property="Width" Value="5"/>
<Setter Property="Margin" Value="4"/>
<Setter Property="ClipToBounds" Value="True"/>
<Setter Property="CornerRadius" Value="0"/>
</Style>
<Style Selector="ScrollBar /template/ Rectangle">
<Setter Property="Fill" Value="#d8ceb9"/>
</Style>
<Style Selector="ScrollBar /template/ Thumb">
<Setter Property="Background" Value="#fd7300"/>
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="CornerRadius" Value="0"/>
</Style>
<Style Selector="ScrollBar /template/ Thumb /template/ Border">
<Setter Property="ClipToBounds" Value="True"/>
<Setter Property="CornerRadius" Value="0"/>
<Setter Property="Width" Value="5"/>
</Style>
</Application.Styles> </Application.Styles>
<Application.Resources> <Application.Resources>
<FontFamily x:Key="PlexMono">avares://млаумчерб/капитал/IBMPlexMono-Regular.ttf</FontFamily> <FontFamily x:Key="MonospaceFont">avares://млаумчерб/капитал/IBMPlexMono-Regular.ttf</FontFamily>
</Application.Resources> </Application.Resources>
</Application> </Application>

View File

@ -6,9 +6,13 @@ namespace Млаумчерб.Клиент.видимое;
public class Приложение : Application public class Приложение : Application
{ {
public static LauncherLogger Логгер = new();
public static Настройки Настройки = new();
public override void Initialize() public override void Initialize()
{ {
Главне.Логгер.LogInfo(nameof(Приложение), "приложение запущено"); Логгер.LogInfo(nameof(Приложение), "приложение запущено");
Настройки = Настройки.ЗагрузитьИзФайла();
AvaloniaXamlLoader.Load(this); AvaloniaXamlLoader.Load(this);
} }

View File

@ -22,11 +22,11 @@ public class GameVersionProps
Name = name; Name = name;
LocalDescriptorPath = descriptorPath; LocalDescriptorPath = descriptorPath;
RemoteDescriptorUrl = url; RemoteDescriptorUrl = url;
IsDownloaded = File.Exists(Пролетариат.GetVersionJarFilePath(name)); IsDownloaded = File.Exists(Пути.GetVersionJarFilePath(name));
} }
public GameVersionProps(string name, string? url) : public GameVersionProps(string name, string? url) :
this(name, url, Пролетариат.GetVersionDescriptorPath(name)) { } this(name, url, Пути.GetVersionDescriptorPath(name)) { }
public override string ToString() => Name; public override string ToString() => Name;
} }

View File

@ -1,27 +1,6 @@
using Млаумчерб.Клиент.видимое; namespace Млаумчерб.Клиент.классы;
namespace Млаумчерб.Клиент.классы;
public static class Пролетариат public static class Пролетариат
{ {
public static IOPath GetAssetIndexFilePath(string id) =>
Path.Concat(Главне.Настройки.путь_к_кубачу, $"assets/indexes/{id}.json");
public static IOPath GetVersionDescriptorDir() => }
Path.Concat(Главне.Настройки.путь_к_кубачу, "version_descriptors");
public static string GetVersionDescriptorName(IOPath path) =>
path.LastName().RemoveExtension().ToString();
public static IOPath GetVersionDescriptorPath(string name) =>
Path.Concat(GetVersionDescriptorDir(), Path.ReplaceRestrictedChars(name) + ".json");
public static IOPath GetVersionDir() =>
Path.Concat(Главне.Настройки.путь_к_кубачу, "versions");
public static IOPath GetVersionJarFilePath(string name) =>
Path.Concat(GetVersionDir(), name + ".jar");
public static IOPath GetLibrariesDir() =>
Path.Concat(Главне.Настройки.путь_к_кубачу, "libraries");
}

View File

@ -0,0 +1,27 @@
using Млаумчерб.Клиент.видимое;
namespace Млаумчерб.Клиент.классы;
public static class Пути
{
public static IOPath GetAssetIndexFilePath(string id) =>
Path.Concat(Приложение.Настройки.путь_к_кубачу, $"assets/indexes/{id}.json");
public static IOPath GetVersionDescriptorDir() =>
Path.Concat(Приложение.Настройки.путь_к_кубачу, "version_descriptors");
public static string GetVersionDescriptorName(IOPath path) =>
path.LastName().RemoveExtension().ToString();
public static IOPath GetVersionDescriptorPath(string name) =>
Path.Concat(GetVersionDescriptorDir(), Path.ReplaceRestrictedChars(name) + ".json");
public static IOPath GetVersionDir() =>
Path.Concat(Приложение.Настройки.путь_к_кубачу, "versions");
public static IOPath GetVersionJarFilePath(string name) =>
Path.Concat(GetVersionDir(), name + ".jar");
public static IOPath GetLibrariesDir() =>
Path.Concat(Приложение.Настройки.путь_к_кубачу, "libraries");
}