diff options
Diffstat (limited to 'src/main.rs')
-rw-r--r-- | src/main.rs | 130 |
1 files changed, 40 insertions, 90 deletions
diff --git a/src/main.rs b/src/main.rs index 13bac74..774d9e6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,6 @@ use std::{env, error::Error, path::PathBuf, sync::Arc}; +use brain::Brain; use confindent::Confindent; use database::{BoardRow, Database, Error as DbError, PermissionSetting}; use twilight_cache_inmemory::{DefaultInMemoryCache, ResourceType}; @@ -26,12 +27,13 @@ use twilight_util::builder::{ embed::EmbedBuilder, }; +mod brain; mod database; mod import; const PROD_APP_ID: u64 = 1363055126264283136; const DEV_APP_ID: u64 = 1363494986699771984; -const APP_ID: u64 = PROD_APP_ID; +const APP_ID: u64 = DEV_APP_ID; macro_rules! bail { ($msg:expr) => { @@ -57,91 +59,6 @@ macro_rules! success { }; } -// A Absolutely Remarkably Terrible Thing -macro_rules! aumau { - ($meow:expr) => { - $meow.await.unwrap().model().await.unwrap() - }; -} - -struct Brain { - db: Database, - http: HttpClient, - cache: DefaultInMemoryCache, -} - -impl Brain { - /// Get the interaction client. Used for responding to interactions - pub fn interaction(&self) -> InteractionClient<'_> { - self.http.interaction(Id::new(APP_ID)) - } - - /// Respond to the interaction indicated by `create`. This method will - /// respond as an `InteractionResponseType::ChannelMessageWithSource` - pub async fn interaction_respond( - &self, - create: &InteractionCreate, - data: InteractionResponseData, - ) { - self.interaction() - .create_response( - create.id, - &create.token, - &InteractionResponse { - kind: InteractionResponseType::ChannelMessageWithSource, - data: Some(data), - }, - ) - .await - .unwrap(); - } - - /// Retrieve information about a member of a guild. This method checks the - /// cache first, and then makes a request if it isn't there - pub async fn guild_member(&self, guild_id: Id<GuildMarker>, user_id: Id<UserMarker>) -> Member { - let user = self.cache.user(user_id); - let member = self.cache.member(guild_id, user_id); - - match user.zip(member) { - Some((user, member)) => Member { - id: user_id, - handle: user.name.clone(), - global_name: user.global_name.clone(), - nick: member.nick().map(<_>::to_owned), - }, - None => { - let member = aumau!(self.http.guild_member(guild_id, user_id)); - - Member { - id: user_id, - handle: member.user.name, - global_name: member.user.global_name, - nick: member.nick, - } - } - } - } - - /// Check the database for a leaderboard belonging to this guild. If it - /// does not exist, create one. Returns whether or not one existed before - /// this function was called - pub fn create_leaderboard_if_not_exists(&self, guild: Id<GuildMarker>) -> bool { - if !self.db.leaderboard_exits(guild.get()) { - self.db.create_leaderboard(guild.get()).unwrap(); - false - } else { - true - } - } -} - -struct Member { - id: Id<UserMarker>, - handle: String, - global_name: Option<String>, - nick: Option<String>, -} - #[tokio::main] async fn main() -> anyhow::Result<()> { //dotenv::dotenv().ok(); @@ -212,7 +129,7 @@ async fn main() -> anyhow::Result<()> { ); } - let brain = Arc::new(Brain { db, http, cache }); + let brain = Arc::new(Brain::new(db, http, cache)); while let Some(item) = shard.next_event(EventTypeFlags::all()).await { let Ok(event) = item else { @@ -220,7 +137,7 @@ async fn main() -> anyhow::Result<()> { continue; }; - brain.cache.update(&event); + brain.update_cache(&event); tokio::spawn(handle_event(event, Arc::clone(&brain))); } @@ -249,6 +166,7 @@ async fn handle_event(event: Event, brain: Arc<Brain>) -> Result<(), Box<dyn Err "leaderboard" => Commands::Leaderboard, "points" => Commands::Points, "permission" => Commands::Permission, + "import" => Commands::Import, _ => panic!("'{}' is not a command", cmd.name), }; @@ -296,7 +214,14 @@ async fn commands() -> Vec<Command> { )) .build(); - vec![leaderboard, points, permission] + let import = CommandBuilder::new( + "import", + "import this server's emboard leaderboard by adding the points in emboard, to leaberblord's", + CommandType::ChatInput, + ) + .build(); + + vec![leaderboard, points, permission, import] } async fn command_handler( @@ -311,6 +236,10 @@ async fn command_handler( Commands::Leaderboard => get_leaderboard(brain.clone(), guild), Commands::Points => add_points(brain.clone(), guild, create, command_data).await, Commands::Permission => permission(brain.clone(), guild, create, command_data).await, + Commands::Import => { + import_cmd(brain.clone(), guild, create, command_data).await; + return; + } }; // Finally, send back the response @@ -442,7 +371,7 @@ async fn permission( let member = create.member.clone().unwrap(); let permissions = member.permissions.unwrap(); if !permissions.contains(twilight_model::guild::Permissions::MANAGE_GUILD) { - bail!("You must have the Manage Server permission to perform this command"); + bail!("You must have the Manage Server permission to perform this action"); } for opt in &data.options { @@ -499,10 +428,31 @@ fn permission_role( )) } +async fn import_cmd( + brain: Arc<Brain>, + guild: Id<GuildMarker>, + create: &InteractionCreate, + data: &CommandData, +) { + let member = create.member.clone().unwrap(); + let permissions = member.permissions.unwrap(); + if !permissions.contains(twilight_model::guild::Permissions::MANAGE_GUILD) { + brain + .interaction_respond( + create, + fail!("You must have the Manage Server permission to perform this action"), + ) + .await; + } else { + import::emboard_direct::import(brain, guild, create).await; + } +} + enum Commands { Leaderboard, Points, Permission, + Import, } fn extract_mentions(mut raw: &str) -> Vec<Id<UserMarker>> { |