WIP: hellfire #1

Draft
sad wants to merge 19 commits from hellfire into main
2 changed files with 98 additions and 4 deletions
Showing only changes of commit 80512dd55c - Show all commits

View File

@ -6,6 +6,8 @@ use tokio::sync::mpsc;
use serde::Deserialize;
use std::fs;
use rand::{thread_rng, Rng};
use std::sync::atomic::{AtomicBool, Ordering};
use colored::*;
use tokio_socks::tcp::Socks5Stream;
@ -41,10 +43,13 @@ mod mods {
pub mod sasl;
pub mod sed;
pub mod ascii;
pub mod vomit;
}
use mods::sasl::{start_sasl_auth, handle_sasl_messages};
use mods::sed::{SedCommand, MessageBuffer};
use mods::ascii::handle_ascii_command;
use mods::vomit::{handle_vomit_command};
#[tokio::main(flavor = "multi_thread", worker_threads = 12)]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
@ -253,7 +258,13 @@ async fn writemsg(mut writer: tokio::io::WriteHalf<tokio_native_tls::TlsStream<T
.unwrap_or("unknown_user");
let host = parts[0].split('@').nth(1).unwrap_or("unknown_host");
let msg_content = if parts.len() > 3 {
parts[3..].join(" ").replace(':', "")
let remainder = &parts[3..].join(" ");
if let Some(pos) = remainder.find(':') {
let (first_part, last_part) = remainder.split_at(pos);
format!("{}{}", first_part, &last_part[1..])
} else {
remainder.to_string()
}
} else {
"".to_string()
};
@ -263,21 +274,24 @@ async fn writemsg(mut writer: tokio::io::WriteHalf<tokio_native_tls::TlsStream<T
if msg_content.starts_with("s/") {
if let Some(sed_command) = SedCommand::parse(&msg_content.clone()) {
if let Some(response) = message_buffer.apply_sed_command(&sed_command) {
writer.write_all(format!("PRIVMSG {} :{}: {}\r\n", channel, user, response).as_bytes()).await.unwrap();
writer.write_all(format!("PRIVMSG {} :{}\r\n", channel, response).as_bytes()).await.unwrap();
writer.flush().await.unwrap();
}
}
} else {
message_buffer.add_message(msg_content.clone());
message_buffer.add_message(msg_content.clone().to_string());
}
// ansi art
//
if msg_content.starts_with("%ascii") {
handle_ascii_command(&mut writer, &config, &msg_content, channel).await;
let _ = handle_ascii_command(&mut writer, config, &msg_content, channel).await;
}
if msg_content.starts_with("%vomit") {
let _ = handle_vomit_command(&mut writer, config, &msg_content, channel).await;
}
// other commands here
}
}
@ -293,3 +307,6 @@ async fn nickme<W: tokio::io::AsyncWriteExt + Unpin>(writer: &mut W, nickname: &
Ok(())
}

77
src/mods/vomit.rs Normal file
View File

@ -0,0 +1,77 @@
use rand::prelude::*;
use tokio::io::AsyncWriteExt;
use tokio::time;
use crate::Config;
async fn generate_random_unicode() -> char {
let codepoint: u32 = thread_rng().gen_range(0..=0x10FFFF);
std::char::from_u32(codepoint).unwrap_or(' ')
}
async fn generate_random_color() -> u8 {
thread_rng().gen_range(0..=15)
}
async fn generate_random_format() -> char {
match thread_rng().gen_range(0..=2) {
0 => '\x02', // Bold
1 => '\x1D', // Italic
_ => '\x1F', // Underline
}
}
async fn generate_vomit(length: usize) -> String {
let mut irc_text = String::new();
for _ in 0..length {
let char = generate_random_unicode().await;
let color_code = generate_random_color().await;
let format_code = generate_random_format().await;
irc_text.push_str(&format!("\x03{:02}{}", color_code, format_code));
irc_text.push(char);
}
irc_text
}
fn split_into_chunks(s: &str, max_chunk_size: usize) -> Vec<String> {
let mut chunks = Vec::new();
let mut current_chunk = String::new();
for char in s.chars() {
if current_chunk.len() + char.len_utf8() > max_chunk_size {
chunks.push(current_chunk.clone());
current_chunk.clear();
}
current_chunk.push(char);
}
if !current_chunk.is_empty() {
chunks.push(current_chunk);
}
chunks
}
const CHUNK_SIZE: usize = 400;
// Function to handle the vomit command
pub async fn handle_vomit_command<W: AsyncWriteExt + Unpin>(
writer: &mut W,
config: &Config,
command: &str,
channel: &str,
) -> Result<(), Box<dyn std::error::Error>> {
let parts: Vec<&str> = command.split_whitespace().collect();
let length = parts.get(1).and_then(|s| s.parse().ok()).unwrap_or(1000);
let vomit = generate_vomit(length).await; // Correctly awaited
let chunks = split_into_chunks(&vomit, CHUNK_SIZE); // Adjust if split_into_chunks is async
for chunk in chunks {
writer.write_all(format!("PRIVMSG {} :{}\r\n", channel, chunk).as_bytes()).await?;
writer.flush().await?;
time::sleep(tokio::time::Duration::from_secs(config.pump_delay)).await;
}
Ok(())
}