diff --git a/BetterGenshinImpact/App.xaml.cs b/BetterGenshinImpact/App.xaml.cs index 81a8676f..435f8bc8 100644 --- a/BetterGenshinImpact/App.xaml.cs +++ b/BetterGenshinImpact/App.xaml.cs @@ -37,6 +37,11 @@ namespace BetterGenshinImpact .ConfigureServices( (context, services) => { + // 提前初始化配置 + var configService = new ConfigService(); + services.AddSingleton(sp => configService); + var all = configService.Get(); + var logFolder = Path.Combine(AppContext.BaseDirectory, @"log"); Directory.CreateDirectory(logFolder); var logFile = Path.Combine(logFolder, $"better-genshin-impact.log"); @@ -44,13 +49,16 @@ namespace BetterGenshinImpact var maskWindow = new MaskWindow(); services.AddSingleton(maskWindow); - Log.Logger = new LoggerConfiguration() + var loggerConfiguration = new LoggerConfiguration() .WriteTo.File(path: logFile, outputTemplate: "[{Timestamp:HH:mm:ss.fff}] [{Level:u3}] {SourceContext}{NewLine}{Message}{NewLine}{Exception}{NewLine}", rollingInterval: RollingInterval.Day) .MinimumLevel.Information() .MinimumLevel.Override("Microsoft", LogEventLevel.Warning) - .MinimumLevel.Override("Microsoft.Hosting.Lifetime", LogEventLevel.Warning) - .WriteTo.RichTextBox(maskWindow.LogBox, outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj}{NewLine}{Exception}") - .CreateLogger(); + .MinimumLevel.Override("Microsoft.Hosting.Lifetime", LogEventLevel.Warning); + if (all.MaskWindowConfig.MaskEnabled) + { + loggerConfiguration.WriteTo.RichTextBox(maskWindow.LogBox, outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj}{NewLine}{Exception}"); + } + Log.Logger = loggerConfiguration.CreateLogger(); services.AddLogging(c => c.AddSerilog()); @@ -78,7 +86,7 @@ namespace BetterGenshinImpact services.AddSingleton(); // My Services - services.AddSingleton(); + // Configuration //services.Configure(context.Configuration.GetSection(nameof(AppConfig))); diff --git a/BetterGenshinImpact/Core/Config/MaskWindowConfig.cs b/BetterGenshinImpact/Core/Config/MaskWindowConfig.cs index 9e1ec1d3..af795354 100644 --- a/BetterGenshinImpact/Core/Config/MaskWindowConfig.cs +++ b/BetterGenshinImpact/Core/Config/MaskWindowConfig.cs @@ -1,4 +1,5 @@ using System; +using System.Text.Json.Serialization; using CommunityToolkit.Mvvm.ComponentModel; using OpenCvSharp; @@ -20,10 +21,10 @@ namespace BetterGenshinImpact.Core.Config /// [ObservableProperty] private bool _displayRecognitionResultsOnMask = true; - /// - /// 显示遮罩窗口边框 - /// - [ObservableProperty] private bool _showMaskBorder = false; + ///// + ///// 显示遮罩窗口边框 + ///// + //[ObservableProperty] private bool _showMaskBorder = false; /// /// 显示日志窗口 @@ -49,6 +50,7 @@ namespace BetterGenshinImpact.Core.Config /// /// 1080p下UID遮盖的位置与大小 /// - [ObservableProperty] private Rect _uidCoverRect = new(1695, 1052, 168, 22); + [JsonIgnore] + public Rect UidCoverRect = new(1695, 1052, 168, 22); } } \ No newline at end of file diff --git a/BetterGenshinImpact/GameTask/TaskTriggerDispatcher.cs b/BetterGenshinImpact/GameTask/TaskTriggerDispatcher.cs index d9d54187..8508382c 100644 --- a/BetterGenshinImpact/GameTask/TaskTriggerDispatcher.cs +++ b/BetterGenshinImpact/GameTask/TaskTriggerDispatcher.cs @@ -196,14 +196,15 @@ namespace BetterGenshinImpact.GameTask /// private bool SyncMaskWindowPosition() { - var currentRect = SystemControl.GetCaptureRect(TaskContext.Instance().GameHandle); + var hWnd = TaskContext.Instance().GameHandle; + var currentRect = SystemControl.GetCaptureRect(hWnd); if (_gameRect == RECT.Empty) { _gameRect = new RECT(currentRect); } else if (_gameRect != currentRect) { - // 后面大概可以取消掉这个判断,支持随意移动变化窗口 + // 后面大概可以取消掉这个判断,支持随意移动变化窗口 —— 不支持 需要考虑的问题太多了 if (_gameRect.Width != currentRect.Width || _gameRect.Height != currentRect.Height) { _logger.LogError("游戏窗口大小发生变化, 请重新启动捕获程序!"); diff --git a/BetterGenshinImpact/Helpers/DpiHelper.cs b/BetterGenshinImpact/Helpers/DpiHelper.cs index fcc88a39..4ab6ba80 100644 --- a/BetterGenshinImpact/Helpers/DpiHelper.cs +++ b/BetterGenshinImpact/Helpers/DpiHelper.cs @@ -12,7 +12,7 @@ public class DpiHelper private static float GetScaleY() { if (Environment.OSVersion.Version >= new Version(6, 3) - && Application.Current?.MainWindow != null) + && UIDispatcherHelper.MainWindow != null) { HWND hWnd = new WindowInteropHelper(Application.Current?.MainWindow).Handle; HMONITOR hMonitor = User32.MonitorFromWindow(hWnd, User32.MonitorFlags.MONITOR_DEFAULTTONEAREST); diff --git a/BetterGenshinImpact/Service/ConfigService.cs b/BetterGenshinImpact/Service/ConfigService.cs index 052ec1c7..7f4f594c 100644 --- a/BetterGenshinImpact/Service/ConfigService.cs +++ b/BetterGenshinImpact/Service/ConfigService.cs @@ -11,9 +11,11 @@ public class ConfigService : IConfigService { private readonly object _locker = new(); // 只有UI线程会调用这个方法,lock好像意义不大,而且浪费了下面的读写锁hhh private readonly ReaderWriterLockSlim _rwLock = new(); + private readonly JsonSerializerOptions _options = new() { NumberHandling = System.Text.Json.Serialization.JsonNumberHandling.AllowNamedFloatingPointLiterals, + PropertyNamingPolicy = JsonNamingPolicy.CamelCase, WriteIndented = true }; diff --git a/BetterGenshinImpact/View/MainWindow.xaml b/BetterGenshinImpact/View/MainWindow.xaml index dc958a4b..781d5b54 100644 --- a/BetterGenshinImpact/View/MainWindow.xaml +++ b/BetterGenshinImpact/View/MainWindow.xaml @@ -12,7 +12,7 @@ ui:Design.Foreground="{DynamicResource TextFillColorPrimaryBrush}" d:DataContext="{d:DesignInstance Type=viewModel:MainWindowViewModel}" ExtendsContentIntoTitleBar="True" - Title="更好的原神Alpha2" Height="600" Width="900"> + Title="更好的原神" Height="600" Width="900"> - + diff --git a/BetterGenshinImpact/View/MaskWindow.xaml b/BetterGenshinImpact/View/MaskWindow.xaml index ea144d0a..f7146154 100644 --- a/BetterGenshinImpact/View/MaskWindow.xaml +++ b/BetterGenshinImpact/View/MaskWindow.xaml @@ -9,7 +9,8 @@ WindowStyle="None" Topmost="True" Width="500" - Height="800"> + Height="800" + ShowInTaskbar="False"> @@ -20,7 +21,7 @@ Command="{Binding LoadedCommand}" /> - + @@ -68,7 +69,7 @@ FontFamily="Cascadia Mono, Consolas, Courier New, monospace" BorderThickness="0" VerticalScrollBarVisibility="Hidden" - Visibility="{Binding LogTextBoxVisibility}"/> + Visibility="{Binding LogTextBoxVisibility}" /> + diff --git a/BetterGenshinImpact/View/MaskWindow.xaml.cs b/BetterGenshinImpact/View/MaskWindow.xaml.cs index a5ceddb8..00e46de7 100644 --- a/BetterGenshinImpact/View/MaskWindow.xaml.cs +++ b/BetterGenshinImpact/View/MaskWindow.xaml.cs @@ -2,6 +2,8 @@ using BetterGenshinImpact.GameTask; using BetterGenshinImpact.Helpers; using BetterGenshinImpact.View.Drawable; +using CommunityToolkit.Mvvm.Messaging.Messages; +using CommunityToolkit.Mvvm.Messaging; using System; using System.Diagnostics; using System.Globalization; @@ -60,8 +62,10 @@ namespace BetterGenshinImpact.View Top = currentRect.Top * scale; Width = currentRect.Width * scale; Height = currentRect.Height * scale; - // todo 重新计算控件位置 }); + // 重新计算控件位置 + // shit code 预定了 + WeakReferenceMessenger.Default.Send(new PropertyChangedMessage(this, "RefreshSettings", new object(), "重新计算控件位置")); } public MaskWindow() diff --git a/BetterGenshinImpact/View/Pages/CommonSettingsPage.xaml b/BetterGenshinImpact/View/Pages/CommonSettingsPage.xaml index 310247d0..37b67c2b 100644 --- a/BetterGenshinImpact/View/Pages/CommonSettingsPage.xaml +++ b/BetterGenshinImpact/View/Pages/CommonSettingsPage.xaml @@ -6,8 +6,9 @@ xmlns:local="clr-namespace:BetterGenshinImpact.View.Pages" xmlns:pages="clr-namespace:BetterGenshinImpact.ViewModel.Pages" xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml" + xmlns:b="http://schemas.microsoft.com/xaml/behaviors" mc:Ignorable="d" - d:DataContext="{d:DesignInstance Type=pages:MacroSettingsPageViewModel}" + d:DataContext="{d:DesignInstance Type=pages:CommonSettingsPageViewModel}" ui:Design.Background="{DynamicResource ApplicationBackgroundBrush}" ui:Design.Foreground="{DynamicResource TextFillColorPrimaryBrush}" Foreground="{DynamicResource TextFillColorPrimaryBrush}" @@ -78,9 +79,18 @@ Grid.RowSpan="2" Grid.Column="1" Margin="0,0,36,0" - IsChecked="{Binding Config.MaskWindowConfig.ShowLogBox, Mode=TwoWay}" /> + IsChecked="{Binding Config.MaskWindowConfig.ShowLogBox, Mode=TwoWay}" > + + + + + + + + + - + @@ -162,7 +172,16 @@ Grid.RowSpan="2" Grid.Column="1" Margin="0,0,36,0" - IsChecked="{Binding Config.MaskWindowConfig.UidCoverEnabled, Mode=TwoWay}" /> + IsChecked="{Binding Config.MaskWindowConfig.UidCoverEnabled, Mode=TwoWay}" > + + + + + + + + + diff --git a/BetterGenshinImpact/View/Pages/TriggerSettingsPage.xaml b/BetterGenshinImpact/View/Pages/TriggerSettingsPage.xaml index 47bffd40..d4f1c015 100644 --- a/BetterGenshinImpact/View/Pages/TriggerSettingsPage.xaml +++ b/BetterGenshinImpact/View/Pages/TriggerSettingsPage.xaml @@ -100,7 +100,7 @@ Grid.Column="0" Foreground="{ui:ThemeResource TextFillColorTertiaryBrush}" TextWrapping="Wrap" - Text="需要主动按下F交互的内容,请配合黑名单使用" /> + Text="需要主动按下 F 交互的内容,请配合黑名单使用" /> _maskButtons = new(); - public AllConfig Config { get; set; } + public AllConfig? Config { get; set; } [ObservableProperty] private Visibility _logTextBoxVisibility = Visibility.Visible; + [ObservableProperty] private Visibility _uidCoverVisibility = Visibility.Visible; + [ObservableProperty] private Rect _uidCoverRect = new(0, 0, 200, 30); public MaskWindowViewModel() { @@ -55,18 +60,54 @@ namespace BetterGenshinImpact.ViewModel { UIDispatcherHelper.Invoke(() => { _maskButtons.Clear(); }); } + else if (msg.PropertyName == "RefreshSettings") + { + UIDispatcherHelper.Invoke(RefreshSettings); + } }); } [RelayCommand] private void OnLoaded() { - // 这个窗口比较特殊,无法直接使用构造函数依赖注入 - var configService = App.GetService(); - if (configService != null) + RefreshSettings(); + } + + private void RefreshSettings() + { + InitConfig(); + if (Config != null) { - Config = configService.Get(); - LogTextBoxVisibility = Config.MaskWindowConfig.ShowLogBox ? Visibility.Visible: Visibility.Collapsed; + // 日志窗口 + LogTextBoxVisibility = Config.MaskWindowConfig.ShowLogBox ? Visibility.Visible : Visibility.Collapsed; + + // UID遮盖 + UidCoverVisibility = Config.MaskWindowConfig.UidCoverEnabled ? Visibility.Visible : Visibility.Collapsed; + // 比较特殊,必须要启动过任务调度器才能够获取到缩放信息 + if (TaskContext.Instance().SystemInfo != null) + { + var assetScale = TaskContext.Instance().SystemInfo.AssetScale; + var dpiScale = TaskContext.Instance().DpiScale; + UidCoverRect = new Rect(Config.MaskWindowConfig.UidCoverRect.X * assetScale / dpiScale, + Config.MaskWindowConfig.UidCoverRect.Y * assetScale / dpiScale, + Config.MaskWindowConfig.UidCoverRect.Width * assetScale / dpiScale, + Config.MaskWindowConfig.UidCoverRect.Height * assetScale / dpiScale); + } + } + } + + /// + /// 这个窗口比较特殊,无法直接使用构造函数依赖注入 + /// + private void InitConfig() + { + if (Config == null) + { + var configService = App.GetService(); + if (configService != null) + { + Config = configService.Get(); + } } } } diff --git a/BetterGenshinImpact/ViewModel/Pages/CommonSettingsPageViewModel.cs b/BetterGenshinImpact/ViewModel/Pages/CommonSettingsPageViewModel.cs index 4cfbc591..1f8608c2 100644 --- a/BetterGenshinImpact/ViewModel/Pages/CommonSettingsPageViewModel.cs +++ b/BetterGenshinImpact/ViewModel/Pages/CommonSettingsPageViewModel.cs @@ -1,6 +1,9 @@ using BetterGenshinImpact.Core.Config; using BetterGenshinImpact.Service.Interface; using CommunityToolkit.Mvvm.ComponentModel; +using CommunityToolkit.Mvvm.Input; +using CommunityToolkit.Mvvm.Messaging.Messages; +using CommunityToolkit.Mvvm.Messaging; using Wpf.Ui.Controls; namespace BetterGenshinImpact.ViewModel.Pages; @@ -21,4 +24,10 @@ public partial class CommonSettingsPageViewModel : ObservableObject, INavigation public void OnNavigatedFrom() { } + + [RelayCommand] + public void OnRefreshMaskSettings() + { + WeakReferenceMessenger.Default.Send(new PropertyChangedMessage(this, "RefreshSettings", new object(), "重新计算控件位置")); + } } \ No newline at end of file diff --git a/BetterGenshinImpact/ViewModel/Pages/HomePageViewModel.cs b/BetterGenshinImpact/ViewModel/Pages/HomePageViewModel.cs index 396ad16f..32b1afeb 100644 --- a/BetterGenshinImpact/ViewModel/Pages/HomePageViewModel.cs +++ b/BetterGenshinImpact/ViewModel/Pages/HomePageViewModel.cs @@ -118,9 +118,9 @@ public partial class HomePageViewModel : ObservableObject, INavigationAware if (!_taskDispatcherEnabled) { _mouseKeyMonitor.Subscribe(hWnd); + _taskDispatcher.Start(hWnd, Config.CaptureMode.ToCaptureMode()); _maskWindow = MaskWindow.Instance(); _maskWindow.RefreshPosition(hWnd); - _taskDispatcher.Start(hWnd, Config.CaptureMode.ToCaptureMode()); _taskDispatcherEnabled = true; StartButtonVisibility = Visibility.Collapsed; StopButtonVisibility = Visibility.Visible; @@ -134,8 +134,8 @@ public partial class HomePageViewModel : ObservableObject, INavigationAware { if (_taskDispatcherEnabled) { - _mouseKeyMonitor.Unsubscribe(); _maskWindow?.Hide(); + _mouseKeyMonitor.Unsubscribe(); _taskDispatcher.Stop(); _taskDispatcherEnabled = false; StartButtonVisibility = Visibility.Visible;