From ed5ea5328d3508d7611934752053835ef7f59d0c Mon Sep 17 00:00:00 2001 From: Martin Indra Date: Wed, 9 Aug 2023 21:53:14 +0200 Subject: [PATCH] Upgrade game joining --- crates/lobby_client/src/endpoints.rs | 25 ++++++++++---- crates/menu/src/multiplayer/joining.rs | 47 +++++++++++++------------- crates/multiplayer/src/game.rs | 16 +++++++-- 3 files changed, 56 insertions(+), 32 deletions(-) diff --git a/crates/lobby_client/src/endpoints.rs b/crates/lobby_client/src/endpoints.rs index 8cdedeb8..ed6b69df 100644 --- a/crates/lobby_client/src/endpoints.rs +++ b/crates/lobby_client/src/endpoints.rs @@ -1,6 +1,8 @@ use std::borrow::Cow; -use de_lobby_model::{Game, GameListing, GameSetup, Token, UserWithPassword, UsernameAndPassword}; +use de_lobby_model::{ + Game, GameListing, GamePlayerInfo, GameSetup, Token, UserWithPassword, UsernameAndPassword, +}; use reqwest::{header::HeaderValue, Method, Request}; use serde::Serialize; use url::Url; @@ -117,11 +119,14 @@ impl LobbyRequestCreator for GetGameRequest { } } -pub struct JoinGameRequest(String); +pub struct JoinGameRequest { + game: String, + player: GamePlayerInfo, +} impl JoinGameRequest { - pub fn new(name: String) -> Self { - Self(name) + pub fn new(game: String, player: GamePlayerInfo) -> Self { + Self { game, player } } } @@ -131,11 +136,13 @@ impl LobbyRequest for JoinGameRequest { impl LobbyRequestCreator for JoinGameRequest { fn path(&self) -> Cow { - encode(&["a", "games", self.0.as_str(), "join"]) + encode(&["a", "games", self.game.as_str(), "join"]) } fn create(&self, url: Url) -> Request { - Request::new(Method::PUT, url) + let mut request = Request::new(Method::PUT, url); + json(&mut request, &self.player); + request } } @@ -255,8 +262,12 @@ mod tests { #[test] fn test_join() { - let request = JoinGameRequest::new("Cool Game".to_owned()); + let request = JoinGameRequest::new("Cool Game".to_owned(), GamePlayerInfo::new(2)); assert_eq!(request.path().as_ref(), "/a/games/Cool%20Game/join"); + + let request = request.create(Url::parse("http://example.com/a/games/123/join").unwrap()); + let body = String::from_utf8(request.body().unwrap().as_bytes().unwrap().to_vec()).unwrap(); + assert_eq!(body, r#"{"ordinal":2}"#); } #[test] diff --git a/crates/menu/src/multiplayer/joining.rs b/crates/menu/src/multiplayer/joining.rs index 76bc9270..c71f2581 100644 --- a/crates/menu/src/multiplayer/joining.rs +++ b/crates/menu/src/multiplayer/joining.rs @@ -1,8 +1,7 @@ -use std::net::SocketAddr; - use bevy::prelude::*; use de_gui::ToastEvent; use de_lobby_client::{GetGameRequest, JoinGameRequest}; +use de_lobby_model::GamePlayerInfo; use de_multiplayer::{ ConnectionType, GameJoinedEvent, NetGameConf, ShutdownMultiplayerEvent, StartMultiplayerEvent, }; @@ -32,8 +31,8 @@ impl Plugin for JoiningGamePlugin { Update, ( handle_get_response, - handle_join_response.run_if(resource_exists::()), handle_joined_event.run_if(on_event::()), + handle_join_response, ) .run_if(in_state(MultiplayerState::GameJoining)), ); @@ -56,9 +55,6 @@ impl JoinGameEvent { #[derive(Resource)] pub(crate) struct GameNameRes(String); -#[derive(Resource)] -pub(crate) struct GameSocketAddrRes(SocketAddr); - fn handle_join_event( mut commands: Commands, mut next_state: ResMut>, @@ -78,7 +74,6 @@ fn cleanup( mut shutdown: EventWriter, ) { commands.remove_resource::(); - commands.remove_resource::(); if state.as_ref() != &MultiplayerState::GameJoined { shutdown.send(ShutdownMultiplayerEvent); @@ -90,19 +85,19 @@ fn get_game(game_name: Res, mut sender: Sender) { } fn handle_get_response( - mut commands: Commands, mut next_state: ResMut>, mut receiver: Receiver, - mut sender: Sender, + mut multiplayer: EventWriter, mut toasts: EventWriter, ) { while let Some(result) = receiver.receive() { match result { Ok(game) => { - sender.send(JoinGameRequest::new( - game.setup().config().name().to_owned(), - )); - commands.insert_resource(GameSocketAddrRes(game.setup().server())); + let server = game.setup().server(); + multiplayer.send(StartMultiplayerEvent::new(NetGameConf::new( + server.ip(), + ConnectionType::JoinGame(server.port()), + ))); } Err(error) => { toasts.send(ToastEvent::new(error)); @@ -112,20 +107,30 @@ fn handle_get_response( } } +fn handle_joined_event( + game_name: Res, + mut events: EventReader, + mut sender: Sender, +) { + let Some(event) = events.iter().last() else { + return; + }; + + sender.send(JoinGameRequest::new( + game_name.0.to_owned(), + GamePlayerInfo::new(event.player().to_num()), + )); +} + fn handle_join_response( - server: Res, mut next_state: ResMut>, mut receiver: Receiver, - mut multiplayer: EventWriter, mut toasts: EventWriter, ) { while let Some(result) = receiver.receive() { match result { Ok(_) => { - multiplayer.send(StartMultiplayerEvent::new(NetGameConf::new( - server.0.ip(), - ConnectionType::JoinGame(server.0.port()), - ))); + next_state.set(MultiplayerState::GameJoined); } Err(error) => { toasts.send(ToastEvent::new(error)); @@ -134,7 +139,3 @@ fn handle_join_response( } } } - -fn handle_joined_event(mut next_state: ResMut>) { - next_state.set(MultiplayerState::GameJoined); -} diff --git a/crates/multiplayer/src/game.rs b/crates/multiplayer/src/game.rs index b47eb820..6a320127 100644 --- a/crates/multiplayer/src/game.rs +++ b/crates/multiplayer/src/game.rs @@ -43,7 +43,19 @@ pub struct GameOpenedEvent(pub SocketAddr); /// A game was just joined. #[derive(Event)] -pub struct GameJoinedEvent; +pub struct GameJoinedEvent { + player: Player, +} + +impl GameJoinedEvent { + fn new(player: Player) -> Self { + Self { player } + } + + pub fn player(&self) -> Player { + self.player + } +} #[derive(Resource)] pub(crate) struct Players { @@ -138,7 +150,7 @@ fn process_from_game( info!("Joined game as Player {player}."); players.local = Some(player); next_state.set(NetState::Joined); - joined_events.send(GameJoinedEvent); + joined_events.send(GameJoinedEvent::new(player)); } Err(err) => { fatals.send(FatalErrorEvent::new(format!(