diff options
| author | mat <27899617+mat-1@users.noreply.github.com> | 2025-12-11 22:47:16 -0600 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-12-11 22:47:16 -0600 |
| commit | 4a66f002c276a57e028e9456f6800b0b3c248885 (patch) | |
| tree | f87cbdc51c09d497548f972b9b1633ceb7606443 /azalea-client/src/plugins | |
| parent | ff1e28f88e93ba83cf76569b5613445b841efd45 (diff) | |
| download | azalea-drasl-4a66f002c276a57e028e9456f6800b0b3c248885.tar.xz | |
Add options to request Mojang sessionserver with a proxy (#293)
* add options to request mojang sessionserver with a socks5 proxy
* update changelog
* rename auth_proxy to sessionserver_proxy
Diffstat (limited to 'azalea-client/src/plugins')
| -rw-r--r-- | azalea-client/src/plugins/join.rs | 17 | ||||
| -rw-r--r-- | azalea-client/src/plugins/login.rs | 51 |
2 files changed, 52 insertions, 16 deletions
diff --git a/azalea-client/src/plugins/join.rs b/azalea-client/src/plugins/join.rs index a8f6e3c5..538369b0 100644 --- a/azalea-client/src/plugins/join.rs +++ b/azalea-client/src/plugins/join.rs @@ -64,9 +64,22 @@ pub struct StartJoinServerEvent { /// This is inserted as a component on clients to make auto-reconnecting work. #[derive(Debug, Clone, Component)] pub struct ConnectOpts { + /// The unresolved address that we're going to tell the server that we used + /// to connect. pub address: ServerAddress, + /// The actual IP and port that we're going to make a connection to. pub resolved_address: SocketAddr, - pub proxy: Option<Proxy>, + /// The SOCKS5 proxy used for connecting to the Minecraft server. + pub server_proxy: Option<Proxy>, + /// The SOCKS5 proxy that will be used when authenticating our server join + /// with Mojang. + /// + /// This should typically be either the same as [`Self::server_proxy`], or + /// `None`. + /// + /// This is useful to set if a server has `prevent-proxy-connections` + /// enabled. + pub sessionserver_proxy: Option<Proxy>, } /// An event that's sent when creating the TCP connection and sending the first @@ -158,7 +171,7 @@ pub fn handle_start_join_server_event( async fn create_conn_and_send_intention_packet( opts: ConnectOpts, ) -> Result<LoginConn, ConnectionError> { - let mut conn = if let Some(proxy) = opts.proxy { + let mut conn = if let Some(proxy) = opts.server_proxy { Connection::new_with_proxy(&opts.resolved_address, proxy).await? } else { Connection::new(&opts.resolved_address).await? diff --git a/azalea-client/src/plugins/login.rs b/azalea-client/src/plugins/login.rs index 46ff8ea9..46ab20c4 100644 --- a/azalea-client/src/plugins/login.rs +++ b/azalea-client/src/plugins/login.rs @@ -1,19 +1,20 @@ #[cfg(feature = "online-mode")] use azalea_auth::sessionserver::ClientSessionServerError; -use azalea_protocol::packets::login::{ - ClientboundHello, ServerboundCustomQueryAnswer, ServerboundKey, +use azalea_protocol::{ + connect::Proxy, + packets::login::{ClientboundHello, ServerboundCustomQueryAnswer, ServerboundKey}, }; use bevy_app::prelude::*; use bevy_ecs::prelude::*; use bevy_tasks::{IoTaskPool, Task, futures_lite::future}; use thiserror::Error; -use tracing::{debug, error, trace}; +use tracing::{debug, error, trace, warn}; use super::{ connection::RawConnection, packet::login::{ReceiveCustomQueryEvent, ReceiveHelloEvent, SendLoginPacketEvent}, }; -use crate::Account; +use crate::{Account, join::ConnectOpts}; /// Some systems that run during the `login` state. pub struct LoginPlugin; @@ -24,15 +25,29 @@ impl Plugin for LoginPlugin { } } -fn handle_receive_hello_event(receive_hello: On<ReceiveHelloEvent>, mut commands: Commands) { +fn handle_receive_hello_event( + receive_hello: On<ReceiveHelloEvent>, + mut commands: Commands, + query: Query<&ConnectOpts>, +) { let task_pool = IoTaskPool::get(); let account = receive_hello.account.clone(); let packet = receive_hello.packet.clone(); - let player = receive_hello.entity; + let client = receive_hello.entity; + + // we store the auth proxy in the ConnectOpts component to make it easily + // configurable. that component should've definitely been inserted by now, but + // if it somehow wasn't then we should let the user know. + let connect_opts = if let Ok(opts) = query.get(client) { + opts.sessionserver_proxy.clone() + } else { + warn!("ConnectOpts component missing on a client ({client}) that got ReceiveHelloEvent"); + None + }; - let task = task_pool.spawn(auth_with_account(account, packet)); - commands.entity(player).insert(AuthTask(task)); + let task = task_pool.spawn(auth_with_account(account, packet, connect_opts)); + commands.entity(client).insert(AuthTask(task)); } /// A marker component on our clients that indicates that the server is @@ -92,6 +107,7 @@ pub enum AuthWithAccountError { pub async fn auth_with_account( account: Account, packet: ClientboundHello, + proxy: Option<Proxy>, ) -> Result<(ServerboundKey, PrivateKey), AuthWithAccountError> { let Ok(encrypt_res) = azalea_crypto::encrypt(&packet.public_key, &packet.challenge) else { return Err(AuthWithAccountError::Encryption(packet)); @@ -116,22 +132,29 @@ pub async fn auth_with_account( // after too many let mut attempts: usize = 1; + let proxy = proxy.map(Proxy::into); + while let Err(err) = { + use azalea_auth::sessionserver::{self, SessionServerJoinOpts}; + let access_token = access_token.lock().clone(); let uuid = &account .uuid .expect("Uuid must be present if access token is present."); + let proxy = proxy.clone(); + // this is necessary since reqwest usually depends on tokio and we're using // `futures` here - async_compat::Compat::new(azalea_auth::sessionserver::join( - &access_token, - &packet.public_key, - &private_key, + async_compat::Compat::new(sessionserver::join(SessionServerJoinOpts { + access_token: &access_token, + public_key: &packet.public_key, + private_key: &private_key, uuid, - &packet.server_id, - )) + server_id: &packet.server_id, + proxy, + })) .await } { if attempts >= 2 { |
