EventWrapper - HimxhMC/HimDSL GitHub Wiki
EventWrapper
事件对象 / The Event Object
事件处理函数里的 event 参数是一个 EventWrapper,它包装了 Bukkit 的原始事件对象。通过它,你可以读取事件的具体信息:谁触发的、在哪里、涉及什么方块或物品。
The event parameter in an event handler is an EventWrapper wrapping the Bukkit event object. Use it to read event details: who, where, which block or item.
语法上就是 event.方法名(),和引用(p.xxx)的写法一致。
Syntactically it is event.method(), consistent with reference access (p.xxx).
读取事件数据 / Reading Event Data
常用的事件方法示例:
Common event methods:
@EventHandler
void onBreak(event(BlockBreakEvent)) {
player p = @s;
string blockType = event.getBlock().getType().name();
int x = event.getBlock().getX();
int y = event.getBlock().getY();
int z = event.getBlock().getZ();
runcmd("CONSOLE", "say " + p.name + " 破坏了 " + blockType
+ " @ (" + x + "," + y + "," + z + ")");
}
event.getBlock() 返回 Bukkit 的 Block 对象,可以继续调用它的方法。方法名与 Bukkit API 一致。
event.getBlock() returns a Bukkit Block; further methods chain off it. Method names match the Bukkit API.
常见事件的常用方法 / Common Methods by Event
| 事件 | 常用方法 |
|---|---|
PlayerJoinEvent |
getPlayer()、getJoinMessage() |
PlayerQuitEvent |
getPlayer()、getQuitMessage() |
BlockBreakEvent |
getPlayer()、getBlock() |
BlockPlaceEvent |
getPlayer()、getBlock()、getBlockPlaced() |
PlayerCommandPreprocessEvent |
getPlayer()、getMessage() |
InventoryClickEvent |
getWhoClicked()、getSlot()、getCurrentItem() |
PlayerInteractEvent |
getPlayer()、getAction()、getItem() |
PlayerMoveEvent |
getPlayer()、getFrom()、getTo() |
SignChangeEvent |
getPlayer()、getLines() |
| Event | Common methods |
|---|---|
PlayerJoinEvent |
getPlayer(), getJoinMessage() |
PlayerQuitEvent |
getPlayer(), getQuitMessage() |
BlockBreakEvent |
getPlayer(), getBlock() |
BlockPlaceEvent |
getPlayer(), getBlock(), getBlockPlaced() |
PlayerCommandPreprocessEvent |
getPlayer(), getMessage() |
InventoryClickEvent |
getWhoClicked(), getSlot(), getCurrentItem() |
PlayerInteractEvent |
getPlayer(), getAction(), getItem() |
PlayerMoveEvent |
getPlayer(), getFrom(), getTo() |
SignChangeEvent |
getPlayer(), getLines() |
表里只列常用项。完整列表见 Bukkit 官方文档。
Only common items listed. Full list in Bukkit docs.
event 与 @s 的关系 / event vs @s
很多事件都有 getPlayer(),返回的玩家就是 @s:
Many events have getPlayer(), which returns the same player as @s:
@EventHandler
void onJoin(event(PlayerJoinEvent)) {
player p1 = @s;
var p2 = event.getPlayer();
// p1 和 p2 指向同一个玩家
runcmd("CONSOLE", "say " + p1.name + " == " + p2.name);
}
用 @s 就够了。getPlayer() 主要在处理不通过 @s 拿到玩家的事件(例如 InventoryClickEvent 的 getWhoClicked())时才有必要。
@s suffices in most cases. getPlayer() matters when the event does not expose the player via @s (e.g. InventoryClickEvent.getWhoClicked()).
修改事件数据 / Modifying Event Data
有些事件可写。调用 setter 修改事件的行为:
Some events are writable. Setters change behavior:
@EventHandler
void onBreak(event(BlockBreakEvent)) {
player p = @s;
if (p.gamemode == "creative") {
event.setCancelled(true); // 取消这次破坏
}
}
setCancelled(true) 会阻止事件的发生——方块不会被破坏。这是事件系统最常用的功能之一。
setCancelled(true) prevents the event — the block is not broken. One of the most used features.
不是所有事件都可写。写入不可写的事件会报错。查官方文档确认。
Not all events are writable. Writing to a read-only event errors. Check the docs.
常见模式 / Common Patterns
拦截特定方块 / Blocking Specific Blocks
@EventHandler
void onPlace(event(BlockPlaceEvent)) {
player p = @s;
string type = event.getBlockPlaced().getType().name().toLowerCase();
if (type == "tnt" || type == "bedrock") {
event.setCancelled(true);
runcmd(p.name, "msg 你不能放置这个方块");
}
}
记录破坏日志 / Logging Block Breaks
@EventHandler
void onBreak(event(BlockBreakEvent)) {
player p = @s;
if (p.gamemode == "creative") return; // 忽略创造模式
int x = event.getBlock().getX();
int y = event.getBlock().getY();
int z = event.getBlock().getZ();
string type = event.getBlock().getType().name().toLowerCase();
string line = p.name + "|" + type + "|" + x + "," + y + "," + z;
fwritelines("break_log.txt", {line});
}
上面的例子每次写入一行。注意它会覆盖整个文件(fwritelines 的行为),生产环境应改成"追加"模式——但 HimDSL 目前只提供覆盖。这是它的局限,不要依赖它写日志。真要做日志,用别的方案。
The above overwrites the entire file each time (fwritelines behavior). For a real log, use another approach — HimDSL's file API only overwrites.
方法的限制 / Method Limits
事件方法通过反射调用。方法不存在或参数不匹配时会报错,不会静默失败。
Event methods go through reflection. Missing methods or mismatched arguments error, not silently fail.
event.getPlayer(); // ✓
event.getPlayerWrong(); // ✗ 报错
每个事件的可用方法只有官方定义的那些。不要猜,查文档。
Available methods are exactly what the official API declares. Do not guess; check the docs.
小结 / Summary
-
event是EventWrapper,通过event.方法()读取数据。 -
方法名与 Bukkit API 一致。
-
常用事件的方法见上表。
-
事件可写时,
setCancelled(true)阻止事件发生。 -
@s通常就够,event.getPlayer()只在没有@s时用到。 -
方法不存在会报错,查官方文档。
-
eventis anEventWrapper; read viaevent.method(). -
Method names match Bukkit.
-
See the table for common event methods.
-
For writable events,
setCancelled(true)prevents the event. -
@ssuffices usually;getPlayer()only when@sis unavailable. -
Missing methods error; consult the docs.
下一步 / Next Steps
下一章 @BukkitRunnable 讲定时任务——让代码每隔一段时间自动执行。
Next, @BukkitRunnable covers scheduled tasks — code that runs repeatedly.