Started working on user tracking, but it's currently very broken.
This commit is contained in:
parent
3f0c3ba175
commit
4e40fd8218
3 changed files with 108 additions and 9 deletions
|
@ -1,9 +1,10 @@
|
|||
//! Data related to IRC functionality.
|
||||
#![unstable]
|
||||
|
||||
pub use data::command::Command;
|
||||
pub use data::config::Config;
|
||||
pub use data::message::Message;
|
||||
pub use data::command::Command;
|
||||
pub use data::user::User;
|
||||
|
||||
pub mod kinds {
|
||||
//! Trait definitions of appropriate Writers and Buffers for use with this library.
|
||||
|
@ -26,3 +27,4 @@ pub mod kinds {
|
|||
pub mod command;
|
||||
pub mod config;
|
||||
pub mod message;
|
||||
pub mod user;
|
||||
|
|
63
src/data/user.rs
Normal file
63
src/data/user.rs
Normal 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 {
|
||||
|
||||
}
|
|
@ -1,11 +1,14 @@
|
|||
//! Interface for working with IRC Servers
|
||||
#![experimental]
|
||||
use std::collections::HashMap;
|
||||
use std::io::{BufferedStream, IoResult};
|
||||
use std::sync::Mutex;
|
||||
use conn::{Connection, NetStream};
|
||||
use data::command::{Command, JOIN, PONG};
|
||||
use data::config::Config;
|
||||
use data::kinds::IrcStream;
|
||||
use data::message::Message;
|
||||
use data::user::User;
|
||||
|
||||
pub mod utils;
|
||||
|
||||
|
@ -26,7 +29,9 @@ pub struct IrcServer<'a, T> where T: IrcStream {
|
|||
/// The thread-safe IRC connection.
|
||||
conn: Connection<T>,
|
||||
/// 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>> {
|
||||
|
@ -39,7 +44,7 @@ impl<'a> IrcServer<'a, BufferedStream<NetStream>> {
|
|||
} else {
|
||||
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.
|
||||
|
@ -50,7 +55,7 @@ impl<'a> IrcServer<'a, BufferedStream<NetStream>> {
|
|||
} else {
|
||||
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.
|
||||
#[experimental]
|
||||
pub fn from_connection(config: Config, conn: Connection<T>) -> IrcServer<'a, T> {
|
||||
IrcServer {
|
||||
conn: conn,
|
||||
config: config
|
||||
}
|
||||
IrcServer { conn: conn, config: config, chanlists: Mutex::new(HashMap::new()) }
|
||||
}
|
||||
|
||||
/// 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() {
|
||||
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 */
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue