事件 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,加了两条约束:
- 一次性:
canPost标志在post()开头置false,同一个事件对象只能 post 一次,重复 post 直接返回false且不再派发 - 可选日志:
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未计入。