|
|
|
@ -5,6 +5,7 @@
|
|
|
|
|
|
|
|
|
|
use std::fs::OpenOptions;
|
|
|
|
|
use std::io::{Read, Write};
|
|
|
|
|
use std::time::SystemTime;
|
|
|
|
|
use std::collections::HashMap;
|
|
|
|
|
use std::net::TcpStream;
|
|
|
|
|
use std::str;
|
|
|
|
@ -22,7 +23,8 @@ use std::thread;
|
|
|
|
|
///
|
|
|
|
|
/// `let stream = connect(nick.to_owned()).unwrap();`
|
|
|
|
|
///
|
|
|
|
|
fn connect(nick: String) -> std::io::Result<TcpStream> {
|
|
|
|
|
fn connect() -> std::io::Result<TcpStream> {
|
|
|
|
|
let nick = gen_name();
|
|
|
|
|
// https://doc.rust-lang.org/std/net/struct.TcpStream.html
|
|
|
|
|
let send_stream = TcpStream::connect("irc.oftc.net:6667")?;
|
|
|
|
|
// let send_stream = connector.connect("irc.oftc.net", send_stream).expect("could not connect via tls");
|
|
|
|
@ -34,8 +36,8 @@ fn connect(nick: String) -> std::io::Result<TcpStream> {
|
|
|
|
|
|
|
|
|
|
send_cmd(&send_stream, "USER", user_string)?;
|
|
|
|
|
send_cmd(&send_stream, "NICK", nick_string)?;
|
|
|
|
|
send_cmd(&send_stream, "JOIN", format!("#wownero"))?;
|
|
|
|
|
send_cmd(&send_stream, "JOIN", format!("#wownero-music"))?;
|
|
|
|
|
send_cmd(&send_stream, "JOIN", format!("#wownero\r\n"))?;
|
|
|
|
|
send_cmd(&send_stream, "JOIN", format!("#wownero-music\r\n"))?;
|
|
|
|
|
|
|
|
|
|
Ok(send_stream)
|
|
|
|
|
}
|
|
|
|
@ -70,7 +72,7 @@ pub fn send_cmd(mut stream: &TcpStream, cmd: &str, msg: String) -> Result<usize,
|
|
|
|
|
/// The following example demonstrates how to set up a threaded TcpStream with one
|
|
|
|
|
/// stream reference listening and one receiving.
|
|
|
|
|
/// ```
|
|
|
|
|
/// let send_stream = connect(nick.to_owned(), server.to_owned())?;
|
|
|
|
|
/// let send_stream = connect()?;
|
|
|
|
|
/// let recv_stream = send_stream.try_clone()?;
|
|
|
|
|
/// thread::spawn(move || receive(&recv_stream).expect("error setting up recv_stream"));
|
|
|
|
|
/// ```
|
|
|
|
@ -92,12 +94,12 @@ fn receive(mut stream: &TcpStream) -> std::io::Result<()> {
|
|
|
|
|
match res_string {
|
|
|
|
|
Ok(r) => {
|
|
|
|
|
if !res_string.unwrap().is_empty() {
|
|
|
|
|
if std::fs::File::open("irc.log").is_err() {
|
|
|
|
|
let _ = std::fs::write("irc.log", "");
|
|
|
|
|
if std::fs::File::open(crate::IRC_LOG).is_err() {
|
|
|
|
|
let _ = std::fs::write(crate::IRC_LOG, "");
|
|
|
|
|
}
|
|
|
|
|
let mut f = OpenOptions::new()
|
|
|
|
|
.append(true)
|
|
|
|
|
.open("irc.log")
|
|
|
|
|
.open(crate::IRC_LOG)
|
|
|
|
|
.unwrap();
|
|
|
|
|
if let Err(e) = writeln!(f, "{}", r.to_string()) {
|
|
|
|
|
eprintln!("[!] Failed to write to file: {}", e);
|
|
|
|
@ -109,30 +111,35 @@ fn receive(mut stream: &TcpStream) -> std::io::Result<()> {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Generates a friendly IRC nick string
|
|
|
|
|
///
|
|
|
|
|
/// # Example
|
|
|
|
|
///
|
|
|
|
|
/// ```
|
|
|
|
|
/// let nick = gen_name(); // wowboombox1232348765
|
|
|
|
|
/// ```
|
|
|
|
|
///
|
|
|
|
|
fn gen_name() -> String {
|
|
|
|
|
let secs = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap().as_secs();
|
|
|
|
|
return format!("wowboombox{}", secs);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// A client struct holds nickname, server, and command information as well as
|
|
|
|
|
/// implementing functions to connect to a server and issue commands.
|
|
|
|
|
pub struct Client {
|
|
|
|
|
/// A user must have a nickname
|
|
|
|
|
nick: String,
|
|
|
|
|
/// Storing command data in a hashmap will supply the
|
|
|
|
|
/// user with accurate feedback
|
|
|
|
|
commands: HashMap<String, String>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Client {
|
|
|
|
|
/// Returns a Client with the given nickname and server
|
|
|
|
|
/// as well as a hashmap built with command data
|
|
|
|
|
///
|
|
|
|
|
/// # Arguments
|
|
|
|
|
///
|
|
|
|
|
/// * `nick` - A string holding the desired nickname
|
|
|
|
|
/// * `server` - A string holding the desired server
|
|
|
|
|
/// Returns a Client with a hashmap built with command data
|
|
|
|
|
///
|
|
|
|
|
/// # Example
|
|
|
|
|
///
|
|
|
|
|
/// `let client = Client::new(nick, server);`
|
|
|
|
|
/// `let client = Client::new();`
|
|
|
|
|
///
|
|
|
|
|
pub fn new(nick: String) -> Client {
|
|
|
|
|
pub fn new() -> Client {
|
|
|
|
|
let mut commands = HashMap::new();
|
|
|
|
|
commands.insert("/quit".to_string(), "Command: /quit".to_string());
|
|
|
|
|
commands.insert(
|
|
|
|
@ -164,8 +171,7 @@ impl Client {
|
|
|
|
|
"Command: /names Parameters: <channel>".to_string(),
|
|
|
|
|
);
|
|
|
|
|
Client {
|
|
|
|
|
nick,
|
|
|
|
|
commands,
|
|
|
|
|
commands
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -196,15 +202,15 @@ impl Client {
|
|
|
|
|
|
|
|
|
|
pub fn read_irc_log(&self) -> String {
|
|
|
|
|
let mut s: String = String::new();
|
|
|
|
|
let f = std::fs::File::open("irc.log"); // ("unable to open irc log");
|
|
|
|
|
let f = std::fs::File::open(crate::IRC_LOG); // ("unable to open irc log");
|
|
|
|
|
if f.is_err() { return "".to_owned() }
|
|
|
|
|
let _ = f.unwrap().read_to_string(&mut s);
|
|
|
|
|
return s;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn send_tune(&self) -> std::io::Result<()> {
|
|
|
|
|
let stream = connect(self.nick.to_owned())?;
|
|
|
|
|
thread::spawn(move || send_cmd(&stream, "PRIVMSG", "#wownero-music !tune".to_owned()));
|
|
|
|
|
let stream = connect()?;
|
|
|
|
|
thread::spawn(move || send_cmd(&stream, "PRIVMSG", "#wownero-music :!tune\r\n".to_owned()));
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -214,7 +220,7 @@ impl Client {
|
|
|
|
|
/// after commands and processed and messages verified,
|
|
|
|
|
/// the send stream is used to send command/message combinations.
|
|
|
|
|
pub fn run(&self) -> Result<TcpStream, std::io::Error> {
|
|
|
|
|
let send_stream = connect(self.nick.to_owned())?;
|
|
|
|
|
let send_stream = connect()?;
|
|
|
|
|
let recv_stream = send_stream.try_clone()?;
|
|
|
|
|
// https://doc.rust-lang.org/nightly/std/thread/
|
|
|
|
|
thread::spawn(move || receive(&recv_stream).expect("error setting up recv_stream"));
|
|
|
|
|