From 6c110f2731c3893af397cc6a660f374ff705c99b Mon Sep 17 00:00:00 2001 From: mat <27899617+mat-1@users.noreply.github.com> Date: Sun, 30 Nov 2025 21:04:12 -0600 Subject: Add `online-mode` Cargo feature (#281) * Add `online-mode` cargo feature * fix bad formatting in Cargo.toml --- azalea-client/src/plugins/chat/handler.rs | 13 ++++- azalea-client/src/plugins/chat_signing.rs | 4 +- azalea-client/src/plugins/disconnect.rs | 7 ++- azalea-client/src/plugins/login.rs | 94 +++++++++++++++++-------------- azalea-client/src/plugins/mod.rs | 8 ++- 5 files changed, 75 insertions(+), 51 deletions(-) (limited to 'azalea-client/src/plugins') diff --git a/azalea-client/src/plugins/chat/handler.rs b/azalea-client/src/plugins/chat/handler.rs index 5a2a065c..49f27209 100644 --- a/azalea-client/src/plugins/chat/handler.rs +++ b/azalea-client/src/plugins/chat/handler.rs @@ -1,6 +1,5 @@ use std::time::{SystemTime, UNIX_EPOCH}; -use azalea_crypto::SignChatMessageOptions; use azalea_protocol::packets::{ Packet, game::{ServerboundChat, ServerboundChatCommand, s_chat::LastSeenMessagesUpdate}, @@ -8,7 +7,9 @@ use azalea_protocol::packets::{ use bevy_ecs::prelude::*; use super::ChatKind; -use crate::{Account, chat_signing::ChatSigningSession, packet::game::SendGamePacketEvent}; +use crate::packet::game::SendGamePacketEvent; +#[cfg(feature = "online-mode")] +use crate::{Account, chat_signing::ChatSigningSession}; /// Send a chat packet to the server of a specific kind (chat message or /// command). Usually you just want [`SendChatEvent`] instead. @@ -31,7 +32,7 @@ pub struct SendChatKindEvent { pub fn handle_send_chat_kind_event( mut events: MessageReader, mut commands: Commands, - mut query: Query<(&Account, &mut ChatSigningSession)>, + #[cfg(feature = "online-mode")] mut query: Query<(&Account, &mut ChatSigningSession)>, ) { for event in events.read() { let content = event @@ -47,6 +48,7 @@ pub fn handle_send_chat_kind_event( ChatKind::Message => { let salt = azalea_crypto::make_salt(); + #[cfg(feature = "online-mode")] let signature = if let Ok((account, mut chat_session)) = query.get_mut(event.entity) { Some(create_signature( @@ -59,6 +61,8 @@ pub fn handle_send_chat_kind_event( } else { None }; + #[cfg(not(feature = "online-mode"))] + let signature = None; ServerboundChat { message: content, @@ -85,6 +89,7 @@ pub fn handle_send_chat_kind_event( } } +#[cfg(feature = "online-mode")] pub fn create_signature( account: &Account, chat_session: &mut ChatSigningSession, @@ -92,6 +97,8 @@ pub fn create_signature( timestamp: SystemTime, message: &str, ) -> azalea_crypto::MessageSignature { + use azalea_crypto::SignChatMessageOptions; + let certs = account.certs.lock(); let certs = certs.as_ref().expect("certs shouldn't be set back to None"); diff --git a/azalea-client/src/plugins/chat_signing.rs b/azalea-client/src/plugins/chat_signing.rs index 612383c2..8e612f5b 100644 --- a/azalea-client/src/plugins/chat_signing.rs +++ b/azalea-client/src/plugins/chat_signing.rs @@ -43,8 +43,8 @@ pub struct RequestCertsTask(pub Task= 2 { - // if this is the second attempt and we failed - // both times, give up - return Err(err.into()); - } - if matches!( - err, - ClientSessionServerError::InvalidSession | ClientSessionServerError::ForbiddenOperation - ) { - // uh oh, we got an invalid session and have - // to reauthenticate now - async_compat::Compat::new(account.refresh()).await?; - } else { - return Err(err.into()); + #[cfg(not(feature = "online-mode"))] + let _ = account; + + #[cfg(feature = "online-mode")] + if packet.should_authenticate { + let Some(access_token) = &account.access_token else { + // offline mode account, no need to do auth + return Ok((key_packet, private_key)); + }; + + // keep track of the number of times we tried authenticating so we can give up + // after too many + let mut attempts: usize = 1; + + while let Err(err) = { + let access_token = access_token.lock().clone(); + + let uuid = &account + .uuid + .expect("Uuid must be present if access token is present."); + + // 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, + uuid, + &packet.server_id, + )) + .await + } { + if attempts >= 2 { + // if this is the second attempt and we failed + // both times, give up + return Err(err.into()); + } + if matches!( + err, + ClientSessionServerError::InvalidSession + | ClientSessionServerError::ForbiddenOperation + ) { + // uh oh, we got an invalid session and have + // to reauthenticate now + async_compat::Compat::new(account.refresh()).await?; + } else { + return Err(err.into()); + } + attempts += 1; } - attempts += 1; } Ok((key_packet, private_key)) diff --git a/azalea-client/src/plugins/mod.rs b/azalea-client/src/plugins/mod.rs index a12d69cb..54f577e3 100644 --- a/azalea-client/src/plugins/mod.rs +++ b/azalea-client/src/plugins/mod.rs @@ -5,6 +5,7 @@ pub mod auto_reconnect; pub mod block_update; pub mod brand; pub mod chat; +#[cfg(feature = "online-mode")] pub mod chat_signing; pub mod chunks; pub mod client_information; @@ -62,8 +63,11 @@ impl PluginGroup for DefaultPlugins { .add(connection::ConnectionPlugin) .add(login::LoginPlugin) .add(join::JoinPlugin) - .add(auto_reconnect::AutoReconnectPlugin) - .add(chat_signing::ChatSigningPlugin); + .add(auto_reconnect::AutoReconnectPlugin); + #[cfg(feature = "online-mode")] + { + group = group.add(chat_signing::ChatSigningPlugin); + } #[cfg(feature = "log")] { group = group.add(bevy_log::LogPlugin::default()); -- cgit v1.2.3