自动烹饪修改成独立任务 (#2949)

This commit is contained in:
辉鸭蛋
2026-03-23 02:31:14 +08:00
committed by GitHub
parent d55b1d867b
commit aef3fa913b
11 changed files with 447 additions and 275 deletions

View File

@@ -1,5 +1,4 @@
using BetterGenshinImpact.GameTask;
using BetterGenshinImpact.GameTask.AutoCook;
using BetterGenshinImpact.GameTask.AutoDomain;
using BetterGenshinImpact.GameTask.AutoFight;
using BetterGenshinImpact.GameTask.AutoFishing;
@@ -23,6 +22,7 @@ using BetterGenshinImpact.GameTask.AutoStygianOnslaught;
using BetterGenshinImpact.GameTask.GetGridIcons;
using BetterGenshinImpact.GameTask.AutoEat;
using BetterGenshinImpact.GameTask.AutoLeyLineOutcrop;
using BetterGenshinImpact.GameTask.AutoCook;
using BetterGenshinImpact.GameTask.MapMask;
using BetterGenshinImpact.GameTask.SkillCd;
using BetterGenshinImpact.GameTask.UseRedeemCode;
@@ -129,11 +129,6 @@ public partial class AllConfig : ObservableObject
/// </summary>
public QuickTeleportConfig QuickTeleportConfig { get; set; } = new();
/// <summary>
/// 自动烹饪配置
/// </summary>
public AutoCookConfig AutoCookConfig { get; set; } = new();
/// <summary>
/// 自动打牌配置
/// </summary>
@@ -179,6 +174,8 @@ public partial class AllConfig : ObservableObject
/// 自动地脉花配置
/// </summary>
public AutoLeyLineOutcropConfig AutoLeyLineOutcropConfig { get; set; } = new();
public AutoCookConfig AutoCookConfig { get; set; } = new();
/// <summary>
/// 地图遮罩
@@ -269,7 +266,6 @@ public partial class AllConfig : ObservableObject
AutoSkipConfig.PropertyChanged += OnAnyPropertyChanged;
AutoFishingConfig.PropertyChanged += OnAnyPropertyChanged;
QuickTeleportConfig.PropertyChanged += OnAnyPropertyChanged;
AutoCookConfig.PropertyChanged += OnAnyPropertyChanged;
MacroConfig.PropertyChanged += OnAnyPropertyChanged;
HotKeyConfig.PropertyChanged += OnAnyPropertyChanged;
AutoWoodConfig.PropertyChanged += OnAnyPropertyChanged;
@@ -280,6 +276,7 @@ public partial class AllConfig : ObservableObject
AutoRedeemCodeConfig.PropertyChanged += OnAnyPropertyChanged;
AutoEatConfig.PropertyChanged += OnAnyPropertyChanged;
AutoLeyLineOutcropConfig.PropertyChanged += OnAnyPropertyChanged;
AutoCookConfig.PropertyChanged += OnAnyPropertyChanged;
MapMaskConfig.PropertyChanged += OnAnyPropertyChanged;
AutoMusicGameConfig.PropertyChanged += OnAnyPropertyChanged;
TpConfig.PropertyChanged += OnAnyPropertyChanged;

View File

@@ -163,6 +163,13 @@ public partial class HotKeyConfig : ObservableObject
[ObservableProperty]
private string _autoFishingGameHotkeyType = HotKeyTypeEnum.KeyboardMonitor.ToString();
// 自动烹饪开始/停止
[ObservableProperty]
private string _autoCookGameHotkey = "";
[ObservableProperty]
private string _autoCookGameHotkeyType = HotKeyTypeEnum.KeyboardMonitor.ToString();
// 自动寻路
[ObservableProperty]
private string _autoTrackPathHotkey = "";

View File

@@ -4,6 +4,7 @@ using BetterGenshinImpact.GameTask;
using BetterGenshinImpact.GameTask.AutoDomain;
using BetterGenshinImpact.GameTask.AutoEat;
using BetterGenshinImpact.GameTask.AutoFishing;
using BetterGenshinImpact.GameTask.AutoCook;
using BetterGenshinImpact.GameTask.AutoGeniusInvokation;
using BetterGenshinImpact.GameTask.AutoPathing.Handler;
using BetterGenshinImpact.GameTask.AutoWood;
@@ -195,6 +196,9 @@ public class Dispatcher
await new AutoFishingTask(AutoFishingTaskParam.BuildFromSoloTaskConfig(soloTask.Config)).Start(
cancellationToken);
return null;
case "AutoCook":
await new AutoCookTask().Start(cancellationToken);
return null;
case "AutoEat":
{
string? foodName = soloTask.Config == null ? null : ScriptObjectConverter.GetValue((ScriptObject)soloTask.Config, "foodName", (string?)null);

View File

@@ -1,17 +1,11 @@
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.ComponentModel;
using System;
namespace BetterGenshinImpact.GameTask.AutoCook;
/// <summary>
///自动烹饪配置
/// </summary>
[Serializable]
public partial class AutoCookConfig : ObservableObject
{
/// <summary>
/// 触发器是否启用
/// </summary>
[ObservableProperty]
private bool _enabled = false;
private int _checkIntervalMs = 10;
}

View File

@@ -0,0 +1,161 @@
using BetterGenshinImpact.Core.Simulator;
using BetterGenshinImpact.GameTask.Common.Element.Assets;
using BetterGenshinImpact.GameTask.Model.Area;
using Microsoft.Extensions.Logging;
using OpenCvSharp;
using System;
using System.Threading;
using System.Threading.Tasks;
using BetterGenshinImpact.GameTask.Common.BgiVision;
using Vanara.PInvoke;
using static BetterGenshinImpact.GameTask.Common.TaskControl;
namespace BetterGenshinImpact.GameTask.AutoCook;
public class AutoCookTask : ISoloTask
{
private readonly ILogger<AutoCookTask> _logger = App.GetLogger<AutoCookTask>();
private const int UiCheckIntervalMs = 400;
private const int PeakMinCount = 600; // 最小仙跳墙 700 多
private const int PeakTolerance = 20;
private const int PeakStableFrameCount = 3;
private const int TriggerDropCount = 300; // 正常是 400多
private static readonly Rect CookColorRect1080P = new(600, 660, 730, 190);
private static readonly Scalar TargetCookColor = new(255, 192, 64);
public string Name => "自动烹饪";
public async Task Start(CancellationToken ct)
{
var assetScale = TaskContext.Instance().SystemInfo.AssetScale;
var checkIntervalMs = Math.Max(1, TaskContext.Instance().Config.AutoCookConfig.CheckIntervalMs);
var peakMinCount = (int)(PeakMinCount * assetScale);
var triggerDropCount = (int)(TriggerDropCount * assetScale);
var cookColorRect = ScaleRect(CookColorRect1080P, assetScale);
_logger.LogInformation("自动烹饪任务启动");
var lastUiCheckTime = DateTime.MinValue;
var inCookUi = false;
int? peakColorCount = null;
int? peakCandidate = null;
var peakCandidateStableFrames = 0;
while (!ct.IsCancellationRequested)
{
using var captureRegion = CaptureToRectArea();
var now = DateTime.UtcNow;
if (!inCookUi || (now - lastUiCheckTime).TotalMilliseconds >= UiCheckIntervalMs)
{
var currentInCookUi = IsInCookUi(captureRegion);
if (currentInCookUi != inCookUi)
{
ResetPeakState(ref peakColorCount, ref peakCandidate, ref peakCandidateStableFrames);
}
inCookUi = currentInCookUi;
lastUiCheckTime = now;
if (!inCookUi)
{
ResetPeakState(ref peakColorCount, ref peakCandidate, ref peakCandidateStableFrames);
}
else
{
if (Bv.ClickWhiteConfirmButton(captureRegion))
{
ResetPeakState(ref peakColorCount, ref peakCandidate, ref peakCandidateStableFrames);
_logger.LogInformation("自动烹饪:{Text}", "自动点击确认");
}
}
}
if (inCookUi)
{
var currentColorCount = CountTargetColor(captureRegion, cookColorRect);
if (peakColorCount.HasValue)
{
if (currentColorCount <= peakColorCount.Value - triggerDropCount)
{
Simulation.SendInput.Keyboard.KeyPress(User32.VK.VK_SPACE);
_logger.LogInformation("自动烹饪:{Text}", $"烹饪条像素数量较峰值下降超过{triggerDropCount},按下空格。峰值:{peakColorCount.Value} 当前:{currentColorCount}");
ResetPeakState(ref peakColorCount, ref peakCandidate, ref peakCandidateStableFrames);
}
}
else if (TryBuildPeak(currentColorCount, peakMinCount, ref peakCandidate, ref peakCandidateStableFrames, out var builtPeak))
{
peakColorCount = builtPeak;
_logger.LogInformation("自动烹饪:{Text}", $"识别到完美烹饪条峰值像素数:{builtPeak}");
}
}
await Delay(checkIntervalMs, ct);
}
}
private static void ResetPeakState(ref int? peakColorCount, ref int? peakCandidate, ref int peakCandidateStableFrames)
{
peakColorCount = null;
peakCandidate = null;
peakCandidateStableFrames = 0;
}
private static bool TryBuildPeak(int currentColorCount, int peakMinCount, ref int? peakCandidate, ref int peakCandidateStableFrames, out int builtPeak)
{
builtPeak = 0;
if (currentColorCount <= peakMinCount)
{
peakCandidate = null;
peakCandidateStableFrames = 0;
return false;
}
if (!peakCandidate.HasValue)
{
peakCandidate = currentColorCount;
peakCandidateStableFrames = 1;
return false;
}
if (Math.Abs(currentColorCount - peakCandidate.Value) <= PeakTolerance)
{
peakCandidate = Math.Max(peakCandidate.Value, currentColorCount);
peakCandidateStableFrames++;
if (peakCandidateStableFrames >= PeakStableFrameCount && peakCandidate.Value > peakMinCount)
{
builtPeak = peakCandidate.Value;
peakCandidate = null;
peakCandidateStableFrames = 0;
return true;
}
return false;
}
peakCandidate = currentColorCount;
peakCandidateStableFrames = 1;
return false;
}
private static Rect ScaleRect(Rect rect, double scale)
{
return new Rect(
(int)(rect.X * scale),
(int)(rect.Y * scale),
(int)(rect.Width * scale),
(int)(rect.Height * scale));
}
private bool IsInCookUi(ImageRegion captureRegion)
{
using var cookIcon = captureRegion.Find(ElementAssets.Instance.UiLeftTopCookIcon);
return cookIcon.IsExist();
}
private int CountTargetColor(ImageRegion captureRegion, Rect cookColorRect)
{
using var crop = captureRegion.DeriveCrop(cookColorRect);
using var rgb = new Mat();
using var mask = new Mat();
Cv2.CvtColor(crop.SrcMat, rgb, ColorConversionCodes.BGR2RGB);
Cv2.InRange(rgb, TargetCookColor, TargetCookColor, mask);
return Cv2.CountNonZero(mask);
}
}

View File

@@ -1,54 +0,0 @@
using BetterGenshinImpact.Core.Recognition.OpenCv;
using BetterGenshinImpact.GameTask.Common.Element.Assets;
using Microsoft.Extensions.Logging;
using OpenCvSharp;
using System.Linq;
namespace BetterGenshinImpact.GameTask.AutoCook;
public class AutoCookTrigger : ITaskTrigger
{
private readonly ILogger<AutoCookTrigger> _logger = App.GetLogger<AutoCookTrigger>();
public string Name => "自动烹饪";
public bool IsEnabled { get; set; }
public int Priority => 50;
public bool IsExclusive { get; set; }
public void Init()
{
IsEnabled = TaskContext.Instance().Config.AutoCookConfig.Enabled;
IsExclusive = false;
}
public void OnCapture(CaptureContent content)
{
// 判断是否处于烹饪界面
IsExclusive = false;
content.CaptureRectArea.Find(ElementAssets.Instance.UiLeftTopCookIcon, _ =>
{
IsExclusive = true;
var captureRect = TaskContext.Instance().SystemInfo.ScaleMax1080PCaptureRect;
using var region = content.CaptureRectArea.DeriveCrop(0, captureRect.Height / 2, captureRect.Width, captureRect.Height / 2);
var perfectBarRects = ContoursHelper.FindSpecifyColorRects(region.SrcMat, new Scalar(255, 192, 64), 0, 8);
if (perfectBarRects.Count >= 2)
{
// 点击烹饪按钮
var btnList = ContoursHelper.FindSpecifyColorRects(region.SrcMat, new Scalar(255, 255, 192), 12, 12);
if (btnList.Count >= 1)
{
if (btnList.Count > 1)
{
_logger.LogWarning("自动烹饪:{Text}", "识别到多个结束烹饪按钮");
btnList = [.. btnList.OrderByDescending(r => r.Width)];
}
var btn = btnList[0];
var x = btn.X + btn.Width / 2;
var y = btn.Y + btn.Height / 2;
region.ClickTo(x, y);
_logger.LogInformation("自动烹饪:{Text}", "点击结束按钮");
}
}
});
}
}

View File

@@ -1,4 +1,4 @@
using BetterGenshinImpact.Core.Config;
using BetterGenshinImpact.Core.Config;
using BetterGenshinImpact.Core.Recognition.OpenCv;
using BetterGenshinImpact.Core.Script.Dependence.Model.TimerConfig;
using BetterGenshinImpact.GameTask.AutoFight.Assets;
@@ -47,7 +47,6 @@ internal class GameTaskManager
TriggerDictionary.TryAdd("QuickTeleport", new QuickTeleport.QuickTeleportTrigger());
TriggerDictionary.TryAdd("AutoSkip", new AutoSkip.AutoSkipTrigger());
TriggerDictionary.TryAdd("AutoFish", new AutoFishing.AutoFishingTrigger());
TriggerDictionary.TryAdd("AutoCook", new AutoCook.AutoCookTrigger());
TriggerDictionary.TryAdd("AutoEat", new AutoEat.AutoEatTrigger());
TriggerDictionary.TryAdd("MapMask", new MapMaskTrigger());
TriggerDictionary.TryAdd("SkillCd", new SkillCdTrigger());
@@ -123,7 +122,6 @@ internal class GameTaskManager
TriggerDictionary.GetValueOrDefault("AutoFish")?.Init();
TriggerDictionary.GetValueOrDefault("QuickTeleport")?.Init();
// TriggerDictionary.GetValueOrDefault("GameLoading")?.Init();
TriggerDictionary.GetValueOrDefault("AutoCook")?.Init();
TriggerDictionary.GetValueOrDefault("AutoEat")?.Init();
TriggerDictionary.GetValueOrDefault("MapMask")?.Init();
TriggerDictionary.GetValueOrDefault("SkillCd")?.Init();

View File

@@ -1,4 +1,4 @@
<Page x:Class="BetterGenshinImpact.View.Pages.TaskSettingsPage"
<Page x:Class="BetterGenshinImpact.View.Pages.TaskSettingsPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:b="http://schemas.microsoft.com/xaml/behaviors"
@@ -2000,163 +2000,7 @@
</Grid>
</StackPanel>
</ui:CardExpander>-->
<!-- 自动音游专辑 -->
<ui:CardExpander Margin="0,0,0,12" ContentPadding="0"
Icon="{ui:SymbolIcon MusicNote224}">
<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}"
TextWrapping="Wrap">
可以自动演奏单个,也可以全自动完成整个专辑 -
<Hyperlink Command="{Binding GoToAutoMusicGameUrlCommand}"
Foreground="{ui:ThemeResource TextFillColorSecondaryBrush}">
点击查看使用教程
</Hyperlink>
</ui:TextBlock>
</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}"
TextWrapping="Wrap">
进入演奏界面使用,下落模式必须选择垂落模式 -
<Hyperlink Command="{Binding GoToAutoMusicGameUrlCommand}"
Foreground="{ui:ThemeResource TextFillColorSecondaryBrush}">
点击查看使用教程
</Hyperlink>
</ui:TextBlock>
<controls:TwoStateButton Grid.Row="0"
Grid.RowSpan="2"
Grid.Column="1"
Margin="0,0,36,0"
DisableCommand="{Binding StopSoloTaskCommand}"
DisableContent="停止"
EnableCommand="{Binding SwitchAutoMusicGameCommand}"
EnableContent="{Binding SwitchAutoMusicGameButtonText}"
IsChecked="{Binding SwitchAutoMusicGameEnabled}" />
</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}"
TextWrapping="Wrap">
进入专辑界面使用,自动演奏未完成乐曲 -
<Hyperlink Command="{Binding GoToAutoMusicGameUrlCommand}"
Foreground="{ui:ThemeResource TextFillColorSecondaryBrush}">
点击查看使用教程
</Hyperlink>
</ui:TextBlock>
<controls:TwoStateButton Grid.Row="0"
Grid.RowSpan="2"
Grid.Column="1"
Margin="0,0,36,0"
DisableCommand="{Binding StopSoloTaskCommand}"
DisableContent="停止"
EnableCommand="{Binding SwitchAutoAlbumCommand}"
EnableContent="{Binding SwitchAutoAlbumButtonText}"
IsChecked="{Binding SwitchAutoAlbumEnabled}" />
</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:ToggleSwitch Grid.Row="0"
Grid.RowSpan="2"
Grid.Column="1"
Margin="0,0,36,0"
IsChecked="{Binding Config.AutoMusicGameConfig.MustCanorusLevel, 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" />
<ComboBox Grid.Row="0"
Grid.RowSpan="2"
Grid.Column="1"
Width="80"
Margin="0,0,36,0"
ItemsSource="{Binding AutoMusicLevelList}"
SelectedItem="{Binding Config.AutoMusicGameConfig.MusicLevel, Mode=TwoWay}"
SelectedIndex="0" />
</Grid>
</StackPanel>
</ui:CardExpander>
<!-- 自动钓鱼 -->
<ui:CardExpander Margin="0,0,0,12" ContentPadding="0">
<ui:CardExpander.Icon>
@@ -2940,9 +2784,10 @@
</Grid>
</StackPanel>
</ui:CardExpander>
<!-- 自动使用兑换码 -->
<ui:CardExpander Margin="0,0,0,12" ContentPadding="0" Icon="{ui:SymbolIcon BarcodeScanner24}">
<!-- 自动音游专辑 -->
<ui:CardExpander Margin="0,0,0,12" ContentPadding="0"
Icon="{ui:SymbolIcon MusicNote224}">
<ui:CardExpander.Header>
<Grid>
<Grid.RowDefinitions>
@@ -2956,23 +2801,179 @@
<ui:TextBlock Grid.Row="0"
Grid.Column="0"
FontTypography="Body"
Text="自动使用兑换码"
Text="自动千音雅集"
TextWrapping="Wrap" />
<ui:TextBlock Grid.Row="1"
Grid.Column="0"
Foreground="{ui:ThemeResource TextFillColorTertiaryBrush}"
TextWrapping="Wrap">
自动使用输入的兑换码
可以自动演奏单个,也可以全自动完成整个专辑 -
<Hyperlink Command="{Binding GoToAutoMusicGameUrlCommand}"
Foreground="{ui:ThemeResource TextFillColorSecondaryBrush}">
点击查看使用教程
</Hyperlink>
</ui:TextBlock>
</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}"
TextWrapping="Wrap">
进入演奏界面使用,下落模式必须选择垂落模式 -
<Hyperlink Command="{Binding GoToAutoMusicGameUrlCommand}"
Foreground="{ui:ThemeResource TextFillColorSecondaryBrush}">
点击查看使用教程
</Hyperlink>
</ui:TextBlock>
<controls:TwoStateButton Grid.Row="0"
Grid.RowSpan="2"
Grid.Column="1"
Margin="0,0,36,0"
DisableCommand="{Binding StopSoloTaskCommand}"
DisableContent="停止"
EnableCommand="{Binding SwitchAutoMusicGameCommand}"
EnableContent="{Binding SwitchAutoMusicGameButtonText}"
IsChecked="{Binding SwitchAutoMusicGameEnabled}" />
</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}"
TextWrapping="Wrap">
进入专辑界面使用,自动演奏未完成乐曲 -
<Hyperlink Command="{Binding GoToAutoMusicGameUrlCommand}"
Foreground="{ui:ThemeResource TextFillColorSecondaryBrush}">
点击查看使用教程
</Hyperlink>
</ui:TextBlock>
<controls:TwoStateButton Grid.Row="0"
Grid.RowSpan="2"
Grid.Column="1"
Margin="0,0,36,0"
DisableCommand="{Binding StopSoloTaskCommand}"
DisableContent="停止"
EnableCommand="{Binding SwitchAutoAlbumCommand}"
EnableContent="{Binding SwitchAutoAlbumButtonText}"
IsChecked="{Binding SwitchAutoAlbumEnabled}" />
</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:ToggleSwitch Grid.Row="0"
Grid.RowSpan="2"
Grid.Column="1"
Margin="0,0,36,0"
IsChecked="{Binding Config.AutoMusicGameConfig.MustCanorusLevel, 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" />
<ComboBox Grid.Row="0"
Grid.RowSpan="2"
Grid.Column="1"
Width="80"
Margin="0,0,36,0"
ItemsSource="{Binding AutoMusicLevelList}"
SelectedItem="{Binding Config.AutoMusicGameConfig.MusicLevel, Mode=TwoWay}"
SelectedIndex="0" />
</Grid>
</StackPanel>
</ui:CardExpander>
<ui:CardExpander Margin="0,0,0,12" ContentPadding="0">
<ui:CardExpander.Icon>
<ui:FontIcon Glyph="&#xe43f;" 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" />
<controls:TwoStateButton Grid.Row="0"
Grid.RowSpan="2"
Grid.Column="1"
Margin="0,0,24,0"
DisableCommand="{Binding StopSoloTaskCommand}"
DisableContent="停止"
EnableCommand="{Binding SwitchAutoRedeemCodeCommand}"
EnableContent="{Binding SwitchAutoRedeemCodeButtonText}"
IsChecked="{Binding SwitchAutoRedeemCodeEnabled}" />
EnableCommand="{Binding SwitchAutoCookCommand}"
EnableContent="{Binding SwitchAutoCookButtonText}"
IsChecked="{Binding SwitchAutoCookEnabled}" />
</Grid>
</ui:CardExpander.Header>
<StackPanel>
@@ -2988,23 +2989,27 @@
<ui:TextBlock Grid.Row="0"
Grid.Column="0"
FontTypography="Body"
Text="获取剪切板上的兑换码"
Text="检测间隔(毫秒)"
TextWrapping="Wrap" />
<ui:TextBlock Grid.Row="1"
Grid.Column="0"
Foreground="{ui:ThemeResource TextFillColorTertiaryBrush}"
Text="在切换到软件界面时候,自动提取兑换码并提示"
Text="每次截图检测的时间间隔,最小 1ms"
TextWrapping="Wrap" />
<ui:ToggleSwitch Grid.Row="0"
Grid.RowSpan="2"
Grid.Column="1"
Margin="0,0,36,0"
IsChecked="{Binding Config.AutoRedeemCodeConfig.ClipboardListenerEnabled, Mode=TwoWay}" />
<ui:NumberBox Grid.Row="0"
Grid.RowSpan="2"
Grid.Column="1"
Margin="0,0,36,0"
Minimum="1"
Maximum="1000"
ValidationMode="InvalidInputOverwritten"
Value="{Binding Config.AutoCookConfig.CheckIntervalMs, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Text="{Binding Config.AutoCookConfig.CheckIntervalMs, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
</Grid>
</StackPanel>
</ui:CardExpander>
<!-- 自动分解圣遗物 -->
<!-- 自动分解圣遗物 -->
<ui:CardExpander Margin="0,0,0,12" ContentPadding="0">
<ui:CardExpander.Icon>
<ui:FontIcon Glyph="&#xf4bb;" Style="{StaticResource FaFontIconStyle}" />
@@ -3232,6 +3237,69 @@
</Grid>
</StackPanel>
</ui:CardExpander>
<!-- 自动使用兑换码 -->
<ui:CardExpander Margin="0,0,0,12" ContentPadding="0" Icon="{ui:SymbolIcon BarcodeScanner24}">
<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}"
TextWrapping="Wrap">
自动使用输入的兑换码
</ui:TextBlock>
<controls:TwoStateButton Grid.Row="0"
Grid.RowSpan="2"
Grid.Column="1"
Margin="0,0,24,0"
DisableCommand="{Binding StopSoloTaskCommand}"
DisableContent="停止"
EnableCommand="{Binding SwitchAutoRedeemCodeCommand}"
EnableContent="{Binding SwitchAutoRedeemCodeButtonText}"
IsChecked="{Binding SwitchAutoRedeemCodeEnabled}" />
</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.AutoRedeemCodeConfig.ClipboardListenerEnabled, Mode=TwoWay}" />
</Grid>
</StackPanel>
</ui:CardExpander>
<!-- 截取物品图标(开发者) -->
<ui:CardExpander Margin="0,0,0,12" ContentPadding="0"

View File

@@ -1478,33 +1478,6 @@
</StackPanel>
</ui:CardExpander>
<!-- 自动烹饪 -->
<ui:CardControl Margin="0,0,0,12">
<ui:CardControl.Icon>
<ui:FontIcon Glyph="&#xe43f;" Style="{StaticResource FaFontIconStyle}" />
</ui:CardControl.Icon>
<ui:CardControl.Header>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<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}"
TextWrapping="Wrap">
手动烹饪时,自动在完美状态下结束烹饪(不用的时候请关闭)
</ui:TextBlock>
</Grid>
</ui:CardControl.Header>
<ui:ToggleSwitch Margin="0,0,40,0" IsChecked="{Binding Config.AutoCookConfig.Enabled, Mode=TwoWay}" />
</ui:CardControl>
<!-- 一键战斗 -->
<!--<ui:CardExpander Margin="0,0,0,12" ContentPadding="0" Icon="{ui:SymbolIcon ArrowSync24}">
<ui:CardExpander.Header>

View File

@@ -443,6 +443,13 @@ public partial class HotKeyPageViewModel : ObservableObject, IViewModel
Config.HotKeyConfig.AutoFishingGameHotkeyType,
(_, _) => { SwitchSoloTask(_taskSettingsPageViewModel.SwitchAutoFishingCommand); }
));
soloTaskDirectory.Children.Add(new HotKeySettingModel(
"启动/停止自动烹饪",
nameof(Config.HotKeyConfig.AutoCookGameHotkey),
Config.HotKeyConfig.AutoCookGameHotkey,
Config.HotKeyConfig.AutoCookGameHotkeyType,
(_, _) => { SwitchSoloTask(_taskSettingsPageViewModel.SwitchAutoCookCommand); }
));
macroDirectory.Children.Add(new HotKeySettingModel(
"快捷点击原神内确认按钮",
@@ -667,4 +674,4 @@ public partial class HotKeyPageViewModel : ObservableObject, IViewModel
{
return enabled.ToChinese();
}
}
}

View File

@@ -3,6 +3,7 @@ using BetterGenshinImpact.Core.Script;
using BetterGenshinImpact.Core.Script.Project;
using BetterGenshinImpact.GameTask;
using BetterGenshinImpact.GameTask.AutoArtifactSalvage;
using BetterGenshinImpact.GameTask.AutoCook;
using BetterGenshinImpact.GameTask.AutoDomain;
using BetterGenshinImpact.GameTask.AutoFight;
using BetterGenshinImpact.GameTask.AutoFishing;
@@ -117,6 +118,12 @@ public partial class TaskSettingsPageViewModel : ViewModel
[ObservableProperty]
private string _switchAutoAlbumButtonText = "启动";
[ObservableProperty]
private bool _switchAutoCookEnabled;
[ObservableProperty]
private string _switchAutoCookButtonText = "启动";
[ObservableProperty]
private List<string> _domainNameList;
@@ -321,6 +328,7 @@ public partial class TaskSettingsPageViewModel : ViewModel
SwitchAutoFightEnabled = false;
SwitchAutoMusicGameEnabled = false;
SwitchAutoAlbumEnabled = false;
SwitchAutoCookEnabled = false;
SwitchAutoFishingEnabled = false;
SwitchAutoLeyLineOutcropEnabled = false;
SwitchArtifactSalvageEnabled = false;
@@ -598,6 +606,15 @@ public partial class TaskSettingsPageViewModel : ViewModel
SwitchAutoAlbumEnabled = false;
}
[RelayCommand]
private async Task OnSwitchAutoCook()
{
SwitchAutoCookEnabled = true;
await new TaskRunner()
.RunSoloTaskAsync(new AutoCookTask());
SwitchAutoCookEnabled = false;
}
[RelayCommand]
private async Task OnSwitchAutoFishing()
{