From 4efe1aaf362390875a2b5e5cdbab59e0cf9fb8e9 Mon Sep 17 00:00:00 2001 From: Lixfel Date: Wed, 2 Mar 2022 22:38:34 +0100 Subject: [PATCH] First runnable --- .gitignore | 1 + Cargo.lock | 365 ------------------------------------- Cargo.toml | 2 +- lixcraft-derive/src/lib.rs | 2 +- src/datatypes.rs | 236 ------------------------ src/deserializer.rs | 208 --------------------- src/main.rs | 131 +++++++++++++ src/serde.rs | 63 ++++--- src/serdemain.rs | 127 ------------- src/serializer.rs | 282 ---------------------------- 10 files changed, 167 insertions(+), 1250 deletions(-) delete mode 100644 Cargo.lock delete mode 100644 src/datatypes.rs delete mode 100644 src/deserializer.rs delete mode 100644 src/serdemain.rs delete mode 100644 src/serializer.rs diff --git a/.gitignore b/.gitignore index 795e8e4..fa2960b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /target *.iml /.idea +/Cargo.lock diff --git a/Cargo.lock b/Cargo.lock deleted file mode 100644 index 002637b..0000000 --- a/Cargo.lock +++ /dev/null @@ -1,365 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "Lixcraft-Proxy" -version = "0.1.0" -dependencies = [ - "bytes", - "lixcraft-derive", - "serde", - "serde_json", - "tokio", - "tokio-stream", - "tokio-util", -] - -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "bytes" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "futures-core" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3" - -[[package]] -name = "futures-sink" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868" - -[[package]] -name = "hermit-abi" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] - -[[package]] -name = "instant" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "itoa" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" - -[[package]] -name = "libc" -version = "0.2.112" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125" - -[[package]] -name = "lixcraft-derive" -version = "0.1.0" -dependencies = [ - "quote", - "syn", -] - -[[package]] -name = "lock_api" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712a4d093c9976e24e7dbca41db895dabcbac38eb5f4045393d17a95bdfb1109" -dependencies = [ - "scopeguard", -] - -[[package]] -name = "log" -version = "0.4.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "memchr" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" - -[[package]] -name = "mio" -version = "0.7.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8067b404fe97c70829f082dec8bcf4f71225d7eaea1d8645349cb76fa06205cc" -dependencies = [ - "libc", - "log", - "miow", - "ntapi", - "winapi", -] - -[[package]] -name = "miow" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21" -dependencies = [ - "winapi", -] - -[[package]] -name = "ntapi" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f6bb902e437b6d86e03cce10a7e2af662292c5dfef23b65899ea3ac9354ad44" -dependencies = [ - "winapi", -] - -[[package]] -name = "num_cpus" -version = "1.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" -dependencies = [ - "hermit-abi", - "libc", -] - -[[package]] -name = "once_cell" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5" - -[[package]] -name = "parking_lot" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" -dependencies = [ - "instant", - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" -dependencies = [ - "cfg-if", - "instant", - "libc", - "redox_syscall", - "smallvec", - "winapi", -] - -[[package]] -name = "pin-project-lite" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e280fbe77cc62c91527259e9442153f4688736748d24660126286329742b4c6c" - -[[package]] -name = "proc-macro2" -version = "1.0.36" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" -dependencies = [ - "unicode-xid", -] - -[[package]] -name = "quote" -version = "1.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47aa80447ce4daf1717500037052af176af5d38cc3e571d9ec1c7353fc10c87d" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "redox_syscall" -version = "0.2.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff" -dependencies = [ - "bitflags", -] - -[[package]] -name = "ryu" -version = "1.0.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" - -[[package]] -name = "scopeguard" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" - -[[package]] -name = "serde" -version = "1.0.136" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.136" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "serde_json" -version = "1.0.79" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e8d9fa5c3b304765ce1fd9c4c8a3de2c8db365a5b91be52f186efc675681d95" -dependencies = [ - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "signal-hook-registry" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" -dependencies = [ - "libc", -] - -[[package]] -name = "smallvec" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" - -[[package]] -name = "syn" -version = "1.0.85" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a684ac3dcd8913827e18cd09a68384ee66c1de24157e3c556c9ab16d85695fb7" -dependencies = [ - "proc-macro2", - "quote", - "unicode-xid", -] - -[[package]] -name = "tokio" -version = "1.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbbf1c778ec206785635ce8ad57fe52b3009ae9e0c9f574a728f3049d3e55838" -dependencies = [ - "bytes", - "libc", - "memchr", - "mio", - "num_cpus", - "once_cell", - "parking_lot", - "pin-project-lite", - "signal-hook-registry", - "tokio-macros", - "winapi", -] - -[[package]] -name = "tokio-macros" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b557f72f448c511a979e2564e55d74e6c4432fc96ff4f6241bc6bded342643b7" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "tokio-stream" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50145484efff8818b5ccd256697f36863f587da82cf8b409c53adf1e840798e3" -dependencies = [ - "futures-core", - "pin-project-lite", - "tokio", -] - -[[package]] -name = "tokio-util" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64910e1b9c1901aaf5375561e35b9c057d95ff41a44ede043a03e09279eabaf1" -dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "log", - "pin-project-lite", - "tokio", -] - -[[package]] -name = "unicode-xid" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/Cargo.toml b/Cargo.toml index 0d976a2..d620e32 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "Lixcraft-Proxy" +name = "lixcraft" version = "0.1.0" authors = ["Lixfel "] edition = "2018" diff --git a/lixcraft-derive/src/lib.rs b/lixcraft-derive/src/lib.rs index 00b8af5..878b2f8 100644 --- a/lixcraft-derive/src/lib.rs +++ b/lixcraft-derive/src/lib.rs @@ -86,6 +86,6 @@ pub fn derive_serializable(input: TokenStream) -> TokenStream { }, Fields::Unit => impl_serializable!(struct_ident, quote! { 0 }, quote! {}, quote! { #struct_ident {} }) }.into(); - println!("{}", result); + //println!("{}", result); result } \ No newline at end of file diff --git a/src/datatypes.rs b/src/datatypes.rs deleted file mode 100644 index dcf63b3..0000000 --- a/src/datatypes.rs +++ /dev/null @@ -1,236 +0,0 @@ -use std::fmt::{Formatter, Write}; -use std::ops::{Deref, DerefMut}; -use serde::{Deserialize, Deserializer, Serialize, Serializer}; -use serde::de::{EnumAccess, Error, MapAccess, SeqAccess, Visitor}; -use lixcraft_derive::Wrapper; - -#[derive(Copy, Clone, Debug, PartialEq, Eq, Wrapper)] -pub struct VarInt(pub i32); - -impl From for usize { - fn from(v: VarInt) -> Self { - v.0 as usize - } -} - -impl From for VarInt { - fn from(v: usize) -> Self { - VarInt(v as i32) - } -} - -impl Serialize for VarInt { - fn serialize(&self, serializer: S) -> Result where S: Serializer { - let mut v = self.0 as u32; - let mut result = Vec::with_capacity(5); - loop { - if v & 0x80 == 0 { - result.push(v as u8); - return serializer.serialize_bytes(&result); - } - - result.push((v as u8 & 0x7f) | 0x80); - v >>= 7; - } - } -} - -impl<'de> Deserialize<'de> for VarInt { - fn deserialize(deserializer: D) -> Result where D: Deserializer<'de> { - let mut num_read = 0; - let mut result = 0; - loop { - let read = (&mut *deserializer).deserialize_u8(VarIntVisitor{})?; - let value = i32::from(read & 0b0111_1111); - result |= value.overflowing_shl(7 * num_read).0; - - num_read += 1; - - if num_read > 5 { - return Err(D::Error::custom("VarInt too large")); - } - if read & 0b1000_0000 == 0 { - break; - } - } - Ok(VarInt(result)) - } -} - -#[derive(Debug)] -pub enum NextState { - Status, - Login -} - -impl Serialize for NextState { - fn serialize(&self, serializer: S) -> Result where S: Serializer { - VarInt::from(match self { - NextState::Status => 1, - NextState::Login => 2 - }).serialize(serializer) - } -} - -impl<'de> Deserialize<'de> for NextState { - fn deserialize(deserializer: D) -> Result where D: Deserializer<'de> { - match VarInt::deserialize(deserializer)? { - VarInt(1) => Ok(NextState::Status), - VarInt(2) => Ok(NextState::Login), - _ => Err(D::Error::custom("Invalid NextState")) - } - } -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct StatusResponseVersion { - pub name: String, - pub protocol: i32 -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct StatusResponseSample { - pub name: String, - pub id: String -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct StatusResponsePlayers { - pub max: i32, - pub online: i32, - pub sample: Vec -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct StatusResponseDescription { - pub text: String -} - -#[derive(Debug)] -pub struct StatusResponse { - pub version: StatusResponseVersion, - pub players: StatusResponsePlayers, - pub description: StatusResponseDescription, - //#[serde(skip_serializing_if = "Option::is_none")] - pub favicon: Option -} - -impl Serialize for StatusResponse { - fn serialize(&self, serializer: S) -> Result where S: Serializer { - serializer.serialize_str(&match serde_json::to_string(self) { - Ok(v) => v, - Err(_) => return Err(serde::ser::Error::custom("Could not serialize status response")) - }) - } -} - -impl<'de> Deserialize<'de> for StatusResponse { - fn deserialize(deserializer: D) -> Result where D: Deserializer<'de> { - match String::deserialize(deserializer) { - Ok(json) => match serde_json::from_str(&json) { - Ok(v) => Ok(v), - Err(_) => Err(D::Error::custom("Could not parse json status response")) - }, - Err(err) => Err(err) - } - } -} - -#[derive(Debug, Serialize, Deserialize)] -//TODO: Serialize, Deserialize -pub enum Font { - Uniform, //minecraft:uniform - Alt, //minecraft:alt - Default //minecraft:default -} - -#[derive(Debug, Serialize, Deserialize)] -pub enum ClickEventAction { - open_url, - run_command, - suggest_command, - change_page, - copy_to_clipboard -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct ClickEvent { - action: ClickEventAction, - value: String -} - -#[derive(Debug, Serialize, Deserialize)] -pub enum HoverEventAction { - show_text, - show_item, - show_entity -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct HoverEvent { - action: HoverEventAction, - value: String //or Chat (Recursion!) -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct SharedChat { - //#[serde(skip_serializing_if = "Option::is_none")] - bold: bool, - //#[serde(skip_serializing_if = "Option::is_none")] - italic: bool, - //#[serde(skip_serializing_if = "Option::is_none")] - underlined: bool, - //#[serde(skip_serializing_if = "Option::is_none")] - strikethrough: bool, - //#[serde(skip_serializing_if = "Option::is_none")] - obfuscated: bool, - //#[serde(skip_serializing_if = "Option::is_none")] - font: Font, - //#[serde(skip_serializing_if = "Option::is_none")] - color: String, //TODO Color code, format code or hex code - //#[serde(skip_serializing_if = "Option::is_none")] - insertion: String, - //#[serde(skip_serializing_if = "Option::is_none")] - clickEvent: ClickEvent, - //#[serde(skip_serializing_if = "Option::is_none")] - hoverEvent: HoverEvent, - //#[serde(skip_serializing_if = "Option::is_none")] - extra: Vec -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct Score { - name: String, //Or UUID - objective: String, - value: String -} - -#[derive(Debug, Serialize, Deserialize)] -//TODO: Serialize, Deserialize -pub enum Chat { - StringComponent { - #[serde(flatten)] - options: SharedChat, - text: String - }, - TranslationComponent { - #[serde(flatten)] - options: SharedChat, - translate: String //TODO Special strings - }, - KeybindComponent { - #[serde(flatten)] - options: SharedChat, - keybind: String - }, - ScoreComponent { - #[serde(flatten)] - options: SharedChat, - score: Score - }, - SelectorComponent { - #[serde(flatten)] - options: SharedChat, - selector: String //TODO ominous - } -} \ No newline at end of file diff --git a/src/deserializer.rs b/src/deserializer.rs deleted file mode 100644 index cb0292b..0000000 --- a/src/deserializer.rs +++ /dev/null @@ -1,208 +0,0 @@ -use std::fmt::{Debug, Display, Formatter}; -use bytes::{Buf, Bytes}; -use serde::de::{DeserializeSeed, Error, SeqAccess, StdError, Visitor}; -use serde::{Deserialize, Deserializer}; -use crate::datatypes::VarInt; - -#[derive(Copy, Clone, Debug)] -pub enum JavaDeserError { - UnexpectedEnd, - UnexpectedCustom, - InvalidValue -} - -impl Display for JavaDeserError { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - Debug::fmt(&self, f) - } -} - -impl StdError for JavaDeserError{} - -impl Error for JavaDeserError{ - fn custom(msg: T) -> Self where T: Display { - JavaDeserError::UnexpectedCustom - } -} - -pub struct JavaDeserializer { - input: Bytes -} - -impl JavaDeserializer { - pub fn from_bytes<'a, T: Deserialize<'a>>(data: Bytes) -> Result { - let mut deserializer = JavaDeserializer{input : data }; - T::deserialize(&mut deserializer) - } - - fn assert_remaining(&self, size: usize) -> Result<(), JavaDeserError> { - match self.input.remaining() >= size { - true => Ok(()), - false => Err(JavaDeserError::UnexpectedEnd) - } - } -} - -impl<'a, 'de> Deserializer<'de> for &'a mut JavaDeserializer { - type Error = JavaDeserError; - - fn deserialize_any(self, visitor: V) -> Result where V: Visitor<'de> { - panic!("Any not deserializable in Java protocol") - } - - fn deserialize_bool(self, visitor: V) -> Result where V: Visitor<'de> { - self.assert_remaining(1)?; - match self.input.get_u8() { - 0x00 => visitor.visit_bool(false), - 0x01 => visitor.visit_bool(true), - _ => Err(JavaDeserError::InvalidValue) - } - } - - fn deserialize_i8(self, visitor: V) -> Result where V: Visitor<'de> { - self.assert_remaining(1)?; - visitor.visit_i8(self.input.get_i8()) - } - - fn deserialize_i16(self, visitor: V) -> Result where V: Visitor<'de> { - self.assert_remaining(2)?; - visitor.visit_i16(self.input.get_i16()) - } - - fn deserialize_i32(self, visitor: V) -> Result where V: Visitor<'de> { - self.assert_remaining(4)?; - visitor.visit_i32(self.input.get_i32()) - } - - fn deserialize_i64(self, visitor: V) -> Result where V: Visitor<'de> { - self.assert_remaining(8)?; - visitor.visit_i64(self.input.get_i64()) - } - - fn deserialize_u8(self, visitor: V) -> Result where V: Visitor<'de> { - self.assert_remaining(1)?; - visitor.visit_u8(self.input.get_u8()) - } - - fn deserialize_u16(self, visitor: V) -> Result where V: Visitor<'de> { - self.assert_remaining(2)?; - visitor.visit_u16(self.input.get_u16()) - } - - fn deserialize_u32(self, visitor: V) -> Result where V: Visitor<'de> { - self.assert_remaining(4)?; - visitor.visit_u32(self.input.get_u32()) - } - - fn deserialize_u64(self, visitor: V) -> Result where V: Visitor<'de> { - self.assert_remaining(8)?; - visitor.visit_u64(self.input.get_u64()) - } - - fn deserialize_f32(self, visitor: V) -> Result where V: Visitor<'de> { - self.assert_remaining(4)?; - visitor.visit_f32(self.input.get_f32()) - } - - fn deserialize_f64(self, visitor: V) -> Result where V: Visitor<'de> { - self.assert_remaining(8)?; - visitor.visit_f64(self.input.get_f64()) - } - - fn deserialize_char(self, visitor: V) -> Result where V: Visitor<'de> { - panic!("Char not deserializable in Java protocol") - } - - fn deserialize_str(self, visitor: V) -> Result where V: Visitor<'de> { - self.deserialize_string(visitor) - } - - fn deserialize_string(self, visitor: V) -> Result where V: Visitor<'de> { - let size = VarInt::deserialize(&mut *self)?; - if *size > 32767 { - return Err(JavaDeserError::InvalidValue) - } - - self.assert_remaining(usize::from(size))?; - visitor.visit_string(match String::from_utf8(self.input.copy_to_bytes(usize::from(size)).to_vec()) { - Ok(v) => v, - Err(_) => return Err(JavaDeserError::InvalidValue) - }) - } - - fn deserialize_bytes(self, visitor: V) -> Result where V: Visitor<'de> { - panic!("Bytes not deserializable in Java protocol") - } - - fn deserialize_byte_buf(self, visitor: V) -> Result where V: Visitor<'de> { - panic!("Byte buf not deserializable in Java protocol") - } - - fn deserialize_option(self, visitor: V) -> Result where V: Visitor<'de> { - panic!("Option not deserializable in Java protocol") - } - - fn deserialize_unit(self, visitor: V) -> Result where V: Visitor<'de> { - panic!("Unit not deserializable in Java protocol") - } - - fn deserialize_unit_struct(self, name: &'static str, visitor: V) -> Result where V: Visitor<'de> { - panic!("Unit struct not deserializable in Java protocol") - } - - fn deserialize_newtype_struct(self, name: &'static str, visitor: V) -> Result where V: Visitor<'de> { - visitor.visit_newtype_struct(self) - } - - fn deserialize_seq(self, visitor: V) -> Result where V: Visitor<'de> { - let size = VarInt::deserialize(&mut *self)?; - visitor.visit_seq(KnownLengthSeq { de: self, remaining: usize::from(size) }) - } - - fn deserialize_tuple(self, len: usize, visitor: V) -> Result where V: Visitor<'de> { - visitor.visit_seq(KnownLengthSeq { de: self, remaining: len }) - } - - fn deserialize_tuple_struct(self, name: &'static str, len: usize, visitor: V) -> Result where V: Visitor<'de> { - panic!("Tuple struct not deserializable in Java protocol") - } - - fn deserialize_map(self, visitor: V) -> Result where V: Visitor<'de> { - panic!("Map not deserializable in Java protocol") - } - - fn deserialize_struct(self, name: &'static str, fields: &'static [&'static str], visitor: V) -> Result where V: Visitor<'de> { - panic!("Struct (missing #[serde(flatten)]?) not deserializable in Java protocol") - } - - fn deserialize_enum(self, name: &'static str, variants: &'static [&'static str], visitor: V) -> Result where V: Visitor<'de> { - panic!("Enum not deserializable in Java protocol") - } - - fn deserialize_identifier(self, visitor: V) -> Result where V: Visitor<'de> { - panic!("Identifier not deserializable in Java protocol") - } - - fn deserialize_ignored_any(self, visitor: V) -> Result where V: Visitor<'de> { - panic!("Ignored any not deserializable in Java protocol") - } -} - -struct KnownLengthSeq<'a> { - de: &'a mut JavaDeserializer, - remaining: usize -} - -impl<'de, 'a> SeqAccess<'de> for KnownLengthSeq<'a> { - type Error = <&'a mut JavaDeserializer as Deserializer<'de>>::Error; - - fn next_element_seed(&mut self, seed: T) -> Result, Self::Error> where T: DeserializeSeed<'de> { - match self.remaining { - 0 => Ok(None), - _ => { - self.remaining -= 1; - seed.deserialize(&mut *self.de).map(Some) - } - } - } -} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 10f8043..c3553f4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,8 +4,139 @@ pub mod serde; mod packets; use std::error::Error; +use std::io::ErrorKind; +use std::net::SocketAddr; +use bytes::{Buf, BufMut, Bytes, BytesMut}; +use tokio::net::{TcpListener, TcpStream}; +use tokio_stream::StreamExt; +use tokio_util::codec::{Decoder, Encoder, Framed}; +use crate::packets::handshake::HandshakePacket; +use crate::serde::{JavaSerializable, VarInt}; #[tokio::main] async fn main() -> Result<(), Box> { + let listen_addr = String::from("127.0.0.1:25565"); + + println!("Listening on: {}", listen_addr); + + let listener = TcpListener::bind(listen_addr).await?; + + while let Ok((inbound, addr)) = listener.accept().await { + tokio::spawn(async move {process_initial(inbound, addr)}.await); + } + Ok(()) +} + + +async fn process_initial(stream: TcpStream, _addr: SocketAddr) { + let mut framed = Framed::new(stream, LengthPrefixedFrame {max_length: 263}); + match framed.next().await { + Some(Ok(buf)) => { + let mut buf = buf.freeze(); + match VarInt::deserialize(&mut buf) { + Ok(VarInt(0)) => { + match HandshakePacket::deserialize(&mut buf) { + Ok(v) => println!("Error: {:?}", v), + Err(e) => println!("Error: {:?}", e) + } + }, + Ok(VarInt(v)) => println!("Error: {}", v), + Err(e) => println!("Error: {:?}", e) + } + }, + Some(Err(e)) => println!("Error: {:?}", e), + None => {} + } +} + + +enum VarIntReadError { + BytesMissing, + InvalidData +} + +pub struct LengthPrefixedFrame { + pub max_length: usize +} + +impl LengthPrefixedFrame { + fn try_read_var_int(&self, src: &mut BytesMut) -> Result<(VarInt, usize), VarIntReadError> { + let src = src.chunk(); + let mut num_read = 0; + let mut result = 0; + loop { + if src.len() <= num_read { + return Err(VarIntReadError::BytesMissing) + } + let read = src[num_read]; + let value = i32::from(read & 0b0111_1111); + result |= value.overflowing_shl((7 * num_read) as u32).0; + + num_read += 1; + + if num_read > 5 { + return Err(VarIntReadError::InvalidData); + } + if read & 0b1000_0000 == 0 { + return if result as usize > self.max_length { + Err(VarIntReadError::InvalidData) + } else { + Ok((VarInt(result), num_read)) + } + } + } + } +} + +impl Decoder for LengthPrefixedFrame { + type Item = BytesMut; + type Error = tokio::io::Error; + + fn decode(&mut self, src: &mut BytesMut) -> Result, Self::Error> { + println!("!"); + match self.try_read_var_int(src) { + Ok((length, prefix_length)) => { + let total_length = prefix_length + usize::from(length); + + if src.len() >= total_length { + src.advance(prefix_length); + println!("a1"); + Ok(Some(src.split_to(usize::from(length)))) + } else { + println!("a2"); + Ok(None) + } + }, + Err(VarIntReadError::BytesMissing) => { + println!("b"); + Ok(None) + }, + Err(VarIntReadError::InvalidData) => { + println!("c"); + Err(tokio::io::Error::from(ErrorKind::InvalidData)) + } + } + } +} +impl Encoder for LengthPrefixedFrame { + type Error = tokio::io::Error; + + fn encode(&mut self, data: Bytes, dst: &mut BytesMut) -> Result<(), Self::Error> { + dst.reserve(5 + data.len()); + + let mut v = data.len(); + loop { + if v & 0x80 == 0 { + dst.put_u8(v as u8); + break; + } + + dst.put_u8((v as u8 & 0x7f) | 0x80); + v >>= 7; + } + + dst.put_slice(&data); + Ok(()) + } } \ No newline at end of file diff --git a/src/serde.rs b/src/serde.rs index 849d11a..8d543b4 100644 --- a/src/serde.rs +++ b/src/serde.rs @@ -4,6 +4,7 @@ use crate::serde::JavaDeserError::{InvalidValue, MissingBytes}; pub use lixcraft_derive::JavaSerializable; +#[derive(Debug)] pub enum JavaDeserError { InvalidValue, MissingBytes @@ -340,12 +341,13 @@ pub enum Font { } #[derive(Debug, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "snake_case")] pub enum ClickEventAction { - open_url, - run_command, - suggest_command, - change_page, - copy_to_clipboard + OpenUrl, + RunCommand, + SuggestCommand, + ChangePage, + CopyToClipboard } #[derive(Debug, serde::Serialize, serde::Deserialize)] @@ -355,10 +357,11 @@ pub struct ClickEvent { } #[derive(Debug, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "snake_case")] pub enum HoverEventAction { - show_text, - show_item, - show_entity + ShowText, + ShowItem, + ShowEntity } #[derive(Debug, serde::Serialize, serde::Deserialize)] @@ -369,28 +372,28 @@ pub struct HoverEvent { #[derive(Debug, serde::Serialize, serde::Deserialize)] pub struct SharedChat { - //#[serde(skip_serializing_if = "Option::is_none")] - bold: bool, - //#[serde(skip_serializing_if = "Option::is_none")] - italic: bool, - //#[serde(skip_serializing_if = "Option::is_none")] - underlined: bool, - //#[serde(skip_serializing_if = "Option::is_none")] - strikethrough: bool, - //#[serde(skip_serializing_if = "Option::is_none")] - obfuscated: bool, - //#[serde(skip_serializing_if = "Option::is_none")] - font: Font, - //#[serde(skip_serializing_if = "Option::is_none")] - color: String, //TODO Color code, format code or hex code - //#[serde(skip_serializing_if = "Option::is_none")] - insertion: String, - //#[serde(skip_serializing_if = "Option::is_none")] - clickEvent: ClickEvent, - //#[serde(skip_serializing_if = "Option::is_none")] - hoverEvent: HoverEvent, - //#[serde(skip_serializing_if = "Option::is_none")] - extra: Vec + #[serde(skip_serializing_if = "Option::is_none")] + bold: Option, + #[serde(skip_serializing_if = "Option::is_none")] + italic: Option, + #[serde(skip_serializing_if = "Option::is_none")] + underlined: Option, + #[serde(skip_serializing_if = "Option::is_none")] + strikethrough: Option, + #[serde(skip_serializing_if = "Option::is_none")] + obfuscated: Option, + #[serde(skip_serializing_if = "Option::is_none")] + font: Option, + #[serde(skip_serializing_if = "Option::is_none")] + color: Option, //TODO Color code, format code or hex code + #[serde(skip_serializing_if = "Option::is_none")] + insertion: Option, + #[serde(skip_serializing_if = "Option::is_none", rename = "clickEvent")] + click_event: Option, + #[serde(skip_serializing_if = "Option::is_none", rename = "hoverEvent")] + hover_event: Option, + #[serde(skip_serializing_if = "Option::is_none")] + extra: Option> } #[derive(Debug, serde::Serialize, serde::Deserialize)] diff --git a/src/serdemain.rs b/src/serdemain.rs deleted file mode 100644 index 1cb4dc4..0000000 --- a/src/serdemain.rs +++ /dev/null @@ -1,127 +0,0 @@ -extern crate core; - -mod serializer; -mod datatypes; -mod deserializer; -mod packets; -mod ser; - -use tokio::net::{TcpListener, TcpStream}; -use tokio_stream::StreamExt; - -use std::error::Error; -use std::io::ErrorKind; -use std::net::SocketAddr; -use bytes::{Buf, BufMut, Bytes, BytesMut}; -use tokio_util::codec::{Decoder, Encoder, Framed}; -use crate::datatypes::VarInt; -use crate::deserializer::JavaDeserializer; -use crate::packets::handshake::HandshakePacket; - -#[tokio::main] -async fn main() -> Result<(), Box> { - let listen_addr = String::from("127.0.0.1:25565"); - - println!("Listening on: {}", listen_addr); - - let listener = TcpListener::bind(listen_addr).await?; - - while let Ok((inbound, addr)) = listener.accept().await { - tokio::spawn(async move {process_initial(inbound, addr)}); - } - - Ok(()) -} - -async fn process_initial(stream: TcpStream, addr: SocketAddr) { - let mut framed = Framed::new(stream, LengthPrefixedFrame {}); - match framed.next().await { - Some(Ok(buf)) => { - match JavaDeserializer::from_bytes(buf.freeze()) { - Ok(v) => { - let v: HandshakePacket = v; - println!("{:?}", v); - }, - Err(_) => {} - } - }, - None | Some(Err(_)) => {} - } -} - - -enum VarIntReadError { - BytesMissing, - InvalidData -} - -pub struct LengthPrefixedFrame {}//TODO: Max expected length - -impl LengthPrefixedFrame { - fn try_read_var_int(src: &mut BytesMut) -> Result<(VarInt, usize), VarIntReadError> { - let src = src.chunk(); - let mut num_read = 0; - let mut result = 0; - loop { - if src.len() <= num_read { - return Err(VarIntReadError::BytesMissing) - } - let read = src[num_read]; - let value = i32::from(read & 0b0111_1111); - result |= value.overflowing_shl((7 * num_read) as u32).0; - - num_read += 1; - - if num_read > 5 { - return Err(VarIntReadError::InvalidData); - } - if read & 0b1000_0000 == 0 { - break; - } - } - Ok((VarInt(result), num_read)) - } -} - -impl Decoder for LengthPrefixedFrame { - type Item = BytesMut; - type Error = tokio::io::Error; - - fn decode(&mut self, src: &mut BytesMut) -> Result, Self::Error> { - match LengthPrefixedFrame::try_read_var_int(src) { - Ok((length, prefix_length)) => { - let total_length = prefix_length + usize::from(length); - - if src.len() >= total_length { - src.advance(prefix_length); - Ok(Some(src.split_to(usize::from(length)))) - } else { - Ok(None) - } - }, - Err(VarIntReadError::BytesMissing) => Ok(None), - Err(VarIntReadError::InvalidData) => Err(tokio::io::Error::from(ErrorKind::InvalidData)) - } - } -} -impl Encoder for LengthPrefixedFrame { - type Error = tokio::io::Error; - - fn encode(&mut self, data: Bytes, dst: &mut BytesMut) -> Result<(), Self::Error> { - dst.reserve(5 + data.len()); - - let mut v = data.len(); - loop { - if v & 0x80 == 0 { - dst.put_u8(v as u8); - break; - } - - dst.put_u8((v as u8 & 0x7f) | 0x80); - v >>= 7; - } - - dst.put_slice(&data); - Ok(()) - } -} \ No newline at end of file diff --git a/src/serializer.rs b/src/serializer.rs deleted file mode 100644 index 8ab7eaf..0000000 --- a/src/serializer.rs +++ /dev/null @@ -1,282 +0,0 @@ -use std::fmt::{Debug, Display, Formatter}; -use bytes::{BufMut, BytesMut}; -use serde::{Serialize, Serializer}; -use serde::ser::{SerializeMap, SerializeSeq, SerializeStruct, SerializeStructVariant, SerializeTuple, SerializeTupleStruct, SerializeTupleVariant, StdError}; -use crate::datatypes::VarInt; - -#[derive(Copy, Clone, Debug)] -struct JavaSerError(); - -impl StdError for JavaSerError {} - -impl Display for JavaSerError { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - Debug::fmt(&self, f) - } -} - -impl serde::ser::Error for JavaSerError { - fn custom(msg: T) -> Self where T: Display { - JavaSerError() - } -} - -pub struct JavaSerializer { - output: BytesMut -} - -impl JavaSerializer { - pub fn serialize(value: &T) -> BytesMut { - let mut serializer = JavaSerializer { - output: BytesMut::with_capacity(256) - }; - - match value.serialize(&mut serializer) { - Ok(()) => serializer.output, - Err(_) => panic!("Serialization error") - } - } -} - -impl<'a> Serializer for &'a mut JavaSerializer { - type Ok = (); - type Error = JavaSerError; - type SerializeSeq = Self; - type SerializeTuple = Self; - type SerializeTupleStruct = Self; - type SerializeTupleVariant = Self; - type SerializeMap = Self; - type SerializeStruct = Self; - type SerializeStructVariant = Self; - - fn serialize_bool(self, v: bool) -> Result { - match v { - true => self.output.put_u8(0x00), - false => self.output.put_u8(0x01), - }; - Ok(()) - } - - fn serialize_i8(self, v: i8) -> Result { - self.output.put_i8(v); - Ok(()) - } - - fn serialize_i16(self, v: i16) -> Result { - self.output.put_i16(v); - Ok(()) - } - - fn serialize_i32(self, v: i32) -> Result { - self.output.put_i32(v); - Ok(()) - } - - fn serialize_i64(self, v: i64) -> Result { - self.output.put_i64(v); - Ok(()) - } - - fn serialize_u8(self, v: u8) -> Result { - self.output.put_u8(v); - Ok(()) - } - - fn serialize_u16(self, v: u16) -> Result { - self.output.put_u16(v); - Ok(()) - } - - fn serialize_u32(self, v: u32) -> Result { - self.output.put_u32(v); - Ok(()) - } - - fn serialize_u64(self, v: u64) -> Result { - self.output.put_u64(v); - Ok(()) - } - - fn serialize_f32(self, v: f32) -> Result { - self.output.put_f32(v); - Ok(()) - } - - fn serialize_f64(self, v: f64) -> Result { - self.output.put_f64(v); - Ok(()) - } - - fn serialize_char(self, v: char) -> Result { - panic!("Char not serializable in Java protocol") - } - - fn serialize_str(self, v: &str) -> Result { - let v = v.as_bytes(); - VarInt::serialize(&VarInt::from(v.len()), &mut *self)?; - self.serialize_bytes(v) - } - - fn serialize_bytes(self, v: &[u8]) -> Result { - self.output.put_slice(v); - Ok(()) - } - - fn serialize_none(self) -> Result { - Ok(()) - } - - fn serialize_some(self, value: &T) -> Result where T: Serialize { - value.serialize(self) - } - - fn serialize_unit(self) -> Result { - panic!("Unit not serializable in Java protocol") - } - - fn serialize_unit_struct(self, name: &'static str) -> Result { - panic!("Unit struct not serializable in Java protocol") - } - - fn serialize_unit_variant(self, name: &'static str, variant_index: u32, variant: &'static str) -> Result { - panic!("Variant not serializable in Java protocol") - //VarInt::from(variant_index as i32).serialize(self) - } - - fn serialize_newtype_struct(self, name: &'static str, value: &T) -> Result where T: Serialize { - value.serialize(self) - } - - fn serialize_newtype_variant(self, name: &'static str, variant_index: u32, variant: &'static str, value: &T) -> Result where T: Serialize { - panic!("Newtype variant not serializable in Java protocol") - //VarInt::from(variant_index as i32).serialize(self)?; - //value.serialize(self) - } - - fn serialize_seq(self, len: Option) -> Result { - match len { - Some(v) => VarInt::from(v).serialize(&mut *self)?, - None => () - } - Ok(self) - } - - fn serialize_tuple(self, len: usize) -> Result { - panic!("Tuple not serializable in Java protocol") - } - - fn serialize_tuple_struct(self, name: &'static str, len: usize) -> Result { - panic!("Tuple struct not serializable in Java protocol") - } - - fn serialize_tuple_variant(self, name: &'static str, variant_index: u32, variant: &'static str, len: usize) -> Result { - panic!("Tuple struct variant not serializable in Java protocol") - } - - fn serialize_map(self, len: Option) -> Result { - panic!("Maps not serializable in Java protocol") - } - - fn serialize_struct(self, name: &'static str, len: usize) -> Result { - Ok(self) - } - - fn serialize_struct_variant(self, name: &'static str, variant_index: u32, variant: &'static str, len: usize) -> Result { - panic!("Struct variant not serializable in Java protocol") - } -} - -impl<'a> SerializeSeq for &'a mut JavaSerializer { - type Ok = <&'a mut JavaSerializer as Serializer>::Ok; - type Error = <&'a mut JavaSerializer as Serializer>::Error; - - fn serialize_element(&mut self, value: &T) -> Result<(), Self::Error> where T: Serialize { - value.serialize(&mut **self) - } - - fn end(self) -> Result { - Ok(()) - } -} - -impl<'a> SerializeStruct for &'a mut JavaSerializer { - type Ok = <&'a mut JavaSerializer as Serializer>::Ok; - type Error = <&'a mut JavaSerializer as Serializer>::Error; - - fn serialize_field(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error> where T: Serialize { - value.serialize(&mut **self) - } - - fn end(self) -> Result { - Ok(()) - } -} - -impl<'a> SerializeTuple for &'a mut JavaSerializer { - type Ok = <&'a mut JavaSerializer as Serializer>::Ok; - type Error = <&'a mut JavaSerializer as Serializer>::Error; - - fn serialize_element(&mut self, value: &T) -> Result<(), Self::Error> where T: Serialize { - panic!("Tuple not serializable in Java protocol") - } - - fn end(self) -> Result { - panic!("Tuple not serializable in Java protocol") - } -} - -impl<'a> SerializeTupleStruct for &'a mut JavaSerializer { - type Ok = <&'a mut JavaSerializer as Serializer>::Ok; - type Error = <&'a mut JavaSerializer as Serializer>::Error; - - fn serialize_field(&mut self, value: &T) -> Result<(), Self::Error> where T: Serialize { - panic!("Tuple struct not serializable in Java protocol") - } - - fn end(self) -> Result { - panic!("Tuple struct not serializable in Java protocol") - } -} - -impl<'a> SerializeTupleVariant for &'a mut JavaSerializer { - type Ok = <&'a mut JavaSerializer as Serializer>::Ok; - type Error = <&'a mut JavaSerializer as Serializer>::Error; - - fn serialize_field(&mut self, value: &T) -> Result<(), Self::Error> where T: Serialize { - panic!("Tuple variant not serializable in Java protocol") - } - - fn end(self) -> Result { - panic!("Tuple variant not serializable in Java protocol") - } -} - -impl<'a> SerializeMap for &'a mut JavaSerializer { - type Ok = <&'a mut JavaSerializer as Serializer>::Ok; - type Error = <&'a mut JavaSerializer as Serializer>::Error; - - fn serialize_key(&mut self, key: &T) -> Result<(), Self::Error> where T: Serialize { - panic!("Map not serializable in Java protocol") - } - - fn serialize_value(&mut self, value: &T) -> Result<(), Self::Error> where T: Serialize { - panic!("Map not serializable in Java protocol") - } - - fn end(self) -> Result { - panic!("Map not serializable in Java protocol") - } -} - -impl<'a> SerializeStructVariant for &'a mut JavaSerializer { - type Ok = <&'a mut JavaSerializer as Serializer>::Ok; - type Error = <&'a mut JavaSerializer as Serializer>::Error; - - fn serialize_field(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error> where T: Serialize { - panic!("Struct variant not serializable in Java protocol") - } - - fn end(self) -> Result { - panic!("Struct variant not serializable in Java protocol") - } -} \ No newline at end of file