mirror of
https://github.com/babalae/better-genshin-impact.git
synced 2026-04-09 13:00:39 +08:00
* 记录一次对hutaofisher的访谈,帮助开发者理解其算法
* 本地化HelloWorld
* .csproj取消windows版本号,此处导致了IDE在新建代码文件和自动生成代码时,默认命名空间丢失的问题。已知VisualStudio和ReSharper存在这个问题。
* 优化扩展方法写法,改为从localizer扩展;Converter优化写法,避免冲突;新增两种语言,待测试ocr效果
* Revert ".csproj取消windows版本号,此处导致了IDE在新建代码文件和自动生成代码时,默认命名空间丢失的问题。已知VisualStudio和ReSharper存在这个问题。"
This reverts commit 8bd7ee74c5.
* localizer改为由构造函数传入以支持单元测试;一个英语上钩的单元测试
* 传送任务支持英语游戏界面;本地化参数挪至OtherConfig类下,但界面位置暂不挪动,待定
* 调整resx位置风格,放在直接使用字符串的类下;一条龙合成树脂及领取每日奖励支持游戏内中英双语
* 删除无用碎片文件
* 删去两个不必要的Sdcb包引用
* Paddle服务类去掉分类模型;检测和识别新增支持繁中和法语,配有单元测试;因小语种识别效果不理想,使用正则匹配替换多处识别文本相等或包含判断;钓鱼、一条龙合成树脂及领取每日奖励支持游戏内繁中和法语;
* 检查今日奖励任务的多语言化;右侧联机的P图标检测区域宽度缩减,避免英语角色名被误识别成P
* AutoDomainTask的游戏多语言化,由于我的游戏账号无法测试,仅配一些测试用例
* 修复有3个Mizuki导致异常的bug,临时用拼音代替新角色英文名,并为该数据初始化方法添加单元测试
* 瓦雷莎删去别名“牛牛”,因荒泷一斗已占用此别名;别名加载和读取优化
* 加个锁避免单元测试中多线程初始化paddle崩溃
285 lines
9.5 KiB
C#
285 lines
9.5 KiB
C#
using BetterGenshinImpact.Core.Config;
|
||
using BetterGenshinImpact.Core.Recognition.OCR;
|
||
using BetterGenshinImpact.Core.Script;
|
||
using BetterGenshinImpact.GameTask;
|
||
using BetterGenshinImpact.Helpers;
|
||
using BetterGenshinImpact.Model;
|
||
using BetterGenshinImpact.Service.Interface;
|
||
using BetterGenshinImpact.View;
|
||
using CommunityToolkit.Mvvm.ComponentModel;
|
||
using CommunityToolkit.Mvvm.Input;
|
||
using Fischless.GameCapture.BitBlt;
|
||
using Microsoft.Extensions.Logging;
|
||
using OpenCvSharp;
|
||
using System;
|
||
using System.ComponentModel;
|
||
using System.Diagnostics;
|
||
using System.Diagnostics.CodeAnalysis;
|
||
using System.IO;
|
||
using System.Net.Http;
|
||
using System.Net.Http.Json;
|
||
using System.Threading.Tasks;
|
||
using System.Windows;
|
||
using System.Windows.Media;
|
||
using BetterGenshinImpact.View.Windows;
|
||
using BetterGenshinImpact.ViewModel.Pages;
|
||
using DeviceId;
|
||
using Wpf.Ui;
|
||
using Wpf.Ui.Controls;
|
||
|
||
namespace BetterGenshinImpact.ViewModel;
|
||
|
||
public partial class MainWindowViewModel : ObservableObject, IViewModel
|
||
{
|
||
private readonly ILogger<MainWindowViewModel> _logger;
|
||
private readonly IConfigService _configService;
|
||
public string Title => $"BetterGI · 更好的原神 · {Global.Version}{(RuntimeHelper.IsDebug ? " · Dev" : string.Empty)}";
|
||
|
||
[ObservableProperty]
|
||
private bool _isVisible = true;
|
||
|
||
[ObservableProperty]
|
||
private WindowState _windowState = WindowState.Normal;
|
||
|
||
[ObservableProperty]
|
||
private WindowBackdropType _currentBackdropType = WindowBackdropType.Auto;
|
||
|
||
[ObservableProperty]
|
||
private bool _isWin11Later = OsVersionHelper.IsWindows11_OrGreater;
|
||
|
||
public AllConfig Config { get; set; }
|
||
|
||
public MainWindowViewModel(INavigationService navigationService, IConfigService configService)
|
||
{
|
||
_configService = configService;
|
||
Config = _configService.Get();
|
||
_logger = App.GetLogger<MainWindowViewModel>();
|
||
}
|
||
|
||
[RelayCommand]
|
||
private async Task OnActivated()
|
||
{
|
||
await ScriptRepoUpdater.Instance.ImportScriptFromClipboard();
|
||
}
|
||
|
||
[RelayCommand]
|
||
private void OnHide()
|
||
{
|
||
IsVisible = false;
|
||
}
|
||
|
||
[RelayCommand]
|
||
private void OnSwitchBackdrop()
|
||
{
|
||
if (!OsVersionHelper.IsWindows11_22523_OrGreater)
|
||
{
|
||
return; // win10 不支持切换主题
|
||
}
|
||
|
||
CurrentBackdropType = CurrentBackdropType switch
|
||
{
|
||
WindowBackdropType.Mica => WindowBackdropType.Acrylic,
|
||
WindowBackdropType.Acrylic => WindowBackdropType.Mica,
|
||
_ => WindowBackdropType.Acrylic
|
||
};
|
||
|
||
Config.CommonConfig.CurrentBackdropType = CurrentBackdropType;
|
||
|
||
if (Application.Current.MainWindow is MainWindow mainWindow)
|
||
{
|
||
mainWindow.Background = new SolidColorBrush(Color.FromArgb(100, 0, 0, 0));
|
||
WindowBackdrop.ApplyBackdrop(mainWindow, CurrentBackdropType);
|
||
}
|
||
}
|
||
|
||
[RelayCommand]
|
||
private void OnClosing(CancelEventArgs e)
|
||
{
|
||
if (Config.CommonConfig.ExitToTray)
|
||
{
|
||
e.Cancel = true;
|
||
OnHide();
|
||
}
|
||
}
|
||
|
||
[RelayCommand]
|
||
private async Task OnLoaded()
|
||
{
|
||
// 预热OCR
|
||
await OcrPreheating();
|
||
|
||
if (Environment.GetCommandLineArgs().Length > 1)
|
||
{
|
||
return;
|
||
}
|
||
|
||
// 自动处理目录配置
|
||
await Patch1();
|
||
|
||
|
||
// 首次运行
|
||
if (Config.CommonConfig.IsFirstRun)
|
||
{
|
||
// 自动初始化键位绑定
|
||
// InitKeyBinding();
|
||
Config.AutoFightConfig.TeamNames = ""; // 此配置以后无用
|
||
Config.CommonConfig.IsFirstRun = false;
|
||
}
|
||
|
||
// 版本是否运行过
|
||
if (Config.CommonConfig.RunForVersion != Global.Version)
|
||
{
|
||
ModifyFolderSecurity();
|
||
Config.CommonConfig.RunForVersion = Global.Version;
|
||
}
|
||
|
||
OnceRun();
|
||
|
||
// 检查更新
|
||
await App.GetService<IUpdateService>()!.CheckUpdateAsync(new UpdateOption());
|
||
|
||
// Win11下 BitBlt截图方式不可用,需要关闭窗口优化功能
|
||
if (OsVersionHelper.IsWindows11_OrGreater && TaskContext.Instance().Config.AutoFixWin11BitBlt)
|
||
{
|
||
BitBltRegistryHelper.SetDirectXUserGlobalSettings();
|
||
}
|
||
|
||
// 更新仓库
|
||
ScriptRepoUpdater.Instance.AutoUpdate();
|
||
|
||
// 清理临时目录
|
||
TempManager.CleanUp();
|
||
}
|
||
|
||
|
||
private void ModifyFolderSecurity()
|
||
{
|
||
// 检查程序是否位于C盘
|
||
if (Global.StartUpPath.StartsWith(@"C:", StringComparison.OrdinalIgnoreCase))
|
||
{
|
||
// 修改文件夹权限
|
||
SecurityControlHelper.AllowFullFolderSecurity(Global.StartUpPath);
|
||
}
|
||
}
|
||
|
||
/*
|
||
private void InitKeyBinding()
|
||
{
|
||
try
|
||
{
|
||
var kbVm = App.GetService<KeyBindingsSettingsPageViewModel>();
|
||
if (kbVm != null)
|
||
{
|
||
kbVm.FetchFromRegistryCommand.Execute(null);
|
||
}
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
_logger.LogError("首次运行自动初始化按键绑定异常:" + e.Source + "\r\n--" + Environment.NewLine + e.StackTrace + "\r\n---" + Environment.NewLine + e.Message);
|
||
|
||
MessageBox.Error("读取原神键位并设置键位绑定数据时发生异常:" + e.Message + ",后续可以手动设置");
|
||
}
|
||
}
|
||
*/
|
||
|
||
/**
|
||
* 不同的安装目录处理
|
||
* 可能当前目录下存在 BetterGI 的文件,需要移动到新的目录
|
||
*/
|
||
private async Task Patch1()
|
||
{
|
||
var embeddedPath = Global.Absolute("BetterGI");
|
||
var embeddedUserPath = Global.Absolute("BetterGI/User");
|
||
var exePath = Global.Absolute("BetterGI/BetterGI.exe");
|
||
if (Directory.Exists(embeddedPath)
|
||
&& File.Exists(exePath)
|
||
&& Directory.Exists(embeddedUserPath)
|
||
)
|
||
{
|
||
var fileVersionInfo = FileVersionInfo.GetVersionInfo(exePath);
|
||
// 低版本才需要迁移
|
||
if (fileVersionInfo.FileVersion != null && !Global.IsNewVersion(fileVersionInfo.FileVersion))
|
||
{
|
||
var res = await MessageBox.ShowAsync("检测到旧的 BetterGI 配置,是否迁移配置并清理旧目录?", "BetterGI", System.Windows.MessageBoxButton.YesNo, MessageBoxImage.Question);
|
||
if (res == System.Windows.MessageBoxResult.Yes)
|
||
{
|
||
// 迁移配置,拷贝整个目录并覆盖
|
||
DirectoryHelper.CopyDirectory(embeddedUserPath, Global.Absolute("User"));
|
||
// 删除旧目录
|
||
DirectoryHelper.DeleteReadOnlyDirectory(embeddedPath);
|
||
await MessageBox.InformationAsync("迁移配置成功, 软件将自动退出,请手动重新启动 BetterGI!");
|
||
Application.Current.Shutdown();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
private async Task OcrPreheating()
|
||
{
|
||
try
|
||
{
|
||
await Task.Run(async () =>
|
||
{
|
||
try
|
||
{
|
||
string gameCultureInfoName = TaskContext.Instance().Config.OtherConfig.GameCultureInfoName;
|
||
await OcrFactory.ChangeCulture(gameCultureInfoName);
|
||
var s = OcrFactory.Paddle.Ocr(new Mat(Global.Absolute(@"Assets\Model\PaddleOCR\test_ocr.png"), ImreadModes.Grayscale));
|
||
Debug.WriteLine("PaddleOcr预热结果:" + s);
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
Console.WriteLine(e);
|
||
_logger.LogError("PaddleOcr预热异常,解决方案:https://bettergi.com/faq.html:" + e.Source + "\r\n--" + Environment.NewLine + e.StackTrace + "\r\n---" + Environment.NewLine + e.Message);
|
||
var innerException = e.InnerException;
|
||
if (innerException != null)
|
||
{
|
||
_logger.LogError("PaddleOcr预热内部异常,解决方案:https://bettergi.com/faq.html:" + innerException.Source + "\r\n--" + Environment.NewLine + innerException.StackTrace + "\r\n---" + Environment.NewLine + innerException.Message);
|
||
throw innerException;
|
||
}
|
||
else
|
||
{
|
||
throw;
|
||
}
|
||
}
|
||
});
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
MessageBox.Warning("PaddleOcr预热失败,解决方案:https://bettergi.com/faq.html," + e.Source + "\r\n--" + Environment.NewLine + e.StackTrace + "\r\n---" + Environment.NewLine + e.Message);
|
||
}
|
||
}
|
||
|
||
private void OnceRun()
|
||
{
|
||
string deviceId = "default";
|
||
try
|
||
{
|
||
deviceId = new DeviceIdBuilder()
|
||
.OnWindows(windows => windows
|
||
.AddMacAddressFromWmi(excludeWireless: true, excludeNonPhysical: true)
|
||
.AddProcessorId()
|
||
.AddMotherboardSerialNumber()
|
||
)
|
||
.ToString();
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
_logger.LogDebug("获取设备ID异常:" + e.Source + "\r\n--" + Environment.NewLine + e.StackTrace + "\r\n---" + Environment.NewLine + e.Message);
|
||
}
|
||
|
||
// 每个设备只运行一次
|
||
if (!Config.CommonConfig.OnceHadRunDeviceIdList.Contains(deviceId))
|
||
{
|
||
WelcomeDialog prompt = new WelcomeDialog
|
||
{
|
||
Owner = Application.Current.MainWindow
|
||
};
|
||
prompt.ShowDialog();
|
||
prompt.Focus();
|
||
|
||
Config.CommonConfig.OnceHadRunDeviceIdList.Add(deviceId);
|
||
_configService.Save();
|
||
}
|
||
}
|
||
} |