mirror of
https://github.com/babalae/bettergi-scripts-list.git
synced 2026-03-21 04:19:51 +08:00
js脚本:药品消耗统计 (#2502)
This commit is contained in:
35
repo/药品消耗统计/README.md
Normal file
35
repo/药品消耗统计/README.md
Normal file
@@ -0,0 +1,35 @@
|
||||
## 一、功能概述
|
||||
|
||||
### 1. 初始化记录
|
||||
|
||||
- 用于建立药品库存的“基准值”
|
||||
- 通常在第一次使用或库存发生大幅变化时执行
|
||||
- 会将当前库存写入【history】
|
||||
|
||||
### 2. 记录 + 消耗计算
|
||||
|
||||
- 在存在初始化记录的前提下运行
|
||||
- 自动查找最近一次初始化记录
|
||||
- 计算当前库存相对于初始化时的消耗量
|
||||
- 记录结果写入【history】
|
||||
- 消耗结果写入【consumption】
|
||||
|
||||
### 3. 纯记录模式
|
||||
|
||||
- 不参与初始化与消耗计算
|
||||
- 每次运行仅记录当前库存
|
||||
- 用于长期留档或手动分析
|
||||
- 输出至【snapshot】
|
||||
|
||||
## 二、输出文件说明
|
||||
|
||||
- 三个模式分别输出三个文件,格式为:年月日时分秒-模式-名称-数量,回血和复活药分行记录。
|
||||
|
||||
## 三、使用说明
|
||||
|
||||
- 纯记录模式:运行一次记录一次,自行操作记录。
|
||||
- 消耗对比模式:普通记录减去上次初始化记录,得出消耗量,如果没有初始化,则自动转化为初始化数据。
|
||||
|
||||
## 四、版本与环境
|
||||
- BGI ≥ v0.54
|
||||
|
||||
530
repo/药品消耗统计/main.js
Normal file
530
repo/药品消耗统计/main.js
Normal file
@@ -0,0 +1,530 @@
|
||||
function mapRecordMode(modeText) {
|
||||
switch (modeText) {
|
||||
case "仅记录库存":
|
||||
return "snapshot";
|
||||
case "记录并计算消耗":
|
||||
return "record";
|
||||
case "重新初始化":
|
||||
return "init";
|
||||
default:
|
||||
return "record";
|
||||
}
|
||||
}
|
||||
let userName = settings.userName || "默认账户";
|
||||
const recoveryFoodName = settings.recoveryFoodName || "回血药名字没填";
|
||||
const resurrectionFoodName = settings.resurrectionFoodName || "复活药名字没填";
|
||||
const currentMode = mapRecordMode(settings.recordMode); // mode: "init" | "record" | "snapshot"
|
||||
const ocrRegion = {
|
||||
x: 150,
|
||||
y: 250,
|
||||
width: 220,
|
||||
height: 270
|
||||
};
|
||||
|
||||
(async function () {
|
||||
// 检验账户名
|
||||
async function getUserName() {
|
||||
userName = userName.trim();
|
||||
// 数字,中英文,长度在20个字符以内
|
||||
if (!userName || !/^[\u4e00-\u9fa5A-Za-z0-9]{1,20}$/.test(userName)) {
|
||||
log.error(`账户名${userName}违规,暂时使用默认账户名,请查看readme后修改`)
|
||||
userName = "默认账户";
|
||||
}
|
||||
return userName;
|
||||
}
|
||||
|
||||
// 格式化日期时间为 YYYY/MM/DD HH:mm:ss
|
||||
async function formatDateTime(date) {
|
||||
return `${date.getFullYear()}/${String(date.getMonth() + 1).padStart(2, '0')}/${String(date.getDate()).padStart(2, '0')} ${String(date.getHours()).padStart(2, '0')}:${String(date.getMinutes()).padStart(2, '0')}:${String(date.getSeconds()).padStart(2, '0')}`;
|
||||
}
|
||||
|
||||
// 处理旧格式记录文件(迁移功能保留)
|
||||
async function migrateOldFormatRecords(filePath) {
|
||||
try {
|
||||
const content = await file.readText(filePath);
|
||||
const lines = content.split('\n').filter(line => line.trim());
|
||||
|
||||
// 检查是否有旧格式的记录(如2025-12-10T02:02:32.460Z|179|546)
|
||||
const hasOldFormat = lines.some(line =>
|
||||
/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z\|\d+\|\d+$/.test(line)
|
||||
);
|
||||
|
||||
if (hasOldFormat) {
|
||||
// 直接清空文件(不创建备份)
|
||||
await file.writeText(filePath, '');
|
||||
notification.send(`${settings.userName}: 检测到旧格式记录,已重置记录文件`);
|
||||
return true;
|
||||
}
|
||||
} catch (error) {
|
||||
// 文件不存在或其他错误
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 文字OCR识别封装函数(支持空文本匹配任意文字)
|
||||
* @param {string} text - 要识别的文字,默认为"空参数",空字符串会匹配任意文字
|
||||
* @param {number} timeout - 超时时间,单位为秒,默认为10秒
|
||||
* @param {number} afterBehavior - 点击模式,0=不点击,1=点击文字位置,2=按F键,默认为0
|
||||
* @param {number} debugmodel - 调试模式,0=无输出,1=基础日志,2=详细输出,3=立即返回,默认为0
|
||||
* @param {number} x - OCR识别区域起始X坐标,默认为0
|
||||
* @param {number} y - OCR识别区域起始Y坐标,默认为0
|
||||
* @param {number} w - OCR识别区域宽度,默认为1920
|
||||
* @param {number} h - OCR识别区域高度,默认为1080
|
||||
* @param {number} matchMode - 匹配模式,0=包含匹配,1=精确匹配,默认为0
|
||||
* @returns {object} 包含识别结果的对象 {text, x, y, found}
|
||||
*/
|
||||
async function textOCREnhanced(
|
||||
text = "空参数",
|
||||
timeout = 10,
|
||||
afterBehavior = 0,
|
||||
debugmodel = 0,
|
||||
x = 0,
|
||||
y = 0,
|
||||
w = 1920,
|
||||
h = 1080,
|
||||
matchMode = 0
|
||||
) {
|
||||
const startTime = Date.now();
|
||||
const timeoutMs = timeout * 1000;
|
||||
let lastResult = null;
|
||||
let captureRegion = null; // 用于存储截图对象
|
||||
|
||||
// 只在调试模式1下输出基本信息
|
||||
if (debugmodel === 1) {
|
||||
if (text === "") {
|
||||
log.info(`OCR: 空文本模式 - 匹配任意文字`);
|
||||
} else if (text === "空参数") {
|
||||
log.warn(`OCR: 使用默认参数"空参数"`);
|
||||
}
|
||||
}
|
||||
|
||||
while (Date.now() - startTime < timeoutMs) {
|
||||
try {
|
||||
// 获取截图并进行OCR识别
|
||||
captureRegion = captureGameRegion();
|
||||
const resList = captureRegion.findMulti(RecognitionObject.ocr(x, y, w, h));
|
||||
|
||||
// 遍历识别结果
|
||||
for (let i = 0; i < resList.count; i++) {
|
||||
const res = resList[i];
|
||||
|
||||
// 检查是否匹配
|
||||
let isMatched = false;
|
||||
if (text === "") {
|
||||
// 空文本匹配任意文字
|
||||
isMatched = true;
|
||||
} else if (matchMode === 1) {
|
||||
// 精确匹配
|
||||
isMatched = res.text === text;
|
||||
} else {
|
||||
// 包含匹配(默认)
|
||||
isMatched = res.text.includes(text);
|
||||
}
|
||||
|
||||
if (isMatched) {
|
||||
// 只在调试模式1下输出匹配成功信息
|
||||
if (debugmodel === 1) {
|
||||
log.info(`OCR成功: "${res.text}" 位置(${res.x},${res.y})`);
|
||||
}
|
||||
|
||||
// 调试模式3: 立即返回
|
||||
if (debugmodel === 3) {
|
||||
// 释放内存
|
||||
if (captureRegion) {
|
||||
captureRegion.dispose();
|
||||
}
|
||||
return { text: res.text, x: res.x, y: res.y, found: true };
|
||||
}
|
||||
|
||||
// 执行后续行为
|
||||
switch (afterBehavior) {
|
||||
case 1: // 点击文字位置
|
||||
await sleep(1000);
|
||||
click(res.x, res.y);
|
||||
break;
|
||||
case 2: // 按F键
|
||||
await sleep(100);
|
||||
keyPress("F");
|
||||
break;
|
||||
default:
|
||||
// 不执行任何操作
|
||||
break;
|
||||
}
|
||||
|
||||
// 记录最后一个匹配结果但不立即返回
|
||||
lastResult = { text: res.text, x: res.x, y: res.y, found: true };
|
||||
}
|
||||
}
|
||||
|
||||
// 释放截图对象内存
|
||||
if (captureRegion) {
|
||||
captureRegion.dispose();
|
||||
}
|
||||
|
||||
// 如果找到匹配结果,根据调试模式决定是否立即返回
|
||||
if (lastResult && debugmodel !== 2) {
|
||||
return lastResult;
|
||||
}
|
||||
|
||||
// 短暂延迟后继续下一轮识别
|
||||
await sleep(100);
|
||||
|
||||
} catch (error) {
|
||||
// 发生异常时释放内存
|
||||
if (captureRegion) {
|
||||
captureRegion.dispose();
|
||||
}
|
||||
log.error(`OCR异常: ${error.message}`);
|
||||
await sleep(100);
|
||||
}
|
||||
}
|
||||
|
||||
if (debugmodel === 1) {
|
||||
// 超时处理
|
||||
if (text === "") {
|
||||
log.info(`OCR超时: ${timeout}秒内未找到任何文字`);
|
||||
} else {
|
||||
log.info(`OCR超时: ${timeout}秒内未找到"${text}"`);
|
||||
}
|
||||
}
|
||||
|
||||
// 返回最后一个结果或未找到
|
||||
return lastResult || { found: false };
|
||||
}
|
||||
|
||||
// 背包过期物品识别
|
||||
async function handleExpiredItems() {
|
||||
const ifGuoqi = await textOCREnhanced("物品过期", 1.5, 0, 3, 870, 280, 170, 40);
|
||||
if (ifGuoqi.found) {
|
||||
log.info("检测到过期物品,正在处理...");
|
||||
await sleep(500);
|
||||
click(980, 750); // 点击确认按钮,关闭提示
|
||||
}
|
||||
else { log.info("未检测到过期物品"); }
|
||||
}
|
||||
|
||||
async function recognizeNumberByOCR(ocrRegion, pattern) {
|
||||
let captureRegion = null;
|
||||
try {
|
||||
const ocrRo = RecognitionObject.ocr(ocrRegion.x, ocrRegion.y, ocrRegion.width, ocrRegion.height);
|
||||
captureRegion = captureGameRegion();
|
||||
const resList = captureRegion.findMulti(ocrRo);
|
||||
|
||||
if (!resList || resList.length === 0) {
|
||||
log.warn("OCR未识别到任何文本");
|
||||
return null;
|
||||
}
|
||||
|
||||
for (const res of resList) {
|
||||
if (!res || !res.text) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const numberMatch = res.text.match(pattern);
|
||||
if (numberMatch) {
|
||||
const number = parseInt(numberMatch[1] || numberMatch[0]);
|
||||
if (!isNaN(number)) {
|
||||
return number;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
log.error(`OCR识别时发生异常: ${error.message}`);
|
||||
}
|
||||
finally {
|
||||
if (captureRegion) {
|
||||
captureRegion.dispose();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// 获取食物数量(核心功能)
|
||||
async function getFoodNum() {
|
||||
keyPress("B");//打开背包
|
||||
await handleExpiredItems(); //处理过期物品弹窗
|
||||
await sleep(2000);
|
||||
click(863, 51);//选择食物
|
||||
await sleep(1000);
|
||||
click(170, 1020);//筛选
|
||||
await sleep(1000);
|
||||
click(195, 1020);//重置
|
||||
await sleep(1000);
|
||||
click(110, 110);//输入名字
|
||||
await sleep(1000);
|
||||
inputText(recoveryFoodName);
|
||||
await sleep(500);
|
||||
click(490, 1020);//确认筛选
|
||||
await sleep(1000);
|
||||
var recoveryNumber = await recognizeNumberByOCR(ocrRegion, /\d+/) //识别回血药数量
|
||||
// 处理回血药识别结果
|
||||
if (recoveryNumber === null) {
|
||||
recoveryNumber = 0;
|
||||
notification.send(`未识别到回血药数量,设置数量为0,药品名:${recoveryFoodName}`)
|
||||
}
|
||||
await sleep(1000);
|
||||
click(170, 1020);//筛选
|
||||
await sleep(1000);
|
||||
click(195, 1020);//重置
|
||||
await sleep(1000);
|
||||
click(110, 110);//输入名字
|
||||
await sleep(1000);
|
||||
inputText(resurrectionFoodName);
|
||||
await sleep(500);
|
||||
click(490, 1020);//确认筛选
|
||||
await sleep(1000);
|
||||
var resurrectionNumber = await recognizeNumberByOCR(ocrRegion, /\d+/) //识别复活药数量
|
||||
// 处理复活药识别结果
|
||||
if (resurrectionNumber === null) {
|
||||
resurrectionNumber = 0;
|
||||
notification.send(`未识别到复活药数量,设置数量为0,药品名:${resurrectionFoodName}`)
|
||||
}
|
||||
await sleep(1000);
|
||||
click(170, 1020);//筛选
|
||||
await sleep(1000);
|
||||
click(195, 1020);//重置
|
||||
await sleep(1000);
|
||||
click(490, 1020);//确认筛选
|
||||
await genshin.returnMainUi();
|
||||
return { recoveryNumber, resurrectionNumber };
|
||||
}
|
||||
|
||||
async function addSnapshotRecord(filePath, recoveryNum, resurrectionNum) {
|
||||
const now = new Date();
|
||||
const dateTimeStr = await formatDateTime(now);
|
||||
|
||||
const recordLine =
|
||||
`${dateTimeStr}—库存—${recoveryFoodName}—${recoveryNum}\n` +
|
||||
`${dateTimeStr}—库存—${resurrectionFoodName}—${resurrectionNum}`;
|
||||
|
||||
try {
|
||||
let content = "";
|
||||
try {
|
||||
content = await file.readText(filePath);
|
||||
} catch (e) {}
|
||||
|
||||
const newContent = content + (content ? "\n" : "") + recordLine;
|
||||
await file.writeText(filePath, newContent);
|
||||
|
||||
log.info(`已记录库存快照`);
|
||||
return true;
|
||||
} catch (error) {
|
||||
log.error(`库存快照记录失败: ${error.message}`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 查找最近一次初始化记录
|
||||
async function findLastInitialization(historyFilePath) {
|
||||
let content = "";
|
||||
try {
|
||||
content = await file.readText(historyFilePath);
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const lines = content.split("\n").filter(l => l.trim());
|
||||
if (lines.length === 0) return null;
|
||||
|
||||
// 只看初始化行
|
||||
const initLines = lines.filter(l => l.includes("—初始化—"));
|
||||
if (initLines.length === 0) return null;
|
||||
|
||||
// 从后往前,找最近的一组时间戳
|
||||
for (let i = initLines.length - 1; i >= 0; i--) {
|
||||
const initLine = initLines[i];
|
||||
const parts = initLine.split("—");
|
||||
if (parts.length < 4) continue;
|
||||
|
||||
const time = parts[0];
|
||||
|
||||
let recoveryNum = null;
|
||||
let resurrectionNum = null;
|
||||
|
||||
// 收集同一时间戳的初始化记录
|
||||
for (const line of lines) {
|
||||
if (!line.startsWith(time)) continue;
|
||||
if (!line.includes("—初始化—")) continue;
|
||||
|
||||
const seg = line.split("—");
|
||||
if (seg.length < 4) continue;
|
||||
|
||||
const name = seg[2];
|
||||
const num = parseInt(seg[3], 10);
|
||||
if (isNaN(num)) continue;
|
||||
|
||||
if (name === recoveryFoodName) {
|
||||
recoveryNum = num;
|
||||
}
|
||||
if (name === resurrectionFoodName) {
|
||||
resurrectionNum = num;
|
||||
}
|
||||
}
|
||||
|
||||
if (recoveryNum !== null && resurrectionNum !== null) {
|
||||
return {
|
||||
time,
|
||||
recoveryNum,
|
||||
resurrectionNum
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// 添加历史记录
|
||||
async function addHistoryRecord(filePath, mode, recoveryNum, resurrectionNum) {
|
||||
const now = new Date();
|
||||
const dateTimeStr = await formatDateTime(now);
|
||||
const recordLine = `${dateTimeStr}—${mode}—${recoveryFoodName}—${recoveryNum}\n` +
|
||||
`${dateTimeStr}—${mode}—${resurrectionFoodName}—${resurrectionNum}`;
|
||||
|
||||
try {
|
||||
// 检查旧格式并迁移
|
||||
await migrateOldFormatRecords(filePath);
|
||||
|
||||
let content = "";
|
||||
try {
|
||||
content = await file.readText(filePath);
|
||||
} catch (error) {
|
||||
// 文件不存在,创建新文件
|
||||
}
|
||||
|
||||
// 追加新记录
|
||||
const newContent = content + (content ? "\n" : "") + recordLine;
|
||||
await file.writeText(filePath, newContent);
|
||||
|
||||
log.info(`已添加历史记录: ${recordLine}`);
|
||||
return { success: true, time: dateTimeStr };
|
||||
} catch (error) {
|
||||
log.error(`添加历史记录失败: ${error.message}`);
|
||||
return { success: false, error: error.message };
|
||||
}
|
||||
}
|
||||
|
||||
// 添加消耗记录
|
||||
async function addConsumptionRecord(filePath, recoveryConsumed, resurrectionConsumed, initTime) {
|
||||
const now = new Date();
|
||||
const dateTimeStr = await formatDateTime(now);
|
||||
const recordLine = `${dateTimeStr}—消耗对比—${recoveryFoodName}—${recoveryConsumed}\n` +
|
||||
`${dateTimeStr}—消耗对比—${resurrectionFoodName}—${resurrectionConsumed}(对比${initTime})`;
|
||||
|
||||
try {
|
||||
let content = "";
|
||||
try {
|
||||
content = await file.readText(filePath);
|
||||
} catch (error) {
|
||||
// 文件不存在,创建新文件
|
||||
}
|
||||
|
||||
// 追加新记录
|
||||
const newContent = content + (content ? "\n" : "") + recordLine;
|
||||
await file.writeText(filePath, newContent);
|
||||
|
||||
log.info(`已添加消耗记录: ${recordLine}`);
|
||||
return { success: true };
|
||||
} catch (error) {
|
||||
log.error(`添加消耗记录失败: ${error.message}`);
|
||||
return { success: false, error: error.message };
|
||||
}
|
||||
}
|
||||
|
||||
// 主执行流程
|
||||
async function main() {
|
||||
// 设置分辨率和缩放
|
||||
setGameMetrics(1920, 1080, 1);
|
||||
// 点击领月卡
|
||||
await genshin.blessingOfTheWelkinMoon();
|
||||
await sleep(1000);
|
||||
await genshin.returnMainUi();
|
||||
await sleep(1000);
|
||||
// 获取食物数量
|
||||
return await getFoodNum();
|
||||
}
|
||||
|
||||
// ==================== 程序入口 ====================
|
||||
userName = await getUserName();
|
||||
const historyFilePath = `assets/${userName}_history.txt`;
|
||||
const snapshotFilePath = `assets/${userName}_snapshot.txt`;
|
||||
const consumptionFilePath = `assets/${userName}_consumption.txt`;
|
||||
|
||||
// 获取当前药物数量
|
||||
const { recoveryNumber, resurrectionNumber } = await main();
|
||||
|
||||
if (currentMode === "init") {
|
||||
// ============ 初始化模式 ============
|
||||
const result = await addHistoryRecord(historyFilePath, "初始化", recoveryNumber, resurrectionNumber);
|
||||
|
||||
if (result.success) {
|
||||
notification.send(`${userName}: 已记录初始库存!${recoveryFoodName}${recoveryNumber}个, ${resurrectionFoodName}${resurrectionNumber}个`);
|
||||
} else {
|
||||
notification.send(`${userName}: 初始化记录失败!`);
|
||||
}
|
||||
|
||||
} else if (currentMode === "record") {
|
||||
// ============ 记录模式 ============
|
||||
// 1. 查找最近一次初始化
|
||||
const lastInit = await findLastInitialization(historyFilePath);
|
||||
|
||||
if (!lastInit) {
|
||||
// 没有找到初始化记录,自动转为初始化模式
|
||||
log.warn("未找到初始化记录,自动转为初始化模式");
|
||||
const result = await addHistoryRecord(historyFilePath, "初始化", recoveryNumber, resurrectionNumber);
|
||||
|
||||
if (result.success) {
|
||||
notification.send(`${userName}: 未找到初始化记录,已自动记录为初始库存!${recoveryFoodName}${recoveryNumber}个, ${resurrectionFoodName}${resurrectionNumber}个`);
|
||||
}
|
||||
|
||||
} else {
|
||||
// 2. 计算消耗量
|
||||
const recoveryConsumed = lastInit.recoveryNum - recoveryNumber;
|
||||
const resurrectionConsumed = lastInit.resurrectionNum - resurrectionNumber;
|
||||
|
||||
// 3. 添加当前记录到历史文件
|
||||
const historyResult = await addHistoryRecord(historyFilePath, "记录", recoveryNumber, resurrectionNumber);
|
||||
|
||||
// 4. 添加消耗记录到消耗文件
|
||||
if (recoveryConsumed > 0 || resurrectionConsumed > 0) {
|
||||
await addConsumptionRecord(
|
||||
consumptionFilePath,
|
||||
recoveryConsumed,
|
||||
resurrectionConsumed,
|
||||
lastInit.time
|
||||
);
|
||||
}
|
||||
|
||||
// 5. 发送通知
|
||||
if (recoveryConsumed > 0 || resurrectionConsumed > 0) {
|
||||
notification.send(`${userName}: 当前库存:${recoveryFoodName}${recoveryNumber}个, ${resurrectionFoodName}${resurrectionNumber}个 | 消耗:${recoveryFoodName}${recoveryConsumed}个, ${resurrectionFoodName}${resurrectionConsumed}个(对比${lastInit.time})`);
|
||||
} else {
|
||||
// 消耗为0或负数(数量增加)
|
||||
const recoveryChange = recoveryConsumed >= 0 ? `消耗${recoveryConsumed}个` : `新增${-recoveryConsumed}个`;
|
||||
const resurrectionChange = resurrectionConsumed >= 0 ? `消耗${resurrectionConsumed}个` : `新增${-resurrectionConsumed}个`;
|
||||
notification.send(`${userName}: 当前库存:${recoveryFoodName}${recoveryNumber}个, ${resurrectionFoodName}${resurrectionNumber}个 | ${recoveryChange}, ${resurrectionChange}(对比${lastInit.time})`);
|
||||
}
|
||||
}
|
||||
|
||||
} else if (currentMode === "snapshot") {
|
||||
// ✅ 新增的纯记录模式
|
||||
const ok = await addSnapshotRecord(
|
||||
snapshotFilePath,
|
||||
recoveryNumber,
|
||||
resurrectionNumber
|
||||
);
|
||||
|
||||
if (ok) {
|
||||
notification.send(
|
||||
`${userName}: 当前库存 — ${recoveryFoodName}${recoveryNumber}个,${resurrectionFoodName}${resurrectionNumber}个`
|
||||
);
|
||||
} else {
|
||||
notification.send(`${userName}: 库存记录失败`);
|
||||
}
|
||||
|
||||
} else {
|
||||
notification.send(`${userName}: 错误!未知的模式: ${currentMode}`);
|
||||
}
|
||||
|
||||
})();
|
||||
18
repo/药品消耗统计/manifest.json
Normal file
18
repo/药品消耗统计/manifest.json
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"manifest_version": 1,
|
||||
"name": "药品消耗统计",
|
||||
"version": "1.0",
|
||||
"bgi_version": "0.54",
|
||||
"description": "基于勺子佬的营养袋吃药统计拓展,本脚本用于自动记录并统计角色使用的回血药与复活药数量,支持初始化记录、纯记录、记录以及消耗计算三种工作方式,适合单账号或多账号长期使用。",
|
||||
"authors": [
|
||||
{
|
||||
"name": "爱丽丝",
|
||||
"links": "https://github.com/itslyh"
|
||||
}
|
||||
],
|
||||
"settings_ui": "settings.json",
|
||||
"main": "main.js",
|
||||
"saved_files": [
|
||||
"assets/*.txt"
|
||||
]
|
||||
}
|
||||
27
repo/药品消耗统计/settings.json
Normal file
27
repo/药品消耗统计/settings.json
Normal file
@@ -0,0 +1,27 @@
|
||||
[
|
||||
{
|
||||
"name": "userName",
|
||||
"type": "input-text",
|
||||
"label": "账户名称\n用于多账户运行时区分不同账户",
|
||||
"default": "默认账户"
|
||||
},
|
||||
{
|
||||
"name": "recordMode",
|
||||
"type": "select",
|
||||
"label": "记录模式",
|
||||
"options": ["仅记录库存", "记录并计算消耗", "重新初始化"],
|
||||
"default": "record"
|
||||
},
|
||||
{
|
||||
"name": "recoveryFoodName",
|
||||
"type": "input-text",
|
||||
"label": "回血药名称",
|
||||
"default": ""
|
||||
},
|
||||
{
|
||||
"name": "resurrectionFoodName",
|
||||
"type": "input-text",
|
||||
"label": "复活药名称",
|
||||
"default": ""
|
||||
}
|
||||
]
|
||||
Reference in New Issue
Block a user