两个狗粮js替换拾取模式 (#1976)
* js:锄地一条龙1.3.1 * js:联机狗粮1.4.0 * Update 509【收尾】枫丹-科学院工坊高塔①-9.json 更新一条路线
@@ -82,6 +82,10 @@ https://www.kdocs.cn/wo/sl/v13uXscL
|
||||
|
||||
|
||||
## 更新日志
|
||||
### 1.3.1(2025.09.22)
|
||||
1.修正等待时间错误
|
||||
### 1.3.0(2025.09.21)
|
||||
1.将拾取方式修改为模板匹配拾取
|
||||
### 1.2.15(2025.09.20)
|
||||
1.修几条路线305①,632,640,628
|
||||
### 1.2.14(2025.09.19)
|
||||
|
||||
BIN
repo/js/AAA-Artifacts-Bulk-Supply/assets/F_Dialogue.png
Normal file
|
After Width: | Height: | Size: 515 B |
BIN
repo/js/AAA-Artifacts-Bulk-Supply/assets/MainUI.png
Normal file
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 888 B |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 971 B |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 5.2 KiB |
|
After Width: | Height: | Size: 6.0 KiB |
|
After Width: | Height: | Size: 9.1 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 4.4 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 6.7 KiB |
|
After Width: | Height: | Size: 8.3 KiB |
|
After Width: | Height: | Size: 4.5 KiB |
|
After Width: | Height: | Size: 6.0 KiB |
|
After Width: | Height: | Size: 12 KiB |
23
repo/js/AAA-Artifacts-Bulk-Supply/assets/info.json
Normal file
@@ -0,0 +1,23 @@
|
||||
[
|
||||
{
|
||||
"position": {
|
||||
"x": 14031,
|
||||
"y": 440
|
||||
},
|
||||
"name": "度假村"
|
||||
},
|
||||
{
|
||||
"position": {
|
||||
"x": 5319,
|
||||
"y": -2330
|
||||
},
|
||||
"name": "智障厅"
|
||||
},
|
||||
{
|
||||
"position": {
|
||||
"x": -3354,
|
||||
"y": -3578
|
||||
},
|
||||
"name": "踏鞴砂"
|
||||
}
|
||||
]
|
||||
BIN
repo/js/AAA-Artifacts-Bulk-Supply/assets/targetItems/冒险家.png
Normal file
|
After Width: | Height: | Size: 4.7 KiB |
BIN
repo/js/AAA-Artifacts-Bulk-Supply/assets/targetItems/幸运儿.png
Normal file
|
After Width: | Height: | Size: 4.1 KiB |
BIN
repo/js/AAA-Artifacts-Bulk-Supply/assets/targetItems/幸运儿a.png
Normal file
|
After Width: | Height: | Size: 4.4 KiB |
BIN
repo/js/AAA-Artifacts-Bulk-Supply/assets/targetItems/幸运儿b.png
Normal file
|
After Width: | Height: | Size: 4.3 KiB |
BIN
repo/js/AAA-Artifacts-Bulk-Supply/assets/targetItems/游医.png
Normal file
|
After Width: | Height: | Size: 3.2 KiB |
BIN
repo/js/AAA-Artifacts-Bulk-Supply/assets/targetItems/火晶蝶.png
Normal file
|
After Width: | Height: | Size: 6.8 KiB |
BIN
repo/js/AAA-Artifacts-Bulk-Supply/assets/targetItems/调查.png
Normal file
|
After Width: | Height: | Size: 4.1 KiB |
25
repo/js/AAA-Artifacts-Bulk-Supply/assets/滚轮上翻.json
Normal file
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"macroEvents": [
|
||||
{
|
||||
"type": 6,
|
||||
"mouseX": 0,
|
||||
"mouseY": 120,
|
||||
"time": 0
|
||||
},
|
||||
{
|
||||
"type": 6,
|
||||
"mouseX": 0,
|
||||
"mouseY": 0,
|
||||
"time": 5
|
||||
}
|
||||
],
|
||||
"info": {
|
||||
"name": "滚轮上翻",
|
||||
"description": "模拟鼠标滚轮向上滚动120单位",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"width": 1920,
|
||||
"height": 1080,
|
||||
"recordDpi": 1
|
||||
}
|
||||
}
|
||||
25
repo/js/AAA-Artifacts-Bulk-Supply/assets/滚轮下翻.json
Normal file
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"macroEvents": [
|
||||
{
|
||||
"type": 6,
|
||||
"mouseX": 0,
|
||||
"mouseY": -120,
|
||||
"time": 0
|
||||
},
|
||||
{
|
||||
"type": 6,
|
||||
"mouseX": 0,
|
||||
"mouseY": 0,
|
||||
"time": 5
|
||||
}
|
||||
],
|
||||
"info": {
|
||||
"name": "",
|
||||
"description": "模拟鼠标滚轮向上滚动120单位",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"width": 1920,
|
||||
"height": 1080,
|
||||
"recordDpi": 1
|
||||
}
|
||||
}
|
||||
@@ -43,8 +43,18 @@ let failcount = 0;
|
||||
let autoSalvageCount = 0;
|
||||
let furinaState = "unknown";
|
||||
|
||||
let targetItems;
|
||||
let pickupDelay = 100;
|
||||
let timeMove = 1000;
|
||||
let timeMoveUp = Math.round(timeMove * 0.45);
|
||||
let timeMoveDown = Math.round(timeMove * 0.55);
|
||||
let rollingDelay = 25;
|
||||
let gameRegion;
|
||||
|
||||
(async function () {
|
||||
setGameMetrics(1920, 1080, 1);
|
||||
targetItems = await loadTargetItems();
|
||||
state.activatePickUp = false;
|
||||
{
|
||||
//校验自定义配置,从未打开过自定义配置时进行警告
|
||||
if (!settings.accountName) {
|
||||
@@ -849,8 +859,6 @@ async function writeCDInfo(accountName) {
|
||||
//运行普通路线
|
||||
async function runNormalPath(doStop) {
|
||||
furinaState = "unknown";
|
||||
//关闭拾取
|
||||
dispatcher.ClearAllTriggers();
|
||||
if (state.cancel) return;
|
||||
const routeMap = { A: normalPathA, B: normalPathB, C: normalPathC };
|
||||
const normalPath = routeMap[state.runningRoute];
|
||||
@@ -860,16 +868,14 @@ async function runNormalPath(doStop) {
|
||||
log.info("填写了清怪队伍,执行清怪路线");
|
||||
await runPaths(normalCombatPath, combatPartyName, doStop, "black");
|
||||
}
|
||||
// 启用自动拾取的实时任务
|
||||
dispatcher.addTimer(new RealtimeTimer("AutoPick"));
|
||||
state.activatePickUp = true;
|
||||
await runPaths(normalExecutePath, artifactPartyName, doStop, "white");
|
||||
state.activatePickUp = false;
|
||||
|
||||
}
|
||||
|
||||
async function runActivatePath() {
|
||||
//furinaState = "unknown";
|
||||
//关闭拾取
|
||||
dispatcher.ClearAllTriggers();
|
||||
if (state.cancel) return;
|
||||
if (!state.activatedToday) {
|
||||
log.info("今日未执行过激活路线");
|
||||
@@ -932,8 +938,6 @@ async function runActivatePath() {
|
||||
|
||||
async function runEndingAndExtraPath() {
|
||||
furinaState = "unknown";
|
||||
// 启用自动拾取的实时任务
|
||||
dispatcher.addTimer(new RealtimeTimer("AutoPick"));
|
||||
if (state.cancel) return;
|
||||
let endingPath = state.runningEndingAndExtraRoute === "收尾额外A"
|
||||
? "assets/ArtifactsPath/优先收尾路线"
|
||||
@@ -958,9 +962,11 @@ async function runEndingAndExtraPath() {
|
||||
? "assets/ArtifactsPath/额外/所有额外"
|
||||
: "assets/ArtifactsPath/额外/仅12h额外";
|
||||
endingPath = endingPath + "/执行";
|
||||
state.activatePickUp = true;
|
||||
await runPaths(endingPath, artifactPartyName, false, "white");
|
||||
extraPath = extraPath + "/执行";
|
||||
await runPaths(extraPath, artifactPartyName, false, "white");
|
||||
state.activatePickUp = false;
|
||||
}
|
||||
|
||||
async function runPaths(folderFilePath, PartyName, doStop, furinaRequirement = "") {
|
||||
@@ -973,7 +979,7 @@ async function runPaths(folderFilePath, PartyName, doStop, furinaRequirement = "
|
||||
if (new Date() >= state.aimActivateTime && doStop) {
|
||||
log.info("已经到达预定时间");
|
||||
break;
|
||||
} else if ((new Date() >= (state.aimActivateTime - minIntervalTime * 60)) && doStop) {
|
||||
} else if ((new Date() >= (state.aimActivateTime - minIntervalTime * 60 * 1000)) && doStop) {
|
||||
log.info(`即将到达预定时间,等待${state.aimActivateTime - new Date()}毫秒`);
|
||||
await sleep(state.aimActivateTime - new Date())
|
||||
break;
|
||||
@@ -1016,11 +1022,10 @@ async function runPaths(folderFilePath, PartyName, doStop, furinaRequirement = "
|
||||
} else {
|
||||
autoSalvageCount++;
|
||||
}
|
||||
await fakeLog(Path.fileName, false, true, 0);
|
||||
const pathInfo = await parsePathing(Path.fullPath);
|
||||
try {
|
||||
log.info(`当前进度:${Path.fileName}为${folderFilePath}第${i + 1}/${Paths.length}个`);
|
||||
await pathingScript.runFile(Path.fullPath);
|
||||
await runPath(Path.fullPath, null);
|
||||
await sleep(1);
|
||||
} catch (error) {
|
||||
skiprecord = true;
|
||||
@@ -1032,7 +1037,6 @@ async function runPaths(folderFilePath, PartyName, doStop, furinaRequirement = "
|
||||
success = false;
|
||||
break;
|
||||
}
|
||||
await fakeLog(Path.fileName, false, false, 0);
|
||||
if (pathInfo.ok) {
|
||||
await genshin.returnMainUi();
|
||||
await sleep(500);
|
||||
@@ -1211,4 +1215,175 @@ async function fakeLog(name, isJs, isStart, duration) {
|
||||
`------------------------------`;
|
||||
log.debug(logMessage);
|
||||
}
|
||||
}
|
||||
|
||||
async function runPath(fullPath, targetItemPath = null) {
|
||||
state = state || {}; // 若已存在则保持原引用,否则新建空对象
|
||||
state.running = true;
|
||||
|
||||
/* ---------- 主任务 ---------- */
|
||||
const pathingTask = (async () => {
|
||||
log.info(`开始执行路线: ${fullPath}`);
|
||||
await fakeLog(fullPath, false, true, 0);
|
||||
await pathingScript.runFile(fullPath);
|
||||
await fakeLog(fullPath, false, false, 0);
|
||||
state.running = false;
|
||||
})();
|
||||
|
||||
/* ---------- 伴随任务 ---------- */
|
||||
|
||||
const pickupTask = (async () => {
|
||||
if (state.activatePickUp) {
|
||||
await recognizeAndInteract();
|
||||
}
|
||||
})();
|
||||
|
||||
const errorProcessTask = (async () => {
|
||||
const revivalRo1 = RecognitionObject.TemplateMatch(file.ReadImageMatSync("assets/RecognitionObject/revival.png"));
|
||||
let errorCheckCount = 9;
|
||||
while (state.running) {
|
||||
await sleep(100);
|
||||
errorCheckCount++;
|
||||
if (errorCheckCount > 50) {
|
||||
errorCheckCount = 0;
|
||||
//log.info("尝试识别并点击复苏按钮");
|
||||
if (await findAndClick(revivalRo1, 2)) {
|
||||
//log.info("识别到复苏按钮,点击复苏");
|
||||
}
|
||||
}
|
||||
}
|
||||
})();
|
||||
|
||||
/* ---------- 并发等待 ---------- */
|
||||
await Promise.allSettled([pathingTask, pickupTask, errorProcessTask]);
|
||||
}
|
||||
|
||||
//加载拾取物图片
|
||||
async function loadTargetItems() {
|
||||
const targetItemPath = 'assets/targetItems'; // 固定目录
|
||||
const items = await readFolder(targetItemPath, false);
|
||||
// 统一预加载模板
|
||||
for (const it of items) {
|
||||
it.template = file.ReadImageMatSync(it.fullPath);
|
||||
it.itemName = it.fileName.replace(/\.png$/i, '');
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
// 定义一个函数用于拾取
|
||||
async function recognizeAndInteract() {
|
||||
//log.info("调试-开始执行图像识别与拾取任务");
|
||||
let lastcenterYF = 0;
|
||||
let lastItemName = "";
|
||||
let fIcontemplate = file.ReadImageMatSync('assets/F_Dialogue.png');
|
||||
let mainUITemplate = file.ReadImageMatSync("assets/MainUI.png");
|
||||
let thisMoveUpTime = 0;
|
||||
let lastMoveDown = 0;
|
||||
|
||||
gameRegion = captureGameRegion();
|
||||
//主循环
|
||||
while (state.running) {
|
||||
gameRegion.dispose();
|
||||
gameRegion = captureGameRegion();
|
||||
let centerYF = await findFIcon();
|
||||
if (!centerYF) {
|
||||
if (await isMainUI()) await keyMouseScript.runFile(`assets/滚轮下翻.json`);
|
||||
continue;
|
||||
}
|
||||
//log.info(`调试-成功找到f图标,centerYF为${centerYF}`);
|
||||
let foundTarget = false;
|
||||
let itemName = await performTemplateMatch(centerYF);
|
||||
if (itemName) {
|
||||
//log.info(`调试-识别到物品${itemName}`);
|
||||
if (Math.abs(lastcenterYF - centerYF) <= 20 && lastItemName === itemName) {
|
||||
//log.info("调试-相同物品名和相近y坐标,本次不拾取");
|
||||
await sleep(2 * pickupDelay);
|
||||
lastcenterYF = -20;
|
||||
lastItemName = null;
|
||||
} else {
|
||||
keyPress("F");
|
||||
log.info(`交互或拾取:"${itemName}"`);
|
||||
lastcenterYF = centerYF;
|
||||
lastItemName = itemName;
|
||||
await sleep(pickupDelay);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
log.info("识别失败,尝试截图");
|
||||
await refreshTargetItems(centerYF);
|
||||
lastItemName = "";
|
||||
*/
|
||||
}
|
||||
|
||||
if (!foundTarget) {
|
||||
//log.info(`调试-执行滚轮动作`);
|
||||
const currentTime = new Date().getTime();
|
||||
if (currentTime - lastMoveDown > timeMoveUp) {
|
||||
await keyMouseScript.runFile(`assets/滚轮下翻.json`);
|
||||
if (thisMoveUpTime === 0) thisMoveUpTime = currentTime;
|
||||
if (currentTime - thisMoveUpTime >= timeMoveDown) {
|
||||
lastMoveDown = currentTime;
|
||||
thisMoveUpTime = 0;
|
||||
}
|
||||
} else {
|
||||
await keyMouseScript.runFile(`assets/滚轮上翻.json`);
|
||||
}
|
||||
await sleep(rollingDelay);
|
||||
}
|
||||
}
|
||||
|
||||
async function performTemplateMatch(centerYF) {
|
||||
try {
|
||||
let result;
|
||||
let itemName = null;
|
||||
for (const targetItem of targetItems) {
|
||||
let recognitionObject = RecognitionObject.TemplateMatch(targetItem.template, 1219, centerYF - 15, 32 + 30 * (targetItem.itemName.length) + 2, 30);
|
||||
result = gameRegion.find(recognitionObject);
|
||||
if (result.isExist()) {
|
||||
itemName = targetItem.itemName;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return itemName;
|
||||
} catch (error) {
|
||||
log.error(`模板匹配时发生异常: ${error.message}`);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async function findFIcon() {
|
||||
let recognitionObject = RecognitionObject.TemplateMatch(fIcontemplate, 1102, 335, 34, 400);
|
||||
try {
|
||||
let result = gameRegion.find(recognitionObject);
|
||||
if (result.isExist()) {
|
||||
return Math.round(result.y + result.height / 2);
|
||||
}
|
||||
} catch (error) {
|
||||
log.error(`识别图像时发生异常: ${error.message}`);
|
||||
if (!state.running)
|
||||
return null;
|
||||
}
|
||||
await sleep(100);
|
||||
return null;
|
||||
}
|
||||
|
||||
async function isMainUI() {
|
||||
const recognitionObject = RecognitionObject.TemplateMatch(mainUITemplate, 0, 0, 150, 150);
|
||||
const maxAttempts = 1;
|
||||
let attempts = 0;
|
||||
|
||||
while (attempts < maxAttempts && state.running) {
|
||||
try {
|
||||
const result = gameRegion.find(recognitionObject);
|
||||
if (result.isExist()) return true;
|
||||
} catch (error) {
|
||||
log.error(`识别图像时发生异常: ${error.message}`);
|
||||
if (!state.running) break;
|
||||
return false;
|
||||
}
|
||||
attempts++;
|
||||
await sleep(50);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"manifest_version": 1,
|
||||
"name": "AAA狗粮批发",
|
||||
"version": "1.2.15",
|
||||
"version": "1.3.1",
|
||||
"tags": [
|
||||
"狗粮"
|
||||
],
|
||||
|
||||
@@ -24,6 +24,9 @@
|
||||
* **预留足够的背包空间**:运行AAA狗粮批发将获取约150个圣遗物,运行本js将获取约230个圣遗物,请确保你的背包有足够的空间容纳这些圣遗物,建议在AAA狗粮批发中选择分解或摧毁,并预留380+的空间
|
||||
|
||||
## 更新日志
|
||||
|
||||
### 1.4.0(2025.09.20)
|
||||
1.将拾取模式修改为模板匹配拾取
|
||||
### 1.3.2(2025.09.20)
|
||||
1.修几处路线度假村踩点,624③,509①②,305①
|
||||
### 1.3.1(2025.09.19)
|
||||
@@ -46,5 +49,4 @@
|
||||
### 1.2.1(2025.09.04)
|
||||
1,修几处路线627,水天丛林,
|
||||
### 1.2.0(2025.09.03)
|
||||
1.增加几处错误处理,增加容错
|
||||
|
||||
1.增加几处错误处理,增加容错
|
||||
@@ -9,7 +9,7 @@
|
||||
"bgi_version": "0.45.0",
|
||||
"description": "",
|
||||
"enable_monster_loot_split": false,
|
||||
"last_modified_time": 1758376990820,
|
||||
"last_modified_time": 1758555670986,
|
||||
"map_match_method": "",
|
||||
"map_name": "Teyvat",
|
||||
"name": "509【收尾】枫丹-科学院工坊高塔①-9",
|
||||
@@ -214,25 +214,16 @@
|
||||
},
|
||||
{
|
||||
"action": "combat_script",
|
||||
"action_params": "keydown(w),keypress(f),attack(4.5),keyup(w)",
|
||||
"action_params": "keypress(x),a(0.1);万叶 attack(0.08),keydown(E),wait(0.51),keyup(E),attack(0.2),wait(0.5);琴 attack(0.08),keydown(E),wait(0.4),moveby(1000,0),wait(0.2),moveby(1000,0),wait(0.2),moveby(1000,0),wait(0.2),moveby(1000,-3500),wait(1.8),keyup(E),wait(0.3),click(middle);",
|
||||
"id": 23,
|
||||
"move_mode": "climb",
|
||||
"type": "orientation",
|
||||
"x": 4397.052734375,
|
||||
"y": 4920.9658203125
|
||||
},
|
||||
{
|
||||
"action": "combat_script",
|
||||
"action_params": "keypress(f),a(0.1),keypress(f),keypress(f);万叶 attack(0.08),keydown(E),wait(0.51),keyup(E),attack(0.2),wait(0.5);琴 attack(0.08),keydown(E),wait(0.4),moveby(1000,0),wait(0.2),moveby(1000,0),wait(0.2),moveby(1000,0),wait(0.2),moveby(1000,-3500),wait(1.8),keyup(E),wait(0.3),click(middle);",
|
||||
"id": 24,
|
||||
"move_mode": "climb",
|
||||
"type": "target",
|
||||
"x": 4398.31640625,
|
||||
"y": 4922.1220703125
|
||||
},
|
||||
{
|
||||
"action": "",
|
||||
"id": 25,
|
||||
"id": 24,
|
||||
"move_mode": "walk",
|
||||
"type": "path",
|
||||
"x": 4399.093769750416,
|
||||
@@ -241,7 +232,7 @@
|
||||
{
|
||||
"action": "",
|
||||
"action_params": "",
|
||||
"id": 26,
|
||||
"id": 25,
|
||||
"move_mode": "climb",
|
||||
"type": "orientation",
|
||||
"x": 4402.75146484375,
|
||||
@@ -250,7 +241,7 @@
|
||||
{
|
||||
"action": "",
|
||||
"action_params": "",
|
||||
"id": 27,
|
||||
"id": 26,
|
||||
"move_mode": "climb",
|
||||
"type": "path",
|
||||
"x": 4402.75146484375,
|
||||
@@ -258,8 +249,8 @@
|
||||
},
|
||||
{
|
||||
"action": "combat_script",
|
||||
"action_params": "keypress(f),wait(0.2),keypress(f),d(0.3),keypress(f),wait(0.2),keypress(x);万叶 attack(0.08),keydown(E),wait(0.51),keyup(E),attack(0.2),wait(0.5);琴 attack(0.08),keydown(E),wait(0.4),moveby(1000,0),wait(0.2),moveby(1000,0),wait(0.2),moveby(1000,0),wait(0.2),moveby(1000,-3500),wait(1.8),keyup(E),wait(0.3),click(middle);",
|
||||
"id": 28,
|
||||
"action_params": "keypress(f),keypress(x),wait(0.2),keypress(f),keypress(x),d(0.3),keypress(f),keypress(x),wait(0.2),keypress(x);万叶 attack(0.08),keydown(E),wait(0.51),keyup(E),attack(0.2),wait(0.5);琴 attack(0.08),keydown(E),wait(0.4),moveby(1000,0),wait(0.2),moveby(1000,0),wait(0.2),moveby(1000,0),wait(0.2),moveby(1000,-3500),wait(1.8),keyup(E),wait(0.3),click(middle);",
|
||||
"id": 27,
|
||||
"move_mode": "climb",
|
||||
"type": "target",
|
||||
"x": 4398.71875,
|
||||
@@ -268,7 +259,7 @@
|
||||
{
|
||||
"action": "combat_script",
|
||||
"action_params": "attack(0.3)",
|
||||
"id": 29,
|
||||
"id": 28,
|
||||
"move_mode": "dash",
|
||||
"type": "path",
|
||||
"x": 4397.109375,
|
||||
@@ -277,7 +268,7 @@
|
||||
{
|
||||
"action": "",
|
||||
"action_params": "",
|
||||
"id": 30,
|
||||
"id": 29,
|
||||
"move_mode": "dash",
|
||||
"type": "path",
|
||||
"x": 4409.123046875,
|
||||
@@ -286,7 +277,7 @@
|
||||
{
|
||||
"action": "",
|
||||
"action_params": "",
|
||||
"id": 31,
|
||||
"id": 30,
|
||||
"move_mode": "dash",
|
||||
"type": "path",
|
||||
"x": 4431.09375,
|
||||
@@ -295,7 +286,7 @@
|
||||
{
|
||||
"action": "",
|
||||
"action_params": "",
|
||||
"id": 32,
|
||||
"id": 31,
|
||||
"move_mode": "dash",
|
||||
"type": "path",
|
||||
"x": 4493.9091796875,
|
||||
@@ -304,7 +295,7 @@
|
||||
{
|
||||
"action": "stop_flying",
|
||||
"action_params": "",
|
||||
"id": 33,
|
||||
"id": 32,
|
||||
"move_mode": "fly",
|
||||
"type": "path",
|
||||
"x": 4503.7236328125,
|
||||
@@ -313,7 +304,7 @@
|
||||
{
|
||||
"action": "combat_script",
|
||||
"action_params": "keypress(f),wait(0.2),keypress(f),wait(0.2),keypress(f)",
|
||||
"id": 34,
|
||||
"id": 33,
|
||||
"move_mode": "dash",
|
||||
"type": "target",
|
||||
"x": 4498.919921875,
|
||||
@@ -322,7 +313,7 @@
|
||||
{
|
||||
"action": "",
|
||||
"action_params": "",
|
||||
"id": 35,
|
||||
"id": 34,
|
||||
"move_mode": "walk",
|
||||
"type": "path",
|
||||
"x": 4493.6455078125,
|
||||
@@ -331,7 +322,7 @@
|
||||
{
|
||||
"action": "combat_script",
|
||||
"action_params": "w(0.3),dash,w(0.7),dash,wait(0.8)",
|
||||
"id": 36,
|
||||
"id": 35,
|
||||
"move_mode": "walk",
|
||||
"type": "orientation",
|
||||
"x": 4463.6845703125,
|
||||
@@ -340,7 +331,7 @@
|
||||
{
|
||||
"action": "",
|
||||
"action_params": "",
|
||||
"id": 37,
|
||||
"id": 36,
|
||||
"move_mode": "dash",
|
||||
"type": "path",
|
||||
"x": 4463.6845703125,
|
||||
@@ -349,7 +340,7 @@
|
||||
{
|
||||
"action": "combat_script",
|
||||
"action_params": "keypress(f),wait(0.2),keypress(f),wait(0.2),keypress(f),wait(0.2),keypress(f),wait(0.2),keypress(f);万叶 attack(0.08),keydown(E),wait(0.7),keyup(E),attack(0.2);琴 attack(0.08),keydown(E),wait(0.4),moveby(1000,0),wait(0.2),moveby(1000,0),wait(0.2),moveby(1000,0),wait(0.2),moveby(1000,-3500),wait(1.8),keyup(E),wait(0.3),click(middle);",
|
||||
"id": 38,
|
||||
"id": 37,
|
||||
"move_mode": "dash",
|
||||
"type": "target",
|
||||
"x": 4440.625,
|
||||
@@ -358,7 +349,7 @@
|
||||
{
|
||||
"action": "",
|
||||
"action_params": "",
|
||||
"id": 39,
|
||||
"id": 38,
|
||||
"move_mode": "dash",
|
||||
"type": "path",
|
||||
"x": 4422.212890625,
|
||||
|
||||
BIN
repo/js/ArtifactsGroupPurchasing/assets/F_Dialogue.png
Normal file
|
After Width: | Height: | Size: 515 B |
BIN
repo/js/ArtifactsGroupPurchasing/assets/MainUI.png
Normal file
|
After Width: | Height: | Size: 2.9 KiB |
BIN
repo/js/ArtifactsGroupPurchasing/assets/targetItems/冒险家.png
Normal file
|
After Width: | Height: | Size: 4.7 KiB |
BIN
repo/js/ArtifactsGroupPurchasing/assets/targetItems/幸运儿.png
Normal file
|
After Width: | Height: | Size: 4.1 KiB |
BIN
repo/js/ArtifactsGroupPurchasing/assets/targetItems/幸运儿a.png
Normal file
|
After Width: | Height: | Size: 4.4 KiB |
BIN
repo/js/ArtifactsGroupPurchasing/assets/targetItems/幸运儿b.png
Normal file
|
After Width: | Height: | Size: 4.3 KiB |
BIN
repo/js/ArtifactsGroupPurchasing/assets/targetItems/游医.png
Normal file
|
After Width: | Height: | Size: 3.2 KiB |
BIN
repo/js/ArtifactsGroupPurchasing/assets/targetItems/火晶蝶.png
Normal file
|
After Width: | Height: | Size: 6.8 KiB |
BIN
repo/js/ArtifactsGroupPurchasing/assets/targetItems/调查.png
Normal file
|
After Width: | Height: | Size: 4.1 KiB |
25
repo/js/ArtifactsGroupPurchasing/assets/滚轮上翻.json
Normal file
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"macroEvents": [
|
||||
{
|
||||
"type": 6,
|
||||
"mouseX": 0,
|
||||
"mouseY": 120,
|
||||
"time": 0
|
||||
},
|
||||
{
|
||||
"type": 6,
|
||||
"mouseX": 0,
|
||||
"mouseY": 0,
|
||||
"time": 5
|
||||
}
|
||||
],
|
||||
"info": {
|
||||
"name": "滚轮上翻",
|
||||
"description": "模拟鼠标滚轮向上滚动120单位",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"width": 1920,
|
||||
"height": 1080,
|
||||
"recordDpi": 1
|
||||
}
|
||||
}
|
||||
25
repo/js/ArtifactsGroupPurchasing/assets/滚轮下翻.json
Normal file
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"macroEvents": [
|
||||
{
|
||||
"type": 6,
|
||||
"mouseX": 0,
|
||||
"mouseY": -120,
|
||||
"time": 0
|
||||
},
|
||||
{
|
||||
"type": 6,
|
||||
"mouseX": 0,
|
||||
"mouseY": 0,
|
||||
"time": 5
|
||||
}
|
||||
],
|
||||
"info": {
|
||||
"name": "",
|
||||
"description": "模拟鼠标滚轮向上滚动120单位",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"width": 1920,
|
||||
"height": 1080,
|
||||
"recordDpi": 1
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,24 @@
|
||||
const runExtra = settings.runExtra || false;
|
||||
const leaveTeamRo = RecognitionObject.TemplateMatch(file.ReadImageMatSync("assets/RecognitionObject/leaveTeam.png"));
|
||||
let targetItems;
|
||||
let pickupDelay = 100;
|
||||
let timeMove = 1000;
|
||||
let timeMoveUp = Math.round(timeMove * 0.45);
|
||||
let timeMoveDown = Math.round(timeMove * 0.55);
|
||||
let rollingDelay = 25;
|
||||
let state;
|
||||
let gameRegion;
|
||||
|
||||
(async function () {
|
||||
if (settings.groupMode != "按照下列配置自动进入并运行") await runGroupPurchasing(runExtra);
|
||||
setGameMetrics(1920, 1080, 1);
|
||||
await genshin.tpToStatueOfTheSeven();
|
||||
await switchPartyIfNeeded(settings.partyName);
|
||||
targetItems = await loadTargetItems();
|
||||
if (settings.groupMode != "按照下列配置自动进入并运行") {
|
||||
await genshin.clearPartyCache();
|
||||
await runGroupPurchasing(runExtra);
|
||||
}
|
||||
if (settings.groupMode != "手动进入后运行") {
|
||||
await switchPartyIfNeeded(settings.partyName)
|
||||
//解析与输出自定义配置
|
||||
const raw = settings.runningOrder || "1234";
|
||||
if (!/^[1-4]+$/.test(raw)) {
|
||||
@@ -25,6 +39,7 @@ const leaveTeamRo = RecognitionObject.TemplateMatch(file.ReadImageMatSync("asset
|
||||
|
||||
// 按 runningOrder 依次进入世界并执行联机收尾
|
||||
for (const idx of enteringIndex) {
|
||||
await genshin.clearPartyCache();
|
||||
if (settings.usingCharacter) { await sleep(1000); keyPress(`${settings.usingCharacter}`); }
|
||||
//构造加入idx号世界的autoEnter的settings
|
||||
let autoEnterSettings;
|
||||
@@ -32,7 +47,7 @@ const leaveTeamRo = RecognitionObject.TemplateMatch(file.ReadImageMatSync("asset
|
||||
// 1. 先收集真实存在的白名单
|
||||
const permits = {};
|
||||
let permitIndex = 1;
|
||||
for (const otherIdx of enteringIndex) {
|
||||
for (const otherIdx of [1, 2, 3, 4]) {
|
||||
if (otherIdx !== yourIndex) {
|
||||
const pName = settings[`p${otherIdx}Name`];
|
||||
if (pName) { // 过滤掉空/undefined
|
||||
@@ -97,6 +112,7 @@ const leaveTeamRo = RecognitionObject.TemplateMatch(file.ReadImageMatSync("asset
|
||||
await runGroupPurchasing(runExtra);
|
||||
}
|
||||
}
|
||||
await genshin.tpToStatueOfTheSeven();
|
||||
}
|
||||
)();
|
||||
|
||||
@@ -147,8 +163,6 @@ async function runGroupPurchasing(runExtra) {
|
||||
let running = true;
|
||||
|
||||
// ===== 4. 主流程 =====
|
||||
setGameMetrics(1920, 1080, 1);
|
||||
await genshin.clearPartyCache();
|
||||
log.info("开始识别队伍编号");
|
||||
let groupNumBer = await getPlayerSign();
|
||||
if (groupNumBer !== 0) log.info(`在队伍中编号为${groupNumBer}`);
|
||||
@@ -160,7 +174,6 @@ async function runGroupPurchasing(runExtra) {
|
||||
}
|
||||
|
||||
if (groupNumBer === 1) {
|
||||
dispatcher.addTimer(new RealtimeTimer("AutoPick"));
|
||||
log.info("是1p,检测当前总人数");
|
||||
const totalNumber = await findTotalNumber();
|
||||
await waitForReady(totalNumber);
|
||||
@@ -211,7 +224,6 @@ async function runGroupPurchasing(runExtra) {
|
||||
}
|
||||
} else if (runExtra) {
|
||||
log.info("请确保联机收尾已结束,将开始运行额外路线");
|
||||
dispatcher.addTimer(new RealtimeTimer("AutoPick"));
|
||||
await runExtraPath();
|
||||
}
|
||||
running = false;
|
||||
@@ -222,8 +234,6 @@ async function runGroupPurchasing(runExtra) {
|
||||
* @param {number} timeOut 最长等待毫秒
|
||||
*/
|
||||
async function waitForReady(totalNumber, timeOut = 300000) {
|
||||
await genshin.tpToStatueOfTheSeven();
|
||||
|
||||
// 实际需要检测的队友编号:2 ~ totalNumber
|
||||
const needCheck = totalNumber - 1; // 队友人数
|
||||
const readyFlags = new Array(needCheck).fill(false); // 下标 0 代表 2P,1 代表 3P …
|
||||
@@ -1011,7 +1021,7 @@ async function readFolder(folderPath, onlyJson) {
|
||||
}
|
||||
|
||||
async function runPath(fullPath, targetItemPath) {
|
||||
const state = { running: true };
|
||||
state = { running: true };
|
||||
|
||||
/* ---------- 主任务 ---------- */
|
||||
const pathingTask = (async () => {
|
||||
@@ -1025,13 +1035,7 @@ async function runPath(fullPath, targetItemPath) {
|
||||
/* ---------- 伴随任务 ---------- */
|
||||
|
||||
const pickupTask = (async () => {
|
||||
//if (!targetItemPath) return; // 没有拾取目录直接跳过
|
||||
//dispatcher.addTimer(new RealtimeTimer("AutoPick"));
|
||||
while (state.running) {
|
||||
await sleep(1000);
|
||||
}
|
||||
//dispatcher.ClearAllTriggers();
|
||||
|
||||
await recognizeAndInteract();
|
||||
})();
|
||||
|
||||
const errorProcessTask = (async () => {
|
||||
@@ -1043,7 +1047,7 @@ async function runPath(fullPath, targetItemPath) {
|
||||
if (errorCheckCount > 50) {
|
||||
errorCheckCount = 0;
|
||||
//log.info("尝试识别并点击复苏按钮");
|
||||
if (await findAndClick(revivalRo1,2)) {
|
||||
if (await findAndClick(revivalRo1, 2)) {
|
||||
//log.info("识别到复苏按钮,点击复苏");
|
||||
}
|
||||
}
|
||||
@@ -1052,4 +1056,134 @@ async function runPath(fullPath, targetItemPath) {
|
||||
|
||||
/* ---------- 并发等待 ---------- */
|
||||
await Promise.allSettled([pathingTask, pickupTask, errorProcessTask]);
|
||||
}
|
||||
|
||||
//加载拾取物图片
|
||||
async function loadTargetItems() {
|
||||
const targetItemPath = 'assets/targetItems'; // 固定目录
|
||||
const items = await readFolder(targetItemPath, false);
|
||||
// 统一预加载模板
|
||||
for (const it of items) {
|
||||
it.template = file.ReadImageMatSync(it.fullPath);
|
||||
it.itemName = it.fileName.replace(/\.png$/i, '');
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
// 定义一个函数用于拾取
|
||||
async function recognizeAndInteract() {
|
||||
//log.info("调试-开始执行图像识别与拾取任务");
|
||||
let lastcenterYF = 0;
|
||||
let lastItemName = "";
|
||||
let fIcontemplate = file.ReadImageMatSync('assets/F_Dialogue.png');
|
||||
let mainUITemplate = file.ReadImageMatSync("assets/MainUI.png");
|
||||
let thisMoveUpTime = 0;
|
||||
let lastMoveDown = 0;
|
||||
|
||||
gameRegion = captureGameRegion();
|
||||
//主循环
|
||||
while (state.running) {
|
||||
gameRegion.dispose();
|
||||
gameRegion = captureGameRegion();
|
||||
let centerYF = await findFIcon();
|
||||
if (!centerYF) {
|
||||
if (await isMainUI()) await keyMouseScript.runFile(`assets/滚轮下翻.json`);
|
||||
continue;
|
||||
}
|
||||
//log.info(`调试-成功找到f图标,centerYF为${centerYF}`);
|
||||
let foundTarget = false;
|
||||
let itemName = await performTemplateMatch(centerYF);
|
||||
if (itemName) {
|
||||
//log.info(`调试-识别到物品${itemName}`);
|
||||
if (Math.abs(lastcenterYF - centerYF) <= 20 && lastItemName === itemName) {
|
||||
//log.info("调试-相同物品名和相近y坐标,本次不拾取");
|
||||
await sleep(2 * pickupDelay);
|
||||
lastcenterYF = -20;
|
||||
lastItemName = null;
|
||||
} else {
|
||||
keyPress("F");
|
||||
log.info(`交互或拾取:"${itemName}"`);
|
||||
lastcenterYF = centerYF;
|
||||
lastItemName = itemName;
|
||||
await sleep(pickupDelay);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
log.info("识别失败,尝试截图");
|
||||
await refreshTargetItems(centerYF);
|
||||
lastItemName = "";
|
||||
*/
|
||||
}
|
||||
|
||||
if (!foundTarget) {
|
||||
//log.info(`调试-执行滚轮动作`);
|
||||
const currentTime = new Date().getTime();
|
||||
if (currentTime - lastMoveDown > timeMoveUp) {
|
||||
await keyMouseScript.runFile(`assets/滚轮下翻.json`);
|
||||
if (thisMoveUpTime === 0) thisMoveUpTime = currentTime;
|
||||
if (currentTime - thisMoveUpTime >= timeMoveDown) {
|
||||
lastMoveDown = currentTime;
|
||||
thisMoveUpTime = 0;
|
||||
}
|
||||
} else {
|
||||
await keyMouseScript.runFile(`assets/滚轮上翻.json`);
|
||||
}
|
||||
await sleep(rollingDelay);
|
||||
}
|
||||
}
|
||||
|
||||
async function performTemplateMatch(centerYF) {
|
||||
try {
|
||||
let result;
|
||||
let itemName = null;
|
||||
for (const targetItem of targetItems) {
|
||||
let recognitionObject = RecognitionObject.TemplateMatch(targetItem.template, 1219, centerYF - 15, 32 + 30 * (targetItem.itemName.length) + 2, 30);
|
||||
result = gameRegion.find(recognitionObject);
|
||||
if (result.isExist()) {
|
||||
itemName = targetItem.itemName;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return itemName;
|
||||
} catch (error) {
|
||||
log.error(`模板匹配时发生异常: ${error.message}`);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async function findFIcon() {
|
||||
let recognitionObject = RecognitionObject.TemplateMatch(fIcontemplate, 1102, 335, 34, 400);
|
||||
try {
|
||||
let result = gameRegion.find(recognitionObject);
|
||||
if (result.isExist()) {
|
||||
return Math.round(result.y + result.height / 2);
|
||||
}
|
||||
} catch (error) {
|
||||
log.error(`识别图像时发生异常: ${error.message}`);
|
||||
if (!state.running)
|
||||
return null;
|
||||
}
|
||||
await sleep(100);
|
||||
return null;
|
||||
}
|
||||
|
||||
async function isMainUI() {
|
||||
const recognitionObject = RecognitionObject.TemplateMatch(mainUITemplate, 0, 0, 150, 150);
|
||||
const maxAttempts = 1;
|
||||
let attempts = 0;
|
||||
|
||||
while (attempts < maxAttempts && state.running) {
|
||||
try {
|
||||
const result = gameRegion.find(recognitionObject);
|
||||
if (result.isExist()) return true;
|
||||
} catch (error) {
|
||||
log.error(`识别图像时发生异常: ${error.message}`);
|
||||
if (!state.running) break;
|
||||
return false;
|
||||
}
|
||||
attempts++;
|
||||
await sleep(50);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"manifest_version": 1,
|
||||
"name": "AAA狗粮联机团购",
|
||||
"version": "1.3.2",
|
||||
"version": "1.4.0",
|
||||
"tags": [
|
||||
"狗粮"
|
||||
],
|
||||
|
||||