335 lines
8.9 KiB
Rust
335 lines
8.9 KiB
Rust
use crate::net::format::MAX_CLIENT_PACKET_SIZE;
|
|
use serde::Serialize;
|
|
use serde::de::DeserializeOwned;
|
|
use std::convert::{From, Into};
|
|
|
|
pub trait PacketData: Sized {
|
|
fn read(deser: &mut impl PacketDeserializer) -> Result<Self, String>
|
|
where Self: std::marker::Sized;
|
|
fn write(&self, ser: &mut impl PacketSerializer);
|
|
}
|
|
|
|
impl<const N: usize> PacketData for [u8; N] {
|
|
fn read(deser: &mut impl PacketDeserializer) -> Result<Self, String> {
|
|
use std::convert::TryInto;
|
|
|
|
let mut buf = [0; N];
|
|
deser.read_exact(&mut buf)?;
|
|
Ok(buf.try_into().unwrap())
|
|
}
|
|
|
|
fn write(&self, ser: &mut impl PacketSerializer) {
|
|
ser.write_exact(self);
|
|
}
|
|
}
|
|
|
|
impl PacketData for bool {
|
|
fn read(deser: &mut impl PacketDeserializer) -> Result<Self, String> {
|
|
let value = deser.read::<u8>()?;
|
|
match value {
|
|
0x00 => Ok(false),
|
|
0x01 => Ok(true),
|
|
n => Err(format!("{:0X} is not a valid boolean.", n))
|
|
}
|
|
}
|
|
|
|
fn write(&self, ser: &mut impl PacketSerializer) {
|
|
ser.write(*self as u8);
|
|
}
|
|
}
|
|
|
|
impl PacketData for u8 {
|
|
fn read(deser: &mut impl PacketDeserializer) -> Result<Self, String> {
|
|
deser.read::<[u8; 1]>().map(u8::from_be_bytes)
|
|
}
|
|
|
|
fn write(&self, ser: &mut impl PacketSerializer) {
|
|
ser.write(self.to_be_bytes())
|
|
}
|
|
}
|
|
|
|
impl PacketData for i8 {
|
|
fn read(deser: &mut impl PacketDeserializer) -> Result<Self, String> {
|
|
deser.read::<[u8; 1]>().map(i8::from_be_bytes)
|
|
}
|
|
|
|
fn write(&self, ser: &mut impl PacketSerializer) {
|
|
ser.write(self.to_be_bytes())
|
|
}
|
|
}
|
|
|
|
impl PacketData for u16 {
|
|
fn read(deser: &mut impl PacketDeserializer) -> Result<Self, String> {
|
|
deser.read::<[u8; 2]>().map(u16::from_be_bytes)
|
|
}
|
|
|
|
fn write(&self, ser: &mut impl PacketSerializer) {
|
|
ser.write(self.to_be_bytes());
|
|
}
|
|
}
|
|
|
|
impl PacketData for i16 {
|
|
fn read(deser: &mut impl PacketDeserializer) -> Result<Self, String> {
|
|
deser.read::<[u8; 2]>().map(i16::from_be_bytes)
|
|
}
|
|
|
|
fn write(&self, ser: &mut impl PacketSerializer) {
|
|
ser.write(self.to_be_bytes());
|
|
}
|
|
}
|
|
|
|
impl PacketData for i32 {
|
|
fn read(deser: &mut impl PacketDeserializer) -> Result<Self, String> {
|
|
deser.read::<[u8; 4]>().map(i32::from_be_bytes)
|
|
}
|
|
|
|
fn write(&self, ser: &mut impl PacketSerializer) {
|
|
ser.write(self.to_be_bytes());
|
|
}
|
|
}
|
|
|
|
impl PacketData for i64 {
|
|
fn read(deser: &mut impl PacketDeserializer) -> Result<Self, String> {
|
|
deser.read::<[u8; 8]>().map(i64::from_be_bytes)
|
|
}
|
|
|
|
fn write(&self, ser: &mut impl PacketSerializer) {
|
|
ser.write(self.to_be_bytes());
|
|
}
|
|
}
|
|
|
|
impl PacketData for f32 {
|
|
fn read(deser: &mut impl PacketDeserializer) -> Result<Self, String> {
|
|
deser.read::<[u8; 4]>().map(f32::from_be_bytes)
|
|
}
|
|
|
|
fn write(&self, ser: &mut impl PacketSerializer) {
|
|
ser.write(self.to_be_bytes());
|
|
}
|
|
}
|
|
|
|
impl PacketData for f64 {
|
|
fn read(deser: &mut impl PacketDeserializer) -> Result<Self, String> {
|
|
deser.read::<[u8; 8]>().map(f64::from_be_bytes)
|
|
}
|
|
|
|
fn write(&self, ser: &mut impl PacketSerializer) {
|
|
ser.write(self.to_be_bytes());
|
|
}
|
|
}
|
|
|
|
pub struct VarInt(pub i32);
|
|
|
|
impl From<i32> for VarInt {
|
|
fn from(x: i32) -> Self { VarInt(x) }
|
|
}
|
|
|
|
impl Into<i32> for VarInt {
|
|
fn into(self) -> i32 { self.0 }
|
|
}
|
|
|
|
impl PacketData for VarInt {
|
|
fn read(deser: &mut impl PacketDeserializer) -> Result<Self, String> {
|
|
let mut length = 1;
|
|
let mut acc = 0;
|
|
// VarInts must not be longer than 5 bytes.
|
|
while length <= 5 {
|
|
// If the highest bit is set, there are further bytes to be read from this VarInt;
|
|
// the rest of the bits are the actual data in the VarInt.
|
|
let read = deser.read::<u8>()?;
|
|
acc |= (read & 0b01111111) as i32;
|
|
|
|
// There are no more bytes.
|
|
if (read & 0b10000000) == 0 {
|
|
return Ok(VarInt(acc));
|
|
}
|
|
|
|
// Make space for the rest of the bits.
|
|
acc = acc << 7;
|
|
length += 1;
|
|
}
|
|
|
|
// The VarInt was too long!
|
|
Err("VarInt was more than 5 bytes.".to_string())
|
|
}
|
|
|
|
fn write(&self, ser: &mut impl PacketSerializer) {
|
|
let mut value = self.0;
|
|
loop {
|
|
let mut temp = (value & 0b01111111) as u8;
|
|
value = value >> 7;
|
|
if value != 0 {
|
|
temp |= 0b10000000;
|
|
}
|
|
ser.write(temp);
|
|
|
|
if value == 0 {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
pub struct VarLong(pub i64);
|
|
|
|
impl From<i64> for VarLong {
|
|
fn from(x: i64) -> Self { VarLong(x) }
|
|
}
|
|
|
|
impl Into<i64> for VarLong {
|
|
fn into(self) -> i64 { self.0 }
|
|
}
|
|
|
|
impl PacketData for VarLong {
|
|
fn read(deser: &mut impl PacketDeserializer) -> Result<Self, String> {
|
|
let mut length = 1;
|
|
let mut acc = 0;
|
|
// VarLongs must not be longer than 5 bytes.
|
|
while length <= 10 {
|
|
// If the highest bit is set, there are further bytes to be read from this VarLong;
|
|
// the rest of the bits are the actual data in the VarLong.
|
|
let read = deser.read::<u8>()?;
|
|
acc |= (read & 0b01111111) as i64;
|
|
|
|
// There are no more bytes.
|
|
if (read & 0b10000000) == 0 {
|
|
return Ok(VarLong(acc));
|
|
}
|
|
|
|
// Make space for the rest of the bits.
|
|
acc = acc << 7;
|
|
length += 1;
|
|
}
|
|
|
|
// The VarLong was too long!
|
|
Err("VarLong was more than 10 bytes.".to_string())
|
|
}
|
|
|
|
fn write(&self, ser: &mut impl PacketSerializer) {
|
|
let mut value = self.0;
|
|
loop {
|
|
let mut temp = (value & 0b01111111) as u8;
|
|
value = value >> 7;
|
|
if value != 0 {
|
|
temp |= 0b10000000;
|
|
}
|
|
ser.write(temp);
|
|
|
|
if value == 0 {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
impl PacketData for Vec<u8> {
|
|
fn read(deser: &mut impl PacketDeserializer) -> Result<Self, String> {
|
|
let length: i32 = deser.read::<VarInt>()?.into();
|
|
if length < 0 {
|
|
return Err("String length cannot be negative.".to_string());
|
|
}
|
|
|
|
let length = length as usize;
|
|
if length > MAX_CLIENT_PACKET_SIZE {
|
|
return Err("Byte array was too long.".to_string());
|
|
}
|
|
|
|
let mut it = Vec::with_capacity(length);
|
|
it.resize(length, 0);
|
|
deser.read_exact(it.as_mut_slice())?;
|
|
|
|
Ok(it)
|
|
}
|
|
|
|
fn write(&self, ser: &mut impl PacketSerializer) {
|
|
ser.write(VarInt(self.len() as i32));
|
|
ser.write_exact(self.as_slice());
|
|
}
|
|
}
|
|
|
|
impl PacketData for String {
|
|
fn read(deser: &mut impl PacketDeserializer) -> Result<Self, String> {
|
|
let bytes = deser.read()?;
|
|
String::from_utf8(bytes).map_err(|_| "String contained invalid UTF-8.".to_string())
|
|
}
|
|
|
|
fn write(&self, ser: &mut impl PacketSerializer) {
|
|
ser.write(self.clone().into_bytes());
|
|
}
|
|
}
|
|
|
|
pub trait PacketJson: DeserializeOwned + Serialize + Sized { }
|
|
|
|
impl PacketJson for crate::net::chat::Chat { }
|
|
|
|
impl<S: PacketJson> PacketData for S {
|
|
fn read(deser: &mut impl PacketDeserializer) -> Result<Self, String> {
|
|
let bytes = deser.read::<Vec<u8>>()?;
|
|
serde_json::from_slice(&bytes).map_err(|_| "Bad JSON syntax".to_string())
|
|
}
|
|
|
|
fn write(&self, ser: &mut impl PacketSerializer) {
|
|
ser.write(serde_json::to_vec(self).unwrap());
|
|
}
|
|
}
|
|
|
|
pub trait PacketSerializer: Sized {
|
|
/// Write a slice of bytes directly, without a length prefix.
|
|
fn write_exact(&mut self, value: &[u8]);
|
|
|
|
fn write<D: PacketData>(&mut self, value: D) {
|
|
value.write(self)
|
|
}
|
|
}
|
|
|
|
impl PacketSerializer for Vec<u8> {
|
|
fn write_exact(&mut self, value: &[u8]) {
|
|
self.extend_from_slice(value);
|
|
}
|
|
}
|
|
|
|
pub trait PacketDeserializer: Sized {
|
|
fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), String>;
|
|
fn read_eof(&mut self) -> Result<(), String>;
|
|
|
|
fn read<D: PacketData>(&mut self) -> Result<D, String> {
|
|
D::read(self)
|
|
}
|
|
}
|
|
|
|
pub struct VecPacketDeserializer<'a> {
|
|
data: &'a [u8],
|
|
index: usize,
|
|
}
|
|
|
|
impl VecPacketDeserializer<'_> {
|
|
pub fn new<'a>(data: &'a [u8]) -> VecPacketDeserializer<'a> {
|
|
VecPacketDeserializer {
|
|
data: data,
|
|
index: 0,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl PacketDeserializer for VecPacketDeserializer<'_> {
|
|
fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), String> {
|
|
if self.index + buf.len() > self.data.len() {
|
|
return Err("Tried to read past length of packet.".to_string());
|
|
}
|
|
|
|
let len = buf.len();
|
|
buf[..].copy_from_slice(&self.data[self.index..self.index + len]);
|
|
self.index += buf.len();
|
|
|
|
Ok(())
|
|
}
|
|
|
|
fn read_eof(&mut self) -> Result<(), String> {
|
|
if self.index != self.data.len() {
|
|
return Err("Packet contained more data than necessary.".to_string());
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
}
|