mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Change Ecs access system to allow write accesses to be used + reintroduced get_player_name
This commit is contained in:
parent
cf46ce70cf
commit
67b24294d6
BIN
assets/plugins/veloren_plugin_template.plugin.tar
(Stored with Git LFS)
Normal file
BIN
assets/plugins/veloren_plugin_template.plugin.tar
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -1,11 +1,13 @@
|
||||
use std::sync::atomic::{AtomicPtr, AtomicU32, AtomicU64, Ordering};
|
||||
|
||||
use serde::{de::DeserializeOwned, Serialize};
|
||||
use specs::{Entities, Read, ReadStorage};
|
||||
use specs::{
|
||||
storage::GenericReadStorage, Component, Entities, Entity, Read, ReadStorage, WriteStorage,
|
||||
};
|
||||
use wasmer::{Function, Memory, Value};
|
||||
|
||||
use common::{
|
||||
comp::Health,
|
||||
comp::{Health, Player},
|
||||
uid::{Uid, UidAllocator},
|
||||
};
|
||||
|
||||
@ -13,12 +15,50 @@ use super::errors::{MemoryAllocationError, PluginModuleError};
|
||||
|
||||
pub struct EcsWorld<'a, 'b> {
|
||||
pub entities: &'b Entities<'a>,
|
||||
pub health: &'b ReadStorage<'a, Health>,
|
||||
pub uid: &'b ReadStorage<'a, Uid>,
|
||||
//pub player: ReadStorage<'a, Player>,
|
||||
pub health: EcsComponentAccess<'a, 'b, Health>,
|
||||
pub uid: EcsComponentAccess<'a, 'b, Uid>,
|
||||
pub player: EcsComponentAccess<'a, 'b, Player>,
|
||||
pub uid_allocator: &'b Read<'a, UidAllocator>,
|
||||
}
|
||||
|
||||
pub enum EcsComponentAccess<'a, 'b, T: Component> {
|
||||
Read(&'b ReadStorage<'a, T>),
|
||||
ReadOwned(ReadStorage<'a, T>),
|
||||
Write(&'b WriteStorage<'a, T>),
|
||||
WriteOwned(WriteStorage<'a, T>),
|
||||
}
|
||||
|
||||
impl<'a, 'b, T: Component> EcsComponentAccess<'a, 'b, T> {
|
||||
pub fn get(&self, entity: Entity) -> Option<&T> {
|
||||
match self {
|
||||
EcsComponentAccess::Read(e) => e.get(entity),
|
||||
EcsComponentAccess::Write(e) => e.get(entity),
|
||||
EcsComponentAccess::ReadOwned(e) => e.get(entity),
|
||||
EcsComponentAccess::WriteOwned(e) => e.get(entity),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b, T: Component> From<&'b ReadStorage<'a, T>> for EcsComponentAccess<'a, 'b, T> {
|
||||
fn from(a: &'b ReadStorage<'a, T>) -> Self { Self::Read(a) }
|
||||
}
|
||||
|
||||
impl<'a, 'b, T: Component> From<ReadStorage<'a, T>> for EcsComponentAccess<'a, 'b, T> {
|
||||
fn from(a: ReadStorage<'a, T>) -> Self { Self::ReadOwned(a) }
|
||||
}
|
||||
|
||||
impl<'a, 'b, T: Component> From<&'b WriteStorage<'a, T>> for EcsComponentAccess<'a, 'b, T> {
|
||||
fn from(a: &'b WriteStorage<'a, T>) -> Self { Self::Write(a) }
|
||||
}
|
||||
|
||||
impl<'a, 'b, T: Component> From<WriteStorage<'a, T>> for EcsComponentAccess<'a, 'b, T> {
|
||||
fn from(a: WriteStorage<'a, T>) -> Self { Self::WriteOwned(a) }
|
||||
}
|
||||
|
||||
// pub enum EcsResourceAccess<'a, T> {
|
||||
// Read(Read<'a, T>),
|
||||
// }
|
||||
|
||||
/// This structure wraps the ECS pointer to ensure safety
|
||||
pub struct EcsAccessManager {
|
||||
ecs_pointer: AtomicPtr<EcsWorld<'static, 'static>>,
|
||||
|
@ -232,29 +232,29 @@ fn retrieve_action(
|
||||
action: Retrieve,
|
||||
) -> Result<RetrieveResult, RetrieveError> {
|
||||
match action {
|
||||
Retrieve::GetPlayerName(_e) => {
|
||||
Retrieve::GetPlayerName(e) => {
|
||||
// Safety: No reference is leaked out the function so it is safe.
|
||||
// let world = unsafe {
|
||||
// ecs.get().ok_or(RetrieveError::EcsAccessError(
|
||||
// EcsAccessError::EcsPointerNotAvailable,
|
||||
// ))?
|
||||
// };
|
||||
// let player = world.uid_allocator.retrieve_entity_internal(e.0).ok_or(
|
||||
// RetrieveError::EcsAccessError(EcsAccessError::EcsEntityNotFound(e)),
|
||||
// )?;
|
||||
let world = unsafe {
|
||||
ecs.get().ok_or(RetrieveError::EcsAccessError(
|
||||
EcsAccessError::EcsPointerNotAvailable,
|
||||
))?
|
||||
};
|
||||
let player = world.uid_allocator.retrieve_entity_internal(e.0).ok_or(
|
||||
RetrieveError::EcsAccessError(EcsAccessError::EcsEntityNotFound(e)),
|
||||
)?;
|
||||
|
||||
Ok(RetrieveResult::GetPlayerName(
|
||||
"<TODO>".to_owned(), /* world
|
||||
* .player.get(player).ok_or_else(|| {
|
||||
*
|
||||
* RetrieveError::EcsAccessError(EcsAccessError::
|
||||
* EcsComponentNotFound(
|
||||
* e,
|
||||
* "Player".to_owned(),
|
||||
* ))
|
||||
* })?
|
||||
* .alias
|
||||
* .to_owned() */
|
||||
world
|
||||
.player
|
||||
.get(player)
|
||||
.ok_or_else(|| {
|
||||
RetrieveError::EcsAccessError(EcsAccessError::EcsComponentNotFound(
|
||||
e,
|
||||
"Player".to_owned(),
|
||||
))
|
||||
})?
|
||||
.alias
|
||||
.to_owned(),
|
||||
))
|
||||
},
|
||||
Retrieve::GetEntityHealth(e) => {
|
||||
|
@ -214,10 +214,10 @@ impl State {
|
||||
Ok(plugin_mgr) => {
|
||||
let ecs_world = EcsWorld {
|
||||
entities: &ecs.entities(),
|
||||
health: &ecs.read_component(),
|
||||
uid: &ecs.read_component(),
|
||||
health: ecs.read_component().into(),
|
||||
uid: ecs.read_component().into(),
|
||||
uid_allocator: &ecs.read_resource::<UidAllocator>().into(),
|
||||
//player: Either::First(ecs.read_component()),
|
||||
player: ecs.read_component().into(),
|
||||
};
|
||||
if let Err(e) = plugin_mgr
|
||||
.execute_event(&ecs_world, &plugin_api::event::PluginLoadEvent {
|
||||
|
@ -842,9 +842,10 @@ impl Server {
|
||||
let plugin_manager = self.state.ecs().read_resource::<PluginMgr>();
|
||||
let ecs_world = EcsWorld {
|
||||
entities: &self.state.ecs().entities(),
|
||||
health: &self.state.ecs().read_component(),
|
||||
uid: &self.state.ecs().read_component(),
|
||||
health: self.state.ecs().read_component().into(),
|
||||
uid: self.state.ecs().read_component().into(),
|
||||
uid_allocator: &self.state.ecs().read_resource::<UidAllocator>().into(),
|
||||
player: self.state.ecs().read_component().into(),
|
||||
};
|
||||
let rs = plugin_manager.execute_event(
|
||||
&ecs_world,
|
||||
|
@ -1,11 +1,16 @@
|
||||
use crate::settings::BanRecord;
|
||||
use authc::{AuthClient, AuthClientError, AuthToken, Uuid};
|
||||
use common::{comp::Player, uid::UidAllocator};
|
||||
use common_net::msg::RegisterError;
|
||||
use common_sys::plugin::memory_manager::EcsWorld;
|
||||
#[cfg(feature = "plugins")]
|
||||
use common_sys::plugin::PluginMgr;
|
||||
use hashbrown::{HashMap, HashSet};
|
||||
use plugin_api::event::{PlayerJoinEvent, PlayerJoinResult};
|
||||
use plugin_api::{
|
||||
event::{PlayerJoinEvent, PlayerJoinResult},
|
||||
Health,
|
||||
};
|
||||
use specs::{Entities, Read, ReadStorage, WriteStorage};
|
||||
use std::str::FromStr;
|
||||
use tracing::{error, info};
|
||||
|
||||
@ -54,10 +59,14 @@ impl LoginProvider {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn try_login(
|
||||
pub fn try_login<'a, 'b>(
|
||||
&mut self,
|
||||
username_or_token: &str,
|
||||
#[cfg(feature = "plugins")] world: &EcsWorld,
|
||||
#[cfg(feature = "plugins")] entities: &Entities<'a>,
|
||||
#[cfg(feature = "plugins")] health_comp: &ReadStorage<'a, Health>,
|
||||
#[cfg(feature = "plugins")] uid_comp: &ReadStorage<'a, common::uid::Uid>,
|
||||
#[cfg(feature = "plugins")] player_comp: &WriteStorage<'a, Player>,
|
||||
#[cfg(feature = "plugins")] uids_res: &Read<'a, UidAllocator>,
|
||||
#[cfg(feature = "plugins")] plugin_manager: &PluginMgr,
|
||||
admins: &HashSet<Uuid>,
|
||||
whitelist: &HashSet<Uuid>,
|
||||
@ -81,21 +90,29 @@ impl LoginProvider {
|
||||
}
|
||||
#[cfg(feature = "plugins")]
|
||||
{
|
||||
match plugin_manager.execute_event(&world, &PlayerJoinEvent {
|
||||
player_name: username.clone(),
|
||||
player_id: *uuid.as_bytes(),
|
||||
}) {
|
||||
Ok(e) => {
|
||||
for i in e.into_iter() {
|
||||
if let PlayerJoinResult::Kick(a) = i {
|
||||
return Err(RegisterError::Kicked(a));
|
||||
}
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
error!("Error occured while executing `on_join`: {:?}",e);
|
||||
},
|
||||
|
||||
let ecs_world = EcsWorld {
|
||||
entities: &entities,
|
||||
health: health_comp.into(),
|
||||
uid: uid_comp.into(),
|
||||
player: player_comp.into(),
|
||||
uid_allocator: uids_res,
|
||||
};
|
||||
match plugin_manager.execute_event(&ecs_world, &PlayerJoinEvent {
|
||||
player_name: username.clone(),
|
||||
player_id: *uuid.as_bytes(),
|
||||
}) {
|
||||
Ok(e) => {
|
||||
for i in e.into_iter() {
|
||||
if let PlayerJoinResult::Kick(a) = i {
|
||||
return Err(RegisterError::Kicked(a));
|
||||
}
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
error!("Error occured while executing `on_join`: {:?}",e);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
// add the user to self.accounts
|
||||
|
@ -14,8 +14,6 @@ use hashbrown::HashMap;
|
||||
use plugin_api::Health;
|
||||
use specs::{Entities, Join, Read, ReadExpect, ReadStorage, WriteExpect, WriteStorage};
|
||||
|
||||
use common_sys::plugin::memory_manager::EcsWorld;
|
||||
|
||||
#[cfg(feature = "plugins")]
|
||||
use common_sys::plugin::PluginMgr;
|
||||
|
||||
@ -77,20 +75,20 @@ impl<'a> System<'a> for Sys {
|
||||
// List of new players to update player lists of all clients.
|
||||
let mut new_players = Vec::new();
|
||||
|
||||
#[cfg(feature = "plugins")]
|
||||
let ecs_world = EcsWorld {
|
||||
entities: &entities,
|
||||
health: &health_comp,
|
||||
uid: &uids,
|
||||
uid_allocator: &uid_allocator,
|
||||
};
|
||||
|
||||
for (entity, client) in (&entities, &clients).join() {
|
||||
let _ = super::try_recv_all(client, 0, |client, msg: ClientRegister| {
|
||||
let (username, uuid) = match login_provider.try_login(
|
||||
&msg.token_or_username,
|
||||
#[cfg(feature = "plugins")]
|
||||
&ecs_world,
|
||||
&entities,
|
||||
#[cfg(feature = "plugins")]
|
||||
&health_comp,
|
||||
#[cfg(feature = "plugins")]
|
||||
&uids,
|
||||
#[cfg(feature = "plugins")]
|
||||
&players,
|
||||
#[cfg(feature = "plugins")]
|
||||
&uid_allocator,
|
||||
#[cfg(feature = "plugins")]
|
||||
&plugin_mgr,
|
||||
&*editable_settings.admins,
|
||||
|
Loading…
Reference in New Issue
Block a user