use iroh::Watcher;
use iroh::{Endpoint, NodeAddr};
use iroh_base::ticket::NodeTicket;
use std::str::FromStr;
use tokio::sync::mpsc::{Receiver, Sender};
use crate::Config;
pub const ALPN: &[u8] = b"saffron/sfn-tpn/0";
pub async fn start_iroh_protocol<const SIZE: usize>(
send_to_game: Sender<[u8; SIZE]>,
mut recv_from_game: Receiver<[u8; SIZE]>,
config: Config,
) {
println!("started iroh protocol in new thread");
match config {
Config::Ticket(t) => {
let client_endpoint = Endpoint::builder().discovery_n0().bind().await.unwrap();
let host_addr = NodeAddr::from(
NodeTicket::from_str(&t).expect("The nodeticket could not be parsed"),
);
println!("trying to connect to host...");
let conn = client_endpoint.connect(host_addr, ALPN).await.unwrap();
let (mut send, mut recv) = conn.open_bi().await.unwrap();
println!("client opened bi-stream");
loop {
send.write_all(&recv_from_game.recv().await.unwrap())
.await
.unwrap();
let mut buf = [0; SIZE];
recv.read_exact(&mut buf).await.unwrap();
send_to_game
.try_send(buf)
.expect("we should never have a full buffer");
}
}
Config::TicketSender(sender) => {
let host_endpoint = Endpoint::builder()
.discovery_n0()
.alpns(vec![ALPN.to_vec()])
.bind()
.await
.unwrap();
sender
.send(
NodeTicket::new(host_endpoint.node_addr().initialized().await.unwrap())
.to_string(),
)
.unwrap();
match host_endpoint.accept().await {
Some(incoming) => {
let connection = incoming.await.unwrap();
let node_id = connection.remote_node_id().unwrap();
println!("accepted connection from {node_id}");
let (mut send, mut recv) = connection.accept_bi().await.unwrap();
loop {
let mut buf = [0; SIZE];
recv.read_exact(&mut buf).await.unwrap();
send_to_game
.try_send(buf)
.expect("we should never have a full buffer");
send.write_all(&recv_from_game.recv().await.unwrap())
.await
.unwrap();
}
}
None => todo!(),
}
}
}
}