From a4035bdea99831ca5041ccb7f19e38348fdc87eb Mon Sep 17 00:00:00 2001 From: Avii Date: Wed, 12 Mar 2025 11:59:24 +0100 Subject: [PATCH] 'auto' reconnect --- src/main.rs | 107 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 61 insertions(+), 46 deletions(-) diff --git a/src/main.rs b/src/main.rs index 72c5db2..db71b57 100644 --- a/src/main.rs +++ b/src/main.rs @@ -118,8 +118,7 @@ impl FromStr for Message { } } -#[tokio::main] -async fn main() -> Result<()> { +async fn real_main() -> Result<()> { dotenvy::dotenv().ok(); let irc_server = std::env::var("IRC_SERVER")?; @@ -131,6 +130,7 @@ async fn main() -> Result<()> { let mut buffer = String::new(); let stdin = io::stdin(); // We get `Stdin` here. + let (term_tx, term_rx) = tokio::sync::broadcast::channel::<()>(1); let (tx, mut rx) = tokio::sync::mpsc::channel(12); let config = Config { @@ -145,25 +145,16 @@ async fn main() -> Result<()> { client.identify()?; let mut stream = client.stream()?; + let mut term_rx_a = term_rx.resubscribe(); tokio::spawn(async move { - while let Some(msg) = rx.recv().await { - client.send(msg)?; - } - Ok::<(), Error>(()) - }); - - let tx_ = tx.clone(); - tokio::spawn(async move { - while let Some(message) = stream.next().await.transpose()? { - print!("{}", &message); - - if let Command::NOTICE(a, b) = message.command { - if a == "p2000" && b.starts_with("This nickname is registered.") { - tx_.send(Command::NICKSERV(vec![ - "identify".into(), - irc_password.clone(), - ])) - .await?; + loop { + tokio::select! { + Some(msg) = rx.recv() => { + client.send(msg)?; + }, + _ = term_rx_a.recv() => { + eprintln!("Closing irc send loop"); + break; } } } @@ -171,43 +162,67 @@ async fn main() -> Result<()> { Ok::<(), Error>(()) }); - // thread::spawn(move || { - // // irc thread - // let config = rustls::ClientConfig::builder() - // .with_root_certificates(rustls::RootCertStore { - // roots: webpki_roots::TLS_SERVER_ROOTS.into(), - // }) - // .with_no_client_auth(); - // let mut conn = rustls::ClientConnection::new(Arc::new(config), "irc.avii.nl".try_into()?)?; - // let mut socket = std::net::TcpStream::connect("irc.avii.nl:6697")?; - // let mut tls = rustls::Stream::new(&mut conn, &mut socket); + let tx_ = tx.clone(); + let mut term_rx_a = term_rx.resubscribe(); + tokio::spawn(async move { + loop { + tokio::select! { + message = stream.next() => { + let Ok(Some(message)) = message.transpose() else { + return Err("".into()); + }; + print!("{}", message); - // tls.write_all(b"CAP LS 302\r\n")?; - // tls.write_all(b"NICK p2000\r\n")?; - // tls.write_all(b"USER p2000 0 * :p2000\r\n")?; - // tls.write_all(b"CAP END\r\n")?; + if let Command::NOTICE(a, b) = message.command { + if a == "p2000" && b.starts_with("This nickname is registered.") { + tx_.send(Command::NICKSERV(vec![ + "identify".into(), + irc_password.clone(), + ])) + .await?; + } + } + }, + _ = term_rx_a.recv() => { + eprintln!("Closing irc receiver loop"); + break; + } + } + } - // tls.write_all(b"JOIN #p2000\r\n")?; + Ok::<(), Error>(()) + }); - // while let Ok(msg) = rx.recv() { - // dbg!(&msg); - // tls.write_all(format!("PRIVMSG #p2000 :{}\r\n", msg).as_bytes())?; - // } - - // Ok::<(), Error>(()) - // }); - - while stdin.read_line(&mut buffer)? > 0 { + 'outer: while stdin.read_line(&mut buffer)? > 0 { if let Ok(msg) = Message::from_str(&buffer) { for msg in msg.to_string().lines() { println!("{}", msg); - let _ = tx + if let Err(e) = tx .send(Command::PRIVMSG("#p2000".to_string(), msg.to_string())) - .await; + .await + { + // shut everything down, we need to reconnect/restart + eprintln!("{:?}", e); + let _ = term_tx.send(()); + break 'outer; + }; } } buffer.clear(); } + eprintln!("End of program..."); + Ok(()) } + +#[tokio::main] +async fn main() -> Result<()> { + loop { + if let Err(e) = real_main().await { + eprintln!("{:?}", e); + continue; + } + eprintln!("Restarting..."); + } +}