From 2acaea1bd2eebc5b4db800e85bf558fe83ad4481 Mon Sep 17 00:00:00 2001 From: Kyler <59854022+KylerOlsen@users.noreply.github.com> Date: Mon, 18 Dec 2023 23:40:36 -0700 Subject: [PATCH] Refactoring --- src/handshake.rs | 47 ++++++------ src/login.rs | 1 - src/main.rs | 22 +++--- src/mc_types.rs | 194 +++++++++++++++++++++++++++++++++++++---------- src/status.rs | 47 ++++++------ 5 files changed, 208 insertions(+), 103 deletions(-) diff --git a/src/handshake.rs b/src/handshake.rs index 0ea0330..f238448 100644 --- a/src/handshake.rs +++ b/src/handshake.rs @@ -1,7 +1,6 @@ // Yeahbut December 2023 use tokio::net::tcp::{OwnedReadHalf, OwnedWriteHalf}; -use tokio::io::{AsyncReadExt, AsyncWriteExt}; use crate::mc_types; @@ -12,33 +11,33 @@ pub struct Handshake { pub next_state: i32, } -pub async fn read_handshake(stream: &mut OwnedReadHalf) -> Option { - Some(Handshake { - protocol_version: mc_types::read_var_int(stream) - .await, - server_address: mc_types::read_string(stream) - .await, - server_port: stream.read_u16() - .await.expect("Error reading from stream"), - next_state: mc_types::read_var_int(stream) - .await, - }) +pub async fn read_handshake(stream: &mut OwnedReadHalf) -> Handshake { + get_handshake(&mut mc_types::read_packet(stream).await) +} + +pub fn get_handshake(data: &mut Vec) -> Handshake { + mc_types::get_var_int(data); + Handshake { + protocol_version: mc_types::get_var_int(data), + server_address: mc_types::get_string(data), + server_port: mc_types::get_u16(data), + next_state: mc_types::get_var_int(data), + } +} + +pub fn convert_handshake(handshake: Handshake) -> Vec { + let mut data: Vec = vec![0]; + data.append(&mut mc_types::convert_var_int(handshake.protocol_version)); + data.append(&mut mc_types::convert_string(&handshake.server_address)); + data.append(&mut mc_types::convert_u16(handshake.server_port)); + data.append(&mut mc_types::convert_var_int(handshake.next_state)); + + data } pub async fn write_handshake( stream: &mut OwnedWriteHalf, handshake: Handshake, ) { - let mut data: Vec = vec![0]; - mc_types::write_var_int_bytes(&mut data, handshake.protocol_version); - mc_types::write_string_bytes(&mut data, &handshake.server_address); - data.append(&mut vec![ - ((handshake.server_port & 0xFF00) >> 8) as u8, - (handshake.server_port & 0xFF) as u8, - ]); - mc_types::write_var_int_bytes(&mut data, handshake.next_state); - - mc_types::write_var_int(stream, data.len() as i32).await; - stream.write_all(&mut data) - .await.expect("Error writing to stream"); + mc_types::write_packet(stream, &mut convert_handshake(handshake)).await; } diff --git a/src/login.rs b/src/login.rs index 94ebbff..7071a55 100644 --- a/src/login.rs +++ b/src/login.rs @@ -1,6 +1,5 @@ // Yeahbut December 2023 use tokio::net::tcp::{OwnedReadHalf, OwnedWriteHalf}; -use tokio::io::{AsyncReadExt, AsyncWriteExt}; use crate::mc_types; diff --git a/src/main.rs b/src/main.rs index ad2404b..77d1253 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,7 @@ // Yeahbut December 2023 use tokio::net::{TcpListener, TcpStream}; -use tokio::io::{self, AsyncReadExt}; //, AsyncWriteExt}; +use tokio::io; use std::error::Error; mod mc_types; @@ -27,14 +27,19 @@ async fn handle_client(client_socket: TcpStream) { let (mut client_reader, mut client_writer) = client_socket.into_split(); if let Ok(backend_socket) = TcpStream::connect(backend_addr).await { - let (mut server_reader, mut server_writer) = backend_socket.into_split(); - let packet_id = client_reader.read_u8() + let (mut server_reader, mut server_writer) = + backend_socket.into_split(); + let mut buffer: [u8; 1] = [0; 1]; + client_reader.peek(&mut buffer) .await.expect("Error reading from stream"); + let packet_id: u8 = buffer[0]; - println!("Packet ID: {}", packet_id); - if packet_id == 0 { + if packet_id == 0xFE { + status::respond_legacy_status(&mut client_writer).await; + return; + } else { let handshake_packet = handshake::read_handshake(&mut client_reader) - .await.unwrap(); + .await; println!("Next state: {}", handshake_packet.next_state); if handshake_packet.next_state == 1 { println!("Receiving Status Request"); @@ -50,11 +55,6 @@ async fn handle_client(client_socket: TcpStream) { } else { return; } - } else if packet_id == 0xFE { - status::respond_legacy_status(&mut client_writer).await; - return; - } else { - return; } // Forward from client to backend diff --git a/src/mc_types.rs b/src/mc_types.rs index 93f9097..97c887f 100644 --- a/src/mc_types.rs +++ b/src/mc_types.rs @@ -2,7 +2,7 @@ use tokio::net::tcp::{OwnedReadHalf, OwnedWriteHalf}; use tokio::io::{AsyncReadExt, AsyncWriteExt}; -use serde::Serialize; +use serde::{Serialize, Deserialize}; pub const VERSION_NAME: &str = "1.19.4"; pub const VERSION_PROTOCOL: i32 = 762; @@ -10,19 +10,153 @@ pub const VERSION_PROTOCOL: i32 = 762; const SEGMENT_BITS: u8 = 0x7F; const CONTINUE_BIT: u8 = 0x80; -#[derive(Serialize)] +#[derive(Serialize, Deserialize)] pub struct Chat { pub text: String, } -pub async fn read_var_int(stream: &mut OwnedReadHalf) -> i32 { +pub async fn read_packet(stream: &mut OwnedReadHalf) -> Vec { + let length = read_var_int_stream(stream).await; + let mut buffer: Vec = vec![0; length as usize]; + stream.read_exact(&mut buffer) + .await.expect("Error reading string from stream"); + buffer +} +pub async fn write_packet(stream: &mut OwnedWriteHalf, data: &mut Vec) { + let length = data.len() as i32; + stream.write_all(&convert_var_int(length)) + .await.expect("Error writing to stream"); + stream.write_all(&data) + .await.expect("Error writing to stream"); +} +async fn read_var_int_stream(stream: &mut OwnedReadHalf) -> i32 { + let mut data: Vec = vec![]; + + loop { + let current_byte = stream.read_u8() + .await.expect("Error reading from stream"); + + data.append(&mut vec![current_byte]); + + if (current_byte & CONTINUE_BIT) == 0 { + break; + } + } + + get_var_int(&mut data) +} + +pub fn get_bool(data: &mut Vec) -> bool { + data.remove(0) != 0 +} +pub fn convert_bool(value: bool) -> Vec { + vec![value as u8] +} + +pub fn get_u8(data: &mut Vec) -> u8 { + data.remove(0) +} +pub fn convert_u8(value: u8) -> Vec { + vec![value] +} + +pub fn get_i8(data: &mut Vec) -> i8 { + get_u8(data) as i8 +} +pub fn convert_i8(value: i8) -> Vec { + convert_u8(value as u8) +} + +pub fn get_u16(data: &mut Vec) -> u16 { + ((data.remove(0) as u16) << 8) | + (data.remove(0) as u16) +} +pub fn convert_u16(value: u16) -> Vec { + vec![ + ((value & 0xFF00) >> 8) as u8, + (value & 0xFF) as u8, + ] +} + +pub fn get_i16(data: &mut Vec) -> i16 { + get_u16(data) as i16 +} +pub fn convert_i16(value: i16) -> Vec { + convert_u16(value as u16) +} + +pub fn get_u32(data: &mut Vec) -> u32 { + ((data.remove(0) as u32) << 24) | + ((data.remove(0) as u32) << 16) | + ((data.remove(0) as u32) << 8) | + (data.remove(0) as u32) +} +pub fn convert_u32(value: u32) -> Vec { + vec![ + ((value & 0xFF0000) >> 24) as u8, + ((value & 0xFF0000) >> 16) as u8, + ((value & 0xFF00) >> 8) as u8, + (value & 0xFF) as u8, + ] +} + +pub fn get_i32(data: &mut Vec) -> i32 { + get_u32(data) as i32 +} +pub fn convert_i32(value: i32) -> Vec { + convert_u32(value as u32) +} + +pub fn get_f32(data: &mut Vec) -> f32 { + get_u32(data) as f32 +} +pub fn convert_f32(value: f32) -> Vec { + convert_u32(value as u32) +} + +pub fn get_u64(data: &mut Vec) -> u64 { + ((data.remove(0) as u64) << 56) | + ((data.remove(0) as u64) << 48) | + ((data.remove(0) as u64) << 40) | + ((data.remove(0) as u64) << 32) | + ((data.remove(0) as u64) << 24) | + ((data.remove(0) as u64) << 16) | + ((data.remove(0) as u64) << 8) | + (data.remove(0) as u64) +} +pub fn convert_u64(value: u64) -> Vec { + vec![ + ((value & 0xFF00000000000000) >> 56) as u8, + ((value & 0xFF000000000000) >> 48) as u8, + ((value & 0xFF0000000000) >> 40) as u8, + ((value & 0xFF00000000) >> 32) as u8, + ((value & 0xFF000000) >> 24) as u8, + ((value & 0xFF0000) >> 16) as u8, + ((value & 0xFF00) >> 8) as u8, + (value & 0xFF) as u8, + ] +} + +pub fn get_i64(data: &mut Vec) -> i64 { + get_u64(data) as i64 +} +pub fn convert_i64(value: i64) -> Vec { + convert_u64(value as u64) +} + +pub fn get_f64(data: &mut Vec) -> f64 { + get_u64(data) as f64 +} +pub fn convert_f64(value: f64) -> Vec { + convert_u64(value as u64) +} + +pub fn get_var_int(data: &mut Vec) -> i32 { let mut value: i32 = 0; let mut position: u32 = 0; loop { - let current_byte = stream.read_u8() - .await - .expect("Error reading from stream"); + let current_byte = data.remove(0); value |= ((current_byte & SEGMENT_BITS) as i32) << position; if (current_byte & CONTINUE_BIT) == 0 { @@ -38,52 +172,28 @@ pub async fn read_var_int(stream: &mut OwnedReadHalf) -> i32 { value } - -pub async fn write_var_int(stream: &mut OwnedWriteHalf, mut value: i32) { +pub fn convert_var_int(mut value: i32) -> Vec { + let mut data: Vec = vec![]; loop { if (value & !(SEGMENT_BITS as i32)) == 0 { - stream.write_u8(value as u8) - .await.expect("Error writing to stream"); - return; + data.append(&mut vec![value as u8]); + return data; } - - stream.write_u8((value & (SEGMENT_BITS as i32)) as u8 | CONTINUE_BIT) - .await - .expect("Error writing to stream"); - - value >>= 7; - } -} - -pub fn write_var_int_bytes(stream: &mut Vec, mut value: i32) { - loop { - if (value & !(SEGMENT_BITS as i32)) == 0 { - stream.append(&mut vec![value as u8]); - return; - } - stream.append( + data.append( &mut vec![(value & (SEGMENT_BITS as i32)) as u8 | CONTINUE_BIT]); value >>= 7; } } -pub async fn read_string(stream: &mut OwnedReadHalf) -> String { - let length = read_var_int(stream).await; +pub fn get_string(data: &mut Vec) -> String { + let length = get_var_int(data); let mut buffer = vec![0; length as usize]; - stream.read_exact(&mut buffer) - .await.expect("Error reading string from stream"); + data.append(&mut buffer); String::from_utf8_lossy(&buffer).to_string() } - -pub async fn write_string(stream: &mut OwnedWriteHalf, s: &str) { +pub fn convert_string(s: &str) -> Vec { let length = s.len() as i32; - write_var_int(stream, length).await; - stream.write_all(s.as_bytes()) - .await.expect("Error writing string to stream"); -} - -pub fn write_string_bytes(stream: &mut Vec, s: &str) { - let length = s.len() as i32; - write_var_int_bytes(stream, length); - stream.append(&mut s.as_bytes().to_vec()); + let mut data = convert_var_int(length); + data.append(&mut s.as_bytes().to_vec()); + data } diff --git a/src/status.rs b/src/status.rs index 50b4716..27b27fb 100644 --- a/src/status.rs +++ b/src/status.rs @@ -1,34 +1,32 @@ // Yeahbut December 2023 -use std::str::Bytes; - use tokio::net::tcp::{OwnedReadHalf, OwnedWriteHalf}; use tokio::io::{AsyncReadExt, AsyncWriteExt}; -use serde::Serialize; +use serde::{Serialize, Deserialize}; use crate::mc_types; use crate::handshake; -#[derive(Serialize)] +#[derive(Serialize, Deserialize)] pub struct StatusVersion { pub name: String, pub protocol: i32, } -#[derive(Serialize)] +#[derive(Serialize, Deserialize)] pub struct StatusPlayerInfo { pub name: String, pub id: String, } -#[derive(Serialize)] +#[derive(Serialize, Deserialize)] pub struct StatusPlayers { pub max: i32, pub online: i32, pub sample: Vec } -#[derive(Serialize)] +#[derive(Serialize, Deserialize)] pub struct StatusResponse { pub version: StatusVersion, pub description: mc_types::Chat, @@ -93,7 +91,8 @@ pub async fn respond_status( Ok(json) => { client_writer.write_u8(0) .await.expect("Error writing to stream"); - mc_types::write_string(client_writer, &json).await; + client_writer.write_all(&mc_types::convert_string(&json)) + .await.expect("Error writing to stream"); }, Err(err) => { eprintln!("Error serializing to JSON: {}", err); @@ -119,23 +118,21 @@ pub async fn get_upstream_status( server_reader: &mut OwnedReadHalf, server_writer: &mut OwnedWriteHalf, ) -> StatusResponse { - StatusResponse { - version: StatusVersion { - name: "1.19.4".to_string(), - protocol: 762, - }, - description: mc_types::Chat { - text: motd(), - }, - players: StatusPlayers { - max: 0, - online: 0, - sample: vec![], - }, - favicon: favicon(), - enforcesSecureChat: false, - previewsChat: false, - } + handshake::write_handshake(server_writer, handshake::Handshake{ + protocol_version: mc_types::VERSION_PROTOCOL, + server_address: "localhost".to_string(), + server_port: 25565, + next_state: 1, + }).await; + server_writer.write_u8(0).await.expect("Error writing to stream"); + + let mut data = mc_types::read_packet(server_reader).await; + mc_types::get_u8(&mut data); + let json = mc_types::get_string(&mut data); + let status_response: StatusResponse = serde_json::from_str(&json) + .expect("Error parsing JSON"); + + status_response } pub async fn respond_legacy_status(client_writer: &mut OwnedWriteHalf) {