Fixed velocity support

This commit is contained in:
Alvsch 2024-10-16 23:44:45 +02:00
parent e725d1995e
commit fb795df5e8
5 changed files with 68 additions and 31 deletions

View File

@ -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(),
))

View File

@ -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,

View File

@ -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<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,
@ -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<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)
@ -221,22 +220,24 @@ 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),
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();
}

View File

@ -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) => {

View File

@ -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,
});
}
}