Added PacketData trait to allow serializing any data types.
parent
d32118db4f
commit
0b5d3c026f
|
@ -12,7 +12,7 @@ jobs:
|
||||||
- name: Install latest nightly
|
- name: Install latest nightly
|
||||||
uses: actions-rs/toolchain@v1
|
uses: actions-rs/toolchain@v1
|
||||||
with:
|
with:
|
||||||
toolchain: stable
|
toolchain: nightly
|
||||||
override: true
|
override: true
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
nightly
|
|
@ -1,3 +1,5 @@
|
||||||
|
#![feature(const_generics)]
|
||||||
|
|
||||||
mod net;
|
mod net;
|
||||||
|
|
||||||
use crate::net::{Reader, Writer};
|
use crate::net::{Reader, Writer};
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
// TODO: Support more features.
|
// TODO: Support more features.
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Clone, Serialize, Deserialize)]
|
||||||
pub struct Chat {
|
pub struct Chat {
|
||||||
pub text: String,
|
pub text: String,
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ use async_trait::async_trait;
|
||||||
use crate::net::{Reader, Writer};
|
use crate::net::{Reader, Writer};
|
||||||
use std::boxed::Box;
|
use std::boxed::Box;
|
||||||
use std::io;
|
use std::io;
|
||||||
use tokio::io::{AsyncReadExt, AsyncWriteExt};
|
use tokio::io::AsyncReadExt;
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
pub trait PacketFormat {
|
pub trait PacketFormat {
|
||||||
|
@ -35,19 +35,23 @@ async fn read_varint<'rr, 'r>(src: &'rr mut Reader<'r>) -> io::Result<(usize, i3
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl PacketFormat for DefaultPacketFormat {
|
impl PacketFormat for DefaultPacketFormat {
|
||||||
async fn send<'wr, 'w>(&self, dest: &'wr mut Writer<'w>, packet_id: i32, data: &[u8]) -> io::Result<()> {
|
async fn send<'wr, 'w>(&self, dest: &'wr mut Writer<'w>, packet_id: i32, data: &[u8]) -> io::Result<()> {
|
||||||
use crate::net::serialize::PacketSerializer;
|
use crate::net::serialize::{PacketSerializer, VarInt};
|
||||||
|
|
||||||
let mut packet_id_buf = Vec::with_capacity(5);
|
let mut packet_id_buf = Vec::with_capacity(5);
|
||||||
packet_id_buf.write_varint(packet_id);
|
packet_id_buf.write(VarInt(packet_id));
|
||||||
|
|
||||||
let packet_length = packet_id_buf.len() + data.len();
|
let packet_length = packet_id_buf.len() + data.len();
|
||||||
let mut packet_length_buf = Vec::with_capacity(5);
|
let mut packet_length_buf = Vec::with_capacity(5);
|
||||||
packet_length_buf.write_varint(packet_length as i32);
|
packet_length_buf.write(VarInt(packet_length as i32));
|
||||||
|
|
||||||
dest.write(packet_length_buf.as_slice()).await?;
|
{
|
||||||
dest.write(packet_id_buf.as_slice()).await?;
|
use tokio::io::AsyncWriteExt;
|
||||||
dest.write(data).await?;
|
|
||||||
dest.flush().await?;
|
dest.write(packet_length_buf.as_slice()).await?;
|
||||||
|
dest.write(packet_id_buf.as_slice()).await?;
|
||||||
|
dest.write(data).await?;
|
||||||
|
dest.flush().await?;
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
pub mod handshake;
|
pub mod handshake;
|
||||||
pub mod status;
|
pub mod status;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::net::serialize::PacketDeserializer;
|
use crate::net::serialize::{PacketData, PacketDeserializer, PacketSerializer, VarInt};
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub enum HandshakeNextState {
|
pub enum HandshakeNextState {
|
||||||
|
@ -14,6 +14,32 @@ pub struct PacketHandshake {
|
||||||
pub next_state: HandshakeNextState,
|
pub next_state: HandshakeNextState,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl PacketData for PacketHandshake {
|
||||||
|
fn read(deser: &mut impl PacketDeserializer) -> Result<Self, String> {
|
||||||
|
let protocol_version = deser.read::<VarInt>()?.into();
|
||||||
|
let server_address = deser.read::<String>()?;
|
||||||
|
let server_port = deser.read::<u16>()?;
|
||||||
|
let next_state = match deser.read::<VarInt>()?.into() {
|
||||||
|
1 => HandshakeNextState::Status,
|
||||||
|
2 => HandshakeNextState::Login,
|
||||||
|
n => return Err(format!("Invalid next protocol state in handshake: {}", n))
|
||||||
|
};
|
||||||
|
deser.read_eof()?;
|
||||||
|
Ok(PacketHandshake {
|
||||||
|
protocol_version: protocol_version,
|
||||||
|
server_address: server_address,
|
||||||
|
server_port: server_port,
|
||||||
|
next_state: next_state,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write(&self, ser: &mut impl PacketSerializer) {
|
||||||
|
ser.write(self.protocol_version);
|
||||||
|
ser.write(self.server_address.clone());
|
||||||
|
ser.write(self.server_port);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum PacketHandshakeServerbound {
|
pub enum PacketHandshakeServerbound {
|
||||||
Handshake(PacketHandshake),
|
Handshake(PacketHandshake),
|
||||||
|
@ -24,23 +50,7 @@ pub fn read_packet_handshake(id: i32, deser: &mut impl PacketDeserializer)
|
||||||
use PacketHandshakeServerbound::*;
|
use PacketHandshakeServerbound::*;
|
||||||
|
|
||||||
match id {
|
match id {
|
||||||
0x00 => {
|
0x00 => deser.read().map(Handshake),
|
||||||
let protocol_version = deser.read_varint()?;
|
|
||||||
let server_address = deser.read_string()?;
|
|
||||||
let server_port = deser.read_u16()?;
|
|
||||||
let next_state = match deser.read_varint()? {
|
|
||||||
1 => HandshakeNextState::Status,
|
|
||||||
2 => HandshakeNextState::Login,
|
|
||||||
n => return Err(format!("Invalid next protocol state in handshake: {}", n))
|
|
||||||
};
|
|
||||||
deser.read_eof()?;
|
|
||||||
Ok(Handshake(PacketHandshake {
|
|
||||||
protocol_version: protocol_version,
|
|
||||||
server_address: server_address,
|
|
||||||
server_port: server_port,
|
|
||||||
next_state: next_state,
|
|
||||||
}))
|
|
||||||
},
|
|
||||||
id => Err(format!("Invalid handshake packet id: {}", id))
|
id => Err(format!("Invalid handshake packet id: {}", id))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,29 +1,31 @@
|
||||||
use crate::net::chat::Chat;
|
use crate::net::chat::Chat;
|
||||||
use crate::net::serialize::{PacketSerializer, PacketDeserializer};
|
use crate::net::serialize::{PacketDeserializer, PacketSerializer, PacketJson};
|
||||||
use serde::Serialize;
|
use serde::{Deserialize, Serialize};
|
||||||
use std::convert::TryInto;
|
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Clone, Deserialize, Serialize)]
|
||||||
pub struct PacketResponseVersion {
|
pub struct PacketResponseVersion {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub protocol: u32,
|
pub protocol: u32,
|
||||||
}
|
}
|
||||||
|
impl PacketJson for PacketResponseVersion {}
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Clone, Deserialize, Serialize)]
|
||||||
pub struct PacketResponsePlayersSample {
|
pub struct PacketResponsePlayersSample {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub id: Uuid,
|
pub id: Uuid,
|
||||||
}
|
}
|
||||||
|
impl PacketJson for PacketResponsePlayersSample {}
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Clone, Deserialize, Serialize)]
|
||||||
pub struct PacketResponsePlayers {
|
pub struct PacketResponsePlayers {
|
||||||
pub max: u32,
|
pub max: u32,
|
||||||
pub online: u32,
|
pub online: u32,
|
||||||
pub sample: Vec<PacketResponsePlayersSample>
|
pub sample: Vec<PacketResponsePlayersSample>
|
||||||
}
|
}
|
||||||
|
impl PacketJson for PacketResponsePlayers {}
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Clone, Deserialize, Serialize)]
|
||||||
pub struct PacketResponse {
|
pub struct PacketResponse {
|
||||||
pub version: PacketResponseVersion,
|
pub version: PacketResponseVersion,
|
||||||
pub players: PacketResponsePlayers,
|
pub players: PacketResponsePlayers,
|
||||||
|
@ -31,6 +33,7 @@ pub struct PacketResponse {
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub favicon: Option<String>,
|
pub favicon: Option<String>,
|
||||||
}
|
}
|
||||||
|
impl PacketJson for PacketResponse {}
|
||||||
|
|
||||||
pub enum PacketStatusClientbound {
|
pub enum PacketStatusClientbound {
|
||||||
Response(PacketResponse),
|
Response(PacketResponse),
|
||||||
|
@ -53,10 +56,9 @@ pub fn read_packet_status(id: i32, deser: &mut impl PacketDeserializer)
|
||||||
Ok(Request)
|
Ok(Request)
|
||||||
},
|
},
|
||||||
1 => {
|
1 => {
|
||||||
let mut buf = [0; 8];
|
let payload = deser.read::<[u8; 8]>()?;
|
||||||
deser.read(&mut buf)?;
|
|
||||||
deser.read_eof()?;
|
deser.read_eof()?;
|
||||||
Ok(Ping(buf.try_into().unwrap()))
|
Ok(Ping(payload))
|
||||||
}
|
}
|
||||||
id => Err(format!("Invalid status packet id: {}", id))
|
id => Err(format!("Invalid status packet id: {}", id))
|
||||||
}
|
}
|
||||||
|
@ -68,11 +70,11 @@ pub fn write_packet_status(ser: &mut impl PacketSerializer, packet: PacketStatus
|
||||||
|
|
||||||
match packet {
|
match packet {
|
||||||
Response(response) => {
|
Response(response) => {
|
||||||
ser.write_json(&response);
|
ser.write(response);
|
||||||
0x00
|
0x00
|
||||||
},
|
},
|
||||||
Pong(payload) => {
|
Pong(payload) => {
|
||||||
ser.write(&payload);
|
ser.write(payload);
|
||||||
0x01
|
0x01
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,85 +1,147 @@
|
||||||
use crate::net::format::MAX_CLIENT_PACKET_SIZE;
|
use crate::net::format::MAX_CLIENT_PACKET_SIZE;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
use serde::de::DeserializeOwned;
|
||||||
|
use std::convert::{From, Into};
|
||||||
|
|
||||||
pub trait PacketSerializer {
|
pub trait PacketData: Sized {
|
||||||
/// Write a slice of bytes directly, without a length prefix.
|
fn read(deser: &mut impl PacketDeserializer) -> Result<Self, String>
|
||||||
fn write(&mut self, value: &[u8]);
|
where Self: std::marker::Sized;
|
||||||
|
fn write(&self, ser: &mut impl PacketSerializer);
|
||||||
|
}
|
||||||
|
|
||||||
fn write_u8(&mut self, value: u8) {
|
impl<const N: usize> PacketData for [u8; N] {
|
||||||
self.write(&value.to_le_bytes());
|
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())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://wiki.vg/Protocol#VarInt_and_VarLong
|
fn write(&self, ser: &mut impl PacketSerializer) {
|
||||||
fn write_varint(&mut self, mut value: i32) {
|
ser.write_exact(self);
|
||||||
loop {
|
}
|
||||||
let mut temp = (value & 0b01111111) as u8;
|
}
|
||||||
value = value >> 7;
|
|
||||||
if value != 0 {
|
|
||||||
temp |= 0b10000000;
|
|
||||||
}
|
|
||||||
self.write_u8(temp);
|
|
||||||
|
|
||||||
if value == 0 {
|
impl PacketData for bool {
|
||||||
break;
|
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))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Write a varint-length-prefixed byte slice.
|
fn write(&self, ser: &mut impl PacketSerializer) {
|
||||||
fn write_slice(&mut self, value: &[u8]) {
|
ser.write(*self as u8);
|
||||||
self.write_varint(value.len() as i32);
|
|
||||||
self.write(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Write a varint-length-prefixed string.
|
|
||||||
fn write_str(&mut self, value: &str) {
|
|
||||||
self.write_slice(value.as_bytes());
|
|
||||||
}
|
|
||||||
|
|
||||||
fn write_json(&mut self, value: &impl Serialize) {
|
|
||||||
self.write_slice(serde_json::to_vec(value).unwrap().as_slice())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PacketSerializer for Vec<u8> {
|
impl PacketData for u8 {
|
||||||
fn write(&mut self, value: &[u8]) {
|
fn read(deser: &mut impl PacketDeserializer) -> Result<Self, String> {
|
||||||
self.extend_from_slice(value);
|
deser.read::<[u8; 1]>().map(u8::from_be_bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_u8(&mut self, value: u8) {
|
fn write(&self, ser: &mut impl PacketSerializer) {
|
||||||
self.push(value);
|
ser.write(self.to_be_bytes())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait PacketDeserializer {
|
impl PacketData for i8 {
|
||||||
fn read(&mut self, buf: &mut [u8]) -> Result<(), String>;
|
fn read(deser: &mut impl PacketDeserializer) -> Result<Self, String> {
|
||||||
fn read_eof(&mut self) -> Result<(), String>;
|
deser.read::<[u8; 1]>().map(i8::from_be_bytes)
|
||||||
|
|
||||||
fn read_u8(&mut self) -> Result<u8, String> {
|
|
||||||
let mut buf = [0; 1];
|
|
||||||
self.read(&mut buf)?;
|
|
||||||
Ok(u8::from_le_bytes(buf))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_u16(&mut self) -> Result<u16, String> {
|
fn write(&self, ser: &mut impl PacketSerializer) {
|
||||||
let mut buf = [0; 2];
|
ser.write(self.to_be_bytes())
|
||||||
self.read(&mut buf)?;
|
}
|
||||||
Ok(u16::from_le_bytes(buf))
|
}
|
||||||
|
|
||||||
|
impl PacketData for u16 {
|
||||||
|
fn read(deser: &mut impl PacketDeserializer) -> Result<Self, String> {
|
||||||
|
deser.read::<[u8; 2]>().map(u16::from_be_bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_varint(&mut self) -> Result<i32, String> {
|
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 length = 1;
|
||||||
let mut acc = 0;
|
let mut acc = 0;
|
||||||
// VarInts must not be longer than 5 bytes.
|
// VarInts must not be longer than 5 bytes.
|
||||||
while length <= 5 {
|
while length <= 5 {
|
||||||
// If the highest bit is set, there are further bytes to be read from this VarInt;
|
// 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.
|
// the rest of the bits are the actual data in the VarInt.
|
||||||
let read = self.read_u8()?;
|
let read = deser.read::<u8>()?;
|
||||||
acc |= (read & 0b01111111) as i32;
|
acc |= (read & 0b01111111) as i32;
|
||||||
|
|
||||||
// There are no mo
|
// There are no more bytes.
|
||||||
if (read & 0b10000000) == 0 {
|
if (read & 0b10000000) == 0 {
|
||||||
return Ok(acc);
|
return Ok(VarInt(acc));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make space for the rest of the bits.
|
// Make space for the rest of the bits.
|
||||||
|
@ -91,21 +153,147 @@ pub trait PacketDeserializer {
|
||||||
Err("VarInt was more than 5 bytes.".to_string())
|
Err("VarInt was more than 5 bytes.".to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_string(&mut self) -> Result<String, String> {
|
fn write(&self, ser: &mut impl PacketSerializer) {
|
||||||
let length = self.read_varint()?;
|
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 {
|
if length < 0 {
|
||||||
return Err("String length cannot be negative.".to_string());
|
return Err("String length cannot be negative.".to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
let length = length as usize;
|
let length = length as usize;
|
||||||
if length > MAX_CLIENT_PACKET_SIZE {
|
if length > MAX_CLIENT_PACKET_SIZE {
|
||||||
return Err("String was too long.".to_string());
|
return Err("Byte array was too long.".to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut buf = Vec::with_capacity(length);
|
let mut it = Vec::with_capacity(length);
|
||||||
buf.resize(length, 0);
|
it.resize(length, 0);
|
||||||
self.read(buf.as_mut_slice())?;
|
deser.read_exact(it.as_mut_slice())?;
|
||||||
String::from_utf8(buf).map_err(|_| "String was invalid UTF-8.".to_string())
|
|
||||||
|
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,7 +312,7 @@ impl VecPacketDeserializer<'_> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PacketDeserializer for VecPacketDeserializer<'_> {
|
impl PacketDeserializer for VecPacketDeserializer<'_> {
|
||||||
fn read(&mut self, buf: &mut [u8]) -> Result<(), String> {
|
fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), String> {
|
||||||
if self.index + buf.len() > self.data.len() {
|
if self.index + buf.len() > self.data.len() {
|
||||||
return Err("Tried to read past length of packet.".to_string());
|
return Err("Tried to read past length of packet.".to_string());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue