diff --git a/Cargo.toml b/Cargo.toml index abe48b6..a16c7cf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,9 +8,9 @@ license = "MIT" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +purple_cello_mc_protocol = { git = "https://github.com/PurpleCelloServer/purple_cello_mc_protocol.git" } tokio = { version = "1", features = ["full"] } serde = { version = "1", features = ["derive"] } serde_json = "1" base64 = "0.21.5" rand = "0.8.5" -async-trait = "0.1.75" diff --git a/src/handshake.rs b/src/handshake.rs deleted file mode 100644 index 8537dfb..0000000 --- a/src/handshake.rs +++ /dev/null @@ -1,57 +0,0 @@ -// Yeahbut December 2023 - -pub mod serverbound { - - use tokio::net::tcp::OwnedReadHalf; - - use crate::mc_types::{self, Result, Packet, PacketError}; - - pub enum HandshakeEnum { - Handshake(Handshake), - } - - impl HandshakeEnum { - pub async fn read(stream: &mut OwnedReadHalf) -> Result { - let mut data = mc_types::read_data(stream).await?; - let packet_id = mc_types::get_var_int(&mut data)?; - if packet_id == Handshake::packet_id() { - return Ok(Self::Handshake(Handshake::get(&mut data)?)) - } else { - return Err(Box::new(PacketError::InvalidPacketId)) - } - } - } - - pub struct Handshake { - pub protocol_version: i32, - pub server_address: String, - pub server_port: u16, - pub next_state: i32, - } - - impl Packet for Handshake { - - fn packet_id() -> i32 {0} - - fn get(data: &mut Vec) -> Result { - Ok(Self { - 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)?, - }) - } - - fn convert(&self) -> Vec { - let mut data: Vec = vec![]; - data.append(&mut mc_types::convert_var_int(Self::packet_id())); - data.append(&mut mc_types::convert_var_int(self.protocol_version)); - data.append(&mut mc_types::convert_string(&self.server_address)); - data.append(&mut mc_types::convert_u16(self.server_port)); - data.append(&mut mc_types::convert_var_int(self.next_state)); - - data - } - - } -} diff --git a/src/login.rs b/src/login.rs deleted file mode 100644 index 95048aa..0000000 --- a/src/login.rs +++ /dev/null @@ -1,169 +0,0 @@ -// Yeahbut December 2023 - -pub mod clientbound { - - use tokio::net::tcp::OwnedReadHalf; - - use crate::mc_types::{self, Result, Packet, PacketArray, PacketError}; - - pub enum Login { - Disconnect(Disconnect), - EncryptionRequest(EncryptionRequest), - LoginSuccess(LoginSuccess), - } - - impl Login { - pub async fn read(stream: &mut OwnedReadHalf) -> Result { - let mut data = mc_types::read_data(stream).await?; - let packet_id = mc_types::get_var_int(&mut data)?; - if packet_id == Disconnect::packet_id() { - return Ok(Self::Disconnect(Disconnect::get(&mut data)?)) - } else if packet_id == EncryptionRequest::packet_id() { - return Ok(Self::EncryptionRequest( - EncryptionRequest::get(&mut data)?)) - } else if packet_id == LoginSuccess::packet_id() { - return Ok(Self::LoginSuccess(LoginSuccess::get(&mut data)?)) - } else { - return Err(Box::new(PacketError::InvalidPacketId)) - } - } - } - - pub struct Disconnect { - pub reason: String - } - - impl Packet for Disconnect { - - fn packet_id() -> i32 {0} - - fn get(mut data: &mut Vec) -> Result { - Ok(Self { - reason: mc_types::get_string(&mut data)? - }) - } - - fn convert(&self) -> Vec { - let mut data: Vec = vec![]; - data.append(&mut mc_types::convert_var_int(Self::packet_id())); - data.append(&mut mc_types::convert_string(&self.reason)); - - data - } - - } - - pub struct EncryptionRequest { - pub server_id: String, - pub public_key: Vec, - pub verify_token: Vec, - } - - impl Packet for EncryptionRequest { - - fn packet_id() -> i32 {1} - - fn get(mut data: &mut Vec) -> Result { - Ok(Self { - server_id: mc_types::get_string(&mut data)?, - public_key: mc_types::get_byte_array(&mut data)?, - verify_token: mc_types::get_byte_array(&mut data)?, - }) - } - - fn convert(&self) -> Vec { - let mut data: Vec = vec![]; - data.append(&mut mc_types::convert_var_int(Self::packet_id())); - data.append(&mut mc_types::convert_string(&self.server_id)); - data.append(&mut mc_types::convert_byte_array( - &mut self.public_key.clone())); - data.append(&mut mc_types::convert_byte_array( - &mut self.verify_token.clone())); - - data - } - - } - - pub struct LoginSuccess { - pub uuid: u128, - pub username: String, - pub properties: Vec, - } - - impl Packet for LoginSuccess { - - fn packet_id() -> i32 {2} - - fn get(mut data: &mut Vec) -> Result { - Ok(Self { - uuid: mc_types::get_uuid(&mut data), - username: mc_types::get_string(&mut data)?, - properties: LoginSuccessProperty::get_array(&mut data)?, - }) - } - - fn convert(&self) -> Vec { - let mut data: Vec = vec![]; - data.append(&mut mc_types::convert_var_int(Self::packet_id())); - data.append(&mut mc_types::convert_uuid(self.uuid)); - data.append(&mut mc_types::convert_string(&self.username)); - data.append(&mut LoginSuccessProperty::convert_array( - &mut self.properties.clone())); - - data - } - - } - - pub struct LoginSuccessProperty { - name: String, - value: String, - signature: Option, - } - - impl Clone for LoginSuccessProperty { - fn clone(&self) -> Self { - Self { - name: self.name.clone(), - value: self.value.clone(), - signature: self.signature.clone(), - } - } - } - - impl PacketArray for LoginSuccessProperty { - - fn get(mut data: &mut Vec) -> Result { - let name = mc_types::get_string(&mut data)?; - let value = mc_types::get_string(&mut data)?; - let is_signed = mc_types::get_bool(&mut data); - let mut signature: Option = None; - if is_signed { - signature = Some(mc_types::get_string(&mut data)?); - } - Ok(Self { - name, - value, - signature, - }) - } - - fn convert(&self) -> Vec { - let mut data: Vec = vec![]; - data.append(&mut mc_types::convert_string(&self.name)); - data.append(&mut mc_types::convert_string(&self.value)); - match &self.signature { - Some(value) => { - data.append(&mut &mut mc_types::convert_bool(true)); - data.append(&mut mc_types::convert_string(&value)); - }, - None => data.append(&mut &mut mc_types::convert_bool(false)) - } - - data - } - - } - -} diff --git a/src/main.rs b/src/main.rs index 777f41c..8510ac8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,13 +4,14 @@ use tokio::net::{TcpListener, TcpStream, tcp::{OwnedReadHalf, OwnedWriteHalf}}; use tokio::io; use std::error::Error; -mod mc_types; -mod handshake; -mod status; -mod login; +use purple_cello_mc_protocol::{ + mc_types::{self, Packet}, + handshake, + login, +}; + mod status_handle; -use mc_types::Packet; #[tokio::main] async fn main() -> Result<(), Box> { diff --git a/src/mc_types.rs b/src/mc_types.rs deleted file mode 100644 index f9d6b2a..0000000 --- a/src/mc_types.rs +++ /dev/null @@ -1,347 +0,0 @@ -// Yeahbut December 2023 - -use std::error::Error; -use std::fmt; - -use tokio::net::tcp::{OwnedReadHalf, OwnedWriteHalf}; -use tokio::io::{AsyncReadExt, AsyncWriteExt}; -use serde::{Serialize, Deserialize}; -use async_trait::async_trait; - -pub type Result = std::result::Result>; - -pub const VERSION_NAME: &str = "1.19.4"; -pub const VERSION_PROTOCOL: i32 = 762; - -const SEGMENT_BITS: u8 = 0x7F; -const CONTINUE_BIT: u8 = 0x80; - -#[derive(Debug)] -pub enum PacketError { - ValueTooLarge, - RanOutOfBytes, - InvalidPacketId, -} - -impl fmt::Display for PacketError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - PacketError::ValueTooLarge => - write!(f, "VarInt value is too large"), - PacketError::RanOutOfBytes => - write!(f, "Ran out of bytes while reading VarInt"), - PacketError::InvalidPacketId => - write!(f, "Invalid packet id"), - } - } -} - -impl Error for PacketError {} - -#[derive(Serialize, Deserialize)] -pub struct Chat { - pub text: String, -} - -#[async_trait] -pub trait Packet: Sized { - fn packet_id() -> i32; - fn get(data: &mut Vec) -> Result; - fn convert(&self) -> Vec; - - async fn read(stream: &mut OwnedReadHalf) -> Result { - let mut data = read_data(stream).await?; - let packet_id = get_var_int(&mut data)?; - if packet_id == Self::packet_id() { - return Ok(Self::get(&mut data)?) - } else { - return Err(Box::new(PacketError::InvalidPacketId)) - } - } - - async fn write(&self, stream: &mut OwnedWriteHalf) -> Result<()> { - write_data(stream, &mut self.convert()).await - } -} - -pub async fn read_data(stream: &mut OwnedReadHalf) -> Result> { - let length = read_var_int_stream(stream).await? as usize; - - let mut buffer: Vec = vec![0; length]; - stream.read_exact(&mut buffer).await?; - - Ok(buffer) -} -pub async fn write_data( - stream: &mut OwnedWriteHalf, - data: &mut Vec, -) -> Result<()> { - let mut out_data = convert_var_int(data.len() as i32); - out_data.append(data); - - stream.write_all(&out_data).await?; - - Ok(()) -} -async fn read_var_int_stream(stream: &mut OwnedReadHalf) -> Result { - let mut data: Vec = vec![]; - - loop { - let current_byte = stream.read_u8().await?; - - data.append(&mut vec![current_byte]); - - if (current_byte & CONTINUE_BIT) == 0 { - break; - } - } - - let varint = get_var_int(&mut data)?; - - Ok(varint) -} - -pub trait PacketArray: Sized { - fn get(data: &mut Vec) -> Result; - fn convert(&self) -> Vec; - - fn get_array(data: &mut Vec) -> Result> { - let length = get_var_int(data)?; - let mut out_data: Vec = vec![]; - for _ in 0..length { - out_data.push(Self::get(data)?); - } - Ok(out_data) - } - - fn convert_array(array: &mut Vec) -> Vec { - let length = array.len() as i32; - let mut data: Vec = convert_var_int(length); - for element in array { - data.append(&mut Self::convert(element)); - } - 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_uuid(data: &mut Vec) -> u128 { - ((data.remove(0) as u128) << 120) | - ((data.remove(0) as u128) << 112) | - ((data.remove(0) as u128) << 104) | - ((data.remove(0) as u128) << 96) | - ((data.remove(0) as u128) << 88) | - ((data.remove(0) as u128) << 80) | - ((data.remove(0) as u128) << 72) | - ((data.remove(0) as u128) << 64) | - ((data.remove(0) as u128) << 56) | - ((data.remove(0) as u128) << 48) | - ((data.remove(0) as u128) << 40) | - ((data.remove(0) as u128) << 32) | - ((data.remove(0) as u128) << 24) | - ((data.remove(0) as u128) << 16) | - ((data.remove(0) as u128) << 8) | - (data.remove(0) as u128) -} -pub fn convert_uuid(value: u128) -> Vec { - vec![ - ((value & 0xFF000000000000000000000000000000) >> 120) as u8, - ((value & 0xFF0000000000000000000000000000) >> 112) as u8, - ((value & 0xFF00000000000000000000000000) >> 104) as u8, - ((value & 0xFF000000000000000000000000) >> 96) as u8, - ((value & 0xFF0000000000000000000000) >> 88) as u8, - ((value & 0xFF00000000000000000000) >> 80) as u8, - ((value & 0xFF000000000000000000) >> 72) as u8, - ((value & 0xFF0000000000000000) >> 64) as u8, - ((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_var_int(data: &mut Vec) -> Result { - Ok(get_var(data, 32)? as i32) -} -pub fn convert_var_int(value: i32) -> Vec { - convert_var(value as i64) -} - -pub fn get_var_long(data: &mut Vec) -> Result { - get_var(data, 64) -} -pub fn convert_var_long(value: i64) -> Vec { - convert_var(value) -} - -fn get_var(data: &mut Vec, size: u8) -> Result { - let mut value: i64 = 0; - let mut position: u8 = 0; - - loop { - if data.is_empty() { - return Err(Box::new(PacketError::RanOutOfBytes)); - } - - let current_byte = data.remove(0); - value |= ((current_byte & SEGMENT_BITS) as i64) << position; - - if (current_byte & CONTINUE_BIT) == 0 { - break; - } - - position += 7; - - if position >= size { - return Err(Box::new(PacketError::ValueTooLarge)); - } - } - - Ok(value) -} -fn convert_var(mut value: i64) -> Vec { - let mut data: Vec = vec![]; - loop { - if (value & !(SEGMENT_BITS as i64)) == 0 { - data.append(&mut vec![value as u8]); - return data; - } - data.append( - &mut vec![(value & (SEGMENT_BITS as i64)) as u8 | CONTINUE_BIT]); - value >>= 7; - } -} - -pub fn get_string(data: &mut Vec) -> Result { - let length = get_var_int(data)? as usize; - let buffer = data[..length].to_vec(); - for _ in 0..length { data.remove(0); } - Ok(String::from_utf8_lossy(&buffer).to_string()) -} -pub fn convert_string(s: &str) -> Vec { - let length = s.len() as i32; - let mut data = convert_var_int(length); - data.append(&mut s.as_bytes().to_vec()); - data -} - -pub fn get_byte_array(data: &mut Vec) -> Result> { - let length = get_var_int(data)? as usize; - let buffer = data[..length].to_vec(); - for _ in 0..length { data.remove(0); } - Ok(buffer) -} -pub fn convert_byte_array(mut s: &mut Vec) -> Vec { - let length = s.len() as i32; - let mut data = convert_var_int(length); - data.append(&mut s); - data -} diff --git a/src/status.rs b/src/status.rs deleted file mode 100644 index 1f9dbdd..0000000 --- a/src/status.rs +++ /dev/null @@ -1,194 +0,0 @@ -// Yeahbut December 2023 - -pub mod clientbound { - - use tokio::net::tcp::OwnedReadHalf; - use serde::{Serialize, Deserialize}; - - use crate::mc_types::{self, Result, Packet, PacketError}; - - #[derive(Serialize, Deserialize)] - pub struct StatusVersion { - pub name: String, - pub protocol: i32, - } - - #[derive(Serialize, Deserialize)] - pub struct StatusPlayerInfo { - pub name: String, - pub id: String, - } - - #[derive(Serialize, Deserialize)] - pub struct StatusPlayers { - pub max: i32, - pub online: i32, - #[serde(skip_serializing_if = "Option::is_none")] - pub sample: Option> - } - - #[derive(Serialize, Deserialize)] - pub struct StatusResponseData { - pub version: StatusVersion, - pub description: mc_types::Chat, - pub players: StatusPlayers, - #[serde(skip_serializing_if = "Option::is_none")] - pub favicon: Option, - #[serde(skip_serializing_if = "Option::is_none")] - pub enforcesSecureChat: Option, - #[serde(skip_serializing_if = "Option::is_none")] - pub previewsChat: Option, - } - - pub enum StatusPackets { - Status(Status), - Ping(Ping), - } - - impl StatusPackets { - pub async fn read(stream: &mut OwnedReadHalf) -> Result { - let mut data = mc_types::read_data(stream).await?; - let packet_id = mc_types::get_var_int(&mut data)?; - if packet_id == Status::packet_id() { - return Ok(Self::Status(Status::get(&mut data)?)) - } else if packet_id == Ping::packet_id() { - return Ok(Self::Ping(Ping::get(&mut data)?)) - } else { - return Err(Box::new(PacketError::InvalidPacketId)) - } - } - } - - pub struct Status { - pub response: String - } - - impl Status { - - pub fn from_json(data: StatusResponseData) -> Result { - Ok(Self { - response: serde_json::to_string(&data)? - }) - } - - pub fn get_json(&self) -> Result { - Ok(serde_json::from_str(&self.response)?) - } - - } - - impl Packet for Status { - - fn packet_id() -> i32 {0} - - fn get(mut data: &mut Vec) -> Result { - Ok(Self { - response: mc_types::get_string(&mut data)? - }) - } - - fn convert(&self) -> Vec { - let mut data: Vec = vec![]; - data.append(&mut mc_types::convert_var_int(Self::packet_id())); - data.append(&mut mc_types::convert_string(&self.response)); - - data - } - - } - - pub struct Ping { - pub payload: i64 - } - - impl Packet for Ping { - - fn packet_id() -> i32 {1} - - fn get(mut data: &mut Vec) -> Result { - Ok(Self { - payload: mc_types::get_i64(&mut data) - }) - } - - fn convert(&self) -> Vec { - let mut data: Vec = vec![]; - data.append(&mut mc_types::convert_var_int(Self::packet_id())); - data.append(&mut mc_types::convert_i64(self.payload)); - - data - } - - } - -} - -pub mod serverbound { - - use tokio::net::tcp::OwnedReadHalf; - - use crate::mc_types::{self, Result, Packet, PacketError}; - - pub enum StatusPackets { - Status(Status), - Ping(Ping), - } - - impl StatusPackets { - pub async fn read(stream: &mut OwnedReadHalf) -> Result { - let mut data = mc_types::read_data(stream).await?; - let packet_id = mc_types::get_var_int(&mut data)?; - if packet_id == Status::packet_id() { - return Ok(Self::Status(Status::get(&mut data)?)) - } else if packet_id == Ping::packet_id() { - return Ok(Self::Ping(Ping::get(&mut data)?)) - } else { - return Err(Box::new(PacketError::InvalidPacketId)) - } - } - } - - pub struct Status {} - - impl Packet for Status { - - fn packet_id() -> i32 {0} - - fn get(mut data: &mut Vec) -> Result { - Ok(Self {}) - } - - fn convert(&self) -> Vec { - let mut data: Vec = vec![]; - data.append(&mut mc_types::convert_var_int(Self::packet_id())); - - data - } - - } - - pub struct Ping { - pub payload: i64 - } - - impl Packet for Ping { - - fn packet_id() -> i32 {1} - - fn get(mut data: &mut Vec) -> Result { - Ok(Self { - payload: mc_types::get_i64(&mut data) - }) - } - - fn convert(&self) -> Vec { - let mut data: Vec = vec![]; - data.append(&mut mc_types::convert_var_int(Self::packet_id())); - data.append(&mut mc_types::convert_i64(self.payload)); - - data - } - - } - -} diff --git a/src/status_handle.rs b/src/status_handle.rs index 7de6ed7..f79a4d0 100644 --- a/src/status_handle.rs +++ b/src/status_handle.rs @@ -9,9 +9,11 @@ use serde_json::Value; use base64::{Engine as _, engine::general_purpose}; use rand::Rng; -use crate::mc_types::{self, Result, Packet}; -use crate::status; -use crate::handshake; +use purple_cello_mc_protocol::{ + mc_types::{self, Result, Packet}, + handshake, + status, +}; async fn online_players( server_reader: &mut OwnedReadHalf, @@ -177,13 +179,17 @@ pub async fn get_upstream_status( server_port: 25565, next_state: 1, }.write(server_writer).await?; - mc_types::write_data(server_writer, &mut vec![0]).await?; - let mut data = mc_types::read_data(server_reader).await?; + status::serverbound::Status{}.write(server_writer).await?; + let packet = status::clientbound::Status::read(server_reader).await?; + let status_response = packet.get_json()?; - mc_types::get_u8(&mut data); - let json = mc_types::get_string(&mut data)?; - let status_response: status::clientbound::StatusResponseData = - serde_json::from_str(&json)?; + // mc_types::write_data(server_writer, &mut vec![0]).await?; + // let mut data = mc_types::read_data(server_reader).await?; + + // mc_types::get_u8(&mut data); + // let json = mc_types::get_string(&mut data)?; + // let status_response: status::clientbound::StatusResponseData = + // serde_json::from_str(&json)?; // let mut out_data: Vec = vec![1]; // out_data.append(&mut mc_types::convert_i64(0));