JS脚本:一只爱可菲(厨娘版)【更新】、JS脚本:联机锄地【新增】 (#973)

* JS脚本:一只爱可菲(厨娘版)【更新】

* JS脚本:联机锄地【新增】

* 修正了几个问题
This commit is contained in:
提瓦特钓鱼玳师
2025-06-04 21:34:37 +08:00
committed by GitHub
parent 3a2db6ee8b
commit 3e0cbca7ca
11 changed files with 2246 additions and 276 deletions

File diff suppressed because one or more lines are too long

View File

@@ -1,7 +1,7 @@
{ {
"manifest_version": 1, "manifest_version": 1,
"name": "一只爱可菲(厨娘版)", "name": "一只爱可菲(厨娘版)",
"version": "1.2.2", "version": "1.2.3",
"bgi_version": "0.45.0", "bgi_version": "0.45.0",
"description": "脚本名称:一只爱可菲(厨娘版)\n功能描述专精料理制作的爱可菲(自动烹饪及解锁、特殊料理)\n核心功能------------------------------>\n1.自动烹饪:支持手动烹饪和自动烹饪,支持只刷满熟练度\n2.自动特殊料理:支持根据菜名和角色名自动进行单/多个特殊料理的烹饪(可以调节预期数量)\n3.其他料理获取:除了烹饪以外的部分料理的获取[仅有数据,未实装]\n注意事项------------------------------>\n1.请确保原神分辨率是1920x1080\n2.请尽量确保食材充足,如果食材不充足会自动跳过\n---------------------------------------->\n作者提瓦特钓鱼玳师\n脚本反馈邮箱hijiwos@hotmail.com", "description": "脚本名称:一只爱可菲(厨娘版)\n功能描述专精料理制作的爱可菲(自动烹饪及解锁、特殊料理)\n核心功能------------------------------>\n1.自动烹饪:支持手动烹饪和自动烹饪,支持只刷满熟练度\n2.自动特殊料理:支持根据菜名和角色名自动进行单/多个特殊料理的烹饪(可以调节预期数量)\n3.其他料理获取:除了烹饪以外的部分料理的获取[仅有数据,未实装]\n注意事项------------------------------>\n1.请确保原神分辨率是1920x1080\n2.请尽量确保食材充足,如果食材不充足会自动跳过\n---------------------------------------->\n作者提瓦特钓鱼玳师\n脚本反馈邮箱hijiwos@hotmail.com",
"authors": [ "authors": [

View File

@@ -1,14 +1,262 @@
[ { [
{
"name": "food_choice_single_select", "name": "food_choice_single_select",
"type": "select", "type": "select",
"label": "<-----------------------------烹饪----------------------------->\n\n注意:单选的料理和多选的料理均会加入烹饪队列\n\n[普通料理(单选)]-所有料理(全部类别)\n (单选,下方多选有值不生效)\n\n", "label": "<-----------------------------烹饪----------------------------->\n\n注意:单选的料理和多选的料理均会加入烹饪队列\n\n[普通料理(单选)]-所有料理(全部类别)\n (单选,下方多选有值不生效)\n\n",
"options": ["无(默认)", "全部料理", "酪香蟹蟹锅", "丰稔之赐", "沃陆果饮", "粒果膨膨棒", "酪烤菇菇串", "乌乌黑蛋", "钱汤馒头", "梅落雪间醉", "炎岩之颂", "清心花饼", "奇瑰之汤", "纵声欢唱", "山与海与天空", "火山蛋糕", "粒果裹裹", "苦水", "串烤牛心", "宝石闪闪", "温泉时光", "咚咚嘭嘭", "苹果金条条", "塔塔可", "兽肉旋风", "巧克力", "龙龙饼干", "奇旅馔匣", "夹心土豆泥", "炸虾豆球", "火焰炖肉", "「强水」", "苹果卷卷", "多彩之森", "粒果肉汤", "粒果片片", "酸汁腌鱼", "薄荷酱烤鱼", "粒果杯", "膨膨冰淇淋", "酥酥羊角包", "奶油炖鸡", "桔香鸭胸肉", "泡泡舒芙蕾", "肉满满寿司", "八宝福禄鸭", "茶好月圆", "知足常乐", "红烧肉圆", "繁弦急管", "宾至如归", "金玉满堂", "茶熏乳鸽", "油爆双脆", "古华鱼羊鲜", "玉纹茶叶蛋", "沉玉茶露", "蜜汁叉烧", "千灵慕斯", "缤纷马卡龙", "圈圈圆圆", "致水神", "羊杂哈吉斯", "桔桔薄饼", "港湾牛肚", "咖啡芭芭露", "卡苏莱砂锅", "纳博内番茄盅", "「纯洁之水」", "百味一缕", "苹果黑布丁", "香烤肋排", "杏仁鳟鱼", "韦西鸡", "花果三重奏", "果果仙酪", "鱼鱼咏唱派", "炸鱼薯条", "生肉塔塔", "肉酱千层面", "白淞鲜汤", "膨膨泡芙", "双果清露", "果果软糖", "晶螺糕", "枫丹肥肝", "奶油蘑菇汤", "塔塞斯杂烩", "浮露白霜", "蒜香面包棍", "水乡肉冻", "枫丹洋葱汤", "油封鸭腿", "琼玉果汤", "脆饼珐提", "超级至尊披萨", "蜜金泡果", "薄荷曼果茶", "镀金锅", "秘香肉团", "萨布兹炖肉", "萨巴桑炸角", "蔷薇奶糊", "帕蒂沙兰布丁", "椰炭饼", "千层酥酥", "假日果酿", "枣椰蜜糖", "阿如拌饭", "唐杜尔烤鸡", "肉肉烤蘑菇披萨", "兽米香香", "土豆船", "口袋饼", "奶香菌菇脆塔", "米圆塔", "黄油鸡", "日落莓莓茶", "雨林沙拉", "绿汁脆球", "咖喱虾", "奶酱鲜鱼", "烤肉卷", "马萨拉芝士球", "杂菇荟萃", "薄荷豆汤", "兰巴德鱼卷", "紫苑云霓", "炸肉排三明治", "山家烧", "乌冬面", "丰年有余", "龙须面", "五宝腌菜", "鳗肉茶泡饭", "绯樱虾仙贝", "树莓水馒头", "鲜鱼炖萝卜", "若竹煮", "荞麦面", "辣肉窝窝头", "蛋包饭", "米饭布丁", "文心豆腐", "活力喵饭", "日落鲷鱼烧", "红烩兽肉", "多多烧", "蒲烧鳗肉", "甜虾寿司", "鸟蛋寿司", "刺身拼盘", "黄油蟹蟹", "绀田煮", "绯樱饼", "兽骨拉面", "三彩团子", "绯樱天妇罗", "串串三味", "渡来禽肉", "市井杂煮", "什锦炒面", "金枪鱼寿司", "饭团", "蟹黄壳壳烧", "鸟蛋烧", "干烧香鱼", "味噌汤", "鸡豆花", "清炒虾仁", "米窝窝", "干锅腊肉", "蟹黄豆腐", "干炒鱼河", "大黄金吮指鸡", "兽肉薄荷卷", "脆脆鸡腿堡", "鲜虾脆薯盏", "香浓土豆泥", "凉拌薄荷", "薄荷果冻", "明月蛋", "素鲍鱼", "岩港三鲜", "四方和平", "绝云锅巴", "黄油煎鱼", "稠汁蔬菜炖肉", "天枢肉", "月亮派", "金丝虾球", "北地苹果焖肉", "腌笃鲜", "扣三丝", "冒险家蛋堡", "莲花酥", "仙跳墙", "翡玉什锦袋", "黄金蟹", "中原杂碎", "蜜酱胡萝卜煎肉", "风神杂烩菜", "蟹黄火腿焗时蔬", "蒙德土豆饼", "松鼠鱼", "水煮黑背鲈", "烤蘑菇披萨", "冷肉拼盘", "黄油松茸", "轻策农家菜", "「堆高高」", "来来菜", "嘟嘟莲海鲜羹", "白汁时蔬烩肉", "莲子禽蛋羹", "庄园烤松饼", "山珍热卤面", "北地烟熏鸡", "松茸酿肉卷", "甜甜花酿鸡", "水晶虾", "火火肉酱面", "炸萝卜丸子", "杏仁豆腐", "香嫩椒椒鸡", "满足沙拉", "珍珠翡翠白玉汤", "渔人吐司", "蒙德烤鱼", "摩拉肉", "爆炒肉片", "提瓦特煎蛋", "烤肉排", "野菇鸡肉串", "烤吃虎鱼", "萝卜时蔬汤"] "options": [
"无(默认)",
"全部料理",
"酪香蟹蟹锅",
"丰稔之赐",
"沃陆果饮",
"粒果膨膨棒",
"酪烤菇菇串",
"乌乌黑蛋",
"钱汤馒头",
"梅落雪间醉",
"炎岩之颂",
"清心花饼",
"奇瑰之汤",
"纵声欢唱",
"山与海与天空",
"火山蛋糕",
"粒果裹裹",
"苦水",
"串烤牛心",
"宝石闪闪",
"温泉时光",
"咚咚嘭嘭",
"苹果金条条",
"塔塔可",
"兽肉旋风",
"巧克力",
"龙龙饼干",
"奇旅馔匣",
"夹心土豆泥",
"炸虾豆球",
"火焰炖肉",
"「强水」",
"苹果卷卷",
"多彩之森",
"粒果肉汤",
"粒果片片",
"酸汁腌鱼",
"薄荷酱烤鱼",
"粒果杯",
"膨膨冰淇淋",
"酥酥羊角包",
"奶油炖鸡",
"桔香鸭胸肉",
"泡泡舒芙蕾",
"肉满满寿司",
"八宝福禄鸭",
"茶好月圆",
"知足常乐",
"红烧肉圆",
"繁弦急管",
"宾至如归",
"金玉满堂",
"茶熏乳鸽",
"油爆双脆",
"古华鱼羊鲜",
"玉纹茶叶蛋",
"沉玉茶露",
"蜜汁叉烧",
"千灵慕斯",
"缤纷马卡龙",
"圈圈圆圆",
"致水神",
"羊杂哈吉斯",
"桔桔薄饼",
"港湾牛肚",
"咖啡芭芭露",
"卡苏莱砂锅",
"纳博内番茄盅",
"「纯洁之水」",
"百味一缕",
"苹果黑布丁",
"香烤肋排",
"杏仁鳟鱼",
"韦西鸡",
"花果三重奏",
"果果仙酪",
"鱼鱼咏唱派",
"炸鱼薯条",
"生肉塔塔",
"肉酱千层面",
"白淞鲜汤",
"膨膨泡芙",
"双果清露",
"果果软糖",
"晶螺糕",
"枫丹肥肝",
"奶油蘑菇汤",
"塔塞斯杂烩",
"浮露白霜",
"蒜香面包棍",
"水乡肉冻",
"枫丹洋葱汤",
"油封鸭腿",
"琼玉果汤",
"脆饼珐提",
"超级至尊披萨",
"蜜金泡果",
"薄荷曼果茶",
"镀金锅",
"秘香肉团",
"萨布兹炖肉",
"萨巴桑炸角",
"蔷薇奶糊",
"帕蒂沙兰布丁",
"椰炭饼",
"千层酥酥",
"假日果酿",
"枣椰蜜糖",
"阿如拌饭",
"唐杜尔烤鸡",
"肉肉烤蘑菇披萨",
"兽米香香",
"土豆船",
"口袋饼",
"奶香菌菇脆塔",
"米圆塔",
"黄油鸡",
"日落莓莓茶",
"雨林沙拉",
"绿汁脆球",
"咖喱虾",
"奶酱鲜鱼",
"烤肉卷",
"马萨拉芝士球",
"杂菇荟萃",
"薄荷豆汤",
"兰巴德鱼卷",
"紫苑云霓",
"炸肉排三明治",
"山家烧",
"乌冬面",
"丰年有余",
"龙须面",
"五宝腌菜",
"鳗肉茶泡饭",
"绯樱虾仙贝",
"树莓水馒头",
"鲜鱼炖萝卜",
"若竹煮",
"荞麦面",
"辣肉窝窝头",
"蛋包饭",
"米饭布丁",
"文心豆腐",
"活力喵饭",
"日落鲷鱼烧",
"红烩兽肉",
"多多烧",
"蒲烧鳗肉",
"甜虾寿司",
"鸟蛋寿司",
"刺身拼盘",
"黄油蟹蟹",
"绀田煮",
"绯樱饼",
"兽骨拉面",
"三彩团子",
"绯樱天妇罗",
"串串三味",
"渡来禽肉",
"市井杂煮",
"什锦炒面",
"金枪鱼寿司",
"饭团",
"蟹黄壳壳烧",
"鸟蛋烧",
"干烧香鱼",
"味噌汤",
"鸡豆花",
"清炒虾仁",
"米窝窝",
"干锅腊肉",
"蟹黄豆腐",
"干炒鱼河",
"大黄金吮指鸡",
"兽肉薄荷卷",
"脆脆鸡腿堡",
"鲜虾脆薯盏",
"香浓土豆泥",
"凉拌薄荷",
"薄荷果冻",
"明月蛋",
"素鲍鱼",
"岩港三鲜",
"四方和平",
"绝云锅巴",
"黄油煎鱼",
"稠汁蔬菜炖肉",
"天枢肉",
"月亮派",
"金丝虾球",
"北地苹果焖肉",
"腌笃鲜",
"扣三丝",
"冒险家蛋堡",
"莲花酥",
"仙跳墙",
"翡玉什锦袋",
"黄金蟹",
"中原杂碎",
"蜜酱胡萝卜煎肉",
"风神杂烩菜",
"蟹黄火腿焗时蔬",
"蒙德土豆饼",
"松鼠鱼",
"水煮黑背鲈",
"烤蘑菇披萨",
"冷肉拼盘",
"黄油松茸",
"轻策农家菜",
"「堆高高」",
"来来菜",
"嘟嘟莲海鲜羹",
"白汁时蔬烩肉",
"莲子禽蛋羹",
"庄园烤松饼",
"山珍热卤面",
"北地烟熏鸡",
"松茸酿肉卷",
"甜甜花酿鸡",
"水晶虾",
"火火肉酱面",
"炸萝卜丸子",
"杏仁豆腐",
"香嫩椒椒鸡",
"满足沙拉",
"珍珠翡翠白玉汤",
"渔人吐司",
"蒙德烤鱼",
"摩拉肉",
"爆炒肉片",
"提瓦特煎蛋",
"烤肉排",
"野菇鸡肉串",
"烤吃虎鱼",
"萝卜时蔬汤"
]
}, },
{ {
"name": "food_Max_HP_Boost", "name": "food_Max_HP_Boost",
"type": "select", "type": "select",
"label": "\n\n[普通料理(单选)]-生命上限提升", "label": "\n\n[普通料理(单选)]-生命上限提升",
"options": ["无(默认)", "全部料理", "酪香蟹蟹锅", "金玉满堂", "「普茹斯蒂司」", "致水神", "镀金锅", "炽金之锅", "绯樱虾仙贝"] "options": [
"无(默认)",
"全部料理",
"酪香蟹蟹锅",
"金玉满堂",
"「普茹斯蒂司」",
"致水神",
"镀金锅",
"炽金之锅",
"绯樱虾仙贝"
]
}, },
{ {
"name": "food_num_Max_HP_Boost", "name": "food_num_Max_HP_Boost",
@@ -19,7 +267,11 @@
"name": "food_Elemental_Recharge_Boost", "name": "food_Elemental_Recharge_Boost",
"type": "select", "type": "select",
"label": "[普通料理(单选)]-元素充能效率提升", "label": "[普通料理(单选)]-元素充能效率提升",
"options": ["无(默认)", "全部料理", "酪香蟹蟹锅"] "options": [
"无(默认)",
"全部料理",
"酪香蟹蟹锅"
]
}, },
{ {
"name": "food_num_Elemental_Recharge_Boost", "name": "food_num_Elemental_Recharge_Boost",
@@ -30,7 +282,19 @@
"name": "food_Others", "name": "food_Others",
"type": "select", "type": "select",
"label": "[普通料理(单选)]-其他", "label": "[普通料理(单选)]-其他",
"options": ["无(默认)", "全部料理", "丰稔之赐", "奇瑰之汤", "纵声欢唱", "宝石闪闪", "温泉时光", "咚咚嘭嘭", "魔术特调", "枫达", "圣水"] "options": [
"无(默认)",
"全部料理",
"丰稔之赐",
"奇瑰之汤",
"纵声欢唱",
"宝石闪闪",
"温泉时光",
"咚咚嘭嘭",
"魔术特调",
"枫达",
"圣水"
]
}, },
{ {
"name": "food_num_Others", "name": "food_num_Others",
@@ -41,7 +305,59 @@
"name": "food_Continuous_Heal", "name": "food_Continuous_Heal",
"type": "select", "type": "select",
"label": "[普通料理(单选)]-持续恢复", "label": "[普通料理(单选)]-持续恢复",
"options": ["无(默认)", "全部料理", "沃陆果饮", "夹心土豆泥", "齐齐整整", "粒果片片", "粒果杯", "膳食均衡餐", "泡泡舒芙蕾", "摇滚团子牛奶", "「时装秀」", "知足常乐", "沉玉茶露", "得闲饮茶", "蜜汁叉烧", "咖啡芭芭露", "杏仁鳟鱼", "「海鸟的驻足」", "白淞鲜汤", "浮露白霜", "朝气盒饭", "蔷薇奶糊", "安眠奢想", "决斗之魂", "米圆塔", "奶酱鲜鱼", "树莓水馒头", "「暖意」", "荞麦面", "活力喵饭", "日落鲷鱼烧", "团子牛奶", "特制风味烤蘑菇披萨", "饭团", "头晕回避术·改", "味噌汤", "干炒鱼河", "鲜虾脆薯盏", "文火慢炖腌笃鲜", "腌笃鲜", "提神醒脑披萨", "水煮黑背鲈", "万民堂水煮鱼", "烤蘑菇披萨", "魔法肉酱面", "水晶虾", "火火肉酱面", "江湖百味", "苹果酿", "萝卜时蔬汤", "大碗茶"] "options": [
"无(默认)",
"全部料理",
"沃陆果饮",
"夹心土豆泥",
"齐齐整整",
"粒果片片",
"粒果杯",
"膳食均衡餐",
"泡泡舒芙蕾",
"摇滚团子牛奶",
"「时装秀」",
"知足常乐",
"沉玉茶露",
"得闲饮茶",
"蜜汁叉烧",
"咖啡芭芭露",
"杏仁鳟鱼",
"「海鸟的驻足」",
"白淞鲜汤",
"浮露白霜",
"朝气盒饭",
"蔷薇奶糊",
"安眠奢想",
"决斗之魂",
"米圆塔",
"奶酱鲜鱼",
"树莓水馒头",
"「暖意」",
"荞麦面",
"活力喵饭",
"日落鲷鱼烧",
"团子牛奶",
"特制风味烤蘑菇披萨",
"饭团",
"头晕回避术·改",
"味噌汤",
"干炒鱼河",
"鲜虾脆薯盏",
"文火慢炖腌笃鲜",
"腌笃鲜",
"提神醒脑披萨",
"水煮黑背鲈",
"万民堂水煮鱼",
"烤蘑菇披萨",
"魔法肉酱面",
"水晶虾",
"火火肉酱面",
"江湖百味",
"苹果酿",
"萝卜时蔬汤",
"大碗茶"
]
}, },
{ {
"name": "food_num_Continuous_Heal", "name": "food_num_Continuous_Heal",
@@ -52,7 +368,58 @@
"name": "food_Revive", "name": "food_Revive",
"type": "select", "type": "select",
"label": "[普通料理(单选)]-复活", "label": "[普通料理(单选)]-复活",
"options": ["无(默认)", "全部料理", "金牌健康餐", "「独门秘法」", "火山蛋糕", "塔塔可", "多彩之森", "玉纹茶叶蛋", "港湾牛肚", "果果仙酪", "鱼鱼咏唱派", "奶油蘑菇汤", "悉心一作", "脆饼珐提", "古法秘制椰炭饼", "椰炭饼", "气泡酸莓汁", "土豆船", "绿汁脆球", "薄荷豆汤", "福内乌冬", "乌冬面", "强者之道", "永恒的信仰", "甜虾寿司", "「红炉一点雪」", "绀田煮", "绯樱饼", "什锦炒面", "鸟蛋烧", "蟹黄豆腐", "「自有方圆」", "明月蛋", "幽幽大行军", "素鲍鱼", "金丝虾球", "绝对不是下酒菜", "蟹黄火腿焗时蔬", "伍玖叁式营养餐", "厚云朵松饼", "庄园烤松饼", "蒙德烤鱼", "炝炒肉片", "提瓦特焦蛋", "摩拉肉", "爆炒肉片", "乾坤摩拉肉", "提瓦特煎蛋", "烤肉排", "侦察骑士烤肉!"] "options": [
"无(默认)",
"全部料理",
"金牌健康餐",
"「独门秘法」",
"火山蛋糕",
"塔塔可",
"多彩之森",
"玉纹茶叶蛋",
"港湾牛肚",
"果果仙酪",
"鱼鱼咏唱派",
"奶油蘑菇汤",
"悉心一作",
"脆饼珐提",
"古法秘制椰炭饼",
"椰炭饼",
"气泡酸莓汁",
"土豆船",
"绿汁脆球",
"薄荷豆汤",
"福内乌冬",
"乌冬面",
"强者之道",
"永恒的信仰",
"甜虾寿司",
"「红炉一点雪」",
"绀田煮",
"绯樱饼",
"什锦炒面",
"鸟蛋烧",
"蟹黄豆腐",
"「自有方圆」",
"明月蛋",
"幽幽大行军",
"素鲍鱼",
"金丝虾球",
"绝对不是下酒菜",
"蟹黄火腿焗时蔬",
"伍玖叁式营养餐",
"厚云朵松饼",
"庄园烤松饼",
"蒙德烤鱼",
"炝炒肉片",
"提瓦特焦蛋",
"摩拉肉",
"爆炒肉片",
"乾坤摩拉肉",
"提瓦特煎蛋",
"烤肉排",
"侦察骑士烤肉!"
]
}, },
{ {
"name": "food_num_Revive", "name": "food_num_Revive",
@@ -63,7 +430,64 @@
"name": "food_HP_Heal", "name": "food_HP_Heal",
"type": "select", "type": "select",
"label": "[普通料理(单选)]-恢复血量", "label": "[普通料理(单选)]-恢复血量",
"options": ["无(默认)", "全部料理", "粒果膨膨棒", "乌乌黑蛋", "龙龙饼干", "奇旅馔匣", "粒果肉汤", "薄荷酱烤鱼", "粒果杯", "炉火的往迹", "肉满满寿司", "茶好月圆", "茶熏乳鸽", "秘烤肋排", "香烤肋排", "生肉塔塔", "肉酱千层面", "塔塞斯杂烩", "油封鸭腿", "「理想情况」", "秘香肉团", "萨布兹炖肉", "萨巴桑炸角", "口袋饼", "奶香菌菇脆塔", "憧憬", "咖喱虾", "兰巴德鱼卷", "常胜传说", "蒲烧鳗肉", "「奇策」", "饱腹感凝胶", "鸟蛋寿司", "兽骨拉面", "夏祭游鱼", "三彩团子", "金枪鱼寿司", "干烧香鱼", "雨奇晴好", "米窝窝", "脆脆鸡腿堡", "审判的晚宴", "薄荷果冻", "海灯节特色烤吃虎鱼", "盛世太平", "四方和平", "北地苹果焖肉", "蒙德土豆饼", "爪爪土豆饼", "松鼠鱼", "松茸酿肉卷", "甜甜花酿鸡", "果香串烤", "野菇鸡肉串", "烤吃虎鱼", "绝境求生烤鱼"] "options": [
"无(默认)",
"全部料理",
"粒果膨膨棒",
"乌乌黑蛋",
"龙龙饼干",
"奇旅馔匣",
"粒果肉汤",
"薄荷酱烤鱼",
"粒果杯",
"炉火的往迹",
"肉满满寿司",
"茶好月圆",
"茶熏乳鸽",
"秘烤肋排",
"香烤肋排",
"生肉塔塔",
"肉酱千层面",
"塔塞斯杂烩",
"油封鸭腿",
"「理想情况」",
"秘香肉团",
"萨布兹炖肉",
"萨巴桑炸角",
"口袋饼",
"奶香菌菇脆塔",
"憧憬",
"咖喱虾",
"兰巴德鱼卷",
"常胜传说",
"蒲烧鳗肉",
"「奇策」",
"饱腹感凝胶",
"鸟蛋寿司",
"兽骨拉面",
"夏祭游鱼",
"三彩团子",
"金枪鱼寿司",
"干烧香鱼",
"雨奇晴好",
"米窝窝",
"脆脆鸡腿堡",
"审判的晚宴",
"薄荷果冻",
"海灯节特色烤吃虎鱼",
"盛世太平",
"四方和平",
"北地苹果焖肉",
"蒙德土豆饼",
"爪爪土豆饼",
"松鼠鱼",
"松茸酿肉卷",
"甜甜花酿鸡",
"果香串烤",
"野菇鸡肉串",
"烤吃虎鱼",
"绝境求生烤鱼"
]
}, },
{ {
"name": "food_num_HP_Heal", "name": "food_num_HP_Heal",
@@ -74,7 +498,54 @@
"name": "food_Crit_Rate_Boost", "name": "food_Crit_Rate_Boost",
"type": "select", "type": "select",
"label": "[普通料理(单选)]-提升暴击", "label": "[普通料理(单选)]-提升暴击",
"options": ["无(默认)", "全部料理", "酪烤菇菇串", "菇菇山脉(单人份)", "「簇火赞歌」", "炎岩之颂", "苹果金条条", "火焰炖肉", "猎龙者的犒赏", "「强水」", "繁弦急管", "油爆双脆", "千灵慕斯", "「纯洁之水」", "「缥雨一滴」", "百味一缕", "韦西鸡", "果果软糖", "方块戏法", "水乡肉冻", "超级至尊披萨", "千层酥酥", "唐杜尔烤鸡", "肉肉烤蘑菇披萨", "马萨拉芝士球", "丰年有余", "鲜鱼炖萝卜", "刺身拼盘", "渡来禽肉", "鸡豆花", "干锅腊肉", "大黄金吮指鸡", "海灯节特色来来菜", "岩港三鲜", "天枢肉", "摇·滚·鸡!", "仙跳墙", "翡玉什锦袋", "「蒙德往事」", "「堆高高」", "来来菜", "没有未来菜", "香嫩椒椒鸡", "满足沙拉", "至高的智慧(生活)", "树莓薄荷饮"] "options": [
"无(默认)",
"全部料理",
"酪烤菇菇串",
"菇菇山脉(单人份)",
"「簇火赞歌」",
"炎岩之颂",
"苹果金条条",
"火焰炖肉",
"猎龙者的犒赏",
"「强水」",
"繁弦急管",
"油爆双脆",
"千灵慕斯",
"「纯洁之水」",
"「缥雨一滴」",
"百味一缕",
"韦西鸡",
"果果软糖",
"方块戏法",
"水乡肉冻",
"超级至尊披萨",
"千层酥酥",
"唐杜尔烤鸡",
"肉肉烤蘑菇披萨",
"马萨拉芝士球",
"丰年有余",
"鲜鱼炖萝卜",
"刺身拼盘",
"渡来禽肉",
"鸡豆花",
"干锅腊肉",
"大黄金吮指鸡",
"海灯节特色来来菜",
"岩港三鲜",
"天枢肉",
"摇·滚·鸡!",
"仙跳墙",
"翡玉什锦袋",
"「蒙德往事」",
"「堆高高」",
"来来菜",
"没有未来菜",
"香嫩椒椒鸡",
"满足沙拉",
"至高的智慧(生活)",
"树莓薄荷饮"
]
}, },
{ {
"name": "food_num_Crit_Rate_Boost", "name": "food_num_Crit_Rate_Boost",
@@ -85,7 +556,31 @@
"name": "food_Stamina_Regen", "name": "food_Stamina_Regen",
"type": "select", "type": "select",
"label": "[普通料理(单选)]-恢复体力", "label": "[普通料理(单选)]-恢复体力",
"options": ["无(默认)", "全部料理", "「一梦治愈」", "钱汤馒头", "清心花饼", "玉剪着花", "果味奶糖", "串烤牛心", "兽肉旋风", "巧克力", "桔香鸭胸肉", "「猎获」", "独家秘闻·美食专栏", "炸鱼薯条", "阿如拌饭", "关怀备至", "五宝腌菜", "米饭布丁", "文心豆腐", "海灯节特色热卤面", "山珍热卤面", "山珍凉卤面", "北地烟熏鸡"] "options": [
"无(默认)",
"全部料理",
"「一梦治愈」",
"钱汤馒头",
"清心花饼",
"玉剪着花",
"果味奶糖",
"串烤牛心",
"兽肉旋风",
"巧克力",
"桔香鸭胸肉",
"「猎获」",
"独家秘闻·美食专栏",
"炸鱼薯条",
"阿如拌饭",
"关怀备至",
"五宝腌菜",
"米饭布丁",
"文心豆腐",
"海灯节特色热卤面",
"山珍热卤面",
"山珍凉卤面",
"北地烟熏鸡"
]
}, },
{ {
"name": "food_num_Stamina_Regen", "name": "food_num_Stamina_Regen",
@@ -96,7 +591,40 @@
"name": "food_Defense_Boost", "name": "food_Defense_Boost",
"type": "select", "type": "select",
"label": "[普通料理(单选)]-提升防御", "label": "[普通料理(单选)]-提升防御",
"options": ["无(默认)", "全部料理", "梅落雪间醉", "粒果裹裹", "苦水", "膨膨冰淇淋", "八宝福禄鸭", "宾至如归", "古华鱼羊鲜", "羊杂哈吉斯", "枫丹肥肝", "枫丹洋葱汤", "薄荷曼果茶", "哈瓦玛玛兹", "枣椰蜜糖", "兽米香香", "杂菇荟萃", "巡林官精选", "若竹煮", "辣肉窝窝头", "黄油蟹蟹", "市井杂煮", "骇浪派", "海灯节特色白玉汤", "月亮派", "莲花酥", "极致一钓", "黄金蟹", "嘟嘟莲海鲜羹", "鱼香吐司", "珍珠翡翠白玉汤", "渔人吐司"] "options": [
"无(默认)",
"全部料理",
"梅落雪间醉",
"粒果裹裹",
"苦水",
"膨膨冰淇淋",
"八宝福禄鸭",
"宾至如归",
"古华鱼羊鲜",
"羊杂哈吉斯",
"枫丹肥肝",
"枫丹洋葱汤",
"薄荷曼果茶",
"哈瓦玛玛兹",
"枣椰蜜糖",
"兽米香香",
"杂菇荟萃",
"巡林官精选",
"若竹煮",
"辣肉窝窝头",
"黄油蟹蟹",
"市井杂煮",
"骇浪派",
"海灯节特色白玉汤",
"月亮派",
"莲花酥",
"极致一钓",
"黄金蟹",
"嘟嘟莲海鲜羹",
"鱼香吐司",
"珍珠翡翠白玉汤",
"渔人吐司"
]
}, },
{ {
"name": "food_num_Defense_Boost", "name": "food_num_Defense_Boost",
@@ -107,7 +635,25 @@
"name": "food_Healing_Boost", "name": "food_Healing_Boost",
"type": "select", "type": "select",
"label": "[普通料理(单选)]-提升治疗效果", "label": "[普通料理(单选)]-提升治疗效果",
"options": ["无(默认)", "全部料理", "梅落雪间醉", "膨膨冰淇淋", "圈圈圆圆", "罪恶·非必要处理型", "羊杂哈吉斯", "午后闲茶", "晶螺糕", "琼玉果汤", "清热降火汤", "真味茶泡饭", "假日果酿", "兽米香香", "鳗肉茶泡饭", "黄油蟹蟹", "黄金蟹"] "options": [
"无(默认)",
"全部料理",
"梅落雪间醉",
"膨膨冰淇淋",
"圈圈圆圆",
"罪恶·非必要处理型",
"羊杂哈吉斯",
"午后闲茶",
"晶螺糕",
"琼玉果汤",
"清热降火汤",
"真味茶泡饭",
"假日果酿",
"兽米香香",
"鳗肉茶泡饭",
"黄油蟹蟹",
"黄金蟹"
]
}, },
{ {
"name": "food_num_Healing_Boost", "name": "food_num_Healing_Boost",
@@ -118,7 +664,36 @@
"name": "food_Stamina_Cost_Reduction", "name": "food_Stamina_Cost_Reduction",
"type": "select", "type": "select",
"label": "[普通料理(单选)]-减少体力消耗", "label": "[普通料理(单选)]-减少体力消耗",
"options": ["无(默认)", "全部料理", "歇止一刻", "山与海与天空", "酥酥羊角包", "「选你喜欢的!」", "缤纷马卡龙", "桔桔薄饼", "苹果黑布丁", "花果三重奏", "蜜金泡果", "帕蒂沙兰布丁", "婆娑一舞", "雨林沙拉", "蛋包饭圆舞曲", "紫苑云霓", "山家烧", "云遮玉", "蛋包饭", "兽肉薄荷卷", "海灯节特色禽蛋羹", "真·风神杂烩菜", "中原杂碎", "蜜酱胡萝卜煎肉", "风神杂烩菜", "白汁时蔬烩肉", "莲子禽蛋羹", "辣味时蔬烩肉"] "options": [
"无(默认)",
"全部料理",
"歇止一刻",
"山与海与天空",
"酥酥羊角包",
"「选你喜欢的!」",
"缤纷马卡龙",
"桔桔薄饼",
"苹果黑布丁",
"花果三重奏",
"蜜金泡果",
"帕蒂沙兰布丁",
"婆娑一舞",
"雨林沙拉",
"蛋包饭圆舞曲",
"紫苑云霓",
"山家烧",
"云遮玉",
"蛋包饭",
"兽肉薄荷卷",
"海灯节特色禽蛋羹",
"真·风神杂烩菜",
"中原杂碎",
"蜜酱胡萝卜煎肉",
"风神杂烩菜",
"白汁时蔬烩肉",
"莲子禽蛋羹",
"辣味时蔬烩肉"
]
}, },
{ {
"name": "food_num_Stamina_Cost_Reduction", "name": "food_num_Stamina_Cost_Reduction",
@@ -129,7 +704,54 @@
"name": "food_Attack_Boost", "name": "food_Attack_Boost",
"type": "select", "type": "select",
"label": "[普通料理(单选)]-提升攻击", "label": "[普通料理(单选)]-提升攻击",
"options": ["无(默认)", "全部料理", "蜜汁腌鱼", "苹果金条条", "酸汁腌鱼", "香馥繁味", "奶油炖鸡", "烤肉香香香卷", "四喜圆满", "红烧肉圆", "千灵慕斯", "纳博内番茄盅", "「纯洁之水」", "双果清露", "蒜香面包棍", "测绘员蛋堡", "轻策家常菜", "鳄鱼肉干", "唐杜尔烤鸡", "肉肉烤蘑菇披萨", "黄油鸡", "日落莓莓茶", "摩拉急速来", "烤肉卷", "唯一的真相", "炸肉排三明治", "丰年有余", "龙须面", "连心面", "刺身拼盘", "串串三味", "蟹黄壳壳烧", "鸡豆花", "大黄金吮指鸡", "香浓土豆泥", "凉拌薄荷", "「美梦」", "海灯节特色炸萝卜丸子", "冒险家蛋堡", "仙跳墙", "翡玉什锦袋", "黄油松茸", "轻策农家菜", "炸萝卜丸子", "杏仁豆腐", "冰钩钩果汁"] "options": [
"无(默认)",
"全部料理",
"蜜汁腌鱼",
"苹果金条条",
"酸汁腌鱼",
"香馥繁味",
"奶油炖鸡",
"烤肉香香香卷",
"四喜圆满",
"红烧肉圆",
"千灵慕斯",
"纳博内番茄盅",
"「纯洁之水」",
"双果清露",
"蒜香面包棍",
"测绘员蛋堡",
"轻策家常菜",
"鳄鱼肉干",
"唐杜尔烤鸡",
"肉肉烤蘑菇披萨",
"黄油鸡",
"日落莓莓茶",
"摩拉急速来",
"烤肉卷",
"唯一的真相",
"炸肉排三明治",
"丰年有余",
"龙须面",
"连心面",
"刺身拼盘",
"串串三味",
"蟹黄壳壳烧",
"鸡豆花",
"大黄金吮指鸡",
"香浓土豆泥",
"凉拌薄荷",
"「美梦」",
"海灯节特色炸萝卜丸子",
"冒险家蛋堡",
"仙跳墙",
"翡玉什锦袋",
"黄油松茸",
"轻策农家菜",
"炸萝卜丸子",
"杏仁豆腐",
"冰钩钩果汁"
]
}, },
{ {
"name": "food_num_Attack_Boost", "name": "food_num_Attack_Boost",
@@ -140,7 +762,25 @@
"name": "food_Shield_Boost", "name": "food_Shield_Boost",
"type": "select", "type": "select",
"label": "[普通料理(单选)]-提升护盾", "label": "[普通料理(单选)]-提升护盾",
"options": ["无(默认)", "全部料理", "炸虾豆球", "好运传递", "八宝福禄鸭", "卡苏莱砂锅", "沾露虾仁", "「静寂闲雅」", "辣肉窝窝头", "绯樱天妇罗", "清炒虾仁", "骇浪派", "海灯节特色扣三丝", "「林之梦」", "黄油煎鱼", "月亮派", "扣三丝"] "options": [
"无(默认)",
"全部料理",
"炸虾豆球",
"好运传递",
"八宝福禄鸭",
"卡苏莱砂锅",
"沾露虾仁",
"「静寂闲雅」",
"辣肉窝窝头",
"绯樱天妇罗",
"清炒虾仁",
"骇浪派",
"海灯节特色扣三丝",
"「林之梦」",
"黄油煎鱼",
"月亮派",
"扣三丝"
]
}, },
{ {
"name": "food_num_Shield_Boost", "name": "food_num_Shield_Boost",
@@ -151,7 +791,20 @@
"name": "food_Damage_Boost", "name": "food_Damage_Boost",
"type": "select", "type": "select",
"label": "[普通料理(单选)]-提升伤害", "label": "[普通料理(单选)]-提升伤害",
"options": ["无(默认)", "全部料理", "「强水」", "韦西鸡", "膨膨泡芙", "超级至尊披萨", "红烩兽肉", "多多烧", "绝云锅巴", "天枢肉", "祝圣交响乐", "冷肉拼盘"] "options": [
"无(默认)",
"全部料理",
"「强水」",
"韦西鸡",
"膨膨泡芙",
"超级至尊披萨",
"红烩兽肉",
"多多烧",
"绝云锅巴",
"天枢肉",
"祝圣交响乐",
"冷肉拼盘"
]
}, },
{ {
"name": "food_num_Damage_Boost", "name": "food_num_Damage_Boost",
@@ -162,7 +815,11 @@
"name": "food_Env_Interaction_Heal", "name": "food_Env_Interaction_Heal",
"type": "select", "type": "select",
"label": "[普通料理(单选)]-环境交互恢复", "label": "[普通料理(单选)]-环境交互恢复",
"options": ["无(默认)", "全部料理", "苹果卷卷"] "options": [
"无(默认)",
"全部料理",
"苹果卷卷"
]
}, },
{ {
"name": "food_num_Env_Interaction_Heal", "name": "food_num_Env_Interaction_Heal",
@@ -173,13 +830,32 @@
"name": "food_Chill_Cost_Reduction", "name": "food_Chill_Cost_Reduction",
"type": "select", "type": "select",
"label": "[普通料理(单选)]-减少严寒消耗", "label": "[普通料理(单选)]-减少严寒消耗",
"options": ["无(默认)", "全部料理", "稠汁蔬菜炖肉"] "options": [
"无(默认)",
"全部料理",
"稠汁蔬菜炖肉"
]
}, },
{ {
"name": "food_num_Chill_Cost_Reduction", "name": "food_num_Chill_Cost_Reduction",
"type": "input-text", "type": "input-text",
"label": "[料理数量]-减少严寒消耗\n (默认为1)" "label": "[料理数量]-减少严寒消耗\n (默认为1)"
}, },
{
"name": "food_Crit_Damage_Boost",
"type": "select",
"label": "[普通料理(单选)]-提升暴击伤害",
"options": [
"无(默认)",
"全部料理",
"稠汁蔬菜炖肉"
]
},
{
"name": "food_num_Crit_Damage_Boost",
"type": "input-text",
"label": "[料理数量]-提升暴击伤害\n (默认为1)"
},
{ {
"name": "food_choice_multi_input", "name": "food_choice_multi_input",
"type": "input-text", "type": "input-text",
@@ -204,7 +880,107 @@
"name": "food_character_select", "name": "food_character_select",
"type": "select", "type": "select",
"label": "[特色料理(单选)]-制作特色料理\n (选择单个角色,下方多选有值不生效)", "label": "[特色料理(单选)]-制作特色料理\n (选择单个角色,下方多选有值不生效)",
"options": ["无(默认)", "全部角色", "伊安珊", "瓦雷莎", "梦见月瑞希", "茜特菈莉", "玛薇卡", "蓝砚", "恰斯卡", "欧洛伦", "希诺宁", "玛拉妮", "基尼奇", "卡齐娜", "艾梅莉埃", "希格雯", "克洛琳德", "赛索斯", "阿蕾奇诺", "千织", "闲云", "嘉明", "娜维娅", "夏沃蕾", "夏洛蒂", "芙宁娜", "那维莱特", "莱欧斯利", "菲米尼", "林尼", "琳妮特", "绮良良", "白术", "卡维", "米卡", "迪希雅", "艾尔海森", "瑶瑶", "珐露珊", "流浪者", "纳西妲", "莱依拉", "妮露", "赛诺", "坎蒂丝", "柯莱", "多莉", "提纳里", "鹿野院平藏", "久岐忍", "夜兰", "神里绫人", "八重神子", "申鹤", "云堇", "五郎", "荒泷一斗", "托马", "九条裟罗", "珊瑚宫心海", "埃洛伊", "神里绫华", "宵宫", "早柚", "枫原万叶", "优菈", "烟绯", "罗莎莉亚", "胡桃", "魈", "甘雨", "阿贝多", "钟离", "达达利亚", "辛焱", "迪奥娜", "温迪", "砂糖", "雷泽", "琴", "香菱", "菲谢尔", "迪卢克", "七七", "芭芭拉", "诺艾尔", "重云", "丽莎", "行秋", "莫娜", "可莉", "北斗", "班尼特", "凝光", "安柏", "凯亚", "刻晴"] "options": [
"无(默认)",
"全部角色",
"爱可菲",
"伊法",
"伊安珊",
"瓦雷莎",
"梦见月瑞希",
"茜特菈莉",
"玛薇卡",
"蓝砚",
"恰斯卡",
"欧洛伦",
"希诺宁",
"玛拉妮",
"基尼奇",
"卡齐娜",
"艾梅莉埃",
"希格雯",
"克洛琳德",
"赛索斯",
"阿蕾奇诺",
"千织",
"闲云",
"嘉明",
"娜维娅",
"夏沃蕾",
"夏洛蒂",
"芙宁娜",
"那维莱特",
"莱欧斯利",
"菲米尼",
"林尼",
"琳妮特",
"绮良良",
"白术",
"卡维",
"米卡",
"迪希雅",
"艾尔海森",
"瑶瑶",
"珐露珊",
"流浪者",
"纳西妲",
"莱依拉",
"妮露",
"赛诺",
"坎蒂丝",
"柯莱",
"多莉",
"提纳里",
"鹿野院平藏",
"久岐忍",
"夜兰",
"神里绫人",
"八重神子",
"申鹤",
"云堇",
"五郎",
"荒泷一斗",
"托马",
"九条裟罗",
"珊瑚宫心海",
"埃洛伊",
"神里绫华",
"宵宫",
"早柚",
"枫原万叶",
"优菈",
"烟绯",
"罗莎莉亚",
"胡桃",
"魈",
"甘雨",
"阿贝多",
"钟离",
"达达利亚",
"辛焱",
"迪奥娜",
"温迪",
"砂糖",
"雷泽",
"香菱",
"琴",
"菲谢尔",
"七七",
"迪卢克",
"芭芭拉",
"诺艾尔",
"重云",
"丽莎",
"行秋",
"莫娜",
"可莉",
"凝光",
"安柏",
"北斗",
"班尼特",
"凯亚",
"刻晴"
]
}, },
{ {
"name": "food_character_multi_name_input", "name": "food_character_multi_name_input",
@@ -219,13 +995,17 @@
{ {
"name": "food_character_num", "name": "food_character_num",
"type": "input-text", "type": "input-text",
"label": "[料理数量]-输入料理数量\n (默认为1适用于单选和多选)" "label": "[料理数量]-输入特色料理数量\n (默认为1适用于单选和多选)"
}, },
{ {
"name": "select_cooking_mode", "name": "select_cooking_mode",
"type": "select", "type": "select",
"label": "\n<---------------------------其他设置--------------------------->\n\n[烹饪模式]-选择自动烹饪模式\n (单选)", "label": "\n<---------------------------其他设置--------------------------->\n\n[烹饪模式]-选择自动烹饪模式\n (单选)",
"options": ["优先自动烹饪(默认)", "优先手动烹饪", "刷满熟练度(将选择的可烹饪食物熟练度刷满)"] "options": [
"优先自动烹饪(默认)",
"优先手动烹饪",
"刷满熟练度(将选择的可烹饪食物熟练度刷满)"
]
}, },
{ {
"name": "extraTime", "name": "extraTime",

View File

@@ -0,0 +1,106 @@
# 1. JS脚本的关键配置和路径选择
- **注意:**
只有严格按照以下步骤配置后才能使用,否则将**无法运行**(也可以参考左下角的日志来确认下一步需要如何配置)
- **配置步骤:**
未配置的情况下直接运行左下角日志会显示```请在assets/pathing文件夹手动添加路径文件夹后重新运行...```,代表你需要进行如下配置
1. 将你的路径文件夹(该文件夹内尤其仅有.json后缀的路径文件)复制粘贴到```assets/pathing```路径
2. 确保原神左上角有派蒙图像,在**调度器**直接运行脚本,左下角日志出现```JS脚本配置已更新请重新选择路径...```字样代表JS脚本已经加载了上一步中的路径文件夹此时脚本应该已经**结束运行**
3. 在**调度器**右键脚本,点击**修改JS脚本自定义配置**选择你要执行的路径-配置好所有的JS配置配置项**路径设置-选择要执行的路径文件夹**就是你刚放入的路径文件加名称)
4. 该步骤根据你选择的加世界模式有所区别
1. 手动加世界
确保在**多人模式**下,运行脚本,此时脚本会在聊天框发送校验信息,代表脚本正常运行
2. 自动加世界
确保在**单人模式**下,运行脚本,此时脚本会自动等待队员加入(作为领队)或加入队长世界(作为队员),代表脚本正常运行
- **更多的路径:**
如果需要添加更多的路径文件,请重复以上**配置步骤**的```1-4```添加路径文件夹即可(文件夹名称不可重复)
添加完成后在**JS脚本自定义配置**的**请选择要执行的路径文件夹**下拉菜单选择对应的路径
# 2. JS脚本自定义配置说明
- **选择加入世界的方式**
1. 自动加世界 \[推荐\]
选择这个选项后,需要配置下方的```自动加世界```内的三个配置项
2. 手动加世界
选择这个选项后,需要配置下方的```自动加世界```内的两个个配置项
- **手动加世界-请挑选你的玩家标识:**
手动加世界模式下,在所有人都已经加入世界的情况下,你的玩家标识
- **手动加世界-选择玩家总数:**
手动加世界模式下,在所有人都已经加入世界的情况下的玩家总数
- **自动加世界-请挑选你的身份:**
自动加世界模式下,你作为领队还是队员(领队只能存在一个,选择多个可能会报错)
- **自动加世界-文本输入框**
1. 作为领队
填入要加入你世界的所有玩家的昵称顺序无关每个玩家的名称ID使用单个空格隔开
2. 作为队员
填入你要加入的世界队长的UID
- **自动加世界-名称匹配模式:**
自动加世界模式下,匹配玩家名称的匹配方式(仅队长生效)
1. 全字匹配(此模式下请使用玩家的全称)
匹配玩家的完整名称,在玩家的名称便于识别时使用
2. 部分匹配(此模式下请填入玩家名称内易于识别的**连续文本**
匹配玩家名称内包含的文本,在玩家的名称难以识别时使用
- **路径设置-选择要执行的路径文件夹**
初次使用时该下拉菜单为空,详情配置见下方```2. JS脚本的关键配置和路径选择```
# 3. 注意事项
所有人使用的路径文件夹及其内容应当**完全一致**,否则验证失败会导致脚本异常终止
- **路径文件夹存放位置:** ```assets/pathing```
假设你有一个文件夹名为```死亡笔记-400```,这个文件夹内含有若干个```.json```后缀的路径文件,你需要将```死亡笔记-400```文件夹复制粘贴到```assets/pathing```文件夹内
- **路径相关格式:** ```assets/pathing/你的路径文件夹名/若干路径文件.json...```
路径```assets/pathing```内只能存放文件夹,存放其他文件无效
路径```assets/pathing你的路径文件夹名```内只能存放```.json```后缀的文件
# 4.适用场景
- **配置了本地远程,可以在一个设备上运行两套原神+BGI**
可以用两个账号实现双倍的锄地收益,例如在调度器内都配置两个锄地脚本,一个先作为房主后作为成员,另一个先作为成员后作为房主,可以自动实现两个号同时锄地,锄完两个世界的资源
- **和其他BGI用户一起锄地**
所有人协商好正确导入相同的路径后就可以实现2-4人的联机锄地路线进度将保持同步确保所有玩家都能获得相同的收益

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -0,0 +1,953 @@
(async function () { // 掉队识别(聊天框增加超时检测,超时后检测玩家数,如果少人则更换策略),队长模式启动时检测到多人模式应当先退出多人模式[待定]加世界自动识别P几[实现]uid加世界[实现]核对JS版号[实现],每个传送点同步[待定],超时检测(等太久了就都跳到进度最新的传送点),每个传送点规定时间完全同步,按照传送切分路径、方法:回到(退出到)单人模式和退出检测、领队的实际逻辑为实现
// const pathingList = file.readPathSync("assets/pathing");
const nameDic = {
"1P": "一号",
"2P": "二号",
"3P": "三号",
"4P": "四号"
}
const picDic = {
"1P": "assets/others/1P.png",
"2P": "assets/others/2P.png",
"3P": "assets/others/3P.png",
"4P": "assets/others/4P.png"
}
let settingDic = {
"mode": undefined,
"player_id": undefined,
"player_all": undefined,
"match_identity": undefined,
"match_detail": undefined,
"match_mode": undefined,
"path_folder": undefined
};
/**
*
* 检查并读取JS脚本配置
*
* @returns {Promise<boolean>}
*/
async function dealSettings() {
let mode = typeof(settings.mode) === "undefined" ? false : settings.mode;
if (mode === false) {
log.warn(`JS脚本配置错误: 选择加入世界的方式`);
} else if (mode === "手动加世界") {
settingDic["mode"] = mode;
let player_id = typeof(settings.player_id) === "undefined" ? false : settings.player_id;
let player_all = typeof(settings.player_all) === "undefined" ? false : settings.player_all;
if (player_id === false || player_all === false) {
log.warn(`JS脚本配置错误: 手动加世界`);
} else {
settingDic["player_id"] = player_id;
settingDic["player_all"] = player_all;
let pathFolder = typeof(settings.path_folder) === "undefined" ? false : settings.path_folder;
if (pathFolder === false) {
log.warn(`JS脚本配置错误: 路径设置`);
} else {
settingDic["path_folder"] = pathFolder;
return true;
}
}
} else if (mode === "自动加世界") {
settingDic["mode"] = mode;
let match_identity = typeof(settings.match_identity) === "undefined" ? false : settings.match_identity;
if (match_identity === false) {
log.warn(`JS脚本配置错误: 请挑选你的身份`);
} else {
if (match_identity.startsWith("作为领队")) { // 领队
settingDic["match_identity"] = "领队";
let match_detail = typeof(settings.match_detail) === "undefined" ? false : settings.match_detail;
if (match_detail === false) {
log.warn(`JS脚本配置错误: 自动加世界`); // 该选项无具体文本-位于 自动加世界
} else {
settingDic["match_detail"] = match_detail.split(" "); // 玩家名
settingDic["match_mode"] = typeof(settings.match_mode) === "undefined" ? "全字匹配" : "部分匹配";
pathingFolder = typeof(settings.path_folder) === "undefined" ? false : settings.path_folder;
if (pathingFolder === false) {
log.warn(`JS脚本配置错误: 路径设置`);
} else {
settingDic["path_folder"] = pathingFolder;
}
return true;
}
} else if (match_identity.startsWith("作为队员")) { // 队员
settingDic["match_identity"] = "队员";
let match_detail = typeof(settings.match_detail) === "undefined" ? false : settings.match_detail;
if (match_detail === false) {
log.warn(`JS脚本配置错误: 自动加世界`); // 该选项无具体文本-位于 自动加世界
} else {
settingDic["match_detail"] = match_detail; // uid
settingDic["match_mode"] = typeof(settings.match_mode) === "undefined" ? "全字匹配" : "部分匹配";
pathingFolder = typeof(settings.path_folder) === "undefined" ? false : settings.path_folder;
if (pathingFolder === false) {
log.warn(`JS脚本配置错误: 路径设置`);
} else {
settingDic["path_folder"] = pathingFolder;
}
return true;
}
}
}
}
return false;
}
/**
*
* 在联机状态下的聊天框发送信息
*
* @param msg 发送的信息
* @returns {Promise<boolean>}
*/
async function sendMessage(msg) {
await genshin.returnMainUi(); // 保证在主界面
await sleep(500);
await keyPress("VK_RETURN"); // 按Enter进入聊天界面
await sleep(500);
const ocrRo = RecognitionObject.Ocr(0, 0, 257, 173);
moveMouseTo(1555, 860); // 移走鼠标防止干扰OCR
await sleep(300);
let ocr = captureGameRegion().Find(ocrRo); // 当前页面OCR
for (let i = 0; i < 3; i++) {
if (ocr.isExist() && ocr.text === "当前队伍") {
ocr.Click(); // 点击 当前队伍
await sleep(500);
click(445, 1010); // 点击聊天框
await sleep(200);
inputText(msg); // 输入文本
keyPress("VK_RETURN"); // 发送
await sleep(200);
await genshin.returnMainUi(); // 返回主界面
return true;
} else {
log.error(`未检测到 当前队伍 ,可能不处于联机状态 ${i + 1}/3`);
await sleep(200); // 等待0.5s
return false;
}
}
log.error(`未检测到 当前队伍 ,尝试发送信息...`);
click(445, 1010); // 点击聊天框
await sleep(200);
inputText(msg); // 输入文本
keyPress("VK_RETURN"); // 发送
await sleep(200);
await genshin.returnMainUi(); // 返回主界面
return false;
}
/**
*
* 生成任务标识
*
* @param num 数字
* @returns {string} 根据数字生成的汉字标识
*/
async function numberToChinese(num) {
// 定义数字到中文的映射
// const chineseDigits = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九'];
const chineseDigits = ['癸', '甲', '乙', '丙', '丁', '戊', '己', '庚', '辛', '壬'];
// 将数字转换为字符串,以便逐个处理
const numStr = num.toString();
let result = '';
for (let i = 0; i < numStr.length; i++) {
const digit = parseInt(numStr[i], 10);
// 获取对应的中文数字
result += chineseDigits[digit];
}
return result;
}
/**
* 计算 SHA-256 哈希(完全纯计算实现)并返回 8 位数字字符串。
* 参考了原先的 Python 实现。
*
* @param {string | number[]} data - 输入数据,可以是字符串(采用 UTF-8 编码)或者字节数组(各元素 0~255
* @returns {string} 返回一个 8 位数字字符串(不足 8 位时左侧补零)。
*/
function sha256To8(data) {
// --- 辅助函数部分 ---
// 将字符串转换为 UTF-8 编码的字节数组
function stringToBytes(str) {
var bytes = [];
for (var i = 0; i < str.length; i++) {
var code = str.charCodeAt(i);
if (code < 0x80) {
bytes.push(code);
} else if (code < 0x800) {
bytes.push(0xc0 | (code >> 6));
bytes.push(0x80 | (code & 0x3f));
} else {
bytes.push(0xe0 | (code >> 12));
bytes.push(0x80 | ((code >> 6) & 0x3f));
bytes.push(0x80 | (code & 0x3f));
}
}
return bytes;
}
// 右旋操作32位无符号数
function rotr(x, n) {
return ((x >>> n) | (x << (32 - n))) >>> 0;
}
// --- 数据预处理 ---
// 如果数据为字符串,则转换为字节数组;否则假设 data 已是数组形式
var bytes;
if (typeof data === "string") {
bytes = stringToBytes(data);
} else {
// 此处要求 data 为一个数组形式,复制一份
bytes = data.slice();
}
// 保存原始数据长度(单位:比特数)
var bitLen = bytes.length * 8;
// 按照 SHA-256 规范先附加一个 0x80 字节
bytes.push(0x80);
// 然后填充 0直到消息长度字节数模 64 等于 56
while ((bytes.length % 64) !== 56) {
bytes.push(0);
}
// 最后附加原始数据长度的 8 字节大端表示
for (var i = 7; i >= 0; i--) {
bytes.push((bitLen >>> (i * 8)) & 0xff);
}
// --- 初始化常量 ---
var k = [
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
];
var h0 = 0x6a09e667;
var h1 = 0xbb67ae85;
var h2 = 0x3c6ef372;
var h3 = 0xa54ff53a;
var h4 = 0x510e527f;
var h5 = 0x9b05688c;
var h6 = 0x1f83d9ab;
var h7 = 0x5be0cd19;
// --- 主循环:分块处理 ---
for (var chunk = 0; chunk < bytes.length; chunk += 64) {
var w = new Array(64);
// 将 64 字节拆分成 16 个 32 位大端字
for (var i = 0; i < 16; i++) {
var j = chunk + i * 4;
w[i] = ((bytes[j] << 24) | (bytes[j+1] << 16) | (bytes[j+2] << 8) | bytes[j+3]) >>> 0;
}
// 扩展消息
for (var i = 16; i < 64; i++) {
var s0 = rotr(w[i - 15], 7) ^ rotr(w[i - 15], 18) ^ (w[i - 15] >>> 3);
var s1 = rotr(w[i - 2], 17) ^ rotr(w[i - 2], 19) ^ (w[i - 2] >>> 10);
w[i] = (w[i - 16] + s0 + w[i - 7] + s1) >>> 0;
}
// 初始化工作变量为当前哈希值
var a = h0;
var b = h1;
var c = h2;
var d = h3;
var e = h4;
var f = h5;
var g = h6;
var hh = h7;
// 主压缩循环
for (var i = 0; i < 64; i++) {
var S1 = rotr(e, 6) ^ rotr(e, 11) ^ rotr(e, 25);
var ch = (e & f) ^ ((~e) & g);
var temp1 = (hh + S1 + ch + k[i] + w[i]) >>> 0;
var S0 = rotr(a, 2) ^ rotr(a, 13) ^ rotr(a, 22);
var maj = (a & b) ^ (a & c) ^ (b & c);
var temp2 = (S0 + maj) >>> 0;
hh = g;
g = f;
f = e;
e = (d + temp1) >>> 0;
d = c;
c = b;
b = a;
a = (temp1 + temp2) >>> 0;
}
// 更新哈希值
h0 = (h0 + a) >>> 0;
h1 = (h1 + b) >>> 0;
h2 = (h2 + c) >>> 0;
h3 = (h3 + d) >>> 0;
h4 = (h4 + e) >>> 0;
h5 = (h5 + f) >>> 0;
h6 = (h6 + g) >>> 0;
h7 = (h7 + hh) >>> 0;
}
// --- 生成最终结果 ---
// 这里取 h0 作为哈希结果的前 32 位数字,并对 100,000,000 取模,
// 保证结果范围在 0 ~ 99,999,999 之间,再手工左侧补零至 8 位字符串格式
var num = h0 >>> 0;
num = num % 100000000;
// 将数字转换为字符串,并手工左侧补零
var numStr = "";
// 这里采用逐位构造补零字符串
var temp = num;
do {
numStr = (temp % 10).toString() + numStr;
temp = Math.floor(temp / 10);
} while (temp > 0);
while (numStr.length < 8) {
numStr = "0" + numStr;
}
return numStr;
}
/**
* 异步计算指定文件夹中所有 JSON 文件内容的 SHA-256 哈希值返回8位数字字符串(附带JS版号)。
*
* 该方法执行步骤如下:
* 1. 调用 file.readPathSync() 读取指定文件夹下所有文件和文件夹的路径(非递归)。
* 2. 使用 Array.from() 将返回值转换为标准数组。
* 3. 过滤出所有非文件夹且文件名以 ".json" 结尾的路径。
* 4. 将这些 JSON 文件内容读取后合并成一个总体字符串。
* 5. 调用自定义的 sha256To8() 方法生成并返回 8 位数字的哈希值。
* 6. 如果没有符合条件的 JSON 文件,返回 "00000000"。
*
* @param {string} path - 文件夹路径(相对于根目录)。
* @returns {Promise<string>} 返回一个 Promise其解析结果为8位数字格式的哈希值字符串。
*/
async function getSha256FromPath(path) {
// 读取指定路径下所有文件和文件夹的路径(非递归)
let allPaths = file.readPathSync(path);
// 将返回值转换为标准数组,以确保可以使用 filter 方法
allPaths = Array.from(allPaths);
// 过滤出所有非文件夹且以 ".json" 结尾的文件路径
const jsonPaths = allPaths.filter(p => !file.isFolder(p) && p.endsWith(".json"));
// 读取JS版号
const version = JSON.parse(file.readTextSync("manifest.json"))["version"];
// 如果有符合条件的文件,读取并合并文件内容后计算哈希
if (jsonPaths.length > 0) {
const combinedContent = jsonPaths
.map(p => file.readTextSync(p))
.join('');
return sha256To8(version + combinedContent);
} else {
// 如果没有符合条件的文件,则返回 "00000000"
return "00000000";
}
}
/**
*
* 验证当前所选文件夹下所有路径文件的哈希值是否与其他玩家一致(附带JS版号)
*
* @param pathDir 路径文件夹路径
* @param mode 领队 队员
* @param sendSignal 是否发送队长信号
* @returns {Promise<boolean>}
*/
async function verifyPlayerPath(pathDir, mode="领队", sendSignal=false) {
const ocrMsgRo = RecognitionObject.Ocr(293, 80, 873, 868); // 聊天框
let playerNum;
if (mode === "领队") {
playerNum = parseInt(settingDic["player_all"], 10);
}
let verifyDic = {};
await sleep(200); // 延时等待
const verifyString = await numberToChinese(await getSha256FromPath(pathDir)); // 计算8位验证值并转换为中文字符串
await sendMessage(`${nameDic[settingDic["player_id"]]}验证${verifyString}`);
await sleep(500);
keyPress("VK_RETURN"); // 进入聊天界面
await sleep(500);
while (true) { // 注意死循环
moveMouseTo(1555, 860); // 移走鼠标防止干扰OCR
await sleep(200);
let ocrList = captureGameRegion().FindMulti(ocrMsgRo); // 当前页面OCR
if (mode === "领队") {
if (Object.keys(verifyDic).length != playerNum) {
for (let j = 1; j < playerNum + 1; j++) {
let playerP = `${j.toString()}P`;
if (!Object.keys(verifyDic).includes(playerP)) {
verifyDic[playerP] = false;
}
}
}
for (let i = 0; i < ocrList.count; i++) {
for (let j = 1; j < playerNum + 1; j++) {
let playerP = `${j.toString()}P`;
if (verifyDic[playerP] == true) {
continue;
}
if (ocrList[i].text.includes(`${nameDic[playerP]}验证`)) {
let tempString = ocrList[i].text.split("验证")[1]; // 可能的报错(indexError)
if (tempString === verifyString){
verifyDic[playerP] = true;
log.info(`${playerP}校验通过`);
} else {
log.error(`${playerP}校验失败: ${ocrList[i].text}`);
if (sendSignal) { // 队长发布检验完成信息
await sendMessage(`校验失败`);
}
return false
}
}
}
if (Object.values(verifyDic).every(value => value === true)) { // 全部验证通过
if (sendSignal) { // 队长发布检验完成信息
await sendMessage(`校验完成`);
}
await sleep(300);
return true;
};
}
} else { // 队员
for (let i = 0; i < ocrList.count; i++) {
if (ocrList[i].text.includes("校验完成")) {
log.info(`检测到队长的校验完成信号`)
return true;
} else if (ocrList[i].text.includes("校验失败")) {
log.error(`检测到队长的校验失败信号`)
return false;
}
}
}
}
}
/**
*
* 更新settings的路径文件夹
*
* @returns {Promise<void>}
*/
async function dealSettingsFolder() {
let settingsJson = JSON.parse(file.readTextSync("settings.json"));
let pathingFiles = file.readPathSync("assets/pathing");
let pathFolder = [];
for (let i = 0; i < pathingFiles.length; i++) {
if (file.isFolder(pathingFiles[i])) {
pathFolder.push(pathingFiles[i].replace(/assets\\pathing\\/, ''));
log.info(`识别到路径文件夹: ${pathingFiles[i]}`);
}
}
if (pathFolder.length == 0) {
log.error("请在assets/pathing文件夹手动添加路径文件夹后重新运行...");
settingsJson[6]["options"] = [];
file.writeTextSync("settings.json", JSON.stringify(settingsJson, null, 2)); // 覆写settings
return false;
} else if (pathFolder.join("") === settingsJson[6]["options"].join("")) { // 内容一样
return true;
} else {
settingsJson[6]["options"] = [];
for (let j = 0; j < pathFolder.length; j++) {
settingsJson[6]["options"].push(pathFolder[j]);
}
file.writeTextSync("settings.json", JSON.stringify(settingsJson, null, 2)); // 覆写settings
log.info("JS脚本配置已更新请重新选择路径...");
return false;
}
}
/**
*
* 获取联机世界的当前玩家标识
*
* @returns {Promise<boolean|string>}
*/
async function getPlayerSign() {
await genshin.returnMainUi();
await sleep(500);
const p1Ro = RecognitionObject.TemplateMatch(file.ReadImageMatSync(picDic["1P"]), 344, 22, 45, 45);
const p2Ro = RecognitionObject.TemplateMatch(file.ReadImageMatSync(picDic["2P"]), 344, 22, 45, 45);
const p3Ro = RecognitionObject.TemplateMatch(file.ReadImageMatSync(picDic["3P"]), 344, 22, 45, 45);
const p4Ro = RecognitionObject.TemplateMatch(file.ReadImageMatSync(picDic["4P"]), 344, 22, 45, 45);
moveMouseTo(1555, 860); // 移走鼠标,防止干扰识别
const gameRegion = captureGameRegion();
await sleep(200);
// 当前页面模板匹配
let p1 = gameRegion.Find(p1Ro);
let p2 = gameRegion.Find(p2Ro);
let p3 = gameRegion.Find(p3Ro);
let p4 = gameRegion.Find(p4Ro);
if (p1.isExist()) return "1P";
if (p2.isExist()) return "2P";
if (p3.isExist()) return "3P";
if (p4.isExist()) return "4P";
return false;
}
/**
*
* 循环等待并点进联机申请界面
*
* @param timeOut 超时时间(应大于等于100)
* @returns {Promise<void>}
*/
async function enterMultiUi(timeOut = 30000) {
const ocrRo = RecognitionObject.Ocr(923, 72, 45, 23);
moveMouseTo(1555, 860); // 移走鼠标,防止干扰识别
let ocr = captureGameRegion().Find(ocrRo);
log.info(`开始检测进入世界申请弹窗, 超时时长: ${timeOut}ms`);
for (let i = 0; i < Math.floor(timeOut / 100); i++) {
if (ocr.isExist() && ocr.text === "世界") {
log.info(`检测到弹窗!`);
keyPress("Y");
await sleep(300); // 弹窗打开的时间
return true;
} else {
ocr = captureGameRegion().Find(ocrRo);
await sleep(100);
}
}
return false;
}
/**
*
* 在联机申请界面处理玩家的进入世界请求(循环检测)
*
* @param playerList 放行的玩家列表
* @param timeOut 检测的超时时长
* @param mode 玩家名匹配模式(exact完全匹配feature部分匹配)
* @returns {Promise<void>}
*/
async function dealPlayerRequest(playerList, timeOut=30000, mode="exact") {
const ocrTitleRo = RecognitionObject.Ocr(874, 236, 171, 33);
const ocrTextRo = RecognitionObject.Ocr(507, 285, 907, 484);
let ocrTitle = captureGameRegion().Find(ocrTitleRo);
let ocrText = captureGameRegion().FindMulti(ocrTextRo);
let count = 0;
await sleep(1000);
if (!(ocrTitle.isExist() && ocrTitle.text === "多人游戏申请")) {
log.error(`未处于 多人游戏申请 界面...`);
return false;
}
log.info(`开始验证进入世界申请, 超时时长: ${timeOut}ms`);
for (let i = 0; i < Math.floor(timeOut / 100); i++) {
for (let j = 0; j < ocrText.count; j++) { // 迭代ocr数组
log.info(`${ocrText[j].text}`);
if (mode === "exact") {
for (let k = 0; k < playerList.length; k++) {
if (playerList[k] === ocrText[j].text) {
let x = ocrText[j].x + 642;
let y = ocrText[j].y + ocrText[j].height; // 尽可能点中间
log.info(`检测到玩家: ${playerList[k]},验证通过(exact)...`);
count++;
click(x, y); // 点击通过申请
await sleep(100);
break;
}
}
} else if (mode === "feature") {
for (let k = 0; k < playerList.length; k++) {
if (ocrText[j].text.includes(playerList[k])) {
let x = ocrText[j].x + 642;
let y = ocrText[j].y + ocrText[j].height; // 尽可能点中间
log.info(`检测到玩家: ${playerList[k]},验证通过(exact)...`);
count++;
click(x, y); // 点击通过申请
await sleep(100);
break;
}
}
}
if (count >= playerList.length) {
keyPress("ESCAPE");
await sleep(5000); // 单人模式进入多人模式的耗时
return true;
};
}
await sleep(100);
ocrText = captureGameRegion().FindMulti(ocrTextRo);
}
return false;
}
/**
*
* 输入玩家UID加入房主
*
* @param playerUid 房主UID
* @returns {Promise<void>}
*/
async function sendMultiRequest(playerUid) {
const ocrMultiRo = RecognitionObject.Ocr(141, 34, 102, 27);
const ocrJoinRo = RecognitionObject.Ocr(1561, 223, 119, 34);
await genshin.returnMainUi();
await sleep(100);
keyPress("F2");
await sleep(200);
moveMouseTo(1555, 860); // 移走鼠标,防止干扰识别
for (let i = 0; i < 3; i++) {
await sleep(200);
let ocrMulti = captureGameRegion().Find(ocrMultiRo);
if (ocrMulti.isExist() && ocrMulti.text === "多人游戏") break;
}
click(260, 115); // 点击搜索框
await sleep(100);
inputText(playerUid);
await sleep(200);
for (let i = 0; i < 10; i++) { // 防止队长未及时通过,此处待改进
log.info(`尝试加入房主(${playerUid})世界[${i + 1}/10]`);
click(1681, 115); // 搜索
await sleep(200);
let ocrJoin = captureGameRegion().Find(ocrJoinRo);
if (ocrJoin.isExist() && ocrJoin.text === "申请加入") {
ocrJoin.Click();
await sleep(10000);
ocrJoin = captureGameRegion().Find(ocrJoinRo);
if (!(ocrJoin.isExist() && ocrJoin.text === "申请加入")) return true;
}
await sleep(8000);
}
log.info(`未能加入房主(${playerUid})世界...`);
return false;
}
async function main() {
if (!(await dealSettingsFolder())) { // 检查路径文件夹
return null;
}
if (!(await dealSettings())) { // 读取JS脚本配置
return null;
}
let choicePath = `assets/pathing/${settingDic["path_folder"]}`;
const pathingList = file.readPathSync(choicePath);
// 以下根据加世界模式存在差异(首先确保所有玩家加入了世界[自动模式])
if (settingDic["mode"] === "手动加世界") { // 运行前确保玩家全部加入了世界
if (!(await verifyPlayerPath(choicePath, "领队"))) { // 验证路径一致性
log.error("路径校验未通过...");
return null;
}
for (let i = 0; i < pathingList.length; i++) {
log.info(`当前路线标识(${i})${pathingList[i]}`);
let pathDic = JSON.parse(file.readTextSync(pathingList[i]));
for (let j = 0; j < pathDic["positions"].length; j++) {
if (pathDic["positions"][j]["id"] === 1) {
for (let i = 0; i < 3; i++) {
await genshin.tp(pathDic["positions"][j]["x"].toString(), pathDic["positions"][j]["y"].toString()); // 传送到第一个点位
await genshin.returnMainUi();
await sleep(200);
let pos = await genshin.getPositionFromMap();
if (pathDic["positions"][j]["x"] - 15 < pos.X && pos.X < pathDic["positions"][j]["x"] + 15 && pathDic["positions"][j]["y"] - 15 < pos.Y && pos.y < pathDic["positions"][j]["y"] + 15) {
log.info(`传送点范围坐标正确`);
break; // 确保在大地图上的位置正确再发送就位消息
}
await sleep(200);
}
// 删去第一个传送点位,避免再次传送
pathDic["positions"].splice(j, 1);
// 发消息
await sendMessage(`${nameDic[settingDic["player_id"]]}已就位${await numberToChinese(i)}`);
// 打开聊天框等待继续
keyPress("VK_RETURN"); // 按Enter进入聊天界面
await sleep(500);
const ocrRo = RecognitionObject.Ocr(0, 0, 257, 173);
moveMouseTo(1555, 860); // 移走鼠标防止干扰OCR
await sleep(200);
let ocr = captureGameRegion().Find(ocrRo); // 当前页面OCR
if (ocr.isExist() && ocr.text === "当前队伍") { // 多此一举
ocr.Click(); // 点击 当前队伍
}
await sleep(200);
// const ocrMsgRo = RecognitionObject.Ocr(397, 83, 662, 870); // 聊天框
const ocrMsgRo = RecognitionObject.Ocr(293, 80, 873, 868); // 聊天框
moveMouseTo(1555, 860); // 移走鼠标防止干扰OCR
await sleep(200);
let wait_flag = true;
const player_num = parseInt(settingDic["player_all"], 10);
let judge_dic = {};
while (wait_flag) { // 循环等待
let ocr = captureGameRegion().FindMulti(ocrMsgRo); // 当前页面OCR
for (let k = 1; k < player_num + 1; k++) { // 遍历总玩家数
const player_key = `${player_num.toString()}P`;
if (Object.keys(judge_dic).length < k) { // 将玩家加入判断字典
judge_dic[player_key] = false;
}
if (!judge_dic[player_key]) { // 未识别到对应玩家就绪的信息,继续识别
for (let l = 0; l < ocr.count; l++) { // 遍历OCR数组
if (ocr[l].text === nameDic[player_key] + `已就位${await numberToChinese(i)}`) { // 检测是否存在该玩家信息
judge_dic[player_key] = true;
log.info(`${player_key} 已就位...`);
break;
}
}
} else {
log.info(`${player_key} 已就位...`);
}
}
if (Object.values(judge_dic).every(value => value === true)) wait_flag = false; // 全部就位
}
break;
}
}
await pathingScript.run(JSON.stringify(pathDic));
}
// 返回单人模式(如果是队长会自动踢出队员)
if (settingDic["player_id"] === "1P") {
// 等待队员退出(防止自己返回单人模式时卡死)
await sleep(12000);
// 返回单人模式(会自动踢出队员)
genshin.returnMainUi();
await sleep(1000);
keyPress("VK_F2");
await sleep(2500);
click(1651, 1019);
await sleep(1000);
click(1180, 754);
} else {
genshin.returnMainUi();
await sleep(1000);
keyPress("VK_F2");
await sleep(2500);
click(1651, 1019);
}
} else if (settingDic["mode"] === "自动加世界") {
if (settingDic["match_identity"] === "领队") { // 作为领队
settingDic["player_id"] = "1P";
settingDic["player_all"] = `${settingDic["match_detail"].length + 1}`;
let enterFeedback = await enterMultiUi(60000); // 超时时间60s
if (enterFeedback) {
let requestFeedback = await dealPlayerRequest(settingDic["match_detail"], 60000, settingDic["match_mode"] === "全字匹配" ? "exact" : "feature");
// if (settingDic["match_mode"] === "全字匹配") {
// requestFeedback = await dealPlayerRequest(settingDic["match_detail"], 60000, "exact");
// } else if (settingDic["match_mode"] === "部分匹配") {
// requestFeedback = await dealPlayerRequest(settingDic["match_detail"], 60000, "feature");
// }
log.info(`${requestFeedback}`);
if (requestFeedback) {
// 第一步,路径文件校验
if (!(await verifyPlayerPath(choicePath, "领队", true))) { // 验证路径一致性
log.error("路径校验未通过...");
return null;
}
// 第二步,跑路线
for (let i = 0; i < pathingList.length; i++) {
log.info(`当前路线标识(${i})${pathingList[i]}`);
let pathDic = JSON.parse(file.readTextSync(pathingList[i]));
for (let j = 0; j < pathDic["positions"].length; j++) {
if (pathDic["positions"][j]["id"] === 1) {
for (let i = 0; i < 3; i++) {
await genshin.tp(pathDic["positions"][j]["x"].toString(), pathDic["positions"][j]["y"].toString()); // 传送到第一个点位
await genshin.returnMainUi();
await sleep(200);
let pos = await genshin.getPositionFromMap();
log.info(`${pathDic["positions"][j]["x"]}${pos.X}${pathDic["positions"][j]["y"]}${pos.Y}`);
if (pathDic["positions"][j]["x"] - 15 < pos.X && pos.X < pathDic["positions"][j]["x"] + 15 && pathDic["positions"][j]["y"] - 15 < pos.Y && pos.y < pathDic["positions"][j]["y"] + 15) {
log.info(`传送点范围坐标正确`);
break; // 确保在大地图上的位置正确再发送就位消息
}
await sleep(200);
}
// 删去第一个传送点位,避免再次传送
pathDic["positions"].splice(j, 1);
// 发消息
await sendMessage(`${nameDic[settingDic["player_id"]]}已就位${await numberToChinese(i)}`);
// 打开聊天框等待继续
keyPress("VK_RETURN"); // 按Enter进入聊天界面
await sleep(500);
const ocrRo = RecognitionObject.Ocr(0, 0, 257, 173);
moveMouseTo(1555, 860); // 移走鼠标防止干扰OCR
await sleep(200);
let ocr = captureGameRegion().Find(ocrRo); // 当前页面OCR
if (ocr.isExist() && ocr.text === "当前队伍") { // 多此一举
ocr.Click(); // 点击 当前队伍
}
await sleep(200);
// const ocrMsgRo = RecognitionObject.Ocr(397, 83, 662, 870); // 聊天框
const ocrMsgRo = RecognitionObject.Ocr(293, 80, 873, 868); // 聊天框
moveMouseTo(1555, 860); // 移走鼠标防止干扰OCR
await sleep(200);
let wait_flag = true;
const player_num = parseInt(settingDic["player_all"], 10);
let judge_dic = {};
while (wait_flag) { // 循环等待
let ocr = captureGameRegion().FindMulti(ocrMsgRo); // 当前页面OCR
for (let k = 1; k < player_num + 1; k++) { // 遍历总玩家数
const player_key = `${player_num.toString()}P`;
if (Object.keys(judge_dic).length < k) { // 将玩家加入判断字典
judge_dic[player_key] = false;
}
if (!judge_dic[player_key]) { // 未识别到对应玩家就绪的信息,继续识别
for (let l = 0; l < ocr.count; l++) { // 遍历OCR数组
if (ocr[l].text === nameDic[player_key] + `已就位${await numberToChinese(i)}`) { // 检测是否存在该玩家信息
judge_dic[player_key] = true;
log.info(`${player_key} 已就位...`);
break;
}
}
} else {
log.info(`${player_key} 已就位...`);
}
}
if (Object.values(judge_dic).every(value => value === true)) { // 全部就位
log.info("全部就位");
await sendMessage("路线启动");
wait_flag = false;
};
}
break;
}
}
await pathingScript.run(JSON.stringify(pathDic));
}
// 跑完了全部路线
await sendMessage("全部路线结束");
// 等待队员退出(防止自己返回单人模式时卡死)
await sleep(12000);
// 返回单人模式(会自动踢出队员)
genshin.returnMainUi();
await sleep(1000);
keyPress("VK_F2");
await sleep(2500);
click(1651, 1019);
await sleep(1000);
click(1180, 754);
} else {
log.error("超时时间内无人加入或未全部加入..."); // 应该加一个解散重试之类的逻辑
}
} else {
log.error("超时时间内无人申请加入...");
}
} else { // 作为队员
let enterFeedback = await sendMultiRequest(settingDic["match_detail"]);
if (enterFeedback) {
let playerSign = await getPlayerSign();
if (playerSign !== false) {
settingDic["player_id"] = playerSign;
// 第一步,发送路径校验信息
if (!(await verifyPlayerPath(choicePath, "队员"))) { // 验证路径一致性
log.error("路径校验未通过...");
return null;
}
// 第二步,跑路线
for (let i = 0; i < pathingList.length; i++) {
log.info(`当前路线标识(${i})${pathingList[i]}`);
let pathDic = JSON.parse(file.readTextSync(pathingList[i]));
for (let j = 0; j < pathDic["positions"].length; j++) {
if (pathDic["positions"][j]["id"] === 1) {
for (let i = 0; i < 3; i++) {
await genshin.tp(pathDic["positions"][j]["x"].toString(), pathDic["positions"][j]["y"].toString()); // 传送到第一个点位
await genshin.returnMainUi();
await sleep(200);
let pos = await genshin.getPositionFromMap();
if (pathDic["positions"][j]["x"] - 15 < pos.X && pos.X < pathDic["positions"][j]["x"] + 15 && pathDic["positions"][j]["y"] - 15 < pos.Y && pos.y < pathDic["positions"][j]["y"] + 15) {
log.info(`传送点范围坐标正确`);
break; // 确保在大地图上的位置正确再发送就位消息
}
await sleep(200);
}
// 删去第一个传送点位,避免再次传送
pathDic["positions"].splice(j, 1);
// 发消息
await sendMessage(`${nameDic[settingDic["player_id"]]}已就位${await numberToChinese(i)}`);
// 打开聊天框等待继续
keyPress("VK_RETURN"); // 按Enter进入聊天界面
await sleep(500);
const ocrRo = RecognitionObject.Ocr(0, 0, 257, 173);
moveMouseTo(1555, 860); // 移走鼠标防止干扰OCR
await sleep(200);
let ocr = captureGameRegion().Find(ocrRo); // 当前页面OCR
if (ocr.isExist() && ocr.text === "当前队伍") { // 多此一举
ocr.Click(); // 点击 当前队伍
}
await sleep(200);
// const ocrMsgRo = RecognitionObject.Ocr(397, 83, 662, 870); // 聊天框
const ocrMsgRo = RecognitionObject.Ocr(293, 80, 873, 868); // 聊天框
moveMouseTo(1555, 860); // 移走鼠标防止干扰OCR
await sleep(200);
let wait_flag = true;
const player_num = parseInt(settingDic["player_all"], 10);
let judge_dic = {};
while (wait_flag) { // 循环等待
let ocr = captureGameRegion().FindMulti(ocrMsgRo); // 当前页面OCR
for (let l = 0; l < ocr.count; l++) { // 遍历OCR数组
if (ocr[l].text === "路线启动") { // 检测队长的消息
log.info(`检测到队长发送的路线启动信息`);
wait_flag = false;
break;
}
}
await sleep(500);
}
break;
}
}
await pathingScript.run(JSON.stringify(pathDic));
}
genshin.returnMainUi();
await sleep(1000);
// 打开聊天框等待继续
keyPress("VK_RETURN"); // 按Enter进入聊天界面
await sleep(500);
const ocrRo = RecognitionObject.Ocr(0, 0, 257, 173);
moveMouseTo(1555, 860); // 移走鼠标防止干扰OCR
await sleep(200);
let ocr = captureGameRegion().Find(ocrRo); // 当前页面OCR
if (ocr.isExist() && ocr.text === "当前队伍") { // 多此一举
ocr.Click(); // 点击 当前队伍
}
await sleep(200);
// const ocrMsgRo = RecognitionObject.Ocr(397, 83, 662, 870); // 聊天框
const ocrMsgRo = RecognitionObject.Ocr(293, 80, 873, 868); // 聊天框
moveMouseTo(1555, 860); // 移走鼠标防止干扰OCR
await sleep(200);
while (true) { // 循环等待
let ocr = captureGameRegion().FindMulti(ocrMsgRo); // 当前页面OCR
for (let l = 0; l < ocr.count; l++) { // 遍历OCR数组
if (ocr[l].text.includes("全部路线结束")) { // 检测队长的消息
log.info(`检测到队长发送的脚本结束信息`);
// 返回单人模式(会自动踢出队员)
genshin.returnMainUi();
await sleep(1000);
keyPress("VK_F2");
await sleep(2500);
click(1651, 1019);
return true;
}
}
await sleep(500);
}
} else {
log.error(`未能获取玩家标识...`);
}
} else {
log.error(`未能成功加入房主(${settingDic["match_detail"]})...`);
}
}
}
}
await main();
})();

View File

@@ -0,0 +1,15 @@
{
"manifest_version": 1,
"name": "锄地-联机版",
"version": "1.0",
"bgi_version": "0.45.0",
"description": "脚本名称:锄地-联机版\n功能描述\n核心功能------------------------------>\n1.实现联机锄地\n2.通过发送聊天内容核验路线进度,实现每条路线同步开始\n注意事项------------------------------>\n1.手动加世界(不推荐)必须两人都在一个世界且必须是联机模式\n2.自动加世界需要再JS脚本配置正确的进行设置\n3.支持自定义路线需要严格按照说明进行配置详细说明位于READEME.md\n---------------------------------------->\n作者提瓦特钓鱼玳师\n脚本反馈邮箱hijiwos@hotmail.com",
"authors": [
{
"name": "提瓦特钓鱼玳师",
"url": "https://github.com/Hijiwos"
}
],
"settings_ui": "settings.json",
"main": "main.js"
}

View File

@@ -0,0 +1,61 @@
[
{
"name": "mode",
"type": "select",
"label": "选择加入世界的方式(所有玩家的该选项应一致): \n(选择后在下方对应区域进行设置)",
"options": [
"手动加世界",
"自动加世界"
]
},
{
"name": "player_id",
"type": "select",
"label": "<--------------------------手动加世界-------------------------->\n\n请挑选你的玩家标识: ",
"options": [
"1P",
"2P",
"3P",
"4P"
]
},
{
"name": "player_all",
"type": "select",
"label": "选择玩家总数: ",
"options": [
"2",
"3",
"4"
]
},
{
"name": "match_identity",
"type": "select",
"label": "<--------------------------自动加世界-------------------------->\n注意: 该模式需要选择领队\n\n请挑选你的身份: ",
"options": [
"作为领队(房主)[下方填入队员昵称,空格隔开]",
"作为队员(组车)[下方填入房主uid]"
]
},
{
"name": "match_detail",
"type": "input-text",
"label": "⏬⏬⏬⏬⏬⏬⏬⏬⏬⏬⏬⏬⏬⏬⏬⏬⏬⏬⏬⏬⏬"
},
{
"name": "match_mode",
"type": "select",
"label": "名称匹配模式: ",
"options": [
"全字匹配",
"部分匹配"
]
},
{
"name": "path_folder",
"type": "select",
"label": "<---------------------------路径设置--------------------------->\n选择要执行的路径文件夹: \n(请手动添加到assets文件夹内添加完成后运行一遍程序)",
"options": []
}
]