Init
This commit is contained in:
217
content/core-concepts/events/event-system.fr.md
Normal file
217
content/core-concepts/events/event-system.fr.md
Normal file
@@ -0,0 +1,217 @@
|
||||
---
|
||||
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
|
||||
```
|
||||
Reference in New Issue
Block a user