Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
Indy2222 committed Jul 17, 2023
1 parent 5c9284f commit 1ce98df
Show file tree
Hide file tree
Showing 10 changed files with 137 additions and 31 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion crates/lobby_client/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ impl LobbyClient {
}

fn fire<T: LobbyRequestCreator>(&self, request: Request) -> Task<Result<T::Response>> {
info!("Requesting {}", request.url());
info!("Requesting {} {}", request.method(), request.url());
let client = self.client.clone();

IoTaskPool::get().spawn(Compat::new(async move {
Expand Down
2 changes: 1 addition & 1 deletion crates/lobby_model/src/games.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ impl validation::Validatable for GameSetup {
}
}

#[derive(Serialize, Deserialize)]
#[derive(Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct GameConfig {
name: String,
Expand Down
2 changes: 2 additions & 0 deletions crates/menu/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,13 @@ categories.workspace = true

[dependencies]
# DE
de_conf.workspace = true
de_core.workspace = true
de_gui.workspace = true
de_lobby_client.workspace = true
de_lobby_model.workspace = true
de_map.workspace = true
de_multiplayer.workspace = true

# Other
async-std.workspace = true
Expand Down
42 changes: 14 additions & 28 deletions crates/menu/src/create.rs
Original file line number Diff line number Diff line change
@@ -1,27 +1,23 @@
use std::net::SocketAddr;

use bevy::prelude::*;
use de_gui::{
ButtonCommands, ButtonOps, GuiCommands, LabelCommands, OuterStyle, TextBoxCommands,
TextBoxQuery, ToastEvent,
};
use de_lobby_client::CreateGameRequest;
use de_lobby_model::{GameConfig, GameMap, GameSetup, Validatable};
use de_lobby_model::{GameConfig, GameMap, Validatable};
use de_map::hash::MapHash;

use crate::{
mapselection::{MapSelectedEvent, SelectMapEvent},
menu::Menu,
requests::{Receiver, RequestsPlugin, Sender},
setup::GameConfigRes,
MenuState,
};

pub(crate) struct CreateGamePlugin;

impl Plugin for CreateGamePlugin {
fn build(&self, app: &mut App) {
app.add_plugin(RequestsPlugin::<CreateGameRequest>::new())
.add_event::<CreateGameEvent>()
app.add_event::<CreateGameEvent>()
.add_system(setup.in_schedule(OnEnter(MenuState::GameCreation)))
.add_system(cleanup.in_schedule(OnExit(MenuState::GameCreation)))
.add_system(
Expand All @@ -40,8 +36,7 @@ impl Plugin for CreateGamePlugin {
.run_if(on_event::<CreateGameEvent>())
.after(CreateSet::Buttons)
.after(CreateSet::MapSelected),
)
.add_system(response_system.run_if(in_state(MenuState::GameCreation)));
);
}
}

Expand Down Expand Up @@ -189,9 +184,13 @@ fn spawn_caption(commands: &mut GuiCommands, parent_id: Entity, caption: &str) {
commands.entity(parent_id).add_child(caption_id);
}

fn cleanup(mut commands: GuiCommands) {
fn cleanup(mut commands: GuiCommands, state: Res<State<MenuState>>) {
commands.remove_resource::<Inputs>();
commands.remove_resource::<SelectedMap>();

if state.0 != MenuState::GameSetup {
commands.remove_resource::<GameConfigRes>();
}
}

fn button_system(
Expand Down Expand Up @@ -237,11 +236,12 @@ fn map_selected_system(
}

fn create_game_system(
mut commands: Commands,
inputs: Res<Inputs>,
texts: TextBoxQuery,
selected_map: Option<Res<SelectedMap>>,
mut toasts: EventWriter<ToastEvent>,
mut sender: Sender<CreateGameRequest>,
mut next_state: ResMut<NextState<MenuState>>,
) {
let Some(selected_map) = selected_map else {
toasts.send(ToastEvent::new("No map selected."));
Expand All @@ -257,26 +257,12 @@ fn create_game_system(
}
};

let game_server: SocketAddr = "127.0.0.1:8082".parse().unwrap();
let game_config = GameConfig::new(name, max_players, selected_map.0.clone());
let game_setup = GameSetup::new(game_server, game_config);
if let Err(error) = game_setup.validate() {
if let Err(error) = game_config.validate() {
toasts.send(ToastEvent::new(format!("{error}")));
return;
}

sender.send(CreateGameRequest::new(game_setup));
}

fn response_system(
mut next_state: ResMut<NextState<MenuState>>,
mut receiver: Receiver<CreateGameRequest>,
mut toasts: EventWriter<ToastEvent>,
) {
if let Some(result) = receiver.receive() {
match result {
Ok(_) => next_state.set(MenuState::MultiPlayerGame),
Err(error) => toasts.send(ToastEvent::new(error)),
}
}
commands.insert_resource(GameConfigRes::new(game_config));
next_state.set(MenuState::GameSetup);
}
4 changes: 4 additions & 0 deletions crates/menu/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use gamelisting::GameListingPlugin;
use mainmenu::MainMenuPlugin;
use mapselection::MapSelectionPlugin;
use menu::MenuPlugin;
use setup::SetupGamePlugin;
use signin::SignInPlugin;
use singleplayer::SinglePlayerPlugin;

Expand All @@ -20,6 +21,7 @@ mod mainmenu;
mod mapselection;
mod menu;
mod requests;
mod setup;
mod signin;
mod singleplayer;

Expand All @@ -36,6 +38,7 @@ impl PluginGroup for MenuPluginGroup {
.add(GameListingPlugin)
.add(SinglePlayerPlugin)
.add(CreateGamePlugin)
.add(SetupGamePlugin)
.add(AfterGamePlugin)
}
}
Expand All @@ -60,6 +63,7 @@ pub(crate) enum MenuState {
SignIn,
GameListing,
GameCreation,
GameSetup,
MultiPlayerGame,
AfterGame,
}
Expand Down
97 changes: 97 additions & 0 deletions crates/menu/src/setup.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
use bevy::prelude::*;
use de_conf::Configuration;
use de_gui::ToastEvent;
use de_lobby_client::CreateGameRequest;
use de_lobby_model::{GameConfig, GameSetup};
use de_multiplayer::{
GameOpenedEvent, NetGameConf, ServerPort, ShutdownMultiplayerEvent, StartMultiplayerEvent,
};

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

pub(crate) struct SetupGamePlugin;

impl Plugin for SetupGamePlugin {
fn build(&self, app: &mut App) {
app.add_plugin(RequestsPlugin::<CreateGameRequest>::new())
.add_system(setup_network.in_schedule(OnEnter(MenuState::GameSetup)))
.add_system(cleanup.in_schedule(OnExit(MenuState::GameSetup)))
.add_system(
create_game_in_lobby
.run_if(in_state(MenuState::GameSetup))
.run_if(on_event::<GameOpenedEvent>()),
)
.add_system(handle_lobby_response.run_if(in_state(MenuState::GameSetup)));
}
}

#[derive(Resource)]
pub(crate) struct GameConfigRes(GameConfig);

impl GameConfigRes {
pub(crate) fn new(config: GameConfig) -> Self {
Self(config)
}
}

fn setup_network(
config: Res<Configuration>,
game_config: Res<GameConfigRes>,
mut multiplayer: EventWriter<StartMultiplayerEvent>,
) {
let connector_conf = config.multiplayer().connector();
multiplayer.send(StartMultiplayerEvent::new(NetGameConf::new(
game_config.0.max_players().try_into().unwrap(),
connector_conf.ip(),
ServerPort::Main(connector_conf.port()),
)));
}

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

if state.0 != MenuState::MultiPlayerGame {
shutdown.send(ShutdownMultiplayerEvent);
}
}

fn create_game_in_lobby(
config: Res<GameConfigRes>,
mut opened_events: EventReader<GameOpenedEvent>,
mut sender: Sender<CreateGameRequest>,
) {
let Some(opened_event) = opened_events.iter().last() else {
return;
};

let game_setup = GameSetup::new(opened_event.0, config.0.clone());
sender.send(CreateGameRequest::new(game_setup));
}

fn handle_lobby_response(
mut next_state: ResMut<NextState<MenuState>>,
mut receiver: Receiver<CreateGameRequest>,
mut toasts: EventWriter<ToastEvent>,
) {
while let Some(result) = receiver.receive() {
match result {
Ok(_) => {
info!("Game successfully created.");
next_state.set(MenuState::MultiPlayerGame);
}
Err(error) => {
toasts.send(ToastEvent::new(error));
next_state.set(MenuState::GameCreation);
}
}
}
}

// TODO handle multiplayer errors
11 changes: 10 additions & 1 deletion crates/multiplayer/src/game.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::net::SocketAddr;

use bevy::prelude::*;
use de_core::{baseset::GameSet, player::Player};
use de_net::{FromGame, FromServer, GameOpenError, JoinError, ToGame, ToServer};
Expand All @@ -16,7 +18,8 @@ pub(crate) struct GamePlugin;

impl Plugin for GamePlugin {
fn build(&self, app: &mut App) {
app.add_system(setup.in_schedule(OnEnter(NetState::Connected)))
app.add_event::<GameOpenedEvent>()
.add_system(setup.in_schedule(OnEnter(NetState::Connected)))
.add_system(cleanup.in_schedule(OnEnter(NetState::None)))
.add_system(open_or_join.in_schedule(OnEnter(NetState::Connected)))
.add_system(
Expand All @@ -35,6 +38,9 @@ impl Plugin for GamePlugin {
}
}

/// A new game on the given socket address was just opened.
pub struct GameOpenedEvent(pub SocketAddr);

#[derive(Resource)]
pub(crate) struct Players {
local: Option<Player>,
Expand Down Expand Up @@ -71,9 +77,11 @@ fn open_or_join(
}

fn process_from_server(
conf: Res<NetGameConfRes>,
mut ports: ResMut<Ports>,
mut events: EventReader<FromMainServerEvent>,
mut outputs: EventWriter<ToGameServerEvent<true>>,
mut opened: EventWriter<GameOpenedEvent>,
mut fatals: EventWriter<FatalErrorEvent>,
) {
for event in events.iter() {
Expand All @@ -86,6 +94,7 @@ fn process_from_server(
info!("Game on port {} opened.", *port);
// Send something to open NAT.
outputs.send(ToGame::Ping(u32::MAX).into());
opened.send(GameOpenedEvent(SocketAddr::new(conf.server_host(), *port)));
}
Err(err) => {
fatals.send(FatalErrorEvent::new(format!("Invalid GameOpened: {err:?}")));
Expand Down
1 change: 1 addition & 0 deletions crates/multiplayer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use stats::StatsPlugin;

pub use crate::{
config::{NetGameConf, ServerPort},
game::GameOpenedEvent,
lifecycle::{ShutdownMultiplayerEvent, StartMultiplayerEvent},
netstate::NetState,
};
Expand Down
5 changes: 5 additions & 0 deletions crates/multiplayer/src/lifecycle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ impl Plugin for LifecyclePlugin {
.add_event::<ShutdownMultiplayerEvent>()
.add_event::<FatalErrorEvent>()
.add_system(cleanup.in_schedule(OnEnter(NetState::None)))
.add_system(log_shutdown.in_schedule(OnEnter(NetState::ShuttingDown)))
.add_system(
finish_game
.in_schedule(OnEnter(NetState::None))
Expand Down Expand Up @@ -88,6 +89,10 @@ fn cleanup(mut commands: Commands) {
commands.remove_resource::<NetGameConfRes>();
}

fn log_shutdown() {
info!("Shutting down multiplayer...");
}

fn finish_game(mut next_state: ResMut<NextState<AppState>>) {
next_state.set(AppState::InMenu);
}
Expand Down

0 comments on commit 1ce98df

Please sign in to comment.