g1r/src/main.rs

154 lines
5.8 KiB
Rust
Raw Normal View History

2023-02-17 08:38:32 +00:00
use std::io::prelude::*;
use std::net::TcpStream;
2023-02-18 06:47:35 +00:00
use std::io::Write;
use openssl::ssl::{SslMethod, SslConnector};
use toml::Value;
2023-02-17 10:50:15 +00:00
use serde::Deserialize;
2023-02-19 05:00:55 +00:00
use colored::*;
2023-02-21 13:03:32 +00:00
use crate::modules::Command;
2023-02-21 13:03:32 +00:00
2023-02-17 08:38:32 +00:00
mod modules {
pub trait Command {
fn handle(&self, message: &str) -> Vec<String>;
}
pub mod ping;
pub mod kill;
pub mod ai;
2023-02-18 06:47:35 +00:00
pub mod invade;
2023-02-19 21:08:48 +00:00
pub mod test;
pub mod aicode;
2023-02-17 08:38:32 +00:00
}
2023-02-17 10:50:15 +00:00
use modules::ai::Ai; // FIX THIS BS
2023-02-17 08:38:32 +00:00
use modules::ping::PingCommand;
2023-02-18 06:47:35 +00:00
use modules::invade::InvadeCommand;
use modules::aicode::AiCode;
2023-02-17 10:50:15 +00:00
use modules::kill::KillCommand; // ...
#[derive(Deserialize)]
struct Config {
server: String,
port: u16,
nick: String,
password: String,
channels: Vec<String>,
admin_users: Vec<String>,
ignore_users: Vec<String>,
2023-02-21 13:03:32 +00:00
2023-02-17 10:50:15 +00:00
}
2023-02-17 08:38:32 +00:00
fn main() {
let rt = tokio::runtime::Builder::new_multi_thread()
.enable_all()
.build()
.unwrap();
// LOAD CONFIG
2023-02-17 10:50:15 +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();
// GIVE THE SERVER A SLOPPPY SPAM OF RETARDEDNESS
let stream = TcpStream::connect(format!("{}:{}", config.server, config.port)).unwrap();
2023-02-17 10:50:15 +00:00
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();
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 admin_users = config.admin_users; // ADMINS
let ignored_users = config.ignore_users; // IGNORED
2023-02-17 08:38:32 +00:00
// ...
ssl_stream.write_all(join_command.as_bytes()).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();
//debug chat
2023-02-19 21:08:48 +00:00
println!("{} {}","[%] DEBUG:".bold().green(), received.purple());
2023-02-17 08:38:32 +00:00
// RESPOND TO PINGS
if message.starts_with("PING") {
2023-02-19 21:08:48 +00:00
println!("{} {}","[%] PONG:".bold().green(), config.nick.blue()); // DEBUG
2023-02-17 08:38:32 +00:00
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;
2023-02-18 06:47:35 +00:00
let invade_command = InvadeCommand;
let aicode = AiCode;
2023-02-19 23:42:34 +00:00
2023-02-19 21:08:48 +00:00
//let test_command = TestCommand;
2023-02-17 08:38:32 +00:00
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()) {
2023-02-19 21:08:48 +00:00
println!("{} {}","[!] UNAUTHORIZED:".bold().clear().on_red(), username.red().bold());
2023-02-17 08:38:32 +00:00
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();
}
2023-02-18 06:47:35 +00:00
} else if message.contains(":%invade") {
for response in invade_command.handle(message) {
ssl_stream.write_all(response.as_bytes()).unwrap();
}
} else if message.contains(":%code") {
for response in aicode.handle(message) {
ssl_stream.write_all(response.as_bytes()).unwrap();
}
}
2023-02-17 08:38:32 +00:00
}
// 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
2023-02-17 08:38:32 +00:00
let channel = message.split("PRIVMSG ").nth(1).and_then(|s| s.splitn(2, ' ').next()).unwrap();
if !channels.contains(&channel) {
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()) {
2023-02-19 05:00:55 +00:00
println!("[!] IGNORED: {}", username.red());
2023-02-17 08:38:32 +00:00
continue;
}
for response in ai.handle(message, ) {
ssl_stream.write_all(response.as_bytes()).unwrap();
}
}
},
Err(e) => {
2023-02-19 05:00:55 +00:00
println!("[!] ERROR: {}", e);
2023-02-17 08:38:32 +00:00
break;
},
}
}
}