2.2.4-dev.1

- Updated librespot to latest commits + login5 PR merged
- Fix non premium account shutting down bot
- Add additional timeouts to credential retrieval
- Add message for if AP connection drops
This commit is contained in:
DaXcess
2024-09-27 14:53:58 +02:00
parent c05624fc76
commit 41d75a956c
13 changed files with 456 additions and 156 deletions
+30 -39
View File
@@ -1,9 +1,9 @@
use anyhow::Result;
use base64::{engine::general_purpose::STANDARD as BASE64, Engine};
use librespot::{
core::{connection::AuthenticationError, Session, SessionConfig},
core::{Session, SessionConfig},
discovery::Credentials,
protocol::{authentication::AuthenticationType, keyexchange::ErrorCode},
protocol::authentication::AuthenticationType,
};
use log::debug;
use std::time::Duration;
@@ -15,17 +15,17 @@ pub async fn validate_token(
let auth_data = BASE64.decode(token.into())?;
let credentials = Credentials {
username: username.into(),
username: Some(username.into()),
auth_type: AuthenticationType::AUTHENTICATION_STORED_SPOTIFY_CREDENTIALS,
auth_data,
};
debug!("Validating session token for {}", credentials.username);
debug!("Validating session token for {:?}", credentials.username);
let new_credentials = request_session_token(credentials.clone()).await?;
if credentials.auth_data != new_credentials.auth_data {
debug!("New session token retrieved for {}", credentials.username);
debug!("New session token retrieved for {:?}", credentials.username);
return Ok(Some(BASE64.encode(new_credentials.auth_data)));
}
@@ -34,54 +34,45 @@ pub async fn validate_token(
}
pub async fn request_session_token(credentials: Credentials) -> Result<Credentials> {
debug!("Requesting session token for {}", credentials.username);
debug!("Requesting session token for {:?}", credentials.username);
let session = Session::new(SessionConfig::default(), None);
let mut tries = 0;
Ok(loop {
let (host, port) = session.apresolver().resolve("accesspoint").await?;
let mut transport = match librespot::core::connection::connect(&host, port, None).await {
Ok(transport) => transport,
Err(why) => {
// Retry
match connect(&session, credentials.clone()).await {
Ok(creds) => break creds,
Err(e) => {
tries += 1;
if tries > 3 {
return Err(why.into());
return Err(e);
}
tokio::time::sleep(Duration::from_millis(100)).await;
continue;
}
};
}
})
}
match librespot::core::connection::authenticate(
/// Wrapper around session connecting that times out if an operation is still busy after 3 seconds
async fn connect(session: &Session, credentials: Credentials) -> Result<Credentials> {
const TIMEOUT: Duration = Duration::from_secs(3);
let (host, port) =
tokio::time::timeout(TIMEOUT, session.apresolver().resolve("accesspoint")).await??;
// `connect` already has a 3 second timeout internally
let mut transport = librespot::core::connection::connect(&host, port, None).await?;
let creds = tokio::time::timeout(
TIMEOUT,
librespot::core::connection::authenticate(
&mut transport,
credentials.clone(),
&session.config().device_id,
)
.await
{
Ok(creds) => break creds,
Err(e) => {
if let Some(AuthenticationError::LoginFailed(ErrorCode::TryAnotherAP)) =
e.error.downcast_ref::<AuthenticationError>()
{
tries += 1;
if tries > 3 {
return Err(e.into());
}
),
)
.await??;
tokio::time::sleep(Duration::from_millis(100)).await;
continue;
} else {
return Err(e.into());
}
}
};
})
Ok(creds)
}