全自动 + 半自动路径任务工具箱 (#2819)
* refactor(FullyAutoAndSemiAutoTools): 优化记录合并逻辑并清理废弃代码 - 实现同一天数据合并功能,将重复记录的paths和groupPaths进行合并 - 移除已注释的无用代码块,包括pathRunMap相关逻辑 - 清理废弃的pathing.json配置文件内容 - 修复字符串拼接格式问题,确保正确的换行符处理 - 删除未使用的变量声明和调试代码 - 优化记录列表的数据处理流程 feat(pathing): 添加路径层级父子关系支持并优化显示结构 - 在PATHING_ALL数组对象中添加parent_name字段以支持父子关系 - 修改addUniquePath函数调用以包含parent_name参数 - 添加getChildFolderNameFromRoot函数获取父级文件夹名称 - 在路径排序逻辑中增加parent_name比较条件 - 重构路径显示逻辑添加父级名称分组显示格式 - 更新main函数中的执行流程控制逻辑 feat(auto-tools): 添加UID识别功能支持 - 在Record对象中新增uid字段用于存储用户ID - 集成uid工具模块,实现OCR识别UID功能 - 添加uid.js工具文件,包含UID识别、验证和比较功能 - 实现在主界面检测和返回主界面的功能 - 集成UID配置验证和错误处理机制 refactor(FullyAutoAndSemiAutoTools): 重构路径执行记录管理 - 将原有的 hasRunning Set 替换为功能更完整的 Record 对象 - 添加路径、错误路径和分组路径的独立记录集合 - 更新路径执行状态检查逻辑以使用新的 Record 结构 - 在路径执行失败时记录错误路径信息 - 为任务分组添加路径记录功能 - 移除手动按键继续执行的交互流程 - 直接执行需要运行的地图任务 feat(auto-tools): 优化自动化脚本执行逻辑 - 添加hasRunning集合避免重复执行相同路径的脚本 - 修复半自动模式判断条件的逻辑错误 - 为runPath、runList、runMap函数添加详细的JSDoc注释 - 优化runPath函数确保执行完成后添加到运行记录 - 统一日志输出中的模式显示使用settings.mode替代硬编码值 - 实现路径去重检查机制防止同一路径被多次执行 - 重构任务执行流程支持Map结构的任务批量处理 refactor(FullyAutoAndSemiAutoTools): 重构路径配置逻辑并优化层级处理 - 修改了路径名称格式,将 levelName 的显示格式从 levelName_level 改为 levelName_level_level - 移除了对同名路径的过滤判断逻辑 - 注释掉了原有的设置项更新逻辑,改用新的分组方式处理 - 添加了按层级分组的工具函数 groupByLevel - 实现了基于层级分组的新设置项生成逻辑 - 新增了用于调试的 pathingALLSize 数组(注释状态) - 重写了多级路径的遍历和配置生成方式 feat(auto-tools): 添加开发者调试模式功能 - 新增 debug 和 isDebug 全局变量用于调试控制 - 实现了 debugKey 函数支持开发者模式下的断点调试 - 添加了 keyMousePress 函数用于检测按键按下和释放事件 - 在 settings.json 中增加 isDebug 复选框和 debug 输入框配置 - 更新自动暂停快捷键标签提醒避免 BGI 快捷键冲突 - 修改 dispatcher.addTimer 为 dispatcher.addTrigger - 在树形结构生成过程中添加调试日志输出功能 refactor(FullyAutoAndSemiAutoTools): 优化路径选择逻辑和标签显示 - 修改错误提示信息中的字符串格式,添加适当的空格 - 重构路径读取逻辑,将 treePathList 的赋值移到条件判断之后 - 添加 level 变量用于动态控制路径层级显示 - 更新设置选项标签,从静态文本改为动态显示当前路径级别 - 移动 level++ 操作到正确的位置以确保层级计算准确 refactor(FullyAutoAndSemiAutoTools): 优化路径配置和按键监听实现 - 将 pathing.json 的读取逻辑简化为 forEach 方式 - 移除多余的 log.warn 调试信息 - 修复 settings 配置的 JSON 解析问题 - 改进路径同步列表的处理方式 - 添加实时自动拾取任务配置 - 实现新的鼠标键盘按键监听函数 keyMousePress - 使用新的按键监听函数替换原有 keyPress 实现 - 优化路径执行时的用户交互提示信息 refactor(FullyAutoAndSemiAutoTools): 重构路径处理逻辑并添加父级目录获取功能 - 添加getParentFolderName函数用于获取指定层级的上级文件夹名称 - 使用新的getParentFolderName函数替换原有的路径处理逻辑 - 在treeList中增加parentName字段用于存储父级目录名称 - 修复路径分隔符处理和层级计算问题 - 临时注释掉主执行循环以进行调试 feat(FullyAutoAndSemiAutoTools): 添加路径执行设置配置功能 - 遍历pathRunMap创建多选框设置项 - 为每个路径生成对应的JSON配置对象 - 将路径名称映射到设置项的name字段 - 将路径执行类型数组作为选项值 - 将生成的设置项添加到settingsList数组 - 将设置列表写入manifest.settings_ui文件 feat(auto-tools): 添加半自动工具配置和路径处理功能 - 新增 needRunMap 存储需要运行的任务映射 - 修改 init 函数返回设置配置并解析为 JSON 格式 - 添加 parentJson 配置选项用于选择执行路径 - 重构路径处理逻辑,支持 @ 符号和特殊路径识别 - 注释掉旧的路径处理代码保持兼容性 - 实现主函数中遍历 needRunMap 执行任务列表 feat(FullyAutoAndSemiAutoTools): 添加全自动半自动工具箱功能 - 实现了自动和半自动路径执行功能 - 添加了配置文件初始化和验证机制 - 实现了路径文件的递归读取和树形结构构建 - 添加了路径映射和执行控制逻辑 - 集成了按键暂停和继续执行功能 - 实现了路径列表转换和执行流程管理 - 添加了 manifest.json、settings.json 和 pathing.json 配置文件支持 * refactor(FullyAutoAndSemiAutoTools): 优化运行队列逻辑提高性能 - 使用 Set 替代数组查找操作提升性能 - 实现批量删除机制避免迭代过程中的元素删除问题 - 重构代码结构优先处理上次群组未执行的任务 - 添加 lastRunMap 存储并处理剩余任务 - 优化迭代逻辑确保任务按预期顺序执行 * feat(auto-tools): 添加择优模式功能 - 修改路径列表处理逻辑,为每个路径对象添加选中状态字段 - 更新执行日志显示,添加模式和选中路径信息输出 - 实现择优运行函数,优先执行上次未完成的任务路径 - 添加choose_best配置选项,支持择优模式开关设置 - 优化记录检查逻辑,提升路径匹配性能 - 整理代码结构,将择优运行逻辑封装为独立函数 feat(auto-tools): 添加黑白名单配置功能 - 在设置中添加白名单和黑名单输入框配置 - 新增 config_list 对象存储黑白名单数组 - 实现从设置读取黑白名单并解析为数组 - 添加路径过滤逻辑,支持黑名单排除和白名单优先 - 实现黑白名单预处理,去除空字符串并trim - 优化路径遍历,跳过黑名单中的路径 fix(FullyAutoAndSemiAutoTools): 修复空映射时的执行逻辑并移除调试代码 - 添加了 needRunMap 非空检查避免无效执行 - 移除了调试用的日志记录和按键等待功能 - 优化了代码流程控制结构 feat(auto-tools): 添加记录管理和用户配置功能 - 定义记录文件路径并实现saveRecord函数保存记录到JSON文件 - 在initRecord函数中添加读取记录文件逻辑,支持Set数据类型的转换 - 实现同一天记录数据合并功能,确保Set属性存在 - 添加用户配置映射管理,支持不同UID的配置存储 - 实现配置模式选择功能,支持刷新和加载两种模式 - 添加错误处理机制确保文件操作的安全性 - 优化配置文件的读写流程,提升数据持久化可靠性 * feat(config): 更新配置文件路径和多复选框数据结构 - 修改配置根目录为 'config' 并更新相关路径引用 - 重构多复选框映射表存储结构,保存标签和选项对象 - 新增根据多选框名称获取JSON数据的异步函数 - 更新从复选框映射表获取值的方法以返回选项数组 - 修改用户设置文件路径和名称为 uid_settings.json - 添加错误处理机制避免写入配置文件时崩溃 - 优化配置过滤逻辑支持路径和标签匹配 - 新增提取方括号内容的工具函数 - 调整配置界面显示格式和索引计数逻辑 * feat(game): 添加七元素队伍配置功能 - 新增 SevenElement 配置对象,包含七元素及其对应材料映射 - 添加 team 配置对象,支持当前元素和战斗状态管理 - 实现路径执行前检查战斗策略配置的功能 - 添加团队七元素设置选项到配置文件 - 优化路径执行流程,增加调试信息输出 * feat(auto-tool): 添加队伍切换功能并支持元素匹配 - 在SevenElement中新增矿物元素类型 - 实现基于路径的元素匹配和队伍切换逻辑 - 添加SwitchTeam工具模块实现队伍配置功能 - 集成OCR识别和图像匹配的队伍切换机制 - 支持自动翻页查找目标队伍功能 - 实现七天神像传送和队伍缓存清理功能 * feat(auto-tool): 更新七元素配置和按键监听功能 - 添加矿物元素对应的材料列表(夜泊石、石珀、清水玉、万相石) - 修复teamSevenElements为空时的分割处理逻辑 - 新增fightKeys配置项用于战斗区域识别 - 重构keyMousePress函数支持跳过功能和更精确的状态返回 - 添加keyMousePressStart函数用于兼容旧调用方式 - 在半自动模式中实现路径执行跳过功能 - 优化按键监听循环逻辑提高响应准确性 * feat(auto-tools): 添加路径记录功能和时间差计算 - 新增 RecordPath 对象用于记录路径信息 - 实现 saveRecordPaths 函数保存路径记录到文件 - 添加 getTimeDifference 函数计算时间差值 - 在路径执行完成后记录时间戳和路径信息 - 从 PathRecord.json 文件读取和解析路径记录 - 将 Set 数据结构转换为数组进行 JSON 序列化 - 重构 RecordLast 对象的 name 字段为 uid 字段 refactor(FullyAutoAndSemiAutoTools): 优化战斗队伍切换逻辑 - 修复了代码缩进和空格格式问题 - 重构了队伍切换条件判断逻辑 - 添加了战斗模式下的队伍切换功能 - 统一了代码风格和命名规范 feat(team): 添加战斗策略配置和队伍切换逻辑 - 在team对象中添加fightName属性用于存储战斗策略名称 - 实现战斗模式下的队伍切换功能,当fight为true时使用fightName进行队伍切换 - 添加战斗策略配置验证,未配置战斗策略时抛出错误 - 保留原有的七元素队伍切换逻辑,在非战斗模式下继续使用 - 添加详细的日志记录以跟踪队伍切换过程 feat(auto-tool): 添加战斗需求检测和自动战斗功能 - 实现战斗需求检查逻辑,检测路径是否需要配置战斗策略 - 添加战斗状态标记和管理机制 - 集成自动战斗任务执行功能 - 优化路径执行流程,在需要时自动启动战斗模式 - 添加战斗状态重置机制确保正确清理 - 完善错误处理和日志记录功能 * feat(auto-tools): 新增cron表达式解析功能并优化路径过滤逻辑 - 添加cron.js工具模块,实现cron表达式解析和下次执行时间计算功能 - 新增timeType枚举类型,支持小时和cron表达式两种时间配置方式 - 重构路径去重逻辑,使用Map按路径字符串和时间戳进行智能去重 - 移除废弃的getTimeDifference函数实现 - 在初始化配置中注册cron工具模块 - 实现基于时间配置的路径过滤机制,支持小时间隔和cron表达式触发 - 从pathing.json加载时间配置,按等级排序后应用到路径过滤逻辑 - 添加cron表达式解析失败的错误处理和日志记录 - 更新pathing.json默认配置,包含地方特产和矿物的时间规则示例 * refactor(cron): 重构Cron时间戳获取功能 - 将getNextCronTimestamp函数改为异步函数,使用HTTP请求替代本地计算 - 移除原有的本地Cron表达式解析和时间计算逻辑 - 添加对远程服务的HTTP请求实现时间戳计算 - 注释掉原有性能较差的本地计算方法 - 移除不再使用的辅助函数parseCron、parseField、parseCronField - 保留isValidCron函数用于验证Cron表达式的功能 * feat(config): 添加七元素配置文件支持并优化密钥验证提示 - 新增 SevenElement.json 配置文件用于管理七元素数据 - 添加 json_path_name 常量对象统一管理配置文件路径 - 优化密钥不匹配错误提示,增加升级说明和文档查看建议 - 实现七元素配置的动态加载和合并功能 - 更新 CD 路径配置使用新的路径常量 - 改进七元素数据解析和排序逻辑 refactor(FullyAutoAndSemiAutoTools): 重构代码结构并优化配置管理 - 修改 getNextCronTimestamp 函数参数,移除默认 URL 参数 - 将全局变量重构为常量对象 auto、dev 和 cd,提高代码可维护性 - 更新团队配置属性名,从 teamFight 和 teamSevenElements 改为 team_fight 和 team_seven_elements - 实现完整的初始化流程,包括工具模块动态加载和配置验证 - 添加 UID 设置持久化功能,支持不同账户的个性化配置 - 重构路径执行逻辑,优化黑白名单过滤和 CD 时间控制 - 移除过时的全局变量和初始化代码,精简代码结构 - 更新设置界面配置,新增 CD 算法开关和改进的半自动模式选项 * feat(config): 添加路径加载层级配置选项 - 新增 loadingLevel 变量用于控制路径加载层级 - 在设置中添加 loading_level 配置项,默认值为 2 - 实现配置解析逻辑,支持自定义加载层级数值 - 添加配置错误时的异常处理和警告日志 - 更新记录文件路径引用,使用统一的 json_path_name 配置 - 注释掉原有的硬编码记录文件路径变量 * feat(core): 添加实时任务处理功能 - 实现了 realTimeMissions 函数用于处理实时任务 - 支持自动对话、自动战斗、自动拾取三种实时任务类型 - 添加了 real_time_missions 配置选项到设置界面 - 集成实时任务调度器替代原有的固定任务执行方式 - 支持通用任务和非通用任务的差异化处理 - 更新了任务执行流程以使用新的实时任务机制 * feat(FullyAutoAndSemiAutoTools): 添加全自动半自动工具箱及文档 - 更新 manifest.json 中的 bgi_version 从 0.44.8 到 0.54.3 - 新增完整的 README.md 文档,包含项目概述、核心功能、文件结构、流程图等详细说明 - 提供了详细的配置项说明和使用流程指南 - 包含了 CD 规则示例和实用建议等完整文档内容 * docs(readme): 更新项目文档添加外部依赖部署说明 - 移除原神相关描述简化为通用工具箱介绍 - 添加 bettergi-scripts-tools 部署指南支持 Cron 解析 - 提供 Windows、Java、Docker 三种部署方式 - 补充 Cron API 接口使用示例 - 修正冷却系统说明明确需要外部 HTTP API 支持 * fix(config): 修复加载路径层级配置验证逻辑 - 添加 finally 块确保 loadingLevel 最小值为 2 - 防止配置错误导致的加载层级异常问题 * refactor(FullyAutoAndSemiAutoTools): 重构文件路径同步和层级处理逻辑 - 添加 settingsRefreshList 用于管理设置项刷新 - 修改 addUniquePath 函数支持传入列表参数 - 修复 parentLevel 计算逻辑,确保层级正确对应 - 更新排序逻辑,使用 path 字段替代 parent_name 进行比较 - 重构 readPaths 函数,实现完整的树形结构构建 - 添加 getFileOrFolderName 和 getParentFolderName 辅助函数 - 优化 settingsList 的合并和去重处理 - 统一使用 children 字段替代 child 字段 * feat(config): 添加配置文件支持并优化设置初始化 - 添加 settings.json 配置文件定义各项功能参数 - 修改 initSettings 函数支持路径前缀参数 - 实现配置文件路径动态拼接功能 - 集成密钥、模式选择、队伍配置等完整配置项 - 支持实时任务、CD算法、调试模式等高级功能配置 * fix(runtime): 修复实时任务配置执行问题 - 添加了对real_time_missions的数组类型检查和转换 - 增加了配置执行日志输出便于调试 - 修复了getMultiCheckboxMap中键值过滤逻辑 - 改进了配置路径处理和前缀拼接功能 - 移除了空的PathRecord.json文件初始化 - 优化了运行映射的过滤和处理流程 * fix(FullyAutoAndSemiAutoTools): 修复设置过滤逻辑和代码格式问题 - 修正了levelName过滤条件,从排除改为包含匹配项 - 修复了recordPaths变量声明和赋值的格式问题 - 修正了needRunMap的日志输出格式,使用数组展开语法 - 添加了configSettings检查,避免重复初始化设置 - 修复了getMultiCheckboxMap函数中的语法格式问题 - 修正了multiCheckboxMap日志输出的格式问题 * feat(FullyAutoAndSemiAutoTools): 添加黑名单白名单过滤功能 - 实现黑名单检查逻辑,过滤包含黑名单关键词的文件名 - 实现白名单检查逻辑,允许白名单中的项目通过过滤 - 添加JSON文件过滤功能,排除.json结尾的文件 - 修改子名称处理逻辑,支持数组形式的子名称存储 - 更新路径添加逻辑,集成过滤后的子名称数组 * feat(config): 添加刷新设置配置并优化黑白名单过滤功能 - 添加 RefreshSettings.json 配置文件路径定义 - 预处理黑白名单数组,移除空字符串并进行 trim 处理 - 实现黑名单白名单过滤逻辑,支持动态排除特定项目 - 优化路径遍历逻辑,支持更灵活的层级关系构建 - 添加安全的可选链操作符处理可能为空的路径数据 - 更新配置项默认值设置,确保 config_run 执行状态正确 - 优化多复选框映射创建,仅处理非空选项数据 - 改进树形结构转列表算法,提升性能和数据完整性 - 添加多个调试日志输出,便于开发过程跟踪和问题排查 * feat(config): 实现基于用户ID的路径配置管理 - 添加了levelName常量定义用于树层级标识 - 新增pathJsonByUid配置路径支持按用户ID存储路径配置 - 实现loadPathJsonListByUid函数根据用户ID加载路径JSON列表 - 创建initRefresh函数重构配置刷新逻辑并支持用户隔离 - 添加initUidSettingsMap函数初始化用户ID设置映射表 - 实现loadUidSettingsMap函数加载用户特定配置 - 创建initRun函数处理执行前配置并完善路径过滤机制 - 重构needRunMap初始化逻辑支持CD时间和路径匹配 - 优化路径筛选算法增加多层次路径匹配和过滤功能 - 实现PATH_JSON_LIST按用户ID保存和加载机制 * fix(FullyAutoAndSemiAutoTools): 修复记录查找和路径设置逻辑 - 添加空值合并操作符确保 RecordList 和 RecordPath 的默认值 - 使用逻辑或赋值运算符简化 uid 和 paths 属性的设置 - 移除冗余的条件检查和赋值操作 - 优化代码可读性和执行效率 * feat(auto-tools): 优化自动化工具的路径执行逻辑 - 添加了按父名称和名称分组路径的功能 - 实现了路径分组的排序机制 - 重构了路径执行逻辑,支持更精确的分组执行 - 修复了变量命名和代码格式问题 - 优化了日志输出,提高执行过程的可追踪性 - 更新了配置初始化和加载流程 * refactor(FullyAutoAndSemiAutoTools): 移除未使用的变量声明 - 注释掉未使用的 label 变量获取逻辑 - 移除未使用的 as_name 变量声明 - 保留 groupByParentAndName 函数定义结构 * feat(settings): 添加执行顺序规则配置功能 - 支持多条规则配置,语法为"parentName->name1=1,parentName->name2=2" - 实现规则解析和排序映射功能 - 添加order_rules配置项到settings.json - 优化日志信息中的参数格式 - 修复代码中的变量命名间距问题 * refactor(FullyAutoAndSemiAutoTools): 更新runPath函数参数和战斗需求检查逻辑 - 为runPath函数添加current_name和parent_name参数,默认值为空字符串 - 注释掉原有的try-catch块以跳过战斗需求检查 - 在执行路径时传递当前名称和父名称参数 - 移除对团队战斗配置的验证逻辑 * Revert "refactor(FullyAutoAndSemiAutoTools): 更新runPath函数参数和战斗需求检查逻辑" This reverts commit7995c67419. * refactor(FullyAutoAndSemiAutoTools): 移除战斗策略配置检查逻辑 - 注释掉JSON解析和描述检查相关代码 - 保留路径关键词匹配的战斗需求检查逻辑 - 简化战斗需求判断流程 * feat(FullyAutoAndSemiAutoTools): 添加路径执行列表的日志记录功能 - 在runList函数中增加了current_name和parent_name参数用于日志记录 - 修改了日志输出格式以显示正确的父名称和当前名称 - 更新了runList调用以传递必要的参数 - 清理了排序相关的todo注释 * refactor(FullyAutoAndSemiAutoTools): 重构路径扫描系统并优化多账号支持 - 修复 manifest.json 中的密钥格式,去除多余空格 - 重构路径扫描功能,支持任意深度目录结构的树状扫描 - 新增按 UID 缓存路径列表功能,提升多账号切换性能 - 优化黑白名单过滤逻辑,使用 Set 数据结构提升查找效率 - 更新 README 文档,详细说明新的路径扫描和缓存机制 - 修改配置文件结构,新增 RefreshSettings.json 和 path-json-by-uid.json - 调整 CD 规则配置,更新示例中的冷却时间设置 - 完善 Cron 解析服务部署文档,提供多种部署方式说明 - 优化用户操作流程,简化首次配置和日常使用的步骤 * refactor(FullyAutoAndSemiAutoTools): 重构队伍切换逻辑 - 提取队伍切换功能到独立的 switchTeamByIndex 函数中 - 添加详细的 JSDoc 注释说明函数用途和参数 - 简化主流程中的条件判断逻辑 - 将原有的队伍切换代码替换为函数调用 - 保留原有功能的同时提高代码可读性和维护性 - 为特定路径"有草神"添加专门的处理逻辑 * docs(settings): 更新队伍配置字段标签说明 - 在队伍配置字段标签中添加草神位置填写建议 - 明确标注建议草神填写至草位的说明信息 * feat(FullyAutoAndSemiAutoTools): 添加调试日志功能并优化队伍切换逻辑 - 添加了needRunMap的调试日志输出功能 - 修改switchTeamByIndex函数增加key参数支持 - 在路线切换时传入对应的元素名称作为标识 - 为草神路线切换添加了明确的调用参数 * style(FullyAutoAndSemiAutoTools): 优化代码格式和团队切换逻辑 - 修复字符串常量中的空格问题 - 重新格式化switchTeamByIndex函数的注释和代码缩进 - 简化团队切换逻辑,移除冗余的条件判断和重复代码 - 优化runList函数参数中的空格格式 - 重构团队切换的执行顺序和条件判断结构 * fix(path): 修复路径执行异常时的记录清理问题 - 在路径执行开始时记录时间戳以确保一致性 - 路径执行失败时删除对应的路径记录 - 执行失败时同步删除错误路径并保存记录 - 任务组执行失败时删除对应的分组路径记录 * fix(core): 修复路径记录功能中的对象引用错误 - 将 RecordPath.paths 替换为 Record.paths 以修正对象引用 - 移除已注释掉的废弃代码块,清理文件结构 - 重构路径执行逻辑,确保记录和错误处理正确同步 - 更新组路径记录方式,使用统一的对象结构管理 - 修改配置文件格式从数组改为对象以适配新逻辑 * feat(auto-tools): 添加路径记录功能并优化执行流程 - 新增 RecordPathList 数组用于存储路径记录 - 修改数据结构使用 RecordPathList 替代原有的 Record.paths - 优化路径匹配逻辑,调整条件判断返回值 - 更新文件保存机制,异步保存路径记录和普通记录 - 重构路径执行流程,改进异常处理和状态管理 - 添加日志输出增强调试信息 - 修复路径数据解析和查找逻辑 - 移除部分 continue 语句改用异常抛出机制 * fix(FullyAutoAndSemiAutoTools): 解决记录路径排序问题 - 添加时间戳降序排序确保最新记录优先显示 * feat(settings): 添加刷新记录配置选项 - 在设置中新增 refresh_record 配置项用于控制记录清空 - 实现刷新时清空 RecordPathText 和 RecordText 文件功能 - 添加日志记录显示已清空记录文件的状态信息 * docs(README): 更新配置项文档 - 添加 refresh_record 配置项说明 - 补充运行记录相关功能描述 * fix(FullyAutoAndSemiAutoTools): 修复selected属性赋值问题 - 修正了selected属性的赋值语法,确保正确传递变量值 - 避免了潜在的属性访问错误 - 保持了对象结构的一致性 * fix(auto-tools): 修复CD过滤逻辑错误 - 重命名cdFiltered为in_cd_paths以提高可读性 - 修正CD路径过滤条件,将返回值取反确保正确过滤 - 修复cron时间类型判断逻辑,添加默认返回false避免意外通过 - 更新变量引用以使用新的变量名in_cd_paths - 修正时间差计算逻辑确保CD状态判断准确 * feat(FullyAutoAndSemiAutoTools): 添加路径排序配置功能 - 新增 PathOrder.json 配置文件用于路径排序 - 实现基于JSON配置的路径排序功能 - 添加 try-catch 错误处理机制 - 支持从 PathOrder.json 文件读取排序规则 - 移除未使用的 readPaths 函数注释代码 - 优化排序逻辑支持多条规则配置 * feat(auto-tool): 添加锄地队伍配置功能 - 新增 HoeGroundMap 用于存储锄地队伍映射关系 - 添加 team_hoe_ground 配置项用于设置锄地队伍规则 - 实现 switchTeamByName 函数按名称切换队伍 - 修改 runPath 函数支持传递父级和当前名称参数 - 在路径执行时根据锄地配置自动切换对应队伍 - 更新设置界面添加锄地队伍配置输入框 - 移除废弃的方案2注释代码 * feat(auto-tools): 添加锄地队伍配置功能 - 新增 HoeGround.json 配置文件用于存储锄地队伍映射 - 实现基于 JSON 的锄地队伍配置支持 - 添加 UID 过滤的锄地队伍映射功能 - 优化 PathOrder.json 默认配置结构 - 移除调试代码并完善配置加载日志 * docs(FullyAutoAndSemiAutoTools): 更新 README 文档内容 - 在标题后添加空行以改善格式 - 为执行时序图部分添加新的章节标题 - 调整 mermaid 图表中的样式定义格式,统一缩进和间距 - 在 sequence diagram 中添加适当的空格以提高可读性 - 将 settings.json 配置表格进行重构,添加新的配置项如 key 和 team_hoe_ground - 为新增配置项添加对应的 JSON 结构示例说明 - 优化 CD 规则示例的格式化显示 - 在版本密钥表格中简化表头格式 - 添加必要的换行以改善文档整体布局 * docs(README): 更新额外json配置标题说明 - 将"额外json配置"修改为"(可选)额外json配置" - 强调该配置项的可选性质以提高文档清晰度 * feat(config): 更新自动化工具配置选项 - 添加配置模式-刷新-清空运行记录复选框 - 新增执行顺序规则输入字段 - 添加锄地队伍配置选项 - 更新七元素队伍配置说明 - 重新整理配置项顺序和分隔符位置 * fix(game): 修复自动切换队伍功能中的点击延迟问题 - 在部署按钮点击后添加 100ms 延迟,确保操作正确执行 - 解决了因点击过快导致的游戏响应异常问题 * feat(config): 添加配置UID显示功能 - 在设置界面添加config_uid复选框用于显示当前配置UID - 实现settings.json和config/settings.json中的UID显示逻辑 - 更新main.js中保存用户配置时同步更新当前配置UID显示 - 修复JSON解析中的数组结构格式化问题 - 添加分隔符优化设置界面布局结构 * feat(core): 添加按UID清空运行记录功能 - 实现了按UID过滤清空记录的功能 - 在设置中添加了清空运行记录模式选择选项 - 新增"全部"和"UID"两种清空模式 - 当选择UID模式时只清空当前UID对应的记录 - 添加了相应的日志输出显示清空的UID信息 - 更新了配置文件中的设置项定义 * docs(FullyAutoAndSemiAutoTools): 更新README文档配置项说明 - 添加config_uid配置项说明,用于显示配置uid - 添加refresh_record_mode配置项说明,用于设置清空运行记录模式 - 优化JSON示例格式,将注释移至下一行以提高可读性 - 更新订单规则和队伍配置的JSON结构展示 * refactor(FullyAutoAndSemiAutoTools): 优化配置管理和代码结构 - 修改配置UID显示格式,在标签中添加换行符以改善可读性 - 修复变量赋值语句的格式化问题,确保代码风格一致性 - 优化日志输出中的参数格式,提升调试信息准确性 - 重构配置设置过滤逻辑,实现基于层级的设置加载机制 - 更新getBracketContent函数的实现方式,从正则表达式改为索引查找方法 - 改进注释文档的表述准确性,明确功能描述和返回值说明 * fix(FullyAutoAndSemiAutoTools): 优化路径筛选逻辑并修复配置加载问题 - 修改循环逻辑,仅遍历有子节点的路径项 - 添加父级节点的层级名称设置功能 - 增加路径配置列表加载检查,防止未初始化时出错 - 重构设置过滤逻辑,提高层级匹配准确性 - 优化路径匹配算法,确保只有含子节点的路径参与筛选 - 移除冗余代码,简化树形结构转列表逻辑 * feat(pathing): 优化路径层级管理和显示功能 - 在 PATHING_ALL 中添加 id 字段用于唯一标识 - 将 parentName 从空字符串改为 undefined,并添加 rootName 字段 - 修改过滤逻辑以支持更完整的路径层级遍历 - 添加 rootName 字段记录最父级下一级名称 - 在设置列表中增加分隔符提升界面可读性 - 优化路径显示格式,添加父子级关系标识 - 重构 addUniquePath 函数支持基于多个条件的去重判断 - 添加对 children 和 child_names 字段的双重支持 - 增加调试日志输出便于问题排查 * fix(FullyAutoAndSemiAutoTools): 修复路径过滤逻辑错误 - 修正了父级路径过滤条件,将相等判断改为不等判断 - 修复了子级选项数组的拼接方式,改用展开运算符合并 - 纠正了配置层级加载的逻辑,反转了条件判断以确保正确的层级加载 - 修正了基于levelName的过滤逻辑,确保设置项能正确匹配对应层级 * feat(auto-tools): 增强路径管理和排序功能 - 添加rootName支持,实现更精确的路径层级管理 - 新增generatedKey函数统一处理路径键值生成逻辑 - 修复路径过滤条件,正确处理parentId匹配 - 更新JSON配置结构,增加root_name字段支持 - 完善排序规则,支持多层级(rootName->parentName->name)排序 - 优化去重逻辑,完整比较所有路径属性 - 更新文档说明,添加详细的语法配置指南 * refactor(FullyAutoAndSemiAutoTools): 优化路径过滤逻辑并清理代码 - 注释掉未使用的 countMatchingElements 函数 - 使用 dir_key 变量存储拼接的路径字符串 - 修改 filterSettings 过滤条件以支持指定目录加载 - 更新注释文字从"对应级别"为"指定级别" - 重构路径过滤逻辑提高代码可读性 * fix(core): 修复自动工具中的逻辑判断错误 - 修复路径过滤条件,将不等于改为等于判断 - 添加高级别过滤功能支持 - 修复设置加载的路径匹配逻辑 - 修复级别过滤的条件判断 - 修复冷却时间检查的异步处理 - 修复团队锄地列表的筛选条件 - 修复排序列表的筛选条件 - 使用统一的键生成函数优化代码结构 * fix(config): 修复配置文件中的标签显示问题 - 在settings.json中为配置uid标签添加换行符以改善显示 - 在config/settings.json中同步更新配置uid标签的换行格式 - 修改main.js中添加theLayer变量来控制层级加载逻辑 - 将硬编码的false条件替换为动态的theLayer变量判断 * feat(auto-tools): 添加指定层级加载功能 - 在配置中新增 the_layer 复选框选项用于控制是否只加载指定层级 - 优化路径查找逻辑,通过预建 levelName 映射提升性能 - 修改过滤条件以支持层级加载功能 - 在两个配置文件中同步添加 the_layer 设置项 * feat(auto-tools): 添加指定层级加载功能 - 在配置中新增 the_layer 复选框选项用于控制是否只加载指定层级 - 优化路径查找逻辑,通过预建 levelName 映射提升性能 - 修改过滤条件以支持层级加载功能 - 在两个配置文件中同步添加 the_layer 设置项 * docs(readme): 更新文档中的语法规则说明 - 移除了关于 name=1 和 name=队伍名 语法支持的描述 - 调整了匹配精度规则,移除了 name 级别的匹配 - 统一了锄地特化队伍配置部分的语法规则说明 * refactor(FullyAutoAndSemiAutoTools): 优化键值生成逻辑 - 修改 generatedKey 函数支持 useParent 参数控制键值生成方式 - 优先处理 rootName->parentName->name 格式的键值生成 - 添加 useParent 模式下的父级键值生成逻辑 - 在 groupByParentAndName 函数中同时生成普通键值和父级键值 - 为每个项目创建两套分组键值以支持不同层级的分组需求 * fix(team): 修复团队锄地数据映射逻辑 - 移除无效的 undefined 初始化检查 - 直接设置团队名称到锄地映射表中 - 简化了键值对的存储逻辑 - 避免了空对象的创建和访问操作 * feat(order): 添加父级键值映射功能 - 为订单项生成父级键值 - 将父级键值与订单建立映射关系 - 保留原有键值映射逻辑不变 * fix(auto-tools): 修复锄地工具中的路径分组逻辑问题 - 移除无用的 groupByParentAndName 函数定义位置 - 修改锄地队映射逻辑,区分 root_name 存在和不存在的情况 - 更新路径排序逻辑,添加映射表处理父子路径关系 - 修复 generatedKey 调用参数传递问题 - 在 README 中添加语法风格一致性说明 * feat(config): 添加模板匹配设置功能并优化配置过滤逻辑 - 新增 templateMatchSettingsJson 配置文件路径定义 - 修复路径筛选中的 find 方法使用方式 - 实现模板匹配设置的读取和配置项过滤 - 优化 UID 设置过滤逻辑并添加分隔符结构 - 调整配置层级判断条件从大于改为大于等于 - 将最终配置写入改为使用模板匹配设置而非 UID 设置 * refactor(config): 更新配置文件处理逻辑 - 添加了 templateMatchSettingsJson 配置文件路径定义 - 使用 templateMatchSettings 替代 uidSettings 进行配置筛选 - 优化了层级设置过滤逻辑,改进了分隔符插入机制 - 重构了配置项的合并与写入流程 - 修复了层级名称匹配和路径过滤的相关问题 - 调整了设置项的排序和展示逻辑 * fix(FullyAutoAndSemiAutoTools): 修复加载层级比较逻辑错误 - 修正了模板匹配设置中的加载层级判断条件 - 将比较逻辑从 loadingLevel > level 更新为 loadingLevel > level+1 - 确保级别检查逻辑与预期行为一致 * feat(config): 添加高阶过滤配置功能 - 在设置中新增 high_level_filtering 配置项用于高级过滤 - 实现高阶过滤逻辑,支持路径层级过滤功能 - 添加 levelName 属性初始化为 undefined - 修复加载层级判断条件中的运算符间距问题 - 添加 levelNameMap 调试日志输出 - 移除重复的变量声明代码 - 添加待优化注释标记后续改进点 * feat(FullyAutoAndSemiAutoTools): 优化路径遍历和数据结构处理逻辑 - 添加了路径JSON列表的调试日志输出功能 - 重构了路径对象创建逻辑,统一使用对象变量赋值方式 - 修改了遍历列表过滤条件,只处理文件类型的元素 - 更新了UI标签文本的显示位置和格式 - 优化了层级名称映射查找逻辑,提高性能 - 添加了详细的调试日志用于跟踪数据处理过程 - 统一了levelName字段初始化为空字符串 - 重构了树转列表算法,支持递归处理所有节点包括非文件节点 * feat(config): 添加高阶过滤功能并限制连续分隔符数量 - 实现了 limitConsecutiveSeparators 函数来限制连续分隔符不超过3个 - 在模板匹配设置中应用分隔符数量限制逻辑 - 更新 README.md 添加 high_level_filtering 配置项说明 - 添加高阶过滤语法说明文档和使用示例 - 修改 settings.json 中高阶过滤标签提示查看文档 - 优化配置界面中的高阶过滤功能描述 * docs(FullyAutoAndSemiAutoTools): 更新 README 文档中的流程图和时序图 - 更新了 Mermaid 流程图,更清晰地展示刷新、加载和执行三种模式 - 重新设计了时序图,突出不同模式下的交互流程差异 - 添加了详细的模式切换说明和过滤逻辑描述 - 优化了图表样式和分类,提高可读性 - 补充了各模块间的调用关系和数据流向说明 * feat(config): 更新路径配置文件增加更多资源类型 - 添加星银矿石、白铁块等矿物资源的定时配置 - 新增「冷鲜肉」、发光髓、鳅宝玉等多种道具的小时制配置 - 添加青蛙、鳗肉、螃蟹等食物资源的定时设置 - 增加沉玉仙茗、冰雾花花朵等植物资源的时间配置 - 新增电气水晶、食材与炼金等综合类资源的定时任务 - 添加敌人与魔物、锄地专区等功能区域的时间规划 * fix(sorting): 修复分组排序逻辑 - 将默认排序值从 9999 改为 0 - 修改比较函数实现倒序数字比较 - 确保不在 JSON 中的项目正确排列到末尾 * fix(tools): 解决排序功能中的空值异常问题 - 为 localeCompare 方法调用添加可选链操作符 - 防止当 a_key 为 null 或 undefined 时引发错误 - 确保排序逻辑在所有情况下都能正常执行 * fix(FullyAutoAndSemiAutoTools): 修复路径匹配逻辑 - 添加额外条件检查 labelParentName 是否等于 pathingName - 确保路径匹配时考虑完整的路径名称匹配 - 修复过滤器中路径匹配的逻辑错误 * fix(FullyAutoAndSemiAutoTools): 修复路径拼接逻辑问题 - 添加了对 parentName 与 rootName 相同情况的判断条件 - 避免了当 parentName 和 rootName 相同时的重复路径拼接 - 确保了路径层级关系的正确性 * Revert "fix(FullyAutoAndSemiAutoTools): 修复路径拼接逻辑问题" This reverts commitcfa86be643. * feat(auto-fight): 弃用自动战斗功能 - 注释掉实时任务中的自动战斗调用 - 在设置选项中标记自动战斗为已弃用状态 - 更新配置文件中的自动战斗选项显示 - 移除自动战斗功能的激活逻辑 - 保留相关代码以供后续完全移除参考 * refactor(FullyAutoAndSemiAutoTools): 重构锄地队配置和排序规则处理逻辑 - 移除原有的team_hoe_ground配置解析代码块 - 将team_hoe_ground配置解析移动到新的位置并保持功能不变 - 调整order_rules配置解析的位置以优化代码结构 - 添加注释说明输入值优先覆盖的处理逻辑 - 重新排列代码顺序以改善可读性和维护性 * ``` refactor(FullyAutoAndSemiAutoTools): 优化模板匹配和路径过滤逻辑 - 添加连续分隔符数量限制功能 - 修复路径匹配中的逻辑运算符间距问题 - 改进订单列表解析和过滤逻辑 - 添加公共排序项支持并实现自定义排序覆盖 - 优化订单列表排序算法确保公共项优先显示 ``` * feat(FullyAutoAndSemiAutoTools): 优化锄地队伍配置逻辑 - 修改 teamHoeGroundList 数据结构,添加 is_common 字段用于区分公共锄地队 - 实现自定义锄地队覆盖公共锄地队的逻辑 - 添加数据过滤和排序功能,确保自定义锄地队优先于公共锄地队 - 更新锄地队映射关系的处理方式 * feat(tools): 添加执行顺序配置功能 - 在needRunMap中添加order字段用于控制执行顺序 - 使用orderMap获取对应组的执行顺序值 - 默认执行顺序为0当orderMap中不存在对应值时 * feat(config): 添加路径排序配置文件 - 新增地方特产分类的路径排序规则 - 新增矿物分类的路径排序规则 - 配置了从挪德卡莱到白铁块的各项资源排序 - 定义了各类别下子项目的显示顺序 - 设置了统一的UID和公共属性标识 - 建立了完整的路径层级结构配置 * docs(config): 更新配置规则文档说明 - 添加order值越大优先级越高的说明 - 新增is_common字段用于标识公共配置 - 补充CD规则中level值优先级说明 * chore(debug): 更新调试日志文件命名规范 - 为初始化刷新流程的调试日志添加 [init-refresh] 前缀 - 为初始化运行流程的调试日志添加 [init-run] 前缀 - 统一调试日志命名格式以便更好地区分不同执行阶段 - 在订单映射处理后添加新的调试日志记录 * fix(FullyAutoAndSemiAutoTools): 修复路径名称处理逻辑并优化调试日志 - 处理 root_name 和 parent_name 字段的兼容性情况 - 添加可选链操作符避免访问不存在的 parentName 属性 - 增加对 parent_name 字段的支持以处理不同命名格式 - 优化调试日志文件名以便更好地区分不同的日志内容 - 添加额外的调试信息记录功能用于问题排查 * refactor(FullyAutoAndSemiAutoTools): 优化 needRunMap 排序逻辑 - 添加对 needRunMap 的整体排序功能 - 使用 order 字段对映射项进行降序排序 - 替换原有的无序 needRunMap 实现 - 确保排序后按照指定顺序执行相关操作 * debug(FullyAutoAndSemiAutoTools): 添加运行时调试日志 - 在执行 chooseBestRun() 后记录 lastRunMap 的调试信息 - 在执行 chooseBestRun() 后记录 needRunMap 的调试信息 - 使用 JSON.stringify 将 Map 对象转换为字符串进行存储 - 通过 debugKey 函数将调试信息写入对应的日志文件 * feat(FullyAutoAndSemiAutoTools): 集成设置配置并添加调试日志 - 使用 settings.open_cd 和 settings.http_api 替代硬编码默认值 - 在初始化过程中添加 timeConfigs、recordPaths 和 in_cd_paths 的调试日志记录 - 添加 CD 设置的调试日志输出以方便排查问题 * feat(cron): 添加批量获取cron时间戳功能并优化CD过滤逻辑 - 新增 getNextCronTimestampAll 函数支持批量处理cron表达式 - 实现统一的HTTP请求接口减少网络请求次数 - 重构generatedKey函数位置提升代码复用性 - 将原有的单个cron时间戳获取改为批量处理模式 - 优化CD过滤流程通过Map映射提高查询效率 - 添加详细的参数验证和错误处理机制 * fix(cron): 修复cron请求参数格式问题 - 修改cron.js中HTTP POST请求的参数格式,将bodyJson包装在CronList对象中 - 添加调试日志功能,记录cdFilterMatchedPaths和nextMap信息 - 增强debugKey函数功能,支持文本模式的日志输出 - 在main.js中添加多处调试信息输出,便于问题排查 * fix(cron): 修复定时任务配置参数和逻辑处理问题 - 修复了POST请求中参数名从CronList改为cronList以匹配后端接口 - 添加了空数组检查避免对空列表执行定时任务查询 - 优化了定时任务配置的查找和更新逻辑 - 修复了代码中的格式化问题包括空格和条件判断语句 - 修正了调试函数参数的格式化错误 * fix(scheduler): 修复定时任务配置中的键值匹配问题 - 修改了时间配置中使用 item.path 替代 generatedKey(item) 作为键值 - 移除了不必要的 generatedKey 函数调用注释 - 在保存记录时实现基于 uid 的重复检查和数据合并 - 当存在相同 uid 记录时,将路径、错误路径和分组路径进行合并 - 优化了记录列表的数据更新逻辑,避免重复添加相同记录 * fix(FullyAutoAndSemiAutoTools): 解决记录路径合并逻辑问题 - 修复 RecordPathList 中重复记录的路径合并逻辑 - 注释掉 errorPaths 和 groupPaths 的合并操作 - 简化 RecordList 的处理逻辑,直接添加新记录而不进行查找合并 - 移除冗余的记录查找和条件判断代码 * fix(FullyAutoAndSemiAutoTools): 修复 RecordPathList 类型转换问题 - 将 RecordPathList 初始化从空数组改为使用 Array.from 进行类型转换 - 确保非数组类型的 RecordPathList 能够正确转换为数组格式 - 保持原有的数组查找逻辑正常工作 * feat(auto-tools): 添加任务执行顺序排序和择优模式支持 - 实现对 lastRunMap 按 order 字段进行降序排序 - 添加择优模式配置选项 choose_best - 在任务执行前后添加择优模式状态日志 - 增加任务组执行顺序打印功能 - 添加分隔线美化任务执行日志输出 * docs(FullyAutoAndSemiAutoTools): 更新文档和版本密钥 - 更新 manifest.json 中的密钥从 PGCSBY37NJ 到 PGCSBY37NJA - 添加运行实例部分日志截图展示 - 更新 bettergi-scripts-tools 版本要求为 v0.0.3 - 修改默认 API 地址为 /all 端点 - 更新版本密钥表格中的密钥值 - 将版本发布日期从 2026.01.18 更改为 2026.01.30 * feat(config): 更新默认CD算法API端点路径 - 将HTTP API默认路径从 /bgi/cron/next-timestamp 修改为 /bgi/cron/next-timestamp/all - 适配新的API接口以支持更完整的功能 - 保持向后兼容性同时提供增强的API功能支持 * fix(auto-tools): 修复自动化工具中的时间判断逻辑 - 修正时间配置判断条件,将 >= 改为 < 以正确判断是否在CD时间内 - 反转cron检查结果,确保不在CD中的项目返回true - 优化CD路径过滤逻辑,使用filter方法替代Set.difference - 移除多余的空行以改善代码整洁性 - 修复日志输出中的空格问题 - 统一变量声明中的空格格式 * feat(task): 更新任务组执行日志信息 - 在任务组执行顺序日志中添加执行路径数统计 - 修复了日志格式参数缺失的问题 - 添加了对路径数量的安全访问处理 * docs(readme): 更新使用说明文档 - 添加快捷使用指南包含账号刷新设置步骤 - 增加全自动执行流程说明和截图演示 - 补充CD算法部署要求和择优模式说明 - 完善队伍配置语法示例和映射规则 - 添加锄地队伍配置实例和路径执行说明 - 优化文档结构提升用户体验 * docs(README): 更新项目概述描述 - 移除原神(BetterGI平台)相关具体内容 - 简化项目功能描述 - 保持核心功能介绍不变 * docs(README): 更新项目描述 - 移除 BetterGI 平台相关宣传语 - 简化项目概述部分内容 * docs(FullyAutoAndSemiAutoTools): 更新README文档添加版本密钥获取说明 - 在快捷使用步骤1中添加先获取版本密钥的说明 - 添加高级配置查看提示作为第3个使用步骤 - 保持核心亮点部分的路径扫描重构说明 * docs(FullyAutoAndSemiAutoTools): 更新README中的冷却时间控制说明 - 在冷却时间控制描述中添加了关于路径CD的具体说明 * feat(auto-tools): 添加执行组最大路径数限制功能 - 新增 LimitMax.json 配置文件用于存储路径限制数据 - 实现执行组最大执行数限制功能,支持按组别配置最大路径数量 - 添加 open_limit_max 配置项用于开启/关闭路径限制功能 - 添加 limit_max_group 配置项用于设置各执行组的最大路径数规则 - 在任务组执行时应用路径数限制,确保不超过设定的最大值 - 更新 README.md 文档,添加新的配置项说明和使用示例 - 优化任务组执行顺序的日志输出格式 * feat(config): 更新矿物采集限制配置 - 将萃凝晶的最大限制从50增加到60 - 添加多个新的矿物采集配置项 - 新增紫晶块相关配置包括大剑版和钟离版 - 添加萃凝晶特殊路线配置支持火神赶路等模式 - 增加枫丹水下及钟离版配置选项 - 添加水晶块多种配置包括忆雪晴版和火山版 - 新增白铁块富集路线配置 - 在开启限制组功能时显示相应日志信息 * refactor(FullyAutoAndSemiAutoTools): 重构generatedKey函数并优化任务执行逻辑 - 重构generatedKey函数,优化三层和二层结构的处理逻辑 - 修改generatedKey函数中的空值检查,使用可选链操作符 - 移除无用的注释代码 - 修复teamHoeGroundList中root_name的空值检查逻辑 - 修正openLimitMax变量声明中的空格问题 - 将PathOrder文件路径改为LimitMax - 添加对limitMaxByGroup中max值的parseInt转换 - 增加调试日志输出limitMaxList的处理情况 - 优化runList函数参数,增加group_key和group_value参数 - 更新任务执行时的日志输出格式 - 修正任务组执行顺序的日志显示格式 - 优化任务组执行的索引计算和日志输出 * refactor(FullyAutoAndSemiAutoTools): 优化组执行数限制逻辑 - 提取 limitMax 变量避免重复计算 - 简化条件表达式提高代码可读性 - 更新调试日志输出格式增加 limitMax 参数 - 保持原有功能不变但改善代码结构 * ``` fix(auto-tools): 修复自动化工具中的键值映射和路径执行问题 - 修正了组键值映射逻辑,避免重复键冲突 - 更新了限制组最大执行数的判断条件,支持多键检查 - 修改了 runPath 函数参数结构,增加 root_name 参数 - 修复了队伍切换功能中的键值查找逻辑 - 改进了路径执行时的参数传递,确保正确的层级关系 ``` * fix(auto-tools): 修复日志格式化参数缺失问题 - 在日志信息中添加缺失的参数以确保正确显示模式信息 - 修正了团队切换日志中的参数传递顺序 - 防止因参数不足导致的日志输出异常 * feat(auto-tools): 禁用战斗检测功能并优化队伍切换逻辑 - 移除自动战斗策略检测功能,简化路径判断逻辑 - 添加队伍配置切换至行走位的自动切换功能 - 更新配置文件标签提示,明确战斗检测已禁用 - 修正README文档中的队伍配置说明描述 - 优化团队切换流程,增强非战斗状态下的队伍管理 * fix(FullyAutoAndSemiAutoTools): 修复逻辑运算符优先级问题 - 修正了 limitMax 变量赋值中的括号位置,确保逻辑或运算符正确执行 - 修正了 order 属性赋值中的括号位置,确保逻辑或运算符正确执行 - 避免因运算符优先级导致的潜在逻辑错误 * fix(tools): 添加错误日志记录功能 - 在记录路径读取失败时添加错误日志 - 在HoeGround数据加载失败时添加错误日志 - 在团队数据加载失败时添加错误日志 - 在路径排序配置加载失败时添加错误日志 - 在顺序映射加载失败时添加错误日志 - 在组限制配置加载失败时添加错误日志
405
repo/js/FullyAutoAndSemiAutoTools/README.md
Normal file
@@ -0,0 +1,405 @@
|
||||
# FullyAutoAndSemiAutoTools
|
||||
|
||||
**全自动 + 半自动路径任务工具箱**
|
||||
|
||||
## 项目概述
|
||||
|
||||
FullyAutoAndSemiAutoTools 是一套高度模块化、可高度自定义的自动化路径执行工具箱。
|
||||
|
||||
支持**全自动**与**半自动**两种运行模式,核心目标包括:
|
||||
|
||||
- 智能扫描 & 多层级管理大量路径文件(支持任意深度目录结构)
|
||||
- 精细的冷却时间控制(小时制 + Cron,需要外部解析服务)`根据路径的CD`
|
||||
- 根据路径特性自动切换战斗/元素队伍
|
||||
- 集成丰富的实时辅助功能
|
||||
- 执行记录防重复 + 择优优先未完成路径
|
||||
- 支持黑白名单、多 UID 隔离记录与路径缓存
|
||||
## 快捷使用
|
||||
- 1.(首次/刷新存储)账号刷新 设置刷新层级 运行一次 (自动识别uid存储) 先获取版本密钥
|
||||
</br>
|
||||
</br>
|
||||
- 2.执行
|
||||
**选择 全自动**</br>
|
||||
</br>
|
||||
**CD算法需要部署 [bettergi-scripts-tools](https://github.com/Kirito520Asuna/bettergi-scripts-tools/releases) 并启用http</br>
|
||||
也可以开启择优模式(择优模式不依赖bettergi-scripts-tools)**</br>
|
||||
</br>
|
||||
</br>
|
||||
**日常选择 全自动**</br>
|
||||
</br>
|
||||
**配置队伍**</br>
|
||||
配置默认 行走队</br>
|
||||
队伍配置 实例语法对应映射: 矿物,火,水,风,雷,草,冰,岩 </br>
|
||||
队伍配置 实例语法: 矿采集,水火风雷,水火风雷,水火风雷,元素,矿采集 </br>
|
||||
没有可留空 如 矿采集,,,,,矿采集</br>
|
||||
**锄地队伍配置**</br>
|
||||
实例语法: 敌人与魔物->发条机关=速通,..... (还不清楚的看`锄地队伍配置图映射`)</br>
|
||||
</br>
|
||||
**`锄地队伍配置图映射`**</br>
|
||||
</br>
|
||||
**`选中执行组`**</br>
|
||||
多选项 为或关系 </br>
|
||||
如选中 地方特产的璃月 和 璃月的石珀 会执行 地方特产的璃月下所有的路径</br>
|
||||
如需要指定 请勿选中上级目录 璃月的石珀(3级路径)->地方特产的璃月(2级路径) </br>
|
||||
如图选中下3级路径时不要选中对应的2级路径</br>
|
||||
</br>
|
||||
</br>
|
||||
- 3.高级配置请继续查看文档后续
|
||||
### 核心亮点(最新版)
|
||||
|
||||
- **路径扫描全面重构**:支持任意层级目录,父子关系清晰,性能稳定
|
||||
- **按 UID 缓存路径列表**(`path-json-by-uid.json`),多账号切换极快
|
||||
- 小时制 & Cron 双冷却系统(需搭配 bettergi-scripts-tools)
|
||||
- 智能队伍切换(战斗/七元素)
|
||||
- 实时任务:自动对话跳过、自动拾取、自动战斗
|
||||
- 择优执行 + 执行记录 + 错误路径追踪
|
||||
- 半自动快捷键干预(继续/跳过)
|
||||
- 开发者模式 + 详细日志 + UID自动识别
|
||||
|
||||
## 文件结构一览
|
||||
|
||||
```
|
||||
FullyAutoAndSemiAutoTools/
|
||||
├── config/
|
||||
│ ├── SevenElement.json # 七元素路径→队伍映射
|
||||
│ ├── cd-pathing.json # 路径冷却规则(hours/cron)
|
||||
│ ├── record.json # 本次执行记录
|
||||
│ ├── PathRecord.json # 历史路径执行记录
|
||||
│ ├── uidSettings.json # 用户配置快照(多UID支持)
|
||||
│ ├── path-json-by-uid.json # 按UID缓存的路径JSON列表
|
||||
│ └── RefreshSettings.json # 刷新配置缓存(可选)
|
||||
├── utils/
|
||||
│ ├── SwitchTeam.js # 队伍切换核心
|
||||
│ ├── cron.js # Cron 解析工具
|
||||
│ └── uid.js # UID 识别模块
|
||||
├── pathing/ # ★ 所有路径文件目录(需符号链接)
|
||||
├── SymLink.bat # 一键创建 pathing 链接
|
||||
├── main.js # 主程序入口(已重构路径扫描)
|
||||
├── manifest.json # 脚本元信息 & 版本标识
|
||||
└── settings.json # 配置模板(用户界面依据)
|
||||
```
|
||||
|
||||
## 核心流程图
|
||||
|
||||
### 1. 整体流程图(graph TD 风格,适合看结构与分支)
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
A[启动脚本] --> B[读取 config_run]
|
||||
|
||||
B --> C{config_run ?}
|
||||
|
||||
%% ────────────── 刷新模式 ──────────────
|
||||
C -->|刷新| Refresh[刷新模式]
|
||||
|
||||
Refresh --> Scan[扫描 pathing 目录<br>readPaths 递归读取所有文件/文件夹]
|
||||
|
||||
Scan --> Depth[应用 loading_level<br>限制最大递归深度]
|
||||
|
||||
Depth --> BlackWhite[应用黑白名单过滤<br>config_white_list / config_black_list<br>(优先级高于其他过滤)]
|
||||
|
||||
BlackWhite --> Generate[生成 multi-checkbox 配置项<br>写入 uidSettings.json<br>写入 path-json-by-uid.json<br>(此时黑白名单已生效)]
|
||||
|
||||
Generate --> RefreshEnd[刷新结束<br>黑白名单已固化到缓存中]
|
||||
|
||||
%% ────────────── 加载模式 ──────────────
|
||||
C -->|加载| Load[加载模式]
|
||||
|
||||
Load --> ReadCache[读取上次缓存<br>path-json-by-uid.json + uidSettings.json<br>(已包含刷新时的黑白名单过滤结果)]
|
||||
|
||||
ReadCache --> LoadFilter{二次过滤项}
|
||||
|
||||
LoadFilter --> TheLayer[the_layer = true ?<br>只保留指定层级]
|
||||
|
||||
LoadFilter --> HighFilter[high_level_filtering 有值 ?<br>路径字符串匹配过滤]
|
||||
|
||||
LoadFilter --> BlackWhiteLoad[黑白名单输入框显示<br>但修改无效<br>(不重新过滤缓存)]
|
||||
|
||||
TheLayer & HighFilter --> ShowOptions[显示最终过滤后的选项列表<br>供用户勾选]
|
||||
|
||||
BlackWhiteLoad -.-> ShowOptions[黑白名单修改不生效]
|
||||
|
||||
ShowOptions --> LoadEnd[加载结束<br>黑白名单不参与二次过滤]
|
||||
|
||||
%% ────────────── 执行模式 ──────────────
|
||||
C -->|执行| Exec[执行模式<br>不显示黑白名单 / 层级 / 高阶过滤项<br>直接使用已勾选路径]
|
||||
|
||||
Exec --> Run[读取 CD + 记录<br>构建 needRunMap → 执行]
|
||||
|
||||
%% 样式
|
||||
classDef refresh fill:#e8f5e9,stroke:#2e7d32
|
||||
classDef load fill:#e3f2fd,stroke:#1976d2
|
||||
classDef exec fill:#f3e5f5,stroke:#7b1fa2
|
||||
classDef filter fill:#fff3e0,stroke:#ef6c00,stroke-width:2px
|
||||
|
||||
class Refresh,Scan,Depth,BlackWhite,Generate refresh
|
||||
class Load,ReadCache,TheLayer,HighFilter,BlackWhiteLoad,ShowOptions load
|
||||
class Exec,Run exec
|
||||
class BlackWhite,TheLayer,HighFilter filter
|
||||
```
|
||||
|
||||
### 2. 执行时序图(sequenceDiagram 风格,适合看交互顺序)
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant U as 用户
|
||||
participant UI as 设置界面
|
||||
participant S as 扫描 & 缓存模块
|
||||
participant F as 过滤逻辑
|
||||
participant R as 记录/缓存文件<br>(uidSettings.json + path-json-by-uid.json)
|
||||
participant CD as 冷却检查
|
||||
participant E as 执行引擎
|
||||
participant T as 队伍切换
|
||||
participant P as 路径执行
|
||||
|
||||
U->>UI: 选择 config_run 并保存
|
||||
|
||||
alt config_run = 刷新
|
||||
UI->>S: 开始刷新(重新扫描 pathing 目录)
|
||||
S->>F: 读取 loading_level
|
||||
F-->>S: 限制递归深度
|
||||
S->>F: 读取黑白名单
|
||||
F-->>S: 过滤掉黑名单文件夹,保留白名单优先
|
||||
Note over S,F: the_layer 与 high_level_filtering<br>在本模式不参与过滤
|
||||
S->>R: 写入完整过滤后的路径列表 & 配置快照
|
||||
R-->>UI: 刷新完成,显示新生成的选项列表
|
||||
else config_run = 加载
|
||||
UI->>R: 请求读取上次缓存
|
||||
R-->>UI: 返回已缓存的路径列表<br>(已包含刷新时的黑白名单结果)
|
||||
UI->>F: 显示 the_layer / high_level_filtering / loading_level 输入框
|
||||
Note over UI,F: 黑白名单输入框显示,但修改无效
|
||||
alt 用户修改了 the_layer 或 high_level_filtering
|
||||
F->>F: 对缓存列表进行二次过滤
|
||||
F-->>UI: 显示过滤后的选项列表
|
||||
else 未修改或修改了黑白名单
|
||||
F-->>UI: 沿用原缓存列表<br>(黑白名单修改被忽略)
|
||||
end
|
||||
UI-->>U: 显示可勾选的路径组
|
||||
else config_run = 执行
|
||||
UI->>R: 读取用户已勾选的路径组 & 配置
|
||||
R-->>UI: 返回最终待执行列表
|
||||
Note over UI,R: 此时所有层级/过滤/黑白名单配置已固化<br>不再受任何影响
|
||||
UI->>CD: 检查冷却规则(hours / cron)
|
||||
CD-->>UI: 过滤掉仍在CD的路径组
|
||||
UI->>E: 开始执行(needRunMap)
|
||||
loop 遍历每个路径组
|
||||
E->>T: 根据路径特性决定队伍
|
||||
alt 需要战斗 / 元素 / 锄地特化
|
||||
T->>T: switchTeamByName / switchTeamByIndex
|
||||
end
|
||||
T-->>E: 队伍就位
|
||||
alt 半自动模式
|
||||
E->>U: 等待快捷键(继续/跳过)
|
||||
U-->>E: 按键响应
|
||||
end
|
||||
E->>P: pathingScript.runFile(路径)
|
||||
P-->>E: 执行完成 / 异常
|
||||
E->>R: 记录执行结果(成功/失败/时间戳)
|
||||
end
|
||||
R-->>UI: 保存最终记录
|
||||
UI-->>U: 执行完成
|
||||
end
|
||||
```
|
||||
|
||||
## 重要配置项一览(settings.json)
|
||||
|
||||
| 配置项 | 类型 | 主要作用 | 推荐默认/示例 |
|
||||
|---------------------|-----|-------------------------------------------------------------------|----------------------------------------------|
|
||||
| config_uid | 复选框 | 当前配置uid:{无}(仅仅显示配置uid无其他作用) | xxx |
|
||||
| key | 文本 | 脚本密钥 | xxx |
|
||||
| config_run | 下拉 | 运行模式:刷新 / 加载 / 执行 | 刷新 → 首次,加载 → 日常 |
|
||||
| refresh_record | 复选框 | 配置模式-刷新-清空运行记录 | |
|
||||
| refresh_record_mode | 下拉 | 清空运行记录模式 全部 | UID | |
|
||||
| high_level_filtering | 文本 | 高阶过滤 | |
|
||||
| loading_level | 文本 | 路径层级深度(≥1,实际支持更高深度) | 2 或 3 |
|
||||
| the_layer | 复选框 | 只加载指定层级 | |
|
||||
| order_rules | 文本 | 执行顺序规则(可留空)<br>语法:父文件夹名称->文件夹名称=顺序整数,...<br>示例:食材与炼金->晶蝶=1, | ""(默认按扫描顺序)或 "食材与炼金->晶蝶=1,pathing->地方特产=2" |
|
||||
| open_limit_max | 复选框 | 开启执行组最大路径数配置 | |
|
||||
| limit_max_group | 文本 | 配置执行组最大路径数(可留空)<br>语法:父文件夹名称->文件夹名称=最大路径数,...<br>示例:食材与炼金->晶蝶=50, | ""(默认按扫描顺序)或 "食材与炼金->晶蝶=50,pathing->地方特产=50" |
|
||||
| config_white_list | 文本 | 白名单(逗号分隔) | 晶蝶,特产 |
|
||||
| config_black_list | 文本 | 黑名单(优先级更高) | 其他,锄地专区,周本 |
|
||||
| open_cd | 复选框 | 启用冷却控制 | 建议开启 |
|
||||
| http_api | 文本 | Cron 解析服务地址 | http://127.0.0.1:8081/... |
|
||||
| real_time_missions | 多选 | 实时辅助(对话/战斗/拾取) | 至少开「自动拾取」 |
|
||||
| choose_best | 复选框 | 择优模式(优先未跑/最久未跑路径) | 推荐开启 |
|
||||
| mode | 下拉 | 全自动 / 半自动 | 全自动(日常) |
|
||||
| auto_semi_key_mode | 下拉 | 半自动快捷键行为(继续/跳过) | 继续运行 |
|
||||
| auto_key | 文本 | 半自动干预快捷键 | F10 / F11(避免冲突) |
|
||||
| team_fight | 文本 | 通用行走队伍名称 | 必须填写 |
|
||||
| team_hoe_ground | 文本 | 锄地特化队伍配置(语法:父文件夹->子文件夹=队伍名,...) | 敌人与魔物->蕈兽=蕈兽队 |
|
||||
| team_seven_elements | 文本 | 七元素队伍(矿物,火,水,风,雷,草,冰,岩) | 按顺序填写 |
|
||||
| is_debug | 复选框 | 开发者模式(详细日志) | 调试时开启 |
|
||||
|
||||
|
||||
|
||||
## 语法说明
|
||||
- high_level_filtering 高阶过滤
|
||||
```text
|
||||
语法:xxx->xxx-> ..... 无限制
|
||||
|
||||
实例:pathing\地方特产\
|
||||
语法:地方特产
|
||||
实例:pathing\地方特产\枫丹\
|
||||
语法:地方特产->枫丹
|
||||
实例:pathing\地方特产\枫丹\幽光星星\
|
||||
语法:地方特产->枫丹->幽光星星
|
||||
实例:pathing\地方特产\枫丹\幽光星星\幽光星星@jbcaaa\
|
||||
语法:地方特产->枫丹->幽光星星->幽光星星@jbcaaa
|
||||
```
|
||||
- 以下语法风格请保持一致 ,否则会导致路径会出现异常运行 如使用 地产->nam=1 同时保持 地产->nam=队伍名1 则路径会出现异常运行
|
||||
- order_rules 执行顺序规则
|
||||
1. `rootName` 根目录下层文件夹名称,`parentName` 父目录名称,`name` 文件夹名称
|
||||
2. 建议语法:`rootName->parentName->name=1,rootName->parentName->name2=2`
|
||||
3. `rootName=parentName`时 语法`rootName->parentName->name=1`不可用, 请使用 `parentName->name=1` 语法
|
||||
4. `rootName->name=1` 语法不支持
|
||||
5. 匹配精度:`rootName->parentName->name` > `parentName->name` > 默认顺序
|
||||
- team_hoe_ground 锄地特化队伍配置
|
||||
1. `rootName` 根目录下层文件夹名称,`parentName` 父目录名称,`name` 文件夹名称
|
||||
2. 建议语法:`rootName->parentName->name=队伍名,rootName->parentName->name2=队伍名`
|
||||
3. `rootName=parentName`时 语法`rootName->parentName->name=队伍名`不可用, 请使用 `parentName->name=队伍名` 语法
|
||||
4. `rootName->name=队伍名` 语法不支持
|
||||
5. 匹配精度:`rootName->parentName->name` > `parentName->name` > 默认顺序
|
||||
- limit_max_group 配置执行组最大路径数
|
||||
1. `parentName` 父目录名称,`name` 文件夹名称
|
||||
2. 建议语法:`parentName->name=50,parentName->name2=50`
|
||||
3. 匹配精度: `parentName->name` > 默认顺序
|
||||
## (可选)额外json配置
|
||||
|
||||
### 配置项order_rules
|
||||
|
||||
路径:config/PathOrder.json
|
||||
order值越大优先级越高 `公共配置 锄地模块排序未配置 希望好心人完善 预留order 900~700`
|
||||
```json
|
||||
[
|
||||
{
|
||||
"uid": "",
|
||||
//账号UID
|
||||
"is_common": false,
|
||||
//是否为公共配置
|
||||
"root_name": "",
|
||||
//根文件夹下对应的文件夹名称
|
||||
"parent_name": "",
|
||||
//父文件夹名称
|
||||
"name": "",
|
||||
//文件夹名称
|
||||
"order": 0
|
||||
//顺序
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
### 配置项team_hoe_ground
|
||||
|
||||
路径:config/HoeGround.json
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"uid": "",
|
||||
//账号UID
|
||||
"is_common": false,
|
||||
//是否为公共配置
|
||||
"root_name": "",
|
||||
//根文件夹下对应的文件夹名称
|
||||
"parent_name": "",
|
||||
//父文件夹名称
|
||||
"name": "",
|
||||
//文件夹名称
|
||||
"team_name": ""
|
||||
//队伍名称
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
## CD 规则示例(cd-pathing.json)
|
||||
level值越大优先级越高
|
||||
```json
|
||||
[
|
||||
{
|
||||
"name": "晶蝶",
|
||||
"type": "hours",
|
||||
"level": 2,
|
||||
"value": 12
|
||||
},
|
||||
{
|
||||
"name": "地方特产",
|
||||
"type": "hours",
|
||||
"level": 1,
|
||||
"value": 46
|
||||
},
|
||||
{
|
||||
"name": "矿物",
|
||||
"type": "cron",
|
||||
"level": 1,
|
||||
"value": "0 0 0 1/3 * ?"
|
||||
}
|
||||
]
|
||||
```
|
||||
## 运行实例部分日志
|
||||
实例==>运行矿物 大类 虹滴晶 运行完成 再次运行 日志截图展示:
|
||||

|
||||
## Cron 解析服务部署(必须)
|
||||
|
||||
**bettergi-scripts-tools** 是 Cron 解析的必要依赖,请至少选择一种方式部署:
|
||||
> bettergi-scripts-tools 版本需要 v0.0.3
|
||||
### 1. Windows 一键运行
|
||||
|
||||
下载 [release](https://github.com/Kirito520Asuna/bettergi-scripts-tools/releases) 中的 windows zip 包 → 解压 → 双击 .exe
|
||||
运行
|
||||
|
||||
### 2. Java 运行
|
||||
|
||||
下载 jar 包 → 执行:
|
||||
|
||||
```bash
|
||||
java -jar bettergi-scripts-tools-xxxx.jar
|
||||
```
|
||||
|
||||
### 3. Docker 部署
|
||||
|
||||
```bash
|
||||
docker pull ghcr.io/kirito520asuna/bettergi-scripts-tools:latest
|
||||
docker run -d -p 8081:8081 --name bettergi-scripts-tools ghcr.io/kirito520asuna/bettergi-scripts-tools:latest
|
||||
```
|
||||
|
||||
**默认 API 地址**:`http://127.0.0.1:8081/bgi/cron/next-timestamp/all`
|
||||
|
||||
## 推荐使用流程
|
||||
|
||||
1. 双击 `SymLink.bat` 创建 pathing 链接
|
||||
2. 首次运行强烈建议先「刷新」一次(生成 path-json-by-uid.json 缓存)
|
||||
3. 日常使用「加载」模式 → 快速恢复配置 & 路径列表
|
||||
4. 微调路径组 → 切换「执行」模式 → 一键启动
|
||||
|
||||
**多账号特别友好**:每个 UID 都有独立路径缓存,切换账号无需重复扫描
|
||||
|
||||
## 小技巧与实用建议
|
||||
|
||||
- 最省事组合:全自动 + 择优模式 + 自动拾取 + 冷却控制
|
||||
- 最安全组合:半自动 + 自动拾取 + 详细日志 + 大量黑名单
|
||||
- 路径目录再深也没关系,扫描已支持任意层级
|
||||
- 错误路径反复出现?查看 record.json 加黑名单或修复
|
||||
- 多UID用户:首次每个号都「刷新」一次,建立独立缓存
|
||||
|
||||
## 注意事项
|
||||
|
||||
- 首次使用或升级后建议删除旧 `path-json-by-uid.json` 重新生成
|
||||
- 半自动模式请确保快捷键不与 BetterGI 冲突
|
||||
- Cron 模式必须部署解析服务,否则冷却检查无效
|
||||
- 最低兼容版本:BetterGI 0.54.3+
|
||||
|
||||
## 版本密钥
|
||||
|
||||
| 版本 | 密钥 |
|
||||
|-------|-------------|
|
||||
| 0.0.1 | PGCSBY37NJA |
|
||||
|
||||
## 版本历史(简要)
|
||||
|
||||
### 0.0.1 2026.01.30
|
||||
|
||||
基本功能完成
|
||||
|
||||
**作者**:云端客 (Kirito520Asuna)
|
||||
|
||||
祝你使用愉快,素材永远收不完~✨
|
||||
12
repo/js/FullyAutoAndSemiAutoTools/SymLink.bat
Normal file
@@ -0,0 +1,12 @@
|
||||
@REM @echo off
|
||||
set "target1=..\..\AutoPathing"
|
||||
set "target2=..\..\pathing"
|
||||
|
||||
if exist "%target1%" (
|
||||
mklink /j pathing "%target1%"
|
||||
) else if exist "%target2%" (
|
||||
mklink /j pathing "%target2%"
|
||||
) else (
|
||||
echo ERROR: Can't find folder "%target1%" or "%target2%"
|
||||
pause
|
||||
)
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 2.0 KiB |
BIN
repo/js/FullyAutoAndSemiAutoTools/assets/Leave Button.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
repo/js/FullyAutoAndSemiAutoTools/assets/Quick Setup Button.png
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
BIN
repo/js/FullyAutoAndSemiAutoTools/assets/Slider Bottom.png
Normal file
|
After Width: | Height: | Size: 307 B |
BIN
repo/js/FullyAutoAndSemiAutoTools/assets/Slider Top.png
Normal file
|
After Width: | Height: | Size: 517 B |
BIN
repo/js/FullyAutoAndSemiAutoTools/assets/paimon_menu.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
114
repo/js/FullyAutoAndSemiAutoTools/config/LimitMax.json
Normal file
@@ -0,0 +1,114 @@
|
||||
[
|
||||
{
|
||||
"uid": "",
|
||||
"is_common": true,
|
||||
"root_name": "矿物",
|
||||
"parent_name": "矿物",
|
||||
"name": "虹滴晶",
|
||||
"max": 50
|
||||
},
|
||||
{
|
||||
"uid": "",
|
||||
"is_common": true,
|
||||
"root_name": "矿物",
|
||||
"parent_name": "矿物",
|
||||
"name": "萃凝晶",
|
||||
"max": 60
|
||||
},
|
||||
{
|
||||
"uid": "",
|
||||
"is_common": true,
|
||||
"root_name": "矿物",
|
||||
"parent_name": "矿物",
|
||||
"name": "紫晶块",
|
||||
"max": 50
|
||||
},
|
||||
{
|
||||
"uid": "",
|
||||
"is_common": true,
|
||||
"root_name": "矿物",
|
||||
"parent_name": "矿物",
|
||||
"name": "水晶块",
|
||||
"max": 50
|
||||
},
|
||||
{
|
||||
"uid": "",
|
||||
"is_common": true,
|
||||
"root_name": "",
|
||||
"parent_name": "紫晶块",
|
||||
"name": "紫晶块[大剑]@蜜柑魚",
|
||||
"max": 25
|
||||
},
|
||||
{
|
||||
"uid": "",
|
||||
"is_common": true,
|
||||
"root_name": "",
|
||||
"parent_name": "紫晶块",
|
||||
"name": "紫晶块[钟离版]@mfkvfhpdx",
|
||||
"max": 25
|
||||
},
|
||||
{
|
||||
"uid": "",
|
||||
"is_common": true,
|
||||
"root_name": "",
|
||||
"parent_name": "萃凝晶",
|
||||
"name": "萃凝晶-火神赶路-大剑@无限不循环",
|
||||
"max": 30
|
||||
},
|
||||
{
|
||||
"uid": "",
|
||||
"is_common": true,
|
||||
"root_name": "",
|
||||
"parent_name": "萃凝晶",
|
||||
"name": "纳塔[钟离版]@成成",
|
||||
"max": 10
|
||||
},
|
||||
{
|
||||
"uid": "",
|
||||
"is_common": true,
|
||||
"root_name": "",
|
||||
"parent_name": "萃凝晶",
|
||||
"name": "枫丹水下@芝士贝果",
|
||||
"max": 10
|
||||
},
|
||||
{
|
||||
"uid": "",
|
||||
"is_common": true,
|
||||
"root_name": "",
|
||||
"parent_name": "萃凝晶",
|
||||
"name": "枫丹[钟离版]@cy",
|
||||
"max": 10
|
||||
},
|
||||
{
|
||||
"uid": "",
|
||||
"is_common": true,
|
||||
"root_name": "",
|
||||
"parent_name": "水晶块",
|
||||
"name": "水晶块@忆雪晴",
|
||||
"max": 20
|
||||
},
|
||||
{
|
||||
"uid": "",
|
||||
"is_common": true,
|
||||
"root_name": "",
|
||||
"parent_name": "水晶块",
|
||||
"name": "水晶块[大剑]@火山@芝士贝果",
|
||||
"max": 20
|
||||
},
|
||||
{
|
||||
"uid": "",
|
||||
"is_common": true,
|
||||
"root_name": "",
|
||||
"parent_name": "水晶块",
|
||||
"name": "水晶块[钟离版]@愚溪",
|
||||
"max": 10
|
||||
},
|
||||
{
|
||||
"uid": "",
|
||||
"is_common": true,
|
||||
"root_name": "",
|
||||
"parent_name": "白铁块",
|
||||
"name": "富集路线@Tool_tingsu",
|
||||
"max": 15
|
||||
}
|
||||
]
|
||||
106
repo/js/FullyAutoAndSemiAutoTools/config/PathOrder.json
Normal file
@@ -0,0 +1,106 @@
|
||||
[
|
||||
{
|
||||
"uid": "",
|
||||
"is_common": true,
|
||||
"root_name": "地方特产",
|
||||
"parent_name": "地方特产",
|
||||
"name": "挪德卡莱",
|
||||
"order": 980
|
||||
},
|
||||
{
|
||||
"uid": "",
|
||||
"is_common": true,
|
||||
"root_name": "地方特产",
|
||||
"parent_name": "地方特产",
|
||||
"name": "纳塔",
|
||||
"order": 979
|
||||
},
|
||||
{
|
||||
"uid": "",
|
||||
"is_common": true,
|
||||
"root_name": "地方特产",
|
||||
"parent_name": "地方特产",
|
||||
"name": "枫丹",
|
||||
"order": 978
|
||||
},
|
||||
{
|
||||
"uid": "",
|
||||
"is_common": true,
|
||||
"root_name": "地方特产",
|
||||
"parent_name": "地方特产",
|
||||
"name": "须弥",
|
||||
"order": 977
|
||||
},
|
||||
{
|
||||
"uid": "",
|
||||
"is_common": true,
|
||||
"root_name": "地方特产",
|
||||
"parent_name": "地方特产",
|
||||
"name": "稻妻",
|
||||
"order": 976
|
||||
},
|
||||
{
|
||||
"uid": "",
|
||||
"is_common": true,
|
||||
"root_name": "地方特产",
|
||||
"parent_name": "地方特产",
|
||||
"name": "璃月",
|
||||
"order": 975
|
||||
},
|
||||
{
|
||||
"uid": "",
|
||||
"is_common": true,
|
||||
"root_name": "地方特产",
|
||||
"parent_name": "地方特产",
|
||||
"name": "蒙德",
|
||||
"order": 974
|
||||
},
|
||||
{
|
||||
"uid": "",
|
||||
"is_common": true,
|
||||
"root_name": "矿物",
|
||||
"parent_name": "矿物",
|
||||
"name": "虹滴晶",
|
||||
"order": 940
|
||||
},
|
||||
{
|
||||
"uid": "",
|
||||
"is_common": true,
|
||||
"root_name": "矿物",
|
||||
"parent_name": "矿物",
|
||||
"name": "萃凝晶",
|
||||
"order": 939
|
||||
},
|
||||
{
|
||||
"uid": "",
|
||||
"is_common": true,
|
||||
"root_name": "矿物",
|
||||
"parent_name": "矿物",
|
||||
"name": "紫晶块",
|
||||
"order": 938
|
||||
},
|
||||
{
|
||||
"uid": "",
|
||||
"is_common": true,
|
||||
"root_name": "矿物",
|
||||
"parent_name": "矿物",
|
||||
"name": "水晶块",
|
||||
"order": 937
|
||||
},
|
||||
{
|
||||
"uid": "",
|
||||
"is_common": true,
|
||||
"root_name": "矿物",
|
||||
"parent_name": "矿物",
|
||||
"name": "星银矿石",
|
||||
"order": 936
|
||||
},
|
||||
{
|
||||
"uid": "",
|
||||
"is_common": true,
|
||||
"root_name": "矿物",
|
||||
"parent_name": "矿物",
|
||||
"name": "白铁块",
|
||||
"order": 935
|
||||
}
|
||||
]
|
||||
42
repo/js/FullyAutoAndSemiAutoTools/config/SevenElement.json
Normal file
@@ -0,0 +1,42 @@
|
||||
[
|
||||
{
|
||||
"name": "矿物",
|
||||
"level": 0,
|
||||
"value": ["夜泊石", "石珀", "清水玉", "万相石", "矿物"]
|
||||
},
|
||||
{
|
||||
"name": "火",
|
||||
"level": 1,
|
||||
"value": []
|
||||
},
|
||||
{
|
||||
"name": "水",
|
||||
"level": 2,
|
||||
"value": ["海露花"]
|
||||
},
|
||||
{
|
||||
"name": "风",
|
||||
"level": 3,
|
||||
"value": ["蒲公英籽"]
|
||||
},
|
||||
{
|
||||
"name": "雷",
|
||||
"level": 4,
|
||||
"value": ["琉鳞石", "绯樱绣球"]
|
||||
},
|
||||
{
|
||||
"name": "草",
|
||||
"level": 5,
|
||||
"value": []
|
||||
},
|
||||
{
|
||||
"name": "冰",
|
||||
"level": 6,
|
||||
"value": []
|
||||
},
|
||||
{
|
||||
"name": "岩",
|
||||
"level": 7,
|
||||
"value": []
|
||||
}
|
||||
]
|
||||
134
repo/js/FullyAutoAndSemiAutoTools/config/cd-pathing.json
Normal file
@@ -0,0 +1,134 @@
|
||||
[
|
||||
{
|
||||
"name": "地方特产",
|
||||
"type": "hours",
|
||||
"level": 1,
|
||||
"value": 46
|
||||
},
|
||||
{
|
||||
"name": "星银矿石",
|
||||
"type": "cron",
|
||||
"level": 2,
|
||||
"value": "0 0 0 1/2 * ?"
|
||||
},
|
||||
{
|
||||
"name": "白铁块",
|
||||
"type": "cron",
|
||||
"level": 2,
|
||||
"value": "0 0 0 1/2 * ?"
|
||||
},
|
||||
{
|
||||
"name": "矿物",
|
||||
"type": "cron",
|
||||
"level": 1,
|
||||
"value": "0 0 0 1/3 * ?"
|
||||
},
|
||||
{
|
||||
"name": "晶蝶",
|
||||
"type": "hours",
|
||||
"level": 2,
|
||||
"value": 12
|
||||
},
|
||||
{
|
||||
"name": "「冷鲜肉」",
|
||||
"type": "hours",
|
||||
"level": 2,
|
||||
"value": "12"
|
||||
},
|
||||
{
|
||||
"name": "发光髓",
|
||||
"type": "hours",
|
||||
"level": 2,
|
||||
"value": "12"
|
||||
},
|
||||
{
|
||||
"name": "鳅鳅宝玉",
|
||||
"type": "hours",
|
||||
"level": 2,
|
||||
"value": "12"
|
||||
},
|
||||
{
|
||||
"name": "青蛙",
|
||||
"type": "hours",
|
||||
"level": 2,
|
||||
"value": "12"
|
||||
},
|
||||
{
|
||||
"name": "鳗肉",
|
||||
"type": "hours",
|
||||
"level": 2,
|
||||
"value": "12"
|
||||
},
|
||||
{
|
||||
"name": "螃蟹",
|
||||
"type": "hours",
|
||||
"level": 2,
|
||||
"value": "12"
|
||||
},
|
||||
{
|
||||
"name": "禽肉",
|
||||
"type": "hours",
|
||||
"level": 2,
|
||||
"value": "12"
|
||||
},
|
||||
{
|
||||
"name": "蜥蜴尾巴",
|
||||
"type": "hours",
|
||||
"level": 2,
|
||||
"value": "12"
|
||||
},
|
||||
{
|
||||
"name": "兽肉",
|
||||
"type": "hours",
|
||||
"level": 2,
|
||||
"value": "12"
|
||||
},
|
||||
{
|
||||
"name": "沉玉仙茗",
|
||||
"type": "hours",
|
||||
"level": 2,
|
||||
"value": "24"
|
||||
},
|
||||
{
|
||||
"name": "冰雾花花朵",
|
||||
"type": "hours",
|
||||
"level": 2,
|
||||
"value": "46"
|
||||
},
|
||||
{
|
||||
"name": "奇异的「牙齿」",
|
||||
"type": "hours",
|
||||
"level": 2,
|
||||
"value": "46"
|
||||
},
|
||||
{
|
||||
"name": "烈焰花花蕊",
|
||||
"type": "hours",
|
||||
"level": 2,
|
||||
"value": "46"
|
||||
},
|
||||
{
|
||||
"name": "电气水晶",
|
||||
"type": "cron",
|
||||
"level": 2,
|
||||
"value": "0 0 0 1/2 * ?"
|
||||
},
|
||||
{
|
||||
"name": "食材与炼金",
|
||||
"type": "cron",
|
||||
"level": 1,
|
||||
"value": "0 0 0 1/1 * ?"
|
||||
},
|
||||
{
|
||||
"name": "敌人与魔物",
|
||||
"type": "cron",
|
||||
"level": 1,
|
||||
"value": "0 0 4 1/1 * ?"
|
||||
},
|
||||
{
|
||||
"name": "锄地专区",
|
||||
"type": "cron",
|
||||
"level": 1,
|
||||
"value": "0 0 4 1/1 * ?"
|
||||
}
|
||||
]
|
||||
199
repo/js/FullyAutoAndSemiAutoTools/config/settings.json
Normal file
@@ -0,0 +1,199 @@
|
||||
[
|
||||
{
|
||||
"name": "config_uid",
|
||||
"type": "checkbox",
|
||||
"label": "当前配置uid:{无}\n(仅仅显示配置uid无其他作用)",
|
||||
"default": false
|
||||
},
|
||||
{
|
||||
"type": "separator"
|
||||
},
|
||||
{
|
||||
"name": "key",
|
||||
"type": "input-text",
|
||||
"label": "密钥",
|
||||
"default": ""
|
||||
},
|
||||
{
|
||||
"type": "separator"
|
||||
},
|
||||
{
|
||||
"name": "config_run",
|
||||
"type": "select",
|
||||
"label": "配置模式",
|
||||
"options": [
|
||||
"刷新",
|
||||
"加载",
|
||||
"执行"
|
||||
],
|
||||
"default": "刷新"
|
||||
},
|
||||
{
|
||||
"name": "refresh_record",
|
||||
"type": "checkbox",
|
||||
"label": "配置模式-刷新-清空运行记录",
|
||||
"default": false
|
||||
},
|
||||
{
|
||||
"name": "refresh_record_mode",
|
||||
"type": "select",
|
||||
"label": "清空运行记录模式",
|
||||
"options": [
|
||||
"全部",
|
||||
"UID"
|
||||
],
|
||||
"default": "UID"
|
||||
},
|
||||
{
|
||||
"name": "loading_level",
|
||||
"type": "input-text",
|
||||
"label": "加载路径层级(不可小于1)<配置模式 刷新||加载 生效>",
|
||||
"default": "2"
|
||||
},
|
||||
{
|
||||
"name": "the_layer",
|
||||
"type": "checkbox",
|
||||
"label": "只加载指定层级<配置模式 加载 生效>",
|
||||
"default": false
|
||||
},
|
||||
{
|
||||
"name": "high_level_filtering",
|
||||
"type": "input-text",
|
||||
"label": "高阶过滤{语法看文档}<配置模式 加载 生效>",
|
||||
"default": ""
|
||||
},
|
||||
{
|
||||
"name": "order_rules",
|
||||
"type": "input-text",
|
||||
"label": "执行顺序规则(可留空)\n{语法:父文件夹名称->文件夹名称=顺序请填整数,.....}",
|
||||
"default": ""
|
||||
},
|
||||
{
|
||||
"type": "separator"
|
||||
},
|
||||
{
|
||||
"name": "config_white_list",
|
||||
"type": "input-text",
|
||||
"label": "刷新白名单 以,分割",
|
||||
"default": "晶蝶"
|
||||
},
|
||||
{
|
||||
"name": "config_black_list",
|
||||
"type": "input-text",
|
||||
"label": "刷新黑名单 以,分割",
|
||||
"default": "其他,锄地专区,食材与炼金"
|
||||
},
|
||||
{
|
||||
"type": "separator"
|
||||
},
|
||||
{
|
||||
"name": "open_cd",
|
||||
"type": "checkbox",
|
||||
"label": "启用CD算法",
|
||||
"default": false
|
||||
},
|
||||
{
|
||||
"name": "http_api",
|
||||
"type": "input-text",
|
||||
"label": "[默认CD算法api]\ncron解析Http地址\n[请部署bettergi-scripts-tools可支持]",
|
||||
"default": "http://<ip:port>/bgi/cron/next-timestamp/all"
|
||||
},
|
||||
{
|
||||
"type": "separator"
|
||||
},
|
||||
{
|
||||
"name": "real_time_missions",
|
||||
"type": "multi-checkbox",
|
||||
"label": "实时任务",
|
||||
"options": [
|
||||
"自动对话",
|
||||
"自动战斗(已弃用)",
|
||||
"自动拾取"
|
||||
],
|
||||
"default": [
|
||||
"自动拾取"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "separator"
|
||||
},
|
||||
{
|
||||
"name": "choose_best",
|
||||
"type": "checkbox",
|
||||
"label": "择优模式(默认关闭 优先跑之前没跑过的)",
|
||||
"default": false
|
||||
},
|
||||
{
|
||||
"name": "mode",
|
||||
"type": "select",
|
||||
"label": "模式",
|
||||
"options": [
|
||||
"全自动",
|
||||
"半自动"
|
||||
],
|
||||
"default": "全自动"
|
||||
},
|
||||
{
|
||||
"name": "auto_semi_key_mode",
|
||||
"type": "select",
|
||||
"label": "[半自动]快捷键模式",
|
||||
"options": [
|
||||
"继续运行",
|
||||
"跳过"
|
||||
],
|
||||
"default": "继续运行"
|
||||
},
|
||||
{
|
||||
"name": "auto_key",
|
||||
"type": "input-text",
|
||||
"label": "<继续运行|跳过>本次路线快捷键 (独立BGI的快捷键请勿冲突)"
|
||||
},
|
||||
{
|
||||
"type": "separator"
|
||||
},
|
||||
{
|
||||
"name": "open_limit_max",
|
||||
"type": "checkbox",
|
||||
"label": "开启执行组最大路径设置"
|
||||
},
|
||||
{
|
||||
"name": "limit_max_group",
|
||||
"type": "input-text",
|
||||
"label": "配置执行组最大路径数\n{语法:父文件夹名称->文件夹名称=最大路径数,.....}\n如:敌人与魔物->蕈兽=50",
|
||||
"default": ""
|
||||
},
|
||||
{
|
||||
"type": "separator"
|
||||
},
|
||||
{
|
||||
"name": "team_fight",
|
||||
"type": "input-text",
|
||||
"label": "战斗队伍配置(同时也是行走队伍配置)\n已禁用战斗检测,战斗队伍配置失效\n只留行走队伍配置"
|
||||
},
|
||||
{
|
||||
"name": "team_hoe_ground",
|
||||
"type": "input-text",
|
||||
"label": "锄地队伍配置\n{语法:父文件夹名称->文件夹名称=队伍名称,.....}\n如:敌人与魔物->蕈兽=队伍名称",
|
||||
"default": ""
|
||||
},
|
||||
{
|
||||
"name": "team_seven_elements",
|
||||
"type": "input-text",
|
||||
"label": "队伍配置 按 `矿物,火,水,风,雷,草,冰,岩` 该顺序填写(建议草神请填至`草`位)",
|
||||
"default": ""
|
||||
},
|
||||
{
|
||||
"type": "separator"
|
||||
},
|
||||
{
|
||||
"name": "is_debug",
|
||||
"type": "checkbox",
|
||||
"label": "开发者模式",
|
||||
"default": false
|
||||
},
|
||||
{
|
||||
"name": "debug",
|
||||
"type": "input-text",
|
||||
"label": "调试快捷键(开发者)"
|
||||
}
|
||||
]
|
||||
2215
repo/js/FullyAutoAndSemiAutoTools/main.js
Normal file
21
repo/js/FullyAutoAndSemiAutoTools/manifest.json
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"manifest_version": 1,
|
||||
"name": "全自动或半自动工具箱",
|
||||
"version": "0.0.1",
|
||||
"bgi_version": "0.54.3",
|
||||
"key": "PGCSBY37NJA",
|
||||
"description": "",
|
||||
"saved_files": [],
|
||||
"authors": [
|
||||
{
|
||||
"name": "云端客",
|
||||
"links": "https://github.com/Kirito520Asuna"
|
||||
}
|
||||
],
|
||||
"http_allowed_urls": [
|
||||
"https://*",
|
||||
"http://*"
|
||||
],
|
||||
"settings_ui": "settings.json",
|
||||
"main": "main.js"
|
||||
}
|
||||
BIN
repo/js/FullyAutoAndSemiAutoTools/md/F-md.jpg
Normal file
|
After Width: | Height: | Size: 603 KiB |
BIN
repo/js/FullyAutoAndSemiAutoTools/md/init-auto.jpg
Normal file
|
After Width: | Height: | Size: 32 KiB |
BIN
repo/js/FullyAutoAndSemiAutoTools/md/init-http.jpg
Normal file
|
After Width: | Height: | Size: 47 KiB |
BIN
repo/js/FullyAutoAndSemiAutoTools/md/init-re.jpg
Normal file
|
After Width: | Height: | Size: 25 KiB |
BIN
repo/js/FullyAutoAndSemiAutoTools/md/init-run-pathing-01.jpg
Normal file
|
After Width: | Height: | Size: 30 KiB |
BIN
repo/js/FullyAutoAndSemiAutoTools/md/init-run-pathing.jpg
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
repo/js/FullyAutoAndSemiAutoTools/md/init-team-map.jpg
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
repo/js/FullyAutoAndSemiAutoTools/md/init-team.jpg
Normal file
|
After Width: | Height: | Size: 36 KiB |
BIN
repo/js/FullyAutoAndSemiAutoTools/md/run-init-01.jpg
Normal file
|
After Width: | Height: | Size: 27 KiB |
BIN
repo/js/FullyAutoAndSemiAutoTools/md/run-init-cd-01.jpg
Normal file
|
After Width: | Height: | Size: 31 KiB |
199
repo/js/FullyAutoAndSemiAutoTools/settings.json
Normal file
@@ -0,0 +1,199 @@
|
||||
[
|
||||
{
|
||||
"name": "config_uid",
|
||||
"type": "checkbox",
|
||||
"label": "当前配置uid:{无}\n(仅仅显示配置uid无其他作用)",
|
||||
"default": false
|
||||
},
|
||||
{
|
||||
"type": "separator"
|
||||
},
|
||||
{
|
||||
"name": "key",
|
||||
"type": "input-text",
|
||||
"label": "密钥",
|
||||
"default": ""
|
||||
},
|
||||
{
|
||||
"type": "separator"
|
||||
},
|
||||
{
|
||||
"name": "config_run",
|
||||
"type": "select",
|
||||
"label": "配置模式",
|
||||
"options": [
|
||||
"刷新",
|
||||
"加载",
|
||||
"执行"
|
||||
],
|
||||
"default": "刷新"
|
||||
},
|
||||
{
|
||||
"name": "refresh_record",
|
||||
"type": "checkbox",
|
||||
"label": "配置模式-刷新-清空运行记录",
|
||||
"default": false
|
||||
},
|
||||
{
|
||||
"name": "refresh_record_mode",
|
||||
"type": "select",
|
||||
"label": "清空运行记录模式",
|
||||
"options": [
|
||||
"全部",
|
||||
"UID"
|
||||
],
|
||||
"default": "UID"
|
||||
},
|
||||
{
|
||||
"name": "loading_level",
|
||||
"type": "input-text",
|
||||
"label": "加载路径层级(不可小于1)<配置模式 刷新||加载 生效>",
|
||||
"default": "2"
|
||||
},
|
||||
{
|
||||
"name": "the_layer",
|
||||
"type": "checkbox",
|
||||
"label": "只加载指定层级<配置模式 加载 生效>",
|
||||
"default": false
|
||||
},
|
||||
{
|
||||
"name": "high_level_filtering",
|
||||
"type": "input-text",
|
||||
"label": "高阶过滤{语法看文档}<配置模式 加载 生效>",
|
||||
"default": ""
|
||||
},
|
||||
{
|
||||
"name": "order_rules",
|
||||
"type": "input-text",
|
||||
"label": "执行顺序规则(可留空)\n{语法:父文件夹名称->文件夹名称=顺序请填整数,.....}",
|
||||
"default": ""
|
||||
},
|
||||
{
|
||||
"type": "separator"
|
||||
},
|
||||
{
|
||||
"name": "config_white_list",
|
||||
"type": "input-text",
|
||||
"label": "刷新白名单 以,分割",
|
||||
"default": "晶蝶"
|
||||
},
|
||||
{
|
||||
"name": "config_black_list",
|
||||
"type": "input-text",
|
||||
"label": "刷新黑名单 以,分割",
|
||||
"default": "其他,锄地专区,食材与炼金"
|
||||
},
|
||||
{
|
||||
"type": "separator"
|
||||
},
|
||||
{
|
||||
"name": "open_cd",
|
||||
"type": "checkbox",
|
||||
"label": "启用CD算法",
|
||||
"default": false
|
||||
},
|
||||
{
|
||||
"name": "http_api",
|
||||
"type": "input-text",
|
||||
"label": "[默认CD算法api]\ncron解析Http地址\n[请部署bettergi-scripts-tools可支持]",
|
||||
"default": "http://<ip:port>/bgi/cron/next-timestamp/all"
|
||||
},
|
||||
{
|
||||
"type": "separator"
|
||||
},
|
||||
{
|
||||
"name": "real_time_missions",
|
||||
"type": "multi-checkbox",
|
||||
"label": "实时任务",
|
||||
"options": [
|
||||
"自动对话",
|
||||
"自动战斗(已弃用)",
|
||||
"自动拾取"
|
||||
],
|
||||
"default": [
|
||||
"自动拾取"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "separator"
|
||||
},
|
||||
{
|
||||
"name": "choose_best",
|
||||
"type": "checkbox",
|
||||
"label": "择优模式(默认关闭 优先跑之前没跑过的)",
|
||||
"default": false
|
||||
},
|
||||
{
|
||||
"name": "mode",
|
||||
"type": "select",
|
||||
"label": "模式",
|
||||
"options": [
|
||||
"全自动",
|
||||
"半自动"
|
||||
],
|
||||
"default": "全自动"
|
||||
},
|
||||
{
|
||||
"name": "auto_semi_key_mode",
|
||||
"type": "select",
|
||||
"label": "[半自动]快捷键模式",
|
||||
"options": [
|
||||
"继续运行",
|
||||
"跳过"
|
||||
],
|
||||
"default": "继续运行"
|
||||
},
|
||||
{
|
||||
"name": "auto_key",
|
||||
"type": "input-text",
|
||||
"label": "<继续运行|跳过>本次路线快捷键 (独立BGI的快捷键请勿冲突)"
|
||||
},
|
||||
{
|
||||
"type": "separator"
|
||||
},
|
||||
{
|
||||
"name": "open_limit_max",
|
||||
"type": "checkbox",
|
||||
"label": "开启执行组最大路径设置"
|
||||
},
|
||||
{
|
||||
"name": "limit_max_group",
|
||||
"type": "input-text",
|
||||
"label": "配置执行组最大路径数\n{语法:父文件夹名称->文件夹名称=最大路径数,.....}\n如:敌人与魔物->蕈兽=50",
|
||||
"default": ""
|
||||
},
|
||||
{
|
||||
"type": "separator"
|
||||
},
|
||||
{
|
||||
"name": "team_fight",
|
||||
"type": "input-text",
|
||||
"label": "战斗队伍配置(同时也是行走队伍配置)\n已禁用战斗检测,战斗队伍配置失效\n只留行走队伍配置"
|
||||
},
|
||||
{
|
||||
"name": "team_hoe_ground",
|
||||
"type": "input-text",
|
||||
"label": "锄地队伍配置\n{语法:父文件夹名称->文件夹名称=队伍名称,.....}\n如:敌人与魔物->蕈兽=队伍名称",
|
||||
"default": ""
|
||||
},
|
||||
{
|
||||
"name": "team_seven_elements",
|
||||
"type": "input-text",
|
||||
"label": "队伍配置 按 `矿物,火,水,风,雷,草,冰,岩` 该顺序填写(建议草神请填至`草`位)",
|
||||
"default": ""
|
||||
},
|
||||
{
|
||||
"type": "separator"
|
||||
},
|
||||
{
|
||||
"name": "is_debug",
|
||||
"type": "checkbox",
|
||||
"label": "开发者模式",
|
||||
"default": false
|
||||
},
|
||||
{
|
||||
"name": "debug",
|
||||
"type": "input-text",
|
||||
"label": "调试快捷键(开发者)"
|
||||
}
|
||||
]
|
||||
211
repo/js/FullyAutoAndSemiAutoTools/utils/SwitchTeam.js
Normal file
@@ -0,0 +1,211 @@
|
||||
// Party Setup
|
||||
const QuickSetupButtonRo = RecognitionObject.TemplateMatch(file.ReadImageMatSync("assets/Quick Setup Button.png"), 1100, 900, 400, 180);
|
||||
const ConfigureTeamButtonRo = RecognitionObject.TemplateMatch(file.ReadImageMatSync("assets/Configure Team Button.png"), 0, 900, 200, 180);
|
||||
const ConfirmDeployButtonRo = RecognitionObject.TemplateMatch(file.ReadImageMatSync("assets/Confirm Deploy Button.png"), 0, 900, 1920, 180);
|
||||
// Slider
|
||||
const LeftSliderTopRo = RecognitionObject.TemplateMatch(file.ReadImageMatSync("assets/Slider Top.png"), 650, 50, 100, 100);
|
||||
const LeftSliderBottomRo = RecognitionObject.TemplateMatch(file.ReadImageMatSync("assets/Slider Bottom.png"), 650, 100, 100, 900);
|
||||
const MiddleSliderTopRo = RecognitionObject.TemplateMatch(file.ReadImageMatSync("assets/Slider Top.png"), 1250, 50, 100, 200);
|
||||
const MiddleSliderBottomRo = RecognitionObject.TemplateMatch(file.ReadImageMatSync("assets/Slider Bottom.png"), 1250, 100, 100, 900);
|
||||
const RightSliderTopRo = RecognitionObject.TemplateMatch(file.ReadImageMatSync("assets/Slider Top.png"), 1750, 100, 100, 100);
|
||||
const RightSliderBottomRo = RecognitionObject.TemplateMatch(file.ReadImageMatSync("assets/Slider Bottom.png"), 1750, 100, 100, 900);
|
||||
|
||||
// 翻页
|
||||
async function pageDown(SliderBottomRo) {
|
||||
let captureRegion = captureGameRegion();
|
||||
let SliderBottom = captureRegion.find(SliderBottomRo);
|
||||
captureRegion.dispose();
|
||||
if (SliderBottom.isExist()) {
|
||||
log.info("当前页面已识别&点击完毕,向下滑动");
|
||||
// log.info("滑块当前位置:({x},{y},{h},{w})", SliderBottom.x, SliderBottom.y, SliderBottom.Width, SliderBottom.Height);
|
||||
click(Math.ceil(SliderBottom.x + SliderBottom.Width / 2), Math.ceil(SliderBottom.y + SliderBottom.Height * 2));
|
||||
await moveMouseTo(0, 0);
|
||||
await sleep(100);
|
||||
}
|
||||
}
|
||||
|
||||
// 滑条顶端
|
||||
async function pageTop(SliderTopRo) {
|
||||
let captureRegion = captureGameRegion();
|
||||
let SliderTop = captureRegion.find(SliderTopRo);
|
||||
captureRegion.dispose();
|
||||
if (SliderTop.isExist()) {
|
||||
log.info("识别到滑条顶端位置:({x},{y},{h},{w})", SliderTop.x, SliderTop.y, SliderTop.Width, SliderTop.Height);
|
||||
await moveMouseTo(Math.ceil(SliderTop.x + SliderTop.Width / 2), Math.ceil(SliderTop.y + SliderTop.Height * 1));
|
||||
leftButtonDown();
|
||||
await sleep(1000);
|
||||
leftButtonUp();
|
||||
await moveMouseTo(0, 0);
|
||||
await sleep(100);
|
||||
}
|
||||
}
|
||||
|
||||
// 切换队伍
|
||||
async function SwitchParty(partyName) {
|
||||
let ConfigureStatue = false;
|
||||
|
||||
let foundQuickSetup = false;
|
||||
for (let j = 0; j < 2; j++) { // 尝试两次
|
||||
keyPress("VK_L");
|
||||
await sleep(2000);
|
||||
for (let i = 0; i < 2; i++) {
|
||||
let captureRegion = captureGameRegion();
|
||||
let QuickSetupButton = captureRegion.find(QuickSetupButtonRo);
|
||||
captureRegion.dispose();
|
||||
if (QuickSetupButton.isExist()) {
|
||||
log.info("已进入队伍配置页面");
|
||||
foundQuickSetup = true;
|
||||
break;
|
||||
} else {
|
||||
await sleep(1000);
|
||||
}
|
||||
}
|
||||
if (foundQuickSetup) {
|
||||
break; // 第一次找到就退出循环
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundQuickSetup) {
|
||||
log.error("两次尝试都未能进入队伍配置页面");
|
||||
return false;
|
||||
}
|
||||
// 识别当前队伍
|
||||
let captureRegion = captureGameRegion();
|
||||
let resList = captureRegion.findMulti(RecognitionObject.ocr(100, 900, 300, 180));
|
||||
captureRegion.dispose();
|
||||
let currentPartyFound = false;
|
||||
|
||||
for (let i = 0; i < resList.count; i++) {
|
||||
let res = resList[i];
|
||||
log.info("当前队伍名称位置:({x},{y},{w},{h}), 识别结果:{text}", res.x, res.y, res.Width, res.Height, res.text);
|
||||
if (res.text.includes(partyName)) {
|
||||
log.info("当前队伍即为目标队伍,无需切换");
|
||||
notification.send(`当前队伍即为目标队伍:${partyName},无需切换`);
|
||||
keyPress("VK_ESCAPE");
|
||||
await sleep(500);
|
||||
currentPartyFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!currentPartyFound) {
|
||||
await sleep(1000);
|
||||
let captureRegion = captureGameRegion();
|
||||
let ConfigureTeamButton = captureRegion.find(ConfigureTeamButtonRo);
|
||||
captureRegion.dispose();
|
||||
if (ConfigureTeamButton.isExist()) {
|
||||
log.info("识别到配置队伍按钮");
|
||||
ConfigureTeamButton.click();
|
||||
await sleep(500);
|
||||
await pageTop(LeftSliderTopRo);
|
||||
|
||||
for (let p = 0; p < 4; p++) {
|
||||
// 识别当前页
|
||||
let captureRegion = captureGameRegion();
|
||||
let resList = captureRegion.findMulti(RecognitionObject.ocr(0, 100, 400, 900));
|
||||
captureRegion.dispose();
|
||||
for (let i = 0; i < resList.count; i++) {
|
||||
let res = resList[i];
|
||||
if (settings.enableDebug) {
|
||||
log.info("文本位置:({x},{y},{w},{h}), 识别内容:{text}", res.x, res.y, res.Width, res.Height, res.text);
|
||||
}
|
||||
if (res.text.includes(partyName)) {
|
||||
log.info("目标队伍位置:({x},{y},{w},{h}), 识别结果:{text}", res.x, res.y, res.Width, res.Height, res.text);
|
||||
click(Math.ceil(res.x + 360), res.y + Math.ceil(res.Height / 2));
|
||||
|
||||
// 找到目标队伍,点击确定、部署
|
||||
await sleep(1500);
|
||||
let ConfirmButtonCaptureRegion = captureGameRegion();
|
||||
let ConfirmButton = ConfirmButtonCaptureRegion.find(ConfirmDeployButtonRo);
|
||||
ConfirmButtonCaptureRegion.dispose();
|
||||
if (ConfirmButton.isExist()) {
|
||||
log.info("识别到确定按钮:({x},{y},{w},{h})", ConfirmButton.x, ConfirmButton.y, ConfirmButton.Width, ConfirmButton.Height);
|
||||
ConfirmButton.click();
|
||||
}
|
||||
await sleep(1500);
|
||||
let DeployButtonCaptureRegion = captureGameRegion();
|
||||
let DeployButton = DeployButtonCaptureRegion.find(ConfirmDeployButtonRo);
|
||||
DeployButtonCaptureRegion.dispose();
|
||||
if (DeployButton.isExist()) {
|
||||
log.info("识别到部署按钮:({x},{y},{w},{h})", DeployButton.x, DeployButton.y, DeployButton.Width, DeployButton.Height);
|
||||
DeployButton.click();
|
||||
await sleep(100);
|
||||
notification.send(`寻找到目标队伍:${partyName}`);
|
||||
ConfigureStatue = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ConfigureStatue) {
|
||||
await genshin.returnMainUi();
|
||||
break;
|
||||
} else {
|
||||
await pageDown(LeftSliderBottomRo);
|
||||
}
|
||||
}
|
||||
if (!ConfigureStatue) {
|
||||
// 没找到指定队伍名称的队伍,抛出异常
|
||||
log.error(`没有找到指定队伍名称:${partyName}`);
|
||||
notification.error(`没有找到指定队伍名称:${partyName}`);
|
||||
await genshin.returnMainUi();
|
||||
throw new Error(`没有找到指定队伍名称:${partyName}`);
|
||||
}
|
||||
} else {
|
||||
// 没找到配置队伍按钮,抛出异常
|
||||
log.error("没有找到配置队伍按钮");
|
||||
notification.error("没有找到配置队伍按钮");
|
||||
await genshin.returnMainUi();
|
||||
throw new Error("没有找到配置队伍按钮");
|
||||
}
|
||||
} else {
|
||||
// 当前队伍就是目标队伍,设置成功状态
|
||||
ConfigureStatue = true;
|
||||
}
|
||||
return ConfigureStatue;
|
||||
}
|
||||
|
||||
async function SwitchPartyMain(partyName, disableGoStatue) {
|
||||
if (!!partyName) {
|
||||
try {
|
||||
if (!disableGoStatue) {
|
||||
// 强制去七天神像换队
|
||||
log.info("强制传送到七天神像切换队伍");
|
||||
await genshin.TpToStatueOfTheSeven();
|
||||
log.info("正在尝试切换至" + partyName);
|
||||
await SwitchParty(partyName);
|
||||
} else {
|
||||
// 先尝试在当前位置换队
|
||||
await genshin.returnMainUi();
|
||||
log.info("正在尝试切换至" + partyName);
|
||||
let switchResult = await SwitchParty(partyName);
|
||||
|
||||
if (!switchResult) {
|
||||
// 如果当前位置换队失败,去七天神像再试一次
|
||||
log.info("当前位置换队失败,传送到七天神像重试");
|
||||
await genshin.TpToStatueOfTheSeven();
|
||||
log.info("正在七天神像重新尝试切换至" + partyName);
|
||||
await SwitchParty(partyName);
|
||||
}
|
||||
}
|
||||
genshin.clearPartyCache();
|
||||
return partyName
|
||||
} catch (error) {
|
||||
log.error("队伍切换失败:" + error.message);
|
||||
notification.error("队伍切换失败:" + error.message);
|
||||
await genshin.returnMainUi();
|
||||
}
|
||||
} else {
|
||||
log.error("没有设置切换队伍");
|
||||
notification.error("没有设置切换队伍");
|
||||
await genshin.returnMainUi();
|
||||
}
|
||||
}
|
||||
this.switchUtil={
|
||||
SwitchPartyMain
|
||||
}
|
||||
// /**
|
||||
// * @returns {Promise<void>}
|
||||
// */
|
||||
//
|
||||
// (async function () {
|
||||
// await SwitchPartyMain(settings.partyName, settings.disableGoStatue);
|
||||
// })();
|
||||
343
repo/js/FullyAutoAndSemiAutoTools/utils/cron.js
Normal file
@@ -0,0 +1,343 @@
|
||||
// 分钟 小时 日期 月份 星期 [年份可选]
|
||||
const cronRegex = /^(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)(?:\s+(\S+))?$/;
|
||||
|
||||
/**
|
||||
* 解析单个 cron 字段,返回匹配的数值数组
|
||||
* @param {string} field - 字段值 如 "1,3-5,* /10"
|
||||
* @param {number} min - 最小值
|
||||
* @param {number} max - 最大值
|
||||
* @param {number} [stepBase=0] - 步进基准(星期从0或1开始都支持)
|
||||
* @returns {Set<number>} 所有匹配的数值集合
|
||||
*/
|
||||
function parseCronField(field, min, max, stepBase = 0) {
|
||||
const result = new Set();
|
||||
const parts = field.split(',');
|
||||
|
||||
for (const part of parts) {
|
||||
// 处理 */n 格式
|
||||
if (part.startsWith('*/')) {
|
||||
const step = parseInt(part.slice(2), 10);
|
||||
if (isNaN(step) || step <= 0) continue;
|
||||
|
||||
for (let i = min; i <= max; i += step) {
|
||||
result.add(i);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// 处理 n-n/n 格式
|
||||
if (part.includes('/')) {
|
||||
const [range, stepStr] = part.split('/');
|
||||
const step = parseInt(stepStr, 10);
|
||||
if (isNaN(step) || step <= 0) continue;
|
||||
|
||||
if (range === '*') {
|
||||
for (let i = min; i <= max; i += step) {
|
||||
result.add(i);
|
||||
}
|
||||
} else if (range.includes('-')) {
|
||||
const [start, end] = range.split('-').map(Number);
|
||||
if (isNaN(start) || isNaN(end)) continue;
|
||||
for (let i = Math.max(min, start); i <= Math.min(max, end); i += step) {
|
||||
result.add(i);
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// 处理范围 n-n
|
||||
if (part.includes('-')) {
|
||||
const [start, end] = part.split('-').map(Number);
|
||||
if (!isNaN(start) && !isNaN(end)) {
|
||||
for (let i = Math.max(min, start); i <= Math.min(max, end); i++) {
|
||||
result.add(i);
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// 处理单个数字 / 列表
|
||||
const num = parseInt(part, 10);
|
||||
if (!isNaN(num) && num >= min && num <= max) {
|
||||
result.add(num);
|
||||
}
|
||||
|
||||
// 处理 L(最后一天) - 只对日期字段有意义,这里简单处理
|
||||
if (part === 'L' && max === 31) {
|
||||
// 实际使用时需要知道当月天数,这里先占位
|
||||
result.add(99); // 特殊标记,后续需处理
|
||||
}
|
||||
|
||||
// ? 在日期/星期中代表「无特定值」 - 这里简单忽略具体值
|
||||
if (part === '?') {
|
||||
// 实际使用时需配合另一字段判断
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 简单版 cron 解析器(只解析出每个字段允许的时间值)
|
||||
* @param {string} cron - cron表达式 "0 9 * * 1-5"
|
||||
* @returns {object|null} 解析结果 或 null(格式错误)
|
||||
*/
|
||||
function parseCron(cron) {
|
||||
const match = cron.trim().match(cronRegex);
|
||||
if (!match) return null;
|
||||
|
||||
const [, min, hour, day, month, dow] = match;
|
||||
|
||||
try {
|
||||
const minutes = parseCronField(min, 0, 59);
|
||||
const hours = parseCronField(hour, 0, 23);
|
||||
const days = parseCronField(day, 1, 31);
|
||||
const months = parseCronField(month, 1, 12);
|
||||
const dows = parseCronField(dow, 0, 7); // 0和7都代表周日
|
||||
|
||||
// 星期字段 7 → 0
|
||||
if (dows.has(7)) dows.add(0);
|
||||
|
||||
return {
|
||||
minutes: [...minutes].sort((a, b) => a - b),
|
||||
hours: [...hours].sort((a, b) => a - b),
|
||||
days: [...days].sort((a, b) => a - b),
|
||||
months: [...months].sort((a, b) => a - b),
|
||||
dows: [...dows].sort((a, b) => a - b),
|
||||
// 注:days和dows同时有特定值时,实际cron是「或」关系
|
||||
// 这里仅简单分开列出,真实调度需复杂判断
|
||||
original: cron.trim(),
|
||||
isValid: true
|
||||
};
|
||||
} catch (e) {
|
||||
return {isValid: false, error: e.message, original: cron};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取下一个Cron时间戳
|
||||
* @param {string} cronExpression - Cron表达式
|
||||
* @param {number} [startTimestamp=Date.now()] - 开始时间戳,默认为当前时间
|
||||
* @param {number} endTimestamp - 结束时间戳
|
||||
* @returns {Promise} 返回一个Promise,解析为下一个Cron时间戳
|
||||
*/
|
||||
async function getNextCronTimestamp(cronExpression, startTimestamp = Date.now(), endTimestamp, url) {
|
||||
log.warn("使用cron CD算法 请开启JS HTTP 权限 如已开启请忽略")
|
||||
const result = await http.request("POST", url, JSON.stringify({
|
||||
cronExpression: `${cronExpression}`,
|
||||
startTimestamp: startTimestamp,
|
||||
endTimestamp: endTimestamp
|
||||
}), JSON.stringify({
|
||||
"Content-Type": "application/json"
|
||||
})).then(res => {
|
||||
log.debug(`[{0}]res=>{1}`, 'next', JSON.stringify(res))
|
||||
if (res.status_code === 200 && res.body) {
|
||||
let result_json = JSON.parse(res.body);
|
||||
if (result_json?.code === 200) {
|
||||
return result_json?.data
|
||||
}
|
||||
throw new Error("请求失败,error:" + result_json?.message)
|
||||
}
|
||||
return undefined
|
||||
})
|
||||
|
||||
return result === null || !result ? undefined : result
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有cron表达式的时间戳
|
||||
* @param {Array} bodyJson - 包含cron表达式和相关参数的对象数组,默认值为空数组
|
||||
* @param {string} url - 请求的目标URL
|
||||
* @returns {Map} 返回一个Map对象,其中key为输入参数中的key,value为对应的ok状态
|
||||
*/
|
||||
async function getNextCronTimestampAll(bodyJson = [{
|
||||
key: '', // 标识符
|
||||
cronExpression: "", // cron表达式
|
||||
startTimestamp: Date.now(), // 开始时间戳
|
||||
endTimestamp: 0 // 结束时间戳
|
||||
}], url) {
|
||||
// 打印警告日志,提示用户需要开启JS HTTP权限
|
||||
log.warn("使用cron CD算法 请开启JS HTTP 权限 如已开启请忽略")
|
||||
// 初始化结果列表,默认包含一个成功的空key项
|
||||
let resultList = [{key: '', ok: true,next:0}]
|
||||
// 发送HTTP POST请求并处理响应
|
||||
resultList = (
|
||||
await http.request("POST", url, JSON.stringify({cronList:bodyJson}), JSON.stringify({
|
||||
"Content-Type": "application/json"
|
||||
})).then(res => {
|
||||
// 打印调试日志,记录响应内容
|
||||
log.debug(`[{0}]res=>{1}`, 'next', JSON.stringify(res))
|
||||
// 检查响应状态码和响应体
|
||||
if (res.status_code === 200 && res.body) {
|
||||
let result_json = JSON.parse(res.body);
|
||||
// 检查响应代码是否为200
|
||||
if (result_json?.code === 200) {
|
||||
return result_json?.data
|
||||
}
|
||||
// 如果响应代码不为200,抛出错误
|
||||
throw new Error("请求失败,error:" + result_json?.message)
|
||||
}
|
||||
return undefined
|
||||
})
|
||||
)
|
||||
// 创建一个Map对象,用于存储结果
|
||||
let map = new Map()
|
||||
// 遍历结果列表,将每个项的key和ok状态存入Map
|
||||
resultList.forEach(item => {
|
||||
map.set(item.key, item.ok)
|
||||
})
|
||||
|
||||
// 返回包含结果的Map对象
|
||||
return map
|
||||
}
|
||||
|
||||
//影响到性能 改http 第三方
|
||||
// function getNextCronTimestamp(cron, fromTime = Date.now(),endTime) {
|
||||
// const parts = cron.trim().split(/\s+/);
|
||||
// if (parts.length < 5 || parts.length > 6) {
|
||||
// throw new Error("不支持的 cron 格式,应为 5~6 段");
|
||||
// }
|
||||
//
|
||||
// const [minStr, hourStr, dayStr, monthStr, dowStr] = parts;
|
||||
//
|
||||
// // 解析每个字段
|
||||
// const minutes = parseField(minStr, 0, 59);
|
||||
// const hours = parseField(hourStr, 0, 23);
|
||||
// const days = parseField(dayStr, 1, 31);
|
||||
// const months = parseField(monthStr, 1, 12);
|
||||
// const dows = parseField(dowStr, 0, 7);
|
||||
//
|
||||
// // 星期 7 → 0 (周日)
|
||||
// if (dows.has(7)) dows.add(0);
|
||||
//
|
||||
// let current = new Date(fromTime);
|
||||
// // 如果没有指定 endTime,默认设置为明天 00:00:00
|
||||
// if (endTime === undefined) {
|
||||
// const tomorrow = new Date(current);
|
||||
// tomorrow.setDate(tomorrow.getDate() + 1);
|
||||
// tomorrow.setHours(0, 0, 0, 0);
|
||||
// endTime = tomorrow.getTime();
|
||||
// }
|
||||
//
|
||||
// // 动态计算最大迭代次数
|
||||
// // 将时间差(毫秒)转换为分钟,向上取整,确保覆盖所有可能的分钟点
|
||||
// const timeDiffMinutes = Math.ceil((endTime - fromTime) / 60000);
|
||||
//
|
||||
// // 设置最大迭代次数,防止意外情况(如 endTime 极大)导致内存溢出或死循环
|
||||
// // 即使 endTime 是 10 年后,也限制在约 2 年内(避免极端情况)
|
||||
// // 2年 ≈ 365 * 2 * 24 * 60 = 1,051,200
|
||||
// const MAX_ITERATIONS_LIMIT = 1051200;
|
||||
// const MAX_ITERATIONS = Math.min(timeDiffMinutes, MAX_ITERATIONS_LIMIT);
|
||||
//
|
||||
// let iteration = 0;
|
||||
// while (iteration++ < MAX_ITERATIONS) {
|
||||
// // 先推进到下一分钟,避免死循环在同一分钟
|
||||
// current.setMinutes(current.getMinutes() + 1);
|
||||
// current.setSeconds(0);
|
||||
// current.setMilliseconds(0);
|
||||
//
|
||||
// const m = current.getMinutes();
|
||||
// const h = current.getHours();
|
||||
// const d = current.getDate();
|
||||
// const mon = current.getMonth() + 1; // JS 月份 0~11
|
||||
// const dow = current.getDay(); // 0=周日, 1=周一, ..., 6=周六
|
||||
//
|
||||
// // 核心匹配条件(日期和星期是 OR 关系)
|
||||
// const minuteMatch = minutes.has(m) || minutes.size === 0;
|
||||
// const hourMatch = hours.has(h) || hours.size === 0;
|
||||
// const monthMatch = months.has(mon) || months.size === 0;
|
||||
// const dayMatch = days.has(d) || days.size === 0;
|
||||
// const dowMatch = dows.has(dow) || dows.size === 0;
|
||||
//
|
||||
// const dateOrDowMatch = (days.size === 0 && dows.size === 0) || // 两者都是 *
|
||||
// (days.size > 0 && dows.size === 0) || // 只指定了日期
|
||||
// (days.size === 0 && dows.size > 0) || // 只指定了星期
|
||||
// (dayMatch && dowMatch); // 两者都满足才算(最严格)
|
||||
//
|
||||
// if (minuteMatch && hourMatch && monthMatch && dateOrDowMatch) {
|
||||
// return current.getTime();
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // 如果是因为超过 MAX_ITERATIONS_LIMIT 而退出,说明时间跨度太大
|
||||
// if (timeDiffMinutes > MAX_ITERATIONS_LIMIT) {
|
||||
// log.warn("查找范围过大,已达到最大迭代次数限制");
|
||||
// } else {
|
||||
// log.warn("未找到合理下一次执行时间");
|
||||
// }
|
||||
// return null;
|
||||
// }
|
||||
|
||||
/**
|
||||
* 解析单个 cron 字段,返回匹配的数值 Set
|
||||
* 支持: * , - / 数值列表 * /n
|
||||
*/
|
||||
function parseField(field, min, max) {
|
||||
const result = new Set();
|
||||
|
||||
if (field === '*' || field === '?') {
|
||||
return result; // 空 set 代表任意
|
||||
}
|
||||
|
||||
const parts = field.split(',');
|
||||
|
||||
for (let part of parts) {
|
||||
part = part.trim();
|
||||
|
||||
// */n
|
||||
if (part.startsWith('*/')) {
|
||||
const step = Number(part.slice(2));
|
||||
if (!isNaN(step) && step > 0) {
|
||||
for (let i = min; i <= max; i += step) {
|
||||
result.add(i);
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// n-n
|
||||
if (part.includes('-') && !part.includes('/')) {
|
||||
const [start, end] = part.split('-').map(Number);
|
||||
if (!isNaN(start) && !isNaN(end)) {
|
||||
for (let i = Math.max(min, start); i <= Math.min(max, end); i++) {
|
||||
result.add(i);
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// n/n 或 */n 已处理,剩下是普通数字或范围/步进
|
||||
if (part.includes('/')) {
|
||||
const [range, stepStr] = part.split('/');
|
||||
const step = Number(stepStr);
|
||||
if (isNaN(step) || step <= 0) continue;
|
||||
|
||||
if (range === '*') {
|
||||
for (let i = min; i <= max; i += step) result.add(i);
|
||||
} else {
|
||||
const [start, end] = range.split('-').map(Number);
|
||||
if (!isNaN(start) && !isNaN(end)) {
|
||||
for (let i = Math.max(min, start); i <= Math.min(max, end); i += step) {
|
||||
result.add(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// 单个数字
|
||||
const num = Number(part);
|
||||
if (!isNaN(num) && num >= min && num <= max) {
|
||||
result.add(num);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
this.cronUtil = {
|
||||
getNextCronTimestamp,
|
||||
getNextCronTimestampAll
|
||||
}
|
||||
142
repo/js/FullyAutoAndSemiAutoTools/utils/uid.js
Normal file
@@ -0,0 +1,142 @@
|
||||
const commonPath = 'Assets/RecognitionObject/'
|
||||
const commonMap = new Map([
|
||||
['main_ui', {
|
||||
path: `${commonPath}`,
|
||||
name: 'paimon_menu',
|
||||
type: '.png',
|
||||
}],
|
||||
])
|
||||
const genshinJson = {
|
||||
width: 1920,//genshin.width,
|
||||
height: 1080,//genshin.height,
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据键值获取JSON路径
|
||||
* @param {string} key - 要查找的键值
|
||||
* @returns {any} 返回与键值对应的JSON路径值
|
||||
*/
|
||||
function getJsonPath(key) {
|
||||
return commonMap.get(key); // 通过commonMap的get方法获取指定键对应的值
|
||||
}
|
||||
|
||||
function saveOnlyNumber(str) {
|
||||
str = str ? str : '';
|
||||
// 使用正则表达式匹配字符串中的所有数字
|
||||
// \d+ 匹配一个或多个数字
|
||||
// .join('') 将匹配到的数字数组连接成一个字符串
|
||||
// parseInt 将连接后的字符串转换为整数
|
||||
return parseInt(str.match(/\d+/g).join(''));
|
||||
}
|
||||
|
||||
async function ocrUID() {
|
||||
let uid_json = {
|
||||
x: 1683,
|
||||
y: 1051,
|
||||
width: 234,
|
||||
height: 28,
|
||||
}
|
||||
let recognitionObjectOcr = RecognitionObject.Ocr(uid_json.x, uid_json.y, uid_json.width, uid_json.height);
|
||||
let region3 = captureGameRegion()
|
||||
let res = region3.find(recognitionObjectOcr);
|
||||
log.debug(`[OCR识别UID]识别结果: ${res.text}, 原始坐标: x=${res.x}, y=${res.y},width:${res.width},height:${res.height}`);
|
||||
//只保留数字
|
||||
let uid
|
||||
try {
|
||||
uid = saveOnlyNumber(res.text)
|
||||
} catch (e) {
|
||||
log.warn(`UID未设置`)
|
||||
uid = 0
|
||||
} finally {
|
||||
region3.dispose()
|
||||
}
|
||||
log.debug(`[OCR识别UID]识别结果: {uid}`, uid);
|
||||
return uid
|
||||
}
|
||||
|
||||
// 判断是否在主界面的函数
|
||||
const isInMainUI = () => {
|
||||
// let name = '主界面'
|
||||
let main_ui = getJsonPath('main_ui');
|
||||
// 定义识别对象
|
||||
let paimonMenuRo = RecognitionObject.TemplateMatch(
|
||||
file.ReadImageMatSync(`${main_ui.path}${main_ui.name}${main_ui.type}`),
|
||||
0,
|
||||
0,
|
||||
genshinJson.width / 3.0,
|
||||
genshinJson.width / 5.0
|
||||
);
|
||||
let captureRegion = captureGameRegion();
|
||||
let res = captureRegion.find(paimonMenuRo);
|
||||
captureRegion.Dispose()
|
||||
return !res.isEmpty();
|
||||
};
|
||||
|
||||
async function toMainUi() {
|
||||
let ms = 1000
|
||||
let index = 1
|
||||
await sleep(ms);
|
||||
while (!isInMainUI()) {
|
||||
await sleep(ms);
|
||||
await genshin.returnMainUi(); // 如果未启用,则返回游戏主界面
|
||||
await sleep(ms);
|
||||
if (index > 3) {
|
||||
throw new Error(`多次尝试返回主界面失败`);
|
||||
}
|
||||
index += 1
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
async function compareUid(UID = settings.uid) {
|
||||
let uid = await ocrUID()
|
||||
let setUid = 0
|
||||
try {
|
||||
setUid = saveOnlyNumber(UID)
|
||||
} catch (e) {
|
||||
// log.warn(`UID未设置`)
|
||||
}
|
||||
let compare = uid === setUid
|
||||
if (compare) {
|
||||
log.info(`[OCR识别UID]识别结果: {uid} 与设置UID相同`, uid);
|
||||
}
|
||||
return compare
|
||||
}
|
||||
|
||||
async function checkUid() {
|
||||
let reJson = {
|
||||
inMainUI: false,
|
||||
isUid: false
|
||||
}
|
||||
if (isInMainUI()) {
|
||||
reJson.isUid = await compareUid()
|
||||
}
|
||||
return reJson
|
||||
}
|
||||
|
||||
async function check() {
|
||||
let check = false
|
||||
if (settings.uid) {
|
||||
try {
|
||||
await toMainUi();
|
||||
} catch (e) {
|
||||
log.warn("多次尝试返回主界面失败")
|
||||
}
|
||||
let checkJson = await checkUid()
|
||||
if ((!checkJson.inMainUI) && (!checkJson.isUid)) {
|
||||
//尝试直接识别
|
||||
checkJson.isUid = await compareUid()
|
||||
}
|
||||
check = checkJson.isUid
|
||||
}
|
||||
return check
|
||||
}
|
||||
|
||||
this.uidUtil = {
|
||||
toMainUi,
|
||||
isInMainUI,
|
||||
checkUid,
|
||||
ocrUID,
|
||||
check,
|
||||
compareUid,
|
||||
}
|
||||