Added some clientbound login packets
This commit is contained in:
parent
7ffe2f3627
commit
b4f039edb6
122
src/login.rs
122
src/login.rs
|
@ -4,10 +4,12 @@ pub mod clientbound {
|
|||
|
||||
use tokio::net::tcp::OwnedReadHalf;
|
||||
|
||||
use crate::mc_types::{self, Result, Packet, PacketError};
|
||||
use crate::mc_types::{self, Result, Packet, PacketArray, PacketError};
|
||||
|
||||
pub enum Login {
|
||||
Disconnect(Disconnect),
|
||||
EncryptionRequest(EncryptionRequest),
|
||||
LoginSuccess(LoginSuccess),
|
||||
}
|
||||
|
||||
impl Login {
|
||||
|
@ -16,6 +18,11 @@ pub mod clientbound {
|
|||
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))
|
||||
}
|
||||
|
@ -46,4 +53,117 @@ pub mod clientbound {
|
|||
|
||||
}
|
||||
|
||||
pub struct EncryptionRequest {
|
||||
pub server_id: String,
|
||||
pub public_key: Vec<u8>,
|
||||
pub verify_token: Vec<u8>,
|
||||
}
|
||||
|
||||
impl Packet for EncryptionRequest {
|
||||
|
||||
fn packet_id() -> i32 {1}
|
||||
|
||||
fn get(mut data: &mut Vec<u8>) -> Result<Self> {
|
||||
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<u8> {
|
||||
let mut data: Vec<u8> = 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<LoginSuccessProperty>,
|
||||
}
|
||||
|
||||
impl Packet for LoginSuccess {
|
||||
|
||||
fn packet_id() -> i32 {2}
|
||||
|
||||
fn get(mut data: &mut Vec<u8>) -> Result<Self> {
|
||||
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<u8> {
|
||||
let mut data: Vec<u8> = 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<String>,
|
||||
}
|
||||
|
||||
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<u8>) -> Result<Self> {
|
||||
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<String> = None;
|
||||
if is_signed {
|
||||
signature = Some(mc_types::get_string(&mut data)?);
|
||||
}
|
||||
Ok(Self {
|
||||
name,
|
||||
value,
|
||||
signature,
|
||||
})
|
||||
}
|
||||
|
||||
fn convert(&self) -> Vec<u8> {
|
||||
let mut data: Vec<u8> = 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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
104
src/mc_types.rs
104
src/mc_types.rs
|
@ -18,12 +18,18 @@ 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"),
|
||||
}
|
||||
|
@ -32,25 +38,6 @@ impl fmt::Display for PacketError {
|
|||
|
||||
impl Error for PacketError {}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum VarIntError {
|
||||
ValueTooLarge,
|
||||
RanOutOfBytes,
|
||||
}
|
||||
|
||||
impl fmt::Display for VarIntError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
VarIntError::ValueTooLarge =>
|
||||
write!(f, "VarInt value is too large"),
|
||||
VarIntError::RanOutOfBytes =>
|
||||
write!(f, "Ran out of bytes while reading VarInt"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Error for VarIntError {}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct Chat {
|
||||
pub text: String,
|
||||
|
@ -114,6 +101,29 @@ async fn read_var_int_stream(stream: &mut OwnedReadHalf) -> Result<i32> {
|
|||
Ok(varint)
|
||||
}
|
||||
|
||||
pub trait PacketArray: Sized {
|
||||
fn get(data: &mut Vec<u8>) -> Result<Self>;
|
||||
fn convert(&self) -> Vec<u8>;
|
||||
|
||||
fn get_array(data: &mut Vec<u8>) -> Result<Vec<Self>> {
|
||||
let length = get_var_int(data)?;
|
||||
let mut out_data: Vec<Self> = vec![];
|
||||
for _ in 0..length {
|
||||
out_data.push(Self::get(data)?);
|
||||
}
|
||||
Ok(out_data)
|
||||
}
|
||||
|
||||
fn convert_array(array: &mut Vec<Self>) -> Vec<u8> {
|
||||
let length = array.len() as i32;
|
||||
let mut data: Vec<u8> = convert_var_int(length);
|
||||
for element in array {
|
||||
data.append(&mut Self::convert(element));
|
||||
}
|
||||
data
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_bool(data: &mut Vec<u8>) -> bool {
|
||||
data.remove(0) != 0
|
||||
}
|
||||
|
@ -219,6 +229,45 @@ pub fn convert_f64(value: f64) -> Vec<u8> {
|
|||
convert_u64(value as u64)
|
||||
}
|
||||
|
||||
pub fn get_uuid(data: &mut Vec<u8>) -> 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<u8> {
|
||||
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<u8>) -> Result<i32> {
|
||||
Ok(get_var(data, 32)? as i32)
|
||||
}
|
||||
|
@ -239,7 +288,7 @@ fn get_var(data: &mut Vec<u8>, size: u8) -> Result<i64> {
|
|||
|
||||
loop {
|
||||
if data.is_empty() {
|
||||
return Err(Box::new(VarIntError::RanOutOfBytes));
|
||||
return Err(Box::new(PacketError::RanOutOfBytes));
|
||||
}
|
||||
|
||||
let current_byte = data.remove(0);
|
||||
|
@ -252,7 +301,7 @@ fn get_var(data: &mut Vec<u8>, size: u8) -> Result<i64> {
|
|||
position += 7;
|
||||
|
||||
if position >= size {
|
||||
return Err(Box::new(VarIntError::ValueTooLarge));
|
||||
return Err(Box::new(PacketError::ValueTooLarge));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -283,3 +332,16 @@ pub fn convert_string(s: &str) -> Vec<u8> {
|
|||
data.append(&mut s.as_bytes().to_vec());
|
||||
data
|
||||
}
|
||||
|
||||
pub fn get_byte_array(data: &mut Vec<u8>) -> Result<Vec<u8>> {
|
||||
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<u8>) -> Vec<u8> {
|
||||
let length = s.len() as i32;
|
||||
let mut data = convert_var_int(length);
|
||||
data.append(&mut s);
|
||||
data
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue