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 serenity::{
|
||||
client::bridge::gateway::ShardId,
|
||||
framework::standard::{
|
||||
macros::{command, group},
|
||||
ArgError, Args, CommandResult,
|
||||
|
@ -10,7 +11,7 @@ use serenity::{
|
|||
};
|
||||
|
||||
#[group]
|
||||
#[commands(longcode, image, older, ping, invite, infos, error, send_message)]
|
||||
#[commands(error, image, infos, invite, latency, longcode, older, ping)]
|
||||
pub struct General;
|
||||
|
||||
#[command]
|
||||
|
@ -19,6 +20,45 @@ pub async fn error(_ctx: &Context, _msg: &Message) -> CommandResult {
|
|||
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]
|
||||
#[description = "Split a huge code"]
|
||||
#[bucket = "longcode"]
|
||||
|
@ -66,6 +106,58 @@ async fn _longcode(ctx: &Context, msg: &Message, mut args: Args) -> crate::comma
|
|||
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]
|
||||
#[description("Print the bot invite link")]
|
||||
async fn invite(ctx: &Context, msg: &Message) -> CommandResult {
|
||||
|
@ -82,22 +174,6 @@ async fn invite(ctx: &Context, msg: &Message) -> CommandResult {
|
|||
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]
|
||||
#[description = "Find who is the older"]
|
||||
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]
|
||||
#[description = "Print bot infos"]
|
||||
async fn infos(ctx: &Context, msg: &Message) -> CommandResult {
|
||||
let current_user = ctx.http.get_current_user().await;
|
||||
#[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
|
||||
.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
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
.say(
|
||||
&ctx.http,
|
||||
format!("Time elapsed : {}ms", elapsed.as_millis()),
|
||||
)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn get_features<'m>() -> Vec<&'m str> {
|
||||
let mut res = Vec::new();
|
||||
if cfg!(feature = "music") {
|
||||
res.push("music");
|
||||
}
|
||||
res
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[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 general;
|
||||
pub(crate) mod owner;
|
||||
pub(crate) mod roulette;
|
||||
|
||||
#[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(())
|
||||
}
|
37
src/main.rs
37
src/main.rs
|
@ -1,5 +1,7 @@
|
|||
use crate::commands::{
|
||||
admin::ADMIN_GROUP,
|
||||
general::GENERAL_GROUP,
|
||||
owner::OWNER_GROUP,
|
||||
roulette::{BulletsContainer, NonKickGuildsContainer, ROULETTE_GROUP},
|
||||
};
|
||||
use async_trait::async_trait;
|
||||
|
@ -111,8 +113,10 @@ async fn main() -> IoResult<()> {
|
|||
.on_dispatch_error(dispatch_error)
|
||||
.after(after_hook)
|
||||
.help(&MY_HELP)
|
||||
.group(&ADMIN_GROUP)
|
||||
.group(&GENERAL_GROUP)
|
||||
.group(&ROULETTE_GROUP);
|
||||
.group(&ROULETTE_GROUP)
|
||||
.group(&OWNER_GROUP);
|
||||
|
||||
#[cfg(feature = "music")]
|
||||
{
|
||||
|
@ -294,14 +298,29 @@ async fn normal_message(_ctx: &Context, msg: &Message) {
|
|||
#[hook]
|
||||
async fn dispatch_error(ctx: &Context, msg: &Message, error: DispatchError) {
|
||||
debugln!("Dispatch error : {:?}", error);
|
||||
if let DispatchError::Ratelimited(seconds) = error {
|
||||
let _ = msg
|
||||
.channel_id
|
||||
.say(
|
||||
&ctx.http,
|
||||
&format!("Try this again in {} seconds.", seconds),
|
||||
)
|
||||
.await;
|
||||
match error {
|
||||
DispatchError::Ratelimited(seconds) => {
|
||||
let _ = msg
|
||||
.channel_id
|
||||
.say(
|
||||
&ctx.http,
|
||||
&format!("Try this again in {} seconds.", seconds),
|
||||
)
|
||||
.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;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue