Compare commits
1 Commits
bec92177cb
...
jude/index
Author | SHA1 | Date | |
---|---|---|---|
a2ac7050d7 |
116
Cargo.lock
generated
116
Cargo.lock
generated
@ -139,55 +139,6 @@ version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "axum"
|
||||
version = "0.6.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"axum-core",
|
||||
"bitflags 1.3.2",
|
||||
"bytes",
|
||||
"futures-util",
|
||||
"http",
|
||||
"http-body",
|
||||
"hyper",
|
||||
"itoa",
|
||||
"matchit",
|
||||
"memchr",
|
||||
"mime",
|
||||
"percent-encoding",
|
||||
"pin-project-lite",
|
||||
"rustversion",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_path_to_error",
|
||||
"serde_urlencoded",
|
||||
"sync_wrapper",
|
||||
"tokio",
|
||||
"tower",
|
||||
"tower-layer",
|
||||
"tower-service",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "axum-core"
|
||||
version = "0.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"bytes",
|
||||
"futures-util",
|
||||
"http",
|
||||
"http-body",
|
||||
"mime",
|
||||
"rustversion",
|
||||
"tower-layer",
|
||||
"tower-service",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "backtrace"
|
||||
version = "0.3.68"
|
||||
@ -1129,12 +1080,6 @@ dependencies = [
|
||||
"regex-automata 0.1.10",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "matchit"
|
||||
version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.5.0"
|
||||
@ -1604,27 +1549,6 @@ dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "prometheus"
|
||||
version = "0.13.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "449811d15fbdf5ceb5c1144416066429cf82316e2ec8ce0c1f6f8a02e7bbcf8c"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"fnv",
|
||||
"lazy_static",
|
||||
"memchr",
|
||||
"parking_lot 0.12.1",
|
||||
"protobuf",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "protobuf"
|
||||
version = "2.28.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "106dd99e98437432fed6519dedecfade6a06a73bb7b2a1e019fdd2bee5778d94"
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.29"
|
||||
@ -2022,16 +1946,6 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_path_to_error"
|
||||
version = "0.1.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4beec8bce849d58d06238cb50db2e1c417cfeafa4c63f692b15c82b7c80f8335"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_repr"
|
||||
version = "0.1.14"
|
||||
@ -2217,14 +2131,12 @@ dependencies = [
|
||||
name = "soundfx-rs"
|
||||
version = "1.5.11"
|
||||
dependencies = [
|
||||
"axum",
|
||||
"dashmap",
|
||||
"dotenv",
|
||||
"env_logger",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"poise",
|
||||
"prometheus",
|
||||
"regex",
|
||||
"reqwest",
|
||||
"serde",
|
||||
@ -2425,12 +2337,6 @@ dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sync_wrapper"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160"
|
||||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.6.0"
|
||||
@ -2623,28 +2529,6 @@ dependencies = [
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tower"
|
||||
version = "0.4.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"pin-project",
|
||||
"pin-project-lite",
|
||||
"tokio",
|
||||
"tower-layer",
|
||||
"tower-service",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tower-layer"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0"
|
||||
|
||||
[[package]]
|
||||
name = "tower-service"
|
||||
version = "0.3.2"
|
||||
|
@ -20,11 +20,6 @@ serde_json = "1.0"
|
||||
dashmap = "5.3"
|
||||
serde = "1.0"
|
||||
dotenv = "0.15.0"
|
||||
prometheus = { version = "0.13.3", optional = true }
|
||||
axum = { version = "0.6.20", optional = true }
|
||||
|
||||
[features]
|
||||
metrics = ["dep:prometheus", "dep:axum"]
|
||||
|
||||
[patch."https://github.com/serenity-rs/serenity"]
|
||||
serenity = { version = "0.11.6" }
|
||||
|
6
migrations/20231021161427_add_indexes.sql
Normal file
6
migrations/20231021161427_add_indexes.sql
Normal file
@ -0,0 +1,6 @@
|
||||
-- Add migration script here
|
||||
ALTER TABLE `sounds` ADD UNIQUE INDEX `uploader_id_name` (`uploader_id`, `name`);
|
||||
ALTER TABLE `sounds` ADD INDEX `name` (`name`);
|
||||
ALTER TABLE `sounds` ADD INDEX `public` (`public`);
|
||||
ALTER TABLE `sounds` ADD INDEX `uploader_id` (`uploader_id`);
|
||||
ALTER TABLE `sounds` ADD INDEX `server_id` (`server_id`);
|
@ -1,16 +1,12 @@
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
|
||||
use poise::serenity_prelude::{
|
||||
builder::CreateActionRow, model::application::component::ButtonStyle, GuildChannel,
|
||||
ReactionType,
|
||||
};
|
||||
|
||||
#[cfg(feature = "metrics")]
|
||||
use crate::metrics::PLAY_COUNTER;
|
||||
use crate::{
|
||||
cmds::autocomplete_sound,
|
||||
models::{guild_data::CtxGuildData, sound::SoundCtx},
|
||||
utils::{join_channel, play_audio, play_from_query, queue_audio},
|
||||
utils::{join_channel, play_from_query, queue_audio},
|
||||
Context, Error,
|
||||
};
|
||||
|
||||
@ -29,9 +25,6 @@ pub async fn play(
|
||||
|
||||
let guild = ctx.guild().unwrap();
|
||||
|
||||
#[cfg(feature = "metrics")]
|
||||
PLAY_COUNTER.inc();
|
||||
|
||||
ctx.say(
|
||||
play_from_query(
|
||||
&ctx.serenity_context(),
|
||||
@ -49,70 +42,6 @@ pub async fn play(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Play a random sound from this server
|
||||
#[poise::command(
|
||||
slash_command,
|
||||
rename = "random",
|
||||
default_member_permissions = "SPEAK",
|
||||
guild_only = true
|
||||
)]
|
||||
pub async fn play_random(
|
||||
ctx: Context<'_>,
|
||||
#[description = "Channel to play in (default: your current voice channel)"]
|
||||
#[channel_types("Voice")]
|
||||
channel: Option<GuildChannel>,
|
||||
) -> Result<(), Error> {
|
||||
ctx.defer().await?;
|
||||
|
||||
let guild = ctx.guild().unwrap();
|
||||
let channel_to_join = channel.map(|c| c.id).or_else(|| {
|
||||
guild
|
||||
.voice_states
|
||||
.get(&ctx.author().id)
|
||||
.and_then(|voice_state| voice_state.channel_id)
|
||||
});
|
||||
|
||||
match channel_to_join {
|
||||
Some(channel) => {
|
||||
let (call_handler, _) =
|
||||
join_channel(ctx.serenity_context(), guild.clone(), channel).await;
|
||||
|
||||
let sounds = ctx.data().guild_sounds(guild.id, None).await?;
|
||||
|
||||
let ts = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
|
||||
|
||||
// This is far cheaper and easier than using an RNG. No reason to use a full RNG here
|
||||
// anyway.
|
||||
match sounds.get(ts.subsec_micros() as usize % sounds.len()) {
|
||||
Some(sound) => {
|
||||
let guild_data = ctx.data().guild_data(guild.id).await.unwrap();
|
||||
let mut lock = call_handler.lock().await;
|
||||
|
||||
play_audio(
|
||||
sound,
|
||||
guild_data.read().await.volume,
|
||||
&mut lock,
|
||||
&ctx.data().database,
|
||||
false,
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
None => {
|
||||
ctx.say("No sounds in this server!").await?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
None => {
|
||||
ctx.say("You are not in a voice chat!").await?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Play up to 25 sounds on queue
|
||||
#[poise::command(
|
||||
slash_command,
|
||||
|
@ -1,8 +1,11 @@
|
||||
use std::{collections::HashMap, env};
|
||||
|
||||
use poise::serenity_prelude::{
|
||||
model::{
|
||||
application::interaction::{Interaction, InteractionResponseType},
|
||||
channel::Channel,
|
||||
},
|
||||
utils::shard_id,
|
||||
ActionRowComponent, Activity, Context, CreateActionRow, CreateComponents,
|
||||
};
|
||||
|
||||
@ -22,6 +25,46 @@ pub async fn listener(ctx: &Context, event: &poise::Event<'_>, data: &Data) -> R
|
||||
poise::Event::Ready { .. } => {
|
||||
ctx.set_activity(Activity::watching("for /play")).await;
|
||||
}
|
||||
poise::Event::GuildCreate { guild, is_new, .. } => {
|
||||
if *is_new {
|
||||
if let Ok(token) = env::var("DISCORDBOTS_TOKEN") {
|
||||
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()
|
||||
.iter()
|
||||
.filter(|g| {
|
||||
shard_id(g.as_u64().to_owned(), shard_count) == current_shard_id
|
||||
})
|
||||
.count() as u64;
|
||||
|
||||
let mut hm = HashMap::new();
|
||||
hm.insert("server_count", guild_count);
|
||||
hm.insert("shard_id", current_shard_id);
|
||||
hm.insert("shard_count", shard_count);
|
||||
|
||||
let response = data
|
||||
.http
|
||||
.post(
|
||||
format!(
|
||||
"https://top.gg/api/bots/{}/stats",
|
||||
ctx.cache.current_user_id().as_u64()
|
||||
)
|
||||
.as_str(),
|
||||
)
|
||||
.header("Authorization", token)
|
||||
.json(&hm)
|
||||
.send()
|
||||
.await;
|
||||
|
||||
if let Err(res) = response {
|
||||
println!("DiscordBots Response: {:?}", res);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
poise::Event::VoiceStateUpdate { old, new, .. } => {
|
||||
if let Some(past_state) = old {
|
||||
if let (Some(guild_id), None) = (past_state.guild_id, new.channel_id) {
|
||||
@ -62,9 +105,10 @@ pub async fn listener(ctx: &Context, event: &poise::Event<'_>, data: &Data) -> R
|
||||
let mut sound = sqlx::query_as_unchecked!(
|
||||
Sound,
|
||||
"
|
||||
SELECT name, id, public, server_id, uploader_id
|
||||
FROM sounds
|
||||
WHERE id = ?",
|
||||
SELECT name, id, public, server_id, uploader_id
|
||||
FROM sounds
|
||||
WHERE id = ?
|
||||
",
|
||||
join_id
|
||||
)
|
||||
.fetch_one(&data.database)
|
||||
|
10
src/main.rs
10
src/main.rs
@ -5,8 +5,6 @@ mod cmds;
|
||||
mod consts;
|
||||
mod error;
|
||||
mod event_handlers;
|
||||
#[cfg(feature = "metrics")]
|
||||
mod metrics;
|
||||
mod models;
|
||||
mod utils;
|
||||
|
||||
@ -87,7 +85,6 @@ async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
||||
cmds::manage::download_file(),
|
||||
cmds::manage::delete_sound(),
|
||||
cmds::play::play(),
|
||||
cmds::play::play_random(),
|
||||
cmds::play::queue_play(),
|
||||
cmds::play::loop_play(),
|
||||
cmds::play::soundboard(),
|
||||
@ -106,6 +103,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
||||
],
|
||||
..cmds::favorite::favorites()
|
||||
},
|
||||
cmds::search::show_random_sounds(),
|
||||
cmds::search::search_sounds(),
|
||||
cmds::stop::stop_playing(),
|
||||
cmds::stop::disconnect(),
|
||||
@ -144,12 +142,6 @@ async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
||||
|
||||
sqlx::migrate!().run(&database).await?;
|
||||
|
||||
#[cfg(feature = "metrics")]
|
||||
{
|
||||
metrics::init_metrics();
|
||||
tokio::spawn(async { metrics::serve().await });
|
||||
}
|
||||
|
||||
poise::Framework::builder()
|
||||
.token(discord_token)
|
||||
.setup(move |ctx, _bot, framework| {
|
||||
|
@ -1,40 +0,0 @@
|
||||
use std::net::SocketAddr;
|
||||
|
||||
use axum::{routing::get, Router};
|
||||
use lazy_static;
|
||||
use log::warn;
|
||||
use prometheus::{register_int_counter, IntCounter, Registry};
|
||||
|
||||
lazy_static! {
|
||||
static ref REGISTRY: Registry = Registry::new();
|
||||
pub static ref PLAY_COUNTER: IntCounter =
|
||||
register_int_counter!("play", "Number of calls to /play").unwrap();
|
||||
}
|
||||
|
||||
pub fn init_metrics() {
|
||||
REGISTRY.register(Box::new(PLAY_COUNTER.clone())).unwrap();
|
||||
}
|
||||
|
||||
pub async fn serve() {
|
||||
let app = Router::new().route("/", get(metrics));
|
||||
let addr = SocketAddr::from(([127, 0, 0, 1], 31755));
|
||||
|
||||
axum::Server::bind(&addr)
|
||||
.serve(app.into_make_service())
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
async fn metrics() -> String {
|
||||
let encoder = prometheus::TextEncoder::new();
|
||||
let res_custom = encoder.encode_to_string(®ISTRY.gather());
|
||||
|
||||
match res_custom {
|
||||
Ok(s) => s,
|
||||
Err(e) => {
|
||||
warn!("Error encoding metrics: {:?}", e);
|
||||
|
||||
String::new()
|
||||
}
|
||||
}
|
||||
}
|
@ -106,7 +106,7 @@ pub async fn play_from_query(
|
||||
user_id: UserId,
|
||||
channel: Option<ChannelId>,
|
||||
query: &str,
|
||||
r#loop: bool,
|
||||
loop_: bool,
|
||||
) -> String {
|
||||
let guild_id = guild.id;
|
||||
|
||||
@ -141,7 +141,7 @@ pub async fn play_from_query(
|
||||
guild_data.read().await.volume,
|
||||
&mut lock,
|
||||
&data.database,
|
||||
r#loop,
|
||||
loop_,
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
Reference in New Issue
Block a user