Skip to content

Commit

Permalink
Merge pull request #137 from Alvsch/velocity-support
Browse files Browse the repository at this point in the history
Fixed velocity support
  • Loading branch information
Snowiiii authored Oct 16, 2024
2 parents 5ed7cae + b8fe6a6 commit a07101d
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 23 deletions.
9 changes: 7 additions & 2 deletions pumpkin/src/client/client_packet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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},
};

Expand Down Expand Up @@ -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,
Expand Down
28 changes: 19 additions & 9 deletions pumpkin/src/client/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::{
collections::VecDeque,
io::{self, Write},
net::SocketAddr,
sync::{
Expand Down Expand Up @@ -112,7 +113,7 @@ pub struct Client {
/// The packet decoder for incoming packets.
dec: Arc<Mutex<PacketDecoder>>,
/// A queue of raw packets received from the client, waiting to be processed.
pub client_packets_queue: Arc<Mutex<Vec<RawPacket>>>,
pub client_packets_queue: Arc<Mutex<VecDeque<RawPacket>>>,

/// Indicates whether the client should be converted into a player.
pub make_player: AtomicBool,
Expand Down Expand Up @@ -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()),
Expand All @@ -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
Expand Down Expand Up @@ -209,8 +210,9 @@ impl Client {

/// Processes all packets send by the client
pub async fn process_packets(&self, server: &Arc<Server>) {
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)
Expand All @@ -224,6 +226,7 @@ impl Client {
server: &Arc<Server>,
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),
Expand Down Expand Up @@ -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();
}
Expand Down
2 changes: 1 addition & 1 deletion pumpkin/src/entity/player.rs
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ impl Player {
impl Player {
pub async fn process_packets(&self, server: &Arc<Server>) {
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) => {
Expand Down
2 changes: 1 addition & 1 deletion pumpkin/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
57 changes: 47 additions & 10 deletions pumpkin/src/proxy/velocity.rs
Original file line number Diff line number Diff line change
@@ -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<Sha256>;

Expand All @@ -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");
Expand All @@ -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;
}
Expand All @@ -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::<IpAddr>().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,
});
}
}

0 comments on commit a07101d

Please sign in to comment.