From fb795df5e877dd2e1e6d2a3ddeaf0ed50b989af3 Mon Sep 17 00:00:00 2001 From: Alvsch Date: Wed, 16 Oct 2024 23:44:45 +0200 Subject: [PATCH 1/6] Fixed velocity support --- pumpkin-protocol/src/bytebuf/mod.rs | 1 + pumpkin/src/client/client_packet.rs | 6 ++-- pumpkin/src/client/mod.rs | 47 +++++++++++++++++------------ pumpkin/src/entity/player.rs | 2 +- pumpkin/src/proxy/velocity.rs | 43 ++++++++++++++++++++------ 5 files changed, 68 insertions(+), 31 deletions(-) diff --git a/pumpkin-protocol/src/bytebuf/mod.rs b/pumpkin-protocol/src/bytebuf/mod.rs index 3b46f2f90..9901615de 100644 --- a/pumpkin-protocol/src/bytebuf/mod.rs +++ b/pumpkin-protocol/src/bytebuf/mod.rs @@ -370,6 +370,7 @@ impl ByteBuffer { if self.buffer.len() >= len { Ok(self.buffer.copy_to_bytes(len)) } else { + dbg!("{:?} < {:?}", self.buffer.len(), len); Err(DeserializerError::Message( "Unable to copy bytes".to_string(), )) diff --git a/pumpkin/src/client/client_packet.rs b/pumpkin/src/client/client_packet.rs index d185438e6..4ee37cf4b 100644 --- a/pumpkin/src/client/client_packet.rs +++ b/pumpkin/src/client/client_packet.rs @@ -20,7 +20,7 @@ use uuid::Uuid; use crate::{ client::authentication::{self, validate_textures, GameProfile}, entity::player::{ChatMode, Hand}, - proxy::velocity::velocity_login, + proxy::velocity::{self, velocity_login}, server::{Server, CURRENT_MC_VERSION}, }; @@ -180,7 +180,9 @@ impl Client { Err(AuthError::MissingAuthClient) } - pub fn handle_plugin_response(&self, _plugin_response: SLoginPluginResponse) {} + pub fn handle_plugin_response(&self, plugin_response: SLoginPluginResponse) { + velocity::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 83e61abaa..b18b1f064 100644 --- a/pumpkin/src/client/mod.rs +++ b/pumpkin/src/client/mod.rs @@ -1,10 +1,8 @@ use std::{ - io::{self, Write}, - net::SocketAddr, - sync::{ + collections::VecDeque, io::{self, Write}, net::SocketAddr, sync::{ atomic::{AtomicBool, AtomicI32}, Arc, - }, + } }; use crate::{ @@ -110,7 +108,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, @@ -140,7 +138,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()), @@ -150,7 +148,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 @@ -206,8 +204,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) @@ -221,22 +220,24 @@ 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), + pumpkin_protocol::ConnectionState::HandShake => self.handle_handshake_packet(packet).unwrap(), + pumpkin_protocol::ConnectionState::Status => self.handle_status_packet(server, packet).unwrap(), // TODO: Check config if transfer is enabled pumpkin_protocol::ConnectionState::Login | pumpkin_protocol::ConnectionState::Transfer => { - self.handle_login_packet(server, packet).await + self.handle_login_packet(server, packet).await.unwrap() } pumpkin_protocol::ConnectionState::Config => { - self.handle_config_packet(server, packet).await + self.handle_config_packet(server, packet).await.unwrap() } _ => { log::error!("Invalid Connection state {:?}", self.connection_state); - Ok(()) + // Ok(()) } - } + }; + Ok(()) } fn handle_handshake_packet(&self, packet: &mut RawPacket) -> Result<(), DeserializerError> { @@ -378,13 +379,21 @@ 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) => { + dbg!("a"); + 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/proxy/velocity.rs b/pumpkin/src/proxy/velocity.rs index e97e84c97..453e4471b 100644 --- a/pumpkin/src/proxy/velocity.rs +++ b/pumpkin/src/proxy/velocity.rs @@ -4,7 +4,7 @@ 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; @@ -27,7 +27,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 +37,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; } @@ -60,11 +60,36 @@ pub fn receive_plugin_response( )); return; } - // TODO: no unwrap - let addr: SocketAddr = buf.get_string().unwrap().parse().unwrap(); + // TODO: dont default to localhost + let addr: SocketAddr = buf.get_string().unwrap().parse() + .unwrap_or_else(|_| ([127, 0, 0, 1], 25565).into()); + *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, + }); } } From 4f17b96f1d9e7758326ee4325be4c935caa57966 Mon Sep 17 00:00:00 2001 From: Alvsch <94403567+Alvsch@users.noreply.github.com> Date: Wed, 16 Oct 2024 23:51:00 +0200 Subject: [PATCH 2/6] Removed dbg statement --- pumpkin-protocol/src/bytebuf/mod.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/pumpkin-protocol/src/bytebuf/mod.rs b/pumpkin-protocol/src/bytebuf/mod.rs index 9901615de..3b46f2f90 100644 --- a/pumpkin-protocol/src/bytebuf/mod.rs +++ b/pumpkin-protocol/src/bytebuf/mod.rs @@ -370,7 +370,6 @@ impl ByteBuffer { if self.buffer.len() >= len { Ok(self.buffer.copy_to_bytes(len)) } else { - dbg!("{:?} < {:?}", self.buffer.len(), len); Err(DeserializerError::Message( "Unable to copy bytes".to_string(), )) From d35461eea1fce59c19805c0a3bafb3033e32febf Mon Sep 17 00:00:00 2001 From: Alvsch Date: Wed, 16 Oct 2024 23:53:23 +0200 Subject: [PATCH 3/6] removed unwraps --- pumpkin/src/client/client_packet.rs | 2 +- pumpkin/src/client/mod.rs | 13 ++++++------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/pumpkin/src/client/client_packet.rs b/pumpkin/src/client/client_packet.rs index aa26b1407..8440a9803 100644 --- a/pumpkin/src/client/client_packet.rs +++ b/pumpkin/src/client/client_packet.rs @@ -20,7 +20,7 @@ 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}, }; diff --git a/pumpkin/src/client/mod.rs b/pumpkin/src/client/mod.rs index 1692f48ca..a362ac19c 100644 --- a/pumpkin/src/client/mod.rs +++ b/pumpkin/src/client/mod.rs @@ -225,22 +225,21 @@ impl Client { ) -> Result<(), DeserializerError> { println!("{:?}", self.connection_state.load()); match self.connection_state.load() { - pumpkin_protocol::ConnectionState::HandShake => self.handle_handshake_packet(packet).unwrap(), - pumpkin_protocol::ConnectionState::Status => self.handle_status_packet(server, packet).unwrap(), + pumpkin_protocol::ConnectionState::HandShake => self.handle_handshake_packet(packet), + pumpkin_protocol::ConnectionState::Status => self.handle_status_packet(server, packet), // TODO: Check config if transfer is enabled pumpkin_protocol::ConnectionState::Login | pumpkin_protocol::ConnectionState::Transfer => { - self.handle_login_packet(server, packet).await.unwrap() + self.handle_login_packet(server, packet).await } pumpkin_protocol::ConnectionState::Config => { - self.handle_config_packet(server, packet).await.unwrap() + self.handle_config_packet(server, packet).await } _ => { log::error!("Invalid Connection state {:?}", self.connection_state); - // Ok(()) + Ok(()) } - }; - Ok(()) + } } fn handle_handshake_packet(&self, packet: &mut RawPacket) -> Result<(), DeserializerError> { From 6c9862cce8bdef7521cf1c850088bd5aefa5b746 Mon Sep 17 00:00:00 2001 From: Alvsch Date: Thu, 17 Oct 2024 00:06:52 +0200 Subject: [PATCH 4/6] velocity forwarded address port default to 0 --- pumpkin/src/proxy/velocity.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/pumpkin/src/proxy/velocity.rs b/pumpkin/src/proxy/velocity.rs index 453e4471b..8a422ff3c 100644 --- a/pumpkin/src/proxy/velocity.rs +++ b/pumpkin/src/proxy/velocity.rs @@ -1,4 +1,4 @@ -use std::net::SocketAddr; +use std::net::{IpAddr, SocketAddr}; use bytes::{BufMut, BytesMut}; use hmac::{Hmac, Mac}; @@ -60,9 +60,8 @@ pub fn receive_plugin_response( )); return; } - // TODO: dont default to localhost - let addr: SocketAddr = buf.get_string().unwrap().parse() - .unwrap_or_else(|_| ([127, 0, 0, 1], 25565).into()); + // TODO: no unwrap + let addr: SocketAddr = SocketAddr::new(buf.get_string().unwrap().parse::().unwrap(), 0); *client.address.lock() = addr; From a863e973688af0cdb07141a3a6112d7f5f0fac34 Mon Sep 17 00:00:00 2001 From: Alvsch Date: Thu, 17 Oct 2024 00:23:05 +0200 Subject: [PATCH 5/6] forwarded port defaults to player socket address port --- pumpkin/src/client/client_packet.rs | 5 ++- pumpkin/src/client/mod.rs | 9 ++++-- pumpkin/src/main.rs | 2 +- pumpkin/src/proxy/velocity.rs | 47 ++++++++++++++++++----------- 4 files changed, 41 insertions(+), 22 deletions(-) diff --git a/pumpkin/src/client/client_packet.rs b/pumpkin/src/client/client_packet.rs index 8440a9803..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::{receive_plugin_response, velocity_login}}, + proxy::{ + bungeecord::bungeecord_login, + velocity::{receive_plugin_response, velocity_login}, + }, server::{Server, CURRENT_MC_VERSION}, }; diff --git a/pumpkin/src/client/mod.rs b/pumpkin/src/client/mod.rs index a362ac19c..12b3b8f7d 100644 --- a/pumpkin/src/client/mod.rs +++ b/pumpkin/src/client/mod.rs @@ -1,8 +1,11 @@ use std::{ - collections::VecDeque, io::{self, Write}, net::SocketAddr, sync::{ + collections::VecDeque, + io::{self, Write}, + net::SocketAddr, + sync::{ atomic::{AtomicBool, AtomicI32}, Arc, - } + }, }; use crate::{ @@ -394,7 +397,7 @@ impl Client { dbg!("a"); self.kick(&err.to_string()); break; - }, + } } } dec.clear(); 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 8a422ff3c..634a72d31 100644 --- a/pumpkin/src/proxy/velocity.rs +++ b/pumpkin/src/proxy/velocity.rs @@ -4,11 +4,14 @@ use bytes::{BufMut, BytesMut}; use hmac::{Hmac, Mac}; use pumpkin_config::proxy::VelocityConfig; use pumpkin_protocol::{ - bytebuf::ByteBuffer, client::login::{CLoginPluginRequest, CLoginSuccess}, server::login::SLoginPluginResponse, Property + 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; @@ -61,28 +64,31 @@ pub fn receive_plugin_response( return; } // TODO: no unwrap - let addr: SocketAddr = SocketAddr::new(buf.get_string().unwrap().parse::().unwrap(), 0); + let addr: SocketAddr = SocketAddr::new( + buf.get_string().unwrap().parse::().unwrap(), + client.address.lock().port(), + ); *client.address.lock() = addr; 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, + 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(); + .unwrap(); client.send_packet(&CLoginSuccess { uuid: &uuid, @@ -90,5 +96,12 @@ pub fn receive_plugin_response( properties: &properties, strict_error_handling: false, }); + + *client.gameprofile.lock() = Some(GameProfile { + id: uuid, + name: username, + properties, + profile_actions: None, + }); } } From b8fe6a63da211125b88a9190a73df8c91a0b18cb Mon Sep 17 00:00:00 2001 From: Alvsch Date: Thu, 17 Oct 2024 00:24:49 +0200 Subject: [PATCH 6/6] removed another debug --- pumpkin/src/client/mod.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/pumpkin/src/client/mod.rs b/pumpkin/src/client/mod.rs index 12b3b8f7d..9702cad41 100644 --- a/pumpkin/src/client/mod.rs +++ b/pumpkin/src/client/mod.rs @@ -394,7 +394,6 @@ impl Client { } } Err(err) => { - dbg!("a"); self.kick(&err.to_string()); break; }