Added plugin command support

This commit is contained in:
ccgauche 2020-12-12 16:02:58 +01:00 committed by Joshua Barretto
parent 2743825181
commit cae81e625e
9 changed files with 101 additions and 29 deletions

Binary file not shown.

View File

@ -17,6 +17,8 @@
option_zip
)]
pub extern crate plugin_api;
pub mod assets;
pub mod astar;
pub mod character;

View File

@ -13,6 +13,13 @@ impl Into<u64> for Uid {
fn into(self) -> u64 { self.0 }
}
impl Into<plugin_api::Uid> for Uid {
fn into(self) -> plugin_api::Uid {
plugin_api::Uid(self.0)
}
}
impl From<u64> for Uid {
fn from(uid: u64) -> Self { Self(uid) }
}

View File

@ -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<String>,
pub player: Player,
}
impl Event for ChatCommandEvent {
type Response = Result<Vec<String>, 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 {

View File

@ -20,7 +20,6 @@ checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
name = "hello"
version = "0.1.0"
dependencies = [
"veloren-plugin-api",
"veloren-plugin-rt",
]

View File

@ -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]

View File

@ -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<Vec<String>, 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))]);

View File

@ -1,5 +1,7 @@
#![feature(const_fn)]
pub extern crate plugin_derive;
pub use plugin_api as api;
pub use plugin_derive::*;

View File

@ -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::<ChatCommand>() {
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::<PluginMgr>();
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::<Uid>().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
))
);
}
}
}
}