Overview
The Context struct is the primary interface between plugins and the Pumpkin server. It provides methods for:
- Registering event handlers
- Registering commands
- Managing permissions
- Accessing server resources
- Service registration and retrieval
Context Structure
pub struct Context {
metadata: PluginMetadata<'static>,
pub server: Arc<Server>,
pub handlers: Arc<RwLock<HandlerMap>>,
pub plugin_manager: Arc<PluginManager>,
pub permission_manager: Arc<RwLock<PermissionManager>>,
pub logger: Arc<OnceLock<LoggerOption>>,
}
Plugin metadata including name, version, authors, and description
Reference to the server instance
Map of registered event handlers
permission_manager
Arc<RwLock<PermissionManager>>
Permission manager for handling plugin permissions
Core Methods
get_data_folder
pub fn get_data_folder(&self) -> PathBuf
Retrieves the data folder path for the plugin, creating it if it does not exist.
Path to the plugin’s data folder (e.g., ./plugins/<plugin_name>)
Example:
fn on_load(&mut self, context: Arc<Context>) -> PluginFuture<'_, Result<(), String>> {
Box::pin(async move {
let data_folder = context.get_data_folder();
println!("Data folder: {:?}", data_folder);
Ok(())
})
}
get_player_by_name
pub fn get_player_by_name(&self, player_name: &str) -> Option<Arc<Player>>
Retrieves a player by their name.
The name of the player to retrieve
Reference to the player if found, or None if not
register_event
pub async fn register_event<E: Payload + 'static, H>(
&self,
handler: Arc<H>,
priority: EventPriority,
blocking: bool,
) where
H: EventHandler<E> + 'static
Registers an event handler for a specific event type.
The event handler implementation
Priority level for the handler (Highest, High, Normal, Low, Lowest)
Whether the handler is blocking (can modify event data)
Example:
use pumpkin::plugin::*;
struct MyHandler;
impl EventHandler<PlayerJoinEvent> for MyHandler {
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 on_load:
context.register_event(
Arc::new(MyHandler),
EventPriority::Normal,
false
).await;
register_command
pub async fn register_command<P: Into<String>>(
&self,
tree: CommandTree,
permission: P,
)
Registers a command with the server.
The command tree structure defining the command syntax
Permission node required to execute the command (automatically prefixed with plugin name)
Example:
use pumpkin::command::tree::CommandTree;
use pumpkin::command::CommandSender;
let tree = CommandTree::new(["mycommand"], "My custom command")
.execute(|sender: &CommandSender, _server, _args| {
Box::pin(async move {
sender.send_message(TextComponent::text("Hello!")).await;
Ok(())
})
});
context.register_command(tree, "mycommand.use").await;
unregister_command
pub async fn unregister_command(&self, name: &str)
Unregisters a command from the server.
The name of the command to unregister
register_permission
pub async fn register_permission(&self, permission: Permission) -> Result<(), String>
Registers a permission for this plugin.
Permission object with node, description, and default level
Ok on success, Err if permission node doesn’t use plugin’s namespace
Example:
use pumpkin_util::permission::Permission;
use pumpkin_util::PermissionLvl;
let permission = Permission {
node: "myplugin:admin".to_string(),
description: "Admin permission".to_string(),
default: PermissionLvl::Zero,
};
context.register_permission(permission).await?;
player_has_permission
pub async fn player_has_permission(&self, player_uuid: &uuid::Uuid, permission: &str) -> bool
Checks if a player has a specific permission.
UUID of the player to check
true if the player has the permission, false otherwise
Service Management
register_service
pub async fn register_service<N: Into<String>, T: Payload + 'static>(
&self,
name: N,
service: Arc<T>,
)
Registers a service with the plugin context, making it available for retrieval by other plugins.
Unique name to register the service under
Service instance wrapped in Arc
Example:
context.register_service("my_service", Arc::new(MyService::new())).await;
get_service
pub async fn get_service<T: Payload + 'static>(&self, name: &str) -> Option<Arc<T>>
Retrieves a registered service by name and type.
Name of the service to retrieve
Service instance if found and type matches, or None
Example:
if let Some(service) = context.get_service::<MyService>("my_service").await {
service.do_something();
}
Logging
init_log
Initializes logging via the tracing crate for the plugin.
log
pub fn log(&self, message: impl std::fmt::Display)
Logs a message using the plugin’s logger.
message
impl std::fmt::Display
required
Message to log
Example:
context.log("Plugin initialized successfully");
Plugin Loader Extension
register_plugin_loader
pub async fn register_plugin_loader(
&self,
loader: Arc<dyn PluginLoader>,
) -> bool
Registers a custom plugin loader that can load additional plugin types (e.g., Lua, JavaScript).
loader
Arc<dyn PluginLoader>
required
Custom plugin loader implementation
true if new plugins were loaded as a result of registering this loader
Example:
let lua_loader = Arc::new(LuaPluginLoader::new());
if context.register_plugin_loader(lua_loader).await {
context.log("Lua plugin loader registered and loaded new plugins");
}