Add pumpkin-plugin

mhh, Whats that?
This commit is contained in:
Snowiiii 2024-08-27 22:47:21 +02:00
parent 8e9ea66787
commit 3b438872a8
9 changed files with 1725 additions and 30 deletions

1
.gitignore vendored
View File

@ -81,6 +81,7 @@ mc-source-code/DecompilerMC/
mc-source-code/src/ mc-source-code/src/
mc-source-code/target/ mc-source-code/target/
plugins/
world/ world/
# project's binary configurations # project's binary configurations

1671
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
[workspace] [workspace]
resolver = "2" resolver = "2"
members = [ "pumpkin-core", "pumpkin-entity", "pumpkin-inventory", "pumpkin-macros/", "pumpkin-protocol/", "pumpkin-registry/", "pumpkin-world", "pumpkin/"] members = [ "pumpkin-core", "pumpkin-entity", "pumpkin-inventory", "pumpkin-macros/", "pumpkin-plugin", "pumpkin-protocol/", "pumpkin-registry/", "pumpkin-world", "pumpkin/"]
[workspace.package] [workspace.package]
version = "0.1.0" version = "0.1.0"
@ -12,6 +12,7 @@ lto = true
codegen-units = 1 codegen-units = 1
[workspace.dependencies] [workspace.dependencies]
log = "0.4"
tokio = { version = "1.39.2", features = ["net", "macros", "rt-multi-thread", "fs", "io-util", "sync"] } tokio = { version = "1.39.2", features = ["net", "macros", "rt-multi-thread", "fs", "io-util", "sync"] }
rayon = "1.10.0" rayon = "1.10.0"
uuid = { version = "1.10.0", features = ["serde", "v3"] } uuid = { version = "1.10.0", features = ["serde", "v3"] }

View File

@ -0,0 +1,8 @@
[package]
name = "pumpkin-plugin"
version.workspace = true
edition.workspace = true
[dependencies]
extism = "1.5.0"
log.workspace = true

49
pumpkin-plugin/src/lib.rs Normal file
View File

@ -0,0 +1,49 @@
use std::path::Path;
use extism::{Manifest, Plugin, Wasm};
pub const PLUGIN_DIR: &str = "plugins";
pub struct PluginLoader {
plugins: Vec<Plugin>,
}
impl PluginLoader {
pub fn load() -> Self {
let plugin_dir = Path::new(PLUGIN_DIR);
if !plugin_dir.exists() || !plugin_dir.is_dir() {
log::info!("Creating plugins dir...");
std::fs::create_dir(plugin_dir).expect("Failed to create Plugin dir");
return Self { plugins: vec![] };
}
let files = std::fs::read_dir(plugin_dir).expect("Failed to read plugin dir");
let mut plugins = Vec::new();
for file in files {
let file = file.expect("Failed to get Plugin file");
let path = file.path();
if path
.extension()
.expect("Failed to get Plugin file extension")
== "wasm"
{
log::info!(
"Loading Plugin {:?}",
path.file_name().expect("Failed to get Plugin file name")
);
let wasm = Wasm::file(path);
let manifest = Manifest::new([wasm]);
let mut plugin = Plugin::new(&manifest, [], true).unwrap();
plugin
.call::<(), ()>("on_enable", ())
.expect("Failed to call on_enable funcation");
plugins.push(plugin);
}
}
Self { plugins }
}
pub fn plugins(&mut self) -> &mut Vec<Plugin> {
&mut self.plugins
}
}

View File

@ -19,7 +19,7 @@ serde_json = "1.0"
flate2 = "1.0.33" flate2 = "1.0.33"
thiserror = "1.0.63" thiserror = "1.0.63"
log = "0.4" log.workspace = true
num-traits = "0.2" num-traits = "0.2"
num-derive = "0.4" num-derive = "0.4"

View File

@ -10,6 +10,7 @@ default = []
[dependencies] [dependencies]
# pumpkin # pumpkin
pumpkin-core = { path = "../pumpkin-core"} pumpkin-core = { path = "../pumpkin-core"}
pumpkin-plugin = { path = "../pumpkin-plugin"}
pumpkin-inventory = { path = "../pumpkin-inventory"} pumpkin-inventory = { path = "../pumpkin-inventory"}
pumpkin-world = { path = "../pumpkin-world"} pumpkin-world = { path = "../pumpkin-world"}
pumpkin-entity = { path = "../pumpkin-entity"} pumpkin-entity = { path = "../pumpkin-entity"}
@ -53,7 +54,7 @@ image = { version = "0.25", default-features = false, features = ["png"]}
# logging # logging
simple_logger = "5.0.0" simple_logger = "5.0.0"
log = "0.4" log.workspace = true
# networking # networking
mio = { version = "1.0.2", features = ["os-poll", "net"]} mio = { version = "1.0.2", features = ["os-poll", "net"]}

View File

@ -34,6 +34,11 @@ fn main() -> io::Result<()> {
use pumpkin_core::text::{color::NamedColor, TextComponent}; use pumpkin_core::text::{color::NamedColor, TextComponent};
use rcon::RCONServer; use rcon::RCONServer;
simple_logger::SimpleLogger::new()
.with_level(log::LevelFilter::Info)
.init()
.unwrap();
let rt = tokio::runtime::Builder::new_multi_thread() let rt = tokio::runtime::Builder::new_multi_thread()
.enable_all() .enable_all()
.build() .build()
@ -60,8 +65,6 @@ fn main() -> io::Result<()> {
let advanced_configuration = AdvancedConfiguration::load("features.toml"); let advanced_configuration = AdvancedConfiguration::load("features.toml");
simple_logger::SimpleLogger::new().init().unwrap();
// Create a poll instance. // Create a poll instance.
let mut poll = Poll::new()?; let mut poll = Poll::new()?;
// Create storage for events. // Create storage for events.

View File

@ -14,6 +14,7 @@ use image::GenericImageView;
use mio::Token; use mio::Token;
use num_traits::ToPrimitive; use num_traits::ToPrimitive;
use pumpkin_entity::{entity_type::EntityType, EntityId}; use pumpkin_entity::{entity_type::EntityType, EntityId};
use pumpkin_plugin::PluginLoader;
use pumpkin_protocol::{ use pumpkin_protocol::{
client::{ client::{
config::CPluginMessage, config::CPluginMessage,
@ -46,6 +47,8 @@ pub struct Server {
pub private_key: RsaPrivateKey, pub private_key: RsaPrivateKey,
pub public_key_der: Box<[u8]>, pub public_key_der: Box<[u8]>,
pub plugin_loader: PluginLoader,
pub world: Arc<tokio::sync::Mutex<World>>, pub world: Arc<tokio::sync::Mutex<World>>,
pub status_response: StatusResponse, pub status_response: StatusResponse,
// We cache the json response here so we don't parse it every time someone makes a Status request. // We cache the json response here so we don't parse it every time someone makes a Status request.
@ -58,10 +61,10 @@ pub struct Server {
/// Cache the registry so we don't have to parse it every time a player joins /// Cache the registry so we don't have to parse it every time a player joins
pub cached_registry: Vec<Registry>, pub cached_registry: Vec<Registry>,
// TODO: place this into every world
pub current_players: HashMap<Arc<Token>, Arc<Mutex<Player>>>, pub current_players: HashMap<Arc<Token>, Arc<Mutex<Player>>>,
// TODO: replace with HashMap <World, Player> entity_id: AtomicI32,
entity_id: AtomicI32, // TODO: place this into every world
pub base_config: BasicConfiguration, pub base_config: BasicConfiguration,
pub advanced_config: AdvancedConfiguration, pub advanced_config: AdvancedConfiguration,
@ -96,6 +99,9 @@ impl Server {
None None
}; };
log::info!("Loading Plugins");
let plugin_loader = PluginLoader::load();
log::warn!("Pumpkin does currently not have World or Chunk generation, Using ../world folder with vanilla pregenerated chunks"); log::warn!("Pumpkin does currently not have World or Chunk generation, Using ../world folder with vanilla pregenerated chunks");
let world = World::load(Dimension::OverWorld.into_level( let world = World::load(Dimension::OverWorld.into_level(
// TODO: load form config // TODO: load form config
@ -103,6 +109,7 @@ impl Server {
)); ));
Self { Self {
plugin_loader,
cached_registry: Registry::get_static(), cached_registry: Registry::get_static(),
// 0 is invalid // 0 is invalid
entity_id: 2.into(), entity_id: 2.into(),