plankircd/src/context.rs
2018-06-20 16:38:12 +02:00

75 lines
3.1 KiB
Rust

use futures::sync::mpsc::UnboundedSender;
use futures::sync::mpsc::SendError;
use std::net::SocketAddr;
use std::collections::HashMap;
use std::sync::{Arc, Mutex};
use user::User;
use channel::Channel;
use models::IrcMessage;
use models::IrcCommand;
#[derive(Clone)]
pub struct Context {
pub connections: Arc<Mutex<HashMap<SocketAddr, UnboundedSender<String>>>>,
pub unregistered_users: Arc<Mutex<HashMap<SocketAddr,User>>>,
pub users: Arc<Mutex<HashMap<String,User>>>,
pub channels: Arc<Mutex<HashMap<String,Channel>>>,
}
impl Context {
pub fn new() -> Context {
Context {
connections: Arc::new(Mutex::new(HashMap::new())),
unregistered_users: Arc::new(Mutex::new(HashMap::new())),
users: Arc::new(Mutex::new(HashMap::new())),
channels: Arc::new(Mutex::new(HashMap::new())),
}
}
pub fn register_user(&mut self, addr: &SocketAddr) -> Result<(), ()> {
let mut users = self.users.lock().unwrap();
let mut unreg = self.unregistered_users.lock().unwrap();
let remove = unreg.remove(addr);
match remove {
Some(user) => {
if users.contains_key(&user.nickname) {
self.send_string_to(&addr, format!(":plankircd 433 {} :Nickname is already in use", user.nickname));
unreg.insert(*addr, user);
return Err(());
}
let mut msg = format!(":plankircd 001 {} :Welcome to IRC!\r\n", user.nickname);
msg += &format!(":plankircd 002 {} :Your host is plankircd, running version 0.0.1\r\n", user.nickname);
msg += &format!(":plankircd 003 {} :This server was created tomorrow\r\n", user.nickname);
msg += &format!(":plankircd 004 {} plankircd plankircd-0.0.1 o o\r\n", user.nickname);
msg += &format!(":plankircd 422 {} :MOTD File is missing\r\n", user.nickname);
let res = self.send_string_to(&addr, msg);
println!("{:?}",res);
users.insert(user.nickname.clone(), user);
Ok(())
},
None => Err(())
}
}
pub fn disconnect(&mut self, addr: &SocketAddr) {
self.send_message_to(addr, IrcMessage::new(Some("plankircd"), IrcCommand::ERROR, vec!["Connection terminated."]));
self.connections.lock().unwrap().remove(addr);
self.unregistered_users.lock().unwrap().remove(addr);
self.users.lock().unwrap().retain(|_, u| u.address != *addr);
}
pub fn is_unreg(&self, addr: &SocketAddr) -> bool {
self.unregistered_users.lock().unwrap().contains_key(addr)
}
pub fn send_string_to(&self, to: &SocketAddr, string: String) -> Result<(),SendError<String>> {
match self.connections.lock().unwrap().get(to) {
Some(tx) => tx.unbounded_send(string),
None => Ok(()), // TODO: proper error
}
}
pub fn send_message_to(&self, to: &SocketAddr, message: IrcMessage) -> Result<(),SendError<String>> {
self.send_string_to(to, message.to_string())
}
}