diff --git a/BetterGenshinImpact/Assets/Model/World/bgi_world.onnx b/BetterGenshinImpact/Assets/Model/World/bgi_world.onnx
index 1c8820dd..e4af2e34 100644
Binary files a/BetterGenshinImpact/Assets/Model/World/bgi_world.onnx and b/BetterGenshinImpact/Assets/Model/World/bgi_world.onnx differ
diff --git a/BetterGenshinImpact/BetterGenshinImpact.csproj b/BetterGenshinImpact/BetterGenshinImpact.csproj
index 286a9169..ec4eb95b 100644
--- a/BetterGenshinImpact/BetterGenshinImpact.csproj
+++ b/BetterGenshinImpact/BetterGenshinImpact.csproj
@@ -10,7 +10,7 @@
true
Assets\Images\logo.ico
BetterGI
- 0.39.4
+ 0.39.6
x64
embedded
diff --git a/BetterGenshinImpact/Core/Config/AllConfig.cs b/BetterGenshinImpact/Core/Config/AllConfig.cs
index 7e6a0d42..dcb50edf 100644
--- a/BetterGenshinImpact/Core/Config/AllConfig.cs
+++ b/BetterGenshinImpact/Core/Config/AllConfig.cs
@@ -17,6 +17,7 @@ using System.Collections.Generic;
using System.ComponentModel;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
+using BetterGenshinImpact.GameTask.AutoTrackPath;
namespace BetterGenshinImpact.Core.Config;
@@ -175,7 +176,11 @@ public partial class AllConfig : ObservableObject
/// 原神按键绑定配置
///
public KeyBindingsConfig KeyBindingsConfig { get; set; } = new();
-
+
+ ///
+ /// 传送相关配置
+ ///
+ public TpConfig TpConfig { get; set; } = new();
[JsonIgnore]
public Action? OnAnyChangedAction { get; set; }
@@ -188,7 +193,6 @@ public partial class AllConfig : ObservableObject
NotificationConfig.PropertyChanged += OnAnyPropertyChanged;
NotificationConfig.PropertyChanged += OnNotificationPropertyChanged;
KeyBindingsConfig.PropertyChanged += OnAnyPropertyChanged;
-
AutoPickConfig.PropertyChanged += OnAnyPropertyChanged;
AutoSkipConfig.PropertyChanged += OnAnyPropertyChanged;
AutoFishingConfig.PropertyChanged += OnAnyPropertyChanged;
@@ -200,7 +204,7 @@ public partial class AllConfig : ObservableObject
AutoFightConfig.PropertyChanged += OnAnyPropertyChanged;
AutoDomainConfig.PropertyChanged += OnAnyPropertyChanged;
AutoMusicGameConfig.PropertyChanged += OnAnyPropertyChanged;
-
+ TpConfig.PropertyChanged += OnAnyPropertyChanged;
ScriptConfig.PropertyChanged += OnAnyPropertyChanged;
PathingConditionConfig.PropertyChanged += OnAnyPropertyChanged;
}
diff --git a/BetterGenshinImpact/Core/Config/CommonConfig.cs b/BetterGenshinImpact/Core/Config/CommonConfig.cs
index 957012f2..6da8e1f9 100644
--- a/BetterGenshinImpact/Core/Config/CommonConfig.cs
+++ b/BetterGenshinImpact/Core/Config/CommonConfig.cs
@@ -32,5 +32,11 @@ public partial class CommonConfig : ObservableObject
/// 主题
///
[ObservableProperty]
- private WindowBackdropType _currentBackdropType = WindowBackdropType.Auto;
+ private WindowBackdropType _currentBackdropType = WindowBackdropType.Mica;
+
+ ///
+ /// 是否是第一次运行
+ ///
+ [ObservableProperty]
+ private bool _isFirstRun = true;
}
diff --git a/BetterGenshinImpact/GameTask/AutoDomain/AutoDomainTask.cs b/BetterGenshinImpact/GameTask/AutoDomain/AutoDomainTask.cs
index 0ebd0030..794764f4 100644
--- a/BetterGenshinImpact/GameTask/AutoDomain/AutoDomainTask.cs
+++ b/BetterGenshinImpact/GameTask/AutoDomain/AutoDomainTask.cs
@@ -436,6 +436,7 @@ public class AutoDomainTask : ISoloTask
finally
{
Logger.LogInformation("自动战斗线程结束");
+ combatScenes.AfterTask();
}
}, cts.Token);
diff --git a/BetterGenshinImpact/GameTask/AutoFight/AutoFightConfig.cs b/BetterGenshinImpact/GameTask/AutoFight/AutoFightConfig.cs
index 4ecfa868..f3ec286f 100644
--- a/BetterGenshinImpact/GameTask/AutoFight/AutoFightConfig.cs
+++ b/BetterGenshinImpact/GameTask/AutoFight/AutoFightConfig.cs
@@ -25,6 +25,13 @@ public partial class AutoFightConfig : ObservableObject
///
[ObservableProperty]
private bool _fightFinishDetectEnabled = true;
+ ///
+ /// 根据技能CD优化出招人员
+ /// 根据填入人或人和cd,来决定当此人元素战技cd未结束时,跳过此人出招,来优化战斗流程,可填入人名或人名数字(用逗号分隔),
+ /// 多种用分号分隔,例如:白术;钟离,12;,如果人名,则用内置cd检查,如果是人名和数字,则把数字当做出招cd(秒)。
+ ///
+ [ObservableProperty] private string _actionSchedulerByCd = "";
+
[Serializable]
public partial class FightFinishDetectConfig : ObservableObject
{
@@ -72,6 +79,40 @@ public partial class AutoFightConfig : ObservableObject
[ObservableProperty]
private bool _pickDropsAfterFightEnabled = true;
+ [Serializable]
+ public partial class PickDropsAfterFightConfig : ObservableObject
+ {
+ ///
+ /// 前进次数
+ ///
+ [ObservableProperty]
+ private int _forwardTimes = 6;
+
+ ///
+ /// 校准次数
+ ///
+ [ObservableProperty]
+ private int _calibrationTimes = 15;
+
+ ///
+ /// 衰减因子
+ ///
+ [ObservableProperty]
+ private double _decayFactor = 0.7;
+
+ ///
+ /// 前进量(秒),设置为0时在[1,3]中随机
+ ///
+ [ObservableProperty]
+ private int _forwardSeconds = 2;
+
+ }
+ ///
+ /// 掉落寻物相关配置
+ ///
+ [ObservableProperty]
+ private PickDropsAfterFightConfig _pickDropsConfig = new();
+
///
/// 战斗结束后,如果存在枫原万叶,则使用该角色捡材料
///
diff --git a/BetterGenshinImpact/GameTask/AutoFight/AutoFightParam.cs b/BetterGenshinImpact/GameTask/AutoFight/AutoFightParam.cs
index 72003705..3e4ac777 100644
--- a/BetterGenshinImpact/GameTask/AutoFight/AutoFightParam.cs
+++ b/BetterGenshinImpact/GameTask/AutoFight/AutoFightParam.cs
@@ -26,6 +26,7 @@ public class AutoFightParam : BaseTaskParam
FightFinishDetectEnabled = autoFightConfig.FightFinishDetectEnabled;
PickDropsAfterFightEnabled = autoFightConfig.PickDropsAfterFightEnabled;
KazuhaPickupEnabled = autoFightConfig.KazuhaPickupEnabled;
+ ActionSchedulerByCd = autoFightConfig.ActionSchedulerByCd;
FinishDetectConfig.FastCheckEnabled = autoFightConfig.FinishDetectConfig.FastCheckEnabled;
FinishDetectConfig.FastCheckParams = autoFightConfig.FinishDetectConfig.FastCheckParams;
@@ -47,6 +48,7 @@ public class AutoFightParam : BaseTaskParam
public int Timeout { get; set; } = 120;
public bool KazuhaPickupEnabled = true;
+ public string ActionSchedulerByCd = "";
}
\ No newline at end of file
diff --git a/BetterGenshinImpact/GameTask/AutoFight/AutoFightTask.cs b/BetterGenshinImpact/GameTask/AutoFight/AutoFightTask.cs
index 256c2a40..16ab96c9 100644
--- a/BetterGenshinImpact/GameTask/AutoFight/AutoFightTask.cs
+++ b/BetterGenshinImpact/GameTask/AutoFight/AutoFightTask.cs
@@ -202,6 +202,7 @@ public class AutoFightTask : ISoloTask
throw new Exception("识别队伍角色失败");
}
+ var actionSchedulerByCd = ParseStringToDictionary(_taskParam.ActionSchedulerByCd);
var combatCommands = _combatScriptBag.FindCombatScript(combatScenes.Avatars);
// 新的取消token
@@ -221,7 +222,8 @@ public class AutoFightTask : ISoloTask
return;
}*/
var fightEndFlag = false;
- string lastFighttName = "";
+ string lastFightName = "";
+ string skipFightName = "";
//统计切换人打架次数
var countFight = 0;
// 战斗操作
@@ -242,6 +244,30 @@ public class AutoFightTask : ISoloTask
break;
}
+ //根据元素技能冷却事件优化出招流程,只有当人物切换后才会触发检查
+ double skillCd;
+ if (lastFightName != command.Name && actionSchedulerByCd.TryGetValue(command.Name,out skillCd))
+ {
+ var avatar = combatScenes.Avatars.FirstOrDefault(a => a.Name == command.Name);
+ if (skillCd < 0)
+ {
+ skillCd = FindMax([avatar.SkillCd,avatar.SkillHoldCd]);
+ }
+ var dif=(DateTime.UtcNow - avatar.LastSkillTime);
+ //当技能未冷却时,跳过此次出招
+ if ((DateTime.UtcNow -avatar.LastSkillTime).TotalSeconds < skillCd)
+ {
+ if (skipFightName != command.Name)
+ {
+ Logger.LogInformation($"{command.Name}cd冷却为{skillCd}秒,剩余{skillCd-dif.TotalSeconds}秒,跳过此次行动");
+ }
+ skipFightName = command.Name;
+ continue;
+ }
+ }
+
+
+
command.Execute(combatScenes);
//统计战斗人次
if (i == combatCommands.Count - 1 || command.Name != combatCommands[i + 1].Name)
@@ -249,7 +275,7 @@ public class AutoFightTask : ISoloTask
countFight++;
}
- lastFighttName = command.Name;
+ lastFightName = command.Name;
if (!fightEndFlag && _taskParam is { FightFinishDetectEnabled: true })
{
//处于最后一个位置,或者当前执行人和下一个人名字不一样的情况,满足一定条件(开启快速检查,并且检查时间大于0或人名存在配置)检查战斗
@@ -341,7 +367,7 @@ public class AutoFightTask : ISoloTask
{
var time = DateTime.UtcNow - kazuha.LastSkillTime;
//当万叶cd大于3时或战斗人次少于2时(通常无怪物情况下),此时不再触发万叶拾取,
- if (!(countFight < 2 || lastFighttName == "枫原万叶" && time.TotalSeconds > 3))
+ if (!(countFight < 2 || lastFightName == "枫原万叶" && time.TotalSeconds > 3))
{
Logger.LogInformation("使用枫原万叶长E拾取掉落物");
await Delay(300, ct);
@@ -470,6 +496,53 @@ public class AutoFightTask : ISoloTask
(g >= 240 && g <= 255) &&
(b >= 240 && b <= 255);
}
+ static double FindMax(double[] numbers)
+ {
+ if (numbers == null || numbers.Length == 0)
+ {
+ throw new ArgumentException("The array is empty or null.");
+ }
+
+ double max = numbers[0]>10000 ? 0 : numbers[0];
+ foreach (var num in numbers)
+ {
+ var cpnum = numbers[0]>10000 ? 0 : num;
+ max = Math.Max(max, num);
+ }
+
+ return max;
+ }
+ private static Dictionary ParseStringToDictionary(string input,double defaultValue=-1)
+ {
+ var dictionary = new Dictionary();
+
+ if (string.IsNullOrEmpty(input))
+ {
+ return dictionary; // 返回空字典
+ }
+
+ string[] pairs = input.Split(';', StringSplitOptions.RemoveEmptyEntries);
+
+ foreach (var pair in pairs)
+ {
+ var parts = pair.Split(',', StringSplitOptions.TrimEntries);
+
+ if (parts.Length > 0)
+ {
+ string name = parts[0];
+ double value = defaultValue;
+
+ if (parts.Length > 1 && double.TryParse(parts[1], out var parsedValue))
+ {
+ value = parsedValue;
+ }
+
+ dictionary[name] = value;
+ }
+ }
+
+ return dictionary;
+ }
private bool HasFightFlagByYolo(ImageRegion imageRegion)
{
diff --git a/BetterGenshinImpact/GameTask/AutoFight/Model/CombatScenes.cs b/BetterGenshinImpact/GameTask/AutoFight/Model/CombatScenes.cs
index e9ae9e05..7d4c26a0 100644
--- a/BetterGenshinImpact/GameTask/AutoFight/Model/CombatScenes.cs
+++ b/BetterGenshinImpact/GameTask/AutoFight/Model/CombatScenes.cs
@@ -31,7 +31,7 @@ public class CombatScenes : IDisposable
///
/// 当前配队
///
- public Avatar[] Avatars { get; set; } = Array.Empty();
+ public Avatar[] Avatars { get; set; } = [];
public Dictionary AvatarMap { get; set; } = [];
@@ -70,6 +70,7 @@ public class CombatScenes : IDisposable
{
throw new Exception("当前处于联机状态,但是队伍人数超过4人,无法识别");
}
+
// 联机状态下判断
var onePRa = imageRegion.Find(AutoFightAssets.Instance.OnePRa);
var p = "p";
@@ -167,7 +168,7 @@ public class CombatScenes : IDisposable
if (result.TopClass.Confidence < 0.51)
{
Cv2.ImWrite(@"log\avatar_side_classify_error.png", src.ToMat());
- throw new Exception($"无法识别第{index}位角色,置信度{result.TopClass.Confidence:F1},结果:{result.TopClass.Name.Name}。请确认您是否阅读了文档中的《快速上手》!");
+ throw new Exception($"无法识别第{index}位角色,置信度{result.TopClass.Confidence:F1},结果:{result.TopClass.Name.Name}。请重新阅读了文档中的《快速上手》!");
}
}
else
@@ -175,7 +176,7 @@ public class CombatScenes : IDisposable
if (result.TopClass.Confidence < 0.7)
{
Cv2.ImWrite(@"log\avatar_side_classify_error.png", src.ToMat());
- throw new Exception($"无法识别第{index}位角色,置信度{result.TopClass.Confidence:F1},结果:{result.TopClass.Name.Name}。请确认您是否阅读了文档中的《快速上手》!");
+ throw new Exception($"无法识别第{index}位角色,置信度{result.TopClass.Confidence:F1},结果:{result.TopClass.Name.Name}。请重新阅读了文档中的《快速上手》!");
}
}
@@ -246,6 +247,21 @@ public class CombatScenes : IDisposable
}
}
+ public void AfterTask()
+ {
+ var mwk = SelectAvatar("玛薇卡");
+ if (mwk != null)
+ {
+ foreach (var avatar in Avatars)
+ {
+ if (avatar.Name != "玛薇卡")
+ {
+ avatar.Switch();
+ }
+ }
+ }
+ }
+
public Avatar? SelectAvatar(string name)
{
return AvatarMap.GetValueOrDefault(name);
@@ -381,4 +397,4 @@ public class CombatScenes : IDisposable
{
_predictor.Dispose();
}
-}
+}
\ No newline at end of file
diff --git a/BetterGenshinImpact/GameTask/AutoGeniusInvokation/AutoGeniusInvokationTask.cs b/BetterGenshinImpact/GameTask/AutoGeniusInvokation/AutoGeniusInvokationTask.cs
index f2610997..731cd993 100644
--- a/BetterGenshinImpact/GameTask/AutoGeniusInvokation/AutoGeniusInvokationTask.cs
+++ b/BetterGenshinImpact/GameTask/AutoGeniusInvokation/AutoGeniusInvokationTask.cs
@@ -1,5 +1,7 @@
using System.Threading;
using System.Threading.Tasks;
+using BetterGenshinImpact.GameTask.Common;
+using Microsoft.Extensions.Logging;
namespace BetterGenshinImpact.GameTask.AutoGeniusInvokation;
@@ -9,9 +11,17 @@ public class AutoGeniusInvokationTask(GeniusInvokationTaskParam taskParam) : ISo
public Task Start(CancellationToken ct)
{
- // 读取策略信息
- var duel = ScriptParser.Parse(taskParam.StrategyContent);
- duel.Run(ct);
+ try
+ {
+ // 读取策略信息
+ var duel = ScriptParser.Parse(taskParam.StrategyContent);
+ duel.Run(ct);
+ }
+ catch (System.Exception e)
+ {
+ TaskControl.Logger.LogDebug(e, "执行自动七圣召唤任务异常");
+ TaskControl.Logger.LogError("执行自动七圣召唤任务异常:{Exception}", e.Message);
+ }
return Task.CompletedTask;
}
-}
+}
\ No newline at end of file
diff --git a/BetterGenshinImpact/GameTask/AutoGeniusInvokation/ScriptParser.cs b/BetterGenshinImpact/GameTask/AutoGeniusInvokation/ScriptParser.cs
index 11fe0f92..fb5cdb37 100644
--- a/BetterGenshinImpact/GameTask/AutoGeniusInvokation/ScriptParser.cs
+++ b/BetterGenshinImpact/GameTask/AutoGeniusInvokation/ScriptParser.cs
@@ -117,7 +117,7 @@ public class ScriptParser
var characterAndSkill = line.Split('{');
var parts = characterAndSkill[0].Split('=');
- character.Index = int.Parse(RegexHelper.ExcludeNumberRegex().Replace(parts[0], ""));
+ character.Index = int.Parse(RegexHelper.ExcludeNumberRegex().Replace(parts[0].Trim(), ""));
MyAssert(character.Index >= 1 && character.Index <= 3, "角色序号必须在1-3之间");
if (parts[1].Contains('|'))
diff --git a/BetterGenshinImpact/GameTask/AutoPathing/Model/Enum/MoveModeEnum.cs b/BetterGenshinImpact/GameTask/AutoPathing/Model/Enum/MoveModeEnum.cs
index 505ea03f..7301da39 100644
--- a/BetterGenshinImpact/GameTask/AutoPathing/Model/Enum/MoveModeEnum.cs
+++ b/BetterGenshinImpact/GameTask/AutoPathing/Model/Enum/MoveModeEnum.cs
@@ -6,6 +6,7 @@ public class MoveModeEnum(string code, string msg)
{
public static readonly MoveModeEnum Walk = new("walk", "步行");
public static readonly MoveModeEnum Run = new("run", "奔跑");
+ public static readonly MoveModeEnum Dash = new("dash", "持续冲刺");
public static readonly MoveModeEnum Climb = new("climb", "攀爬");
public static readonly MoveModeEnum Fly = new("fly", "飞行");
public static readonly MoveModeEnum Jump = new("jump", "跳跃");
diff --git a/BetterGenshinImpact/GameTask/AutoPathing/PathExecutor.cs b/BetterGenshinImpact/GameTask/AutoPathing/PathExecutor.cs
index e6b444d0..82e56065 100644
--- a/BetterGenshinImpact/GameTask/AutoPathing/PathExecutor.cs
+++ b/BetterGenshinImpact/GameTask/AutoPathing/PathExecutor.cs
@@ -680,7 +680,23 @@ public class PathExecutor
// 只有设置为run才会一直疾跑
if (waypoint.MoveMode == MoveModeEnum.Run.Code)
{
- if (distance > 25) // 距离大于25时可以使用疾跑
+ if (distance > 20 != fastMode) // 距离大于20时可以使用疾跑/自由泳
+ {
+ if (fastMode)
+ {
+ Simulation.SendInput.SimulateAction(GIActions.SprintMouse, KeyType.KeyUp);
+ }
+ else
+ {
+ Simulation.SendInput.SimulateAction(GIActions.SprintMouse, KeyType.KeyDown);
+ }
+
+ fastMode = !fastMode;
+ }
+ }
+ else if (waypoint.MoveMode == MoveModeEnum.Dash.Code)
+ {
+ if (distance > 20) // 距离大于25时可以使用疾跑
{
if (Math.Abs((fastModeColdTime - DateTime.UtcNow).TotalMilliseconds) > 1000) //冷却一会
{
diff --git a/BetterGenshinImpact/GameTask/AutoSkip/Assets/hangout.json b/BetterGenshinImpact/GameTask/AutoSkip/Assets/hangout.json
index 677e458f..09f77f9e 100644
--- a/BetterGenshinImpact/GameTask/AutoSkip/Assets/hangout.json
+++ b/BetterGenshinImpact/GameTask/AutoSkip/Assets/hangout.json
@@ -41,25 +41,25 @@
"我带凯亚去没去过的地方玩吧"
],
"卡维结局1:未来蓝图": [
- "一起去说服委托人吧",
+ "一起去说服刚刚的委托人吧",
"尝试一下新的风格"
],
"卡维结局2:契约达成": [
- "一起去说服委托人吧",
+ "一起去说服刚刚的委托人吧",
"可以找其他商人筹款"
],
"卡维结局3:闲时小聚": [
- "做些别的事转化心情",
+ "做些别的事转换心情",
"卡维为什么要当设计师呢",
"去找熟人问问"
],
"卡维结局4:群星之下": [
- "做些别的事转化心情",
+ "做些别的事转换心情",
"卡维为什么要当设计师呢",
"还是先别管这个了"
],
"卡维结局5:第1堂课": [
- "做些别的事转化心情",
+ "做些别的事转换心情",
"找份其他工作赚钱"
],
"莱依拉结局1:不可说之事": [
@@ -74,7 +74,7 @@
"莱依拉结局2:代价与回报": [
"虽然有些不靠谱",
"我陪你去找答案",
- "仙灵应该不想苛责你"
+ "仙灵应该不只是想苛责你"
],
"莱依拉结局3:不愿重蹈覆辙": [
"虽然有些不靠谱",
diff --git a/BetterGenshinImpact/GameTask/AutoTrackPath/TpConfig.cs b/BetterGenshinImpact/GameTask/AutoTrackPath/TpConfig.cs
new file mode 100644
index 00000000..5187dd84
--- /dev/null
+++ b/BetterGenshinImpact/GameTask/AutoTrackPath/TpConfig.cs
@@ -0,0 +1,55 @@
+using CommunityToolkit.Mvvm.ComponentModel;
+using System;
+
+namespace BetterGenshinImpact.GameTask.AutoTrackPath;
+
+public partial class TpConfig : ObservableObject
+{
+ [ObservableProperty]
+ private bool _mapZoomEnabled = true; // 地图缩放开关
+
+ [ObservableProperty]
+ private int _mapZoomOutDistance = 2000; // 地图缩小的最小距离,单位:像素
+
+ [ObservableProperty]
+ private int _mapZoomInDistance = 400; // 地图放大的最大距离,单位:像素
+
+ [ObservableProperty]
+ private int _stepIntervalMilliseconds = 20; // 鼠标移动时间间隔,单位:ms
+
+ [ObservableProperty]
+ private double _maxZoomLevel = 5.0; // 最大缩放等级
+
+ [ObservableProperty]
+ private double _minZoomLevel = 1.7; // 最小缩放等级
+
+ [ObservableProperty]
+ private double _reviveStatueOfTheSevenPointX = 2296.4; // 七天神像点位X坐标
+
+ [ObservableProperty]
+ private double _reviveStatueOfTheSevenPointY = -824.4; // 七天神像点位Y坐标
+
+ [ObservableProperty]
+ private int _zoomOutButtonY = 654; // y-coordinate for zoom-out button
+
+ [ObservableProperty]
+ private int _zoomInButtonY = 428; // y-coordinate for zoom-in button
+
+ [ObservableProperty]
+ private int _zoomButtonX = 49; // x-coordinate for zoom button
+
+ [ObservableProperty]
+ private int _zoomStartY = 453; // y-coordinate for zoom start
+
+ [ObservableProperty]
+ private int _zoomEndY = 628; // y-coordinate for zoom end
+
+ [ObservableProperty]
+ private double _tolerance = 200; // 允许的移动误差
+
+ [ObservableProperty]
+ private int _maxIterations = 30; // 移动最大次数
+
+ [ObservableProperty]
+ private int _maxMouseMove = 300; // 单次移动最大距离
+}
\ No newline at end of file
diff --git a/BetterGenshinImpact/GameTask/AutoTrackPath/TpTask.cs b/BetterGenshinImpact/GameTask/AutoTrackPath/TpTask.cs
index 824ec549..bce6d9e9 100644
--- a/BetterGenshinImpact/GameTask/AutoTrackPath/TpTask.cs
+++ b/BetterGenshinImpact/GameTask/AutoTrackPath/TpTask.cs
@@ -1,28 +1,26 @@
-using BetterGenshinImpact.Core.Recognition;
+using System;
+using System.Diagnostics;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using BetterGenshinImpact.Core.Recognition;
using BetterGenshinImpact.Core.Recognition.OpenCv;
+using BetterGenshinImpact.Core.Script.Dependence;
using BetterGenshinImpact.Core.Simulator;
+using BetterGenshinImpact.Core.Simulator.Extensions;
using BetterGenshinImpact.GameTask.AutoGeniusInvokation.Exception;
using BetterGenshinImpact.GameTask.Common;
using BetterGenshinImpact.GameTask.Common.BgiVision;
using BetterGenshinImpact.GameTask.Common.Element.Assets;
+using BetterGenshinImpact.GameTask.Common.Exceptions;
using BetterGenshinImpact.GameTask.Common.Map;
using BetterGenshinImpact.GameTask.Model.Area;
using BetterGenshinImpact.GameTask.QuickTeleport.Assets;
using BetterGenshinImpact.Helpers.Extensions;
using Microsoft.Extensions.Logging;
using OpenCvSharp;
-using System;
-using System.Diagnostics;
-using System.Linq;
-using System.Threading;
-using System.Threading.Tasks;
-using BetterGenshinImpact.GameTask.Common.Exceptions;
using Vanara.PInvoke;
using static BetterGenshinImpact.GameTask.Common.TaskControl;
-using BetterGenshinImpact.Core.Simulator.Extensions;
-using BetterGenshinImpact.GameTask.Common.Job;
-using BetterGenshinImpact.Core.Script.Dependence;
-using Microsoft.Diagnostics.Utilities;
namespace BetterGenshinImpact.GameTask.AutoTrackPath;
@@ -34,89 +32,17 @@ public class TpTask(CancellationToken ct)
private readonly QuickTeleportAssets _assets = QuickTeleportAssets.Instance;
private readonly Rect _captureRect = TaskContext.Instance().SystemInfo.ScaleMax1080PCaptureRect;
private readonly double _zoomOutMax1080PRatio = TaskContext.Instance().SystemInfo.ZoomOutMax1080PRatio;
-
- private static double ReviveStatueOfTheSevenPointX = 2296.4;
- private static double ReviveStatueOfTheSevenPointY = -824.4;
-
- private static int zoomOutButtonY = 654; // y-coordinate for zoom-out button
- private static int zoomInButtonY = 428; // y-coordinate for zoom-in button
- private static int zoomButtonX = 49; // x-coordinate for zoom button
- private static int zoomStartY = 453; // y-coordinate for zoom start
- private static int zoomEndY = 628; // y-coordinate for zoom end
- private static bool _mapZoomEnabled = true;
- private static int _mapZoomOutDistance = 1000;
- private static int _mapZoomInDistance = 400;
-
- private static int _stepIntervalMilliseconds = 20;
-
- public static bool MapZoomEnabled
- {
- get => _mapZoomEnabled;
- set
- {
- _mapZoomEnabled = value;
- if(!value)
- {
- Logger.LogInformation("禁用了缩放功能,请自行调整合适的缩放,部分脚本可能会因为禁用缩放功能无法使用");
- }
- }
- }
-
- public static int MapZoomOutDistance
- {
- get => _mapZoomOutDistance;
- set
- {
- if (value < 500 || value > 5000) // 自动设置合理范围
- {
- _mapZoomOutDistance = 1000;
- }
- if (value <= _mapZoomInDistance)
- {
- _mapZoomOutDistance = _mapZoomInDistance * 2;
- }
- _mapZoomOutDistance = value;
- }
- }
-
- public static int MapZoomInDistance
- {
- get => _mapZoomInDistance;
- set
- {
- if (value < 200 || value > 1000) // 自动设置合理范围
- {
- _mapZoomInDistance = 400;
- }
- if (value >= _mapZoomOutDistance)
- {
- _mapZoomInDistance = _mapZoomOutDistance / 2;
- }
- _mapZoomInDistance = value;
- }
- }
-
- public static int StepIntervalMilliseconds
- {
- get => _stepIntervalMilliseconds;
- set
- {
- if (value < 5 || value > 100)
- {
- _stepIntervalMilliseconds = 20;
- }
- _stepIntervalMilliseconds = value;
- }
- }
-
+ private readonly TpConfig _tpConfig = TaskContext.Instance().Config.TpConfig;
+
+ ///
+ /// 传送到须弥七天神像
+ ///
public async Task TpToStatueOfTheSeven()
{
await CheckInBigMapUi();
- if (_mapZoomEnabled)
+ if (_tpConfig.MapZoomEnabled)
{
double currentZoomLevel = GetBigMapZoomLevel(CaptureToRectArea());
- bool tempMapZoomEnable = _mapZoomEnabled;
- _mapZoomEnabled = false; // 临时禁用缩放功能
if (currentZoomLevel > 4.5)
{
await AdjustMapZoomLevel(currentZoomLevel, 4.5);
@@ -125,13 +51,8 @@ public class TpTask(CancellationToken ct)
{
await AdjustMapZoomLevel(currentZoomLevel, 3);
}
- await Tp(ReviveStatueOfTheSevenPointX, ReviveStatueOfTheSevenPointY);
- _mapZoomEnabled = tempMapZoomEnable;
- }
- else
- {
- await Tp(ReviveStatueOfTheSevenPointX, ReviveStatueOfTheSevenPointY);
}
+ await Tp(_tpConfig.ReviveStatueOfTheSevenPointX, _tpConfig.ReviveStatueOfTheSevenPointY);
}
///
/// 通过大地图传送到指定坐标最近的传送点,然后移动到指定坐标
@@ -139,9 +60,10 @@ public class TpTask(CancellationToken ct)
///
///
/// 强制以当前的tpX,tpY坐标进行自动传送
- public async Task<(double, double)> TpOnce(double tpX, double tpY, bool force = false)
+ private async Task<(double, double)> TpOnce(double tpX, double tpY, bool force = false)
{
var (x, y) = (tpX, tpY);
+
string? country = null;
if (!force)
{
@@ -152,25 +74,23 @@ public class TpTask(CancellationToken ct)
// 计算传送点位置离哪个地图切换后的中心点最近,切换到该地图
await SwitchRecentlyCountryMap(x, y, country);
-
- // 计算坐标后点击
- var bigMapInAllMapRect = GetBigMapRect();
- if (_mapZoomEnabled)
+
+ if (_tpConfig.MapZoomEnabled)
{
double zoomLevel = GetBigMapZoomLevel(CaptureToRectArea());
if (zoomLevel > 4.5)
{
// 显示传送锚点和秘境的缩放等级
await AdjustMapZoomLevel(zoomLevel, 4.5);
- Logger.LogInformation("当前缩放等级过大,调整为 {zoomLevel:0.000}", 4.5);
+ Logger.LogInformation("当前缩放等级过大,调整为 {zoomLevel:0.00}", 4.5);
}
}
-
+ var bigMapInAllMapRect = GetBigMapRect();
while (!IsPointInBigMapWindow(bigMapInAllMapRect, x, y)) // 左上角 350x400也属于禁止点击区域
{
Debug.WriteLine($"({x},{y}) 不在 {bigMapInAllMapRect} 内,继续移动");
Logger.LogInformation("传送点不在当前大地图范围内,继续移动");
- await MoveMapTo(x, y, maxMouseMove: 400);
+ await MoveMapTo(x, y);
await Delay(300, ct); // 等待地图移动完成
bigMapInAllMapRect = GetBigMapRect();
}
@@ -318,10 +238,8 @@ public class TpTask(CancellationToken ct)
///
/// 目标x坐标
/// 目标y坐标
- /// 允许误差,默认200
- /// 最大尝试次数,默认30
- /// 单次移动最大距离,默认250
- public async Task MoveMapTo(double x, double y, double tolerance = 200, int maxIterations = 30, int maxMouseMove = 250)
+
+ private async Task MoveMapTo(double x, double y)
{
// 获取当前地图中心点并计算到目标传送点的初始偏移
// await AdjustMapZoomLevel(mapZoomLevel);
@@ -333,7 +251,7 @@ public class TpTask(CancellationToken ct)
int moveSteps = 10;
double totalMoveMouseX = Double.MaxValue;
double totalMoveMouseY = Double.MaxValue;
- for (int iteration = 0; iteration < maxIterations; iteration++)
+ for (int iteration = 0; iteration < _tpConfig.MaxIterations; iteration++)
{
// 尝试移动鼠标
await MouseMoveMap(moveMouseX, moveMouseY, moveSteps);
@@ -363,20 +281,22 @@ public class TpTask(CancellationToken ct)
totalMoveMouseY = Math.Abs(moveMouseY * yOffset / diffMapY);
double mouseDistance = Math.Sqrt(totalMoveMouseX * totalMoveMouseX + totalMoveMouseY * totalMoveMouseY);
- if (_mapZoomEnabled)
+ if (_tpConfig.MapZoomEnabled)
{
// 调整地图缩放
// mapZoomLevel<5 才显示传送锚点和秘境; mapZoomLevel>1.7 可以避免点错传送锚点
double currentZoomLevel = GetBigMapZoomLevel(CaptureToRectArea());
double oldZoomLevel = currentZoomLevel;
- while (mouseDistance > MapZoomOutDistance || mouseDistance < MapZoomInDistance)
+ while (mouseDistance > _tpConfig.MapZoomOutDistance || mouseDistance < _tpConfig.MapZoomInDistance)
{
- bool zoomOut = mouseDistance > MapZoomOutDistance;
- bool zoomIn = mouseDistance < MapZoomInDistance;
- if (zoomOut && currentZoomLevel < 4.0 || zoomIn && currentZoomLevel > 2.7)
+ bool zoomOut = mouseDistance > _tpConfig.MapZoomOutDistance;
+ bool zoomIn = mouseDistance < _tpConfig.MapZoomInDistance;
+ if (zoomOut && currentZoomLevel < _tpConfig.MaxZoomLevel - 1.0
+ || zoomIn && currentZoomLevel > _tpConfig.MinZoomLevel + 1.0)
{
await AdjustMapZoomLevel(zoomIn);
+ await Delay(50, ct);
currentZoomLevel = GetBigMapZoomLevel(CaptureToRectArea());
totalMoveMouseX *= oldZoomLevel / currentZoomLevel;
totalMoveMouseY *= oldZoomLevel / currentZoomLevel;
@@ -385,9 +305,9 @@ public class TpTask(CancellationToken ct)
}
else
{
- double targetZoom = zoomIn ? 1.7 : 5.0;
+ double targetZoom = zoomIn ? _tpConfig.MinZoomLevel : _tpConfig.MaxZoomLevel;
// 考虑调整和识别误差,所以相差0.05就不再调整。
- if (currentZoomLevel > 4.95 || currentZoomLevel < 1.75)
+ if (currentZoomLevel > _tpConfig.MaxZoomLevel - 0.05 || currentZoomLevel < _tpConfig.MinZoomLevel + 0.05)
{
break;
}
@@ -398,21 +318,20 @@ public class TpTask(CancellationToken ct)
}
// 非常接近目标点,不再进一步调整
- if (mouseDistance < tolerance)
+ if (mouseDistance < _tpConfig.Tolerance)
{
Logger.LogInformation("移动 {I} 次鼠标后,已经接近目标点,不再移动地图。", iteration + 1);
break;
}
-
- // 单次移动最大距离为 maxMouseMove
- moveMouseX = (int)Math.Min(totalMoveMouseX, maxMouseMove * totalMoveMouseX / mouseDistance) * Math.Sign(xOffset);
- moveMouseY = (int)Math.Min(totalMoveMouseY, maxMouseMove * totalMoveMouseY / mouseDistance) * Math.Sign(yOffset);
+
+ moveMouseX = (int)Math.Min(totalMoveMouseX, _tpConfig.MaxMouseMove * totalMoveMouseX / mouseDistance) * Math.Sign(xOffset);
+ moveMouseY = (int)Math.Min(totalMoveMouseY, _tpConfig.MaxMouseMove * totalMoveMouseY / mouseDistance) * Math.Sign(yOffset);
double moveMouseLength = Math.Sqrt(moveMouseX * moveMouseX + moveMouseY * moveMouseY);
moveSteps = Math.Max((int)moveMouseLength / 10, 3); // 每次移动的步数最小为3,避免除0错误
}
else
{
- Logger.LogDebug($"第 {iteration} 次移动鼠标失败,可能是点击了传送点或者其他交互对象。");
+ Logger.LogDebug($"第 {iteration + 1} 次移动鼠标失败,可能是点击了传送点或者其他交互对象。");
}
}
}
@@ -440,25 +359,26 @@ public class TpTask(CancellationToken ct)
/// 调整地图缩放级别以加速移动
///
/// 是否放大地图
- public async Task AdjustMapZoomLevel(bool zoomIn)
+ private async Task AdjustMapZoomLevel(bool zoomIn)
{
if (zoomIn)
{
- GameCaptureRegion.GameRegionClick((rect, scale) => (zoomButtonX * scale, zoomInButtonY * scale));
+ GameCaptureRegion.GameRegionClick((rect, scale) => (_tpConfig.ZoomButtonX * scale, _tpConfig.ZoomInButtonY * scale));
}
else
{
- GameCaptureRegion.GameRegionClick((rect, scale) => (zoomButtonX * scale, zoomOutButtonY * scale));
+ GameCaptureRegion.GameRegionClick((rect, scale) => (_tpConfig.ZoomButtonX * scale, _tpConfig.ZoomOutButtonY * scale));
}
await Delay(50, ct);
}
- [Obsolete]
+
///
/// 调整地图的缩放等级(整数缩放级别)。
///
/// 目标等级:1-6。整数。随着数字变大地图越小,细节越少。
+ [Obsolete]
public async Task AdjustMapZoomLevel(int zoomLevel)
{
for (int i = 0; i < 5; i++)
@@ -478,15 +398,15 @@ public class TpTask(CancellationToken ct)
///
/// 当前缩放等级:1.0-6.0,浮点数。
/// 目标缩放等级:1.0-6.0,浮点数。
- public async Task AdjustMapZoomLevel(double zoomLevel, double targetZoomLevel)
+ private async Task AdjustMapZoomLevel(double zoomLevel, double targetZoomLevel)
{
// Logger.LogInformation("调整地图缩放等级:{zoomLevel:0.000} -> {targetZoomLevel:0.000}", zoomLevel, targetZoomLevel);
- int initialY = (int)(zoomStartY + (zoomEndY - zoomStartY) * (zoomLevel - 1) / 5d);
- int targetY = (int)(zoomStartY + (zoomEndY - zoomStartY) * (targetZoomLevel - 1) / 5d);
- await MouseClickAndMove(zoomButtonX, initialY, zoomButtonX, targetY);
+ int initialY = (int)(_tpConfig.ZoomStartY + (_tpConfig.ZoomEndY - _tpConfig.ZoomStartY) * (zoomLevel - 1) / 5d);
+ int targetY = (int)(_tpConfig.ZoomStartY + (_tpConfig.ZoomEndY - _tpConfig.ZoomStartY) * (targetZoomLevel - 1) / 5d);
+ await MouseClickAndMove(_tpConfig.ZoomButtonX, initialY, _tpConfig.ZoomButtonX, targetY);
}
- public async Task MouseMoveMap(int pixelDeltaX, int pixelDeltaY, int steps = 10)
+ private async Task MouseMoveMap(int pixelDeltaX, int pixelDeltaY, int steps = 10)
{
// 确保不影响总移动距离
int totalX = 0;
@@ -506,8 +426,8 @@ public class TpTask(CancellationToken ct)
}
// 均匀分配多余的部分到前半段
- int remainingX = (int)(pixelDeltaX - totalX);
- int remainingY = (int)(pixelDeltaY - totalY);
+ int remainingX = (pixelDeltaX - totalX);
+ int remainingY = (pixelDeltaY - totalY);
for (int i = 0; i < steps / 2 + 1; i++)
{
stepX[i] += remainingX / (steps / 2 + 1) + ((remainingX % (steps / 2 + 1) > i) ? 0 : 1);
@@ -523,7 +443,7 @@ public class TpTask(CancellationToken ct)
for (var i = 0; i < steps; i++)
{
GlobalMethod.MoveMouseBy(stepX[i], stepY[i]);
- await Delay(StepIntervalMilliseconds, ct);
+ await Delay(_tpConfig.StepIntervalMilliseconds, ct);
}
GlobalMethod.LeftButtonUp();
}
@@ -604,7 +524,7 @@ public class TpTask(CancellationToken ct)
}
///
- /// 获取最近的传送点位置
+ /// 获取最近的传送点位置和所处区域
///
///
///
@@ -820,4 +740,4 @@ public class TpTask(CancellationToken ct)
// 1~6 的缩放等级
return (-5 * s) + 6;
}
-}
\ No newline at end of file
+}
diff --git a/BetterGenshinImpact/GameTask/AutoWood/AutoWoodTask.cs b/BetterGenshinImpact/GameTask/AutoWood/AutoWoodTask.cs
index 7b3146a2..2834f97a 100644
--- a/BetterGenshinImpact/GameTask/AutoWood/AutoWoodTask.cs
+++ b/BetterGenshinImpact/GameTask/AutoWood/AutoWoodTask.cs
@@ -16,6 +16,7 @@ using System.Linq;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
+using BetterGenshinImpact.Core.Simulator.Extensions;
using Vanara.PInvoke;
using static BetterGenshinImpact.GameTask.Common.TaskControl;
using static Vanara.PInvoke.User32;
@@ -30,7 +31,7 @@ public partial class AutoWoodTask : ISoloTask
{
public string Name => "自动伐木";
- private readonly AutoWoodAssets _assets;
+ private AutoWoodAssets _assets;
private bool _first = true;
@@ -38,7 +39,7 @@ public partial class AutoWoodTask : ISoloTask
private readonly Login3rdParty _login3rdParty;
- private VK _zKey = VK.VK_Z;
+ // private VK _zKey = VK.VK_Z;
private readonly WoodTaskParam _taskParam;
@@ -49,12 +50,13 @@ public partial class AutoWoodTask : ISoloTask
this._taskParam = taskParam;
_login3rdParty = new();
AutoWoodAssets.DestroyInstance();
- _assets = AutoWoodAssets.Instance;
+
_printer = new WoodStatisticsPrinter(_assets);
}
public Task Start(CancellationToken ct)
{
+ _assets = AutoWoodAssets.Instance;
var runTimeWatch = new Stopwatch();
_ct = ct;
_printer.Ct = _ct;
@@ -70,20 +72,20 @@ public partial class AutoWoodTask : ISoloTask
Logger.LogInformation("自动伐木启用B服模式");
}
- SettingsContainer settingsContainer = new();
-
- if (settingsContainer.OverrideController?.KeyboardMap?.ActionElementMap.Where(item => item.ActionId == ActionId.Gadget).FirstOrDefault()?.ElementIdentifierId is ElementIdentifierId key)
- {
- if (key != ElementIdentifierId.Z)
- {
- _zKey = key.ToVK();
- Logger.LogInformation($"自动伐木检测到用户改键 {ElementIdentifierId.Z.ToName()} 改为 {key.ToName()}");
- if (key == ElementIdentifierId.LeftShift || key == ElementIdentifierId.RightShift)
- {
- Logger.LogInformation($"用户改键 {key.ToName()} 可能不受模拟支持,若使用正常则忽略");
- }
- }
- }
+ // SettingsContainer settingsContainer = new();
+ //
+ // if (settingsContainer.OverrideController?.KeyboardMap?.ActionElementMap.Where(item => item.ActionId == ActionId.Gadget).FirstOrDefault()?.ElementIdentifierId is ElementIdentifierId key)
+ // {
+ // if (key != ElementIdentifierId.Z)
+ // {
+ // _zKey = key.ToVK();
+ // Logger.LogInformation($"自动伐木检测到用户改键 {ElementIdentifierId.Z.ToName()} 改为 {key.ToName()}");
+ // if (key == ElementIdentifierId.LeftShift || key == ElementIdentifierId.RightShift)
+ // {
+ // Logger.LogInformation($"用户改键 {key.ToName()} 可能不受模拟支持,若使用正常则忽略");
+ // }
+ // }
+ // }
SystemControl.ActivateWindow();
// 伐木开始计时
@@ -168,6 +170,7 @@ public partial class AutoWoodTask : ISoloTask
TaskContext.Instance().Config.AutoWoodConfig.WoodCountOcrEnabled = false;
throw new NormalEndException("首次伐木就未识别到木材数据,已经自动关闭【OCR识别并累计木材数】的功能,请重新启动【自动伐木】功能!");
}
+
return;
}
@@ -210,6 +213,7 @@ public partial class AutoWoodTask : ISoloTask
return _firstWoodOcrText;
}
}
+
stopwatch.Stop(); // 停止计时
_firstWoodOcrText = FindBestOcrResult(firstOcrResultList);
return _firstWoodOcrText;
@@ -234,6 +238,7 @@ public partial class AutoWoodTask : ISoloTask
return !string.IsNullOrEmpty(recognizedText) &&
recognizedText.Contains("获得");
}
+
return !string.IsNullOrEmpty(recognizedText) &&
recognizedText.Contains("获得") &&
(recognizedText.Contains('×') || recognizedText.Contains('x'));
@@ -291,6 +296,7 @@ public partial class AutoWoodTask : ISoloTask
Logger.LogWarning("未知的木材名:{woodName},数量{Cnt}", materialName, quantity);
return;
}
+
WoodTotalDict.AddOrUpdate(
key: materialName,
addValue: quantity,
@@ -334,6 +340,7 @@ public partial class AutoWoodTask : ISoloTask
isFound = false;
continue;
}
+
var materialName = match.Groups[1].Value.Trim();
Debug.WriteLine($"第一次获取的木材名称:{materialName}");
if (!ExistWoods.Contains(materialName))
@@ -417,14 +424,14 @@ public partial class AutoWoodTask : ISoloTask
throw new NormalEndException("请先装备小道具「王树瑞佑」!");
#else
System.Threading.Thread.Sleep(2000);
- Simulation.SendInput.Keyboard.KeyPress(_zKey);
+ Simulation.SendInput.SimulateAction(GIActions.QuickUseGadget);
Debug.WriteLine("[AutoWood] Z");
_first = false;
#endif
}
else
{
- Simulation.SendInput.Keyboard.KeyPress(_zKey);
+ Simulation.SendInput.SimulateAction(GIActions.QuickUseGadget);
Debug.WriteLine("[AutoWood] Z");
_first = false;
}
@@ -445,7 +452,7 @@ public partial class AutoWoodTask : ISoloTask
#endif
}
- Simulation.SendInput.Keyboard.KeyPress(_zKey);
+ Simulation.SendInput.SimulateAction(GIActions.QuickUseGadget);
Debug.WriteLine("[AutoWood] Z");
Sleep(500, _ct);
}, TimeSpan.FromSeconds(1), 120);
@@ -542,4 +549,4 @@ public partial class AutoWoodTask : ISoloTask
throw new RetryException("未检测进入游戏界面");
}
}
-}
+}
\ No newline at end of file
diff --git a/BetterGenshinImpact/GameTask/Common/Job/GoToAdventurersGuildTask.cs b/BetterGenshinImpact/GameTask/Common/Job/GoToAdventurersGuildTask.cs
index f7bb5ae9..e8e5ecd4 100644
--- a/BetterGenshinImpact/GameTask/Common/Job/GoToAdventurersGuildTask.cs
+++ b/BetterGenshinImpact/GameTask/Common/Job/GoToAdventurersGuildTask.cs
@@ -31,14 +31,14 @@ public class GoToAdventurersGuildTask
{
try
{
- // 合成完毕后领取奖励
- await new ClaimEncounterPointsRewardsTask().Start(ct);
-
// 如果有好感队伍名称,先切换到好感队伍
if (!string.IsNullOrEmpty(dailyRewardPartyName))
{
await new SwitchPartyTask().Start(dailyRewardPartyName, ct);
}
+
+ // F1领取奖励
+ await new ClaimEncounterPointsRewardsTask().Start(ct);
await DoOnce(country, ct);
break;
diff --git a/BetterGenshinImpact/GameTask/Common/Job/ScanPickTask.cs b/BetterGenshinImpact/GameTask/Common/Job/ScanPickTask.cs
index 1810c0e4..f0f6758a 100644
--- a/BetterGenshinImpact/GameTask/Common/Job/ScanPickTask.cs
+++ b/BetterGenshinImpact/GameTask/Common/Job/ScanPickTask.cs
@@ -44,13 +44,15 @@ public class ScanPickTask
public async Task DoOnce(CancellationToken ct)
{
- await ResetCamera(ct);
-
- for (int n = 0; n < 5; n++) // 最多跑5次
+ var forwardTimes = TaskContext.Instance().Config.AutoFightConfig.PickDropsConfig.ForwardTimes;
+ for (int n = 0; n < forwardTimes; n++) // 直走次数
{
+ await ResetCamera(ct);
var hasDrops = false;
// 旋转视角
+ var step = 300 * _dpi; // TODO:把300换成一个更加普适的值
+ step = n % 2 == 0 ? step : -step;
for (var i = 0; i < 20; i++)
{
var ra = CaptureToRectArea();
@@ -63,18 +65,14 @@ public class ScanPickTask
if (pickItems.Count > 0)
{
hasDrops = true;
- // 把鼠标位置和物品位置重合
- MoveCursorTo(pickItems.First(), ra);
- await Delay(100, ct);
- // 物体越小,距离越远
- await WalkForward(ct);
+ await MoveTowardsFirstDrop(ct, 300 * _dpi);
break;
}
- Simulation.SendInput.Mouse.MoveMouseBy((int)(300 * _dpi), 0);
+ Simulation.SendInput.Mouse.MoveMouseBy((int)step, 0);
await Delay(100, ct);
}
-
+
if (!hasDrops)
{
break;
@@ -83,13 +81,56 @@ public class ScanPickTask
}
- private static async Task WalkForward(CancellationToken ct)
+ private static async Task WalkForward(CancellationToken ct, int ms = 1000)
{
Simulation.SendInput.SimulateAction(GIActions.MoveForward, KeyType.KeyDown);
- await Delay(1000, ct);
+ await Delay(ms, ct);
Simulation.SendInput.SimulateAction(GIActions.MoveForward, KeyType.KeyUp);
}
+ private async Task MoveTowardsFirstDrop(CancellationToken ct, double step)
+ {
+ //通过每次缩小之前的步长来定位,可能有一定开销
+ var decayFactor = TaskContext.Instance().Config.AutoFightConfig.PickDropsConfig.DecayFactor;
+ var calibrationTimes = TaskContext.Instance().Config.AutoFightConfig.PickDropsConfig.CalibrationTimes;
+
+ var found = false;
+ for (var i = 0; i < calibrationTimes; i++)
+ {
+ var ra = CaptureToRectArea();
+ var resultDic = _predictor.Detect(ra);
+ var pickItems = resultDic.Where(x => x.Key is "drops" or "ore")
+ .SelectMany(x => x.Value).ToList();
+ if (pickItems.Count > 0)
+ {
+ step *= decayFactor;
+ found = true;
+ //只关心横坐标
+ var centerX = (pickItems.First().Left + pickItems.First().Right) / 2;
+ var dx = centerX - ra.Width / 2;
+ if (dx > 0)
+ Simulation.SendInput.Mouse.MoveMouseBy((int)step, 0);
+ else if (dx < 0)
+ Simulation.SendInput.Mouse.MoveMouseBy(-(int)step, 0);
+ await Delay(100, ct);
+ }
+ else
+ {
+ //也许已经对准,被人物挡住
+ break;
+ }
+ }
+ if (found) //仅在找到物品时前进(在误判进入该函数时避免远离原地)
+ {
+ Logger.LogInformation("前进采集");
+ var forwardms = TaskContext.Instance().Config.AutoFightConfig.PickDropsConfig.ForwardSeconds * 1000;
+ if (forwardms == 0)
+ forwardms = new Random().Next(1000, 3000);
+
+ await WalkForward(ct, forwardms);
+ }
+ }
+
private void MoveCursorTo(Rect item, ImageRegion ra)
{
var centerX = (item.Left + item.Right) / 2;
@@ -103,8 +144,8 @@ public class ScanPickTask
// 回正 并下移视角
private async Task ResetCamera(CancellationToken ct)
{
- // Simulation.SendInput.Keyboard.Mouse.MiddleButtonClick();
- // await Delay(500, ct);
+ Simulation.SendInput.Keyboard.Mouse.MiddleButtonClick();
+ await Delay(500, ct);
Simulation.SendInput.Keyboard.Mouse.MoveMouseBy(0, (int)(500 * _dpi));
await Delay(100, ct);
}
diff --git a/BetterGenshinImpact/GameTask/LogParse/LogParse.cs b/BetterGenshinImpact/GameTask/LogParse/LogParse.cs
index 8feb53e5..83ef540e 100644
--- a/BetterGenshinImpact/GameTask/LogParse/LogParse.cs
+++ b/BetterGenshinImpact/GameTask/LogParse/LogParse.cs
@@ -325,7 +325,8 @@ namespace LogParse
(name: "最后小怪日期", value: ms => ms.LastSmallTime),
(name: "精英", value: ms => ms.EliteGameStatistics.ToString()),
(name: "精英详细", value: ms => ms.EliteDetails), (name: "最后精英日期", value: ms => ms.LastEliteTime),
- (name: "总计锄地摩拉", value: ms => ms.TotalMoraKillingMonstersMora.ToString())
+ (name: "总计锄地摩拉", value: ms => ms.TotalMoraKillingMonstersMora.ToString()),
+ (name: "突发事件获取摩拉", value: ms => ms.EmergencyBonus)
];
//锄地部分新曾字段
(string name, Func value)[] col2Configs=[..msColConfigs.ToList().Where(item=>item.name!="日期" && item.name!="最后小怪日期" && item.name!="最后精英日期"),
@@ -386,7 +387,7 @@ namespace LogParse
.OrderBy(group => group.Key)
.Reverse().ToList();
- html.AppendLine($"按日锄地摩拉统计
");
+ html.AppendLine($"按日摩拉收益统计
");
html.AppendLine("");
html.AppendLine(" ");
diff --git a/BetterGenshinImpact/GameTask/LogParse/MoraStatistics.cs b/BetterGenshinImpact/GameTask/LogParse/MoraStatistics.cs
index 50ca2b3e..ae62e5ea 100644
--- a/BetterGenshinImpact/GameTask/LogParse/MoraStatistics.cs
+++ b/BetterGenshinImpact/GameTask/LogParse/MoraStatistics.cs
@@ -25,6 +25,16 @@ namespace LogParse
public List SmallMonsterActionItems =>
this.MonsterActionItems.Except(EliteMonsterActionItems).ToList();
+ public string EmergencyBonus
+ {
+ get
+ {
+ var ls = this.ActionItems.Where(item => item.ActionId == 28).ToList();
+ var count = ls.Count();
+ return ls.Sum(item=>item.Num)+((count==0 || count>=10)?"":$"({count}/10)");
+ }
+ }
+
public string LastEliteTime => EliteMonsterActionItems.MaxBy(item => item?.Time)?.Time ?? null;
public string LastSmallTime => SmallMonsterActionItems.MaxBy(item => item?.Time)?.Time ?? null;
diff --git a/BetterGenshinImpact/GameTask/LogParse/TravelsDiaryDetailManager.cs b/BetterGenshinImpact/GameTask/LogParse/TravelsDiaryDetailManager.cs
index a8db8801..721192f5 100644
--- a/BetterGenshinImpact/GameTask/LogParse/TravelsDiaryDetailManager.cs
+++ b/BetterGenshinImpact/GameTask/LogParse/TravelsDiaryDetailManager.cs
@@ -50,8 +50,8 @@ public class TravelsDiaryDetailManager
var _temp = JsonSerializer.Deserialize>(File.ReadAllText(tddfile));
if (_temp != null)
{
- //只统计杀怪的
- actionItems.AddRange(_temp.Data.List.Where(item => item.ActionId == 37));
+ //统计杀怪或突发事件奖励
+ actionItems.AddRange(_temp.Data.List.Where(item => item.ActionId == 37 || item.ActionId == 28));
}
}
}
diff --git a/BetterGenshinImpact/GameTask/QuickTeleport/Assets/1920x1080/ObsidianTotemPole.png b/BetterGenshinImpact/GameTask/QuickTeleport/Assets/1920x1080/ObsidianTotemPole.png
new file mode 100644
index 00000000..9cf0f052
Binary files /dev/null and b/BetterGenshinImpact/GameTask/QuickTeleport/Assets/1920x1080/ObsidianTotemPole.png differ
diff --git a/BetterGenshinImpact/GameTask/QuickTeleport/Assets/QuickTeleportAssets.cs b/BetterGenshinImpact/GameTask/QuickTeleport/Assets/QuickTeleportAssets.cs
index 0fa74470..07028321 100644
--- a/BetterGenshinImpact/GameTask/QuickTeleport/Assets/QuickTeleportAssets.cs
+++ b/BetterGenshinImpact/GameTask/QuickTeleport/Assets/QuickTeleportAssets.cs
@@ -34,6 +34,7 @@ public class QuickTeleportAssets : BaseAssets
BuildMapChooseIconRo("StatueOfTheSeven.png"),
BuildMapChooseIconRo("Domain.png"),
BuildMapChooseIconRo("Domain2.png"),
+ BuildMapChooseIconRo("ObsidianTotemPole.png"),
BuildMapChooseIconRo("PortableWaypoint.png"),
BuildMapChooseIconRo("Mansion.png"),
BuildMapChooseIconRo("SubSpaceWaypoint.png"),
@@ -140,7 +141,6 @@ public class QuickTeleportAssets : BaseAssets
///
public RecognitionObject BuildMapChooseIconRo(string name)
{
- var info = TaskContext.Instance().SystemInfo;
var ro = new RecognitionObject
{
Name = name + "MapChooseIcon",
diff --git a/BetterGenshinImpact/GameTask/TaskContext.cs b/BetterGenshinImpact/GameTask/TaskContext.cs
index 1f4ea76e..fd3023e6 100644
--- a/BetterGenshinImpact/GameTask/TaskContext.cs
+++ b/BetterGenshinImpact/GameTask/TaskContext.cs
@@ -65,7 +65,7 @@ namespace BetterGenshinImpact.GameTask
}
}
- public SettingsContainer? GameSettings { get; set; }
+ // public SettingsContainer? GameSettings { get; set; }
///
/// 关联启动原神的时间
diff --git a/BetterGenshinImpact/GameTask/TaskRunner.cs b/BetterGenshinImpact/GameTask/TaskRunner.cs
index f5aacc6d..f0902164 100644
--- a/BetterGenshinImpact/GameTask/TaskRunner.cs
+++ b/BetterGenshinImpact/GameTask/TaskRunner.cs
@@ -10,7 +10,7 @@ using System.Threading.Tasks;
using BetterGenshinImpact.Helpers;
using Wpf.Ui.Violeta.Controls;
using static BetterGenshinImpact.GameTask.Common.TaskControl;
-using BetterGenshinImpact.Core.Recorder;
+using BetterGenshinImpact.Service;
namespace BetterGenshinImpact.GameTask;
@@ -119,6 +119,8 @@ public class TaskRunner
public async Task RunSoloTaskAsync(ISoloTask soloTask)
{
+ // 没启动的时候先启动
+ await ScriptService.StartGameTask();
await Task.Run(() => RunCurrentAsync(async () => await soloTask.Start(CancellationContext.Instance.Cts.Token)));
}
diff --git a/BetterGenshinImpact/Helpers/DirectoryHelper.cs b/BetterGenshinImpact/Helpers/DirectoryHelper.cs
index 2fa3aab9..00f9df40 100644
--- a/BetterGenshinImpact/Helpers/DirectoryHelper.cs
+++ b/BetterGenshinImpact/Helpers/DirectoryHelper.cs
@@ -33,6 +33,15 @@ public class DirectoryHelper
private static void DeleteDirectory(DirectoryInfo directoryInfo)
{
+
+ //通过软链接生成的目录,直接删除该链接目录,而不涉及其文件本体
+ var attributes = directoryInfo.Attributes;
+ if ((attributes & FileAttributes.ReparsePoint) == FileAttributes.ReparsePoint)
+ {
+ directoryInfo.Delete();
+ return;
+ }
+
// 递归处理子目录
foreach (var subDirectory in directoryInfo.GetDirectories())
{
@@ -80,4 +89,54 @@ public class DirectoryHelper
RemoveReadOnlyAttribute(subDirectory);
}
}
+
+ public static void CopyDirectory(string sourceDir, string destDir)
+ {
+ // 创建目标目录
+ Directory.CreateDirectory(destDir);
+
+ // 获取源目录中的所有文件
+ foreach (var file in Directory.GetFiles(sourceDir))
+ {
+ var destFile = Path.Combine(destDir, Path.GetFileName(file));
+ File.Copy(file, destFile, true); // 覆盖同名文件
+ }
+
+ // 获取源目录中的所有子目录
+ foreach (var subDir in Directory.GetDirectories(sourceDir))
+ {
+ var destSubDir = Path.Combine(destDir, Path.GetFileName(subDir));
+ CopyDirectory(subDir, destSubDir); // 递归拷贝子目录
+ }
+ }
+
+ ///
+ /// 递归删除指定目录及其所有子目录和文件
+ ///
+ /// 要删除的目录的路径
+ public static void DeleteDirectoryRecursively(string directoryPath)
+ {
+ // 检查目录是否存在
+ if (Directory.Exists(directoryPath))
+ {
+ // 获取目录中的所有子目录
+ string[] subDirectories = Directory.GetDirectories(directoryPath);
+ foreach (string subDirectory in subDirectories)
+ {
+ // 递归调用删除子目录
+ DeleteDirectoryRecursively(subDirectory);
+ }
+
+ // 获取目录中的所有文件
+ string[] files = Directory.GetFiles(directoryPath);
+ foreach (string file in files)
+ {
+ // 删除文件
+ File.Delete(file);
+ }
+
+ // 删除空目录
+ Directory.Delete(directoryPath);
+ }
+ }
}
diff --git a/BetterGenshinImpact/Helpers/Ui/WindowHelper.cs b/BetterGenshinImpact/Helpers/Ui/WindowHelper.cs
index f0820b3c..36cd3278 100644
--- a/BetterGenshinImpact/Helpers/Ui/WindowHelper.cs
+++ b/BetterGenshinImpact/Helpers/Ui/WindowHelper.cs
@@ -1,4 +1,5 @@
-using System.Windows.Media;
+using System.Diagnostics;
+using System.Windows.Media;
using BetterGenshinImpact.GameTask;
using Wpf.Ui.Controls;
@@ -8,14 +9,16 @@ public class WindowHelper
{
public static void TryApplySystemBackdrop(System.Windows.Window window)
{
- window.Background = new SolidColorBrush(Colors.Transparent);
-
if (WindowBackdrop.IsSupported(TaskContext.Instance().Config.CommonConfig.CurrentBackdropType))
{
if (TaskContext.Instance().Config.CommonConfig.CurrentBackdropType == WindowBackdropType.Acrylic)
{
window.Background = new SolidColorBrush(Color.FromArgb(100, 0, 0, 0));
}
+ else
+ {
+ window.Background = new SolidColorBrush(Colors.Transparent);
+ }
WindowBackdrop.ApplyBackdrop(window, TaskContext.Instance().Config.CommonConfig.CurrentBackdropType);
return;
@@ -24,14 +27,12 @@ public class WindowHelper
if (WindowBackdrop.IsSupported(WindowBackdropType.Mica))
{
+ window.Background = new SolidColorBrush(Colors.Transparent);
WindowBackdrop.ApplyBackdrop(window, WindowBackdropType.Mica);
}
- else if (WindowBackdrop.IsSupported(WindowBackdropType.Tabbed))
- {
- WindowBackdrop.ApplyBackdrop(window, WindowBackdropType.Tabbed);
- }
else if (WindowBackdrop.IsSupported(WindowBackdropType.Acrylic))
{
+ window.Background = new SolidColorBrush(Color.FromArgb(100, 0, 0, 0));
WindowBackdrop.ApplyBackdrop(window, WindowBackdropType.Acrylic);
}
}
diff --git a/BetterGenshinImpact/Service/UpdateService.cs b/BetterGenshinImpact/Service/UpdateService.cs
index 5f4d72f4..a483ccff 100644
--- a/BetterGenshinImpact/Service/UpdateService.cs
+++ b/BetterGenshinImpact/Service/UpdateService.cs
@@ -93,14 +93,14 @@ public class UpdateService : IUpdateService
case CheckUpdateWindow.CheckUpdateWindowButton.Update:
{
// 唤起更新程序
- string updaterExePath = Global.Absolute("updater.exe");
+ string updaterExePath = Global.Absolute("BetterGI.update.exe");
if (!File.Exists(updaterExePath))
{
await MessageBox.ErrorAsync("更新程序不存在,请选择其他更新方式!");
return;
}
// 启动
- Process.Start(updaterExePath);
+ Process.Start(updaterExePath, "-I");
// 退出程序
Application.Current.Shutdown();
diff --git a/BetterGenshinImpact/View/MaskWindow.xaml.cs b/BetterGenshinImpact/View/MaskWindow.xaml.cs
index f341722f..0c772f67 100644
--- a/BetterGenshinImpact/View/MaskWindow.xaml.cs
+++ b/BetterGenshinImpact/View/MaskWindow.xaml.cs
@@ -176,26 +176,26 @@ public partial class MaskWindow : Window
}
// 读取游戏注册表配置
- ReadGameSettings();
+ // ReadGameSettings();
}
- private void ReadGameSettings()
- {
- try
- {
- SettingsContainer settings = new();
- TaskContext.Instance().GameSettings = settings;
- var lang = settings.Language?.TextLang;
- if (lang != null && lang != TextLanguage.SimplifiedChinese)
- {
- _logger.LogWarning("当前游戏语言{Lang}不是简体中文,部分功能可能无法正常使用。The game language is not Simplified Chinese, some functions may not work properly", lang);
- }
- }
- catch (Exception e)
- {
- _logger.LogWarning("游戏注册表配置信息读取失败:" + e.Source + "\r\n--" + Environment.NewLine + e.StackTrace + "\r\n---" + Environment.NewLine + e.Message);
- }
- }
+ // private void ReadGameSettings()
+ // {
+ // try
+ // {
+ // SettingsContainer settings = new();
+ // TaskContext.Instance().GameSettings = settings;
+ // var lang = settings.Language?.TextLang;
+ // if (lang != null && lang != TextLanguage.SimplifiedChinese)
+ // {
+ // _logger.LogWarning("当前游戏语言{Lang}不是简体中文,部分功能可能无法正常使用。The game language is not Simplified Chinese, some functions may not work properly", lang);
+ // }
+ // }
+ // catch (Exception e)
+ // {
+ // _logger.LogWarning("游戏注册表配置信息读取失败:" + e.Source + "\r\n--" + Environment.NewLine + e.StackTrace + "\r\n---" + Environment.NewLine + e.Message);
+ // }
+ // }
protected override void OnSourceInitialized(EventArgs e)
{
diff --git a/BetterGenshinImpact/View/Pages/TaskSettingsPage.xaml b/BetterGenshinImpact/View/Pages/TaskSettingsPage.xaml
index 8f419032..24815d17 100644
--- a/BetterGenshinImpact/View/Pages/TaskSettingsPage.xaml
+++ b/BetterGenshinImpact/View/Pages/TaskSettingsPage.xaml
@@ -428,7 +428,34 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -624,33 +651,147 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
+
diff --git a/BetterGenshinImpact/View/Pages/TriggerSettingsPage.xaml b/BetterGenshinImpact/View/Pages/TriggerSettingsPage.xaml
index 73040063..66b65fc9 100644
--- a/BetterGenshinImpact/View/Pages/TriggerSettingsPage.xaml
+++ b/BetterGenshinImpact/View/Pages/TriggerSettingsPage.xaml
@@ -778,7 +778,166 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/BetterGenshinImpact/View/Pages/View/ScriptGroupConfigView.xaml b/BetterGenshinImpact/View/Pages/View/ScriptGroupConfigView.xaml
index 6975a47c..970e8715 100644
--- a/BetterGenshinImpact/View/Pages/View/ScriptGroupConfigView.xaml
+++ b/BetterGenshinImpact/View/Pages/View/ScriptGroupConfigView.xaml
@@ -370,6 +370,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
WindowBackdropType.Mica,
WindowBackdropType.Mica => WindowBackdropType.Acrylic,
- WindowBackdropType.Acrylic => WindowBackdropType.Tabbed,
- WindowBackdropType.Tabbed => WindowBackdropType.Auto,
- _ => WindowBackdropType.Auto
+ 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));;
+ mainWindow.Background = new SolidColorBrush(Color.FromArgb(100, 0, 0, 0));
WindowBackdrop.ApplyBackdrop(mainWindow, CurrentBackdropType);
}
}
@@ -92,8 +98,78 @@ public partial class MainWindowViewModel : ObservableObject, IViewModel
}
[RelayCommand]
- [SuppressMessage("CommunityToolkit.Mvvm.SourceGenerators.RelayCommandGenerator", "MVVMTK0039:Async void returning method annotated with RelayCommand")]
- private async void OnLoaded()
+ private async Task OnLoaded()
+ {
+ // 自动处理目录配置
+ await Patch1();
+
+ // 预热OCR
+ await OcrPreheating();
+
+ // 首次运行自动初始化绑定
+ InitKeyBinding();
+
+ // 检查更新
+ await App.GetService()!.CheckUpdateAsync(new UpdateOption());
+
+ // Win11下 BitBlt截图方式不可用,需要关闭窗口优化功能
+ if (OsVersionHelper.IsWindows11_OrGreater && TaskContext.Instance().Config.AutoFixWin11BitBlt)
+ {
+ BitBltRegistryHelper.SetDirectXUserGlobalSettings();
+ }
+
+ // 更新仓库
+ ScriptRepoUpdater.Instance.AutoUpdate();
+ }
+
+
+ private void InitKeyBinding()
+ {
+ if (Config.CommonConfig.IsFirstRun)
+ {
+ try
+ {
+ var kbVm = App.GetService();
+ 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()
+ {
+ if (Directory.Exists(Global.Absolute("BetterGI"))
+ // && File.Exists(Global.Absolute("BetterGI/BetterGI.exe"))
+ && Directory.Exists(Global.Absolute("BetterGI/User"))
+ )
+ {
+ var res = await MessageBox.ShowAsync("检测到旧的 BetterGI 配置,是否迁移配置并清理旧目录?", "BetterGI", System.Windows.MessageBoxButton.YesNo, MessageBoxImage.Question);
+ if (res == System.Windows.MessageBoxResult.Yes)
+ {
+ var dir = Global.Absolute("BetterGI/User");
+ // 迁移配置,拷贝整个目录并覆盖
+ DirectoryHelper.CopyDirectory(dir, Global.Absolute("User"));
+ // 删除旧目录
+ DirectoryHelper.DeleteDirectoryRecursively(Global.Absolute("BetterGI"));
+ }
+
+ }
+ }
+
+ private async Task OcrPreheating()
{
try
{
@@ -125,16 +201,5 @@ public partial class MainWindowViewModel : ObservableObject, IViewModel
{
MessageBox.Warning("PaddleOcr预热失败,解决方案:https://bgi.huiyadan.com/faq.html," + e.Source + "\r\n--" + Environment.NewLine + e.StackTrace + "\r\n---" + Environment.NewLine + e.Message);
}
-
- await App.GetService()!.CheckUpdateAsync(new UpdateOption());
-
- // Win11下 BitBlt截图方式不可用,需要关闭窗口优化功能
- if (OsVersionHelper.IsWindows11_OrGreater && TaskContext.Instance().Config.AutoFixWin11BitBlt)
- {
- BitBltRegistryHelper.SetDirectXUserGlobalSettings();
- }
-
- // 更新仓库
- ScriptRepoUpdater.Instance.AutoUpdate();
}
-}
+}
\ No newline at end of file
diff --git a/BetterGenshinImpact/ViewModel/Pages/KeyBindingsSettingsPageViewModel.cs b/BetterGenshinImpact/ViewModel/Pages/KeyBindingsSettingsPageViewModel.cs
index a35725aa..e20c8b32 100644
--- a/BetterGenshinImpact/ViewModel/Pages/KeyBindingsSettingsPageViewModel.cs
+++ b/BetterGenshinImpact/ViewModel/Pages/KeyBindingsSettingsPageViewModel.cs
@@ -372,7 +372,7 @@ public partial class KeyBindingsSettingsPageViewModel : ObservableObject, INavig
{
foreach (var item in keySetting)
{
- if (item.ElementIdentifierId is ElementIdentifierId keyId)
+ if (item.ElementIdentifierId is { } keyId)
{
// 跳过无法识别的按键
if (keyId.ToName() == "Unknown" || keyId.ToName() == "None")
diff --git a/BetterGenshinImpact/ViewModel/Pages/ScriptControlViewModel.cs b/BetterGenshinImpact/ViewModel/Pages/ScriptControlViewModel.cs
index c1bf7ab8..1d8b0387 100644
--- a/BetterGenshinImpact/ViewModel/Pages/ScriptControlViewModel.cs
+++ b/BetterGenshinImpact/ViewModel/Pages/ScriptControlViewModel.cs
@@ -702,6 +702,7 @@ public partial class ScriptControlViewModel : ObservableObject, INavigationAware
private List LoadAllJsScriptProjects()
{
var path = Global.ScriptPath();
+ Directory.CreateDirectory(path);
// 获取所有脚本项目
var projects = Directory.GetDirectories(path)
.Select(x => new ScriptProject(Path.GetFileName(x)))