From f1df8cad234dbf89fe75e892d795adf9edcab7a1 Mon Sep 17 00:00:00 2001 From: Bjorn Beishline <75190918+BjornTheProgrammer@users.noreply.github.com> Date: Wed, 21 Jan 2026 22:07:21 -0700 Subject: [PATCH] Get onDisable working --- rust/src/lib.rs | 58 +++++++++++++++++++++++++++++--------- rust/src/plugin/manager.rs | 48 ++++++++++++++++++++++++++----- 2 files changed, 86 insertions(+), 20 deletions(-) diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 33df551..8075ce2 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -1,5 +1,6 @@ use std::sync::Arc; +use j4rs::Jvm; use pumpkin::plugin::Context; use pumpkin_api_macros::{plugin_impl, plugin_method}; @@ -17,29 +18,30 @@ use java::{ use crate::{java::jar::read_configs_from_jar, plugin::manager::PluginManager}; -async fn on_load_inner(_plugin: &mut MyPlugin, server: Arc) -> Result<(), String> { +async fn on_load_inner(plugin: &mut PatchBukkitPlugin, server: Arc) -> Result<(), String> { server.init_log(); log::info!("Starting PatchBukkit"); // Setup directories let dirs = setup_directories(&server)?; - let mut plugin_manager = PluginManager::new(); - // Discover and prepare JAR files let jar_paths = discover_jar_files(&dirs.plugins); for jar_path in &jar_paths { match read_configs_from_jar(jar_path) { Ok(configs) => match configs { (Some(paper_plugin_config), spigot @ _) => { - match plugin_manager.load_paper_plugin(jar_path, &paper_plugin_config, &spigot) - { + match plugin.plugin_manager.load_paper_plugin( + jar_path, + &paper_plugin_config, + &spigot, + ) { Ok(_) => log::info!("Loaded Paper plugin from JAR: {}", jar_path.display()), Err(err) => log::error!("Failed to load Paper plugin from JAR: {}", err), } } (None, Some(spigot)) => { - match plugin_manager.load_spigot_plugin(jar_path, &spigot) { + match plugin.plugin_manager.load_spigot_plugin(jar_path, &spigot) { Ok(_) => { log::info!("Loaded Spigot plugin from JAR: {}", jar_path.display()) } @@ -68,32 +70,62 @@ async fn on_load_inner(_plugin: &mut MyPlugin, server: Arc) -> Result<( let jvm = initialize_jvm(&dirs.j4rs)?; setup_patchbukkit_server(&jvm)?; - plugin_manager + plugin + .plugin_manager .load_all_plugins(&jvm) .map_err(|err| format!("Failed to load PatchBukkit plugins: {}", err))?; - plugin_manager + plugin + .plugin_manager .enable_all_plugins(&jvm) .map_err(|err| format!("Failed to enable PatchBukkit plugins: {}", err))?; Ok(()) } +async fn on_unload_inner( + plugin: &mut PatchBukkitPlugin, + _server: Arc, +) -> Result<(), String> { + let jvm = Jvm::attach_thread().map_err(|e| format!("Failed to attach thread to JVM: {}", e))?; + + plugin + .plugin_manager + .disable_all_plugins(&jvm) + .map_err(|err| format!("Failed to disable PatchBukkit plugins: {}", err))?; + + plugin + .plugin_manager + .unload_all_plugins() + .map_err(|err| format!("Failed to unload PatchBukkit plugins: {}", err))?; + + Ok(()) +} + #[plugin_method] async fn on_load(&mut self, server: Arc) -> Result<(), String> { on_load_inner(self, server).await } -#[plugin_impl] -pub struct MyPlugin {} +#[plugin_method] +async fn on_unload(&mut self, server: Arc) -> Result<(), String> { + on_unload_inner(self, server).await +} -impl MyPlugin { +#[plugin_impl] +pub struct PatchBukkitPlugin { + plugin_manager: PluginManager, +} + +impl PatchBukkitPlugin { pub fn new() -> Self { - MyPlugin {} + PatchBukkitPlugin { + plugin_manager: PluginManager::new(), + } } } -impl Default for MyPlugin { +impl Default for PatchBukkitPlugin { fn default() -> Self { Self::new() } diff --git a/rust/src/plugin/manager.rs b/rust/src/plugin/manager.rs index 3849799..34f1e40 100644 --- a/rust/src/plugin/manager.rs +++ b/rust/src/plugin/manager.rs @@ -1,4 +1,7 @@ -use std::path::{Path, PathBuf}; +use std::{ + path::{Path, PathBuf}, + sync::{Arc, Mutex}, +}; use anyhow::Result; use j4rs::{Instance, InvocationArg, Jvm}; @@ -55,18 +58,18 @@ pub struct Plugin { } pub struct PluginManager { - plugins: Vec, + plugins: Arc>>, } impl PluginManager { pub fn new() -> Self { Self { - plugins: Vec::new(), + plugins: Arc::new(Mutex::new(Vec::new())), } } - pub fn add_plugin(&mut self, plugin: Plugin) { - self.plugins.push(plugin); + pub fn add_plugin(&self, plugin: Plugin) { + self.plugins.lock().unwrap().push(plugin); } pub fn load_paper_plugin>( @@ -124,7 +127,7 @@ impl PluginManager { } pub fn enable_all_plugins(&mut self, jvm: &Jvm) -> Result<()> { - for plugin in &mut self.plugins { + for plugin in &mut *self.plugins.lock().unwrap() { let result = jvm.invoke( plugin.instance.as_ref().unwrap(), "onEnable", @@ -149,8 +152,34 @@ impl PluginManager { Ok(()) } + pub fn disable_all_plugins(&mut self, jvm: &Jvm) -> Result<()> { + for plugin in &mut *self.plugins.lock().unwrap() { + let result = jvm.invoke( + plugin.instance.as_ref().unwrap(), + "onDisable", + InvocationArg::empty(), + ); + + match result { + Ok(_) => { + plugin.state = PluginState::Disabled; + log::info!("Disabled PatchBukkit plugin: {}", plugin.name); + } + Err(e) => { + plugin.state = PluginState::Disabled; + log::error!( + "Failed to disable PatchBukkit plugin {}: {:?}", + plugin.name, + e + ); + } + } + } + Ok(()) + } + pub fn load_all_plugins(&mut self, jvm: &Jvm) -> Result<()> { - for plugin in &mut self.plugins { + for plugin in &mut *self.plugins.lock().unwrap() { let result = jvm.invoke_static( "org.patchbukkit.loader.PatchBukkitPluginLoader", "createPlugin", @@ -174,4 +203,9 @@ impl PluginManager { } Ok(()) } + + pub fn unload_all_plugins(&mut self) -> Result<()> { + self.plugins.lock().unwrap().clear(); + Ok(()) + } }