diff --git a/Cargo.lock b/Cargo.lock index 59f5011..32efbfd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -240,6 +240,17 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "command_attr" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88da8d7e9fe6f30d8e3fcf72d0f84102b49de70fece952633e8439e89bdc7631" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.102", +] + [[package]] name = "core-foundation" version = "0.9.3" @@ -890,6 +901,12 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +[[package]] +name = "levenshtein" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db13adb97ab515a3691f56e4dbab09283d0b86cb45abd991d8634a9d6f501760" + [[package]] name = "libc" version = "0.2.155" @@ -924,6 +941,15 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata", +] + [[package]] name = "memchr" version = "2.5.0" @@ -999,6 +1025,16 @@ dependencies = [ "tempfile", ] +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + [[package]] name = "num-conv" version = "0.1.0" @@ -1084,6 +1120,12 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + [[package]] name = "parking_lot" version = "0.12.1" @@ -1113,6 +1155,26 @@ version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +[[package]] +name = "pin-project" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + [[package]] name = "pin-project-lite" version = "0.2.14" @@ -1258,6 +1320,15 @@ dependencies = [ "regex-syntax", ] +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax", +] + [[package]] name = "regex-syntax" version = "0.6.27" @@ -1580,10 +1651,12 @@ dependencies = [ "bitflags 2.5.0", "bytes", "chrono", + "command_attr", "dashmap", "flate2", "futures", "fxhash", + "levenshtein", "mime_guess", "parking_lot", "percent-encoding", @@ -1592,6 +1665,7 @@ dependencies = [ "serde", "serde_cow", "serde_json", + "static_assertions", "time", "tokio", "tokio-tungstenite", @@ -1599,6 +1673,7 @@ dependencies = [ "typemap_rev", "typesize", "url", + "uwl", ] [[package]] @@ -1612,6 +1687,15 @@ dependencies = [ "digest", ] +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + [[package]] name = "signal-hook-registry" version = "1.4.0" @@ -1673,6 +1757,12 @@ version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + [[package]] name = "strsim" version = "0.11.1" @@ -1755,8 +1845,13 @@ dependencies = [ "reqwest", "serde", "serde_json", + "serenity", "tokio", "toml", + "tracing", + "tracing-futures", + "tracing-log", + "tracing-subscriber", ] [[package]] @@ -1802,6 +1897,16 @@ dependencies = [ "syn 1.0.102", ] +[[package]] +name = "thread_local" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +dependencies = [ + "cfg-if", + "once_cell", +] + [[package]] name = "time" version = "0.3.36" @@ -1984,6 +2089,46 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" dependencies = [ "once_cell", + "valuable", +] + +[[package]] +name = "tracing-futures" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" +dependencies = [ + "pin-project", + "tracing", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", ] [[package]] @@ -2132,6 +2277,18 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5190c9442dcdaf0ddd50f37420417d219ae5261bbf5db120d0f9bab996c9cba1" +[[package]] +name = "uwl" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4bf03e0ca70d626ecc4ba6b0763b934b6f2976e8c744088bb3c1d646fbb1ad0" + +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + [[package]] name = "vcpkg" version = "0.2.15" diff --git a/Cargo.toml b/Cargo.toml index bdcc2d8..fb0af1a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,10 +20,15 @@ humantime = "2.1.0" itertools = "0.10.3" lastfm-rs = "0.5.0" poise = "0.6.1" +serenity = "0.12.2" serde = { version = "1.0.203", features = ["derive"] } serde_json = "1.0.117" tokio = { version = "1.38.0", features = ["full"] } toml = "0.5.8" +tracing = "0.1.40" +tracing-futures = "0.2.5" +tracing-log = "0.2.0" +tracing-subscriber = { version = "0.3.16", features = ["env-filter"] } [dependencies.reqwest] version = "0.11.12" diff --git a/src/listeners/handler.rs b/src/listeners/handler.rs new file mode 100644 index 0000000..fdaf86f --- /dev/null +++ b/src/listeners/handler.rs @@ -0,0 +1,30 @@ +use serenity::{all::{ActivityData, Context, EventHandler, OnlineStatus, Ready}, async_trait}; +use tracing::info; + +pub struct Handler; + +#[async_trait] +impl EventHandler for Handler { + async fn ready(&self, context: Context, ready: Ready) { + let http = &context.http; + + let api_version = ready.version; + let bot_gateway = http.get_bot_gateway().await.unwrap(); + let bot_owner = http.get_current_application_info().await.unwrap().owner.expect("Could not get owner!"); + let t_sessions = bot_gateway.session_start_limit.total; + let r_sessions = bot_gateway.session_start_limit.remaining; + + info!("Successfully logged into Discord as the following user:"); + info!("Bot username: {}", ready.user.tag()); + info!("Bot user ID: {}", ready.user.id); + info!("Bot owner: {}", bot_owner.tag()); + + let guild_count = ready.guilds.len(); + + info!("Connected to the Discord API (version {api_version}) with {r_sessions}/{t_sessions} sessions remaining."); + info!("Connected to and serving a total of {guild_count} guild(s)."); + + let presence = format!("on {guild_count} guilds | e.help"); + context.set_presence(Some(ActivityData::playing(presence)), OnlineStatus::Online); + } +} diff --git a/src/listeners/mod.rs b/src/listeners/mod.rs new file mode 100644 index 0000000..062ae9d --- /dev/null +++ b/src/listeners/mod.rs @@ -0,0 +1 @@ +pub mod handler; diff --git a/src/main.rs b/src/main.rs index 26f34ab..0cb586a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,9 +1,14 @@ use crate::serenity::GatewayIntents; +use listeners::handler::Handler; use poise::serenity_prelude as serenity; use poise::{builtins::register_application_commands_buttons, Framework, FrameworkOptions, PrefixFrameworkOptions}; +use tracing::{info, Level}; +use tracing_log::LogTracer; +use tracing_subscriber::{EnvFilter, FmtSubscriber}; use utils::read_config; mod config; +mod listeners; mod utils; type Error = Box; @@ -20,6 +25,28 @@ async fn register(ctx: Context<'_>) -> Result<(), Error> { #[tokio::main(worker_threads = 16)] async fn main() -> Result<(), Error> { let configuration = read_config("config.toml"); + if configuration.bot.logging.enabled { + LogTracer::init()?; + + let level = match configuration.bot.logging.level.as_str() { + "error" => Level::ERROR, + "warn" => Level::WARN, + "info" => Level::INFO, + "debug" => Level::DEBUG, + _ => Level::TRACE, + }; + + let subscriber = FmtSubscriber::builder() + .with_target(false) + .with_max_level(level) + .with_env_filter(EnvFilter::from_default_env()) + .finish(); + + tracing::subscriber::set_global_default(subscriber)?; + + info!("Tracing initialized with logging level set to {}.", level); + } + let token = configuration.bot.discord.token; let framework = Framework::builder() .options(FrameworkOptions { @@ -33,7 +60,7 @@ async fn main() -> Result<(), Error> { .setup(move |_ctx, _ready, _framework| Box::pin(async move { Ok(Data {}) })) .build(); - let client = serenity::Client::builder(token, GatewayIntents::all()).framework(framework).await; + let client = serenity::Client::builder(token, GatewayIntents::all()).event_handler(Handler).framework(framework).await; client.unwrap().start().await.unwrap(); Ok(())