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

251 lines
6.5 KiB
Markdown

---
title: Cancellable Events
type: docs
weight: 3
---
Some events implement the `ICancellable` interface, allowing you to prevent the default game behavior.
## The ICancellable Interface
```java
public interface ICancellable {
boolean isCancelled();
void setCancelled(boolean cancelled);
}
```
## ECS Cancellable Events
ECS events use a similar interface `ICancellableEcsEvent`:
```java
public interface ICancellableEcsEvent {
boolean isCancelled();
void setCancelled(boolean cancelled);
}
```
## Cancelling Events
```java
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
```java
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:
```java
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
```java
// 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:
```java
// 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:
```java
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
```java
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
```java
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
```java
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;
}
}
```