mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Add Debug impls for a few plugin things
This commit is contained in:
parent
457026a48e
commit
b5ca279634
@ -24,18 +24,13 @@ use rayon::prelude::*;
|
||||
pub enum PluginEnvironement {
|
||||
LOCAL,
|
||||
DISTANT,
|
||||
BOTH
|
||||
BOTH,
|
||||
}
|
||||
|
||||
impl PluginEnvironement {
|
||||
pub fn is_local(&self) -> bool { matches!(self, Self::LOCAL | Self::BOTH) }
|
||||
|
||||
pub fn is_local(&self) -> bool {
|
||||
matches!(self, Self::LOCAL | Self::BOTH)
|
||||
}
|
||||
|
||||
pub fn is_distant(&self) -> bool {
|
||||
matches!(self, Self::DISTANT | Self::BOTH)
|
||||
}
|
||||
pub fn is_distant(&self) -> bool { matches!(self, Self::DISTANT | Self::BOTH) }
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
@ -62,6 +57,28 @@ pub enum PluginFile {
|
||||
modules: Vec<PluginModule>,
|
||||
files: HashMap<PathBuf, Vec<u8>>,
|
||||
bytes: Vec<Vec<u8>>,
|
||||
},
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for PluginFile {
|
||||
fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
match self {
|
||||
Self::ForDistant { data, bytes } => fmt
|
||||
.debug_struct("ForDistant")
|
||||
.field("data", data)
|
||||
.field("num modules", &bytes.len())
|
||||
.finish(),
|
||||
Self::ForLocal { data, modules, .. } => fmt
|
||||
.debug_struct("ForLocals")
|
||||
.field("data", data)
|
||||
.field("modules", modules)
|
||||
.finish(),
|
||||
Self::Both { data, modules, .. } => fmt
|
||||
.debug_struct("Both")
|
||||
.field("data", data)
|
||||
.field("modules", modules)
|
||||
.finish(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -91,22 +108,26 @@ impl PluginFile {
|
||||
)
|
||||
.map_err(PluginError::Toml)?;
|
||||
|
||||
|
||||
Ok(match (data.target.is_local(),data.target.is_distant()) {
|
||||
(true,e) => {
|
||||
Ok(match (data.target.is_local(), data.target.is_distant()) {
|
||||
(true, e) => {
|
||||
let mut bytes = Vec::new();
|
||||
let modules = data
|
||||
.modules
|
||||
.iter()
|
||||
.map(|path| {
|
||||
let wasm_data = files.remove(path).ok_or(PluginError::NoSuchModule)?;
|
||||
let tmp = PluginModule::new(data.name.to_owned(), &wasm_data).map_err(|e| {
|
||||
PluginError::PluginModuleError(data.name.to_owned(), "<init>".to_owned(), e)
|
||||
});
|
||||
bytes.push(wasm_data);
|
||||
tmp
|
||||
})
|
||||
.collect::<Result<_, _>>()?;
|
||||
.modules
|
||||
.iter()
|
||||
.map(|path| {
|
||||
let wasm_data = files.remove(path).ok_or(PluginError::NoSuchModule)?;
|
||||
let tmp =
|
||||
PluginModule::new(data.name.to_owned(), &wasm_data).map_err(|e| {
|
||||
PluginError::PluginModuleError(
|
||||
data.name.to_owned(),
|
||||
"<init>".to_owned(),
|
||||
e,
|
||||
)
|
||||
});
|
||||
bytes.push(wasm_data);
|
||||
tmp
|
||||
})
|
||||
.collect::<Result<_, _>>()?;
|
||||
if e {
|
||||
Self::Both {
|
||||
data,
|
||||
@ -122,30 +143,25 @@ impl PluginFile {
|
||||
}
|
||||
}
|
||||
},
|
||||
(false,_) => {
|
||||
(false, _) => {
|
||||
let bytes = data
|
||||
.modules
|
||||
.iter()
|
||||
.map(|path| {
|
||||
files.remove(path).ok_or(PluginError::NoSuchModule)
|
||||
})
|
||||
.collect::<Result<_, _>>()?;
|
||||
Self::ForDistant {
|
||||
data,
|
||||
bytes,
|
||||
}
|
||||
|
||||
}
|
||||
.modules
|
||||
.iter()
|
||||
.map(|path| files.remove(path).ok_or(PluginError::NoSuchModule))
|
||||
.collect::<Result<_, _>>()?;
|
||||
Self::ForDistant { data, bytes }
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
pub fn get_data(&self) -> &PluginData {
|
||||
// Wait for let-or syntax to be stable
|
||||
match self {
|
||||
Self::ForLocal {data,..} | Self::Both {data,..} | Self::ForDistant {data,..} => data
|
||||
Self::ForLocal { data, .. }
|
||||
| Self::Both { data, .. }
|
||||
| Self::ForDistant { data, .. } => data,
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
impl PluginExecutable for PluginFile {
|
||||
@ -157,35 +173,33 @@ impl PluginExecutable for PluginFile {
|
||||
where
|
||||
T: Event,
|
||||
{
|
||||
if let Self::ForLocal {modules,data,..} | Self::Both {modules,data,..} = self {
|
||||
if let Self::ForLocal { modules, data, .. } | Self::Both { modules, data, .. } = self {
|
||||
modules
|
||||
.iter()
|
||||
.flat_map(|module| {
|
||||
module.try_execute(event_name, event).map(|x| {
|
||||
x.map_err(|e| {
|
||||
PluginError::PluginModuleError(
|
||||
data.name.to_owned(),
|
||||
event_name.to_owned(),
|
||||
e,
|
||||
)
|
||||
.iter()
|
||||
.flat_map(|module| {
|
||||
module.try_execute(event_name, event).map(|x| {
|
||||
x.map_err(|e| {
|
||||
PluginError::PluginModuleError(
|
||||
data.name.to_owned(),
|
||||
event_name.to_owned(),
|
||||
e,
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
.collect::<Result<Vec<_>, _>>()
|
||||
.collect::<Result<Vec<_>, _>>()
|
||||
} else {
|
||||
Ok(Vec::new())
|
||||
}
|
||||
}
|
||||
|
||||
fn get_name(&self) -> &str {
|
||||
&self.get_data().name
|
||||
}
|
||||
fn get_name(&self) -> &str { &self.get_data().name }
|
||||
}
|
||||
|
||||
#[derive(Clone, Default)]
|
||||
#[derive(Clone, Default, Debug)]
|
||||
pub struct PluginMgr {
|
||||
plugins: Vec<PluginFile>,
|
||||
plugins_from_server: Vec<BinaryPlugin>
|
||||
plugins_from_server: Vec<BinaryPlugin>,
|
||||
}
|
||||
|
||||
impl PluginMgr {
|
||||
@ -194,44 +208,70 @@ impl PluginMgr {
|
||||
let mut assets_path = (&*ASSETS_PATH).clone();
|
||||
assets_path.push("plugins");
|
||||
info!("Searching {:?} for plugins...", assets_path);
|
||||
Self::from_dir(assets_path)
|
||||
let this = Self::from_dir(assets_path);
|
||||
if this.is_ok() {
|
||||
dbg!(&this.as_ref().unwrap().plugins);
|
||||
}
|
||||
this
|
||||
}
|
||||
|
||||
pub fn load_server_plugins(&mut self, plugins: &Vec<(String,Vec<Vec<u8>>)>) {
|
||||
let prepared = PreparedEventQuery::new(&plugin_api::event::PluginLoadEvent { game_mode: plugin_api::GameMode::Client }).unwrap();
|
||||
self.plugins_from_server.extend(plugins.iter().flat_map(|(name,bytes)| {
|
||||
info!("Loading {} with {} module(s) from server",name,bytes.len());
|
||||
match BinaryPlugin::from_bytes(name.clone(), bytes) {
|
||||
Ok(e) => {
|
||||
if let Err(e) = e.modules.iter().flat_map(|x| {
|
||||
x.try_execute("on_load", &prepared)
|
||||
}).collect::<Result<Vec<_>, _>>() {
|
||||
error!("Error while executing `on_load` on network retreived plugin: `{}` \n{:?}",name,e);
|
||||
}
|
||||
Some(e)
|
||||
},
|
||||
Err(e) => {
|
||||
tracing::error!("Error while loading distant plugin! Contact the server administrator!\n{:?}",e);
|
||||
pub fn load_server_plugins(&mut self, plugins: &Vec<(String, Vec<Vec<u8>>)>) {
|
||||
let prepared = PreparedEventQuery::new(&plugin_api::event::PluginLoadEvent {
|
||||
game_mode: plugin_api::GameMode::Client,
|
||||
})
|
||||
.unwrap();
|
||||
self.plugins_from_server
|
||||
.extend(plugins.iter().flat_map(|(name, bytes)| {
|
||||
info!(
|
||||
"Loading {} with {} module(s) from server",
|
||||
name,
|
||||
bytes.len()
|
||||
);
|
||||
match BinaryPlugin::from_bytes(name.clone(), bytes) {
|
||||
Ok(e) => {
|
||||
if let Err(e) = e
|
||||
.modules
|
||||
.iter()
|
||||
.flat_map(|x| x.try_execute("on_load", &prepared))
|
||||
.collect::<Result<Vec<_>, _>>()
|
||||
{
|
||||
error!(
|
||||
"Error while executing `on_load` on network retreived plugin: \
|
||||
`{}` \n{:?}",
|
||||
name, e
|
||||
);
|
||||
}
|
||||
Some(e)
|
||||
},
|
||||
Err(e) => {
|
||||
tracing::error!(
|
||||
"Error while loading distant plugin! Contact the server \
|
||||
administrator!\n{:?}",
|
||||
e
|
||||
);
|
||||
None
|
||||
},
|
||||
}
|
||||
}));
|
||||
println!("Plugins from server: {}", self.plugins_from_server.len());
|
||||
dbg!(&self.plugins_from_server);
|
||||
}
|
||||
|
||||
pub fn clear_server_plugins(&mut self) { self.plugins_from_server.clear(); }
|
||||
|
||||
pub fn get_module_bytes(&self) -> Vec<(String, Vec<Vec<u8>>)> {
|
||||
self.plugins
|
||||
.iter()
|
||||
.flat_map(|x| {
|
||||
if let PluginFile::ForDistant { data, bytes, .. }
|
||||
| PluginFile::Both { data, bytes, .. } = x
|
||||
{
|
||||
Some((data.name.clone(), bytes.clone()))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}));
|
||||
println!("Plugins from server: {}",self.plugins_from_server.len());
|
||||
}
|
||||
|
||||
pub fn clear_server_plugins(&mut self) {
|
||||
self.plugins_from_server.clear();
|
||||
}
|
||||
|
||||
pub fn get_module_bytes(&self) -> Vec<(String,Vec<Vec<u8>>)> {
|
||||
self.plugins.iter().flat_map(|x| {
|
||||
if let PluginFile::ForDistant {data, bytes, ..} |
|
||||
PluginFile::Both {data, bytes, ..} = x {
|
||||
Some((data.name.clone(), bytes.clone()))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}).collect()
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn execute_prepared<T>(
|
||||
@ -242,7 +282,7 @@ impl PluginMgr {
|
||||
where
|
||||
T: Event,
|
||||
{
|
||||
println!("{}",event_name);
|
||||
println!("{}", event_name);
|
||||
let mut o = self
|
||||
.plugins
|
||||
.par_iter()
|
||||
@ -251,17 +291,18 @@ impl PluginMgr {
|
||||
.into_iter()
|
||||
.flatten()
|
||||
.collect::<Vec<_>>();
|
||||
println!("Event exe 2 {}",self.plugins_from_server.len());
|
||||
o.extend(self
|
||||
.plugins_from_server
|
||||
.par_iter()
|
||||
.map(|plugin| {
|
||||
println!("Event exe 3");
|
||||
plugin.execute_prepared(event_name, event)
|
||||
})
|
||||
.collect::<Result<Vec<_>, _>>()?
|
||||
.into_iter()
|
||||
.flatten());
|
||||
println!("Event exe 2 {}", self.plugins_from_server.len());
|
||||
o.extend(
|
||||
self.plugins_from_server
|
||||
.par_iter()
|
||||
.map(|plugin| {
|
||||
println!("Event exe 3");
|
||||
plugin.execute_prepared(event_name, event)
|
||||
})
|
||||
.collect::<Result<Vec<_>, _>>()?
|
||||
.into_iter()
|
||||
.flatten(),
|
||||
);
|
||||
Ok(o)
|
||||
}
|
||||
|
||||
@ -273,7 +314,6 @@ impl PluginMgr {
|
||||
where
|
||||
T: Event,
|
||||
{
|
||||
|
||||
println!("Event exe 1");
|
||||
self.execute_prepared(event_name, &PreparedEventQuery::new(event)?)
|
||||
}
|
||||
@ -306,46 +346,51 @@ impl PluginMgr {
|
||||
|
||||
for plugin in &plugins {
|
||||
match plugin {
|
||||
PluginFile::Both { data, modules, .. } | PluginFile::ForLocal { data, modules, .. } => {
|
||||
PluginFile::Both { data, modules, .. }
|
||||
| PluginFile::ForLocal { data, modules, .. } => {
|
||||
info!(
|
||||
"Loaded plugin '{}' with {} module(s)",
|
||||
data.name,
|
||||
modules.len()
|
||||
);
|
||||
}
|
||||
},
|
||||
PluginFile::ForDistant { data, bytes } => {
|
||||
info!(
|
||||
"Loaded plugin '{}' with {} module(s)",
|
||||
data.name,
|
||||
bytes.len()
|
||||
);
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
Ok(Self { plugins, plugins_from_server: Vec::new() })
|
||||
Ok(Self {
|
||||
plugins,
|
||||
plugins_from_server: Vec::new(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct BinaryPlugin {
|
||||
modules: Vec<PluginModule>,
|
||||
name: String,
|
||||
}
|
||||
|
||||
impl BinaryPlugin {
|
||||
|
||||
pub fn from_bytes(name: String, bytes: &Vec<Vec<u8>>) -> Result<Self, PluginError> {
|
||||
Ok(
|
||||
Self {
|
||||
modules: bytes.iter().enumerate().map(|(i,module)| {
|
||||
PluginModule::new(format!("{}-module({})",name,i), module).map_err(|e| {
|
||||
Ok(Self {
|
||||
modules: bytes
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(i, module)| {
|
||||
PluginModule::new(format!("{}-module({})", name, i), module).map_err(|e| {
|
||||
PluginError::PluginModuleError(name.clone(), "<init>".to_owned(), e)
|
||||
})
|
||||
}).collect::<Result<Vec<_>,_>>()?,
|
||||
name
|
||||
}
|
||||
)
|
||||
})
|
||||
.collect::<Result<Vec<_>, _>>()?,
|
||||
name,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -362,7 +407,7 @@ impl PluginExecutable for BinaryPlugin {
|
||||
self.modules
|
||||
.iter()
|
||||
.flat_map(|module| {
|
||||
println!("1: {}",event_name);
|
||||
println!("1: {}", event_name);
|
||||
module.try_execute(event_name, event).map(|x| {
|
||||
x.map_err(|e| {
|
||||
PluginError::PluginModuleError(
|
||||
@ -376,13 +421,10 @@ impl PluginExecutable for BinaryPlugin {
|
||||
.collect::<Result<Vec<_>, _>>()
|
||||
}
|
||||
|
||||
fn get_name(&self) -> &str {
|
||||
&self.name
|
||||
}
|
||||
fn get_name(&self) -> &str { &self.name }
|
||||
}
|
||||
|
||||
pub trait PluginExecutable {
|
||||
|
||||
fn execute_prepared<T>(
|
||||
&self,
|
||||
event_name: &str,
|
||||
@ -392,4 +434,4 @@ pub trait PluginExecutable {
|
||||
T: Event;
|
||||
|
||||
fn get_name(&self) -> &str;
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,15 @@ pub struct PluginModule {
|
||||
name: String,
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for PluginModule {
|
||||
fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
fmt.debug_struct("PluginModule")
|
||||
.field("events", &self.events)
|
||||
.field("name", &self.name)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl PluginModule {
|
||||
// This function takes bytes from a WASM File and compile them
|
||||
pub fn new(name: String, wasm_data: &[u8]) -> Result<Self, PluginModuleError> {
|
||||
|
@ -256,10 +256,10 @@ impl Server {
|
||||
let map = WorldMapMsg {
|
||||
dimensions_lg: Vec2::zero(),
|
||||
max_height: 1.0,
|
||||
rgba: vec![0],
|
||||
rgba: common::grid::Grid::new(Vec2::new(1, 1), 1),
|
||||
horizons: [(vec![0], vec![0]), (vec![0], vec![0])],
|
||||
sea_level: 0.0,
|
||||
alt: vec![30],
|
||||
alt: common::grid::Grid::new(Vec2::new(1, 1), 1),
|
||||
sites: Vec::new(),
|
||||
};
|
||||
|
||||
@ -941,10 +941,12 @@ impl Server {
|
||||
world_map: self.map.clone(),
|
||||
recipe_book: default_recipe_book().cloned(),
|
||||
#[cfg(feature = "plugins")]
|
||||
plugins: Some(self
|
||||
.state
|
||||
.ecs()
|
||||
.read_resource::<PluginMgr>().get_module_bytes()),
|
||||
plugins: Some(
|
||||
self.state
|
||||
.ecs()
|
||||
.read_resource::<PluginMgr>()
|
||||
.get_module_bytes(),
|
||||
),
|
||||
#[cfg(not(feature = "plugins"))]
|
||||
plugins: None,
|
||||
ability_map: (&*self
|
||||
|
Loading…
Reference in New Issue
Block a user