Suite

Capability API

registerCapability/getCapability 机制及所有内置 Capability 接口(TitleGrantable、MailDispatchable、ChatCardSendable、EventBusCapability 等)的方法签名参考。

Capability API

Capability 是 Suite 推荐的跨模块通信机制。模块通过 ModuleContext 注册自己提供的能力接口,其他模块通过类型查找来调用,实现松耦合的模块间协作。

工作原理

┌──────────┐  registerCapability   ┌──────────────┐  getCapability   ┌──────────┐
│ Title    │ ─────────────────────→│  Capability  │←──────────────── │ EventPkt │
│ Module   │  TitleGrantable.class │  Registry    │  TitleGrantable  │ Module   │
└──────────┘                       └──────────────┘                  └──────────┘
  1. 提供方startService() 中注册 Capability
  2. 使用方通过 Supplier 延迟查找,避免加载顺序问题
  3. 模块 onDisable 时宿主自动注销其注册的所有 Capability

registerCapability / getCapability

// 提供方:注册
context.registerCapability(TitleGrantable.class, titleService);
 
// 使用方:查找(务必判空)
TitleGrantable title = context.getCapability(TitleGrantable.class);
if (title != null) {
    title.giveTitle(player.getUniqueId(), "hero", "7d", "MyModule");
}

公开 Capability:外部插件入口

context.getCapability() 仅供 AXS 模块内部使用。面向外部 Bukkit 插件,Suite 提供统一静态门面 AxsCapabilities,并配合 @PublicCapability 注解做可见性过滤:

  • 只有标注 @PublicCapability 的接口才能被 AxsCapabilities.get() 返回;未标记的类型对外一律返回 null(模块内部 getCapability 不受限)
  • 宿主启动时把门面直连 ModuleRegistry 的 capability 注册表;模块热卸载后对应 capability 自动摘除,get() 返回 null
  • 公开 capability 的约定:入参用富对象(spec/record),阻塞操作返回 CompletableFuture

当前公开的 Capability

接口提供方用途
EventBusCapability宿主EventBus 主题 pub/sub
SecondaryPasswordAccess宿主二级密码访问
AxsMailServicemail邮件发送/查询/领取/删除(全异步 API)
AxsMarketServicemarket市场 UI 打开/挂单/搜索/计数
MapNavigablemap地图第三方插件注册路径点推送、导航回调注册、导航互斥
QuestGpsNavigablequestgps任务推送/接取/追踪/门禁检查
BattlePassAccessbattlepass战令经验/等级/档位/任务进度
FishingAccessfishing钓鱼小游戏/图鉴/经验/疲劳/领奖
RegionQueryableregions保护区域查询(RegionInfo 只读视图)
BossTrackerQueryableentitytracker活跃 Boss 会话查询
LotteryAccesslottery抽奖积分/兑换/开箱
LoginViewQueryableloginview认证状态查询/打开登录界面
PropAccessibleprop道具列表/应用到主手
AnnouncerBroadcastableannouncer即时/排队公告广播
SubtitlePlayableannouncer播放字幕组
RgbRenderablergb渐变文本渲染
TitleGrantable / TitleConfigQueryabletitle发放称号 / 查询称号元数据
ChatCardSendable / ChatMutablechat发送聊天卡片 / 禁言管理
TabRefreshabletab刷新 Tab 列表
CombatEffectTriggerablecombateffect触发战斗特效
SignalDispatchableeventpacket触发规则引擎信号
MenuOpenablemenu打开配置菜单
AfkRewardDispatchableafkreward挂机状态/原地挂机
WarehouseAutoDepositablewarehouse仓库自动存入
ExtraBackpackAccessextrabackpack扩展背包访问
PickupNotifiable / PickupInterceptorpickup拾取通知推送 / 拾取拦截查询(分模式注册)
QQBotNotifiable / QQBotBroadcastable / QqBindCapableqqbot群消息监听 / 群推送 / QQ 绑定
EssentialsQueryableessentialsAFK/隐身/禁言/昵称查询
OnlineRewardsQueryableonlinerewards签到/在线时长查询与操作
InteractionStateconversation对话交互状态查询

MailDispatchablePlayerDataPurgeableDatabaseMigratablePolygonSelectionCapabilityModuleAdminCapability 等接口为内部专用(未标注 @PublicCapability),外部插件调用 AxsCapabilities.get() 会返回 null。完整对照见文末 内置 Capability 能力图

外部插件接入

插件 plugin.yml 声明 depend: [ArcartXSuite](或 softdepend),构建时 compileOnly 依赖 axs-api

MapNavigable map = AxsCapabilities.get(MapNavigable.class);
if (map != null) {
    map.openMenuFor(player, targetId);
}
  • AxsCapabilities.get(Class) — 返回实现实例;类型未公开、未注册或本体未就绪时返回 null
  • AxsCapabilities.has(Class) — 判断指定公开 capability 当前是否可用

外部插件无需再为每个模块编写 AxsXxxApi 静态门面,AxsCapabilities 是唯一入口。

内置 Capability 接口

TitleGrantable

称号授予能力(公开 capability)。由 Title 模块实现。

public interface TitleGrantable {
    boolean giveTitle(UUID playerId, String titleId, String duration, String source);
}
参数说明
playerId玩家 UUID
titleId称号 id
duration持续时间(如 "permanent""7d"
source来源标识(如 "EventPacket"

TitleConfigQueryable

称号配置查询能力(公开 capability)。由 Title 模块实现。

public interface TitleConfigQueryable {
    TitleInfo queryTitle(String titleId);
    record TitleInfo(String displayName, String qualityName, String description) {}
}

MailDispatchable

邮件发送能力(内部专用,未标记 @PublicCapability,外部插件请使用 AxsMailService)。由 Mail 模块实现。两个方法均可在任意线程调用(同步执行,内部落库阻塞至完成后返回)。

public interface MailDispatchable {
    MailSendResult sendMail(MailSendRequest request);
    MailSendResult dispatchPreset(MailPresetRequest request);
}
  • sendMail — 发送带混合附件(物品+货币)的系统邮件,收件人无需在线
  • dispatchPreset — 按预设模板发送邮件,收件人用玩家名(支持离线玩家)

Mail 模块未启用时返回 failure,调用方应自行降级处理。

AxsMailService

邮件公开服务接口(公开 capability@PublicCapability + @Stable)。由 Mail 模块实现,面向外部 Bukkit 插件。所有方法返回 CompletableFuture,异步执行——不要在 Bukkit 主线程 join()/get(),应用 thenAccept/whenComplete 回调。

// 获取(外部插件唯一入口;AXS 模块内部用 getCapability(AxsMailService.class) 取同一实例)
AxsMailService service = AxsCapabilities.get(AxsMailService.class);
if (service == null) return; // mail 模块未启用
方法返回说明
send(AxsMailRequest)CompletableFuture<AxsDeliveryReceipt>发送系统邮件(含物品/货币/命令附件),idempotencyKey 去重
sendDurable(AxsMailRequest)CompletableFuture<AxsDeliveryReceipt>恢复持久化的发送意图(当前与 send 行为一致)
getMail(UUID, long)CompletableFuture<AxsMailView>查询玩家单封邮件
getInbox(UUID, AxsMailQuery)CompletableFuture<List<AxsMailView>>查询收件箱
getUnreadCount(UUID)CompletableFuture<Integer>查询未读数
markRead(UUID, long)CompletableFuture<AxsMailView>标记已读并返回详情
claim(UUID, long)CompletableFuture<AxsClaimResult>领取全部可领附件(物品附件需玩家在线)
delete(UUID, long)CompletableFuture<AxsDeleteResult>删除邮件(有未领取受保护附件时拒绝)

ChatCardSendable

聊天卡片发送能力(公开 capability)。由 Chat 模块或宿主桥接实现。

public interface ChatCardSendable {
    boolean sendChatCard(Player player, String cardId, Map<String, String> data);
}

ChatMutable

聊天禁言能力(公开 capability)。由 Chat 模块实现。

public interface ChatMutable {
    String mutePlayer(String playerName, Instant expiresAt, String reason, String mutedBy);
    String unmutePlayer(String playerName);
    boolean isMuted(UUID playerUuid);
    List<MuteInfo> listMutes();
    record MuteInfo(UUID playerUuid, String playerName, String mutedBy,
                     String reason, Instant createdAt, Instant expiresAt) {}
}

expiresAt 为 null 表示永久禁言。

SubtitlePlayable

字幕播放能力(公开 capability)。由 Announcer 模块实现。

public interface SubtitlePlayable {
    boolean playGroup(Player player, String groupId);
}

SignalDispatchable

信号派发能力(公开 capability)。由 EventPacket 模块实现,供其他模块触发规则引擎信号。

public interface SignalDispatchable {
    void dispatchSignal(String signal, Player subject, Map<String, String> variables);
}

CombatEffectTriggerable

战斗特效触发能力(公开 capability)。由 CombatEffect 模块实现。

public interface CombatEffectTriggerable {
    boolean triggerPacket(String packetId, Player recipient, Map<String, String> variables);
    boolean triggerDirect(String uiId, String packetHandler, Player recipient, Object payload);
}

MapNavigable

地图导航能力(公开 capability@PublicCapability + @Stable)。由 Map 模块实现。地图是展示层与事件源:来源推送第三方插件注册路径点、接收导航点击回调;导航的实际执行由来源负责,或经 useMapNavigation/navigateExternalTarget 交给地图内置导航栈代执行。按场景选型的完整对接方案见 Map - 第三方插件对接方案

public interface MapNavigable {
    void upsertExternalTarget(Player player, MapExternalTargetSpec spec, boolean select);
    void upsertExternalTargets(Player player, List<MapExternalTargetSpec> specs);
    void reconcileExternalTargets(Player player, String source, List<MapExternalTargetSpec> specs);
    void clearExternalTargets(Player player, String source, boolean syncView);
    void setExternalNavigated(Player player, String targetId, boolean navigated);
    boolean navigateExternalTarget(Player player, String targetId);
    void registerNavigationSource(Plugin owner, String source, MapNavigationHandler handler);
    void unregisterNavigationSource(String source);
    void setNavigationDelegate(Plugin owner, MapNavigationDelegate delegate);
    void clearNavigationDelegate(Plugin owner);
    boolean hasNavigationDelegate();
    void clearTrack(Player player);
    void openMenuFor(Player player, String targetId);
}
方法说明
upsertExternalTarget新增/更新单个第三方插件注册路径点(紫色标记,不占玩家路径点上限),select=true 时切到目标世界并选中
upsertExternalTargets批量推送第三方插件注册路径点,一次视图同步
reconcileExternalTargets用给定集合原子替换某来源的全部目标:单次同步、仍存在的目标选中态不闪断;空列表 = 清空该来源
clearExternalTargets清除指定来源的所有第三方插件注册路径点(source 为空串 = 全部来源)
setExternalNavigated来源回推导航状态,驱动面板"导航 ↔ 取消"按钮切换(useMapNavigation 目标由地图自维护)
navigateExternalTarget由地图内置导航栈开始导航指定第三方插件注册路径点("地图代导航"命令式入口,不过全局委托);已在导航返回 true
registerNavigationSourcesource 注册导航回调;玩家点击该来源目标的"导航/取消"时回调;owner 插件禁用时自动注销
unregisterNavigationSource注销指定来源的导航回调
setNavigationDelegate注册全局导航委托(全量接管导航点击);同一时间全服只有一个委托,重复注册由后者覆盖;owner 插件禁用时自动注销
clearNavigationDelegate注销导航委托(仅当当前委托属于该插件时生效)
hasNavigationDelegate当前是否已注册全局导航委托
clearTrack清除玩家当前的地图导航(锚点/路径点追踪)——来源开始自身导航时调用,实现导航互斥
openMenuFor打开地图并选中目标;targetId 依次匹配第三方插件注册路径点 → 路径点 → 标记点,未命中时按世界 ID 兜底打开

MapExternalTargetSpec 为 record:targetId / source / worldId / title / description / x / y / z / iconId / navigated / sortOrder / useMapNavigation(保留省略 useMapNavigation 的兼容构造,另有省略 iconId/navigated/sortOrder/useMapNavigation 的便捷构造)。useMapNavigation=true 时"导航"点击由地图内置导航栈执行,不回调来源 handler。

MapNavigationHandler 回调接口:

public interface MapNavigationHandler {
    boolean onNavigateRequest(Player player, String targetId); // true=已接管;false=提示导航失败
    default void onCancelRequest(Player player, String targetId) {} // 停止自身导航,标记保留
}

MapNavigationDelegate 全局委托接口(@Stable):

public interface MapNavigationDelegate {
    // 玩家请求开始导航;true=已接管(地图记录委托态),false=交还原处理方
    boolean onNavigateRequest(Player player, MapNavigationRequest request);
    // 委托态被终止(玩家取消/互斥清除/来源接管/退出关闭),实现需幂等
    default void onCancelRequest(Player player, MapNavigationRequest request) {}
}

MapNavigationRequest 为 record:targetType"anchor"/"waypoint"/"external")/ targetId / worldId / title / x / y / z / source(地图自有目标固定 "map",第三方插件注册路径点为其注册 source)。标记点(pin)无 Y 坐标、不可导航,不经此接口。

委托契约:导航执行(信标/路径/追踪)完全由委托方负责,地图不建客户端路标;委托接管后地图记录一条委托导航态,面板"导航"按钮切换为"取消";委托接管第三方插件注册路径点时应另调 setExternalNavigated 驱动该目标行按钮切换。

监测事件(EventBus 主题,可经 EventBusCapability 订阅):

主题触发时机
axs.map.nav_started玩家开始地图导航(payload 含 type/id/world)——来源应停止自身导航实现互斥
axs.map.nav_cleared玩家停止地图导航
axs.map.external_navigate面板点击第三方插件注册路径点"导航"(转发回调的同时发布,供监测/兜底)
axs.map.external_nav_cancel面板点击第三方插件注册路径点"取消"

QuestGpsNavigable

任务导航能力(公开 capability)。由 QuestGPS 模块实现,外部插件经 AxsCapabilities.get(QuestGpsNavigable.class) 获取。

public interface QuestGpsNavigable {
    void offerQuest(Player player, String questId, boolean openMenu);
    void acceptQuest(Player player, String questId);
    void openMenu(Player player);
    void trackQuest(Player player, String questId);
    void trackTask(Player player, String questId, String taskId);
    boolean eventRuleLocked(Player player, String ruleId);
    boolean moduleEntryLocked(Player player, String moduleEntryId);
}

TabRefreshable

Tab 列表刷新能力(公开 capability)。由 Tab 模块实现。

public interface TabRefreshable {
    void requestViewerRefresh(Player viewer, String reason);
    void requestGlobalRefresh(String reason);
}

通用菜单打开能力(公开 capability)。由 Menu 模块实现。

public interface MenuOpenable {
    boolean openMenu(Player player, String menuId);
    void refreshMenu(Player player);
}

AfkRewardDispatchable

挂机状态查询与控制能力(公开 capability)。由 AfkReward 模块实现。

public interface AfkRewardDispatchable {
    boolean isAfk(UUID playerUuid);
    String getAreaName(UUID playerUuid);
    int getAfkSeconds(UUID playerUuid);
    String getAfkMode(UUID playerUuid);  // "REGION" / "MANUAL" / null
    boolean startManualAfk(Player player, String areaName);
}

WarehouseAutoDepositable

仓库自动入库能力(公开 capability)。由 Warehouse 模块实现。

public interface WarehouseAutoDepositable {
    DepositResult depositToPersonalWarehouse(Player player, ItemStack itemStack);
    record DepositResult(boolean success, long storedAmount, int remainingAmount, String message) {}
}

PickupNotifiable

拾取通知能力(公开 capability)。由 Pickup 模块(通知模式)实现;scanner 模式下不注册,get() 返回 null

public interface PickupNotifiable {
    boolean isNotificationActive(UUID playerId);
    boolean notifyPickup(Player player, ItemStack itemStack, int amount);
}

notifyPickup 用于"物品已被其他模块接管、但玩家确实拾取了"的补发场景(如 Warehouse 自动入库取消 EntityPickupItemEvent)。前置校验通过后会同步发布 EventBus 主题 axs.pickup.item_pickup(payload 含 material/amount),与原版监听器路径语义一致——每次补发即一次拾取。请在 Bukkit 主线程调用。

PickupInterceptor

拾取拦截能力(公开 capability)。由 Pickup 模块(扫描模式)实现;notification 模式下不注册,get() 返回 null

public interface PickupInterceptor {
    boolean isAutoPickupIntercepted(UUID playerId);
}

扫描模式接管掉落物拾取流程后,其他自动拾取类模块/插件(如 Warehouse 自动入库、磁铁插件)应在处理 EntityPickupItemEvent 前调用本接口判断是否让步。

ExtraBackpackAccess

扩展背包操作能力(公开 capability)。由 ExtraBackpack 模块实现。

public interface ExtraBackpackAccess {
    boolean isAvailable(Player player);
    Snapshot snapshot(Player player);
    DepositResult deposit(Player player, ItemStack itemStack);
    WithdrawResult withdraw(Player player, String categoryId, int slot, int amount);
    // record Snapshot, CategorySnapshot, SlotSnapshot, DepositResult, WithdrawResult
}

AxsMarketService

市场公开服务接口(公开 capability)。由 Market 模块实现,覆盖拍卖行 / 系统商店 / 回收 / 玩家商店的 UI 打开与常用操作。所有方法请在 Bukkit 主线程调用。

public interface AxsMarketService {
    enum MarketView { AUCTION, AUCTION_SELL, SHOP_LIST, SHOP, RECYCLE,
                      HISTORY, SELL, PLAYER_SHOP, MY_LISTINGS }
    void openUi(Player player, MarketView view);
    CompletableFuture<Boolean> createAuctionListing(Player player, ItemStack item,
                              double startingBid, String currency, long durationSeconds);
    CompletableFuture<Boolean> cancelListing(Player player, long listingId);
    CompletableFuture<Boolean> searchAuction(Player player, String keyword);
    int auctionCount();
    int shopCount();
    int myListingCount(Player player);
    boolean playerShopEnabled();
}

写操作返回 CompletableFuture<Boolean>:操作在调用线程同步完成(涉及背包与落库,须主线程调用),返回的 Future 已完成,false 表示校验失败(价格/货币/黑名单/数量上限等,失败原因已通过消息发给玩家)。createAuctionListing 有防复制约束:item 必须与玩家主手物品匹配,上架从主手扣除,不支持上架玩家未持有的物品。

市场事件订阅 EventBus 主题 axs.market.*listing_created / auction_purchased / shop_dynamic_triggered),详见 EventBus 已注册主题

BattlePassAccess

战令公开能力(公开 capability)。由 BattlePass 模块实现。所有方法请在 Bukkit 主线程调用。

public interface BattlePassAccess {
    boolean isSeasonActive();
    int addXp(Player player, int xp);           // 返回增加后的总经验
    void setXp(Player player, int xp);
    void removeXp(Player player, int xp);
    void setLevel(Player player, int level);
    boolean unlockTier(Player player, String tier);  // "PREMIUM" / "DELUXE",大小写不敏感
    int claimAllRewards(Player player);          // 返回领取的奖励份数
    void updateTaskProgress(Player player, String taskId, int increment);
    void resetProgress(UUID playerUuid);         // 重置本赛季进度
}

FishingAccess

钓鱼公开能力(公开 capability)。由 Fishing 模块实现。所有方法请在 Bukkit 主线程调用。

public interface FishingAccess {
    boolean isInMinigame(UUID playerUuid);
    boolean startMinigame(Player player);        // 鱼竿/条件不满足返回 false
    int collectionCount(UUID playerUuid);
    int totalFishTypes();
    void giveXp(UUID playerUuid, int amount);
    int fatigue(UUID playerUuid);
    void setFatigue(UUID playerUuid, int value);
    boolean claimReward(Player player, String rewardId);
    String sellAllFish(Player player);           // 返回结果提示消息
}

钓鱼事件订阅 axs.fishing.*success / perfect / collection_unlock / treasure / level_up)。

RegionQueryable

区域查询能力(公开 capability)。由 Regions 模块实现。返回 API 侧只读 RegionInfo record(owners/members 为不可变集合拷贝),不暴露模块内部 Region 类型。请在 Bukkit 主线程调用——Region 内部成员集合非并发容器,快照拷贝遇异步并发修改可能抛出 ConcurrentModificationException

public interface RegionQueryable {
    List<RegionInfo> regionsAt(String world, int x, int y, int z); // 按优先级排序
    List<RegionInfo> regionsInWorld(String world);
    List<RegionInfo> allRegions();
    int countRegionsByOwner(UUID owner);
 
    record RegionInfo(String id, String world,
                      int minX, int minY, int minZ,
                      int maxX, int maxY, int maxZ,
                      int priority, String parentId,
                      Set<UUID> owners, Set<UUID> members) {
        boolean contains(String world, int x, int y, int z);
        boolean hasAccess(UUID playerUuid); // owner 或 member,不含权限组判定
    }
}

区域变更订阅 axs.regions.region_change

BossTrackerQueryable

Boss 追踪查询能力(公开 capability)。由 EntityTracker 模块实现。

public interface BossTrackerQueryable {
    boolean isTrackedBoss(UUID entityUuid);
    int activeSessionCount();
    int activeViewerCount();
    List<BossSessionInfo> activeSessions(String mobIdFilter); // null = 不过滤
 
    record BossSessionInfo(UUID entityUuid, String mythicMobId, String displayName,
                           double health, double maxHealth,
                           int participantCount, int trackedPlayerCount,
                           double totalDamage) {}
}

Boss 击杀订阅 axs.entitytracker.boss_kill

LotteryAccess

抽奖公开能力(公开 capability)。由 Lottery 模块实现。所有方法请在 Bukkit 主线程调用。

public interface LotteryAccess {
    long getPoint(UUID playerUuid, String pointId);
    Map<String, Long> getPoints(UUID playerUuid);
    boolean givePoints(UUID playerUuid, String pointId, long amount);
    boolean exchange(Player player, String itemId);
    List<CaseDrawResult> openCase(Player player, String poolId, int count); // 开箱动画照常播放
 
    record CaseDrawResult(String rarity, int poolIndex,
                          String itemKey, String itemName, int amount) {}
}

CaseDrawResult 屏蔽内部 PoolItem 类型:itemKey/itemName 无奖品时为 nullpoolIndex 为 1 基索引(无奖品 -1)。

LoginViewQueryable

登录界面查询能力(公开 capability)。由 LoginView 模块实现。isAuthenticated/isRegistered 可从任意线程调用——注意冷路径(内存未命中/自建认证模式)会同步执行一次数据库查询,高频路径请缓存结果或异步调用;openFor 涉及 UI 打开,须在 Bukkit 主线程调用。

public interface LoginViewQueryable {
    boolean isAuthenticated(Player player);
    boolean isRegistered(Player player);
    void openFor(Player player);
    void openFor(Player player, boolean force); // force=true 已认证也强制打开
}

登录成功订阅 axs.loginview.login_success

PropAccessible

快捷道具公开能力(公开 capability)。由 Prop 模块实现。所有方法请在 Bukkit 主线程调用。

public interface PropAccessible {
    List<String> propIds();
    PropApplyResult applyPropToMainHand(Player player, String propId);
 
    record PropApplyResult(boolean success, String message) {}
}

道具使用事件订阅 axs.prop.prop_used

AnnouncerBroadcastable

公告广播能力(公开 capability)。由 Announcer 模块实现,文本支持 PlaceholderAPI 变量。

public interface AnnouncerBroadcastable {
    void broadcastNow(String text);               // 立即播报,打断当前展示
    void broadcastNow(String text, boolean forward);
    void enqueue(String text, boolean forward);   // 加入队列,当前展示结束后播报
}

forward=true 时经跨服通道转发到其他子服(需 cross-server.enabled)。

RgbRenderable

渐变文本渲染能力(公开 capability)。由 RGB 模块实现。

public interface RgbRenderable {
    String render(String entryId, OfflinePlayer player); // player 可为 null;条目不存在返回空串
    List<String> entryIds();
}

player 参数用于解析条目 text 中的 PlaceholderAPI 占位符。

OnlineRewardsQueryable

在线奖励查询与操作能力(公开 capability,接口位于 xuanmo.arcartxsuite.api.capability)。由 OnlineRewards 模块实现。

public interface OnlineRewardsQueryable {
    boolean hasSignedToday(UUID playerUuid);
    int todayOnlineMinutes(UUID playerUuid);
    int weeklyOnlineMinutes(UUID playerUuid);
    int monthlyOnlineMinutes(UUID playerUuid);
    boolean signIn(Player player);
    boolean makeupSignIn(Player player, String date);   // yyyy-MM-dd
    boolean addMakeupCards(Player player, int amount);
    void grantDailyRewards(Player player);
    boolean addOnlineMinutes(Player player, int minutes);
}

全服目标达成订阅 axs.onlinerewards.server_goal_reached

EventBusCapability

模块间解耦事件总线(pub/sub 模式)。由宿主注册唯一实例,任何模块可发布/订阅主题。

public interface EventBusCapability {
    void publish(String topic, Player player, Object payload);
    void publish(String topic, Player player, Map<String, String> payload); // 向后兼容
    void registerPublisher(String topic);
    boolean hasPublisher(String topic);
    String subscribe(String topic, EventHandler handler);  // 支持通配符 "axs.market.*"
    void unsubscribe(String subscriptionId);
    record BusEvent(String topic, Player player, Object typedPayload, long timestamp) {}
    @FunctionalInterface interface EventHandler { void handle(BusEvent event); }
}
EventBusCapability bus = context.getCapability(EventBusCapability.class);
if (bus != null) {
    // 发布(AXS 内置主题统一 axs.<模块id>.<事件名> 前缀)
    bus.publish("axs.market.listing_created", player, Map.of("price", "1000"));
    // 订阅
    String subId = bus.subscribe("axs.market.*", event -> {
        logger.info(event.player().getName() + " 触发了 " + event.topic());
    });
    // 取消订阅
    bus.unsubscribe(subId);
}

其他 Capability 接口

接口提供模块公开用途
EssentialsQueryableessentialsAFK/隐身/禁言/昵称查询
QQBotBroadcastableqqbot推送消息到 QQ 群
QQBotNotifiableqqbot监听群消息/进退群
QqBindCapableqqbotQQ 绑定查询
InteractionStateconversation对话中让出共享按键
TooltipDataCapabletooltip物品提示数据
PlayerDataPurgeable多模块清除玩家数据(/axs purge
DatabaseMigratable多模块跨库迁移(/axs migrate
PolygonSelectionCapability宿主/regions多边形选区管理
ModuleAdminCapability宿主模块管理能力(@Internal

内置 Capability 能力图

Capability 接口提供模块公开典型使用方用途
TitleGrantabletitleeventpacket, battlepass, 外部插件发放称号
TitleConfigQueryabletitletab, chat, 外部插件查询称号元数据
AxsMailServicemail外部插件邮件发送/查询/领取/删除
MailDispatchablemaileventpacket, onlinerewards发送邮件(内部)
SubtitlePlayableannouncereventpacket, 外部插件播放字幕组
AnnouncerBroadcastableannouncer外部插件即时/排队公告广播
ChatCardSendablechateventpacket, 外部插件发送聊天卡片
ChatMutablechatessentials, 外部插件禁言/解禁
QuestGpsNavigablequestgpseventpacket, 外部插件任务导航
MapNavigablemapquestgps, 外部插件地图外部导航点
TabRefreshabletabtitle, chat, 外部插件刷新 Tab 列表
CombatEffectTriggerablecombateffecteventpacket, prop, 外部插件触发战斗特效
SignalDispatchableeventpacketonlinerewards, afkreward, 外部插件触发规则引擎信号
EventBusCapability宿主market, qqbot, 第三方/外部插件主题 pub/sub
AxsMarketServicemarket外部插件市场 UI/挂单/搜索
BattlePassAccessbattlepass外部插件战令经验/等级/档位/任务进度
FishingAccessfishing外部插件钓鱼状态/小游戏/经验/疲劳
RegionQueryableregions外部插件区域信息查询
BossTrackerQueryableentitytracker外部插件活跃 Boss 会话查询
LotteryAccesslottery外部插件抽奖积分/兑换/开箱
LoginViewQueryableloginview外部插件认证状态查询/打开登录界面
PropAccessibleprop外部插件道具列表/应用到主手
RgbRenderablergb外部插件渐变文本渲染
OnlineRewardsQueryableonlinerewards外部插件签到/在线时长查询
WarehouseAutoDepositablewarehousepickup, 外部插件仓库自动存入
ExtraBackpackAccessextrabackpack外部插件扩展背包访问
PickupNotifiable / PickupInterceptorpickupwarehouse, 外部插件拾取通知/拦截(分模式注册)
QQBotNotifiable / QQBotBroadcastable / QqBindCapableqqbot外部插件QQ 推送/群事件/绑定查询
EssentialsQueryableessentials外部插件基础工具查询
AfkRewardDispatchableafkreward外部插件挂机状态/原地挂机
InteractionStateconversation外部插件交互状态
MenuOpenablemenu外部插件打开菜单
SecondaryPasswordAccess宿主外部插件二级密码访问
PlayerDataPurgeable多模块宿主 /axs purge清除玩家数据
DatabaseMigratable多模块宿主 /axs migrate跨库迁移
PolygonSelectionCapability宿主/regionsfishing 等多边形选区管理
ModuleAdminCapability宿主调试工具模块管理(@Internal

"公开" = 标注 @PublicCapability,外部 Bukkit 插件可通过 AxsCapabilities.get() 获取;其余仅限 AXS 模块内部 getCapability 使用。