diff --git a/assets/plugins/hello.plugin.tar b/assets/plugins/hello.plugin.tar index 358e51550a..4e054cf800 100644 Binary files a/assets/plugins/hello.plugin.tar and b/assets/plugins/hello.plugin.tar differ diff --git a/common/src/lib.rs b/common/src/lib.rs index 145d62a593..6bef59fea8 100644 --- a/common/src/lib.rs +++ b/common/src/lib.rs @@ -17,6 +17,8 @@ option_zip )] +pub extern crate plugin_api; + pub mod assets; pub mod astar; pub mod character; diff --git a/common/src/sync/uid.rs b/common/src/sync/uid.rs index cff2dc9664..495aba2293 100644 --- a/common/src/sync/uid.rs +++ b/common/src/sync/uid.rs @@ -13,6 +13,13 @@ impl Into for Uid { fn into(self) -> u64 { self.0 } } + +impl Into for Uid { + fn into(self) -> plugin_api::Uid { + plugin_api::Uid(self.0) + } +} + impl From for Uid { fn from(uid: u64) -> Self { Self(uid) } } diff --git a/plugin/api/src/lib.rs b/plugin/api/src/lib.rs index 2619f5de9e..3c6127cded 100644 --- a/plugin/api/src/lib.rs +++ b/plugin/api/src/lib.rs @@ -12,11 +12,34 @@ pub trait Event: Serialize + DeserializeOwned{ type Response: Serialize + DeserializeOwned; } +// 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; use serde::{Serialize,Deserialize}; - #[derive(Serialize, Deserialize, Debug)] + #[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)] + pub struct ChatCommandEvent { + pub command: String, + pub command_args: Vec, + pub player: Player, + } + + impl Event for ChatCommandEvent { + type Response = Result, String>; + } + + #[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)] + pub struct Player { + pub id: Uid, + } + + #[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)] pub struct PlayerJoinEvent { pub player_name: String, pub player_id: usize @@ -26,7 +49,7 @@ pub mod events { type Response = PlayerJoinResult; } - #[derive(Serialize, Deserialize, Debug)] + #[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)] pub enum PlayerJoinResult { CloseConnection, None @@ -38,7 +61,7 @@ pub mod events { } } - #[derive(Serialize, Deserialize, Debug)] + #[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)] pub struct PluginLoadEvent; impl Event for PluginLoadEvent { diff --git a/plugin/hello/Cargo.lock b/plugin/hello/Cargo.lock index 28c9d0d77f..2d5d3dbb68 100644 --- a/plugin/hello/Cargo.lock +++ b/plugin/hello/Cargo.lock @@ -20,7 +20,6 @@ checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" name = "hello" version = "0.1.0" dependencies = [ - "veloren-plugin-api", "veloren-plugin-rt", ] diff --git a/plugin/hello/Cargo.toml b/plugin/hello/Cargo.toml index bb4d5fc40e..2368f8ca00 100644 --- a/plugin/hello/Cargo.toml +++ b/plugin/hello/Cargo.toml @@ -9,6 +9,5 @@ crate-type = ["cdylib"] [dependencies] plugin-rt = { package = "veloren-plugin-rt", path = "../rt" } -plugin-api = { package = "veloren-plugin-api", path = "../api" } [workspace] diff --git a/plugin/hello/src/lib.rs b/plugin/hello/src/lib.rs index b781880064..1d15335a46 100644 --- a/plugin/hello/src/lib.rs +++ b/plugin/hello/src/lib.rs @@ -1,7 +1,7 @@ -pub extern crate plugin_rt; +extern crate plugin_rt; use plugin_rt::*; -use plugin_api::{Action, events::*}; +use plugin_rt::api::{Action, events::*}; #[event_handler] pub fn on_load(load: PluginLoadEvent) -> () { @@ -9,6 +9,11 @@ pub fn on_load(load: PluginLoadEvent) -> () { println!("Hello world"); } +#[event_handler] +pub fn on_command_testplugin(command: ChatCommandEvent) -> Result, String> { + Ok(vec![format!("Player of id {:?} sended command with args {:?}",command.player,command.command_args)]) +} + #[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))]); diff --git a/plugin/rt/src/lib.rs b/plugin/rt/src/lib.rs index e5f459a6b3..fdbb5b773e 100644 --- a/plugin/rt/src/lib.rs +++ b/plugin/rt/src/lib.rs @@ -1,5 +1,7 @@ #![feature(const_fn)] +pub extern crate plugin_derive; + pub use plugin_api as api; pub use plugin_derive::*; diff --git a/server/src/lib.rs b/server/src/lib.rs index 4ee22c485c..1dc02f3182 100644 --- a/server/src/lib.rs +++ b/server/src/lib.rs @@ -46,22 +46,9 @@ use crate::{ state_ext::StateExt, sys::sentinel::{DeletedEntities, TrackedComps}, }; -use common::{ - assets::Asset, - cmd::ChatCommand, - comp::{self, ChatType}, - event::{EventBus, ServerEvent}, - msg::{ +use common::{assets::Asset, cmd::ChatCommand, comp::{self, ChatType}, event::{EventBus, ServerEvent}, msg::{ ClientType, DisconnectReason, ServerGeneral, ServerInfo, ServerInit, ServerMsg, WorldMapMsg, - }, - outcome::Outcome, - recipe::default_recipe_book, - resources::TimeOfDay, - rtsim::RtSimEntity, - sync::WorldSyncExt, - terrain::TerrainChunkSize, - vol::{ReadVol, RectVolSize}, -}; + }, outcome::Outcome, plugin::PluginMgr, recipe::default_recipe_book, resources::TimeOfDay, rtsim::RtSimEntity, sync::{Uid, WorldSyncExt}, terrain::TerrainChunkSize, vol::{ReadVol, RectVolSize}}; use common_sys::state::State; use futures_executor::block_on; use metrics::{PhysicsMetrics, ServerMetrics, StateTickMetrics, TickMetrics}; @@ -1008,13 +995,61 @@ impl Server { if let Ok(command) = kwd.parse::() { command.execute(self, entity, args); } else { - self.notify_client( - entity, - ChatType::CommandError.server_msg(format!( - "Unknown command '/{}'.\nType '/help' for available commands", - kwd - )), - ); + let plugin_manager = self.state.ecs().read_resource::(); + let rs = plugin_manager.execute_event(&format!("on_command_{}",&kwd), &common::plugin_api::events::ChatCommandEvent { + command: kwd.clone(), + command_args: args.split(" ").map(|x| x.to_owned()).collect(), + player: common::plugin_api::events::Player { + id: (*(self.state.ecs().read_storage::().get(entity).expect("Can't get player UUID [This should never appen]"))).into() + }, + }); + match rs { + Ok(e) => { + if e.is_empty() { + self.notify_client( + entity, + ChatType::CommandError.server_msg(format!( + "Unknown command '/{}'.\nType '/help' for available commands", + kwd + )) + ); + } else { + e.into_iter().for_each(|e| { + match e { + Ok(e) => { + if !e.is_empty() { + self.notify_client( + entity, + ChatType::CommandInfo.server_msg(e.join("\n")), + ); + } + }, + Err(e) => { + self.notify_client( + entity, + ChatType::CommandError.server_msg(format!( + "Error occurred while executing command '/{}'.\n{}", + kwd, + e + )), + ); + } + } + }); + } + }, + Err(e) => { + error!(?e, "Can't execute command {} {}",kwd,args); + self.notify_client( + entity, + ChatType::CommandError.server_msg(format!( + "Internal error while executing '/{}'.\nContact the server administrator", + kwd + )) + ); + } + } + } }