78 lines
2.4 KiB
Rust
78 lines
2.4 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 hostname: Arc<Mutex<String>>,
|
|
pub users: Arc<Mutex<HashMap<SocketAddr,User>>>,
|
|
pub channels: Arc<Mutex<HashMap<String,Channel>>>,
|
|
}
|
|
|
|
impl Context {
|
|
pub fn new() -> Context {
|
|
Context {
|
|
hostname: Arc::new(Mutex::new("plankircd".to_string())),
|
|
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 cloned = {
|
|
users.get(addr).cloned()
|
|
};
|
|
|
|
match cloned {
|
|
Some(cloned) => {
|
|
if !cloned.is_valid() || cloned.is_registered() {
|
|
return Err(());
|
|
}
|
|
if users.iter().any(|(k, v)| k != addr && v.nickname == cloned.nickname) {
|
|
return Err(());
|
|
}
|
|
|
|
users.get_mut(addr).unwrap().register();
|
|
Ok(())
|
|
},
|
|
None => Err(())
|
|
}
|
|
}
|
|
|
|
pub fn nick_exists(&self, nick: &str) -> bool {
|
|
self.users.lock().unwrap().values().any(|user| user.nickname == nick)
|
|
}
|
|
|
|
pub fn send_message_to(&self, addr: &SocketAddr, msg: IrcMessage) -> Result<(), SendError<String>> {
|
|
if let Some(user) = self.users.lock().unwrap().get(addr) {
|
|
user.send(msg)
|
|
}
|
|
else { Ok(()) }
|
|
}
|
|
|
|
pub fn is_registered(&self, addr: &SocketAddr) -> bool {
|
|
if let Some(user) = self.users.lock().unwrap().get(addr) {
|
|
user.is_registered()
|
|
}
|
|
else {
|
|
false
|
|
}
|
|
}
|
|
|
|
pub fn connect(&mut self, addr: SocketAddr, send: UnboundedSender<String>) {
|
|
self.users.lock().unwrap().insert(addr, User::new(send));
|
|
}
|
|
|
|
pub fn disconnect(&mut self, addr: &SocketAddr) {
|
|
if let Some(user) = self.users.lock().unwrap().remove(addr) {
|
|
user.send(IrcMessage::new(Some(&self.hostname.lock().unwrap()), IrcCommand::ERROR, vec!["Connection terminated."]));
|
|
}
|
|
}
|
|
} |