Suite

联动

Announcer 跨模块联动、Capability 与跨服通道

Announcer 模块通过 Capability 注册、跨服通道、客户端变量推送等机制与其他模块和子系统联动。模块本身不使用 EventBus 发布事件,但通过 SubtitlePlayable 能力为其他模块提供字幕播放服务。

Capability 注册

模块在启动时注册以下 Capability,供其他模块通过 getCapability() 获取并调用:

AnnouncerBroadcastable(公开)

公告广播能力(@PublicCapability),外部插件经 AxsCapabilities.get(AnnouncerBroadcastable.class) 获取;Announcer 未启用时返回 null。文本支持 PlaceholderAPI 变量。

方法说明
broadcastNow(text)立即播报(打断当前展示),本服生效
broadcastNow(text, forward)立即播报,forward=true 时跨服转发
enqueue(text, forward)加入手动广播队列,当前展示结束后播报

SubtitlePlayable

提供字幕播放能力,接口定义位于 xuanmo.arcartxsuite.api.capability.SubtitlePlayable。由 Announcer 模块的 SubtitleService 实现,供 EventPacket、OnlineRewards、Conversation、QuestGps、AfkReward 等模块跨模块调用。

方法签名返回值说明
playGroup(Player player, String groupId)boolean为指定玩家播放字幕组,true 表示播放成功,false 表示字幕组不存在

使用示例(其他模块中):

SubtitlePlayable subtitle = getCapability(SubtitlePlayable.class);
if (subtitle != null) {
    boolean ok = subtitle.playGroup(player, "welcome_subtitle");
    // true = 播放成功,false = 字幕组不存在
}

每个玩家同一时间只有一个字幕序列在播放。新的播放请求会终止旧序列(不发 close 包,新的 play 直接覆盖客户端状态)。

QQBotBroadcastable(消费方)

Announcer 模块作为消费方,通过 getCapability(QQBotBroadcastable.class) 获取 QQBot 模块提供的广播能力。当 settings.forward-to-qqtrue 时,自动轮播与手动广播的公告文本会去除颜色代码后发送到所有已配置的 QQ 群。

方法签名返回值说明
sendToGroup(long groupId, String message)void向指定 QQ 群发送消息
sendToAllGroups(String message)void向所有已配置的 QQ 群发送消息

Announcer 调用的是 sendToAllGroups,消息格式为 [公告] <去除颜色代码的公告文本>

跨服广播

跨服通道

模块通过 CrossServerAPI.openChannel("announcer", config, handler) 建立跨服通道。当 cross-server.enabledtrue 且宿主已配置跨服连接时,手动广播命令(broadcast / broadcastnow / gbroadcast / gbroadcastnow)会转发到其他子服。

操作转发方式说明
broadcast <文本>gbroadcast 时转发排队广播,跨服时转发为排队消息
broadcastnow <文本>gbroadcastnow 时转发立即广播,跨服时转发为立即消息
gbroadcast <文本>直接转发跨服排队广播
gbroadcastnow <文本>直接转发跨服立即广播

自动轮播条目不会跨服转发,仅手动广播会跨服。

跨服消息格式(AnnouncerEnvelope)

跨服消息使用 AnnouncerEnvelope 记录封装,通过 AnnouncerEnvelopeCodec 编解码为 YAML 字符串传输:

字段类型说明
messageIdString消息唯一 ID(UUID),用于去重
originNodeString发送节点 ID
textString公告文本(已渲染,不含 PAPI 变量)
immediateboolean是否立即广播(broadcastnow / gbroadcastnow
# 跨服消息 YAML 格式
message-id: "550e8400-e29b-41d4-a716-446655440000"
origin-node: "survival-1"
text: "全服双倍经验活动已开启!"
immediate: true

去重与节点过滤

收到跨服消息时,服务端执行以下处理:

  1. 节点过滤:跳过自身节点发送的消息(originNode 等于本节点 ID)
  2. 去重检查:使用 dedupeKeyoriginNode:messageId)查重,最近 128 条消息的去重集合中已存在则跳过
  3. 主线程调度:在主线程中执行本地展示
    • immediate: true → 立即广播(打断当前展示)
    • immediate: false → 加入待播队列

跨服前提条件

  1. 宿主 config.ymlcross-server 节已正确配置(Redis 或 Proxy Forward)
  2. cross-server.enabled 设为 true
  3. 可选覆盖后端:cross-server.redis.enabled / cross-server.proxy.enabled

跨服通道连接参数与签名密钥由宿主统一管理,模块仅控制启用开关与后端覆盖。详见 跨服配置指南

数据存储

Announcer 模块无数据库表。模块的运行时状态全部保存在内存中:

状态存储位置说明
公告条目AnnouncerModuleConfiguration.entries启动时从 YAML 文件加载,reload 时重新读取
字幕组SubtitleService.groups启动时从 subtitle/groups/*.yml 加载
已初始化玩家AnnouncerService.initializedPlayers客户端就绪的玩家 UUID 集合
已打开 UI 玩家AnnouncerService.openedPlayers已打开公告 HUD 的玩家 UUID 集合
手动广播队列AnnouncerService.manualBroadcastQueue待播报的手动广播文本队列
字幕播放会话SubtitleService.activePlayers玩家 UUID → 活跃播放任务映射
跨服去重集合AnnouncerService.recentDedupeKeys最近 128 条跨服消息去重

玩家退出时自动清理 initializedPlayersopenedPlayers 与字幕播放会话。模块停止时关闭跨服通道、取消定时任务并清空所有内存状态。

客户端变量推送

模块通过 ClientBridgeAPI.sendServerVariable 向 ArcartX 客户端推送以下变量:

变量名类型说明
AXS_announcer_textString当前公告文本(已渲染 PAPI)
AXS_announcer_idString当前公告条目 ID
AXS_announcer_clickableboolean当前公告是否可点击
AXS_announcer_revisionString数据修订版本号(时间戳 + 自增序列)

这些变量与 display 包的字段同步推送,客户端 HUD 可通过任一渠道获取当前公告状态。

与其他模块联动

QQBot 模块

settings.forward-to-qqtrue 且 QQBot 模块已启用时,Announcer 通过 QQBotBroadcastable.sendToAllGroups(message) 将公告转发到所有已配置的 QQ 群。转发前会去除 Minecraft 颜色代码,消息格式为 [公告] <纯文本>

触发场景转发条件消息格式
自动轮播forward-to-qq: true[公告] <公告文本>
手动广播forward-to-qq: true[公告] <广播文本>

SubtitlePlayable 消费方

以下模块通过 SubtitlePlayable 能力调用 Announcer 的字幕播放功能:

模块调用场景说明
EventPacket事件包触发字幕事件条件满足时播放指定字幕组
OnlineRewards全服签到目标达成目标达成时向在线玩家播放字幕组
Conversation对话剧情字幕剧情动作中触发字幕播放
QuestGps任务引导字幕任务状态变更时播放字幕
AfkRewardAFK 奖励字幕奖励触发时播放字幕

跨服传输

Announcer 使用宿主提供的 CrossServerAPI 建立跨服通道,支持 Redis 与 Proxy Forward 双后端。后端选择逻辑:

配置Redis 后端Proxy 后端
cross-server.redis.enabled: true启用继承全局
cross-server.proxy.enabled: true继承全局启用
均不填继承宿主全局配置继承宿主全局配置
cross-server.enabled: false禁用禁用

至少一种后端成功启动时 crossServerChannel.isActive() 返回 true,跨服广播命令才可用。

配置版本迁移

模块支持配置版本自动迁移,当前配置版本为 2。

迁移说明
1→2UI 配置抽离到统一 ui 节:settings.ui-idui.ui-idsettings.register-ui-on-enableui.register-ui-on-enablesettings.overwrite-ui-fileui.overwrite-ui-filessubtitle.settings.ui-idui.subtitle-ui-id,移除 subtitle.settings.register-ui-on-enablesubtitle.settings.overwrite-ui-file

迁移规则定义在 migrations/1-2.yml 中,模块启动时自动检测 config-version 并执行迁移,无需手动干预。

UI 注册与覆盖

模块启动时通过 registerModuleUi 注册公告 HUD 与字幕 HUD:

UI 文件源路径目标路径说明
公告 HUDarcartx/ui/announcer_hud.ymlui/announcer_hud.yml轮播公告显示与点击回传
字幕 HUDarcartx/ui/subtitle_hud.ymlui/subtitle_hud.yml打字机字幕显示

注册行为由 ui.register-ui-on-enableui.overwrite-ui-files 控制。多 UI 支持下,模块会为每个 UI ID 尝试注册,至少一个成功即视为可用。

UI 自定义请参考 图标指南多 UI 指南。公告显示条件可参考 条件指南。若需在自定义 HUD 中展示物品图标,可参考 物品来源 获取物品 JSON。