-
-
Notifications
You must be signed in to change notification settings - Fork 132
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(lavalink)!: Lavalink refactor to v4 API #2322
base: main
Are you sure you want to change the base?
Changes from all commits
9ad9051
d309466
b099660
338cfa4
a7866f1
d52bf32
ee4f523
0534c02
b92b2f3
98e76cc
5fc8850
cbf10ad
1a5b5dd
e7435e1
1cc0047
c26de22
e33c8ce
ec43697
4d87d91
09e57fa
b48ec2b
a498dd9
2c5e10e
c3f79de
9b75e43
f532c43
17d4a84
fad0435
a82950a
7ae3b51
bab628c
dfd42ce
38f2aaa
3147e92
b08ccbd
5da3c95
b0277aa
422cb43
a37e113
25c60b6
7ba6c16
8f50b4a
dd66b21
4964939
588b4d2
2fa60e2
e027013
89d472d
2e78099
9477c59
22b6ae9
7095e46
cd4906c
ddbd6f4
f8d66ac
99a00b7
885c4d8
a999a13
1159372
a4c7af6
2510e16
d12aed8
199190d
3038739
28c720f
9de5656
61b8cd5
fd521d9
571355e
9d7ad7b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,6 +9,10 @@ use twilight_gateway::{ | |
Event, EventTypeFlags, Intents, MessageSender, Shard, ShardId, StreamExt as _, | ||
}; | ||
use twilight_http::Client as HttpClient; | ||
use twilight_lavalink::{ | ||
http::LoadResultData::{Playlist, Search, Track}, | ||
model::{Equalizer, EqualizerBand}, | ||
}; | ||
use twilight_lavalink::{ | ||
http::LoadedTracks, | ||
model::{Destroy, Pause, Play, Seek, Stop, Volume}, | ||
|
@@ -53,6 +57,7 @@ async fn main() -> anyhow::Result<()> { | |
let http = HttpClient::new(token.clone()); | ||
let user_id = http.current_user().await?.model().await?.id; | ||
|
||
// The client is [`Lavalink`](crate::client::Lavalink) that forwards the required events from Discord. | ||
let lavalink = Lavalink::new(user_id, shard_count); | ||
lavalink.add(lavalink_host, lavalink_auth).await?; | ||
|
||
|
@@ -81,6 +86,10 @@ async fn main() -> anyhow::Result<()> { | |
}; | ||
|
||
state.standby.process(&event); | ||
|
||
// We read the [Voice State and Voice Server Updates](https://discord.com/developers/docs/topics/gateway-events#voice) from discord to format the data to send to a Lavalink `VoiceUpdate` Event. | ||
// There is a lower level [node](crate::node) that processes this for you. It isn't recommended to use this but rather the lavalink struct with the players. If you don't find functionality please open up and issue to expose what you need. | ||
// See the command functions for where we use the players. | ||
Comment on lines
+90
to
+92
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same here |
||
state.lavalink.process(&event).await?; | ||
|
||
if let Event::MessageCreate(msg) = event { | ||
|
@@ -96,6 +105,7 @@ async fn main() -> anyhow::Result<()> { | |
Some("!seek") => spawn(seek(msg.0, Arc::clone(&state))), | ||
Some("!stop") => spawn(stop(msg.0, Arc::clone(&state))), | ||
Some("!volume") => spawn(volume(msg.0, Arc::clone(&state))), | ||
Some("!equalize") => spawn(equalize(msg.0, Arc::clone(&state))), | ||
_ => continue, | ||
} | ||
} | ||
|
@@ -194,13 +204,21 @@ async fn play(msg: Message, state: State) -> anyhow::Result<()> { | |
|
||
let loaded = serde_json::from_slice::<LoadedTracks>(&response_bytes)?; | ||
|
||
if let Some(track) = loaded.tracks.first() { | ||
player.send(Play::from((guild_id, &track.track)))?; | ||
let track = match loaded.data { | ||
Track(track) => Some(track), | ||
Playlist(top_track) => top_track.tracks.first().cloned(), | ||
Search(result) => result.first().cloned(), | ||
_ => None, | ||
}; | ||
|
||
if let Some(track) = track { | ||
player.send(Play::from((guild_id, &track.encoded)))?; | ||
|
||
let content = format!( | ||
"Playing **{:?}** by **{:?}**", | ||
track.info.title, track.info.author | ||
); | ||
|
||
state | ||
.http | ||
.create_message(msg.channel_id) | ||
|
@@ -274,6 +292,57 @@ async fn seek(msg: Message, state: State) -> anyhow::Result<()> { | |
Ok(()) | ||
} | ||
|
||
async fn equalize(msg: Message, state: State) -> anyhow::Result<()> { | ||
tracing::debug!( | ||
"equalize command in channel {} by {}", | ||
msg.channel_id, | ||
msg.author.name | ||
); | ||
state | ||
.http | ||
.create_message(msg.channel_id) | ||
.content("What band do you want to equalize (0-14)?") | ||
.await?; | ||
|
||
let author_id = msg.author.id; | ||
let band_msg = state | ||
.standby | ||
.wait_for_message(msg.channel_id, move |new_msg: &MessageCreate| { | ||
new_msg.author.id == author_id | ||
}) | ||
.await?; | ||
let guild_id = msg.guild_id.unwrap(); | ||
let band = band_msg.content.parse::<i64>()?; | ||
|
||
state | ||
.http | ||
.create_message(msg.channel_id) | ||
.content("What gain do you want to equalize (-0.25 to 1.0)?") | ||
.await?; | ||
|
||
let gain_msg = state | ||
.standby | ||
.wait_for_message(msg.channel_id, move |new_msg: &MessageCreate| { | ||
new_msg.author.id == author_id | ||
}) | ||
.await?; | ||
let gain = gain_msg.content.parse::<f64>()?; | ||
|
||
let player = state.lavalink.player(guild_id).await.unwrap(); | ||
player.send(Equalizer::from(( | ||
guild_id, | ||
vec![EqualizerBand::new(band, gain)], | ||
)))?; | ||
|
||
state | ||
.http | ||
.create_message(msg.channel_id) | ||
.content(&format!("Changed gain level to {gain} on band {band}.")) | ||
.await?; | ||
|
||
Ok(()) | ||
} | ||
|
||
async fn stop(msg: Message, state: State) -> anyhow::Result<()> { | ||
tracing::debug!( | ||
"stop command in channel {} by {}", | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,15 +17,16 @@ version = "0.16.0-rc.1" | |
dashmap = { default-features = false, version = "5.3" } | ||
futures-util = { default-features = false, features = ["bilock", "sink", "std", "unstable"], version = "0.3" } | ||
http = { default-features = false, version = "1" } | ||
hyper = { default-features = false, features = ["client", "http1"], version = "1" } | ||
hyper-util = { default-features = false, features = ["client-legacy", "client", "http1", "tokio"], version = "0.1" } | ||
http-body-util = "0.1" | ||
serde = { default-features = false, features = ["derive", "std"], version = "1" } | ||
serde_json = { default-features = false, features = ["std"], version = "1" } | ||
tokio = { default-features = false, features = ["macros", "net", "rt", "sync", "time"], version = "1.0" } | ||
tokio-websockets = { default-features = false, features = ["client", "fastrand", "sha1_smol", "simd"], version = "0.7" } | ||
tracing = { default-features = false, features = ["std", "attributes"], version = "0.1" } | ||
twilight-model = { default-features = false, path = "../twilight-model", version = "0.16.0-rc.1" } | ||
|
||
# Optional dependencies. | ||
percent-encoding = { default-features = false, optional = true, version = "2" } | ||
percent-encoding = { default-features = false, version = "2" } | ||
|
||
[dev-dependencies] | ||
anyhow = { default-features = false, features = ["std"], version = "1" } | ||
|
@@ -37,8 +38,8 @@ twilight-gateway = { default-features = false, features = ["rustls-native-roots" | |
twilight-http = { default-features = false, features = ["rustls-native-roots"], path = "../twilight-http", version = "0.16.0-rc.1" } | ||
|
||
[features] | ||
default = ["http-support", "rustls-native-roots"] | ||
http-support = ["dep:percent-encoding"] | ||
default = ["http2", "rustls-native-roots"] | ||
http2 = ["hyper/http2", "hyper-util/http2"] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. HTTP2 as a separate feature makes little sense because it is pointless without prior knowledge, which I assume is virtually never the case. I'd add this implicitly to the TLS features. |
||
native-tls = ["tokio-websockets/native-tls", "tokio-websockets/openssl"] | ||
rustls-native-roots = ["tokio-websockets/ring", "tokio-websockets/rustls-native-roots"] | ||
rustls-webpki-roots = ["tokio-websockets/ring", "tokio-websockets/rustls-webpki-roots"] | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,12 +13,19 @@ handle sending voice channel updates to Lavalink by processing events via | |
the [client's `process` method][`Lavalink::process`], which you must call | ||
with every Voice State Update and Voice Server Update you receive. | ||
|
||
Currently some [Filters](crate::model::outgoing::Filters) are not yet supported. | ||
Some endpoints such as [Lavalink Info] and [Update Session] have also not yet | ||
been implemented. Please reach out and open an issue for any missing feature you | ||
would like to use. The Lavalink V4 port did not add support for any new features | ||
not previously found in V3. | ||
Comment on lines
+16
to
+20
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I feel like this is supposed to go inside the changelog, not the README |
||
|
||
## Features | ||
|
||
### `http-support` | ||
### `http2` | ||
|
||
The `http-support` feature adds support for the `http` module to return | ||
request types from the [`http`] crate. This is enabled by default. | ||
The `http2` feature enables support for communicating with the Lavalink server | ||
over HTTP/2. You will also need to enable http2 support in your Lavalink server | ||
configuration as it is disabled by default. | ||
|
||
### TLS | ||
|
||
|
@@ -104,6 +111,8 @@ There is also an example of a basic bot located in the [root of the | |
`twilight` repository][github examples link]. | ||
|
||
[Lavalink]: https://github.com/freyacodes/Lavalink | ||
[Lavalink Info]: https://lavalink.dev/api/rest.html#get-lavalink-version | ||
[Update Session]: https://lavalink.dev/api/rest#update-session | ||
[`http`]: https://crates.io/crates/http | ||
[`rustls`]: https://crates.io/crates/rustls | ||
[`rustls-native-certs`]: https://crates.io/crates/rustls-native-certs | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's nice that you are trying to document what is going on here, but this is not a doc comment and won't get rendered anywhere. I'd try and rephrase it as a comment rather than documentation