fix(qconnect): correct track_ids wire type to fixed32 packed in outbound queue commands
track_ids in QueueLoadTracks, QueueInsertTracks, QueueAddTracks, and AutoplayLoadTracks was int32 packed=false but the server expects fixed32 (packed by default). This silently broke all outbound queue manipulation commands.
This commit is contained in:
2 files changed
+37
-12
No files matched your search
@@ -158,7 +158,7 @@ fn map_queue_command(command: &QueueCommand) -> Result<QConnectMessage, Protocol
|
||||
..Default::default()
|
||||
}),
|
||||
QueueCommandType::CtrlSrvrQueueAddTracks => {
|
||||
let track_ids = required_i32_list(&command.payload, "track_ids")?;
|
||||
let track_ids = required_u32_list(&command.payload, "track_ids")?;
|
||||
let shuffle_seed = optional_i32(&command.payload, "shuffle_seed")?.map(|v| v as u32);
|
||||
let context_uuid = optional_uuid_bytes(&command.payload, &["context_uuid"])?;
|
||||
let autoplay_reset = optional_bool(&command.payload, "autoplay_reset", false);
|
||||
@@ -180,7 +180,7 @@ fn map_queue_command(command: &QueueCommand) -> Result<QConnectMessage, Protocol
|
||||
})
|
||||
}
|
||||
QueueCommandType::CtrlSrvrQueueLoadTracks => {
|
||||
let track_ids = required_i32_list(&command.payload, "track_ids")?;
|
||||
let track_ids = required_u32_list(&command.payload, "track_ids")?;
|
||||
let queue_position = optional_i32(&command.payload, "queue_position")?;
|
||||
let shuffle_seed = optional_i32(&command.payload, "shuffle_seed")?.map(|v| v as u32);
|
||||
let shuffle_pivot_index = optional_i32(&command.payload, "shuffle_pivot_index")?;
|
||||
@@ -208,7 +208,7 @@ fn map_queue_command(command: &QueueCommand) -> Result<QConnectMessage, Protocol
|
||||
})
|
||||
}
|
||||
QueueCommandType::CtrlSrvrQueueInsertTracks => {
|
||||
let track_ids = required_i32_list(&command.payload, "track_ids")?;
|
||||
let track_ids = required_u32_list(&command.payload, "track_ids")?;
|
||||
let insert_after = optional_i32(&command.payload, "insert_after")?;
|
||||
let shuffle_seed = optional_i32(&command.payload, "shuffle_seed")?.map(|v| v as u32);
|
||||
let context_uuid = optional_uuid_bytes(&command.payload, &["context_uuid"])?;
|
||||
@@ -325,7 +325,7 @@ fn map_queue_command(command: &QueueCommand) -> Result<QConnectMessage, Protocol
|
||||
})
|
||||
}
|
||||
QueueCommandType::CtrlSrvrAutoplayLoadTracks => {
|
||||
let track_ids = required_i32_list(&command.payload, "track_ids")?;
|
||||
let track_ids = required_u32_list(&command.payload, "track_ids")?;
|
||||
let context_uuid = optional_uuid_bytes(&command.payload, &["context_uuid"])?;
|
||||
|
||||
Ok(QConnectMessage {
|
||||
@@ -536,6 +536,31 @@ fn required_i32_list(payload: &Value, key: &str) -> Result<Vec<i32>, ProtocolErr
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn required_u32_list(payload: &Value, key: &str) -> Result<Vec<u32>, ProtocolError> {
|
||||
let values = payload
|
||||
.get(key)
|
||||
.and_then(Value::as_array)
|
||||
.ok_or_else(|| ProtocolError::InvalidPayload(format!("missing array field '{key}'")))?;
|
||||
|
||||
values
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(idx, value)| {
|
||||
let raw = value
|
||||
.as_i64()
|
||||
.or_else(|| value.as_u64().map(|v| v as i64))
|
||||
.ok_or_else(|| {
|
||||
ProtocolError::InvalidPayload(format!("field '{key}[{idx}]' is not numeric"))
|
||||
})?;
|
||||
u32::try_from(raw).map_err(|_| {
|
||||
ProtocolError::InvalidPayload(format!(
|
||||
"field '{key}[{idx}]' value {raw} out of u32 range"
|
||||
))
|
||||
})
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn optional_i32_list(payload: &Value, key: &str) -> Result<Vec<i32>, ProtocolError> {
|
||||
let Some(values) = payload.get(key).and_then(Value::as_array) else {
|
||||
return Ok(Vec::new());
|
||||
|
||||
@@ -229,8 +229,8 @@ pub struct QueueLoadTracksMessage {
|
||||
pub queue_version_ref: Option<QueueVersionRef>,
|
||||
#[prost(bytes = "vec", optional, tag = "2")]
|
||||
pub action_uuid: Option<Vec<u8>>,
|
||||
#[prost(int32, repeated, packed = "false", tag = "3")]
|
||||
pub track_ids: Vec<i32>,
|
||||
#[prost(fixed32, repeated, tag = "3")]
|
||||
pub track_ids: Vec<u32>,
|
||||
#[prost(int32, optional, tag = "4")]
|
||||
pub queue_position: Option<i32>,
|
||||
#[prost(fixed32, optional, tag = "5")]
|
||||
@@ -253,8 +253,8 @@ pub struct QueueInsertTracksMessage {
|
||||
pub queue_version_ref: Option<QueueVersionRef>,
|
||||
#[prost(bytes = "vec", optional, tag = "2")]
|
||||
pub action_uuid: Option<Vec<u8>>,
|
||||
#[prost(int32, repeated, packed = "false", tag = "3")]
|
||||
pub track_ids: Vec<i32>,
|
||||
#[prost(fixed32, repeated, tag = "3")]
|
||||
pub track_ids: Vec<u32>,
|
||||
#[prost(int32, optional, tag = "4")]
|
||||
pub insert_after: Option<i32>,
|
||||
#[prost(fixed32, optional, tag = "5")]
|
||||
@@ -273,8 +273,8 @@ pub struct QueueAddTracksMessage {
|
||||
pub queue_version_ref: Option<QueueVersionRef>,
|
||||
#[prost(bytes = "vec", optional, tag = "2")]
|
||||
pub action_uuid: Option<Vec<u8>>,
|
||||
#[prost(int32, repeated, packed = "false", tag = "3")]
|
||||
pub track_ids: Vec<i32>,
|
||||
#[prost(fixed32, repeated, tag = "3")]
|
||||
pub track_ids: Vec<u32>,
|
||||
#[prost(fixed32, optional, tag = "4")]
|
||||
pub shuffle_seed: Option<u32>,
|
||||
#[prost(bytes = "vec", optional, tag = "5")]
|
||||
@@ -353,8 +353,8 @@ pub struct AutoplayLoadTracksMessage {
|
||||
pub queue_version_ref: Option<QueueVersionRef>,
|
||||
#[prost(bytes = "vec", optional, tag = "2")]
|
||||
pub action_uuid: Option<Vec<u8>>,
|
||||
#[prost(int32, repeated, packed = "false", tag = "3")]
|
||||
pub track_ids: Vec<i32>,
|
||||
#[prost(fixed32, repeated, tag = "3")]
|
||||
pub track_ids: Vec<u32>,
|
||||
#[prost(bytes = "vec", optional, tag = "4")]
|
||||
pub context_uuid: Option<Vec<u8>>,
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user