mirror of
https://github.com/mat-1/azalea.git
synced 2025-08-02 23:44:38 +00:00
Add TicksAlive component
This commit is contained in:
parent
ebc2e0c067
commit
9e1952de7a
7 changed files with 102 additions and 16 deletions
|
@ -705,6 +705,8 @@ async fn run_schedule_loop(ecs: Arc<Mutex<World>>, outer_schedule_label: Interne
|
||||||
"GameTick is more than 10 ticks behind, skipping ticks so we don't have to burst too much"
|
"GameTick is more than 10 ticks behind, skipping ticks so we don't have to burst too much"
|
||||||
);
|
);
|
||||||
*last_tick = now;
|
*last_tick = now;
|
||||||
|
|
||||||
|
// TODO: do we increment TickComponent here?
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
last_tick = Some(now);
|
last_tick = Some(now);
|
||||||
|
|
|
@ -128,6 +128,9 @@ impl Default for Hunger {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Component, Clone, Debug, Default)]
|
||||||
|
pub struct TicksAlive(pub u64);
|
||||||
|
|
||||||
impl InstanceHolder {
|
impl InstanceHolder {
|
||||||
/// Create a new `InstanceHolder` for the given entity.
|
/// Create a new `InstanceHolder` for the given entity.
|
||||||
///
|
///
|
||||||
|
|
|
@ -11,7 +11,7 @@ use tracing::info;
|
||||||
use super::login::IsAuthenticated;
|
use super::login::IsAuthenticated;
|
||||||
use crate::{
|
use crate::{
|
||||||
chat_signing, client::JoinedClientBundle, connection::RawConnection, loading::HasClientLoaded,
|
chat_signing, client::JoinedClientBundle, connection::RawConnection, loading::HasClientLoaded,
|
||||||
local_player::InstanceHolder,
|
local_player::{InstanceHolder, TicksAlive},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct DisconnectPlugin;
|
pub struct DisconnectPlugin;
|
||||||
|
@ -72,6 +72,8 @@ pub struct RemoveOnDisconnectBundle {
|
||||||
pub is_authenticated: IsAuthenticated,
|
pub is_authenticated: IsAuthenticated,
|
||||||
// send ServerboundPlayerLoaded next time we join.
|
// send ServerboundPlayerLoaded next time we join.
|
||||||
pub has_client_loaded: HasClientLoaded,
|
pub has_client_loaded: HasClientLoaded,
|
||||||
|
// TickCounter is reset on reconnect
|
||||||
|
pub ticks_alive: TicksAlive,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A system that removes the several components from our clients when they get
|
/// A system that removes the several components from our clients when they get
|
||||||
|
|
|
@ -22,6 +22,7 @@ pub mod pong;
|
||||||
pub mod respawn;
|
pub mod respawn;
|
||||||
pub mod task_pool;
|
pub mod task_pool;
|
||||||
pub mod tick_broadcast;
|
pub mod tick_broadcast;
|
||||||
|
pub mod tick_counter;
|
||||||
pub mod tick_end;
|
pub mod tick_end;
|
||||||
|
|
||||||
/// This plugin group will add all the default plugins necessary for Azalea to
|
/// This plugin group will add all the default plugins necessary for Azalea to
|
||||||
|
@ -54,6 +55,7 @@ impl PluginGroup for DefaultPlugins {
|
||||||
.add(loading::PlayerLoadedPlugin)
|
.add(loading::PlayerLoadedPlugin)
|
||||||
.add(brand::BrandPlugin)
|
.add(brand::BrandPlugin)
|
||||||
.add(tick_broadcast::TickBroadcastPlugin)
|
.add(tick_broadcast::TickBroadcastPlugin)
|
||||||
|
.add(tick_counter::TickCounterPlugin)
|
||||||
.add(pong::PongPlugin)
|
.add(pong::PongPlugin)
|
||||||
.add(connection::ConnectionPlugin)
|
.add(connection::ConnectionPlugin)
|
||||||
.add(login::LoginPlugin)
|
.add(login::LoginPlugin)
|
||||||
|
|
|
@ -22,22 +22,9 @@ pub use events::*;
|
||||||
use tracing::{debug, error, trace, warn};
|
use tracing::{debug, error, trace, warn};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ClientInformation,
|
block_update::QueuedServerBlockUpdates, chat::{ChatPacket, ChatReceivedEvent}, chunks, connection::RawConnection, declare_packet_handlers, disconnect::DisconnectEvent, interact::BlockStatePredictionHandler, inventory::{
|
||||||
block_update::QueuedServerBlockUpdates,
|
|
||||||
chat::{ChatPacket, ChatReceivedEvent},
|
|
||||||
chunks,
|
|
||||||
connection::RawConnection,
|
|
||||||
declare_packet_handlers,
|
|
||||||
disconnect::DisconnectEvent,
|
|
||||||
interact::BlockStatePredictionHandler,
|
|
||||||
inventory::{
|
|
||||||
ClientSideCloseContainerEvent, Inventory, MenuOpenedEvent, SetContainerContentEvent,
|
ClientSideCloseContainerEvent, Inventory, MenuOpenedEvent, SetContainerContentEvent,
|
||||||
},
|
}, loading::HasClientLoaded, local_player::{Hunger, InstanceHolder, LocalGameMode, PlayerAbilities, TabList, TicksAlive}, movement::{KnockbackEvent, KnockbackType}, packet::as_system, player::{GameProfileComponent, PlayerInfo}, ClientInformation
|
||||||
loading::HasClientLoaded,
|
|
||||||
local_player::{Hunger, InstanceHolder, LocalGameMode, PlayerAbilities, TabList},
|
|
||||||
movement::{KnockbackEvent, KnockbackType},
|
|
||||||
packet::as_system,
|
|
||||||
player::{GameProfileComponent, PlayerInfo},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn process_packet(ecs: &mut World, player: Entity, packet: &ClientboundGamePacket) {
|
pub fn process_packet(ecs: &mut World, player: Entity, packet: &ClientboundGamePacket) {
|
||||||
|
@ -299,6 +286,7 @@ impl GamePacketHandler<'_> {
|
||||||
previous: p.common.previous_game_type.into(),
|
previous: p.common.previous_game_type.into(),
|
||||||
},
|
},
|
||||||
entity_bundle,
|
entity_bundle,
|
||||||
|
TicksAlive(0),
|
||||||
));
|
));
|
||||||
|
|
||||||
azalea_entity::indexing::add_entity_to_indexes(
|
azalea_entity::indexing::add_entity_to_indexes(
|
||||||
|
|
32
azalea-client/src/plugins/tick_counter.rs
Normal file
32
azalea-client/src/plugins/tick_counter.rs
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
use azalea_core::tick::GameTick;
|
||||||
|
use azalea_physics::PhysicsSet;
|
||||||
|
use azalea_world::InstanceName;
|
||||||
|
|
||||||
|
use bevy_app::{App, Plugin};
|
||||||
|
use bevy_ecs::prelude::*;
|
||||||
|
|
||||||
|
use crate::{local_player::TicksAlive, mining::MiningSet, movement::send_position, tick_broadcast::send_tick_broadcast};
|
||||||
|
|
||||||
|
/// Inserts the counter-increment system into the `GameTick` schedule **before**
|
||||||
|
/// physics, mining and movement.
|
||||||
|
pub struct TickCounterPlugin;
|
||||||
|
|
||||||
|
impl Plugin for TickCounterPlugin {
|
||||||
|
fn build(&self, app: &mut App) {
|
||||||
|
app.add_systems(
|
||||||
|
GameTick,
|
||||||
|
increment_counter
|
||||||
|
.before(PhysicsSet)
|
||||||
|
.before(MiningSet)
|
||||||
|
.before(send_position)
|
||||||
|
.before(send_tick_broadcast),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Increment the [`GameTickCounter`] on every entity that lives in an instance.
|
||||||
|
fn increment_counter(mut query: Query<&mut TicksAlive, With<InstanceName>>) {
|
||||||
|
for mut counter in &mut query {
|
||||||
|
counter.0 += 1;
|
||||||
|
}
|
||||||
|
}
|
57
azalea-client/tests/ticks_alive.rs
Normal file
57
azalea-client/tests/ticks_alive.rs
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
use azalea_client::{local_player::TicksAlive, test_utils::prelude::*};
|
||||||
|
use azalea_core::resource_location::ResourceLocation;
|
||||||
|
use azalea_protocol::packets::{config::{ClientboundFinishConfiguration, ClientboundRegistryData}, ConnectionProtocol};
|
||||||
|
use azalea_registry::{DataRegistry, DimensionType};
|
||||||
|
use simdnbt::owned::{NbtCompound, NbtTag};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn counter_increments_and_resets_on_disconnect() {
|
||||||
|
init_tracing();
|
||||||
|
|
||||||
|
let mut simulation = Simulation::new(ConnectionProtocol::Configuration);
|
||||||
|
|
||||||
|
simulation.receive_packet(ClientboundRegistryData {
|
||||||
|
registry_id: ResourceLocation::new("minecraft:dimension_type"),
|
||||||
|
entries: vec![(
|
||||||
|
ResourceLocation::new("minecraft:overworld"),
|
||||||
|
Some(NbtCompound::from_values(vec![
|
||||||
|
("height".into(), NbtTag::Int(384)),
|
||||||
|
("min_y".into(), NbtTag::Int(-64)),
|
||||||
|
])),
|
||||||
|
)]
|
||||||
|
.into_iter()
|
||||||
|
.collect(),
|
||||||
|
});
|
||||||
|
|
||||||
|
simulation.receive_packet(ClientboundFinishConfiguration);
|
||||||
|
|
||||||
|
simulation.tick();
|
||||||
|
// we need a second tick to handle the state switch properly
|
||||||
|
simulation.tick();
|
||||||
|
|
||||||
|
assert!(!simulation.has_component::<TicksAlive>());
|
||||||
|
|
||||||
|
simulation.receive_packet(make_basic_login_packet(
|
||||||
|
DimensionType::new_raw(0), // overworld
|
||||||
|
ResourceLocation::new("minecraft:overworld"),
|
||||||
|
));
|
||||||
|
simulation.tick();
|
||||||
|
|
||||||
|
assert!(simulation.has_component::<TicksAlive>());
|
||||||
|
assert_eq!(simulation.component::<TicksAlive>().0, 1);
|
||||||
|
|
||||||
|
// Tick three times; counter should read 2, 3, 4.
|
||||||
|
for expected in 2..=4 {
|
||||||
|
simulation.tick();
|
||||||
|
let counter = simulation.component::<TicksAlive>();
|
||||||
|
assert_eq!(
|
||||||
|
counter.0, expected,
|
||||||
|
"after {expected} tick(s) counter should be {expected}"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
simulation.disconnect();
|
||||||
|
simulation.tick();
|
||||||
|
|
||||||
|
assert!(!simulation.has_component::<TicksAlive>());
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue