From 1ad3e80d448394f1e5937026ef67e80309744575 Mon Sep 17 00:00:00 2001 From: Henauxg <19689618+Henauxg@users.noreply.github.com> Date: Wed, 12 Jun 2024 10:22:34 +0200 Subject: [PATCH 01/11] build: Update tests and examples to bevy `0.14.0-rc.2` --- Cargo.toml | 12 +++++++++-- examples/breakout/breakout.rs | 20 ++++++++++++++++-- examples/breakout/client.rs | 40 ++++++++++++++++++----------------- examples/breakout/server.rs | 18 ++++++++++++---- examples/chat/client.rs | 2 +- tests/certificates.rs | 30 ++++++++++++++------------ tests/channels.rs | 4 ++-- tests/connection.rs | 33 ++++++++++++++++------------- tests/utils/mod.rs | 32 ++++++++++++++++------------ 9 files changed, 119 insertions(+), 72 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 1887ad3..949684e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,7 +15,7 @@ exclude = ["assets/"] members = ["bevy_replicon_quinnet"] [dependencies] -bevy = { version = "0.13.0", default-features = false, features = [] } +bevy = { version = "0.14.0-rc.2", default-features = false, features = [] } rustls = { version = "0.21.0", default-features = false, features = [ "quic", "dangerous_configuration", @@ -41,7 +41,7 @@ default = ["shared-client-id"] shared-client-id = [] [dev-dependencies] -bevy = { version = "0.13.0", default-features = false, features = [ +bevy = { version = "0.14.0-rc.2", default-features = false, features = [ "bevy_asset", # Provides asset functionality "bevy_audio", # Provides audio functionality "vorbis", # OGG/VORBIS audio format support @@ -52,6 +52,14 @@ bevy = { version = "0.13.0", default-features = false, features = [ "bevy_text", # Provides text functionality "bevy_core_pipeline", # Provides cameras and other basic render pipeline features "x11", # X11 display server support + + # Can be removed later, temporary fixes for a bug in "0.14.0-rc.2" + "bevy_state", + "serialize", + "bevy_scene", + "bevy_pbr", + "ktx2", + "zstd", ] } rand = "0.8.5" diff --git a/examples/breakout/breakout.rs b/examples/breakout/breakout.rs index b8a73cc..f8f1af2 100644 --- a/examples/breakout/breakout.rs +++ b/examples/breakout/breakout.rs @@ -6,7 +6,7 @@ use std::net::{IpAddr, Ipv4Addr}; use bevy::prelude::*; use bevy_quinnet::{ client::QuinnetClientPlugin, - server::{QuinnetServerPlugin, QuinnetServer}, + server::{QuinnetServer, QuinnetServerPlugin}, }; use client::BACKGROUND_COLOR; @@ -134,7 +134,7 @@ fn main() { .insert_resource(client::BricksMapping::default()); // ------ Main menu - app.add_systems(Update, bevy::window::close_on_esc) + app.add_systems(Update, close_on_esc) .add_systems(OnEnter(GameState::MainMenu), client::setup_main_menu) .add_systems( Update, @@ -202,3 +202,19 @@ fn main() { app.run(); } + +pub fn close_on_esc( + mut commands: Commands, + focused_windows: Query<(Entity, &Window)>, + input: Res>, +) { + for (window, focus) in focused_windows.iter() { + if !focus.focused { + continue; + } + + if input.just_pressed(KeyCode::Escape) { + commands.entity(window).despawn(); + } + } +} diff --git a/examples/breakout/client.rs b/examples/breakout/client.rs index 08fc089..93445bf 100644 --- a/examples/breakout/client.rs +++ b/examples/breakout/client.rs @@ -6,19 +6,21 @@ use bevy::{ prelude::{ default, AssetServer, AudioBundle, BuildChildren, Bundle, Button, ButtonBundle, Camera2dBundle, Changed, Color, Commands, Component, DespawnRecursiveExt, Entity, - EventReader, EventWriter, KeyCode, Local, NextState, PlaybackSettings, Query, Res, ResMut, - Resource, TextBundle, Transform, Vec2, Vec3, With, Without, + EventReader, EventWriter, KeyCode, Local, PlaybackSettings, Query, Res, ResMut, Resource, + TextBundle, Transform, Vec2, Vec3, With, Without, }, sprite::{Sprite, SpriteBundle}, + state::state::NextState, text::{Text, TextSection, TextStyle}, ui::{ node_bundles::NodeBundle, AlignItems, BackgroundColor, Interaction, JustifyContent, - PositionType, Style, UiRect, Val, + PositionType, Style, UiImage, UiRect, Val, }, }; use bevy_quinnet::{ client::{ - certificate::CertificateVerificationMode, connection::ClientEndpointConfiguration, QuinnetClient, + certificate::CertificateVerificationMode, connection::ClientEndpointConfiguration, + QuinnetClient, }, shared::ClientId, }; @@ -33,19 +35,19 @@ use crate::{ const SCOREBOARD_FONT_SIZE: f32 = 40.0; const SCOREBOARD_TEXT_PADDING: Val = Val::Px(5.0); -pub(crate) const BACKGROUND_COLOR: Color = Color::rgb(0.9, 0.9, 0.9); -const PADDLE_COLOR: Color = Color::rgb(0.3, 0.3, 0.7); -const OPPONENT_PADDLE_COLOR: Color = Color::rgb(1.0, 0.5, 0.5); -const BALL_COLOR: Color = Color::rgb(0.35, 0.35, 0.6); -const OPPONENT_BALL_COLOR: Color = Color::rgb(0.9, 0.6, 0.6); -const BRICK_COLOR: Color = Color::rgb(0.5, 0.5, 1.0); -const WALL_COLOR: Color = Color::rgb(0.8, 0.8, 0.8); -const TEXT_COLOR: Color = Color::rgb(0.5, 0.5, 1.0); -const SCORE_COLOR: Color = Color::rgb(1.0, 0.5, 0.5); -const NORMAL_BUTTON_COLOR: Color = Color::rgb(0.15, 0.15, 0.15); -const HOVERED_BUTTON_COLOR: Color = Color::rgb(0.25, 0.25, 0.25); -const PRESSED_BUTTON_COLOR: Color = Color::rgb(0.35, 0.75, 0.35); -const BUTTON_TEXT_COLOR: Color = Color::rgb(0.9, 0.9, 0.9); +pub(crate) const BACKGROUND_COLOR: Color = Color::srgb(0.9, 0.9, 0.9); +const PADDLE_COLOR: Color = Color::srgb(0.3, 0.3, 0.7); +const OPPONENT_PADDLE_COLOR: Color = Color::srgb(1.0, 0.5, 0.5); +const BALL_COLOR: Color = Color::srgb(0.35, 0.35, 0.6); +const OPPONENT_BALL_COLOR: Color = Color::srgb(0.9, 0.6, 0.6); +const BRICK_COLOR: Color = Color::srgb(0.5, 0.5, 1.0); +const WALL_COLOR: Color = Color::srgb(0.8, 0.8, 0.8); +const TEXT_COLOR: Color = Color::srgb(0.5, 0.5, 1.0); +const SCORE_COLOR: Color = Color::srgb(1.0, 0.5, 0.5); +const NORMAL_BUTTON_COLOR: Color = Color::srgb(0.15, 0.15, 0.15); +const HOVERED_BUTTON_COLOR: Color = Color::srgb(0.25, 0.25, 0.25); +const PRESSED_BUTTON_COLOR: Color = Color::srgb(0.35, 0.75, 0.35); +const BUTTON_TEXT_COLOR: Color = Color::srgb(0.9, 0.9, 0.9); const BOLD_FONT: &str = "fonts/FiraSans-Bold.ttf"; const NORMAL_FONT: &str = "fonts/FiraMono-Medium.ttf"; @@ -380,7 +382,7 @@ pub(crate) fn setup_main_menu(mut commands: Commands, asset_server: Res) { .unwrap(); } -pub(crate) fn handle_client_messages(mut server: ResMut, mut players: ResMut) { +pub(crate) fn handle_client_messages( + mut server: ResMut, + mut players: ResMut, +) { let endpoint = server.endpoint_mut(); for client_id in endpoint.clients() { while let Some((_, message)) = endpoint.try_receive_message_from::(client_id) @@ -249,7 +255,11 @@ pub(crate) fn apply_velocity(mut query: Query<(&mut Transform, &Velocity), With< } } -fn start_game(commands: &mut Commands, server: &mut ResMut, players: &ResMut) { +fn start_game( + commands: &mut Commands, + server: &mut ResMut, + players: &ResMut, +) { let endpoint = server.endpoint_mut(); // Assign ids for client_id in players.map.keys().into_iter() { diff --git a/examples/chat/client.rs b/examples/chat/client.rs index 716519f..6c26418 100644 --- a/examples/chat/client.rs +++ b/examples/chat/client.rs @@ -97,7 +97,7 @@ fn handle_terminal_messages( ) { while let Ok(message) = terminal_messages.try_recv() { if message == "quit" { - app_exit_events.send(AppExit); + app_exit_events.send(AppExit::Success); } else { client .connection() diff --git a/tests/certificates.rs b/tests/certificates.rs index 588161e..516dfdb 100644 --- a/tests/certificates.rs +++ b/tests/certificates.rs @@ -11,7 +11,8 @@ use bevy_quinnet::{ QuinnetClient, QuinnetClientPlugin, DEFAULT_KNOWN_HOSTS_FILE, }, server::{ - certificate::CertificateRetrievalMode, QuinnetServerPlugin, QuinnetServer, ServerEndpointConfiguration, + certificate::CertificateRetrievalMode, QuinnetServer, QuinnetServerPlugin, + ServerEndpointConfiguration, }, shared::channels::ChannelsConfiguration, }; @@ -77,7 +78,7 @@ fn trust_on_first_use() { // Server listens with a cert loaded from a file { - let mut server = server_app.world.resource_mut::(); + let mut server = server_app.world_mut().resource_mut::(); let server_cert = server .start_endpoint( ServerEndpointConfiguration::from_ip("0.0.0.0".parse().unwrap(), port), @@ -97,7 +98,7 @@ fn trust_on_first_use() { // Client connects with empty cert store { - let mut client = client_app.world.resource_mut::(); + let mut client = client_app.world_mut().resource_mut::(); client .open_connection( default_client_configuration(port), @@ -116,7 +117,7 @@ fn trust_on_first_use() { // The server's certificate is treatead as Unknown by the client, which stores it and continues the connection { - let mut client_test_data = client_app.world.resource_mut::(); + let mut client_test_data = client_app.world_mut().resource_mut::(); assert_eq!( client_test_data.cert_trust_update_events_received, 1, "The client should have received exactly 1 certificate trust update event" @@ -140,7 +141,7 @@ fn trust_on_first_use() { "The server name should match the one we configured" ); - let mut client = client_app.world.resource_mut::(); + let mut client = client_app.world_mut().resource_mut::(); assert!( client.is_connected(), "The default connection should be connected to the server" @@ -170,16 +171,19 @@ fn trust_on_first_use() { { assert!( - client_app.world.resource_mut::().is_connected(), + client_app + .world_mut() + .resource_mut::() + .is_connected(), "The default connection should be connected to the server" ); - let client_test_data = client_app.world.resource::(); + let client_test_data = client_app.world().resource::(); assert_eq!(client_test_data.cert_trust_update_events_received, 1, "The client should still have only 1 certificate trust update event after his reconnection"); // Clients disconnects client_app - .world + .world_mut() .resource_mut::() .close_all_connections() .expect("Failed to close connections on the client"); @@ -187,7 +191,7 @@ fn trust_on_first_use() { // Server reboots, and generates a new self-signed certificate server_app - .world + .world_mut() .resource_mut::() .stop_endpoint() .unwrap(); @@ -196,7 +200,7 @@ fn trust_on_first_use() { sleep(Duration::from_secs_f32(0.1)); let server_cert = server_app - .world + .world_mut() .resource_mut::() .start_endpoint( ServerEndpointConfiguration::from_ip(LOCAL_BIND_IP, port), @@ -209,7 +213,7 @@ fn trust_on_first_use() { // Client reconnects with its cert store containing the previously store certificate fingerprint { - let mut client = client_app.world.resource_mut::(); + let mut client = client_app.world_mut().resource_mut::(); client .open_connection( default_client_configuration(port), @@ -239,7 +243,7 @@ fn trust_on_first_use() { // The server's certificate is treatead as Untrusted by the client, which requests a client action // We received the client action request and asked to abort the connection { - let mut client_test_data = client_app.world.resource_mut::(); + let mut client_test_data = client_app.world_mut().resource_mut::(); assert_eq!( client_test_data.cert_interactions_received, 1, "The client should have received exactly 1 certificate interaction event" @@ -294,7 +298,7 @@ fn trust_on_first_use() { "The certificate verification status in the connection abort event should be `Untrusted`" ); - let client = client_app.world.resource::(); + let client = client_app.world().resource::(); assert!( client.is_connected() == false, "The default connection should not be connected to the server" diff --git a/tests/channels.rs b/tests/channels.rs index 5e46dd2..ce4c7c3 100644 --- a/tests/channels.rs +++ b/tests/channels.rs @@ -34,7 +34,7 @@ fn default_channel() { close_server_channel(server_default_channel, &mut server_app); { - let mut server = server_app.world.resource_mut::(); + let mut server = server_app.world_mut().resource_mut::(); assert_eq!( server.endpoint().get_default_channel(), None, @@ -52,7 +52,7 @@ fn default_channel() { ); } { - let mut client = client_app.world.resource_mut::(); + let mut client = client_app.world_mut().resource_mut::(); assert_eq!( client.connection().get_default_channel(), None, diff --git a/tests/connection.rs b/tests/connection.rs index 1ab49f7..9d30a4c 100644 --- a/tests/connection.rs +++ b/tests/connection.rs @@ -22,32 +22,35 @@ fn connection_with_two_apps() { assert!( client_app - .world + .world() .resource::() .get_connection() .is_some(), "The default connection should exist" ); - let server = server_app.world.resource::(); + let server = server_app.world().resource::(); assert!(server.is_listening(), "The server should be listening"); let client_id = wait_for_client_connected(&mut client_app, &mut server_app); assert_eq!( server_app - .world + .world() .resource::() .connection_events_received, 1 ); assert!( - client_app.world.resource::().is_connected(), + client_app + .world() + .resource::() + .is_connected(), "The default connection should be connected to the server" ); assert_eq!( client_app - .world + .world() .resource::() .connection_events_received, 1 @@ -55,7 +58,7 @@ fn connection_with_two_apps() { let sent_client_message = SharedMessage::TestMessage("Test message content".to_string()); client_app - .world + .world() .resource::() .connection() .send_message(sent_client_message.clone()) @@ -66,7 +69,7 @@ fn connection_with_two_apps() { server_app.update(); let (_channel_id, client_message) = server_app - .world + .world_mut() .resource_mut::() .endpoint_mut() .receive_message_from::(client_id) @@ -77,7 +80,7 @@ fn connection_with_two_apps() { let sent_server_message = SharedMessage::TestMessage("Server response".to_string()); server_app - .world + .world() .resource::() .endpoint() .broadcast_message(sent_server_message.clone()) @@ -88,7 +91,7 @@ fn connection_with_two_apps() { client_app.update(); let (_channel_id, server_message) = client_app - .world + .world_mut() .resource_mut::() .connection_mut() .receive_message::() @@ -114,7 +117,7 @@ fn reconnection() { assert_eq!( server_app - .world + .world() .resource::() .connection_events_received, 1 @@ -122,14 +125,14 @@ fn reconnection() { assert_eq!( client_app - .world + .world() .resource::() .connection_events_received, 1 ); client_app - .world + .world_mut() .resource_mut::() .connection_mut() .disconnect() @@ -139,7 +142,7 @@ fn reconnection() { assert_eq!(last_disconnected_client_id, client_id_1); client_app - .world + .world_mut() .resource_mut::() .connection_mut() .reconnect() @@ -154,7 +157,7 @@ fn reconnection() { assert_eq!( server_app - .world + .world() .resource::() .connection_events_received, 2 @@ -162,7 +165,7 @@ fn reconnection() { assert_eq!( client_app - .world + .world() .resource::() .connection_events_received, 2 diff --git a/tests/utils/mod.rs b/tests/utils/mod.rs index d44aae6..e32a278 100644 --- a/tests/utils/mod.rs +++ b/tests/utils/mod.rs @@ -190,12 +190,16 @@ pub fn wait_for_client_connected(client_app: &mut App, server_app: &mut App) -> loop { client_app.update(); server_app.update(); - if client_app.world.resource::().is_connected() { + if client_app + .world() + .resource::() + .is_connected() + { break; } } server_app - .world + .world() .resource::() .last_connected_client_id .expect("A client should have connected") @@ -205,7 +209,7 @@ pub fn wait_for_all_clients_disconnected(server_app: &mut App) -> ClientId { loop { server_app.update(); if server_app - .world + .world() .resource::() .endpoint() .clients() @@ -216,14 +220,14 @@ pub fn wait_for_all_clients_disconnected(server_app: &mut App) -> ClientId { } } server_app - .world + .world() .resource::() .last_disconnected_client_id .expect("A client should have connected") } pub fn get_default_client_channel(app: &App) -> ChannelId { - let client = app.world.resource::(); + let client = app.world().resource::(); client .connection() .get_default_channel() @@ -231,7 +235,7 @@ pub fn get_default_client_channel(app: &App) -> ChannelId { } pub fn get_default_server_channel(app: &App) -> ChannelId { - let server = app.world.resource::(); + let server = app.world().resource::(); server .endpoint() .get_default_channel() @@ -239,7 +243,7 @@ pub fn get_default_server_channel(app: &App) -> ChannelId { } pub fn close_client_channel(channel_id: ChannelId, app: &mut App) { - let mut client = app.world.resource_mut::(); + let mut client = app.world_mut().resource_mut::(); client .connection_mut() .close_channel(channel_id) @@ -247,7 +251,7 @@ pub fn close_client_channel(channel_id: ChannelId, app: &mut App) { } pub fn close_server_channel(channel_id: ChannelId, app: &mut App) { - let mut server = app.world.resource_mut::(); + let mut server = app.world_mut().resource_mut::(); server .endpoint_mut() .close_channel(channel_id) @@ -255,7 +259,7 @@ pub fn close_server_channel(channel_id: ChannelId, app: &mut App) { } pub fn open_client_channel(channel_type: ChannelType, app: &mut App) -> ChannelId { - let mut client = app.world.resource_mut::(); + let mut client = app.world_mut().resource_mut::(); client .connection_mut() .open_channel(channel_type) @@ -263,7 +267,7 @@ pub fn open_client_channel(channel_type: ChannelType, app: &mut App) -> ChannelI } pub fn open_server_channel(channel_type: ChannelType, app: &mut App) -> ChannelId { - let mut server = app.world.resource_mut::(); + let mut server = app.world_mut().resource_mut::(); server .endpoint_mut() .open_channel(channel_type) @@ -274,7 +278,7 @@ pub fn wait_for_client_message( client_id: ClientId, server_app: &mut App, ) -> (ChannelId, SharedMessage) { - let mut server = server_app.world.resource_mut::(); + let mut server = server_app.world_mut().resource_mut::(); loop { sleep(Duration::from_secs_f32(0.05)); @@ -290,7 +294,7 @@ pub fn wait_for_client_message( } pub fn wait_for_server_message(client_app: &mut App) -> (ChannelId, SharedMessage) { - let mut client = client_app.world.resource_mut::(); + let mut client = client_app.world_mut().resource_mut::(); loop { sleep(Duration::from_secs_f32(0.05)); @@ -318,7 +322,7 @@ pub fn send_and_test_client_message( .to_string(), ); - let client = client_app.world.resource_mut::(); + let client = client_app.world_mut().resource_mut::(); client .connection() .send_message_on(channel, client_message.clone()) @@ -344,7 +348,7 @@ pub fn send_and_test_server_message( .to_string(), ); - let mut server = server_app.world.resource_mut::(); + let mut server = server_app.world_mut().resource_mut::(); server .endpoint_mut() .send_message_on(client_id, channel, server_message.clone()) From 66d7650c40218fcb8deb6b62cfd6985612d24b1b Mon Sep 17 00:00:00 2001 From: Henauxg <19689618+Henauxg@users.noreply.github.com> Date: Wed, 12 Jun 2024 11:09:59 +0200 Subject: [PATCH 02/11] examples(breakout): Fix UI buttons interactions --- examples/breakout/client.rs | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/examples/breakout/client.rs b/examples/breakout/client.rs index 93445bf..1cc8b3f 100644 --- a/examples/breakout/client.rs +++ b/examples/breakout/client.rs @@ -13,8 +13,8 @@ use bevy::{ state::state::NextState, text::{Text, TextSection, TextStyle}, ui::{ - node_bundles::NodeBundle, AlignItems, BackgroundColor, Interaction, JustifyContent, - PositionType, Style, UiImage, UiRect, Val, + node_bundles::NodeBundle, AlignItems, Interaction, JustifyContent, PositionType, Style, + UiImage, UiRect, Val, }, }; use bevy_quinnet::{ @@ -81,7 +81,7 @@ pub(crate) struct Paddle; pub(crate) struct Ball; #[derive(Component)] -pub(crate) struct Brick(BrickId); +pub(crate) struct Brick; /// The buttons in the main menu. #[derive(Clone, Copy, Component)] @@ -172,7 +172,7 @@ pub(crate) fn spawn_bricks( let brick = commands .spawn(( - Brick(brick_id), + Brick, SpriteBundle { sprite: Sprite { color: BRICK_COLOR, @@ -407,7 +407,7 @@ pub(crate) fn setup_main_menu(mut commands: Commands, asset_server: Res, With