Skip to content

PySpigot 事件

PySpigot 目前有四个事件,您可以在插件中监听这些事件。

Note

可能 脚本事件可能会在异步环境中触发(例如,如果在异步任务中发生脚本异常)。要检查事件是否在异步环境中,请使用 script.isAsynchronous()。此方法在事件上下文为异步时返回 true,否则返回 false

ScriptEvent

这是 PySpigot 的基本脚本事件。当脚本加载、卸载或脚本中发生异常时,将触发此事件。下面详细介绍的 ScriptExceptionEventScriptLoadEventScriptUnloadEvent 都是此事件的子类。

调用 event.getScript() 来获取与事件关联的脚本。

ScriptExceptionEvent

当脚本内发生异常(无论是 Java 异常还是 Python 异常)时,将调用此事件。

此事件有四种可用方法:

  • event.getScript(): 获取抛出异常的脚本。
  • event.getException(): 返回表示抛出的异常的 PyException 对象。
  • event.doReportException(): 如果应将异常记录到控制台和脚本的日志文件,则返回 true,否则返回 false
  • event.setReportException(boolean reportException): 设置是否将异常记录到控制台和脚本的日志文件。

ScriptLoadEvent

当一个脚本加载时,将调用此事件。仅当脚本成功加载时(即 RunResultRunResult.SUCCESS)才会触发此事件。

调用 event.getScript() 来获取与事件关联的脚本。

ScriptUnloadEvent

当一个脚本被卸载时,将调用此事件。

调用event.getScript()以获取与事件相关联的脚本。

自定义脚本事件

PySpigot还包括了一个自定义事件(CustomEvent),脚本可以实例化并调用该事件。这个事件旨在实现脚本和插件之间更轻松的互动。

这个事件可以像任何其他Bukkit/Spigot事件一样进行监听。它包含几个可供使用的方法:

  • event.getScript(): 获取创建并调用此事件的脚本。
  • event.getName(): 获取此事件的“名称”。这个变量可用于提高自定义事件的细粒度。由于多个脚本可以使用此事件进行不同目的,事件名称可用于区分不同的用例。
  • event.getData(): 获取附加到此事件的数据。这将返回一个PyObject,在大多数情况下可以简单地转换为Java类型。
  • event.getDataAsType(String clazz): 将附加到事件的数据作为提供的类名的实例获取。如果无法将PyObject数据转换为适当的Java类型,此方法将非常有用。
  • event.getDataAsType(Class<T> clazz): 将附加到事件的数据作为提供的类的实例获取。如果无法将PyObject数据转换为适当的Java类型,此方法将非常有用。

CustomEvent还实现了Cancellable,因此event.isCancelled()event.setCancelled(boolean cancelled)也可供使用。

警告

CustomEvent应该仅从脚本中实例化。试图在脚本上下文之外实例化事件将导致异常。

类型转换

Jython 通常在从 Python 上下文转向 Java 上下文时自动处理类型转换。正如前面所述,大多数 Python 类型可以简单地转换为 Java 类型。如果无法转换,请尝试使用 CustomEvent 中的一个 event.getDataAsType 方法手动将 PyObject 转换为所需的类型。如果这种方法不起作用,那么这些类型可能不可互换,您将需要为数据使用不同的类型。要查看 Python 类型及其对应的 Java 类型的完整列表,请参阅 类型转换 页面。

代码示例

考虑以下 PySpigot 脚本:

1
2
3
4
5
6
7
8
from dev.magicmq.pyspigot.event.custom import CustomEvent
from org.bukkit import Bukkit

dictionary = {'test': '1', 'test2': '2'} # (1)!

event = CustomEvent('test_event', dictionary) # (2)!

Bukkit.getPluginManager().callEvent(event) # (3)!
  1. 在这里,我们创建一个新的 dict 并填充一些数据。

  2. 在这里,我们创建一个 CustomEvent 的新实例,将“test_event”作为名称赋给它,并将之前创建的字典作为数据。

  3. 在这里,我们通过 Bukkit 的插件管理器调用事件。

然后,在 Java 插件中,我们可以为此事件创建一个事件监听器,处理事件并对附加到其中的数据执行操作:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
import org.bukkit.event.Listener;
import org.bukkit.event.EventHandler;
import dev.magicmq.pyspigot.event.custom.CustomEvent

public class PluginListener implements Listener {

    @EventHandler
    public void onCustomEvent(CustomEvent event) {
        String name = event.getName();
        if (name.equals("test_event")) { // (1)!
            PyObject data = event.getData()
            Map data_map = (Map) data; // (2)!
1
2
3
4
5
        for (Object key : data_map.keySet()) { // (3)!
            System.out.println(key + ": " + data_map.get(key));
        }
    }
}
  1. 在这里,我们检查事件名称是否等于"test_event",这是当我们从脚本中调用事件时分配的名称。再次使用事件名称是有用的,如果有多个脚本利用CustomEvent,因为脚本可能根据上下文设置不同的名称,插件可以检查名称,就像这里所做的那样。

  2. 在这里,我们将数据​​转换为一个map。由于我们知道来自此事件的数据是Python的 dict,因此我们可以安全地进行强制转换,因为Python的dict类型相当于Jython中的Java Map

  3. 在这里,我们循环遍历map中的每个元素,并打印键及其相关值。

结论

请查看完整的脚本事件API文档PySpigot JavaDocs