don't apply metadata updates multiple times in swarms

This commit is contained in:
mat 2023-09-16 22:30:28 -05:00
parent a920359c9a
commit 61e63c0896
3 changed files with 49 additions and 12 deletions

View file

@ -87,6 +87,8 @@ pub struct Client {
/// This is immutable; the server cannot change it. To get the username and
/// skin the server chose for you, get your player from the [`TabList`]
/// component.
///
/// This as also available from the ECS as [`GameProfileComponent`].
pub profile: GameProfile,
/// The entity for this client in the ECS.
pub entity: Entity,
@ -580,6 +582,28 @@ impl Client {
pub fn hunger(&self) -> Hunger {
self.component::<Hunger>().to_owned()
}
/// Get the username of this client.
///
/// This is a shortcut for
/// `bot.component::<GameProfileComponent>().name.clone()`.
pub fn username(&self) -> String {
self.component::<GameProfileComponent>().name.clone()
}
/// Get the Minecraft UUID of this client.
///
/// This is a shortcut for `bot.component::<GameProfileComponent>().uuid`.
pub fn uuid(&self) -> Uuid {
self.component::<GameProfileComponent>().uuid
}
/// Get a map of player UUIDs to their information in the tab list.
///
/// This is a shortcut for `bot.component::<TabList>().0`.
pub fn tab_list(&self) -> HashMap<Uuid, PlayerInfo> {
self.component::<TabList>().0
}
}
/// A bundle for the components that are present on a local player that received

View file

@ -634,11 +634,11 @@ pub fn process_packet_events(ecs: &mut World) {
let mut system_state: SystemState<(
Commands,
Query<&EntityIdIndex>,
Query<(&EntityIdIndex, &LocalPlayer)>,
Query<&EntityKind>,
)> = SystemState::new(ecs);
let (mut commands, mut query, entity_kind_query) = system_state.get_mut(ecs);
let entity_id_index = query.get_mut(player_entity).unwrap();
let (entity_id_index, local_player) = query.get_mut(player_entity).unwrap();
let entity = entity_id_index.get(&MinecraftEntityId(p.id));
@ -646,15 +646,28 @@ pub fn process_packet_events(ecs: &mut World) {
warn!("Server sent an entity data packet for an entity id ({}) that we don't know about", p.id);
continue;
};
let entity_kind = entity_kind_query.get(entity).unwrap();
let mut entity_commands = commands.entity(entity);
if let Err(e) = apply_metadata(
&mut entity_commands,
**entity_kind,
(*p.packed_items).clone(),
) {
warn!("{e}");
}
let entity_kind = *entity_kind_query.get(entity).unwrap();
// we use RelativeEntityUpdate because it makes sure changes aren't made
// multiple times
commands.entity(entity).add(RelativeEntityUpdate {
partial_world: local_player.partial_instance.clone(),
update: Box::new(move |entity| {
let entity_id = entity.id();
entity.world_scope(|world| {
let mut commands_system_state = SystemState::<Commands>::new(world);
let mut commands = commands_system_state.get_mut(world);
let mut entity_comands = commands.entity(entity_id);
if let Err(e) = apply_metadata(
&mut entity_comands,
*entity_kind,
(*p.packed_items).clone(),
) {
warn!("{e}");
}
});
}),
});
system_state.apply(ecs);
}

View file

@ -35,7 +35,7 @@ fn tick_global_task_pools(_main_thread_marker: Option<NonSend<NonSendMarker>>) {
}
/// Helper for configuring and creating the default task pools. For end-users
/// who want full control, set up [`TaskPoolPlugin`](TaskPoolPlugin)
/// who want full control, set up [`TaskPoolPlugin`]
#[derive(Clone, Resource)]
pub struct TaskPoolOptions {
/// If the number of physical cores is less than min_total_threads, force