Compare commits
2 Commits
177be872a8
...
6ef48be979
Author | SHA1 | Date | |
---|---|---|---|
legitnull | 6ef48be979 | ||
legitnull | 7806149daa |
|
@ -46,11 +46,11 @@ this is the dev branch
|
|||
- `%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).
|
||||
|
||||
Pro tip: When you use the `%invade #channel` command, G.1.R will set up that channel to be the commander channel, so you can control all the bots from one place and only that place. Talk about efficient invasion tactics!
|
||||
Pro tip: When you use the `%invade 5 #channel` command, G.1.R will set up that channel to be the commander channel, so you can control all the bots from one place and only that place. Talk about efficient invasion tactics!
|
||||
|
||||
## TODO
|
||||
|
||||
|
@ -70,4 +70,5 @@ Pro tip: When you use the `%invade #channel` command, G.1.R will set up that cha
|
|||
- [ ] DM commander: To control the bots from the shadows, like a true mastermind.
|
||||
- [ ] Key rotation: To avoid API attempts from stopping the invasion.
|
||||
|
||||
So what are you waiting for? Join us in our quest for world domination, and let's make Invader Zim proud!
|
||||
So what are you waiting for? Join us in our quest for world domination, and let's make Invader Zim proud!
|
||||
t
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
nick = "g1r"
|
||||
server = "ircd.chat"
|
||||
port = 6697
|
||||
password = "mine"
|
||||
channels = [ "#s4d", "wiki", "#emo", "#tcpdirect", "#macros", "#b0tsh0p" ] #add key access
|
||||
password = ""
|
||||
channels = [ "#sad", "#s4d", "wiki", "#emo", "#tcpdirect", "#macros", "#b0tsh0p" ] #add key access
|
||||
admin_users = ["s4d", "sad", "g", "d", "h3x", "kayos", "moony"] # add host identification
|
||||
ignore_users = ["maple", "aibird", "professorOak", "van"]
|
||||
openai = "sk-"
|
||||
|
|
18
src/main.rs
18
src/main.rs
|
@ -12,7 +12,7 @@ use crate::modules::Command;
|
|||
|
||||
mod modules {
|
||||
pub trait Command {
|
||||
fn handle(&self, message: &str) -> Vec<String>;
|
||||
fn handle(&mut self, message: &str) -> Vec<String>;
|
||||
}
|
||||
pub mod ping;
|
||||
pub mod kill;
|
||||
|
@ -56,6 +56,7 @@ fn main() {
|
|||
let connector = SslConnector::builder(SslMethod::tls()).unwrap().build();
|
||||
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();
|
||||
|
@ -88,14 +89,15 @@ fn main() {
|
|||
continue; // skip processing the PING message further
|
||||
}
|
||||
|
||||
|
||||
// MODULES
|
||||
let ping_command = PingCommand;
|
||||
let kill_command = KillCommand;
|
||||
let invade_command = InvadeCommand;
|
||||
let aicode = AiCode;
|
||||
let mut ping_command = PingCommand;
|
||||
let mut kill_command = KillCommand;
|
||||
let mut invade_command = InvadeCommand::new();
|
||||
let mut aicode = AiCode;
|
||||
|
||||
//let test_command = TestCommand;
|
||||
let ai = Ai;
|
||||
let mut ai = Ai;
|
||||
|
||||
// ADMIN MODULES
|
||||
if message.starts_with(":") && message.contains(" :%") {
|
||||
|
@ -117,6 +119,10 @@ fn main() {
|
|||
for response in invade_command.handle(message) {
|
||||
ssl_stream.write_all(response.as_bytes()).unwrap();
|
||||
}
|
||||
} else if message.contains(":%%kill") {
|
||||
for response in invade_command.handle(message) {
|
||||
ssl_stream.write_all(response.as_bytes()).unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ struct Config {
|
|||
pub struct Ai;
|
||||
|
||||
impl Command for Ai {
|
||||
fn handle(&self, message: &str) -> Vec<String> {
|
||||
fn handle(&mut 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();
|
||||
|
|
|
@ -15,7 +15,7 @@ struct Config {
|
|||
pub struct AiCode;
|
||||
// setup a prompt and respnse log for training other bots
|
||||
impl Command for AiCode {
|
||||
fn handle(&self, message: &str) -> Vec<String> {
|
||||
fn handle(&mut 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();
|
||||
|
|
|
@ -8,29 +8,31 @@ use toml::{Value, to_string};
|
|||
use colored::*;
|
||||
use leetspeak;
|
||||
use regex::Regex;
|
||||
|
||||
//use anyhow::Result;
|
||||
//use socks5_proxy::{client, Addr};
|
||||
// use tokio::net::TcpStream;
|
||||
use tokio_native_tls::{TlsConnector, TlsStream};
|
||||
use tokio::io::{AsyncReadExt, AsyncWriteExt};
|
||||
|
||||
// add better error handling
|
||||
// add ai invasion
|
||||
// add proxy support
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::sync::{Arc, mpsc, Mutex};
|
||||
|
||||
#[derive(Clone, Deserialize)]
|
||||
struct Config {
|
||||
//invaders: Vec<String>,
|
||||
server: String,
|
||||
port: u16,
|
||||
}
|
||||
|
||||
pub struct InvadeCommand;
|
||||
pub struct InvadeCommand {
|
||||
kill_flag: Arc<AtomicBool>,
|
||||
kill_sender: Option<mpsc::Sender<()>>,
|
||||
}
|
||||
|
||||
impl InvadeCommand {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
kill_flag: Arc::new(AtomicBool::new(false)),
|
||||
kill_sender: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Command for InvadeCommand {
|
||||
fn handle(&self, message: &str) -> Vec<String> {
|
||||
fn handle(&mut self, message: &str) -> Vec<String> {
|
||||
let mut response = vec![];
|
||||
|
||||
if message.contains("PRIVMSG") && message.contains(":%invade") {
|
||||
|
@ -39,24 +41,28 @@ impl Command for InvadeCommand {
|
|||
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 scream = if parts.len() > 6 { parts[6] } else { "" };
|
||||
|
||||
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 (kill_sender, kill_receiver) = mpsc::channel();
|
||||
self.kill_sender = Some(kill_sender);
|
||||
let kill_receiver = Arc::new(Mutex::new(kill_receiver));
|
||||
|
||||
for _invader in 1..=num_invaders {//&config.invaders[1..num_invaders] { //1..=20 {
|
||||
for _invader in 1..=num_invaders {
|
||||
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 thread_invader = random_word::gen();
|
||||
|
||||
let kill_flag_clone = Arc::clone(&self.kill_flag);
|
||||
let kill_receiver = Arc::clone(&kill_receiver);
|
||||
|
||||
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();
|
||||
|
@ -73,6 +79,15 @@ impl Command for InvadeCommand {
|
|||
ssl_stream.write_all(msg.as_bytes()).unwrap();
|
||||
|
||||
loop {
|
||||
if kill_flag_clone.load(Ordering::SeqCst) {
|
||||
break;
|
||||
}
|
||||
|
||||
if let Ok(_) = kill_receiver.lock().unwrap().try_recv() {
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -91,10 +106,21 @@ impl Command for InvadeCommand {
|
|||
println!("{} {}","[%] PONG:".bold().green(), thread_invader.blue());
|
||||
ssl_stream.write_all(response.as_bytes()).unwrap();
|
||||
}
|
||||
if message.starts_with("433") { // Numeric reply for nickname in use
|
||||
let leet_nick = leetspeak::translate(&thread_invader);
|
||||
if message.starts_with(":ircd.chat 433") { // Numeric reply for nickname in use
|
||||
let leet_nick = leetspeak::translate_with_level(&thread_invader, &leetspeak::Level::One);
|
||||
let nick_command = format!("NICK {}\r\n", leet_nick);
|
||||
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();
|
||||
ssl_stream.write_all(msg.as_bytes()).unwrap();
|
||||
|
||||
//break;
|
||||
}
|
||||
// turn to mods
|
||||
// setup so these will only run from the server admin to avoid handle/host conflicts
|
||||
|
@ -135,6 +161,13 @@ impl Command for InvadeCommand {
|
|||
}
|
||||
|
||||
response.push(format!("PRIVMSG {} :\x0304,01[!] INVADING {} WITH {} INVADERS...\x0f\r\n", channel, invadechannel, num_invaders));
|
||||
} else if message.contains("PRIVMSG") && message.contains(":%%kill") {
|
||||
let channel = message.split("PRIVMSG ").nth(1).and_then(|s| s.splitn(2, ' ').next()).unwrap();
|
||||
if let Some(kill_sender) = &self.kill_sender {
|
||||
let _ = kill_sender.send(());
|
||||
}
|
||||
self.kill_flag.store(true, Ordering::SeqCst);
|
||||
response.push(format!("PRIVMSG {} :\x0304,01[!] TERMINATING ALL INVADERS...\x0f\r\n", channel));
|
||||
}
|
||||
|
||||
response
|
||||
|
|
|
@ -3,7 +3,7 @@ use crate::modules::Command;
|
|||
|
||||
pub struct KillCommand;
|
||||
impl Command for KillCommand {
|
||||
fn handle(&self, message: &str) -> Vec<String> {
|
||||
fn handle(&mut self, message: &str) -> Vec<String> {
|
||||
let mut response = vec![];
|
||||
|
||||
if message.contains("PRIVMSG") && message.contains(":%kill") {
|
||||
|
|
|
@ -3,7 +3,7 @@ use std::time::{Instant};
|
|||
use crate::modules::Command;
|
||||
pub struct PingCommand;
|
||||
impl Command for PingCommand {
|
||||
fn handle(&self, message: &str) -> Vec<String> {
|
||||
fn handle(&mut self, message: &str) -> Vec<String> {
|
||||
let mut response = vec![];
|
||||
|
||||
if message.contains("PRIVMSG") && message.contains(":%ping") {
|
||||
|
|
Loading…
Reference in New Issue