From 04ad9c6ed77952ef4e70c8a72a313870450e0515 Mon Sep 17 00:00:00 2001 From: tali Date: Wed, 24 Jan 2024 12:10:33 -0500 Subject: [PATCH] cover some edge cases such as join a channel twice --- lib/server/connection.ml | 84 +++++++++++++++++++--------------------- 1 file changed, 40 insertions(+), 44 deletions(-) diff --git a/lib/server/connection.ml b/lib/server/connection.ml index 87863fb..38c925d 100644 --- a/lib/server/connection.ml +++ b/lib/server/connection.ml @@ -261,21 +261,16 @@ let on_msg_names t name = Ok () let join t user chan = - begin - (* TODO: check if already a member *) - (* TODO: check channel mode +k, +l *) - let msg = Msg.make "JOIN" [Chan.name chan] in - Router.relay msg ~from:user [`to_chan chan; `to_self]; - - Router.join chan user; - - if not (Chan.is_registered chan ~router:t.router) then - begin - (* 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 + (* TODO: check channel mode +k, +l *) + let msg = Msg.make "JOIN" [Chan.name chan] in + Router.relay msg ~from:user [`to_chan chan; `to_self]; + Router.join chan user; + if not (Chan.is_registered chan ~router:t.router) then + begin + (* 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 let on_msg_join t name = 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); Ok (Chan.make ~name) in - join t me chan; - (* TODO: send channel topic *) - list_names t chan; - Ok () + match Router.membership chan me with + | _already_a_member -> + 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 - begin - (* edge case: don't relay PART messages if the user is QUIT'ing *) - (* FIXME: this will need to be changed again to handle KICK, i think *) - if User.is_registered user ~router:t.router then - begin - let always_trailing = Option.is_some reason in - let reason = Option.to_list reason in - let msg = Msg.make "PART" (Chan.name chan :: reason) ~always_trailing in - Router.relay msg ~from:user [`to_chan chan; `to_self]; - end; - - Router.part mem; - - (* TODO: if user was op then choose a new op? *) - - if Chan.no_members chan then - begin - debug (fun m -> m "recycling empty channel %S" (Chan.name chan)); - Chan.unregister chan ~router:t.router; - end - end + begin match why with + (* TODO: KICK *) + | `quit -> + (* if called from [quit], then we already relayed the QUIT message *) + () + | `part reason -> + let always_trailing = Option.is_some reason in + let reason = Option.to_list reason in + let msg = Msg.make "PART" (Chan.name chan :: reason) ~always_trailing in + Router.relay msg ~from:user [`to_chan chan; `to_self] + end; + Router.part mem; + (* TODO: if user was op then choose a new op? *) + if Chan.no_members chan then + begin + debug (fun m -> m "recycling empty channel %S" (Chan.name chan)); + Chan.unregister chan ~router:t.router; + end let on_msg_part t name reason = let reason = match reason with @@ -334,7 +330,7 @@ let on_msg_part t name reason = Error (nosuchchannel name) in try - part t me chan ~reason; + leave t me chan ~why:(`part reason); Ok () with Not_found -> 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 Router.relay msg ~from:me [`to_interested]; - User.unregister me ~router:t.router; List.iter - (part t me ~reason:None) + (leave t me ~why:`quit) (User.channels me); + User.unregister me ~router:t.router; t.user <- None end