parent
ff8578fd82
commit
bb66d28f06
12 changed files with 3238 additions and 105 deletions
File diff suppressed because it is too large
Load Diff
@ -1 +1,2 @@ |
|||||||
pub mod block; |
pub mod block; |
||||||
|
pub mod network; |
||||||
|
|||||||
@ -0,0 +1,63 @@ |
|||||||
|
use std::net::{Ipv4Addr, SocketAddr}; |
||||||
|
|
||||||
|
use bevy::prelude::*; |
||||||
|
use lightyear::prelude::client::*; |
||||||
|
use lightyear::prelude::*; |
||||||
|
|
||||||
|
// FIXME: Don't hardcode this!
|
||||||
|
pub const DIGEST: &'static str = ""; |
||||||
|
|
||||||
|
pub struct ClientPlugin; |
||||||
|
|
||||||
|
impl Plugin for ClientPlugin { |
||||||
|
fn build(&self, app: &mut App) { |
||||||
|
app.add_plugins(ClientPlugins::default()); |
||||||
|
// This maybe should be added by `ClientPlugins` but it currently isn't.
|
||||||
|
// (Unless we're using `NetcodeClientPlugin`, which would've added it.)
|
||||||
|
if !app.is_plugin_added::<lightyear::connection::client::ConnectionPlugin>() { |
||||||
|
app.add_plugins(lightyear::connection::client::ConnectionPlugin); |
||||||
|
} |
||||||
|
|
||||||
|
if !app.is_plugin_added::<super::ProtocolPlugin>() { |
||||||
|
app.add_plugins(super::ProtocolPlugin); |
||||||
|
} |
||||||
|
|
||||||
|
app.add_systems(Startup, connect_to_server); |
||||||
|
|
||||||
|
app.add_observer(on_connecting); |
||||||
|
app.add_observer(on_connected); |
||||||
|
app.add_observer(on_disconnected); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
fn connect_to_server(mut commands: Commands) { |
||||||
|
let client_addr = SocketAddr::new(Ipv4Addr::UNSPECIFIED.into(), 0); |
||||||
|
let server_addr = SocketAddr::new(Ipv4Addr::LOCALHOST.into(), super::DEFAULT_PORT); |
||||||
|
let certificate_digest = DIGEST.to_string(); |
||||||
|
|
||||||
|
commands |
||||||
|
.spawn(( |
||||||
|
Name::from("Client"), |
||||||
|
LocalAddr(client_addr), |
||||||
|
PeerAddr(server_addr), |
||||||
|
ReplicationReceiver::default(), |
||||||
|
WebTransportClientIo { certificate_digest }, |
||||||
|
RawClient, |
||||||
|
)) |
||||||
|
.trigger(|entity| LinkStart { entity }); |
||||||
|
} |
||||||
|
|
||||||
|
fn on_connecting(event: On<Add, Connecting>) { |
||||||
|
let client = event.entity; |
||||||
|
info!("Client '{client}' connecting ..."); |
||||||
|
} |
||||||
|
|
||||||
|
fn on_connected(event: On<Add, Connected>) { |
||||||
|
let client = event.entity; |
||||||
|
info!("Client '{client}' connected!"); |
||||||
|
} |
||||||
|
|
||||||
|
fn on_disconnected(event: On<Remove, Connected>) { |
||||||
|
let client = event.entity; |
||||||
|
info!("Client '{client}' disconnected!"); |
||||||
|
} |
||||||
@ -0,0 +1,9 @@ |
|||||||
|
mod client; |
||||||
|
mod protocol; |
||||||
|
mod server; |
||||||
|
|
||||||
|
pub use client::*; |
||||||
|
pub use protocol::*; |
||||||
|
pub use server::*; |
||||||
|
|
||||||
|
pub const DEFAULT_PORT: u16 = 13580; |
||||||
@ -0,0 +1,13 @@ |
|||||||
|
use bevy::prelude::*; |
||||||
|
use lightyear::prelude::*; |
||||||
|
|
||||||
|
use crate::block::Block; |
||||||
|
|
||||||
|
pub struct ProtocolPlugin; |
||||||
|
|
||||||
|
impl Plugin for ProtocolPlugin { |
||||||
|
fn build(&self, app: &mut App) { |
||||||
|
app.register_component::<Transform>(); |
||||||
|
app.register_component::<Block>(); |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,91 @@ |
|||||||
|
use std::net::{Ipv4Addr, SocketAddr}; |
||||||
|
|
||||||
|
use bevy::prelude::*; |
||||||
|
use lightyear::prelude::server::*; |
||||||
|
use lightyear::prelude::*; |
||||||
|
|
||||||
|
pub struct ServerPlugin; |
||||||
|
|
||||||
|
impl Plugin for ServerPlugin { |
||||||
|
fn build(&self, app: &mut App) { |
||||||
|
app.add_plugins(ServerPlugins::default()); |
||||||
|
// These maybe should be added by `ServerPlugins` but currently aren't.
|
||||||
|
// (Unless we're using `NetcodeServerPlugin`, which would've added it.)
|
||||||
|
if !app.is_plugin_added::<lightyear::connection::client::ConnectionPlugin>() { |
||||||
|
app.add_plugins(lightyear::connection::client::ConnectionPlugin); |
||||||
|
} |
||||||
|
if !app.is_plugin_added::<lightyear::connection::server::ConnectionPlugin>() { |
||||||
|
app.add_plugins(lightyear::connection::server::ConnectionPlugin); |
||||||
|
} |
||||||
|
|
||||||
|
if !app.is_plugin_added::<super::ProtocolPlugin>() { |
||||||
|
app.add_plugins(super::ProtocolPlugin); |
||||||
|
} |
||||||
|
|
||||||
|
app.add_systems(Startup, start_server); |
||||||
|
|
||||||
|
// TODO: See what happens when we try to start a server, but it
|
||||||
|
// can't, for example due to the port already being in use.
|
||||||
|
app.add_observer(on_server_started); |
||||||
|
app.add_observer(on_server_stopped); |
||||||
|
app.add_observer(handle_client_connected); |
||||||
|
app.add_observer(handle_client_disconnected); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
fn start_server(mut commands: Commands) -> Result { |
||||||
|
let server_addr = SocketAddr::new(Ipv4Addr::UNSPECIFIED.into(), super::DEFAULT_PORT); |
||||||
|
let certificate = Identity::self_signed(["localhost", "127.0.0.1", "::1"])?; |
||||||
|
|
||||||
|
commands |
||||||
|
.spawn(( |
||||||
|
Name::from("Server"), |
||||||
|
LocalAddr(server_addr), |
||||||
|
WebTransportServerIo { certificate }, |
||||||
|
RawServer, |
||||||
|
)) |
||||||
|
.trigger(|entity| LinkStart { entity }); |
||||||
|
|
||||||
|
Ok(()) |
||||||
|
} |
||||||
|
|
||||||
|
fn on_server_started(event: On<Add, Started>, servers: Query<&WebTransportServerIo>) -> Result { |
||||||
|
let server = event.entity; |
||||||
|
info!("Server '{server}' started!"); |
||||||
|
|
||||||
|
let certificate = &servers.get(server)?.certificate; |
||||||
|
let certificate_hash = certificate.certificate_chain().as_slice()[0].hash(); |
||||||
|
let certificate_digest = certificate_hash.to_string().replace(':', ""); |
||||||
|
|
||||||
|
info!("== Certificate Digest =="); |
||||||
|
info!(" Clients use this to securely connect to the server."); |
||||||
|
info!(" {certificate_digest}"); |
||||||
|
|
||||||
|
Ok(()) |
||||||
|
} |
||||||
|
|
||||||
|
fn on_server_stopped(event: On<Add, Stopped>) { |
||||||
|
let server = event.entity; |
||||||
|
info!("Server '{server}' stopped!"); |
||||||
|
} |
||||||
|
|
||||||
|
fn handle_client_connected( |
||||||
|
event: On<Add, Connected>, |
||||||
|
clients: Query<&LinkOf>, |
||||||
|
mut commands: Commands, |
||||||
|
) -> Result { |
||||||
|
let client = event.entity; |
||||||
|
let server = clients.get(client)?.server; |
||||||
|
info!("Client '{client}' connected to server '{server}'"); |
||||||
|
|
||||||
|
commands.entity(client).insert(ReplicationSender::default()); |
||||||
|
|
||||||
|
Ok(()) |
||||||
|
} |
||||||
|
|
||||||
|
fn handle_client_disconnected(event: On<Add, Disconnected>, clients: Query<&LinkOf>) -> Result { |
||||||
|
let client = event.entity; |
||||||
|
let server = clients.get(client)?.server; |
||||||
|
info!("Client '{client}' disconnected from server '{server}'"); |
||||||
|
Ok(()) |
||||||
|
} |
||||||
Loading…
Reference in new issue