外观
📨 事件参考
事件继承 InvSyncEvent,基于 Bukkit Event/Cancellable。不是 EasyLib 事件类,不通过内部包访问。
事件表
| 事件 | 内容 / 时机 | 取消语义 |
|---|---|---|
PlayerDataSyncPreEvent | player,Join 之后主同步开始前,显式同步事件 | 可取消主同步;不能撤销已发生的预加载离线写 |
PlayerDataSyncDoneEvent | player、可空 data,正常同步完成;显式同步事件 | 继承可取消,但核心不使用取消结果,不撤销同步 |
PlayerDataSaveEvent | player、reason,生命周期保存门禁 | 可取消当前保存;退出场景可能释放锁,取消责任需由接入者承担 |
InvSyncPluginDataSaveEvent | player、pluginDataSync,Addon 保存后广播 | 不可取消,putData 写自己的键;事件本身没有 reason 属性 |
InvSyncPluginDataSyncEvent | player、pluginDataSync,Addon 应用后广播 | 不可取消,readData 读取 |
InvSyncSkipItemEvent | player、itemStack、可写 isSkip,采集物品时 | 不可取消,使用 isSkip,不是应用每个物品时触发 |
不可取消事件调用 setCancelled 会抛错,不是安静忽略。并非所有 API 保存入口都触发生命周期门禁;直接 savePlayerData 不能假设自动广播 PlayerDataSaveEvent。
同步完成监听
java
import com.xbaimiao.invsync.api.events.PlayerDataSyncDoneEvent;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
public final class SyncListener implements Listener {
@EventHandler
public void onDone(PlayerDataSyncDoneEvent event) {
// data 为 null 可以是首次无存档,不解引用假定总有数据。
boolean hasStoredSnapshot = event.getData() != null;
// 这里完成本服初始化;不要当作 DB 新写入完成或网络事务完成。
if (!hasStoredSnapshot) {
// 自己的默认值初始化策略。
}
}
}Listener 仍需在自己的插件注册。对 Folia 按实际玩家线程执行,不通过显式同步标志推断传统主线程。
保存原因
SaveReason 当前包含:
| 值 | 含义 |
|---|---|
DISCONNECT | 退出,包括跨服预保存,不保证玩家最终离开 |
WORLD_SAVE | 世界保存 |
COMMAND | 命令保存 |
SHUT_DOWN / SHUT_DOWN_HOOK | 关闭相关入口 |
AUTO_SAVE | 定时保存 |
MIGRATOR | 迁移 |
EDIT | 编辑或恢复 |
INIT | 内部预热,不能视为正常业务持久化 |
UNKNOWN | 其他 |
Addon onSave(event, reason) 才直接接收原因。监听 InvSyncPluginDataSaveEvent 时不要调用不存在的 getReason()。
原因与 Future
事件表示门禁/采集/应用时机,不代表 I/O 已完成。保存 Future 的语义见API。回调可能非玩家线程,发消息、打开 GUI、修改玩家必须重新调度。