Implement very basic and bad and specific netcode
All checks were successful
CI / Formatting (push) Successful in 1m14s

The game can now retrieve its seed from another game on the network
This commit is contained in:
Michael Bradley 2025-05-25 00:54:16 -04:00
parent 50ef78f7aa
commit dad37262a5
Signed by: MichaelBradley
SSH key fingerprint: SHA256:o/aaeYtRubILK7OYYjYP12DmU7BsPUhKji1AgaQ+ge4
7 changed files with 116 additions and 5 deletions

94
src/net.rs Normal file
View file

@ -0,0 +1,94 @@
use std::{
net::{Ipv6Addr, SocketAddr, UdpSocket},
thread,
};
use bevy::prelude::*;
use crossbeam_channel::{Receiver, Sender, unbounded};
use crate::game::seed::Seed;
#[derive(Resource)]
pub struct NetworkSend(Sender<(u64, SocketAddr)>);
#[derive(Resource)]
pub struct NetworkReceive(Receiver<(u64, SocketAddr)>);
fn handle_network_io(
receive: Res<NetworkReceive>,
send: Res<NetworkSend>,
seed: Option<Res<Seed>>,
mut commands: Commands,
) -> Result {
let Ok((message, address)) = receive.0.try_recv() else {
return Ok(());
};
if let Some(value) = seed {
send.0.try_send((value.clone().into(), address))?;
} else {
commands.insert_resource::<Seed>(message.into());
}
Ok(())
}
pub struct NetIOPlugin {
listen: u16,
peer: Option<SocketAddr>,
}
impl NetIOPlugin {
pub fn new(listen: u16, peer: Option<SocketAddr>) -> Self {
Self { listen, peer }
}
}
impl Plugin for NetIOPlugin {
fn build(&self, app: &mut App) {
app.add_systems(FixedUpdate, handle_network_io);
let (send, receive) = match UdpSocket::bind((Ipv6Addr::LOCALHOST, self.listen)) {
Ok(socket) => {
socket.set_read_timeout(None).unwrap();
socket.set_write_timeout(None).unwrap();
let (send_outbound, receive_outbound) = unbounded::<(u64, SocketAddr)>();
let send_socket = socket.try_clone().unwrap();
thread::spawn(move || {
loop {
match receive_outbound.recv() {
Ok((message, address)) => send_socket
.send_to(&message.to_le_bytes(), address)
.unwrap(),
Err(err) => {
error!("{err}");
break;
}
};
}
});
let (send_inbound, receive_inbound) = unbounded::<(u64, SocketAddr)>();
thread::spawn(move || {
loop {
let mut message = [0u8; 8];
let (len, address) = socket.recv_from(&mut message).unwrap();
info!("Received {len} bytes");
send_inbound
.try_send((u64::from_le_bytes(message), address))
.unwrap();
}
});
(send_outbound, receive_inbound)
}
Err(err) => {
error!("Could not bind socket: {err}");
todo!("bounded(0) is apparently meaningful so find another solution")
}
};
if let Some(socket) = self.peer {
send.try_send((0, socket)).unwrap();
}
app.insert_resource(NetworkSend(send));
app.insert_resource(NetworkReceive(receive));
}
}