1
0

Finalize Handshake, Status and Login serde

Dieser Commit ist enthalten in:
Lixfel 2022-03-07 12:32:17 +01:00
Ursprung 4efe1aaf36
Commit 2989ac7938
5 geänderte Dateien mit 227 neuen und 121 gelöschten Zeilen

Datei anzeigen

@ -11,4 +11,5 @@ tokio-stream = "0.1"
serde = { version = "1.0", features = ["derive", "std"] }
serde_json = "1.0"
bytes = "1.1"
uuid = "0.8"
lixcraft-derive = { path = "lixcraft-derive" }

87
src/frames.rs Normale Datei
Datei anzeigen

@ -0,0 +1,87 @@
use std::io::ErrorKind;
use bytes::{Buf, BufMut, Bytes, BytesMut};
use tokio::io::Error;
use tokio_util::codec::{Decoder, Encoder};
use crate::VarInt;
pub struct LengthPrefixedFrame {
pub max_length: usize
}
enum VarIntReadError {
BytesMissing,
InvalidData
}
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<Option<Self::Item>, Self::Error> {
println!("!");
match self.try_read_var_int(src) { //TODO: Packet length maximal 2097151 byte
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(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

@ -1,18 +1,49 @@
extern crate core;
pub mod serde;
mod packets;
pub mod packets;
pub mod frames;
use std::collections::HashMap;
use std::error::Error;
use std::io::ErrorKind;
use std::net::SocketAddr;
use bytes::{Buf, BufMut, Bytes, BytesMut};
use std::sync::Arc;
use bytes::BytesMut;
use tokio::net::{TcpListener, TcpStream};
use tokio_stream::StreamExt;
use tokio_util::codec::{Decoder, Encoder, Framed};
use tokio_util::codec::Framed;
use crate::frames::LengthPrefixedFrame;
use crate::packets::handshake::HandshakePacket;
use crate::serde::{JavaSerializable, VarInt};
pub struct Server {
listener: Arc<TcpListener> //TODO: TcpListener not required from anybody
}
pub struct RawConnection {
pub server: Arc<Server>,
pub remote_addr: SocketAddr
}
impl Server {
pub async fn new(listen_addr: String) -> Result<Arc<Server>, Box<dyn Error>> {
let server = Arc::new(Server {
listener : Arc::new(TcpListener::bind(listen_addr).await?)
});
let server_clone = server.clone();
tokio::spawn(async move {
while let Ok((inbound, addr)) = server_clone.listener.accept().await {
tokio::spawn(async move {process_initial(inbound, addr)}.await);
}
});
Ok(server)
}
}
//TODO: Shutdown construction! Yay
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
let listen_addr = String::from("127.0.0.1:25565");
@ -28,8 +59,25 @@ async fn main() -> Result<(), Box<dyn Error>> {
Ok(())
}
enum Reason {
Disconnected,
ConnectionDrop,
ProtocolError
}
struct Protocol {
packet_handlers: HashMap<VarInt, Box<dyn FnMut(BytesMut) -> Reason>>
}
fn handle_handshake(buf: BytesMut) -> Result<Framed<TcpStream, LengthPrefixedFrame>, Reason> {
Err(Reason::Disconnected)
}
async fn process_initial(stream: TcpStream, _addr: SocketAddr) {
/*let handshake_protocol = Protocol {
packet_handlers: HashMap::from([(VarInt(0), Box::new(handle_handshake) as Box<dyn FnMut(BytesMut) -> Reason>)]),
};*/
let mut framed = Framed::new(stream, LengthPrefixedFrame {max_length: 263});
match framed.next().await {
Some(Ok(buf)) => {
@ -48,95 +96,4 @@ async fn process_initial(stream: TcpStream, _addr: SocketAddr) {
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<Option<Self::Item>, 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<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

@ -1,10 +1,10 @@
pub mod handshake {
use crate::serde::{VarInt, JavaSerializable, NextState};
use crate::serde::{VarInt, JavaSerializable, NextState, String255};
#[derive(JavaSerializable, Debug)]
pub struct HandshakePacket {
pub protocol_version: VarInt,
pub server_address: String,
pub server_address: String255,
pub server_port: u16,
pub next_state: NextState
}
@ -28,8 +28,9 @@ pub mod status {
}
pub mod login {
use bytes::{BufMut, Bytes, BytesMut};
use crate::serde::{VarInt, JavaSerializable, Chat, JavaDeserError};
use bytes::{Bytes, BytesMut};
use uuid::Uuid;
use crate::serde::{VarInt, JavaSerializable, Chat, JavaDeserError, String20, String16, Identifier, RemainingBytes};
#[derive(JavaSerializable, Debug)]
pub struct DisconnectPacket{
@ -38,15 +39,15 @@ pub mod login {
#[derive(JavaSerializable, Debug)]
pub struct EncryptionRequestPacket {
server_id: String,
server_id: String20,
public_key: Vec::<u8>,
verify_token: Vec::<u8>
}
#[derive(JavaSerializable, Debug)]
pub struct LoginSuccessPacket {
uuid: String, //TODO: UUID
username: String
uuid: Uuid,
username: String16
}
#[derive(JavaSerializable, Debug)]
@ -57,13 +58,13 @@ pub mod login {
#[derive(JavaSerializable, Debug)]
pub struct PluginRequestPacket {
message_id: VarInt,
channel: String, //TODO: Identifier
data: Vec::<u8> //TODO: Length inferred by packet length
channel: Identifier,
data: RemainingBytes
}
#[derive(JavaSerializable, Debug)]
pub struct LoginStartPacket {
name: String
name: String16
}
#[derive(JavaSerializable, Debug)]
@ -74,7 +75,7 @@ pub mod login {
#[derive(Debug)]
pub enum PluginResponseSuccessful {
Successful(Vec<u8>),
Successful(RemainingBytes),
Failed
}
impl JavaSerializable for PluginResponseSuccessful {
@ -89,7 +90,7 @@ pub mod login {
match self {
PluginResponseSuccessful::Successful(v) => {
true.serialize(buf);
buf.put_slice(v.as_slice())
v.serialize(buf);
}
PluginResponseSuccessful::Failed => false.serialize(buf)
}
@ -97,7 +98,7 @@ pub mod login {
fn deserialize(buf: &mut Bytes) -> Result<Self, JavaDeserError> {
match bool::deserialize(buf)? {
true => Ok(PluginResponseSuccessful::Successful(buf.to_vec())),
true => Ok(PluginResponseSuccessful::Successful(RemainingBytes::deserialize(buf)?)),
false => Ok(PluginResponseSuccessful::Failed)
}
}

Datei anzeigen

@ -3,6 +3,7 @@ use bytes::{Buf, BufMut, Bytes, BytesMut};
use crate::serde::JavaDeserError::{InvalidValue, MissingBytes};
pub use lixcraft_derive::JavaSerializable;
use uuid::Uuid;
#[derive(Debug)]
pub enum JavaDeserError {
@ -105,7 +106,7 @@ macro_rules! impl_wrapper {
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub struct VarInt(pub i32);
impl_wrapper!(VarInt, i32, VarInt);
@ -211,22 +212,63 @@ impl JavaSerializable for VarLong {
}
}
impl JavaSerializable for String {
impl JavaSerializable for Uuid {
fn size_in_bytes(&self) -> usize {
VarInt(self.len() as i32).size_in_bytes() + self.len()
16
}
fn serialize(&self, buf: &mut BytesMut) {
VarInt(self.len() as i32).serialize(buf);
buf.put_slice(self.as_bytes())
buf.put_u128(self.as_u128())
}
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)?)
Ok(Uuid::from_u128(save_get!(16, buf, get_u128)?))
}
}
macro_rules! impl_string {
($i:ident, $v:expr) => {
#[derive(Debug)]
pub struct $i(pub String);
impl_wrapper!($i, String, $i);
impl JavaSerializable for $i {
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)?;
if usize::from(len) > $v * 4 {
Err(InvalidValue)
} else if buf.len() < usize::from(len) {
Err(MissingBytes)
} else {
let string = String::from_utf8(buf.split_to(usize::from(len)).to_vec()).map_err(|_| InvalidValue)?;
if string.chars().count() > $v {
Err(InvalidValue)
} else {
Ok($i(string))
}
}
}
}
}
}
impl_string!(String16, 16);
impl_string!(String20, 20);
impl_string!(String255, 255);
impl_string!(String32767, 32767);
impl_string!(String262144, 262144);
impl_string!(Identifier, 32767);
impl<T: JavaSerializable> JavaSerializable for Vec<T> {
fn size_in_bytes(&self) -> usize {
VarInt(self.len() as i32).size_in_bytes() + self.len()
@ -249,6 +291,24 @@ impl<T: JavaSerializable> JavaSerializable for Vec<T> {
}
}
#[derive(Debug)]
pub struct RemainingBytes(pub Vec<u8>);
impl_wrapper!(RemainingBytes, Vec<u8>, RemainingBytes);
impl JavaSerializable for RemainingBytes {
fn size_in_bytes(&self) -> usize {
self.len()
}
fn serialize(&self, buf: &mut BytesMut) {
buf.put_slice(self.as_slice());
}
fn deserialize(buf: &mut Bytes) -> Result<Self, JavaDeserError> {
Ok(RemainingBytes(buf.to_vec()))
}
}
#[derive(Debug)]
pub enum NextState {
Status,
@ -301,18 +361,18 @@ pub struct StatusResponseDescription {
}
macro_rules! impl_json {
($t:ty) => {
($t:ty, $st:ident) => {
impl JavaSerializable for $t {
fn size_in_bytes(&self) -> usize {
serde_json::to_string(self).unwrap().size_in_bytes()
$st(serde_json::to_string(self).unwrap()).size_in_bytes()
}
fn serialize(&self, buf: &mut BytesMut) {
serde_json::to_string(self).unwrap().serialize(buf)
$st(serde_json::to_string(self).unwrap()).serialize(buf)
}
fn deserialize(buf: &mut Bytes) -> Result<Self, JavaDeserError> {
match serde_json::from_str(&String::deserialize(buf)?) {
match serde_json::from_str(&$st::deserialize(buf)?) {
Ok(v) => Ok(v),
Err(_) => Err(InvalidValue)
}
@ -329,7 +389,7 @@ pub struct StatusResponse {
#[serde(skip_serializing_if = "Option::is_none")]
pub favicon: Option<String>
}
impl_json!(StatusResponse);
impl_json!(StatusResponse, String32767);
#[derive(Debug, serde::Serialize, serde::Deserialize)]
@ -431,4 +491,4 @@ pub enum Chat {
selector: String //TODO ominous
}
}
impl_json!(Chat);
impl_json!(Chat, String262144);