-use mt_net::{MtReceiver, MtSender, RemoteSrv, ToCltPkt, ToSrvPkt};
-use rand::RngCore;
-use sha2::Sha256;
-use srp::{client::SrpClient, groups::G_2048};
-use std::time::Duration;
-use tokio::sync::oneshot;
-
-async fn handle(tx: MtSender<RemoteSrv>, rx: &mut MtReceiver<RemoteSrv>) {
- let mut username = "hydra".to_string();
- let password = "password";
-
- let (init_tx, mut init_rx) = oneshot::channel();
-
- {
- let tx = tx.clone();
- let pkt = ToSrvPkt::Init {
- serialize_version: 29,
- min_proto_version: 40,
- max_proto_version: 40,
- player_name: username.clone(),
- send_full_item_meta: false,
- };
-
- tokio::spawn(async move {
- let mut interval = tokio::time::interval(Duration::from_millis(100));
- while tokio::select! {
- _ = &mut init_rx => false,
- _ = interval.tick() => true,
- } {
- tx.send(&pkt).await.unwrap()
- }
- });
- }
-
- let mut init_tx = Some(init_tx);
- let mut auth = None;
-
- while let Some(res) = rx.recv().await {
- match res {
- Ok(pkt) => {
- use ToCltPkt::*;
-
- match pkt {
- Hello {
- auth_methods,
- username: name,
- ..
- } => {
- use mt_net::AuthMethod;
-
- if let Some(chan) = init_tx.take() {
- chan.send(()).unwrap();
-
- let client = SrpClient::<Sha256>::new(&G_2048);
-
- let mut rand_bytes = vec![0; 32];
- rand::thread_rng().fill_bytes(&mut rand_bytes);
-
- username = name;
+mod gfx;
+mod net;
+
+use cgmath::{Deg, Point3};
+use std::collections::HashMap;
+use tokio::sync::mpsc;
+
+#[derive(Debug, Clone)]
+pub enum GfxEvent {
+ Close,
+ Media(HashMap<String, Vec<u8>>, bool),
+ NodeDefs(HashMap<u16, mt_net::NodeDef>),
+ MapBlock(Point3<i16>, Box<mt_net::MapBlock>),
+ PlayerPos(Point3<f32>, Deg<f32>, Deg<f32>),
+}
- if auth_methods.contains(AuthMethod::FirstSrp) {
- let verifier = client.compute_verifier(
- username.to_lowercase().as_bytes(),
- password.as_bytes(),
- &rand_bytes,
- );
+#[derive(Debug, Clone)]
+pub enum NetEvent {
+ PlayerPos(Point3<f32>, Deg<f32>, Deg<f32>),
+ Ready,
+}
- tx.send(&ToSrvPkt::FirstSrp {
- salt: rand_bytes,
- verifier,
- empty_passwd: password.is_empty(),
- })
- .await
- .unwrap();
- } else if auth_methods.contains(AuthMethod::Srp) {
- let a = client.compute_public_ephemeral(&rand_bytes);
- auth = Some((rand_bytes, client));
+fn main() {
+ println!(include_str!("../assets/ascii-art.txt"));
+ println!("Early WIP. Expext breakage. Trans rights <3");
- tx.send(&ToSrvPkt::SrpBytesA { a, no_sha1: true })
- .await
- .unwrap();
- } else {
- panic!("unsupported auth methods: {auth_methods:?}");
- }
- }
- }
- SrpBytesSaltB { salt, b } => {
- if let Some((a, client)) = auth.take() {
- let m = client
- .process_reply(
- &a,
- username.to_lowercase().as_bytes(),
- password.as_bytes(),
- &salt,
- &b,
- )
- .unwrap()
- .proof()
- .into();
+ let (net_tx, net_rx) = mpsc::unbounded_channel();
+ let event_loop = winit::event_loop::EventLoopBuilder::<GfxEvent>::with_user_event().build();
+ let event_loop_proxy = event_loop.create_proxy();
- tx.send(&ToSrvPkt::SrpBytesM { m }).await.unwrap();
- }
- }
- x => println!("{x:?}"),
- }
- }
- Err(err) => eprintln!("{err}"),
- }
- }
-}
+ let runtime = tokio::runtime::Builder::new_multi_thread()
+ .enable_io()
+ .enable_time()
+ .thread_name("network")
+ .build()
+ .unwrap();
-#[tokio::main]
-async fn main() {
- let (tx, mut rx) = mt_net::connect("localhost:30000").await.unwrap();
+ let net_thread = runtime.spawn(net::run(event_loop_proxy, net_rx));
- tokio::select! {
- _ = tokio::signal::ctrl_c() => println!("canceled"),
- _ = handle(tx, &mut rx) => {
- println!("disconnected");
- }
- }
+ // graphics code is pseudo async: the winit event loop is blocking
+ // so we can't really use async capabilities
+ futures::executor::block_on(gfx::run(event_loop, net_tx));
- rx.close().await;
+ // wait for net to finish
+ runtime.block_on(net_thread).unwrap();
}