Join sounds per-server

This commit is contained in:
jude 2022-07-31 14:56:38 +01:00
parent 31b6f7a0ab
commit f5acab7440
9 changed files with 300 additions and 127 deletions

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="dataSourceStorageLocal" created-in="CL-221.5921.27"> <component name="dataSourceStorageLocal" created-in="CL-222.3345.126">
<data-source name="MySQL for 5.1 - soundfx@localhost" uuid="1067c1d0-1386-4a39-b3f5-6d48d6f279eb"> <data-source name="MySQL for 5.1 - soundfx@localhost" uuid="1067c1d0-1386-4a39-b3f5-6d48d6f279eb">
<database-info product="" version="" jdbc-version="" driver-name="" driver-version="" dbms="MYSQL" exact-version="0" /> <database-info product="" version="" jdbc-version="" driver-name="" driver-version="" dbms="MYSQL" exact-version="0" />
<secret-storage>master_key</secret-storage> <secret-storage>master_key</secret-storage>

128
Cargo.lock generated
View File

@ -190,9 +190,9 @@ checksum = "37ccbd214614c6783386c1af30caf03192f17891059cecc394b4fb119e363de3"
[[package]] [[package]]
name = "bytemuck" name = "bytemuck"
version = "1.10.0" version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c53dfa917ec274df8ed3c572698f381a24eef2efba9492d797301b72b6db408a" checksum = "a5377c8865e74a160d21f29c2d40669f53286db6eab59b88540cbb12ffc8b835"
[[package]] [[package]]
name = "byteorder" name = "byteorder"
@ -202,9 +202,9 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
[[package]] [[package]]
name = "bytes" name = "bytes"
version = "1.2.0" version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0b3de4a0c5e67e16066a0715723abd91edc2f9001d09c46e1dca929351e130e" checksum = "ec8a7b6a70fde80372154c65702f00a0f56f3e1c36abbc6c440484be248856db"
[[package]] [[package]]
name = "cc" name = "cc"
@ -291,9 +291,9 @@ dependencies = [
[[package]] [[package]]
name = "crossbeam-queue" name = "crossbeam-queue"
version = "0.3.5" version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1f25d8400f4a7a5778f0e4e52384a48cbd9b5c495d110786187fc750075277a2" checksum = "1cd42583b04998a5363558e5f9291ee5a5ff6b49944332103f251e7479a82aa7"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"crossbeam-utils", "crossbeam-utils",
@ -301,9 +301,9 @@ dependencies = [
[[package]] [[package]]
name = "crossbeam-utils" name = "crossbeam-utils"
version = "0.8.10" version = "0.8.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d82ee10ce34d7bc12c2122495e7593a9c41347ecdd64185af4ecf72cb1a7f83" checksum = "51887d4adc7b564537b15adcfb307936f8075dfcd5f00dde9a9f1d29383682bc"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"once_cell", "once_cell",
@ -365,16 +365,6 @@ dependencies = [
"syn", "syn",
] ]
[[package]]
name = "dashmap"
version = "4.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e77a43b28d0668df09411cb0bc9a8c2adc40f9a048afe863e05fd43251e8e39c"
dependencies = [
"cfg-if",
"num_cpus",
]
[[package]] [[package]]
name = "dashmap" name = "dashmap"
version = "5.3.4" version = "5.3.4"
@ -470,9 +460,9 @@ dependencies = [
[[package]] [[package]]
name = "env_logger" name = "env_logger"
version = "0.8.4" version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a19187fea3ac7e84da7dacf48de0c45d63c6a76f9490dae389aead16c243fce3" checksum = "0b2cf0344971ee6c64c31be0d530793fba457d322dfec2810c453d0ef228f9c3"
dependencies = [ dependencies = [
"atty", "atty",
"humantime", "humantime",
@ -483,9 +473,9 @@ dependencies = [
[[package]] [[package]]
name = "fastrand" name = "fastrand"
version = "1.7.0" version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf" checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499"
dependencies = [ dependencies = [
"instant", "instant",
] ]
@ -502,9 +492,9 @@ dependencies = [
[[package]] [[package]]
name = "flume" name = "flume"
version = "0.10.13" version = "0.10.14"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ceeb589a3157cac0ab8cc585feb749bd2cea5cb55a6ee802ad72d9fd38303da" checksum = "1657b4441c3403d9f7b3409e47575237dac27b1b5726df654a6ecbf92f0f7577"
dependencies = [ dependencies = [
"futures-core", "futures-core",
"futures-sink", "futures-sink",
@ -896,9 +886,9 @@ checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d"
[[package]] [[package]]
name = "js-sys" name = "js-sys"
version = "0.3.58" version = "0.3.59"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3fac17f7123a73ca62df411b1bf727ccc805daa070338fda671c86dac1bdc27" checksum = "258451ab10b34f8af53416d1fdab72c22e805f0c92a1136d59470ec0b11138b2"
dependencies = [ dependencies = [
"wasm-bindgen", "wasm-bindgen",
] ]
@ -920,9 +910,9 @@ checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836"
[[package]] [[package]]
name = "libm" name = "libm"
version = "0.2.2" version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "33a33a362ce288760ec6a508b94caaec573ae7d3bbbd91b87aa0bad4456839db" checksum = "da83a57f3f5ba3680950aa3cbc806fc297bc0b289d42e8942ed528ace71b8145"
[[package]] [[package]]
name = "lock_api" name = "lock_api"
@ -1420,9 +1410,9 @@ checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872"
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.40" version = "1.0.42"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd96a1e8ed2596c337f8eae5f24924ec83f5ad5ab21ea8e455d3566c69fbcaf7" checksum = "c278e965f1d8cf32d6e0e96de3d3e79712178ae67986d9cf9151f51e95aac89b"
dependencies = [ dependencies = [
"unicode-ident", "unicode-ident",
] ]
@ -1468,9 +1458,9 @@ dependencies = [
[[package]] [[package]]
name = "redox_syscall" name = "redox_syscall"
version = "0.2.13" version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42" checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
dependencies = [ dependencies = [
"bitflags", "bitflags",
] ]
@ -1712,9 +1702,9 @@ dependencies = [
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.139" version = "1.0.140"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0171ebb889e45aa68b44aee0859b3eede84c6f5f5c228e6f140c0b2a0a46cad6" checksum = "fc855a42c7967b7c369eb5860f7164ef1f6f81c20c7cc1141f2a604e18723b03"
dependencies = [ dependencies = [
"serde_derive", "serde_derive",
] ]
@ -1731,9 +1721,9 @@ dependencies = [
[[package]] [[package]]
name = "serde_derive" name = "serde_derive"
version = "1.0.139" version = "1.0.140"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc1d3230c1de7932af58ad8ffbe1d784bd55efd5a9d84ac24f69c72d83543dfb" checksum = "6f2122636b9fe3b81f1cb25099fcf2d3f542cdb1d45940d56c713158884a05da"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -1776,9 +1766,9 @@ dependencies = [
[[package]] [[package]]
name = "serenity" name = "serenity"
version = "0.11.4" version = "0.11.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d1a6cef5e72d4e5787c96413ec0a45f9317c59f0099e2ff2038b73cb352fefd" checksum = "82fd5e7b5858ad96e99d440138f34f5b98e1b959ebcd3a1036203b30e78eb788"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"async-tungstenite", "async-tungstenite",
@ -1787,7 +1777,7 @@ dependencies = [
"bytes", "bytes",
"cfg-if", "cfg-if",
"chrono", "chrono",
"dashmap 5.3.4", "dashmap",
"flate2", "flate2",
"futures", "futures",
"mime", "mime",
@ -1809,7 +1799,8 @@ dependencies = [
[[package]] [[package]]
name = "serenity-voice-model" name = "serenity-voice-model"
version = "0.1.1" version = "0.1.1"
source = "git+https://github.com/serenity-rs/serenity?branch=next#b6d6ce0de112112bbbe4ecdc49c8c8f521bedef1" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8be3aec8849ca2fde1e8a5dfbed96fbd68e9b5f4283fbe277d8694ce811d4952"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"enum_primitive", "enum_primitive",
@ -1900,14 +1891,15 @@ dependencies = [
[[package]] [[package]]
name = "songbird" name = "songbird"
version = "0.2.2" version = "0.3.0"
source = "git+https://github.com/serenity-rs/songbird?branch=next#49c33461029f5c3a22e12e3d251319237d73b4a4" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4c965f6625a2653e0733abfe217679562eb8c4787f000f4f13047541a444217"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"async-tungstenite", "async-tungstenite",
"audiopus", "audiopus",
"byteorder", "byteorder",
"dashmap 5.3.4", "dashmap",
"derivative", "derivative",
"discortp", "discortp",
"flume", "flume",
@ -1932,9 +1924,9 @@ dependencies = [
[[package]] [[package]]
name = "soundfx-rs" name = "soundfx-rs"
version = "1.5.0" version = "1.5.1"
dependencies = [ dependencies = [
"dashmap 4.0.2", "dashmap",
"dotenv", "dotenv",
"env_logger", "env_logger",
"lazy_static", "lazy_static",
@ -2219,9 +2211,9 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
[[package]] [[package]]
name = "tokio" name = "tokio"
version = "1.20.0" version = "1.20.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57aec3cfa4c296db7255446efb4928a6be304b431a806216105542a67b6ca82e" checksum = "7a8325f63a7d4774dd041e363b2409ed1c5cbbd0f867795e661df066b2b0a581"
dependencies = [ dependencies = [
"autocfg 1.1.0", "autocfg 1.1.0",
"bytes", "bytes",
@ -2313,9 +2305,9 @@ checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52"
[[package]] [[package]]
name = "tracing" name = "tracing"
version = "0.1.35" version = "0.1.36"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a400e31aa60b9d44a52a8ee0343b5b18566b03a8321e0d321f695cf56e940160" checksum = "2fce9567bd60a67d08a16488756721ba392f24f29006402881e43b19aac64307"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"log", "log",
@ -2337,9 +2329,9 @@ dependencies = [
[[package]] [[package]]
name = "tracing-core" name = "tracing-core"
version = "0.1.28" version = "0.1.29"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b7358be39f2f274f322d2aaed611acc57f382e8eb1e5b48cb9ae30933495ce7" checksum = "5aeea4303076558a00714b823f9ad67d58a3bbda1df83d8827d21193156e22f7"
dependencies = [ dependencies = [
"once_cell", "once_cell",
"valuable", "valuable",
@ -2368,9 +2360,9 @@ dependencies = [
[[package]] [[package]]
name = "tracing-subscriber" name = "tracing-subscriber"
version = "0.3.14" version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3a713421342a5a666b7577783721d3117f1b69a393df803ee17bb73b1e122a59" checksum = "60db860322da191b40952ad9affe65ea23e7dd6a5c442c2c42865810c6ab8e6b"
dependencies = [ dependencies = [
"ansi_term", "ansi_term",
"matchers", "matchers",
@ -2551,9 +2543,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]] [[package]]
name = "wasm-bindgen" name = "wasm-bindgen"
version = "0.2.81" version = "0.2.82"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7c53b543413a17a202f4be280a7e5c62a1c69345f5de525ee64f8cfdbc954994" checksum = "fc7652e3f6c4706c8d9cd54832c4a4ccb9b5336e2c3bd154d5cccfbf1c1f5f7d"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"wasm-bindgen-macro", "wasm-bindgen-macro",
@ -2561,13 +2553,13 @@ dependencies = [
[[package]] [[package]]
name = "wasm-bindgen-backend" name = "wasm-bindgen-backend"
version = "0.2.81" version = "0.2.82"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5491a68ab4500fa6b4d726bd67408630c3dbe9c4fe7bda16d5c82a1fd8c7340a" checksum = "662cd44805586bd52971b9586b1df85cdbbd9112e4ef4d8f41559c334dc6ac3f"
dependencies = [ dependencies = [
"bumpalo", "bumpalo",
"lazy_static",
"log", "log",
"once_cell",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn", "syn",
@ -2576,9 +2568,9 @@ dependencies = [
[[package]] [[package]]
name = "wasm-bindgen-futures" name = "wasm-bindgen-futures"
version = "0.4.31" version = "0.4.32"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de9a9cec1733468a8c657e57fa2413d2ae2c0129b95e87c5b72b8ace4d13f31f" checksum = "fa76fb221a1f8acddf5b54ace85912606980ad661ac7a503b4570ffd3a624dad"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"js-sys", "js-sys",
@ -2588,9 +2580,9 @@ dependencies = [
[[package]] [[package]]
name = "wasm-bindgen-macro" name = "wasm-bindgen-macro"
version = "0.2.81" version = "0.2.82"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c441e177922bc58f1e12c022624b6216378e5febc2f0533e41ba443d505b80aa" checksum = "b260f13d3012071dfb1512849c033b1925038373aea48ced3012c09df952c602"
dependencies = [ dependencies = [
"quote", "quote",
"wasm-bindgen-macro-support", "wasm-bindgen-macro-support",
@ -2598,9 +2590,9 @@ dependencies = [
[[package]] [[package]]
name = "wasm-bindgen-macro-support" name = "wasm-bindgen-macro-support"
version = "0.2.81" version = "0.2.82"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d94ac45fcf608c1f45ef53e748d35660f168490c10b23704c7779ab8f5c3048" checksum = "5be8e654bdd9b79216c2929ab90721aa82faf65c48cdf08bdc4e7f51357b80da"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -2611,15 +2603,15 @@ dependencies = [
[[package]] [[package]]
name = "wasm-bindgen-shared" name = "wasm-bindgen-shared"
version = "0.2.81" version = "0.2.82"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a89911bd99e5f3659ec4acf9c4d93b0a90fe4a2a11f15328472058edc5261be" checksum = "6598dd0bd3c7d51095ff6531a5b23e02acdc81804e30d8f07afb77b7215a140a"
[[package]] [[package]]
name = "web-sys" name = "web-sys"
version = "0.3.58" version = "0.3.59"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2fed94beee57daf8dd7d51f2b15dc2bcde92d7a72304cdf662a4371008b71b90" checksum = "ed055ab27f941423197eb86b2035720b1a3ce40504df082cac2ecc6ed73335a1"
dependencies = [ dependencies = [
"js-sys", "js-sys",
"wasm-bindgen", "wasm-bindgen",

View File

@ -1,22 +1,22 @@
[package] [package]
name = "soundfx-rs" name = "soundfx-rs"
version = "1.5.0" version = "1.5.1"
authors = ["jellywx <judesouthworth@pm.me>"] authors = ["jellywx <judesouthworth@pm.me>"]
edition = "2018" edition = "2018"
[dependencies] [dependencies]
songbird = { git = "https://github.com/serenity-rs/songbird", branch = "next", features = ["builtin-queue"] } songbird = { version = "0.3", features = ["builtin-queue"] }
poise = "0.2" poise = "0.2"
sqlx = { version = "0.5", default-features = false, features = ["runtime-tokio-rustls", "macros", "mysql", "bigdecimal"] } sqlx = { version = "0.5", default-features = false, features = ["runtime-tokio-rustls", "macros", "mysql", "bigdecimal"] }
dotenv = "0.15" dotenv = "0.15"
tokio = { version = "1", features = ["fs", "process", "io-util"] } tokio = { version = "1", features = ["fs", "process", "io-util"] }
lazy_static = "1.4" lazy_static = "1.4"
reqwest = "0.11" reqwest = "0.11"
env_logger = "0.8" env_logger = "0.9"
regex = "1.4" regex = "1.4"
log = "0.4" log = "0.4"
serde_json = "1.0" serde_json = "1.0"
dashmap = "4.0" dashmap = "5.3"
[patch."https://github.com/serenity-rs/serenity"] [patch."https://github.com/serenity-rs/serenity"]
serenity = { version = "0.11.4" } serenity = { version = "0.11.5" }

View File

@ -4,7 +4,7 @@ A bot for managing sound effects in Discord.
### Building ### Building
`sudo apt install gcc gcc-multilib cmake` `sudo apt install gcc gcc-multilib cmake ffmpeg`
Run the migrations in the `migrations` directory to set up the database. Run the migrations in the `migrations` directory to set up the database.

View File

@ -0,0 +1,10 @@
CREATE TABLE join_sounds (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`user` BIGINT UNSIGNED NOT NULL,
`join_sound_id` INT UNSIGNED NOT NULL,
`guild` BIGINT UNSIGNED,
FOREIGN KEY (`join_sound_id`) REFERENCES sounds(id) ON DELETE CASCADE,
PRIMARY KEY (`id`)
);
INSERT INTO join_sounds (`user`, `join_sound_id`) SELECT `user`, `join_sound_id` FROM `users` WHERE `join_sound_id` is not null;

View File

@ -1,4 +1,7 @@
use poise::serenity_prelude::{GuildId, User};
use crate::{ use crate::{
cmds::autocomplete_sound,
models::{guild_data::CtxGuildData, join_sound::JoinSoundCtx, sound::SoundCtx}, models::{guild_data::CtxGuildData, join_sound::JoinSoundCtx, sound::SoundCtx},
Context, Error, Context, Error,
}; };
@ -31,18 +34,44 @@ pub async fn change_volume(
Ok(()) Ok(())
} }
/// Manage greet sounds on this server /// Manage greet sounds
#[poise::command(slash_command, rename = "greet", guild_only = true)] #[poise::command(slash_command, rename = "greet", guild_only = true)]
pub async fn greet_sound(_ctx: Context<'_>) -> Result<(), Error> { pub async fn greet_sound(_ctx: Context<'_>) -> Result<(), Error> {
Ok(()) Ok(())
} }
/// Set a join sound /// Manage greet sounds in this server
#[poise::command(slash_command, rename = "server")]
pub async fn guild_greet_sound(_ctx: Context<'_>) -> Result<(), Error> {
Ok(())
}
/// Set a user's guild-specific join sound
#[poise::command(slash_command, rename = "set")] #[poise::command(slash_command, rename = "set")]
pub async fn set_greet_sound( pub async fn set_guild_greet_sound(
ctx: Context<'_>, ctx: Context<'_>,
#[description = "Name or ID of sound to set as your join sound"] name: String, #[description = "Name or ID of sound to set as join sound"]
#[autocomplete = "autocomplete_sound"]
name: String,
#[description = "User to set join sound for"] user: User,
) -> Result<(), Error> { ) -> Result<(), Error> {
if user.id != ctx.author().id {
let guild = ctx.guild().unwrap();
let permissions = guild
.member_permissions(&ctx.discord(), ctx.author().id)
.await;
if permissions.map_or(true, |p| !p.manage_guild()) {
ctx.send(|b| {
b.ephemeral(true)
.content("Only admins can change other user's greet sounds.")
})
.await?;
return Ok(());
}
}
let sound_vec = ctx let sound_vec = ctx
.data() .data()
.search_for_sound(&name, ctx.guild_id().unwrap(), ctx.author().id, true) .search_for_sound(&name, ctx.guild_id().unwrap(), ctx.author().id, true)
@ -51,7 +80,7 @@ pub async fn set_greet_sound(
match sound_vec.first() { match sound_vec.first() {
Some(sound) => { Some(sound) => {
ctx.data() ctx.data()
.update_join_sound(ctx.author().id, Some(sound.id)) .update_join_sound(user.id, ctx.guild_id(), Some(sound.id))
.await; .await;
ctx.say(format!( ctx.say(format!(
@ -69,18 +98,104 @@ pub async fn set_greet_sound(
Ok(()) Ok(())
} }
/// Set a join sound /// Unset your global join sound
#[poise::command(slash_command, rename = "unset", guild_only = true)] #[poise::command(slash_command, rename = "unset", guild_only = true)]
pub async fn unset_greet_sound(ctx: Context<'_>) -> Result<(), Error> { pub async fn unset_guild_greet_sound(
ctx.data().update_join_sound(ctx.author().id, None).await; ctx: Context<'_>,
#[description = "User to set join sound for"] user: User,
) -> Result<(), Error> {
if user.id != ctx.author().id {
let guild = ctx.guild().unwrap();
let permissions = guild
.member_permissions(&ctx.discord(), ctx.author().id)
.await;
if permissions.map_or(true, |p| !p.manage_guild()) {
ctx.send(|b| {
b.ephemeral(true)
.content("Only admins can change other user's greet sounds.")
})
.await?;
return Ok(());
}
}
ctx.data()
.update_join_sound(user.id, ctx.guild_id(), None)
.await;
ctx.say("Greet sound has been unset").await?; ctx.say("Greet sound has been unset").await?;
Ok(()) Ok(())
} }
/// Manage your own greet sound
#[poise::command(slash_command, rename = "user")]
pub async fn user_greet_sound(_ctx: Context<'_>) -> Result<(), Error> {
Ok(())
}
/// Set your global join sound
#[poise::command(slash_command, rename = "set")]
pub async fn set_user_greet_sound(
ctx: Context<'_>,
#[description = "Name or ID of sound to set as your join sound"]
#[autocomplete = "autocomplete_sound"]
name: String,
) -> Result<(), Error> {
let sound_vec = ctx
.data()
.search_for_sound(&name, ctx.guild_id().unwrap(), ctx.author().id, true)
.await?;
match sound_vec.first() {
Some(sound) => {
ctx.data()
.update_join_sound(ctx.author().id, None::<GuildId>, Some(sound.id))
.await;
ctx.send(|b| {
b.ephemeral(true).content(format!(
"Greet sound has been set to {} (ID {})",
sound.name, sound.id
))
})
.await?;
}
None => {
ctx.send(|b| {
b.ephemeral(true)
.content("Could not find a sound by that name.")
})
.await?;
}
}
Ok(())
}
/// Unset your global join sound
#[poise::command(slash_command, rename = "unset", guild_only = true)]
pub async fn unset_user_greet_sound(ctx: Context<'_>) -> Result<(), Error> {
ctx.data()
.update_join_sound(ctx.author().id, None::<GuildId>, None)
.await;
ctx.send(|b| b.ephemeral(true).content("Greet sound has been unset"))
.await?;
Ok(())
}
/// Disable greet sounds on this server /// Disable greet sounds on this server
#[poise::command(slash_command, rename = "disable", guild_only = true)] #[poise::command(
slash_command,
rename = "disable",
guild_only = true,
required_permissions = "MANAGE_GUILD"
)]
pub async fn disable_greet_sound(ctx: Context<'_>) -> Result<(), Error> { pub async fn disable_greet_sound(ctx: Context<'_>) -> Result<(), Error> {
let guild_data_opt = ctx.guild_data(ctx.guild_id().unwrap()).await; let guild_data_opt = ctx.guild_data(ctx.guild_id().unwrap()).await;
@ -97,7 +212,12 @@ pub async fn disable_greet_sound(ctx: Context<'_>) -> Result<(), Error> {
} }
/// Enable greet sounds on this server /// Enable greet sounds on this server
#[poise::command(slash_command, rename = "enable", guild_only = true)] #[poise::command(
slash_command,
rename = "enable",
guild_only = true,
required_permissions = "MANAGE_GUILD"
)]
pub async fn enable_greet_sound(ctx: Context<'_>) -> Result<(), Error> { pub async fn enable_greet_sound(ctx: Context<'_>) -> Result<(), Error> {
let guild_data_opt = ctx.guild_data(ctx.guild_id().unwrap()).await; let guild_data_opt = ctx.guild_data(ctx.guild_id().unwrap()).await;

View File

@ -92,7 +92,8 @@ pub async fn listener(ctx: &Context, event: &poise::Event<'_>, data: &Data) -> R
} }
if allowed_greets { if allowed_greets {
if let Some(join_id) = data.join_sound(new.user_id).await { if let Some(join_id) = data.join_sound(new.user_id, new.guild_id).await
{
let mut sound = sqlx::query_as_unchecked!( let mut sound = sqlx::query_as_unchecked!(
Sound, Sound,
" "

View File

@ -25,14 +25,13 @@ use tokio::sync::RwLock;
use crate::{event_handlers::listener, models::guild_data::GuildData}; use crate::{event_handlers::listener, models::guild_data::GuildData};
// Which database driver are we using?
type Database = MySql; type Database = MySql;
pub struct Data { pub struct Data {
database: Pool<Database>, database: Pool<Database>,
http: reqwest::Client, http: reqwest::Client,
guild_data_cache: DashMap<GuildId, Arc<RwLock<GuildData>>>, guild_data_cache: DashMap<GuildId, Arc<RwLock<GuildData>>>,
join_sound_cache: DashMap<UserId, Option<u32>>, join_sound_cache: DashMap<UserId, DashMap<Option<GuildId>, Option<u32>>>,
} }
type Error = Box<dyn std::error::Error + Send + Sync>; type Error = Box<dyn std::error::Error + Send + Sync>;
@ -103,10 +102,22 @@ async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
cmds::settings::change_volume(), cmds::settings::change_volume(),
poise::Command { poise::Command {
subcommands: vec![ subcommands: vec![
poise::Command {
subcommands: vec![
cmds::settings::set_guild_greet_sound(),
cmds::settings::unset_guild_greet_sound(),
],
..cmds::settings::guild_greet_sound()
},
poise::Command {
subcommands: vec![
cmds::settings::set_user_greet_sound(),
cmds::settings::unset_user_greet_sound(),
],
..cmds::settings::user_greet_sound()
},
cmds::settings::disable_greet_sound(), cmds::settings::disable_greet_sound(),
cmds::settings::enable_greet_sound(), cmds::settings::enable_greet_sound(),
cmds::settings::set_greet_sound(),
cmds::settings::unset_greet_sound(),
], ],
..cmds::settings::greet_sound() ..cmds::settings::greet_sound()
}, },

View File

@ -1,45 +1,69 @@
use poise::serenity::{async_trait, model::id::UserId}; use poise::{
serenity::{async_trait, model::id::UserId},
serenity_prelude::GuildId,
};
use crate::Data; use crate::Data;
#[async_trait] #[async_trait]
pub trait JoinSoundCtx { pub trait JoinSoundCtx {
async fn join_sound<U: Into<UserId> + Send + Sync>(&self, user_id: U) -> Option<u32>; async fn join_sound<U: Into<UserId> + Send + Sync, G: Into<GuildId> + Send + Sync>(
async fn update_join_sound<U: Into<UserId> + Send + Sync>(
&self, &self,
user_id: U, user_id: U,
guild_id: Option<G>,
) -> Option<u32>;
async fn update_join_sound<U: Into<UserId> + Send + Sync, G: Into<GuildId> + Send + Sync>(
&self,
user_id: U,
guild_id: Option<G>,
join_id: Option<u32>, join_id: Option<u32>,
); ) -> Result<(), sqlx::Error>;
} }
#[async_trait] #[async_trait]
impl JoinSoundCtx for Data { impl JoinSoundCtx for Data {
async fn join_sound<U: Into<UserId> + Send + Sync>(&self, user_id: U) -> Option<u32> { async fn join_sound<U: Into<UserId> + Send + Sync, G: Into<GuildId> + Send + Sync>(
&self,
user_id: U,
guild_id: Option<G>,
) -> Option<u32> {
let user_id = user_id.into(); let user_id = user_id.into();
let guild_id = guild_id.map(|g| g.into());
let x = if let Some(join_sound_id) = self.join_sound_cache.get(&user_id) { let cached_join_id = self
join_sound_id.value().clone() .join_sound_cache
.get(&user_id)
.map(|d| d.get(&guild_id).map(|i| i.value().clone()))
.flatten();
let x = if let Some(join_sound_id) = cached_join_id {
join_sound_id
} else { } else {
let join_sound_id = { let join_sound_id = {
let join_id_res = sqlx::query!( let join_id_res = sqlx::query!(
" "
SELECT join_sound_id SELECT join_sound_id
FROM users FROM join_sounds
WHERE user = ? WHERE user = ?
AND (guild IS NULL OR guild = ?)
ORDER BY guild IS NULL
", ",
user_id.as_u64() user_id.as_u64(),
guild_id.map(|g| g.0)
) )
.fetch_one(&self.database) .fetch_one(&self.database)
.await; .await;
if let Ok(row) = join_id_res { if let Ok(row) = join_id_res {
row.join_sound_id Some(row.join_sound_id)
} else { } else {
None None
} }
}; };
self.join_sound_cache.insert(user_id, join_sound_id); self.join_sound_cache.entry(user_id).and_modify(|d| {
d.insert(guild_id, join_sound_id);
});
join_sound_id join_sound_id
}; };
@ -47,39 +71,54 @@ SELECT join_sound_id
x x
} }
async fn update_join_sound<U: Into<UserId> + Send + Sync>( async fn update_join_sound<U: Into<UserId> + Send + Sync, G: Into<GuildId> + Send + Sync>(
&self, &self,
user_id: U, user_id: U,
guild_id: Option<G>,
join_id: Option<u32>, join_id: Option<u32>,
) { ) -> Result<(), sqlx::Error> {
let user_id = user_id.into(); let user_id = user_id.into();
let guild_id = guild_id.map(|g| g.into());
self.join_sound_cache.insert(user_id, join_id); self.join_sound_cache.entry(user_id).and_modify(|d| {
d.insert(guild_id, join_id);
});
let pool = self.database.clone(); let mut transaction = self.database.begin().await?;
let _ = sqlx::query!( match join_id {
" Some(join_id) => {
INSERT IGNORE INTO users (user) sqlx::query!(
VALUES (?) "DELETE FROM join_sounds WHERE user = ? AND guild <=> ?",
", user_id.0,
user_id.as_u64() guild_id.map(|g| g.0)
) )
.execute(&pool) .execute(&mut transaction)
.await; .await?;
let _ = sqlx::query!( sqlx::query!(
" "INSERT INTO join_sounds (user, join_sound_id, guild) VALUES (?, ?, ?)",
UPDATE users user_id.0,
SET join_id,
join_sound_id = ? guild_id.map(|g| g.0)
WHERE )
user = ? .execute(&mut transaction)
", .await?;
join_id, }
user_id.as_u64()
) None => {
.execute(&pool) sqlx::query!(
.await; "DELETE FROM join_sounds WHERE user = ? AND guild <=> ?",
user_id.0,
guild_id.map(|g| g.0)
)
.execute(&mut transaction)
.await?;
}
}
transaction.commit().await?;
Ok(())
} }
} }