commit
4d12d38186
|
@ -72,9 +72,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aho-corasick"
|
name = "aho-corasick"
|
||||||
version = "1.1.0"
|
version = "1.1.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0f2135563fb5c609d2b2b87c1e8ce7bc41b0b45430fa9661f457981503dd5bf0"
|
checksum = "ea5d730647d4fadd988536d06fecce94b7b4f2a7efdae548f1cf4b63205518ab"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
@ -816,9 +816,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hermit-abi"
|
name = "hermit-abi"
|
||||||
version = "0.3.2"
|
version = "0.3.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b"
|
checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hex"
|
name = "hex"
|
||||||
|
@ -1028,7 +1028,7 @@ version = "0.4.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b"
|
checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"hermit-abi 0.3.2",
|
"hermit-abi 0.3.3",
|
||||||
"rustix",
|
"rustix",
|
||||||
"windows-sys",
|
"windows-sys",
|
||||||
]
|
]
|
||||||
|
@ -1497,7 +1497,7 @@ version = "1.16.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43"
|
checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"hermit-abi 0.3.2",
|
"hermit-abi 0.3.3",
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -1983,9 +1983,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustix"
|
name = "rustix"
|
||||||
version = "0.38.13"
|
version = "0.38.14"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d7db8590df6dfcd144d22afd1b83b36c21a18d7cbc1dc4bb5295a8712e9eb662"
|
checksum = "747c788e9ce8e92b12cd485c49ddf90723550b654b32508f979b71a7b1ecda4f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.4.0",
|
"bitflags 2.4.0",
|
||||||
"errno",
|
"errno",
|
||||||
|
@ -2029,9 +2029,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustls-webpki"
|
name = "rustls-webpki"
|
||||||
version = "0.101.5"
|
version = "0.101.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "45a27e3b59326c16e23d30aeb7a36a24cc0d29e71d68ff611cdfb4a01d013bed"
|
checksum = "3c7d5dece342910d9ba34d259310cae3e0154b873b35408b787b59bce53d34fe"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ring",
|
"ring",
|
||||||
"untrusted",
|
"untrusted",
|
||||||
|
@ -2124,9 +2124,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "semver"
|
name = "semver"
|
||||||
version = "1.0.18"
|
version = "1.0.19"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918"
|
checksum = "ad977052201c6de01a8ef2aa3378c4bd23217a056337d1d6da40468d267a4fb0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
|
@ -2265,9 +2265,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sha1"
|
name = "sha1"
|
||||||
version = "0.10.5"
|
version = "0.10.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3"
|
checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"cpufeatures",
|
"cpufeatures",
|
||||||
|
@ -2324,9 +2324,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "smallvec"
|
name = "smallvec"
|
||||||
version = "1.11.0"
|
version = "1.11.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9"
|
checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "socket2"
|
name = "socket2"
|
||||||
|
@ -2398,7 +2398,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "spoticord"
|
name = "spoticord"
|
||||||
version = "2.1.0"
|
version = "2.1.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"dotenv",
|
"dotenv",
|
||||||
|
@ -2658,9 +2658,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio-util"
|
name = "tokio-util"
|
||||||
version = "0.7.8"
|
version = "0.7.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d"
|
checksum = "1d68074620f57a0b21594d9735eb2e98ab38b17f80d3fcb189fca266771ca60d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
|
@ -2820,9 +2820,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-width"
|
name = "unicode-width"
|
||||||
version = "0.1.10"
|
version = "0.1.11"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
|
checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "universal-hash"
|
name = "universal-hash"
|
||||||
|
@ -3058,9 +3058,9 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi-util"
|
name = "winapi-util"
|
||||||
version = "0.1.5"
|
version = "0.1.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
|
checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "spoticord"
|
name = "spoticord"
|
||||||
version = "2.1.0"
|
version = "2.1.1"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
rust-version = "1.65.0"
|
rust-version = "1.65.0"
|
||||||
|
|
||||||
|
|
|
@ -53,7 +53,9 @@ impl Sink for StreamSink {
|
||||||
fn write(&mut self, packet: AudioPacket, converter: &mut Converter) -> SinkResult<()> {
|
fn write(&mut self, packet: AudioPacket, converter: &mut Converter) -> SinkResult<()> {
|
||||||
use zerocopy::AsBytes;
|
use zerocopy::AsBytes;
|
||||||
|
|
||||||
let AudioPacket::Samples(samples) = packet else { return Ok(()); };
|
let AudioPacket::Samples(samples) = packet else {
|
||||||
|
return Ok(());
|
||||||
|
};
|
||||||
let samples_f32: &[f32] = &converter.f64_to_f32(&samples);
|
let samples_f32: &[f32] = &converter.f64_to_f32(&samples);
|
||||||
|
|
||||||
let resampled = samplerate::convert(
|
let resampled = samplerate::convert(
|
||||||
|
@ -65,10 +67,7 @@ impl Sink for StreamSink {
|
||||||
)
|
)
|
||||||
.expect("to succeed");
|
.expect("to succeed");
|
||||||
|
|
||||||
let samples_i16 =
|
self.write_bytes(resampled.as_bytes())?;
|
||||||
&converter.f64_to_s16(&resampled.iter().map(|v| *v as f64).collect::<Vec<f64>>());
|
|
||||||
|
|
||||||
self.write_bytes(samples_i16.as_bytes())?;
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,7 @@ impl Read for Stream {
|
||||||
}
|
}
|
||||||
|
|
||||||
let max_read = usize::min(buf.len(), buffer.len());
|
let max_read = usize::min(buf.len(), buffer.len());
|
||||||
|
|
||||||
buf[0..max_read].copy_from_slice(&buffer[0..max_read]);
|
buf[0..max_read].copy_from_slice(&buffer[0..max_read]);
|
||||||
buffer.drain(0..max_read);
|
buffer.drain(0..max_read);
|
||||||
condvar.notify_all();
|
condvar.notify_all();
|
||||||
|
|
|
@ -231,49 +231,74 @@ pub fn command(ctx: Context, command: ApplicationCommandInteraction) -> CommandO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(session) = session_opt.as_mut() {
|
macro_rules! report_error {
|
||||||
if let Err(why) = session.update_owner(&ctx, command.user.id).await {
|
($why:ident) => {
|
||||||
// Need to link first
|
match $why {
|
||||||
if let SessionCreateError::NoSpotify = why {
|
// User has not linked their account
|
||||||
update_message(
|
SessionCreateError::NoSpotify => {
|
||||||
&ctx,
|
update_message(
|
||||||
&command,
|
&ctx,
|
||||||
EmbedBuilder::new()
|
&command,
|
||||||
.title("Cannot join voice channel")
|
EmbedBuilder::new()
|
||||||
.description("You need to link your Spotify account. Use </link:1036714850367320136> or go to [the accounts website](https://account.spoticord.com/) to get started.")
|
.title("Cannot join voice channel")
|
||||||
.status(Status::Error)
|
.description("You need to link your Spotify account. Use </link:1036714850367320136> or go to [the accounts website](https://account.spoticord.com/) to get started.")
|
||||||
.build(),
|
.status(Status::Error)
|
||||||
)
|
.build(),
|
||||||
.await;
|
)
|
||||||
|
.await;
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
// Spotify credentials have expired or are invalid
|
||||||
} else if let SessionCreateError::SpotifyExpired = why {
|
SessionCreateError::SpotifyExpired => {
|
||||||
update_message(
|
update_message(
|
||||||
&ctx,
|
&ctx,
|
||||||
&command,
|
&command,
|
||||||
EmbedBuilder::new()
|
EmbedBuilder::new()
|
||||||
.title("Cannot join voice channel")
|
.title("Cannot join voice channel")
|
||||||
.description("Spoticord no longer has access to your Spotify account. Use </link:1036714850367320136> or go to [the accounts website](https://account.spoticord.com/) to relink your Spotify account.")
|
.description("Spoticord no longer has access to your Spotify account. Use </link:1036714850367320136> or go to [the accounts website](https://account.spoticord.com/) to relink your Spotify account.")
|
||||||
.status(Status::Error)
|
.status(Status::Error)
|
||||||
.build(),
|
.build(),
|
||||||
).await;
|
).await;
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
// Songbird error
|
||||||
|
SessionCreateError::JoinError(why) => {
|
||||||
|
update_message(
|
||||||
|
&ctx,
|
||||||
|
&command,
|
||||||
|
EmbedBuilder::new()
|
||||||
|
.title("Cannot join voice channel")
|
||||||
|
.description(format!(
|
||||||
|
"An error occured while joining the channel. Please try running </join:1036714850367320142> again.\n\nError details: `{why}`"
|
||||||
|
))
|
||||||
|
.status(Status::Error)
|
||||||
|
.build(),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Any other error
|
||||||
|
_ => {
|
||||||
|
update_message(
|
||||||
|
&ctx,
|
||||||
|
&command,
|
||||||
|
EmbedBuilder::new()
|
||||||
|
.title("Cannot join voice channel")
|
||||||
|
.description("An error occured while joining the channel. Please try again later.")
|
||||||
|
.status(Status::Error)
|
||||||
|
.build(),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Any other error
|
|
||||||
update_message(
|
|
||||||
&ctx,
|
|
||||||
&command,
|
|
||||||
EmbedBuilder::new()
|
|
||||||
.title("Cannot join voice channel")
|
|
||||||
.description("An error occured while joining the channel. Please try again later.")
|
|
||||||
.status(Status::Error)
|
|
||||||
.build(),
|
|
||||||
)
|
|
||||||
.await;
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(session) = session_opt.as_mut() {
|
||||||
|
if let Err(why) = session.update_owner(&ctx, command.user.id).await {
|
||||||
|
report_error!(why);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Create the session, and handle potential errors
|
// Create the session, and handle potential errors
|
||||||
|
@ -287,47 +312,7 @@ pub fn command(ctx: Context, command: ApplicationCommandInteraction) -> CommandO
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
// Need to link first
|
report_error!(why);
|
||||||
if let SessionCreateError::NoSpotify = why {
|
|
||||||
update_message(
|
|
||||||
&ctx,
|
|
||||||
&command,
|
|
||||||
EmbedBuilder::new()
|
|
||||||
.title("Cannot join voice channel")
|
|
||||||
.description("You need to link your Spotify account. Use </link:1036714850367320136> or go to [the accounts website](https://account.spoticord.com/) to get started.")
|
|
||||||
.status(Status::Error)
|
|
||||||
.build(),
|
|
||||||
)
|
|
||||||
.await;
|
|
||||||
|
|
||||||
return;
|
|
||||||
} else if let SessionCreateError::SpotifyExpired = why {
|
|
||||||
update_message(
|
|
||||||
&ctx,
|
|
||||||
&command,
|
|
||||||
EmbedBuilder::new()
|
|
||||||
.title("Cannot join voice channel")
|
|
||||||
.description("Spoticord no longer has access to your Spotify account. Use </link:1036714850367320136> or go to [the accounts website](https://account.spoticord.com/) to relink your Spotify account.")
|
|
||||||
.status(Status::Error)
|
|
||||||
.build(),
|
|
||||||
).await;
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Any other error
|
|
||||||
update_message(
|
|
||||||
&ctx,
|
|
||||||
&command,
|
|
||||||
EmbedBuilder::new()
|
|
||||||
.title("Cannot join voice channel")
|
|
||||||
.description("An error occured while joining the channel. Please try again later.")
|
|
||||||
.status(Status::Error)
|
|
||||||
.build(),
|
|
||||||
)
|
|
||||||
.await;
|
|
||||||
|
|
||||||
return;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ use serenity::{
|
||||||
model::prelude::{ChannelId, GuildId, UserId},
|
model::prelude::{ChannelId, GuildId, UserId},
|
||||||
prelude::{Context, TypeMapKey},
|
prelude::{Context, TypeMapKey},
|
||||||
};
|
};
|
||||||
|
use songbird::error::JoinError;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
use super::SpoticordSession;
|
use super::SpoticordSession;
|
||||||
|
@ -22,8 +23,8 @@ pub enum SessionCreateError {
|
||||||
#[error("An error has occured while communicating with the database")]
|
#[error("An error has occured while communicating with the database")]
|
||||||
DatabaseError,
|
DatabaseError,
|
||||||
|
|
||||||
#[error("Failed to join voice channel {0} ({1})")]
|
#[error("Failed to join voice channel")]
|
||||||
JoinError(ChannelId, GuildId),
|
JoinError(JoinError),
|
||||||
|
|
||||||
#[error("Failed to start the player")]
|
#[error("Failed to start the player")]
|
||||||
PlayerStartError,
|
PlayerStartError,
|
||||||
|
|
|
@ -13,6 +13,7 @@ use crate::{
|
||||||
utils::embed::Status,
|
utils::embed::Status,
|
||||||
};
|
};
|
||||||
use log::*;
|
use log::*;
|
||||||
|
use reqwest::StatusCode;
|
||||||
use serenity::{
|
use serenity::{
|
||||||
async_trait,
|
async_trait,
|
||||||
http::Http,
|
http::Http,
|
||||||
|
@ -78,7 +79,7 @@ impl SpoticordSession {
|
||||||
|
|
||||||
if let Err(why) = result {
|
if let Err(why) = result {
|
||||||
error!("Error joining voice channel: {:?}", why);
|
error!("Error joining voice channel: {:?}", why);
|
||||||
return Err(SessionCreateError::JoinError(channel_id, guild_id));
|
return Err(SessionCreateError::JoinError(why));
|
||||||
}
|
}
|
||||||
|
|
||||||
let inner = InnerSpoticordSession {
|
let inner = InnerSpoticordSession {
|
||||||
|
@ -182,15 +183,15 @@ impl SpoticordSession {
|
||||||
let token = match database.get_access_token(owner_id.to_string()).await {
|
let token = match database.get_access_token(owner_id.to_string()).await {
|
||||||
Ok(token) => token,
|
Ok(token) => token,
|
||||||
Err(why) => {
|
Err(why) => {
|
||||||
if let DatabaseError::InvalidStatusCode(code) = why {
|
return match why {
|
||||||
if code == 404 {
|
DatabaseError::InvalidStatusCode(StatusCode::NOT_FOUND) => {
|
||||||
return Err(SessionCreateError::NoSpotify);
|
Err(SessionCreateError::NoSpotify)
|
||||||
} else if code == 400 {
|
|
||||||
return Err(SessionCreateError::SpotifyExpired);
|
|
||||||
}
|
}
|
||||||
}
|
DatabaseError::InvalidStatusCode(StatusCode::BAD_REQUEST) => {
|
||||||
|
Err(SessionCreateError::SpotifyExpired)
|
||||||
return Err(SessionCreateError::DatabaseError);
|
}
|
||||||
|
_ => Err(SessionCreateError::DatabaseError),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -209,7 +210,7 @@ impl SpoticordSession {
|
||||||
let (mut track, track_handle) = create_player(Input::new(
|
let (mut track, track_handle) = create_player(Input::new(
|
||||||
true,
|
true,
|
||||||
Reader::Extension(Box::new(stream.clone())),
|
Reader::Extension(Box::new(stream.clone())),
|
||||||
Codec::Pcm,
|
Codec::FloatPcm,
|
||||||
Container::Raw,
|
Container::Raw,
|
||||||
None,
|
None,
|
||||||
));
|
));
|
||||||
|
|
Loading…
Reference in New Issue