diff --git a/lib/server/connection.ml b/lib/server/connection.ml index 98557d4..d90238f 100644 --- a/lib/server/connection.ml +++ b/lib/server/connection.ml @@ -299,14 +299,15 @@ let on_msg_join t name = Ok () let part user chan ~router ~reason = + let mem = Router.membership chan user in begin - let mem = Router.membership chan user in - - Option.iter - (fun reason -> - let msg = Irc.Msg.make "PART" [Chan.name chan; reason] in - Router.relay msg ~from:user [`to_chan chan; `to_self]) - reason; + if User.is_registered user ~router then + begin + let always_trailing = Option.is_some reason in + let reason = Option.to_list reason in + let msg = Irc.Msg.make "PART" (Chan.name chan :: reason) ~always_trailing in + Router.relay msg ~from:user [`to_chan chan; `to_self]; + end; Router.part mem; @@ -319,7 +320,11 @@ let part user chan ~router ~reason = end end -let on_msg_part t name = +let on_msg_part t name reason = + let reason = match reason with + | [] -> None + | xs -> Some (String.concat " " xs) + in let* me = require_registered t in let* chan = try @@ -330,7 +335,7 @@ let on_msg_part t name = Error (nosuchchannel name) in try - part me chan ~router:t.router ~reason:(Some "Parting"); + part me chan ~router:t.router ~reason; Ok () with Not_found -> Error (notonchannel name) @@ -375,11 +380,11 @@ let quit t me ~reason = let msg = Irc.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 me ~router:t.router ~reason:None) (User.channels me); - User.unregister me ~router:t.router; t.user <- None end @@ -388,9 +393,6 @@ let close ?(reason = "Client closed") t = Outbox.close t.outbox let on_msg_quit t reason = - (* TODO: '''When connections are terminated by a client-sent QUIT command, servers - SHOULD prepend with the ASCII string "Quit: " when sending QUIT messages to - other clients''' *) let reason = match reason with | [] -> "Quit" | xs -> String.concat " " ("Quit:" :: xs) @@ -472,7 +474,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 - | "PART", tgt :: _ when tgt <> "" -> on_msg_part t tgt + | "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, _ -> Error (needmoreparams cmd)