Rename to PatchBukkit

This commit is contained in:
Bjorn Beishline 2026-01-21 13:35:19 -07:00
parent f0e3e01f16
commit 8286a34eb9
18 changed files with 157 additions and 94 deletions

4
.gitignore vendored
View File

@ -15,8 +15,8 @@ java/.gradle/
# Build outputs
build/
java/build/
java/papkin/build/
java/papkin/bin/
java/patchbukkit/build/
java/patchbukkit/bin/
# Keep Gradle wrapper
!gradle/wrapper/gradle-wrapper.jar

View File

@ -1,23 +1,23 @@
# Papkin
# PatchBukkit
A plugin for [PumpkinMC](https://pumpkinmc.org/) that adds support for [PaperMC](https://papermc.io/), [Spigot](https://www.spigotmc.org/), and [Bukkit](https://dev.bukkit.org/) plugins.
## Installation
> [!IMPORTANT]
> Currently Papkin is in heavy development, as such releases are not yet available.
> Currently PatchBukkit is in heavy development, as such releases are not yet available.
1. Install [java](https://docs.papermc.io/misc/java-install/)
2. Download the plugin in releases `papkin-mac.dylib`, `papkin-linux-aarch64.so`, `papkin-linux-x86.so`, or `papkin-windows-x86.dll`.
2. Download the plugin in releases `patchbukkit-mac.dylib`, `patchbukkit-linux-aarch64.so`, `patchbukkit-linux-x86.so`, or `patchbukkit-windows-x86.dll`.
3. Add it into your PumpkinMC plugin directory (this gets created after runing PumpkinMC for the first time).
4. Run PumpkinMC again, and you should see a new directory in PumpkinMC called `papkin`. You can add any `bukkit`, `spigot`, or `paper` plugin you wish, and it will run.
4. Run PumpkinMC again, and you should see a new directory in PumpkinMC called `patchbukkit`. You can add any `bukkit`, `spigot`, or `paper` plugin you wish, and it will run.
## Development
If you wish to contribute to Papkin, follow the following steps:
If you wish to contribute to PatchBukkit, follow the following steps:
1. Build PumpkinMC from source with the `nightly-2025-12-11` rust toolchain.
2. Clone this repository
3. `cd` into the `java` directory and run `./gradlew build`
4. `cd` into the `rust` directory and run `cargo build`
5. Copy the `target/debug/papkin` binary to the `plugins` directory in your PumpkinMC server.
5. Copy the `target/debug/patchbukkit` binary to the `plugins` directory in your PumpkinMC server.

View File

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

View File

@ -1,4 +1,4 @@
package org.papkin;
package org.patchbukkit;
import com.destroystokyo.paper.entity.ai.MobGoals;
import io.papermc.paper.ban.BanListType;
@ -84,7 +84,7 @@ import org.bukkit.util.CachedServerIcon;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class PapkinServer implements Server {
public class PatchBukkitServer implements Server {
private final String serverName =
io.papermc.paper.ServerBuildInfo.buildInfo().brandName();
@ -1537,7 +1537,7 @@ public class PapkinServer implements Server {
@Override
public @NotNull UnsafeValues getUnsafe() {
return PapkinUnsafeValues.INSTANCE;
return PatchBukkitUnsafeValues.INSTANCE;
}
@Override

View File

@ -1,4 +1,4 @@
package org.papkin;
package org.patchbukkit;
import com.google.common.collect.Multimap;
import com.google.gson.JsonObject;
@ -6,6 +6,10 @@ import io.papermc.paper.entity.EntitySerializationFlag;
import io.papermc.paper.inventory.tooltip.TooltipContext;
import io.papermc.paper.plugin.lifecycle.event.LifecycleEventManager;
import io.papermc.paper.registry.RegistryKey;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.function.BooleanSupplier;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.event.HoverEvent;
import net.kyori.adventure.text.flattener.ComponentFlattener;
@ -38,15 +42,11 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jspecify.annotations.NonNull;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.function.BooleanSupplier;
@SuppressWarnings("removal")
public class PapkinUnsafeValues implements UnsafeValues {
public class PatchBukkitUnsafeValues implements UnsafeValues {
public static final PapkinUnsafeValues INSTANCE = new PapkinUnsafeValues();
public static final PatchBukkitUnsafeValues INSTANCE =
new PatchBukkitUnsafeValues();
// These are commonly used - implement first
@Override
@ -79,22 +79,33 @@ public class PapkinUnsafeValues implements UnsafeValues {
}
@Override
public @NotNull JsonObject serializeItemAsJson(@NotNull ItemStack itemStack) {
public @NotNull JsonObject serializeItemAsJson(
@NotNull ItemStack itemStack
) {
return null;
}
@Override
public @NotNull ItemStack deserializeItemFromJson(@NotNull JsonObject data) throws IllegalArgumentException {
public @NotNull ItemStack deserializeItemFromJson(@NotNull JsonObject data)
throws IllegalArgumentException {
return null;
}
@Override
public byte @NotNull [] serializeEntity(@NotNull Entity entity, @NonNull @NotNull EntitySerializationFlag... serializationFlags) {
public byte@NotNull [] serializeEntity(
@NotNull Entity entity,
@NonNull @NotNull EntitySerializationFlag... serializationFlags
) {
return new byte[0];
}
@Override
public @NotNull Entity deserializeEntity(byte @NotNull [] data, @NotNull World world, boolean preserveUUID, boolean preservePassengers) {
public @NotNull Entity deserializeEntity(
byte@NotNull [] data,
@NotNull World world,
boolean preserveUUID,
boolean preservePassengers
) {
return null;
}
@ -114,29 +125,45 @@ public class PapkinUnsafeValues implements UnsafeValues {
}
@Override
public boolean isValidRepairItemStack(@NotNull ItemStack itemToBeRepaired, @NotNull ItemStack repairMaterial) {
public boolean isValidRepairItemStack(
@NotNull ItemStack itemToBeRepaired,
@NotNull ItemStack repairMaterial
) {
return false;
}
@Override
public boolean hasDefaultEntityAttributes(@NotNull NamespacedKey entityKey) {
public boolean hasDefaultEntityAttributes(
@NotNull NamespacedKey entityKey
) {
return false;
}
@Override
public @NotNull Attributable getDefaultEntityAttributes(@NotNull NamespacedKey entityKey) {
public @NotNull Attributable getDefaultEntityAttributes(
@NotNull NamespacedKey entityKey
) {
return null;
}
@Override
public @NotNull NamespacedKey getBiomeKey(RegionAccessor accessor, int x, int y, int z) {
public @NotNull NamespacedKey getBiomeKey(
RegionAccessor accessor,
int x,
int y,
int z
) {
return null;
}
@Override
public void setBiomeKey(RegionAccessor accessor, int x, int y, int z, NamespacedKey biomeKey) {
}
public void setBiomeKey(
RegionAccessor accessor,
int x,
int y,
int z,
NamespacedKey biomeKey
) {}
@Override
public String getStatisticCriteriaKey(@NotNull Statistic statistic) {
@ -144,17 +171,27 @@ public class PapkinUnsafeValues implements UnsafeValues {
}
@Override
public @Nullable Color getSpawnEggLayerColor(EntityType entityType, int layer) {
public @Nullable Color getSpawnEggLayerColor(
EntityType entityType,
int layer
) {
return null;
}
@Override
public LifecycleEventManager<Plugin> createPluginLifecycleEventManager(JavaPlugin plugin, BooleanSupplier registrationCheck) {
public LifecycleEventManager<Plugin> createPluginLifecycleEventManager(
JavaPlugin plugin,
BooleanSupplier registrationCheck
) {
return null;
}
@Override
public @NotNull List<Component> computeTooltipLines(@NotNull ItemStack itemStack, @NotNull TooltipContext tooltipContext, @Nullable Player player) {
public @NotNull List<Component> computeTooltipLines(
@NotNull ItemStack itemStack,
@NotNull TooltipContext tooltipContext,
@Nullable Player player
) {
return List.of();
}
@ -169,17 +206,22 @@ public class PapkinUnsafeValues implements UnsafeValues {
}
@Override
public @NotNull ItemStack deserializeStack(@NotNull Map<String, Object> args) {
public @NotNull ItemStack deserializeStack(
@NotNull Map<String, Object> args
) {
return null;
}
@Override
public @NotNull ItemStack deserializeItemHover(HoverEvent.@NotNull ShowItem itemHover) {
public @NotNull ItemStack deserializeItemHover(
HoverEvent.@NotNull ShowItem itemHover
) {
return null;
}
@Override
public void checkSupported(PluginDescriptionFile pdf) throws InvalidPluginException {
public void checkSupported(PluginDescriptionFile pdf)
throws InvalidPluginException {
// Be lenient during development - accept most plugins
String api = pdf.getAPIVersion();
if (api != null && !isSupportedApiVersion(api)) {
@ -208,7 +250,10 @@ public class PapkinUnsafeValues implements UnsafeValues {
}
@Override
public Multimap<Attribute, AttributeModifier> getDefaultAttributeModifiers(Material material, EquipmentSlot slot) {
public Multimap<Attribute, AttributeModifier> getDefaultAttributeModifiers(
Material material,
EquipmentSlot slot
) {
return null;
}
@ -243,12 +288,16 @@ public class PapkinUnsafeValues implements UnsafeValues {
}
@Override
public PotionType.InternalPotionData getInternalPotionData(NamespacedKey key) {
public PotionType.InternalPotionData getInternalPotionData(
NamespacedKey key
) {
return null;
}
@Override
public DamageSource.@NotNull Builder createDamageSourceBuilder(@NotNull DamageType damageType) {
public DamageSource.@NotNull Builder createDamageSourceBuilder(
@NotNull DamageType damageType
) {
return null;
}
@ -294,7 +343,12 @@ public class PapkinUnsafeValues implements UnsafeValues {
}
@Override
public Component resolveWithContext(Component component, CommandSender context, Entity scoreboardSubject, boolean bypassPermissions) throws IOException {
public Component resolveWithContext(
Component component,
CommandSender context,
Entity scoreboardSubject,
boolean bypassPermissions
) throws IOException {
return null;
}

View File

@ -1,4 +1,4 @@
package org.papkin.loader;
package org.patchbukkit.loader;
import io.papermc.paper.plugin.provider.util.ProviderUtil;
import java.io.File;

View File

@ -1,4 +1,4 @@
package org.papkin;
package org.patchbukkit;
import io.papermc.paper.ServerBuildInfo;
import java.time.Instant;

View File

@ -1,4 +1,4 @@
package org.papkin;
package org.patchbukkit;
import java.io.IOException;
import java.io.InputStream;

View File

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

View File

@ -10,5 +10,5 @@ plugins {
id("org.gradle.toolchains.foojay-resolver-convention") version "0.8.0"
}
rootProject.name = "papkin"
include("papkin")
rootProject.name = "patchbukkit"
include("patchbukkit")

44
rust/Cargo.lock generated
View File

@ -1588,28 +1588,6 @@ dependencies = [
"sha2 0.10.9",
]
[[package]]
name = "papkin"
version = "0.1.0"
dependencies = [
"anyhow",
"async-trait",
"env_logger",
"glob",
"j4rs",
"j4rs_derive",
"log",
"pumpkin",
"pumpkin-api-macros",
"pumpkin-util",
"rust-embed",
"serde",
"serde-saphyr",
"tokio",
"walkdir",
"zip",
]
[[package]]
name = "parking_lot"
version = "0.12.5"
@ -1633,6 +1611,28 @@ dependencies = [
"windows-link",
]
[[package]]
name = "patchbukkit"
version = "0.1.0"
dependencies = [
"anyhow",
"async-trait",
"env_logger",
"glob",
"j4rs",
"j4rs_derive",
"log",
"pumpkin",
"pumpkin-api-macros",
"pumpkin-util",
"rust-embed",
"serde",
"serde-saphyr",
"tokio",
"walkdir",
"zip",
]
[[package]]
name = "pbkdf2"
version = "0.12.2"

View File

@ -1,5 +1,5 @@
[package]
name = "papkin"
name = "patchbukkit"
version = "0.1.0"
edition = "2024"

View File

@ -129,14 +129,14 @@ fn main() -> Result<(), Box<dyn Error>> {
}
}
if !Path::new("../java/papkin/build/libs/papkin.jar").exists() {
if !Path::new("../java/patchbukkit/build/libs/patchbukkit.jar").exists() {
panic!(
"Failed to find papkin.jar, build the java library first by running `gradle build` in the java directory!"
"Failed to find patchbukkit.jar, build the java library first by running `gradle build` in the java directory!"
);
}
jvm.deploy_artifact(&LocalJarArtifact::new(
"../java/papkin/build/libs/papkin.jar",
"../java/patchbukkit/build/libs/patchbukkit.jar",
))
.unwrap();

View File

@ -2,7 +2,7 @@ use std::{fs, path::PathBuf};
use pumpkin::plugin::Context;
pub struct PapkinDirectories {
pub struct PatchBukkitDirectories {
pub base: PathBuf,
pub plugins: PathBuf,
pub plugin_updates: PathBuf,
@ -10,13 +10,13 @@ pub struct PapkinDirectories {
pub jassets: PathBuf,
}
pub fn setup_directories(server: &Context) -> Result<PapkinDirectories, String> {
pub fn setup_directories(server: &Context) -> Result<PatchBukkitDirectories, String> {
let base = server
.get_data_folder()
.canonicalize()
.map_err(|_| "Failed to get absolute directory from relative")?;
let plugins = base.join("papkin-plugins");
let plugins = base.join("patchbukkit-plugins");
let plugin_updates = plugins.join("update");
let j4rs = base.join("j4rs");
let jassets = j4rs.join("jassets");
@ -27,7 +27,7 @@ pub fn setup_directories(server: &Context) -> Result<PapkinDirectories, String>
fs::create_dir_all(&jassets)
.map_err(|err| format!("Failed to create jassets folder: {:?}", err))?;
Ok(PapkinDirectories {
Ok(PatchBukkitDirectories {
base,
plugins,
plugin_updates,

View File

@ -15,15 +15,15 @@ pub fn initialize_jvm(
Ok(jvm)
}
pub fn setup_papkin_server(jvm: &Jvm) -> Result<(), String> {
let papkin_server = jvm
.create_instance("org.papkin.PapkinServer", InvocationArg::empty())
.map_err(|err| format!("Failed to create PapkinServer instance: {:?}", err))?;
pub fn setup_patchbukkit_server(jvm: &Jvm) -> Result<(), String> {
let patchbukkit_server = jvm
.create_instance("org.patchbukkit.PatchBukkitServer", InvocationArg::empty())
.map_err(|err| format!("Failed to create PatchBukkitServer instance: {:?}", err))?;
jvm.invoke_static(
"org.bukkit.Bukkit",
"setServer",
&[InvocationArg::from(papkin_server)],
&[InvocationArg::from(patchbukkit_server)],
)
.map_err(|err| format!("Failed to set Bukkit server: {:?}", err))?;

View File

@ -12,7 +12,7 @@ pub mod plugin;
use directories::setup_directories;
use java::{
jar::discover_jar_files,
jvm::{initialize_jvm, setup_papkin_server},
jvm::{initialize_jvm, setup_patchbukkit_server},
resources::{cleanup_stale_files, sync_embedded_resources},
};
@ -20,7 +20,7 @@ use crate::{java::jar::read_configs_from_jar, plugin::manager::PluginManager};
async fn on_load_inner(_plugin: &mut MyPlugin, server: Arc<Context>) -> Result<(), String> {
server.init_log();
log::info!("Starting Papkin");
log::info!("Starting PatchBukkit");
// Setup directories
let dirs = setup_directories(&server)?;
@ -53,7 +53,10 @@ async fn on_load_inner(_plugin: &mut MyPlugin, server: Arc<Context>) -> Result<(
),
},
Err(err) => {
log::error!("Failed to read configs from papkin plugin jar: {}", err);
log::error!(
"Failed to read configs from PatchBukkit plugin jar: {}",
err
);
}
}
}
@ -66,17 +69,17 @@ async fn on_load_inner(_plugin: &mut MyPlugin, server: Arc<Context>) -> Result<(
cleanup_stale_files(&dirs.j4rs);
sync_embedded_resources(&dirs.j4rs)?;
// Initialize JVM and Papkin server
// Initialize JVM and PatchBukkit server
let jvm = initialize_jvm(classpath_entries, &dirs.j4rs)?;
setup_papkin_server(&jvm)?;
setup_patchbukkit_server(&jvm)?;
plugin_manager
.load_all_plugins(&jvm)
.map_err(|err| format!("Failed to load papkin plugins: {}", err))?;
.map_err(|err| format!("Failed to load PatchBukkit plugins: {}", err))?;
plugin_manager
.enable_all_plugins(&jvm)
.map_err(|err| format!("Failed to enable papkin plugins: {}", err))?;
.map_err(|err| format!("Failed to enable PatchBukkit plugins: {}", err))?;
Ok(())
}

View File

@ -134,11 +134,15 @@ impl PluginManager {
match result {
Ok(_) => {
plugin.state = PluginState::Enabled;
log::info!("Enabled papkin plugin: {}", plugin.name);
log::info!("Enabled PatchBukkit plugin: {}", plugin.name);
}
Err(e) => {
plugin.state = PluginState::Errored;
log::error!("Failed to enable papkin plugin {}: {:?}", plugin.name, e);
log::error!(
"Failed to enable PatchBukkit plugin {}: {:?}",
plugin.name,
e
);
}
}
}
@ -146,8 +150,10 @@ impl PluginManager {
}
pub fn load_all_plugins(&mut self, jvm: &Jvm) -> Result<()> {
let loader =
jvm.create_instance("org.papkin.loader.PluginLoader", InvocationArg::empty())?;
let loader = jvm.create_instance(
"org.patchbukkit.loader.PluginLoader",
InvocationArg::empty(),
)?;
for plugin in &mut self.plugins {
let result = jvm.invoke(
&loader,
@ -159,11 +165,11 @@ impl PluginManager {
Ok(instance) => {
plugin.instance = Some(instance);
plugin.state = PluginState::Loaded;
log::info!("Loaded papkin plugin: {}", plugin.name);
log::info!("Loaded PatchBukkit plugin: {}", plugin.name);
}
Err(e) => {
plugin.state = PluginState::Errored;
log::error!("Failed to load papkin plugin {}: {:?}", plugin.name, e);
log::error!("Failed to load PatchBukkit plugin {}: {:?}", plugin.name, e);
}
}
}