2 #![feature(cursor_remaining)]
3 use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
4 use num_enum::{TryFromPrimitive, TryFromPrimitiveError};
14 pub const PROTO_ID: u32 = 0x4f457403;
15 pub const UDP_PKT_SIZE: usize = 512;
16 pub const NUM_CHANNELS: usize = 3;
17 pub const REL_BUFFER: usize = 0x8000;
18 pub const INIT_SEQNUM: u16 = 65500;
20 #[derive(Debug, Copy, Clone, PartialEq)]
27 #[derive(Debug, Copy, Clone, PartialEq, TryFromPrimitive)]
53 impl From<io::Error> for Error {
54 fn from(err: io::Error) -> Self {
59 impl From<TryFromPrimitiveError<PktType>> for Error {
60 fn from(err: TryFromPrimitiveError<PktType>) -> Self {
61 Self::InvalidType(err.number)
65 impl From<mpsc::SendError<PktResult>> for Error {
66 fn from(_err: mpsc::SendError<PktResult>) -> Self {
71 impl fmt::Display for Error {
72 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
74 write!(f, "RUDP Error: ")?;
77 IoError(err) => write!(f, "IO Error: {}", err),
78 InvalidProtoId(id) => write!(f, "Invalid Protocol ID: {id}"),
79 InvalidPeerID => write!(f, "Invalid Peer ID"),
80 InvalidChannel(ch) => write!(f, "Invalid Channel: {ch}"),
81 InvalidType(tp) => write!(f, "Invalid Type: {tp}"),
82 LocalHangup => write!(f, "Local packet receiver hung up"),
92 type RelPkt = Cell<Option<Vec<u8>>>;
94 struct RecvChannel<'a> {
95 packets: Vec<RelPkt>, // used to be called char **
100 pub type PktResult = Result<Pkt<Vec<u8>>, Error>;
101 type PktSender = mpsc::Sender<PktResult>;
104 fn handle(&self, res: Result<(), Error>) -> bool;
107 impl HandleError for PktSender {
108 fn handle(&self, res: Result<(), Error>) -> bool {
109 if let Err(err) = res {
110 if !self.send(Err(err)).is_ok() {
119 fn to_seqnum(seqnum: u16) -> usize {
120 (seqnum as usize) & (REL_BUFFER - 1)
125 sock: net::UdpSocket,
132 pub fn send(&self, pkt: Pkt<&[u8]>) -> io::Result<()> {
133 let mut buf = Vec::with_capacity(4 + 2 + 1 + 1 + pkt.data.len());
134 buf.write_u32::<BigEndian>(PROTO_ID)?;
135 buf.write_u16::<BigEndian>(self.remote_id)?;
136 buf.write_u8(pkt.chan as u8)?;
137 buf.write_u8(PktType::Orig as u8)?;
138 buf.write(pkt.data)?;
140 self.sock.send(&buf)?;
145 fn recv_loop(&self, tx: PktSender) {
146 let mut inbox = [0; UDP_PKT_SIZE];
148 let mut recv_chans = self
151 .map(|main| RecvChannel {
153 packets: (0..REL_BUFFER).map(|_| Cell::new(None)).collect(),
158 while tx.handle(self.recv_pkt(&mut inbox, &mut recv_chans, &tx)) {}
164 chans: &mut Vec<RecvChannel>,
166 ) -> Result<(), Error> {
169 // todo: reset timeout
170 let len = self.sock.recv(buffer)?;
171 let mut cursor = io::Cursor::new(&buffer[..len]);
173 let proto_id = cursor.read_u32::<BigEndian>()?;
174 if proto_id != PROTO_ID {
175 do yeet InvalidProtoId(proto_id);
178 let peer_id = cursor.read_u16::<BigEndian>()?;
180 let n_chan = cursor.read_u8()?;
182 .get_mut(n_chan as usize)
183 .ok_or(InvalidChannel(n_chan))?;
185 self.process_pkt(cursor, chan, tx)
190 mut cursor: io::Cursor<&[u8]>,
191 chan: &mut RecvChannel,
193 ) -> Result<(), Error> {
196 match cursor.read_u8()?.try_into()? {
199 dbg!(cursor.remaining_slice());
205 data: cursor.remaining_slice().into(),
210 dbg!(cursor.remaining_slice());
213 let seqnum = cursor.read_u16::<BigEndian>()?;
214 chan.packets[to_seqnum(seqnum)].set(Some(cursor.remaining_slice().into()));
216 while let Some(pkt) = chan.packets[to_seqnum(chan.seqnum)].take() {
217 tx.handle(self.process_pkt(io::Cursor::new(&pkt), chan, tx));
218 chan.seqnum = chan.seqnum.overflowing_add(1).0;
229 inner: Arc<ConnInner>,
230 rx: mpsc::Receiver<PktResult>,
234 pub fn connect(addr: &str) -> io::Result<Self> {
235 let (tx, rx) = mpsc::channel();
237 let inner = Arc::new(ConnInner {
238 sock: net::UdpSocket::bind("0.0.0.0:0")?,
239 id: PeerID::Srv as u16,
240 remote_id: PeerID::Nil as u16,
241 chans: (0..NUM_CHANNELS as u8).map(|num| Channel { num }).collect(),
244 inner.sock.connect(addr)?;
246 let recv_inner = Arc::clone(&inner);
247 thread::spawn(move || {
248 recv_inner.recv_loop(tx);
251 Ok(Conn { inner, rx })
254 pub fn send(&self, pkt: Pkt<&[u8]>) -> io::Result<()> {
258 pub fn recv(&self) -> Result<PktResult, mpsc::RecvError> {
264 //println!("{}", x.deep_size_of());
265 let conn = Conn::connect("127.0.0.1:30000").expect("the spanish inquisition");
267 let mut mtpkt = vec![];
268 mtpkt.write_u16::<BigEndian>(2).unwrap(); // high level type
269 mtpkt.write_u8(29).unwrap(); // serialize ver
270 mtpkt.write_u16::<BigEndian>(0).unwrap(); // compression modes
271 mtpkt.write_u16::<BigEndian>(40).unwrap(); // MinProtoVer
272 mtpkt.write_u16::<BigEndian>(40).unwrap(); // MaxProtoVer
273 mtpkt.write_u16::<BigEndian>(3).unwrap(); // player name length
274 mtpkt.write(b"foo").unwrap(); // player name
283 while let Ok(result) = conn.recv() {
286 io::stdout().write(pkt.data.as_slice()).unwrap();
288 Err(err) => eprintln!("Error: {}", err),