void OnUserLogin(User *u) override { ServiceBot *NickServ = Config->GetClient("NickServ"); if (!NickServ) return; std::vector<AutoJoin *> channels = u->Account()->GetRefs<AutoJoin *>(); if (channels.empty()) return; /* Set +r now, so we can ajoin users into +R channels */ ModeManager::ProcessModes(); for (AutoJoin *entry : channels) { Channel *c = Channel::Find(entry->GetChannel()); ChanServ::Channel *ci; if (c) ci = c->ci; else ci = ChanServ::Find(entry->GetChannel()); bool need_invite = false; Anope::string key = entry->GetKey(); ChanServ::AccessGroup u_access; if (ci != NULL) { if (ci->HasFieldS("CS_SUSPENDED")) continue; u_access = ci->AccessFor(u); } if (c != NULL) { if (c->FindUser(u) != NULL) continue; else if (c->HasMode("OPERONLY") && !u->HasMode("OPER")) continue; else if (c->HasMode("ADMINONLY") && !u->HasMode("ADMIN")) continue; else if (c->HasMode("SSL") && !(u->HasMode("SSL") || u->HasExtOK("ssl"))) continue; else if (c->MatchesList(u, "BAN") == true && c->MatchesList(u, "EXCEPT") == false) need_invite = true; else if (c->HasMode("INVITE") && c->MatchesList(u, "INVITEOVERRIDE") == false) need_invite = true; if (c->HasMode("KEY")) { Anope::string k; if (c->GetParam("KEY", k)) { if (u_access.HasPriv("GETKEY")) key = k; else if (key != k) need_invite = true; } } if (c->HasMode("LIMIT")) { Anope::string l; if (c->GetParam("LIMIT", l)) { try { unsigned limit = convertTo<unsigned>(l); if (c->users.size() >= limit) need_invite = true; } catch (const ConvertException &) { } } } } if (need_invite && c != NULL) { if (!u_access.HasPriv("INVITE")) continue; IRCD->SendInvite(NickServ, c, u); } IRCD->SendSVSJoin(NickServ, u, entry->GetChannel(), key); } }