summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/conn.rs104
-rw-r--r--src/lib.rs10
-rw-r--r--src/to_clt.rs18
-rw-r--r--src/to_srv.rs27
4 files changed, 157 insertions, 2 deletions
diff --git a/src/conn.rs b/src/conn.rs
new file mode 100644
index 0000000..3fc0e55
--- /dev/null
+++ b/src/conn.rs
@@ -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(())
+ }
+}
diff --git a/src/lib.rs b/src/lib.rs
index 77538cd..8e134c5 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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);
+}
diff --git a/src/to_clt.rs b/src/to_clt.rs
index 3792018..5f99be3 100644
--- a/src/to_clt.rs
+++ b/src/to_clt.rs
@@ -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),
+ }
+ }
+}
diff --git a/src/to_srv.rs b/src/to_srv.rs
index 704acdb..dc9a342 100644
--- a/src/to_srv.rs
+++ b/src/to_srv.rs
@@ -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),
+ }
+ }
+}