Files
bettergi-scripts-list/repo/js/AutoCommission/lib/steps/auto-skip.js
躁动的氨气 204825f37d 强制所有脚本进行dispose(如发生提前释放问题请自行修复) (#2292)
* 强制dispose

* 强制dispose(版本号更新)
2025-11-02 13:27:59 +08:00

351 lines
11 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 原神每日委托自动执行脚本 - AutoSkip步骤处理器
// 共同的AutoSkip逻辑函数
var executeAutoSkipLogic = async function (stepData, stepName) {
try {
log.info("执行{stepName}步骤", stepName);
// 从stepData中提取配置参数
var customPriorityOptions = stepData.priorityOptions || [];
var customBlacklist = stepData.blacklist || [];
var customPriorityIcons = stepData.priorityIcons || [];
var customNpcWhiteList = stepData.npcWhiteList || [];
var StoryRo = RecognitionObject.TemplateMatch(
file.ReadImageMatSync("Data/RecognitionObject/disabled_ui.png"),
265,
37,
30,
22
);
// 识别图像函数
var recognizeImage = async function (recognitionObject) {
try {
// 尝试识别图像
let captureRegion = captureGameRegion();
var imageResult = captureRegion.find(recognitionObject);
captureRegion.dispose();
if (
imageResult &&
imageResult.x !== 0 &&
imageResult.y !== 0 &&
imageResult.width !== 0 &&
imageResult.height !== 0
) {
return { success: true, x: imageResult.x, y: imageResult.y };
}
} catch (error) {
log.error("识别图像时发生异常: {error}", error.message);
}
return { success: false };
};
var AutoSkip = async function (
customPriorityOptions,
customBlacklist,
customPriorityIcons,
customNpcWhiteList
) {
customPriorityOptions = customPriorityOptions || [];
customBlacklist = customBlacklist || [];
customPriorityIcons = customPriorityIcons || [];
customNpcWhiteList = customNpcWhiteList || [];
// 默认配置
var defaultPriorityOptions = [];
var defaultBlacklist = [];
var defaultPriorityIcons = [];
// 将npcWhiteList添加到priorityOptions的前面
var mergedPriorityOptions = customNpcWhiteList.concat(
customPriorityOptions
);
// 合并用户自定义配置和默认配置
var effectivePriorityOptions = defaultPriorityOptions.concat(
mergedPriorityOptions
);
var effectiveBlacklist = defaultBlacklist.concat(customBlacklist);
var effectivePriorityIcons =
customPriorityIcons.length > 0
? customPriorityIcons
: defaultPriorityIcons;
// 重复执行自动剧情,直到返回主界面
var maxAttempts = 1200; // 设置最大尝试次数,防止无限循环
var attempts = 0;
var SkipTime = 100; // 跳过间隔时间(毫秒)
var storyIconDetectedOnce = false; // 首次出现机制标志
await sleep(1000);
// 预加载优先图标识别对象
var priorityIconROs = [];
for (var k = 0; k < effectivePriorityIcons.length; k++) {
var iconName = effectivePriorityIcons[k];
try {
var iconPath = "Data/RecognitionObject/" + iconName;
var iconMat = file.ReadImageMatSync(iconPath);
if (iconMat) {
var ro = RecognitionObject.TemplateMatch(iconMat);
priorityIconROs.push(ro);
}
} catch (error) {
log.warn(
"无法加载优先图标 {iconName}: {error}",
iconName,
error.message
);
}
}
while (attempts < maxAttempts) {
var StoryResult = await recognizeImage(StoryRo);
// 首次出现机制:如果图标曾经出现过,就必须通过这个判断
if (storyIconDetectedOnce) {
if (!StoryResult.success) {
log.info("剧情图标消失结束AutoSkip");
return;
}
} else {
// 如果图标第一次被检测到,记录首次出现
if (StoryResult.success) {
storyIconDetectedOnce = true;
log.info("检测到剧情图标首次出现,启用图标检测机制");
}
// 如果图标从未出现过,继续执行不进行判断
}
attempts++;
var startTime = new Date().getTime();
// 1秒内按空格键跳过
while (new Date().getTime() - startTime < 1000) {
keyPress("VK_SPACE");
await sleep(SkipTime);
}
// 1. 查找F图标
var fIconFound = false;
var fIconY = 0;
// F图标检测逻辑
var fIconRO = RecognitionObject.TemplateMatch(
file.ReadImageMatSync("Data/RecognitionObject/F.png"),
1207,
0,
43,
850
);
var fIconResult = await recognizeImage(fIconRO);
log.info(fIconResult.success)
if (fIconResult.success) {
fIconFound = true;
fIconY = fIconResult.y;
}
// 2. 查找优先图标
var priorityIconClicked = false;
if (fIconFound) {
for (var m = 0; m < priorityIconROs.length; m++) {
var iconRO = priorityIconROs[m];
var iconResult = await recognizeImage(iconRO);
if (iconResult.success) {
log.info("找到优先图标点击");
click(iconResult.x, iconResult.y);
priorityIconClicked = true;
break;
}
}
}
// 3. 如果没有找到优先图标进行OCR识别
if (fIconFound && !priorityIconClicked) {
// 定义OCR区域1250, F图标的y+10 到 1800,850
var ocrStartY = fIconY + 10;
var ocrHeight = 850 - ocrStartY;
if (ocrHeight > 0) {
var captureRegion = captureGameRegion();
var dialogArea = captureRegion.DeriveCrop(
1250,
ocrStartY,
550,
ocrHeight
);
// 创建OCR识别对象并识别文本
var ocrRo = RecognitionObject.Ocr(
0,
0,
dialogArea.width,
dialogArea.height
);
var ocrResults = dialogArea.FindMulti(ocrRo);
captureRegion.dispose();
dialogArea.dispose();
if (ocrResults && ocrResults.count > 0) {
var foundValidOption = false;
var firstNonBlacklistOption = null;
// 首先查找优先选项
for (var i = 0; i < ocrResults.count; i++) {
var ocrText = ocrResults[i].text;
log.debug("选项 {index}: {text}", i + 1, ocrText);
// 检查是否在优先选项列表中
for (var j = 0; j < effectivePriorityOptions.length; j++) {
var priorityOption = effectivePriorityOptions[j];
if (ocrText.includes(priorityOption)) {
log.info(
"找到优先选项: {option},点击该选项",
priorityOption
);
ocrResults[i].click();
foundValidOption = true;
break;
}
}
if (foundValidOption) break;
// 记录第一个非黑名单选项
if (!firstNonBlacklistOption) {
var isBlacklisted = false;
for (var k = 0; k < effectiveBlacklist.length; k++) {
var blackOption = effectiveBlacklist[k];
if (ocrText.includes(blackOption)) {
isBlacklisted = true;
break;
}
}
if (!isBlacklisted) {
firstNonBlacklistOption = ocrResults[i];
}
}
}
// 如果没有找到优先选项,但有非黑名单选项,点击第一个非黑名单选项
if (!foundValidOption && firstNonBlacklistOption) {
firstNonBlacklistOption.click();
foundValidOption = true;
}
// 如果既没有优先选项也没有非黑名单选项按F键
if (!foundValidOption) {
keyPress("F");
}
} else {
keyPress("F");
}
}
}
}
};
// 执行AutoSkip功能
await AutoSkip(
customPriorityOptions,
customBlacklist,
customPriorityIcons,
customNpcWhiteList
);
log.info("{stepName}步骤执行完成", stepName);
} catch (error) {
log.error("执行{stepName}步骤时出错: {error}", stepName, error.message);
throw error;
}
};
// 注册"AutoSkip"步骤处理器
StepProcessorLoader.register("AutoSkip", async function (stepData, context) {
await executeAutoSkipLogic(stepData, "AutoSkip");
});
// 注册"对话"步骤处理器
StepProcessorLoader.register("对话", async function (stepData, context) {
await executeAutoSkipLogic(stepData, "对话");
});
/*
使用示例 - JSON格式配置
1. 基本用法(使用默认配置):
{
"type": "AutoSkip"
}
2. 带优先选项的用法:
{
"type": "AutoSkip",
"priorityOptions": ["帮助", "同意", "确认"],
"note": "优先点击包含'帮助'、'同意'、'确认'的选项"
}
3. 带NPC白名单的用法
{
"type": "AutoSkip",
"npcWhiteList": ["派蒙", "旅行者", "温迪"],
"note": "最优先点击包含指定NPC名称的选项"
}
4. 带黑名单选项的用法:
{
"type": "AutoSkip",
"blacklist": ["拒绝", "离开", "结束对话"],
"note": "避免点击包含'拒绝'、'离开'、'结束对话'的选项"
}
5. 带优先图标的用法:
{
"type": "AutoSkip",
"priorityIcons": ["icon_quest.png", "icon_important.png"],
"note": "优先点击指定图标"
}
6. 完整配置示例:
{
"type": "AutoSkip",
"npcWhiteList": ["委托发布者", "任务NPC"],
"priorityOptions": ["帮助", "委托", "任务"],
"blacklist": ["拒绝", "离开"],
"priorityIcons": ["icon_quest.png"],
"note": "完整配置NPC白名单优先级最高然后是任务相关选项避免拒绝类选项"
}
7. 实际场景示例:
{
"type": "AutoSkip",
"npcWhiteList": ["凯瑟琳", "委托发布人"],
"priorityOptions": ["接受", "好的", "没问题"],
"blacklist": ["算了", "不了", "再见"],
"note": "委托对话最优先选择NPC相关选项然后是接受委托选项避免拒绝选项"
}
参数说明:
- npcWhiteList: NPC白名单关键词数组具有最高优先级会被添加到priorityOptions的前面
- priorityOptions: 优先选项关键词数组,会优先点击包含这些关键词的对话选项
- blacklist: 黑名单关键词数组,会避免点击包含这些关键词的选项
- priorityIcons: 优先图标文件名数组图标文件需放在Data/RecognitionObject/目录下
- note: 步骤说明(可选),用于注释当前步骤的作用
优先级顺序:
1. NPC白名单选项npcWhiteList- 最高优先级
2. 普通优先选项priorityOptions
3. 非黑名单选项
4. 按F键默认操作
功能说明:
- 自动识别剧情对话界面通过disabled_ui.png图标
- 连续按空格键跳过剧情文本
- 检测F键提示图标的位置
- 优先点击指定的图标如果配置了priorityIcons
- 使用OCR识别对话选项文本
- 按上述优先级顺序选择对话选项
- 循环执行直到剧情结束
*/