diff --git a/pumpkin/src/client/client_packet.rs b/pumpkin/src/client/client_packet.rs index b2cfd5bb5..dbfcc89d5 100644 --- a/pumpkin/src/client/client_packet.rs +++ b/pumpkin/src/client/client_packet.rs @@ -20,7 +20,10 @@ use uuid::Uuid; use crate::{ client::authentication::{self, validate_textures, GameProfile}, entity::player::{ChatMode, Hand}, - proxy::{bungeecord::bungeecord_login, velocity::velocity_login}, + proxy::{ + bungeecord::bungeecord_login, + velocity::{receive_plugin_response, velocity_login}, + }, server::{Server, CURRENT_MC_VERSION}, }; @@ -194,7 +197,9 @@ impl Client { Err(AuthError::MissingAuthClient) } - pub fn handle_plugin_response(&self, _plugin_response: SLoginPluginResponse) {} + pub fn handle_plugin_response(&self, plugin_response: SLoginPluginResponse) { + receive_plugin_response(self, &ADVANCED_CONFIG.proxy.velocity, plugin_response); + } pub fn handle_login_acknowledged( &self, diff --git a/pumpkin/src/client/mod.rs b/pumpkin/src/client/mod.rs index cf0cc8b74..9702cad41 100644 --- a/pumpkin/src/client/mod.rs +++ b/pumpkin/src/client/mod.rs @@ -1,4 +1,5 @@ use std::{ + collections::VecDeque, io::{self, Write}, net::SocketAddr, sync::{ @@ -112,7 +113,7 @@ pub struct Client { /// The packet decoder for incoming packets. dec: Arc>, /// A queue of raw packets received from the client, waiting to be processed. - pub client_packets_queue: Arc>>, + pub client_packets_queue: Arc>>, /// Indicates whether the client should be converted into a player. pub make_player: AtomicBool, @@ -143,7 +144,7 @@ impl Client { dec: Arc::new(Mutex::new(PacketDecoder::default())), encryption: AtomicBool::new(false), closed: AtomicBool::new(false), - client_packets_queue: Arc::new(Mutex::new(Vec::new())), + client_packets_queue: Arc::new(Mutex::new(VecDeque::new())), make_player: AtomicBool::new(false), keep_alive_sender, last_alive_received: AtomicCell::new(std::time::Instant::now()), @@ -153,7 +154,7 @@ impl Client { /// Adds a Incoming packet to the queue pub fn add_packet(&self, packet: RawPacket) { let mut client_packets_queue = self.client_packets_queue.lock(); - client_packets_queue.push(packet); + client_packets_queue.push_back(packet); } /// Sets the Packet encryption @@ -209,8 +210,9 @@ impl Client { /// Processes all packets send by the client pub async fn process_packets(&self, server: &Arc) { - while let Some(mut packet) = self.client_packets_queue.lock().pop() { + while let Some(mut packet) = self.client_packets_queue.lock().pop_front() { let _ = self.handle_packet(server, &mut packet).await.map_err(|e| { + dbg!("{:?}", packet.id); let text = format!("Error while reading incoming packet {}", e); log::error!("{}", text); self.kick(&text) @@ -224,6 +226,7 @@ impl Client { server: &Arc, packet: &mut RawPacket, ) -> Result<(), DeserializerError> { + println!("{:?}", self.connection_state.load()); match self.connection_state.load() { pumpkin_protocol::ConnectionState::HandShake => self.handle_handshake_packet(packet), pumpkin_protocol::ConnectionState::Status => self.handle_status_packet(server, packet), @@ -381,13 +384,20 @@ impl Client { if !received_data.is_empty() { let mut dec = self.dec.lock(); dec.queue_slice(&received_data); - match dec.decode() { - Ok(packet) => { - if let Some(packet) = packet { - self.add_packet(packet); + loop { + match dec.decode() { + Ok(packet) => { + if let Some(packet) = packet { + self.add_packet(packet); + } else { + break; + } + } + Err(err) => { + self.kick(&err.to_string()); + break; } } - Err(err) => self.kick(&err.to_string()), } dec.clear(); } diff --git a/pumpkin/src/entity/player.rs b/pumpkin/src/entity/player.rs index e51e2ad32..865c8a58a 100644 --- a/pumpkin/src/entity/player.rs +++ b/pumpkin/src/entity/player.rs @@ -276,7 +276,7 @@ impl Player { impl Player { pub async fn process_packets(&self, server: &Arc) { let mut packets = self.client.client_packets_queue.lock(); - while let Some(mut packet) = packets.pop() { + while let Some(mut packet) = packets.pop_back() { match self.handle_play_packet(server, &mut packet).await { Ok(_) => {} Err(e) => { diff --git a/pumpkin/src/main.rs b/pumpkin/src/main.rs index 59944e348..7b7be6fae 100644 --- a/pumpkin/src/main.rs +++ b/pumpkin/src/main.rs @@ -221,7 +221,7 @@ fn main() -> io::Result<()> { )?; let keep_alive = tokio::sync::mpsc::channel(1024); let client = - Arc::new(Client::new(id, connection, addr, keep_alive.0.into())); + Arc::new(Client::new(id, connection, address, keep_alive.0.into())); { let client = client.clone(); diff --git a/pumpkin/src/proxy/velocity.rs b/pumpkin/src/proxy/velocity.rs index e97e84c97..634a72d31 100644 --- a/pumpkin/src/proxy/velocity.rs +++ b/pumpkin/src/proxy/velocity.rs @@ -1,14 +1,17 @@ -use std::net::SocketAddr; +use std::net::{IpAddr, SocketAddr}; use bytes::{BufMut, BytesMut}; use hmac::{Hmac, Mac}; use pumpkin_config::proxy::VelocityConfig; use pumpkin_protocol::{ - bytebuf::ByteBuffer, client::login::CLoginPluginRequest, server::login::SLoginPluginResponse, + bytebuf::ByteBuffer, + client::login::{CLoginPluginRequest, CLoginSuccess}, + server::login::SLoginPluginResponse, + Property, }; use sha2::Sha256; -use crate::client::Client; +use crate::client::{authentication::GameProfile, Client}; type HmacSha256 = Hmac; @@ -27,7 +30,7 @@ pub fn velocity_login(client: &Client) { )); } -pub fn check_integrity(data: (&[u8], &[u8]), secret: String) -> bool { +pub fn check_integrity(data: (&[u8], &[u8]), secret: &str) -> bool { let (signature, data_without_signature) = data; let mut mac = HmacSha256::new_from_slice(secret.as_bytes()).expect("HMAC can take key of any size"); @@ -37,14 +40,14 @@ pub fn check_integrity(data: (&[u8], &[u8]), secret: String) -> bool { pub fn receive_plugin_response( client: &Client, - config: VelocityConfig, + config: &VelocityConfig, response: SLoginPluginResponse, ) { dbg!("velocity response"); if let Some(data) = response.data { let (signature, data_without_signature) = data.split_at(32); - if !check_integrity((signature, data_without_signature), config.secret) { + if !check_integrity((signature, data_without_signature), &config.secret) { client.kick("Unable to verify player details"); return; } @@ -61,10 +64,44 @@ pub fn receive_plugin_response( return; } // TODO: no unwrap - let addr: SocketAddr = buf.get_string().unwrap().parse().unwrap(); + let addr: SocketAddr = SocketAddr::new( + buf.get_string().unwrap().parse::().unwrap(), + client.address.lock().port(), + ); + *client.address.lock() = addr; - todo!() - } else { - client.kick("This server requires you to connect with Velocity.") + + let uuid = buf.get_uuid().unwrap(); + + let username = buf.get_string().unwrap(); + + // Read game profile properties + let properties = buf + .get_list(|data| { + let name = data.get_string()?; + let value = data.get_string()?; + let signature = data.get_option(|data| data.get_string())?; + + Ok(Property { + name, + value, + signature, + }) + }) + .unwrap(); + + client.send_packet(&CLoginSuccess { + uuid: &uuid, + username: &username, + properties: &properties, + strict_error_handling: false, + }); + + *client.gameprofile.lock() = Some(GameProfile { + id: uuid, + name: username, + properties, + profile_actions: None, + }); } }