refactor set_nick flow

This commit is contained in:
tali 2024-01-22 12:48:44 -05:00
parent 2ddd0bc827
commit ec0deb9667
3 changed files with 38 additions and 41 deletions

View File

@ -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

View File

@ -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)

View File

@ -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 =