parent
1c28b1238c
commit
5e125052c5
|
@ -1 +1,97 @@
|
||||||
|
use crate::debugln;
|
||||||
|
use serenity::{
|
||||||
|
framework::standard::{
|
||||||
|
macros::{command, group},
|
||||||
|
CommandResult,
|
||||||
|
},
|
||||||
|
model::prelude::*,
|
||||||
|
prelude::*,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[group]
|
||||||
|
#[commands(ban, kick)]
|
||||||
|
pub struct Admin;
|
||||||
|
|
||||||
|
#[command]
|
||||||
|
#[description = "Kick an user"]
|
||||||
|
#[only_in(guilds)]
|
||||||
|
#[required_permissions("KICK_MEMBERS")]
|
||||||
|
async fn kick(ctx: &Context, msg: &Message) -> CommandResult {
|
||||||
|
// TODO CACHE ?
|
||||||
|
if let Some(sender_member) = msg.member(ctx).await {
|
||||||
|
for user in &msg.mentions {
|
||||||
|
if let Some(member) = ctx.cache.member(msg.guild_id.unwrap(), user.id).await {
|
||||||
|
debugln!("Kicking {:?}", user);
|
||||||
|
let kick = if let Some(role_member) = sender_member.highest_role_info(ctx).await {
|
||||||
|
if let Some(role) = member.highest_role_info(ctx).await {
|
||||||
|
role_member.1 > role.1
|
||||||
|
} else {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
true
|
||||||
|
};
|
||||||
|
if kick {
|
||||||
|
member.kick(ctx).await?;
|
||||||
|
} else {
|
||||||
|
msg.channel_id
|
||||||
|
.say(
|
||||||
|
ctx,
|
||||||
|
&format!(
|
||||||
|
"Error, you can't kick {}",
|
||||||
|
if let Some(nick) = member.nick {
|
||||||
|
nick
|
||||||
|
} else {
|
||||||
|
user.name.clone()
|
||||||
|
}
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[command]
|
||||||
|
#[description = "Ban an user"]
|
||||||
|
#[only_in(guilds)]
|
||||||
|
#[required_permissions("BAN_MEMBERS")]
|
||||||
|
async fn ban(ctx: &Context, msg: &Message) -> CommandResult {
|
||||||
|
// TODO CACHE ?
|
||||||
|
if let Some(sender_member) = msg.member(ctx).await {
|
||||||
|
for user in &msg.mentions {
|
||||||
|
if let Some(member) = ctx.cache.member(msg.guild_id.unwrap(), user.id).await {
|
||||||
|
debugln!("Kicking {:?}", user);
|
||||||
|
let kick = if let Some(role_member) = sender_member.highest_role_info(ctx).await {
|
||||||
|
if let Some(role) = member.highest_role_info(ctx).await {
|
||||||
|
role_member.1 > role.1
|
||||||
|
} else {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
true
|
||||||
|
};
|
||||||
|
if kick {
|
||||||
|
member.ban(ctx, 0).await?;
|
||||||
|
} else {
|
||||||
|
msg.channel_id
|
||||||
|
.say(
|
||||||
|
ctx,
|
||||||
|
&format!(
|
||||||
|
"Error, you can't ban {}",
|
||||||
|
if let Some(nick) = member.nick {
|
||||||
|
nick
|
||||||
|
} else {
|
||||||
|
user.name.clone()
|
||||||
|
}
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use crate::{api, debugln};
|
use crate::{api, debugln, ShardManagerContainer};
|
||||||
use futures::StreamExt;
|
use futures::StreamExt;
|
||||||
use serenity::{
|
use serenity::{
|
||||||
|
client::bridge::gateway::ShardId,
|
||||||
framework::standard::{
|
framework::standard::{
|
||||||
macros::{command, group},
|
macros::{command, group},
|
||||||
ArgError, Args, CommandResult,
|
ArgError, Args, CommandResult,
|
||||||
|
@ -10,7 +11,7 @@ use serenity::{
|
||||||
};
|
};
|
||||||
|
|
||||||
#[group]
|
#[group]
|
||||||
#[commands(longcode, image, older, ping, invite, infos, error, send_message)]
|
#[commands(error, image, infos, invite, latency, longcode, older, ping)]
|
||||||
pub struct General;
|
pub struct General;
|
||||||
|
|
||||||
#[command]
|
#[command]
|
||||||
|
@ -19,6 +20,45 @@ pub async fn error(_ctx: &Context, _msg: &Message) -> CommandResult {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[command]
|
||||||
|
async fn latency(ctx: &Context, msg: &Message) -> CommandResult {
|
||||||
|
// The shard manager is an interface for mutating, stopping, restarting, and
|
||||||
|
// retrieving information about shards.
|
||||||
|
let data = ctx.data.read().await;
|
||||||
|
|
||||||
|
let shard_manager = match data.get::<ShardManagerContainer>() {
|
||||||
|
Some(v) => v,
|
||||||
|
None => {
|
||||||
|
let _ = msg
|
||||||
|
.reply(ctx, "There was a problem getting the shard manager")
|
||||||
|
.await;
|
||||||
|
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let manager = shard_manager.lock().await;
|
||||||
|
let runners = manager.runners.lock().await;
|
||||||
|
|
||||||
|
// Shards are backed by a "shard runner" responsible for processing events
|
||||||
|
// over the shard, so we'll get the information about the shard runner for
|
||||||
|
// the shard this command was sent over.
|
||||||
|
let runner = match runners.get(&ShardId(ctx.shard_id)) {
|
||||||
|
Some(runner) => runner,
|
||||||
|
None => {
|
||||||
|
let _ = msg.reply(ctx, "No shard found");
|
||||||
|
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let _ = msg
|
||||||
|
.reply(ctx, &format!("The shard latency is {:?}", runner.latency))
|
||||||
|
.await;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
#[command]
|
#[command]
|
||||||
#[description = "Split a huge code"]
|
#[description = "Split a huge code"]
|
||||||
#[bucket = "longcode"]
|
#[bucket = "longcode"]
|
||||||
|
@ -66,6 +106,58 @@ async fn _longcode(ctx: &Context, msg: &Message, mut args: Args) -> crate::comma
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[command]
|
||||||
|
#[description = "Print bot infos"]
|
||||||
|
async fn infos(ctx: &Context, msg: &Message) -> CommandResult {
|
||||||
|
let current_user = ctx.http.get_current_user().await;
|
||||||
|
msg.channel_id
|
||||||
|
.send_message(ctx, |m| {
|
||||||
|
m.embed(|e| {
|
||||||
|
e.title(format!(
|
||||||
|
"{} v{}, by {}",
|
||||||
|
option_env!("CARGO_PKG_NAME").unwrap_or("unknown"),
|
||||||
|
option_env!("CARGO_PKG_VERSION").unwrap_or("unknown"),
|
||||||
|
option_env!("CARGO_PKG_AUTHORS").unwrap_or("unknows")
|
||||||
|
))
|
||||||
|
.description(format!(
|
||||||
|
concat!(
|
||||||
|
"Features : {:?}\n",
|
||||||
|
"Mode : {}\n",
|
||||||
|
"Source code : https://git.oupsman.fr/oupson/discord_rusty_bot"
|
||||||
|
),
|
||||||
|
get_features(),
|
||||||
|
if cfg!(debug_assertions) {
|
||||||
|
"debug"
|
||||||
|
} else {
|
||||||
|
"release"
|
||||||
|
},
|
||||||
|
))
|
||||||
|
.colour((247, 76, 0))
|
||||||
|
.footer(|f| {
|
||||||
|
if let Ok(user) = ¤t_user {
|
||||||
|
let mut f = f.text(&user.name);
|
||||||
|
if let Some(avatar) = user.avatar_url() {
|
||||||
|
f = f.icon_url(avatar);
|
||||||
|
}
|
||||||
|
f
|
||||||
|
} else {
|
||||||
|
f
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_features<'m>() -> Vec<&'m str> {
|
||||||
|
let mut res = Vec::new();
|
||||||
|
if cfg!(feature = "music") {
|
||||||
|
res.push("music");
|
||||||
|
}
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
#[command]
|
#[command]
|
||||||
#[description("Print the bot invite link")]
|
#[description("Print the bot invite link")]
|
||||||
async fn invite(ctx: &Context, msg: &Message) -> CommandResult {
|
async fn invite(ctx: &Context, msg: &Message) -> CommandResult {
|
||||||
|
@ -82,22 +174,6 @@ async fn invite(ctx: &Context, msg: &Message) -> CommandResult {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[command]
|
|
||||||
#[description("Pong !")]
|
|
||||||
async fn ping(ctx: &Context, msg: &Message) -> CommandResult {
|
|
||||||
let now = std::time::Instant::now();
|
|
||||||
msg.channel_id.say(&ctx.http, "Pong!").await?;
|
|
||||||
let elapsed = now.elapsed();
|
|
||||||
msg.channel_id
|
|
||||||
.say(
|
|
||||||
&ctx.http,
|
|
||||||
format!("Time elapsed : {}ms", elapsed.as_millis()),
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[command]
|
#[command]
|
||||||
#[description = "Find who is the older"]
|
#[description = "Find who is the older"]
|
||||||
pub async fn older(ctx: &Context, msg: &Message, args: Args) -> CommandResult {
|
pub async fn older(ctx: &Context, msg: &Message, args: Args) -> CommandResult {
|
||||||
|
@ -153,55 +229,19 @@ async fn _older(ctx: &Context, msg: &Message, mut args: Args) -> crate::commands
|
||||||
}
|
}
|
||||||
|
|
||||||
#[command]
|
#[command]
|
||||||
#[description = "Print bot infos"]
|
#[description("Pong !")]
|
||||||
async fn infos(ctx: &Context, msg: &Message) -> CommandResult {
|
async fn ping(ctx: &Context, msg: &Message) -> CommandResult {
|
||||||
let current_user = ctx.http.get_current_user().await;
|
let now = std::time::Instant::now();
|
||||||
|
msg.channel_id.say(&ctx.http, "Pong!").await?;
|
||||||
|
let elapsed = now.elapsed();
|
||||||
msg.channel_id
|
msg.channel_id
|
||||||
.send_message(ctx, |m| {
|
.say(
|
||||||
m.embed(|e| {
|
&ctx.http,
|
||||||
e.title(format!(
|
format!("Time elapsed : {}ms", elapsed.as_millis()),
|
||||||
"{} v{}, by {}",
|
)
|
||||||
option_env!("CARGO_PKG_NAME").unwrap_or("unknown"),
|
|
||||||
option_env!("CARGO_PKG_VERSION").unwrap_or("unknown"),
|
|
||||||
option_env!("CARGO_PKG_AUTHORS").unwrap_or("unknows")
|
|
||||||
))
|
|
||||||
.description(format!(
|
|
||||||
concat!(
|
|
||||||
"Features : {:?}\n",
|
|
||||||
"Mode : {}\n",
|
|
||||||
"Source code : https://git.oupsman.fr/oupson/discord_rusty_bot"
|
|
||||||
),
|
|
||||||
get_features(),
|
|
||||||
if cfg!(debug_assertions) {
|
|
||||||
"debug"
|
|
||||||
} else {
|
|
||||||
"release"
|
|
||||||
},
|
|
||||||
))
|
|
||||||
.colour((247, 76, 0))
|
|
||||||
.footer(|f| {
|
|
||||||
if let Ok(user) = ¤t_user {
|
|
||||||
let mut f = f.text(&user.name);
|
|
||||||
if let Some(avatar) = user.avatar_url() {
|
|
||||||
f = f.icon_url(avatar);
|
|
||||||
}
|
|
||||||
f
|
|
||||||
} else {
|
|
||||||
f
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.await?;
|
.await?;
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_features<'m>() -> Vec<&'m str> {
|
Ok(())
|
||||||
let mut res = Vec::new();
|
|
||||||
if cfg!(feature = "music") {
|
|
||||||
res.push("music");
|
|
||||||
}
|
|
||||||
res
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[command]
|
#[command]
|
||||||
|
@ -288,13 +328,3 @@ impl std::str::FromStr for Image {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[command]
|
|
||||||
#[owners_only]
|
|
||||||
async fn send_message(ctx: &Context, _msg: &Message, mut args: Args) -> CommandResult {
|
|
||||||
let channel_id = args.single::<ChannelId>()?;
|
|
||||||
let message = args.single::<String>()?;
|
|
||||||
debugln!("Send {} into {:?}", message, channel_id);
|
|
||||||
channel_id.say(ctx, message).await?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
pub(crate) mod admin;
|
pub(crate) mod admin;
|
||||||
pub(crate) mod general;
|
pub(crate) mod general;
|
||||||
|
pub(crate) mod owner;
|
||||||
pub(crate) mod roulette;
|
pub(crate) mod roulette;
|
||||||
|
|
||||||
#[cfg(feature = "music")]
|
#[cfg(feature = "music")]
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
use crate::debugln;
|
||||||
|
use serenity::{
|
||||||
|
framework::standard::{
|
||||||
|
macros::{command, group},
|
||||||
|
Args, CommandResult,
|
||||||
|
},
|
||||||
|
model::prelude::*,
|
||||||
|
prelude::*,
|
||||||
|
};
|
||||||
|
use std::convert::TryFrom;
|
||||||
|
|
||||||
|
#[group]
|
||||||
|
#[commands(leave, send_message)]
|
||||||
|
pub(crate) struct Owner;
|
||||||
|
|
||||||
|
#[command]
|
||||||
|
#[owners_only]
|
||||||
|
pub async fn leave(ctx: &Context, _msg: &Message, mut args: Args) -> CommandResult {
|
||||||
|
let guild = GuildId::try_from(args.single::<u64>()?)?;
|
||||||
|
guild.leave(&ctx.http).await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[command]
|
||||||
|
#[owners_only]
|
||||||
|
async fn send_message(ctx: &Context, _msg: &Message, mut args: Args) -> CommandResult {
|
||||||
|
let channel_id = args.single::<ChannelId>()?;
|
||||||
|
let message = args.single::<String>()?;
|
||||||
|
debugln!("Send {} into {:?}", message, channel_id);
|
||||||
|
channel_id.say(ctx, message).await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
23
src/main.rs
23
src/main.rs
|
@ -1,5 +1,7 @@
|
||||||
use crate::commands::{
|
use crate::commands::{
|
||||||
|
admin::ADMIN_GROUP,
|
||||||
general::GENERAL_GROUP,
|
general::GENERAL_GROUP,
|
||||||
|
owner::OWNER_GROUP,
|
||||||
roulette::{BulletsContainer, NonKickGuildsContainer, ROULETTE_GROUP},
|
roulette::{BulletsContainer, NonKickGuildsContainer, ROULETTE_GROUP},
|
||||||
};
|
};
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
|
@ -111,8 +113,10 @@ async fn main() -> IoResult<()> {
|
||||||
.on_dispatch_error(dispatch_error)
|
.on_dispatch_error(dispatch_error)
|
||||||
.after(after_hook)
|
.after(after_hook)
|
||||||
.help(&MY_HELP)
|
.help(&MY_HELP)
|
||||||
|
.group(&ADMIN_GROUP)
|
||||||
.group(&GENERAL_GROUP)
|
.group(&GENERAL_GROUP)
|
||||||
.group(&ROULETTE_GROUP);
|
.group(&ROULETTE_GROUP)
|
||||||
|
.group(&OWNER_GROUP);
|
||||||
|
|
||||||
#[cfg(feature = "music")]
|
#[cfg(feature = "music")]
|
||||||
{
|
{
|
||||||
|
@ -294,7 +298,8 @@ async fn normal_message(_ctx: &Context, msg: &Message) {
|
||||||
#[hook]
|
#[hook]
|
||||||
async fn dispatch_error(ctx: &Context, msg: &Message, error: DispatchError) {
|
async fn dispatch_error(ctx: &Context, msg: &Message, error: DispatchError) {
|
||||||
debugln!("Dispatch error : {:?}", error);
|
debugln!("Dispatch error : {:?}", error);
|
||||||
if let DispatchError::Ratelimited(seconds) = error {
|
match error {
|
||||||
|
DispatchError::Ratelimited(seconds) => {
|
||||||
let _ = msg
|
let _ = msg
|
||||||
.channel_id
|
.channel_id
|
||||||
.say(
|
.say(
|
||||||
|
@ -303,6 +308,20 @@ async fn dispatch_error(ctx: &Context, msg: &Message, error: DispatchError) {
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
}
|
}
|
||||||
|
DispatchError::OnlyForOwners => {
|
||||||
|
let _ = msg
|
||||||
|
.channel_id
|
||||||
|
.say(&ctx.http, "Error : only the owner can call this command")
|
||||||
|
.await;
|
||||||
|
}
|
||||||
|
DispatchError::LackingPermissions(perms) => {
|
||||||
|
let _ = msg
|
||||||
|
.channel_id
|
||||||
|
.say(&ctx.http, &format!("Error, only {:?} can do that", perms))
|
||||||
|
.await;
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[hook]
|
#[hook]
|
||||||
|
|
Loading…
Reference in New Issue