2023-02-18 06:47:35 +00:00
|
|
|
use crate::modules::Command;
|
|
|
|
|
2023-02-18 21:01:55 +00:00
|
|
|
use std::io::{Write};
|
2023-02-18 06:47:35 +00:00
|
|
|
use std::net::TcpStream;
|
|
|
|
|
|
|
|
use openssl::ssl::{SslConnector, SslMethod};
|
|
|
|
use serde::Deserialize;
|
|
|
|
use toml::Value;
|
|
|
|
|
|
|
|
#[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();
|
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-19 03:44:10 +00:00
|
|
|
let scream = if parts.len() > 6 { parts[6] } else { "" };
|
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-18 23:55:51 +00:00
|
|
|
for invader in &config.invaders[0..num_invaders] {
|
2023-02-18 06:47:35 +00:00
|
|
|
let thread_channel = invadechannel.to_string();
|
|
|
|
let thread_invader = invader.to_string();
|
|
|
|
let config_clone = config.clone();
|
|
|
|
let screaming = scream.to_string();
|
|
|
|
|
|
|
|
std::thread::spawn(move || {
|
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-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-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-18 21:01:55 +00:00
|
|
|
let mut buffer = [0; 512];
|
|
|
|
match ssl_stream.ssl_read(&mut buffer) {
|
2023-02-18 06:47:35 +00:00
|
|
|
Ok(0) => break,
|
2023-02-18 21:01:55 +00:00
|
|
|
Ok(n) => {
|
|
|
|
let message = String::from_utf8_lossy(&buffer[..n]);
|
2023-02-18 06:47:35 +00:00
|
|
|
if message.starts_with("PING") {
|
|
|
|
let response = message.replace("PING", "PONG");
|
2023-02-18 21:01:55 +00:00
|
|
|
println!("[%] PONG {}", thread_invader);
|
|
|
|
ssl_stream.write_all(response.as_bytes()).unwrap();
|
2023-02-18 06:47:35 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
Err(e) => {
|
|
|
|
eprintln!("Error reading from server: {}", e);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2023-02-18 23:55:51 +00:00
|
|
|
response.push(format!("PRIVMSG {} :INVADING WITH {} INVADERS...\r\n", channel, num_invaders));
|
2023-02-18 06:47:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
response
|
|
|
|
}
|
2023-02-18 21:01:55 +00:00
|
|
|
}
|