Skip to main content

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>>,
}
metadata
PluginMetadata<'static>
Plugin metadata including name, version, authors, and description
server
Arc<Server>
Reference to the server instance
handlers
Arc<RwLock<HandlerMap>>
Map of registered event handlers
plugin_manager
Arc<PluginManager>
Plugin manager instance
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.
returns
PathBuf
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.
player_name
&str
required
The name of the player to retrieve
returns
Option<Arc<Player>>
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.
handler
Arc<H>
required
The event handler implementation
priority
EventPriority
required
Priority level for the handler (Highest, High, Normal, Low, Lowest)
blocking
bool
required
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.
tree
CommandTree
required
The command tree structure defining the command syntax
permission
P: Into<String>
required
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.
name
&str
required
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
Permission
required
Permission object with node, description, and default level
returns
Result<(), String>
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.
player_uuid
&uuid::Uuid
required
UUID of the player to check
permission
&str
required
Permission node to check
returns
bool
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.
name
N: Into<String>
required
Unique name to register the service under
service
Arc<T>
required
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
&str
required
Name of the service to retrieve
returns
Option<Arc<T>>
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

pub fn init_log(&self)
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
returns
bool
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");
}

Build docs developers (and LLMs) love