irc-bot/channel.ml

78 lines
2.0 KiB
OCaml
Raw Normal View History

2008-03-19 16:19:24 -06:00
module String_map =
Map.Make (struct
type t = string
let compare = compare
end)
2008-03-19 16:19:24 -06:00
type client = Iobuf.t * Irc.nuhost
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-03-19 16:19:24 -06:00
let modes = "aimnqpsrtklb"
2008-05-09 08:01:11 -06:00
let by_name = ref String_map.empty
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
| _ ->
()