support TOPIC command

This commit is contained in:
tali 2024-01-24 12:38:20 -05:00
parent f057eb1648
commit 3658be9fe4
2 changed files with 48 additions and 3 deletions

View File

@ -16,6 +16,7 @@ let make ~name =
let name t = t.name
let topic t = t.topic
let set_topic t s = t.topic <- s
let mode t = t.chan_mode
let set_mode t new_mode = t.chan_mode <- new_mode
let limit t = t.chan_limit

View File

@ -39,8 +39,13 @@ let reply t (num, params) =
| Some me -> User.nick me
| None -> "*"
in
let always_trailing = match num with
| "324" | "332" | "353" -> true
| _ -> false
in
Outbox.send t.outbox
(Msg.make ~prefix num (target :: params))
(Msg.make num (target :: params)
~prefix ~always_trailing)
let tryagain cmd = "263", [cmd; "Please wait a while and try again."]
let nosuchnick tgt = "401", [tgt; "No such nick/channel"]
@ -264,6 +269,41 @@ let on_msg_names t name =
list_names t chan;
Ok ()
let get_topic ?(reply_if_missing=true) t chan =
match Chan.topic chan with
| Some topic ->
reply t ("332", [Chan.name chan; topic])
(* TODO: RPL_TOPICWHOTIME ? *)
| None ->
if reply_if_missing then
reply t ("331", [Chan.name chan; "No topic is set"])
let set_topic chan topic =
Chan.set_topic chan topic
let on_msg_topic t name args =
let* me = require_registered t in
let* chan =
try
match name_type name with
| `chan -> Ok (Router.find_chan t.router name)
| `nick | `invalid -> raise Not_found
with Not_found ->
Error (nosuchchannel name)
in
match args with
| [] ->
(* TODO: if +s then don't send topic to non-members *)
get_topic t chan;
Ok ()
| args ->
(* TODO: if +t then only allow +o to set topic *)
let topic = String.concat " " args in
let msg = Msg.make "TOPIC" [Chan.name chan; topic] ~always_trailing:true in
Router.relay msg ~from:me [`to_chan chan; `to_self];
set_topic chan (if args = [""] then None else Some topic);
Ok ()
let join t user chan =
(* TODO: check channel mode +k, +l *)
let msg = Msg.make "JOIN" [Chan.name chan] in
@ -284,7 +324,10 @@ let on_msg_join t name =
try
match name_type name with
| `chan -> Ok (Router.find_chan t.router name)
| _ -> Error (nosuchchannel name)
| `nick | `invalid ->
(* pretend malformed channel name means the channel doesn't exist and
DON'T try to make a new channel *)
Error (nosuchchannel name)
with Not_found ->
debug (fun m -> m "making new channel %S" name);
Ok (Chan.make ~name)
@ -294,7 +337,7 @@ let on_msg_join t name =
Ok ()
| exception Not_found ->
join t me chan;
(* TODO: send channel topic *)
get_topic t chan ~reply_if_missing:false;
list_names t chan;
Ok ()
@ -471,6 +514,7 @@ let dispatch t = function
| "PRIVMSG", tgt :: msg :: _ -> on_msg_privmsg t tgt msg
| "JOIN", tgt :: _ when tgt <> "" -> on_msg_join t tgt
| "NAMES", tgt :: _ when tgt <> "" -> on_msg_names t tgt
| "TOPIC", tgt :: args when tgt <> "" -> on_msg_topic t tgt args
| "PART", tgt :: reason when tgt <> "" -> on_msg_part t tgt reason
| "MODE", tgt :: args when tgt <> "" -> on_msg_mode t tgt args
| ("USER" | "JOIN" | "NAMES" | "PART" | "MODE") as cmd, _ ->