mirror of
https://github.com/mat-1/azalea.git
synced 2025-08-02 14:26:04 +00:00
fix entity deindexing happening at the wrong time
This commit is contained in:
parent
02de98240f
commit
4e5c551d65
4 changed files with 59 additions and 25 deletions
|
@ -703,7 +703,10 @@ impl GamePacketHandler<'_> {
|
||||||
let mut spawned =
|
let mut spawned =
|
||||||
commands.spawn((entity_id, LoadedBy(HashSet::from([self.player])), bundle));
|
commands.spawn((entity_id, LoadedBy(HashSet::from([self.player])), bundle));
|
||||||
let ecs_entity: Entity = spawned.id();
|
let ecs_entity: Entity = spawned.id();
|
||||||
debug!("spawned entity {ecs_entity:?} with id {entity_id:?}");
|
debug!(
|
||||||
|
"spawned entity {ecs_entity:?} with id {entity_id:?} at {pos:?}",
|
||||||
|
pos = p.position
|
||||||
|
);
|
||||||
|
|
||||||
azalea_entity::indexing::add_entity_to_indexes(
|
azalea_entity::indexing::add_entity_to_indexes(
|
||||||
entity_id,
|
entity_id,
|
||||||
|
@ -918,11 +921,9 @@ impl GamePacketHandler<'_> {
|
||||||
|
|
||||||
debug!("Got move entity pos packet {p:?}");
|
debug!("Got move entity pos packet {p:?}");
|
||||||
|
|
||||||
let Some(entity) = entity_id_index.get(p.entity_id) else {
|
let entity_id = p.entity_id;
|
||||||
debug!(
|
let Some(entity) = entity_id_index.get(entity_id) else {
|
||||||
"Got move entity pos packet for unknown entity id {}",
|
debug!("Got move entity pos packet for unknown entity id {entity_id}");
|
||||||
p.entity_id
|
|
||||||
);
|
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -944,6 +945,11 @@ impl GamePacketHandler<'_> {
|
||||||
if new_pos != **position {
|
if new_pos != **position {
|
||||||
**position = new_pos;
|
**position = new_pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trace!(
|
||||||
|
"Applied movement update for {entity_id} / {entity}",
|
||||||
|
entity = entity_mut.id()
|
||||||
|
);
|
||||||
},
|
},
|
||||||
));
|
));
|
||||||
},
|
},
|
||||||
|
@ -1071,7 +1077,7 @@ impl GamePacketHandler<'_> {
|
||||||
for &id in &p.entity_ids {
|
for &id in &p.entity_ids {
|
||||||
let Some(entity) = entity_id_index.remove(id) else {
|
let Some(entity) = entity_id_index.remove(id) else {
|
||||||
debug!(
|
debug!(
|
||||||
"Tried to remove entity with id {id} but it wasn't in the EntityIdIndex"
|
"Tried to remove entity with id {id} but it wasn't in the EntityIdIndex. This may be expected on certain server setups (like if they're using VeryManyPlayers)."
|
||||||
);
|
);
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
@ -1082,7 +1088,7 @@ impl GamePacketHandler<'_> {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
// the [`remove_despawned_entities_from_indexes`] system will despawn the entity
|
// the `remove_despawned_entities_from_indexes` system will despawn the entity
|
||||||
// if it's not loaded by anything anymore
|
// if it's not loaded by anything anymore
|
||||||
|
|
||||||
// also we can't just ecs.despawn because if we're in a swarm then the entity
|
// also we can't just ecs.despawn because if we're in a swarm then the entity
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use azalea_entity::{EntityUpdateSet, metadata::Health};
|
use azalea_entity::metadata::Health;
|
||||||
use bevy_app::{App, First, Plugin, PreUpdate, Update};
|
use bevy_app::{App, First, Plugin, PreUpdate, Update};
|
||||||
use bevy_ecs::{
|
use bevy_ecs::{
|
||||||
prelude::*,
|
prelude::*,
|
||||||
|
@ -46,9 +46,7 @@ impl Plugin for PacketPlugin {
|
||||||
.add_systems(
|
.add_systems(
|
||||||
PreUpdate,
|
PreUpdate,
|
||||||
(
|
(
|
||||||
game::process_packet_events
|
game::process_packet_events,
|
||||||
// we want to index and deindex right after
|
|
||||||
.before(EntityUpdateSet::Deindex),
|
|
||||||
config::process_packet_events,
|
config::process_packet_events,
|
||||||
login::handle_send_packet_event,
|
login::handle_send_packet_event,
|
||||||
login::process_packet_events,
|
login::process_packet_events,
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
//! Stuff related to entity indexes and keeping track of entities in the world.
|
//! Stuff related to entity indexes and keeping track of entities in the world.
|
||||||
|
|
||||||
use std::{collections::HashMap, fmt::Debug};
|
use std::{
|
||||||
|
collections::{HashMap, HashSet},
|
||||||
|
fmt::Debug,
|
||||||
|
};
|
||||||
|
|
||||||
use azalea_core::position::ChunkPos;
|
use azalea_core::position::ChunkPos;
|
||||||
use azalea_world::{Instance, InstanceContainer, InstanceName, MinecraftEntityId};
|
use azalea_world::{Instance, InstanceContainer, InstanceName, MinecraftEntityId};
|
||||||
|
@ -12,7 +15,7 @@ use bevy_ecs::{
|
||||||
};
|
};
|
||||||
use derive_more::{Deref, DerefMut};
|
use derive_more::{Deref, DerefMut};
|
||||||
use nohash_hasher::IntMap;
|
use nohash_hasher::IntMap;
|
||||||
use tracing::{debug, warn};
|
use tracing::{debug, trace, warn};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
use super::LoadedBy;
|
use super::LoadedBy;
|
||||||
|
@ -75,22 +78,39 @@ impl EntityIdIndex {
|
||||||
pub fn insert(&mut self, id: MinecraftEntityId, entity: Entity) {
|
pub fn insert(&mut self, id: MinecraftEntityId, entity: Entity) {
|
||||||
self.entity_by_id.insert(id, entity);
|
self.entity_by_id.insert(id, entity);
|
||||||
self.id_by_entity.insert(entity, id);
|
self.id_by_entity.insert(entity, id);
|
||||||
|
trace!("Inserted {id} -> {entity:?} into a client's EntityIdIndex");
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove(&mut self, id: MinecraftEntityId) -> Option<Entity> {
|
pub fn remove(&mut self, id: MinecraftEntityId) -> Option<Entity> {
|
||||||
if let Some(entity) = self.entity_by_id.remove(&id) {
|
if let Some(entity) = self.entity_by_id.remove(&id) {
|
||||||
|
trace!(
|
||||||
|
"Removed {id} -> {entity:?} from a client's EntityIdIndex (using EntityIdIndex::remove)"
|
||||||
|
);
|
||||||
self.id_by_entity.remove(&entity);
|
self.id_by_entity.remove(&entity);
|
||||||
Some(entity)
|
Some(entity)
|
||||||
} else {
|
} else {
|
||||||
|
trace!(
|
||||||
|
"Failed to remove {id} from a client's EntityIdIndex (using EntityIdIndex::remove)"
|
||||||
|
);
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove_by_ecs_entity(&mut self, entity: Entity) -> Option<MinecraftEntityId> {
|
pub fn remove_by_ecs_entity(&mut self, entity: Entity) -> Option<MinecraftEntityId> {
|
||||||
if let Some(id) = self.id_by_entity.remove(&entity) {
|
if let Some(id) = self.id_by_entity.remove(&entity) {
|
||||||
|
trace!(
|
||||||
|
"Removed {id} -> {entity:?} from a client's EntityIdIndex (using EntityIdIndex::remove_by_ecs_entity)."
|
||||||
|
);
|
||||||
self.entity_by_id.remove(&id);
|
self.entity_by_id.remove(&id);
|
||||||
Some(id)
|
Some(id)
|
||||||
} else {
|
} else {
|
||||||
|
// this is expected to happen when despawning entities if it was already
|
||||||
|
// despawned for another reason (like because the client received a
|
||||||
|
// remove_entities packet, or if we're in a shared instance where entity ids are
|
||||||
|
// different for each client)
|
||||||
|
trace!(
|
||||||
|
"Failed to remove {entity:?} from a client's EntityIdIndex (using EntityIdIndex::remove_by_ecs_entity). This may be expected behavior."
|
||||||
|
);
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -132,6 +152,7 @@ pub fn update_entity_chunk_positions(
|
||||||
.entry(new_chunk)
|
.entry(new_chunk)
|
||||||
.or_default()
|
.or_default()
|
||||||
.insert(entity);
|
.insert(entity);
|
||||||
|
trace!("Entity {entity:?} moved from {old_chunk:?} to {new_chunk:?}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -208,9 +229,22 @@ pub fn remove_despawned_entities_from_indexes(
|
||||||
instance.entities_by_chunk.remove(&chunk);
|
instance.entities_by_chunk.remove(&chunk);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
warn!(
|
// search all the other chunks for it :(
|
||||||
"Tried to remove entity {entity:?} from chunk {chunk:?} but the entity was not there."
|
let mut found_in_other_chunks = HashSet::new();
|
||||||
);
|
for (other_chunk, entities_in_other_chunk) in &mut instance.entities_by_chunk {
|
||||||
|
if entities_in_other_chunk.remove(&entity) {
|
||||||
|
found_in_other_chunks.insert(other_chunk);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if found_in_other_chunks.is_empty() {
|
||||||
|
warn!(
|
||||||
|
"Tried to remove entity {entity:?} from chunk {chunk:?} but the entity was not there or in any other chunks."
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
warn!(
|
||||||
|
"Tried to remove entity {entity:?} from chunk {chunk:?} but the entity was not there. Found in and removed from other chunk(s): {found_in_other_chunks:?}"
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
@ -225,17 +259,13 @@ pub fn remove_despawned_entities_from_indexes(
|
||||||
}
|
}
|
||||||
if instance.entity_by_id.remove(minecraft_id).is_none() {
|
if instance.entity_by_id.remove(minecraft_id).is_none() {
|
||||||
debug!(
|
debug!(
|
||||||
"Tried to remove entity {entity:?} from the id index but it was not there. This may be expected if you're in a shared instance."
|
"Tried to remove entity {entity:?} from the per-instance entity id index but it was not there. This may be expected if you're in a shared instance."
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove it from every client's EntityIdIndex
|
// remove it from every client's EntityIdIndex
|
||||||
for mut entity_id_index in entity_id_index_query.iter_mut() {
|
for mut entity_id_index in entity_id_index_query.iter_mut() {
|
||||||
if entity_id_index.remove_by_ecs_entity(entity).is_none() {
|
entity_id_index.remove_by_ecs_entity(entity);
|
||||||
debug!(
|
|
||||||
"Tried to remove entity {entity:?} from the id index but it was not there. This may be expected if you're in a shared instance."
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// and now remove the entity from the ecs
|
// and now remove the entity from the ecs
|
||||||
|
|
|
@ -9,7 +9,7 @@ use azalea_core::{
|
||||||
tick::GameTick,
|
tick::GameTick,
|
||||||
};
|
};
|
||||||
use azalea_world::{InstanceContainer, InstanceName, MinecraftEntityId};
|
use azalea_world::{InstanceContainer, InstanceName, MinecraftEntityId};
|
||||||
use bevy_app::{App, Plugin, PreUpdate, Update};
|
use bevy_app::{App, Plugin, PostUpdate, Update};
|
||||||
use bevy_ecs::prelude::*;
|
use bevy_ecs::prelude::*;
|
||||||
use derive_more::{Deref, DerefMut};
|
use derive_more::{Deref, DerefMut};
|
||||||
use indexing::EntityUuidIndex;
|
use indexing::EntityUuidIndex;
|
||||||
|
@ -39,7 +39,7 @@ impl Plugin for EntityPlugin {
|
||||||
// modified during update
|
// modified during update
|
||||||
// despawned post-update (done by this plugin)
|
// despawned post-update (done by this plugin)
|
||||||
app.add_systems(
|
app.add_systems(
|
||||||
PreUpdate,
|
PostUpdate,
|
||||||
indexing::remove_despawned_entities_from_indexes.in_set(EntityUpdateSet::Deindex),
|
indexing::remove_despawned_entities_from_indexes.in_set(EntityUpdateSet::Deindex),
|
||||||
)
|
)
|
||||||
.add_systems(
|
.add_systems(
|
||||||
|
|
Loading…
Add table
Reference in a new issue