事件 API

基本信息

属性 值
包路径 serverutils.events
源码目录 src/main/java/serverutils/events/
文件总数 38(git ls-files 'src/main/java/serverutils/events/**/*.java' | grep -v package-info | wc -l)
事件类 37
接口 1(IReloadHandler)
事件总线 MinecraftForge.EVENT_BUS(cpw.mods.fml.common.eventhandler.Event 子类)
基类 serverutils.lib.EventBase

事件基类

EventBase(src/main/java/serverutils/lib/EventBase.java:8-27)继承 Forge 的 Event,加了两条约束:

  1. 一次性:canPost 标志在 post() 开头置 false,同一个事件对象只能 post 一次,重复 post 直接返回 false 且不再派发
  2. 可选日志:debugging.log_events 开启时打印 Event <类名> fired, cancelled: <结果>

post() 的返回值即 MinecraftForge.EVENT_BUS.post(this) 的结果,即「是否被取消」。

继承树

EventBase                                   (lib/EventBase.java)
 └─ ServerUtilitiesEvent                    (events/ServerUtilitiesEvent.java)
     ├─ UniverseEvent                       (events/universe/UniverseEvent.java)
     │   ├─ UniverseClearCacheEvent
     │   ├─ UniverseClosedEvent
     │   ├─ UniverseLoadedEvent
     │   ├─ UniverseSavedEvent
     │   ├─ ForgeTeamEvent                  (events/team/ForgeTeamEvent.java)
     │   │   ├─ ForgeTeamChangedEvent
     │   │   ├─ ForgeTeamConfigEvent
     │   │   │   └─ ForgeTeamConfigSavedEvent
     │   │   ├─ ForgeTeamCreatedEvent
     │   │   ├─ ForgeTeamDataEvent
     │   │   ├─ ForgeTeamDeletedEvent
     │   │   ├─ ForgeTeamLoadedEvent
     │   │   ├─ ForgeTeamOwnerChangedEvent
     │   │   └─ ForgeTeamSavedEvent
     │   ├─ ForgePlayerEvent                (events/player/ForgePlayerEvent.java)
     │   │   ├─ ForgePlayerConfigEvent
     │   │   │   └─ ForgePlayerConfigSavedEvent
     │   │   ├─ ForgePlayerDataEvent
     │   │   ├─ ForgePlayerLoadedEvent
     │   │   ├─ ForgePlayerLoggedInEvent
     │   │   ├─ ForgePlayerLoggedOutEvent
     │   │   ├─ ForgePlayerSavedEvent
     │   │   ├─ ForgeTeamPlayerJoinedEvent
     │   │   └─ ForgeTeamPlayerLeftEvent
     │   └─ ServerReloadEvent
     ├─ ChunkModifiedEvent
     ├─ UpdateClientDataEvent
     ├─ CustomClickEvent
     ├─ CustomPermissionPrefixesRegistryEvent
     ├─ LeaderboardRegistryEvent
     ├─ RegisterRankConfigEvent
     ├─ RegisterRankConfigHandlerEvent
     ├─ ServerUtilitiesPreInitRegistryEvent
     ├─ SidebarButtonCreatedEvent
     └─ SyncGamerulesEvent

[!NOTE] ForgePlayerEvent extends ForgeTeamEvent(不是直接继承 UniverseEvent)—— 玩家事件携带所属队伍上下文。 ForgeTeamPlayerJoinedEvent / ForgeTeamPlayerLeftEvent 虽然名字带 Team,但继承的是 ForgePlayerEvent(events/player/ 包下),而非 ForgeTeamEvent。订阅时注意别选错父类型。

生命周期事件(28 个)

Universe(4) — events/universe/

类 触发时机
UniverseLoadedEvent Universe 数据加载完成
UniverseClosedEvent Universe 关闭
UniverseSavedEvent Universe 存档写入
UniverseClearCacheEvent 缓存被清空(重建索引时)

Team(11) — events/team/

类 触发时机
ForgeTeamCreatedEvent 新队伍创建(/team create 流程中 post)
ForgeTeamDeletedEvent 队伍删除
ForgeTeamChangedEvent 队伍数据变更
ForgeTeamLoadedEvent 队伍从存档加载
ForgeTeamSavedEvent 队伍存档写入
ForgeTeamDataEvent 队伍底层数据变化
ForgeTeamOwnerChangedEvent 队长更替(/team transfer_ownership)
ForgeTeamConfigEvent 队伍配置被打开编辑
ForgeTeamConfigSavedEvent 队伍配置保存

Player(8) — events/player/

类 触发时机
ForgePlayerLoadedEvent 玩家数据加载
ForgePlayerLoggedInEvent 玩家进服
ForgePlayerLoggedOutEvent 玩家退服
ForgePlayerSavedEvent 玩家数据存档
ForgePlayerDataEvent 玩家底层数据变化
ForgePlayerConfigEvent 玩家个人配置被编辑
ForgePlayerConfigSavedEvent 玩家个人配置保存
ForgeTeamPlayerJoinedEvent 玩家加入队伍
ForgeTeamPlayerLeftEvent 玩家离开队伍

Chunk(2) — events/chunks/

类 触发时机
ChunkModifiedEvent 领地数据变更(领取/取消/加载变更)
UpdateClientDataEvent 需要向客户端推送数据

扩展点事件(8 个)

这些不是「发生了什么」的通知,而是让外部模组往模组里注册东西的钩子。它们都接受一个 Consumer,在 post() 时把注册器交给监听者。

类 Consumer 类型 用途
ServerUtilitiesPreInitRegistryEvent 内嵌 Registry 接口 preInit 阶段注册资源(getRegistry())
CustomPermissionPrefixesRegistryEvent Consumer<NodeEntry> 追加权限前缀
LeaderboardRegistryEvent Consumer<Leaderboard> 注册自定义排行榜
RegisterRankConfigEvent Consumer<RankConfigValueInfo> 追加 rank 可配置项
RegisterRankConfigHandlerEvent Consumer<IRankConfigHandler> 替换 rank 处理器(setHandler)
SyncGamerulesEvent Consumer<String> 声明需同步的游戏规则
SidebarButtonCreatedEvent 直接构造 侧边栏按钮创建后(getButton())
CustomClickEvent — 侧边栏 custom: 点击动作

CustomPermissionPrefixesRegistryEvent 提供两个重载(:16、:20):register(NodeEntry) 与 register(String node, DefaultPermissionLevel level, String desc)。

RegisterRankConfigEvent 提供 3 个重载:消费回调版(:16)、(id, defaultPlayerValue, defaultOPValue)(:20)、(id, defaultValue)(:26)。

CustomPermissionPrefixesRegistryEvent 的实际触发点

// ServerUtilitiesPermissions.java:388
new CustomPermissionPrefixesRegistryEvent(CUSTOM_PERM_PREFIX::add).post();

在 registerPrefixes() 末尾触发。5 个模组自带前缀先注册,再由监听者追加 —— 外部模组无法覆盖自带前缀,只能追加。

LeaderboardRegistryEvent 的实际触发点

// ServerUtilitiesLeaderboards.java:83
new LeaderboardRegistryEvent(ServerUtilitiesLeaderboards::registerLeaderboard).post();

在 loadLeaderboards() 末尾,位于 4 个内置排行榜注册与 loadFromFile() 之后。外部注册的排行榜同样会自动获得 serverutilities.leaderboard.<modid>.<id> 权限节点(ServerUtilitiesPermissions.getLeaderboardNode(),ServerUtilitiesPermissions.java:427-431)。

重载事件

ServerReloadEvent extends UniverseEvent(events/ServerReloadEvent.java:14)是 /reload 的核心:

成员 说明
ALL 静态常量 new ResourceLocation("*:*")(:16),表示全部重载
构造函数 (Universe, ICommandSender, EnumReloadType, ResourceLocation id, HashSet<ResourceLocation> failed)(:25)
getSender() / getType() 触发者与重载类型
setClientReloadRequired() 要求客户端也重载
reload(ResourceLocation) 供每个 IReloadHandler 查询自己是否该重载

ServerUtilitiesAPI.reloadServer()(lib/data/ServerUtilitiesAPI.java:34-...)遍历 ServerUtilitiesRegistry.RELOAD_IDS,对每个 handler:

  • event.reload(id) 为真且 handler.onReload(event) 返回 false → event.failedToReload(id)
  • handler 抛异常 → 同样标记失败,且只有 debugging.print_more_errors 开启时才 printStackTrace()(:51-56)

IReloadHandler(events/IReloadHandler.java:4)是本目录唯一的非事件文件,定义 onReload 契约。

事件计数核验

统计 值 方法
目录内文件(排除 package-info) 38 git ls-files 'src/main/java/serverutils/events/**/*.java'
事件类 37 38 减去 IReloadHandler(接口)
生命周期事件 28 universe 4 + team 11 + player 8 + chunks 2 = 25,另有 ServerUtilitiesEvent 直系 3(ChunkModifiedEvent、UpdateClientDataEvent、CustomClickEvent)
扩展点事件 8 ServerUtilitiesPreInitRegistryEvent、CustomPermissionPrefixesRegistryEvent、LeaderboardRegistryEvent、RegisterRankConfigEvent、RegisterRankConfigHandlerEvent、SyncGamerulesEvent、SidebarButtonCreatedEvent、CustomClickEvent
抽象基类 4 ServerUtilitiesEvent、UniverseEvent、ForgeTeamEvent、ForgePlayerEvent

[!NOTE] 生命周期/扩展点是按用途分类的,同一个类可能在两栏中出现(如 CustomClickEvent 既是 ServerUtilitiesEvent 直系也是扩展点)。events 目录共 5 个 package-info.java 未计入。

相关条目