Working on music
This commit is contained in:
parent
5ac371acb1
commit
b9b631c892
|
@ -24,4 +24,4 @@ serde_json = "1.0"
|
|||
log = "0.4"
|
||||
log4rs = "1.0"
|
||||
ctrlc = "3.1"
|
||||
songbird = { version = "0.1.0", features = ["driver"], optional = true }
|
||||
songbird = { version = "0.1.4", features = ["driver", "builtin-queue"], optional = true }
|
|
@ -1,4 +1,3 @@
|
|||
use crate::commands::Result;
|
||||
use serenity::{framework::standard::CommandResult, model::channel::Message, prelude::Context};
|
||||
|
||||
/// Send a reply to the channel the message was received on.
|
||||
|
|
|
@ -4,9 +4,9 @@ use serenity::{
|
|||
macros::{command, group},
|
||||
CommandResult,
|
||||
},
|
||||
http::CacheHttp,
|
||||
model::prelude::*,
|
||||
prelude::*,
|
||||
http::CacheHttp,
|
||||
};
|
||||
|
||||
use crate::data::GuildOptionsKey;
|
||||
|
@ -120,14 +120,16 @@ async fn ghost_pings(ctx: &Context, msg: &Message) -> CommandResult {
|
|||
.map(|u| u.name)
|
||||
.unwrap_or_else(|_| String::from("Unkown"));
|
||||
|
||||
message += &format!("{} : {:?}\n", sender, ping.roles.iter().map(|r| format!("<!@{}>", r)))
|
||||
message += &format!(
|
||||
"{} : {:?}\n",
|
||||
sender,
|
||||
ping.roles.iter().map(|r| format!("<!@{}>", r))
|
||||
)
|
||||
}
|
||||
message += "\x60\x60\x60";
|
||||
|
||||
crate::api::send_reply(ctx, msg, message).await?;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
use crate::{api, data::ShardManagerContainer};
|
||||
use futures::StreamExt;
|
||||
use log::error;
|
||||
use rand::prelude::IteratorRandom;
|
||||
use serenity::{
|
||||
client::bridge::gateway::ShardId,
|
||||
framework::standard::{
|
||||
|
@ -306,7 +305,15 @@ async fn random_mute(ctx: &Context, msg: &Message) -> CommandResult {
|
|||
|
||||
members[m].add_role(&ctx.http, role).await?;
|
||||
|
||||
api::send_reply(ctx, msg, format!("{} was choosen by the roulette of the mute !", members[m].mention())).await?;
|
||||
api::send_reply(
|
||||
ctx,
|
||||
msg,
|
||||
format!(
|
||||
"{} was choosen by the roulette of the mute !",
|
||||
members[m].mention()
|
||||
),
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -1,20 +1,136 @@
|
|||
use std::sync::Arc;
|
||||
|
||||
use tokio::sync::Mutex as TokioMutex;
|
||||
|
||||
use crate::data::{GuildOptions, GuildOptionsKey};
|
||||
use log::{error, info};
|
||||
use log::error;
|
||||
use serenity::{
|
||||
client::{Context},
|
||||
builder::CreateMessage,
|
||||
client::Context,
|
||||
framework::standard::{
|
||||
macros::{command, group},
|
||||
Args, CommandResult,
|
||||
},
|
||||
model::{channel::Message, guild::PartialMember, id::GuildId, misc::Mentionable},
|
||||
prelude::*,
|
||||
Result as SerenityResult,
|
||||
http::Http,
|
||||
model::{
|
||||
channel::Message,
|
||||
guild::PartialMember,
|
||||
id::{ChannelId, GuildId},
|
||||
misc::Mentionable,
|
||||
},
|
||||
};
|
||||
use std::sync::Arc;
|
||||
use songbird::{input::Metadata, Call, Event, EventContext, TrackEvent};
|
||||
|
||||
struct TrackStartNotifier {
|
||||
chan_id: ChannelId,
|
||||
http: Arc<Http>,
|
||||
handler_lock: Arc<TokioMutex<Call>>,
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl songbird::EventHandler for TrackStartNotifier {
|
||||
async fn act(&self, ctx: &EventContext<'_>) -> Option<Event> {
|
||||
if let EventContext::Track(_track_list) = ctx {
|
||||
let handler = self.handler_lock.lock().await;
|
||||
if let Some(np) = handler.queue().current() {
|
||||
let metadata = np.metadata();
|
||||
if let Err(why) = self
|
||||
.chan_id
|
||||
.send_message(&self.http, |m| {
|
||||
embed_song(m, metadata);
|
||||
m
|
||||
})
|
||||
.await
|
||||
{
|
||||
error!("Error sending message: {:?}", why);
|
||||
}
|
||||
} else {
|
||||
if let Err(why) = self.chan_id.say(&self.http, "Queue finished").await {
|
||||
error!("Error sending message: {:?}", why);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn embed_song(msg: &mut CreateMessage, metadata: &Metadata) {
|
||||
msg.embed(|e| {
|
||||
e.title("Now playing");
|
||||
|
||||
if let Some(title) = &metadata.title {
|
||||
e.field("title", title, true);
|
||||
}
|
||||
|
||||
if let Some(url) = &metadata.source_url {
|
||||
e.url(url);
|
||||
}
|
||||
|
||||
if let Some(duration) = &metadata.duration {
|
||||
let seconds = duration.as_secs();
|
||||
|
||||
let hours = seconds / (60 * 60);
|
||||
let min = (seconds - (hours * 60 * 60)) / 60;
|
||||
let seconds = seconds - (min * 60);
|
||||
|
||||
e.field(
|
||||
"duration",
|
||||
if hours > 0 {
|
||||
format!("{}:{:02}:{:02}", hours, min, seconds)
|
||||
} else {
|
||||
format!("{}:{:02}", min, seconds)
|
||||
},
|
||||
false,
|
||||
);
|
||||
}
|
||||
|
||||
if let Some(img) = &metadata.thumbnail {
|
||||
e.image(img);
|
||||
}
|
||||
e
|
||||
});
|
||||
}
|
||||
|
||||
fn embed_queued(msg: &mut CreateMessage, metadata: &Metadata) {
|
||||
msg.embed(|e| {
|
||||
e.title("Queued");
|
||||
|
||||
if let Some(title) = &metadata.title {
|
||||
e.field("title", title, true);
|
||||
}
|
||||
|
||||
if let Some(url) = &metadata.source_url {
|
||||
e.url(url);
|
||||
}
|
||||
|
||||
if let Some(duration) = &metadata.duration {
|
||||
let seconds = duration.as_secs();
|
||||
|
||||
let hours = seconds / (60 * 60);
|
||||
let min = (seconds - (hours * 60 * 60)) / 60;
|
||||
let seconds = seconds - (min * 60);
|
||||
|
||||
e.field(
|
||||
"duration",
|
||||
if hours > 0 {
|
||||
format!("{}:{:02}:{:02}", hours, min, seconds)
|
||||
} else {
|
||||
format!("{}:{:02}", min, seconds)
|
||||
},
|
||||
false,
|
||||
);
|
||||
}
|
||||
|
||||
if let Some(img) = &metadata.thumbnail {
|
||||
e.image(img);
|
||||
}
|
||||
e
|
||||
});
|
||||
}
|
||||
|
||||
#[group]
|
||||
#[commands(join, leave, play, stop)]
|
||||
#[commands(join, leave, play, stop, next)]
|
||||
struct Music;
|
||||
|
||||
#[command]
|
||||
|
@ -23,7 +139,7 @@ async fn join(ctx: &Context, msg: &Message) -> CommandResult {
|
|||
let guild = match msg.guild(&ctx.cache).await {
|
||||
Some(guild) => guild,
|
||||
None => {
|
||||
msg.channel_id.say(&ctx.http, "DMs not supported").await;
|
||||
msg.channel_id.say(&ctx.http, "DMs not supported").await?;
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
|
@ -34,9 +150,9 @@ async fn join(ctx: &Context, msg: &Message) -> CommandResult {
|
|||
} else {
|
||||
false
|
||||
} {
|
||||
msg.channel_id
|
||||
.say(&ctx.http, "Error, you cant play music")
|
||||
.await;
|
||||
msg.channel_id
|
||||
.say(&ctx.http, "Error, you cant play music")
|
||||
.await?;
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
|
@ -50,25 +166,47 @@ async fn join(ctx: &Context, msg: &Message) -> CommandResult {
|
|||
let connect_to = match channel_id {
|
||||
Some(channel) => channel,
|
||||
None => {
|
||||
msg.reply(ctx, "Not in a voice channel").await;
|
||||
msg.reply(ctx, "Not in a voice channel").await?;
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
};
|
||||
|
||||
let manager = songbird::get(ctx).await
|
||||
.expect("Songbird Voice client placed in at initialisation.").clone();
|
||||
let manager = songbird::get(ctx)
|
||||
.await
|
||||
.expect("Songbird Voice client placed in at initialisation.")
|
||||
.clone();
|
||||
|
||||
if manager.join(guild_id, connect_to).await.1.is_ok() {
|
||||
|
||||
// TODO ADMIN PERMISSION
|
||||
if manager.get(guild_id).is_none() {
|
||||
let (handler_lock, success) = manager.join(guild_id, connect_to).await;
|
||||
|
||||
if success.is_ok() {
|
||||
let mut handler = handler_lock.lock().await;
|
||||
handler.add_global_event(
|
||||
Event::Track(TrackEvent::Play),
|
||||
TrackStartNotifier {
|
||||
chan_id: msg.channel_id,
|
||||
http: ctx.http.clone(),
|
||||
handler_lock: handler_lock.clone(),
|
||||
},
|
||||
);
|
||||
msg.channel_id
|
||||
.say(&ctx.http, &format!("Joined {}", connect_to.mention()))
|
||||
.await;
|
||||
} else {
|
||||
|
||||
.say(
|
||||
&ctx.http,
|
||||
&format!("Joined channel {}", connect_to.mention()),
|
||||
)
|
||||
.await?;
|
||||
} else {
|
||||
msg.channel_id
|
||||
.say(&ctx.http, "Error joining the channel")
|
||||
.await;
|
||||
.await?;
|
||||
}
|
||||
} else {
|
||||
// TODO WARN
|
||||
msg.channel_id
|
||||
.say(&ctx.http, "Error : Already connected on another channel")
|
||||
.await?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -84,7 +222,7 @@ async fn leave(ctx: &Context, msg: &Message) -> CommandResult {
|
|||
{
|
||||
Some(id) => id,
|
||||
None => {
|
||||
msg.channel_id.say(&ctx.http, "DMs not supported").await;
|
||||
msg.channel_id.say(&ctx.http, "DMs not supported").await?;
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
|
@ -95,26 +233,28 @@ async fn leave(ctx: &Context, msg: &Message) -> CommandResult {
|
|||
} else {
|
||||
false
|
||||
} {
|
||||
msg.channel_id
|
||||
.say(&ctx.http, "Error, you cant play music")
|
||||
.await;
|
||||
msg.channel_id
|
||||
.say(&ctx.http, "Error, you cant play music")
|
||||
.await?;
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let manager = songbird::get(ctx).await
|
||||
.expect("Songbird Voice client placed in at initialisation.").clone();
|
||||
let manager = songbird::get(ctx)
|
||||
.await
|
||||
.expect("Songbird Voice client placed in at initialisation.")
|
||||
.clone();
|
||||
|
||||
let has_handler = manager.get(guild_id).is_some();
|
||||
|
||||
if has_handler {
|
||||
if let Err(e) = manager.remove(guild_id).await {
|
||||
msg.channel_id.say(&ctx.http, format!("Failed: {:?}", e)).await;
|
||||
}
|
||||
|
||||
msg.channel_id.say(&ctx.http, "Left voice channel").await;
|
||||
} else {
|
||||
msg.reply(ctx, "Not in a voice channel").await;
|
||||
if let Some(_handler) = manager.get(guild_id) {
|
||||
if let Err(e) = manager.remove(guild_id).await {
|
||||
msg.channel_id
|
||||
.say(&ctx.http, format!("Failed: {:?}", e))
|
||||
.await?;
|
||||
}
|
||||
|
||||
msg.channel_id.say(&ctx.http, "Left voice channel").await?;
|
||||
} else {
|
||||
msg.reply(ctx, "Not in a voice channel").await?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -124,31 +264,20 @@ async fn play(ctx: &Context, msg: &Message, mut args: Args) -> CommandResult {
|
|||
let url = match args.single::<String>() {
|
||||
Ok(url) => url,
|
||||
Err(_) => {
|
||||
|
||||
msg.channel_id
|
||||
.say(&ctx.http, "Must provide a URL to a video or audio")
|
||||
.await;
|
||||
msg.channel_id
|
||||
.say(&ctx.http, "Must provide a URL to a video or audio")
|
||||
.await?;
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
};
|
||||
|
||||
if !url.starts_with("http") {
|
||||
|
||||
msg.channel_id
|
||||
.say(&ctx.http, "Must provide a valid URL")
|
||||
.await;
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let guild_id = match ctx.cache.guild_channel(msg.channel_id).await {
|
||||
Some(channel) => channel.guild_id,
|
||||
None => {
|
||||
|
||||
msg.channel_id
|
||||
.say(&ctx.http, "Error finding channel info")
|
||||
.await;
|
||||
msg.channel_id
|
||||
.say(&ctx.http, "Error finding channel info")
|
||||
.await?;
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
|
@ -159,36 +288,128 @@ async fn play(ctx: &Context, msg: &Message, mut args: Args) -> CommandResult {
|
|||
} else {
|
||||
false
|
||||
} {
|
||||
msg.channel_id
|
||||
.say(&ctx.http, "Error, you cant play music")
|
||||
.await;
|
||||
msg.channel_id
|
||||
.say(&ctx.http, "Error, you cant play music")
|
||||
.await?;
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let manager = songbird::get(ctx).await
|
||||
.expect("Songbird Voice client placed in at initialisation.").clone();
|
||||
let manager = songbird::get(ctx)
|
||||
.await
|
||||
.expect("Songbird Voice client placed in at initialisation.")
|
||||
.clone();
|
||||
|
||||
if let Some(handler_lock) = manager.get(guild_id) {
|
||||
let mut handler = handler_lock.lock().await;
|
||||
|
||||
let source = match songbird::ytdl(&url).await {
|
||||
if let Some(handler_lock) = manager.get(guild_id) {
|
||||
let mut handler = handler_lock.lock().await;
|
||||
|
||||
let source = if url.starts_with("http") {
|
||||
match songbird::ytdl(&url).await {
|
||||
Ok(source) => source,
|
||||
Err(why) => {
|
||||
error!("Err starting source: {:?}", why);
|
||||
|
||||
msg.channel_id.say(&ctx.http, "Error sourcing ffmpeg").await;
|
||||
|
||||
|
||||
msg.channel_id
|
||||
.say(&ctx.http, "Error sourcing ffmpeg")
|
||||
.await?;
|
||||
|
||||
return Ok(());
|
||||
},
|
||||
};
|
||||
|
||||
handler.play_source(source);
|
||||
|
||||
msg.channel_id.say(&ctx.http, "Playing song").await;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
msg.channel_id.say(&ctx.http, "Not in a voice channel to play in").await;
|
||||
match songbird::input::ytdl_search(&url).await {
|
||||
Ok(source) => source,
|
||||
Err(why) => {
|
||||
error!("Err starting source: {:?}", why);
|
||||
|
||||
msg.channel_id
|
||||
.say(&ctx.http, "Error sourcing ffmpeg")
|
||||
.await?;
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let meta = &source.metadata.clone();
|
||||
|
||||
handler.enqueue_source(source);
|
||||
|
||||
msg.channel_id
|
||||
.send_message(&ctx.http, |m| {
|
||||
if handler.queue().len() == 1 {
|
||||
embed_song(m, meta);
|
||||
} else {
|
||||
embed_queued(m, meta);
|
||||
}
|
||||
m
|
||||
})
|
||||
.await?;
|
||||
} else {
|
||||
msg.channel_id
|
||||
.say(&ctx.http, "Not in a voice channel to play in")
|
||||
.await?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[command]
|
||||
#[description("Next music")]
|
||||
async fn next(ctx: &Context, msg: &Message) -> CommandResult {
|
||||
let guild_id = match ctx.cache.guild_channel(msg.channel_id).await {
|
||||
Some(channel) => channel.guild_id,
|
||||
None => {
|
||||
msg.channel_id
|
||||
.say(&ctx.http, "Error finding channel info")
|
||||
.await?;
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
if if let Some(member) = &msg.member {
|
||||
is_mute(ctx, member, guild_id).await.unwrap_or(false)
|
||||
} else {
|
||||
false
|
||||
} {
|
||||
msg.channel_id
|
||||
.say(&ctx.http, "Error, you cant play music")
|
||||
.await?;
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let manager = songbird::get(ctx)
|
||||
.await
|
||||
.expect("Songbird Voice client placed in at initialisation.")
|
||||
.clone();
|
||||
|
||||
if let Some(handler) = manager.get(guild_id) {
|
||||
let handler = handler.lock().await;
|
||||
|
||||
let queue = handler.queue();
|
||||
|
||||
if let Some(current) = queue.current() {
|
||||
let metadata = current.metadata();
|
||||
log::debug!("Metadata : {:?}", metadata);
|
||||
}
|
||||
|
||||
let current_queue = queue.current_queue();
|
||||
let next = current_queue.get(1);
|
||||
queue.skip()?;
|
||||
|
||||
if let Some(current) = next {
|
||||
let metadata = current.metadata();
|
||||
log::debug!("{:?}", metadata);
|
||||
|
||||
if let Some(title) = &metadata.title {
|
||||
msg.channel_id
|
||||
.say(&ctx.http, format!("Playing {}", title))
|
||||
.await?;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
msg.reply(ctx, "Not in a voice channel").await?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -199,10 +420,9 @@ async fn stop(ctx: &Context, msg: &Message) -> CommandResult {
|
|||
let guild_id = match ctx.cache.guild_channel(msg.channel_id).await {
|
||||
Some(channel) => channel.guild_id,
|
||||
None => {
|
||||
|
||||
msg.channel_id
|
||||
.say(&ctx.http, "Error finding channel info")
|
||||
.await;
|
||||
msg.channel_id
|
||||
.say(&ctx.http, "Error finding channel info")
|
||||
.await?;
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
|
@ -213,26 +433,24 @@ async fn stop(ctx: &Context, msg: &Message) -> CommandResult {
|
|||
} else {
|
||||
false
|
||||
} {
|
||||
|
||||
msg.channel_id
|
||||
.say(&ctx.http, "Error, you cant play music")
|
||||
.await;
|
||||
msg.channel_id
|
||||
.say(&ctx.http, "Error, you cant play music")
|
||||
.await?;
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
|
||||
let manager = songbird::get(ctx)
|
||||
.await
|
||||
.expect("Songbird Voice client placed in at initialisation.")
|
||||
.clone();
|
||||
if let Some(handler) = manager.get(guild_id) {
|
||||
let mut handler = handler.lock().await;
|
||||
handler.stop();
|
||||
|
||||
let manager = songbird::get(ctx).await
|
||||
.expect("Songbird Voice client placed in at initialisation.").clone();
|
||||
if let Some(handler) = manager.get(guild_id) {
|
||||
|
||||
let mut handler = handler.lock().await;
|
||||
handler.stop();
|
||||
|
||||
msg.channel_id.say(&ctx.http, "Stopping").await;
|
||||
} else {
|
||||
msg.reply(ctx, "Not in a voice channel").await;
|
||||
}
|
||||
msg.channel_id.say(&ctx.http, "Stopping").await?;
|
||||
} else {
|
||||
msg.reply(ctx, "Not in a voice channel").await?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use log::debug;
|
||||
use serenity::{
|
||||
framework::standard::{
|
||||
macros::{command, group},
|
||||
|
@ -6,7 +7,6 @@ use serenity::{
|
|||
model::prelude::*,
|
||||
prelude::*,
|
||||
};
|
||||
use log::debug;
|
||||
use std::convert::TryFrom;
|
||||
|
||||
#[group]
|
||||
|
|
|
@ -2,7 +2,7 @@ use crate::{
|
|||
api,
|
||||
data::{GuildOptions, GuildOptionsKey},
|
||||
};
|
||||
use log::{debug, error};
|
||||
use log::debug;
|
||||
use rand::Rng;
|
||||
use serenity::{
|
||||
framework::standard::{
|
||||
|
@ -24,7 +24,7 @@ struct Roulette;
|
|||
#[bucket = "roulette"]
|
||||
async fn shot(ctx: &Context, msg: &Message, args: Args) -> CommandResult {
|
||||
let _message = args.message().trim_end();
|
||||
if _message == "shot" || _message == "" {
|
||||
if _message == "shot" || _message.is_empty() {
|
||||
if rand::thread_rng().gen_range(0..6) == 0 {
|
||||
api::send_reply(ctx, &msg, "💥").await?;
|
||||
} else {
|
||||
|
@ -59,24 +59,22 @@ async fn kick(ctx: &Context, msg: &Message) -> CommandResult {
|
|||
"Error : You cannot play to the REAL RUSSIAN ROULETTE in this guild",
|
||||
)
|
||||
.await?;
|
||||
} else if rand::thread_rng().gen_range(0..6) == 0 {
|
||||
api::send_reply(ctx, &msg, "💥").await?;
|
||||
|
||||
msg.author
|
||||
.create_dm_channel(&ctx)
|
||||
.await?
|
||||
.send_message(&ctx.http, |m| m.content("<:cheh:780736245675982909>"))
|
||||
.await?;
|
||||
|
||||
guild_id
|
||||
.member(&ctx.http, &msg.author)
|
||||
.await?
|
||||
.kick_with_reason(&ctx.http, "You loose at the roulette")
|
||||
.await?;
|
||||
} else {
|
||||
if rand::thread_rng().gen_range(0..6) == 0 {
|
||||
api::send_reply(ctx, &msg, "💥").await?;
|
||||
|
||||
msg.author
|
||||
.create_dm_channel(&ctx)
|
||||
.await?
|
||||
.send_message(&ctx.http, |m| m.content("<:cheh:780736245675982909>"))
|
||||
.await?;
|
||||
|
||||
guild_id
|
||||
.member(&ctx.http, &msg.author)
|
||||
.await?
|
||||
.kick_with_reason(&ctx.http, "You loose at the roulette")
|
||||
.await?;
|
||||
} else {
|
||||
api::send_reply(&ctx, &msg, format!("Click ! Reloading")).await?;
|
||||
}
|
||||
api::send_reply(&ctx, &msg, format!("Click ! Reloading")).await?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
|
|
|
@ -26,7 +26,7 @@ pub(crate) struct GuildOptions {
|
|||
pub(crate) mute_id: Option<RoleId>,
|
||||
pub(crate) roulette_options: RouletteOptions,
|
||||
pub(crate) last_ghost_pings: Vec<GhostPing>,
|
||||
pub(crate) mutes : Vec<(UserId, u64)>,
|
||||
pub(crate) mutes: Vec<(UserId, u64)>,
|
||||
}
|
||||
|
||||
impl GuildOptions {
|
||||
|
@ -155,7 +155,7 @@ impl Default for GuildOptions {
|
|||
guild_id: None,
|
||||
mute_id: None,
|
||||
last_ghost_pings: Vec::new(),
|
||||
mutes: Vec::new()
|
||||
mutes: Vec::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue