g1r/src/modules/invade.rs

134 lines
6.6 KiB
Rust
Raw Normal View History

2023-02-18 06:47:35 +00:00
use crate::modules::Command;
2023-02-19 21:08:48 +00:00
use std::io::{BufRead, BufReader, Write};
2023-02-18 06:47:35 +00:00
use std::net::TcpStream;
use openssl::ssl::{SslConnector, SslMethod};
use serde::Deserialize;
2023-02-21 13:03:32 +00:00
use toml::{Value, to_string};
2023-02-19 21:08:48 +00:00
use colored::*;
//use anyhow::Result;
//use socks5_proxy::{client, Addr};
use tokio::io::{AsyncReadExt, AsyncWriteExt};
2023-02-21 13:03:32 +00:00
// add better error handling
// add ai invasion
2023-02-24 01:04:54 +00:00
// add proxy support
2023-02-19 21:08:48 +00:00
2023-02-18 06:47:35 +00:00
#[derive(Clone, Deserialize)]
struct Config {
2023-02-21 13:03:32 +00:00
//invaders: Vec<String>,
2023-02-18 06:47:35 +00:00
server: String,
port: u16,
2023-02-24 01:04:54 +00:00
proxy_server: String,
proxy_port: u16,
2023-02-18 06:47:35 +00:00
}
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();
2023-02-18 23:55:51 +00:00
let num_invaders = parts[4].parse::<u32>().unwrap_or(1) as usize;
2023-02-18 06:47:35 +00:00
let channel = parts[2];
let invadechannel = parts[5];
2023-02-21 13:03:32 +00:00
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();
2023-02-18 06:47:35 +00:00
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();
2023-02-19 21:08:48 +00:00
2023-02-21 13:03:32 +00:00
for _invader in 1..=num_invaders {//&config.invaders[1..num_invaders] { //1..=20 {
2023-02-18 06:47:35 +00:00
let thread_channel = invadechannel.to_string();
let config_clone = config.clone();
let screaming = scream.to_string();
2023-02-20 05:48:17 +00:00
let command_channel = channel.to_string();
2023-02-21 13:03:32 +00:00
let thread_invader = random_word::gen(); // change to leetspeak on nick collision
2023-02-24 01:04:54 +00:00
2023-02-18 06:47:35 +00:00
std::thread::spawn(move || {
2023-02-24 01:04:54 +00:00
2023-02-18 21:01:55 +00:00
let stream = TcpStream::connect((config_clone.server.as_str(), config_clone.port)).unwrap();
2023-02-18 06:47:35 +00:00
let connector = SslConnector::builder(SslMethod::tls()).unwrap().build();
2023-02-18 21:01:55 +00:00
let mut ssl_stream = connector.connect(config_clone.server.as_str(), stream).unwrap();
2023-02-24 01:04:54 +00:00
2023-02-18 06:47:35 +00:00
let nick_command = format!("NICK {}\r\n", thread_invader);
let user_command = format!("USER {} 0 * :{}\r\n", thread_invader, thread_invader);
2023-02-18 21:01:55 +00:00
ssl_stream.write_all(nick_command.as_bytes()).unwrap();
ssl_stream.write_all(user_command.as_bytes()).unwrap();
2023-02-18 06:47:35 +00:00
let join_command = format!("JOIN {} \r\n", thread_channel);
2023-02-20 05:48:17 +00:00
let commander = format!("JOIN {} \r\n", command_channel);
ssl_stream.write_all(commander.as_bytes()).unwrap();
2023-02-18 21:01:55 +00:00
ssl_stream.write_all(join_command.as_bytes()).unwrap();
2023-02-18 06:47:35 +00:00
let msg = format!("PRIVMSG {} :{}\r\n", thread_channel, screaming);
2023-02-18 21:01:55 +00:00
ssl_stream.write_all(msg.as_bytes()).unwrap();
2023-02-18 06:47:35 +00:00
loop {
2023-02-19 21:08:48 +00:00
let mut buf = [0; 512];
match ssl_stream.ssl_read(&mut buf) {
2023-02-18 06:47:35 +00:00
Ok(0) => break,
2023-02-18 21:01:55 +00:00
Ok(n) => {
2023-02-19 21:08:48 +00:00
let received = String::from_utf8_lossy(&buf[0..n]);
let message = received.trim();
//debug chat
println!("{} {} {}","[%] DEBUG:".bold().green(), thread_invader.green(), received.blue());
2023-02-18 06:47:35 +00:00
if message.starts_with("PING") {
let response = message.replace("PING", "PONG");
2023-02-19 21:08:48 +00:00
println!("{} {}","[%] PONG:".bold().green(), thread_invader.blue());
ssl_stream.write_all(response.as_bytes()).unwrap();
}
2023-02-21 13:03:32 +00:00
// 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);
2023-02-20 05:48:17 +00:00
ssl_stream.write_all(response.as_bytes()).unwrap();
}
2023-02-21 13:03:32 +00:00
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();
}
}
2023-02-20 05:48:17 +00:00
}
2023-02-21 13:03:32 +00:00
// ...1
2023-02-18 06:47:35 +00:00
}
Err(e) => {
2023-02-19 21:08:48 +00:00
eprintln!("{} {}","[!] ERROR FROM SERVER:".on_red(), e);
2023-02-18 06:47:35 +00:00
break;
}
}
}
});
}
2023-02-19 21:08:48 +00:00
response.push(format!("PRIVMSG {} :\x0304,01[!] INVADING {} WITH {} INVADERS...\x0f\r\n", channel, invadechannel, num_invaders));
2023-02-18 06:47:35 +00:00
}
response
}
2023-02-18 21:01:55 +00:00
}