diff --git a/connect/src/spirc.rs b/connect/src/spirc.rs index ef9da811..af8189de 100644 --- a/connect/src/spirc.rs +++ b/connect/src/spirc.rs @@ -710,7 +710,7 @@ impl SpircTask { fn handle_connection_id_update(&mut self, connection_id: String) { trace!("Received connection ID update: {:?}", connection_id); - self.session.set_connection_id(connection_id); + self.session.set_connection_id(&connection_id); } fn handle_user_attributes_update(&mut self, update: UserAttributesUpdate) { @@ -754,23 +754,9 @@ impl SpircTask { } fn handle_remote_update(&mut self, update: Frame) -> Result<(), Error> { - let state_string = match update.get_state().get_status() { - PlayStatus::kPlayStatusLoading => "kPlayStatusLoading", - PlayStatus::kPlayStatusPause => "kPlayStatusPause", - PlayStatus::kPlayStatusStop => "kPlayStatusStop", - PlayStatus::kPlayStatusPlay => "kPlayStatusPlay", - }; - - debug!( - "{:?} {:?} {} {} {} {}", - update.get_typ(), - update.get_device_state().get_name(), - update.get_ident(), - update.get_seq_nr(), - update.get_state_update_id(), - state_string, - ); + trace!("Received update frame: {:#?}", update,); + // First see if this update was intended for us. let device_id = &self.ident; let ident = update.get_ident(); if ident == device_id @@ -779,6 +765,13 @@ impl SpircTask { return Err(SpircError::Ident(ident.to_string()).into()); } + for entry in update.get_device_state().get_metadata().iter() { + if entry.get_field_type() == "client_id" { + self.session.set_client_id(entry.get_metadata()); + break; + } + } + match update.get_typ() { MessageType::kMessageTypeHello => self.notify(Some(ident)), diff --git a/core/src/config.rs b/core/src/config.rs index 4c1b1dd8..bc4e3037 100644 --- a/core/src/config.rs +++ b/core/src/config.rs @@ -2,8 +2,11 @@ use std::{fmt, path::PathBuf, str::FromStr}; use url::Url; +const KEYMASTER_CLIENT_ID: &str = "65b708073fc0480ea92a077233ca87bd"; + #[derive(Clone, Debug)] pub struct SessionConfig { + pub client_id: String, pub device_id: String, pub proxy: Option, pub ap_port: Option, @@ -14,6 +17,7 @@ impl Default for SessionConfig { fn default() -> SessionConfig { let device_id = uuid::Uuid::new_v4().to_hyphenated().to_string(); SessionConfig { + client_id: KEYMASTER_CLIENT_ID.to_owned(), device_id, proxy: None, ap_port: None, diff --git a/core/src/session.rs b/core/src/session.rs index 2b431715..913f5813 100644 --- a/core/src/session.rs +++ b/core/src/session.rs @@ -71,6 +71,7 @@ pub struct UserData { #[derive(Debug, Clone, Default)] struct SessionData { + client_id: String, connection_id: String, time_delta: i64, invalid: bool, @@ -345,12 +346,20 @@ impl Session { &self.config().device_id } + pub fn client_id(&self) -> String { + self.0.data.read().client_id.clone() + } + + pub fn set_client_id(&self, client_id: &str) { + self.0.data.write().client_id = client_id.to_owned(); + } + pub fn connection_id(&self) -> String { self.0.data.read().connection_id.clone() } - pub fn set_connection_id(&self, connection_id: String) { - self.0.data.write().connection_id = connection_id; + pub fn set_connection_id(&self, connection_id: &str) { + self.0.data.write().connection_id = connection_id.to_owned(); } pub fn username(&self) -> String { diff --git a/core/src/spclient.rs b/core/src/spclient.rs index 9985041a..1aa0da00 100644 --- a/core/src/spclient.rs +++ b/core/src/spclient.rs @@ -333,7 +333,12 @@ impl SpClient { .get_user_attribute(attribute) .ok_or_else(|| SpClientError::Attribute(attribute.to_string()))?; - let url = template.replace("{id}", &preview_id.to_base16()); + let mut url = template.replace("{id}", &preview_id.to_base16()); + let separator = match url.find('?') { + Some(_) => "&", + None => "?", + }; + url.push_str(&format!("{}cid={}", separator, self.session().client_id())); self.request_url(url).await } diff --git a/core/src/token.rs b/core/src/token.rs index 0c0b7394..f7c8d350 100644 --- a/core/src/token.rs +++ b/core/src/token.rs @@ -52,8 +52,6 @@ struct TokenData { } impl TokenProvider { - const KEYMASTER_CLIENT_ID: &'static str = "65b708073fc0480ea92a077233ca87bd"; - fn find_token(&self, scopes: Vec<&str>) -> Option { self.lock(|inner| { for i in 0..inner.tokens.len() { @@ -84,8 +82,8 @@ impl TokenProvider { let query_uri = format!( "hm://keymaster/token/authenticated?scope={}&client_id={}&device_id={}", scopes, - Self::KEYMASTER_CLIENT_ID, - self.session().device_id() + self.session().client_id(), + self.session().device_id(), ); let request = self.session().mercury().get(query_uri)?; let response = request.await?; diff --git a/src/main.rs b/src/main.rs index e3cb4e7a..818a1c0b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1274,6 +1274,7 @@ fn get_setup() -> Setup { } }), tmp_dir, + ..SessionConfig::default() }; let player_config = {