mirror of
https://github.com/librespot-org/librespot.git
synced 2024-12-18 17:11:53 +00:00
Add configurable client ID and listen for updates
This commit is contained in:
parent
0b7ccc803c
commit
32df4a401d
6 changed files with 34 additions and 24 deletions
|
@ -710,7 +710,7 @@ impl SpircTask {
|
||||||
|
|
||||||
fn handle_connection_id_update(&mut self, connection_id: String) {
|
fn handle_connection_id_update(&mut self, connection_id: String) {
|
||||||
trace!("Received connection ID update: {:?}", connection_id);
|
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) {
|
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> {
|
fn handle_remote_update(&mut self, update: Frame) -> Result<(), Error> {
|
||||||
let state_string = match update.get_state().get_status() {
|
trace!("Received update frame: {:#?}", update,);
|
||||||
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,
|
|
||||||
);
|
|
||||||
|
|
||||||
|
// First see if this update was intended for us.
|
||||||
let device_id = &self.ident;
|
let device_id = &self.ident;
|
||||||
let ident = update.get_ident();
|
let ident = update.get_ident();
|
||||||
if ident == device_id
|
if ident == device_id
|
||||||
|
@ -779,6 +765,13 @@ impl SpircTask {
|
||||||
return Err(SpircError::Ident(ident.to_string()).into());
|
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() {
|
match update.get_typ() {
|
||||||
MessageType::kMessageTypeHello => self.notify(Some(ident)),
|
MessageType::kMessageTypeHello => self.notify(Some(ident)),
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,11 @@ use std::{fmt, path::PathBuf, str::FromStr};
|
||||||
|
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
|
const KEYMASTER_CLIENT_ID: &str = "65b708073fc0480ea92a077233ca87bd";
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct SessionConfig {
|
pub struct SessionConfig {
|
||||||
|
pub client_id: String,
|
||||||
pub device_id: String,
|
pub device_id: String,
|
||||||
pub proxy: Option<Url>,
|
pub proxy: Option<Url>,
|
||||||
pub ap_port: Option<u16>,
|
pub ap_port: Option<u16>,
|
||||||
|
@ -14,6 +17,7 @@ impl Default for SessionConfig {
|
||||||
fn default() -> SessionConfig {
|
fn default() -> SessionConfig {
|
||||||
let device_id = uuid::Uuid::new_v4().to_hyphenated().to_string();
|
let device_id = uuid::Uuid::new_v4().to_hyphenated().to_string();
|
||||||
SessionConfig {
|
SessionConfig {
|
||||||
|
client_id: KEYMASTER_CLIENT_ID.to_owned(),
|
||||||
device_id,
|
device_id,
|
||||||
proxy: None,
|
proxy: None,
|
||||||
ap_port: None,
|
ap_port: None,
|
||||||
|
|
|
@ -71,6 +71,7 @@ pub struct UserData {
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default)]
|
#[derive(Debug, Clone, Default)]
|
||||||
struct SessionData {
|
struct SessionData {
|
||||||
|
client_id: String,
|
||||||
connection_id: String,
|
connection_id: String,
|
||||||
time_delta: i64,
|
time_delta: i64,
|
||||||
invalid: bool,
|
invalid: bool,
|
||||||
|
@ -345,12 +346,20 @@ impl Session {
|
||||||
&self.config().device_id
|
&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 {
|
pub fn connection_id(&self) -> String {
|
||||||
self.0.data.read().connection_id.clone()
|
self.0.data.read().connection_id.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_connection_id(&self, connection_id: String) {
|
pub fn set_connection_id(&self, connection_id: &str) {
|
||||||
self.0.data.write().connection_id = connection_id;
|
self.0.data.write().connection_id = connection_id.to_owned();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn username(&self) -> String {
|
pub fn username(&self) -> String {
|
||||||
|
|
|
@ -333,7 +333,12 @@ impl SpClient {
|
||||||
.get_user_attribute(attribute)
|
.get_user_attribute(attribute)
|
||||||
.ok_or_else(|| SpClientError::Attribute(attribute.to_string()))?;
|
.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
|
self.request_url(url).await
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,8 +52,6 @@ struct TokenData {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TokenProvider {
|
impl TokenProvider {
|
||||||
const KEYMASTER_CLIENT_ID: &'static str = "65b708073fc0480ea92a077233ca87bd";
|
|
||||||
|
|
||||||
fn find_token(&self, scopes: Vec<&str>) -> Option<usize> {
|
fn find_token(&self, scopes: Vec<&str>) -> Option<usize> {
|
||||||
self.lock(|inner| {
|
self.lock(|inner| {
|
||||||
for i in 0..inner.tokens.len() {
|
for i in 0..inner.tokens.len() {
|
||||||
|
@ -84,8 +82,8 @@ impl TokenProvider {
|
||||||
let query_uri = format!(
|
let query_uri = format!(
|
||||||
"hm://keymaster/token/authenticated?scope={}&client_id={}&device_id={}",
|
"hm://keymaster/token/authenticated?scope={}&client_id={}&device_id={}",
|
||||||
scopes,
|
scopes,
|
||||||
Self::KEYMASTER_CLIENT_ID,
|
self.session().client_id(),
|
||||||
self.session().device_id()
|
self.session().device_id(),
|
||||||
);
|
);
|
||||||
let request = self.session().mercury().get(query_uri)?;
|
let request = self.session().mercury().get(query_uri)?;
|
||||||
let response = request.await?;
|
let response = request.await?;
|
||||||
|
|
|
@ -1274,6 +1274,7 @@ fn get_setup() -> Setup {
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
tmp_dir,
|
tmp_dir,
|
||||||
|
..SessionConfig::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
let player_config = {
|
let player_config = {
|
||||||
|
|
Loading…
Reference in a new issue