拓展自动吃药,基于图标识别 (#2051)
@@ -1,9 +1,10 @@
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using BetterGenshinImpact.GameTask;
|
||||
using BetterGenshinImpact.GameTask.AutoEat;
|
||||
using BetterGenshinImpact.GameTask.AutoFight;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json.Serialization;
|
||||
using BetterGenshinImpact.GameTask;
|
||||
using BetterGenshinImpact.GameTask.AutoFight;
|
||||
|
||||
namespace BetterGenshinImpact.Core.Config;
|
||||
|
||||
@@ -96,6 +97,13 @@ public partial class PathingPartyConfig : ObservableObject
|
||||
[ObservableProperty]
|
||||
private bool _autoEatEnabled = false;
|
||||
|
||||
/// <summary>
|
||||
/// 自动吃食物配置
|
||||
/// 供JS脚本使用
|
||||
/// </summary>
|
||||
[ObservableProperty]
|
||||
private AutoEatConfig _autoEatConfig = new();
|
||||
|
||||
//在连续执行时是否隐藏
|
||||
[ObservableProperty]
|
||||
private bool _hideOnRepeat = false;
|
||||
|
||||
@@ -1,19 +1,26 @@
|
||||
using BetterGenshinImpact.Core.Script.Dependence.Model;
|
||||
using BetterGenshinImpact.Core.Config;
|
||||
using BetterGenshinImpact.Core.Script.Dependence.Model;
|
||||
using BetterGenshinImpact.GameTask;
|
||||
using BetterGenshinImpact.ViewModel.Pages;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using BetterGenshinImpact.GameTask.AutoDomain;
|
||||
using BetterGenshinImpact.GameTask.AutoEat;
|
||||
using BetterGenshinImpact.GameTask.AutoFishing;
|
||||
using BetterGenshinImpact.GameTask.AutoWood;
|
||||
using BetterGenshinImpact.GameTask.AutoGeniusInvokation;
|
||||
using BetterGenshinImpact.GameTask.AutoPathing.Handler;
|
||||
using BetterGenshinImpact.GameTask.AutoWood;
|
||||
using BetterGenshinImpact.Helpers;
|
||||
using BetterGenshinImpact.ViewModel.Pages;
|
||||
using Microsoft.ClearScript;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BetterGenshinImpact.Core.Script.Dependence;
|
||||
|
||||
public class Dispatcher
|
||||
{
|
||||
private readonly ILogger<Dispatcher> _logger = App.GetLogger<Dispatcher>();
|
||||
|
||||
private object _config = null;
|
||||
|
||||
public Dispatcher(object config)
|
||||
@@ -127,7 +134,7 @@ public class Dispatcher
|
||||
// 如果没有自定义令牌,就使用全局令牌
|
||||
cancellationToken = CancellationContext.Instance.Cts.Token;
|
||||
}
|
||||
|
||||
|
||||
// 根据名称执行任务
|
||||
switch (soloTask.Name)
|
||||
{
|
||||
@@ -162,7 +169,69 @@ public class Dispatcher
|
||||
await new AutoFishingTask(AutoFishingTaskParam.BuildFromSoloTaskConfig(soloTask.Config)).Start(
|
||||
cancellationToken);
|
||||
break;
|
||||
case "AutoEat":
|
||||
string? foodName = soloTask.Config == null ? null : ScriptObjectConverter.GetValue<string?>((ScriptObject)soloTask.Config, "foodName", null);
|
||||
FoodEffectType? foodEffectType = soloTask.Config == null ? null : (FoodEffectType?)ScriptObjectConverter.GetValue<int?>((ScriptObject)soloTask.Config, "foodEffectType", null);
|
||||
|
||||
if (foodName != null && foodEffectType != null)
|
||||
{
|
||||
throw new NotSupportedException("不能同时指定foodName和foodEffectType");
|
||||
}
|
||||
|
||||
if (foodName == null)
|
||||
{
|
||||
if (foodEffectType != null)
|
||||
{
|
||||
PathingPartyConfig? pathingPartyConfig = _config as PathingPartyConfig;
|
||||
if (pathingPartyConfig == null)
|
||||
{
|
||||
throw new NotSupportedException("foodEffectType参数需要调度器配置,请在调度器下使用");
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (foodEffectType)
|
||||
{
|
||||
case FoodEffectType.ATKBoostingDish:
|
||||
foodName = pathingPartyConfig.AutoEatConfig.DefaultAtkBoostingDishName;
|
||||
if (foodName == null)
|
||||
{
|
||||
_logger.LogInformation("缺少{Text}配置,跳过吃Buff", "默认的攻击类料理");
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case FoodEffectType.AdventurersDish:
|
||||
foodName = pathingPartyConfig.AutoEatConfig.DefaultAdventurersDishName;
|
||||
if (foodName == null)
|
||||
{
|
||||
_logger.LogInformation("缺少{Text}配置,跳过吃Buff", "默认的冒险类料理");
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case FoodEffectType.DEFBoostingDish:
|
||||
foodName = pathingPartyConfig.AutoEatConfig.DefaultDefBoostingDishName;
|
||||
if (foodName == null)
|
||||
{
|
||||
_logger.LogInformation("缺少{Text}配置,跳过吃Buff", "默认的防御类料理");
|
||||
return;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new NotSupportedException("JS脚本入参错误:错误的foodEffectType");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var autoEatConfig = TaskContext.Instance().Config.AutoEatConfig;
|
||||
await new AutoEatTask(new AutoEatParam()
|
||||
{
|
||||
CheckInterval = autoEatConfig.CheckInterval,
|
||||
EatInterval = autoEatConfig.EatInterval,
|
||||
ShowNotification = autoEatConfig.ShowNotification,
|
||||
FoodName = foodName
|
||||
}).Start(cancellationToken);
|
||||
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentException($"未知的任务名称: {soloTask.Name}", nameof(soloTask.Name));
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using BetterGenshinImpact.GameTask.Common.BgiVision;
|
||||
using BetterGenshinImpact.GameTask.Common.BgiVision;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Threading;
|
||||
@@ -35,7 +35,6 @@ public class AutoArtifactSalvageTask : ISoloTask
|
||||
{
|
||||
private readonly ILogger logger = App.GetLogger<AutoArtifactSalvageTask>();
|
||||
private readonly InputSimulator input = Simulation.SendInput;
|
||||
private readonly ReturnMainUiTask _returnMainUiTask = new();
|
||||
|
||||
private CancellationToken ct;
|
||||
|
||||
@@ -51,7 +50,7 @@ public class AutoArtifactSalvageTask : ISoloTask
|
||||
|
||||
private readonly int? maxNumToCheck;
|
||||
|
||||
private bool returnToMainUi = true;
|
||||
private readonly bool returnToMainUi = true;
|
||||
|
||||
public AutoArtifactSalvageTask(int star, string? regularExpression = null, int? maxNumToCheck = null)
|
||||
{
|
||||
@@ -75,12 +74,51 @@ public class AutoArtifactSalvageTask : ISoloTask
|
||||
this.returnToMainUi = returnToMainUi;
|
||||
}
|
||||
|
||||
public async Task Start(CancellationToken ct)
|
||||
public static async Task OpenBag(GridScreenName gridScreenName, InputSimulator input, ILogger logger, CancellationToken ct)
|
||||
{
|
||||
this.ct = ct;
|
||||
if (returnToMainUi)
|
||||
RecognitionObject? recognitionObjectChecked;
|
||||
RecognitionObject? recognitionObjectUnchecked;
|
||||
|
||||
switch (gridScreenName)
|
||||
{
|
||||
await _returnMainUiTask.Start(ct);
|
||||
case GridScreenName.Weapons:
|
||||
recognitionObjectChecked = ElementAssets.Instance.BagWeaponChecked;
|
||||
recognitionObjectUnchecked = ElementAssets.Instance.BagWeaponUnchecked;
|
||||
break;
|
||||
case GridScreenName.Artifacts:
|
||||
recognitionObjectChecked = ElementAssets.Instance.BagArtifactChecked;
|
||||
recognitionObjectUnchecked = ElementAssets.Instance.BagArtifactUnchecked;
|
||||
break;
|
||||
case GridScreenName.CharacterDevelopmentItems:
|
||||
recognitionObjectChecked = ElementAssets.Instance.BagCharacterDevelopmentItemChecked;
|
||||
recognitionObjectUnchecked = ElementAssets.Instance.BagCharacterDevelopmentItemUnchecked;
|
||||
break;
|
||||
case GridScreenName.Food:
|
||||
recognitionObjectChecked = ElementAssets.Instance.BagFoodChecked;
|
||||
recognitionObjectUnchecked = ElementAssets.Instance.BagFoodUnchecked;
|
||||
break;
|
||||
case GridScreenName.Materials:
|
||||
recognitionObjectChecked = ElementAssets.Instance.BagMaterialChecked;
|
||||
recognitionObjectUnchecked = ElementAssets.Instance.BagMaterialUnchecked;
|
||||
break;
|
||||
case GridScreenName.Gadget:
|
||||
recognitionObjectChecked = ElementAssets.Instance.BagGadgetChecked;
|
||||
recognitionObjectUnchecked = ElementAssets.Instance.BagGadgetUnchecked;
|
||||
break;
|
||||
case GridScreenName.Quest:
|
||||
recognitionObjectChecked = ElementAssets.Instance.BagQuestChecked;
|
||||
recognitionObjectUnchecked = ElementAssets.Instance.BagQuestUnchecked;
|
||||
break;
|
||||
case GridScreenName.PreciousItems:
|
||||
recognitionObjectChecked = ElementAssets.Instance.BagPreciousItemChecked;
|
||||
recognitionObjectUnchecked = ElementAssets.Instance.BagPreciousItemUnchecked;
|
||||
break;
|
||||
case GridScreenName.Furnishings:
|
||||
recognitionObjectChecked = ElementAssets.Instance.BagFurnishingChecked;
|
||||
recognitionObjectUnchecked = ElementAssets.Instance.BagFurnishingUnchecked;
|
||||
break;
|
||||
default:
|
||||
throw new NotSupportedException($"背包不支持的界面:{gridScreenName.GetDescription()}");
|
||||
}
|
||||
|
||||
// B键打开背包
|
||||
@@ -89,12 +127,11 @@ public class AutoArtifactSalvageTask : ISoloTask
|
||||
|
||||
var openBagSuccess = await NewRetry.WaitForAction(() =>
|
||||
{
|
||||
// 选择圣遗物
|
||||
using var ra = CaptureToRectArea();
|
||||
using var artifactBtn = ra.Find(ElementAssets.Instance.BagArtifactChecked);
|
||||
using var artifactBtn = ra.Find(recognitionObjectChecked);
|
||||
if (artifactBtn.IsEmpty())
|
||||
{
|
||||
using var artifactBtn2 = ra.Find(ElementAssets.Instance.BagArtifactUnchecked);
|
||||
using var artifactBtn2 = ra.Find(recognitionObjectUnchecked);
|
||||
if (artifactBtn2.IsExist())
|
||||
{
|
||||
artifactBtn2.Click();
|
||||
@@ -118,12 +155,23 @@ public class AutoArtifactSalvageTask : ISoloTask
|
||||
|
||||
if (!openBagSuccess)
|
||||
{
|
||||
logger.LogError("未找到背包中圣遗物菜单按钮,打开背包失败");
|
||||
logger.LogError("未找到背包中{name}菜单按钮,打开背包失败", gridScreenName.GetDescription());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
await Delay(800, ct);
|
||||
}
|
||||
|
||||
public async Task Start(CancellationToken ct)
|
||||
{
|
||||
this.ct = ct;
|
||||
if (returnToMainUi)
|
||||
{
|
||||
await new ReturnMainUiTask().Start(ct);
|
||||
}
|
||||
|
||||
await OpenBag(GridScreenName.Artifacts, this.input, this.logger, this.ct);
|
||||
|
||||
// 点击分解按钮打开分解界面
|
||||
using var ra2 = CaptureToRectArea();
|
||||
@@ -217,7 +265,7 @@ public class AutoArtifactSalvageTask : ISoloTask
|
||||
|
||||
if (returnToMainUi)
|
||||
{
|
||||
await _returnMainUiTask.Start(ct);
|
||||
await new ReturnMainUiTask().Start(ct);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,4 +33,28 @@ public partial class AutoEatConfig : ObservableObject
|
||||
/// </summary>
|
||||
[ObservableProperty]
|
||||
private int _eatInterval = 2000;
|
||||
|
||||
/// <summary>
|
||||
/// 测试食物名称
|
||||
/// </summary>
|
||||
[ObservableProperty]
|
||||
private string? _testFoodName;
|
||||
|
||||
/// <summary>
|
||||
/// 默认的攻击类料理名称
|
||||
/// </summary>
|
||||
[ObservableProperty]
|
||||
private string? _defaultAtkBoostingDishName;
|
||||
|
||||
/// <summary>
|
||||
/// 默认的冒险类料理名称
|
||||
/// </summary>
|
||||
[ObservableProperty]
|
||||
private string? _defaultAdventurersDishName;
|
||||
|
||||
/// <summary>
|
||||
/// 默认的防御类料理名称
|
||||
/// </summary>
|
||||
[ObservableProperty]
|
||||
private string? _defaultDefBoostingDishName;
|
||||
}
|
||||
@@ -22,16 +22,9 @@ public class AutoEatParam : BaseTaskParam
|
||||
/// </summary>
|
||||
public int EatInterval { get; set; }
|
||||
|
||||
public AutoEatParam()
|
||||
{
|
||||
SetDefault();
|
||||
}
|
||||
|
||||
public void SetDefault()
|
||||
{
|
||||
var config = TaskContext.Instance().Config.AutoEatConfig;
|
||||
ShowNotification = config.ShowNotification;
|
||||
CheckInterval = config.CheckInterval;
|
||||
EatInterval = config.EatInterval;
|
||||
}
|
||||
/// <summary>
|
||||
/// 食物名称
|
||||
/// 如果传空就使用便携营养袋,否则进入背包查找对应食物并使用
|
||||
/// </summary>
|
||||
public string? FoodName { get; set; }
|
||||
}
|
||||
@@ -1,13 +1,19 @@
|
||||
using BetterGenshinImpact.Core.Recognition.OCR;
|
||||
using BetterGenshinImpact.Core.Simulator;
|
||||
using BetterGenshinImpact.Core.Simulator.Extensions;
|
||||
using BetterGenshinImpact.GameTask.AutoArtifactSalvage;
|
||||
using BetterGenshinImpact.GameTask.Common.BgiVision;
|
||||
using BetterGenshinImpact.GameTask.Common.Element.Assets;
|
||||
using BetterGenshinImpact.GameTask.Common.Job;
|
||||
using BetterGenshinImpact.GameTask.GetGridIcons;
|
||||
using BetterGenshinImpact.GameTask.Model;
|
||||
using BetterGenshinImpact.Service.Notification;
|
||||
using BetterGenshinImpact.Service.Notification.Model.Enum;
|
||||
using BetterGenshinImpact.GameTask.Model.Area;
|
||||
using BetterGenshinImpact.GameTask.Model.GameUI;
|
||||
using Fischless.WindowsInput;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.ML.OnnxRuntime;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using static BetterGenshinImpact.GameTask.Common.TaskControl;
|
||||
@@ -24,6 +30,8 @@ public class AutoEatTask : BaseIndependentTask, ISoloTask
|
||||
|
||||
private readonly AutoEatParam _taskParam;
|
||||
private readonly AutoEatConfig _config;
|
||||
private readonly ILogger _logger = App.GetLogger<AutoEatTask>();
|
||||
private readonly InputSimulator _input = Simulation.SendInput;
|
||||
private CancellationToken _ct;
|
||||
|
||||
public AutoEatTask(AutoEatParam taskParam)
|
||||
@@ -37,33 +45,75 @@ public class AutoEatTask : BaseIndependentTask, ISoloTask
|
||||
_ct = ct;
|
||||
|
||||
Init();
|
||||
Logger.LogInformation("自动吃药任务启动");
|
||||
_logger.LogInformation("自动吃药任务启动");
|
||||
|
||||
if (!IsTakeFood())
|
||||
if (String.IsNullOrWhiteSpace(_taskParam.FoodName))
|
||||
{
|
||||
Logger.LogWarning("未装备 \"{Tool}\",无法启用自动吃药功能", "便携营养袋");
|
||||
return;
|
||||
}
|
||||
if (!IsTakeFood())
|
||||
{
|
||||
_logger.LogWarning("未装备 \"{Tool}\",无法启用自动吃药功能", "便携营养袋");
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
await AutoEatLoop();
|
||||
try
|
||||
{
|
||||
await AutoEatLoop();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger.LogError(e, "自动吃药任务发生异常");
|
||||
throw;
|
||||
}
|
||||
finally
|
||||
{
|
||||
_logger.LogInformation("自动吃药任务结束");
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
else
|
||||
{
|
||||
Logger.LogError(e, "自动吃药任务发生异常");
|
||||
throw;
|
||||
}
|
||||
finally
|
||||
{
|
||||
Logger.LogInformation("自动吃药任务结束");
|
||||
_logger.LogInformation("打开背包寻找{name}……", _taskParam.FoodName);
|
||||
await new ReturnMainUiTask().Start(ct);
|
||||
await AutoArtifactSalvageTask.OpenBag(GridScreenName.Food, _input, _logger, _ct);
|
||||
|
||||
using InferenceSession session = GridIconsAccuracyTestTask.LoadModel(out Dictionary<string, float[]> prototypes);
|
||||
|
||||
using var ra0 = CaptureToRectArea();
|
||||
GridScreenParams gridParams = GridScreenParams.Templates[GridScreenName.Food];
|
||||
var gridRoi = gridParams.GetRect(ra0);
|
||||
GridScreen gridScreen = new GridScreen(gridRoi, gridParams, _logger, _ct);
|
||||
bool isAte = false;
|
||||
await foreach (ImageRegion itemRegion in gridScreen)
|
||||
{
|
||||
var result = GridIconsAccuracyTestTask.Infer(itemRegion.SrcMat, session, prototypes);
|
||||
string predName = result.Item1;
|
||||
if (predName == _taskParam.FoodName)
|
||||
{
|
||||
// 点击item
|
||||
itemRegion.Click();
|
||||
await Delay(300, ct);
|
||||
// 点击确定
|
||||
using var ra = ra0.Find(ElementAssets.Instance.BtnWhiteConfirm);
|
||||
if (ra.IsExist())
|
||||
{
|
||||
ra.Click();
|
||||
}
|
||||
_logger.LogInformation("吃了一份{name},真香!", predName);
|
||||
isAte = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!isAte)
|
||||
{
|
||||
_logger.LogInformation("没有找到{name}", _taskParam.FoodName);
|
||||
}
|
||||
await new ReturnMainUiTask().Start(ct);
|
||||
}
|
||||
}
|
||||
|
||||
private void Init()
|
||||
{
|
||||
Logger.LogInformation("→ {Text} 检测间隔: {Interval}ms", "自动吃药,", _config.CheckInterval);
|
||||
Logger.LogInformation("→ {Text} 吃药间隔: {Interval}ms", "自动吃药,", _config.EatInterval);
|
||||
_logger.LogInformation("→ {Text} 检测间隔: {Interval}ms", "自动吃药,", _config.CheckInterval);
|
||||
_logger.LogInformation("→ {Text} 吃药间隔: {Interval}ms", "自动吃药,", _config.EatInterval);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -87,8 +137,8 @@ public class AutoEatTask : BaseIndependentTask, ISoloTask
|
||||
// 模拟按键 "Z" 使用便携营养袋
|
||||
Simulation.SendInput.SimulateAction(GIActions.QuickUseGadget);
|
||||
lastEatTime = now;
|
||||
|
||||
Logger.LogInformation("检测到红血,自动吃药");
|
||||
|
||||
_logger.LogInformation("检测到红血,自动吃药");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,7 +151,7 @@ public class AutoEatTask : BaseIndependentTask, ISoloTask
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.LogDebug(e, "自动吃药检测时发生异常");
|
||||
_logger.LogDebug(e, "自动吃药检测时发生异常");
|
||||
await Delay(1000, _ct); // 异常时稍作等待
|
||||
}
|
||||
}
|
||||
@@ -124,7 +174,7 @@ public class AutoEatTask : BaseIndependentTask, ISoloTask
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.LogDebug(e, "检测便携营养袋时发生异常");
|
||||
_logger.LogDebug(e, "检测便携营养袋时发生异常");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
23
BetterGenshinImpact/GameTask/AutoEat/FoodEffectType.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Text;
|
||||
|
||||
namespace BetterGenshinImpact.GameTask.AutoEat
|
||||
{
|
||||
public enum FoodEffectType
|
||||
{
|
||||
[Description("恢复类料理")]
|
||||
RecoveryDish,
|
||||
[Description("攻击类料理")]
|
||||
ATKBoostingDish,
|
||||
[Description("冒险类料理")]
|
||||
AdventurersDish,
|
||||
[Description("防御类料理")]
|
||||
DEFBoostingDish,
|
||||
[Description("药剂")]
|
||||
Potion,
|
||||
[Description("其他")]
|
||||
Other
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.6 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 2.0 KiB |
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using BetterGenshinImpact.Core.Recognition;
|
||||
using BetterGenshinImpact.GameTask.Model;
|
||||
using BetterGenshinImpact.Helpers.Extensions;
|
||||
@@ -35,8 +35,24 @@ public class ElementAssets : BaseAssets<ElementAssets>
|
||||
public RecognitionObject Keyreduce;
|
||||
public RecognitionObject Keyincrease;
|
||||
|
||||
public RecognitionObject BagWeaponUnchecked;
|
||||
public RecognitionObject BagWeaponChecked;
|
||||
public RecognitionObject BagArtifactUnchecked;
|
||||
public RecognitionObject BagArtifactChecked;
|
||||
public RecognitionObject BagCharacterDevelopmentItemUnchecked;
|
||||
public RecognitionObject BagCharacterDevelopmentItemChecked;
|
||||
public RecognitionObject BagFoodUnchecked;
|
||||
public RecognitionObject BagFoodChecked;
|
||||
public RecognitionObject BagMaterialUnchecked;
|
||||
public RecognitionObject BagMaterialChecked;
|
||||
public RecognitionObject BagGadgetUnchecked;
|
||||
public RecognitionObject BagGadgetChecked;
|
||||
public RecognitionObject BagQuestUnchecked;
|
||||
public RecognitionObject BagQuestChecked;
|
||||
public RecognitionObject BagPreciousItemUnchecked;
|
||||
public RecognitionObject BagPreciousItemChecked;
|
||||
public RecognitionObject BagFurnishingUnchecked;
|
||||
public RecognitionObject BagFurnishingChecked;
|
||||
public RecognitionObject BtnArtifactSalvage;
|
||||
public RecognitionObject BtnArtifactSalvageConfirm;
|
||||
|
||||
@@ -245,7 +261,26 @@ public class ElementAssets : BaseAssets<ElementAssets>
|
||||
DrawOnWindow = false
|
||||
}.InitTemplate();
|
||||
|
||||
// 分解圣遗物
|
||||
// 背包武器
|
||||
BagWeaponUnchecked = new RecognitionObject
|
||||
{
|
||||
Name = "BagWeaponUnchecked",
|
||||
RecognitionType = RecognitionTypes.TemplateMatch,
|
||||
TemplateImageMat = GameTaskManager.LoadAssetImage(@"Common\Element", "bag_weapon_unchecked.png"),
|
||||
RegionOfInterest = CaptureRect.CutTop(0.1),
|
||||
Threshold = 0.87,
|
||||
DrawOnWindow = false
|
||||
}.InitTemplate();
|
||||
BagWeaponChecked = new RecognitionObject
|
||||
{
|
||||
Name = "BagWeaponChecked",
|
||||
RecognitionType = RecognitionTypes.TemplateMatch,
|
||||
TemplateImageMat = GameTaskManager.LoadAssetImage(@"Common\Element", "bag_weapon_checked.png"),
|
||||
RegionOfInterest = CaptureRect.CutTop(0.1),
|
||||
Threshold = 0.8,
|
||||
DrawOnWindow = false
|
||||
}.InitTemplate();
|
||||
// 背包圣遗物
|
||||
BagArtifactUnchecked = new RecognitionObject
|
||||
{
|
||||
Name = "BagArtifactUnchecked",
|
||||
@@ -264,6 +299,141 @@ public class ElementAssets : BaseAssets<ElementAssets>
|
||||
Threshold = 0.8,
|
||||
DrawOnWindow = false
|
||||
}.InitTemplate();
|
||||
// 背包养成道具
|
||||
BagCharacterDevelopmentItemUnchecked = new RecognitionObject
|
||||
{
|
||||
Name = "BagCharacterDevelopmentItemUnchecked",
|
||||
RecognitionType = RecognitionTypes.TemplateMatch,
|
||||
TemplateImageMat = GameTaskManager.LoadAssetImage(@"Common\Element", "bag_characterdevelopmentitem_unchecked.png"),
|
||||
RegionOfInterest = CaptureRect.CutTop(0.1),
|
||||
Threshold = 0.87,
|
||||
DrawOnWindow = false
|
||||
}.InitTemplate();
|
||||
BagCharacterDevelopmentItemChecked = new RecognitionObject
|
||||
{
|
||||
Name = "BagCharacterDevelopmentItemChecked",
|
||||
RecognitionType = RecognitionTypes.TemplateMatch,
|
||||
TemplateImageMat = GameTaskManager.LoadAssetImage(@"Common\Element", "bag_characterdevelopmentitem_checked.png"),
|
||||
RegionOfInterest = CaptureRect.CutTop(0.1),
|
||||
Threshold = 0.8,
|
||||
DrawOnWindow = false
|
||||
}.InitTemplate();
|
||||
// 背包食物
|
||||
BagFoodUnchecked = new RecognitionObject
|
||||
{
|
||||
Name = "BagFoodUnchecked",
|
||||
RecognitionType = RecognitionTypes.TemplateMatch,
|
||||
TemplateImageMat = GameTaskManager.LoadAssetImage(@"Common\Element", "bag_food_unchecked.png"),
|
||||
RegionOfInterest = CaptureRect.CutTop(0.1),
|
||||
Threshold = 0.87,
|
||||
DrawOnWindow = false
|
||||
}.InitTemplate();
|
||||
BagFoodChecked = new RecognitionObject
|
||||
{
|
||||
Name = "BagFoodChecked",
|
||||
RecognitionType = RecognitionTypes.TemplateMatch,
|
||||
TemplateImageMat = GameTaskManager.LoadAssetImage(@"Common\Element", "bag_food_checked.png"),
|
||||
RegionOfInterest = CaptureRect.CutTop(0.1),
|
||||
Threshold = 0.8,
|
||||
DrawOnWindow = false
|
||||
}.InitTemplate();
|
||||
// 背包材料
|
||||
BagMaterialUnchecked = new RecognitionObject
|
||||
{
|
||||
Name = "BagMaterialUnchecked",
|
||||
RecognitionType = RecognitionTypes.TemplateMatch,
|
||||
TemplateImageMat = GameTaskManager.LoadAssetImage(@"Common\Element", "bag_material_unchecked.png"),
|
||||
RegionOfInterest = CaptureRect.CutTop(0.1),
|
||||
Threshold = 0.87,
|
||||
DrawOnWindow = false
|
||||
}.InitTemplate();
|
||||
BagMaterialChecked = new RecognitionObject
|
||||
{
|
||||
Name = "BagMaterialChecked",
|
||||
RecognitionType = RecognitionTypes.TemplateMatch,
|
||||
TemplateImageMat = GameTaskManager.LoadAssetImage(@"Common\Element", "bag_material_checked.png"),
|
||||
RegionOfInterest = CaptureRect.CutTop(0.1),
|
||||
Threshold = 0.8,
|
||||
DrawOnWindow = false
|
||||
}.InitTemplate();
|
||||
// 背包小道具
|
||||
BagGadgetUnchecked = new RecognitionObject
|
||||
{
|
||||
Name = "BagGadgetUnchecked",
|
||||
RecognitionType = RecognitionTypes.TemplateMatch,
|
||||
TemplateImageMat = GameTaskManager.LoadAssetImage(@"Common\Element", "bag_gadget_unchecked.png"),
|
||||
RegionOfInterest = CaptureRect.CutTop(0.1),
|
||||
Threshold = 0.87,
|
||||
DrawOnWindow = false
|
||||
}.InitTemplate();
|
||||
BagGadgetChecked = new RecognitionObject
|
||||
{
|
||||
Name = "BagGadgetChecked",
|
||||
RecognitionType = RecognitionTypes.TemplateMatch,
|
||||
TemplateImageMat = GameTaskManager.LoadAssetImage(@"Common\Element", "bag_gadget_checked.png"),
|
||||
RegionOfInterest = CaptureRect.CutTop(0.1),
|
||||
Threshold = 0.8,
|
||||
DrawOnWindow = false
|
||||
}.InitTemplate();
|
||||
// 背包任务
|
||||
BagQuestUnchecked = new RecognitionObject
|
||||
{
|
||||
Name = "BagQuestUnchecked",
|
||||
RecognitionType = RecognitionTypes.TemplateMatch,
|
||||
TemplateImageMat = GameTaskManager.LoadAssetImage(@"Common\Element", "bag_quest_unchecked.png"),
|
||||
RegionOfInterest = CaptureRect.CutTop(0.1),
|
||||
Threshold = 0.87,
|
||||
DrawOnWindow = false
|
||||
}.InitTemplate();
|
||||
BagQuestChecked = new RecognitionObject
|
||||
{
|
||||
Name = "BagQuestChecked",
|
||||
RecognitionType = RecognitionTypes.TemplateMatch,
|
||||
TemplateImageMat = GameTaskManager.LoadAssetImage(@"Common\Element", "bag_quest_checked.png"),
|
||||
RegionOfInterest = CaptureRect.CutTop(0.1),
|
||||
Threshold = 0.8,
|
||||
DrawOnWindow = false
|
||||
}.InitTemplate();
|
||||
// 背包贵重道具
|
||||
BagPreciousItemUnchecked = new RecognitionObject
|
||||
{
|
||||
Name = "BagPreciousItemUnchecked",
|
||||
RecognitionType = RecognitionTypes.TemplateMatch,
|
||||
TemplateImageMat = GameTaskManager.LoadAssetImage(@"Common\Element", "bag_preciousitem_unchecked.png"),
|
||||
RegionOfInterest = CaptureRect.CutTop(0.1),
|
||||
Threshold = 0.87,
|
||||
DrawOnWindow = false
|
||||
}.InitTemplate();
|
||||
BagPreciousItemChecked = new RecognitionObject
|
||||
{
|
||||
Name = "BagPreciousItemChecked",
|
||||
RecognitionType = RecognitionTypes.TemplateMatch,
|
||||
TemplateImageMat = GameTaskManager.LoadAssetImage(@"Common\Element", "bag_preciousitem_checked.png"),
|
||||
RegionOfInterest = CaptureRect.CutTop(0.1),
|
||||
Threshold = 0.8,
|
||||
DrawOnWindow = false
|
||||
}.InitTemplate();
|
||||
// 背包摆设
|
||||
BagFurnishingUnchecked = new RecognitionObject
|
||||
{
|
||||
Name = "BagFurnishingUnchecked",
|
||||
RecognitionType = RecognitionTypes.TemplateMatch,
|
||||
TemplateImageMat = GameTaskManager.LoadAssetImage(@"Common\Element", "bag_furnishing_unchecked.png"),
|
||||
RegionOfInterest = CaptureRect.CutTop(0.1),
|
||||
Threshold = 0.87,
|
||||
DrawOnWindow = false
|
||||
}.InitTemplate();
|
||||
BagFurnishingChecked = new RecognitionObject
|
||||
{
|
||||
Name = "BagFurnishingChecked",
|
||||
RecognitionType = RecognitionTypes.TemplateMatch,
|
||||
TemplateImageMat = GameTaskManager.LoadAssetImage(@"Common\Element", "bag_furnishing_checked.png"),
|
||||
RegionOfInterest = CaptureRect.CutTop(0.1),
|
||||
Threshold = 0.8,
|
||||
DrawOnWindow = false
|
||||
}.InitTemplate();
|
||||
|
||||
// 分解圣遗物
|
||||
BtnArtifactSalvage = new RecognitionObject
|
||||
{
|
||||
Name = "BtnArtifactSalvage",
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using BetterGenshinImpact.GameTask.Model.GameUI;
|
||||
using BetterGenshinImpact.GameTask.Model.GameUI;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using System;
|
||||
|
||||
@@ -8,8 +8,7 @@ namespace BetterGenshinImpact.GameTask.GetGridIcons;
|
||||
public partial class GetGridIconsConfig : ObservableObject
|
||||
{
|
||||
/// <summary>
|
||||
/// 昼夜策略
|
||||
/// 钓全天的鱼、还是只钓白天或夜晚的鱼
|
||||
/// Grid界面名称
|
||||
/// </summary>
|
||||
[ObservableProperty]
|
||||
private GridScreenName _gridName = GridScreenName.Weapons;
|
||||
|
||||
@@ -1,17 +1,21 @@
|
||||
using BetterGenshinImpact.Core.Recognition.OCR;
|
||||
using BetterGenshinImpact.Core.Simulator;
|
||||
using BetterGenshinImpact.GameTask.AutoArtifactSalvage;
|
||||
using BetterGenshinImpact.GameTask.Common.Job;
|
||||
using BetterGenshinImpact.GameTask.Model.Area;
|
||||
using BetterGenshinImpact.GameTask.Model.GameUI;
|
||||
using BetterGenshinImpact.Helpers.Extensions;
|
||||
using Fischless.WindowsInput;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using OpenCvSharp;
|
||||
using OpenCvSharp.Extensions;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using static BetterGenshinImpact.GameTask.Common.TaskControl;
|
||||
using Microsoft.Extensions.Localization;
|
||||
using BetterGenshinImpact.GameTask.Model.Area;
|
||||
using System.Collections.Generic;
|
||||
using OpenCvSharp;
|
||||
using System.Linq;
|
||||
using BetterGenshinImpact.Core.Recognition.OCR;
|
||||
using System.IO;
|
||||
using OpenCvSharp.Extensions;
|
||||
using BetterGenshinImpact.GameTask.Model.GameUI;
|
||||
|
||||
namespace BetterGenshinImpact.GameTask.GetGridIcons;
|
||||
|
||||
@@ -21,6 +25,7 @@ namespace BetterGenshinImpact.GameTask.GetGridIcons;
|
||||
public class GetGridIconsTask : ISoloTask
|
||||
{
|
||||
private readonly ILogger logger = App.GetLogger<GetGridIconsTask>();
|
||||
private readonly InputSimulator input = Simulation.SendInput;
|
||||
|
||||
private CancellationToken ct;
|
||||
|
||||
@@ -37,13 +42,31 @@ public class GetGridIconsTask : ISoloTask
|
||||
this.gridScreenName = gridScreenName;
|
||||
this.starAsSuffix = starAsSuffix;
|
||||
this.maxNumToGet = maxNumToGet;
|
||||
IStringLocalizer<GetGridIconsTask> stringLocalizer = App.GetService<IStringLocalizer<GetGridIconsTask>>() ?? throw new NullReferenceException();
|
||||
}
|
||||
|
||||
public async Task Start(CancellationToken ct)
|
||||
{
|
||||
this.ct = ct;
|
||||
|
||||
switch (this.gridScreenName)
|
||||
{
|
||||
case GridScreenName.Weapons:
|
||||
case GridScreenName.Artifacts:
|
||||
case GridScreenName.CharacterDevelopmentItems:
|
||||
case GridScreenName.Food:
|
||||
case GridScreenName.Materials:
|
||||
case GridScreenName.Gadget:
|
||||
case GridScreenName.Quest:
|
||||
case GridScreenName.PreciousItems:
|
||||
case GridScreenName.Furnishings:
|
||||
await new ReturnMainUiTask().Start(ct);
|
||||
await AutoArtifactSalvageTask.OpenBag(this.gridScreenName, this.input, this.logger, this.ct);
|
||||
break;
|
||||
default:
|
||||
logger.LogInformation("{name}暂不支持自动打开,请提前手动打开界面", gridScreenName.GetDescription());
|
||||
break;
|
||||
}
|
||||
|
||||
using var ra0 = CaptureToRectArea();
|
||||
GridScreenParams gridParams = GridScreenParams.Templates[this.gridScreenName];
|
||||
Rect gridRoi = gridParams.GetRect(ra0);
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
using BetterGenshinImpact.Core.Recognition.OCR;
|
||||
using BetterGenshinImpact.Core.Simulator;
|
||||
using BetterGenshinImpact.GameTask.AutoArtifactSalvage;
|
||||
using BetterGenshinImpact.GameTask.Common.Job;
|
||||
using BetterGenshinImpact.GameTask.Model.Area;
|
||||
using BetterGenshinImpact.GameTask.Model.GameUI;
|
||||
using BetterGenshinImpact.Helpers.Extensions;
|
||||
using Fischless.WindowsInput;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.ML.OnnxRuntime;
|
||||
using Microsoft.ML.OnnxRuntime.Tensors;
|
||||
@@ -21,6 +26,7 @@ namespace BetterGenshinImpact.GameTask.GetGridIcons;
|
||||
public class GridIconsAccuracyTestTask : ISoloTask
|
||||
{
|
||||
private readonly ILogger logger = App.GetLogger<GetGridIconsTask>();
|
||||
private readonly InputSimulator input = Simulation.SendInput;
|
||||
|
||||
private CancellationToken ct;
|
||||
|
||||
@@ -36,25 +42,28 @@ public class GridIconsAccuracyTestTask : ISoloTask
|
||||
this.maxNumToTest = maxNumToTest;
|
||||
}
|
||||
|
||||
public async Task Start(CancellationToken ct)
|
||||
/// <summary>
|
||||
/// 加载图标识别模型
|
||||
/// </summary>
|
||||
/// <param name="prototypes">原型向量</param>
|
||||
/// <returns>推理会话</returns>
|
||||
/// <exception cref="Exception"></exception>
|
||||
public static InferenceSession LoadModel(out Dictionary<string, float[]> prototypes)
|
||||
{
|
||||
this.ct = ct;
|
||||
|
||||
#region 加载model
|
||||
using var session = new InferenceSession(@".\GameTask\GetGridIcons\gridIcon.onnx"); // todo 所有数据炼好后放到onnx统一存放的位置去
|
||||
var session = new InferenceSession(@".\GameTask\GetGridIcons\gridIcon.onnx"); // todo 所有数据炼好后放到onnx统一存放的位置去
|
||||
|
||||
var metadata = session.ModelMetadata;
|
||||
|
||||
if (!metadata.CustomMetadataMap.TryGetValue("prefix_list", out string? prefixListJson))
|
||||
{
|
||||
logger.LogError("模型文件缺少prefix_list");
|
||||
return;
|
||||
throw new Exception("模型文件缺少prefix_list");
|
||||
}
|
||||
List<string> prefixList = System.Text.Json.JsonSerializer.Deserialize<List<string>>(prefixListJson) ?? throw new Exception(); // 不预测前缀
|
||||
#endregion
|
||||
#region 加载原型向量
|
||||
var allLines = File.ReadLines(@".\GameTask\GetGridIcons\训练集原型特征.csv").Skip(1); // 跳过首行列名
|
||||
Dictionary<string, float[]> prototypes = new Dictionary<string, float[]>();
|
||||
prototypes = new Dictionary<string, float[]>();
|
||||
foreach (string line in allLines)
|
||||
{
|
||||
var columns = line.Split(",").ToArray();
|
||||
@@ -65,6 +74,33 @@ public class GridIconsAccuracyTestTask : ISoloTask
|
||||
prototypes.Add(columns[0], flatData);
|
||||
}
|
||||
#endregion
|
||||
return session;
|
||||
}
|
||||
|
||||
public async Task Start(CancellationToken ct)
|
||||
{
|
||||
this.ct = ct;
|
||||
|
||||
switch (this.gridScreenName)
|
||||
{
|
||||
case GridScreenName.Weapons:
|
||||
case GridScreenName.Artifacts:
|
||||
case GridScreenName.CharacterDevelopmentItems:
|
||||
case GridScreenName.Food:
|
||||
case GridScreenName.Materials:
|
||||
case GridScreenName.Gadget:
|
||||
case GridScreenName.Quest:
|
||||
case GridScreenName.PreciousItems:
|
||||
case GridScreenName.Furnishings:
|
||||
await new ReturnMainUiTask().Start(ct);
|
||||
await AutoArtifactSalvageTask.OpenBag(this.gridScreenName, this.input, this.logger, this.ct);
|
||||
break;
|
||||
default:
|
||||
logger.LogInformation("{name}暂不支持自动打开,请提前手动打开界面", gridScreenName.GetDescription());
|
||||
break;
|
||||
}
|
||||
|
||||
using InferenceSession session = LoadModel(out Dictionary<string, float[]> prototypes);
|
||||
|
||||
using var ra0 = CaptureToRectArea();
|
||||
GridScreenParams gridParams = GridScreenParams.Templates[this.gridScreenName];
|
||||
@@ -89,6 +125,8 @@ public class GridIconsAccuracyTestTask : ISoloTask
|
||||
|
||||
await Task.WhenAll(task1, task2);
|
||||
(string, int) result = task2.Result;
|
||||
string predName = result.Item1;
|
||||
int predStarNum = result.Item2;
|
||||
|
||||
// 用CV方法得到的结果
|
||||
using var ra1 = CaptureToRectArea();
|
||||
@@ -101,14 +139,14 @@ public class GridIconsAccuracyTestTask : ISoloTask
|
||||
|
||||
// 统计结果
|
||||
total_count++;
|
||||
if (itemName.Contains(result.Item1) && result.Item2 == itemStarNum)
|
||||
if (itemName.Contains(predName) && predStarNum == itemStarNum)
|
||||
{
|
||||
total_acc++;
|
||||
logger.LogInformation($"{result.Item1}|{result.Item2}星,✔,正确率{total_acc / total_count:0.00}");
|
||||
logger.LogInformation($"{predName}|{predStarNum}星,✔,正确率{total_acc / total_count:0.00}");
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.LogInformation($"{result.Item1}|{result.Item2}星,应为:{itemName}|{itemStarNum}星,❌,正确率{total_acc / total_count:0.00}");
|
||||
logger.LogInformation($"{predName}|{predStarNum}星,应为:{itemName}|{itemStarNum}星,❌,正确率{total_acc / total_count:0.00}");
|
||||
}
|
||||
|
||||
count--;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Microsoft.ClearScript;
|
||||
using Microsoft.ClearScript;
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
@@ -45,7 +45,7 @@ public class ScriptObjectConverter
|
||||
if (source[propertyName] is not Undefined && source[propertyName] != null)
|
||||
{
|
||||
object value = source.GetProperty(propertyName);
|
||||
return (T)Convert.ChangeType(value, typeof(T));
|
||||
return (T)value;
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
@@ -782,7 +782,8 @@
|
||||
ItemsSource=' 1234'
|
||||
SelectedIndex="{Binding Config.AutoFightConfig.GuardianAvatar, Mode=TwoWay}"
|
||||
SelectedItem="{Binding Config.AutoFightConfig.GuardianAvatar, Mode=TwoWay}" />
|
||||
|
||||
<!--todo ItemsSource=' 1234'导致XAML设计器无法加载-->
|
||||
|
||||
<ui:TextBlock Grid.Row="0"
|
||||
Grid.Column="2"
|
||||
Margin="0,0,8,0"
|
||||
@@ -2395,7 +2396,7 @@
|
||||
<ui:CardExpander Margin="0,0,0,12" ContentPadding="0"
|
||||
Visibility="{Binding Config.CommonConfig.ScreenshotEnabled, Converter={StaticResource BooleanToVisibilityConverter}}">
|
||||
<ui:CardExpander.Icon>
|
||||
<ui:FontIcon Glyph="" Style="{StaticResource FaFontIconStyle}" />
|
||||
<ui:FontIcon Glyph="🔧" Style="{StaticResource FaFontIconStyle}" />
|
||||
</ui:CardExpander.Icon>
|
||||
<ui:CardExpander.Header>
|
||||
<Grid>
|
||||
@@ -2580,7 +2581,7 @@
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
</ui:CardExpander>
|
||||
|
||||
|
||||
<!--<ui:CardExpander Margin="0,0,0,12" ContentPadding="0" Icon="{ui:SymbolIcon Accessibility24}">
|
||||
<ui:CardExpander.Header>
|
||||
<Grid>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<UserControl x:Class="BetterGenshinImpact.View.Pages.View.ScriptGroupConfigView"
|
||||
<UserControl x:Class="BetterGenshinImpact.View.Pages.View.ScriptGroupConfigView"
|
||||
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"
|
||||
@@ -8,20 +8,20 @@
|
||||
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
|
||||
Width="800"
|
||||
d:DataContext="{d:DesignInstance Type=pages:ScriptGroupConfigViewModel}"
|
||||
d:DesignHeight="850"
|
||||
d:DesignHeight="1600"
|
||||
d:DesignWidth="800"
|
||||
ui:Design.Background="{DynamicResource ApplicationBackgroundBrush}"
|
||||
ui:Design.Foreground="{DynamicResource TextFillColorPrimaryBrush}"
|
||||
mc:Ignorable="d">
|
||||
<ScrollViewer Height="800"
|
||||
d:DesignHeight="1600"
|
||||
HorizontalScrollBarVisibility="Auto"
|
||||
VerticalScrollBarVisibility="Auto">
|
||||
<StackPanel Width="700" Margin="42,16,42,12">
|
||||
<StackPanel Height="Auto" Width="700" Margin="42,16,42,12">
|
||||
|
||||
<ui:CardExpander Margin="0,0,0,12"
|
||||
ContentPadding="0"
|
||||
Icon="{ui:SymbolIcon Map24}"
|
||||
IsExpanded="True">
|
||||
Icon="{ui:SymbolIcon Map24}">
|
||||
<ui:CardExpander.Header>
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
@@ -743,8 +743,7 @@
|
||||
</StackPanel>
|
||||
</ui:CardExpander>
|
||||
<ui:CardExpander Margin="0,0,0,12"
|
||||
ContentPadding="0"
|
||||
IsExpanded="True">
|
||||
ContentPadding="0">
|
||||
<ui:CardExpander.Icon>
|
||||
<ui:FontIcon Glyph="" Style="{StaticResource FaFontIconStyle}" />
|
||||
</ui:CardExpander.Icon>
|
||||
@@ -1130,8 +1129,9 @@
|
||||
ItemsSource=' 1234'
|
||||
SelectedIndex="{Binding PathingConfig.AutoFightConfig.GuardianAvatar, Mode=TwoWay}"
|
||||
SelectedItem="{Binding PathingConfig.AutoFightConfig.GuardianAvatar, Mode=TwoWay}" />
|
||||
|
||||
<ui:TextBlock Grid.Row="0"
|
||||
<!--todo ItemsSource=' 1234'导致XAML设计器无法加载-->
|
||||
|
||||
<ui:TextBlock Grid.Row="0"
|
||||
Grid.Column="2"
|
||||
Margin="0,0,8,0"
|
||||
HorizontalAlignment="Right"
|
||||
@@ -1427,10 +1427,127 @@
|
||||
</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}"
|
||||
TextWrapping="Wrap">
|
||||
供JS脚本调用Buff类食物配置;食物名称会忽略“美味的”等前缀,请填不带前缀的名称
|
||||
</ui:TextBlock>
|
||||
</Grid>
|
||||
</ui:CardExpander.Header>
|
||||
<StackPanel>
|
||||
<Grid Margin="16">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="3*" />
|
||||
<ColumnDefinition Width="2*" />
|
||||
</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">
|
||||
入参"foodEffectType":1时使用
|
||||
</ui:TextBlock>
|
||||
<ui:TextBox Grid.Row="0"
|
||||
Grid.RowSpan="2"
|
||||
Grid.Column="1"
|
||||
MinWidth="180"
|
||||
MaxWidth="800"
|
||||
Margin="0,0,36,0"
|
||||
Text="{Binding PathingConfig.AutoEatConfig.DefaultAtkBoostingDishName, Mode=TwoWay}"
|
||||
TextWrapping="Wrap" Cursor="IBeam" />
|
||||
</Grid>
|
||||
<Grid Margin="16">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="3*" />
|
||||
<ColumnDefinition Width="2*" />
|
||||
</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">
|
||||
入参"foodEffectType":2时使用
|
||||
</ui:TextBlock>
|
||||
<ui:TextBox Grid.Row="0"
|
||||
Grid.RowSpan="2"
|
||||
Grid.Column="1"
|
||||
MinWidth="180"
|
||||
MaxWidth="800"
|
||||
Margin="0,0,36,0"
|
||||
Text="{Binding PathingConfig.AutoEatConfig.DefaultAdventurersDishName, Mode=TwoWay}"
|
||||
TextWrapping="Wrap" Cursor="IBeam" />
|
||||
</Grid>
|
||||
<Grid Margin="16">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="3*" />
|
||||
<ColumnDefinition Width="2*" />
|
||||
</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">
|
||||
入参"foodEffectType":3时使用
|
||||
</ui:TextBlock>
|
||||
<ui:TextBox Grid.Row="0"
|
||||
Grid.RowSpan="2"
|
||||
Grid.Column="1"
|
||||
MinWidth="180"
|
||||
MaxWidth="800"
|
||||
Margin="0,0,36,0"
|
||||
Text="{Binding PathingConfig.AutoEatConfig.DefaultDefBoostingDishName, Mode=TwoWay}"
|
||||
TextWrapping="Wrap" Cursor="IBeam" />
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
</ui:CardExpander>
|
||||
<ui:CardExpander Margin="0,0,0,12"
|
||||
ContentPadding="0"
|
||||
Icon="{ui:SymbolIcon FlashSettings24}"
|
||||
IsExpanded="True">
|
||||
Icon="{ui:SymbolIcon FlashSettings24}">
|
||||
<ui:CardExpander.Header>
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
|
||||
@@ -123,7 +123,7 @@ public partial class TaskSettingsPageViewModel : ViewModel
|
||||
private List<string> _domainNameList;
|
||||
|
||||
public static List<string> ArtifactSalvageStarList = ["4", "3", "2", "1"];
|
||||
|
||||
|
||||
public static List<int> BossNumList = [1, 2, 3];
|
||||
|
||||
|
||||
@@ -225,6 +225,12 @@ public partial class TaskSettingsPageViewModel : ViewModel
|
||||
SwitchAutoDomainEnabled = false;
|
||||
SwitchAutoFightEnabled = false;
|
||||
SwitchAutoMusicGameEnabled = false;
|
||||
SwitchAutoAlbumEnabled = false;
|
||||
SwitchAutoFishingEnabled = false;
|
||||
SwitchArtifactSalvageEnabled = false;
|
||||
SwitchAutoRedeemCodeEnabled = false;
|
||||
SwitchAutoStygianOnslaughtEnabled = false;
|
||||
SwitchGetGridIconsEnabled = false;
|
||||
await Task.Delay(800);
|
||||
}
|
||||
|
||||
@@ -597,20 +603,20 @@ public partial class TaskSettingsPageViewModel : ViewModel
|
||||
p.Height = 500;
|
||||
p.ShowDialog();
|
||||
if (p.DialogResult == true && !string.IsNullOrWhiteSpace(multilineTextBox.Text))
|
||||
{
|
||||
{
|
||||
char[] separators = ['\r', '\n'];
|
||||
var codes = multilineTextBox.Text.Split(separators, StringSplitOptions.RemoveEmptyEntries)
|
||||
var codes = multilineTextBox.Text.Split(separators, StringSplitOptions.RemoveEmptyEntries)
|
||||
|
||||
.Select(code => code.Trim())
|
||||
.Where(code => !string.IsNullOrEmpty(code))
|
||||
.ToList();
|
||||
.Select(code => code.Trim())
|
||||
.Where(code => !string.IsNullOrEmpty(code))
|
||||
.ToList();
|
||||
|
||||
if (codes.Count == 0)
|
||||
{
|
||||
Toast.Warning("没有有效的兑换码");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
SwitchAutoRedeemCodeEnabled = true;
|
||||
await new TaskRunner()
|
||||
.RunSoloTaskAsync(new UseRedemptionCodeTask(codes));
|
||||
|
||||