123 lines
3.0 KiB
Rust
123 lines
3.0 KiB
Rust
use clap::Parser;
|
|
use fomo_reducer::{VCs, initialize_vcs, update_vcs};
|
|
use opendal::{IntoOperatorUri, Operator, OperatorUri};
|
|
use secrecy::{ExposeSecret, SecretString};
|
|
use snafu::Snafu;
|
|
use std::{fmt::Debug, str::FromStr};
|
|
use tracing_subscriber::fmt::format::FmtSpan;
|
|
use twilight_gateway::{
|
|
Event, EventTypeFlags, Intents, Shard, ShardId, StreamExt, error::ReceiveMessageErrorType,
|
|
};
|
|
use twilight_model::id::{Id, marker::UserMarker};
|
|
|
|
#[derive(Clone)]
|
|
struct OpendalOperator {
|
|
uri: OperatorUri,
|
|
operator: Operator,
|
|
}
|
|
|
|
impl FromStr for OpendalOperator {
|
|
type Err = opendal::Error;
|
|
|
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
|
let uri = s.into_operator_uri()?;
|
|
let operator = Operator::from_uri(&uri)?;
|
|
|
|
Ok(Self { uri, operator })
|
|
}
|
|
}
|
|
|
|
impl OpendalOperator {
|
|
fn into_inner(self) -> Operator {
|
|
self.operator
|
|
}
|
|
}
|
|
|
|
impl From<OpendalOperator> for Operator {
|
|
fn from(wrapper: OpendalOperator) -> Self {
|
|
wrapper.into_inner()
|
|
}
|
|
}
|
|
|
|
impl Debug for OpendalOperator {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
Debug::fmt(&self.uri, f)
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Parser)]
|
|
struct Args {
|
|
#[arg(long, env)]
|
|
discord_token: SecretString,
|
|
|
|
#[arg(long, env)]
|
|
storage: OpendalOperator,
|
|
|
|
#[arg(long, env)]
|
|
bot_owner: Id<UserMarker>,
|
|
}
|
|
|
|
#[derive(Debug, Snafu)]
|
|
enum MainError {}
|
|
|
|
#[snafu::report]
|
|
#[tokio::main]
|
|
async fn main() -> Result<(), MainError> {
|
|
tracing_subscriber::fmt()
|
|
.pretty()
|
|
.with_span_events(FmtSpan::NEW | FmtSpan::CLOSE)
|
|
.init();
|
|
|
|
let args = Parser::parse();
|
|
|
|
tracing::debug!(?args, "using");
|
|
|
|
let Args {
|
|
discord_token,
|
|
storage,
|
|
bot_owner,
|
|
} = args;
|
|
|
|
rustls::crypto::aws_lc_rs::default_provider()
|
|
.install_default()
|
|
.unwrap();
|
|
|
|
let shard_id = ShardId::new(0, 1);
|
|
let intents = Intents::GUILD_VOICE_STATES;
|
|
let mut shard = Shard::new(shard_id, discord_token.expose_secret().to_owned(), intents);
|
|
|
|
let vc_event_types = EventTypeFlags::GUILD_VOICE_STATES;
|
|
let mut next_event = shard.next_event(vc_event_types);
|
|
|
|
let discord_client = twilight_http::Client::new(discord_token.expose_secret().to_owned());
|
|
let mut voice_status = initialize_vcs(&discord_client).await;
|
|
while let Some(event_res) = next_event.await {
|
|
match event_res {
|
|
Ok(event) => {
|
|
tracing::debug!(?voice_status, "before handling");
|
|
handle_event(event, &mut voice_status).await;
|
|
tracing::debug!(?voice_status, "after handling");
|
|
}
|
|
Err(error) => {
|
|
tracing::error!(?error);
|
|
}
|
|
}
|
|
|
|
next_event = shard.next_event(vc_event_types);
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[tracing::instrument(skip(vcs))]
|
|
async fn handle_event(event: Event, vcs: &mut VCs) {
|
|
match event {
|
|
Event::VoiceStateUpdate(voice_state_update) => {
|
|
update_vcs(&voice_state_update, vcs);
|
|
}
|
|
other => {
|
|
tracing::warn!(?other, "wasn't expected");
|
|
}
|
|
}
|
|
}
|