Started working on user tracking, but it's currently very broken.

This commit is contained in:
Aaron Weiss 2014-11-11 01:24:01 -05:00
parent 3f0c3ba175
commit 4e40fd8218
3 changed files with 108 additions and 9 deletions

View file

@ -1,9 +1,10 @@
//! Data related to IRC functionality. //! Data related to IRC functionality.
#![unstable] #![unstable]
pub use data::command::Command;
pub use data::config::Config; pub use data::config::Config;
pub use data::message::Message; pub use data::message::Message;
pub use data::command::Command; pub use data::user::User;
pub mod kinds { pub mod kinds {
//! Trait definitions of appropriate Writers and Buffers for use with this library. //! Trait definitions of appropriate Writers and Buffers for use with this library.
@ -26,3 +27,4 @@ pub mod kinds {
pub mod command; pub mod command;
pub mod config; pub mod config;
pub mod message; pub mod message;
pub mod user;

63
src/data/user.rs Normal file
View file

@ -0,0 +1,63 @@
//! Data for tracking user information.
use std::from_str::FromStr;
/// IRC User data.
#[deriving(PartialEq, Clone, Show)]
pub struct User {
/// The user's nickname.
name: String,
/// The user's access level.
access_level: AccessLevel,
}
impl User {
/// Creates a new User.
pub fn new(name: &str) -> User {
let rank = from_str(name);
User {
name: if let Some(Member) = rank {
name.into_string()
} else {
name[1..].into_string()
},
access_level: rank.unwrap(),
}
}
}
///
#[deriving(PartialEq, Clone, Show)]
pub enum AccessLevel {
/// The channel owner (~).
Owner,
/// A channel administrator (&).
Admin,
/// A channel operator (@),
Oper,
/// A channel half-oper (%),
HalfOp,
/// A user with voice (+),
Voice,
/// A normal user,
Member,
}
impl FromStr for AccessLevel {
fn from_str(s: &str) -> Option<AccessLevel> {
if s.len() == 0 { None } else {
Some(match s.char_at(0) {
'~' => Owner,
'&' => Admin,
'@' => Oper,
'%' => HalfOp,
'+' => Voice,
_ => Member,
})
}
}
}
#[cfg(test)]
mod test {
}

View file

@ -1,11 +1,14 @@
//! Interface for working with IRC Servers //! Interface for working with IRC Servers
#![experimental] #![experimental]
use std::collections::HashMap;
use std::io::{BufferedStream, IoResult}; use std::io::{BufferedStream, IoResult};
use std::sync::Mutex;
use conn::{Connection, NetStream}; use conn::{Connection, NetStream};
use data::command::{Command, JOIN, PONG}; use data::command::{Command, JOIN, PONG};
use data::config::Config; use data::config::Config;
use data::kinds::IrcStream; use data::kinds::IrcStream;
use data::message::Message; use data::message::Message;
use data::user::User;
pub mod utils; pub mod utils;
@ -26,7 +29,9 @@ pub struct IrcServer<'a, T> where T: IrcStream {
/// The thread-safe IRC connection. /// The thread-safe IRC connection.
conn: Connection<T>, conn: Connection<T>,
/// The configuration used with this connection. /// The configuration used with this connection.
config: Config config: Config,
/// A thread-safe map of channels to the list of users in them.
chanlists: Mutex<HashMap<String, Vec<User>>>,
} }
impl<'a> IrcServer<'a, BufferedStream<NetStream>> { impl<'a> IrcServer<'a, BufferedStream<NetStream>> {
@ -39,7 +44,7 @@ impl<'a> IrcServer<'a, BufferedStream<NetStream>> {
} else { } else {
Connection::connect(config.server[], config.port) Connection::connect(config.server[], config.port)
}); });
Ok(IrcServer { config: config, conn: conn }) Ok(IrcServer { config: config, conn: conn, chanlists: Mutex::new(HashMap::new()) })
} }
/// Creates a new IRC server connection from the specified configuration, connecting immediately. /// Creates a new IRC server connection from the specified configuration, connecting immediately.
@ -50,7 +55,7 @@ impl<'a> IrcServer<'a, BufferedStream<NetStream>> {
} else { } else {
Connection::connect(config.server[], config.port) Connection::connect(config.server[], config.port)
}); });
Ok(IrcServer { config: config, conn: conn }) Ok(IrcServer { config: config, conn: conn, chanlists: Mutex::new(HashMap::new()) })
} }
} }
@ -72,10 +77,7 @@ impl<'a, T> IrcServer<'a, T> where T: IrcStream {
/// Creates an IRC server from the specified configuration, and any arbitrary Connection. /// Creates an IRC server from the specified configuration, and any arbitrary Connection.
#[experimental] #[experimental]
pub fn from_connection(config: Config, conn: Connection<T>) -> IrcServer<'a, T> { pub fn from_connection(config: Config, conn: Connection<T>) -> IrcServer<'a, T> {
IrcServer { IrcServer { conn: conn, config: config, chanlists: Mutex::new(HashMap::new()) }
conn: conn,
config: config
}
} }
/// Gets a reference to the IRC server's connection. /// Gets a reference to the IRC server's connection.
@ -92,7 +94,39 @@ impl<'a, T> IrcServer<'a, T> where T: IrcStream {
for chan in self.config.channels.iter() { for chan in self.config.channels.iter() {
self.send(JOIN(chan[], None)).unwrap(); self.send(JOIN(chan[], None)).unwrap();
} }
} } /* FIXME: it's not really clear why this stuff is broken.
else if message.command[] == "353" { // /NAMES
if let Some(users) = message.suffix.clone() {
if let [_, _, ref chan] = message.args[] {
for user in users.split_str(" ") {
if match self.chanlists.lock().get_mut(chan) {
Some(vec) => { vec.push(User::new(user)); false },
None => true,
} {
self.chanlists.lock().insert(chan.clone(), vec!(User::new(user)));
}
}
}
}
} else if message.command[] == "JOIN" || message.command[] == "PART" {
let chan = match message.suffix {
Some(ref suffix) => suffix[],
None => message.args[0][],
};
if let Some(vec) = self.chanlists.lock().get_mut(&String::from_str(chan)) {
if let Some(ref source) = message.suffix {
if let Some(i) = source.find('!') {
if message.command[] == "JOIN" {
vec.push(User::new(source[..i]));
} else {
if let Some(n) = vec.as_slice().position_elem(&User::new(source[..i])) {
vec.swap_remove(n);
}
}
}
}
}
} */
/* TODO: implement more message handling */ /* TODO: implement more message handling */
} }
} }