aboutsummaryrefslogtreecommitdiff
path: root/azalea-protocol/src/read.rs
diff options
context:
space:
mode:
authormat <27899617+mat-1@users.noreply.github.com>2023-09-21 11:16:29 -0500
committerGitHub <noreply@github.com>2023-09-21 11:16:29 -0500
commit7b3e2e4bf793466a351510c7fbbd08234e93bb0e (patch)
tree7177a919de9982d9e3c7f36a76d2025696f465b6 /azalea-protocol/src/read.rs
parent83cce236145cdab1872a472a70943b669a880965 (diff)
downloadazalea-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-xazalea-protocol/src/read.rs136
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))
}