spiffbot/src/main.rs
2024-09-09 07:40:00 -03:00

161 lines
4.9 KiB
Rust

#![deny(clippy::unwrap_used)]
#![deny(clippy::expect_used)]
#![deny(clippy::pedantic)]
mod arguments;
mod bot;
mod commands;
mod constants;
mod lua;
mod tasks;
use std::collections::HashMap;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{Arc, Condvar, OnceLock};
use bot::BotHandler;
use commands::{Command, CommandFnKind};
use metadata::LevelFilter;
use serenity::all::GatewayIntents;
use serenity::all::{Context, GuildId, ShardManager};
use serenity::model::channel::Message;
use serenity::Client;
use tracing::*;
// pub const CAT_DEV: &'static str = "Dev";
pub const CAT_FUN: &'static str = "Fun";
pub const CAT_MOD: &'static str = "Moderation";
pub const CAT_GEN: &'static str = "General";
pub const CAT_INF: &'static str = "Info";
pub const CAT_HID: &'static str = "Hidden";
static SHARD_MANAGER: OnceLock<Arc<ShardManager>> = OnceLock::new();
// static SHARDS_READY: AtomicBool = AtomicBool::new(false);
static DO_SHUTDOWN: (AtomicBool, Condvar) = (AtomicBool::new(false), Condvar::new()); // atombool and condvar combo to ensure maximum coverage when the bot needs to power off
#[tokio::main]
async fn main() {
tracing::subscriber::set_global_default(
tracing_subscriber::fmt()
.with_max_level(LevelFilter::INFO)
.finish(),
)
.unwrap();
info!("Logging initialized.");
let mut commands = HashMap::default();
info!("Loading stock commands.");
insert_stock(&mut commands);
info!("Loading rust dynamic commands.");
insert_rust(&mut commands);
info!("Initializing Lua runtime.");
let mut lua = lua::initialize(); // may not need to be mutable, but its fine for now
info!("Loading lua commandlets.");
insert_lua(&mut commands, &mut lua);
warn!("ABORTING CONNECTING TO DISCORD, BYE BYE!");
return;
// // TODO load this at runtime so the key will not be stored in the binary?
// #[cfg(not(debug_assertions))]
// let token = {
// info!("Initializing bot with production token.");
// include_str!("bot_token.prod")
// };
// #[cfg(debug_assertions)]
// let token = {
// info!("Initializing bot with development token.");
// include_str!("bot_token.dev")
// };
// let intents = GatewayIntents::DIRECT_MESSAGES
// | GatewayIntents::DIRECT_MESSAGE_REACTIONS
// | GatewayIntents::GUILDS
// | GatewayIntents::GUILD_MODERATION
// // | GatewayIntents::GUILD_EMOJIS_AND_STICKERS
// | GatewayIntents::GUILD_MEMBERS
// | GatewayIntents::GUILD_MESSAGE_REACTIONS
// | GatewayIntents::GUILD_MESSAGES
// | GatewayIntents::MESSAGE_CONTENT;
// let mut client = match Client::builder(&token, intents)
// .event_handler(BotHandler { commands })
// .await
// {
// Ok(client) => client,
// Err(err) => panic!("Error starting client connection: `{err}`"),
// };
// SHARD_MANAGER.set(client.shard_manager.clone()).unwrap();
// if let Err(why) = client.start_shards(2).await {
// error!("Client error: {why:?}");
// }
// warn!("MAIN FUNCTION EXITING");
}
/// The last set of commands, these are used by the hoster of the engine.
pub fn insert_lua(_commands: &mut HashMap<String, Command>, _lua: &mut mlua::Lua) {
// commands.insert(
// "stop".to_owned(),
// Command::new("stop".to_owned())
// .alias("svs".to_owned())
// .category(CAT_HID.to_owned())
// .hidden(true)
// .dm_command(CommandFnKind::Rust(stop_command))
// .guild_command(CommandFnKind::Rust(stop_command))
// .pretty_name("Stop the bot".to_owned())
// .help("Stops the bot. Does nothing unless you are a developer.".to_owned()),
// );
}
/// Cannot use any command names of stock commands, but gets to pick before lua commands are loaded.
pub fn insert_rust(_commands: &mut HashMap<String, Command>) {
// commands.insert(
// "stop".to_owned(),
// Command::new("stop".to_owned())
// .alias("svs".to_owned())
// .category(CAT_HID.to_owned())
// .hidden(true)
// .dm_command(CommandFnKind::Rust(stop_command))
// .guild_command(CommandFnKind::Rust(stop_command))
// .pretty_name("Stop the bot".to_owned())
// .help("Stops the bot. Does nothing unless you are a developer.".to_owned()),
// );
}
/// Will never fail, gets first pick of command names and properties. It is up to the maintainer to make damn sure this works.
pub fn insert_stock(commands: &mut HashMap<String, Command>) {
commands.insert(
"stop".to_owned(),
Command::new("stop".to_owned())
.alias("svs".to_owned())
.category(CAT_HID.to_owned())
.hidden(true)
.dm_command(CommandFnKind::Rust(stop_command))
.guild_command(CommandFnKind::Rust(stop_command))
.pretty_name("Stop the bot".to_owned())
.help("Stops the bot. Does nothing unless you are a developer.".to_owned()),
);
}
fn stop_command(_: Context, msg: Message, _: Option<GuildId>) {
// hardcode my id for now
if msg.author.id != 380045419381784576 {
return;
}
DO_SHUTDOWN.0.store(true, Ordering::SeqCst);
DO_SHUTDOWN.1.notify_all();
let handle = tokio::runtime::Handle::current();
let _eg = handle.enter();
handle.spawn(async {
SHARD_MANAGER.get().unwrap().shutdown_all().await;
});
}