1
0

Pre serde-delete

Dieser Commit ist enthalten in:
Lixfel 2022-03-02 21:58:17 +01:00
Ursprung b48c214318
Commit 00befafc33
12 geänderte Dateien mit 1043 neuen und 186 gelöschten Zeilen

39
Cargo.lock generiert
Datei anzeigen

@ -11,6 +11,8 @@ dependencies = [
"serde",
"serde_json",
"tokio",
"tokio-stream",
"tokio-util",
]
[[package]]
@ -31,6 +33,18 @@ 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"
@ -297,6 +311,31 @@ dependencies = [
"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"

Datei anzeigen

@ -6,7 +6,9 @@ edition = "2018"
[dependencies]
tokio = { version = "1.15", features = ["full"] }
tokio-util = { version = "0.7", features = ["codec"] }
tokio-stream = "0.1"
serde = { version = "1.0", features = ["derive", "std"] }
bytes = "1.1"
serde_json = "1.0"
lixcraft-derive = { path = "lixcraft-derive" }
bytes = "1.1"
lixcraft-derive = { path = "lixcraft-derive" }

Datei anzeigen

@ -9,4 +9,4 @@ proc-macro = true
[dependencies]
syn = { version = "1.0", features = ["full"] }
quote = "1.0"
quote = "1.0"

Datei anzeigen

@ -1,55 +1,91 @@
use proc_macro::TokenStream;
use syn::{Data, DeriveInput, parse_macro_input};
use syn::{Data, DeriveInput, Fields, parse_macro_input};
use quote::quote;
#[proc_macro_derive(Wrapper)]
pub fn derive_wrapper(input: TokenStream) -> TokenStream {
macro_rules! iter_named_fields {
($f:expr, $m:expr, $r:expr) => {
$f.iter().map(|field| {
let ty = &field.ty;
let ident = &field.ident.as_ref().unwrap();
$m(ty, ident)
}).reduce($r).unwrap_or_default()
}
}
macro_rules! iter_unnamed_fields {
($f:expr, $m:expr, $r:expr) => {
$f.iter().enumerate().map(|(id, field)| {
let ty = &field.ty;
$m(ty, id)
}).reduce($r).unwrap_or_default()
}
}
macro_rules! impl_serializable {
($struct_ident:expr, $size:expr, $serialize:expr, $deserialize:expr) => {
{
let struct_ident = $struct_ident;
let mut size = $size;
if size.is_empty() {
size = quote!{ 0 }
}
let serialize = $serialize;
let deserialize = $deserialize;
quote!{
impl JavaSerializable for #struct_ident {
fn size_in_bytes(&self) -> usize {
#size
}
fn serialize(&self, buf: &mut bytes::BytesMut) {
#serialize
}
fn deserialize(buf: &mut bytes::Bytes) -> Result<Self, crate::serde::JavaDeserError> {
Ok(#deserialize)
}
}
}
}
}
}
#[proc_macro_derive(JavaSerializable)]
pub fn derive_serializable(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput);
let ident = &input.ident;
let struct_ident = &input.ident;
match &input.data {
Data::Struct(s) => {
if s.fields.len() != 1 {
panic!("#[derive(Wrapper)] only usable with one value")
}
for field in s.fields.iter() {
if field.ident.is_some() {
panic!("#[derive(Wrapper)] only usable on newtype structs")
}
let s = match &input.data {
Data::Struct(s) => s,
_ => panic!("#[derive(JavaSerializable)] currently only usable on structs")
};
let field_type = &field.ty;
let output = quote!{
impl From<#ident> for #field_type {
fn from(v: #ident) -> Self {
v.0
}
}
impl Deref for #ident {
type Target = #field_type;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl DerefMut for #ident {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl From<#field_type> for #ident {
fn from(v: #field_type) -> Self {
#ident(v)
}
}
};
return output.into();
}
panic!("Unreachable")
let result = match &s.fields {
Fields::Named(named) => {
let fields = &named.named;
fields.iter().map(|field| {
let ty = &field.ty;
let ident = &field.ident.as_ref().unwrap();
quote!{ #ident: #ty::deserialize(buf)? }
}).reduce(|a, b| quote!{ #a, #b }).unwrap_or_default();
let (size_in_bytes, serialize, deserialize) = (
iter_named_fields!(fields, |_, ident| quote!{ self.#ident.size_in_bytes() }, |a, b| quote!{ #a + #b }),
iter_named_fields!(fields, |_, ident| quote!{ self.#ident.serialize(buf); }, |a, b| quote!{ #a #b }),
iter_named_fields!(fields, |ty, ident| quote!{ #ident: #ty::deserialize(buf)? }, |a, b| quote!{ #a, #b })
);
impl_serializable!(struct_ident, size_in_bytes, serialize, quote! { #struct_ident {#deserialize} })
},
_ => panic!("#[derive(Wrapper)] only usable on structs")
}
Fields::Unnamed(unnamed) => {
let fields = &unnamed.unnamed;
let (size_in_bytes, serialize, deserialize) = (
iter_unnamed_fields!(fields, |_, ident| quote!{ self.#ident.size_in_bytes() }, |a, b| quote!{ #a + #b }),
iter_unnamed_fields!(fields, |_, ident| quote!{ self.#ident.serialize(buf); }, |a, b| quote!{ #a #b }),
iter_unnamed_fields!(fields, |ty, _| quote!{ #ty::deserialize(buf)? }, |a, b| quote!{ #a, #b })
);
impl_serializable!(struct_ident, size_in_bytes, serialize, quote! { #struct_ident (#deserialize) })
},
Fields::Unit => impl_serializable!(struct_ident, quote! { 0 }, quote! {}, quote! { #struct_ident {} })
}.into();
println!("{}", result);
result
}

Datei anzeigen

@ -1,6 +1,7 @@
use std::fmt::{Formatter, Write};
use std::ops::{Deref, DerefMut};
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use serde::de::Error;
use serde::de::{EnumAccess, Error, MapAccess, SeqAccess, Visitor};
use lixcraft_derive::Wrapper;
#[derive(Copy, Clone, Debug, PartialEq, Eq, Wrapper)]
@ -21,12 +22,14 @@ impl From<usize> for VarInt {
impl Serialize for VarInt {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer {
let mut v = self.0 as u32;
let mut result = Vec::with_capacity(5);
loop {
if v & 0x80 == 0 {
return serializer.serialize_u8(v as u8);
result.push(v as u8);
return serializer.serialize_bytes(&result);
}
serializer.serialize_u8((v as u8 & 0x7f) | 0x80)?;
result.push((v as u8 & 0x7f) | 0x80);
v >>= 7;
}
}
@ -37,7 +40,7 @@ impl<'de> Deserialize<'de> for VarInt {
let mut num_read = 0;
let mut result = 0;
loop {
let read = u8::deserialize(deserializer)?;
let read = (&mut *deserializer).deserialize_u8(VarIntVisitor{})?;
let value = i32::from(read & 0b0111_1111);
result |= value.overflowing_shl(7 * num_read).0;
@ -81,35 +84,35 @@ impl<'de> Deserialize<'de> for NextState {
#[derive(Debug, Serialize, Deserialize)]
pub struct StatusResponseVersion {
name: String,
protocol: i32
pub name: String,
pub protocol: i32
}
#[derive(Debug, Serialize, Deserialize)]
pub struct StatusResponseSample {
name: String,
id: String
pub name: String,
pub id: String
}
#[derive(Debug, Serialize, Deserialize)]
pub struct StatusResponsePlayers {
max: i32,
online: i32,
sample: Vec<StatusResponseSample>
pub max: i32,
pub online: i32,
pub sample: Vec<StatusResponseSample>
}
#[derive(Debug, Serialize, Deserialize)]
pub struct StatusResponseDescription {
text: String
pub text: String
}
#[derive(Debug)]
pub struct StatusResponse {
version: StatusResponseVersion,
players: StatusResponsePlayers,
description: StatusResponseDescription,
pub version: StatusResponseVersion,
pub players: StatusResponsePlayers,
pub description: StatusResponseDescription,
//#[serde(skip_serializing_if = "Option::is_none")]
favicon: Option<String>
pub favicon: Option<String>
}
impl Serialize for StatusResponse {
@ -131,4 +134,103 @@ impl<'de> Deserialize<'de> for StatusResponse {
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<Chat>
}
#[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
}
}

Datei anzeigen

@ -30,6 +30,10 @@ pub struct JavaDeserializer {
}
impl JavaDeserializer {
pub fn from_bytes<'a, T: Deserialize<'a>>(data: Bytes) -> Result<T, JavaDeserError> {
let mut deserializer = JavaDeserializer{input : data };
T::deserialize(&mut deserializer)
}
fn assert_remaining(&self, size: usize) -> Result<(), JavaDeserError> {
match self.input.remaining() >= size {
@ -114,7 +118,7 @@ impl<'a, 'de> Deserializer<'de> for &'a mut JavaDeserializer {
}
fn deserialize_string<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> {
let size = VarInt::deserialize(self)?;
let size = VarInt::deserialize(&mut *self)?;
if *size > 32767 {
return Err(JavaDeserError::InvalidValue)
}
@ -151,12 +155,12 @@ impl<'a, 'de> Deserializer<'de> for &'a mut JavaDeserializer {
}
fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> {
let size = VarInt::deserialize(self)?;
visitor.visit_seq(LengthPrefixedSeq { de: self, remaining: usize::from(size) })
let size = VarInt::deserialize(&mut *self)?;
visitor.visit_seq(KnownLengthSeq { de: self, remaining: usize::from(size) })
}
fn deserialize_tuple<V>(self, len: usize, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> {
panic!("Tuple not deserializable in Java protocol")
visitor.visit_seq(KnownLengthSeq { de: self, remaining: len })
}
fn deserialize_tuple_struct<V>(self, name: &'static str, len: usize, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> {
@ -184,12 +188,12 @@ impl<'a, 'de> Deserializer<'de> for &'a mut JavaDeserializer {
}
}
struct LengthPrefixedSeq<'a> {
struct KnownLengthSeq<'a> {
de: &'a mut JavaDeserializer,
remaining: usize
}
impl<'de, 'a> SeqAccess<'de> for LengthPrefixedSeq<'a> {
impl<'de, 'a> SeqAccess<'de> for KnownLengthSeq<'a> {
type Error = <&'a mut JavaDeserializer as Deserializer<'de>>::Error;
fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error> where T: DeserializeSeed<'de> {
@ -197,7 +201,7 @@ impl<'de, 'a> SeqAccess<'de> for LengthPrefixedSeq<'a> {
0 => Ok(None),
_ => {
self.remaining -= 1;
seed.deserialize(self.de).map(Some)
seed.deserialize(&mut *self.de).map(Some)
}
}
}

Datei anzeigen

@ -1,103 +1,11 @@
extern crate core;
mod serializer;
mod datatypes;
mod deserializer;
pub mod serde;
mod packets;
use tokio::io::{AsyncRead};
use tokio::net::{TcpListener, TcpStream};
use std::error::Error;
use std::sync::Arc;
use tokio::net::tcp::{OwnedReadHalf, OwnedWriteHalf};
use async_trait::async_trait;
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
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 {
//TODO
}
Ok(())
}
pub struct Stoppable {
interruptor: tokio::sync::oneshot::Receiver<bool>,
interrupted: tokio::sync::oneshot::Sender<bool>
}
pub struct Stopper {
interruptable: tokio::sync::oneshot::Sender<bool>,
interrupted: tokio::sync::oneshot::Receiver<bool>
}
impl Stopper {
pub fn new() -> (Stopper, Stoppable) {
let (interruptable, interruptor) = tokio::sync::oneshot::channel();
let (interrupted_s, interrupted_r) = tokio::sync::oneshot::channel();
(Stopper {interruptable, interrupted: interrupted_r}, Stoppable {interruptor, interrupted: interrupted_s})
}
pub async fn stop(&mut self) {
if self.interruptable.is_closed() {
return;
}
self.interruptable.send(true).unwrap_or_default();
self.interrupted.await.expect_err("Send on Stopper.interrupted occured");
}
}
pub trait InputStream {}
pub trait OutputStream {}
pub struct StoppableAsyncRead<T: AsyncRead> {
inner: T,
stoppable: Stoppable
}
impl <T: AsyncRead> StoppableAsyncRead<T> {
pub fn new(inner: T, stoppable: Stoppable) -> StoppableAsyncRead<T> {
StoppableAsyncRead { inner, stoppable }
}
pub fn unwrap(self) -> T {
self.inner
}
}
impl <T: AsyncRead> InputStream for StoppableAsyncRead<T> {}
impl OutputStream for OwnedWriteHalf {}
#[async_trait]
pub trait Reader<T: InputStream> {
async fn run(self, stream: T, connection: Arc<Connection>);
}
pub struct Connection {
writer: Box<parking_lot::Mutex<dyn OutputStream>>,
stopper: Stopper
}
impl Connection {
pub fn new<T: 'static + Reader<StoppableAsyncRead<OwnedReadHalf>>>(stream: TcpStream, reader: T) -> Arc<Connection> {
let (read, write) = stream.into_split();
let (stopper, stoppable) = Stopper::new();
let connection = Arc::new(Connection {
writer: Box::new(parking_lot::Mutex::new(write)),
stopper
});
tokio::spawn(reader.run(StoppableAsyncRead::new(read, stoppable), connection.clone()));
connection
}
}

128
src/oldmain.rs Normale Datei
Datei anzeigen

@ -0,0 +1,128 @@
use tokio::io;
use tokio::io::{AsyncRead, AsyncWriteExt};
use tokio::net::{TcpListener, TcpStream};
use futures::FutureExt;
use std::error::Error;
use std::sync::Arc;
use tokio::net::tcp::{OwnedReadHalf, OwnedWriteHalf};
use async_trait::async_trait;
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
let listen_addr = String::from("127.0.0.1:25565");
let server_addr = String::from("steamwar.de:25565");
println!("Listening on: {}", listen_addr);
println!("Proxying to: {}", server_addr);
let listener = TcpListener::bind(listen_addr).await?;
while let Ok((inbound, _)) = listener.accept().await {
let transfer = transfer(inbound, server_addr.clone()).map(|r| {
if let Err(e) = r {
println!("Failed to transfer; error={}", e);
}
});
tokio::spawn(transfer);
}
Ok(())
}
pub struct Stoppable {
interruptor: tokio::sync::oneshot::Receiver<bool>,
interrupted: tokio::sync::oneshot::Sender<bool>
}
pub struct Stopper {
interruptable: tokio::sync::oneshot::Sender<bool>,
interrupted: tokio::sync::oneshot::Receiver<bool>
}
impl Stopper {
pub fn new() -> (Stopper, Stoppable) {
let (interruptable, interruptor) = tokio::sync::oneshot::channel();
let (interrupted_s, interrupted_r) = tokio::sync::oneshot::channel();
(Stopper {interruptable, interrupted: interrupted_r}, Stoppable {interruptor, interrupted: interrupted_s})
}
pub async fn stop(&mut self) {
if self.interruptable.is_closed() {
return;
}
self.interruptable.send(true).unwrap_or_default();
self.interrupted.await.expect_err("Send on Stopper.interrupted occured");
}
}
pub trait InputStream {}
pub trait OutputStream {}
pub struct StoppableAsyncRead<T: AsyncRead> {
inner: T,
stoppable: Stoppable
}
impl <T: AsyncRead> StoppableAsyncRead<T> {
pub fn new(inner: T, stoppable: Stoppable) -> StoppableAsyncRead<T> {
StoppableAsyncRead { inner, stoppable }
}
pub fn unwrap(self) -> T {
self.inner
}
}
impl <T: AsyncRead> InputStream for StoppableAsyncRead<T> {}
impl OutputStream for OwnedWriteHalf {}
#[async_trait]
pub trait Reader<T: InputStream> {
async fn run(self, stream: T, connection: Arc<Connection>);
}
pub struct Connection {
writer: Box<parking_lot::Mutex<dyn OutputStream>>,
stopper: Stopper
}
impl Connection {
pub fn new<T: 'static + Reader<StoppableAsyncRead<OwnedReadHalf>>>(stream: TcpStream, reader: T) -> Arc<Connection> {
let (read, write) = stream.into_split();
let (stopper, stoppable) = Stopper::new();
let connection = Arc::new(Connection {
writer: Box::new(parking_lot::Mutex::new(write)),
stopper
});
tokio::spawn(reader.run(StoppableAsyncRead::new(read, stoppable), connection.clone()));
connection
}
}
async fn transfer(mut inbound: TcpStream, proxy_addr: String) -> Result<(), Box<dyn Error>> {
let mut outbound = TcpStream::connect(proxy_addr).await?;
let (mut ri, mut wi) = inbound.split();
let (mut ro, mut wo) = outbound.split();
let client_to_server = async {
io::copy(&mut ri, &mut wo).await?;
wo.shutdown().await
};
let server_to_client = async {
io::copy(&mut ro, &mut wi).await?;
wi.shutdown().await
};
tokio::try_join!(client_to_server, server_to_client)?;
Ok(())
}

Datei anzeigen

@ -1,31 +1,111 @@
mod handshake {
use serde::{Serialize, Deserialize};
use crate::datatypes::{NextState, VarInt};
pub mod handshake {
use crate::serde::{VarInt, JavaSerializable, NextState};
#[derive(Serialize, Deserialize, Debug)]
#[derive(JavaSerializable, Debug)]
pub struct HandshakePacket {
protocol_version: VarInt,
server_address: String,
server_port: u16,
next_state: NextState
pub protocol_version: VarInt,
pub server_address: String,
pub server_port: u16,
pub next_state: NextState
}
}
mod status {
use serde::{Serialize, Deserialize};
use crate::datatypes::StatusResponse;
pub mod status {
use crate::serde::{JavaSerializable, StatusResponse};
#[derive(Serialize, Deserialize, Debug)]
pub struct RequestPacket {}
#[derive(JavaSerializable, Debug)]
pub struct RequestPacket{}
#[derive(Serialize, Deserialize, Debug)]
#[derive(JavaSerializable, Debug)]
pub struct ResponsePacket {
response: StatusResponse
pub response: StatusResponse
}
#[derive(Serialize, Deserialize, Debug)]
#[derive(JavaSerializable, Debug)]
pub struct PingPacket {
payload: u64
pub payload: i64
}
}
pub mod login {
use bytes::{BufMut, Bytes, BytesMut};
use crate::serde::{VarInt, JavaSerializable, Chat, JavaDeserError};
#[derive(JavaSerializable, Debug)]
pub struct DisconnectPacket{
reason: Chat
}
#[derive(JavaSerializable, Debug)]
pub struct EncryptionRequestPacket {
server_id: String,
public_key: Vec::<u8>,
verify_token: Vec::<u8>
}
#[derive(JavaSerializable, Debug)]
pub struct LoginSuccessPacket {
uuid: String, //TODO: UUID
username: String
}
#[derive(JavaSerializable, Debug)]
pub struct SetCompressionPacket {
threshold: VarInt
}
#[derive(JavaSerializable, Debug)]
pub struct PluginRequestPacket {
message_id: VarInt,
channel: String, //TODO: Identifier
data: Vec::<u8> //TODO: Length inferred by packet length
}
#[derive(JavaSerializable, Debug)]
pub struct LoginStartPacket {
name: String
}
#[derive(JavaSerializable, Debug)]
pub struct EncryptionResponsePacket {
shared_secret: Vec::<u8>,
verify_token: Vec::<u8>
}
#[derive(Debug)]
pub enum PluginResponseSuccessful {
Successful(Vec<u8>),
Failed
}
impl JavaSerializable for PluginResponseSuccessful {
fn size_in_bytes(&self) -> usize {
match self {
PluginResponseSuccessful::Successful(v) => true.size_in_bytes() + v.len(),
PluginResponseSuccessful::Failed => false.size_in_bytes()
}
}
fn serialize(&self, buf: &mut BytesMut) {
match self {
PluginResponseSuccessful::Successful(v) => {
true.serialize(buf);
buf.put_slice(v.as_slice())
}
PluginResponseSuccessful::Failed => false.serialize(buf)
}
}
fn deserialize(buf: &mut Bytes) -> Result<Self, JavaDeserError> {
match bool::deserialize(buf)? {
true => Ok(PluginResponseSuccessful::Successful(buf.to_vec())),
false => Ok(PluginResponseSuccessful::Failed)
}
}
}
#[derive(JavaSerializable, Debug)]
pub struct PluginResponsePacket {
message_id: VarInt,
data: PluginResponseSuccessful
}
}

431
src/serde.rs Normale Datei
Datei anzeigen

@ -0,0 +1,431 @@
use std::ops::{DerefMut, Deref};
use bytes::{Buf, BufMut, Bytes, BytesMut};
use crate::serde::JavaDeserError::{InvalidValue, MissingBytes};
pub use lixcraft_derive::JavaSerializable;
pub enum JavaDeserError {
InvalidValue,
MissingBytes
}
pub trait JavaSerializable: Sized {
fn size_in_bytes(&self) -> usize;
fn serialize(&self, buf: &mut BytesMut);
fn deserialize(buf: &mut Bytes) -> Result<Self, JavaDeserError>; // where Self: Sized
}
impl JavaSerializable for bool {
fn size_in_bytes(&self) -> usize {
1
}
fn serialize(&self, buf: &mut BytesMut) {
match *self {
true => buf.put_u8(1),
false => buf.put_u8(0)
}
}
fn deserialize(buf: &mut Bytes) -> Result<Self, JavaDeserError> {
match buf.len() > 0 {
true => match buf.get_u8() {
0 => Ok(false),
1 => Ok(true),
_ => Err(InvalidValue)
},
false => Err(MissingBytes)
}
}
}
macro_rules! save_get {
($s:expr, $b:expr, $g:ident) => {
match $b.len() >= $s {
true => Ok($b.$g()),
false => Err(MissingBytes)
}
}
}
macro_rules! impl_num {
($t:ty, $s:expr, $p:ident, $g:ident) => {
impl JavaSerializable for $t {
fn size_in_bytes(&self) -> usize {
$s
}
fn serialize(&self, buf: &mut BytesMut) {
buf.$p(*self)
}
fn deserialize(buf: &mut Bytes) -> Result<Self, JavaDeserError> {
save_get!($s, buf, $g)
}
}
}
}
impl_num!(i8, 1, put_i8, get_i8);
impl_num!(u8, 1, put_u8, get_u8);
impl_num!(i16, 2, put_i16, get_i16);
impl_num!(u16, 2, put_u16, get_u16);
impl_num!(i32, 4, put_i32, get_i32);
impl_num!(i64, 8, put_i64, get_i64);
impl_num!(f32, 4, put_f32, get_f32);
impl_num!(f64, 8, put_f64, get_f64);
macro_rules! impl_wrapper {
($t:ty, $f:ty, $c:expr) => {
impl From<$t> for $f {
fn from(v: $t) -> Self {
v.0
}
}
impl Deref for $t {
type Target = $f;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl DerefMut for $t {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl From<$f> for $t {
fn from(v: $f) -> Self {
$c(v)
}
}
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct VarInt(pub i32);
impl_wrapper!(VarInt, i32, VarInt);
impl From<VarInt> for usize {
fn from(v: VarInt) -> Self {
v.0 as usize
}
}
impl From<usize> for VarInt {
fn from(v: usize) -> Self {
VarInt(v as i32)
}
}
macro_rules! impl_varnum_ser {
($u:ty, $v:expr, $b:expr) => {
{
let mut v = $v as $u;
loop {
if v & 0x80 == 0 {
$b.put_u8(v as u8);
return;
}
$b.put_u8((v as u8 & 0x7f) | 0x80);
v >>= 7;
}
}
}
}
macro_rules! impl_varnum_de {
($t:ty, $r:expr, $b:expr, $m:expr) => {
let mut num_read = 0;
loop {
let read = save_get!(1, $b, get_u8)?;
let value = <$t>::from(read & 0x7f);
$r |= value.overflowing_shl(7 * num_read).0;
num_read += 1;
if num_read > $m {
return Err(InvalidValue);
}
if read & 0x80 == 0 {
break;
}
}
}
}
impl JavaSerializable for VarInt {
fn size_in_bytes(&self) -> usize {
match **self {
0..=127 => 1,
128..=16383 => 2,
16384..=2097151 => 3,
2097152..=268435455 => 4,
_ => 5
}
}
fn serialize(&self, buf: &mut BytesMut) {
impl_varnum_ser!(u32, **self, buf)
}
fn deserialize(buf: &mut Bytes) -> Result<Self, JavaDeserError> {
let mut result = 0;
impl_varnum_de!(i32, result, buf, 5);
Ok(VarInt(result))
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct VarLong(pub i64);
impl_wrapper!(VarLong, i64, VarLong);
impl JavaSerializable for VarLong {
fn size_in_bytes(&self) -> usize {
match **self {
0..=127 => 1,
128..=16383 => 2,
16384..=2097151 => 3,
2097152..=268435455 => 4,
268435456..=34359738367 => 5,
34359738368..=4398046511103 => 6,
4398046511104..=562949953421311 => 7,
562949953421312..=72057594037927935 => 8,
72057594037927936..=9223372036854775807 => 9,
_ => 10
}
}
fn serialize(&self, buf: &mut BytesMut) {
impl_varnum_ser!(u64, **self, buf)
}
fn deserialize(buf: &mut Bytes) -> Result<Self, JavaDeserError> {
let mut result = 0;
impl_varnum_de!(i64, result, buf, 10);
Ok(VarLong(result))
}
}
impl JavaSerializable for String {
fn size_in_bytes(&self) -> usize {
VarInt(self.len() as i32).size_in_bytes() + self.len()
}
fn serialize(&self, buf: &mut BytesMut) {
VarInt(self.len() as i32).serialize(buf);
buf.put_slice(self.as_bytes())
}
fn deserialize(buf: &mut Bytes) -> Result<Self, JavaDeserError> {
let len = VarInt::deserialize(buf)?;
Ok(String::from_utf8(buf.split_to(usize::from(len)).to_vec()).map_err(|_| InvalidValue)?)
}
}
impl<T: JavaSerializable> JavaSerializable for Vec<T> {
fn size_in_bytes(&self) -> usize {
VarInt(self.len() as i32).size_in_bytes() + self.len()
}
fn serialize(&self, buf: &mut BytesMut) {
VarInt(self.len() as i32).serialize(buf);
for i in self.iter() {
i.serialize(buf)
}
}
fn deserialize(buf: &mut Bytes) -> Result<Self, JavaDeserError> {
let len = VarInt::deserialize(buf)?;
let mut result = Vec::with_capacity(usize::from(len));
for _ in 0..*len {
result.push(T::deserialize(buf)?)
}
Ok(result)
}
}
#[derive(Debug)]
pub enum NextState {
Status,
Login
}
impl JavaSerializable for NextState {
fn size_in_bytes(&self) -> usize {
1
}
fn serialize(&self, buf: &mut BytesMut) {
VarInt::from(match self {
NextState::Status => 1,
NextState::Login => 2
}).serialize(buf)
}
fn deserialize(buf: &mut Bytes) -> Result<Self, JavaDeserError> {
match VarInt::deserialize(buf)? {
VarInt(1) => Ok(NextState::Status),
VarInt(2) => Ok(NextState::Login),
_ => Err(InvalidValue)
}
}
}
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub struct StatusResponseVersion {
pub name: String,
pub protocol: i32
}
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub struct StatusResponseSample {
pub name: String,
pub id: String
}
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub struct StatusResponsePlayers {
pub max: i32,
pub online: i32,
pub sample: Vec<StatusResponseSample>
}
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub struct StatusResponseDescription {
pub text: String
}
macro_rules! impl_json {
($t:ty) => {
impl JavaSerializable for $t {
fn size_in_bytes(&self) -> usize {
serde_json::to_string(self).unwrap().size_in_bytes()
}
fn serialize(&self, buf: &mut BytesMut) {
serde_json::to_string(self).unwrap().serialize(buf)
}
fn deserialize(buf: &mut Bytes) -> Result<Self, JavaDeserError> {
match serde_json::from_str(&String::deserialize(buf)?) {
Ok(v) => Ok(v),
Err(_) => Err(InvalidValue)
}
}
}
}
}
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub struct StatusResponse {
pub version: StatusResponseVersion,
pub players: StatusResponsePlayers,
pub description: StatusResponseDescription,
#[serde(skip_serializing_if = "Option::is_none")]
pub favicon: Option<String>
}
impl_json!(StatusResponse);
#[derive(Debug, serde::Serialize, serde::Deserialize)]
//TODO: Serialize, Deserialize
pub enum Font {
Uniform, //minecraft:uniform
Alt, //minecraft:alt
Default //minecraft:default
}
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub enum ClickEventAction {
open_url,
run_command,
suggest_command,
change_page,
copy_to_clipboard
}
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub struct ClickEvent {
action: ClickEventAction,
value: String
}
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub enum HoverEventAction {
show_text,
show_item,
show_entity
}
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub struct HoverEvent {
action: HoverEventAction,
value: String //or Chat (Recursion!)
}
#[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<Chat>
}
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub struct Score {
name: String, //Or UUID
objective: String,
value: String
}
#[derive(Debug, serde::Serialize, serde::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
}
}
impl_json!(Chat);

127
src/serdemain.rs Normale Datei
Datei anzeigen

@ -0,0 +1,127 @@
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<dyn Error>> {
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<Option<Self::Item>, 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<Bytes> 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(())
}
}

Datei anzeigen

@ -113,7 +113,7 @@ impl<'a> Serializer for &'a mut JavaSerializer {
fn serialize_str(self, v: &str) -> Result<Self::Ok, Self::Error> {
let v = v.as_bytes();
VarInt::serialize(&VarInt::from(v.len()), self)?;
VarInt::serialize(&VarInt::from(v.len()), &mut *self)?;
self.serialize_bytes(v)
}
@ -155,7 +155,7 @@ impl<'a> Serializer for &'a mut JavaSerializer {
fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
match len {
Some(v) => VarInt::from(v).serialize(self)?,
Some(v) => VarInt::from(v).serialize(&mut *self)?,
None => ()
}
Ok(self)
@ -191,7 +191,7 @@ impl<'a> SerializeSeq for &'a mut JavaSerializer {
type Error = <&'a mut JavaSerializer as Serializer>::Error;
fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error> where T: Serialize {
value.serialize(*self)
value.serialize(&mut **self)
}
fn end(self) -> Result<Self::Ok, Self::Error> {
@ -204,7 +204,7 @@ impl<'a> SerializeStruct for &'a mut JavaSerializer {
type Error = <&'a mut JavaSerializer as Serializer>::Error;
fn serialize_field<T: ?Sized>(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error> where T: Serialize {
value.serialize(*self)
value.serialize(&mut **self)
}
fn end(self) -> Result<Self::Ok, Self::Error> {