diff --git a/Cargo.toml b/Cargo.toml index 8c8809e..30275af 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,6 +15,7 @@ toml = "0.7.2" serde = "1.0.152" tokio-openssl = "0.6.3" colored = "2" +tokio-socks = "0.5.1" socks = "0.3.4" random_word = "0.3.0" -leetspeak = "0.2.0" \ No newline at end of file +#leetspeak = "0.2.0" diff --git a/README.md b/README.md index 84eb212..803ac46 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,7 @@ - `%ping`: Send this command to G.1.R and he'll respond back with "pong" and the time it took. Because why not? - `%kill`: Do you hate your bot companion and want to end his miserable existence? Just type this command and he'll self-destruct, leaving you alone with your conscience (and your loneliness). - `%invade 5 #channel SCREAM`: Do you want to summon the Invaders to a specific channel? This command will do just that, plus a chance to let out your deepest screams of despair. 5 being the number of invaders to join! -`%%scream #channel SCREAM`: In case the invaders weren't enough to scare off your enemies, use this command to make them hear your battle cry across the IRC lands. +- `%%scream #channel SCREAM`: In case the invaders weren't enough to scare off your enemies, use this command to make them hear your battle cry across the IRC lands. - `%%join #channel`: More bots, more fun! Tell G.1.R to join the party in a specific channel and watch the madness unfold. - `%%leave #channel`: Tired of all the chaos? Use this command to make the bots leave the channel and leave you in peace (or in silence, at least). diff --git a/config.toml b/config.toml index e38a9bc..88ec755 100644 --- a/config.toml +++ b/config.toml @@ -15,4 +15,4 @@ 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" \ No newline at end of file +proxy_list = "./proxies.txt" diff --git a/src/modules/invade copy.rs b/src/modules/invade copy.rs new file mode 100644 index 0000000..5b7134c --- /dev/null +++ b/src/modules/invade copy.rs @@ -0,0 +1,126 @@ +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 index 55c915e..ba612f8 100644 --- a/src/modules/invade.rs +++ b/src/modules/invade.rs @@ -6,17 +6,20 @@ 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 optional +// add proxy support #[derive(Clone, Deserialize)] struct Config { //invaders: Vec, server: String, port: u16, - + + proxy_server: String, + proxy_port: u16, + } pub struct InvadeCommand; @@ -44,11 +47,13 @@ impl Command for InvadeCommand { 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();