Skip to content

EventWrapper

Himxh edited this page Oct 4, 2026 · 1 revision

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 时用到。

  • 方法不存在会报错,查官方文档。

  • event is an EventWrapper; read via event.method().

  • Method names match Bukkit.

  • See the table for common event methods.

  • For writable events, setCancelled(true) prevents the event.

  • @s suffices usually; getPlayer() only when @s is unavailable.

  • Missing methods error; consult the docs.


下一步 / Next Steps

下一章 @BukkitRunnable 讲定时任务——让代码每隔一段时间自动执行。

Next, @BukkitRunnable covers scheduled tasks — code that runs repeatedly.


HimDSL 文档 / Documentation

入门 / Getting Started

语言基础 / Language Basics

控制流 / Control Flow

函数 / Functions

数据结构 / Data Structures

自定义类型 / Custom Types

Minecraft 集成 / Minecraft Integration

事件与调度 / Events & Scheduling

GUI 系统 / GUI System

内置函数参考 / Built-ins Reference

进阶 / Advanced

扩展 API / Extension API

你真的需要 API 吗?/ Do you really need the API?

Clone this wiki locally