From 039655997d6feb7b763ea315dca22653d65d0889 Mon Sep 17 00:00:00 2001 From: Imbris Date: Sun, 23 Aug 2020 16:17:16 -0400 Subject: [PATCH 1/2] Fix broken features and avoid panic if the client leaves before character data loads --- network/src/participant.rs | 1 + server/src/lib.rs | 5 +++- server/src/state_ext.rs | 54 ++++++++++++++++++-------------------- 3 files changed, 30 insertions(+), 30 deletions(-) diff --git a/network/src/participant.rs b/network/src/participant.rs index 9cedd3ea45..84da3454dd 100644 --- a/network/src/participant.rs +++ b/network/src/participant.rs @@ -614,6 +614,7 @@ impl BParticipant { trace!("Start participant_shutdown_mgr"); let sender = s2b_shutdown_bparticipant_r.await.unwrap(); + #[cfg(feature = "metrics")] let mut send_cache = MultiCidFrameCache::new(self.metrics.frames_out_total.clone()); self.close_api(None).await; diff --git a/server/src/lib.rs b/server/src/lib.rs index ce83a971f7..4de5f4c577 100644 --- a/server/src/lib.rs +++ b/server/src/lib.rs @@ -1,6 +1,7 @@ #![deny(unsafe_code)] #![allow(clippy::option_map_unit_fn)] #![feature(bool_to_option, drain_filter, option_zip)] +#![cfg_attr(not(feature = "worldgen"), feature(const_panic))] pub mod alias_validator; pub mod chunk_generator; @@ -191,10 +192,12 @@ impl Server { let (world, index) = World::generate(settings.world_seed); #[cfg(not(feature = "worldgen"))] let map = WorldMapMsg { - dimensions: Vec2::new(1, 1), + dimensions_lg: Vec2::zero(), max_height: 1.0, rgba: vec![0], horizons: [(vec![0], vec![0]), (vec![0], vec![0])], + sea_level: 0.0, + alt: vec![30], }; #[cfg(feature = "worldgen")] diff --git a/server/src/state_ext.rs b/server/src/state_ext.rs index 3b0a4afcbe..8e7f1b1fad 100644 --- a/server/src/state_ext.rs +++ b/server/src/state_ext.rs @@ -171,6 +171,9 @@ impl StateExt for State { comp::Alignment::Owned(self.read_component_cloned(entity).unwrap()), ); + // Make sure physics components are updated + self.write_component(entity, comp::ForceUpdate); + // Set the character id for the player // TODO this results in a warning in the console: "Error modifying synced // component, it doesn't seem to exist" @@ -203,38 +206,31 @@ impl StateExt for State { fn update_character_data(&mut self, entity: EcsEntity, components: PersistedComponents) { let (body, stats, inventory, loadout) = components; - // Make sure physics are accepted. - self.write_component(entity, comp::ForceUpdate); - // Notify clients of a player list update - let client_uid = self - .read_component_cloned::(entity) - .expect("Client doesn't have a Uid!!!"); + if let Some(player_uid) = self.read_component_cloned::(entity) { + // Notify clients of a player list update + self.notify_registered_clients(ServerMsg::PlayerListUpdate( + PlayerListUpdate::SelectedCharacter(player_uid, CharacterInfo { + name: String::from(&stats.name), + level: stats.level.level(), + }), + )); - self.notify_registered_clients(ServerMsg::PlayerListUpdate( - PlayerListUpdate::SelectedCharacter(client_uid, CharacterInfo { - name: String::from(&stats.name), - level: stats.level.level(), - }), - )); + self.write_component(entity, comp::Collider::Box { + radius: body.radius(), + z_min: 0.0, + z_max: body.height(), + }); + self.write_component(entity, body); + self.write_component(entity, stats); + self.write_component(entity, inventory); + self.write_component(entity, loadout); - self.write_component(entity, comp::Collider::Box { - radius: body.radius(), - z_min: 0.0, - z_max: body.height(), - }); - self.write_component(entity, body); - self.write_component(entity, stats); - self.write_component(entity, inventory); - self.write_component(entity, loadout); - - self.write_component( - entity, - comp::InventoryUpdate::new(comp::InventoryUpdateEvent::default()), - ); - - // Make sure physics are accepted. - self.write_component(entity, comp::ForceUpdate); + self.write_component( + entity, + comp::InventoryUpdate::new(comp::InventoryUpdateEvent::default()), + ); + } } /// Send the chat message to the proper players. Say and region are limited From c259f6cbde686d0a2cefc6d52209c4b009a42dc2 Mon Sep 17 00:00:00 2001 From: Imbris Date: Sun, 23 Aug 2020 16:29:40 -0400 Subject: [PATCH 2/2] Add State::read_component_copied --- client/src/lib.rs | 8 ++++---- common/src/state.rs | 7 ++++++- server/src/cmd.rs | 26 ++++++++++++------------ server/src/events/entity_manipulation.rs | 2 +- server/src/events/inventory_manip.rs | 14 ++++++------- server/src/events/player.rs | 2 +- server/src/state_ext.rs | 4 ++-- voxygen/src/hud/social.rs | 2 +- voxygen/src/scene/particle.rs | 2 +- 9 files changed, 36 insertions(+), 31 deletions(-) diff --git a/client/src/lib.rs b/client/src/lib.rs index 53a7b5d22a..fc73ee4abd 100644 --- a/client/src/lib.rs +++ b/client/src/lib.rs @@ -556,7 +556,7 @@ impl Client { } pub fn pick_up(&mut self, entity: EcsEntity) { - if let Some(uid) = self.state.read_component_cloned(entity) { + if let Some(uid) = self.state.read_component_copied(entity) { self.singleton_stream .send(ClientMsg::ControlEvent(ControlEvent::InventoryManip( InventoryManip::Pickup(uid), @@ -680,7 +680,7 @@ impl Client { } pub fn mount(&mut self, entity: EcsEntity) { - if let Some(uid) = self.state.read_component_cloned(entity) { + if let Some(uid) = self.state.read_component_copied(entity) { self.singleton_stream .send(ClientMsg::ControlEvent(ControlEvent::Mount(uid))) .unwrap(); @@ -1456,7 +1456,7 @@ impl Client { pub fn entity(&self) -> EcsEntity { self.entity } /// Get the player's Uid. - pub fn uid(&self) -> Option { self.state.read_component_cloned(self.entity) } + pub fn uid(&self) -> Option { self.state.read_component_copied(self.entity) } /// Get the client state pub fn get_client_state(&self) -> ClientState { self.client_state } @@ -1509,7 +1509,7 @@ impl Client { pub fn is_admin(&self) -> bool { let client_uid = self .state - .read_component_cloned::(self.entity) + .read_component_copied::(self.entity) .expect("Client doesn't have a Uid!!!"); self.player_list diff --git a/common/src/state.rs b/common/src/state.rs index d53e91f964..74919be12e 100644 --- a/common/src/state.rs +++ b/common/src/state.rs @@ -199,10 +199,15 @@ impl State { } /// Read a component attributed to a particular entity. - pub fn read_component_cloned(&self, entity: EcsEntity) -> Option { + pub fn read_component_cloned(&self, entity: EcsEntity) -> Option { self.ecs.read_storage().get(entity).cloned() } + /// Read a component attributed to a particular entity. + pub fn read_component_copied(&self, entity: EcsEntity) -> Option { + self.ecs.read_storage().get(entity).copied() + } + /// Get a read-only reference to the storage of a particular component type. pub fn read_storage(&self) -> EcsStorage>> { self.ecs.read_storage::() diff --git a/server/src/cmd.rs b/server/src/cmd.rs index 968da28e7d..e3a836c471 100644 --- a/server/src/cmd.rs +++ b/server/src/cmd.rs @@ -190,7 +190,7 @@ fn handle_make_block( ) { if let Some(block_name) = scan_fmt_some!(&args, &action.arg_fmt(), String) { if let Ok(bk) = BlockKind::try_from(block_name.as_str()) { - match server.state.read_component_cloned::(target) { + match server.state.read_component_copied::(target) { Some(pos) => server.state.set_block( pos.0.map(|e| e.floor() as i32), Block::new(bk, Rgb::broadcast(255)), @@ -262,7 +262,7 @@ fn handle_jump( action: &ChatCommand, ) { if let Ok((x, y, z)) = scan_fmt!(&args, &action.arg_fmt(), f32, f32, f32) { - match server.state.read_component_cloned::(target) { + match server.state.read_component_copied::(target) { Some(current_pos) => { server .state @@ -287,7 +287,7 @@ fn handle_goto( if let Ok((x, y, z)) = scan_fmt!(&args, &action.arg_fmt(), f32, f32, f32) { if server .state - .read_component_cloned::(target) + .read_component_copied::(target) .is_some() { server @@ -498,9 +498,9 @@ fn handle_tp( ); return; }; - if let Some(_pos) = server.state.read_component_cloned::(target) { + if let Some(_pos) = server.state.read_component_copied::(target) { if let Some(player) = opt_player { - if let Some(pos) = server.state.read_component_cloned::(player) { + if let Some(pos) = server.state.read_component_copied::(player) { server.state.write_component(target, pos); server.state.write_component(target, comp::ForceUpdate); } else { @@ -545,7 +545,7 @@ fn handle_spawn( (Some(opt_align), Some(npc::NpcBody(id, mut body)), opt_amount, opt_ai) => { let uid = server .state - .read_component_cloned(target) + .read_component_copied(target) .expect("Expected player to have a UID"); if let Some(alignment) = parse_alignment(uid, &opt_align) { let amount = opt_amount @@ -556,7 +556,7 @@ fn handle_spawn( let ai = opt_ai.unwrap_or_else(|| "true".to_string()); - match server.state.read_component_cloned::(target) { + match server.state.read_component_copied::(target) { Some(pos) => { let agent = if let comp::Alignment::Owned(_) | comp::Alignment::Npc = alignment { @@ -667,7 +667,7 @@ fn handle_spawn_training_dummy( _args: String, _action: &ChatCommand, ) { - match server.state.read_component_cloned::(target) { + match server.state.read_component_copied::(target) { Some(pos) => { let vel = Vec3::new( rand::thread_rng().gen_range(-2.0, 3.0), @@ -708,7 +708,7 @@ fn handle_spawn_campfire( _args: String, _action: &ChatCommand, ) { - match server.state.read_component_cloned::(target) { + match server.state.read_component_copied::(target) { Some(pos) => { server .state @@ -1067,7 +1067,7 @@ fn handle_explosion( let ecs = server.state.ecs(); - match server.state.read_component_cloned::(target) { + match server.state.read_component_copied::(target) { Some(pos) => { ecs.read_resource::>() .emit_now(ServerEvent::Explosion { @@ -1092,7 +1092,7 @@ fn handle_waypoint( _args: String, _action: &ChatCommand, ) { - match server.state.read_component_cloned::(target) { + match server.state.read_component_copied::(target) { Some(pos) => { let time = server.state.ecs().read_resource(); let _ = server @@ -1128,7 +1128,7 @@ fn handle_adminify( Some(player) => { let is_admin = if server .state - .read_component_cloned::(player) + .read_component_copied::(player) .is_some() { ecs.write_storage::().remove(player); @@ -1672,7 +1672,7 @@ fn handle_remove_lights( action: &ChatCommand, ) { let opt_radius = scan_fmt_some!(&args, &action.arg_fmt(), f32); - let opt_player_pos = server.state.read_component_cloned::(target); + let opt_player_pos = server.state.read_component_copied::(target); let mut to_delete = vec![]; match opt_player_pos { diff --git a/server/src/events/entity_manipulation.rs b/server/src/events/entity_manipulation.rs index 63598b7077..ccd0ca47eb 100644 --- a/server/src/events/entity_manipulation.rs +++ b/server/src/events/entity_manipulation.rs @@ -386,7 +386,7 @@ pub fn handle_respawn(server: &Server, entity: EcsEntity) { .is_some() { let respawn_point = state - .read_component_cloned::(entity) + .read_component_copied::(entity) .map(|wp| wp.get_pos()) .unwrap_or(state.ecs().read_resource::().0); diff --git a/server/src/events/inventory_manip.rs b/server/src/events/inventory_manip.rs index a646b561f9..4d2a1a6650 100644 --- a/server/src/events/inventory_manip.rs +++ b/server/src/events/inventory_manip.rs @@ -169,10 +169,10 @@ pub fn handle_inventory(server: &mut Server, entity: EcsEntity, manip: comp::Inv thrown_items.push(( *pos, state - .read_component_cloned::(entity) + .read_component_copied::(entity) .unwrap_or_default(), state - .read_component_cloned::(entity) + .read_component_copied::(entity) .unwrap_or_default(), *kind, )); @@ -187,7 +187,7 @@ pub fn handle_inventory(server: &mut Server, entity: EcsEntity, manip: comp::Inv state.read_storage::().get(entity) { let uid = state - .read_component_cloned(entity) + .read_component_copied(entity) .expect("Expected player to have a UID"); if ( &state.read_storage::(), @@ -344,7 +344,7 @@ pub fn handle_inventory(server: &mut Server, entity: EcsEntity, manip: comp::Inv dropped_items.push(( *pos, state - .read_component_cloned::(entity) + .read_component_copied::(entity) .unwrap_or_default(), item, )); @@ -377,10 +377,10 @@ pub fn handle_inventory(server: &mut Server, entity: EcsEntity, manip: comp::Inv for _ in 0..amount { dropped_items.push(( state - .read_component_cloned::(entity) + .read_component_copied::(entity) .unwrap_or_default(), state - .read_component_cloned::(entity) + .read_component_copied::(entity) .unwrap_or_default(), item.clone(), )); @@ -422,7 +422,7 @@ pub fn handle_inventory(server: &mut Server, entity: EcsEntity, manip: comp::Inv }, }; - let uid = state.read_component_cloned::(entity); + let uid = state.read_component_copied::(entity); let mut new_entity = state .create_object(Default::default(), match kind { diff --git a/server/src/events/player.rs b/server/src/events/player.rs index b7415c2b73..664c5fec56 100644 --- a/server/src/events/player.rs +++ b/server/src/events/player.rs @@ -20,7 +20,7 @@ pub fn handle_exit_ingame(server: &mut Server, entity: EcsEntity) { // Note: If other `ServerEvent`s are referring to this entity they will be // disrupted let maybe_client = state.ecs().write_storage::().remove(entity); - let maybe_uid = state.read_component_cloned::(entity); + let maybe_uid = state.read_component_copied::(entity); let maybe_player = state.ecs().write_storage::().remove(entity); let maybe_group = state .ecs() diff --git a/server/src/state_ext.rs b/server/src/state_ext.rs index 8e7f1b1fad..51646d9ab4 100644 --- a/server/src/state_ext.rs +++ b/server/src/state_ext.rs @@ -168,7 +168,7 @@ impl StateExt for State { self.write_component(entity, comp::CharacterState::default()); self.write_component( entity, - comp::Alignment::Owned(self.read_component_cloned(entity).unwrap()), + comp::Alignment::Owned(self.read_component_copied(entity).unwrap()), ); // Make sure physics components are updated @@ -207,7 +207,7 @@ impl StateExt for State { fn update_character_data(&mut self, entity: EcsEntity, components: PersistedComponents) { let (body, stats, inventory, loadout) = components; - if let Some(player_uid) = self.read_component_cloned::(entity) { + if let Some(player_uid) = self.read_component_copied::(entity) { // Notify clients of a player list update self.notify_registered_clients(ServerMsg::PlayerListUpdate( PlayerListUpdate::SelectedCharacter(player_uid, CharacterInfo { diff --git a/voxygen/src/hud/social.rs b/voxygen/src/hud/social.rs index 2b3773c51e..fd85c7b38c 100644 --- a/voxygen/src/hud/social.rs +++ b/voxygen/src/hud/social.rs @@ -515,7 +515,7 @@ impl<'a> Widget for Social<'a> { }) .or_else(|| { self.selected_entity - .and_then(|s| self.client.state().read_component_cloned(s.0)) + .and_then(|s| self.client.state().read_component_copied(s.0)) }) .filter(|selected| { // Prevent inviting entities already in the same group diff --git a/voxygen/src/scene/particle.rs b/voxygen/src/scene/particle.rs index f14d1cfbe8..362cfdd0c4 100644 --- a/voxygen/src/scene/particle.rs +++ b/voxygen/src/scene/particle.rs @@ -265,7 +265,7 @@ impl ParticleMgr { let time = scene_data.state.get_time(); let player_pos = scene_data .state - .read_component_cloned::(scene_data.player_entity) + .read_component_copied::(scene_data.player_entity) .unwrap_or_default(); let player_chunk = player_pos.0.xy().map2(TerrainChunk::RECT_SIZE, |e, sz| { (e.floor() as i32).div_euclid(sz as i32)