open! Import include Router_types include (val Logging.sublogs logger "Router") type t = router let make ~whowas_history_len = { users = Hashtbl.create 1024; channels = Hashtbl.create 1024; whowas = Cache.make whowas_history_len; lusers = 0; luserchannels = 0; } let lusers t = t.lusers let luserchannels t = t.luserchannels let is_nick_available t nick = not (Hashtbl.mem t.users (string_ci nick)) let find_user t nick = Hashtbl.find t.users (string_ci nick) let find_chan t name = Hashtbl.find t.channels (string_ci name) let whowas t nick = Cache.find_all t.whowas (string_ci nick) let all_channels_seq t = Hashtbl.to_seq_values t.channels let nuke t = begin Hashtbl.iter (fun _ u -> Dllist.reset u.membership) t.users; Hashtbl.iter (fun _ c -> Dllist.reset c.members) t.channels; Hashtbl.clear t.users; Hashtbl.clear t.channels; t.lusers <- 0; t.luserchannels <- 0; end let relay ~(from : user) (msg : Msg.t) tgts = let msg = if msg.prefix = No_prefix then { msg with prefix = User.prefix from } else msg in let bcc u = Outbox.Bcc.add u.outbox in let bcc_not_self u = if u != from then bcc u in let bcc_channel c = List.iter bcc_not_self (Chan.members c) in List.iter (function | `to_self -> bcc from | `to_user tgt -> bcc tgt | `to_chan tgt -> bcc_channel tgt | `to_interested -> bcc from; List.iter bcc_channel (User.channels from)) tgts; Outbox.Bcc.send_all msg let join chan user = let mem = { mem_chan = chan; mem_user = user; mem_priv = Normal; mem_in_chan = None; mem_in_user = None; } in begin mem.mem_in_chan <- Some (Dllist.add_r mem chan.members); mem.mem_in_user <- Some (Dllist.add_r mem user.membership); chan.member_count <- succ chan.member_count; mem end let membership chan user = Dllist.find (fun mem -> mem.mem_chan == chan) user.membership let part mem = try Dllist.remove (Option.get mem.mem_in_user); Dllist.remove (Option.get mem.mem_in_chan); mem.mem_in_user <- None; mem.mem_in_chan <- None; mem.mem_chan.member_count <- pred mem.mem_chan.member_count; with Invalid_argument _ -> warn (fun m -> m "part (%S,%S): already removed" (Chan.name mem.mem_chan) (User.nick mem.mem_user))