diff --git a/CHANGELOG.md b/CHANGELOG.md index 7aa0e7e..d80f73f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## Version 0.9.0 (2024-06-05) + +- Update to use Bevy 0.14 + ## Version 0.8.0 (2024-05-12) - Added a new crate `bevy_replicon_quinnet` with tests and examples, providing an integration of bevy_quinnet as a replicon back-end. diff --git a/Cargo.toml b/Cargo.toml index 1887ad3..ce4c810 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "bevy_quinnet" -version = "0.8.0" +version = "0.9.0" description = "Bevy plugin for Client/Server multiplayer games using QUIC" repository = "https://github.com/Henauxg/bevy_quinnet" documentation = "https://docs.rs/bevy_quinnet" @@ -15,7 +15,7 @@ exclude = ["assets/"] members = ["bevy_replicon_quinnet"] [dependencies] -bevy = { version = "0.13.0", default-features = false, features = [] } +bevy = { version = "0.14", default-features = false, features = [] } rustls = { version = "0.21.0", default-features = false, features = [ "quic", "dangerous_configuration", @@ -30,7 +30,7 @@ quinn-proto = "0.10.1" futures-util = "0.3.24" futures = "0.3.24" bincode = "1.3.3" -serde = "1.0.145" +serde = { version = "1.0.145", features = ["derive"] } bytes = "1.5.0" base64 = "0.13.1" thiserror = "1.0.37" @@ -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", 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/README.md b/README.md index d906802..0fe8afb 100644 --- a/README.md +++ b/README.md @@ -19,8 +19,8 @@ A Client/Server game networking plugin using [QUIC](https://www.chromium.org/qui - [Server](#server) - [Channels](#channels) - [Certificates and server authentication](#certificates-and-server-authentication) - - [Replicon integration](#replicon-integration) - [Examples](#examples) + - [Replicon integration](#replicon-integration) - [Compatible Bevy versions](#compatible-bevy-versions) - [Misc](#misc) - [Cargo features](#cargo-features) @@ -331,6 +331,7 @@ Bevy Quinnet can be used as a transport in [`bevy_replicon`](https://github.com/ | bevy_quinnet | bevy | | :----------- | :--- | +| 0.9 | 0.14 | | 0.7-0.8 | 0.13 | | 0.6 | 0.12 | | 0.5 | 0.11 | diff --git a/bevy_replicon_quinnet/CHANGELOG.md b/bevy_replicon_quinnet/CHANGELOG.md index 17587db..c9ce896 100644 --- a/bevy_replicon_quinnet/CHANGELOG.md +++ b/bevy_replicon_quinnet/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## Version 0.4.0 (2024-07-05) + +- Update `bevy_replicon` dependency from 0.26 to 0.27 + ## Version 0.3.0 (2024-05-27) - Update `bevy_replicon` dependency from 0.25 to 0.26 diff --git a/bevy_replicon_quinnet/Cargo.toml b/bevy_replicon_quinnet/Cargo.toml index 769f72c..75897a1 100644 --- a/bevy_replicon_quinnet/Cargo.toml +++ b/bevy_replicon_quinnet/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "bevy_replicon_quinnet" -version = "0.3.0" +version = "0.4.0" description = "Integration with bevy_quinnet for bevy_replicon" repository = "https://github.com/Henauxg/bevy_quinnet" documentation = "https://docs.rs/bevy_replicon_quinnet" @@ -12,19 +12,27 @@ readme = "README.md" exclude = ["assets/"] [dependencies] -bevy_replicon = { version = "0.26" } -bevy_quinnet = { version = "0.8.0", path = ".." } -bevy = { version = "0.13", default-features = false } +bevy_replicon = { version = "0.27" } +bevy_quinnet = { version = "0.9.0", path = ".." } +bevy = { version = "0.14", default-features = false } [dev-dependencies] serde = "1.0" clap = { version = "4.1", features = ["derive"] } -bevy = { version = "0.13", default-features = false, features = [ +bevy = { version = "0.14", default-features = false, features = [ "bevy_text", "bevy_ui", + "bevy_state", "bevy_gizmos", "x11", "default_font", + + + # Can be removed later, temporary fixes for a bug in "0.14.0-rc.2" + "bevy_scene", + "bevy_pbr", + "ktx2", + "zstd", ] } [[example]] diff --git a/bevy_replicon_quinnet/README.md b/bevy_replicon_quinnet/README.md index a2b1ec2..c7e06e1 100644 --- a/bevy_replicon_quinnet/README.md +++ b/bevy_replicon_quinnet/README.md @@ -34,6 +34,7 @@ Sources for the examples can be found in the [examples](examples) directory. | bevy | bevy_quinnet | bevy_replicon_quinnet | bevy_replicon | | :--- | :----------- | :-------------------- | :------------ | +| 0.14 | 0.9 | 0.4 | 0.27 | | 0.13 | 0.8 | 0.3 | 0.26 | | 0.13 | 0.8 | 0.2 | 0.25 | | 0.13 | 0.8 | 0.1 | 0.24 | diff --git a/bevy_replicon_quinnet/examples/simple_box.rs b/bevy_replicon_quinnet/examples/simple_box.rs index f440dee..e4f46fa 100644 --- a/bevy_replicon_quinnet/examples/simple_box.rs +++ b/bevy_replicon_quinnet/examples/simple_box.rs @@ -22,6 +22,8 @@ use bevy_replicon_quinnet::{ChannelsConfigurationExt, RepliconQuinnetPlugins}; use clap::Parser; use serde::{Deserialize, Serialize}; +use bevy::color::palettes::css::GREEN; + const PORT: u16 = 5000; fn main() { @@ -76,7 +78,7 @@ impl SimpleBoxPlugin { commands.spawn(PlayerBundle::new( ClientId::SERVER, Vec2::ZERO, - Color::GREEN, + GREEN.into(), )); } Cli::Server { port } => { @@ -101,7 +103,7 @@ impl SimpleBoxPlugin { commands.spawn(PlayerBundle::new( ClientId::SERVER, Vec2::ZERO, - Color::GREEN, + GREEN.into(), )); } Cli::Client { port, ip } => { @@ -149,7 +151,7 @@ impl SimpleBoxPlugin { commands.spawn(PlayerBundle::new( *client_id, Vec2::ZERO, - Color::rgb(r, g, b), + Color::srgb(r, g, b), )); } ServerEvent::ClientDisconnected { client_id, reason } => { diff --git a/bevy_replicon_quinnet/examples/tic_tac_toe.rs b/bevy_replicon_quinnet/examples/tic_tac_toe.rs index 97d4744..b63ba32 100644 --- a/bevy_replicon_quinnet/examples/tic_tac_toe.rs +++ b/bevy_replicon_quinnet/examples/tic_tac_toe.rs @@ -89,7 +89,7 @@ impl Plugin for TicTacToePlugin { const GRID_SIZE: usize = 3; -const BACKGROUND_COLOR: Color = Color::rgb(0.9, 0.9, 0.9); +const BACKGROUND_COLOR: Color = Color::srgb(0.9, 0.9, 0.9); // Bottom text defined in two sections, first for text and second for symbols with different font. const TEXT_SECTION: usize = 0; @@ -105,7 +105,7 @@ impl TicTacToePlugin { const LINE_THICKNESS: f32 = 10.0; const BOARD_SIZE: f32 = CELL_SIZE * GRID_SIZE as f32 + LINES_COUNT as f32 * LINE_THICKNESS; - const BOARD_COLOR: Color = Color::rgb(0.8, 0.8, 0.8); + const BOARD_COLOR: Color = Color::srgb(0.8, 0.8, 0.8); for line in 0..LINES_COUNT { let position = -BOARD_SIZE / 2.0 @@ -144,7 +144,7 @@ impl TicTacToePlugin { const BUTTON_SIZE: f32 = CELL_SIZE / 1.2; const BUTTON_MARGIN: f32 = (CELL_SIZE + LINE_THICKNESS - BUTTON_SIZE) / 2.0; - const TEXT_COLOR: Color = Color::rgb(0.5, 0.5, 1.0); + const TEXT_COLOR: Color = Color::srgb(0.5, 0.5, 1.0); const FONT_SIZE: f32 = 40.0; commands @@ -351,7 +351,7 @@ impl TicTacToePlugin { children: Query<&Children>, mut pick_events: EventWriter, ) { - const HOVER_COLOR: Color = Color::rgb(0.85, 0.85, 0.85); + const HOVER_COLOR: Color = Color::srgb(0.85, 0.85, 0.85); for (button_entity, button_parent, interaction, mut background) in &mut buttons { match interaction { @@ -572,8 +572,8 @@ impl Symbol { fn color(self) -> Color { match self { - Symbol::Cross => Color::rgb(1.0, 0.5, 0.5), - Symbol::Nought => Color::rgb(0.5, 0.5, 1.0), + Symbol::Cross => Color::srgb(1.0, 0.5, 0.5), + Symbol::Nought => Color::srgb(0.5, 0.5, 1.0), } } diff --git a/bevy_replicon_quinnet/tests/transport.rs b/bevy_replicon_quinnet/tests/transport.rs index 78ea934..01aa589 100644 --- a/bevy_replicon_quinnet/tests/transport.rs +++ b/bevy_replicon_quinnet/tests/transport.rs @@ -34,22 +34,22 @@ fn connect_disconnect() { setup(&mut server_app, &mut client_app, port); - let mut quinnet_client = client_app.world.resource_mut::(); + let mut quinnet_client = client_app.world_mut().resource_mut::(); assert!(quinnet_client.is_connected()); let default_connection = quinnet_client.get_default_connection().unwrap(); quinnet_client.close_connection(default_connection).unwrap(); client_app.update(); - let replicon_client = client_app.world.resource_mut::(); + let replicon_client = client_app.world_mut().resource_mut::(); assert!(replicon_client.is_disconnected()); server_wait_for_disconnect(&mut server_app); - let quinnet_server = server_app.world.resource::(); + let quinnet_server = server_app.world().resource::(); assert_eq!(quinnet_server.endpoint().clients().len(), 0); - let connected_clients = server_app.world.resource::(); + let connected_clients = server_app.world().resource::(); assert_eq!(connected_clients.len(), 0); } @@ -71,12 +71,12 @@ fn replication() { setup(&mut server_app, &mut client_app, port); - server_app.world.spawn(Replicated); + server_app.world_mut().spawn(Replicated); server_app.update(); client_wait_for_message(&mut client_app); - assert_eq!(client_app.world.entities().len(), 1); + assert_eq!(client_app.world().entities().len(), 1); } #[test] @@ -98,7 +98,7 @@ fn server_event() { setup(&mut server_app, &mut client_app, port); - server_app.world.send_event(ToClients { + server_app.world_mut().send_event(ToClients { mode: SendMode::Broadcast, event: DummyEvent, }); @@ -106,7 +106,7 @@ fn server_event() { server_app.update(); client_wait_for_message(&mut client_app); - let dummy_events = client_app.world.resource::>(); + let dummy_events = client_app.world().resource::>(); assert_eq!(dummy_events.len(), 1); } @@ -129,12 +129,12 @@ fn client_event() { setup(&mut server_app, &mut client_app, port); - client_app.world.send_event(DummyEvent); + client_app.world_mut().send_event(DummyEvent); client_app.update(); server_wait_for_message(&mut server_app); let client_events = server_app - .world + .world() .resource::>>(); assert_eq!(client_events.len(), 1); } @@ -147,11 +147,11 @@ fn setup(server_app: &mut App, client_app: &mut App, server_port: u16) { fn setup_client(app: &mut App, server_port: u16) { let channels_config = app - .world + .world() .resource::() .get_client_configs(); - let mut client = app.world.resource_mut::(); + let mut client = app.world_mut().resource_mut::(); client .open_connection( ClientEndpointConfiguration::from_ips( @@ -168,11 +168,11 @@ fn setup_client(app: &mut App, server_port: u16) { fn setup_server(app: &mut App, server_port: u16) { let channels_config = app - .world + .world() .resource::() .get_server_configs(); - let mut server = app.world.resource_mut::(); + let mut server = app.world_mut().resource_mut::(); server .start_endpoint( ServerEndpointConfiguration::from_ip(IpAddr::V4(Ipv4Addr::LOCALHOST), server_port), @@ -188,7 +188,11 @@ fn wait_for_connection(server_app: &mut App, client_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; } } @@ -199,7 +203,7 @@ fn client_wait_for_message(client_app: &mut App) { sleep(Duration::from_secs_f32(0.05)); client_app.update(); if client_app - .world + .world() .resource::() .connection() .received_messages_count() @@ -215,7 +219,7 @@ fn server_wait_for_message(server_app: &mut App) { sleep(Duration::from_secs_f32(0.05)); server_app.update(); if server_app - .world + .world() .resource::() .endpoint() .endpoint_stats() @@ -232,7 +236,7 @@ fn server_wait_for_disconnect(server_app: &mut App) { sleep(Duration::from_secs_f32(0.05)); server_app.update(); if server_app - .world + .world() .resource::() .endpoint() .endpoint_stats() 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..d2bffd9 100644 --- a/examples/breakout/client.rs +++ b/examples/breakout/client.rs @@ -6,10 +6,11 @@ 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, @@ -18,7 +19,8 @@ use bevy::{ }; 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"; @@ -79,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)] @@ -170,7 +172,7 @@ pub(crate) fn spawn_bricks( let brick = commands .spawn(( - Brick(brick_id), + Brick, SpriteBundle { sprite: Sprite { color: BRICK_COLOR, @@ -419,12 +421,8 @@ pub(crate) fn handle_menu_buttons( MenuItem::Join => next_state.set(GameState::JoiningLobby), } } - Interaction::Hovered => { - *color = HOVERED_BUTTON_COLOR.into(); - } - Interaction::None => { - *color = NORMAL_BUTTON_COLOR.into(); - } + Interaction::Hovered => *color = HOVERED_BUTTON_COLOR.into(), + Interaction::None => *color = NORMAL_BUTTON_COLOR.into(), } } } diff --git a/examples/breakout/server.rs b/examples/breakout/server.rs index fe6e4b8..78a0cab 100644 --- a/examples/breakout/server.rs +++ b/examples/breakout/server.rs @@ -6,10 +6,13 @@ use bevy::{ default, Bundle, Commands, Component, Entity, EventReader, Query, Res, ResMut, Resource, Transform, Vec2, Vec3, With, }, - transform::TransformBundle, + transform::bundles::TransformBundle, }; use bevy_quinnet::{ - server::{certificate::CertificateRetrievalMode, ConnectionEvent, QuinnetServer, ServerEndpointConfiguration}, + server::{ + certificate::CertificateRetrievalMode, ConnectionEvent, QuinnetServer, + ServerEndpointConfiguration, + }, shared::ClientId, }; @@ -87,7 +90,10 @@ pub(crate) fn start_listening(mut server: ResMut) { .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/src/client.rs b/src/client.rs index b6e5a1e..61139ee 100644 --- a/src/client.rs +++ b/src/client.rs @@ -7,7 +7,7 @@ use std::{ }; use bevy::prelude::*; -use quinn::ConnectionError; + use tokio::{ runtime::{self}, sync::oneshot, @@ -57,7 +57,7 @@ pub enum QuinnetConnectionError { pub(crate) enum ClientAsyncMessage { Connected(InternalConnectionRef, Option), ConnectionFailed(QuinnetConnectionError), - ConnectionClosed(ConnectionError), + ConnectionClosed, // TODO Might set a ConnectionError CertificateInteractionRequest { status: CertVerificationStatus, info: CertVerificationInfo, @@ -317,7 +317,7 @@ pub fn update_sync_client( err, }); } - ClientAsyncMessage::ConnectionClosed(_) => match connection.state { + ClientAsyncMessage::ConnectionClosed => match connection.state { InternalConnectionState::Disconnected => (), _ => { connection.try_disconnect(); diff --git a/src/client/connection.rs b/src/client/connection.rs index b70842f..85b3506 100644 --- a/src/client/connection.rs +++ b/src/client/connection.rs @@ -807,12 +807,12 @@ pub(crate) async fn async_connection_task( let conn = connection_handle.clone(); let to_sync_client = to_sync_client_send.clone(); tokio::spawn(async move { - let conn_err = conn.closed().await; - info!("Connection {} closed: {}", local_id, conn_err); + let _conn_err = conn.closed().await; + info!("Connection {} closed: {}", local_id, _conn_err); // If we requested the connection to close, channel may have been closed already. if !to_sync_client.is_closed() { to_sync_client - .send(ClientAsyncMessage::ConnectionClosed(conn_err)) + .send(ClientAsyncMessage::ConnectionClosed) .await .expect("Failed to signal connection closed in async connection"); } diff --git a/src/server.rs b/src/server.rs index b9f7361..c77467c 100644 --- a/src/server.rs +++ b/src/server.rs @@ -6,7 +6,7 @@ use std::{ use bevy::prelude::*; use bytes::Bytes; -use quinn::{ConnectionError, Endpoint as QuinnEndpoint, ServerConfig}; +use quinn::{Endpoint as QuinnEndpoint, ServerConfig}; use quinn_proto::ConnectionStats; use serde::Deserialize; use tokio::{ @@ -133,7 +133,7 @@ impl ServerEndpointConfiguration { #[derive(Debug)] pub(crate) enum ServerAsyncMessage { ClientConnected(ClientConnection), - ClientConnectionClosed(ClientId, ConnectionError), + ClientConnectionClosed(ClientId), // TODO Might add a ConnectionError } #[derive(Debug, Clone)] @@ -994,14 +994,12 @@ async fn client_connection_task( let conn = connection_handle.clone(); let to_sync_server = to_sync_server_send.clone(); tokio::spawn(async move { - let conn_err = conn.closed().await; - info!("Connection {} closed: {}", client_id, conn_err); + let _conn_err = conn.closed().await; + info!("Connection {} closed: {}", client_id, _conn_err); // If we requested the connection to close, channel may have been closed already. if !to_sync_server.is_closed() { to_sync_server - .send(ServerAsyncMessage::ClientConnectionClosed( - client_id, conn_err, - )) + .send(ServerAsyncMessage::ClientConnectionClosed(client_id)) .await .expect("Failed to signal connection lost in async connection"); } @@ -1051,7 +1049,7 @@ pub fn update_sync_server( } }; } - ServerAsyncMessage::ClientConnectionClosed(client_id, _) => { + ServerAsyncMessage::ClientConnectionClosed(client_id) => { match endpoint.clients.contains_key(&client_id) { true => { endpoint.stats.disconnect_count += 1; 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())