Attempt to figure out why it crashes

This commit is contained in:
Yash Karandikar 2022-07-07 11:52:39 +05:30
parent f34c424425
commit 67500f8e98
4 changed files with 96 additions and 34 deletions

5
Cargo.lock generated
View file

@ -206,6 +206,7 @@ dependencies = [
"serde", "serde",
"serenity", "serenity",
"tokio", "tokio",
"tokio-stream",
"toml", "toml",
"vergen", "vergen",
] ]
@ -1476,9 +1477,9 @@ dependencies = [
[[package]] [[package]]
name = "tokio-stream" name = "tokio-stream"
version = "0.1.8" version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "50145484efff8818b5ccd256697f36863f587da82cf8b409c53adf1e840798e3" checksum = "df54d54117d6fdc4e4fea40fe1e4e566b3505700e148a6827e59b34b0d2600d9"
dependencies = [ dependencies = [
"futures-core", "futures-core",
"pin-project-lite", "pin-project-lite",

View file

@ -13,6 +13,7 @@ serde = "1.0"
lazy_static = "1.4" lazy_static = "1.4"
pulldown-cmark = "0.9.1" pulldown-cmark = "0.9.1"
fancy-regex = "0.10.0" fancy-regex = "0.10.0"
tokio-stream = "0.1.9"
[dependencies.tokio] [dependencies.tokio]
version = "1.15.0" version = "1.15.0"

View file

@ -2,7 +2,9 @@ use irc::{client::Client as IrcClient, proto::Command};
use std::{collections::HashMap, sync::Arc}; use std::{collections::HashMap, sync::Arc};
use tokio::sync::Mutex; use tokio::sync::{mpsc::unbounded_channel, Mutex};
use tokio_stream::wrappers::UnboundedReceiverStream;
use serenity::{ use serenity::{
futures::StreamExt, futures::StreamExt,
@ -27,6 +29,7 @@ macro_rules! unwrap_or_continue {
}; };
} }
#[allow(clippy::too_many_lines)] // missing, fight me
pub async fn irc_loop( pub async fn irc_loop(
mut client: IrcClient, mut client: IrcClient,
http: Arc<Http>, http: Arc<Http>,
@ -34,6 +37,9 @@ pub async fn irc_loop(
webhooks: HashMap<String, Webhook>, webhooks: HashMap<String, Webhook>,
members: Arc<Mutex<Vec<Member>>>, members: Arc<Mutex<Vec<Member>>>,
) -> anyhow::Result<()> { ) -> anyhow::Result<()> {
let (send, recv) = unbounded_channel();
tokio::spawn(msg_task(UnboundedReceiverStream::new(recv)));
let mut avatar_cache: HashMap<String, Option<String>> = HashMap::new(); let mut avatar_cache: HashMap<String, Option<String>> = HashMap::new();
let mut id_cache: HashMap<String, Option<u64>> = HashMap::new(); let mut id_cache: HashMap<String, Option<u64>> = HashMap::new();
let mut channel_users: HashMap<String, Vec<String>> = HashMap::new(); let mut channel_users: HashMap<String, Vec<String>> = HashMap::new();
@ -63,7 +69,6 @@ pub async fn irc_loop(
}; };
let nickname = unwrap_or_continue!(orig_message.source_nickname()); let nickname = unwrap_or_continue!(orig_message.source_nickname());
if let Command::PRIVMSG(ref channel, ref message) = orig_message.command { if let Command::PRIVMSG(ref channel, ref message) = orig_message.command {
let channel_id = ChannelId::from(*unwrap_or_continue!(mapping.get(channel))); let channel_id = ChannelId::from(*unwrap_or_continue!(mapping.get(channel)));
@ -90,19 +95,20 @@ pub async fn irc_loop(
}) })
}); });
webhook let m = QueuedMessage::Webhook {
.execute(&http, false, |w| { webhook: webhook.clone(),
if let Some(ref url) = avatar { http: http.clone(),
w.avatar_url(url); avatar_url: avatar.clone(),
} content: computed,
nickname: nickname.to_string(),
w.username(nickname).content(computed) };
}) send.send(m)?;
.await?;
} else { } else {
channel_id send.send(QueuedMessage::Raw {
.say(&http, format!("<{}> {}", nickname, computed)) channel_id,
.await?; http: http.clone(),
message: format!("<{}>, {}", nickname, computed),
})?;
} }
} else if let Command::JOIN(ref channel, _, _) = orig_message.command { } else if let Command::JOIN(ref channel, _, _) = orig_message.command {
let channel_id = ChannelId::from(*unwrap_or_continue!(mapping.get(channel))); let channel_id = ChannelId::from(*unwrap_or_continue!(mapping.get(channel)));
@ -110,9 +116,11 @@ pub async fn irc_loop(
users.push(nickname.to_string()); users.push(nickname.to_string());
channel_id send.send(QueuedMessage::Raw {
.say(&http, format!("*{}* has joined the channel", nickname)) channel_id,
.await?; http: http.clone(),
message: format!("*{}* has joined the channel", nickname),
})?;
} else if let Command::PART(ref channel, ref reason) = orig_message.command { } else if let Command::PART(ref channel, ref reason) = orig_message.command {
let users = unwrap_or_continue!(channel_users.get_mut(channel)); let users = unwrap_or_continue!(channel_users.get_mut(channel));
let channel_id = ChannelId::from(*unwrap_or_continue!(mapping.get(channel))); let channel_id = ChannelId::from(*unwrap_or_continue!(mapping.get(channel)));
@ -122,9 +130,11 @@ pub async fn irc_loop(
let reason = reason.as_deref().unwrap_or("Connection closed"); let reason = reason.as_deref().unwrap_or("Connection closed");
channel_id send.send(QueuedMessage::Raw {
.say(&http, format!("*{}* has quit ({})", nickname, reason)) channel_id,
.await?; http: http.clone(),
message: format!("*{}* has quit ({})", nickname, reason),
})?;
} else if let Command::QUIT(ref reason) = orig_message.command { } else if let Command::QUIT(ref reason) = orig_message.command {
for (channel, users) in &mut channel_users { for (channel, users) in &mut channel_users {
let channel_id = ChannelId::from(*unwrap_or_continue!(mapping.get(channel))); let channel_id = ChannelId::from(*unwrap_or_continue!(mapping.get(channel)));
@ -134,9 +144,11 @@ pub async fn irc_loop(
let reason = reason.as_deref().unwrap_or("Connection closed"); let reason = reason.as_deref().unwrap_or("Connection closed");
channel_id send.send(QueuedMessage::Raw {
.say(&http, format!("*{}* has quit ({})", nickname, reason)) channel_id,
.await?; http: http.clone(),
message: format!("*{}* has quit ({})", nickname, reason),
})?;
} }
} else if let Command::NICK(ref new_nick) = orig_message.command { } else if let Command::NICK(ref new_nick) = orig_message.command {
for (channel, users) in &mut channel_users { for (channel, users) in &mut channel_users {
@ -145,12 +157,11 @@ pub async fn irc_loop(
users[pos] = new_nick.to_string(); users[pos] = new_nick.to_string();
channel_id send.send(QueuedMessage::Raw {
.say( channel_id,
&http, http: http.clone(),
format!("*{}* is now known as *{}*", nickname, new_nick), message: format!("*{}* is now known as *{}*", nickname, new_nick),
) })?;
.await?;
} }
} }
} }
@ -263,3 +274,52 @@ fn irc_to_discord_processing(
computed computed
} }
#[allow(clippy::large_enum_variant)] // lmao
#[derive(Debug)]
enum QueuedMessage {
Webhook {
webhook: Webhook,
http: Arc<Http>,
avatar_url: Option<String>,
content: String,
nickname: String,
},
Raw {
channel_id: ChannelId,
http: Arc<Http>,
message: String,
},
}
async fn msg_task(mut recv: UnboundedReceiverStream<QueuedMessage>) -> anyhow::Result<()> {
while let Some(msg) = recv.next().await {
match msg {
QueuedMessage::Webhook {
webhook,
http,
avatar_url,
content,
nickname,
} => {
webhook
.execute(&http, true, |w| {
if let Some(ref url) = avatar_url {
w.avatar_url(url);
}
w.username(nickname).content(content)
})
.await?;
}
QueuedMessage::Raw {
channel_id,
http,
message,
} => {
channel_id.say(&http, message).await?;
}
}
}
Ok(())
}

View file

@ -144,12 +144,12 @@ async fn main() -> anyhow::Result<()> {
} }
select! { select! {
r = irc_loop(irc_client, http.clone(), channels.clone(), webhooks_transformed, members) => r?, r = irc_loop(irc_client, http.clone(), channels.clone(), webhooks_transformed, members) => r.unwrap(),
r = discord_client.start() => r?, r = discord_client.start() => r.unwrap(),
_ = terminate_signal() => { _ = terminate_signal() => {
for (_, &v) in channels.iter() { for (_, &v) in channels.iter() {
let channel_id = ChannelId::from(v); let channel_id = ChannelId::from(v);
channel_id.say(&http, format!("dircord shutting down! (dircord {}-{})", env!("VERGEN_GIT_BRANCH"), &env!("VERGEN_GIT_SHA")[..7])).await?; channel_id.say(&http, format!("dircord shutting down! (dircord {}-{})", env!("VERGEN_GIT_BRANCH"), &env!("VERGEN_GIT_SHA")[..7])).await.unwrap();
} }
}, },
} }