Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
Indy2222 committed Aug 3, 2023
1 parent 26d550b commit 8ab3485
Show file tree
Hide file tree
Showing 7 changed files with 182 additions and 9 deletions.
24 changes: 23 additions & 1 deletion crates/lobby_client/src/endpoints.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::borrow::Cow;

use de_lobby_model::{GameListing, GameSetup, Token, UserWithPassword, UsernameAndPassword};
use de_lobby_model::{Game, GameListing, GameSetup, Token, UserWithPassword, UsernameAndPassword};
use reqwest::{header::HeaderValue, Method, Request};
use serde::Serialize;
use url::Url;
Expand Down Expand Up @@ -95,6 +95,28 @@ impl LobbyRequestCreator for ListGamesRequest {
}
}

pub struct GetGameRequest(String);

impl GetGameRequest {
pub fn new(id: impl ToString) -> Self {
Self(id.to_string())
}
}

impl LobbyRequest for GetGameRequest {
type Response = Game;
}

impl LobbyRequestCreator for GetGameRequest {
fn path(&self) -> Cow<str> {
encode(&["a", "games", self.0.as_str()])
}

fn create(&self, url: Url) -> Request {
Request::new(Method::GET, url)
}
}

pub struct JoinGameRequest(String);

impl JoinGameRequest {
Expand Down
1 change: 1 addition & 0 deletions crates/lobby_client/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ impl PluginGroup for LobbyClientPluginGroup {
.add(EndpointPlugin::<SignInRequest>::default())
.add(EndpointPlugin::<CreateGameRequest>::default())
.add(EndpointPlugin::<ListGamesRequest>::default())
.add(EndpointPlugin::<GetGameRequest>::default())
.add(EndpointPlugin::<JoinGameRequest>::default())
.add(EndpointPlugin::<LeaveGameRequest>::default())
}
Expand Down
12 changes: 6 additions & 6 deletions crates/menu/src/multiplayer/gamelisting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use de_gui::{ButtonCommands, GuiCommands, LabelCommands, OuterStyle, ToastEvent}
use de_lobby_client::{ListGamesRequest, RequestEvent, ResponseEvent};
use de_lobby_model::GamePartial;

use super::MultiplayerState;
use super::{joining::JoinGameEvent, MultiplayerState};
use crate::menu::Menu;

const REFRESH_INTERVAL: Duration = Duration::from_secs(10);
Expand All @@ -30,7 +30,7 @@ struct GamesTable(Entity);
#[derive(Component)]
enum ButtonAction {
Create,
Join,
Join(String),
}

fn setup(
Expand Down Expand Up @@ -141,7 +141,7 @@ fn row(commands: &mut GuiCommands, game: &GamePartial) -> Entity {
},
"Join",
)
.insert(ButtonAction::Join)
.insert(ButtonAction::Join(game.config().name().to_owned()))
.id();
commands.entity(row_id).add_child(button_id);
}
Expand Down Expand Up @@ -186,14 +186,14 @@ fn list_games_system(
fn button_system(
mut next_state: ResMut<NextState<MultiplayerState>>,
interactions: Query<(&Interaction, &ButtonAction), Changed<Interaction>>,
mut toasts: EventWriter<ToastEvent>,
mut joins: EventWriter<JoinGameEvent>,
) {
for (&interaction, action) in interactions.iter() {
if let Interaction::Pressed = interaction {
match action {
ButtonAction::Create => next_state.set(MultiplayerState::GameCreation),
ButtonAction::Join => {
toasts.send(ToastEvent::new("Not yet implemented (issue #301)."))
ButtonAction::Join(name) => {
joins.send(JoinGameEvent::new(name.to_owned()));
}
}
}
Expand Down
140 changes: 140 additions & 0 deletions crates/menu/src/multiplayer/joining.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
use std::net::SocketAddr;

use bevy::prelude::*;
use de_gui::ToastEvent;
use de_lobby_client::{GetGameRequest, JoinGameRequest};
use de_multiplayer::{
ConnectionType, GameJoinedEvent, NetGameConf, ShutdownMultiplayerEvent, StartMultiplayerEvent,
};

use super::{
requests::{Receiver, RequestsPlugin, Sender},
MultiplayerState,
};
use crate::MenuState;

pub(crate) struct JoiningGamePlugin;

impl Plugin for JoiningGamePlugin {
fn build(&self, app: &mut App) {
app.add_plugins((
RequestsPlugin::<GetGameRequest>::new(),
RequestsPlugin::<JoinGameRequest>::new(),
))
.add_event::<JoinGameEvent>()
.add_systems(OnEnter(MultiplayerState::GameJoining), get_game)
.add_systems(OnExit(MultiplayerState::GameJoining), cleanup)
.add_systems(
PreUpdate,
handle_join_event.run_if(in_state(MenuState::Multiplayer)),
)
.add_systems(
Update,
(
handle_get_response,
handle_join_response.run_if(resource_exists::<GameSocketAddrRes>()),
handle_joined_event.run_if(on_event::<GameJoinedEvent>()),
)
.run_if(in_state(MultiplayerState::GameJoining)),
);
}
}

/// Send this event to initiate joining of a multiplayer game.
///
/// The game will be joined at both DE Lobby and the DE Connector. Once this is
/// done, the menu transitions to [`MultiplayerState::GameJoined`].
#[derive(Event)]
pub(super) struct JoinGameEvent(String);

impl JoinGameEvent {
pub(super) fn new(name: String) -> Self {
Self(name)
}
}

#[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<NextState<MultiplayerState>>,
mut events: EventReader<JoinGameEvent>,
) {
let Some(event) = events.iter().last() else {
return;
};

commands.insert_resource(GameNameRes(event.0.to_owned()));
next_state.set(MultiplayerState::GameJoining);
}

fn cleanup(
mut commands: Commands,
state: Res<State<MultiplayerState>>,
mut shutdown: EventWriter<ShutdownMultiplayerEvent>,
) {
commands.remove_resource::<GameNameRes>();
commands.remove_resource::<GameSocketAddrRes>();

if state.as_ref() != &MultiplayerState::GameJoined {
shutdown.send(ShutdownMultiplayerEvent);
}
}

fn get_game(game_name: Res<GameNameRes>, mut sender: Sender<GetGameRequest>) {
sender.send(GetGameRequest::new(game_name.0.to_owned()));
}

fn handle_get_response(
mut commands: Commands,
mut next_state: ResMut<NextState<MultiplayerState>>,
mut receiver: Receiver<GetGameRequest>,
mut sender: Sender<JoinGameRequest>,
mut toasts: EventWriter<ToastEvent>,
) {
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()));
}
Err(error) => {
toasts.send(ToastEvent::new(error));
next_state.set(MultiplayerState::SignIn);
}
}
}
}

fn handle_join_response(
server: Res<GameSocketAddrRes>,
mut next_state: ResMut<NextState<MultiplayerState>>,
mut receiver: Receiver<JoinGameRequest>,
mut multiplayer: EventWriter<StartMultiplayerEvent>,
mut toasts: EventWriter<ToastEvent>,
) {
while let Some(result) = receiver.receive() {
match result {
Ok(_) => {
multiplayer.send(StartMultiplayerEvent::new(NetGameConf::new(
server.0.ip(),
ConnectionType::JoinGame(server.0.port()),
)));
}
Err(error) => {
toasts.send(ToastEvent::new(error));
next_state.set(MultiplayerState::SignIn);
}
}
}
}

fn handle_joined_event(mut next_state: ResMut<NextState<MultiplayerState>>) {
next_state.set(MultiplayerState::GameJoined);
}
5 changes: 4 additions & 1 deletion crates/menu/src/multiplayer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@ use de_multiplayer::MultiplayerShuttingDownEvent;

use self::{
create::CreateGamePlugin, gamelisting::GameListingPlugin, joined::JoinedGamePlugin,
setup::SetupGamePlugin, signin::SignInPlugin,
joining::JoiningGamePlugin, setup::SetupGamePlugin, signin::SignInPlugin,
};
use crate::{menu::ScreenStatePlugin, MenuState};

mod create;
mod gamelisting;
mod joined;
mod joining;
mod requests;
mod setup;
mod signin;
Expand All @@ -26,6 +27,7 @@ impl Plugin for MultiplayerPlugin {
GameListingPlugin,
CreateGamePlugin,
SetupGamePlugin,
JoiningGamePlugin,
JoinedGamePlugin,
))
.add_systems(
Expand All @@ -46,6 +48,7 @@ nested_state!(
GameListing,
GameCreation,
GameSetup,
GameJoining,
GameJoined,
}
);
Expand Down
7 changes: 7 additions & 0 deletions crates/multiplayer/src/game.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ pub(crate) struct GamePlugin;
impl Plugin for GamePlugin {
fn build(&self, app: &mut App) {
app.add_event::<GameOpenedEvent>()
.add_event::<GameJoinedEvent>()
.add_systems(OnEnter(NetState::Connected), (setup, open_or_join))
.add_systems(OnEnter(NetState::None), cleanup)
.add_systems(
Expand All @@ -40,6 +41,10 @@ impl Plugin for GamePlugin {
#[derive(Event)]
pub struct GameOpenedEvent(pub SocketAddr);

/// A game was just joined.
#[derive(Event)]
pub struct GameJoinedEvent;

#[derive(Resource)]
pub(crate) struct Players {
local: Option<Player>,
Expand Down Expand Up @@ -115,6 +120,7 @@ fn process_from_game(
mut inputs: EventReader<FromGameServerEvent>,
mut fatals: EventWriter<FatalErrorEvent>,
state: Res<State<NetState>>,
mut joined_events: EventWriter<GameJoinedEvent>,
mut next_state: ResMut<NextState<NetState>>,
) {
for event in inputs.iter() {
Expand All @@ -132,6 +138,7 @@ fn process_from_game(
info!("Joined game as Player {player}.");
players.local = Some(player);
next_state.set(NetState::Joined);
joined_events.send(GameJoinedEvent);
}
Err(err) => {
fatals.send(FatalErrorEvent::new(format!(
Expand Down
2 changes: 1 addition & 1 deletion crates/multiplayer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use stats::StatsPlugin;

pub use crate::{
config::{ConnectionType, NetGameConf},
game::GameOpenedEvent,
game::{GameJoinedEvent, GameOpenedEvent},
lifecycle::{MultiplayerShuttingDownEvent, ShutdownMultiplayerEvent, StartMultiplayerEvent},
netstate::NetState,
};
Expand Down

0 comments on commit 8ab3485

Please sign in to comment.