自定义事件

You can write your own event classes and dispatch those events using the method described above. An event class must extend the Event class. Depending on the exact nature of the event, more interfaces should be implemented, like Cancellable for events that can be cancelled by a listener or interfaces like AffectEntityEvent clarifying what sort of object is affected by your event.

小技巧

You can extend AbstractEvent for common methods to be implementated for you

示例:自定义事件类

下面这个类描述了一个表示 :javadoc:ServerPlayer``接触 FLARD 后以事件指定的方式进行变化的事件。因为这个事件可以取消,所以它实现了 ``Cancellable 接口。

因为一般的自定义事件旨在使其他插件监听,所以最好的办法自然是把它们以合适的方式整理归类。我们可以在 Cause 类中找到一串对象用于表示事件的来源。在下面的示例中,我们虚构了一个 FLARDSource 类用于表示事件的来源信息,并作为根对象包含于事件原因(Cause)中。

import org.spongepowered.api.entity.living.player.server.ServerPlayer;
import org.spongepowered.api.event.Cancellable;
import org.spongepowered.api.event.Cause;
import org.spongepowered.api.event.impl.AbstractEvent;

public class PlayerMutationEvent extends AbstractEvent implements Cancellable {

    public enum Mutation {
        COMPULSIVE_POETRY,
        ROTTED_SOCKS,
        SPONTANEOUS_COMBUSTION;
    };

    private final Cause cause;
    private final ServerPlayer victim;
    private final Mutation mutation;
    private boolean cancelled = false;

    public PlayerMutationEvent(ServerPlayer victim, Mutation mutation, Cause cause) {
        this.victim = victim;
        this.mutation = mutation;
        this.cause = cause;
    }

    public ServerPlayer victim() {
        return this.victim;
    }

    public Mutation mutation() {
        return this.mutation;
    }

    @Override
    public boolean isCancelled() {
        return this.cancelled;
    }

    @Override
    public void setCancelled(boolean cancel) {
        this.cancelled = cancel;
    }

    @Override
    public Cause cause() {
        return this.cause;
    }
}

示例:发布自定义事件

import org.spongepowered.api.event.Cause;
import org.spongepowered.api.event.EventContext;
import org.spongepowered.api.event.EventContextKeys;
import org.spongepowered.api.Sponge;

PluginContainer plugin = ...;
EventContext eventContext = EventContext.builder().add(EventContextKeys.PLUGIN, plugin).build();

PlayerMutationEvent event = new PlayerMutationEvent(victim, PlayerMutationEvent.Mutation.ROTTED_SOCKS,
        Cause.of(eventContext, plugin));
Sponge.eventManager().post(event);
if (!event.isCancelled()) {
    // Mutation code
}

必须谨记,您必须提供一个非空的事件原因。如果您的事件是可取消的,请确保它在取消之前不会执行相应的操作。

示例:监听自定义事件

import net.kyori.adventure.text.Component;
import org.spongepowered.api.event.Listener;

@Listener
public void onPrivateMessage(PlayerMutationEvent event) {
    if (event.mutation() == PlayerMutationEvent.Mutation.SPONTANEOUS_COMBUSTION) {
        event.setCancelled(true);
        event.victim().sendMessage(Component.text("You cannot combust here, this is a non-smoking area!"));
    }
}