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

218 lines
6.1 KiB
Markdown

---
title: Event System
type: docs
weight: 1
---
Hytale uses an event-driven architecture where your plugin can subscribe to and react to game events.
## The EventBus
The `EventBus` is the central hub for all events. It manages event registration and dispatching.
## Registering Event Listeners
Use the `EventRegistry` from your plugin to register listeners:
```java
@Override
public void start() {
// Lambda syntax - PlayerReadyEvent fires when player is fully loaded
// Note: PlayerReadyEvent has a String key, so use registerGlobal()
getEventRegistry().registerGlobal(PlayerReadyEvent.class, event -> {
Player player = event.getPlayer();
getLogger().at(Level.INFO).log("Player ready: " + player.getDisplayName());
});
// Method reference
getEventRegistry().register(PlayerDisconnectEvent.class, this::onPlayerDisconnect);
}
private void onPlayerDisconnect(PlayerDisconnectEvent event) {
PlayerRef playerRef = event.getPlayerRef();
getLogger().at(Level.INFO).log("Player left: " + playerRef.getUsername());
}
```
## Registration Methods
### Basic Registration
```java
// Register with default priority (NORMAL)
getEventRegistry().register(PlayerConnectEvent.class, event -> {
// Handle event
});
```
{{< callout type="warning" >}}
**Important:** The simple `register(Class, Consumer)` method only works for events with a `Void` key type (like `PlayerConnectEvent`). For keyed events (like `PlayerReadyEvent` which has a `String` key), you must use `registerGlobal()` instead. Check the event's type parameter to determine which method to use.
{{< /callout >}}
### With Priority
```java
// Register with specific priority
getEventRegistry().register(EventPriority.EARLY, PlayerConnectEvent.class, event -> {
// This runs before NORMAL priority handlers
});
```
### With Key
Some events support key-based registration for filtering:
```java
// Only listen to events for a specific key
getEventRegistry().register(SomeKeyedEvent.class, myKey, event -> {
// Only called when event key matches myKey
});
```
### Global Registration
Listen to all events of a type, regardless of key:
```java
getEventRegistry().registerGlobal(KeyedEvent.class, event -> {
// Called for all instances of this event
});
```
### Unhandled Registration
Handle events that weren't processed by any key-specific listener:
```java
getEventRegistry().registerUnhandled(KeyedEvent.class, event -> {
// Called when no specific handler matched
});
```
### Async Global and Unhandled
For async events with global or unhandled registration:
```java
// Async global - all keys
getEventRegistry().registerAsyncGlobal(AsyncKeyedEvent.class, future ->
future.thenApply(event -> {
// Process async
return event;
})
);
// Async unhandled - unmatched keys
getEventRegistry().registerAsyncUnhandled(AsyncKeyedEvent.class, future ->
future.thenApply(event -> {
// Handle unmatched
return event;
})
);
```
## EventRegistration
Registration methods return an `EventRegistration` object:
```java
EventRegistration<?, PlayerConnectEvent> registration =
getEventRegistry().register(PlayerConnectEvent.class, this::onConnect);
// Later, you can unregister manually if needed
registration.unregister();
```
{{< callout type="info" >}}
Event registrations are automatically cleaned up when your plugin shuts down. Manual unregistration is rarely needed.
{{< /callout >}}
## Event Interface Hierarchy
Events implement different interfaces based on their capabilities:
| Interface | Description |
|-----------|-------------|
| `IBaseEvent<K>` | Base interface for all events |
| `IEvent<K>` | Synchronous events |
| `IAsyncEvent<K>` | Asynchronous events |
| `ICancellable` | Events that can be cancelled |
| `ICancellableEcsEvent` | ECS events that can be cancelled |
## Getting Registered Events
Query which events are registered:
```java
// Get all registered event classes
Set<Class<? extends IBaseEvent<?>>> eventClasses =
HytaleServer.get().getEventBus().getRegisteredEventClasses();
// Get registered event names
Set<String> eventNames =
HytaleServer.get().getEventBus().getRegisteredEventClassNames();
// Get a specific registry by name
EventBusRegistry<?, ?, ?> registry =
HytaleServer.get().getEventBus().getRegistry("PlayerConnectEvent");
```
## Complete Example
```java
public class WelcomePlugin extends JavaPlugin {
public WelcomePlugin(JavaPluginInit init) {
super(init);
}
@Override
public void start() {
// Handle player connection
getEventRegistry().register(PlayerConnectEvent.class, event -> {
PlayerRef playerRef = event.getPlayerRef();
getLogger().at(Level.INFO).log("Player connecting: " + playerRef.getUsername());
// You can set the world the player spawns in
World lobbyWorld = Universe.get().getWorld("lobby");
if (lobbyWorld != null) {
event.setWorld(lobbyWorld);
}
});
// Welcome message when fully ready
// Note: PlayerReadyEvent has a String key, so use registerGlobal()
getEventRegistry().registerGlobal(PlayerReadyEvent.class, event -> {
Player player = event.getPlayer();
player.sendMessage(Message.raw("Welcome to the server, " + player.getDisplayName() + "!"));
});
// Goodbye message on disconnect
getEventRegistry().register(PlayerDisconnectEvent.class, event -> {
PlayerRef playerRef = event.getPlayerRef();
getLogger().at(Level.INFO).log(playerRef.getUsername() + " has left the server");
});
}
}
```
## Player Event Lifecycle
Understanding when each event fires:
```
PlayerSetupConnectEvent → Can cancel/redirect connection
PlayerConnectEvent → Player connecting, set spawn world
AddPlayerToWorldEvent → Player added to world
PlayerReadyEvent → Player fully loaded, safe to interact
(gameplay events)
DrainPlayerFromWorldEvent → Player leaving world
PlayerDisconnectEvent → Player disconnected
```