未发布版本 v6.6.0-SNAPSHOT。 本页内容来自 alpha 分支,随时可能变更,不属于任何已发布版本。

commit b152663 · 注入于 2026-11-14 08:35 UTC

Skip to content

UltiTools-API 6.5.0 更新说明 ​

6.5.0 加强了面板远程命令检查,修复了 UltiCloud 回复和玩家链接投递,并允许在未改变的 YAML 块标量后追加缺失的配置默认键。本次还改进了模块错误报告和链接诊断,校验玩家缓存保存声明,并弃用但不删除旧的语言声明。

面向模块作者的完整清单见 COMPATIBILITY.md,发布页见 GitHub 上的 v6.5.0。

远程命令默认值变化

默认 ultipanel.commands.blocklist 新增 execute、return 和 function。已有列表不会自动追加或改写;如需相同的拦截,请自行添加。停服、编辑列表后重新启动:/ul reload 不会重读此列表。

重点:远程命令边界与回复可靠性 ​

  • 默认黑名单从十项增加到十三项。新安装和缺少此键的配置会拒绝直接执行 execute、return 和 function,也拒绝 minecraft:execute 等带命名空间的形式。远程命令仍由 ultipanel.capabilities.commands: false 默认关闭。(#912)
  • 在服务器线程即将执行命令时,检查按 Bukkit 的命令名、标签和别名进行双向匹配,忽略大小写和命名空间。列入 plugins 会同时拦截 pl、bukkit:pl,列入 pl 也会拦截 plugins。同步嵌套进入 BaseCommandExecutor 的调用会在帮助、校验器和命令体之前再次检查。(#905)
  • 确认接收请求后,若未包装的 Error 从命令分发中逸出,现在会返回 command_failed,不再让面板收不到结果。LinkageError 被处理后不再抛出,其他错误则在回复后继续传播。在 Paper 1.21.11 上,原始 Bukkit 命令失败会被包装成 CommandException,6.4.0 就已返回 command_failed;未包装错误的路径由仓库单元测试构件覆盖。反射调用的框架命令体失败仍作为普通命令输出返回。(#905)
  • 异步玩家传送的回复等待上限为 25 秒。超时返回 internal_error 和 teleport did not complete in time,但不会取消传送;重试前请检查玩家实际位置。晚到的完成通知不会产生第二个回复。(#905)

升级前准备 ​

  • 支持的服务器仍为 Paper 1.19.2 build 163 至 Paper 1.21.x,Spigot 不是受支持的目标。6.4.0 更新说明中的旧版 Paper 模块要求仍然适用。
  • 手工检查已有远程命令黑名单。若要允许三个新增的默认命令,请在停服时只删除对应条目,再重新启动。空列表([])会关闭可配置黑名单,但不会取消对面板发起的 UltiCloud 登录和登出的独立拒绝。
  • 检查每个 @PlayerCache(saveBeforeRemove = true) Bean:具体 Bean 必须实现 PlayerCacheSaver,继承的字段也适用。否则注册现在会抛出 PluginModuleException。请实现 savePlayerData(UUID);不需要保存时,改为 saveBeforeRemove = false。(#897)
  • 检查查询条件中的 null 和非有限数字。SQLite、MySQL 和 JSON 的 getAll、exist、page 及条件删除现在会一致拒绝这些值。updateIf 保留已记录的 EQUAL 配 null 语义(IS NULL),但拒绝其他 null 比较和非有限条件值。
  • 用打包进 JAR 的 lang/<code>.json、.yml 或 .yaml 资源替换旧语言声明。@I18n 和 @UltiToolsModule(i18n = ...) 在 6.5.0 中仍可编译和加载;缺少打包资源时会新增警告。

新增 ​

  • ErrorReportCollector#reportErrorFromClass(Throwable, Class<?>, TriggerContext) 根据具体类的 JAR 解析错误所属模块。已有 reportError 入口仍然保留。ErrorReportCollector 标记为 @ApiStatus.Internal,这些入口不供模块代码使用。(#900)

修复 ​

  • 未改变的字面量(|)或折叠(>)YAML 块标量后跟空行时,现在可以追加缺失的配置默认键。块标量的原始写法、缩进指示、chomping 标记、指示行注释和尾部空行保持逐字节不变,也保留一致的 LF、CRLF 或 CR 换行。此项修复了 6.4.0 列出的默认键插入限制。(#895)
  • SQLite、MySQL 和 JSON 现在以 DataAccessException 和 DATA_ENTITY_INVALID 拒绝 null 或无穷大/NaN 条件值,不再因后端不同而得到空结果、意外匹配或原始异常。JSON 的 del(WhereCondition.empty()) 也会抛出该类型异常;所有后端对没有 ID 的实体调用 exist(entity) 都返回 false。上文说明的 updateIf 例外保持不变。(#873)
  • 玩家链接创建回复丢失时,暂存的完成事件占用会在连接关闭或报错后释放,以便无需重启即可重投。回执检查与占用是原子的;暂存的完成或过期事件会等创建 future 的回调返回后再投递。调用方取消 future 不再阻止传输层清理。(#905)
  • 命令和 @ExceptionCatch 错误按具体执行器或 Bean 类所属的 JAR 归属到已加载模块,代理 Bean 也适用。来源缺失、无法匹配或匹配不唯一时,仍不标记模块。去重、采样和合并按模块隔离,两个模块的同形异常不再合为一组。identify-string 缺失或无效时,回退到规范化的 plugin.yml 名称。(#900)
  • 错误文本遵守网关的 UTF-16 长度上限,且不会拆开代理对;日志时间戳被限制在协议范围内,避免单个无效时间戳使整批日志被拒绝。(#900)
  • REST 设备登录的 Retry-After 接受 1–86400 秒,且不会把过期处理推迟到设备码截止时间之后。支持协议的响应头使用约定的 1–99 范围;登录冷却剩余秒数向上取整,不再在冷却尚未结束时显示零秒。不存在或不是目录的可编辑根路径不再出现在远程文件列表中。(#886)
  • 遥测快照只在监控发布新样本后重建;被拒绝且内容不变的负载不再每秒重试。缓冲日志文本在内存中设有上限,凭据文件中的整数在保存后仍保持整数。(#886)
  • 链接审计的字段引用采用 Owner.name:descriptor 格式。离线 --own 接受点分或斜杠分隔的包根,并按包边界匹配;退出码区分自身代码问题(1)、参数错误(2)、API 路径不存在或模块 JAR 无法读取(3)。跳过类的汇总会在正常日志级别显示原因,没有丢失处理器时不再提示隔离处理器。哪些类和 Bean 能加载没有变化。(#892)

变更 ​

  • plugin.yml 的 libraries: 现在请求 net.bytebuddy:byte-buddy:1.18.17(原为 1.18.15),由 Paper 在首次启动时下载;预先填充 libraries/ 的离线服务器须包含新版本。(#894)
  • 模块能力版本只读取版本核心部分:2.0-rc1 和 2.0+build.9 都声明为 2.0.0,不再从后缀提取数字。(#905)
  • 构建与工具:二进制兼容性基线改为 6.4.0;离线运行时 API 测试构件检查新增显式跳过选项,并修正构建辅助程序和发布资产检查。本次包含依赖、CI 和测试隔离维护,不改变框架最低服务器要求。(#893、#896)

已知限制 ​

  • 远程命令黑名单不是沙箱。检查覆盖外层命令和同步嵌套的框架执行器,不覆盖经包装命令、commands.yml、数据包函数、第三方转派器或后续 tick 到达的全部原版/Bukkit 目标。除非自行加入 schedule,否则 schedule function <pack>:x … 仍被允许。必须禁用这些路径时,请保持 ultipanel.capabilities.commands: false,不要向不可信的操作员开放远程命令。
  • 别名匹配依据 Bukkit 元数据,不会传递遍历别名关系,也不覆盖原版 Brigadier 重定向。需要时请逐项列出各个拼写。只有包装命令保留面板 sender 时,嵌套拒绝才会进入面板结果;若改用控制台或玩家 sender,拒绝就发送到对应位置。
  • 命令回复不是秘密脱敏边界。未登记的参数及第三方异常文本可能出现在本地记录或回复中;不要在命令回复里打印其他用户的秘密。
  • 在玩家链接处理器注册前收到的过期事件仍会被消费。请先注册处理器,再创建链接。已经运行的处理器在重连期间仍保持执行中。
  • 若需要改变块标量本身的值或分隔行、输入无效、包含锚点/别名,或其他布局无法保留,仍会拒绝追加 YAML 默认键。文件保持不变,请手工添加缺失键。6.4.0 中独立的单文件崩溃安全 YAML 限制继续适用。
  • PlayerCacheSaver 保存失败时仍会警告并删除缓存条目。注册检查不提供重试或持久化保证;关服时也不会通过此 hook 保存仍在线的玩家。
  • 文件/配置、云端客户端和关闭窗口的其余限制见 COMPATIBILITY.md。

弃用 ​

@I18n 和 @UltiToolsModule(i18n = ...) 自 6.5.0 起弃用并标记待删除,并未移除。按既有政策,它们最早可能在 6.6.0 删除。自 6.3.0 起,支持语言来自模块自身 JAR 内的资源,而不是这些声明。请删除旧声明并打包语言文件。(#901、#915)

获准加载的模块声明了语言却未在 JAR 内打包对应资源时,会输出一条列出全部缺失代码的警告。两种声明会合并、排序并去重;资源齐全或声明为空时不额外警告。磁盘文件和 supported() 覆盖不能满足此资源检查,但语言选择及已有覆盖行为不变。

已删除的 API ​

6.5.0 删除了以下八个数据访问成员;它们在 6.4.0 中已弃用,并预告于 6.5.0 删除:

  • DataStore#checkOwnership(File, Class)
  • DataStore#checkOwnership(UltiToolsPlugin, Class)
  • JsonStore#getOperator(UltiToolsPlugin, Class)
  • JsonStore#getOperator(File, Class)
  • MysqlDataStore#getOperator(UltiToolsPlugin, Class)
  • MysqlDataStore#getOperator(File, Class)
  • SQLiteDataStore#getOperator(UltiToolsPlugin, Class)
  • SQLiteDataStore#getOperator(File, Class)

请迁移到 DataStore#getOperator(DataScope, Class);普通模块应使用 UltiToolsPlugin#getDataOperator(Class)。第三方调用方必须更新源码并重新编译。已发布的 UltiKits 模块均未使用这些成员。

破坏性变更 ​

上述八个数据访问 API 的删除对第三方调用方不保持二进制兼容。本次还包含以下行为兼容性变化:

  • 新配置或缺少该键的配置默认禁止远程执行 execute、return 和 function。已有列表不变;已注册别名和同步嵌套框架命令会接受更严格的检查。
  • 要求保存玩家缓存但未实现保存接口时,现在会拒绝注册,不再静默删除条目而不保存。
  • 无效查询条件值在各后端统一以类型化异常拒绝。依赖空结果、原始异常或意外匹配的代码需要调整;updateIf 的 EQUAL 配 null 契约保留。

这些属于行为变化,不是删除 @I18n 或它的模块别名。从 6.3.x 升级时,仍须完成 6.4.0 的 API 删除迁移。

贡献者

暂无相关贡献者

基于 MIT 许可发布