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 std::sync::atomic::{AtomicPtr, AtomicU32, AtomicU64, Ordering};
|
||||||
|
|
||||||
use serde::{de::DeserializeOwned, Serialize};
|
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 wasmer::{Function, Memory, Value};
|
||||||
|
|
||||||
use common::{
|
use common::{
|
||||||
comp::Health,
|
comp::{Health, Player},
|
||||||
uid::{Uid, UidAllocator},
|
uid::{Uid, UidAllocator},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -13,12 +15,50 @@ use super::errors::{MemoryAllocationError, PluginModuleError};
|
|||||||
|
|
||||||
pub struct EcsWorld<'a, 'b> {
|
pub struct EcsWorld<'a, 'b> {
|
||||||
pub entities: &'b Entities<'a>,
|
pub entities: &'b Entities<'a>,
|
||||||
pub health: &'b ReadStorage<'a, Health>,
|
pub health: EcsComponentAccess<'a, 'b, Health>,
|
||||||
pub uid: &'b ReadStorage<'a, Uid>,
|
pub uid: EcsComponentAccess<'a, 'b, Uid>,
|
||||||
//pub player: ReadStorage<'a, Player>,
|
pub player: EcsComponentAccess<'a, 'b, Player>,
|
||||||
pub uid_allocator: &'b Read<'a, UidAllocator>,
|
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
|
/// This structure wraps the ECS pointer to ensure safety
|
||||||
pub struct EcsAccessManager {
|
pub struct EcsAccessManager {
|
||||||
ecs_pointer: AtomicPtr<EcsWorld<'static, 'static>>,
|
ecs_pointer: AtomicPtr<EcsWorld<'static, 'static>>,
|
||||||
|
@ -232,29 +232,29 @@ fn retrieve_action(
|
|||||||
action: Retrieve,
|
action: Retrieve,
|
||||||
) -> Result<RetrieveResult, RetrieveError> {
|
) -> Result<RetrieveResult, RetrieveError> {
|
||||||
match action {
|
match action {
|
||||||
Retrieve::GetPlayerName(_e) => {
|
Retrieve::GetPlayerName(e) => {
|
||||||
// Safety: No reference is leaked out the function so it is safe.
|
// Safety: No reference is leaked out the function so it is safe.
|
||||||
// let world = unsafe {
|
let world = unsafe {
|
||||||
// ecs.get().ok_or(RetrieveError::EcsAccessError(
|
ecs.get().ok_or(RetrieveError::EcsAccessError(
|
||||||
// EcsAccessError::EcsPointerNotAvailable,
|
EcsAccessError::EcsPointerNotAvailable,
|
||||||
// ))?
|
))?
|
||||||
// };
|
};
|
||||||
// let player = world.uid_allocator.retrieve_entity_internal(e.0).ok_or(
|
let player = world.uid_allocator.retrieve_entity_internal(e.0).ok_or(
|
||||||
// RetrieveError::EcsAccessError(EcsAccessError::EcsEntityNotFound(e)),
|
RetrieveError::EcsAccessError(EcsAccessError::EcsEntityNotFound(e)),
|
||||||
// )?;
|
)?;
|
||||||
|
|
||||||
Ok(RetrieveResult::GetPlayerName(
|
Ok(RetrieveResult::GetPlayerName(
|
||||||
"<TODO>".to_owned(), /* world
|
world
|
||||||
* .player.get(player).ok_or_else(|| {
|
.player
|
||||||
*
|
.get(player)
|
||||||
* RetrieveError::EcsAccessError(EcsAccessError::
|
.ok_or_else(|| {
|
||||||
* EcsComponentNotFound(
|
RetrieveError::EcsAccessError(EcsAccessError::EcsComponentNotFound(
|
||||||
* e,
|
e,
|
||||||
* "Player".to_owned(),
|
"Player".to_owned(),
|
||||||
* ))
|
))
|
||||||
* })?
|
})?
|
||||||
* .alias
|
.alias
|
||||||
* .to_owned() */
|
.to_owned(),
|
||||||
))
|
))
|
||||||
},
|
},
|
||||||
Retrieve::GetEntityHealth(e) => {
|
Retrieve::GetEntityHealth(e) => {
|
||||||
|
@ -214,10 +214,10 @@ impl State {
|
|||||||
Ok(plugin_mgr) => {
|
Ok(plugin_mgr) => {
|
||||||
let ecs_world = EcsWorld {
|
let ecs_world = EcsWorld {
|
||||||
entities: &ecs.entities(),
|
entities: &ecs.entities(),
|
||||||
health: &ecs.read_component(),
|
health: ecs.read_component().into(),
|
||||||
uid: &ecs.read_component(),
|
uid: ecs.read_component().into(),
|
||||||
uid_allocator: &ecs.read_resource::<UidAllocator>().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
|
if let Err(e) = plugin_mgr
|
||||||
.execute_event(&ecs_world, &plugin_api::event::PluginLoadEvent {
|
.execute_event(&ecs_world, &plugin_api::event::PluginLoadEvent {
|
||||||
|
@ -842,9 +842,10 @@ impl Server {
|
|||||||
let plugin_manager = self.state.ecs().read_resource::<PluginMgr>();
|
let plugin_manager = self.state.ecs().read_resource::<PluginMgr>();
|
||||||
let ecs_world = EcsWorld {
|
let ecs_world = EcsWorld {
|
||||||
entities: &self.state.ecs().entities(),
|
entities: &self.state.ecs().entities(),
|
||||||
health: &self.state.ecs().read_component(),
|
health: self.state.ecs().read_component().into(),
|
||||||
uid: &self.state.ecs().read_component(),
|
uid: self.state.ecs().read_component().into(),
|
||||||
uid_allocator: &self.state.ecs().read_resource::<UidAllocator>().into(),
|
uid_allocator: &self.state.ecs().read_resource::<UidAllocator>().into(),
|
||||||
|
player: self.state.ecs().read_component().into(),
|
||||||
};
|
};
|
||||||
let rs = plugin_manager.execute_event(
|
let rs = plugin_manager.execute_event(
|
||||||
&ecs_world,
|
&ecs_world,
|
||||||
|
@ -1,11 +1,16 @@
|
|||||||
use crate::settings::BanRecord;
|
use crate::settings::BanRecord;
|
||||||
use authc::{AuthClient, AuthClientError, AuthToken, Uuid};
|
use authc::{AuthClient, AuthClientError, AuthToken, Uuid};
|
||||||
|
use common::{comp::Player, uid::UidAllocator};
|
||||||
use common_net::msg::RegisterError;
|
use common_net::msg::RegisterError;
|
||||||
use common_sys::plugin::memory_manager::EcsWorld;
|
use common_sys::plugin::memory_manager::EcsWorld;
|
||||||
#[cfg(feature = "plugins")]
|
#[cfg(feature = "plugins")]
|
||||||
use common_sys::plugin::PluginMgr;
|
use common_sys::plugin::PluginMgr;
|
||||||
use hashbrown::{HashMap, HashSet};
|
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 std::str::FromStr;
|
||||||
use tracing::{error, info};
|
use tracing::{error, info};
|
||||||
|
|
||||||
@ -54,10 +59,14 @@ impl LoginProvider {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn try_login(
|
pub fn try_login<'a, 'b>(
|
||||||
&mut self,
|
&mut self,
|
||||||
username_or_token: &str,
|
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,
|
#[cfg(feature = "plugins")] plugin_manager: &PluginMgr,
|
||||||
admins: &HashSet<Uuid>,
|
admins: &HashSet<Uuid>,
|
||||||
whitelist: &HashSet<Uuid>,
|
whitelist: &HashSet<Uuid>,
|
||||||
@ -81,21 +90,29 @@ impl LoginProvider {
|
|||||||
}
|
}
|
||||||
#[cfg(feature = "plugins")]
|
#[cfg(feature = "plugins")]
|
||||||
{
|
{
|
||||||
match plugin_manager.execute_event(&world, &PlayerJoinEvent {
|
|
||||||
player_name: username.clone(),
|
let ecs_world = EcsWorld {
|
||||||
player_id: *uuid.as_bytes(),
|
entities: &entities,
|
||||||
}) {
|
health: health_comp.into(),
|
||||||
Ok(e) => {
|
uid: uid_comp.into(),
|
||||||
for i in e.into_iter() {
|
player: player_comp.into(),
|
||||||
if let PlayerJoinResult::Kick(a) = i {
|
uid_allocator: uids_res,
|
||||||
return Err(RegisterError::Kicked(a));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Err(e) => {
|
|
||||||
error!("Error occured while executing `on_join`: {:?}",e);
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
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
|
// add the user to self.accounts
|
||||||
|
@ -14,8 +14,6 @@ use hashbrown::HashMap;
|
|||||||
use plugin_api::Health;
|
use plugin_api::Health;
|
||||||
use specs::{Entities, Join, Read, ReadExpect, ReadStorage, WriteExpect, WriteStorage};
|
use specs::{Entities, Join, Read, ReadExpect, ReadStorage, WriteExpect, WriteStorage};
|
||||||
|
|
||||||
use common_sys::plugin::memory_manager::EcsWorld;
|
|
||||||
|
|
||||||
#[cfg(feature = "plugins")]
|
#[cfg(feature = "plugins")]
|
||||||
use common_sys::plugin::PluginMgr;
|
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.
|
// List of new players to update player lists of all clients.
|
||||||
let mut new_players = Vec::new();
|
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() {
|
for (entity, client) in (&entities, &clients).join() {
|
||||||
let _ = super::try_recv_all(client, 0, |client, msg: ClientRegister| {
|
let _ = super::try_recv_all(client, 0, |client, msg: ClientRegister| {
|
||||||
let (username, uuid) = match login_provider.try_login(
|
let (username, uuid) = match login_provider.try_login(
|
||||||
&msg.token_or_username,
|
&msg.token_or_username,
|
||||||
#[cfg(feature = "plugins")]
|
#[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")]
|
#[cfg(feature = "plugins")]
|
||||||
&plugin_mgr,
|
&plugin_mgr,
|
||||||
&*editable_settings.admins,
|
&*editable_settings.admins,
|
||||||
|
Loading…
Reference in New Issue
Block a user