2008-03-19 16:19:24 -06:00
|
|
|
module String_map =
|
|
|
|
Map.Make (struct
|
|
|
|
type t = string
|
|
|
|
let compare = compare
|
|
|
|
end)
|
2008-02-28 22:00:24 -07:00
|
|
|
|
2008-03-19 16:19:24 -06:00
|
|
|
type client = Iobuf.t * Irc.nuhost
|
2008-03-02 21:30:37 -07:00
|
|
|
|
2008-03-19 16:19:24 -06:00
|
|
|
type t = {name: string;
|
|
|
|
modes: string ref;
|
2008-05-09 08:01:11 -06:00
|
|
|
clients: client String_map.t ref}
|
2008-02-28 22:00:24 -07:00
|
|
|
|
2008-03-19 16:19:24 -06:00
|
|
|
let modes = "aimnqpsrtklb"
|
2008-02-28 22:00:24 -07:00
|
|
|
|
2008-05-09 08:01:11 -06:00
|
|
|
let by_name = ref String_map.empty
|
2008-03-07 12:00:40 -07:00
|
|
|
|
|
|
|
let is_channel_name name =
|
|
|
|
match name.[0] with
|
|
|
|
| '#' | '&' | '!' | '+' ->
|
|
|
|
true
|
|
|
|
| _ ->
|
|
|
|
false
|
2008-03-19 16:19:24 -06:00
|
|
|
|
|
|
|
let has_mode chan mode =
|
|
|
|
String.contains !(chan.modes) mode
|
|
|
|
|
2008-05-09 08:01:11 -06:00
|
|
|
(* Channels handle:
|
|
|
|
|
|
|
|
NICK, MODE, JOIN, PART, QUIT, TOPIC, NAMES, LIST, INVITE, KICK, PRIVMSG, NOTICE
|
|
|
|
*)
|
|
|
|
|
|
|
|
let write iobuf command args text =
|
|
|
|
Iobuf.write iobuf (Command.create (Some !(Irc.name)) command args text)
|
|
|
|
|
|
|
|
let broadcast ?(metoo=false) chan sender command args text =
|
|
|
|
let sender_iobuf, sender_nuhost = sender in
|
|
|
|
let cmd =
|
|
|
|
Command.create
|
|
|
|
(Some (Irc.string_of_nuhost sender_nuhost))
|
|
|
|
command
|
|
|
|
args
|
|
|
|
text
|
|
|
|
in
|
|
|
|
let bwrite _ (iobuf, nuhost) =
|
|
|
|
if (metoo || (nuhost <> sender_nuhost)) then
|
|
|
|
Iobuf.write iobuf cmd
|
|
|
|
in
|
|
|
|
String_map.iter bwrite !(chan.clients)
|
|
|
|
|
|
|
|
|
|
|
|
let reply iobuf nick num ?(args=[]) text =
|
|
|
|
write iobuf num (nick :: args) (Some text)
|
|
|
|
|
|
|
|
let handle_command cli nuhost cmd =
|
2008-03-19 16:19:24 -06:00
|
|
|
match (Command.as_tuple cmd) with
|
2008-05-09 08:01:11 -06:00
|
|
|
| (None, "JOIN", ["0"], None) ->
|
|
|
|
(* Leave all channels *)
|
|
|
|
failwith "XXX: JOIN 0"
|
|
|
|
| (None, "JOIN", [name], None) ->
|
|
|
|
let nick = Irc.nick nuhost in
|
|
|
|
let chan =
|
|
|
|
try
|
|
|
|
String_map.find name !by_name
|
|
|
|
with Not_found ->
|
|
|
|
let c = {name = name; modes = ref ""; clients = ref String_map.empty} in
|
|
|
|
by_name := String_map.add name c !by_name;
|
|
|
|
c
|
|
|
|
in
|
|
|
|
if String_map.mem nick !(chan.clients) then
|
|
|
|
(* Apparently we're expected to drop the command *)
|
|
|
|
()
|
|
|
|
else
|
|
|
|
let me = (cli, nuhost) in
|
|
|
|
chan.clients := String_map.add nick me !(chan.clients);
|
|
|
|
broadcast ~metoo:true chan me "JOIN" [name] None
|
2008-03-19 16:19:24 -06:00
|
|
|
| _ ->
|
|
|
|
()
|