js: CD-Aware-AutoGather: 改进对地图追踪中已订阅的任务目录的处理方式 (#1225)
This commit is contained in:
@@ -32,10 +32,12 @@
|
|||||||
| 设置备选队伍名称 | 首选队伍缺少对应的采集角色时使用。<br>两支队伍的名称不要存在包含关系,例如不能一支叫`特产`一支叫`特产备选` |
|
| 设置备选队伍名称 | 首选队伍缺少对应的采集角色时使用。<br>两支队伍的名称不要存在包含关系,例如不能一支叫`特产`一支叫`特产备选` |
|
||||||
| 停止运行时间 | 超过此时间后,停止后续的任务(会等待正在运行的那条json路线结束)。 |
|
| 停止运行时间 | 超过此时间后,停止后续的任务(会等待正在运行的那条json路线结束)。 |
|
||||||
| 我肝的账号不止一个 | 如果你有多个账号,可以选中此选项,选中后将分账号维护对应的材料刷新时间。 |
|
| 我肝的账号不止一个 | 如果你有多个账号,可以选中此选项,选中后将分账号维护对应的材料刷新时间。 |
|
||||||
| 采集扫描到的所有材料 | 选中后将不管后面的每个材料⬇️的选项实际是否勾选,全都视为已勾选 |
|
| `地图追踪`中已订阅的任务目录的处理方式 | 有三种处理方式:<br>- `每次自动扫描,并采集扫描到的所有材料`<br>- `手动扫描,并采集扫描到的所有材料`<br>- `手动扫描,只采集已勾选的材料`<br>`自动扫描`会在每次执行采集前扫描当前已订阅的任务目录,`手动扫描`则是手动将运行模式切换到扫描模式执行脚本进行扫描。<br>`采集所有`会无视后面的每个材料⬇️是否选中,`采集已勾选`则是根据勾选的列表进行采集 |
|
||||||
| 即使同一种材料有多个版本的路线,也全都执行采集 | 如果某种材料选中了多个版本的路线(常见于不同作者),默认只会执行第一个。勾选此选项后会每个版本都执行,可能造成部分点位重复(空跑)。 |
|
| 即使同一种材料有多个版本的路线,也全都执行采集 | 如果某种材料选中了多个版本的路线(常见于不同作者),默认只会执行第一个。勾选此选项后会每个版本都执行,可能造成部分点位重复(空跑)。 |
|
||||||
| `↓` 地方特产\稻妻\绯樱绣球 | 根据你订阅的路径追踪任务数量,这里将会显示相应个数的选择框。<br>勾选后将执行你选中的条目的采集任务。<br>Tip: `↓`符号是在提示你应该勾选文本下面的选择框 |
|
| `↓` 地方特产\稻妻\绯樱绣球 | 根据你订阅的路径追踪任务数量,这里将会显示相应个数的选择框。<br>勾选后将执行你选中的条目的采集任务。<br>Tip: `↓`符号是在提示你应该勾选文本下面的选择框 |
|
||||||
|
|
||||||
|
**推荐的配置**: 运行模式设置为`采集选中的材料`,已订阅的任务目录的处理方式设置为`每次自动扫描,并采集扫描到的所有材料`。这样一来,待采集的材料列表自动保持与你订阅的列表一致,新增/删除材料也直接通过BetterGI的界面执行,每次直接运行脚本即可。
|
||||||
|
|
||||||
运行此模式后,将按照你勾选的条目,执行相应的采集任务。每执行完一条json路线后,将会计算它的下次刷新时间并写入`record`文件夹下的记录文件。下次运行脚本时,未刷新的路线将自动跳过。
|
运行此模式后,将按照你勾选的条目,执行相应的采集任务。每执行完一条json路线后,将会计算它的下次刷新时间并写入`record`文件夹下的记录文件。下次运行脚本时,未刷新的路线将自动跳过。
|
||||||
|
|
||||||
可以同时勾选多种材料,会逐个进行采集。
|
可以同时勾选多种材料,会逐个进行采集。
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ const CooldownDataBase = readRefreshInfo("CooldownData.txt");
|
|||||||
|
|
||||||
let stopAtTime = null;
|
let stopAtTime = null;
|
||||||
let currentParty = null;
|
let currentParty = null;
|
||||||
|
let runMode = settings.runMode;
|
||||||
|
let subscribeMode = settings.subscribeMode;
|
||||||
|
|
||||||
class ReachStopTime extends Error {
|
class ReachStopTime extends Error {
|
||||||
constructor(message) {
|
constructor(message) {
|
||||||
@@ -13,6 +15,12 @@ class ReachStopTime extends Error {
|
|||||||
this.name = "ReachStopTime";
|
this.name = "ReachStopTime";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
class UserCancelled extends Error {
|
||||||
|
constructor(message) {
|
||||||
|
super(message);
|
||||||
|
this.name = "UserCancelled";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
(async function () {
|
(async function () {
|
||||||
if (!file.IsFolder("pathing")) {
|
if (!file.IsFolder("pathing")) {
|
||||||
@@ -24,21 +32,33 @@ class ReachStopTime extends Error {
|
|||||||
log.error("{0}文件夹不存在,请双击运行下列位置的脚本以创建文件夹链接\n{1}", "pathing", batFile);
|
log.error("{0}文件夹不存在,请双击运行下列位置的脚本以创建文件夹链接\n{1}", "pathing", batFile);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const runMode = settings.runMode;
|
if (!runMode) {
|
||||||
|
const defaultRunMode = "采集选中的材料";
|
||||||
|
log.warn("运行模式 未选择或无效: {0},默认为{1}", runMode, defaultRunMode);
|
||||||
|
runMode = defaultRunMode;
|
||||||
|
}
|
||||||
|
if (!subscribeMode) {
|
||||||
|
const defaultSubscribeMode = "每次自动扫描,并采集扫描到的所有材料";
|
||||||
|
log.warn("已订阅的任务目录的处理方式 未选择或无效: {0},默认为{1}", subscribeMode, defaultSubscribeMode);
|
||||||
|
subscribeMode = defaultSubscribeMode;
|
||||||
|
}
|
||||||
|
if (!settings.runMode || !settings.subscribeMode) {
|
||||||
|
await sleep(3000);
|
||||||
|
}
|
||||||
|
|
||||||
log.info("当前运行模式:{0}", runMode);
|
log.info("当前运行模式:{0}", runMode);
|
||||||
if (runMode === "扫描文件夹更新可选材料列表") {
|
if (runMode === "扫描文件夹更新可选材料列表") {
|
||||||
await runScanMode();
|
await runScanMode();
|
||||||
} else if (runMode === "采集选中的材料") {
|
} else if (runMode === "采集选中的材料") {
|
||||||
let startTime = logFakeScriptStart();
|
let startTime = logFakeScriptStart();
|
||||||
|
log.info("已订阅的任务目录的处理方式:{0}", subscribeMode);
|
||||||
|
if (subscribeMode === "每次自动扫描,并采集扫描到的所有材料") {
|
||||||
|
await runScanMode();
|
||||||
|
}
|
||||||
await runGatherMode();
|
await runGatherMode();
|
||||||
logFakeScriptEnd({ startTime: startTime });
|
logFakeScriptEnd({ startTime: startTime });
|
||||||
} else if (runMode === "清除运行记录(重置材料刷新时间)") {
|
} else if (runMode === "清除运行记录(重置材料刷新时间)") {
|
||||||
await runClearMode();
|
await runClearMode();
|
||||||
} else {
|
|
||||||
log.warn("未选择运行模式或运行模式无效: {0}\n这可能是你的首次运行,将为你执行{1}模式", runMode, "扫描文件夹更新可选材料列表");
|
|
||||||
await sleep(3000);
|
|
||||||
await runScanMode();
|
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
|
||||||
@@ -129,6 +149,8 @@ async function runGatherMode() {
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e instanceof ReachStopTime) {
|
if (e instanceof ReachStopTime) {
|
||||||
log.info("达到设置的停止时间 {0},终止运行", stopAtTime);
|
log.info("达到设置的停止时间 {0},终止运行", stopAtTime);
|
||||||
|
} else if (e instanceof UserCancelled) {
|
||||||
|
log.info("用户取消,终止运行");
|
||||||
} else {
|
} else {
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
@@ -245,6 +267,17 @@ function filterFilesInTaskDir(taskDir) {
|
|||||||
return getFilesByExtension("pathing\\" + taskDir, ".json");
|
return getFilesByExtension("pathing\\" + taskDir, ".json");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function runPathScriptFile(jsonPath) {
|
||||||
|
await pathingScript.runFile(jsonPath);
|
||||||
|
//捕获任务取消的信息并跳出循环
|
||||||
|
try {
|
||||||
|
await sleep(10);
|
||||||
|
} catch (error) {
|
||||||
|
return error.toString();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
async function runPathTaskIfCooldownExpired(account, pathTask) {
|
async function runPathTaskIfCooldownExpired(account, pathTask) {
|
||||||
const recordFile = getRecordFilePath(account, pathTask);
|
const recordFile = getRecordFilePath(account, pathTask);
|
||||||
const jsonFiles = filterFilesInTaskDir(pathTask.label);
|
const jsonFiles = filterFilesInTaskDir(pathTask.label);
|
||||||
@@ -282,22 +315,17 @@ async function runPathTaskIfCooldownExpired(account, pathTask) {
|
|||||||
log.info(`${progress}{0}: 开始执行`, pathName);
|
log.info(`${progress}{0}: 开始执行`, pathName);
|
||||||
|
|
||||||
let pathStartTime = new Date();
|
let pathStartTime = new Date();
|
||||||
try {
|
// 延迟抛出`UserCancelled`,以便正确更新运行记录
|
||||||
await pathingScript.runFile(jsonPath);
|
const cancel = await runPathScriptFile(jsonPath);
|
||||||
} catch (error) {
|
|
||||||
log.error(`${progress}{0}: 文件不存在或执行失败: {1}`, jsonPath, error.toString());
|
|
||||||
logFakePathEnd(fileName, pathStart);
|
|
||||||
continue; // 跳过当前任务
|
|
||||||
}
|
|
||||||
|
|
||||||
let diffTime = new Date() - pathStartTime;
|
let diffTime = new Date() - pathStartTime;
|
||||||
if (diffTime < 500) {
|
if (diffTime < 1000) {
|
||||||
// "队伍中没有对应元素角色"的错误不会抛出为异常,只能通过路径文件迅速结束来推测
|
// "队伍中没有对应元素角色"的错误不会抛出为异常,只能通过路径文件迅速结束来推测
|
||||||
if (settings.partyName && settings.partyName2nd) {
|
if (settings.partyName && settings.partyName2nd) {
|
||||||
let newParty = (currentParty === settings.partyName) ? settings.partyName2nd : settings.partyName;
|
let newParty = (currentParty === settings.partyName) ? settings.partyName2nd : settings.partyName;
|
||||||
log.info("当前队伍{0}缺少该路线所需角色,尝试切换到{1}", currentParty, newParty);
|
log.info("当前队伍{0}缺少该路线所需角色,尝试切换到{1}", currentParty, newParty);
|
||||||
await switchPartySafely(newParty);
|
await switchPartySafely(newParty);
|
||||||
await pathingScript.runFile(jsonPath);
|
await runPathScriptFile(jsonPath);
|
||||||
}
|
}
|
||||||
} else if (diffTime > 5000) {
|
} else if (diffTime > 5000) {
|
||||||
recordMap[fileName] = calculateNextRunTime(new Date(), jsonPath);
|
recordMap[fileName] = calculateNextRunTime(new Date(), jsonPath);
|
||||||
@@ -312,6 +340,10 @@ async function runPathTaskIfCooldownExpired(account, pathTask) {
|
|||||||
log.info(`${progress}{0}: 执行时间过短,不更新记录`, pathName);
|
log.info(`${progress}{0}: 执行时间过短,不更新记录`, pathName);
|
||||||
}
|
}
|
||||||
logFakePathEnd(fileName, pathStart);
|
logFakePathEnd(fileName, pathStart);
|
||||||
|
|
||||||
|
if (cancel) {
|
||||||
|
throw new UserCancelled(cancel);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
log.info(`${progress}{0}: 已跳过 (${formatDateTimeShort(recordMap[fileName])}刷新)`, pathName);
|
log.info(`${progress}{0}: 已跳过 (${formatDateTimeShort(recordMap[fileName])}刷新)`, pathName);
|
||||||
}
|
}
|
||||||
@@ -359,9 +391,10 @@ function getSelectedMaterials() {
|
|||||||
|
|
||||||
const selectedMaterials = [];
|
const selectedMaterials = [];
|
||||||
|
|
||||||
|
const selectAllMaterials = subscribeMode.includes("采集扫描到的所有材料");
|
||||||
for (const entry of config) {
|
for (const entry of config) {
|
||||||
if (entry.name && entry.name.startsWith("OPT_") && entry.type === "checkbox") {
|
if (entry.name && entry.name.startsWith("OPT_") && entry.type === "checkbox") {
|
||||||
if (settings.selectAllMaterials || settings[entry.name] === true) {
|
if (selectAllMaterials || settings[entry.name] === true) {
|
||||||
let index = entry.label.indexOf(" ");
|
let index = entry.label.indexOf(" ");
|
||||||
entry.label = entry.label.slice(index + 1); // 去除⬇️指示
|
entry.label = entry.label.slice(index + 1); // 去除⬇️指示
|
||||||
selectedMaterials.push(entry);
|
selectedMaterials.push(entry);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"manifest_version": 1,
|
"manifest_version": 1,
|
||||||
"name": "带CD管理的自动采集",
|
"name": "带CD管理的自动采集",
|
||||||
"version": "1.3",
|
"version": "1.4",
|
||||||
"bgi_version": "0.45.0",
|
"bgi_version": "0.45.0",
|
||||||
"description": "自动同步你通过BetterGI订阅的地图追踪任务,执行采集任务,并管理材料刷新时间(支持多账号)。\n首次使用前请先简单阅读说明(可在`全自动`——`JS脚本`页面,点击本脚本名称查看)",
|
"description": "自动同步你通过BetterGI订阅的地图追踪任务,执行采集任务,并管理材料刷新时间(支持多账号)。\n首次使用前请先简单阅读说明(可在`全自动`——`JS脚本`页面,点击本脚本名称查看)",
|
||||||
"authors": [
|
"authors": [
|
||||||
|
|||||||
@@ -1,10 +1,47 @@
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
"name": "runMode",
|
"name": "runMode",
|
||||||
"type": "select",
|
"type": "select",
|
||||||
"label": "首次使用前请先简单阅读说明(可在`全自动`——`JS脚本`页面,点击本脚本名称查看)",
|
"label": "运行模式",
|
||||||
"options": [
|
"options": [
|
||||||
"扫描文件夹更新可选材料列表"
|
"扫描文件夹更新可选材料列表",
|
||||||
]
|
"采集选中的材料",
|
||||||
}
|
"清除运行记录(重置材料刷新时间)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "partyName",
|
||||||
|
"type": "input-text",
|
||||||
|
"label": "设置首选队伍名称(留空则不进行切换)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "partyName2nd",
|
||||||
|
"type": "input-text",
|
||||||
|
"label": "设置备选队伍名称(首选队伍缺少对应的采集角色时使用)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "stopAtTime",
|
||||||
|
"type": "input-text",
|
||||||
|
"label": "停止运行时间(HH:mm,24小时制。例如09:28为上午9点28分)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "iHaveMultipleAccounts",
|
||||||
|
"type": "checkbox",
|
||||||
|
"label": "我肝的账号不止一个(选中后将分账号维护对应的材料刷新时间)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "subscribeMode",
|
||||||
|
"type": "select",
|
||||||
|
"label": "'地图追踪'中已订阅的任务目录的处理方式:",
|
||||||
|
"options": [
|
||||||
|
"每次自动扫描,并采集扫描到的所有材料",
|
||||||
|
"手动扫描,并采集扫描到的所有材料",
|
||||||
|
"手动扫描,只采集已勾选的材料"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "acceptMultiplePathOfSameMaterial",
|
||||||
|
"type": "checkbox",
|
||||||
|
"label": "即使同一种材料有多个版本的路线,也全都执行采集"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
@@ -30,9 +30,14 @@
|
|||||||
"label": "我肝的账号不止一个(选中后将分账号维护对应的材料刷新时间)"
|
"label": "我肝的账号不止一个(选中后将分账号维护对应的材料刷新时间)"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "selectAllMaterials",
|
"name": "subscribeMode",
|
||||||
"type": "checkbox",
|
"type": "select",
|
||||||
"label": "采集扫描到的所有材料(选中后将无视后面的每个材料⬇️是否选中)"
|
"label": "'地图追踪'中已订阅的任务目录的处理方式:",
|
||||||
|
"options": [
|
||||||
|
"每次自动扫描,并采集扫描到的所有材料",
|
||||||
|
"手动扫描,并采集扫描到的所有材料",
|
||||||
|
"手动扫描,只采集已勾选的材料"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "acceptMultiplePathOfSameMaterial",
|
"name": "acceptMultiplePathOfSameMaterial",
|
||||||
|
|||||||
Reference in New Issue
Block a user