refactor set_nick flow
This commit is contained in:
parent
2ddd0bc827
commit
ec0deb9667
|
@ -40,8 +40,8 @@ let srv_motd_lines = [
|
|||
"meowmeowmeowmeowmeowmeow";
|
||||
]
|
||||
|
||||
let initial_user_modestr = "iw"
|
||||
let initial_chan_modestr = "nst"
|
||||
let initial_user_mode = Irc.Mode.Set.of_string "iw"
|
||||
let initial_chan_mode = Irc.Mode.Set.of_string "nst"
|
||||
|
||||
|
||||
(* numeric replies *)
|
||||
|
@ -135,7 +135,7 @@ let set_user_mode user chg =
|
|||
in
|
||||
if chg <> Irc.Mode.Set.no_change then
|
||||
let modestr = Fmt.str "%a" Irc.Mode.Set.pp_change chg in
|
||||
let msg = Irc.Msg.make "MODE" [User.nick user; modestr] ~always_trailing:true in
|
||||
let msg = Irc.Msg.make "MODE" [User.nick user; modestr] in
|
||||
begin
|
||||
Router.relay msg ~from:user [`to_self];
|
||||
User.set_mode user mode;
|
||||
|
@ -145,7 +145,7 @@ let set_chan_mode chan ~from chg =
|
|||
let mode, chg = Irc.Mode.Set.normalize (Chan.mode chan) chg in
|
||||
if chg <> Irc.Mode.Set.no_change then
|
||||
let modestr = Fmt.str "%a" Irc.Mode.Set.pp_change chg in
|
||||
let msg = Irc.Msg.make "MODE" [Chan.name chan; modestr] ~always_trailing:true in
|
||||
let msg = Irc.Msg.make "MODE" [Chan.name chan; modestr] in
|
||||
begin
|
||||
Router.relay msg ~from [`to_chan chan; `to_self];
|
||||
Chan.set_mode chan mode;
|
||||
|
@ -237,8 +237,7 @@ let on_set_chan_mode chan me modestr args =
|
|||
set_chan_mode chan ~from:me chg.chan_modes;
|
||||
Option.iter (set_chan_key chan ~from:me) chg.chan_key;
|
||||
Option.iter (set_chan_limit chan ~from:me) chg.chan_limit;
|
||||
|
||||
(* TODO: chg.chan_ban/op/voice *)
|
||||
(* TODO: ban/op/voice *)
|
||||
|
||||
Ok []
|
||||
|
||||
|
@ -257,12 +256,13 @@ let on_msg_mode t name args =
|
|||
with Not_found ->
|
||||
Error (nosuchnick name)
|
||||
in
|
||||
let+ rpls =
|
||||
let* rpls =
|
||||
match args with
|
||||
| [] -> on_get me
|
||||
| modestr :: args -> on_set me modestr args
|
||||
in
|
||||
List.iter (reply t) rpls
|
||||
List.iter (reply t) rpls;
|
||||
Ok ()
|
||||
|
||||
|
||||
(* messages and channels *)
|
||||
|
@ -295,6 +295,8 @@ let list_names t chan =
|
|||
List.iter
|
||||
(fun user ->
|
||||
(* TODO: check if user is +i and not in channel with them *)
|
||||
(* ("=", 0x3D) - Public channel. *)
|
||||
(* ("@", 0x40) - Secret channel (secret channel mode "+s"). *)
|
||||
reply t ("353", ["@"; Chan.name chan; User.nick user]))
|
||||
(Chan.members chan);
|
||||
reply t ("366", [Chan.name chan; "End of NAMES list"])
|
||||
|
@ -335,11 +337,10 @@ let on_msg_join t name =
|
|||
Chan.join chan me;
|
||||
|
||||
if not (Chan.is_registered chan ~router:t.router) then
|
||||
(* set up newly created channel *)
|
||||
begin
|
||||
Chan.register chan ~router:t.router;
|
||||
set_chan_mode chan ~from:me {
|
||||
add = Irc.Mode.Set.of_string initial_chan_modestr;
|
||||
add = initial_user_mode;
|
||||
rem = Irc.Mode.Set.empty;
|
||||
};
|
||||
(* TODO: make founder +o / +q etc. *)
|
||||
|
@ -377,21 +378,29 @@ let attempt_to_register t =
|
|||
match t.pending_nick, t.pending_userinfo with
|
||||
| Some nick, Some userinfo ->
|
||||
t.pending_nick <- None;
|
||||
let me = User.make ~userinfo ~outbox:t.outbox in
|
||||
begin match User.set_nick me nick ~router:t.router with
|
||||
| `nick_in_use -> Error (nicknameinuse nick)
|
||||
| `nick_set ->
|
||||
t.user <- Some me;
|
||||
welcome t me;
|
||||
set_user_mode me {
|
||||
add = Irc.Mode.Set.of_string initial_user_modestr;
|
||||
rem = Irc.Mode.Set.empty;
|
||||
};
|
||||
Ok ()
|
||||
end
|
||||
if not (Router.is_nick_available t.router nick) then
|
||||
Error (nicknameinuse nick)
|
||||
else
|
||||
let me = User.make ~userinfo ~outbox:t.outbox in
|
||||
t.user <- Some me;
|
||||
welcome t me;
|
||||
set_user_mode me {
|
||||
add = initial_user_mode;
|
||||
rem = Irc.Mode.Set.empty;
|
||||
};
|
||||
Ok ()
|
||||
| _, _ ->
|
||||
Ok ()
|
||||
|
||||
let user_set_nick t me nick =
|
||||
if not (Router.is_nick_available t.router nick) then
|
||||
Error (nicknameinuse nick)
|
||||
else
|
||||
let msg = Irc.Msg.make "NICK" [nick] in
|
||||
Router.relay msg ~from:me [`to_interested];
|
||||
User.set_nick me nick ~router:t.router;
|
||||
Ok ()
|
||||
|
||||
let on_msg_nick t nick =
|
||||
let* () =
|
||||
match Irc.name_type nick with
|
||||
|
@ -400,16 +409,7 @@ let on_msg_nick t nick =
|
|||
in
|
||||
match t.user with
|
||||
| Some me ->
|
||||
begin
|
||||
let msg = Irc.Msg.make "NICK" [nick] in
|
||||
match
|
||||
User.set_nick me nick
|
||||
~router:t.router
|
||||
~success_callback:(fun () -> Router.relay msg ~from:me [`to_interested])
|
||||
with
|
||||
| `nick_in_use -> Error (nicknameinuse nick)
|
||||
| `nick_set -> Ok ()
|
||||
end
|
||||
user_set_nick t me nick
|
||||
| None ->
|
||||
t.pending_nick <- Some nick;
|
||||
attempt_to_register t
|
||||
|
|
|
@ -7,6 +7,9 @@ let make () =
|
|||
{ users = Hashtbl.create 4096;
|
||||
channels = Hashtbl.create 4096 }
|
||||
|
||||
let is_nick_available t nick =
|
||||
Hashtbl.mem t.users (string_ci nick)
|
||||
|
||||
let find_user t nick =
|
||||
Hashtbl.find t.users (string_ci nick)
|
||||
|
||||
|
|
|
@ -30,18 +30,12 @@ let register t ~router =
|
|||
let unregister t ~router =
|
||||
Hashtbl.remove router.users t.nick_key
|
||||
|
||||
let set_nick ?(success_callback = ignore) t new_nick ~router =
|
||||
let key = string_ci new_nick in
|
||||
if Hashtbl.mem router.users key then
|
||||
`nick_in_use
|
||||
else begin
|
||||
(* hack to allow broadcasting a NICK message before nick is actually changed *)
|
||||
success_callback ();
|
||||
let set_nick t new_nick ~router =
|
||||
begin
|
||||
unregister t ~router;
|
||||
t.nick <- new_nick;
|
||||
t.nick_key <- key;
|
||||
t.nick_key <- string_ci new_nick;
|
||||
register t ~router;
|
||||
`nick_set
|
||||
end
|
||||
|
||||
let rec part_all t =
|
||||
|
|
Loading…
Reference in New Issue