updated serenity and songbird versions to latest
This commit is contained in:
parent
9db0265f5e
commit
7354646c89
750
Cargo.lock
generated
750
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -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"] }
|
||||
|
@ -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),
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
151
src/framework.rs
151
src/framework.rs
@ -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 {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user