Writing a Event Handler
Event handlers are one of the main functions of plugins. They allow a plugin to tap into the internal workings of the server and alter its behavior to perform some other action. For a simple example, we will implement a handler for the PlayerJoinEvent and the PlayerLeaveEvent.
Implementing an Event
Individual event handlers are just structs which implement the EventHandler<E> trait (where E is a specific event data).
What are blocking events?
The Pumpkin plugin event system differentiates between two types of events: blocking and non-blocking. Each have their benefits:
Blocking events
Pros:
+ Can modify the event (like editing the join message)
+ Can cancel the event
+ Have a priority system
Cons:
- Are executed in sequence
- Can slow down the server if not implemented wellNon-blocking events
Pros:
+ Are executed concurrently
+ Are executed after all blocking events finish
+ Can still do some modifications (anything that is behind a Mutex or RwLock)
Cons:
- Cannot cancel the event
- Have no priority system
- Allow for less control over the eventWriting a handler
Since our main aim here is to change the welcome message that the player sees when they join a server, we will be choosing the blocking event type with a normal priority.
use pumpkin_plugin_api::{
Context, Plugin, PluginMetadata, Server,
events::{EventData, EventHandler, EventPriority, PlayerJoinEvent},
text::TextComponent,
};
use tracing::*;
struct MyJoinHandler;
impl EventHandler<PlayerJoinEvent> for MyJoinHandler {
fn handle<'a>(
&'a self,
server: Server,
mut event: EventData<PlayerJoinEvent>,
) -> EventData<PlayerJoinEvent> {
event.join_message = TextComponent::text("Hello, world!");
event
}
}Explanation:
struct MyJoinHandler;: The struct for our event handler- If the event is non-blocking, we still use the handle function, and return the event data. The event data will still be ignored.
Registering the handler
Now that we have written the event handler, we need to tell the plugin to use it. We can do that by adding a single line into the on_load method:
struct HelloPlugin;
impl Plugin for HelloPlugin {
fn new() -> Self {
HelloPlugin
}
fn metadata(&self) -> PluginMetadata {
// ...
}
fn on_load(&mut self, context: Context) -> pumpkin_plugin_api::Result<()> {
info!("Hello from the example plugin!");
context.register_event_handler(MyJoinHandler, EventPriority::Normal, true)?;
Ok(())
}
fn on_unload(&mut self, _context: Context) -> pumpkin_plugin_api::Result<()> {
info!("Example plugin unloaded. Goodbye!");
Ok(())
}
}Now if we build the plugin and join the server, we should see a "Hello, World!" message!
Adding a leave event
As an exercise for the reader, try adding a PlayerLeaveEvent