Better plugin API

This commit is contained in:
Joshua Barretto 2020-12-12 19:26:42 +00:00
parent b18eda37b5
commit 8e937a50ca
9 changed files with 34 additions and 21 deletions

View File

@ -17,8 +17,6 @@
option_zip
)]
pub extern crate plugin_api;
pub mod assets;
pub mod astar;
pub mod character;
@ -61,3 +59,4 @@ pub mod volumes;
pub use combat::{Damage, DamageSource, GroupTarget, Knockback};
pub use explosion::{Explosion, RadiusEffect};
pub use loadout_builder::LoadoutBuilder;
pub use plugin_api;

View File

@ -24,7 +24,7 @@ impl PluginModule {
let module = compile(&wasm_data).map_err(|e| PluginModuleError::Compile(e))?;
let instance = module
.instantiate(&imports! {"env" => {
"send_action" => func!(read_action),
"raw_emit_actions" => func!(read_action),
}}).map_err(|e| PluginModuleError::Instantiate(e))?;
Ok(Self {

View File

@ -181,7 +181,7 @@ impl State {
// Load plugins from asset directory
ecs.insert(match PluginMgr::from_assets() {
Ok(plugin_mgr) => {
if let Err(e) = plugin_mgr.execute_event("on_load", &plugin_api::events::PluginLoadEvent {}) {
if let Err(e) = plugin_mgr.execute_event("on_load", &plugin_api::event::PluginLoadEvent {}) {
tracing::error!(?e, "Failed to run plugin init");
info!("Error occurred when loading plugins. Running without plugins instead.");
PluginMgr::default()

View File

@ -12,15 +12,19 @@ pub trait Event: Serialize + DeserializeOwned + Send + Sync{
type Response: Serialize + DeserializeOwned + Send + Sync;
}
#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)]
pub enum PluginMode {
Server,
Client,
Singleplayer, // To be used later when we no longer start up an entirely new server for singleplayer
}
// TODO: Unify this with common/src/comp/uid.rs:Uid
#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub struct Uid(pub u64);
pub mod events {
use crate::Uid;
use super::Event;
pub mod event {
use super::*;
use serde::{Serialize,Deserialize};
#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)]
@ -62,7 +66,9 @@ pub mod events {
}
#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)]
pub struct PluginLoadEvent;
pub struct PluginLoadEvent {
pub mode: PluginMode,
}
impl Event for PluginLoadEvent {
type Response = ();

View File

@ -11,3 +11,7 @@ crate-type = ["cdylib"]
plugin-rt = { package = "veloren-plugin-rt", path = "../rt" }
[workspace]
[profile.dev]
opt-level = "s"
debug = false

View File

@ -1,11 +1,11 @@
extern crate plugin_rt;
use plugin_rt::*;
use plugin_rt::api::{Action, events::*};
use plugin_rt::api::{Action, event::*};
#[event_handler]
pub fn on_load(load: PluginLoadEvent) -> () {
send_actions(vec![Action::Print("This is a test".to_owned())]);
emit_action(Action::Print("This is a test".to_owned()));
println!("Hello world");
}
@ -16,7 +16,7 @@ pub fn on_command_testplugin(command: ChatCommandEvent) -> Result<Vec<String>, S
#[event_handler]
pub fn on_player_join(input: PlayerJoinEvent) -> PlayerJoinResult {
send_actions(vec![Action::PlayerSendMessage(input.player_id,format!("Welcome {} on our server",input.player_name))]);
emit_action(Action::PlayerSendMessage(input.player_id,format!("Welcome {} on our server",input.player_name)));
if input.player_name == "Cheater123" {
PlayerJoinResult::CloseConnection
} else {

View File

@ -9,13 +9,17 @@ use serde::de::DeserializeOwned;
use serde::Serialize;
extern "C" {
fn send_action(ptr: *const u8, len: usize);
fn raw_emit_actions(ptr: *const u8, len: usize);
}
pub fn send_actions(action: Vec<api::Action>) {
let ret = bincode::serialize(&action).unwrap();
pub fn emit_action(action: api::Action) {
emit_actions(vec![action])
}
pub fn emit_actions(actions: Vec<api::Action>) {
let ret = bincode::serialize(&actions).unwrap();
unsafe {
send_action(ret.as_ptr(), ret.len());
raw_emit_actions(ret.as_ptr(), ret.len());
}
}

View File

@ -1 +1 @@
nightly-2020-12-10
nightly-2020-12-12

View File

@ -996,10 +996,10 @@ impl Server {
command.execute(self, entity, args);
} else {
let plugin_manager = self.state.ecs().read_resource::<PluginMgr>();
let rs = plugin_manager.execute_event(&format!("on_command_{}",&kwd), &common::plugin_api::events::ChatCommandEvent {
let rs = plugin_manager.execute_event(&format!("on_command_{}",&kwd), &common::plugin_api::event::ChatCommandEvent {
command: kwd.clone(),
command_args: args.split(" ").map(|x| x.to_owned()).collect(),
player: common::plugin_api::events::Player {
player: common::plugin_api::event::Player {
id: (*(self.state.ecs().read_storage::<Uid>().get(entity).expect("Can't get player UUID [This should never appen]"))).into()
},
});
@ -1049,7 +1049,7 @@ impl Server {
);
}
}
}
}