1use std::time::Duration;
6use tokio::{sync::oneshot, time::sleep};
7
8use sfn_tpn::{Config, NetcodeInterface};
9
10fn is_client() -> Result<bool, String> {
18 let mut is_client = false;
19 let mut is_server = false;
20 for arg in std::env::args() {
21 if arg == "client" {
22 is_client = true;
23 }
24 if arg == "server" {
25 is_server = true;
26 }
27 }
28 if is_client && is_server {
29 Err("This process cannot be both the client and the server.".to_string())
30 } else {
31 Ok(is_client)
32 }
33}
34
35fn ticket() -> Result<String, String> {
37 for arg in std::env::args() {
38 if let Some(("--ticket", t)) = arg.split_once("=") {
39 return Ok(t.to_string());
40 }
41 }
42
43 Err("No ticket provided. Clients must provide a ticket to find a server.".to_string())
44}
45
46async fn wait_for<A, T>(f: fn(&mut A) -> Result<T, ()>, a: &mut A) -> T {
48 loop {
49 if let Ok(t) = f(a) {
50 return t;
51 }
52 sleep(Duration::from_secs(1)).await;
53 }
54}
55
56#[tokio::main]
57async fn main() -> Result<(), String> {
58 if is_client()? {
59 let mut netcode = NetcodeInterface::new(Config::Ticket(ticket()?));
61 netcode.send_turn(b"ping");
62 println!("Client sent ping");
63
64 assert_eq!(
65 b"pong",
66 &wait_for(NetcodeInterface::try_recv_turn, &mut netcode).await
67 );
68 println!("Client recieved pong");
69
70 let mut counter = 0;
71
72 loop {
73 let bytes = [0, 0, 0, counter];
74 netcode.send_turn(&bytes);
75 println!("Client sent {bytes:?}");
76
77 assert_eq!(
78 &bytes,
79 &wait_for(NetcodeInterface::try_recv_turn, &mut netcode).await
80 );
81 println!("Client got {bytes:?} back");
82
83 counter += 1;
84 }
85 } else {
86 let (send, recv) = oneshot::channel();
88 let mut netcode = NetcodeInterface::new(Config::TicketSender(send));
89
90 println!(
91 "hosting ping_echo. another player may join with \n\n\
92 cargo run --example ping_echo client --ticket={}",
93 recv.await.unwrap()
94 );
95
96 assert_eq!(
97 b"ping",
98 &wait_for(NetcodeInterface::try_recv_turn, &mut netcode).await
99 );
100 println!("Server received ping");
101
102 netcode.send_turn(b"pong");
103 println!("Server sent pong");
104
105 loop {
106 let bytes = wait_for(NetcodeInterface::try_recv_turn, &mut netcode).await;
107 println!("Server received: {:?}", &bytes);
108
109 netcode.send_turn(&bytes);
110 println!("Server echoed");
111
112 sleep(Duration::from_secs(1)).await;
113 }
114 }
115}