背包统计采集,新增noRecord模式、怪物材料CD文件 (#1985)

* 背包统计采集,新增noRecord模式、怪物材料CD文件

增加无路径间的扫描、无数量记录的noRecord模式,适合路径记录已经炼成的玩家。新增怪物材料CD文件,以支持轻度刷怪需求。

* Update settings.json

* Add files via upload
This commit is contained in:
JJMdzh
2025-09-24 23:34:44 +08:00
committed by GitHub
parent 26bf5a129f
commit e2dec938f2
6 changed files with 354 additions and 258 deletions

View File

@@ -1,6 +1,6 @@
// ==UserScript==
// @name 背包统计采集系统
// @version 2.40
// @version 2.42
// @description 识别路径文件,根据材料数量,自动执行路线,或者主动选择材料类别,统计材料数量
// @author 吉吉喵
// @match 原神版本5.6BGI 版本0.44.8
@@ -22,7 +22,7 @@
*
* 使用即表示您已阅读并同意上述条款。
*
* Last Updated: 2025-05-19
* Last Updated: 2025-09-23
*/
# 背包材料统计
@@ -40,6 +40,8 @@
📄 薄荷-吉吉喵.json
📁 苹果/
📄 旅行者的果园.json
📁 名刀镡/
📄 旅行者的名刀镡.json
📁history_record/ 背包统计 自动生成每类的历史记录每类中旧纪录上限为365个
📁overwrite_record/ 背包统计 自动生成,每类的最新一次记录
📁pathing_record/ 自动生成,路径运行时间记录
@@ -49,8 +51,8 @@
## 使用方法
1. 将脚本添加至调度器。
2. 右键点击脚本以修改JS自定义配置。
3. 执行路径功能需要📁pathing有路径文件夹
2. 右键点击脚本以修改JS自定义配置:刷怪、采集推荐:2.仅📁pathing材料纯材料数量识别选3.仅【材料分类】勾选
3. 执行路径功能需要📁pathing有【材料正式名】的文件夹具体可参考BetterGI\Repos\bettergi-scripts-list-git\repo\pathing目录选取【材料正式名】的文件夹内有子文件夹或者路径。复制到BetterGI\User\JsScript\背包材料统计\pathing目录具体参考## 文件结构
## 注意
因食物部分图片未补足,为适配快速滑页,苹果、日落果、星蕈、活化的星蕈、枯焦的星蕈、泡泡桔、烛伞蘑菇、美味的宝石闪闪,这八个食物必须有,且在第一行。不然这几个食物会无法识别。
@@ -81,4 +83,5 @@
+ v2.29 新增排除提示;调整平均时间成本计算;过滤掉差异较大的记录;
+ v2.30 更改路径专注模式默认值加log提示去除注释掉的调试log背包材料统计更改名为背包统计采集系统
+ v2.40 优化背包识别时占用的内存;增加通知;
+ v2.41 修复勾选分类的本地记录bug新增仅背包统计选项如果本地记录已经遭到破坏。比如每条路径都产生大量材料名-0.txt就只能手动清理或者删除本地记录pathing_record重新跑
+ v2.41 修复勾选分类的本地记录bug新增仅背包统计选项如果本地记录已经遭到破坏。比如每条路径都产生大量材料名-0.txt就只能手动清理或者删除本地记录pathing_record重新跑
+ v2.42 增加无路径间的扫描、无数量记录的noRecord模式适合路径记录已经炼成的玩家。新增怪物材料CD文件以支持轻度刷怪需求。

View File

@@ -4,6 +4,7 @@ const OCRdelay = Math.min(50, Math.max(0, Math.floor(Number(settings.OcrDelay) |
const imageDelay = Math.min(1000, Math.max(0, Math.floor(Number(settings.ImageDelay) || 0))); // 识图基准时长
const timeCost = Math.min(300, Math.max(0, Math.floor(Number(settings.TimeCost) || 30))); // 耗时和材料数量的比值,即一个材料多少秒
const notify = settings.notify || false;
const noRecord = settings.noRecord || false; // 全局控制参数(无需传递)
// 定义映射表"unselected": "反选材料分类",
const material_mapping = {
"General": "一般素材",
@@ -774,7 +775,6 @@ function readAllFilePaths(dirPath, currentDepth = 0, maxDepth = 3, includeExtens
const fileExtension = entry.substring(entry.lastIndexOf('.'));
if (includeExtensions.includes(fileExtension.toLowerCase())) {
filePaths.push(entry); // 添加文件路径
} else {
}
}
}
@@ -980,30 +980,86 @@ function recordRunTime(resourceName, pathName, startTime, endTime, runTime, reco
}
}
// -------------------------- 新增:通知分段发送工具函数 --------------------------
/**
* 通知分段发送超过500字符自动拆分
* @param {string} msg - 原始通知消息
* @param {Function} sendFn - 原始通知发送函数如notification.Send
* @param {number} chunkSize - 每段最大字符数默认500
*/
function sendNotificationInChunks(msg, sendFn, chunkSize = 500) {
if (!notify) return; // 未开启通知,直接返回
if (typeof msg !== 'string' || msg.length === 0) return;
// 短消息直接发送
if (msg.length <= chunkSize) {
sendFn(msg);
return;
}
// 长消息拆分发送
const totalChunks = Math.ceil(msg.length / chunkSize);
log.info(`通知消息过长(${msg.length}字符),将拆分为${totalChunks}段发送`);
let start = 0;
for (let i = 0; i < totalChunks; i++) {
// 截取当前段(最后一段取剩余所有字符)
const end = Math.min(start + chunkSize, msg.length);
const chunkMsg = `【通知${i+1}/${totalChunks}\n${msg.substring(start, end)}`;
// 发送当前段
sendFn(chunkMsg);
log.info(`已发送第${i+1}段通知(${chunkMsg.length}字符)`);
// 更新起始位置
start = end;
}
}
// noRecord=true时的最终汇总记录函数
function recordFinalSummary(recordDir, firstScanTime, endTime, totalRunTime, totalDifferences) {
const summaryPath = `${recordDir}/final_summary_noRecord.txt`;
const content = `===== 材料收集最终汇总noRecord模式=====
首次扫描时间:${firstScanTime}
末次扫描时间:${endTime}
总耗时:${totalRunTime.toFixed(1)}
累计获取材料:
${Object.entries(totalDifferences).map(([name, diff]) => ` ${name}: +${diff}`).join('\n')}
=========================================\n\n`;
writeContentToFile(summaryPath, content);
log.info(`noRecord模式最终汇总已记录至 ${summaryPath}`);
}
// 读取材料对应的文件,获取上次运行的结束时间
function getLastRunEndTime(resourceName, pathName, recordDir) {
const recordPath = `${recordDir}/${resourceName}.txt`; // 记录文件路径,以材料名命名
try {
const content = file.readTextSync(recordPath); // 同步读取记录文件
const lines = content.split('\n');
function getLastRunEndTime(resourceName, pathName, recordDir, noRecordDir) { // 接收recordDir和noRecordDir参数
const checkDirs = [recordDir, noRecordDir];
let latestEndTime = null;
// 从文件内容的开头开始查找
for (let i = 0; i < lines.length; i++) {
if (lines[i].startsWith('路径名: ')) {
const currentPathName = lines[i].split('路径名: ')[1];
if (currentPathName === pathName) {
const endTimeLine = lines[i + 2]; // 假设结束时间在路径名后的第三行
if (endTimeLine.startsWith('结束时间: ')) {
return endTimeLine.split('结束时间: ')[1]; // 返回结束时间
checkDirs.forEach(dir => {
const recordPath = `${dir}/${resourceName}.txt`;
try {
const content = file.readTextSync(recordPath);
const lines = content.split('\n');
for (let i = 0; i < lines.length; i++) {
if (lines[i].startsWith('路径名: ') && lines[i].split('路径名: ')[1] === pathName) {
const endTimeLine = lines[i + 2];
if (endTimeLine?.startsWith('结束时间: ')) {
const endTimeStr = endTimeLine.split('结束时间: ')[1];
const endTime = new Date(endTimeStr);
if (!latestEndTime || endTime > new Date(latestEndTime)) {
latestEndTime = endTimeStr;
}
}
}
}
} catch (error) {
log.debug(`目录${dir}中无${resourceName}.txt记录跳过检查`);
}
} catch (error) {
log.warn(`未找到记录文件或记录文件中无结束时间: ${recordPath}`);
}
return null; // 如果未找到记录文件或结束时间,返回 null
});
return latestEndTime;
}
// 计算时间成本
@@ -1091,9 +1147,6 @@ function canRunPathingFile(currentTime, lastEndTime, refreshCD, pathName) {
// 处理“N次0点”这样的特殊规则
const times = refreshCD.times;
// 计算从上次运行时间到当前时间的天数差
let daysPassed = Math.floor((currentDate - lastEndTimeDate) / (1000 * 60 * 60 * 24));
// 计算下一个刷新时间
const nextRunTime = new Date(lastEndTimeDate);
nextRunTime.setDate(lastEndTimeDate.getDate() + times); // 在上次运行时间的基础上加上N天
@@ -1184,12 +1237,13 @@ function matchImageAndGetCategory(resourceName, imagesDir) {
return result;
}
(async function () {
// 定义文件夹路径
const materialDir = "materialsCD"; // 存储材料信息的文件夹
const pathingDir = "pathing"; // 存储路径信息的文件夹
const recordDir = "pathing_record"; // 存储运行记录的文件夹
const noRecordDir = `${recordDir}/noRecord`; // 基于recordDir定义
const imagesDir = "assets\\images"; // 存储图片的文件夹
// 从设置中获取目标材料名称
@@ -1262,8 +1316,8 @@ function matchImageAndGetCategory(resourceName, imagesDir) {
// 调用背包材料统计
const pathingMaterialCounts = await MaterialPath(materialCategoryMap);
log.info(`materialCategoryMap文本${JSON.stringify(materialCategoryMap)}`);
log.info(`目标文本:${JSON.stringify(pathingMaterialCounts)}`);
// log.info(`materialCategoryMap文本${JSON.stringify(materialCategoryMap)}`);
// log.info(`目标文本:${JSON.stringify(pathingMaterialCounts)}`);
if (pathingMode.onlyCategory) {
return;
}
@@ -1282,7 +1336,7 @@ function matchImageAndGetCategory(resourceName, imagesDir) {
if (lowCountMaterialNames.length === 0) {
log.info(`所有路径材料的数量均高于目标数量${targetCount}`);
}
log.info(`目标文本:${JSON.stringify(lowCountMaterialNames)}`);
// log.info(`目标文本:${JSON.stringify(lowCountMaterialNames)}`);
// 将路径文件按是否为目标材料分类
const prioritizedPaths = [];
const normalPaths = [];
@@ -1316,6 +1370,12 @@ function matchImageAndGetCategory(resourceName, imagesDir) {
// 假设 flattenedLowCountMaterials 是一个全局变量或在外部定义的变量
let currentMaterialName = null; // 用于记录当前材料名
// 记录首次扫描时间和初始数量noRecord=true时用
const firstScanTime = new Date().toLocaleString();
const initialMaterialCounts = flattenedLowCountMaterials.reduce((acc, mat) => {
acc[mat.name] = parseInt(mat.count, 10) || 0;
return acc;
}, {});
// 全局累积差值统计(记录所有材料的总变化量)
const globalAccumulatedDifferences = {};
// 按材料分类的累积差值统计(记录每种材料的累计变化)
@@ -1331,152 +1391,179 @@ function matchImageAndGetCategory(resourceName, imagesDir) {
for (const [refreshCDKey, materialList] of Object.entries(materials)) {
const refreshCD = JSON.parse(refreshCDKey);
if (materialList.includes(resourceName)) {
// 获取当前时间
const currentTime = getCurrentTimeInHours();
// 调用时传递recordDir和noRecordDir
const lastEndTime = getLastRunEndTime(resourceName, pathName, recordDir, noRecordDir);
// 调用时传递recordDir
const isPathValid = checkPathNameFrequency(resourceName, pathName, recordDir);
// 调用时传递recordDir
const perTime = noRecord ? null : calculatePerTime(resourceName, pathName, recordDir);
// 读取上次运行的结束时间
const lastEndTime = getLastRunEndTime(resourceName, pathName, recordDir);
log.info(`路径文件:${pathName} 单个材料耗时:${perTime || 'noRecord模式忽略'}`);
// 计算效率
const perTime = calculatePerTime(resourceName, pathName, recordDir);
log.info(`路径文件:${pathName} 单个材料耗时:${perTime}`);
// 判断是否可以运行脚本
if (
canRunPathingFile(currentTime, lastEndTime, refreshCD, pathName) &&
checkPathNameFrequency(recordDir, resourceName, pathName) &&
(perTime === null || perTime <= timeCost)
isPathValid &&
(noRecord || perTime === null || perTime <= timeCost)
) {
log.info(`可调用路径文件:${pathName}`);
// 根据 materialCategoryMap 构建 resourceCategoryMap
const resourceCategoryMap = {};
for (const [materialCategory, materialList] of Object.entries(materialCategoryMap)) {
if (materialList.includes(resourceName)) {
resourceCategoryMap[materialCategory] = [resourceName];
break;
}
}
// 输出 resourceCategoryMap 以供调试
log.info(`resourceCategoryMap: ${JSON.stringify(resourceCategoryMap, null, 2)}`);
// 如果材料名发生变化,更新 flattenedLowCountMaterials
if (currentMaterialName !== resourceName) {
// 材料名变更前,输出上一材料的累积差值并通知
if (currentMaterialName && materialAccumulatedDifferences[currentMaterialName]) {
const prevDiffs = materialAccumulatedDifferences[currentMaterialName];
log.info(`材料[${currentMaterialName}]收集完成,累积差值:${JSON.stringify(prevDiffs, null, 2)}`);
if (notify) {
notification.Send(`材料[${currentMaterialName}]收集完成,累计获取:${JSON.stringify(prevDiffs, null, 2)}`);
}
const resourceCategoryMap = {};
for (const [materialCategory, materialList] of Object.entries(materialCategoryMap)) {
if (materialList.includes(resourceName)) {
resourceCategoryMap[materialCategory] = [resourceName];
break;
}
currentMaterialName = resourceName; // 更新当前材料名
// 调用背包材料统计(获取当前材料数量)
}
log.info(`resourceCategoryMap: ${JSON.stringify(resourceCategoryMap, null, 2)}`);
if (noRecord) {
if (currentMaterialName !== resourceName) {
currentMaterialName = resourceName;
materialAccumulatedDifferences[resourceName] = {};
log.info(`noRecord模式材料名变更为【${resourceName}`);
}
const startTime = new Date().toLocaleString();
const initialPosition = genshin.getPositionFromMap();
await pathingScript.runFile(pathingFilePath);
const finalPosition = genshin.getPositionFromMap();
const finalCumulativeDistance = calculateDistance(initialPosition, finalPosition);
const endTime = new Date().toLocaleString();
const runTime = (new Date(endTime) - new Date(startTime)) / 1000;
const noRecordContent = `路径名: ${pathName}\n开始时间: ${startTime}\n结束时间: ${endTime}\n运行时间: ${runTime}\n数量变化: noRecord模式忽略\n\n`;
writeContentToFile(`${noRecordDir}/${resourceName}.txt`, noRecordContent);
log.info(`noRecord模式已记录至 ${noRecordDir}/${resourceName}.txt`);
} else {
if (currentMaterialName !== resourceName) {
if (currentMaterialName && materialAccumulatedDifferences[currentMaterialName]) {
const prevDiffs = materialAccumulatedDifferences[currentMaterialName];
log.info(`材料[${currentMaterialName}]收集完成,累积差值:${JSON.stringify(prevDiffs, null, 2)}`);
const prevMsg = `材料[${currentMaterialName}]收集完成,累计获取:${JSON.stringify(prevDiffs, null, 2)}`;
sendNotificationInChunks(prevMsg, notification.Send);
}
currentMaterialName = resourceName;
const updatedLowCountMaterials = await MaterialPath(resourceCategoryMap);
flattenedLowCountMaterials = updatedLowCountMaterials
.flat()
.sort((a, b) => parseInt(a.count, 10) - parseInt(b.count, 10));
materialAccumulatedDifferences[resourceName] = {};
}
const startTime = new Date().toLocaleString();
const initialPosition = genshin.getPositionFromMap();
await pathingScript.runFile(pathingFilePath);
const finalPosition = genshin.getPositionFromMap();
const finalCumulativeDistance = calculateDistance(initialPosition, finalPosition);
const endTime = new Date().toLocaleString();
const runTime = (new Date(endTime) - new Date(startTime)) / 1000;
const updatedLowCountMaterials = await MaterialPath(resourceCategoryMap);
// 展平数组并按数量从小到大排序
flattenedLowCountMaterials = updatedLowCountMaterials
const flattenedUpdatedMaterialCounts = updatedLowCountMaterials
.flat()
.sort((a, b) => parseInt(a.count, 10) - parseInt(b.count, 10));
log.info(`材料名变更,更新了 flattenedLowCountMaterials`);
// 初始化当前材料的累积差值记录
materialAccumulatedDifferences[resourceName] = {};
}
// 记录开始时间
const startTime = new Date().toLocaleString();
// 在路径执行前执行一次位移监测
const initialPosition = genshin.getPositionFromMap();
let initialCumulativeDistance = 0;
// 调用路径文件
await pathingScript.runFile(pathingFilePath);
// 在路径执行后执行一次位移监测
const finalPosition = genshin.getPositionFromMap();
const finalCumulativeDistance = calculateDistance(initialPosition, finalPosition);
// 记录结束时间
const endTime = new Date().toLocaleString();
// 计算运行时间
const runTime = (new Date(endTime) - new Date(startTime)) / 1000; // 秒
// 调用背包材料统计(获取调用路径文件后的材料数量)
const updatedLowCountMaterials = await MaterialPath(resourceCategoryMap);
// 展平数组并按数量从小到大排序
const flattenedUpdatedMaterialCounts = updatedLowCountMaterials
.flat()
.sort((a, b) => parseInt(a.count, 10) - parseInt(b.count, 10));
// 创建一个映射,用于存储更新前后的数量差值
const materialCountDifferences = {};
// 遍历更新后的材料数量,计算差值
flattenedUpdatedMaterialCounts.forEach(updatedMaterial => {
const originalMaterial = flattenedLowCountMaterials.find(material => material.name === updatedMaterial.name);
if (originalMaterial) {
const originalCount = parseInt(originalMaterial.count, 10);
const updatedCount = parseInt(updatedMaterial.count, 10);
const difference = updatedCount - originalCount;
// 只记录非零差值或者是当前处理的resourceName即使差值为0
if (difference !== 0 || updatedMaterial.name === resourceName) {
materialCountDifferences[updatedMaterial.name] = difference;
// 更新全局累积差值
if (globalAccumulatedDifferences[updatedMaterial.name]) {
globalAccumulatedDifferences[updatedMaterial.name] += difference;
} else {
globalAccumulatedDifferences[updatedMaterial.name] = difference;
}
// 更新当前材料的累积差值
if (materialAccumulatedDifferences[resourceName][updatedMaterial.name]) {
materialAccumulatedDifferences[resourceName][updatedMaterial.name] += difference;
} else {
materialAccumulatedDifferences[resourceName][updatedMaterial.name] = difference;
const materialCountDifferences = {};
flattenedUpdatedMaterialCounts.forEach(updatedMaterial => {
const originalMaterial = flattenedLowCountMaterials.find(material => material.name === updatedMaterial.name);
if (originalMaterial) {
const originalCount = parseInt(originalMaterial.count, 10);
const updatedCount = parseInt(updatedMaterial.count, 10);
const difference = updatedCount - originalCount;
if (difference !== 0 || updatedMaterial.name === resourceName) {
materialCountDifferences[updatedMaterial.name] = difference;
if (globalAccumulatedDifferences[updatedMaterial.name]) {
globalAccumulatedDifferences[updatedMaterial.name] += difference;
} else {
globalAccumulatedDifferences[updatedMaterial.name] = difference;
}
if (materialAccumulatedDifferences[resourceName][updatedMaterial.name]) {
materialAccumulatedDifferences[resourceName][updatedMaterial.name] += difference;
} else {
materialAccumulatedDifferences[resourceName][updatedMaterial.name] = difference;
}
}
}
}
});
});
// 更新 flattenedLowCountMaterials 为最新的材料数量
flattenedLowCountMaterials = flattenedLowCountMaterials.map(material => {
// 找到对应的更新后的材料数量
const updatedMaterial = flattenedUpdatedMaterialCounts.find(updated => updated.name === material.name);
if (updatedMaterial) {
return { ...material, count: updatedMaterial.count }; // 更新数量
flattenedLowCountMaterials = flattenedLowCountMaterials.map(material => {
const updatedMaterial = flattenedUpdatedMaterialCounts.find(updated => updated.name === material.name);
if (updatedMaterial) {
return { ...material, count: updatedMaterial.count };
}
return material;
});
log.info(`数量变化: ${JSON.stringify(materialCountDifferences, null, 2)}`);
// 调用时传递recordDir
recordRunTime(resourceName, pathName, startTime, endTime, runTime, recordDir, materialCountDifferences, finalCumulativeDistance);
}
return material;
});
// 打印数量差值
log.info(`数量变化: ${JSON.stringify(materialCountDifferences, null, 2)}`);
// 记录运行时间到材料对应的文件中
recordRunTime(resourceName, pathName, startTime, endTime, runTime, recordDir, materialCountDifferences, finalCumulativeDistance);
log.info(`当前材料名: ${JSON.stringify(resourceName, null, 2)}`);
categoryFound = true;
break;
categoryFound = true;
break;
} else {
if (perTime !== null && perTime > timeCost) {
log.info(`路径文件 ${pathName} 的单个材料耗时大于 ${timeCost} ,不执行`);
} else {
log.info(`路径文件 ${pathName} 未能执行!`);
}
log.info(`路径文件 ${pathName} 未能执行`);
}
}
}
if (categoryFound) break;
}
await sleep(1); // 夹断
}
// noRecord=false时保留原有全局通知true时跳过末次统一通知
if (!noRecord && Object.keys(globalAccumulatedDifferences).length > 0) {
log.info(`所有材料收集完成,全局累积差值:${JSON.stringify(globalAccumulatedDifferences, null, 2)}`);
// -------------------------- 替换2所有材料完成通知分段发送--------------------------
let allDoneMsg = "所有材料收集完成,累计获取:\n";
for (const [name, diff] of Object.entries(globalAccumulatedDifferences)) {
allDoneMsg += ` ${name}: ${diff}\n`;
}
sendNotificationInChunks(allDoneMsg, notification.Send);
}
// noRecord=true时执行末次扫描和总汇总
if (noRecord) {
log.info(`\nnoRecord模式开始末次背包扫描计算总差值`);
// 末次扫描获取最终数量
const finalMaterialCounts = await MaterialPath(materialCategoryMap);
const flattenedFinal = finalMaterialCounts.flat();
const finalCounts = flattenedFinal.reduce((acc, mat) => {
acc[mat.name] = parseInt(mat.count, 10) || 0;
return acc;
}, {});
// 计算总差值(仅保留增加的材料)
const totalDifferences = {};
Object.keys(initialMaterialCounts).forEach(name => {
const diff = finalCounts[name] - initialMaterialCounts[name];
if (diff > 0) {
totalDifferences[name] = diff;
}
});
// 输出总结果
const endTime = new Date().toLocaleString();
const totalRunTime = (new Date(endTime) - new Date(firstScanTime)) / 1000;
log.info(`\nnoRecord模式所有材料收集完成`);
log.info(`首次扫描时间:${firstScanTime}`);
log.info(`末次扫描时间:${endTime}`);
log.info(`总耗时:${totalRunTime.toFixed(1)}`);
log.info(`总累积获取:${JSON.stringify(totalDifferences, null, 2)}`);
// 记录最终汇总
recordFinalSummary(recordDir, firstScanTime, endTime, totalRunTime, totalDifferences);
// 发送最终通知(分段发送)
// -------------------------- 替换3noRecord模式最终通知分段发送--------------------------
let finalMsg = `材料收集完成noRecord模式\n总耗时:${totalRunTime.toFixed(1)}\n累计获取:\n`;
for (const [n, d] of Object.entries(totalDifferences)) {
finalMsg += ` ${n}: ${d}\n`;
}
sendNotificationInChunks(finalMsg, notification.Send);
}
await sleep(1); // 夹断
} catch (error) {
log.error(`操作失败: ${error}`);
}

View File

@@ -1,13 +1,12 @@
{
"manifest_version": 1,
"name": "背包统计采集系统",
"version": "2.41",
"version": "2.42",
"bgi_version": "0.44.8",
"description": "默认四行为一页;模板匹配材料OCR识别数量\n数字太小可能无法识别,用?代替。\n目前支持采集材料的数量统计+路径CD管理。",
"description": "模板匹配材料OCR识别数量\n支持背包材料的数量统计+路径CD管理自动优选路径\n具体支持看材料CD文件可自行增减材料CD。",
"authors": [
{
"name": "吉吉喵",
"links": "https://github.com/JJMdzh"
"name": "吉吉喵"
}
],
"settings_ui": "settings.json",

View File

@@ -0,0 +1,2 @@
4点偏光棱镜地脉的旧枝大英雄的经验特工祭刀冒险家的经验水晶棱镜混沌炉心猎兵祭刀流浪者的经验混沌回路石化的骨片黯淡棱镜混沌装置结实的骨片隐兽鬼爪黑晶号角脆弱的骨片隐兽利爪雾虚灯芯黑铜号角沉重号角混沌真眼隐兽指爪雾虚草囊地脉的新芽幽邃刻像混沌枢纽雾虚花粉地脉的枯叶夤夜刻像混沌机关督察长祭刀初生的浊水幻灵晦暗刻像混浊棱晶老旧的役人怀表浊水的一掬渊光鳍翅破缺棱晶茁壮菌核休眠菌核月色鳍翅浊水的一滴锲纹的横脊失活菌核密固的横脊异界生命核羽状鳍翅外世突触未熄的剑柄残毁的横脊混沌锚栓混沌模块漫游者的盛放之花裂断的剑柄隙间之核何人所珍藏之花役人的时时刻刻残毁的剑柄混沌容器役人的制式怀表意志巡游的符像来自何处的待放之花辉光棱晶史莱姆凝液意志明晰的寄偶繁光躯外骸迷光的蜷叶之心不祥的面具惑光的阔叶意志破碎的残片稀光遗骼失光块骨折光的胚芽污秽的面具聚燃的游像眼幽雾兜盔破损的面具聚燃的命种明燃的棱状壳蕴热的背壳冷裂壳块幽雾片甲禁咒绘卷聚燃的石块封魔绘卷幽雾化形秘源真芯霜夜的煌荣史莱姆原浆导能绘卷秘源机鞘霜夜的柔辉历战的箭簇史莱姆清秘源轴霜夜的残照原素花蜜异海之块浮游干核锐利的箭簇孢囊晶尘异海凝珠微光花蜜牢固的箭簇奇械机芯齿轮尉官的徽记荧光孢粉骗骗花蜜名刀镡士官的徽记机关正齿轮蕈兽孢子啮合齿轮影打刀镡新兵的徽记织金红绸攫金鸦印横行霸者的利齿破旧的刀镡镶边红绸浮游晶化核老练的坚齿藏银鸦印褪色红绸寻宝鸦印异色结晶石浮游幽核稚嫩的尖齿磨损的执凭龙冠武士的金哨战士的铁哨卫从的木哨精制机轴加固机轴毁损机轴霜镌的执凭精致的执凭

View File

@@ -1,20 +1,19 @@
12小时晶蝶野猪松鼠狐狸鸭子路边闪光点兽肉禽肉神秘的肉鱼肉鳗肉螃蟹青蛙发光髓蜥蜴尾巴晶核鳅鳅宝玉燃素蜜虫固晶甲虫
12小时晶蝶野猪松鼠狐狸鸭子路边闪光点兽肉禽肉神秘的肉鱼肉鳗肉螃蟹青蛙发光髓蜥蜴尾巴晶核鳅鳅宝玉吉光虫,燃素蜜虫,固晶甲虫,月萤虫,
24小时沉玉仙茗狗粮
24小时沉玉仙茗狗粮
46小时小灯草嘟嘟莲落落莓塞西莉亚花慕风蘑菇蒲公英籽钩钩果风车菊霓裳花清心琉璃袋琉璃百合夜泊石绝云椒椒星螺石珀清水玉海灵芝鬼兜虫绯樱绣球鸣草珊瑚真珠晶化骨髓血斛天云草实幽灯蕈沙脂蛹月莲帕蒂沙兰树王圣体菇圣金虫万相石悼灵花劫波莲赤念果苍晶螺海露花柔灯铃子探测单元湖光铃兰幽光星星虹彩蔷薇初露之源浪沫羽鳃灼灼彩菊肉龙掌青蜜莓枯叶紫英微光角菌云岩裂叶琉鳞石奇异的「牙齿」冰雾花花朵烈焰花花蕊便携轴承霜盏花月落银
46小时小灯草嘟嘟莲落落莓塞西莉亚花慕风蘑菇蒲公英籽钩钩果风车菊霓裳花清心琉璃袋琉璃百合夜泊石绝云椒椒星螺石珀清水玉海灵芝鬼兜虫绯樱绣球鸣草珊瑚真珠晶化骨髓血斛天云草实幽灯蕈沙脂蛹月莲帕蒂沙兰树王圣体菇圣金虫万相石悼灵花劫波莲赤念果苍晶螺海露花柔灯铃子探测单元湖光铃兰幽光星星虹彩蔷薇初露之源浪沫羽鳃灼灼彩菊肉龙掌青蜜莓枯叶紫英微光角菌云岩裂叶琉鳞石奇异的「牙齿」冰雾花花朵烈焰花花蕊便携轴承霜盏花月落银
72小时
1次0点铁块甜甜花胡萝卜蘑菇松茸松果金鱼草莲蓬薄荷鸟蛋树莓白萝卜苹果日落果竹笋海草堇瓜星蕈墩墩桃须弥蔷薇香辛果枣椰泡泡桔汐藻茉洁草久雨莲颗粒果烛伞蘑菇澄晶实红果果菇苦种烬芯花夏槲果白灵果寒涌石宿影花
1次0点铁块甜甜花胡萝卜蘑菇松茸松果金鱼草莲蓬薄荷鸟蛋树莓白萝卜苹果日落果竹笋海草堇瓜星蕈墩墩桃须弥蔷薇香辛果枣椰泡泡桔汐藻茉洁草久雨莲颗粒果烛伞蘑菇澄晶实红果果菇苦种烬芯花夏槲果白灵果寒涌石宿影花
2次0点白铁块星银矿石
2次0点白铁块星银矿石
3次0点水晶块紫晶块萃凝晶魔晶块钓鱼点虹滴晶
3次0点水晶块紫晶块萃凝晶魔晶块钓鱼点虹滴晶
4点精英怪物,吉光虫,盐,胡椒,洋葱,牛奶,番茄,卷心菜,土豆,小麦,稻米,虾仁,豆腐,杏仁,发酵果实汁,咖啡豆,秃秃豆,面粉,奶油,熏禽肉,黄油,火腿,糖,香辛料,蟹黄,果酱,奶酪,培根,香肠,「冷鲜肉」,黑麦,酸奶油,黑麦粉
4点胡椒洋葱牛奶番茄卷心菜土豆小麦稻米虾仁豆腐杏仁发酵果实汁咖啡豆秃秃豆面粉奶油熏禽肉黄油火腿香辛料蟹黄果酱奶酪培根香肠「冷鲜肉」黑麦黑麦粉,酸奶油,
6点
即时刷新:蝴蝶,萤火虫,蝴蝶的翅膀,发光髓

View File

@@ -1,97 +1,103 @@
[
{
"name": "TargetCount",
"type": "input-text",
"label": "js目录下默认扫描的文件结构\n./📁BetterGI/📁User/📁JsScript/\n📁背包材料统计/\n 📁pathing/\n 📁 薄荷/\n 📄 薄荷1.json\n 📁 薄荷效率/\n 📄 薄荷-吉吉喵.json\n 📁 苹果/\n 📄 旅行者的果园.json\n----------------------------------\n目标数量默认5000\n给📁pathing下材料设定的目标数"
},
{
"name": "TargetresourceName",
"type": "input-text",
"label": "----------------------------------\n优先级材料跳过目标数直接运行\n如填入 甜甜花,薄荷,苹果"
},
{
"name": "TimeCost",
"type": "input-text",
"label": "====================\n时间成本秒\n一单位材料的平均耗时默认30"
},
{
"name": "notify",
"type": "checkbox",
"label": "----------------------------------\n是否发送通知。默认否\n需在BGI开启JS通知并设置通知地址"
},
{
"name": "Pathing",
"type": "select",
"label": "====================\n扫描📁pathing下的\n勾选【材料分类】的材料。默认:兼并",
"options": [
"1.兼并:📁pathing材料+【材料分类】",
"2.仅📁pathing材料",
"3.仅【材料分类】勾选"
{
"name": "TargetCount",
"type": "input-text",
"label": "js目录下默认扫描的文件结构\n./📁BetterGI/📁User/📁JsScript/\n📁背包材料统计/\n 📁pathing/\n 📁 薄荷/\n 📄 薄荷1.json\n 📁 薄荷效率/\n 📄 薄荷-吉吉喵.json\n 📁 名刀镡/\n 📄 旅行者的名刀镡.json\n----------------------------------\n目标数量默认5000\n给📁pathing下材料设定的目标数"
},
{
"name": "TargetresourceName",
"type": "input-text",
"label": "----------------------------------\n优先级材料跳过目标数直接运行\n如填入 甜甜花,薄荷,苹果"
},
{
"name": "TimeCost",
"type": "input-text",
"label": "====================\n时间成本秒\n一单位材料的平均耗时默认30"
},
{
"name": "notify",
"type": "checkbox",
"label": "----------------------------------\n是否发送通知。默认否\n需在BGI开启JS通知并设置通知地址"
},
{
"name": "noRecord",
"type": "checkbox",
"label": "----------------------------------\n取消扫描数量。默认\n勾选将不进行单路径的扫描,但保留时间记录\n(推荐路径记录炼成后启用)"
},
{
"name": "Pathing",
"type": "select",
"label": "====================\n扫描📁pathing下的\n或勾选【材料分类】的材料。默认兼并",
"options": [
"1.兼并:📁pathing材料+【材料分类】",
"2.仅📁pathing材料",
"3.仅【材料分类】勾选",
]
},
{
"name": "Smithing",
"type": "checkbox",
"label": "\n----------------------------------\n【锻造素材】"
},
{
"name": "Drops",
"type": "checkbox",
"label": "如:矿石、原胚\n----------------------------------\n【怪物掉落素材】"
},
{
"name": "ForagedFood",
"type": "checkbox",
"label": "如:经验书、怪物掉落\n----------------------------------\n【采集食物】食用回血"
},
{
"name": "General",
"type": "checkbox",
"label": "如:苹果、日落果、泡泡桔\n----------------------------------\n【一般素材】"
},
{
"name": "CookingIngs",
"type": "checkbox",
"label": "如:特产、非食用素材\n----------------------------------\n\n【烹饪用食材】"
},
{
"name": "Weekly",
"type": "checkbox",
"label": "----------------------------------\n\n【周本素材】"
},
{
"name": "Wood",
"type": "checkbox",
"label": "----------------------------------\n\n【木材】"
},
{
"name": "CharAscension",
"type": "checkbox",
"label": "----------------------------------\n\n【角色突破素材】"
},
{
"name": "Fishing",
"type": "checkbox",
"label": "----------------------------------\n\n【鱼饵、鱼类】"
},
{
"name": "Gems",
"type": "checkbox",
"label": "----------------------------------\n\n【宝石】"
},
{
"name": "Talent",
"type": "checkbox",
"label": "----------------------------------\n\n【角色天赋素材】"
},
{
"name": "WeaponAscension",
"type": "checkbox",
"label": "----------------------------------\n\n【武器突破素材】"
},
{
"name": "ImageDelay",
"type": "input-text",
"label": "数字太小可能无法识别,用?代替\n====================\n识图延迟时间默认:10 毫秒)"
}
]
},
{
"name": "Smithing",
"type": "checkbox",
"label": "刷怪、采集推荐:2.仅📁pathing材料\n----------------------------------\n【锻造素材】"
},
{
"name": "Drops",
"type": "checkbox",
"label": "如:矿石、原胚\n----------------------------------\n【怪物掉落素材】"
},
{
"name": "ForagedFood",
"type": "checkbox",
"label": "如:经验书、怪物掉落\n----------------------------------\n【采集食物】食用回血"
},
{
"name": "General",
"type": "checkbox",
"label": "如:苹果、日落果、泡泡桔\n----------------------------------\n【一般素材】"
},
{
"name": "CookingIngs",
"type": "checkbox",
"label": "如:特产、非食用素材\n----------------------------------\n\n【烹饪用食材】"
},
{
"name": "Weekly",
"type": "checkbox",
"label": "----------------------------------\n\n【周本素材】"
},
{
"name": "Wood",
"type": "checkbox",
"label": "----------------------------------\n\n【木材】"
},
{
"name": "CharAscension",
"type": "checkbox",
"label": "----------------------------------\n\n【角色突破素材】"
},
{
"name": "Fishing",
"type": "checkbox",
"label": "----------------------------------\n\n【鱼饵、鱼类】"
},
{
"name": "Gems",
"type": "checkbox",
"label": "----------------------------------\n\n【宝石】"
},
{
"name": "Talent",
"type": "checkbox",
"label": "----------------------------------\n\n【角色天赋素材】"
},
{
"name": "WeaponAscension",
"type": "checkbox",
"label": "----------------------------------\n\n【武器突破素材】"
},
{
"name": "ImageDelay",
"type": "input-text",
"label": "数字太小可能无法识别,用?代替\n====================\n识图延迟时间默认:10 毫秒)"
}
]