mirror of
https://github.com/mat-1/azalea.git
synced 2025-08-02 06:16:04 +00:00
fix errors when switching to Game state and add fast_login test
This commit is contained in:
parent
72d87349fe
commit
c9022e8f67
6 changed files with 101 additions and 20 deletions
|
@ -23,8 +23,8 @@ pub mod test_simulation;
|
|||
pub use account::{Account, AccountOpts};
|
||||
pub use azalea_protocol::common::client_information::ClientInformation;
|
||||
pub use client::{
|
||||
Client, DefaultPlugins, InConfigState, JoinError, JoinedClientBundle, LocalPlayerBundle,
|
||||
StartClientOpts, TickBroadcast, start_ecs_runner,
|
||||
Client, DefaultPlugins, InConfigState, InGameState, JoinError, JoinedClientBundle,
|
||||
LocalPlayerBundle, StartClientOpts, TickBroadcast, start_ecs_runner,
|
||||
};
|
||||
pub use events::Event;
|
||||
pub use local_player::{GameProfileComponent, Hunger, InstanceHolder, TabList};
|
||||
|
|
|
@ -55,7 +55,7 @@ pub fn handle_send_packet_event(
|
|||
}
|
||||
}
|
||||
|
||||
pub fn send_packet_events(
|
||||
pub fn emit_receive_config_packet_events(
|
||||
query: Query<(Entity, &RawConnection), With<InConfigState>>,
|
||||
mut packet_events: ResMut<Events<ReceiveConfigPacketEvent>>,
|
||||
) {
|
||||
|
@ -67,7 +67,9 @@ pub fn send_packet_events(
|
|||
let packets_lock = raw_conn.incoming_packet_queue();
|
||||
let mut packets = packets_lock.lock();
|
||||
if !packets.is_empty() {
|
||||
let mut packets_read = 0;
|
||||
for raw_packet in packets.iter() {
|
||||
packets_read += 1;
|
||||
let packet = match deserialize_packet::<ClientboundConfigPacket>(&mut Cursor::new(
|
||||
raw_packet,
|
||||
)) {
|
||||
|
@ -78,13 +80,32 @@ pub fn send_packet_events(
|
|||
continue;
|
||||
}
|
||||
};
|
||||
|
||||
let should_interrupt = packet_interrupts(&packet);
|
||||
|
||||
packet_events.send(ReceiveConfigPacketEvent {
|
||||
entity: player_entity,
|
||||
packet,
|
||||
});
|
||||
|
||||
if should_interrupt {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// clear the packets right after we read them
|
||||
packets.clear();
|
||||
packets.drain(0..packets_read);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Whether the given packet should make us stop deserializing the received
|
||||
/// packets until next update.
|
||||
///
|
||||
/// This is used for packets that can switch the client state.
|
||||
fn packet_interrupts(packet: &ClientboundConfigPacket) -> bool {
|
||||
matches!(
|
||||
packet,
|
||||
ClientboundConfigPacket::FinishConfiguration(_)
|
||||
| ClientboundConfigPacket::Disconnect(_)
|
||||
| ClientboundConfigPacket::Transfer(_)
|
||||
)
|
||||
}
|
||||
|
|
|
@ -75,7 +75,7 @@ pub fn handle_outgoing_packets(
|
|||
}
|
||||
}
|
||||
|
||||
pub fn send_receivepacketevent(
|
||||
pub fn emit_receive_packet_events(
|
||||
query: Query<(Entity, &RawConnection), With<InGameState>>,
|
||||
mut packet_events: ResMut<Events<ReceivePacketEvent>>,
|
||||
) {
|
||||
|
@ -87,7 +87,9 @@ pub fn send_receivepacketevent(
|
|||
let packets_lock = raw_connection.incoming_packet_queue();
|
||||
let mut packets = packets_lock.lock();
|
||||
if !packets.is_empty() {
|
||||
let mut packets_read = 0;
|
||||
for raw_packet in packets.iter() {
|
||||
packets_read += 1;
|
||||
let packet =
|
||||
match deserialize_packet::<ClientboundGamePacket>(&mut Cursor::new(raw_packet))
|
||||
{
|
||||
|
@ -98,17 +100,36 @@ pub fn send_receivepacketevent(
|
|||
continue;
|
||||
}
|
||||
};
|
||||
|
||||
let should_interrupt = packet_interrupts(&packet);
|
||||
|
||||
packet_events.send(ReceivePacketEvent {
|
||||
entity: player_entity,
|
||||
packet: Arc::new(packet),
|
||||
});
|
||||
|
||||
if should_interrupt {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// clear the packets right after we read them
|
||||
packets.clear();
|
||||
packets.drain(0..packets_read);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Whether the given packet should make us stop deserializing the received
|
||||
/// packets until next update.
|
||||
///
|
||||
/// This is used for packets that can switch the client state.
|
||||
fn packet_interrupts(packet: &ClientboundGamePacket) -> bool {
|
||||
matches!(
|
||||
packet,
|
||||
ClientboundGamePacket::StartConfiguration(_)
|
||||
| ClientboundGamePacket::Disconnect(_)
|
||||
| ClientboundGamePacket::Transfer(_)
|
||||
)
|
||||
}
|
||||
|
||||
/// A player joined the game (or more specifically, was added to the tab
|
||||
/// list of a local player).
|
||||
#[derive(Event, Debug, Clone)]
|
||||
|
|
|
@ -38,7 +38,10 @@ impl Plugin for PacketPlugin {
|
|||
fn build(&self, app: &mut App) {
|
||||
app.add_systems(
|
||||
First,
|
||||
(game::send_receivepacketevent, config::send_packet_events),
|
||||
(
|
||||
game::emit_receive_packet_events,
|
||||
config::emit_receive_config_packet_events,
|
||||
),
|
||||
)
|
||||
.add_systems(
|
||||
PreUpdate,
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
use azalea_client::{InConfigState, test_simulation::*};
|
||||
use azalea_client::{InConfigState, InGameState, test_simulation::*};
|
||||
use azalea_core::{position::ChunkPos, resource_location::ResourceLocation};
|
||||
use azalea_entity::{LocalEntity, metadata::Health};
|
||||
use azalea_entity::LocalEntity;
|
||||
use azalea_protocol::packets::{
|
||||
ConnectionProtocol,
|
||||
config::{ClientboundFinishConfiguration, ClientboundRegistryData},
|
||||
game::ClientboundSetHealth,
|
||||
};
|
||||
use azalea_registry::DimensionType;
|
||||
use azalea_world::InstanceName;
|
||||
|
@ -17,6 +16,7 @@ fn test_change_dimension_to_nether_and_back() {
|
|||
|
||||
let mut simulation = Simulation::new(ConnectionProtocol::Configuration);
|
||||
assert!(simulation.has_component::<InConfigState>());
|
||||
assert!(!simulation.has_component::<InGameState>());
|
||||
|
||||
simulation.receive_packet(ClientboundRegistryData {
|
||||
registry_id: ResourceLocation::new("minecraft:dimension_type"),
|
||||
|
@ -53,16 +53,9 @@ fn test_change_dimension_to_nether_and_back() {
|
|||
simulation.tick();
|
||||
|
||||
assert!(!simulation.has_component::<InConfigState>());
|
||||
assert!(simulation.has_component::<InGameState>());
|
||||
assert!(simulation.has_component::<LocalEntity>());
|
||||
|
||||
simulation.receive_packet(ClientboundSetHealth {
|
||||
health: 15.,
|
||||
food: 20,
|
||||
saturation: 20.,
|
||||
});
|
||||
simulation.tick();
|
||||
assert_eq!(*simulation.component::<Health>(), 15.);
|
||||
|
||||
//
|
||||
// OVERWORLD
|
||||
//
|
||||
|
|
43
azalea-client/tests/fast_login.rs
Normal file
43
azalea-client/tests/fast_login.rs
Normal file
|
@ -0,0 +1,43 @@
|
|||
use azalea_client::{InConfigState, test_simulation::*};
|
||||
use azalea_core::resource_location::ResourceLocation;
|
||||
use azalea_entity::metadata::Health;
|
||||
use azalea_protocol::packets::{
|
||||
ConnectionProtocol,
|
||||
config::{ClientboundFinishConfiguration, ClientboundRegistryData},
|
||||
game::ClientboundSetHealth,
|
||||
};
|
||||
use bevy_log::tracing_subscriber;
|
||||
use simdnbt::owned::{NbtCompound, NbtTag};
|
||||
|
||||
#[test]
|
||||
fn test_fast_login() {
|
||||
let _ = tracing_subscriber::fmt::try_init();
|
||||
|
||||
let mut simulation = Simulation::new(ConnectionProtocol::Configuration);
|
||||
assert!(simulation.has_component::<InConfigState>());
|
||||
|
||||
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);
|
||||
// note that there's no simulation tick here
|
||||
simulation.receive_packet(ClientboundSetHealth {
|
||||
health: 15.,
|
||||
food: 20,
|
||||
saturation: 20.,
|
||||
});
|
||||
simulation.tick();
|
||||
// we need a second tick to handle the state switch properly
|
||||
simulation.tick();
|
||||
assert_eq!(*simulation.component::<Health>(), 15.);
|
||||
}
|
Loading…
Add table
Reference in a new issue