Commit e6dfd702 authored by insert's avatar insert

Work on serde de.

parent 20a2659d
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "lldb",
"request": "launch",
"name": "Debug executable 'minecraft-rs'",
"cargo": {
"args": [
"build",
"--bin=minecraft-rs",
"--package=minecraft-rs"
],
"filter": {
"name": "minecraft-rs",
"kind": "bin"
}
},
"args": [],
"cwd": "${workspaceFolder}"
},
{
"type": "lldb",
"request": "launch",
"name": "Debug unit tests in executable 'minecraft-rs'",
"cargo": {
"args": [
"test",
"--no-run",
"--bin=minecraft-rs",
"--package=minecraft-rs"
],
"filter": {
"name": "minecraft-rs",
"kind": "bin"
}
},
"args": [],
"cwd": "${workspaceFolder}"
}
]
}
\ No newline at end of file
......@@ -72,6 +72,7 @@ dependencies = [
"nanoid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_with 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
......@@ -185,6 +186,25 @@ dependencies = [
"serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "serde_with"
version = "1.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_with_macros 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "serde_with_macros"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "syn"
version = "0.15.44"
......@@ -255,6 +275,8 @@ dependencies = [
"checksum serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)" = "7fe5626ac617da2f2d9c48af5515a21d5a480dbd151e01bb1c355e26a3e68113"
"checksum serde_derive 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)" = "01e69e1b8a631f245467ee275b8c757b818653c6d704cdbcaeb56b56767b529c"
"checksum serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)" = "051c49229f282f7c6f3813f8286cc1e3323e8051823fce42c7ea80fe13521704"
"checksum serde_with 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "32dc67e726b4b06ccf46860bef46fe713fffde11181d6c3c2f3104a670ceddb1"
"checksum serde_with_macros 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f6304d92ad5493e340b95c353b8328c312d020f0eb5cb6df8506f160f5b7300d"
"checksum syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)" = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5"
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
"checksum winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "f10e386af2b13e47c89e7236a7a14a086791a2b88ebad6df9bf42040195cf770"
......
......@@ -13,6 +13,7 @@ colored = "1.8.0"
serde_json = "1.0.40"
base64 = "0.10.1"
byteorder = "1.3.2"
serde_with = "1.3.1"
[[bin]]
name = "minecraft-rs"
......
......@@ -17,6 +17,8 @@ mod proto;
use proto::read::{VarIntRead, MinecraftRead};
use proto::write::{VarIntWrite, MinecraftWrite};
mod packets;
#[derive(Serialize, Deserialize)]
struct SLPVersion {
name: String,
......@@ -123,24 +125,65 @@ impl Client {
}
}
fn handle_packet(client: &mut Client, cur: &mut Cursor<&mut [u8]>, length: u64) {
use packets::server::ServerPacket;
fn de_packet(client: &mut Client, id: i32, cur: &mut Cursor<&mut [u8]>, length: usize) -> ServerPacket {
let pos = cur.position().try_into().unwrap();
let mut cur = Cursor::new(&mut cur.get_mut()[pos .. pos + length]);
match client.state {
State::HANDSHAKE => {
match id {
0x00 => ServerPacket::H00(from_vec(&mut cur).unwrap()),
_ => ServerPacket::Unknown(id)
}
},
State::STATUS => {
match id {
0x00 => ServerPacket::S00(from_vec(&mut cur).unwrap()),
0x01 => ServerPacket::S01(from_vec(&mut cur).unwrap()),
_ => ServerPacket::Unknown(id)
}
},
State::LOGIN => {
match id {
0x00 => ServerPacket::L00(from_vec(&mut cur).unwrap()),
_ => ServerPacket::Unknown(id)
}
},
State::PLAY => {
match id {
_ => ServerPacket::Unknown(id)
}
}
}
}
fn handle_packet(client: &mut Client, cur: &mut Cursor<&mut [u8]>, length: usize) {
let v = cur.read_var_int().unwrap();
let id = v.value;
let pos = cur.position() as usize - 1;
client.debug(id, true, &cur.get_mut()[pos .. pos + length as usize].to_vec());
let pos = cur.position() as usize - v.length as usize;
client.debug(id, true, &cur.get_mut()[pos .. pos + length].to_vec());
match client.state {
match de_packet(client, id, cur, length - v.length as usize) {
ServerPacket::H00(packet) => {
println!("Protocol: {}\nAddress: {}\nPort: {}\nState: {}", (packet.0).0, packet.1, packet.2, (packet.3).0);
if (packet.3).0 == 1 {
client.state = State::STATUS;
} else if (packet.3).0 == 2 {
client.state = State::LOGIN;
}
},
ServerPacket::Unknown(id) => client.unknown_packet(id),
_ => {}
}
/*match client.state {
State::HANDSHAKE => {
match id {
0x00 => {
// Handshake
let protocol = cur.read_var_int().unwrap().value;
let address = cur.read_string(Some(255)).unwrap();
let port = cur.read_ushort().unwrap();
let state = cur.read_var_int().unwrap().value;
let packets::server::H00Handshake(protocol, address, port, state) = from_vec(&mut cur).unwrap();
println!("Protocol: {}\nAddress: {}\nPort: {}\nState: {}", protocol, address, port, state);
match state {
......@@ -152,29 +195,25 @@ fn handle_packet(client: &mut Client, cur: &mut Cursor<&mut [u8]>, length: u64)
}
_ => {}
}
}
},
_ => client.unknown_packet(id)
}
}
State::STATUS => {
match id {
0x00 => {
// Request
let mut buf = Vec::<u8>::new();
buf.write_string(get_status().unwrap()).unwrap();
client.send(0x00, &mut buf).unwrap();
}
},
0x01 => {
// Ping
let payload = cur.read_ilong().unwrap();
let packets::server::S01Ping(payload) = from_vec(&mut cur).unwrap();
client.println("ping", &format!("received payload: {}", payload));
let mut buf = Vec::<u8>::new();
buf.write_ilong(payload).unwrap();
client.send(0x01, &mut buf).unwrap();
}
},
_ => client.unknown_packet(id)
}
}
......@@ -263,7 +302,7 @@ fn handle_packet(client: &mut Client, cur: &mut Cursor<&mut [u8]>, length: u64)
_ => client.unknown_packet(id)
}
}
}
}*/
}
fn handle_client(stream: TcpStream) {
......@@ -285,7 +324,7 @@ fn handle_client(stream: TcpStream) {
break;
}
handle_packet(&mut client, &mut cur, length as u64);
handle_packet(&mut client, &mut cur, length.try_into().unwrap());
cur.set_position(start + length as u64);
}
true
......@@ -298,6 +337,7 @@ fn handle_client(stream: TcpStream) {
} {}
}
use packets::{from_vec};
fn main() {
let listener = TcpListener::bind("0.0.0.0:3333").unwrap();
......
use serde::Deserialize;
/**
* 0x01 Pong
* Allows the client to display ping on SL.
* -> Client::status
*/
#[derive(Deserialize)]
pub struct CS01_Pong {
payload: i64
}
pub enum ClientPacket {
// client-bound
CS01(CS01_Pong),
// unknown
Unknown(i32)
}
\ No newline at end of file
use byteorder::{BigEndian, ReadBytesExt};
use std::io::{Cursor, Read};
use std::str::from_utf8;
use serde::Deserialize;
use serde::de::{
self, Visitor, SeqAccess, DeserializeSeed
};
use super::error::{Error, Result};
use crate::proto::read::VarIntRead;
pub struct Deserializer<'de> {
input: &'de mut Cursor<&'de mut [u8]>,
}
impl<'de> Deserializer<'de> {
pub fn from_vec(input: &'de mut Cursor<&'de mut [u8]>) -> Self {
Deserializer { input }
}
}
pub fn from_vec<'a, T>(s: &'a mut Cursor<&'a mut [u8]>) -> Result<T>
where
T: Deserialize<'a>,
{
let mut deserializer = Deserializer::from_vec(s);
let t = T::deserialize(&mut deserializer)?;
if deserializer.input.position() == deserializer.input.get_ref().len() as u64 {
Ok(t)
} else {
Err(Error::TrailingCharacters)
}
}
impl<'de> Deserializer<'de> {
fn parse_bool(&mut self) -> Result<bool> {
if let Ok(val) = self.input.read_u8() {
Ok(val > 0)
} else {
Err(Error::ExpectedBoolean)
}
}
fn parse_i8(&mut self) -> Result<i8> {
Ok(self.input.read_i8().unwrap())
}
fn parse_i16(&mut self) -> Result<i16> {
Ok(self.input.read_i16::<BigEndian>().unwrap())
}
fn parse_i32(&mut self) -> Result<i32> {
Ok(self.input.read_i32::<BigEndian>().unwrap())
}
fn parse_i64(&mut self) -> Result<i64> {
Ok(self.input.read_i64::<BigEndian>().unwrap())
}
fn parse_u8(&mut self) -> Result<u8> {
Ok(self.input.read_u8().unwrap())
}
fn parse_u16(&mut self) -> Result<u16> {
Ok(self.input.read_u16::<BigEndian>().unwrap())
}
fn parse_u32(&mut self) -> Result<u32> {
Ok(self.input.read_u32::<BigEndian>().unwrap())
}
fn parse_u64(&mut self) -> Result<u64> {
Ok(self.input.read_u64::<BigEndian>().unwrap())
}
fn parse_f32(&mut self) -> Result<f32> {
Ok(self.input.read_f32::<BigEndian>().unwrap())
}
fn parse_f64(&mut self) -> Result<f64> {
Ok(self.input.read_f64::<BigEndian>().unwrap())
}
fn parse_char(&mut self) -> Result<char> {
Ok(self.input.read_u8().unwrap() as char)
}
fn parse_vi32(&mut self) -> Result<i32> {
println!("{}", self.input.position());
let val = self.input.read_vi32().unwrap();
println!("{}", val);
println!("{}", self.input.position());
Ok(val)
}
fn parse_string(&mut self) -> Result<&str> {
let length = self.parse_vi32().unwrap();
Ok(from_utf8(&self.input.get_ref()[self.input.position() as usize .. self.input.position() as usize + length as usize]).unwrap())
}
}
impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
type Error = super::error::Error;
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
where V: Visitor<'de>,
{
unimplemented!()
}
fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value>
where V: Visitor<'de>,
{
visitor.visit_bool(self.parse_bool()?)
}
fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value>
where V: Visitor<'de>,
{
visitor.visit_i8(self.parse_i8()?)
}
fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value>
where V: Visitor<'de>,
{
visitor.visit_i16(self.parse_i16()?)
}
fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value>
where V: Visitor<'de>,
{
visitor.visit_i32(self.parse_i32()?)
}
fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value>
where V: Visitor<'de>,
{
visitor.visit_i64(self.parse_i64()?)
}
fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value>
where V: Visitor<'de>,
{
visitor.visit_u8(self.parse_u8()?)
}
fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value>
where V: Visitor<'de>,
{
visitor.visit_u16(self.parse_u16()?)
}
fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value>
where V: Visitor<'de>,
{
visitor.visit_u32(self.parse_u32()?)
}
fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value>
where V: Visitor<'de>,
{
visitor.visit_u64(self.parse_u64()?)
}
fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value>
where V: Visitor<'de>,
{
visitor.visit_f32(self.parse_f32()?)
}
fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value>
where V: Visitor<'de>,
{
visitor.visit_f64(self.parse_f64()?)
}
fn deserialize_char<V>(self, visitor: V) -> Result<V::Value>
where V: Visitor<'de>,
{
visitor.visit_char(self.parse_char()?)
}
fn deserialize_str<V>(self, visitor: V) -> Result<V::Value>
where V: Visitor<'de>,
{
unimplemented!()
}
fn deserialize_string<V>(self, visitor: V) -> Result<V::Value>
where V: Visitor<'de>,
{
visitor.visit_str(self.parse_string()?)
}
fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value>
where V: Visitor<'de>,
{
unimplemented!()
}
fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value>
where V: Visitor<'de>,
{
unimplemented!()
}
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value>
where V: Visitor<'de>,
{
unimplemented!()
}
fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value>
where V: Visitor<'de>,
{
unimplemented!()
}
fn deserialize_unit_struct<V>(
self,
_name: &'static str,
visitor: V,
) -> Result<V::Value>
where V: Visitor<'de>,
{
self.deserialize_unit(visitor)
}
fn deserialize_newtype_struct<V>(
self,
_name: &'static str,
visitor: V,
) -> Result<V::Value>
where V: Visitor<'de>,
{
visitor.visit_newtype_struct(self)
}
fn deserialize_seq<V>(mut self, visitor: V) -> Result<V::Value>
where V: Visitor<'de>,
{
visitor.visit_seq(SequenceIterator::new(&mut self))
}
fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value>
where V: Visitor<'de>,
{
unimplemented!()
}
fn deserialize_tuple_struct<V>(
mut self,
_name: &'static str,
len: usize,
visitor: V,
) -> Result<V::Value>
where V: Visitor<'de>,
{
println!("{}", _name);
if _name == "VarInt" {
return visitor.visit_i32(self.parse_vi32()?)
}
visitor.visit_seq(TupleIterator::new(&mut self, len))
}
fn deserialize_map<V>(self, visitor: V) -> Result<V::Value>
where V: Visitor<'de>,
{
unimplemented!()
}
fn deserialize_struct<V>(
self,
_name: &'static str,
_fields: &'static [&'static str],
visitor: V,
) -> Result<V::Value>
where V: Visitor<'de>,
{
unimplemented!()
}
fn deserialize_enum<V>(
self,
_name: &'static str,
_variants: &'static [&'static str],
visitor: V,
) -> Result<V::Value>
where V: Visitor<'de>,
{
unimplemented!()
}
fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value>
where V: Visitor<'de>,
{
self.deserialize_str(visitor)
}
fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value>
where V: Visitor<'de>,
{
self.deserialize_any(visitor)
}
}
struct SequenceIterator<'a, 'de: 'a> {
de: &'a mut Deserializer<'de>
}
impl<'a, 'de> SequenceIterator<'a, 'de> {
fn new(de: &'a mut Deserializer<'de>) -> Self {
SequenceIterator {
de
}
}
}
impl<'de, 'a> SeqAccess<'de> for SequenceIterator<'a, 'de> {
type Error = Error;
fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
where
T: DeserializeSeed<'de>,
{
if self.de.input.position() == self.de.input.get_ref().len() as u64 {
return Ok(None);
}
seed.deserialize(&mut *self.de).map(Some)
}
}
struct TupleIterator<'a, 'de: 'a> {
de: &'a mut Deserializer<'de>,
pos: usize,
len: usize
}
impl<'a, 'de> TupleIterator<'a, 'de> {
fn new(de: &'a mut Deserializer<'de>, len: usize) -> Self {
TupleIterator {
de,
pos: 0,
len
}
}
}
impl<'de, 'a> SeqAccess<'de> for TupleIterator<'a, 'de> {
type Error = Error;
fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
where
T: DeserializeSeed<'de>,
{
if self.pos == self.len {
return Ok(None);
}
if self.de.input.position() == self.de.input.get_ref().len() as u64 {
return Err(Error::ExpectedArray);
}
self.pos += 1;
seed.deserialize(&mut *self.de).map(Some)
}
}
\ No newline at end of file
use std;
use std::fmt::{self, Display};
use serde::{de, ser};
pub type Result<T> = std::result::Result<T, Error>;
// This is a bare-bones implementation. A real library would provide additional
// information in its error type, for example the line and column at which the
// error occurred, the byte offset into the input, or the current key being
// processed.
#[derive(Clone, Debug, PartialEq)]
pub enum Error {
// One or more variants that can be created by data structures through the
// `ser::Error` and `de::Error` traits. For example the Serialize impl for
// Mutex<T> might return an error because the mutex is poisoned, or the
// Deserialize impl for a struct may return an error because a required
// field is missing.
Message(String),
// Zero or more variants that can be created directly by the Serializer and
// Deserializer without going through `ser::Error` and `de::Error`. These
// are specific to the format, in this case JSON.
Eof,
Syntax,
ExpectedBoolean,
ExpectedInteger,
ExpectedString,
ExpectedNull,
ExpectedArray,
ExpectedArrayComma,
ExpectedArrayEnd,
ExpectedMap,
ExpectedMapColon,
ExpectedMapComma,
ExpectedMapEnd,
ExpectedEnum,
TrailingCharacters,
}
impl ser::Error for Error {
fn custom<T: Display>(msg: T) -> Self {
Error::Message(msg.to_string())
}
}
impl de::Error for Error {
fn custom<T: Display>(msg: T) -> Self {
Error::Message(msg.to_string())
}
}
impl Display for Error {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str(std::error::Error::description(self))
}
}
impl std::error::Error for Error {
fn description(&self) -> &str {
match *self {
Error::Message(ref msg) => msg,
Error::Eof => "unexpected end of input",
/* and so forth */
_ => "Unknown"
}
}
}
\ No newline at end of file
pub mod client;
pub mod server;
mod de;
mod error;
pub use de::{from_vec, Deserializer};
pub use error::{Error, Result};
\ No newline at end of file
use serde::Deserialize;
#[derive(Deserialize)]
pub struct VarInt(
pub i32
);
/**
* 0x00 Handshake
* Causes the server to switch into the target state.
* -> Server::handshake
*/
#[derive(Deserialize)]
pub struct H00Handshake (
/// protocol
pub VarInt,
/// address
pub String,
/// port
pub u16,
/// state
pub VarInt
);
/**
* 0x00 Request
* Request for Server List Ping.