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"),
90 pub type PktResult = Result<Pkt<Vec<u8>>, Error>;
91 type PktSender = mpsc::Sender<PktResult>;
102 packets: Vec<Cell<Option<Vec<u8>>>>, // used to be called char **
107 struct ConnReceiver {
109 inner: Arc<ConnInner>,
110 chans: Vec<RecvChannel>,
111 inbox: [u8; UDP_PKT_SIZE],
115 pub fn run(inner: Arc<ConnInner>, tx: PktSender) {
119 chans: (0..NUM_CHANNELS as u8)
120 .map(|num| RecvChannel {
122 packets: (0..REL_BUFFER).map(|_| Cell::new(None)).collect(),
126 inbox: [0; UDP_PKT_SIZE],
131 fn handle_err(&self, res: Result<(), Error>) -> bool {
132 if let Err(err) = res {
133 if !self.tx.send(Err(err)).is_ok() {
141 fn do_loop(&mut self) {
142 while self.handle_err(self.recv_pkt()) {}
145 fn recv_pkt(&mut self) -> Result<(), Error> {
148 // todo: reset timeout
149 let len = self.inner.sock.recv(&mut self.inbox)?;
150 let mut cursor = io::Cursor::new(&self.inbox[..len]);
152 let proto_id = cursor.read_u32::<BigEndian>()?;
153 if proto_id != PROTO_ID {
154 do yeet InvalidProtoId(proto_id);
157 let peer_id = cursor.read_u16::<BigEndian>()?;
159 let n_channel = cursor.read_u8()?;
160 let mut channel = self
162 .get(n_channel as usize)
163 .ok_or(InvalidChannel(n_channel))?;
165 self.process_pkt(cursor, channel)
168 fn process_pkt(&self, mut cursor: io::Cursor<&[u8]>, chan: &RecvChannel) -> Result<(), Error> {
171 match cursor.read_u8()?.try_into()? {
173 dbg!(cursor.remaining_slice());
176 self.tx.send(Ok(Pkt {
179 data: cursor.remaining_slice().into(),
183 dbg!(cursor.remaining_slice());
186 let seqnum = cursor.read_u16::<BigEndian>()?;
187 chan.packets[seqnum as usize].set(Some(cursor.remaining_slice().into()));
189 while let Some(pkt) = chan.packets[chan.seqnum as usize].take() {
190 self.handle_err(self.process_pkt(io::Cursor::new(&pkt), chan));
191 chan.seqnum.overflowing_add(1);
201 pub fn send(&self, pkt: Pkt<&[u8]>) -> io::Result<()> {
202 let mut buf = Vec::with_capacity(4 + 2 + 1 + 1 + pkt.data.len());
203 buf.write_u32::<BigEndian>(PROTO_ID)?;
204 buf.write_u16::<BigEndian>(self.remote_id)?;
205 buf.write_u8(pkt.chan as u8)?;
206 buf.write_u8(PktType::Orig as u8)?;
207 buf.write(pkt.data)?;
209 self.sock.send(&buf)?;
217 inner: Arc<ConnInner>,
218 rx: mpsc::Receiver<PktResult>,
222 pub fn connect(addr: &str) -> io::Result<Self> {
223 let (tx, rx) = mpsc::channel();
225 let inner = Arc::new(ConnInner {
226 sock: net::UdpSocket::bind("0.0.0.0:0")?,
227 id: PeerID::Srv as u16,
228 remote_id: PeerID::Nil as u16,
229 chans: (0..NUM_CHANNELS).map(|_| Channel {}).collect(),
232 inner.sock.connect(addr)?;
234 let recv_inner = Arc::clone(&inner);
235 thread::spawn(move || {
236 ConnReceiver::run(recv_inner, tx);
239 Ok(Conn { inner, rx })
242 pub fn send(&self, pkt: Pkt<&[u8]>) -> io::Result<()> {
246 pub fn recv(&self) -> Result<PktResult, mpsc::RecvError> {
252 //println!("{}", x.deep_size_of());
253 let conn = Conn::connect("127.0.0.1:30000").expect("the spanish inquisition");
255 let mut mtpkt = vec![];
256 mtpkt.write_u16::<BigEndian>(2).unwrap(); // high level type
257 mtpkt.write_u8(29).unwrap(); // serialize ver
258 mtpkt.write_u16::<BigEndian>(0).unwrap(); // compression modes
259 mtpkt.write_u16::<BigEndian>(40).unwrap(); // MinProtoVer
260 mtpkt.write_u16::<BigEndian>(40).unwrap(); // MaxProtoVer
261 mtpkt.write_u16::<BigEndian>(3).unwrap(); // player name length
262 mtpkt.write(b"foo").unwrap(); // player name
271 while let Ok(result) = conn.recv() {
274 io::stdout().write(pkt.data.as_slice()).unwrap();
276 Err(err) => eprintln!("Error: {}", err),