spoticord/src/main.rs

158 lines
4.0 KiB
Rust
Raw Normal View History

2022-10-18 20:59:32 +00:00
use dotenv::dotenv;
2023-03-03 09:03:57 +00:00
use crate::{bot::commands::CommandManager, database::Database, session::manager::SessionManager};
2022-10-18 20:59:32 +00:00
use log::*;
use serenity::{framework::StandardFramework, prelude::GatewayIntents, Client};
use songbird::SerenityInit;
use std::{any::Any, env, process::exit};
2022-10-18 20:59:32 +00:00
#[cfg(unix)]
use tokio::signal::unix::SignalKind;
2022-10-18 20:59:32 +00:00
mod audio;
mod bot;
2022-11-01 08:36:25 +00:00
mod consts;
2022-10-18 20:59:32 +00:00
mod database;
mod librespot_ext;
mod player;
mod session;
mod utils;
2023-09-19 11:49:32 +00:00
#[cfg(feature = "stats")]
mod stats;
#[cfg(feature = "stats")]
use crate::stats::StatsManager;
#[tokio::main]
2022-10-18 20:59:32 +00:00
async fn main() {
2022-10-31 21:46:34 +00:00
if std::env::var("RUST_LOG").is_err() {
#[cfg(debug_assertions)]
{
std::env::set_var("RUST_LOG", "spoticord");
}
#[cfg(not(debug_assertions))]
{
std::env::set_var("RUST_LOG", "spoticord=info");
}
}
2022-10-18 20:59:32 +00:00
env_logger::init();
info!("It's a good day");
2023-01-02 18:08:45 +00:00
info!(" - Spoticord {}", time::OffsetDateTime::now_utc().year());
2022-10-18 20:59:32 +00:00
let result = dotenv();
if let Ok(path) = result {
debug!(
"Loaded environment file: {}",
path.to_str().expect("to get the string")
);
2022-10-18 20:59:32 +00:00
} else {
warn!("No .env file found, expecting all necessary environment variables");
}
2022-11-07 15:54:41 +00:00
let token = env::var("DISCORD_TOKEN").expect("a token in the environment");
2022-10-18 20:59:32 +00:00
let db_url = env::var("DATABASE_URL").expect("a database URL in the environment");
2022-10-31 21:46:34 +00:00
2023-09-19 11:49:32 +00:00
#[cfg(feature = "stats")]
let stats_manager =
StatsManager::new(env::var("KV_URL").expect("a redis URL in the environment"))
.expect("Failed to connect to redis");
2022-10-31 21:46:34 +00:00
let session_manager = SessionManager::new();
2022-10-18 20:59:32 +00:00
// Create client
let mut client = Client::builder(
token,
GatewayIntents::GUILDS | GatewayIntents::GUILD_VOICE_STATES,
)
.event_handler(crate::bot::events::Handler)
.framework(StandardFramework::new())
.register_songbird()
.await
.expect("to create a client");
2022-10-18 20:59:32 +00:00
{
let mut data = client.data.write().await;
data.insert::<Database>(Database::new(db_url, None));
data.insert::<CommandManager>(CommandManager::new());
2022-10-31 21:46:34 +00:00
data.insert::<SessionManager>(session_manager.clone());
2022-10-18 20:59:32 +00:00
}
let shard_manager = client.shard_manager.clone();
2023-09-19 11:49:32 +00:00
#[cfg(feature = "stats")]
let cache = client.cache_and_http.cache.clone();
2022-10-31 21:46:34 +00:00
#[cfg(unix)]
2022-11-07 14:07:40 +00:00
let mut term: Option<Box<dyn Any + Send>> = Some(Box::new(
tokio::signal::unix::signal(SignalKind::terminate())
.expect("to be able to create the signal stream"),
2022-11-07 14:07:40 +00:00
));
#[cfg(not(unix))]
let term: Option<Box<dyn Any + Send>> = None;
2022-10-18 20:59:32 +00:00
2022-10-31 21:46:34 +00:00
// Background tasks
2022-10-18 20:59:32 +00:00
tokio::spawn(async move {
2022-10-31 21:46:34 +00:00
loop {
tokio::select! {
2023-09-19 11:49:32 +00:00
_ = tokio::time::sleep(std::time::Duration::from_secs(60)) => {
#[cfg(feature = "stats")]
{
let guild_count = cache.guilds().len();
let active_count = session_manager.get_active_session_count().await;
if let Err(why) = stats_manager.set_server_count(guild_count) {
error!("Failed to update server count: {why}");
}
if let Err(why) = stats_manager.set_active_count(active_count) {
error!("Failed to update active count: {why}");
}
}
}
2022-10-31 21:46:34 +00:00
_ = tokio::signal::ctrl_c() => {
info!("Received interrupt signal, shutting down...");
2023-09-18 20:39:11 +00:00
session_manager.shutdown().await;
2022-10-31 21:46:34 +00:00
shard_manager.lock().await.shutdown_all().await;
break;
}
_ = async {
2022-11-07 11:58:22 +00:00
#[cfg(unix)]
match term {
Some(ref mut term) => {
let term = term.downcast_mut::<tokio::signal::unix::Signal>().expect("to be able to downcast");
term.recv().await
}
_ => None
}
}, if term.is_some() => {
2022-10-31 21:46:34 +00:00
info!("Received terminate signal, shutting down...");
2023-09-18 20:39:11 +00:00
session_manager.shutdown().await;
2022-10-31 21:46:34 +00:00
shard_manager.lock().await.shutdown_all().await;
break;
}
}
}
2022-10-18 20:59:32 +00:00
});
2022-10-31 21:46:34 +00:00
// Start the bot
2022-10-18 20:59:32 +00:00
if let Err(why) = client.start_autosharded().await {
2022-10-31 21:46:34 +00:00
error!("FATAL Error in bot: {:?}", why);
exit(1);
2022-10-18 20:59:32 +00:00
}
}