This commit is contained in:
Bjorn Beishline 2026-01-27 23:47:38 -07:00
parent 9422749511
commit 21fd37457c
6 changed files with 49 additions and 140 deletions

View File

@ -1,102 +0,0 @@
package org.patchbukkit;
import io.papermc.paper.ServerBuildInfo;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.Optional;
import java.util.OptionalInt;
import net.kyori.adventure.key.Key;
import org.jetbrains.annotations.NotNull;
public final class PumpkinServerBuildInfo implements ServerBuildInfo {
Key brandId;
Instant startTime = Instant.now();
private static final String BUILD_DEV = "DEV";
@Override
public Key brandId() {
this.brandId = Key.key("pumpkinmc:paper");
return brandId;
}
@Override
public boolean isBrandCompatible(Key brandId) {
return (
brandId.equals(this.brandId) ||
brandId.equals(Key.key("papermc:paper"))
);
}
@Override
public String brandName() {
return "Pumpkin";
}
@Override
public String minecraftVersionId() {
return "1.21.10";
}
@Override
public String minecraftVersionName() {
return "1.21.10";
}
@Override
public OptionalInt buildNumber() {
return OptionalInt.empty();
}
@Override
public Instant buildTime() {
return this.startTime;
}
@Override
public Optional<String> gitBranch() {
return Optional.empty();
}
@Override
public Optional<String> gitCommit() {
return Optional.empty();
}
@Override
public @NotNull String asString(
final @NotNull StringRepresentation representation
) {
final StringBuilder sb = new StringBuilder();
sb.append(this.minecraftVersionId());
sb.append('-');
if (this.buildNumber().isPresent()) {
sb.append(this.buildNumber().getAsInt());
} else {
sb.append(BUILD_DEV);
}
final boolean hasGitBranch = this.gitBranch().isPresent();
final boolean hasGitCommit = this.gitCommit().isPresent();
if (hasGitBranch || hasGitCommit) {
sb.append('-');
}
if (
hasGitBranch && representation == StringRepresentation.VERSION_FULL
) {
sb.append(this.gitBranch().get());
if (hasGitCommit) {
sb.append('@');
}
}
if (hasGitCommit) {
sb.append(this.gitCommit().get());
}
if (representation == StringRepresentation.VERSION_FULL) {
sb.append(' ');
sb.append('(');
sb.append(this.buildTime().truncatedTo(ChronoUnit.SECONDS));
sb.append(')');
}
return sb.toString();
}
}

View File

@ -1 +0,0 @@
org.patchbukkit.PumpkinServerBuildInfo

View File

@ -6,11 +6,12 @@ use pumpkin::{
}; };
use pumpkin_api_macros::with_runtime; use pumpkin_api_macros::with_runtime;
use pumpkin_util::text::{TextComponent, color::NamedColor}; use pumpkin_util::text::{TextComponent, color::NamedColor};
use tokio::sync::Mutex;
use crate::plugin::manager::Plugins; use crate::plugin::manager::PluginManager;
pub struct PatchBukkitJoinHandler { pub struct PatchBukkitJoinHandler {
pub plugins: Plugins, pub plugin_manager: Arc<Mutex<PluginManager>>,
} }
#[with_runtime(global)] #[with_runtime(global)]
@ -21,7 +22,7 @@ impl EventHandler<PlayerJoinEvent> for PatchBukkitJoinHandler {
event: &'a mut PlayerJoinEvent, event: &'a mut PlayerJoinEvent,
) -> BoxFuture<'a, ()> { ) -> BoxFuture<'a, ()> {
Box::pin(async { Box::pin(async {
for (_plugin_name, plugin) in self.plugins.lock().unwrap().iter_mut() {} // for (_plugin_name, plugin) in self.plugins.lock().unwrap().iter_mut() {}
event.join_message = event.join_message =
TextComponent::text(format!("Welcome, {}!", event.player.gameprofile.name)) TextComponent::text(format!("Welcome, {}!", event.player.gameprofile.name))
.color_named(NamedColor::Green); .color_named(NamedColor::Green);

View File

@ -1,15 +1,16 @@
use std::sync::Arc; use std::sync::Arc;
use pumpkin::plugin::{Context, EventPriority}; use pumpkin::plugin::{Context, EventPriority};
use tokio::sync::Mutex;
use crate::{events::join::PatchBukkitJoinHandler, plugin::manager::Plugins}; use crate::{events::join::PatchBukkitJoinHandler, plugin::manager::PluginManager};
pub mod join; pub mod join;
pub async fn register_handlers(plugins: Plugins, server: &Arc<Context>) { pub async fn register_handlers(plugin_manager: Arc<Mutex<PluginManager>>, server: &Arc<Context>) {
server server
.register_event( .register_event(
Arc::new(PatchBukkitJoinHandler { plugins }), Arc::new(PatchBukkitJoinHandler { plugin_manager }),
EventPriority::Highest, EventPriority::Highest,
true, true,
) )

View File

@ -16,6 +16,7 @@ use java::{
jvm::{initialize_jvm, setup_patchbukkit_server}, jvm::{initialize_jvm, setup_patchbukkit_server},
resources::{cleanup_stale_files, sync_embedded_resources}, resources::{cleanup_stale_files, sync_embedded_resources},
}; };
use tokio::sync::Mutex;
use crate::{ use crate::{
events::register_handlers, java::jar::read_configs_from_jar, plugin::manager::PluginManager, events::register_handlers, java::jar::read_configs_from_jar, plugin::manager::PluginManager,
@ -25,7 +26,7 @@ async fn on_load_inner(plugin: &mut PatchBukkitPlugin, server: Arc<Context>) ->
server.init_log(); server.init_log();
log::info!("Starting PatchBukkit"); log::info!("Starting PatchBukkit");
register_handlers(&server).await; register_handlers(plugin.plugin_manager.clone(), &server).await;
// Setup directories // Setup directories
let dirs = setup_directories(&server)?; let dirs = setup_directories(&server)?;
@ -36,7 +37,7 @@ async fn on_load_inner(plugin: &mut PatchBukkitPlugin, server: Arc<Context>) ->
match read_configs_from_jar(jar_path) { match read_configs_from_jar(jar_path) {
Ok(configs) => match configs { Ok(configs) => match configs {
(Some(paper_plugin_config), spigot @ _) => { (Some(paper_plugin_config), spigot @ _) => {
match plugin.plugin_manager.load_paper_plugin( match plugin.plugin_manager.lock().await.load_paper_plugin(
jar_path, jar_path,
&paper_plugin_config, &paper_plugin_config,
&spigot, &spigot,
@ -46,7 +47,12 @@ async fn on_load_inner(plugin: &mut PatchBukkitPlugin, server: Arc<Context>) ->
} }
} }
(None, Some(spigot)) => { (None, Some(spigot)) => {
match plugin.plugin_manager.load_spigot_plugin(jar_path, &spigot) { match plugin
.plugin_manager
.lock()
.await
.load_spigot_plugin(jar_path, &spigot)
{
Ok(_) => { Ok(_) => {
log::info!("Loaded Spigot plugin from JAR: {}", jar_path.display()) log::info!("Loaded Spigot plugin from JAR: {}", jar_path.display())
} }
@ -80,20 +86,20 @@ async fn on_load_inner(plugin: &mut PatchBukkitPlugin, server: Arc<Context>) ->
.map_err(|err| err.to_string())?; .map_err(|err| err.to_string())?;
let r = jvm.init_callback_channel(&i).unwrap(); let r = jvm.init_callback_channel(&i).unwrap();
let plugins = plugin.plugin_manager.plugins.clone(); let plugin_manager = plugin.plugin_manager.clone();
std::thread::spawn(move || { tokio::spawn(async move {
let jvm = match Jvm::attach_thread() {
Ok(jvm) => jvm,
Err(e) => {
log::error!("Failed to attach callback thread to JVM: {}", e);
return;
}
};
loop { loop {
match r.rx().recv() { match r.rx().recv() {
Ok(ret) => { Ok(ret) => {
let result: anyhow::Result<()> = (|| { let result: anyhow::Result<()> = (async || {
let jvm = match Jvm::attach_thread() {
Ok(jvm) => jvm,
Err(e) => {
log::error!("Failed to attach callback thread to JVM: {}", e);
return Ok(());
}
};
let result = jvm.invoke(&ret, "getCallbackName", InvocationArg::empty())?; let result = jvm.invoke(&ret, "getCallbackName", InvocationArg::empty())?;
let callback_name: String = jvm.to_rust(result)?; let callback_name: String = jvm.to_rust(result)?;
@ -126,7 +132,7 @@ async fn on_load_inner(plugin: &mut PatchBukkitPlugin, server: Arc<Context>) ->
InvocationArg::empty(), InvocationArg::empty(),
)?)?; )?)?;
match plugins.lock().unwrap().get_mut(&plugin_name) { match plugin_manager.lock().await.plugins.get_mut(&plugin_name) {
Some(rust_plugin) => { Some(rust_plugin) => {
rust_plugin.listeners.insert(listener_name, listener) rust_plugin.listeners.insert(listener_name, listener)
} }
@ -137,7 +143,8 @@ async fn on_load_inner(plugin: &mut PatchBukkitPlugin, server: Arc<Context>) ->
} }
return Ok(()); return Ok(());
})(); })()
.await;
result.unwrap(); result.unwrap();
} }
@ -151,11 +158,15 @@ async fn on_load_inner(plugin: &mut PatchBukkitPlugin, server: Arc<Context>) ->
plugin plugin
.plugin_manager .plugin_manager
.lock()
.await
.load_all_plugins(&jvm) .load_all_plugins(&jvm)
.map_err(|err| format!("Failed to load PatchBukkit plugins: {}", err))?; .map_err(|err| format!("Failed to load PatchBukkit plugins: {}", err))?;
plugin plugin
.plugin_manager .plugin_manager
.lock()
.await
.enable_all_plugins(&jvm) .enable_all_plugins(&jvm)
.map_err(|err| format!("Failed to enable PatchBukkit plugins: {}", err))?; .map_err(|err| format!("Failed to enable PatchBukkit plugins: {}", err))?;
@ -170,11 +181,15 @@ async fn on_unload_inner(
plugin plugin
.plugin_manager .plugin_manager
.lock()
.await
.disable_all_plugins(&jvm) .disable_all_plugins(&jvm)
.map_err(|err| format!("Failed to disable PatchBukkit plugins: {}", err))?; .map_err(|err| format!("Failed to disable PatchBukkit plugins: {}", err))?;
plugin plugin
.plugin_manager .plugin_manager
.lock()
.await
.unload_all_plugins() .unload_all_plugins()
.map_err(|err| format!("Failed to unload PatchBukkit plugins: {}", err))?; .map_err(|err| format!("Failed to unload PatchBukkit plugins: {}", err))?;
@ -193,13 +208,13 @@ async fn on_unload(&mut self, server: Arc<Context>) -> Result<(), String> {
#[plugin_impl] #[plugin_impl]
pub struct PatchBukkitPlugin { pub struct PatchBukkitPlugin {
plugin_manager: PluginManager, plugin_manager: Arc<Mutex<PluginManager>>,
} }
impl PatchBukkitPlugin { impl PatchBukkitPlugin {
pub fn new() -> Self { pub fn new() -> Self {
PatchBukkitPlugin { PatchBukkitPlugin {
plugin_manager: PluginManager::new(), plugin_manager: Arc::new(Mutex::new(PluginManager::new())),
} }
} }
} }

View File

@ -1,7 +1,6 @@
use std::{ use std::{
collections::HashMap, collections::HashMap,
path::{Path, PathBuf}, path::{Path, PathBuf},
sync::{Arc, Mutex},
}; };
use anyhow::Result; use anyhow::Result;
@ -59,23 +58,19 @@ pub struct Plugin {
pub listeners: HashMap<String, Instance>, pub listeners: HashMap<String, Instance>,
} }
pub type Plugins = Arc<Mutex<HashMap<String, Plugin>>>;
pub struct PluginManager { pub struct PluginManager {
pub plugins: Plugins, pub plugins: HashMap<String, Plugin>,
} }
impl PluginManager { impl PluginManager {
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
plugins: Arc::new(Mutex::new(HashMap::new())), plugins: HashMap::new(),
} }
} }
pub fn add_plugin(&self, plugin: Plugin) { pub fn add_plugin(&mut self, plugin: Plugin) {
self.plugins self.plugins.insert(plugin.name.clone(), plugin);
.lock()
.unwrap()
.insert(plugin.name.clone(), plugin);
} }
pub fn load_paper_plugin<P: AsRef<Path>>( pub fn load_paper_plugin<P: AsRef<Path>>(
@ -135,7 +130,7 @@ impl PluginManager {
} }
pub fn enable_all_plugins(&mut self, jvm: &Jvm) -> Result<()> { pub fn enable_all_plugins(&mut self, jvm: &Jvm) -> Result<()> {
for (_plugin_name, plugin) in &mut *self.plugins.lock().unwrap() { for (_plugin_name, plugin) in &mut self.plugins {
let result = jvm.invoke( let result = jvm.invoke(
plugin.instance.as_ref().unwrap(), plugin.instance.as_ref().unwrap(),
"onEnable", "onEnable",
@ -161,7 +156,7 @@ impl PluginManager {
} }
pub fn disable_all_plugins(&mut self, jvm: &Jvm) -> Result<()> { pub fn disable_all_plugins(&mut self, jvm: &Jvm) -> Result<()> {
for (_plugin_name, plugin) in &mut *self.plugins.lock().unwrap() { for (_plugin_name, plugin) in &mut self.plugins {
let result = jvm.invoke( let result = jvm.invoke(
plugin.instance.as_ref().unwrap(), plugin.instance.as_ref().unwrap(),
"onDisable", "onDisable",
@ -187,7 +182,7 @@ impl PluginManager {
} }
pub fn load_all_plugins(&mut self, jvm: &Jvm) -> Result<()> { pub fn load_all_plugins(&mut self, jvm: &Jvm) -> Result<()> {
for (_plugin_name, plugin) in &mut *self.plugins.lock().unwrap() { for (_plugin_name, plugin) in &mut self.plugins {
let result = jvm.invoke_static( let result = jvm.invoke_static(
"org.patchbukkit.loader.PatchBukkitPluginLoader", "org.patchbukkit.loader.PatchBukkitPluginLoader",
"createPlugin", "createPlugin",
@ -213,7 +208,7 @@ impl PluginManager {
} }
pub fn unload_all_plugins(&mut self) -> Result<()> { pub fn unload_all_plugins(&mut self) -> Result<()> {
self.plugins.lock().unwrap().clear(); self.plugins.clear();
Ok(()) Ok(())
} }
} }