commit 9abb3d5a58006d1edb28dd93751c29eabe09469d
Author: Daniel <daniel@steew.eu>
Date: Wed Jan 07 14:12:52 2026 +0000
diff --git a/src/main.rs b/src/main.rs
index 05aeb81..e559a45 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1201 +121 @@
-use std::collections::HashMap;
-use std::collections::VecDeque;
use std::str::FromStr;
use std::sync::Arc;
-use futures_util::StreamExt;
use ini::Ini;
-use irc::client::Sender;
use irc::client::data::Config;
-use irc::proto::Command;
use serenity::all::ChannelId;
-use serenity::all::ExecuteWebhook;
-use serenity::all::Http;
-use serenity::all::Message;
-use serenity::all::Ready;
use serenity::all::Webhook;
-use serenity::async_trait;
use serenity::prelude::*;
use tokio::spawn;
-use tokio::sync::Notify;
-#[derive(Debug)]
-enum RelayDirection {
- INVALID,
- IRC2DIS(String),
- DIS2IRC(ChannelId),
-}
-
-struct RelayMessage {
- contents: String,
- direction: RelayDirection,
- author: String,
-}
-
-struct MessageBuffer {
- pending_relay_messages: VecDeque<RelayMessage>,
-}
-
-struct RelayNotify {
- notify: Notify,
-}
-
-impl Default for RelayNotify {
- fn default() -> Self {
- RelayNotify {
- notify: Notify::new(),
- }
- }
-}
-
-struct RelayAssoc {
- // stores the Discord - IRC channel bridge associations
- bridge_assoc: HashMap<ChannelId, Vec<String>>,
- // stores the webhook URL for the discord channels
- chid_webhook_assoc: HashMap<ChannelId, String>,
-}
+mod relay;
+mod relay_discord;
+mod relay_irc;
-impl Default for RelayAssoc {
- fn default() -> Self {
- RelayAssoc {
- bridge_assoc: HashMap::new(),
- chid_webhook_assoc: HashMap::new()
- }
- }
-}
-
-impl Default for RelayMessage {
- fn default() -> Self {
- RelayMessage {
- contents: String::new(),
- direction: RelayDirection::INVALID,
- author: String::new()
- }
- }
-}
-
-impl Default for MessageBuffer {
- fn default() -> Self {
- MessageBuffer {
- pending_relay_messages: VecDeque::new(),
- }
- }
-}
-
-impl TypeMapKey for MessageBuffer {
- type Value = Arc<RwLock<MessageBuffer>>;
-}
+use relay::*;
+use relay_discord::*;
+use relay_irc::*;
-impl TypeMapKey for RelayNotify {
- type Value = Arc<RelayNotify>;
-}
-
-struct Handler;
-
-#[async_trait]
-impl EventHandler for Handler {
- async fn message(&self, ctx: Context, msg: Message) {
- // open the shared lock as write
- let data = ctx.data.read().await;
- let buffer_lock = data.get::<MessageBuffer>().unwrap().clone();
-
- if msg.author.bot {
- return;
- };
-
- {
- let mut relay_buffer = buffer_lock.write().await;
- // create a new message with the received discord message contents
- let mut new_message = RelayMessage::default();
- new_message.contents = msg.content;
- new_message.direction = RelayDirection::DIS2IRC(msg.channel_id);
- new_message.author = msg.author.name;
- // push the pending message to the relay buffer
- relay_buffer.pending_relay_messages.push_back(new_message);
- }
- println!("Added discord message to buffer.");
- {
- let notify = data.get::<RelayNotify>().unwrap().clone();
- notify.notify.notify_one();
- }
- }
-
- async fn ready(&self, _: Context, ready: Ready) {
- println!("{} is connected!", ready.user.name);
- }
-}
-
-async fn relay_consumer(
- buffer: Arc<RwLock<MessageBuffer>>,
- notify: Arc<RelayNotify>,
- http: Arc<Http>,
- webhook: Webhook,
- sender: Sender,
- assoc: RelayAssoc
-) {
- loop {
- // await for new relay pending events
- notify.notify.notified().await;
- let pending: RelayMessage;
- {
- let mut buffer_lock = buffer.write().await;
- pending = buffer_lock.pending_relay_messages.pop_front().unwrap();
- }
- println!(
- "Received message to relay: {}, {:?}",
- pending.contents, pending.direction
- );
- match pending.direction {
- RelayDirection::IRC2DIS(chan) => {
- // let chanid = ChannelId::new(591954698664149044);
- // chanid.say(http.clone(), pending.contents).await.unwrap();
- let builder = ExecuteWebhook::new().content(pending.contents).username(pending.author);
- webhook.execute(&http, false, builder).await.expect("Could not execute webhook.");
- }
- RelayDirection::DIS2IRC(chan) => {
- let unpingable_name = pending.author.clone();
- let (first, rest) = unpingable_name.split_at(1);
- let mut unpingable_name = String::new();
- unpingable_name.push_str(first);
- unpingable_name.push_str("");
- unpingable_name.push_str(rest);
-
- let response = format!("<{}>: {}", unpingable_name, pending.contents);
- sender.send_privmsg("##steew", response).unwrap();
- }
- _ => {}
- }
- }
-}
-
-async fn irc_producer(
- mut irc_client: irc::client::Client,
- buffer_reference: Arc<RwLock<MessageBuffer>>,
- notify: Arc<RelayNotify>
-) {
- let mut irc_stream: irc::client::ClientStream = irc_client.stream().unwrap();
-
- while let Ok(Some(message)) = irc_stream.next().await.transpose() {
- let msg_clone = message.clone();
- match message.command {
- Command::PRIVMSG(_, contents) => {
- {
- let uname = msg_clone.source_nickname().unwrap();
- let mut buffer = buffer_reference.write().await;
- let mut new_message = RelayMessage::default();
- new_message.contents = contents;
- new_message.direction = RelayDirection::IRC2DIS(String::from_str(msg_clone.response_target().unwrap()).unwrap());
- new_message.author.push_str(uname);
- buffer.pending_relay_messages.push_back(new_message);
- notify.notify.notify_one();
- }
- println!("Added IRC message to buffer");
- }
- _ => {}
- }
- }
-
-}
#[tokio::main]
async fn main() {
diff --git a/src/relay.rs b/src/relay.rs
new file mode 100644
index 0000000..b6ebad5
--- /dev/null
+++ b/src/relay.rs
@@ -00 +1127 @@
+use std::collections::HashMap;
+use std::collections::VecDeque;
+use std::sync::Arc;
+
+use irc::client::Sender;
+use serenity::all::ChannelId;
+use serenity::all::ExecuteWebhook;
+use serenity::all::Http;
+use serenity::all::Webhook;
+use serenity::prelude::*;
+use tokio::sync::Notify;
+
+#[derive(Debug)]
+pub enum RelayDirection {
+ INVALID,
+ IRC2DIS(String),
+ DIS2IRC(ChannelId),
+}
+
+pub struct RelayMessage {
+ pub contents: String,
+ pub direction: RelayDirection,
+ pub author: String,
+}
+
+pub struct MessageBuffer {
+ pub pending_relay_messages: VecDeque<RelayMessage>,
+}
+
+pub struct RelayNotify {
+ pub notify: Notify,
+}
+
+impl Default for RelayNotify {
+ fn default() -> Self {
+ RelayNotify {
+ notify: Notify::new(),
+ }
+ }
+}
+
+pub struct RelayAssoc {
+ // stores the Discord - IRC channel bridge associations
+ pub bridge_assoc: HashMap<ChannelId, Vec<String>>,
+ // stores the webhook URL for the discord channels
+ pub chid_webhook_assoc: HashMap<ChannelId, String>,
+}
+
+impl Default for RelayAssoc {
+ fn default() -> Self {
+ RelayAssoc {
+ bridge_assoc: HashMap::new(),
+ chid_webhook_assoc: HashMap::new()
+ }
+ }
+}
+
+impl Default for RelayMessage {
+ fn default() -> Self {
+ RelayMessage {
+ contents: String::new(),
+ direction: RelayDirection::INVALID,
+ author: String::new()
+ }
+ }
+}
+
+impl Default for MessageBuffer {
+ fn default() -> Self {
+ MessageBuffer {
+ pending_relay_messages: VecDeque::new(),
+ }
+ }
+}
+
+impl TypeMapKey for MessageBuffer {
+ type Value = Arc<RwLock<MessageBuffer>>;
+}
+
+impl TypeMapKey for RelayNotify {
+ type Value = Arc<RelayNotify>;
+}
+
+
+pub async fn relay_consumer(
+ buffer: Arc<RwLock<MessageBuffer>>,
+ notify: Arc<RelayNotify>,
+ http: Arc<Http>,
+ webhook: Webhook,
+ sender: Sender,
+ assoc: RelayAssoc
+) {
+ loop {
+ // await for new relay pending events
+ notify.notify.notified().await;
+ let pending: RelayMessage;
+ {
+ let mut buffer_lock = buffer.write().await;
+ pending = buffer_lock.pending_relay_messages.pop_front().unwrap();
+ }
+ println!(
+ "Received message to relay: {}, {:?}",
+ pending.contents, pending.direction
+ );
+ match pending.direction {
+ RelayDirection::IRC2DIS(chan) => {
+ // let chanid = ChannelId::new(591954698664149044);
+ // chanid.say(http.clone(), pending.contents).await.unwrap();
+ let builder = ExecuteWebhook::new().content(pending.contents).username(pending.author);
+ webhook.execute(&http, false, builder).await.expect("Could not execute webhook.");
+ }
+ RelayDirection::DIS2IRC(chan) => {
+ let unpingable_name = pending.author.clone();
+ let (first, rest) = unpingable_name.split_at(1);
+ let mut unpingable_name = String::new();
+ unpingable_name.push_str(first);
+ unpingable_name.push_str("");
+ unpingable_name.push_str(rest);
+
+ let response = format!("<{}>: {}", unpingable_name, pending.contents);
+ sender.send_privmsg("##steew", response).unwrap();
+ }
+ _ => {}
+ }
+ }
+}
+
diff --git a/src/relay_discord.rs b/src/relay_discord.rs
new file mode 100644
index 0000000..1afabb2
--- /dev/null
+++ b/src/relay_discord.rs
@@ -00 +142 @@
+use serenity::all::Message;
+use serenity::all::Ready;
+use serenity::async_trait;
+use serenity::prelude::*;
+
+use crate::relay::*;
+
+pub struct Handler;
+
+#[async_trait]
+impl EventHandler for Handler {
+ async fn message(&self, ctx: Context, msg: Message) {
+ // open the shared lock as write
+ let data = ctx.data.read().await;
+ let buffer_lock = data.get::<MessageBuffer>().unwrap().clone();
+
+ if msg.author.bot {
+ return;
+ };
+
+ {
+ let mut relay_buffer = buffer_lock.write().await;
+ // create a new message with the received discord message contents
+ let mut new_message = RelayMessage::default();
+ new_message.contents = msg.content;
+ new_message.direction = RelayDirection::DIS2IRC(msg.channel_id);
+ new_message.author = msg.author.name;
+ // push the pending message to the relay buffer
+ relay_buffer.pending_relay_messages.push_back(new_message);
+ }
+ println!("Added discord message to buffer.");
+ {
+ let notify = data.get::<RelayNotify>().unwrap().clone();
+ notify.notify.notify_one();
+ }
+ }
+
+ async fn ready(&self, _: Context, ready: Ready) {
+ println!("{} is connected!", ready.user.name);
+ }
+}
+
diff --git a/src/relay_irc.rs b/src/relay_irc.rs
new file mode 100644
index 0000000..2129a0f
--- /dev/null
+++ b/src/relay_irc.rs
@@ -00 +137 @@
+use std::str::FromStr;
+use std::sync::Arc;
+
+use futures_util::StreamExt;
+use irc::proto::Command;
+use serenity::prelude::*;
+
+use crate::relay::*;
+
+pub async fn irc_producer(
+ mut irc_client: irc::client::Client,
+ buffer_reference: Arc<RwLock<MessageBuffer>>,
+ notify: Arc<RelayNotify>
+) {
+ let mut irc_stream: irc::client::ClientStream = irc_client.stream().unwrap();
+
+ while let Ok(Some(message)) = irc_stream.next().await.transpose() {
+ let msg_clone = message.clone();
+ match message.command {
+ Command::PRIVMSG(_, contents) => {
+ {
+ let uname = msg_clone.source_nickname().unwrap();
+ let mut buffer = buffer_reference.write().await;
+ let mut new_message = RelayMessage::default();
+ new_message.contents = contents;
+ new_message.direction = RelayDirection::IRC2DIS(String::from_str(msg_clone.response_target().unwrap()).unwrap());
+ new_message.author.push_str(uname);
+ buffer.pending_relay_messages.push_back(new_message);
+ notify.notify.notify_one();
+ }
+ println!("Added IRC message to buffer");
+ }
+ _ => {}
+ }
+ }
+
+}