Skip to content

Commit

Permalink
Gateway: Generic Shard and Twilight v0.8 Support (#109)
Browse files Browse the repository at this point in the history
This PR adds support for twilight v0.8, mainly adapting to significant API changes introduced by v0.7. As a result of these, twilight no longer accepts arbitrary JSON input, so it seemed sensible to adapt our `Shard` design to no longer require the same.

Adding to this, I've added in a trait to allow an arbitrary `Shard` to be installed, given only an implementation of a method to send a `VoiceStateUpdate`. Together, `Sharder::Generic` (songbird::shards::VoiceUpdate) and `Shard::Generic` (songbird::shards::GenericSharder) should allow any library to be hooked in to Songbird.

This PR was tested using `cargo make ready` and by manually testing `examples/twilight`.
  • Loading branch information
FelixMcFelix committed Jul 22, 2022
1 parent 12c76a9 commit b4ce845
Show file tree
Hide file tree
Showing 9 changed files with 187 additions and 54 deletions.
5 changes: 3 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ repository = "https://github.com/serenity-rs/songbird.git"
version = "0.2.2"

[dependencies]
derivative = "2"
serde = { version = "1", features = ["derive"] }
serde_json = "1"
tracing = { version = "0.1", features = ["log"] }
Expand Down Expand Up @@ -104,12 +105,12 @@ default-features = false

[dependencies.twilight-gateway]
optional = true
version = ">=0.5, <0.7"
version = "0.8"
default-features = false

[dependencies.twilight-model]
optional = true
version = ">=0.5, <0.7"
version = "0.8"
default-features = false

[dependencies.typemap_rev]
Expand Down
8 changes: 4 additions & 4 deletions examples/twilight/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ futures = "0.3"
tracing = "0.1"
tracing-subscriber = "0.2"
tokio = { features = ["macros", "rt-multi-thread", "sync"], version = "1" }
twilight-gateway = "0.6"
twilight-http = "0.6"
twilight-model = "0.6"
twilight-standby = "0.6"
twilight-gateway = "0.8"
twilight-http = "0.8"
twilight-model = "0.8"
twilight-standby = "0.8"

[dependencies.songbird]
default-features = false
Expand Down
6 changes: 2 additions & 4 deletions examples/twilight/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,13 @@ use std::{collections::HashMap, env, error::Error, future::Future, sync::Arc};
use tokio::sync::RwLock;
use twilight_gateway::{Cluster, Event, Intents};
use twilight_http::Client as HttpClient;
use twilight_model::{channel::Message, gateway::payload::MessageCreate, id::GuildId};
use twilight_model::{channel::Message, gateway::payload::incoming::MessageCreate, id::GuildId};
use twilight_standby::Standby;

type State = Arc<StateRef>;

#[derive(Debug)]
struct StateRef {
cluster: Cluster,
http: HttpClient,
trackdata: RwLock<HashMap<GuildId, TrackHandle>>,
songbird: Songbird,
Expand Down Expand Up @@ -69,12 +68,11 @@ async fn main() -> Result<(), Box<dyn Error + Send + Sync + 'static>> {
let (cluster, events) = Cluster::new(token, intents).await?;
cluster.up().await;

let songbird = Songbird::twilight(cluster.clone(), user_id);
let songbird = Songbird::twilight(Arc::new(cluster), user_id);

(
events,
Arc::new(StateRef {
cluster,
http,
trackdata: Default::default(),
songbird,
Expand Down
34 changes: 28 additions & 6 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use serenity::gateway::InterMessage;
#[cfg(feature = "gateway-core")]
use std::{error::Error, fmt};
#[cfg(feature = "twilight")]
use twilight_gateway::shard::CommandError;
use twilight_gateway::{cluster::ClusterCommandError, shard::CommandError};

#[cfg(feature = "gateway-core")]
#[derive(Debug)]
Expand Down Expand Up @@ -36,6 +36,10 @@ pub enum JoinError {
///
/// [the `Call`'s configuration]: crate::Config
TimedOut,
/// The given guild ID was zero.
IllegalGuild,
/// The given channel ID was zero.
IllegalChannel,
#[cfg(feature = "driver-core")]
/// The driver failed to establish a voice connection.
///
Expand All @@ -46,8 +50,11 @@ pub enum JoinError {
/// Serenity-specific WebSocket send error.
Serenity(TrySendError<InterMessage>),
#[cfg(feature = "twilight")]
/// Twilight-specific WebSocket send error.
Twilight(CommandError),
/// Twilight-specific WebSocket send error returned when using a shard cluster.
TwilightCluster(ClusterCommandError),
#[cfg(feature = "twilight")]
/// Twilight-specific WebSocket send error when explicitly using a single shard.
TwilightShard(CommandError),
}

#[cfg(feature = "gateway-core")]
Expand Down Expand Up @@ -84,12 +91,16 @@ impl fmt::Display for JoinError {
JoinError::NoSender => write!(f, "no gateway destination"),
JoinError::NoCall => write!(f, "tried to leave a non-existent call"),
JoinError::TimedOut => write!(f, "gateway response from Discord timed out"),
JoinError::IllegalGuild => write!(f, "target guild ID was zero"),
JoinError::IllegalChannel => write!(f, "target channel ID was zero"),
#[cfg(feature = "driver-core")]
JoinError::Driver(_) => write!(f, "establishing connection failed"),
#[cfg(feature = "serenity")]
JoinError::Serenity(e) => e.fmt(f),
#[cfg(feature = "twilight")]
JoinError::Twilight(e) => e.fmt(f),
JoinError::TwilightCluster(e) => e.fmt(f),
#[cfg(feature = "twilight")]
JoinError::TwilightShard(e) => e.fmt(f),
}
}
}
Expand All @@ -102,12 +113,16 @@ impl Error for JoinError {
JoinError::NoSender => None,
JoinError::NoCall => None,
JoinError::TimedOut => None,
JoinError::IllegalGuild => None,
JoinError::IllegalChannel => None,
#[cfg(feature = "driver-core")]
JoinError::Driver(e) => Some(e),
#[cfg(feature = "serenity")]
JoinError::Serenity(e) => e.source(),
#[cfg(feature = "twilight")]
JoinError::Twilight(e) => e.source(),
JoinError::TwilightCluster(e) => e.source(),
#[cfg(feature = "twilight")]
JoinError::TwilightShard(e) => e.source(),
}
}
}
Expand All @@ -122,7 +137,14 @@ impl From<TrySendError<InterMessage>> for JoinError {
#[cfg(all(feature = "twilight", feature = "gateway-core"))]
impl From<CommandError> for JoinError {
fn from(e: CommandError) -> Self {
JoinError::Twilight(e)
JoinError::TwilightShard(e)
}
}

#[cfg(all(feature = "twilight", feature = "gateway-core"))]
impl From<ClusterCommandError> for JoinError {
fn from(e: ClusterCommandError) -> Self {
JoinError::TwilightCluster(e)
}
}

Expand Down
21 changes: 8 additions & 13 deletions src/handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,10 @@ use crate::{
id::{ChannelId, GuildId, UserId},
info::{ConnectionInfo, ConnectionProgress},
join::*,
shards::Shard,
shards::{Shard, VoiceUpdate},
Config,
};
use flume::Sender;
use serde_json::json;
use std::fmt::Debug;
use tracing::instrument;

Expand Down Expand Up @@ -448,17 +447,13 @@ impl Call {
#[instrument(skip(self))]
async fn update(&mut self) -> JoinResult<()> {
if let Some(ws) = self.ws.as_mut() {
let map = json!({
"op": 4,
"d": {
"channel_id": self.connection.as_ref().map(|c| c.0.channel_id().0),
"guild_id": self.guild_id.0,
"self_deaf": self.self_deaf,
"self_mute": self.self_mute,
}
});

ws.send(map).await
ws.update_voice_state(
self.guild_id,
self.connection.as_ref().map(|c| c.0.channel_id()),
self.self_deaf,
self.self_mute,
)
.await
} else {
Err(JoinError::NoSender)
}
Expand Down
6 changes: 3 additions & 3 deletions src/id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ impl From<SerenityChannel> for ChannelId {
#[cfg(feature = "twilight")]
impl From<TwilightChannel> for ChannelId {
fn from(id: TwilightChannel) -> Self {
Self(id.0)
Self(id.0.into())
}
}

Expand Down Expand Up @@ -83,7 +83,7 @@ impl From<GuildId> for DriverGuild {
#[cfg(feature = "twilight")]
impl From<TwilightGuild> for GuildId {
fn from(id: TwilightGuild) -> Self {
Self(id.0)
Self(id.0.into())
}
}

Expand Down Expand Up @@ -116,6 +116,6 @@ impl From<UserId> for DriverUser {
#[cfg(feature = "twilight")]
impl From<TwilightUser> for UserId {
fn from(id: TwilightUser) -> Self {
Self(id.0)
Self(id.0.into())
}
}
6 changes: 6 additions & 0 deletions src/input/dca.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ async fn _dca(path: &OsStr) -> Result<Input, DcaError> {
))
}

#[allow(dead_code)]
#[derive(Debug, Deserialize)]
pub(crate) struct DcaMetadata {
pub(crate) dca: Dca,
Expand All @@ -74,12 +75,14 @@ pub(crate) struct DcaMetadata {
pub(crate) extra: Option<serde_json::Value>,
}

#[allow(dead_code)]
#[derive(Debug, Deserialize)]
pub(crate) struct Dca {
pub(crate) version: u64,
pub(crate) tool: Tool,
}

#[allow(dead_code)]
#[derive(Debug, Deserialize)]
pub(crate) struct Tool {
pub(crate) name: String,
Expand All @@ -88,6 +91,7 @@ pub(crate) struct Tool {
pub(crate) author: String,
}

#[allow(dead_code)]
#[derive(Debug, Deserialize)]
pub(crate) struct Opus {
pub(crate) mode: String,
Expand All @@ -98,6 +102,7 @@ pub(crate) struct Opus {
pub(crate) channels: u8,
}

#[allow(dead_code)]
#[derive(Debug, Deserialize)]
pub(crate) struct Info {
pub(crate) title: Option<String>,
Expand All @@ -107,6 +112,7 @@ pub(crate) struct Info {
pub(crate) cover: Option<String>,
}

#[allow(dead_code)]
#[derive(Debug, Deserialize)]
pub(crate) struct Origin {
pub(crate) source: Option<String>,
Expand Down
8 changes: 4 additions & 4 deletions src/manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ impl Songbird {
/// [`process`].
///
/// [`process`]: Songbird::process
pub fn twilight<U>(cluster: Cluster, user_id: U) -> Self
pub fn twilight<U>(cluster: Arc<Cluster>, user_id: U) -> Self
where
U: Into<UserId>,
{
Expand All @@ -102,7 +102,7 @@ impl Songbird {
/// [`process`].
///
/// [`process`]: Songbird::process
pub fn twilight_from_config<U>(cluster: Cluster, user_id: U, config: Config) -> Self
pub fn twilight_from_config<U>(cluster: Arc<Cluster>, user_id: U, config: Config) -> Self
where
U: Into<UserId>,
{
Expand All @@ -117,7 +117,7 @@ impl Songbird {
user_id: user_id.into(),
}),
calls: Default::default(),
sharder: Sharder::Twilight(cluster),
sharder: Sharder::TwilightCluster(cluster),
config: Some(config).into(),
}
}
Expand Down Expand Up @@ -378,7 +378,7 @@ impl Songbird {
}
},
TwilightEvent::VoiceStateUpdate(v) => {
if v.0.user_id.0 != self.client_data.read().user_id.0 {
if v.0.user_id.0.get() != self.client_data.read().user_id.0 {
return;
}

Expand Down
Loading

0 comments on commit b4ce845

Please sign in to comment.