Pumpkin/pumpkin-protocol/src/bedrock/ack.rs
Alexander Medvedev b58822319d fix: CI
2026-01-28 23:40:48 +01:00

82 lines
2.1 KiB
Rust

use std::io::{Error, ErrorKind, Read, Write};
use pumpkin_macros::packet;
const MAX_ACK_RECORDS: u16 = 4096;
use crate::{
codec::u24,
serial::{PacketRead, PacketWrite},
};
#[packet(0xC0)]
pub struct Ack {
sequences: Vec<u32>,
}
impl Ack {
#[must_use]
pub const fn new(sequences: Vec<u32>) -> Self {
Self { sequences }
}
fn write_range<W: Write>(start: u32, end: u32, writer: &mut W) -> Result<(), Error> {
if start == end {
1u8.write(writer)?;
u24(start).write(writer)
} else {
0u8.write(writer)?;
u24(start).write(writer)?;
u24(end).write(writer)
}
}
pub fn read<R: Read>(reader: &mut R) -> Result<Self, Error> {
let size = u16::read_be(reader)?;
if size > MAX_ACK_RECORDS {
return Err(Error::new(
ErrorKind::InvalidData,
"ACK packet range is too large.",
));
}
let mut sequences = Vec::with_capacity(size as usize);
for _ in 0..size {
let single = bool::read(reader)?;
if single {
sequences.push(u24::read(reader)?.0);
} else {
let start = u24::read(reader)?.0;
let end = u24::read(reader)?.0;
for i in start..end {
sequences.push(i);
}
}
}
Ok(Self { sequences })
}
pub fn write<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
0xC0u8.write(writer)?;
let mut count: u16 = 0;
let mut buf = Vec::new();
let mut start = self.sequences[0];
let mut end = start;
for seq in self.sequences.iter().copied() {
if seq != end + 1 {
Self::write_range(start, end, &mut buf)?;
count += 1;
start = seq;
}
end = seq;
}
Self::write_range(start, end, &mut buf)?;
count += 1;
count.write_be(writer)?;
writer.write_all(&buf)
}
}