cover some edge cases such as join a channel twice

This commit is contained in:
tali 2024-01-24 12:10:33 -05:00
parent 67024c572e
commit 04ad9c6ed7
1 changed files with 40 additions and 44 deletions

View File

@ -261,21 +261,16 @@ let on_msg_names t name =
Ok () Ok ()
let join t user chan = let join t user chan =
begin (* TODO: check channel mode +k, +l *)
(* TODO: check if already a member *) let msg = Msg.make "JOIN" [Chan.name chan] in
(* TODO: check channel mode +k, +l *) Router.relay msg ~from:user [`to_chan chan; `to_self];
let msg = Msg.make "JOIN" [Chan.name chan] in Router.join chan user;
Router.relay msg ~from:user [`to_chan chan; `to_self]; if not (Chan.is_registered chan ~router:t.router) then
begin
Router.join chan user; (* TODO: make founder +o / +q etc. *)
Chan.register chan ~router:t.router;
if not (Chan.is_registered chan ~router:t.router) then set_chan_mode chan ~from:user ~add:t.server_info.conf.init_cmode;
begin end
(* TODO: make founder +o / +q etc. *)
Chan.register chan ~router:t.router;
set_chan_mode chan ~from:user ~add:t.server_info.conf.init_cmode;
end
end
let on_msg_join t name = let on_msg_join t name =
let* me = require_registered t in let* me = require_registered t in
@ -290,34 +285,35 @@ let on_msg_join t name =
debug (fun m -> m "making new channel %S" name); debug (fun m -> m "making new channel %S" name);
Ok (Chan.make ~name) Ok (Chan.make ~name)
in in
join t me chan; match Router.membership chan me with
(* TODO: send channel topic *) | _already_a_member ->
list_names t chan; Ok ()
Ok () | exception Not_found ->
join t me chan;
(* TODO: send channel topic *)
list_names t chan;
Ok ()
let part t user chan ~reason = let leave t user chan ~why =
let mem = Router.membership chan user in let mem = Router.membership chan user in
begin begin match why with
(* edge case: don't relay PART messages if the user is QUIT'ing *) (* TODO: KICK *)
(* FIXME: this will need to be changed again to handle KICK, i think *) | `quit ->
if User.is_registered user ~router:t.router then (* if called from [quit], then we already relayed the QUIT message *)
begin ()
let always_trailing = Option.is_some reason in | `part reason ->
let reason = Option.to_list reason in let always_trailing = Option.is_some reason in
let msg = Msg.make "PART" (Chan.name chan :: reason) ~always_trailing in let reason = Option.to_list reason in
Router.relay msg ~from:user [`to_chan chan; `to_self]; let msg = Msg.make "PART" (Chan.name chan :: reason) ~always_trailing in
end; Router.relay msg ~from:user [`to_chan chan; `to_self]
end;
Router.part mem; Router.part mem;
(* TODO: if user was op then choose a new op? *)
(* TODO: if user was op then choose a new op? *) if Chan.no_members chan then
begin
if Chan.no_members chan then debug (fun m -> m "recycling empty channel %S" (Chan.name chan));
begin Chan.unregister chan ~router:t.router;
debug (fun m -> m "recycling empty channel %S" (Chan.name chan)); end
Chan.unregister chan ~router:t.router;
end
end
let on_msg_part t name reason = let on_msg_part t name reason =
let reason = match reason with let reason = match reason with
@ -334,7 +330,7 @@ let on_msg_part t name reason =
Error (nosuchchannel name) Error (nosuchchannel name)
in in
try try
part t me chan ~reason; leave t me chan ~why:(`part reason);
Ok () Ok ()
with Not_found -> with Not_found ->
Error (notonchannel name) Error (notonchannel name)
@ -380,11 +376,11 @@ let quit t me ~reason =
let msg = Msg.make "QUIT" [User.nick me; reason] ~always_trailing:true in let msg = Msg.make "QUIT" [User.nick me; reason] ~always_trailing:true in
Router.relay msg ~from:me [`to_interested]; Router.relay msg ~from:me [`to_interested];
User.unregister me ~router:t.router;
List.iter List.iter
(part t me ~reason:None) (leave t me ~why:`quit)
(User.channels me); (User.channels me);
User.unregister me ~router:t.router;
t.user <- None t.user <- None
end end