Repository navigation
EventWrapper
事件处理函数里的 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).
常用的事件方法示例:
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.
| 事件 | 常用方法 |
|---|---|
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.
很多事件都有 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()).
有些事件可写。调用 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.
@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 你不能放置这个方块");
}
}
@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.
事件方法通过反射调用。方法不存在或参数不匹配时会报错,不会静默失败。
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.
-
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.
下一章 @BukkitRunnable 讲定时任务——让代码每隔一段时间自动执行。
Next, @BukkitRunnable covers scheduled tasks — code that runs repeatedly.
- 首页 / Home
- 安装与快速开始 / Installation & Quick Start
- 第一个脚本 / Your First Script
- 命令速查 / Command Reference
- 自动执行脚本 / Auto-run Scripts
- 定义函数 / Defining Functions
- 函数重载 / Function Overloading
- Lambda 表达式 / Lambda Expressions
- 函数式接口 / Functional Interfaces
- 选择器总览 / Selectors Overview
- 选择器过滤器 / Selector Filters
- EntityRef 引用 / EntityRef
- 占位符参考 / Placeholders Reference
- PlaceholderAPI 桥接 / PAPI Bridge
- 创建 GUI / Creating a GUI
- GUISlot 槽位 / GUISlot
- 点击回调 / Click Callbacks
- onClose 回调 / onClose Callback
- GUI 刷新 / GUI Refresh
- 数学函数 / Math Built-ins
- 高精度计算 / BigDecimal Built-ins
- 字符串函数 / String Built-ins
- 集合函数 / Collection Built-ins
- 文件 I/O / File I/O
- 命令与 sleep / Commands & sleep