mirror of
https://github.com/babalae/better-genshin-impact.git
synced 2026-05-21 09:45:48 +08:00
Merge branch 'babalae:main' into main
This commit is contained in:
Binary file not shown.
@@ -10,7 +10,7 @@
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<ApplicationIcon>Assets\Images\logo.ico</ApplicationIcon>
|
||||
<AssemblyName>BetterGI</AssemblyName>
|
||||
<AssemblyVersion>0.39.4</AssemblyVersion>
|
||||
<AssemblyVersion>0.39.6</AssemblyVersion>
|
||||
<Platforms>x64</Platforms>
|
||||
<DebugType>embedded</DebugType>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -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
|
||||
/// 原神按键绑定配置
|
||||
/// </summary>
|
||||
public KeyBindingsConfig KeyBindingsConfig { get; set; } = new();
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 传送相关配置
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -32,5 +32,11 @@ public partial class CommonConfig : ObservableObject
|
||||
/// 主题
|
||||
/// </summary>
|
||||
[ObservableProperty]
|
||||
private WindowBackdropType _currentBackdropType = WindowBackdropType.Auto;
|
||||
private WindowBackdropType _currentBackdropType = WindowBackdropType.Mica;
|
||||
|
||||
/// <summary>
|
||||
/// 是否是第一次运行
|
||||
/// </summary>
|
||||
[ObservableProperty]
|
||||
private bool _isFirstRun = true;
|
||||
}
|
||||
|
||||
@@ -436,6 +436,7 @@ public class AutoDomainTask : ISoloTask
|
||||
finally
|
||||
{
|
||||
Logger.LogInformation("自动战斗线程结束");
|
||||
combatScenes.AfterTask();
|
||||
}
|
||||
}, cts.Token);
|
||||
|
||||
|
||||
@@ -25,6 +25,13 @@ public partial class AutoFightConfig : ObservableObject
|
||||
/// </summary>
|
||||
[ObservableProperty]
|
||||
private bool _fightFinishDetectEnabled = true;
|
||||
/// <summary>
|
||||
/// 根据技能CD优化出招人员
|
||||
/// 根据填入人或人和cd,来决定当此人元素战技cd未结束时,跳过此人出招,来优化战斗流程,可填入人名或人名数字(用逗号分隔),
|
||||
/// 多种用分号分隔,例如:白术;钟离,12;,如果人名,则用内置cd检查,如果是人名和数字,则把数字当做出招cd(秒)。
|
||||
/// </summary>
|
||||
[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
|
||||
{
|
||||
/// <summary>
|
||||
/// 前进次数
|
||||
/// </summary>
|
||||
[ObservableProperty]
|
||||
private int _forwardTimes = 6;
|
||||
|
||||
/// <summary>
|
||||
/// 校准次数
|
||||
/// </summary>
|
||||
[ObservableProperty]
|
||||
private int _calibrationTimes = 15;
|
||||
|
||||
/// <summary>
|
||||
/// 衰减因子
|
||||
/// </summary>
|
||||
[ObservableProperty]
|
||||
private double _decayFactor = 0.7;
|
||||
|
||||
/// <summary>
|
||||
/// 前进量(秒),设置为0时在[1,3]中随机
|
||||
/// </summary>
|
||||
[ObservableProperty]
|
||||
private int _forwardSeconds = 2;
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
/// 掉落寻物相关配置
|
||||
/// </summary>
|
||||
[ObservableProperty]
|
||||
private PickDropsAfterFightConfig _pickDropsConfig = new();
|
||||
|
||||
/// <summary>
|
||||
/// 战斗结束后,如果存在枫原万叶,则使用该角色捡材料
|
||||
/// </summary>
|
||||
|
||||
@@ -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 = "";
|
||||
|
||||
|
||||
}
|
||||
@@ -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<string, double> ParseStringToDictionary(string input,double defaultValue=-1)
|
||||
{
|
||||
var dictionary = new Dictionary<string, double>();
|
||||
|
||||
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)
|
||||
{
|
||||
|
||||
@@ -31,7 +31,7 @@ public class CombatScenes : IDisposable
|
||||
/// <summary>
|
||||
/// 当前配队
|
||||
/// </summary>
|
||||
public Avatar[] Avatars { get; set; } = Array.Empty<Avatar>();
|
||||
public Avatar[] Avatars { get; set; } = [];
|
||||
|
||||
public Dictionary<string, Avatar> 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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('|'))
|
||||
|
||||
@@ -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", "跳跃");
|
||||
|
||||
@@ -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) //冷却一会
|
||||
{
|
||||
|
||||
@@ -41,25 +41,25 @@
|
||||
"我带凯亚去没去过的地方玩吧"
|
||||
],
|
||||
"卡维结局1:未来蓝图": [
|
||||
"一起去说服委托人吧",
|
||||
"一起去说服刚刚的委托人吧",
|
||||
"尝试一下新的风格"
|
||||
],
|
||||
"卡维结局2:契约达成": [
|
||||
"一起去说服委托人吧",
|
||||
"一起去说服刚刚的委托人吧",
|
||||
"可以找其他商人筹款"
|
||||
],
|
||||
"卡维结局3:闲时小聚": [
|
||||
"做些别的事转化心情",
|
||||
"做些别的事转换心情",
|
||||
"卡维为什么要当设计师呢",
|
||||
"去找熟人问问"
|
||||
],
|
||||
"卡维结局4:群星之下": [
|
||||
"做些别的事转化心情",
|
||||
"做些别的事转换心情",
|
||||
"卡维为什么要当设计师呢",
|
||||
"还是先别管这个了"
|
||||
],
|
||||
"卡维结局5:第1堂课": [
|
||||
"做些别的事转化心情",
|
||||
"做些别的事转换心情",
|
||||
"找份其他工作赚钱"
|
||||
],
|
||||
"莱依拉结局1:不可说之事": [
|
||||
@@ -74,7 +74,7 @@
|
||||
"莱依拉结局2:代价与回报": [
|
||||
"虽然有些不靠谱",
|
||||
"我陪你去找答案",
|
||||
"仙灵应该不想苛责你"
|
||||
"仙灵应该不只是想苛责你"
|
||||
],
|
||||
"莱依拉结局3:不愿重蹈覆辙": [
|
||||
"虽然有些不靠谱",
|
||||
|
||||
55
BetterGenshinImpact/GameTask/AutoTrackPath/TpConfig.cs
Normal file
55
BetterGenshinImpact/GameTask/AutoTrackPath/TpConfig.cs
Normal file
@@ -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; // 单次移动最大距离
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// 传送到须弥七天神像
|
||||
/// </summary>
|
||||
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);
|
||||
}
|
||||
/// <summary>
|
||||
/// 通过大地图传送到指定坐标最近的传送点,然后移动到指定坐标
|
||||
@@ -139,9 +60,10 @@ public class TpTask(CancellationToken ct)
|
||||
/// <param name="tpX"></param>
|
||||
/// <param name="tpY"></param>
|
||||
/// <param name="force">强制以当前的tpX,tpY坐标进行自动传送</param>
|
||||
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)
|
||||
/// </summary>
|
||||
/// <param name="x">目标x坐标</param>
|
||||
/// <param name="y">目标y坐标</param>
|
||||
/// <param name="tolerance">允许误差,默认200</param>
|
||||
/// <param name="maxIterations">最大尝试次数,默认30</param>
|
||||
/// <param name="maxMouseMove">单次移动最大距离,默认250</param>
|
||||
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)
|
||||
/// 调整地图缩放级别以加速移动
|
||||
/// </summary>
|
||||
/// <param name="zoomIn">是否放大地图</param>
|
||||
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]
|
||||
|
||||
/// <summary>
|
||||
/// 调整地图的缩放等级(整数缩放级别)。
|
||||
/// </summary>
|
||||
/// <param name="zoomLevel">目标等级:1-6。整数。随着数字变大地图越小,细节越少。</param>
|
||||
[Obsolete]
|
||||
public async Task AdjustMapZoomLevel(int zoomLevel)
|
||||
{
|
||||
for (int i = 0; i < 5; i++)
|
||||
@@ -478,15 +398,15 @@ public class TpTask(CancellationToken ct)
|
||||
/// </summary>
|
||||
/// <param name="zoomLevel">当前缩放等级:1.0-6.0,浮点数。</param>
|
||||
/// <param name="targetZoomLevel">目标缩放等级:1.0-6.0,浮点数。</param>
|
||||
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)
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取最近的传送点位置
|
||||
/// 获取最近的传送点位置和所处区域
|
||||
/// </summary>
|
||||
/// <param name="x"></param>
|
||||
/// <param name="y"></param>
|
||||
@@ -820,4 +740,4 @@ public class TpTask(CancellationToken ct)
|
||||
// 1~6 的缩放等级
|
||||
return (-5 * s) + 6;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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("未检测进入游戏界面");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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<MoraStatistics, string> 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($"<h2>按日锄地摩拉统计</h2>");
|
||||
html.AppendLine($"<h2>按日摩拉收益统计</h2>");
|
||||
html.AppendLine("<table>");
|
||||
|
||||
html.AppendLine(" <tr>");
|
||||
|
||||
@@ -25,6 +25,16 @@ namespace LogParse
|
||||
|
||||
public List<ActionItem> 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;
|
||||
|
||||
@@ -50,8 +50,8 @@ public class TravelsDiaryDetailManager
|
||||
var _temp = JsonSerializer.Deserialize<ApiResponse<ActionItem>>(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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 2.9 KiB |
@@ -34,6 +34,7 @@ public class QuickTeleportAssets : BaseAssets<QuickTeleportAssets>
|
||||
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<QuickTeleportAssets>
|
||||
/// <returns></returns>
|
||||
public RecognitionObject BuildMapChooseIconRo(string name)
|
||||
{
|
||||
var info = TaskContext.Instance().SystemInfo;
|
||||
var ro = new RecognitionObject
|
||||
{
|
||||
Name = name + "MapChooseIcon",
|
||||
|
||||
@@ -65,7 +65,7 @@ namespace BetterGenshinImpact.GameTask
|
||||
}
|
||||
}
|
||||
|
||||
public SettingsContainer? GameSettings { get; set; }
|
||||
// public SettingsContainer? GameSettings { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 关联启动原神的时间
|
||||
|
||||
@@ -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)));
|
||||
}
|
||||
|
||||
|
||||
@@ -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); // 递归拷贝子目录
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 递归删除指定目录及其所有子目录和文件
|
||||
/// </summary>
|
||||
/// <param name="directoryPath">要删除的目录的路径</param>
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -428,7 +428,34 @@
|
||||
</b:Interaction.Triggers>
|
||||
</ComboBox>
|
||||
</Grid>
|
||||
|
||||
<Grid Margin="16">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<ui:TextBlock Grid.Row="0"
|
||||
Grid.Column="0"
|
||||
FontTypography="Body"
|
||||
Text="根据技能CD优化出招人员"
|
||||
TextWrapping="Wrap" />
|
||||
<ui:TextBlock Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Foreground="{ui:ThemeResource TextFillColorTertiaryBrush}"
|
||||
Text="根据填入人或人和cd,来决定当此人元素战技cd未结束时,跳过此人出招,来优化战斗流程,可填入人名或人名数字(用逗号分隔),多种用分号分隔,例如:白术;钟离,12;,如果人名,则用内置cd检查(或填入数字也小于0),如果是人名和数字,则把数字当做出招cd(秒)。"
|
||||
TextWrapping="Wrap" />
|
||||
<ui:TextBox Grid.Row="0"
|
||||
Grid.RowSpan="2"
|
||||
Grid.Column="1"
|
||||
MinWidth="180"
|
||||
MaxWidth="800"
|
||||
Margin="0,0,36,0"
|
||||
Text="{Binding Config.AutoFightConfig.ActionSchedulerByCd, Mode=TwoWay}"
|
||||
TextWrapping="Wrap" />
|
||||
</Grid>
|
||||
<!--内嵌的设置-->
|
||||
<Separator Margin="-18,0" BorderThickness="0,1,0,0" />
|
||||
<Grid Margin="16,10,52,0">
|
||||
@@ -624,33 +651,147 @@
|
||||
</ui:CardExpander>
|
||||
</Grid>
|
||||
<Separator Margin="-18,0" BorderThickness="0,1,0,0" />
|
||||
<Grid Margin="16,10,52,0">
|
||||
|
||||
<ui:CardExpander Margin="0,0,0,12"
|
||||
ContentPadding="0"
|
||||
IsExpanded="False">
|
||||
|
||||
<ui:CardExpander.Header>
|
||||
<Grid>
|
||||
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<ui:TextBlock Grid.Row="0"
|
||||
Grid.Column="0"
|
||||
FontTypography="Body"
|
||||
Text="自动拾取掉落物"
|
||||
TextWrapping="Wrap"/>
|
||||
<ui:TextBlock Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Foreground="{ui:ThemeResource TextFillColorTertiaryBrush}"
|
||||
Text="战斗结束后尽可能拾取周围掉落物(与万叶配合更佳)"
|
||||
TextWrapping="Wrap"/>
|
||||
<ui:ToggleSwitch Grid.Row="0"
|
||||
Grid.RowSpan="2"
|
||||
Grid.Column="1"
|
||||
Margin="0,0,36,0"
|
||||
IsChecked="{Binding Config.AutoFightConfig.PickDropsAfterFightEnabled}"/>
|
||||
</Grid>
|
||||
</ui:CardExpander.Header>
|
||||
<StackPanel>
|
||||
<Grid Margin="16">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<ui:TextBlock Grid.Row="0"
|
||||
Grid.Column="0"
|
||||
FontTypography="Body"
|
||||
Text="前进次数"
|
||||
TextWrapping="Wrap"/>
|
||||
<ui:TextBlock Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Foreground="{ui:ThemeResource TextFillColorTertiaryBrush}"
|
||||
Text="通过往前走来接近掉落物的次数"
|
||||
TextWrapping="Wrap"/>
|
||||
<ui:TextBox Grid.Row="0"
|
||||
Grid.RowSpan="2"
|
||||
Grid.Column="1"
|
||||
MinWidth="120"
|
||||
Text="{Binding Config.AutoFightConfig.PickDropsConfig.ForwardTimes}"/>
|
||||
</Grid>
|
||||
<Grid Margin="16">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<ui:TextBlock Grid.Row="0"
|
||||
Grid.Column="0"
|
||||
FontTypography="Body"
|
||||
Text="校准次数"
|
||||
TextWrapping="Wrap"/>
|
||||
<ui:TextBlock Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Foreground="{ui:ThemeResource TextFillColorTertiaryBrush}"
|
||||
Text="视角调整次数,理论上越高越好"
|
||||
TextWrapping="Wrap"/>
|
||||
<ui:TextBox Grid.Row="0"
|
||||
Grid.RowSpan="2"
|
||||
Grid.Column="1"
|
||||
MinWidth="120"
|
||||
Text="{Binding Config.AutoFightConfig.PickDropsConfig.CalibrationTimes}"/>
|
||||
</Grid>
|
||||
<Grid Margin="16">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<ui:TextBlock Grid.Row="0"
|
||||
Grid.Column="0"
|
||||
FontTypography="Body"
|
||||
Text="衰减因子"
|
||||
TextWrapping="Wrap"/>
|
||||
<ui:TextBlock Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Foreground="{ui:ThemeResource TextFillColorTertiaryBrush}"
|
||||
Text="视角调整的精细程度,应在0.5到1之间(数值越小越精细,数值越高校准范围越大)"
|
||||
TextWrapping="Wrap"/>
|
||||
<ui:TextBox Grid.Row="0"
|
||||
Grid.RowSpan="2"
|
||||
Grid.Column="1"
|
||||
MinWidth="120"
|
||||
Text="{Binding Config.AutoFightConfig.PickDropsConfig.DecayFactor}"/>
|
||||
</Grid>
|
||||
<Grid Margin="16">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<ui:TextBlock Grid.Row="0"
|
||||
Grid.Column="0"
|
||||
FontTypography="Body"
|
||||
Text="前进量"
|
||||
TextWrapping="Wrap"/>
|
||||
<ui:TextBlock Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Foreground="{ui:ThemeResource TextFillColorTertiaryBrush}"
|
||||
Text="每次视角校准后前进的时长(秒)。设置为0时,前进量在1到3秒内随机(大了可能跑到奇奇怪怪的地方去,小了可能采集不到,可以和前进次数配合)"
|
||||
TextWrapping="Wrap"/>
|
||||
<ui:TextBox Grid.Row="0"
|
||||
Grid.RowSpan="2"
|
||||
Grid.Column="1"
|
||||
MinWidth="120"
|
||||
Text="{Binding Config.AutoFightConfig.PickDropsConfig.ForwardSeconds}"/>
|
||||
</Grid>
|
||||
|
||||
</StackPanel>
|
||||
</ui:CardExpander>
|
||||
|
||||
<Grid Margin="16">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<ui:TextBlock Grid.Row="0"
|
||||
Grid.Column="0"
|
||||
FontTypography="Body"
|
||||
Text="战斗结束后自动拾取掉落物"
|
||||
TextWrapping="Wrap" />
|
||||
<ui:TextBlock Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Foreground="{ui:ThemeResource TextFillColorTertiaryBrush}"
|
||||
Text="战斗结束后自动拾取掉落物"
|
||||
TextWrapping="Wrap" />
|
||||
<ui:ToggleSwitch Grid.Row="0"
|
||||
Grid.RowSpan="2"
|
||||
Grid.Column="1"
|
||||
Margin="0,0,36,0"
|
||||
IsChecked="{Binding Config.AutoFightConfig.PickDropsAfterFightEnabled, Mode=TwoWay}" />
|
||||
</Grid>
|
||||
<Separator Margin="-18,0" BorderThickness="0,1,0,0" />
|
||||
<Grid Margin="16">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
|
||||
@@ -778,7 +778,166 @@
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
</ui:CardExpander>
|
||||
|
||||
|
||||
<!-- 快速传送 -->
|
||||
<ui:CardExpander Margin="0,0,0,12" ContentPadding="0">
|
||||
<ui:CardExpander.Icon>
|
||||
<ui:FontIcon Glyph="" Style="{StaticResource FaFontIconStyle}" />
|
||||
</ui:CardExpander.Icon>
|
||||
<ui:CardExpander.Header>
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<ui:TextBlock Grid.Row="0"
|
||||
Grid.Column="0"
|
||||
FontTypography="Body"
|
||||
Text="地图移动"
|
||||
TextWrapping="Wrap" />
|
||||
<ui:TextBlock Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Foreground="{ui:ThemeResource TextFillColorTertiaryBrush}"
|
||||
Text="传送点不在当前地图中时,传送过程中移动地图"
|
||||
TextWrapping="Wrap" />
|
||||
</Grid>
|
||||
</ui:CardExpander.Header>
|
||||
<StackPanel>
|
||||
<Grid Margin="16">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<ui:TextBlock Grid.Row="0"
|
||||
Grid.Column="0"
|
||||
FontTypography="Body"
|
||||
Text="地图移动过程中是否缩放地图"
|
||||
TextWrapping="Wrap" />
|
||||
<ui:TextBlock Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Foreground="{ui:ThemeResource TextFillColorTertiaryBrush}"
|
||||
Text="建议开启,关闭该设置可能在运行部分脚本时发生错误"
|
||||
TextWrapping="Wrap" />
|
||||
<ui:ToggleSwitch Grid.Row="0"
|
||||
Grid.RowSpan="2"
|
||||
Grid.Column="1"
|
||||
Margin="0,0,36,0"
|
||||
IsChecked="{Binding Config.TpConfig.MapZoomEnabled, Mode=TwoWay}" />
|
||||
</Grid>
|
||||
<Grid Margin="16">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<ui:TextBlock Grid.Row="0"
|
||||
Grid.Column="0"
|
||||
FontTypography="Body"
|
||||
Text="单次鼠标移动的最大距离"
|
||||
TextWrapping="Wrap" />
|
||||
<ui:TextBlock Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Foreground="{ui:ThemeResource TextFillColorTertiaryBrush}"
|
||||
Text="过大可能会导致鼠标移动出窗口,单位:像素"
|
||||
TextWrapping="Wrap" />
|
||||
<ui:TextBox Grid.Row="0"
|
||||
Grid.RowSpan="2"
|
||||
Grid.Column="1"
|
||||
MinWidth="90"
|
||||
Margin="0,0,36,0"
|
||||
Text="{Binding Config.TpConfig.MaxMouseMove, Mode=TwoWay}" />
|
||||
</Grid>
|
||||
<Grid Margin="16">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<ui:TextBlock Grid.Row="0"
|
||||
Grid.Column="0"
|
||||
FontTypography="Body"
|
||||
Text="地图缩小的距离"
|
||||
TextWrapping="Wrap" />
|
||||
<ui:TextBlock Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Foreground="{ui:ThemeResource TextFillColorTertiaryBrush}"
|
||||
Text="大于这个距离会缩小地图以加快传送,单位:像素"
|
||||
TextWrapping="Wrap" />
|
||||
<ui:TextBox Grid.Row="0"
|
||||
Grid.RowSpan="2"
|
||||
Grid.Column="1"
|
||||
MinWidth="90"
|
||||
Margin="0,0,36,0"
|
||||
Text="{Binding Config.TpConfig.MapZoomOutDistance, Mode=TwoWay}" />
|
||||
</Grid>
|
||||
<Grid Margin="16">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<ui:TextBlock Grid.Row="0"
|
||||
Grid.Column="0"
|
||||
FontTypography="Body"
|
||||
Text="地图放大的距离"
|
||||
TextWrapping="Wrap" />
|
||||
<ui:TextBlock Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Foreground="{ui:ThemeResource TextFillColorTertiaryBrush}"
|
||||
Text="小于这个距离会放大地图以提高移动的精度,单位:像素"
|
||||
TextWrapping="Wrap" />
|
||||
<ui:TextBox Grid.Row="0"
|
||||
Grid.RowSpan="2"
|
||||
Grid.Column="1"
|
||||
MinWidth="90"
|
||||
Margin="0,0,36,0"
|
||||
Text="{Binding Config.TpConfig.MapZoomInDistance, Mode=TwoWay}" />
|
||||
</Grid>
|
||||
<Grid Margin="16">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<ui:TextBlock Grid.Row="0"
|
||||
Grid.Column="0"
|
||||
FontTypography="Body"
|
||||
Text="鼠标移动的时间间隔"
|
||||
TextWrapping="Wrap" />
|
||||
<ui:TextBlock Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Foreground="{ui:ThemeResource TextFillColorTertiaryBrush}"
|
||||
Text="数字越小移动鼠标的速度越快,如果移动地图时产生卡顿,请提高这个数值,单位:毫秒"
|
||||
TextWrapping="Wrap" />
|
||||
<ui:TextBox Grid.Row="0"
|
||||
Grid.RowSpan="2"
|
||||
Grid.Column="1"
|
||||
MinWidth="90"
|
||||
Margin="0,0,36,0"
|
||||
Text="{Binding Config.TpConfig.StepIntervalMilliseconds, Mode=TwoWay}" />
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
</ui:CardExpander>
|
||||
<!-- 自动烹饪 -->
|
||||
<ui:CardControl Margin="0,0,0,12">
|
||||
<ui:CardControl.Icon>
|
||||
|
||||
@@ -370,6 +370,34 @@
|
||||
</b:Interaction.Triggers>
|
||||
</ComboBox>
|
||||
</Grid>
|
||||
<Grid Margin="16">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<ui:TextBlock Grid.Row="0"
|
||||
Grid.Column="0"
|
||||
FontTypography="Body"
|
||||
Text="根据技能CD优化出招人员"
|
||||
TextWrapping="Wrap" />
|
||||
<ui:TextBlock Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Foreground="{ui:ThemeResource TextFillColorTertiaryBrush}"
|
||||
Text="根据填入人或人和cd,来决定当此人元素战技cd未结束时,跳过此人出招,来优化战斗流程,可填入人名或人名数字(用逗号分隔),多种用分号分隔,例如:白术;钟离,12;,如果人名,则用内置cd检查(或填入数字也小于0),如果是人名和数字,则把数字当做出招cd(秒)。"
|
||||
TextWrapping="Wrap" />
|
||||
<ui:TextBox Grid.Row="0"
|
||||
Grid.RowSpan="2"
|
||||
Grid.Column="1"
|
||||
MinWidth="180"
|
||||
MaxWidth="800"
|
||||
Margin="0,0,36,0"
|
||||
Text="{Binding PathingConfig.AutoFightConfig.ActionSchedulerByCd, Mode=TwoWay}"
|
||||
TextWrapping="Wrap" />
|
||||
</Grid>
|
||||
<Grid Margin="16">
|
||||
|
||||
<ui:CardExpander Margin="0,0,0,12"
|
||||
|
||||
@@ -15,11 +15,13 @@ 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.ViewModel.Pages;
|
||||
using Wpf.Ui;
|
||||
using Wpf.Ui.Controls;
|
||||
|
||||
@@ -39,7 +41,7 @@ public partial class MainWindowViewModel : ObservableObject, IViewModel
|
||||
|
||||
[ObservableProperty]
|
||||
public WindowBackdropType _currentBackdropType = WindowBackdropType.Auto;
|
||||
|
||||
|
||||
public AllConfig Config { get; set; }
|
||||
|
||||
public MainWindowViewModel(INavigationService navigationService, IConfigService configService)
|
||||
@@ -60,23 +62,27 @@ public partial class MainWindowViewModel : ObservableObject, IViewModel
|
||||
{
|
||||
IsVisible = false;
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void OnSwitchBackdrop()
|
||||
{
|
||||
if (!OsVersionHelper.IsWindows11_22523_OrGreater)
|
||||
{
|
||||
return; // win10 不支持切换主题
|
||||
}
|
||||
|
||||
CurrentBackdropType = CurrentBackdropType switch
|
||||
{
|
||||
WindowBackdropType.Auto => 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<IUpdateService>()!.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<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()
|
||||
{
|
||||
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<IUpdateService>()!.CheckUpdateAsync(new UpdateOption());
|
||||
|
||||
// Win11下 BitBlt截图方式不可用,需要关闭窗口优化功能
|
||||
if (OsVersionHelper.IsWindows11_OrGreater && TaskContext.Instance().Config.AutoFixWin11BitBlt)
|
||||
{
|
||||
BitBltRegistryHelper.SetDirectXUserGlobalSettings();
|
||||
}
|
||||
|
||||
// 更新仓库
|
||||
ScriptRepoUpdater.Instance.AutoUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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")
|
||||
|
||||
@@ -702,6 +702,7 @@ public partial class ScriptControlViewModel : ObservableObject, INavigationAware
|
||||
private List<ScriptProject> LoadAllJsScriptProjects()
|
||||
{
|
||||
var path = Global.ScriptPath();
|
||||
Directory.CreateDirectory(path);
|
||||
// 获取所有脚本项目
|
||||
var projects = Directory.GetDirectories(path)
|
||||
.Select(x => new ScriptProject(Path.GetFileName(x)))
|
||||
|
||||
Reference in New Issue
Block a user