updated serenity and songbird versions to latest

This commit is contained in:
jellywx 2021-08-13 14:20:45 +01:00
parent 9db0265f5e
commit 7354646c89
9 changed files with 406 additions and 601 deletions

750
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -1,12 +1,12 @@
[package]
name = "soundfx-rs"
version = "1.3.1"
version = "1.4.0"
authors = ["jellywx <judesouthworth@pm.me>"]
edition = "2018"
[dependencies]
songbird = { path = "/home/jude/songbird" }
serenity = { path = "/home/jude/serenity", features = ["voice", "collector", "unstable_discord_api"] }
songbird = { git = "https://github.com/serenity-rs/songbird", branch = "next" }
serenity = { git = "https://github.com/serenity-rs/serenity", branch = "next", features = ["voice", "collector", "unstable_discord_api"] }
sqlx = { version = "0.5", default-features = false, features = ["runtime-tokio-rustls", "macros", "mysql", "bigdecimal"] }
dotenv = "0.15"
tokio = { version = "1", features = ["fs", "process", "io-util"] }

View File

@ -296,7 +296,9 @@ impl ApplicationCommandOptionType {
impl ToTokens for ApplicationCommandOptionType {
fn to_tokens(&self, stream: &mut TokenStream2) {
let path = quote!(serenity::model::interactions::ApplicationCommandOptionType);
let path = quote!(
serenity::model::interactions::application_command::ApplicationCommandOptionType
);
let variant = match self {
ApplicationCommandOptionType::SubCommand => quote!(SubCommand),
ApplicationCommandOptionType::SubCommandGroup => quote!(SubCommandGroup),

View File

@ -192,7 +192,7 @@ async fn info(
invoke: &(dyn CommandInvoke + Sync + Send),
_args: Args,
) -> CommandResult {
let current_user = ctx.cache.current_user().await;
let current_user = ctx.cache.current_user();
invoke.respond(ctx.http.clone(), CreateGenericResponse::new()
.embed(|e| e

View File

@ -225,7 +225,7 @@ pub async fn delete_sound(
} else {
let has_perms = {
if let Ok(member) = invoke.member(&ctx).await {
if let Ok(perms) = member.permissions(&ctx).await {
if let Ok(perms) = member.permissions(&ctx) {
perms.manage_guild()
} else {
false

View File

@ -4,7 +4,7 @@ use serenity::{
builder::CreateActionRow,
client::Context,
framework::standard::CommandResult,
model::interactions::{ButtonStyle, InteractionResponseType},
model::interactions::{message_component::ButtonStyle, InteractionResponseType},
};
use songbird::{
@ -42,7 +42,7 @@ pub async fn play(
invoke: &(dyn CommandInvoke + Sync + Send),
args: Args,
) -> CommandResult {
let guild = invoke.guild(ctx.cache.clone()).await.unwrap();
let guild = invoke.guild(ctx.cache.clone()).unwrap();
invoke
.respond(
@ -72,7 +72,7 @@ pub async fn loop_play(
invoke: &(dyn CommandInvoke + Sync + Send),
args: Args,
) -> CommandResult {
let guild = invoke.guild(ctx.cache.clone()).await.unwrap();
let guild = invoke.guild(ctx.cache.clone()).unwrap();
invoke
.respond(
@ -101,7 +101,7 @@ pub async fn play_ambience(
invoke: &(dyn CommandInvoke + Sync + Send),
args: Args,
) -> CommandResult {
let guild = invoke.guild(ctx.cache.clone()).await.unwrap();
let guild = invoke.guild(ctx.cache.clone()).unwrap();
let channel_to_join = guild
.voice_states

View File

@ -14,7 +14,7 @@ use serenity::{
gateway::{Activity, Ready},
guild::Guild,
id::GuildId,
interactions::Interaction,
interactions::{Interaction, InteractionResponseType},
voice::VoiceState,
},
utils::shard_id,
@ -22,9 +22,8 @@ use serenity::{
use songbird::{Event, EventContext, EventHandler as SongbirdEventHandler};
use crate::framework::{Args, CommandInvoke};
use serenity::model::interactions::{InteractionData, InteractionType};
use serenity::model::prelude::InteractionResponseType;
use crate::framework::Args;
use std::{collections::HashMap, env};
pub struct RestartTrack;
@ -63,13 +62,12 @@ impl EventHandler for Handler {
async fn guild_create(&self, ctx: Context, guild: Guild, is_new: bool) {
if is_new {
if let Ok(token) = env::var("DISCORDBOTS_TOKEN") {
let shard_count = ctx.cache.shard_count().await;
let shard_count = ctx.cache.shard_count();
let current_shard_id = shard_id(guild.id.as_u64().to_owned(), shard_count);
let guild_count = ctx
.cache
.guilds()
.await
.iter()
.filter(|g| shard_id(g.as_u64().to_owned(), shard_count) == current_shard_id)
.count() as u64;
@ -91,7 +89,7 @@ impl EventHandler for Handler {
.post(
format!(
"https://top.gg/api/bots/{}/stats",
ctx.cache.current_user_id().await.as_u64()
ctx.cache.current_user_id().as_u64()
)
.as_str(),
)
@ -117,8 +115,7 @@ impl EventHandler for Handler {
if let Some(past_state) = old {
if let (Some(guild_id), None) = (guild_id_opt, new.channel_id) {
if let Some(channel_id) = past_state.channel_id {
if let Some(Channel::Guild(channel)) = channel_id.to_channel_cached(&ctx).await
{
if let Some(Channel::Guild(channel)) = channel_id.to_channel_cached(&ctx) {
if channel.members(&ctx).await.map(|m| m.len()).unwrap_or(0) <= 1 {
let songbird = songbird::get(&ctx).await.unwrap();
@ -128,7 +125,7 @@ impl EventHandler for Handler {
}
}
} else if let (Some(guild_id), Some(user_channel)) = (guild_id_opt, new.channel_id) {
if let Some(guild) = ctx.cache.guild(guild_id).await {
if let Some(guild) = ctx.cache.guild(guild_id) {
let pool = ctx
.data
.read()
@ -183,12 +180,12 @@ SELECT name, id, plays, public, server_id, uploader_id
}
async fn interaction_create(&self, ctx: Context, interaction: Interaction) {
if interaction.guild_id.is_none() {
return;
}
match interaction {
Interaction::ApplicationCommand(application_command) => {
if application_command.guild_id.is_none() {
return;
}
match interaction.kind {
InteractionType::ApplicationCommand => {
let framework = ctx
.data
.read()
@ -197,33 +194,34 @@ SELECT name, id, plays, public, server_id, uploader_id
.cloned()
.expect("RegexFramework not found in context");
framework.execute(ctx, interaction).await;
framework.execute(ctx, application_command).await;
}
InteractionType::MessageComponent => {
if let (Some(InteractionData::MessageComponent(data)), Some(member)) =
(interaction.clone().data, interaction.clone().member)
{
let mut args = Args {
args: Default::default(),
};
args.args.insert("query".to_string(), data.custom_id);
play_from_query(
&ctx,
interaction.guild(ctx.cache.clone()).await.unwrap(),
member.user.id,
args,
false,
)
.await;
interaction
.create_interaction_response(ctx, |r| {
r.kind(InteractionResponseType::DeferredUpdateMessage)
})
.await
.unwrap();
Interaction::MessageComponent(component) => {
if component.guild_id.is_none() {
return;
}
let mut args = Args {
args: Default::default(),
};
args.args
.insert("query".to_string(), component.data.custom_id.clone());
play_from_query(
&ctx,
component.guild_id.unwrap().to_guild_cached(&ctx).unwrap(),
component.user.id,
args,
false,
)
.await;
component
.create_interaction_response(ctx, |r| {
r.kind(InteractionResponseType::DeferredUpdateMessage)
})
.await
.unwrap();
}
_ => {}
}

View File

@ -10,8 +10,12 @@ use serenity::{
channel::{Channel, GuildChannel, Message},
guild::{Guild, Member},
id::{ChannelId, GuildId, UserId},
interactions::{ApplicationCommand, Interaction, InteractionData},
prelude::{ApplicationCommandOptionType, InteractionResponseType},
interactions::{
application_command::{
ApplicationCommand, ApplicationCommandInteraction, ApplicationCommandOptionType,
},
InteractionResponseType,
},
},
prelude::TypeMapKey,
Result as SerenityResult,
@ -126,11 +130,11 @@ impl CreateGenericResponse {
pub trait CommandInvoke {
fn channel_id(&self) -> ChannelId;
fn guild_id(&self) -> Option<GuildId>;
async fn guild(&self, cache: Arc<Cache>) -> Option<Guild>;
fn guild(&self, cache: Arc<Cache>) -> Option<Guild>;
fn author_id(&self) -> UserId;
async fn member(&self, context: &Context) -> SerenityResult<Member>;
fn msg(&self) -> Option<Message>;
fn interaction(&self) -> Option<Interaction>;
fn interaction(&self) -> Option<ApplicationCommandInteraction>;
async fn respond(
&self,
http: Arc<Http>,
@ -153,8 +157,8 @@ impl CommandInvoke for Message {
self.guild_id
}
async fn guild(&self, cache: Arc<Cache>) -> Option<Guild> {
self.guild(cache).await
fn guild(&self, cache: Arc<Cache>) -> Option<Guild> {
self.guild(cache)
}
fn author_id(&self) -> UserId {
@ -169,7 +173,7 @@ impl CommandInvoke for Message {
Some(self.clone())
}
fn interaction(&self) -> Option<Interaction> {
fn interaction(&self) -> Option<ApplicationCommandInteraction> {
None
}
@ -187,7 +191,10 @@ impl CommandInvoke for Message {
}
if let Some(components) = generic_response.components {
m.set_components(components.clone());
m.components(|c| {
*c = components;
c
});
}
m
@ -210,7 +217,10 @@ impl CommandInvoke for Message {
}
if let Some(components) = generic_response.components {
m.set_components(components.clone());
m.components(|c| {
*c = components;
c
});
}
m
@ -221,18 +231,18 @@ impl CommandInvoke for Message {
}
#[async_trait]
impl CommandInvoke for Interaction {
impl CommandInvoke for ApplicationCommandInteraction {
fn channel_id(&self) -> ChannelId {
self.channel_id.unwrap()
self.channel_id
}
fn guild_id(&self) -> Option<GuildId> {
self.guild_id
}
async fn guild(&self, cache: Arc<Cache>) -> Option<Guild> {
fn guild(&self, cache: Arc<Cache>) -> Option<Guild> {
if let Some(guild_id) = self.guild_id {
guild_id.to_guild_cached(cache).await
guild_id.to_guild_cached(cache)
} else {
None
}
@ -250,7 +260,7 @@ impl CommandInvoke for Interaction {
None
}
fn interaction(&self) -> Option<Interaction> {
fn interaction(&self) -> Option<ApplicationCommandInteraction> {
Some(self.clone())
}
@ -269,7 +279,10 @@ impl CommandInvoke for Interaction {
}
if let Some(components) = generic_response.components {
d.set_components(components.clone());
d.components(|c| {
*c = components;
c
});
}
d
@ -292,7 +305,10 @@ impl CommandInvoke for Interaction {
}
if let Some(components) = generic_response.components {
d.set_components(components.clone());
d.components(|c| {
*c = components;
c
});
}
d
@ -652,63 +668,64 @@ impl RegexFramework {
info!("{} slash commands built! Ready to go", count);
}
pub async fn execute(&self, ctx: Context, interaction: Interaction) {
if let Some(InteractionData::ApplicationCommand(data)) = interaction.data.clone() {
let command = {
let name = data.name;
pub async fn execute(&self, ctx: Context, interaction: ApplicationCommandInteraction) {
let command = {
self.commands.get(&interaction.data.name).expect(&format!(
"Received invalid command: {}",
interaction.data.name
))
};
self.commands
.get(&name)
.expect(&format!("Received invalid command: {}", name))
};
if command
.check_permissions(
&ctx,
&interaction.guild(ctx.cache.clone()).unwrap(),
&interaction.clone().member.unwrap(),
)
.await
{
let mut args = HashMap::new();
if command
.check_permissions(
&ctx,
&interaction.guild(ctx.cache.clone()).await.unwrap(),
&interaction.member(&ctx).await.unwrap(),
)
.await
for arg in interaction
.data
.options
.iter()
.filter(|o| o.value.is_some())
{
let mut args = HashMap::new();
for arg in data.options.iter().filter(|o| o.value.is_some()) {
args.insert(
arg.name.clone(),
match arg.value.clone().unwrap() {
Value::Bool(b) => {
if b {
arg.name.clone()
} else {
String::new()
}
args.insert(
arg.name.clone(),
match arg.value.clone().unwrap() {
Value::Bool(b) => {
if b {
arg.name.clone()
} else {
String::new()
}
Value::Number(n) => n.to_string(),
Value::String(s) => s,
_ => String::new(),
},
);
}
}
Value::Number(n) => n.to_string(),
Value::String(s) => s,
_ => String::new(),
},
);
}
(command.fun)(&ctx, &interaction, Args { args })
.await
.unwrap();
} else if command.required_permissions == PermissionLevel::Managed {
let _ = interaction
(command.fun)(&ctx, &interaction, Args { args })
.await
.unwrap();
} else if command.required_permissions == PermissionLevel::Managed {
let _ = interaction
.respond(
ctx.http.clone(),
CreateGenericResponse::new().content("You must either be an Admin or have a role specified in `?roles` to do this command")
)
.await;
} else if command.required_permissions == PermissionLevel::Restricted {
let _ = interaction
.respond(
ctx.http.clone(),
CreateGenericResponse::new()
.content("You must be an Admin to do this command"),
)
.await;
}
} else if command.required_permissions == PermissionLevel::Restricted {
let _ = interaction
.respond(
ctx.http.clone(),
CreateGenericResponse::new().content("You must be an Admin to do this command"),
)
.await;
}
}
}
@ -725,9 +742,9 @@ impl Framework for RegexFramework {
ctx: &Context,
channel: &GuildChannel,
) -> SerenityResult<PermissionCheck> {
let user_id = ctx.cache.current_user_id().await;
let user_id = ctx.cache.current_user_id();
let channel_perms = channel.permissions_for_user(ctx, user_id).await?;
let channel_perms = channel.permissions_for_user(ctx, user_id)?;
Ok(
if channel_perms.send_messages() && channel_perms.embed_links() {
@ -754,8 +771,8 @@ impl Framework for RegexFramework {
if msg.author.bot || msg.content.is_empty() {
}
// Guild Command
else if let (Some(guild), Some(Channel::Guild(channel))) =
(msg.guild(&ctx).await, msg.channel(&ctx).await)
else if let (Some(guild), Ok(Channel::Guild(channel))) =
(msg.guild(&ctx), msg.channel(&ctx).await)
{
if let Some(full_match) = self.command_matcher.captures(&msg.content) {
if check_prefix(&ctx, &guild, full_match.name("prefix")).await {

View File

@ -110,7 +110,7 @@ async fn join_channel(
channel_id: ChannelId,
) -> (Arc<Mutex<Call>>, JoinResult<()>) {
let songbird = songbird::get(ctx).await.unwrap();
let current_user = ctx.cache.current_user_id().await;
let current_user = ctx.cache.current_user_id();
let current_voice_state = guild
.voice_states
@ -138,9 +138,9 @@ async fn join_channel(
let _ = call.lock().await.deafen(true).await;
}
if let Some(Channel::Guild(channel)) = channel_id.to_channel_cached(&ctx).await {
if let Some(Channel::Guild(channel)) = channel_id.to_channel_cached(&ctx) {
channel
.edit_voice_state(&ctx, ctx.cache.current_user().await, |v| v.suppress(false))
.edit_voice_state(&ctx, ctx.cache.current_user(), |v| v.suppress(false))
.await;
}