implement and use read_exact_bytes, cleanup

This commit is contained in:
Christof Petig 2023-06-24 14:22:29 +02:00
parent 65966294a0
commit 01223d7174
5 changed files with 28 additions and 59 deletions

View File

@ -1,6 +1,8 @@
//! This crate contains the [`State`] and shared between //! This crate contains the [`State`] and shared between
//! server (`veloren-server`) and the client (`veloren-client`) //! server (`veloren-server`) and the client (`veloren-client`)
#![feature(maybe_uninit_uninit_array, maybe_uninit_array_assume_init)]
#[cfg(feature = "plugins")] pub mod plugin; #[cfg(feature = "plugins")] pub mod plugin;
mod special_areas; mod special_areas;
mod state; mod state;

View File

@ -1,4 +1,7 @@
use std::sync::atomic::{AtomicPtr, Ordering}; use std::{
mem::MaybeUninit,
sync::atomic::{AtomicPtr, Ordering},
};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use specs::{ use specs::{
@ -171,9 +174,11 @@ pub fn write_data_as_pointer<T: Serialize>(
} }
/// This function writes an raw bytes to WASM memory returning a pointer and /// This function writes an raw bytes to WASM memory returning a pointer and
/// a length. Will realloc the buffer is not wide enough /// 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 /// 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( pub fn write_bytes(
store: &mut StoreMut, store: &mut StoreMut,
memory: &Memory, memory: &Memory,
@ -246,3 +251,16 @@ pub fn read_bytes(
.and_then(|s| s.read_to_vec()) .and_then(|s| s.read_to_vec())
.map_err(|_| PluginModuleError::InvalidPointer) .map_err(|_| PluginModuleError::InvalidPointer)
} }
/// This function reads a constant amount of raw bytes from memory
pub fn read_exact_bytes<const N: usize>(
memory: &Memory,
store: &StoreRef,
ptr: WasmPtr<u8, MemoryModel>,
) -> 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)) }
}

View File

@ -243,16 +243,10 @@ fn execute_raw(
.call(&mut module.store.as_store_mut(), ptr, len) .call(&mut module.store.as_store_mut(), ptr, len)
.map_err(PluginModuleError::RunFunction)?; .map_err(PluginModuleError::RunFunction)?;
// The first 4/8 bytes correspond to the length of the result // The first bytes correspond to the length of the result
let mut result_len = [0u8; std::mem::size_of::<<MemoryModel as wasmer::MemorySize>::Offset>()]; let result_len: [u8; std::mem::size_of::<<MemoryModel as wasmer::MemorySize>::Offset>()] =
result_ptr memory_manager::read_exact_bytes(&module.memory, &module.store.as_store_ref(), result_ptr)
.slice( .map_err(|_| PluginModuleError::InvalidPointer)?;
&module.memory.view(&module.store.as_store_ref()),
std::mem::size_of::<<MemoryModel as wasmer::MemorySize>::Offset>()
as <MemoryModel as wasmer::MemorySize>::Offset,
)
.and_then(|s| s.read_slice(&mut result_len))
.map_err(|_| PluginModuleError::InvalidPointer)?;
let result_len = <MemoryModel as wasmer::MemorySize>::Offset::from_le_bytes(result_len); let result_len = <MemoryModel as wasmer::MemorySize>::Offset::from_le_bytes(result_len);
// Read the result of the function with the pointer and the length // Read the result of the function with the pointer and the length

View File

@ -9,8 +9,6 @@ use std::{str::FromStr, sync::Arc};
use tokio::{runtime::Runtime, sync::oneshot}; use tokio::{runtime::Runtime, sync::oneshot};
use tracing::{error, info}; use tracing::{error, info};
// #[cfg(feature = "plugins")] use {};
fn derive_uuid(username: &str) -> Uuid { fn derive_uuid(username: &str) -> Uuid {
let mut state = 144066263297769815596495629667062367629; let mut state = 144066263297769815596495629667062367629;
@ -95,8 +93,6 @@ impl LoginProvider {
pub(crate) fn login<R>( pub(crate) fn login<R>(
pending: &mut PendingLogin, pending: &mut PendingLogin,
// #[cfg(feature = "plugins")] world: &EcsWorld,
// #[cfg(feature = "plugins")] plugin_manager: &PluginMgr,
admins: &HashMap<Uuid, AdminRecord>, admins: &HashMap<Uuid, AdminRecord>,
whitelist: &HashMap<Uuid, WhitelistRecord>, whitelist: &HashMap<Uuid, WhitelistRecord>,
banlist: &HashMap<Uuid, BanEntry>, banlist: &HashMap<Uuid, BanEntry>,
@ -133,37 +129,6 @@ impl LoginProvider {
return Some(Err(RegisterError::NotOnWhitelist)); 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. // non-admins can only join if the player count has not been exceeded.
let (player_count_exceeded, res) = player_count_exceeded(username, uuid); let (player_count_exceeded, res) = player_count_exceeded(username, uuid);
if admin.is_none() && player_count_exceeded { if admin.is_none() && player_count_exceeded {

View File

@ -138,16 +138,6 @@ impl<'a> System<'a> for Sys {
} }
let old_player_count = player_list.len(); 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. // NOTE: this is just default value.
// //