Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions repo/js/ArtifactsGroupPurchasing/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
* **预留足够的背包空间**:运行AAA狗粮批发将获取约150个圣遗物,运行本js将获取约230个圣遗物,请确保你的背包有足够的空间容纳这些圣遗物,建议在AAA狗粮批发中选择分解或摧毁,并预留380+的空间

## 更新日志
### 1.3.0(2025.09.17)
1.增加识别并点击复苏
### 1.2.7(2025.09.16)
1.修几处路线624①②③,509①
2.新增304神无卓狸猫火炬
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
235 changes: 135 additions & 100 deletions repo/js/ArtifactsGroupPurchasing/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -442,10 +442,7 @@ async function runGroupPurchasing(runExtra) {
}
if (!settings.runDebug) {
for (const { fullPath } of files) {
log.info(`开始执行路线: ${fullPath}`);
await fakeLog(`${fullPath}`, false, true, 0);
await pathingScript.runFile(fullPath);
await fakeLog(`${fullPath}`, false, false, 0);
await runPath(fullPath, 1);
}

log.info(`${folderName} 的全部路线已完成`);
Expand All @@ -469,10 +466,7 @@ async function runGroupPurchasing(runExtra) {

if (!settings.runDebug) {
for (const { fullPath } of files) {
log.info(`开始执行路线: ${fullPath}`);
await fakeLog(`${fullPath}`, false, true, 0);
await pathingScript.runFile(fullPath);
await fakeLog(`${fullPath}`, false, false, 0);
await runPath(fullPath, 1);
}

log.info(`额外 的全部路线已完成`);
Expand Down Expand Up @@ -508,101 +502,12 @@ async function runGroupPurchasing(runExtra) {
}

for (const { fullPath } of files) {
log.info(`开始执行路线: ${fullPath}`);
await fakeLog(`${fullPath}`, false, true, 0);
await pathingScript.runFile(fullPath);
await fakeLog(`${fullPath}`, false, false, 0);
await runPath(fullPath, 1);
}

log.info(`${folderName} 的全部路线已完成`);
}

// fakeLog 函数,使用方法:将本函数放在主函数前,调用时请务必使用await,否则可能出现v8白框报错
//在js开头处伪造该js结束运行的日志信息,如 await fakeLog("js脚本", true, true, 0);
//在js结尾处伪造该js开始运行的日志信息,如 await fakeLog("js脚本", true, false, 2333);
//duration项目仅在伪造结束信息时有效,且无实际作用,可以任意填写,当你需要在日志中输出特定值时才需要,单位为毫秒
//在调用地图追踪前伪造该地图追踪开始运行的日志信息,如 await fakeLog(`地图追踪.json`, false, true, 0);
//在调用地图追踪后伪造该地图追踪结束运行的日志信息,如 await fakeLog(`地图追踪.json`, false, false, 0);
//如此便可以在js运行过程中伪造地图追踪的日志信息,可以在日志分析等中查看

async function fakeLog(name, isJs, isStart, duration) {
await sleep(10);
const currentTime = Date.now();
// 参数检查
if (typeof name !== 'string') {
log.error("参数 'name' 必须是字符串类型!");
return;
}
if (typeof isJs !== 'boolean') {
log.error("参数 'isJs' 必须是布尔型!");
return;
}
if (typeof isStart !== 'boolean') {
log.error("参数 'isStart' 必须是布尔型!");
return;
}
if (typeof currentTime !== 'number' || !Number.isInteger(currentTime)) {
log.error("参数 'currentTime' 必须是整数!");
return;
}
if (typeof duration !== 'number' || !Number.isInteger(duration)) {
log.error("参数 'duration' 必须是整数!");
return;
}

// 将 currentTime 转换为 Date 对象并格式化为 HH:mm:ss.sss
const date = new Date(currentTime);
const hours = String(date.getHours()).padStart(2, '0');
const minutes = String(date.getMinutes()).padStart(2, '0');
const seconds = String(date.getSeconds()).padStart(2, '0');
const milliseconds = String(date.getMilliseconds()).padStart(3, '0');
const formattedTime = `${hours}:${minutes}:${seconds}.${milliseconds}`;

// 将 duration 转换为分钟和秒,并保留三位小数
const durationInSeconds = duration / 1000; // 转换为秒
const durationMinutes = Math.floor(durationInSeconds / 60);
const durationSeconds = (durationInSeconds % 60).toFixed(3); // 保留三位小数

// 使用四个独立的 if 语句处理四种情况
if (isJs && isStart) {
// 处理 isJs = true 且 isStart = true 的情况
const logMessage = `正在伪造js开始的日志记录\n\n` +
`[${formattedTime}] [INF] BetterGenshinImpact.Service.ScriptService\n` +
`------------------------------\n\n` +
`[${formattedTime}] [INF] BetterGenshinImpact.Service.ScriptService\n` +
`→ 开始执行JS脚本: "${name}"`;
log.debug(logMessage);
}
if (isJs && !isStart) {
// 处理 isJs = true 且 isStart = false 的情况
const logMessage = `正在伪造js结束的日志记录\n\n` +
`[${formattedTime}] [INF] BetterGenshinImpact.Service.ScriptService\n` +
`→ 脚本执行结束: "${name}", 耗时: ${durationMinutes}分${durationSeconds}秒\n\n` +
`[${formattedTime}] [INF] BetterGenshinImpact.Service.ScriptService\n` +
`------------------------------`;
log.debug(logMessage);
}
if (!isJs && isStart) {
// 处理 isJs = false 且 isStart = true 的情况
const logMessage = `正在伪造地图追踪开始的日志记录\n\n` +
`[${formattedTime}] [INF] BetterGenshinImpact.Service.ScriptService\n` +
`------------------------------\n\n` +
`[${formattedTime}] [INF] BetterGenshinImpact.Service.ScriptService\n` +
`→ 开始执行地图追踪任务: "${name}"`;
log.debug(logMessage);
}
if (!isJs && !isStart) {
// 处理 isJs = false 且 isStart = false 的情况
const logMessage = `正在伪造地图追踪结束的日志记录\n\n` +
`[${formattedTime}] [INF] BetterGenshinImpact.Service.ScriptService\n` +
`→ 脚本执行结束: "${name}", 耗时: ${durationMinutes}分${durationSeconds}秒\n\n` +
`[${formattedTime}] [INF] BetterGenshinImpact.Service.ScriptService\n` +
`------------------------------`;
log.debug(logMessage);
}
}
}

/**
* 自动联机脚本(整体打包为一个函数)
* @param {Object} autoEnterSettings 配置对象
Expand Down Expand Up @@ -676,7 +581,8 @@ async function autoEnter(autoEnterSettings) {
await sleep(1000); inputText(enteringUID);
await sleep(1000);
if (!await findAndClick(searchRo)) { await genshin.returnMainUi(); continue; }
if (await confirmSearchResult()) { await genshin.returnMainUi(); continue; }
await sleep(500);
if (!await confirmSearchResult()) { await genshin.returnMainUi(); log.warn("无搜索结果"); continue; }

await sleep(500);
if (!await findAndClick(requestEnterRo)) { await genshin.returnMainUi(); continue; }
Expand Down Expand Up @@ -744,7 +650,7 @@ async function autoEnter(autoEnterSettings) {
}

async function confirmSearchResult() {
for (let i = 0; i < 5; i++) {
for (let i = 0; i < 4; i++) {
const gameRegion = captureGameRegion();
const res = gameRegion.find(requestEnter2Ro);
gameRegion.dispose();
Expand Down Expand Up @@ -965,6 +871,91 @@ async function findTotalNumber() {
return count;
}

// fakeLog 函数,使用方法:将本函数放在主函数前,调用时请务必使用await,否则可能出现v8白框报错
//在js开头处伪造该js结束运行的日志信息,如 await fakeLog("js脚本", true, true, 0);
//在js结尾处伪造该js开始运行的日志信息,如 await fakeLog("js脚本", true, false, 2333);
//duration项目仅在伪造结束信息时有效,且无实际作用,可以任意填写,当你需要在日志中输出特定值时才需要,单位为毫秒
//在调用地图追踪前伪造该地图追踪开始运行的日志信息,如 await fakeLog(`地图追踪.json`, false, true, 0);
//在调用地图追踪后伪造该地图追踪结束运行的日志信息,如 await fakeLog(`地图追踪.json`, false, false, 0);
//如此便可以在js运行过程中伪造地图追踪的日志信息,可以在日志分析等中查看

async function fakeLog(name, isJs, isStart, duration) {
await sleep(10);
const currentTime = Date.now();
// 参数检查
if (typeof name !== 'string') {
log.error("参数 'name' 必须是字符串类型!");
return;
}
if (typeof isJs !== 'boolean') {
log.error("参数 'isJs' 必须是布尔型!");
return;
}
if (typeof isStart !== 'boolean') {
log.error("参数 'isStart' 必须是布尔型!");
return;
}
if (typeof currentTime !== 'number' || !Number.isInteger(currentTime)) {
log.error("参数 'currentTime' 必须是整数!");
return;
}
if (typeof duration !== 'number' || !Number.isInteger(duration)) {
log.error("参数 'duration' 必须是整数!");
return;
}

// 将 currentTime 转换为 Date 对象并格式化为 HH:mm:ss.sss
const date = new Date(currentTime);
const hours = String(date.getHours()).padStart(2, '0');
const minutes = String(date.getMinutes()).padStart(2, '0');
const seconds = String(date.getSeconds()).padStart(2, '0');
const milliseconds = String(date.getMilliseconds()).padStart(3, '0');
const formattedTime = `${hours}:${minutes}:${seconds}.${milliseconds}`;

// 将 duration 转换为分钟和秒,并保留三位小数
const durationInSeconds = duration / 1000; // 转换为秒
const durationMinutes = Math.floor(durationInSeconds / 60);
const durationSeconds = (durationInSeconds % 60).toFixed(3); // 保留三位小数

// 使用四个独立的 if 语句处理四种情况
if (isJs && isStart) {
// 处理 isJs = true 且 isStart = true 的情况
const logMessage = `正在伪造js开始的日志记录\n\n` +
`[${formattedTime}] [INF] BetterGenshinImpact.Service.ScriptService\n` +
`------------------------------\n\n` +
`[${formattedTime}] [INF] BetterGenshinImpact.Service.ScriptService\n` +
`→ 开始执行JS脚本: "${name}"`;
log.debug(logMessage);
}
if (isJs && !isStart) {
// 处理 isJs = true 且 isStart = false 的情况
const logMessage = `正在伪造js结束的日志记录\n\n` +
`[${formattedTime}] [INF] BetterGenshinImpact.Service.ScriptService\n` +
`→ 脚本执行结束: "${name}", 耗时: ${durationMinutes}分${durationSeconds}秒\n\n` +
`[${formattedTime}] [INF] BetterGenshinImpact.Service.ScriptService\n` +
`------------------------------`;
log.debug(logMessage);
}
if (!isJs && isStart) {
// 处理 isJs = false 且 isStart = true 的情况
const logMessage = `正在伪造地图追踪开始的日志记录\n\n` +
`[${formattedTime}] [INF] BetterGenshinImpact.Service.ScriptService\n` +
`------------------------------\n\n` +
`[${formattedTime}] [INF] BetterGenshinImpact.Service.ScriptService\n` +
`→ 开始执行地图追踪任务: "${name}"`;
log.debug(logMessage);
}
if (!isJs && !isStart) {
// 处理 isJs = false 且 isStart = false 的情况
const logMessage = `正在伪造地图追踪结束的日志记录\n\n` +
`[${formattedTime}] [INF] BetterGenshinImpact.Service.ScriptService\n` +
`→ 脚本执行结束: "${name}", 耗时: ${durationMinutes}分${durationSeconds}秒\n\n` +
`[${formattedTime}] [INF] BetterGenshinImpact.Service.ScriptService\n` +
`------------------------------`;
log.debug(logMessage);
}
}

// 定义 readFolder 函数
async function readFolder(folderPath, onlyJson) {
// 新增一个堆栈,初始时包含 folderPath
Expand Down Expand Up @@ -1018,3 +1009,47 @@ async function readFolder(folderPath, onlyJson) {

return files;
}

async function runPath(fullPath, targetItemPath) {
const 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 (!targetItemPath) return; // 没有拾取目录直接跳过
//dispatcher.addTimer(new RealtimeTimer("AutoPick"));
while (state.running) {
await sleep(1000);
}
//dispatcher.ClearAllTriggers();

})();

const errorProcessTask = (async () => {
const revivalRo1 = RecognitionObject.TemplateMatch(file.ReadImageMatSync("assets/RecognitionObject/revival1.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]);
}
7 changes: 4 additions & 3 deletions repo/js/ArtifactsGroupPurchasing/manifest.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
{
"manifest_version": 1,
"name": "AAA狗粮联机团购",
"version": "1.2.7",
"version": "1.3.0",
"tags": [
"狗粮"
],
"description": "配合AAA狗粮批发使用,联机运行多条收尾路线",
"saved_files": [
"records/*.txt"
"records/*.txt",
"targets/*.png"
],
"authors": [
{
Expand All @@ -21,4 +22,4 @@
],
"settings_ui": "settings.json",
"main": "main.js"
}
}
2 changes: 2 additions & 0 deletions repo/js/AutoHoeingOneDragon/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@

---
### 更新日志
### 1.6.3(2025.09.17)
1.修正汐佬乱填的路线信息
### 1.6.2(2025.09.16)
1.增加路线:挪德卡莱精英
### 1.6.1(2025.09.15)
Expand Down
Loading