Advertisement
Guest User

Untitled

a guest
Apr 7th, 2020
165
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 3.27 KB | None | 0 0
  1. use crate::IrcClientInformation;
  2. use irc_core::MsgTo::User;
  3. use irc_core::{entities, Message, Reply, UserMode};
  4. use std::sync::mpsc::Receiver;
  5. use std::sync::Mutex;
  6. use std::time::Duration;
  7. use std::{
  8.     io::{Read, Write},
  9.     net::{TcpStream, ToSocketAddrs},
  10.     sync::{mpsc::channel, Arc},
  11.     thread,
  12. };
  13.  
  14. pub struct IrcClient {
  15.     client: TcpStream,
  16.     hooks: Arc<Mutex<Vec<Box<dyn IrcClientEvent + Sync + Send>>>>,
  17. }
  18.  
  19. pub trait IrcClientEvent {
  20.     fn on_message_received(&self, _message: &str) {}
  21. }
  22.  
  23. impl IrcClient {
  24.     pub fn connect<T: ToSocketAddrs>(addr: T) -> std::io::Result<Self> {
  25.         let client_res = TcpStream::connect(addr);
  26.         if let Ok(client) = client_res {
  27.             return Ok(Self {
  28.                 client,
  29.                 hooks: Arc::new(Mutex::new(Vec::new())),
  30.             });
  31.         }
  32.         Err(client_res.unwrap_err())
  33.     }
  34.  
  35.     pub fn add_hook<E: IrcClientEvent + Sync + Send + 'static>(&mut self, hook: E) {
  36.        self.hooks.lock().unwrap().push(Box::new(hook));
  37.    }
  38.  
  39.    pub fn start(&mut self, client_information: IrcClientInformation, mode: UserMode) {
  40.        let (tx, rx) = channel::<Reply>();
  41.        let mut client = self
  42.            .client
  43.            .try_clone()
  44.            .expect("Error creating TcpStream clone for listener thread");
  45.        let hooks = self.hooks.clone();
  46.  
  47.        thread::spawn(move || {
  48.            let mut buffer = [0_u8; 4096];
  49.  
  50.            loop {
  51.                let bytes_read = client.read(&mut buffer).unwrap();
  52.                let mut raw_messages = std::str::from_utf8(&buffer[..bytes_read]).unwrap();
  53.                let message_strings: Vec<&str> = raw_messages.split("\r\n").collect();
  54.  
  55.                for msg_str in message_strings {
  56.                    if msg_str.starts_with("RPL") || msg_str.starts_with("ERR") {
  57.                        tx.send(Reply::None(msg_str.to_string())).unwrap()
  58.                    } else {
  59.                        let lock = hooks.lock().unwrap();
  60.                        for hook in &*lock {
  61.                            hook.on_message_received(msg_str)
  62.                        }
  63.                    }
  64.                }
  65.            }
  66.        });
  67.  
  68.        thread::sleep(Duration::new(1, 0));
  69.  
  70.        let user = entities::User {
  71.            nickname: client_information.nickname,
  72.            username: client_information.username,
  73.            realname: client_information.realname,
  74.        };
  75.  
  76.        Self::write_message(&mut self.client, Message::nick(user.clone()));
  77.        Self::write_message(&mut self.client, Message::user(user, mode));
  78.    }
  79.  
  80.    fn write_message(client: &mut TcpStream, message: Message) {
  81.        client
  82.            .write(message.into_bytes().as_ref())
  83.            .expect("Error sending message to server");
  84.    }
  85.  
  86.    fn await_message_response(
  87.        client: &mut TcpStream,
  88.        rx: &Receiver<Reply>,
  89.        message: Message,
  90.    ) -> Reply {
  91.        Self::write_message(client, message);
  92.  
  93.        rx.recv_timeout(Duration::new(0, 2000))
  94.            .expect("Timeout waiting for reply")
  95.    }
  96.  
  97.    fn read_message(client: &mut TcpStream, buffer: &mut [u8]) -> usize {
  98.        client
  99.            .read(buffer)
  100.            .expect("Error reading response message from server")
  101.    }
  102. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement