aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFuwn <[email protected]>2021-06-25 03:55:45 -0700
committerFuwn <[email protected]>2021-06-25 03:55:45 -0700
commitc6df8a46d4f62739318a1b7bfe7b744244cd9138 (patch)
treea6b42f316f4f21de43909f07051db9fc8cf0a1d6
parentfeat(cmds): say command (diff)
downloaddos-bot-c6df8a46d4f62739318a1b7bfe7b744244cd9138.tar.xz
dos-bot-c6df8a46d4f62739318a1b7bfe7b744244cd9138.zip
feat(cmds): create, remove, and count commands
-rw-r--r--Cargo.toml5
-rw-r--r--src/commands.rs116
-rw-r--r--src/config.rs9
-rw-r--r--src/database.rs58
-rw-r--r--src/main.rs24
5 files changed, 189 insertions, 23 deletions
diff --git a/Cargo.toml b/Cargo.toml
index e8f8d24..2e3a433 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -18,13 +18,16 @@ serenity = { version = "0.10.8", features = ["cache", "framework", "standard_fra
dotenv = "0.15.0"
tokio = { version = "1.7.1", features = ["macros", "signal", "rt-multi-thread"] }
config = "0.11.0"
+lazy_static = "1.4.0"
+simple-error = "0.2.3"
+array_tool = "1.0.3"
# Serialization
serde = "1.0.126"
serde_derive = "1.0.126"
# Database
-redis = "0.20.2"
+simplebase = "0.3.35"
# Logging
log = "0.4.14"
diff --git a/src/commands.rs b/src/commands.rs
index fb31f14..26dbfbc 100644
--- a/src/commands.rs
+++ b/src/commands.rs
@@ -1,6 +1,7 @@
// Copyright (C) 2021-2021 Fuwn
// SPDX-License-Identifier: GPL-3.0-only
+use array_tool::vec::Intersect;
use serenity::{
framework::standard::{macros::command, Args, CommandResult},
model::prelude::*,
@@ -25,8 +26,12 @@ pub async fn help(ctx: &Context, msg: &Message) -> CommandResult {
commands
========
-help - you are here
-ping - pong!
+help - you are here
+ping - pong!
+
+create - create a role reaction
+remove - remove a role reaction
+count - count the role reactions
information
===========
@@ -62,3 +67,110 @@ pub async fn say(ctx: &Context, msg: &Message, args: Args) -> CommandResult {
Ok(())
}
+
+#[command]
+pub async fn create(ctx: &Context, msg: &Message, mut args: Args) -> CommandResult {
+ if msg
+ .guild(&ctx.cache)
+ .await
+ .unwrap()
+ .member(&ctx.http, msg.author.id)
+ .await?
+ .roles
+ .intersect(
+ crate::config::Config::get()
+ .admin_roles
+ .iter()
+ .map(|r| RoleId(*r))
+ .collect(),
+ )
+ .is_empty()
+ {
+ msg
+ .channel_id
+ .say(&ctx.http, "invalid permissions!")
+ .await?;
+
+ return Ok(());
+ }
+
+ crate::database::Database::new()
+ .create_reaction_role(args.single::<u64>()?, args.single::<u64>()?);
+
+ msg
+ .channel_id
+ .say(&ctx.http, "created created role reaction")
+ .await?;
+
+ Ok(())
+}
+
+#[command]
+pub async fn remove(ctx: &Context, msg: &Message, mut args: Args) -> CommandResult {
+ if msg
+ .guild(&ctx.cache)
+ .await
+ .unwrap()
+ .member(&ctx.http, msg.author.id)
+ .await?
+ .roles
+ .intersect(
+ crate::config::Config::get()
+ .admin_roles
+ .iter()
+ .map(|r| RoleId(*r))
+ .collect(),
+ )
+ .is_empty()
+ {
+ msg
+ .channel_id
+ .say(&ctx.http, "invalid permissions!")
+ .await?;
+
+ return Ok(());
+ }
+
+ crate::database::Database::new().remove_reaction_role(args.single::<u64>()?);
+
+ msg
+ .channel_id
+ .say(&ctx.http, "removed role reaction")
+ .await?;
+
+ Ok(())
+}
+
+#[command]
+pub async fn count(ctx: &Context, msg: &Message) -> CommandResult {
+ if msg
+ .guild(&ctx.cache)
+ .await
+ .unwrap()
+ .member(&ctx.http, msg.author.id)
+ .await?
+ .roles
+ .intersect(
+ crate::config::Config::get()
+ .admin_roles
+ .iter()
+ .map(|r| RoleId(*r))
+ .collect(),
+ )
+ .is_empty()
+ {
+ msg
+ .channel_id
+ .say(&ctx.http, "invalid permissions!")
+ .await?;
+
+ return Ok(());
+ }
+
+ msg
+ .channel_id
+ .say(&ctx.http, crate::database::Database::new().count())
+ .await?;
+
+ Ok(())
+}
diff --git a/src/config.rs b/src/config.rs
index afdba2d..57fc823 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -5,14 +5,9 @@ use config::ConfigError;
use serde_derive::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Debug)]
-pub struct RolesRole {
- pub message: u64,
- pub role: u64,
-}
-#[derive(Serialize, Deserialize, Debug)]
pub struct Config {
- pub token: String,
- pub roles: Vec<RolesRole>,
+ pub token: String,
+ pub admin_roles: Vec<u64>,
}
impl Config {
#[allow(future_prelude_collision)]
diff --git a/src/database.rs b/src/database.rs
new file mode 100644
index 0000000..9dc9f5a
--- /dev/null
+++ b/src/database.rs
@@ -0,0 +1,58 @@
+// Copyright (C) 2021-2021 Fuwn
+// SPDX-License-Identifier: GPL-3.0-only
+
+use simple_error::SimpleResult;
+#[allow(clippy::wildcard_imports)]
+use simplebase::engine::*;
+
+pub struct Database(pub RecordData);
+impl Database {
+ #[must_use]
+ pub fn new() -> Self {
+ if std::path::Path::new(".dos-bot/db.txt").exists() {
+ Self(load_hash_database(".dos-bot/db.txt"))
+ } else {
+ Self(new_empty_database())
+ }
+ }
+
+ pub fn create_reaction_role(&mut self, message: u64, role: u64) {
+ self
+ .0
+ .add_record_with_key(message.to_string(), role.to_string());
+
+ self.0.save_database(".dos-bot/db.txt");
+ }
+
+ /// # Panics
+ /// if the record index is unable to be parsed.
+ pub fn remove_reaction_role(&mut self, message: u64) {
+ self.0.delete_record(
+ self.0.find_key(message.to_string().as_str())[0]
+ .parse::<usize>()
+ .unwrap(),
+ );
+
+ self.0.save_database(".dos-bot/db.txt");
+ }
+
+ /// # Errors
+ /// if no record is found for the given `message`.
+ ///
+ /// # Panics
+ /// if the record is unable to be parsed.
+ pub fn get_reaction_role(&self, message: u64) -> SimpleResult<u64> {
+ let record = self.0.find_key(message.to_string().as_str());
+ if record.is_empty() {
+ simple_error::bail!("no record found");
+ }
+
+ Ok(record[1].clone().parse::<u64>().unwrap())
+ }
+
+ #[must_use]
+ pub fn count(&self) -> String { self.0.record_counter.to_string() }
+}
+impl Default for Database {
+ fn default() -> Self { Self::new() }
+}
diff --git a/src/main.rs b/src/main.rs
index 7a938e9..3e2bfb7 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -27,6 +27,7 @@
pub mod commands;
pub mod config;
+pub mod database;
#[macro_use]
extern crate log;
@@ -59,16 +60,12 @@ struct Handler;
impl EventHandler for Handler {
async fn reaction_add(&self, ctx: Context, reaction: Reaction) {
if let Some(guild) = reaction.guild_id {
- if let Some(c) = config::Config::get()
- .roles
- .iter()
- .find(|x| x.message == reaction.message_id.0)
- {
+ if let Ok(role) = database::Database::new().get_reaction_role(reaction.message_id.0) {
guild
.member(&ctx, reaction.user_id.expect("unable to locate user id"))
.await
.expect("unable to locate member")
- .add_role(&ctx, c.role)
+ .add_role(&ctx, role)
.await
.expect("unable to add role to member");
}
@@ -77,16 +74,12 @@ impl EventHandler for Handler {
async fn reaction_remove(&self, ctx: Context, reaction: Reaction) {
if let Some(guild) = reaction.guild_id {
- if let Some(c) = config::Config::get()
- .roles
- .iter()
- .find(|x| x.message == reaction.message_id.0)
- {
+ if let Ok(role) = database::Database::new().get_reaction_role(reaction.message_id.0) {
guild
.member(&ctx, reaction.user_id.expect("unable to locate user id"))
.await
.expect("unable to locate member")
- .remove_role(&ctx, c.role)
+ .remove_role(&ctx, role)
.await
.expect("unable to add role to member");
}
@@ -106,6 +99,10 @@ impl EventHandler for Handler {
#[commands(ping, help, say)]
struct General;
+#[group]
+#[commands(create, remove, count)]
+struct RoleReactions;
+
#[tokio::main]
async fn main() {
dotenv::dotenv().ok();
@@ -127,7 +124,8 @@ async fn main() {
let framework = StandardFramework::new()
.configure(|c| c.owners(owners).prefix(">"))
- .group(&GENERAL_GROUP);
+ .group(&GENERAL_GROUP)
+ .group(&ROLEREACTIONS_GROUP);
let mut client = Client::builder(Config::get().token.as_str())
.framework(framework)