Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 19 additions & 9 deletions feather/protocol/src/codec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,23 +67,29 @@ impl MinecraftCodec {
}

/// Writes a packet into the provided writer.
pub fn encode(&mut self, packet: &impl Writeable, output: &mut Vec<u8>) {
packet.write(&mut self.staging_buf, ProtocolVersion::V1_16_2);
pub fn encode(&mut self, packet: &impl Writeable, output: &mut Vec<u8>) -> anyhow::Result<()> {
packet.write(&mut self.staging_buf, ProtocolVersion::V1_16_2)?;

if let Some(threshold) = self.compression {
self.encode_compressed(output, threshold);
self.encode_compressed(output, threshold)?;
} else {
self.encode_uncompressed(output);
self.encode_uncompressed(output)?;
}

if let Some(cryptor) = &mut self.cryptor {
cryptor.encrypt(output);
}

self.staging_buf.clear();

Ok(())
}

fn encode_compressed(&mut self, output: &mut Vec<u8>, threshold: CompressionThreshold) {
fn encode_compressed(
&mut self,
output: &mut Vec<u8>,
threshold: CompressionThreshold,
) -> anyhow::Result<()> {
let (data_length, data) = if self.staging_buf.len() >= threshold {
self.data_compressed()
} else {
Expand All @@ -98,11 +104,13 @@ impl MinecraftCodec {
.unwrap();

let packet_length = data_length_bytes.position() as usize + data.len();
VarInt(packet_length as i32).write(output, ProtocolVersion::V1_16_2);
VarInt(data_length as i32).write(output, ProtocolVersion::V1_16_2);
VarInt(packet_length as i32).write(output, ProtocolVersion::V1_16_2)?;
VarInt(data_length as i32).write(output, ProtocolVersion::V1_16_2)?;
output.extend_from_slice(data);

self.compression_target.clear();

Ok(())
}

fn data_compressed(&mut self) -> (usize, &[u8]) {
Expand All @@ -117,12 +125,14 @@ impl MinecraftCodec {
(0, self.staging_buf.as_slice())
}

fn encode_uncompressed(&mut self, output: &mut Vec<u8>) {
fn encode_uncompressed(&mut self, output: &mut Vec<u8>) -> anyhow::Result<()> {
// TODO: we should probably be able to determine the length without writing the packet,
// which could remove an unnecessary copy.
let length = self.staging_buf.len() as i32;
VarInt(length).write(output, ProtocolVersion::V1_16_2);
VarInt(length).write(output, ProtocolVersion::V1_16_2)?;
output.extend_from_slice(&self.staging_buf);

Ok(())
}

/// Accepts newly received bytes.
Expand Down
Loading