commit 5b9bd7230828c7f98c9fa51a341ffa40c67a74aa Author: Timerix Date: Sat Aug 31 23:55:57 2024 +0500 projekt sozdan diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..62faaac --- /dev/null +++ b/.gitignore @@ -0,0 +1,22 @@ +# Build results +[Bb]in/ +.bin/ +[Dd]ebug/ +[Rr]elease/ +[Rr]eleases/ +[Oo]bj/ +[Oo]ut/ +[Ll]og/ +[Ll]ogs/ +[Pp]ublish/ + +# IDE files +.vs/ +.vscode/ +.vshistory/ +.idea/ +.editorconfig +*.user + +#backups +.old*/ \ No newline at end of file diff --git a/Млаумчерб.Клиент/Config.cs b/Млаумчерб.Клиент/Config.cs new file mode 100644 index 0000000..d5f0640 --- /dev/null +++ b/Млаумчерб.Клиент/Config.cs @@ -0,0 +1,50 @@ +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace Млаумчерб.Клиент; + +public class Config +{ + public string username { get; set; } = ""; + public int memory { get; set; } = 4096; + public bool fullscreen { get; set; } + + [JsonIgnore] public static Config Instance { get; private set; } = new(); + + public const string FileName = "млаумчерб.конфиг"; + public const string BackupFileName = "млаумчерб.конфиг.старый"; + public static readonly Encoding UTF8WithoutBom = new UTF8Encoding(false); + + public static void LoadFromFile() + { + //TODO: log + if(!File.Exists(FileName)) + { + SaveToFile(); + return; + } + + string text = File.ReadAllText(FileName); + Config? c = JsonSerializer.Deserialize(text); + if (c is not null) + Instance = c; + else + { + File.Move(FileName, BackupFileName, true); + SaveToFile(); + Errors.ShowMessageBox($"Не удалось прочитать конфиг.\n" + + $"Сломанный конфиг переименован в '{BackupFileName}'.\n" + + $"Создан новый файл '{FileName}'."); + } + } + + public static void SaveToFile() + { + //TODO: log + var text = JsonSerializer.Serialize(Instance, new JsonSerializerOptions + { + WriteIndented = true + }); + File.WriteAllText(FileName, text, UTF8WithoutBom); + } +} \ No newline at end of file diff --git a/Млаумчерб.Клиент/Errors.cs b/Млаумчерб.Клиент/Errors.cs new file mode 100644 index 0000000..780a5c8 --- /dev/null +++ b/Млаумчерб.Клиент/Errors.cs @@ -0,0 +1,34 @@ +using Avalonia.Controls; +using DTLib.Ben.Demystifier; +using MsBox.Avalonia; +using MsBox.Avalonia.Dto; +using MsBox.Avalonia.Models; + +namespace Млаумчерб.Клиент; + +public static class Errors +{ + internal static void ShowMessageBox(Exception err) + => ShowMessageBox(err.ToStringDemystified()); + + internal static async void ShowMessageBox(string err) + { + var box = MessageBoxManager.GetMessageBoxCustom(new MessageBoxCustomParams + { + ButtonDefinitions = new List { new() { Name = "пон" } }, + ContentTitle = "ОШИБКА", + ContentMessage = err, + Icon = MsBox.Avalonia.Enums.Icon.Error, + WindowStartupLocation = WindowStartupLocation.CenterOwner, + CanResize = true, + MaxWidth = 1000, + MaxHeight = 1000, + SizeToContent = SizeToContent.WidthAndHeight, + ShowInCenter = true, + Topmost = true + } + ); + //TODO: write to log + await box.ShowAsync().ConfigureAwait(false); + } +} \ No newline at end of file diff --git a/Млаумчерб.Клиент/Главне.cs b/Млаумчерб.Клиент/Главне.cs new file mode 100644 index 0000000..3d24583 --- /dev/null +++ b/Млаумчерб.Клиент/Главне.cs @@ -0,0 +1,25 @@ +global using System; +global using System.Collections.Generic; +global using System.IO; +global using System.Text; +using System.Globalization; +using Avalonia; + +namespace Млаумчерб.Клиент; + +class Главне +{ + [STAThread] + public static void Main(string[] args) + { + CultureInfo.DefaultThreadCurrentCulture = CultureInfo.InvariantCulture; + BuildAvaloniaApp() + .StartWithClassicDesktopLifetime(args); + } + + // Avalonia configuration, don't remove; also used by visual designer. + public static AppBuilder BuildAvaloniaApp() + => AppBuilder.Configure<Приложение>() + .UsePlatformDetect() + .LogToTrace(); +} \ No newline at end of file diff --git a/Млаумчерб.Клиент/Млаумчерб.Клиент.csproj b/Млаумчерб.Клиент/Млаумчерб.Клиент.csproj new file mode 100644 index 0000000..7977120 --- /dev/null +++ b/Млаумчерб.Клиент/Млаумчерб.Клиент.csproj @@ -0,0 +1,28 @@ + + + WinExe + net8.0 + latest + enable + disable + true + гойда.manifest + true + капитал\icon.ico + млаумчерб + + + + + + + + + + + + + + + + diff --git a/Млаумчерб.Клиент/Окне.axaml b/Млаумчерб.Клиент/Окне.axaml new file mode 100644 index 0000000..afd68d1 --- /dev/null +++ b/Млаумчерб.Клиент/Окне.axaml @@ -0,0 +1,51 @@ + + + 40 * + + + + * 400 * + + + * 60 + + Username: + + + Memory limit: + + + Mb + + + + Fullscreen + Update game files + + + + + + + diff --git a/Млаумчерб.Клиент/Окне.axaml.cs b/Млаумчерб.Клиент/Окне.axaml.cs new file mode 100644 index 0000000..9ede669 --- /dev/null +++ b/Млаумчерб.Клиент/Окне.axaml.cs @@ -0,0 +1,82 @@ +using Avalonia; +using Avalonia.Controls; +using Avalonia.Data; +using Avalonia.Interactivity; + +namespace Млаумчерб.Клиент; + +public partial class Окне : Window +{ + public static readonly StyledProperty UsernameProperty = + AvaloniaProperty.Register<Окне, string>(nameof(Username), + defaultBindingMode: BindingMode.TwoWay); + public string Username + { + get => GetValue(UsernameProperty); + set => SetValue(UsernameProperty, value); + } + + public static readonly StyledProperty MemoryLimitProperty = + AvaloniaProperty.Register<Окне, int>(nameof(MemoryLimit), + defaultBindingMode: BindingMode.TwoWay, defaultValue: 2048); + public int MemoryLimit + { + get => GetValue(MemoryLimitProperty); + set => SetValue(MemoryLimitProperty, value); + } + + public static readonly StyledProperty FullscreenProperty = + AvaloniaProperty.Register<Окне, bool>(nameof(Fullscreen), + defaultBindingMode: BindingMode.TwoWay, defaultValue: false); + public bool Fullscreen + { + get => GetValue(FullscreenProperty); + set => SetValue(FullscreenProperty, value); + } + + public static readonly StyledProperty UpdateGameFilesProperty = + AvaloniaProperty.Register<Окне, bool>(nameof(UpdateGameFiles), + defaultBindingMode: BindingMode.TwoWay, defaultValue: true); + public bool UpdateGameFiles + { + get => GetValue(UpdateGameFilesProperty); + set => SetValue(UpdateGameFilesProperty, value); + } + + public Окне() + { + InitializeComponent(); + } + + protected override void OnLoaded(RoutedEventArgs e) + { + try + { + Config.LoadFromFile(); + Username = Config.Instance.username; + MemoryLimit = Config.Instance.memory; + Fullscreen = Config.Instance.fullscreen; + } + catch (Exception ex) + { + Errors.ShowMessageBox(ex); + } + } + + private void LaunchButtonHandler(object? sender, RoutedEventArgs e) + { + try + { + Config.Instance.username = Username; + Config.Instance.memory = MemoryLimit; + Config.Instance.fullscreen = Fullscreen; + Config.SaveToFile(); + + + } + catch (Exception ex) + { + Errors.ShowMessageBox(ex); + } + } +} \ No newline at end of file diff --git a/Млаумчерб.Клиент/Приложение.axaml b/Млаумчерб.Клиент/Приложение.axaml new file mode 100644 index 0000000..78bbfe3 --- /dev/null +++ b/Млаумчерб.Клиент/Приложение.axaml @@ -0,0 +1,12 @@ + + + + + + + avares://млаумчерб/капитал/IBMPlexMono-Regular.ttf + + \ No newline at end of file diff --git a/Млаумчерб.Клиент/Приложение.axaml.cs b/Млаумчерб.Клиент/Приложение.axaml.cs new file mode 100644 index 0000000..679bf36 --- /dev/null +++ b/Млаумчерб.Клиент/Приложение.axaml.cs @@ -0,0 +1,23 @@ +using Avalonia; +using Avalonia.Controls.ApplicationLifetimes; +using Avalonia.Markup.Xaml; + +namespace Млаумчерб.Клиент; + +public partial class Приложение : Application +{ + public override void Initialize() + { + AvaloniaXamlLoader.Load(this); + } + + public override void OnFrameworkInitializationCompleted() + { + if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) + { + desktop.MainWindow = new Окне(); + } + + base.OnFrameworkInitializationCompleted(); + } +} \ No newline at end of file diff --git a/Млаумчерб.Клиент/гойда.manifest b/Млаумчерб.Клиент/гойда.manifest new file mode 100644 index 0000000..f332ecc --- /dev/null +++ b/Млаумчерб.Клиент/гойда.manifest @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + diff --git a/Млаумчерб.Клиент/капитал/IBMPlexMono-Regular.ttf b/Млаумчерб.Клиент/капитал/IBMPlexMono-Regular.ttf new file mode 100644 index 0000000..81ca3dc Binary files /dev/null and b/Млаумчерб.Клиент/капитал/IBMPlexMono-Regular.ttf differ diff --git a/Млаумчерб.Клиент/капитал/background.png b/Млаумчерб.Клиент/капитал/background.png new file mode 100644 index 0000000..51eb05d Binary files /dev/null and b/Млаумчерб.Клиент/капитал/background.png differ diff --git a/Млаумчерб.Клиент/капитал/button.png b/Млаумчерб.Клиент/капитал/button.png new file mode 100644 index 0000000..c4c41c0 Binary files /dev/null and b/Млаумчерб.Клиент/капитал/button.png differ diff --git a/Млаумчерб.Клиент/капитал/icon.ico b/Млаумчерб.Клиент/капитал/icon.ico new file mode 100644 index 0000000..abd2ff9 Binary files /dev/null and b/Млаумчерб.Клиент/капитал/icon.ico differ diff --git a/Млаумчерб.Клиент/собрать b/Млаумчерб.Клиент/собрать new file mode 100644 index 0000000..6fcbcfb --- /dev/null +++ b/Млаумчерб.Клиент/собрать @@ -0,0 +1,47 @@ +#!/usr/bin/env bash +set -eo pipefail + +mode="$1" + +outdir="bin/publish" +args_selfcontained=" + --self-contained + --use-current-runtime + -p:PublishSingleFile=true + -p:PublishTrimmed=true + -p:TrimMode=partial + -p:EnableCompressionInSingleFile=true + -p:OptimizationPreference=Size + -p:InvariantGlobalization=true + -p:DebugType=none + -p:IncludeNativeLibrariesForSelfExtract=true" + +args_aot=" + -p:PublishAot=true + -p:OptimizationPreference=Size + -p:DebugType=none" + +case "$mode" in + aot | native | бинарное) + args="$args_aot" + ;; + self-contained | selfcontained | небинарное) + args="$args_selfcontained" + ;; + *) + echo "ПОЛЬЗОВАНИЕ: ./собрать.sh [способ]" + echo " СПОСОБЫ:" + echo " бинарное - компилирует промежуточный (управляемый) код в машинный вместе с рантаймом" + echo " небинарное - приделывает промежуточный (управляемый) код к рантайму" + echo " Оба способа собирают программу в один файл, который не является 80-мегабайтовым умственно отсталым кубом. Он 20-мегабайтовый >w<" + exit 1 + ;; +esac + +rm -rf "$outdir" +command="dotnet publish -c Release -o $outdir $args" +echo "$command" +$command + +find "$outdir" -name '*.pdb' -delete -printf "deleted '%p'\n" +ls -shk "$outdir" | sort -h diff --git a/млаумчерб.sln b/млаумчерб.sln new file mode 100644 index 0000000..7a76a1d --- /dev/null +++ b/млаумчерб.sln @@ -0,0 +1,16 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Млаумчерб.Клиент", "Млаумчерб.Клиент\Млаумчерб.Клиент.csproj", "{9B9D8B05-255F-49C3-89EC-3F43A66491D3}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {9B9D8B05-255F-49C3-89EC-3F43A66491D3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9B9D8B05-255F-49C3-89EC-3F43A66491D3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9B9D8B05-255F-49C3-89EC-3F43A66491D3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9B9D8B05-255F-49C3-89EC-3F43A66491D3}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal