complete rewrite
This commit is contained in:
parent
6795691b44
commit
0c848899a7
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
Cargo.lock
|
||||
/target
|
||||
|
21
Cargo.toml
21
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"
|
||||
|
20
config.toml
20
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"
|
||||
|
78
proxies.txt
78
proxies.txt
@ -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
|
187
src/main.rs
187
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<String>;
|
||||
}
|
||||
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<String>,
|
||||
admin_users: Vec<String>,
|
||||
ignore_users: Vec<String>,
|
||||
|
||||
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::<Value>().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 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 admin_users = config.admin_users; // ADMINS
|
||||
let ignored_users = config.ignore_users; // IGNORED
|
||||
// ...
|
||||
ssl_stream.write_all(join_command.as_bytes()).unwrap();
|
||||
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();
|
||||
|
||||
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();
|
||||
// Perform the SSL handshake
|
||||
match Pin::new(&mut ssl_stream).connect().await {
|
||||
Ok(_) => println!("SSL connection established!"),
|
||||
Err(e) => {
|
||||
println!("Error establishing SSL connection: {:?}", e);
|
||||
return Err(Box::new(e) as Box<dyn std::error::Error>);
|
||||
}
|
||||
};
|
||||
|
||||
//debug chat
|
||||
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());
|
||||
|
||||
|
||||
// RESPOND TO PINGS
|
||||
let message = received.trim();
|
||||
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) {
|
||||
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;
|
||||
}
|
||||
// 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();
|
||||
} else {
|
||||
println!("Non-SSL connection not implemented.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
Err(e) => {
|
||||
println!("[!] ERROR: {}", e);
|
||||
break;
|
||||
},
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -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<String> {
|
||||
let mut responses = Vec::new();
|
||||
let config_str = std::fs::read_to_string("config.toml").unwrap();
|
||||
let config_value = config_str.parse::<Value>().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<String> {
|
||||
let config_str = std::fs::read_to_string("config.toml").unwrap();
|
||||
let config_value = config_str.parse::<Value>().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::<String>(),
|
||||
//);
|
||||
//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
|
||||
}
|
@ -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<String>,
|
||||
server: String,
|
||||
port: u16,
|
||||
|
||||
|
||||
}
|
||||
|
||||
pub struct InvadeCommand;
|
||||
|
||||
impl Command for InvadeCommand {
|
||||
fn handle(&self, message: &str) -> Vec<String> {
|
||||
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::<u32>().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::<Value>().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
|
||||
}
|
||||
}
|
@ -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<String>,
|
||||
server: String,
|
||||
port: u16,
|
||||
|
||||
proxy_server: String,
|
||||
proxy_port: u16,
|
||||
|
||||
}
|
||||
|
||||
pub struct InvadeCommand;
|
||||
|
||||
impl Command for InvadeCommand {
|
||||
fn handle(&self, message: &str) -> Vec<String> {
|
||||
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::<u32>().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::<Value>().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
|
||||
}
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
|
||||
use crate::modules::Command;
|
||||
|
||||
pub struct KillCommand;
|
||||
impl Command for KillCommand {
|
||||
fn handle(&self, message: &str) -> Vec<String> {
|
||||
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
|
||||
}
|
||||
}
|
@ -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<String> {
|
||||
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
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user