JS脚本:提瓦特自动钓鱼【更新】 (#1354)

This commit is contained in:
提瓦特钓鱼玳师
2025-07-16 23:13:14 +08:00
committed by GitHub
parent 91fd9eeb2f
commit 24f70e0fe2
4 changed files with 245 additions and 30 deletions

View File

@@ -0,0 +1,31 @@
脚本名称:提瓦特自动钓鱼(全流程+自选)
功能描述支持自动追踪并垂钓bgi支持的全提瓦特垂钓点
## 核心功能
1. 可自选地区、鱼类、鱼饵
2. 可直接钓取特定物品的兑换材料(例如渔获)
3. 脚本会根据需要的鱼类自动调节时间,不需要的时段会跳过
4. 支持部分地图追踪无法到达的钓鱼点(例如炽岩斗士急流鱼钓鱼点,枫丹廷东北钓鱼点、雷鸣仙垂钓点)
5. 支持从特定的垂钓点继续任务(仅启用所有垂钓点时可用)
6. 默认禁用需要战斗的路线如有需要请在JS脚本配置内启用
7. 支持自定义钓鱼超时时间
8. 支持设置定时关闭最多24小时
9. 4点自动领取月卡可选
10. 自动记录垂钓点冷却时间(进入其他世界钓鱼时请关闭此功能)
11. 启用自动拾取(可选)
## 注意事项
1. 部分点位涉及战斗,且队伍内不能有双风和跑步(不是冲刺)时加移速的角色
2. 跑图位必须是少男体型(防止键鼠路线[GCM]出错)
3. 同时选择鱼类和鱼饵的情况下按照以下逻辑选择路线: 所有被选的鱼类会被加入任务列表,如果选择的鱼饵中某个鱼饵不是已选的任何一个鱼类的对应的鱼饵,那么这个鱼饵对应的所有鱼类将被添加到任务列表
4. JS脚本的设置内各设置项含有优先级如果存在高优先级且选项不为默认则只有最高优先级的设置项生效
5. 部分钓鱼点为路径追踪+键鼠脚本(GCM)的混合模式可能会出现因键鼠脚本误差卡死的情况如果出现这种情况请在JS脚本设置禁用键鼠路线来禁用所有包含键鼠脚本的钓鱼点
## 其它
作者:提瓦特钓鱼玳师
脚本反馈邮箱hijiwos@hotmail.com

View File

@@ -1,4 +1,4 @@
(async function () {
(async function () { // 多人模式不计CDCD读写仍有优化空间
const area_list = ['蒙德', '璃月', '稻妻', '须弥', '枫丹', '纳塔', '至冬', '层岩巨渊·地下矿区', '渊下宫']
const fish_list = ['花鳉', '波波心羽鲈', '烘烘心羽鲈', '维护机关·水域清理者', '维护机关·态势控制者', '维护机关·澄金领队型', '海涛斧枪鱼', '维护机关·初始能力型', '维护机关·白金典藏型', '吹沙角鲀', '甜甜花鳉', '擒霞客', '水晶宴', '斗棘鱼', '炮鲀', '流纹褐蝶鱼', '锖假龙', '金赤假龙', '玉玉心羽鲈', '赤魔王', '长生仙', '苦炮鲀', '肺棘鱼', '流纹京紫蝶鱼', '琉璃花鳉', '伪装鲨鲨独角鱼', '繁花斗士急流鱼', '深潜斗士急流鱼', '晚霞翻车鲀', '青浪翻车鲀', '拟似燃素独角鱼', '炽岩斗士急流鱼', '蓝染花鳉', '鸩棘鱼', '流纹茶蝶鱼', '雪中君', '真果角鲀', '青金斧枪鱼', '暮云角鲀', '翡玉斧枪鱼', '沉波蜜桃', '雷鸣仙', '佛玛洛鳐', '迪芙妲鳐', '秘源机关·巡戒使']
@@ -158,6 +158,95 @@
// 存储本次任务中的所有鱼类,作为调节时间的关键参考
let list_fish = [];
/**
*
* 将毫秒形式的字符串转换为更清晰的时间格式
*
* @param ms
* @returns {string}
*/
function formatTimeDifference(ms) {
ms = Number(ms);
// 计算天、小时、分钟、秒
const seconds = Math.floor(ms / 1000);
const minutes = Math.floor(seconds / 60);
const hours = Math.floor(minutes / 60);
const days = Math.floor(hours / 24);
// 计算剩余的小时、分钟、秒
const remainingHours = hours % 24;
const remainingMinutes = minutes % 60;
const remainingSeconds = seconds % 60;
// 返回格式化字符串
return `${days}${remainingHours}小时 ${remainingMinutes}分钟 ${remainingSeconds}`;
}
/**
*
* 垂钓点CD存档写入
*
* @param {string} pathing_name 路径名称
* @param {string} time_status 垂钓点时间状态(白天,夜晚)
* @param {string} timestamp 时间戳
* @param {string} user_id 原神UID
*/
function write_archive(pathing_name, time_status, timestamp, user_id) {
let assets_dir = Array.from(file.readPathSync("assets"));
let content = {};
if (assets_dir.includes("assets\\archive.json")) {
content = JSON.parse(file.readTextSync("assets/archive.json"));
if (time_status === "全天") {
content[user_id][pathing_name]["Daytime"] = timestamp;
content[user_id][pathing_name]["Nighttime"] = timestamp;
} else if (time_status === "白天") {
content[user_id][pathing_name]["Daytime"] = timestamp;
content[user_id][pathing_name]["Nighttime"] = Object.keys(content[user_id][pathing_name]).includes("Nighttime") ? content[user_id][pathing_name]["Nighttime"]: null;
} else if (time_status === "夜晚") {
content[user_id][pathing_name]["Daytime"] = Object.keys(content[user_id][pathing_name]).includes("Daytime") ? content[user_id][pathing_name]["Daytime"]: null;
content[user_id][pathing_name]["Nighttime"] = timestamp;
}
} else {
content[user_id] = {};
content[user_id][pathing_name] = {
"Daytime": time_status === "白天" || time_status === "全天" ? timestamp : null,
"Nighttime": time_status === "夜晚" || time_status === "全天" ? timestamp : null
};
}
file.WriteTextSync("assets/archive.json", JSON.stringify(content, null, 2), false);
}
/**
*
* 垂钓点CD存档读取
*
* @param {string} pathing_name 路径名称
* @param {string} user_id 原神UID
*
* @return Daytime/Nighttime 字典
*/
function read_archive(pathing_name, user_id) {
let assets_dir = Array.from(file.readPathSync("assets"));
if (assets_dir.includes("assets\\archive.json")) {
let content = JSON.parse(file.readTextSync("assets/archive.json"));
if (Object.keys(content).includes(user_id)) {
if (Object.keys(content[user_id]).includes(pathing_name)) {
return content[user_id][pathing_name];
} else {
return null;
}
} else {
return null;
}
} else {
return null;
}
}
/**
* 获取路径包含的信息
*
@@ -298,7 +387,7 @@
}
}
async function run_file(path_msg, time_out_throw, time_out_whole, is_con, block_gcm, block_fight, block_tsurumi, auto_skip) {
async function run_file(path_msg, time_out_throw, time_out_whole, is_con, block_gcm, block_fight, block_tsurumi, auto_skip, fishing_cd, uid = "default_user") {
const base_path_pathing = "assets/pathing/";
const base_path_gcm = "assets/KeyMouseScript/";
const base_path_statues = "assets/pathing_statues/";
@@ -408,7 +497,65 @@
log.info(`该钓鱼点的时间: ${fishing_time}`);
await pathingScript.runFile(base_path_pathing + file_name + ".json");
// 检查垂钓点CD
if (fishing_cd) {
let current_cd = read_archive(file_name, uid);
if (current_cd !== null) {
const now = Date.now();
if (fishing_time === "全天") {
let daytime = true;
if (current_cd["Daytime"] !== null) {
let difference = now - current_cd["Daytime"];
if (difference < 259200000) {
log.info(`该垂钓点(白天)处于冷却状态,剩余时间: ${formatTimeDifference(259200000 - difference)}`);
log.info(`${file_name}(白天) 已跳过...`);
daytime = false;
fishing_time = "夜晚";
} else {
log.info(`该垂钓点(白天)未处于冷却状态,闲置时间: ${formatTimeDifference(difference - 259200000)}`);
}
}
if (current_cd["Nighttime"] !== null) {
let difference = now - current_cd["Nighttime"];
if (difference < 259200000) {
log.info(`该垂钓点(夜晚)处于冷却状态,剩余时间: ${formatTimeDifference(259200000 - difference)}`);
log.info(`${file_name}(夜晚) 已跳过...`);
if (daytime) {
fishing_time = "白天";
} else {
return null;
}
} else {
log.info(`该垂钓点(夜晚)未处于冷却状态,闲置时间: ${formatTimeDifference(difference - 259200000)}`);
}
}
} else if (fishing_time === "白天") {
if (current_cd["Daytime"] !== null) {
let difference = now - current_cd["Daytime"];
if (difference < 259200000) {
log.info(`该垂钓点(白天)处于冷却状态,剩余时间: ${formatTimeDifference(259200000 - difference)}`);
log.info(`${file_name}(白天) 已跳过...`);
return null;
} else {
log.info(`该垂钓点(白天)未处于冷却状态,闲置时间: ${formatTimeDifference(difference - 259200000)}`);
}
}
} else if (fishing_time === "夜晚") {
if (current_cd["Nighttime"] !== null) {
let difference = now - current_cd["Nighttime"];
if (difference < 259200000) {
log.info(`该垂钓点(夜晚)处于冷却状态,剩余时间: ${formatTimeDifference(259200000 - difference)}`);
log.info(`${file_name}(夜晚) 已跳过...`);
return null;
} else {
log.info(`该垂钓点(夜晚)未处于冷却状态,闲置时间: ${formatTimeDifference(difference - 259200000)}`);
}
}
}
}
}
//await pathingScript.runFile(base_path_pathing + file_name + ".json");
// 执行键鼠脚本
if (path_msg["addition"] === "GCM") {
@@ -417,11 +564,15 @@
// 调用自动钓鱼
// await genshin.autofishing(fishing_time_dic[fishing_time]["param"]);
await dispatcher.runTask(new SoloTask("AutoFishing", {
"fishingTimePolicy": fishing_time_dic[fishing_time]["param"],
"throwRodTimeOutTimeoutSeconds": time_out_throw,
"wholeProcessTimeoutSeconds": time_out_whole
}));
// await dispatcher.runTask(new SoloTask("AutoFishing", {
// "fishingTimePolicy": fishing_time_dic[fishing_time]["param"],
// "throwRodTimeOutTimeoutSeconds": time_out_throw,
// "wholeProcessTimeoutSeconds": time_out_whole
// }));
if (fishing_cd) {
write_archive(file_name, fishing_time, Date.now(), uid);
}
}
async function main() {
@@ -451,12 +602,33 @@
const auto_pick = typeof(settings.auto_pick) === 'undefined' ? false : settings.auto_pick;
// 读取4点自动领取月卡的设置
const auto_skip = typeof(settings.auto_skip) === 'undefined' ? false : settings.auto_skip;
// 读取垂钓点CD统计
const fishing_cd = typeof(settings.fishing_cd) === 'undefined' ? false: settings.fishing_cd;
// 读取终止时间
const kill_hour = typeof(settings.time_kill_hour) === 'undefined' ? "无" : settings.time_kill_hour;
const kill_minute = typeof(settings.time_kill_minute) === 'undefined' ? "无" : settings.time_kill_minute;
const is_time_kill = kill_hour !== "无" && kill_minute !== "无"; // 判断是否启用
let time_target = new Date();
// 获取当前用户UID
let uid = "default_user";
if (fishing_cd) {
const ocrRo = RecognitionObject.Ocr(166, 198, 120, 22);
genshin.returnMainUi();
await sleep(1000);
keyPress("Escape");
await sleep(1000);
let ocr = captureGameRegion().Find(ocrRo); // 当前页面OCR
if (ocr.isExist()) {
uid = ocr.text;
}
keyPress("Escape");
}
if (is_time_kill) {
let now = new Date();
time_target.setHours(parseInt(kill_hour), 10);
@@ -495,8 +667,7 @@
}
// 路径详细信息
const path_msg = get_pathing_msg(path_filter[i]);
try {
await sleep(100);
// try {
let current_msg = `${path_msg["area"]}-${path_msg["detail"]}`
log.info(`当前钓鱼点: ${current_msg}(进度: ${i + 1}/${path_filter.length})`);
if (path_continue === current_msg) {
@@ -509,13 +680,13 @@
continue;
}
await run_file(path_msg, time_out_throw, time_out_whole, is_con, block_gcm, block_fight, block_tsurumi, auto_skip);
} catch (error) {
const file_name = `${path_msg["area"]}-${path_msg["type"]}-${path_msg["detail"]}`;
log.info(`路径: ${file_name} 执行时出错,已跳过...\n错误信息: ${error}`)
}
await run_file(path_msg, time_out_throw, time_out_whole, is_con, block_gcm, block_fight, block_tsurumi, auto_skip, fishing_cd, uid);
// } catch (error) {
// const file_name = `${path_msg["area"]}-${path_msg["type"]}-${path_msg["detail"]}`;
// log.info(`路径: ${file_name} 执行时出错,已跳过...\n错误信息: ${error}`)
// }
}
}
await main();
})();
})();

View File

@@ -1,15 +1,14 @@
{
"manifest_version": 1,
"name": "提瓦特自动钓鱼(全流程+自选)",
"version": "2.1.0",
"bgi_version": "0.45.0",
"description": "脚本名称:提瓦特自动钓鱼(全流程+自选)\n功能描述支持自动追踪并垂钓bgi支持的全提瓦特垂钓点\n核心功能------------------------------>\n1.可自选地区、鱼类、鱼饵\n2.可直接钓取特定物品的兑换材料(例如渔获)\n3.脚本会根据需要的鱼类自动调节时间,不需要的时段会跳过\n4.支持部分地图追踪无法到达的钓鱼点(例如炽岩斗士急流鱼钓鱼点,枫丹廷东北钓鱼点、雷鸣仙垂钓点)\n5.支持从特定的垂钓点继续任务(仅启用所有垂钓点时可用)\n6.默认禁用需要战斗的路线如有需要请在JS脚本配置内启用\n7.支持自定义钓鱼超时时间\n8.支持设置定时关闭最多24小时\n9.4点自动领取月卡(可选)\n10.启用自动拾取(可选)\n注意事项------------------------------>\n1.部分点位涉及战斗,且队伍内不能有双风和跑步(不是冲刺)时加移速的角色\n2.跑图位必须是少男体型(防止键鼠路线[GCM]出错)\n3.同时选择鱼类和鱼饵的情况下按照以下逻辑选择路线: 所有被选的鱼类会被加入任务列表,如果选择的鱼饵中某个鱼饵不是已选的任何一个鱼类的对应的鱼饵,那么这个鱼饵对应的所有鱼类将被添加到任务列表\n4.JS脚本的设置内各设置项含有优先级如果存在高优先级且选项不为默认则只有最高优先级的设置项生效\n5.部分钓鱼点为路径追踪+键鼠脚本(GCM)的混合模式可能会出现因键鼠脚本误差卡死的情况如果出现这种情况请在JS脚本设置禁用键鼠路线来禁用所有包含键鼠脚本的钓鱼点\n---------------------------------------->\n作者提瓦特钓鱼玳师\n脚本反馈邮箱hijiwos@hotmail.com",
"version": "2.2.0",
"bgi_version": "0.47.0",
"description": "脚本名称:提瓦特自动钓鱼(全流程+自选)\n功能描述支持自动追踪并垂钓bgi支持的全提瓦特垂钓点\n核心功能------------------------------>\n1.可自选地区、鱼类、鱼饵\n2.可直接钓取特定物品的兑换材料(例如渔获)\n3.脚本会根据需要的鱼类自动调节时间,不需要的时段会跳过\n4.支持部分地图追踪无法到达的钓鱼点(例如炽岩斗士急流鱼钓鱼点,枫丹廷东北钓鱼点、雷鸣仙垂钓点)\n5.支持从特定的垂钓点继续任务(仅启用所有垂钓点时可用)\n6.默认禁用需要战斗的路线如有需要请在JS脚本配置内启用\n7.支持自定义钓鱼超时时间\n8.支持设置定时关闭最多24小时\n9.4点自动领取月卡(可选)\n10.自动记录垂钓点冷却时间(进入其他世界钓鱼时请关闭此功能)\n11.启用自动拾取(可选)\n注意事项------------------------------>\n1.部分点位涉及战斗,且队伍内不能有双风和跑步(不是冲刺)时加移速的角色\n2.跑图位必须是少男体型(防止键鼠路线[GCM]出错)\n3.同时选择鱼类和鱼饵的情况下按照以下逻辑选择路线: 所有被选的鱼类会被加入任务列表,如果选择的鱼饵中某个鱼饵不是已选的任何一个鱼类的对应的鱼饵,那么这个鱼饵对应的所有鱼类将被添加到任务列表\n4.JS脚本的设置内各设置项含有优先级如果存在高优先级且选项不为默认则只有最高优先级的设置项生效\n5.部分钓鱼点为路径追踪+键鼠脚本(GCM)的混合模式可能会出现因键鼠脚本误差卡死的情况如果出现这种情况请在JS脚本设置禁用键鼠路线来禁用所有包含键鼠脚本的钓鱼点\n---------------------------------------->\n作者提瓦特钓鱼玳师\n脚本反馈邮箱hijiwos@hotmail.com",
"authors": [
{
"name": "提瓦特钓鱼玳师",
"links": "https://github.com/Hijiwos"
"name": "提瓦特钓鱼玳师"
}
],
"settings_ui": "settings.json",
"main": "main.js"
}
}

View File

@@ -2,7 +2,8 @@
{
"name": "show_info",
"type": "input-text",
"label": "下方输入的内容用空格隔开、括号内是优先级\n只会执行当前非默认最高优先级的选项"
"label": "下方输入的内容用空格隔开、括号内是优先级\n只会执行当前非默认最高优先级的选项",
"default": "该输入框无需输入内容"
},
{
"name": "path_sort_area",
@@ -127,22 +128,32 @@
{
"name": "time_out_throw",
"type": "input-text",
"label": "自动抛竿未上钩超时时间(秒) 默认: 10"
"label": "自动抛竿未上钩超时时间(秒)",
"default": 10
},
{
"name": "time_out_whole",
"type": "input-text",
"label": "整个任务超时时间(秒) 默认: 300"
"label": "整个任务超时时间(秒)",
"default": 300
},
{
"name": "auto_pick",
"type": "checkbox",
"label": "启用自动拾取(默认禁用)"
"label": "启用自动拾取",
"default": false
},
{
"name": "auto_skip",
"type": "checkbox",
"label": "启用4点领取月卡(默认禁用)"
"label": "启用4点领取月卡",
"default": false
},
{
"name": "fishing_cd",
"type": "checkbox",
"label": "启用垂钓点CD统计(自动跳过冷却中的垂钓点)",
"default": true
},
{
"name": "time_kill_hour",
@@ -247,17 +258,20 @@
{
"name": "block_gcm",
"type": "checkbox",
"label": "禁用键鼠路线(默认启用键鼠路线)"
"label": "禁用键鼠路线(启用前请自行了解队伍配置要求)",
"default": false
},
{
"name": "block_fight",
"type": "checkbox",
"label": "启用战斗路线(默认禁用战斗路线)"
"label": "启用战斗路线(需要自行配置战斗策略)",
"default": false
},
{
"name": "block_tsurumi",
"type": "checkbox",
"label": "启用鹤观路线(默认禁用鹤观路线)"
"label": "启用鹤观路线(请确保任务已经完成,小道具交互的点位尚不可用)",
"default": false
},
{
"name": "path_select",