采集cd管理更新 (#916)
* 一些js更新 * js:修正逻辑,现在路径组文件不存在时会先尝试生成文件 * js:采集cd管理更新,顺便修了一些bug * fix typos. Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: 秋云 <physligl@gmail.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -43,7 +43,7 @@
|
|||||||
"y": -683.6240234375,
|
"y": -683.6240234375,
|
||||||
"action": "combat_script",
|
"action": "combat_script",
|
||||||
"move_mode": "walk",
|
"move_mode": "walk",
|
||||||
"action_params": "keypress(z)",
|
"action_params": "wait(5),keypress(z)",
|
||||||
"type": "path"
|
"type": "path"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -350,6 +350,6 @@ function basename(filePath) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//伪造一个js开始的记录(实际上没必要)
|
//伪造一个js开始的记录(实际上没必要)
|
||||||
await fakeLog("自动精英锄地规划", true, true, 0);
|
await fakeLog("自动小怪锄地规划", true, true, 0);
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# 采集CD管理脚本
|
# 采集CD管理脚本
|
||||||
|
|
||||||
## 简介
|
## 简介
|
||||||
这是一个基于文件夹操作的自动化脚本,用于管理采集路线的冷却时间(CD)。它会按照路径组的顺序依次运行任务,直到指定的时间,并根据给定的CD类型自动跳过未刷新的路线。
|
这是一个基于文件夹操作的自动化脚本,用于管理采集路线的冷却时间(CD)。它会按照路径组的顺序依次运行任务,直到指定的时间,并根据给定的CD类型自动跳过未刷新的路线。同时加入了伪造日志功能,日志分析可以解析具体路线的信息。
|
||||||
|
|
||||||
## 文件结构
|
## 文件结构
|
||||||
- `main.js`:主要的脚本文件,负责执行任务和管理CD。
|
- `main.js`:主要的脚本文件,负责执行任务和管理CD。
|
||||||
|
|||||||
@@ -1,15 +1,93 @@
|
|||||||
|
// fakeLog 函数,使用方法:将本函数放在主函数前,调用时请务必使用await,否则可能出现v8白框报错
|
||||||
|
//在js开头处伪造该js结束运行的日志信息,如 await fakeLog("js脚本", true, true, 0);
|
||||||
|
//在js结尾处伪造该js开始运行的日志信息,如 await fakeLog("js脚本", true, false, 2333);
|
||||||
|
//duration项目仅在伪造结束信息时有效,且无实际作用,可以任意填写,当你需要在日志中输出特定值时才需要,单位为毫秒
|
||||||
|
//在调用地图追踪前伪造该地图追踪开始运行的日志信息,如 await fakeLog(`地图追踪.json`, false, true, 0);
|
||||||
|
//在调用地图追踪后伪造该地图追踪结束运行的日志信息,如 await fakeLog(`地图追踪.json`, false, false, 0);
|
||||||
|
//如此便可以在js运行过程中伪造地图追踪的日志信息,可以在日志分析等中查看
|
||||||
|
|
||||||
|
async function fakeLog(name, isJs, isStart, duration) {
|
||||||
|
await sleep(10);
|
||||||
|
const currentTime = Date.now();
|
||||||
|
// 参数检查
|
||||||
|
if (typeof name !== 'string') {
|
||||||
|
log.error("参数 'name' 必须是字符串类型!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (typeof isJs !== 'boolean') {
|
||||||
|
log.error("参数 'isJs' 必须是布尔型!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (typeof isStart !== 'boolean') {
|
||||||
|
log.error("参数 'isStart' 必须是布尔型!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (typeof currentTime !== 'number' || !Number.isInteger(currentTime)) {
|
||||||
|
log.error("参数 'currentTime' 必须是整数!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (typeof duration !== 'number' || !Number.isInteger(duration)) {
|
||||||
|
log.error("参数 'duration' 必须是整数!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 将 currentTime 转换为 Date 对象并格式化为 HH:mm:ss.sss
|
||||||
|
const date = new Date(currentTime);
|
||||||
|
const hours = String(date.getHours()).padStart(2, '0');
|
||||||
|
const minutes = String(date.getMinutes()).padStart(2, '0');
|
||||||
|
const seconds = String(date.getSeconds()).padStart(2, '0');
|
||||||
|
const milliseconds = String(date.getMilliseconds()).padStart(3, '0');
|
||||||
|
const formattedTime = `${hours}:${minutes}:${seconds}.${milliseconds}`;
|
||||||
|
|
||||||
|
// 将 duration 转换为分钟和秒,并保留三位小数
|
||||||
|
const durationInSeconds = duration / 1000; // 转换为秒
|
||||||
|
const durationMinutes = Math.floor(durationInSeconds / 60);
|
||||||
|
const durationSeconds = (durationInSeconds % 60).toFixed(3); // 保留三位小数
|
||||||
|
|
||||||
|
// 使用四个独立的 if 语句处理四种情况
|
||||||
|
if (isJs && isStart) {
|
||||||
|
// 处理 isJs = true 且 isStart = true 的情况
|
||||||
|
const logMessage = `正在伪造js开始的日志记录\n\n` +
|
||||||
|
`[${formattedTime}] [INF] BetterGenshinImpact.Service.ScriptService\n` +
|
||||||
|
`------------------------------\n\n` +
|
||||||
|
`[${formattedTime}] [INF] BetterGenshinImpact.Service.ScriptService\n` +
|
||||||
|
`→ 开始执行JS脚本: "${name}"`;
|
||||||
|
log.info(logMessage);
|
||||||
|
}
|
||||||
|
if (isJs && !isStart) {
|
||||||
|
// 处理 isJs = true 且 isStart = false 的情况
|
||||||
|
const logMessage = `正在伪造js结束的日志记录\n\n` +
|
||||||
|
`[${formattedTime}] [INF] BetterGenshinImpact.Service.ScriptService\n` +
|
||||||
|
`→ 脚本执行结束: "${name}", 耗时: ${durationMinutes}分${durationSeconds}秒\n\n` +
|
||||||
|
`[${formattedTime}] [INF] BetterGenshinImpact.Service.ScriptService\n` +
|
||||||
|
`------------------------------`;
|
||||||
|
log.info(logMessage);
|
||||||
|
}
|
||||||
|
if (!isJs && isStart) {
|
||||||
|
// 处理 isJs = false 且 isStart = true 的情况
|
||||||
|
const logMessage = `正在伪造地图追踪开始的日志记录\n\n` +
|
||||||
|
`[${formattedTime}] [INF] BetterGenshinImpact.Service.ScriptService\n` +
|
||||||
|
`------------------------------\n\n` +
|
||||||
|
`[${formattedTime}] [INF] BetterGenshinImpact.Service.ScriptService\n` +
|
||||||
|
`→ 开始执行地图追踪任务: "${name}"`;
|
||||||
|
log.info(logMessage);
|
||||||
|
}
|
||||||
|
if (!isJs && !isStart) {
|
||||||
|
// 处理 isJs = false 且 isStart = false 的情况
|
||||||
|
const logMessage = `正在伪造地图追踪结束的日志记录\n\n` +
|
||||||
|
`[${formattedTime}] [INF] BetterGenshinImpact.Service.ScriptService\n` +
|
||||||
|
`→ 脚本执行结束: "${name}", 耗时: ${durationMinutes}分${durationSeconds}秒\n\n` +
|
||||||
|
`[${formattedTime}] [INF] BetterGenshinImpact.Service.ScriptService\n` +
|
||||||
|
`------------------------------`;
|
||||||
|
log.info(logMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// 定义目标文件夹路径和记录文件路径
|
// 定义目标文件夹路径和记录文件路径
|
||||||
const recordFolder = "record"; // 存储记录文件的文件夹路径
|
const recordFolder = "record"; // 存储记录文件的文件夹路径
|
||||||
const timestamp = "::2000-01-01T00:00:00.000Z"; // 固定的时间戳
|
const timestamp = "::2000-01-01T00:00:00.000Z"; // 固定的时间戳
|
||||||
|
|
||||||
// 定义六个运行时变量,初始值分别为 2000、1000、0、0、0、0
|
|
||||||
let runtime1 = 2000;
|
|
||||||
let runtime2 = 1000;
|
|
||||||
let runtime3 = 0;
|
|
||||||
let runtime4 = 0;
|
|
||||||
let runtime5 = 0;
|
|
||||||
let runtime6 = 0;
|
|
||||||
|
|
||||||
// 从 settings 中读取用户配置,并设置默认值
|
// 从 settings 中读取用户配置,并设置默认值
|
||||||
const userSettings = {
|
const userSettings = {
|
||||||
operationMode: settings.operationMode || "执行任务(若不存在索引文件则自动创建)",
|
operationMode: settings.operationMode || "执行任务(若不存在索引文件则自动创建)",
|
||||||
@@ -146,9 +224,10 @@ function removeJsonSuffix(fileName) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 新增逻辑:当选择“执行任务(若不存在索引文件则自动创建)”时,执行类似路径执行的逻辑
|
// 新增逻辑:当选择“执行任务(若不存在索引文件则自动创建)”时,执行类似路径执行的逻辑
|
||||||
if (userSettings.operationMode === "执行任务(若不存在索引文件则自动创建)") {
|
if (userSettings.operationMode === "执行任务(若不存在索引文件则自动创建)") {
|
||||||
log.info("启用自动拾取的实时任务");
|
log.info("启用自动拾取的实时任务");
|
||||||
dispatcher.addTimer(new RealtimeTimer("AutoPick"));
|
dispatcher.addTimer(new RealtimeTimer("AutoPick"));
|
||||||
|
await fakeLog("采集cd管理", true, false, 1000);
|
||||||
// 获取子文件夹内的所有文件路径
|
// 获取子文件夹内的所有文件路径
|
||||||
const recordFiles = file.ReadPathSync(subFolderPath);
|
const recordFiles = file.ReadPathSync(subFolderPath);
|
||||||
// 直接获取文件数量作为路径组数量
|
// 直接获取文件数量作为路径组数量
|
||||||
@@ -158,16 +237,16 @@ if (userSettings.operationMode === "执行任务(若不存在索引文件则
|
|||||||
for (let groupNumber = 1; groupNumber <= totalPathGroups; groupNumber++) {
|
for (let groupNumber = 1; groupNumber <= totalPathGroups; groupNumber++) {
|
||||||
const pathGroupFilePath = `${subFolderPath}/路径组${groupNumber}.txt`; // 动态生成路径组文件路径
|
const pathGroupFilePath = `${subFolderPath}/路径组${groupNumber}.txt`; // 动态生成路径组文件路径
|
||||||
|
|
||||||
genshin.returnMainUi();
|
genshin.returnMainUi();
|
||||||
|
|
||||||
//切换到指定配队
|
//切换到指定配队
|
||||||
if (partyNamesArray[groupNumber - 1] !== "") {
|
if (partyNamesArray[groupNumber - 1] !== "") {
|
||||||
await genshin.switchParty(partyNamesArray[groupNumber - 1])
|
await genshin.switchParty(partyNamesArray[groupNumber - 1])
|
||||||
}
|
}
|
||||||
|
|
||||||
genshin.returnMainUi();
|
genshin.returnMainUi();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let pathGroupContent = await file.readText(pathGroupFilePath);
|
let pathGroupContent = await file.readText(pathGroupFilePath);
|
||||||
let pathGroupEntries = pathGroupContent.trim().split('\n');
|
let pathGroupEntries = pathGroupContent.trim().split('\n');
|
||||||
for (let i = 0; i < pathGroupEntries.length; i++) {
|
for (let i = 0; i < pathGroupEntries.length; i++) {
|
||||||
@@ -180,29 +259,11 @@ try {
|
|||||||
// 获取开始时间
|
// 获取开始时间
|
||||||
const startTime = new Date();
|
const startTime = new Date();
|
||||||
|
|
||||||
// 更新 runtime 变量
|
|
||||||
runtime6 = runtime5;
|
|
||||||
runtime5 = runtime4;
|
|
||||||
runtime4 = runtime3;
|
|
||||||
runtime3 = runtime2;
|
|
||||||
runtime2 = runtime1;
|
|
||||||
runtime1 = startTime.getTime();
|
|
||||||
|
|
||||||
// 检查时间差条件
|
|
||||||
if ((runtime1 - runtime2) < 500 &&
|
|
||||||
(runtime2 - runtime3) < 500 &&
|
|
||||||
(runtime3 - runtime4) < 500 &&
|
|
||||||
(runtime4 - runtime5) < 500 &&
|
|
||||||
(runtime5 - runtime6) < 500) {
|
|
||||||
log.info(`连续五次时间差小于 500 毫秒,循环终止。`);
|
|
||||||
break; // 如果连续五次时间差小于 500 毫秒,退出循环
|
|
||||||
}
|
|
||||||
|
|
||||||
// 比较当前时间戳与任务的时间戳
|
// 比较当前时间戳与任务的时间戳
|
||||||
const entryDate = new Date(entryTimestamp);
|
const entryDate = new Date(entryTimestamp);
|
||||||
if (startTime <= entryDate) {
|
if (startTime <= entryDate) {
|
||||||
log.info(`当前任务 ${entryName} 未刷新,跳过任务 ${i + 1}/${pathGroupEntries.length} 个`);
|
log.info(`当前任务 ${entryName} 未刷新,跳过任务 ${i + 1}/${pathGroupEntries.length} 个`);
|
||||||
await sleep(500);
|
await sleep(10);
|
||||||
continue; // 跳过当前任务
|
continue; // 跳过当前任务
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -214,6 +275,10 @@ try {
|
|||||||
continue; // 跳过当前任务
|
continue; // 跳过当前任务
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//伪造地图追踪开始的日志
|
||||||
|
await fakeLog(entryName, false, true, 0);
|
||||||
|
|
||||||
// 日志输出当前任务信息
|
// 日志输出当前任务信息
|
||||||
log.info(`当前任务 ${entryName} 为第 ${i + 1}/${pathGroupEntries.length} 个`);
|
log.info(`当前任务 ${entryName} 为第 ${i + 1}/${pathGroupEntries.length} 个`);
|
||||||
|
|
||||||
@@ -226,21 +291,35 @@ try {
|
|||||||
continue; // 跳过当前任务
|
continue; // 跳过当前任务
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//捕获任务取消的信息并跳出循环
|
||||||
|
try {
|
||||||
|
await sleep(10); // 假设 sleep 是一个异步函数,休眠 10 毫秒
|
||||||
|
} catch (error) {
|
||||||
|
log.error(`发生错误: ${error}`);
|
||||||
|
break; // 终止循环
|
||||||
|
}
|
||||||
|
|
||||||
// 获取结束时间
|
// 获取结束时间
|
||||||
const endTime = new Date();
|
const endTime = new Date();
|
||||||
|
|
||||||
// 比较开始时间与结束时间
|
// 比较开始时间与结束时间
|
||||||
const timeDiff = endTime.getTime() - startTime.getTime(); // 时间差(毫秒)
|
const timeDiff = endTime.getTime() - startTime.getTime(); // 时间差(毫秒)
|
||||||
|
|
||||||
|
//伪造地图追踪结束的日志
|
||||||
|
await fakeLog(entryName, false, false, timeDiff);
|
||||||
|
|
||||||
if (timeDiff > 3000) { // 时间差大于3秒
|
if (timeDiff > 3000) { // 时间差大于3秒
|
||||||
// 获取当前路径组的 cdtype
|
// 获取当前路径组的 cdtype
|
||||||
const currentCdType = pathGroupCdType[groupNumber - 1] || "未知类型";
|
const currentCdType = pathGroupCdType[groupNumber - 1] || "未知类型";
|
||||||
|
|
||||||
// 初始化 newTimestamp 和 nextAvailableTime
|
// 初始化 newTimestamp 和 nextAvailableTime
|
||||||
let newTimestamp;
|
let newTimestamp;
|
||||||
let nextAvailableTime;
|
let nextAvailableTime;
|
||||||
|
|
||||||
// 根据 cdtype 执行不同的操作
|
// 根据 cdtype 执行不同的操作
|
||||||
switch (currentCdType) {
|
switch (currentCdType) {
|
||||||
case "1次0点刷新":
|
case "1次0点刷新":
|
||||||
// 将任务文件中对应的时间戳改为下一个0点
|
// 将任务文件中对应的时间戳改为下一个0点
|
||||||
const tomorrow = new Date(startTime.getTime() + 24 * 60 * 60 * 1000);
|
const tomorrow = new Date(startTime.getTime() + 24 * 60 * 60 * 1000);
|
||||||
@@ -307,24 +386,24 @@ switch (currentCdType) {
|
|||||||
newTimestamp = startTime.toISOString();
|
newTimestamp = startTime.toISOString();
|
||||||
nextAvailableTime = startTime.toLocaleString(); // 转换为本地时间格式
|
nextAvailableTime = startTime.toLocaleString(); // 转换为本地时间格式
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新任务文件中的时间戳
|
// 更新任务文件中的时间戳
|
||||||
// 首先根据newTimestamp修改pathGroupEntries中对应项
|
// 首先根据newTimestamp修改pathGroupEntries中对应项
|
||||||
pathGroupEntries = pathGroupEntries.map(entry => {
|
pathGroupEntries = pathGroupEntries.map(entry => {
|
||||||
const [name, timestamp] = entry.split('::');
|
const [name, timestamp] = entry.split('::');
|
||||||
if (name === entryName) {
|
if (name === entryName) {
|
||||||
return `${name}::${newTimestamp}`;
|
return `${name}::${newTimestamp}`;
|
||||||
}
|
}
|
||||||
return entry;
|
return entry;
|
||||||
});
|
});
|
||||||
|
|
||||||
// 然后根据pathGroupEntries修改pathGroupContent
|
// 然后根据pathGroupEntries修改pathGroupContent
|
||||||
pathGroupContent = pathGroupEntries.join('\n');
|
pathGroupContent = pathGroupEntries.join('\n');
|
||||||
|
|
||||||
// 最后将pathGroupContent写回原文件
|
// 最后将pathGroupContent写回原文件
|
||||||
await file.writeText(pathGroupFilePath, pathGroupContent);
|
await file.writeText(pathGroupFilePath, pathGroupContent);
|
||||||
log.info(`本任务执行大于10秒,cd信息已更新,下一次可用时间为 ${nextAvailableTime}`);
|
log.info(`本任务执行大于3秒,cd信息已更新,下一次可用时间为 ${nextAvailableTime}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
log.info(`路径组${groupNumber} 的所有任务运行完成`);
|
log.info(`路径组${groupNumber} 的所有任务运行完成`);
|
||||||
@@ -333,7 +412,10 @@ log.info(`本任务执行大于10秒,cd信息已更新,下一次可用时间
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
log.info('所有路径组的任务运行完成');
|
log.info('所有路径组的任务运行完成');
|
||||||
}
|
|
||||||
|
//伪造js开始的日志
|
||||||
|
await fakeLog("采集cd管理", true, true, 0);
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error(`操作失败: ${error}`);
|
log.error(`操作失败: ${error}`);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"manifest_version": 1,
|
"manifest_version": 1,
|
||||||
"name": "采集cd管理",
|
"name": "采集cd管理",
|
||||||
"version": "1.0",
|
"version": "1.1",
|
||||||
"bgi_version": "0.44.8",
|
"bgi_version": "0.44.8",
|
||||||
"description": "仅面对会操作文件和读readme的用户,基于文件夹操作自动管理采集路线的cd,会按照路径组的顺序依次运行,直到指定的时间,并会按照给定的cd类型,自动跳过未刷新的路线",
|
"description": "仅面对会操作文件和读readme的用户,基于文件夹操作自动管理采集路线的cd,会按照路径组的顺序依次运行,直到指定的时间,并会按照给定的cd类型,自动跳过未刷新的路线",
|
||||||
"authors": [
|
"authors": [
|
||||||
|
|||||||
Reference in New Issue
Block a user