Compare commits
2 Commits
177be872a8
...
6ef48be979
Author | SHA1 | Date | |
---|---|---|---|
|
6ef48be979 | ||
|
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?
|
- `%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).
|
- `%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!
|
- `%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.
|
- `%%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).
|
- `%%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
|
## TODO
|
||||||
|
|
||||||
@ -71,3 +71,4 @@ Pro tip: When you use the `%invade #channel` command, G.1.R will set up that cha
|
|||||||
- [ ] Key rotation: To avoid API attempts from stopping the invasion.
|
- [ ] 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"
|
nick = "g1r"
|
||||||
server = "ircd.chat"
|
server = "ircd.chat"
|
||||||
port = 6697
|
port = 6697
|
||||||
password = "mine"
|
password = ""
|
||||||
channels = [ "#s4d", "wiki", "#emo", "#tcpdirect", "#macros", "#b0tsh0p" ] #add key access
|
channels = [ "#sad", "#s4d", "wiki", "#emo", "#tcpdirect", "#macros", "#b0tsh0p" ] #add key access
|
||||||
admin_users = ["s4d", "sad", "g", "d", "h3x", "kayos", "moony"] # add host identification
|
admin_users = ["s4d", "sad", "g", "d", "h3x", "kayos", "moony"] # add host identification
|
||||||
ignore_users = ["maple", "aibird", "professorOak", "van"]
|
ignore_users = ["maple", "aibird", "professorOak", "van"]
|
||||||
openai = "sk-"
|
openai = "sk-"
|
||||||
|
18
src/main.rs
18
src/main.rs
@ -12,7 +12,7 @@ use crate::modules::Command;
|
|||||||
|
|
||||||
mod modules {
|
mod modules {
|
||||||
pub trait Command {
|
pub trait Command {
|
||||||
fn handle(&self, message: &str) -> Vec<String>;
|
fn handle(&mut self, message: &str) -> Vec<String>;
|
||||||
}
|
}
|
||||||
pub mod ping;
|
pub mod ping;
|
||||||
pub mod kill;
|
pub mod kill;
|
||||||
@ -56,6 +56,7 @@ fn main() {
|
|||||||
let connector = SslConnector::builder(SslMethod::tls()).unwrap().build();
|
let connector = SslConnector::builder(SslMethod::tls()).unwrap().build();
|
||||||
let mut ssl_stream = connector.connect(&config.server, stream).unwrap();
|
let mut ssl_stream = connector.connect(&config.server, stream).unwrap();
|
||||||
let nick_command = format!("NICK {}_\r\n", config.nick); //setup passwords
|
let nick_command = format!("NICK {}_\r\n", config.nick); //setup passwords
|
||||||
|
|
||||||
let user_command = format!("USER {} 0 * :{}\r\n", config.nick, config.nick);
|
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(nick_command.as_bytes()).unwrap();
|
||||||
ssl_stream.write_all(user_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
|
continue; // skip processing the PING message further
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// MODULES
|
// MODULES
|
||||||
let ping_command = PingCommand;
|
let mut ping_command = PingCommand;
|
||||||
let kill_command = KillCommand;
|
let mut kill_command = KillCommand;
|
||||||
let invade_command = InvadeCommand;
|
let mut invade_command = InvadeCommand::new();
|
||||||
let aicode = AiCode;
|
let mut aicode = AiCode;
|
||||||
|
|
||||||
//let test_command = TestCommand;
|
//let test_command = TestCommand;
|
||||||
let ai = Ai;
|
let mut ai = Ai;
|
||||||
|
|
||||||
// ADMIN MODULES
|
// ADMIN MODULES
|
||||||
if message.starts_with(":") && message.contains(" :%") {
|
if message.starts_with(":") && message.contains(" :%") {
|
||||||
@ -117,6 +119,10 @@ fn main() {
|
|||||||
for response in invade_command.handle(message) {
|
for response in invade_command.handle(message) {
|
||||||
ssl_stream.write_all(response.as_bytes()).unwrap();
|
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;
|
pub struct Ai;
|
||||||
|
|
||||||
impl Command for 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 mut responses = Vec::new();
|
||||||
let config_str = std::fs::read_to_string("config.toml").unwrap();
|
let config_str = std::fs::read_to_string("config.toml").unwrap();
|
||||||
let config_value = config_str.parse::<Value>().unwrap();
|
let config_value = config_str.parse::<Value>().unwrap();
|
||||||
|
@ -15,7 +15,7 @@ struct Config {
|
|||||||
pub struct AiCode;
|
pub struct AiCode;
|
||||||
// setup a prompt and respnse log for training other bots
|
// setup a prompt and respnse log for training other bots
|
||||||
impl Command for AiCode {
|
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 mut responses = Vec::new();
|
||||||
let config_str = std::fs::read_to_string("config.toml").unwrap();
|
let config_str = std::fs::read_to_string("config.toml").unwrap();
|
||||||
let config_value = config_str.parse::<Value>().unwrap();
|
let config_value = config_str.parse::<Value>().unwrap();
|
||||||
|
@ -8,29 +8,31 @@ use toml::{Value, to_string};
|
|||||||
use colored::*;
|
use colored::*;
|
||||||
use leetspeak;
|
use leetspeak;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
//use anyhow::Result;
|
use std::sync::{Arc, mpsc, Mutex};
|
||||||
//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
|
|
||||||
|
|
||||||
#[derive(Clone, Deserialize)]
|
#[derive(Clone, Deserialize)]
|
||||||
struct Config {
|
struct Config {
|
||||||
//invaders: Vec<String>,
|
|
||||||
server: String,
|
server: String,
|
||||||
port: u16,
|
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 {
|
impl Command for InvadeCommand {
|
||||||
fn handle(&self, message: &str) -> Vec<String> {
|
fn handle(&mut self, message: &str) -> Vec<String> {
|
||||||
let mut response = vec![];
|
let mut response = vec![];
|
||||||
|
|
||||||
if message.contains("PRIVMSG") && message.contains(":%invade") {
|
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 num_invaders = parts[4].parse::<u32>().unwrap_or(1) as usize;
|
||||||
let channel = parts[2];
|
let channel = parts[2];
|
||||||
let invadechannel = parts[5];
|
let invadechannel = parts[5];
|
||||||
let scream = if parts.len() > 6 { parts[6] } else { "" }; // read entire message
|
let scream = if parts.len() > 6 { parts[6] } else { "" };
|
||||||
//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_str = std::fs::read_to_string("config.toml").unwrap();
|
||||||
let config_value = config_str.parse::<Value>().unwrap();
|
let config_value = config_str.parse::<Value>().unwrap();
|
||||||
let config: Config = config_value.try_into().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 thread_channel = invadechannel.to_string();
|
||||||
let config_clone = config.clone();
|
let config_clone = config.clone();
|
||||||
let screaming = scream.to_string();
|
let screaming = scream.to_string();
|
||||||
let command_channel = channel.to_string();
|
let command_channel = channel.to_string();
|
||||||
|
|
||||||
let thread_invader = random_word::gen(); // change to leetspeak on nick collision
|
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 || {
|
std::thread::spawn(move || {
|
||||||
|
|
||||||
let stream = TcpStream::connect((config_clone.server.as_str(), config_clone.port)).unwrap();
|
let stream = TcpStream::connect((config_clone.server.as_str(), config_clone.port)).unwrap();
|
||||||
let connector = SslConnector::builder(SslMethod::tls()).unwrap().build();
|
let connector = SslConnector::builder(SslMethod::tls()).unwrap().build();
|
||||||
let mut ssl_stream = connector.connect(config_clone.server.as_str(), stream).unwrap();
|
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();
|
ssl_stream.write_all(msg.as_bytes()).unwrap();
|
||||||
|
|
||||||
loop {
|
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());
|
println!("{} {}","[%] PONG:".bold().green(), thread_invader.blue());
|
||||||
ssl_stream.write_all(response.as_bytes()).unwrap();
|
ssl_stream.write_all(response.as_bytes()).unwrap();
|
||||||
}
|
}
|
||||||
if message.starts_with("433") { // Numeric reply for nickname in use
|
if message.starts_with(":ircd.chat 433") { // Numeric reply for nickname in use
|
||||||
let leet_nick = leetspeak::translate(&thread_invader);
|
let leet_nick = leetspeak::translate_with_level(&thread_invader, &leetspeak::Level::One);
|
||||||
let nick_command = format!("NICK {}\r\n", leet_nick);
|
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(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
|
// turn to mods
|
||||||
// setup so these will only run from the server admin to avoid handle/host conflicts
|
// 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));
|
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
|
response
|
||||||
|
@ -3,7 +3,7 @@ use crate::modules::Command;
|
|||||||
|
|
||||||
pub struct KillCommand;
|
pub struct KillCommand;
|
||||||
impl Command for KillCommand {
|
impl Command for KillCommand {
|
||||||
fn handle(&self, message: &str) -> Vec<String> {
|
fn handle(&mut self, message: &str) -> Vec<String> {
|
||||||
let mut response = vec![];
|
let mut response = vec![];
|
||||||
|
|
||||||
if message.contains("PRIVMSG") && message.contains(":%kill") {
|
if message.contains("PRIVMSG") && message.contains(":%kill") {
|
||||||
|
@ -3,7 +3,7 @@ use std::time::{Instant};
|
|||||||
use crate::modules::Command;
|
use crate::modules::Command;
|
||||||
pub struct PingCommand;
|
pub struct PingCommand;
|
||||||
impl Command for PingCommand {
|
impl Command for PingCommand {
|
||||||
fn handle(&self, message: &str) -> Vec<String> {
|
fn handle(&mut self, message: &str) -> Vec<String> {
|
||||||
let mut response = vec![];
|
let mut response = vec![];
|
||||||
|
|
||||||
if message.contains("PRIVMSG") && message.contains(":%ping") {
|
if message.contains("PRIVMSG") && message.contains(":%ping") {
|
||||||
|
Loading…
Reference in New Issue
Block a user