diff options
Diffstat (limited to 'src/brain.rs')
-rw-r--r-- | src/brain.rs | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/src/brain.rs b/src/brain.rs new file mode 100644 index 0000000..0ec6a59 --- /dev/null +++ b/src/brain.rs @@ -0,0 +1,125 @@ +use crate::database::Database; + +use twilight_cache_inmemory::DefaultInMemoryCache; +use twilight_gateway::Event; +use twilight_http::{Client as HttpClient, client::InteractionClient}; +use twilight_model::{ + channel::message::Embed, + gateway::payload::incoming::InteractionCreate, + http::interaction::{InteractionResponse, InteractionResponseData, InteractionResponseType}, + id::{ + Id, + marker::{ChannelMarker, GuildMarker, MessageMarker, UserMarker}, + }, +}; +const PROD_APP_ID: u64 = 1363055126264283136; +const DEV_APP_ID: u64 = 1363494986699771984; +const APP_ID: u64 = PROD_APP_ID; + +// A Absolutely Remarkably Terrible Thing +macro_rules! aumau { + ($meow:expr) => { + $meow.await.unwrap().model().await.unwrap() + }; +} + +pub struct Brain { + pub db: Database, + http: HttpClient, + cache: DefaultInMemoryCache, +} + +impl Brain { + pub fn new(db: Database, http: HttpClient, cache: DefaultInMemoryCache) -> Self { + Self { db, http, cache } + } + + pub fn update_cache(&self, event: &Event) { + self.cache.update(event); + } + + /// 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(); + } + + pub async fn send_message_with_embed<S: AsRef<str>>( + &self, + channel: Id<ChannelMarker>, + msg: S, + embed: Embed, + ) -> Id<MessageMarker> { + aumau!( + self.http + .create_message(channel) + .embeds(&[embed]) + .content(msg.as_ref()) + ) + .id + } + + /// 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 + } + } +} + +pub struct Member { + pub id: Id<UserMarker>, + pub handle: String, + pub global_name: Option<String>, + pub nick: Option<String>, +} |