From d36323c12c9758424478a73bf21a622349f002f0 Mon Sep 17 00:00:00 2001 From: Natsu Kagami Date: Fri, 1 Nov 2019 19:27:29 -0400 Subject: [PATCH] Progress! --- .gitignore | 1 + Cargo.lock | 10 ++++ youmubot/Cargo.toml | 2 + youmubot/src/commands/admin/mod.rs | 44 ++++++++++++++ youmubot/src/commands/mod.rs | 25 ++++++++ youmubot/src/main.rs | 93 ++++++++++++++++++++++++++++++ 6 files changed, 175 insertions(+) create mode 100644 youmubot/src/commands/admin/mod.rs create mode 100644 youmubot/src/commands/mod.rs diff --git a/.gitignore b/.gitignore index eb5a316..c5dd462 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ target +.env diff --git a/Cargo.lock b/Cargo.lock index 2254c26..68127bf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -232,6 +232,11 @@ dependencies = [ "generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "dotenv" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "dtoa" version = "0.4.4" @@ -1529,6 +1534,10 @@ dependencies = [ [[package]] name = "youmubot" version = "0.1.0" +dependencies = [ + "dotenv 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serenity 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] name = "youmubot-osu" @@ -1566,6 +1575,7 @@ dependencies = [ "checksum crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "04973fa96e96579258a5091af6003abde64af786b860f18622b82e026cca60e6" "checksum ct-logs 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4d3686f5fa27dbc1d76c751300376e167c5a43387f44bb451fd1c24776e49113" "checksum digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" +"checksum dotenv 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" "checksum dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ea57b42383d091c85abcc2706240b94ab2a8fa1fc81c10ff23c4de06e2a90b5e" "checksum either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3" "checksum encoding_rs 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)" = "87240518927716f79692c2ed85bfe6e98196d18c6401ec75355760233a7e12e9" diff --git a/youmubot/Cargo.toml b/youmubot/Cargo.toml index ab02352..d087142 100644 --- a/youmubot/Cargo.toml +++ b/youmubot/Cargo.toml @@ -7,3 +7,5 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +serenity = "0.7" +dotenv = "0.15" diff --git a/youmubot/src/commands/admin/mod.rs b/youmubot/src/commands/admin/mod.rs new file mode 100644 index 0000000..e311bce --- /dev/null +++ b/youmubot/src/commands/admin/mod.rs @@ -0,0 +1,44 @@ +use serenity::prelude::*; +use serenity::{ + framework::standard::{ + macros::{command, group}, + Args, CommandResult, + }, + model::channel::Message, +}; +use std::{thread::sleep, time::Duration}; + +group!({ + name: "admin", + options: { + only_in: "guilds", + prefixes: ["admin", "a"], + description: "Administrative commands for the server.", + }, + commands: [clean, ban], +}); + +#[command] +#[aliases("cleanall")] +#[required_permissions(MANAGE_MESSAGES)] +#[description = "Clean at most X latest messages from the current channel. Defaults to 10."] +#[usage = "clean 50"] +fn clean(ctx: &mut Context, msg: &Message, mut args: Args) -> CommandResult { + let limit = args.single().unwrap_or(10); + let messages = msg + .channel_id + .messages(&ctx.http, |b| b.before(msg.id).limit(limit))?; + msg.channel_id.delete_messages(&ctx.http, messages.iter())?; + msg.react(&ctx, "🌋")?; + + sleep(Duration::from_secs(2)); + msg.delete(&ctx)?; + + Ok(()) +} + +#[command] +#[required_permissions(ADMINISTRATOR)] +#[description = "Ban an user with a certain reason."] +#[usage = "ban user#1234 spam"] +fn ban(ctx: &mut Context, msg: &Message, mut args: Args) -> CommandResult {} diff --git a/youmubot/src/commands/mod.rs b/youmubot/src/commands/mod.rs new file mode 100644 index 0000000..64fcc87 --- /dev/null +++ b/youmubot/src/commands/mod.rs @@ -0,0 +1,25 @@ +use serenity::prelude::*; +use serenity::{ + framework::standard::{ + help_commands, macros::help, Args, CommandGroup, CommandResult, HelpOptions, + }, + model::{channel::Message, id::UserId}, +}; +use std::collections::HashSet; + +mod admin; + +pub use admin::ADMIN_GROUP; + +// A help command +#[help] +pub fn help( + context: &mut Context, + msg: &Message, + args: Args, + help_options: &'static HelpOptions, + groups: &[&'static CommandGroup], + owners: HashSet, +) -> CommandResult { + help_commands::with_embeds(context, msg, args, help_options, groups, owners) +} diff --git a/youmubot/src/main.rs b/youmubot/src/main.rs index e7a11a9..dd22ef4 100644 --- a/youmubot/src/main.rs +++ b/youmubot/src/main.rs @@ -1,3 +1,96 @@ +use dotenv; +use dotenv::var; +use serenity::{ + framework::standard::{DispatchError, StandardFramework}, + model::gateway, + prelude::*, +}; + +mod commands; + +struct Handler; + +impl EventHandler for Handler { + fn ready(&self, _: Context, ready: gateway::Ready) { + println!("{} is connected!", ready.user.name); + } +} + fn main() { + // Setup dotenv + if let Ok(path) = dotenv::dotenv() { + println!("Loaded dotenv from {:?}", path); + } + + // Sets up a client + let mut client = { + // Collect the token + let token = var("TOKEN").expect("Please set TOKEN as the Discord Bot's token to be used."); + // Attempt to connect and set up a framework + setup_framework(Client::new(token, Handler).expect("Cannot connect...")) + }; + + println!("Starting..."); + if let Err(v) = client.start() { + panic!(v) + } + println!("Hello, world!"); } + +// Sets up a framework for a client +fn setup_framework(mut client: Client) -> Client { + // Collect owners + let owner = client + .cache_and_http + .http + .get_current_application_info() + .expect("Should be able to get app info") + .owner; + + client.with_framework( + StandardFramework::new() + .configure(|c| { + c.with_whitespace(false) + .prefix("y!") + .delimiters(vec![" / ", "/ ", " /", "/"]) + .owners([owner.id].iter().cloned().collect()) + }) + .help(&commands::HELP) + .before(|_, msg, command_name| { + println!( + "Got command '{}' by user '{}'", + command_name, msg.author.name + ); + true + }) + .after(|ctx, msg, command_name, error| match error { + Ok(()) => println!("Processed command '{}'", command_name), + Err(why) => { + let reply = format!("Command '{}' returned error {:?}", command_name, why); + if let Err(_) = msg.reply(&ctx, &reply) {} + println!("{}", reply) + } + }) + .on_dispatch_error(|ctx, msg, error| { + if let DispatchError::Ratelimited(seconds) = error { + let _ = msg.channel_id.say( + &ctx.http, + &format!("Try this again in {} seconds.", seconds), + ); + } + }) + // Set a function that's called whenever an attempted command-call's + // command could not be found. + .unrecognised_command(|_, _, unknown_command_name| { + println!("Could not find command named '{}'", unknown_command_name); + }) + // Set a function that's called whenever a message is not a command. + .normal_message(|_, message| { + println!("Message is not a command '{}'", message.content); + }) + // groups here + .group(&commands::ADMIN_GROUP), + ); + client +}