190 lines
9.4 KiB
JavaScript
190 lines
9.4 KiB
JavaScript
(async function () {
|
||
// 初始化所有用到的参数
|
||
const operationMode = settings.operationMode || "生成路径文件"; // 默认值为“生成路径文件”
|
||
const requiredMonsterCount = parseInt(settings.requiredMonsterCount || 1800, 10); // 默认值为1800
|
||
const excludeWaterFree = !!settings.excludeWaterFree; // 默认值为false(默认不排除)
|
||
const excludeHighRisk = !!settings.excludeHighRisk; // 默认值为false(默认不排除)
|
||
const weight = parseFloat(settings.weight || 2); // 默认值为2
|
||
const disableAutoPick = !!settings.disableAutoPick; // 默认值为false(默认不禁用)
|
||
const enableCooldownCheck = !!settings.enableCooldownCheck; // 默认值为false(默认不启用)
|
||
const pathingDir = 'pathing/'; // 初始化pathingDir参数
|
||
|
||
// 初始化用于计数的变量
|
||
let outputFolderName = ""; // 初始化为空
|
||
let totalMonsterCount = 0; // 筛选出的怪物总数
|
||
let selectedRoutes = []; // 筛选出的路线数组
|
||
let successCount = 0; // 成功复制的文件数量
|
||
let failCount = 0; // 失败复制的文件数量
|
||
let routeIndex = 0; // 当前筛选的路线序号
|
||
|
||
// 日志输出配置参数
|
||
log.info(
|
||
`自动小怪锄地规划 - 配置信息:` +
|
||
`操作模式=${operationMode}(默认:生成路径文件),` +
|
||
`怪物数量=${requiredMonsterCount}(默认1800),` +
|
||
`${excludeWaterFree ? '排除水免(默认:不排除)' : '包含水免(默认)'},` +
|
||
`${excludeHighRisk ? '排除高危(默认:不排除)' : '包含高危(默认)'},` +
|
||
`权重=${weight}(默认2),` +
|
||
`自动拾取=${disableAutoPick ? '禁用' : '启用'}`
|
||
);
|
||
|
||
// 验证配置参数
|
||
if (
|
||
isNaN(requiredMonsterCount) ||
|
||
requiredMonsterCount < 0 ||
|
||
requiredMonsterCount > 2000 ||
|
||
!Number.isInteger(requiredMonsterCount)
|
||
) {
|
||
log.warn(`怪物数量 ${requiredMonsterCount} 不符合要求,必须为0到2000之间的整数`);
|
||
return;
|
||
}
|
||
if (isNaN(weight) || weight < 0) {
|
||
log.warn(`权重 ${weight} 不符合要求,必须为0及以上的数`);
|
||
return;
|
||
}
|
||
|
||
// 文件夹/文件名称,则使用默认规则命名
|
||
outputFolderName = `${requiredMonsterCount}${excludeWaterFree ? '排除水免' : '包含水免'}${excludeHighRisk ? '排除高危' : '包含高危'}权重${weight}`;
|
||
|
||
// 根据自定义配置,如果没有禁用自动拾取,则启用自动拾取
|
||
if (!disableAutoPick) {
|
||
log.info("启用自动拾取的实时任务");
|
||
dispatcher.addTimer(new RealtimeTimer("AutoPick"));
|
||
}
|
||
|
||
// 判断操作模式是否为“执行路径文件”,若是则执行路径文件
|
||
if (operationMode === "执行路径文件") {
|
||
try {
|
||
// 定义路径组文件的路径,使用 outputFolderName
|
||
const pathGroupFilePath = `route/${outputFolderName}.txt`;
|
||
|
||
const pathGroupContent = await file.readText(pathGroupFilePath);
|
||
const savedRoutes = pathGroupContent.trim().split('\n');
|
||
for (let i = 0; i < savedRoutes.length; i++) {
|
||
const routeWithTimestamp = savedRoutes[i].trim();
|
||
const [routeName, routeTimestamp] = routeWithTimestamp.split('::');
|
||
log.info(`当前任务为第 ${i + 1}/${savedRoutes.length} 个`);
|
||
const now = new Date(); // 获取开始时间
|
||
const startTime = now.toISOString();
|
||
if (enableCooldownCheck && startTime < routeTimestamp) {
|
||
log.info(`当前路线 ${routeName} 未刷新,跳过任务`);
|
||
continue; // 跳过当前循环
|
||
}
|
||
log.info(`当前路线 ${routeName} 已刷新或未启用CD检测,执行任务`);
|
||
|
||
// 拼接路径文件的完整路径
|
||
const pathingFilePath = `pathing/${routeName}.json`;
|
||
// 执行路径文件
|
||
await pathingScript.runFile(pathingFilePath);
|
||
|
||
// 如果启用了CD检测,获取结束时间并判断时间差
|
||
if (enableCooldownCheck) {
|
||
const endTime = new Date(); // 获取结束时间
|
||
const timeDiff = endTime - now; // 计算时间差(单位:毫秒)
|
||
if (timeDiff > 10000) { // 如果时间差大于10秒(10000毫秒)
|
||
// 计算新的时间戳,增加12小时
|
||
const newTimestamp = new Date(startTime).getTime() + 12 * 60 * 60 * 1000;
|
||
const formattedNewTimestamp = new Date(newTimestamp).toISOString();
|
||
const nextAvailableTime = new Date(formattedNewTimestamp).toLocaleString(); // 转换为本地时间格式
|
||
log.info(`任务 ${routeName} 运行超过10秒且当前启用刷新CD检测,下一次可用时间为 ${nextAvailableTime}`);
|
||
log.info(`新的时间戳为:${formattedNewTimestamp}`);
|
||
|
||
// 更新 savedRoutes 中对应部分的时间戳
|
||
savedRoutes[i] = `${routeName}::${formattedNewTimestamp}`;
|
||
|
||
// 立即将更新后的内容写回文件
|
||
const updatedContent = savedRoutes.join('\n');
|
||
await file.writeText(pathGroupFilePath, updatedContent);
|
||
}
|
||
}
|
||
}
|
||
} catch (error) {
|
||
log.error(`读取或写入路径组文件时出错: ${error}`);
|
||
}
|
||
}
|
||
|
||
// 筛选、排序并选取路线
|
||
const indexPath = `index.txt`;
|
||
try {
|
||
const indexContent = await file.readText(indexPath);
|
||
const pathingFiles = indexContent.trim().split('\n').map(line => {
|
||
const parts = line.trim().split('\t');
|
||
return {
|
||
name: parts[0],
|
||
monsterCount: parseFloat(parts[1]),
|
||
secPerMonster: parseFloat(parts[2]),
|
||
monsterPerSec: parseFloat(parts[3]),
|
||
isWaterFree: parseInt(parts[4], 10) === 1,
|
||
isHighRisk: parseInt(parts[5], 10) === 1,
|
||
efficiency: weight >= 5 ? parseFloat(parts[2]) : Math.pow(parseFloat(parts[2]), weight) * parseFloat(parts[3]),
|
||
selected: 0
|
||
};
|
||
}).filter(route => !isNaN(route.monsterCount) && route.monsterCount > 0 && Number.isInteger(route.monsterCount));
|
||
|
||
const sortedPathingFiles = [...pathingFiles];
|
||
sortedPathingFiles.sort((a, b) => b.efficiency - a.efficiency || a.monsterCount - b.monsterCount);
|
||
|
||
for (const route of sortedPathingFiles) {
|
||
routeIndex++; // 每次循环时递增
|
||
const meetsWaterFreeCondition = !excludeWaterFree || !route.isWaterFree;
|
||
const meetsHighRiskCondition = !excludeHighRisk || !route.isHighRisk;
|
||
|
||
// 修改后的日志输出,增加当前路线的序号
|
||
//log.debug(`筛选路线 ${routeIndex}(${route.name}):水免条件 ${meetsWaterFreeCondition},高危条件 ${meetsHighRiskCondition}`);
|
||
|
||
if (meetsWaterFreeCondition && meetsHighRiskCondition) {
|
||
totalMonsterCount += route.monsterCount;
|
||
route.selected = 1;
|
||
selectedRoutes.push(route.name);
|
||
if (totalMonsterCount >= requiredMonsterCount) break;
|
||
}
|
||
}
|
||
|
||
if (totalMonsterCount < requiredMonsterCount) {
|
||
log.warn(`数量不足,最多可以包含 ${totalMonsterCount} 只怪物,不满足所需的 ${requiredMonsterCount} 只怪物`);
|
||
}
|
||
|
||
// 根据操作模式执行相应的操作
|
||
if (operationMode === "生成路径文件") {
|
||
const pathGroupName = `${requiredMonsterCount}${excludeWaterFree ? '排除水免' : '包含水免'}${excludeHighRisk ? '排除高危' : '包含高危'}权重${weight}.txt`;
|
||
const pathGroupFilePath = `route/${pathGroupName}`;
|
||
|
||
// 初始化CD信息的时间戳
|
||
const initialCDTimestamp = "::2000-01-01T00:00:00.000Z";
|
||
|
||
// 按照 index.txt 中的顺序依次检验每个路线是否需要写入文件
|
||
const resultContent = pathingFiles
|
||
.filter(route => selectedRoutes.includes(route.name))
|
||
.map(route => `${route.name}${initialCDTimestamp}`)
|
||
.join('\n');
|
||
|
||
await file.writeText(pathGroupFilePath, resultContent);
|
||
log.info(`生成成功,共计 ${selectedRoutes.length} 条路线,路径组文件已保存到 ${pathGroupFilePath},请将js自定义配置中操作模式改为执行路径文件以执行`);
|
||
} else if (operationMode === "输出地图追踪文件") {
|
||
const pathingOutDir = `pathingout/${outputFolderName}/`; // 输出文件夹路径
|
||
|
||
// 将选中的地图追踪文件复制到对应的输出文件夹
|
||
for (const routeName of selectedRoutes) {
|
||
const sourceFilePath = `${pathingDir}${routeName}.json`;
|
||
const targetFilePath = `${pathingOutDir}${routeName}.json`;
|
||
try {
|
||
const fileContent = await file.readText(sourceFilePath);
|
||
await file.writeText(targetFilePath, fileContent);
|
||
// log.debug(`文件 ${routeName}.json 已复制到 ${pathingOutDir}`);
|
||
successCount++;
|
||
} catch (error) {
|
||
log.warn(`复制文件 ${routeName}.json 时出错: ${error}`);
|
||
failCount++;
|
||
}
|
||
}
|
||
|
||
log.info(`筛选完成,共计 ${selectedRoutes.length} 条路线。`);
|
||
log.info(`文件复制完成:成功 ${successCount} 个,失败 ${failCount} 个。`);
|
||
}
|
||
} catch (error) {
|
||
log.error(`读取路径文件索引文件 ${indexPath} 时出错: ${error}`);
|
||
}
|
||
|
||
log.info('脚本执行完成');
|
||
})();
|