运行时可以在聊天、书页、物品和部分服务器公告中识别 文本[@描述符]。它使用公开事件和对象接口处理文本,在 Paper 上自动启用可用的组件接口,不拦截或修改数据包。
在 plugins/LinlangRuntimeBukkit/config.yml 中设置 game-text,修改后执行 /linlang reload-all:
game-text:
chat: false
command: false
book: false
anvil: false
sign: false
join: false
quit: false
death: false
advancement: false
kick: false
broadcast: false
motd: false
item: false
entity: false
text-display: false
allow-server-sources: false
这些开关只控制游戏输入监听,默认全部关闭,各项互不依赖。琳琅 Messenger 发送的 Title 和 ActionBar 始终解析高级字符串,不受 game-text 控制。
玩家来源还需要对应的 Bukkit 权限,以下权限默认只授予管理员。公告中的权限检查对象是相关玩家;例如加入公告检查加入的玩家,踢出消息检查被踢出的玩家,而不是消息接收者。
| 位置 | 配置项 | 权限 | 支持范围 | ||||
|---|---|---|---|---|---|---|---|
| 玩家聊天 | chat | linlang.text.chat | 颜色、渐变、样式,以及 hover、click.*、insertion 交互 | ||||
| 文本命令 | command | linlang.text.command | Bukkit 的原版 /say 保留组件;Paper 可增强进入原生命令装饰流程的消息 | ||||
| 书页 | book | linlang.text.book | 编辑、打开与拾取时解析书页;支持颜色、悬浮和点击,也处理讲台上的书 | ||||
| 铁砧改名结果 | anvil | linlang.text.anvil | 名称样式;Paper 保留可显示的组件属性 | ||||
| 告示牌 | sign | linlang.text.sign | 编辑或右键时解析;支持的版本处理正反面,Paper 使用组件行 | ||||
| 加入公告 | join | linlang.text.join | Bukkit 保留旧式样式,Paper 保留聊天组件 | ||||
| 退出公告 | quit | linlang.text.quit | Bukkit 保留旧式样式,Paper 保留聊天组件 | ||||
| 死亡公告 | death | linlang.text.death | Bukkit 保留旧式样式,Paper 保留聊天组件 | ||||
| 进度公告 | advancement | linlang.text.advancement | 需要平台提供可修改的公告组件接口;普通 Bukkit 不额外广播替代消息 | ||||
| 踢出消息 | kick | linlang.text.kick | 退出公告可使用组件;踢出界面只保留显示属性 | ||||
| 服务器广播 | broadcast | linlang.text.broadcast | 只处理经过服务器广播事件的消息,保留原接收者 | ||||
| 服务器 MOTD | motd | linlang.text.motd | 服务器列表的显示样式,不支持聊天式交互 | ||||
| 物品名称与 Lore | item | linlang.text.item | 打开、编辑、拾取或丢出物品时解析;Paper 保留组件显示属性 | ||||
| 实体名称 | entity | linlang.text.entity | 交互、命名牌应用后解析;生成和加载另需系统来源授权 | ||||
| 文字展示实体 | text-display | linlang.text.text-display | 在提供 TextDisplay 的版本中处理生成和加载,须系统来源授权;不模拟点击或悬浮 |
例如,启用 anvil 并授予权限后,玩家在铁砧输入 宝剑[@color=red;bold],生成的物品名称会带颜色和粗体。书页可以写 帮助[@color=yellow;click.run="/help"],编辑提交时按组件保存。交互应在签名后的书页界面测试,编辑界面不会像聊天一样响应点击。书的标题不参与解析。
广播和 MOTD 没有可识别的发送玩家。实体、掉落物和告示牌的生成或区块加载也可能没有玩家来源。这些入口必须同时开启 allow-server-sources 和对应位置开关,并且控制台拥有对应的 linlang.text.* 权限,才会处理。开启它表示管理员信任这些系统来源,不能据此推断发起广播的插件或玩家已经通过权限检查。玩家主动执行文本命令时,检查实际命令发送者的权限。
启动时会打印 Linlang running on Paper server 或 Linlang running on Bukkit server。平台标签表示选用的文本接入方式;Paper 的具体能力仍逐项探测。Paper 衍生服务端只要提供相同接口,也可使用增强功能;缺少的新接口不会妨碍 Bukkit 基础功能加载。
Paper 使用 AsyncChatEvent 修改消息组件,沿用原来的聊天渲染器和接收者。提供命令装饰事件的版本也会直接处理原生命令消息,尽量保留原命令的执行过程。其他插件若在之后重写组件,仍可能覆盖结果。修改了玩家输入的可见内容,也不保证保留原始签名的显示状态。
游戏输入只有包含 [@ 时才进入解析器。形如 [VIP] 或单独的 [] 和其他文本不会被改动。需要使用的语法和描述符列表见高级字符串 ⇱。同一方括号内,@ 只写一次:查看帮助[@click.suggest="/help";hover="打开帮助"] 有效,查看帮助[@click.suggest="/help";@hover="打开帮助"] 无效。若描述符无效,该次输入保持原样;书页或告示牌有多处修改时,任意一处无效都不会应用本次解析结果。
开启 chat 并授予 linlang.text.chat 后,玩家可以在聊天栏输入 查看帮助[@color=yellow;underlined;hover="打开帮助";click.suggest="/help"]。文字的颜色和下划线用于提示可交互;悬浮和点击需要在游戏客户端的聊天界面操作,控制台只显示传统文本。
在 Bukkit 基础路径中,只有颜色、渐变等样式的聊天仍交给原事件发送。需要 hover、click.*、insertion、font、keybind 或 translate 的消息,会在 HIGHEST 阶段取消原事件,再按处理时的格式和接收者投递组件,控制台收到传统文本。已经取消的事件不参与处理。这个接管过程不在 MONITOR 阶段修改事件。
接管聊天会改变原有投递方式,可能影响签名、聊天记录及其他插件对取消事件的处理。同优先级或后续监听器仍可能产生冲突,因此 chat 默认关闭。物品、实体和告示牌只保留显示属性,不会把聊天描述符变成服务器执行命令的入口;书页保留交互事件,最终响应取决于客户端和游戏版本。
没有可用的 Paper 命令装饰事件时,琳琅在分发命令前处理 /say、/me、/teammsg、/tm、/msg、/tell、/w、/whisper 的消息正文,也识别 minecraft: 和 bukkit: 命名空间。/msg 等命令的接收者参数不会被解析,控制台也需对应权限。
原版 /say 是例外:只有命令发送者具有原版 /say 权限,并且 Bukkit 未暴露同名插件命令时,琳琅才会取消裸 /say 并以组件向在线玩家广播,保留颜色、点击和悬浮效果。/minecraft:say 可以明确指定这一行为。控制台也会收到一份传统文本。若描述符无效,琳琅不会接管该命令。其他列出的命令仍只改写消息参数,再交给原命令执行;它们的点击、悬浮等效果会降级,颜色是否显示也取决于目标命令如何处理参数。包括 /title 在内的其余命令不会被处理。
接管 /say 会绕过原命令的执行过程、签名、审计以及其他插件对该命令本身的处理,也可能使服务器日志和命令回显与原版不同。动态注册的同名命令不一定能被上述检查发现。因此 game-text.command 默认关闭;开启前应先检查服务器所用的命令插件和聊天审计规则。新生成的运行时配置文件也会在该键前写出风险说明;已有配置文件不会仅因注释更新而被重写。
物品、书页、告示牌和实体名称会实际写回游戏对象。琳琅在其 PDC 的 linlangruntimebukkit:game-text-sources 中保存原始组件与渲染快照,后续在对应入口重新渲染。命名牌的原始名称也会随命名操作保留到实体。
如果其他插件或玩家修改了已经渲染的字段,且当前值不再匹配快照,琳琅会把它当作新内容处理;新内容没有描述符时清除该字段的旧来源,不会强行恢复旧文字。再次遇到相同源码和结果时也不会反复改写物品。
物品在玩家背包、当前打开的容器、手持交互、拾取和丢出等入口处理;书页还覆盖讲台。授权的系统来源在实体生成和区块加载时处理实体、掉落物与告示牌。不进行全服定时扫描,启用开关或重载配置也不会立即重写全部已加载对象。共享对象保存的是共同显示内容,不是每个查看者独立的文本。
琳琅不能自动处理其他插件任意调用 sendMessage、Title 或 ActionBar API 发出的消息。BossBar、计分板、Tab 列表和其他插件的 GUI 标题也没有统一的修改监听入口,需要对应插件主动解析或接入。琳琅 Messenger 发送的 Title 和 ActionBar 始终解析高级字符串,不需要开启游戏输入监听;这两处不响应点击或悬浮。书的标题不属于书页监听范围。
普通 Bukkit 的公告字段只能通过旧式字符串改写,因此加入、退出和死亡公告不能像 Paper 一样保留交互。琳琅不会为弥补此差异另发一条公告,以免改变死亡可见性等原有规则。
不要把这组开关当作允许所有玩家执行任意高级字符串的总开关。玩家输入的书页可包含命令点击和网址,授予 linlang.text.book 前应确认服务器对此类内容的管理策略。默认关闭输入监听和默认仅管理员可用,是为了避免普通玩家借描述符制造伪装信息。
讨论