diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..fa04883 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +Cargo.lock +/target + diff --git a/Cargo.toml b/Cargo.toml index 30275af..8a7557c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,16 +6,13 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -openssl = "0.10.45" -async-openai = "0.6.1" -tokio = { version = "1.23.0", features = ["full"] } -rand = "0.8.4" -regex = "1.7.1" -toml = "0.7.2" -serde = "1.0.152" -tokio-openssl = "0.6.3" -colored = "2" +tokio = { version = "1.36.0", features = ["full"] } +tokio-openssl = "0.6.4" tokio-socks = "0.5.1" -socks = "0.3.4" -random_word = "0.3.0" -#leetspeak = "0.2.0" +openssl = "0.10.64" +rand = "0.8.5" +regex = "1.10.3" +toml = "0.8.10" +serde = { version = "1.0.197", features = ["derive"] } +colored = "2.1.0" +futures = "0.3.30" diff --git a/config.toml b/config.toml index 88ec755..966f19f 100644 --- a/config.toml +++ b/config.toml @@ -1,18 +1,6 @@ -nick = "g1r" -server = "ircd.chat" +server = "irc.supernets.org" port = 6697 -password = "" -channels = [ "#tcpdirect", "#macros", "#b0tsh0p" ] #add key access -admin_users = ["s4d", "s4d[m]", "g"] # add host identification -ignore_users = ["maple", "aibird", "professorOak", "van"] -openai = "sk-" -model = "text-davinci-003" -accents = "funny, completely insane, and hyperactive" -personalities = "GIR from Invader Zim" +use_ssl = true +nickname = "g1r" +channel = "#superbowl" -proxy_server = "127.0.0.1" -proxy_port = 9050 - -# INVADER SETTINGS -invaders = ["d1b", "z1m", "t4k", "m3mbr4n3", "g4z", "4l4n", "m1yuk1", "purpl3", "r3d", "5p0rk", "t3nn", "l4rb", "ch1nn", "d00ky", "3l", "fl0rb3", "g00ch", "gr4p4", "gr00t", "k00t", "k1m", "krunk", "l4dn4r", "n3n", "p3st0", "p00t"] -proxy_list = "./proxies.txt" diff --git a/proxies.txt b/proxies.txt deleted file mode 100644 index 290dda7..0000000 --- a/proxies.txt +++ /dev/null @@ -1,78 +0,0 @@ -184.185.2.12:4145 -174.138.33.62:59166 -206.220.175.2:4145 -96.126.113.216:59166 -205.240.77.164:4145 -174.75.211.222:4145 -72.210.252.137:4145 -192.111.129.145:16894 -68.71.254.6:4145 -159.203.13.82:59166 -107.170.81.141:59166 -159.65.220.89:59166 -192.241.143.216:59166 -149.56.247.67:59166 -157.245.223.201:59166 -203.57.114.228:59166 -192.111.135.18:18301 -192.252.216.81:4145 -68.183.90.210:59166 -123.171.245.162:1080 -72.195.34.58:4145 -208.111.40.144:59166 -98.162.25.29:31679 -192.252.214.20:15864 -95.213.228.10:59166 -142.93.77.151:59166 -72.195.114.169:4145 -192.111.135.17:18302 -75.119.157.170:59166 -75.127.13.195:59166 -167.71.10.234:59166 -51.255.219.244:59166 -51.178.82.49:59166 -184.178.172.14:4145 -68.71.247.130:4145 -192.111.137.37:18762 -176.58.125.165:59166 -205.186.162.190:59166 -47.243.95.228:10080 -142.54.228.193:4145 -168.196.160.61:59166 -138.68.124.120:59166 -174.138.63.144:59166 -74.119.147.209:4145 -68.183.20.254:59166 -67.205.181.126:59166 -139.144.31.132:59166 -159.89.49.172:59166 -43.226.26.120:59166 -23.253.253.26:59166 -206.189.157.253:59166 -184.170.248.5:4145 -159.203.78.174:59166 -46.101.37.189:59166 -184.170.249.65:4145 -192.111.137.34:18765 -167.71.190.131:59166 -174.64.199.79:4145 -184.178.172.25:15291 -45.79.46.53:59166 -40.87.45.45:59166 -199.58.184.97:4145 -198.8.94.170:4145 -192.252.208.67:14287 -184.170.245.148:4145 -69.164.224.53:59166 -68.71.249.153:48606 -143.198.229.170:59166 -165.227.153.96:59166 -192.252.220.89:4145 -138.197.185.192:59166 -151.80.45.47:59166 -69.194.181.6:7497 -170.210.156.33:59166 -209.94.62.123:59166 -198.8.94.174:39078 -184.178.172.23:4145 -72.221.232.155:4145 \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 857d908..f72e4cf 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,151 +1,78 @@ -use std::io::prelude::*; -use std::net::TcpStream; -use std::io::Write; -use openssl::ssl::{SslMethod, SslConnector}; -use toml::Value; -use serde::Deserialize; use colored::*; - - -mod modules { - pub trait Command { - fn handle(&self, message: &str) -> Vec; - } - pub mod ping; - pub mod kill; - pub mod ai; - pub mod invade; - pub mod test; - //pub mod ai_invade; -} - -use modules::ai::Ai; // FIX THIS BS -use modules::ping::PingCommand; -use modules::invade::InvadeCommand; -//use modules::ai_invade::AiInvadeCommand; -use modules::kill::KillCommand; // ... -use crate::modules::Command; +use openssl::ssl::{SslConnector, SslMethod, SslVerifyMode}; +use serde::Deserialize; +use std::fs; +use tokio::io::{AsyncBufReadExt, AsyncWriteExt, BufReader, BufWriter}; +use tokio::net::TcpStream; +use tokio_openssl::SslStream; +use std::pin::Pin; #[derive(Deserialize)] struct Config { server: String, port: u16, - nick: String, - password: String, - channels: Vec, - admin_users: Vec, - ignore_users: Vec, - + use_ssl: bool, + nickname: String, + channel: String, } -fn main() { - let rt = tokio::runtime::Builder::new_multi_thread() - .enable_all() - .build() - .unwrap(); +#[tokio::main] +async fn main() -> Result<(), Box<(dyn std::error::Error)>> { + println!("Loading Config..."); + let config_contents = fs::read_to_string("config.toml").expect("Error reading config.toml"); + let config: Config = toml::from_str(&config_contents).expect("Error parsing config.toml"); + println!("Config loaded!"); - // LOAD CONFIG - let config_str = std::fs::read_to_string("config.toml").unwrap(); - let config_value = config_str.parse::().unwrap(); - let config: Config = config_value.try_into().unwrap(); - // GIVE THE SERVER A SLOPPPY SPAM OF RETARDEDNESS - let stream = TcpStream::connect(format!("{}:{}", config.server, config.port)).unwrap(); - let connector = SslConnector::builder(SslMethod::tls()).unwrap().build(); - // DONT DO DRUGS YOU WILL END UP LIKE ME - let mut ssl_stream = connector.connect(&config.server, stream).unwrap(); - let nick_command = format!("NICK {}_\r\n", config.nick); //setup passwords - let user_command = format!("USER {} 0 * :{}\r\n", config.nick, config.nick); - ssl_stream.write_all(nick_command.as_bytes()).unwrap(); - ssl_stream.write_all(user_command.as_bytes()).unwrap(); - let identify_command = format!("PRIVMSG NickServ :IDENTIFY {} {}\r\n", config.nick, config.password); - ssl_stream.write(identify_command.as_bytes()).unwrap(); - let channels = config.channels.join(","); - let join_command = format!("JOIN {}\r\n", channels); - - let admin_users = config.admin_users; // ADMINS - let ignored_users = config.ignore_users; // IGNORED -// ... - ssl_stream.write_all(join_command.as_bytes()).unwrap(); + let addr = format!("{}:{}", config.server, config.port); + println!("Connecting to {}...", addr.green()); + let tcp_stream = TcpStream::connect(&addr).await.unwrap(); + println!("Connected to {}!", addr.green()); - let mut buf = [0; 512]; - loop { - match ssl_stream.read(&mut buf) { - Ok(0) => break, - Ok(n) => { - let received = String::from_utf8_lossy(&buf[0..n]); - let message = received.trim(); + if config.use_ssl { + println!("Establishing SSL connection..."); + let mut connector = SslConnector::builder(SslMethod::tls()).unwrap().build().configure().unwrap().into_ssl(&addr).unwrap(); + connector.set_verify(SslVerifyMode::NONE); + let mut ssl_stream = SslStream::new(connector, tcp_stream).unwrap(); - //debug chat - println!("{} {}","[%] DEBUG:".bold().green(), received.purple()); - - - // RESPOND TO PINGS - if message.starts_with("PING") { - println!("{} {}","[%] PONG:".bold().green(), config.nick.blue()); // DEBUG - ssl_stream.write_all("PONG ircd.chat\r\n".as_bytes()).unwrap(); - continue; // skip processing the PING message further - } - - // MODULES - let ping_command = PingCommand; - let kill_command = KillCommand; - let invade_command = InvadeCommand; - //let ai_invade_command = AiInvadeCommand; - - //let test_command = TestCommand; - let ai = Ai; - - // ADMIN MODULES - if message.starts_with(":") && message.contains(" :%") { - let parts: Vec<&str> = message.splitn(2, ' ').collect(); // Check if user is admin_user - let username = parts[0].trim_start_matches(':').split("!").next().unwrap(); - if !admin_users.contains(&username.to_string()) { - println!("{} {}","[!] UNAUTHORIZED:".bold().clear().on_red(), username.red().bold()); - continue; // ... - } - if message.contains(":%ping") { - for response in ping_command.handle(message) { - ssl_stream.write_all(response.as_bytes()).unwrap(); - } - } else if message.contains(":%kill") { - for response in kill_command.handle(message) { - ssl_stream.write_all(response.as_bytes()).unwrap(); - } - } else if message.contains(":%invade") { - for response in invade_command.handle(message) { - ssl_stream.write_all(response.as_bytes()).unwrap(); - } - } //else if message.contains(":%aiinvade") { - // for response in ai_invade_command.handle(message) { - // ssl_stream.write_all(response.as_bytes()).unwrap(); - // } - //} - } - - // Check if the message is user and respond via ai - else if message.starts_with(":") && message.contains("PRIVMSG ") && message.contains(&config.nick) { //modify for on mention - let channel = message.split("PRIVMSG ").nth(1).and_then(|s| s.splitn(2, ' ').next()).unwrap(); - if !channels.contains(&channel) { - continue; - } - // extract the username from the first part and check if ignored - let parts: Vec<&str> = message.splitn(2, ' ').collect(); // split the message into two parts at the first space - let username = parts[0].trim_start_matches(':').split("!").next().unwrap(); - if ignored_users.contains(&username.to_string()) { - println!("[!] IGNORED: {}", username.red()); - continue; - } - for response in ai.handle(message, ) { - ssl_stream.write_all(response.as_bytes()).unwrap(); - } - - } - - }, + // Perform the SSL handshake + match Pin::new(&mut ssl_stream).connect().await { + Ok(_) => println!("SSL connection established!"), Err(e) => { - println!("[!] ERROR: {}", e); - break; - }, + println!("Error establishing SSL connection: {:?}", e); + return Err(Box::new(e) as Box); + } + }; + + println!("Sending NICK and USER commands..."); + ssl_stream.write_all(format!("NICK {}\r\n", config.nickname).as_bytes()).await.unwrap(); + ssl_stream.write_all(format!("USER {} 0 * :{}\r\n", config.nickname, config.nickname).as_bytes()).await.unwrap(); + ssl_stream.write_all(format!("JOIN {}\r\n", config.channel).as_bytes()).await.unwrap(); + + + let (read_half, write_half) = tokio::io::split(ssl_stream); + + // split the stream and then transfer this for non-ssl + let mut reader = BufReader::new(read_half); + let mut writer = BufWriter::new(write_half); + let mut lines = reader.lines(); + + while let Some(result) = lines.next_line().await.unwrap() { + + let received = String::from_utf8_lossy(result.as_bytes()).trim().to_string(); + println!("{} {}","[%] DEBUG:".bold().green(), received.purple()); + + let message = received.trim(); + if message.starts_with("PING") { + println!("Sending PONG..."); + let response = message.replace("PING", "PONG"); + println!("{} {}","[%] PONG:".bold().green(), config.nickname.blue()); + writer.write_all(response.as_bytes()).await.unwrap(); + continue; + } } + } else { + println!("Non-SSL connection not implemented."); } + + Ok(()) } diff --git a/src/modules/ai.rs b/src/modules/ai.rs deleted file mode 100644 index ba7df92..0000000 --- a/src/modules/ai.rs +++ /dev/null @@ -1,89 +0,0 @@ -// Check if the message is user and respond via ai -use async_openai::{Client, types::{CreateCompletionRequestArgs}}; -use regex::Regex; -use crate::modules::Command; -use toml::Value; -use serde::Deserialize; -use colored::*; - -#[derive(Deserialize)] -struct Config { - nick: String, - openai: String, - model: String, - accents: String, - personalities: String, -} -pub struct Ai; - // setup a prompt and respnse log for training other bots -impl Command for Ai { - fn handle(&self, message: &str) -> Vec { - let mut responses = Vec::new(); - let config_str = std::fs::read_to_string("config.toml").unwrap(); - let config_value = config_str.parse::().unwrap(); - let config: Config = config_value.try_into().unwrap(); // respond to name with and without leet VVV - if message.starts_with(":") && message.contains("PRIVMSG ") && message.contains(&config.nick) { - let channel = message.split("PRIVMSG ").nth(1).and_then(|s| s.splitn(2, ' ').next()).unwrap(); // set the response to varible - let user_message = format!("The following is a chat log:\n{}\nRespond {} as you are chatting as {}: \n\n", - message.split(&format!("PRIVMSG {} :", channel.to_string())).nth(1).unwrap(), - config.accents, - config.personalities - ); - let parts: Vec<&str> = message.splitn(2, ' ').collect(); - let username = parts[0].trim_start_matches(':').split("!").next().unwrap(); - - let rt = tokio::runtime::Runtime::new().unwrap(); - let result = rt.block_on(ai(&user_message, &username, &channel)); - responses.extend(result); - } - - responses - } -} -async fn ai(user_message: &str, username: &str, channel: &str) -> Vec { - let config_str = std::fs::read_to_string("config.toml").unwrap(); - let config_value = config_str.parse::().unwrap(); - let config: Config = config_value.try_into().unwrap(); - let api_key = config.openai; // set this from config - - let client = Client::new().with_api_key(api_key); - println!("{} {} {}: {}", "[?]".on_green().bold(), "PROMPT:".green().bold(), username, user_message); - let chat_request = CreateCompletionRequestArgs::default() - .prompt(user_message) - .max_tokens(40_u16) - .model(config.model) - .build() - .unwrap(); - let chat_response = client - .completions() - .create(chat_request) - .await - .unwrap(); - println!("{} {} {}","[+]".on_green().bold(), "RESPONSE:".green().bold(), chat_response.choices.first().unwrap().text); - //modify regex for varible username ie G1R g1r GIR gir but as handle nick for bots - let response_text = &chat_response.choices.first().unwrap().text; - let regex = Regex::new(r#""|[gG][1iI][rR]:\s"#).unwrap(); // THIS IS FUCKING UP EVERYTHING - //let nick = &config.nick; - //let regex_str = format!( - // r#""|[{}{}{}]|\b[gG][1iI][rR]:\s*|\b[mM][eE]:?\s"#, - // nick.to_lowercase(), - // nick.to_uppercase(), - // nick.chars().map(|c| match c { /// regex magic nick removal in progress - // 'a' => '4', - // 'e' => '3', - // 'i' => '1', - // 'o' => '0', - // 's' => '5', - // _ => c, - // }).collect::(), - //); - //let regex = Regex::new(®ex_str).unwrap(); - let response_text = regex.replace_all(response_text, "").trim().to_string(); - let response_lines = response_text.split("\n").filter(|line| !line.trim().is_empty()); - let mut responses = Vec::new(); - for line in response_lines { - responses.push(format!("PRIVMSG {} :\x0313{}\x0f: {}\r\n", channel, username, line)); - } - - responses -} diff --git a/src/modules/invade copy.rs b/src/modules/invade copy.rs deleted file mode 100644 index 5b7134c..0000000 --- a/src/modules/invade copy.rs +++ /dev/null @@ -1,126 +0,0 @@ -use crate::modules::Command; - -use std::io::{BufRead, BufReader, Write}; -use std::net::TcpStream; -use openssl::ssl::{SslConnector, SslMethod}; -use serde::Deserialize; -use toml::{Value, to_string}; -use colored::*; - -// add better error handling -// add ai invasion -// add proxy support - -#[derive(Clone, Deserialize)] -struct Config { - //invaders: Vec, - server: String, - port: u16, - - -} - -pub struct InvadeCommand; - -impl Command for InvadeCommand { - fn handle(&self, message: &str) -> Vec { - let mut response = vec![]; - - if message.contains("PRIVMSG") && message.contains(":%invade") { - let parts: Vec<&str> = message.split_whitespace().collect(); - let num_invaders = parts[4].parse::().unwrap_or(1) as usize; - let channel = parts[2]; - let invadechannel = parts[5]; - let scream = if parts.len() > 6 { parts[6] } else { "" }; // read entire message - //message.split(&format!("PRIVMSG {} :", channel.to_string())).nth(1).unwrap(), - //let channel = message.split("PRIVMSG ").nth(1).and_then(|s| s.splitn(2, ' ').next()).unwrap(); - let config_str = std::fs::read_to_string("config.toml").unwrap(); - let config_value = config_str.parse::().unwrap(); - let config: Config = config_value.try_into().unwrap(); - - - for _invader in 1..=num_invaders {//&config.invaders[1..num_invaders] { //1..=20 { - let thread_channel = invadechannel.to_string(); - let config_clone = config.clone(); - let screaming = scream.to_string(); - let command_channel = channel.to_string(); - let thread_invader = random_word::gen(); // change to leetspeak on nick collision - - std::thread::spawn(move || { - let stream = TcpStream::connect((config_clone.server.as_str(), config_clone.port)).unwrap(); - let connector = SslConnector::builder(SslMethod::tls()).unwrap().build(); - let mut ssl_stream = connector.connect(config_clone.server.as_str(), stream).unwrap(); - let nick_command = format!("NICK {}\r\n", thread_invader); - let user_command = format!("USER {} 0 * :{}\r\n", thread_invader, thread_invader); - ssl_stream.write_all(nick_command.as_bytes()).unwrap(); - ssl_stream.write_all(user_command.as_bytes()).unwrap(); - let join_command = format!("JOIN {} \r\n", thread_channel); - let commander = format!("JOIN {} \r\n", command_channel); - ssl_stream.write_all(commander.as_bytes()).unwrap(); - ssl_stream.write_all(join_command.as_bytes()).unwrap(); - let msg = format!("PRIVMSG {} :{}\r\n", thread_channel, screaming); - ssl_stream.write_all(msg.as_bytes()).unwrap(); - - loop { - - - - let mut buf = [0; 512]; - match ssl_stream.ssl_read(&mut buf) { - Ok(0) => break, - Ok(n) => { - let received = String::from_utf8_lossy(&buf[0..n]); - let message = received.trim(); - - //debug chat - println!("{} {} {}","[%] DEBUG:".bold().green(), thread_invader.green(), received.blue()); - - if message.starts_with("PING") { - let response = message.replace("PING", "PONG"); - println!("{} {}","[%] PONG:".bold().green(), thread_invader.blue()); - ssl_stream.write_all(response.as_bytes()).unwrap(); - } - // turn to mods - // setup so these will only run from the server admin to avoid handle/host conflicts - let commandi = format!("PRIVMSG {} :%%",command_channel); // & check for admin and verify with server - - if message.contains(&commandi) && message.contains(":%%") { - if message.contains("PRIVMSG") && message.contains(":%%join") { // fix so commands get picked up faster - let parts: Vec<&str> = message.splitn(3, ":%%join ").collect(); - let invade_channel = parts[1]; - let response = format!("JOIN {} \r\n", invade_channel); - ssl_stream.write_all(response.as_bytes()).unwrap(); - } - if message.contains("PRIVMSG") && message.contains(":%%leave") { - let parts: Vec<&str> = message.splitn(3, ":%%leave ").collect(); - let invade_channel = parts[1]; - let response = format!("PART {} \r\n", invade_channel); - ssl_stream.write_all(response.as_bytes()).unwrap(); - } - if message.contains("PRIVMSG") && message.contains(":%%scream") { - let parts: Vec<&str> = message.splitn(3, ":%%scream ").collect(); - let invade_channel = parts[1]; - if parts.len() == 2 { - let scream = parts[1]; - let response = format!("PRIVMSG {} :{}\r\n", invade_channel, scream); - ssl_stream.write_all(response.as_bytes()).unwrap(); - } - } - } - // ...1 - } - Err(e) => { - eprintln!("{} {}","[!] ERROR FROM SERVER:".on_red(), e); - break; - } - } - } - }); - } - - response.push(format!("PRIVMSG {} :\x0304,01[!] INVADING {} WITH {} INVADERS...\x0f\r\n", channel, invadechannel, num_invaders)); - } - - response - } -} \ No newline at end of file diff --git a/src/modules/invade.rs b/src/modules/invade.rs deleted file mode 100644 index ba612f8..0000000 --- a/src/modules/invade.rs +++ /dev/null @@ -1,130 +0,0 @@ -use crate::modules::Command; - -use std::io::{BufRead, BufReader, Write}; -use std::net::TcpStream; -use openssl::ssl::{SslConnector, SslMethod}; -use serde::Deserialize; -use toml::{Value, to_string}; -use colored::*; -use socks::*; -// add better error handling -// add ai invasion -// add proxy support - -#[derive(Clone, Deserialize)] -struct Config { - //invaders: Vec, - server: String, - port: u16, - - proxy_server: String, - proxy_port: u16, - -} - -pub struct InvadeCommand; - -impl Command for InvadeCommand { - fn handle(&self, message: &str) -> Vec { - let mut response = vec![]; - - if message.contains("PRIVMSG") && message.contains(":%invade") { - let parts: Vec<&str> = message.split_whitespace().collect(); - let num_invaders = parts[4].parse::().unwrap_or(1) as usize; - let channel = parts[2]; - let invadechannel = parts[5]; - let scream = if parts.len() > 6 { parts[6] } else { "" }; // read entire message - //message.split(&format!("PRIVMSG {} :", channel.to_string())).nth(1).unwrap(), - //let channel = message.split("PRIVMSG ").nth(1).and_then(|s| s.splitn(2, ' ').next()).unwrap(); - let config_str = std::fs::read_to_string("config.toml").unwrap(); - let config_value = config_str.parse::().unwrap(); - let config: Config = config_value.try_into().unwrap(); - - - for _invader in 1..=num_invaders {//&config.invaders[1..num_invaders] { //1..=20 { - let thread_channel = invadechannel.to_string(); - let config_clone = config.clone(); - let screaming = scream.to_string(); - let command_channel = channel.to_string(); - let thread_invader = random_word::gen(); // change to leetspeak on nick collision - - std::thread::spawn(move || { - - let stream = TcpStream::connect((config_clone.server.as_str(), config_clone.port)).unwrap(); - let connector = SslConnector::builder(SslMethod::tls()).unwrap().build(); - let mut ssl_stream = connector.connect(config_clone.server.as_str(), stream).unwrap(); - - let nick_command = format!("NICK {}\r\n", thread_invader); - let user_command = format!("USER {} 0 * :{}\r\n", thread_invader, thread_invader); - ssl_stream.write_all(nick_command.as_bytes()).unwrap(); - ssl_stream.write_all(user_command.as_bytes()).unwrap(); - let join_command = format!("JOIN {} \r\n", thread_channel); - let commander = format!("JOIN {} \r\n", command_channel); - ssl_stream.write_all(commander.as_bytes()).unwrap(); - ssl_stream.write_all(join_command.as_bytes()).unwrap(); - let msg = format!("PRIVMSG {} :{}\r\n", thread_channel, screaming); - ssl_stream.write_all(msg.as_bytes()).unwrap(); - - loop { - - - - let mut buf = [0; 512]; - match ssl_stream.ssl_read(&mut buf) { - Ok(0) => break, - Ok(n) => { - let received = String::from_utf8_lossy(&buf[0..n]); - let message = received.trim(); - - //debug chat - println!("{} {} {}","[%] DEBUG:".bold().green(), thread_invader.green(), received.blue()); - - if message.starts_with("PING") { - let response = message.replace("PING", "PONG"); - println!("{} {}","[%] PONG:".bold().green(), thread_invader.blue()); - ssl_stream.write_all(response.as_bytes()).unwrap(); - } - // turn to mods - // setup so these will only run from the server admin to avoid handle/host conflicts - let commandi = format!("PRIVMSG {} :%%",command_channel); // & check for admin and verify with server - - if message.contains(&commandi) && message.contains(":%%") { - if message.contains("PRIVMSG") && message.contains(":%%join") { // fix so commands get picked up faster - let parts: Vec<&str> = message.splitn(3, ":%%join ").collect(); - let invade_channel = parts[1]; - let response = format!("JOIN {} \r\n", invade_channel); - ssl_stream.write_all(response.as_bytes()).unwrap(); - } - if message.contains("PRIVMSG") && message.contains(":%%leave") { - let parts: Vec<&str> = message.splitn(3, ":%%leave ").collect(); - let invade_channel = parts[1]; - let response = format!("PART {} \r\n", invade_channel); - ssl_stream.write_all(response.as_bytes()).unwrap(); - } - if message.contains("PRIVMSG") && message.contains(":%%scream") { - let parts: Vec<&str> = message.splitn(3, ":%%scream ").collect(); - let invade_channel = parts[1]; - if parts.len() == 2 { - let scream = parts[1]; - let response = format!("PRIVMSG {} :{}\r\n", invade_channel, scream); - ssl_stream.write_all(response.as_bytes()).unwrap(); - } - } - } - // ...1 - } - Err(e) => { - eprintln!("{} {}","[!] ERROR FROM SERVER:".on_red(), e); - break; - } - } - } - }); - } - - response.push(format!("PRIVMSG {} :\x0304,01[!] INVADING {} WITH {} INVADERS...\x0f\r\n", channel, invadechannel, num_invaders)); - } - - response - } -} \ No newline at end of file diff --git a/src/modules/kill.rs b/src/modules/kill.rs deleted file mode 100644 index 2696506..0000000 --- a/src/modules/kill.rs +++ /dev/null @@ -1,17 +0,0 @@ - -use crate::modules::Command; - -pub struct KillCommand; -impl Command for KillCommand { - fn handle(&self, message: &str) -> Vec { - let mut response = vec![]; - - if message.contains("PRIVMSG") && message.contains(":%kill") { - let channel = message.split("PRIVMSG ").nth(1).and_then(|s| s.splitn(2, ' ').next()).unwrap(); - response.push(format!("PRIVMSG {} :SELF DESTRUCTING...\r\n", channel)); - println!("[!] KILLING!"); - std::process::exit(0); - } - response - } -} diff --git a/src/modules/ping.rs b/src/modules/ping.rs deleted file mode 100644 index 80ace04..0000000 --- a/src/modules/ping.rs +++ /dev/null @@ -1,17 +0,0 @@ - -use std::time::{Instant}; -use crate::modules::Command; -pub struct PingCommand; -impl Command for PingCommand { - fn handle(&self, message: &str) -> Vec { - let mut response = vec![]; - - if message.contains("PRIVMSG") && message.contains(":%ping") { - let channel = message.split("PRIVMSG ").nth(1).and_then(|s| s.splitn(2, ' ').next()).unwrap(); - let start = Instant::now(); - let elapsed = start.elapsed(); - response.push(format!("PRIVMSG {} :PONG: {:?}\r\n", channel, elapsed)); - } - response - } -} diff --git a/src/modules/test.rs b/src/modules/test.rs deleted file mode 100644 index e69de29..0000000