talircd/lib/server/router.ml

83 lines
1.8 KiB
OCaml

open! Import
type t = {
users : (string_ci, user) Hashtbl.t
(* TODO: channels *)
}
and user = {
router : t;
hostname : string;
outbox : Outbox.t;
mutable key : string_ci;
mutable nick : Irc.name;
mutable userinfo : Irc.userinfo option;
mutable mode : Irc.Mode.t;
}
let make () =
{ users = Hashtbl.create 4096 }
let find_user t nick =
Hashtbl.find_opt t.users (string_ci nick)
module User = struct
type t = user
let make ~router ~hostname ~outbox =
{
router;
hostname;
key = empty_string_ci;
nick = "*";
userinfo = None;
mode = Irc.Mode.of_string "iw";
outbox;
}
let outbox t = t.outbox
let nick t = t.nick
let prefix t = Irc.Msg.User_prefix (t.nick, t.userinfo, Some t.hostname)
let is_registered t = t.key <> empty_string_ci
let unregister t =
Hashtbl.remove t.router.users t.key;
t.key <- empty_string_ci
let set_nick t new_nick =
let key = string_ci new_nick in
if Hashtbl.mem t.router.users key then
`nick_in_use
else begin
((* TODO: relay NICK message *));
if is_registered t then
Outbox.send t.outbox
(Irc.Msg.make "NICK" [new_nick]
~prefix:(prefix t)
~always_trailing:true);
unregister t;
Hashtbl.add t.router.users key t;
t.key <- key;
t.nick <- new_nick;
`nick_set
end
let quit t =
if is_registered t then begin
(* TODO: quit reason *)
Outbox.send t.outbox
(Irc.Msg.make "QUIT" ["Closed"]
~prefix:(prefix t)
~always_trailing:true);
(* TODO: relay QUIT message *)
unregister t
end
end
let privmsg src dst txt =
let prefix = User.prefix src in
match dst with
| `user dst ->
let msg = Irc.Msg.make "PRIVMSG" [User.nick dst; txt] ~prefix in
Outbox.send (User.outbox dst) msg