WIP: hellfire #1
25
src/main.rs
25
src/main.rs
@ -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
77
src/mods/vomit.rs
Normal 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(())
|
||||
}
|
Loading…
Reference in New Issue
Block a user