1
0
Dieser Commit ist enthalten in:
Lixfel 2022-03-01 20:45:10 +01:00
Commit b48c214318
12 geänderte Dateien mit 1343 neuen und 0 gelöschten Zeilen

3
.gitignore vendored Normale Datei
Datei anzeigen

@ -0,0 +1,3 @@
/target
*.iml
/.idea

326
Cargo.lock generiert Normale Datei
Datei anzeigen

@ -0,0 +1,326 @@
# 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",
]
[[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 = "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 = "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"

12
Cargo.toml Normale Datei
Datei anzeigen

@ -0,0 +1,12 @@
[package]
name = "Lixcraft-Proxy"
version = "0.1.0"
authors = ["Lixfel <agga-games@gmx.de>"]
edition = "2018"
[dependencies]
tokio = { version = "1.15", features = ["full"] }
serde = { version = "1.0", features = ["derive", "std"] }
bytes = "1.1"
serde_json = "1.0"
lixcraft-derive = { path = "lixcraft-derive" }

46
lixcraft-derive/Cargo.lock generiert Normale Datei
Datei anzeigen

@ -0,0 +1,46 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "lixcraft-derive"
version = "0.1.0"
dependencies = [
"quote",
"syn",
]
[[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.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145"
dependencies = [
"proc-macro2",
]
[[package]]
name = "syn"
version = "1.0.86"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a65b3f4ffa0092e9887669db0eae07941f023991ab58ea44da8fe8e2d511c6b"
dependencies = [
"proc-macro2",
"quote",
"unicode-xid",
]
[[package]]
name = "unicode-xid"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"

12
lixcraft-derive/Cargo.toml Normale Datei
Datei anzeigen

@ -0,0 +1,12 @@
[package]
name = "lixcraft-derive"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[lib]
proc-macro = true
[dependencies]
syn = { version = "1.0", features = ["full"] }
quote = "1.0"

55
lixcraft-derive/src/lib.rs Normale Datei
Datei anzeigen

@ -0,0 +1,55 @@
use proc_macro::TokenStream;
use syn::{Data, DeriveInput, parse_macro_input};
use quote::quote;
#[proc_macro_derive(Wrapper)]
pub fn derive_wrapper(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput);
let 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 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")
},
_ => panic!("#[derive(Wrapper)] only usable on structs")
}
}

134
src/datatypes.rs Normale Datei
Datei anzeigen

@ -0,0 +1,134 @@
use std::ops::{Deref, DerefMut};
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use serde::de::Error;
use lixcraft_derive::Wrapper;
#[derive(Copy, Clone, Debug, PartialEq, Eq, Wrapper)]
pub struct VarInt(pub i32);
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)
}
}
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;
loop {
if v & 0x80 == 0 {
return serializer.serialize_u8(v as u8);
}
serializer.serialize_u8((v as u8 & 0x7f) | 0x80)?;
v >>= 7;
}
}
}
impl<'de> Deserialize<'de> for VarInt {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de> {
let mut num_read = 0;
let mut result = 0;
loop {
let read = u8::deserialize(deserializer)?;
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<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer {
VarInt::from(match self {
NextState::Status => 1,
NextState::Login => 2
}).serialize(serializer)
}
}
impl<'de> Deserialize<'de> for NextState {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> 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 {
name: String,
protocol: i32
}
#[derive(Debug, Serialize, Deserialize)]
pub struct StatusResponseSample {
name: String,
id: String
}
#[derive(Debug, Serialize, Deserialize)]
pub struct StatusResponsePlayers {
max: i32,
online: i32,
sample: Vec<StatusResponseSample>
}
#[derive(Debug, Serialize, Deserialize)]
pub struct StatusResponseDescription {
text: String
}
#[derive(Debug)]
pub struct StatusResponse {
version: StatusResponseVersion,
players: StatusResponsePlayers,
description: StatusResponseDescription,
//#[serde(skip_serializing_if = "Option::is_none")]
favicon: Option<String>
}
impl Serialize for StatusResponse {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> 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<D>(deserializer: D) -> Result<Self, D::Error> 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)
}
}
}

204
src/deserializer.rs Normale Datei
Datei anzeigen

@ -0,0 +1,204 @@
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<T>(msg: T) -> Self where T: Display {
JavaDeserError::UnexpectedCustom
}
}
pub struct JavaDeserializer {
input: Bytes
}
impl JavaDeserializer {
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<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> {
panic!("Any not deserializable in Java protocol")
}
fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value, Self::Error> 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<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> {
self.assert_remaining(1)?;
visitor.visit_i8(self.input.get_i8())
}
fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> {
self.assert_remaining(2)?;
visitor.visit_i16(self.input.get_i16())
}
fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> {
self.assert_remaining(4)?;
visitor.visit_i32(self.input.get_i32())
}
fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> {
self.assert_remaining(8)?;
visitor.visit_i64(self.input.get_i64())
}
fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> {
self.assert_remaining(1)?;
visitor.visit_u8(self.input.get_u8())
}
fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> {
self.assert_remaining(2)?;
visitor.visit_u16(self.input.get_u16())
}
fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> {
self.assert_remaining(4)?;
visitor.visit_u32(self.input.get_u32())
}
fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> {
self.assert_remaining(8)?;
visitor.visit_u64(self.input.get_u64())
}
fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> {
self.assert_remaining(4)?;
visitor.visit_f32(self.input.get_f32())
}
fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> {
self.assert_remaining(8)?;
visitor.visit_f64(self.input.get_f64())
}
fn deserialize_char<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> {
panic!("Char not deserializable in Java protocol")
}
fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> {
self.deserialize_string(visitor)
}
fn deserialize_string<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> {
let size = VarInt::deserialize(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<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> {
panic!("Bytes not deserializable in Java protocol")
}
fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> {
panic!("Byte buf not deserializable in Java protocol")
}
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> {
panic!("Option not deserializable in Java protocol")
}
fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> {
panic!("Unit not deserializable in Java protocol")
}
fn deserialize_unit_struct<V>(self, name: &'static str, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> {
panic!("Unit struct not deserializable in Java protocol")
}
fn deserialize_newtype_struct<V>(self, name: &'static str, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> {
visitor.visit_newtype_struct(self)
}
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) })
}
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")
}
fn deserialize_tuple_struct<V>(self, name: &'static str, len: usize, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> {
panic!("Tuple struct not deserializable in Java protocol")
}
fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> {
panic!("Map not deserializable in Java protocol")
}
fn deserialize_struct<V>(self, name: &'static str, fields: &'static [&'static str], visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> {
panic!("Struct (missing #[serde(flatten)]?) not deserializable in Java protocol")
}
fn deserialize_enum<V>(self, name: &'static str, variants: &'static [&'static str], visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> {
panic!("Enum not deserializable in Java protocol")
}
fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> {
panic!("Identifier not deserializable in Java protocol")
}
fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> {
panic!("Ignored any not deserializable in Java protocol")
}
}
struct LengthPrefixedSeq<'a> {
de: &'a mut JavaDeserializer,
remaining: usize
}
impl<'de, 'a> SeqAccess<'de> for LengthPrefixedSeq<'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> {
match self.remaining {
0 => Ok(None),
_ => {
self.remaining -= 1;
seed.deserialize(self.de).map(Some)
}
}
}
}

103
src/main.rs Normale Datei
Datei anzeigen

@ -0,0 +1,103 @@
extern crate core;
mod serializer;
mod datatypes;
mod deserializer;
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
}
}

31
src/packets.rs Normale Datei
Datei anzeigen

@ -0,0 +1,31 @@
mod handshake {
use serde::{Serialize, Deserialize};
use crate::datatypes::{NextState, VarInt};
#[derive(Serialize, Deserialize, Debug)]
pub struct HandshakePacket {
protocol_version: VarInt,
server_address: String,
server_port: u16,
next_state: NextState
}
}
mod status {
use serde::{Serialize, Deserialize};
use crate::datatypes::StatusResponse;
#[derive(Serialize, Deserialize, Debug)]
pub struct RequestPacket {}
#[derive(Serialize, Deserialize, Debug)]
pub struct ResponsePacket {
response: StatusResponse
}
#[derive(Serialize, Deserialize, Debug)]
pub struct PingPacket {
payload: u64
}
}

135
src/passthroughmain.rs Normale Datei
Datei anzeigen

@ -0,0 +1,135 @@
extern crate core;
mod serializer;
mod datatypes;
mod deserializer;
mod packets;
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(())
}

282
src/serializer.rs Normale Datei
Datei anzeigen

@ -0,0 +1,282 @@
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<T>(msg: T) -> Self where T: Display {
JavaSerError()
}
}
pub struct JavaSerializer {
output: BytesMut
}
impl JavaSerializer {
pub fn serialize<T: 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<Self::Ok, Self::Error> {
match v {
true => self.output.put_u8(0x00),
false => self.output.put_u8(0x01),
};
Ok(())
}
fn serialize_i8(self, v: i8) -> Result<Self::Ok, Self::Error> {
self.output.put_i8(v);
Ok(())
}
fn serialize_i16(self, v: i16) -> Result<Self::Ok, Self::Error> {
self.output.put_i16(v);
Ok(())
}
fn serialize_i32(self, v: i32) -> Result<Self::Ok, Self::Error> {
self.output.put_i32(v);
Ok(())
}
fn serialize_i64(self, v: i64) -> Result<Self::Ok, Self::Error> {
self.output.put_i64(v);
Ok(())
}
fn serialize_u8(self, v: u8) -> Result<Self::Ok, Self::Error> {
self.output.put_u8(v);
Ok(())
}
fn serialize_u16(self, v: u16) -> Result<Self::Ok, Self::Error> {
self.output.put_u16(v);
Ok(())
}
fn serialize_u32(self, v: u32) -> Result<Self::Ok, Self::Error> {
self.output.put_u32(v);
Ok(())
}
fn serialize_u64(self, v: u64) -> Result<Self::Ok, Self::Error> {
self.output.put_u64(v);
Ok(())
}
fn serialize_f32(self, v: f32) -> Result<Self::Ok, Self::Error> {
self.output.put_f32(v);
Ok(())
}
fn serialize_f64(self, v: f64) -> Result<Self::Ok, Self::Error> {
self.output.put_f64(v);
Ok(())
}
fn serialize_char(self, v: char) -> Result<Self::Ok, Self::Error> {
panic!("Char not serializable in Java protocol")
}
fn serialize_str(self, v: &str) -> Result<Self::Ok, Self::Error> {
let v = v.as_bytes();
VarInt::serialize(&VarInt::from(v.len()), self)?;
self.serialize_bytes(v)
}
fn serialize_bytes(self, v: &[u8]) -> Result<Self::Ok, Self::Error> {
self.output.put_slice(v);
Ok(())
}
fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
Ok(())
}
fn serialize_some<T: ?Sized>(self, value: &T) -> Result<Self::Ok, Self::Error> where T: Serialize {
value.serialize(self)
}
fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
panic!("Unit not serializable in Java protocol")
}
fn serialize_unit_struct(self, name: &'static str) -> Result<Self::Ok, Self::Error> {
panic!("Unit struct not serializable in Java protocol")
}
fn serialize_unit_variant(self, name: &'static str, variant_index: u32, variant: &'static str) -> Result<Self::Ok, Self::Error> {
panic!("Variant not serializable in Java protocol")
//VarInt::from(variant_index as i32).serialize(self)
}
fn serialize_newtype_struct<T: ?Sized>(self, name: &'static str, value: &T) -> Result<Self::Ok, Self::Error> where T: Serialize {
value.serialize(self)
}
fn serialize_newtype_variant<T: ?Sized>(self, name: &'static str, variant_index: u32, variant: &'static str, value: &T) -> Result<Self::Ok, Self::Error> 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<usize>) -> Result<Self::SerializeSeq, Self::Error> {
match len {
Some(v) => VarInt::from(v).serialize(self)?,
None => ()
}
Ok(self)
}
fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, Self::Error> {
panic!("Tuple not serializable in Java protocol")
}
fn serialize_tuple_struct(self, name: &'static str, len: usize) -> Result<Self::SerializeTupleStruct, Self::Error> {
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<Self::SerializeTupleVariant, Self::Error> {
panic!("Tuple struct variant not serializable in Java protocol")
}
fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
panic!("Maps not serializable in Java protocol")
}
fn serialize_struct(self, name: &'static str, len: usize) -> Result<Self::SerializeStruct, Self::Error> {
Ok(self)
}
fn serialize_struct_variant(self, name: &'static str, variant_index: u32, variant: &'static str, len: usize) -> Result<Self::SerializeStructVariant, Self::Error> {
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<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error> where T: Serialize {
value.serialize(*self)
}
fn end(self) -> Result<Self::Ok, Self::Error> {
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<T: ?Sized>(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error> where T: Serialize {
value.serialize(*self)
}
fn end(self) -> Result<Self::Ok, Self::Error> {
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<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error> where T: Serialize {
panic!("Tuple not serializable in Java protocol")
}
fn end(self) -> Result<Self::Ok, Self::Error> {
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<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error> where T: Serialize {
panic!("Tuple struct not serializable in Java protocol")
}
fn end(self) -> Result<Self::Ok, Self::Error> {
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<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error> where T: Serialize {
panic!("Tuple variant not serializable in Java protocol")
}
fn end(self) -> Result<Self::Ok, Self::Error> {
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<T: ?Sized>(&mut self, key: &T) -> Result<(), Self::Error> where T: Serialize {
panic!("Map not serializable in Java protocol")
}
fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error> where T: Serialize {
panic!("Map not serializable in Java protocol")
}
fn end(self) -> Result<Self::Ok, Self::Error> {
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<T: ?Sized>(&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<Self::Ok, Self::Error> {
panic!("Struct variant not serializable in Java protocol")
}
}