This also means that the peer can be started up before the main game
This commit is contained in:
parent
293ccf9370
commit
cceca83dac
1 changed files with 50 additions and 12 deletions
|
@ -1,21 +1,21 @@
|
||||||
use std::net::SocketAddr;
|
use std::{net::SocketAddr, time::Duration};
|
||||||
|
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
|
|
||||||
use crate::game::prelude::Seed;
|
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
queues::{NetworkReceive, NetworkSend},
|
queues::{NetworkReceive, NetworkSend},
|
||||||
socket::bind_socket,
|
socket::bind_socket,
|
||||||
};
|
};
|
||||||
|
use crate::game::prelude::Seed;
|
||||||
|
|
||||||
fn handle_network_io(
|
fn handle_network_input(
|
||||||
receive: Res<NetworkReceive>,
|
receive: Res<NetworkReceive>,
|
||||||
send: Res<NetworkSend>,
|
send: Res<NetworkSend>,
|
||||||
seed: Option<Res<Seed>>,
|
seed: Option<Res<Seed>>,
|
||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
) -> Result {
|
) -> Result {
|
||||||
for (message, address) in receive.iter() {
|
for (message, address) in receive.iter() {
|
||||||
|
// Temporary logic just for initial connection, if there is already a seed then the peer wants it
|
||||||
if let Some(ref value) = seed {
|
if let Some(ref value) = seed {
|
||||||
send.send((**value).into(), address)?;
|
send.send((**value).into(), address)?;
|
||||||
} else {
|
} else {
|
||||||
|
@ -26,6 +26,25 @@ fn handle_network_io(
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const TIMEOUT: Duration = Duration::from_secs(5);
|
||||||
|
|
||||||
|
fn heartbeat(
|
||||||
|
peers: Query<(&Peer, &mut PeerSendTiming)>,
|
||||||
|
send: Res<NetworkSend>,
|
||||||
|
time: Res<Time>,
|
||||||
|
) -> Result {
|
||||||
|
for (peer, ref mut last) in peers {
|
||||||
|
if let Some(previous) = last.timestamp {
|
||||||
|
if previous + TIMEOUT > time.elapsed() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
send.send(Vec::new(), peer.addr)?;
|
||||||
|
last.timestamp = Some(time.elapsed());
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(States, Default, Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(States, Default, Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
enum NetworkState {
|
enum NetworkState {
|
||||||
#[default]
|
#[default]
|
||||||
|
@ -33,6 +52,28 @@ enum NetworkState {
|
||||||
MultiPlayer,
|
MultiPlayer,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Component, Debug, Default)]
|
||||||
|
struct PeerSendTiming {
|
||||||
|
timestamp: Option<Duration>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Component, Debug, Default)]
|
||||||
|
struct PeerReceiveTiming {
|
||||||
|
timestamp: Option<Duration>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Component, Debug)]
|
||||||
|
#[require(PeerSendTiming, PeerReceiveTiming)]
|
||||||
|
struct Peer {
|
||||||
|
addr: SocketAddr,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Peer {
|
||||||
|
fn new(addr: SocketAddr) -> Self {
|
||||||
|
Self { addr }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct NetIOPlugin {
|
pub struct NetIOPlugin {
|
||||||
listen: u16,
|
listen: u16,
|
||||||
peer: Option<SocketAddr>,
|
peer: Option<SocketAddr>,
|
||||||
|
@ -48,21 +89,18 @@ impl Plugin for NetIOPlugin {
|
||||||
fn build(&self, app: &mut App) {
|
fn build(&self, app: &mut App) {
|
||||||
app.init_state::<NetworkState>().add_systems(
|
app.init_state::<NetworkState>().add_systems(
|
||||||
FixedUpdate,
|
FixedUpdate,
|
||||||
handle_network_io.run_if(in_state(NetworkState::MultiPlayer)),
|
(handle_network_input, heartbeat).run_if(in_state(NetworkState::MultiPlayer)),
|
||||||
);
|
);
|
||||||
|
|
||||||
match bind_socket(self.listen) {
|
match bind_socket(self.listen) {
|
||||||
Ok((send, receive)) => {
|
Ok((send, receive)) => {
|
||||||
if let Some(socket) = self.peer {
|
|
||||||
if let Err(err) = send.try_send((Vec::new(), socket)) {
|
|
||||||
warn!("Failed to send to peer: {err}");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
app.insert_state(NetworkState::MultiPlayer)
|
app.insert_state(NetworkState::MultiPlayer)
|
||||||
.insert_resource(NetworkSend::new(send))
|
.insert_resource(NetworkSend::new(send))
|
||||||
.insert_resource(NetworkReceive::new(receive));
|
.insert_resource(NetworkReceive::new(receive));
|
||||||
|
|
||||||
|
if let Some(socket) = self.peer {
|
||||||
|
app.world_mut().spawn(Peer::new(socket));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
warn!("Failed to set up networking: {err}");
|
warn!("Failed to set up networking: {err}");
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue