diff --git a/common/state/src/lib.rs b/common/state/src/lib.rs index 53c52c3c7d..aacbfcf589 100644 --- a/common/state/src/lib.rs +++ b/common/state/src/lib.rs @@ -1,6 +1,8 @@ //! This crate contains the [`State`] and shared between //! server (`veloren-server`) and the client (`veloren-client`) +#![feature(maybe_uninit_uninit_array, maybe_uninit_array_assume_init)] + #[cfg(feature = "plugins")] pub mod plugin; mod special_areas; mod state; diff --git a/common/state/src/plugin/memory_manager.rs b/common/state/src/plugin/memory_manager.rs index 2aafdccf9a..f6d0943ba3 100644 --- a/common/state/src/plugin/memory_manager.rs +++ b/common/state/src/plugin/memory_manager.rs @@ -1,4 +1,7 @@ -use std::sync::atomic::{AtomicPtr, Ordering}; +use std::{ + mem::MaybeUninit, + sync::atomic::{AtomicPtr, Ordering}, +}; use serde::{Deserialize, Serialize}; use specs::{ @@ -171,9 +174,11 @@ pub fn write_data_as_pointer( } /// This function writes an raw bytes to WASM memory returning a pointer and -/// a length. Will realloc the buffer is not wide enough -/// As this is often called with a length and an object it accepts to slices and -/// concatenates them +/// a length. Will realloc the buffer is not wide enough. +/// +/// As this function is often called after prepending a length to an existing +/// object it accepts two slices and concatenates them to cut down copying in +/// the caller. pub fn write_bytes( store: &mut StoreMut, memory: &Memory, @@ -246,3 +251,16 @@ pub fn read_bytes( .and_then(|s| s.read_to_vec()) .map_err(|_| PluginModuleError::InvalidPointer) } + +/// This function reads a constant amount of raw bytes from memory +pub fn read_exact_bytes( + memory: &Memory, + store: &StoreRef, + ptr: WasmPtr, +) -> Result<[u8; N], PluginModuleError> { + let mut result = MaybeUninit::uninit_array(); + ptr.slice(&memory.view(store), N.try_into().unwrap()) + .and_then(|s| s.read_slice_uninit(&mut result)) + .map_err(|_| PluginModuleError::InvalidPointer)?; + unsafe { Ok(MaybeUninit::array_assume_init(result)) } +} diff --git a/common/state/src/plugin/module.rs b/common/state/src/plugin/module.rs index 382505c2fb..50c9cb4986 100644 --- a/common/state/src/plugin/module.rs +++ b/common/state/src/plugin/module.rs @@ -243,16 +243,10 @@ fn execute_raw( .call(&mut module.store.as_store_mut(), ptr, len) .map_err(PluginModuleError::RunFunction)?; - // The first 4/8 bytes correspond to the length of the result - let mut result_len = [0u8; std::mem::size_of::<::Offset>()]; - result_ptr - .slice( - &module.memory.view(&module.store.as_store_ref()), - std::mem::size_of::<::Offset>() - as ::Offset, - ) - .and_then(|s| s.read_slice(&mut result_len)) - .map_err(|_| PluginModuleError::InvalidPointer)?; + // The first bytes correspond to the length of the result + let result_len: [u8; std::mem::size_of::<::Offset>()] = + memory_manager::read_exact_bytes(&module.memory, &module.store.as_store_ref(), result_ptr) + .map_err(|_| PluginModuleError::InvalidPointer)?; let result_len = ::Offset::from_le_bytes(result_len); // Read the result of the function with the pointer and the length diff --git a/server/src/login_provider.rs b/server/src/login_provider.rs index 181308eec4..e928c7b034 100644 --- a/server/src/login_provider.rs +++ b/server/src/login_provider.rs @@ -9,8 +9,6 @@ use std::{str::FromStr, sync::Arc}; use tokio::{runtime::Runtime, sync::oneshot}; use tracing::{error, info}; -// #[cfg(feature = "plugins")] use {}; - fn derive_uuid(username: &str) -> Uuid { let mut state = 144066263297769815596495629667062367629; @@ -95,8 +93,6 @@ impl LoginProvider { pub(crate) fn login( pending: &mut PendingLogin, - // #[cfg(feature = "plugins")] world: &EcsWorld, - // #[cfg(feature = "plugins")] plugin_manager: &PluginMgr, admins: &HashMap, whitelist: &HashMap, banlist: &HashMap, @@ -133,37 +129,6 @@ impl LoginProvider { return Some(Err(RegisterError::NotOnWhitelist)); } - #[cfg(feature = "plugins")] - { - // Plugin player join hooks execute for all players, but are - // only allowed to filter non-admins. - // - // We also run it before checking player count, to avoid - // lock contention in the plugin. - - // Two events can't be handled on the same plugin in - // parallel, so this needs rework - - // match plugin_manager.execute_event(world, - // &PlayerJoinEvent { player_name: - // username.clone(), player_id: - // *uuid.as_bytes(), }) { - // Ok(e) => { - // if admin.is_none() { - // for i in e.into_iter() { - // if let PlayerJoinResult::Kick(a) = i { - // return - // Some(Err(RegisterError::Kicked(a))); - // } - // } - // } - // }, - // Err(e) => { - // error!("Error occured while executing `on_join`: - // {:?}", e); }, - // }; - } - // non-admins can only join if the player count has not been exceeded. let (player_count_exceeded, res) = player_count_exceeded(username, uuid); if admin.is_none() && player_count_exceeded { diff --git a/server/src/sys/msg/register.rs b/server/src/sys/msg/register.rs index 199a14931a..144ff89fbd 100644 --- a/server/src/sys/msg/register.rs +++ b/server/src/sys/msg/register.rs @@ -138,16 +138,6 @@ impl<'a> System<'a> for Sys { } let old_player_count = player_list.len(); - // #[cfg(feature = "plugins")] - // let ecs_world = EcsWorld { - // entities: &read_data.entities, - // health: (&read_data._healths).into(), - // uid: (&read_data.uids).into(), - // // NOTE: Only the old player list is provided, to avoid scalability - // // bottlenecks. - // player: (&players).into(), - // id_maps: &read_data._id_maps, - // }; // NOTE: this is just default value. //