Files
Documentation/content/core-concepts/events/cancellable-events.fr.md
2026-01-20 20:33:59 +01:00

6.5 KiB

title, type, weight
title type weight
Cancellable Events docs 3

Some events implement the ICancellable interface, allowing you to prevent the default game behavior.

The ICancellable Interface

public interface ICancellable {
    boolean isCancelled();
    void setCancelled(boolean cancelled);
}

ECS Cancellable Events

ECS events use a similar interface ICancellableEcsEvent:

public interface ICancellableEcsEvent {
    boolean isCancelled();
    void setCancelled(boolean cancelled);
}

Cancelling Events

getEventRegistry().register(BreakBlockEvent.class, event -> {
    Vector3i position = event.getTargetBlock();

    if (isProtectedArea(position)) {
        event.setCancelled(true);
        // Note: BreakBlockEvent doesn't have direct player access
        // Use ECS components if you need to message the player
    }
});

Checking Cancellation Status

getEventRegistry().register(EventPriority.LATE, BreakBlockEvent.class, event -> {
    if (event.isCancelled()) {
        // Another handler cancelled this event
        return;
    }

    // Process the event
    recordBlockBreak(event.getTargetBlock(), event.getBlockType());
});

Common Cancellable Events

Player Events

Event Cancel Effect
PlayerSetupConnectEvent Prevents player from connecting
PlayerChatEvent Prevents message from being sent
PlayerMouseButtonEvent Prevents mouse button action
PlayerInteractEvent Prevents interaction (deprecated)

ECS Block Events

Event Cancel Effect
BreakBlockEvent Prevents block from being broken
PlaceBlockEvent Prevents block from being placed
DamageBlockEvent Prevents damage to block
UseBlockEvent.Pre Prevents block use action

Other ECS Events

Event Cancel Effect
DropItemEvent Prevents item from being dropped
CraftRecipeEvent Prevents crafting

Best Practices

Check Before Acting

Always check isCancelled() before performing actions:

getEventRegistry().register(BreakBlockEvent.class, event -> {
    // Check if already cancelled
    if (event.isCancelled()) {
        return;
    }

    // Your logic here
    if (shouldPrevent(event.getTargetBlock())) {
        event.setCancelled(true);
    }
});

Use Appropriate Priority

// Protection plugins should use EARLY
getEventRegistry().register(EventPriority.EARLY, BreakBlockEvent.class, event -> {
    if (isProtected(event.getTargetBlock())) {
        event.setCancelled(true);
    }
});

// Feature plugins should respect cancellation
getEventRegistry().register(EventPriority.NORMAL, BreakBlockEvent.class, event -> {
    if (!event.isCancelled()) {
        giveBlockReward(event.getTargetBlock());
    }
});

// Logging should use LATE
getEventRegistry().register(EventPriority.LATE, BreakBlockEvent.class, event -> {
    logBlockBreakAttempt(event.getTargetBlock(), event.isCancelled());
});

Provide Feedback with Chat Events

When cancelling chat events, you can notify the player:

// Note: PlayerChatEvent has String key, use registerAsyncGlobal()
getEventRegistry().registerAsyncGlobal(PlayerChatEvent.class, future -> {
    return future.thenApply(event -> {
        if (containsBadWord(event.getContent())) {
            event.setCancelled(true);

            // Send message via PlayerRef (PlayerRef.sendMessage() works)
            event.getSender().sendMessage(Message.raw("Please don't use that word!"));
        }
        return event;
    });
});

Uncancelling Events

You can also uncancel an event that was previously cancelled:

getEventRegistry().register(EventPriority.LATE, BreakBlockEvent.class, event -> {
    // Override cancellation for certain block types
    if (event.isCancelled() && event.getBlockType().getId().equals("temporary_block")) {
        event.setCancelled(false);
    }
});

{{< callout type="warning" >}} Uncancelling events can cause conflicts with other plugins. Use sparingly and document this behavior. {{< /callout >}}

Example: Connection Whitelist

public class WhitelistPlugin extends JavaPlugin {

    private final Set<UUID> whitelist = new HashSet<>();

    @Override
    public void start() {
        // Cancel connection for non-whitelisted players
        getEventRegistry().register(PlayerSetupConnectEvent.class, event -> {
            if (!whitelist.contains(event.getUuid())) {
                event.setCancelled(true);
                event.setReason("You are not whitelisted on this server!");
            }
        });
    }

    public void addToWhitelist(UUID uuid) {
        whitelist.add(uuid);
    }

    public void removeFromWhitelist(UUID uuid) {
        whitelist.remove(uuid);
    }
}

Example: Chat Filter

public class ChatFilterPlugin extends JavaPlugin {

    private final Set<String> bannedWords = new HashSet<>();

    @Override
    public void start() {
        loadBannedWords();

        // Note: PlayerChatEvent has String key, use registerAsyncGlobal()
        getEventRegistry().registerAsyncGlobal(PlayerChatEvent.class, future -> {
            return future.thenApply(event -> {
                String message = event.getContent().toLowerCase();

                for (String banned : bannedWords) {
                    if (message.contains(banned)) {
                        event.setCancelled(true);
                        // Send message via PlayerRef
                        event.getSender().sendMessage(Message.raw("Your message was blocked!"));
                        break;
                    }
                }
                return event;
            });
        });
    }
}

Example: Block Protection

public class ProtectionPlugin extends JavaPlugin {

    private final Set<Vector3i> protectedBlocks = new HashSet<>();

    @Override
    public void start() {
        // Register at EARLY to cancel before other plugins process
        getEventRegistry().register(EventPriority.EARLY, BreakBlockEvent.class, event -> {
            if (protectedBlocks.contains(event.getTargetBlock())) {
                event.setCancelled(true);
            }
        });

        getEventRegistry().register(EventPriority.EARLY, PlaceBlockEvent.class, event -> {
            if (isProtectedArea(event.getTargetBlock())) {
                event.setCancelled(true);
            }
        });
    }

    private boolean isProtectedArea(Vector3i pos) {
        // Check if position is in a protected region
        return false;
    }
}