1 use mt_net::{MtReceiver, MtSender, RemoteSrv, ToCltPkt, ToSrvPkt};
4 use srp::{client::SrpClient, groups::G_2048};
5 use std::time::Duration;
6 use tokio::sync::oneshot;
8 async fn handle(tx: MtSender<RemoteSrv>, rx: &mut MtReceiver<RemoteSrv>) {
9 let mut username = "hydra".to_string();
10 let password = "password";
12 let (init_tx, mut init_rx) = oneshot::channel();
16 let pkt = ToSrvPkt::Init {
17 serialize_version: 29,
18 min_proto_version: 40,
19 max_proto_version: 40,
20 player_name: username.clone(),
21 send_full_item_meta: false,
24 tokio::spawn(async move {
25 let mut interval = tokio::time::interval(Duration::from_millis(100));
26 while tokio::select! {
27 _ = &mut init_rx => false,
28 _ = interval.tick() => true,
30 tx.send(&pkt).await.unwrap()
35 let mut init_tx = Some(init_tx);
38 while let Some(res) = rx.recv().await {
49 use mt_net::AuthMethod;
51 if let Some(chan) = init_tx.take() {
52 chan.send(()).unwrap();
54 let client = SrpClient::<Sha256>::new(&G_2048);
56 let mut rand_bytes = vec![0; 32];
57 rand::thread_rng().fill_bytes(&mut rand_bytes);
61 if auth_methods.contains(AuthMethod::FirstSrp) {
62 let verifier = client.compute_verifier(
63 username.to_lowercase().as_bytes(),
68 tx.send(&ToSrvPkt::FirstSrp {
71 empty_passwd: password.is_empty(),
75 } else if auth_methods.contains(AuthMethod::Srp) {
76 let a = client.compute_public_ephemeral(&rand_bytes);
77 auth = Some((rand_bytes, client));
79 tx.send(&ToSrvPkt::SrpBytesA { a, no_sha1: true })
83 panic!("unsupported auth methods: {auth_methods:?}");
87 SrpBytesSaltB { salt, b } => {
88 if let Some((a, client)) = auth.take() {
92 username.to_lowercase().as_bytes(),
101 tx.send(&ToSrvPkt::SrpBytesM { m }).await.unwrap();
104 x => println!("{x:?}"),
107 Err(err) => eprintln!("{err}"),
114 let (tx, mut rx) = mt_net::connect("localhost:30000").await.unwrap();
117 _ = tokio::signal::ctrl_c() => println!("canceled"),
118 _ = handle(tx, &mut rx) => {
119 println!("disconnected");