diff options
| author | mat <27899617+mat-1@users.noreply.github.com> | 2023-09-21 11:16:29 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-09-21 11:16:29 -0500 |
| commit | 7b3e2e4bf793466a351510c7fbbd08234e93bb0e (patch) | |
| tree | 7177a919de9982d9e3c7f36a76d2025696f465b6 /azalea-protocol/src/read.rs | |
| parent | 83cce236145cdab1872a472a70943b669a880965 (diff) | |
| download | azalea-drasl-7b3e2e4bf793466a351510c7fbbd08234e93bb0e.tar.xz | |
1.20.2 (#99)
* add configuration state
* start updating to 23w31a
* implement a bit more of 23w31a
* chunk batching
* start adding configuration state
* ioasfhjgsd
* almost works
* configuration state mostly implemented
* handle other packets in configuration state and fix keepalive
* cleanup, fix warnings
* 23w32a
* fix some doctests
* 23w33a
* 23w35a
* 1.20.2-pre2
* fix system conflicts
* 1.20.2-pre4
* make tests compile
* tests pass
* 1.20.2-rc2
* 1.20.2
* Revert "1.20.2"
This reverts commit dd152fd265332ead333c919e585ded6d609d7468.
* didn't mean to commit that code
---------
Co-authored-by: mat <git@matdoes.dev>
Diffstat (limited to 'azalea-protocol/src/read.rs')
| -rwxr-xr-x | azalea-protocol/src/read.rs | 136 |
1 files changed, 93 insertions, 43 deletions
diff --git a/azalea-protocol/src/read.rs b/azalea-protocol/src/read.rs index bffb22bd..4002f4cb 100755 --- a/azalea-protocol/src/read.rs +++ b/azalea-protocol/src/read.rs @@ -127,7 +127,7 @@ fn frame_splitter(buffer: &mut BytesMut) -> Result<Option<Vec<u8>>, FrameSplitte Ok(None) } -fn packet_decoder<P: ProtocolPacket + Debug>( +pub fn deserialize_packet<P: ProtocolPacket + Debug>( stream: &mut Cursor<&[u8]>, ) -> Result<P, Box<ReadPacketError>> { // Packet ID @@ -216,71 +216,123 @@ pub async fn read_packet<'a, P: ProtocolPacket + Debug, R>( where R: AsyncRead + std::marker::Unpin + std::marker::Send + std::marker::Sync, { - let mut framed = FramedRead::new(stream, BytesCodec::new()); + let raw_packet = read_raw_packet(stream, buffer, compression_threshold, cipher).await?; + let packet = deserialize_packet(&mut Cursor::new(raw_packet.as_slice()))?; + Ok(packet) +} + +/// Try to read a single packet from a stream. Returns None if we haven't +/// received a full packet yet. +pub fn try_read_packet<P: ProtocolPacket + Debug, R>( + stream: &mut R, + buffer: &mut BytesMut, + compression_threshold: Option<u32>, + cipher: &mut Option<Aes128CfbDec>, +) -> Result<Option<P>, Box<ReadPacketError>> +where + R: AsyncRead + Unpin + Send + Sync, +{ + let Some(raw_packet) = try_read_raw_packet(stream, buffer, compression_threshold, cipher)? + else { + return Ok(None); + }; + let packet = deserialize_packet(&mut Cursor::new(raw_packet.as_slice()))?; + Ok(Some(packet)) +} + +pub async fn read_raw_packet<'a, R>( + stream: &'a mut R, + buffer: &mut BytesMut, + compression_threshold: Option<u32>, + cipher: &mut Option<Aes128CfbDec>, +) -> Result<Vec<u8>, Box<ReadPacketError>> +where + R: AsyncRead + std::marker::Unpin + std::marker::Send + std::marker::Sync, +{ loop { - if let Some(buf) = try_process_buffer::<P, R>(buffer, compression_threshold)? { + if let Some(buf) = read_raw_packet_from_buffer::<R>(buffer, compression_threshold)? { // we got a full packet!! return Ok(buf); }; - // if we were given a cipher, decrypt the packet - if let Some(message) = framed.next().await { - let mut bytes = message.map_err(ReadPacketError::from)?; - - if let Some(cipher) = cipher { - azalea_crypto::decrypt_packet(cipher, &mut bytes); - } - - buffer.extend_from_slice(&bytes); - } else { - return Err(Box::new(ReadPacketError::ConnectionClosed)); - }; + let bytes = read_and_decrypt_frame(stream, cipher).await?; + buffer.extend_from_slice(&bytes); } } - -/// Try to read a single packet from a stream. Returns None if we haven't -/// received a full packet yet. -pub fn try_read_packet<P: ProtocolPacket + Debug, R>( +pub fn try_read_raw_packet<R>( stream: &mut R, buffer: &mut BytesMut, compression_threshold: Option<u32>, cipher: &mut Option<Aes128CfbDec>, -) -> Result<Option<P>, Box<ReadPacketError>> +) -> Result<Option<Vec<u8>>, Box<ReadPacketError>> where R: AsyncRead + std::marker::Unpin + std::marker::Send + std::marker::Sync, { - let mut framed = FramedRead::new(stream, BytesCodec::new()); loop { - if let Some(buf) = try_process_buffer::<P, R>(buffer, compression_threshold)? { + if let Some(buf) = read_raw_packet_from_buffer::<R>(buffer, compression_threshold)? { // we got a full packet!! return Ok(Some(buf)); }; + let Some(bytes) = try_read_and_decrypt_frame(stream, cipher)? else { + // no data received + return Ok(None); + }; + // we got some data, so add it to the buffer and try again + buffer.extend_from_slice(&bytes); + } +} - // if we were given a cipher, decrypt the packet - if let Some(message) = future::block_on(future::poll_once(framed.next())) { - if let Some(message) = message { - let mut bytes = message.map_err(ReadPacketError::from)?; +async fn read_and_decrypt_frame<R>( + stream: &mut R, + cipher: &mut Option<Aes128CfbDec>, +) -> Result<BytesMut, Box<ReadPacketError>> +where + R: AsyncRead + Unpin + Send + Sync, +{ + let mut framed = FramedRead::new(stream, BytesCodec::new()); - if let Some(cipher) = cipher { - azalea_crypto::decrypt_packet(cipher, &mut bytes); - } + let Some(message) = framed.next().await else { + return Err(Box::new(ReadPacketError::ConnectionClosed)); + }; + let mut bytes = message.map_err(ReadPacketError::from)?; - buffer.extend_from_slice(&bytes); - } else { - return Err(Box::new(ReadPacketError::ConnectionClosed)); - } - } else { - return Ok(None); - }; + // decrypt if necessary + if let Some(cipher) = cipher { + azalea_crypto::decrypt_packet(cipher, &mut bytes); } + + Ok(bytes) +} +fn try_read_and_decrypt_frame<R>( + stream: &mut R, + cipher: &mut Option<Aes128CfbDec>, +) -> Result<Option<BytesMut>, Box<ReadPacketError>> +where + R: AsyncRead + Unpin + Send + Sync, +{ + let mut framed = FramedRead::new(stream, BytesCodec::new()); + + let Some(message) = future::block_on(future::poll_once(framed.next())) else { + // nothing yet + return Ok(None); + }; + let Some(message) = message else { + return Err(Box::new(ReadPacketError::ConnectionClosed)); + }; + let mut bytes = message.map_err(ReadPacketError::from)?; + + // decrypt if necessary + if let Some(cipher) = cipher { + azalea_crypto::decrypt_packet(cipher, &mut bytes); + } + + Ok(Some(bytes)) } -/// Try to get a Minecraft packet from a buffer. Returns None if the packet -/// isn't complete yet. -pub fn try_process_buffer<P: ProtocolPacket + Debug, R>( +pub fn read_raw_packet_from_buffer<R>( buffer: &mut BytesMut, compression_threshold: Option<u32>, -) -> Result<Option<P>, Box<ReadPacketError>> +) -> Result<Option<Vec<u8>>, Box<ReadPacketError>> where R: AsyncRead + std::marker::Unpin + std::marker::Send + std::marker::Sync, { @@ -306,7 +358,5 @@ where trace!("Reading packet with bytes: {buf_string}"); } - let packet = packet_decoder(&mut Cursor::new(&buf[..]))?; - - Ok(Some(packet)) + Ok(Some(buf)) } |
