更新跳楼机 (#3027)

This commit is contained in:
skyflag2022
2026-03-22 21:52:52 +08:00
committed by GitHub
parent 33131ecbb6
commit a8d0b9a4c3
4 changed files with 248 additions and 56 deletions

View File

@@ -2,14 +2,36 @@
## 食用方法
### 模式选择
脚本支持两种使用模式,根据需求选择:
### 1. 固定数量模式
1. 将脚本添加至调度器。
2. 右键点击脚本以修改 JS 自定义配置。
1. 队伍名称:包含伊涅芙的队伍,必填
2. 伊涅芙今天吃什么:需要投喂的食材,不选择的情况下默认是苹果
3. 食材数量单次投喂的数量吃多少个再跳楼默认99个
4. 运行次数想嘎伊涅芙多少次默认1次
5. 模式选择:选择"固定数量模式"
3. 完成上述设置后点击运行即可
### 2. 剩余数量模式
1. 将脚本添加至调度器。
2. 右键点击脚本以修改 JS 自定义配置。
1. 队伍名称:包含伊涅芙的队伍,必填
2. 伊涅芙今天吃什么:需要投喂的食材(可多选)
3. 模式选择:选择"剩余数量模式"
4. 最终剩余数量:为每种选中的食材设置最终剩余数量(不设置则视为不处理该食材)
3. 完成上述设置后点击运行即可
### 通知设置
- 可勾选"通知"选项,运行结束后会收到通知
- 通知内容包括:
- 总共吃了多少个食物
- 每种食物的详细食用情况
- 没吃东西时也会收到提醒
## 注意事项
1. 队伍名称有一定长度并且清晰,避免系统识别失败
@@ -23,6 +45,10 @@
3. 感谢所有提供意见和修改建议用户,他们提供的素材让脚本运行更稳定
---------------------------------------------------------------------------------------------------------------------------------
## 更新日志
### 1.6.52026.03.22
1. 增加剩余数量模式
2. 增加通知功能
3. 优化排版
### 1.6.22026.01.31
1. 修复了一些bug
### 1.6.12025.11.04

View File

@@ -2,19 +2,27 @@
// ===== 1. 预处理部分 =====
const party = settings.n;//设置好要切换的队伍
const food = settings.food;//设置要吃的食物
let foods = []; //要吃的食物数组(剩余数量模式)
const food = settings.food;//固定数量模式要吃的食物
const foodNumber = Number(settings.foodNumber);
const foodCount = foodNumber - 1;//点击“+”的次数比食物数量少1
let n = settings.runNumber;//运行次数
const mode = settings.mode;//运行模式
const remainingFood = Number(settings.remainingFood);//最终剩余数量
let totalFoodToEat = 0; //需要消耗的食物总数
let autoCalculateRuns = false; //是否自动计算运行次数
let currentCount = 0; //当前食物数量
let eatNumbers = []; //每次要吃的食物数量数组
let currentFoodIndex = 0; //当前正在处理的食物索引
let foodInfos = []; //食物信息数组,包含每种食物的数量和计划
// 获取特定食材的剩余数量
function getRemainingFood(foodName) {
const value = settings[`remaining_${foodName}`];
// 如果值为空字符串或者转换为数字后是NaN则返回9999
return value === "" || isNaN(Number(value)) ? 9999 : Number(value);
}
const Dm = `assets/地脉.png`
const pingguo = `assets/${food}.png`;//食物图片路径
const zjz = `assets/zhengjianzhao.png`;//伊涅芙证件照
const foodbag = `assets/foodbag.png`;//背包的“食物”界面
@@ -26,7 +34,12 @@
if (foodCount > 98 || foodCount < 0) { log.error("食材数量请填写1-99之间的数字"); return; }//确保食材数量1~99
}
if (mode === "剩余数量模式") {
if (remainingFood < 0 ) { log.error("最终剩余数量请填写大于0的数字"); return; }//确保最终剩余数量合法
// 处理多食物设置
foods = Array.from(settings.foods);
if (foods.length === 0) {
log.error("请至少选择一种食物!");
return;
}
autoCalculateRuns = true;
}
if (!autoCalculateRuns && n <= 0) { log.error("不是哥们运行次数还能小于0"); return; }//确保运行次数合法
@@ -581,56 +594,112 @@
let currentFoodCount = foodCount;
let currentFoodNumber = foodNumber;
let currentFood = food; // 当前正在处理的食物
let currentFoodPath = `assets/${currentFood}.png`; // 当前食物的图片路径
// 只在第一次运行时获取当前食物数量并计算所有运行参数
if (dieCount === 0 && autoCalculateRuns) {
const currentCountStr = await getFoodCount(food, pingguo);
if (currentCountStr) {
currentCount = Number(currentCountStr);
// 计算需要消耗的食物总数
totalFoodToEat = currentCount - remainingFood;
// 重置食物信息数组
foodInfos = [];
eatNumbers = [];
// 获取所有选中食物的数量
for (let i = 0; i < foods.length; i++) {
const currentFoodName = foods[i];
const currentFoodPath = `assets/${currentFoodName}.png`;
const currentCountStr = await getFoodCount(currentFoodName, currentFoodPath);
if (totalFoodToEat <= 0) {
log.info(`当前${food}数量为${currentCount},已经满足或低于剩余数量${remainingFood}的要求,不需要再吃了!`);
await returnMijingUi();
n = 1;
return;
if (currentCountStr) {
const currentCount = Number(currentCountStr);
// 获取当前食物对应的剩余数量
const currentRemainingFood = getRemainingFood(currentFoodName);
// 验证剩余数量是否合法
if (currentRemainingFood < 0) {
log.error(`${currentFoodName}的最终剩余数量请填写大于等于0的数字`);
continue;
}
// 计算需要消耗的食物数量
const needToEat = currentCount - currentRemainingFood;
if (needToEat > 0) {
// 计算每次要吃的数量每次最多99个
const currentEatNumbers = [];
let remainingToEat = needToEat;
while (remainingToEat > 0) {
const eatNumber = Math.min(remainingToEat, 99);
currentEatNumbers.push(eatNumber);
remainingToEat -= eatNumber;
}
// 保存食物信息
foodInfos.push({
name: currentFoodName,
currentCount: currentCount,
remainingFood: currentRemainingFood,
needToEat: needToEat,
eatNumbers: currentEatNumbers,
currentIndex: 0
});
// 将当前食物的计划添加到总计划中
eatNumbers = eatNumbers.concat(currentEatNumbers);
//log.info(`当前${currentFoodName}数量为${currentCount},目标剩余${currentRemainingFood}个,需要消耗${needToEat}个。`);
//log.info(`计划分批次吃的数量列表为:${currentEatNumbers.join('、')}`);
} else {
log.info(`当前${currentFoodName}数量为${currentCount},已经满足或低于填写的剩余数量${currentRemainingFood},不需要再吃了!`);
}
} else {
log.info(`未获取到${currentFoodName}的数量,跳过进食。`);
}
// 计算每次要吃的数量每次最多99个
eatNumbers = [];
while (totalFoodToEat > 0) {
const eatNumber = Math.min(totalFoodToEat, 99);
eatNumbers.push(eatNumber);
totalFoodToEat -= eatNumber;
}
// 设置运行次数
n = eatNumbers.length;
log.info(`当前${food}数量为${currentCount},目标剩余${remainingFood}个,需要消耗${currentCount - remainingFood}个,将分${n}次完成。`);
log.info(`计划分批次吃的数量列表为:${eatNumbers.join('、')}`);
// 设置第一次要吃的数量
currentFoodNumber = eatNumbers[dieCount];
currentFoodCount = currentFoodNumber - 1;
} else {
// 如果无法获取数量,使用默认值
log.info(`未获取到食物数量,使用固定数量模式的设置`);
autoCalculateRuns = false;
}
} else if (autoCalculateRuns) {
// 非第一次运行,使用预计算的数量
currentFoodNumber = eatNumbers[dieCount];
// 如果没有需要吃的食物,退出
if (eatNumbers.length === 0) {
log.info("所有选中的食物都已经等于或低于填写的剩余数量,不需要再吃了!");
n = 1;
await returnMijingUi();
return;
}
// 设置运行次数
n = eatNumbers.length;
//log.info(`总共需要分${n}次完成所有食物的消耗。`);
// 设置第一次要吃的食物和数量
currentFoodIndex = 0;
currentFood = foodInfos[0].name;
currentFoodPath = `assets/${currentFood}.png`;
currentFoodNumber = foodInfos[0].eatNumbers[0];
currentFoodCount = currentFoodNumber - 1;
foodInfos[0].currentIndex = 1;
} else if (autoCalculateRuns) {
// 非第一次运行,确定当前要吃的食物和数量
let totalProcessed = 0;
for (let i = 0; i < foodInfos.length; i++) {
const foodInfo = foodInfos[i];
if (dieCount < totalProcessed + foodInfo.eatNumbers.length) {
currentFoodIndex = i;
currentFood = foodInfo.name;
currentFoodPath = `assets/${currentFood}.png`;
currentFoodNumber = foodInfo.eatNumbers[dieCount - totalProcessed];
currentFoodCount = currentFoodNumber - 1;
foodInfo.currentIndex = dieCount - totalProcessed + 1;
break;
}
totalProcessed += foodInfo.eatNumbers.length;
}
}
while (retries < maxRetries) {
const ifpingguo = await imageRecognitionEnhanced(pingguo, 1, 0, 0, 115, 120, 1150, 880);//识别"苹果"图片
if (ifpingguo.found) {
const ifFood = await imageRecognitionEnhanced(currentFoodPath, 1, 0, 0, 115, 120, 1150, 880);//识别当前食物图片
if (ifFood.found) {
await leftButtonUp();
await sleep(500);
await click(ifpingguo.x + 45, ifpingguo.y + 50);
await click(ifFood.x + 45, ifFood.y + 50);
await sleep(1000);
await click(1700, 1020);//点击使用
@@ -646,7 +715,7 @@
await click(1180, 770);//点击确认
await sleep(500);
log.info("看我一口气吃掉" + currentFoodNumber + "个" + food + "");
log.info("看我一口气吃掉" + currentFoodNumber + "个" + currentFood + "");
totalFoodEaten += currentFoodNumber;
await returnMijingUi();
@@ -663,7 +732,7 @@
await sleep(100);
await moveMouseTo(1287, 131);
await genshin.returnMainUi();
throw new Error("没有找到指定的食物:" + food + ",请检查背包中该食材数量是否足够!");
throw new Error("没有找到指定的食物:" + currentFood + ",请检查背包中该食材数量是否足够!");
}
await moveMouseTo(1287, 161 + YOffset);
await sleep(300);
@@ -723,14 +792,53 @@
for (let i = 0; i < n; i++) {
await doit(dieCount);
dieCount++;
log.warn(`当前进度:第${i + 1}轮 / 共${n} 已吃 ${totalFoodEaten}${food}`);
// 在剩余数量模式下,显示当前正在处理的食物名称
if (autoCalculateRuns && foodInfos.length > 0) {
let currentFood = food;
let totalProcessed = 0;
for (let j = 0; j < foodInfos.length; j++) {
const foodInfo = foodInfos[j];
if (dieCount <= totalProcessed + foodInfo.eatNumbers.length) {
currentFood = foodInfo.name;
break;
}
totalProcessed += foodInfo.eatNumbers.length;
}
log.warn(`当前进度:第${i + 1}轮 / 共${n} 已吃 ${totalFoodEaten} 个食物`);
} else {
log.warn(`当前进度:第${i + 1}轮 / 共${n} 已吃 ${totalFoodEaten}${food}`);
}
}
} catch (error) {
await returnMijingUi();
log.error(`脚本运行中断: ${error.message}`);
return;
}
log.info("运行结束!今天的" + food + "味道不错哦~");
if (autoCalculateRuns && foodInfos.length > 0) {
log.info(`运行结束!今天的美食盛宴圆满完成~`);
log.info(`本次享用的食物有:${foods.join('、')}`);
log.info(`每一种都超级美味呢!`);
} else {
log.info("运行结束!今天的" + food + "味道不错哦~");
}
// 通知今天的进食情况
if (settings.notify) {
if (totalFoodEaten > 0) {
// 构建包含每种食物名字和个数的字符串
let foodDetails = "";
if (autoCalculateRuns && foodInfos.length > 0) {
foodDetails = foodInfos.map(info => `${info.name}: ${info.needToEat}`).join('、');
} else {
foodDetails = `${food}: ${totalFoodEaten}`;
}
notification.send(`总共吃了 ${totalFoodEaten} 个食物(${foodDetails}),伊涅芙吃得很开心呢!`);
} else {
notification.send("这次没吃东西哦");
}
}
await genshin.tpToStatueOfTheSeven();
})();

View File

@@ -1,7 +1,7 @@
{
"manifest_version": 1,
"name": "伊涅芙の自助餐",
"version": "1.6.4",
"version": "1.6.5",
"tags": [
"伊涅芙",
"调味品"

View File

@@ -9,6 +9,11 @@
],
"default": "固定数量模式"
},
{
"name": "notify",
"type": "checkbox",
"label": "通知"
},
{
"name": "n",
"type": "input-text",
@@ -18,7 +23,7 @@
{
"name": "food",
"type": "select",
"label": "伊涅芙今天吃什么(默认苹果)",
"label": "=============\n固定数量模式设置\n=============\n伊涅芙今天吃什么(默认苹果)",
"options": [
"苹果",
"日落果",
@@ -30,22 +35,75 @@
],
"default": "苹果"
},
{
"name": "remainingFood",
"type": "input-text",
"label": "最终剩余数量(剩余数量模式下生效)",
"default": "100"
},
{
"name": "foodNumber",
"type": "input-text",
"label": "食材数量\n想让伊涅芙吃多少个(固定数量模式下生效)",
"label": "食材数量\n想让伊涅芙吃多少个(单次)",
"default": "99"
},
{
"name": "runNumber",
"type": "input-text",
"label": "运行次数\n想嘎伊涅芙多少次(固定数量模式下生效",
"label": "运行次数想嘎伊涅芙多少次)",
"default": "1"
},
{
"name": "foods",
"type": "multi-checkbox",
"label": "=============\n剩余数量模式设置\n=============\n伊涅芙今天吃什么可多选",
"options": [
"苹果",
"日落果",
"泡泡桔",
"烛伞蘑菇",
"星蕈",
"活化的星蕈",
"枯焦的星蕈"
],
"default": [
"苹果"
]
},
{
"name": "remaining_苹果",
"type": "input-text",
"label": "苹果剩余数量",
"default": ""
},
{
"name": "remaining_日落果",
"type": "input-text",
"label": "日落果剩余数量",
"default": ""
},
{
"name": "remaining_泡泡桔",
"type": "input-text",
"label": "泡泡桔剩余数量",
"default": ""
},
{
"name": "remaining_烛伞蘑菇",
"type": "input-text",
"label": "烛伞蘑菇剩余数量",
"default": ""
},
{
"name": "remaining_星蕈",
"type": "input-text",
"label": "星蕈剩余数量",
"default": ""
},
{
"name": "remaining_活化的星蕈",
"type": "input-text",
"label": "活化的星蕈剩余数量",
"default": ""
},
{
"name": "remaining_枯焦的星蕈",
"type": "input-text",
"label": "枯焦的星蕈剩余数量",
"default": ""
}
]