Skip to content

Commit

Permalink
Use stable version of librespot, fix various bugs
Browse files Browse the repository at this point in the history
  • Loading branch information
codetheweb committed May 4, 2021
1 parent 21d4bd8 commit e03ef07
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 66 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
/target
/cache
76 changes: 39 additions & 37 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ authors = ["Max Isom <[email protected]>"]
edition = "2018"

[dependencies]
# TODO: Update this to stable version when async version is released
librespot = {git = "https://github.com/librespot-org/librespot", branch = "dev", default-features = false}
librespot = {version = "0.2.0", default-features = false}
songbird = "0.1.6"
tracing = "0.1"
tracing-subscriber = "0.2"
Expand Down
12 changes: 9 additions & 3 deletions src/lib/player.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,12 @@ impl SpotifyPlayer {

let mut cache: Option<Cache> = None;

if let Ok(c) = Cache::new(cache_dir.clone(), cache_dir) {
// 4 GB
let mut cache_limit: u64 = 10;
cache_limit = cache_limit.pow(9);
cache_limit *= 4;

if let Ok(c) = Cache::new(cache_dir.clone(), cache_dir, Some(cache_limit)) {
cache = Some(c);
}

Expand Down Expand Up @@ -218,13 +223,14 @@ impl SpotifyPlayer {
self.spirc = Some(Box::new(spirc));

let mut channel_lock = self.event_channel.as_ref().unwrap().lock().await;

*channel_lock = player_events;
}

pub fn disable_connect(&mut self) {
pub async fn disable_connect(&mut self) {
if let Some(spirc) = self.spirc.as_ref() {
spirc.shutdown();

self.event_channel.as_ref().unwrap().lock().await.close();
}
}
}
87 changes: 63 additions & 24 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@ use songbird::SerenityInit;

mod lib {
pub mod player;
// pub mod forward_mpsc;
}
use lib::player::{SpotifyPlayer, SpotifyPlayerKey};
use librespot::core::mercury::MercuryError;
use librespot::playback::config::Bitrate;
use librespot::playback::player::PlayerEvent;
use std::sync::Arc;
use tokio::sync::Mutex;
use tokio::time::{sleep, Duration};

use serenity::client::Context;

Expand All @@ -37,31 +39,36 @@ impl EventHandler for Handler {
println!("Ready!");
println!("Invite me with https://discord.com/api/oauth2/authorize?client_id={}&permissions=36700160&scope=bot", ready.user.id);

ctx.set_presence(None, user::OnlineStatus::Online).await;
}

async fn cache_ready(&self, ctx: Context, guilds: Vec<id::GuildId>) {
let guild_id = match guilds.first() {
Some(guild_id) => *guild_id,
None => {
panic!("Not currently in any guilds.");
}
};

let data = ctx.data.read().await;

let player = data.get::<SpotifyPlayerKey>().unwrap().clone();
let user_id = *data
.get::<UserIdKey>()
.expect("User ID placed in at initialisation.");

// Get guild so it's cached
let _guilds = ctx.cache.current_user().await.guilds(&ctx.http).await;

let guild = match ctx.cache.guilds().await.first() {
Some(guild_id) => match ctx.cache.guild(guild_id).await {
Some(guild) => guild,
None => panic!("Could not find guild."),
},
None => {
panic!("Not currently in any guilds.");
}
};

// Handle case when user is in VC when bot starts
let guild = ctx
.cache
.guild(guild_id)
.await
.expect("Could not find guild in cache.");

let channel_id = guild
.voice_states
.get(&user_id)
.and_then(|voice_state| voice_state.channel_id);
drop(guild);

if channel_id.is_some() {
// Enable casting
Expand All @@ -70,7 +77,7 @@ impl EventHandler for Handler {

let c = ctx.clone();

// Spawn event channel handler for Spotify
// Handle Spotify events
tokio::spawn(async move {
loop {
let channel = player.lock().await.event_channel.clone().unwrap();
Expand All @@ -79,6 +86,8 @@ impl EventHandler for Handler {
let event = match receiver.recv().await {
Some(e) => e,
None => {
// Busy waiting bad but quick and easy
sleep(Duration::from_millis(256)).await;
continue;
}
};
Expand All @@ -92,7 +101,7 @@ impl EventHandler for Handler {
.expect("Songbird Voice client placed in at initialisation.")
.clone();

let _ = manager.remove(guild.id).await;
let _ = manager.remove(guild_id).await;
}

PlayerEvent::Started { .. } => {
Expand All @@ -101,6 +110,12 @@ impl EventHandler for Handler {
.expect("Songbird Voice client placed in at initialisation.")
.clone();

let guild = c
.cache
.guild(guild_id)
.await
.expect("Could not find guild in cache.");

let channel_id = match guild
.voice_states
.get(&user_id)
Expand All @@ -113,9 +128,9 @@ impl EventHandler for Handler {
}
};

let _handler = manager.join(guild.id, channel_id).await;
let _handler = manager.join(guild_id, channel_id).await;

if let Some(handler_lock) = manager.get(guild.id) {
if let Some(handler_lock) = manager.get(guild_id) {
let mut handler = handler_lock.lock().await;

let mut decoder = input::codec::OpusDecoderState::new().unwrap();
Expand Down Expand Up @@ -194,6 +209,12 @@ impl EventHandler for Handler {

let player = data.get::<SpotifyPlayerKey>().unwrap();

let guild = ctx
.cache
.guild(ctx.cache.guilds().await.first().unwrap())
.await
.unwrap();

// If user just connected
if old.clone().is_none() {
// Enable casting
Expand All @@ -204,19 +225,37 @@ impl EventHandler for Handler {
// If user disconnected
if old.clone().unwrap().channel_id.is_some() && new.channel_id.is_none() {
// Disable casting
player.lock().await.disable_connect();
return;
}
player.lock().await.disable_connect().await;

// If user moved channels
if old.unwrap().channel_id.unwrap() != new.channel_id.unwrap() {
// Disconnect
let manager = songbird::get(&ctx)
.await
.expect("Songbird Voice client placed in at initialisation.")
.clone();

if let Some(guild_id) = ctx.cache.guilds().await.first() {
let _handler = manager.join(*guild_id, new.channel_id.unwrap()).await;
let _handler = manager.remove(guild.id).await;

return;
}

// If user moved channels
if old.unwrap().channel_id.unwrap() != new.channel_id.unwrap() {
let bot_id = ctx.cache.current_user_id().await;

let bot_channel = guild
.voice_states
.get(&bot_id)
.and_then(|voice_state| voice_state.channel_id);

if Option::is_some(&bot_channel) {
let manager = songbird::get(&ctx)
.await
.expect("Songbird Voice client placed in at initialisation.")
.clone();

if let Some(guild_id) = ctx.cache.guilds().await.first() {
let _handler = manager.join(*guild_id, new.channel_id.unwrap()).await;
}
}

return;
Expand Down

0 comments on commit e03ef07

Please sign in to comment.