]> git.lizzy.rs Git - mt_net.git/commitdiff
Add wrappers around mt_rudp
authorLizzy Fleckenstein <eliasfleckenstein@web.de>
Wed, 15 Feb 2023 22:44:21 +0000 (23:44 +0100)
committerLizzy Fleckenstein <eliasfleckenstein@web.de>
Wed, 15 Feb 2023 22:54:40 +0000 (23:54 +0100)
Cargo.toml
src/conn.rs [new file with mode: 0644]
src/lib.rs
src/to_clt.rs
src/to_srv.rs

index afbc3e4998da34ff4b76cb651608280b9232669e..0d822927f8afb68a02f5e52d51959e23f10d195f 100644 (file)
@@ -4,20 +4,24 @@ version = "0.1.0"
 edition = "2021"
 
 [features]
-all = ["client", "server", "random", "serde"]
+all = ["client", "server", "random", "serde", "conn"]
 client = []
+conn = ["dep:mt_rudp", "dep:thiserror"]
 random = ["dep:generate-random", "dep:rand"]
 serde = ["dep:serde", "dep:serde_arrays", "enumset/serde"]
 server = []
 test = ["client", "server", "random"]
 
 [dependencies]
+delegate = "0.9.0"
 enumset = { git = "https://github.com/Lymia/enumset" }
 generate-random = { git = "https://github.com/minetest-rust/generate-random", features = ["enumset"], optional = true }
+mt_rudp = { git = "https://github.com/minetest-rust/mt_rudp", optional = true }
 mt_ser = { git = "https://github.com/minetest-rust/mt_ser" }
 rand = { version = "0.8.5", optional = true }
 serde = { version = "1.0.152", features = ["derive"], optional = true }
 serde_arrays = { version = "0.1.0", optional = true }
+thiserror = { version = "1.0.38", optional = true }
 
 [dev-dependencies]
 libtest-mimic = "0.6.0"
diff --git a/src/conn.rs b/src/conn.rs
new file mode 100644 (file)
index 0000000..3fc0e55
--- /dev/null
@@ -0,0 +1,104 @@
+use super::PktInfo;
+use delegate::delegate;
+use mt_ser::{DefCfg, MtDeserialize, MtSerialize};
+use std::{borrow::Cow, io};
+use thiserror::Error;
+
+pub trait Remote {
+    type UdpSender: mt_rudp::UdpSender;
+    type PktFrom: MtDeserialize;
+    type PktTo: MtSerialize + PktInfo;
+}
+
+#[cfg(feature = "client")]
+pub struct RemoteSrv;
+
+#[cfg(feature = "client")]
+impl Remote for RemoteSrv {
+    type UdpSender = mt_rudp::ToSrv;
+    type PktTo = crate::ToSrvPkt;
+    type PktFrom = crate::ToCltPkt;
+}
+
+#[cfg(feature = "client")]
+pub async fn connect(addr: &str) -> io::Result<(MtSender<RemoteSrv>, MtReceiver<RemoteSrv>)> {
+    let (tx, rx) = mt_rudp::connect(addr).await?;
+    Ok((MtSender(tx), MtReceiver(rx)))
+}
+
+/*
+
+pub struct RemoteClt;
+impl Remote for RemoteClt {
+    type Sender = mt_rudp::ToClt;
+    type To = crate::ToCltPkt;
+    type From = crate::ToSrvPkt;
+}
+
+*/
+
+pub struct MtSender<R: Remote>(pub mt_rudp::RudpSender<R::UdpSender>);
+pub struct MtReceiver<R: Remote>(pub mt_rudp::RudpReceiver<R::UdpSender>);
+
+#[derive(Error, Debug)]
+pub enum RecvError {
+    #[error("connection error: {0}")]
+    ConnError(#[from] mt_rudp::Error),
+    #[error("deserialize error: {0}")]
+    DeserializeError(#[from] mt_ser::DeserializeError),
+}
+
+#[derive(Error, Debug)]
+pub enum SendError {
+    #[error("connection error: {0}")]
+    ConnError(#[from] io::Error),
+    #[error("serialize error: {0}")]
+    SerializeError(#[from] mt_ser::SerializeError),
+}
+
+macro_rules! impl_delegate {
+    ($T:ident) => {
+        impl<R: Remote> $T<R> {
+            delegate! {
+                to self.0 {
+                    pub async fn peer_id(&self) -> u16;
+                    pub async fn is_server(&self) -> bool;
+                    pub async fn close(self);
+                }
+            }
+        }
+    };
+}
+
+impl_delegate!(MtSender);
+impl_delegate!(MtReceiver);
+
+impl<R: Remote> MtReceiver<R> {
+    pub async fn recv(&mut self) -> Option<Result<R::PktFrom, RecvError>> {
+        self.0.recv().await.map(|res| {
+            res.map_err(RecvError::from).and_then(|pkt| {
+                // TODO: warn on trailing data
+                R::PktFrom::mt_deserialize::<DefCfg>(&mut io::Cursor::new(pkt.data))
+                    .map_err(RecvError::from)
+            })
+        })
+    }
+}
+
+impl<R: Remote> MtSender<R> {
+    pub async fn send(&self, pkt: &R::PktTo) -> Result<(), SendError> {
+        let mut writer = Vec::new();
+        pkt.mt_serialize::<DefCfg>(&mut writer)?;
+
+        let (chan, unrel) = pkt.pkt_info();
+        self.0
+            .send(mt_rudp::Pkt {
+                chan,
+                unrel,
+                data: Cow::Borrowed(&writer),
+            })
+            .await?;
+
+        Ok(())
+    }
+}
index 77538cd2943b7036e28d6b8868cc67a27c1c8973..8e134c514bb2cc369af5fe531ab3baf79e7bdb40 100644 (file)
@@ -29,8 +29,18 @@ use generate_random::GenerateRandom;
 #[cfg(feature = "serde")]
 use serde::{Deserialize, Serialize};
 
+#[cfg(feature = "conn")]
+mod conn;
+
+#[cfg(feature = "conn")]
+pub use conn::*;
+
 mod to_clt;
 mod to_srv;
 
 pub use to_clt::*;
 pub use to_srv::*;
+
+pub trait PktInfo {
+    fn pkt_info(&self) -> (u8, bool);
+}
index 3792018a305b6062952bc676e653fa4fddc36e93..5f99be31775e273bf79930809697d230dc2598a8 100644 (file)
@@ -285,7 +285,7 @@ pub enum ToCltPkt {
         flags: EnumSet<HudFlag>,
         mask: EnumSet<HudFlag>,
     } = 76,
-    SetHotbarParam(HotbarParam) = 77,
+    HotbarParam(HotbarParam) = 77,
     Breath {
         breath: u16,
     } = 78,
@@ -345,3 +345,19 @@ pub enum ToCltPkt {
     } = 97,
     MinimapModes(MinimapModesPkt) = 98,
 }
+
+impl PktInfo for ToCltPkt {
+    fn pkt_info(&self) -> (u8, bool) {
+        use ToCltPkt::*;
+
+        match self {
+            BlockData { .. } | Media { .. } => (2, true),
+            AddHud { .. }
+            | ChangeHud { .. }
+            | RemoveHud { .. }
+            | HudFlags { .. }
+            | HotbarParam(_) => (1, true),
+            _ => (0, true),
+        }
+    }
+}
index 704acdb78e111c040339047f99b362a866bc2256..dc9a34210d9843f6903a0171c232a006d21204e6 100644 (file)
@@ -77,6 +77,10 @@ pub enum ToSrvPkt {
         #[mt(len = "u8")]
         blocks: Vec<[i16; 3]>,
     } = 37,
+    HaveMedia {
+        #[mt(len = "u8")]
+        tokens: Vec<u32>,
+    } = 41,
     InvAction {
         #[mt(len = "()")]
         action: String,
@@ -113,7 +117,7 @@ pub enum ToSrvPkt {
         #[mt(len = "(DefCfg, (DefCfg, u32))")]
         fields: HashMap<String, String>,
     } = 60,
-    ReqMedia {
+    RequestMedia {
         filenames: Vec<String>,
     } = 64,
     CltReady {
@@ -138,3 +142,24 @@ pub enum ToSrvPkt {
     } = 82,
     Disco = 0xffff,
 }
+
+impl PktInfo for ToSrvPkt {
+    fn pkt_info(&self) -> (u8, bool) {
+        use ToSrvPkt::*;
+
+        match self {
+            Init { .. } => (1, false),
+            Init2 { .. }
+            | RequestMedia { .. }
+            | CltReady { .. }
+            | FirstSrp { .. }
+            | SrpBytesA { .. }
+            | SrpBytesM { .. } => (1, true),
+            PlayerPos { .. } => (0, false),
+            GotBlocks { .. } | HaveMedia { .. } | DeletedBlocks { .. } | RemovedSounds { .. } => {
+                (2, true)
+            }
+            _ => (0, true),
+        }
+    }
+}