2022-02-19 13:28:24 +00:00
|
|
|
#![feature(int_roundings)]
|
2020-08-26 17:26:28 +00:00
|
|
|
#[macro_use]
|
|
|
|
extern crate lazy_static;
|
|
|
|
|
2020-08-09 22:59:31 +00:00
|
|
|
mod commands;
|
2021-09-11 19:40:58 +00:00
|
|
|
mod component_models;
|
2020-09-28 12:42:20 +00:00
|
|
|
mod consts;
|
2022-02-19 13:28:24 +00:00
|
|
|
mod event_handlers;
|
2020-10-12 20:01:27 +00:00
|
|
|
mod framework;
|
2021-09-22 20:12:29 +00:00
|
|
|
mod hooks;
|
2022-02-01 23:04:31 +00:00
|
|
|
mod interval_parser;
|
2020-10-12 20:01:27 +00:00
|
|
|
mod models;
|
|
|
|
mod time_parser;
|
2022-02-19 13:28:24 +00:00
|
|
|
mod utils;
|
2020-08-06 14:22:13 +00:00
|
|
|
|
2021-12-20 13:48:18 +00:00
|
|
|
use std::{
|
|
|
|
collections::HashMap,
|
|
|
|
env,
|
2022-02-19 13:28:24 +00:00
|
|
|
sync::{atomic::AtomicBool, Arc},
|
2021-12-20 13:48:18 +00:00
|
|
|
};
|
2021-09-06 12:46:16 +00:00
|
|
|
|
|
|
|
use chrono_tz::Tz;
|
|
|
|
use dotenv::dotenv;
|
2022-02-19 13:28:24 +00:00
|
|
|
use log::info;
|
2020-08-06 14:22:13 +00:00
|
|
|
use serenity::{
|
2022-02-01 23:04:31 +00:00
|
|
|
client::Client,
|
2022-02-19 13:28:24 +00:00
|
|
|
http::client::Http,
|
2020-10-03 16:31:23 +00:00
|
|
|
model::{
|
2022-02-19 13:28:24 +00:00
|
|
|
gateway::GatewayIntents,
|
2020-10-12 20:01:27 +00:00
|
|
|
id::{GuildId, UserId},
|
2020-09-15 13:43:49 +00:00
|
|
|
},
|
2022-02-19 13:28:24 +00:00
|
|
|
prelude::TypeMapKey,
|
2020-08-06 14:22:13 +00:00
|
|
|
};
|
2020-11-20 16:37:39 +00:00
|
|
|
use sqlx::mysql::MySqlPool;
|
2022-02-06 15:47:59 +00:00
|
|
|
use tokio::sync::RwLock;
|
2020-08-06 14:22:13 +00:00
|
|
|
|
2020-09-28 12:42:20 +00:00
|
|
|
use crate::{
|
2021-09-24 11:55:35 +00:00
|
|
|
commands::{info_cmds, moderation_cmds, reminder_cmds, todo_cmds},
|
2021-09-11 19:40:58 +00:00
|
|
|
component_models::ComponentDataModel,
|
2022-02-19 13:28:24 +00:00
|
|
|
consts::THEME_COLOR,
|
2020-09-28 12:42:20 +00:00
|
|
|
framework::RegexFramework,
|
2021-10-26 20:10:14 +00:00
|
|
|
models::command_macro::CommandMacro,
|
2020-08-09 22:59:31 +00:00
|
|
|
};
|
2020-10-11 16:41:26 +00:00
|
|
|
|
2020-08-06 14:22:13 +00:00
|
|
|
struct SQLPool;
|
|
|
|
|
|
|
|
impl TypeMapKey for SQLPool {
|
2020-11-20 16:37:39 +00:00
|
|
|
type Value = MySqlPool;
|
2020-08-06 14:22:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
struct ReqwestClient;
|
|
|
|
|
|
|
|
impl TypeMapKey for ReqwestClient {
|
|
|
|
type Value = Arc<reqwest::Client>;
|
|
|
|
}
|
|
|
|
|
2021-01-19 12:19:20 +00:00
|
|
|
struct PopularTimezones;
|
|
|
|
|
|
|
|
impl TypeMapKey for PopularTimezones {
|
|
|
|
type Value = Arc<Vec<Tz>>;
|
|
|
|
}
|
|
|
|
|
2021-09-22 20:12:29 +00:00
|
|
|
struct RecordingMacros;
|
|
|
|
|
|
|
|
impl TypeMapKey for RecordingMacros {
|
|
|
|
type Value = Arc<RwLock<HashMap<(GuildId, UserId), CommandMacro>>>;
|
|
|
|
}
|
|
|
|
|
2021-12-20 13:48:18 +00:00
|
|
|
struct Handler {
|
|
|
|
is_loop_running: AtomicBool,
|
|
|
|
}
|
2020-10-18 16:26:07 +00:00
|
|
|
|
2020-08-06 14:22:13 +00:00
|
|
|
#[tokio::main]
|
|
|
|
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
2020-10-17 22:56:19 +00:00
|
|
|
env_logger::init();
|
|
|
|
|
2020-08-06 14:22:13 +00:00
|
|
|
dotenv()?;
|
|
|
|
|
2020-10-11 16:41:26 +00:00
|
|
|
let token = env::var("DISCORD_TOKEN").expect("Missing DISCORD_TOKEN from environment");
|
|
|
|
|
2021-12-20 13:48:18 +00:00
|
|
|
let application_id = {
|
|
|
|
let http = Http::new_with_token(&token);
|
2020-10-11 16:41:26 +00:00
|
|
|
|
2021-12-20 13:48:18 +00:00
|
|
|
http.get_current_application_info().await?.id
|
|
|
|
};
|
2020-10-12 17:37:14 +00:00
|
|
|
|
2021-01-19 12:01:14 +00:00
|
|
|
let dm_enabled = env::var("DM_ENABLED").map_or(true, |var| var == "1");
|
|
|
|
|
2021-10-30 19:57:33 +00:00
|
|
|
let framework = RegexFramework::new()
|
2020-10-12 18:12:33 +00:00
|
|
|
.ignore_bots(env::var("IGNORE_BOTS").map_or(true, |var| var == "1"))
|
2021-09-10 17:09:25 +00:00
|
|
|
.debug_guild(env::var("DEBUG_GUILD").map_or(None, |g| {
|
2021-09-10 23:14:23 +00:00
|
|
|
Some(GuildId(g.parse::<u64>().expect("DEBUG_GUILD must be a guild ID")))
|
2021-09-10 17:09:25 +00:00
|
|
|
}))
|
2021-01-19 12:01:14 +00:00
|
|
|
.dm_enabled(dm_enabled)
|
2020-10-17 14:21:00 +00:00
|
|
|
// info commands
|
2021-11-13 14:12:37 +00:00
|
|
|
.add_command(&info_cmds::HELP_COMMAND)
|
2021-09-06 12:46:16 +00:00
|
|
|
.add_command(&info_cmds::INFO_COMMAND)
|
|
|
|
.add_command(&info_cmds::DONATE_COMMAND)
|
2021-09-10 17:09:25 +00:00
|
|
|
.add_command(&info_cmds::DASHBOARD_COMMAND)
|
|
|
|
.add_command(&info_cmds::CLOCK_COMMAND)
|
2020-10-17 14:21:00 +00:00
|
|
|
// reminder commands
|
2021-09-12 15:09:57 +00:00
|
|
|
.add_command(&reminder_cmds::TIMER_COMMAND)
|
2021-09-18 12:40:30 +00:00
|
|
|
.add_command(&reminder_cmds::REMIND_COMMAND)
|
2021-09-16 17:30:16 +00:00
|
|
|
// management commands
|
|
|
|
.add_command(&reminder_cmds::DELETE_COMMAND)
|
2021-09-11 19:40:58 +00:00
|
|
|
.add_command(&reminder_cmds::LOOK_COMMAND)
|
2021-09-10 23:14:23 +00:00
|
|
|
.add_command(&reminder_cmds::PAUSE_COMMAND)
|
2021-09-11 19:40:58 +00:00
|
|
|
.add_command(&reminder_cmds::OFFSET_COMMAND)
|
|
|
|
.add_command(&reminder_cmds::NUDGE_COMMAND)
|
2020-10-17 14:21:00 +00:00
|
|
|
// to-do commands
|
2021-09-24 11:55:35 +00:00
|
|
|
.add_command(&todo_cmds::TODO_COMMAND)
|
2020-10-17 14:21:00 +00:00
|
|
|
// moderation commands
|
2021-09-10 23:14:23 +00:00
|
|
|
.add_command(&moderation_cmds::TIMEZONE_COMMAND)
|
2021-09-22 20:12:29 +00:00
|
|
|
.add_command(&moderation_cmds::MACRO_CMD_COMMAND)
|
|
|
|
.add_hook(&hooks::CHECK_SELF_PERMISSIONS_HOOK)
|
2021-10-30 19:57:33 +00:00
|
|
|
.add_hook(&hooks::MACRO_CHECK_HOOK);
|
2020-08-06 14:22:13 +00:00
|
|
|
|
2021-03-14 10:27:30 +00:00
|
|
|
let framework_arc = Arc::new(framework);
|
2020-09-03 23:29:19 +00:00
|
|
|
|
2020-10-25 11:19:21 +00:00
|
|
|
let mut client = Client::builder(&token)
|
2021-11-07 13:23:41 +00:00
|
|
|
.intents(GatewayIntents::GUILDS)
|
2021-06-27 15:31:54 +00:00
|
|
|
.application_id(application_id.0)
|
2021-12-20 13:48:18 +00:00
|
|
|
.event_handler(Handler { is_loop_running: AtomicBool::from(false) })
|
2020-10-12 20:01:27 +00:00
|
|
|
.await
|
|
|
|
.expect("Error occurred creating client");
|
2020-08-06 14:22:13 +00:00
|
|
|
|
2020-08-07 15:45:19 +00:00
|
|
|
{
|
2020-11-20 16:37:39 +00:00
|
|
|
let pool = MySqlPool::connect(
|
2020-10-12 20:01:27 +00:00
|
|
|
&env::var("DATABASE_URL").expect("Missing DATABASE_URL from environment"),
|
|
|
|
)
|
|
|
|
.await
|
|
|
|
.unwrap();
|
2020-08-07 15:45:19 +00:00
|
|
|
|
2021-01-19 12:19:20 +00:00
|
|
|
let popular_timezones = sqlx::query!(
|
|
|
|
"SELECT timezone FROM users GROUP BY timezone ORDER BY COUNT(timezone) DESC LIMIT 21"
|
|
|
|
)
|
|
|
|
.fetch_all(&pool)
|
|
|
|
.await
|
|
|
|
.unwrap()
|
|
|
|
.iter()
|
|
|
|
.map(|t| t.timezone.parse::<Tz>().unwrap())
|
|
|
|
.collect::<Vec<Tz>>();
|
|
|
|
|
2020-08-07 15:45:19 +00:00
|
|
|
let mut data = client.data.write().await;
|
|
|
|
|
|
|
|
data.insert::<SQLPool>(pool);
|
2021-01-19 12:19:20 +00:00
|
|
|
data.insert::<PopularTimezones>(Arc::new(popular_timezones));
|
2020-08-07 15:45:19 +00:00
|
|
|
data.insert::<ReqwestClient>(Arc::new(reqwest::Client::new()));
|
2021-09-10 17:09:25 +00:00
|
|
|
data.insert::<RegexFramework>(framework_arc.clone());
|
2021-09-22 20:12:29 +00:00
|
|
|
data.insert::<RecordingMacros>(Arc::new(RwLock::new(HashMap::new())));
|
2020-08-07 15:45:19 +00:00
|
|
|
}
|
|
|
|
|
2021-11-13 14:12:37 +00:00
|
|
|
framework_arc.build_slash(&client.cache_and_http.http).await;
|
|
|
|
|
2022-02-19 13:28:24 +00:00
|
|
|
info!("Starting client as autosharded");
|
2020-10-17 22:56:19 +00:00
|
|
|
|
2022-02-19 13:28:24 +00:00
|
|
|
client.start_autosharded().await?;
|
2020-08-06 14:22:13 +00:00
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|