Overview
The event system in Pumpkin allows plugins to respond to game events. Events are dispatched through the PluginManager and handled by registered EventHandler implementations.
EventHandler Trait
pub trait EventHandler<E: Payload>: Send + Sync {
fn handle<'a>(&'a self, server: &'a Arc<Server>, event: &'a E) -> BoxFuture<'a, ()> {
Box::pin(async {})
}
fn handle_blocking<'a>(
&'a self,
server: &'a Arc<Server>,
event: &'a mut E,
) -> BoxFuture<'a, ()> {
Box::pin(async {})
}
}
handle
Handles a non-blocking event (read-only access).
Reference to the server instance
Immutable reference to the event
handle_blocking
Handles a blocking event (can modify event data).
Reference to the server instance
Mutable reference to the event
EventPriority
pub enum EventPriority {
Highest,
High,
Normal,
Low,
Lowest,
}
Events are executed in priority order. Lower priority values execute first, allowing higher priority events to override changes.
Executed last, can see/override all other handler changes
Executed after Normal handlers
Executed before Normal handlers
Payload Trait
pub trait Payload: Send + Sync {
fn get_name_static() -> &'static str where Self: Sized;
fn get_name(&self) -> &'static str;
fn as_any(&self) -> &dyn Any;
fn as_any_mut(&mut self) -> &mut dyn Any;
}
All events must implement the Payload trait for type-safe event handling.
Cancellable Trait
pub trait Cancellable: Send + Sync {
fn cancelled(&self) -> bool;
fn set_cancelled(&mut self, cancelled: bool);
}
Events that can be cancelled implement this trait.
Event Types
Player Events
All player events are located in pumpkin::plugin::player::
PlayerJoinEvent
pub struct PlayerJoinEvent {
pub player: Arc<Player>,
pub join_message: TextComponent,
}
Fired when a player joins the server.
Join message to broadcast (can be modified in blocking handlers)
Example:
impl EventHandler<PlayerJoinEvent> for MyHandler {
fn handle_blocking<'a>(
&'a self,
_server: &'a Arc<Server>,
event: &'a mut PlayerJoinEvent,
) -> BoxFuture<'a, ()> {
Box::pin(async move {
event.join_message = TextComponent::text(format!(
"Welcome {}!",
event.player.gameprofile.name
));
})
}
}
PlayerLeaveEvent
pub struct PlayerLeaveEvent {
pub player: Arc<Player>,
pub leave_message: TextComponent,
}
Fired when a player leaves the server.
PlayerLoginEvent
pub struct PlayerLoginEvent {
pub player: Arc<Player>,
pub kick_message: TextComponent,
}
Fired when a player attempts to login. Can be cancelled to deny login.
Example:
impl EventHandler<PlayerLoginEvent> for MyHandler {
fn handle_blocking<'a>(
&'a self,
_server: &'a Arc<Server>,
event: &'a mut PlayerLoginEvent,
) -> BoxFuture<'a, ()> {
Box::pin(async move {
if event.player.gameprofile.name == "BadPlayer" {
event.set_cancelled(true);
event.kick_message = TextComponent::text("You are banned");
}
})
}
}
PlayerChatEvent
pub struct PlayerChatEvent {
pub player: Arc<Player>,
pub message: String,
}
Fired when a player sends a chat message. Can be cancelled.
PlayerMoveEvent
pub struct PlayerMoveEvent {
pub player: Arc<Player>,
pub from: Vector3<f64>,
pub to: Vector3<f64>,
}
Fired when a player moves.
PlayerGamemodeChangeEvent
pub struct PlayerGamemodeChangeEvent {
pub player: Arc<Player>,
pub old_gamemode: GameMode,
pub new_gamemode: GameMode,
}
Fired when a player’s gamemode changes. Can be cancelled.
Block Events
All block events are in pumpkin::plugin::block::
BlockBreakEvent
pub struct BlockBreakEvent {
pub player: Arc<Player>,
pub block: &'static Block,
pub pos: BlockPos,
}
Fired when a player breaks a block. Can be cancelled.
The player breaking the block
BlockPlaceEvent
pub struct BlockPlaceEvent {
pub player: Arc<Player>,
pub block: Block,
pub pos: BlockPos,
}
Fired when a player places a block. Can be cancelled.
World Events
All world events are in pumpkin::plugin::world::
ChunkLoadEvent
pub struct ChunkLoadEvent {
pub world: Arc<World>,
pub chunk_pos: Vector2<i32>,
}
Fired when a chunk is loaded.
ChunkSaveEvent
pub struct ChunkSaveEvent {
pub world: Arc<World>,
pub chunk_pos: Vector2<i32>,
}
Fired when a chunk is saved.
Server Events
All server events are in pumpkin::plugin::server::
ServerBroadcastEvent
pub struct ServerBroadcastEvent {
pub message: TextComponent,
pub sender: TextComponent,
}
Fired when the server broadcasts a message.
The message being broadcast (can be modified)
The sender of the message
Registering Event Handlers
use pumpkin::plugin::*;
struct MyEventHandler;
impl EventHandler<PlayerJoinEvent> for MyEventHandler {
fn handle<'a>(&'a self, server: &'a Arc<Server>, event: &'a PlayerJoinEvent) -> BoxFuture<'a, ()> {
Box::pin(async move {
println!("Player joined: {}", event.player.gameprofile.name);
})
}
}
// In plugin's on_load:
context.register_event(
Arc::new(MyEventHandler),
EventPriority::Normal,
false // non-blocking
).await;
Firing Events from Plugins
Plugins can fire custom events:
use pumpkin::plugin::*;
// Define custom event
#[derive(Clone)]
pub struct MyCustomEvent {
pub data: String,
}
impl Payload for MyCustomEvent {
fn get_name_static() -> &'static str {
"MyCustomEvent"
}
fn get_name(&self) -> &'static str {
Self::get_name_static()
}
fn as_any(&self) -> &dyn Any {
self
}
fn as_any_mut(&mut self) -> &mut dyn Any {
self
}
}
// Fire the event
let event = MyCustomEvent {
data: "Hello".to_string(),
};
let result = context.plugin_manager.fire(event).await;