void DoChannel(XMLRPCServiceInterface *iface, HTTPClient *client, XMLRPCRequest &request) { if (request.data.empty()) return; Channel *c = Channel::Find(request.data[0]); request.reply("name", iface->Sanitize(c ? c->name : request.data[0])); if (c) { request.reply("bancount", stringify(c->HasMode("BAN"))); int count = 0; std::vector<Anope::string> v = c->GetModeList("BAN"); for (unsigned int i = 0; i < v.size(); ++i) request.reply("ban" + stringify(++count), iface->Sanitize(v[i])); request.reply("exceptcount", stringify(c->HasMode("EXCEPT"))); count = 0; v = c->GetModeList("EXCEPT"); for (unsigned int i = 0; i < v.size(); ++i) request.reply("except" + stringify(++count), iface->Sanitize(v[i])); request.reply("invitecount", stringify(c->HasMode("INVITEOVERRIDE"))); count = 0; v = c->GetModeList("INVITEOVERRIDE"); for (unsigned int i = 0; i < v.size(); ++i) request.reply("invite" + stringify(++count), iface->Sanitize(v[i])); Anope::string users; for (Channel::ChanUserList::const_iterator it = c->users.begin(); it != c->users.end(); ++it) { ChanUserContainer *uc = it->second; users += uc->status.BuildModePrefixList() + uc->user->nick + " "; } if (!users.empty()) { users.erase(users.length() - 1); request.reply("users", iface->Sanitize(users)); } if (!c->topic.empty()) request.reply("topic", iface->Sanitize(c->topic)); if (!c->topic_setter.empty()) request.reply("topicsetter", iface->Sanitize(c->topic_setter)); request.reply("topictime", stringify(c->topic_time)); request.reply("topicts", stringify(c->topic_ts)); } }
void DoChannel(XMLRPCServiceInterface *iface, XMLRPCClientSocket *source, XMLRPCRequest *request) { if (request->data.empty()) return; Channel *c = findchan(request->data[0]); request->reply("name", iface->Sanitize(c ? c->name : request->data[0])); if (c) { request->reply("bancount", stringify(c->HasMode(CMODE_BAN))); int count = 0; std::pair<Channel::ModeList::iterator, Channel::ModeList::iterator> its = c->GetModeList(CMODE_BAN); for (; its.first != its.second; ++its.first) request->reply("ban" + stringify(++count), iface->Sanitize(its.first->second)); request->reply("exceptcount", stringify(c->HasMode(CMODE_EXCEPT))); count = 0; its = c->GetModeList(CMODE_EXCEPT); for (; its.first != its.second; ++its.first) request->reply("except" + stringify(++count), iface->Sanitize(its.first->second)); request->reply("invitecount", stringify(c->HasMode(CMODE_INVITEOVERRIDE))); count = 0; its = c->GetModeList(CMODE_INVITEOVERRIDE); for (; its.first != its.second; ++its.first) request->reply("invite" + stringify(++count), iface->Sanitize(its.first->second)); Anope::string users; for (CUserList::const_iterator it = c->users.begin(); it != c->users.end(); ++it) { UserContainer *uc = *it; users += uc->Status->BuildModePrefixList() + uc->user->nick + " "; } if (!users.empty()) { users.erase(users.length() - 1); request->reply("users", iface->Sanitize(users)); } if (!c->topic.empty()) request->reply("topic", iface->Sanitize(c->topic)); if (!c->topic_setter.empty()) request->reply("topicsetter", iface->Sanitize(c->topic_setter)); request->reply("topictime", stringify(c->topic_time)); } }
void Execute(IRCServer *server, User *u, const std::vector<std::string> ¶ms) { const std::string &target = params[0]; Channel *c = server->FindChannel(target); if (c == NULL) u->WriteNumeric(403, target + " :No such channel"); else if (params.size() == 1) { u->WriteNumeric(332, c->GetName() + " :" + c->GetTopic()); u->WriteNumeric(333, c->GetName() + " " + u->GetNick() + " " + Sinkhole::stringify(c->topic_time)); } else { user_status *status = c->FindUserStatus(u); if (c->HasMode(CMODE_PROTECTEDTOPIC) && (status == NULL || !status->HasMode(CMODE_OP))) u->WriteNumeric(482, c->GetName() + " :You're not a channel operator"); else { std::string topic = params[1]; if (topic.length() > IRCServer::topiclen) topic = topic.substr(0, IRCServer::topiclen); c->SetTopic(topic); c->Send(u->GetMask(), "TOPIC " + c->GetName() + " :" + topic); } } }
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); } }
void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) { const Anope::string &chan = params[0]; const Anope::string &chdesc = params.size() > 1 ? params[1] : ""; User *u = source.u; Channel *c = findchan(params[0]); ChannelInfo *ci = cs_findchan(params[0]); if (readonly) source.Reply(_("Sorry, channel registration is temporarily disabled.")); else if (u->Account()->HasFlag(NI_UNCONFIRMED)) source.Reply(_("You must confirm your account before you can register a channel.")); else if (chan[0] == '&') source.Reply(_("Local channels cannot be registered.")); else if (chan[0] != '#') source.Reply(CHAN_SYMBOL_REQUIRED); else if (!ircdproto->IsChannelValid(chan)) source.Reply(CHAN_X_INVALID, chan.c_str()); else if (ci) source.Reply(_("Channel \002%s\002 is already registered!"), chan.c_str()); else if (c && !c->HasUserStatus(u, CMODE_OP)) source.Reply(_("You must be a channel operator to register the channel.")); else if (Config->CSMaxReg && u->Account()->channelcount >= Config->CSMaxReg && !u->HasPriv("chanserv/no-register-limit")) source.Reply(u->Account()->channelcount > Config->CSMaxReg ? CHAN_EXCEEDED_CHANNEL_LIMIT : _(CHAN_REACHED_CHANNEL_LIMIT), Config->CSMaxReg); else { ci = new ChannelInfo(chan); ci->SetFounder(u->Account()); if (!chdesc.empty()) ci->desc = chdesc; ci->mode_locks = def_mode_locks; for (ChannelInfo::ModeList::iterator it = ci->mode_locks.begin(), it_end = ci->mode_locks.end(); it != it_end; ++it) { it->second.setter = u->nick; it->second.ci = ci; } if (c && !c->topic.empty()) { ci->last_topic = c->topic; ci->last_topic_setter = c->topic_setter; ci->last_topic_time = c->topic_time; } else ci->last_topic_setter = source.owner->nick; Log(LOG_COMMAND, u, this, ci); source.Reply(_("Channel \002%s\002 registered under your nickname: %s"), chan.c_str(), u->nick.c_str()); /* Implement new mode lock */ if (c) { check_modes(c); ChannelMode *cm; if (u->FindChannel(c) != NULL) { /* On most ircds you do not receive the admin/owner mode till its registered */ if ((cm = ModeManager::FindChannelModeByName(CMODE_OWNER))) c->SetMode(NULL, cm, u->nick); else if ((cm = ModeManager::FindChannelModeByName(CMODE_PROTECT))) c->RemoveMode(NULL, cm, u->nick); } /* Mark the channel as persistent */ if (c->HasMode(CMODE_PERM)) ci->SetFlag(CI_PERSIST); /* Persist may be in def cflags, set it here */ else if (ci->HasFlag(CI_PERSIST) && (cm = ModeManager::FindChannelModeByName(CMODE_PERM))) c->SetMode(NULL, CMODE_PERM); } FOREACH_MOD(I_OnChanRegistered, OnChanRegistered(ci)); } return; }
void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) { const Anope::string &pattern = !params.empty() ? params[0] : ""; const Anope::string &opt = params.size() > 1 ? params[1] : ""; std::list<ChannelModeName> Modes; User *u2; if (!opt.empty() && opt.equals_ci("SECRET")) { Modes.push_back(CMODE_SECRET); Modes.push_back(CMODE_PRIVATE); } ListFormatter list; list.addColumn("Name").addColumn("Users").addColumn("Modes").addColumn("Topic"); if (!pattern.empty() && (u2 = finduser(pattern))) { source.Reply(_("\002%s\002 channel list:"), u2->nick.c_str()); for (UChannelList::iterator uit = u2->chans.begin(), uit_end = u2->chans.end(); uit != uit_end; ++uit) { ChannelContainer *cc = *uit; if (!Modes.empty()) for (std::list<ChannelModeName>::iterator it = Modes.begin(), it_end = Modes.end(); it != it_end; ++it) if (!cc->chan->HasMode(*it)) continue; ListFormatter::ListEntry entry; entry["Name"] = cc->chan->name; entry["Users"] = stringify(cc->chan->users.size()); entry["Modes"] = cc->chan->GetModes(true, true); entry["Topic"] = cc->chan->topic; list.addEntry(entry); } } else { source.Reply(_("Channel list:")); for (channel_map::const_iterator cit = ChannelList.begin(), cit_end = ChannelList.end(); cit != cit_end; ++cit) { Channel *c = cit->second; if (!pattern.empty() && !Anope::Match(c->name, pattern)) continue; if (!Modes.empty()) for (std::list<ChannelModeName>::iterator it = Modes.begin(), it_end = Modes.end(); it != it_end; ++it) if (!c->HasMode(*it)) continue; ListFormatter::ListEntry entry; entry["Name"] = c->name; entry["Users"] = stringify(c->users.size()); entry["Modes"] = c->GetModes(true, true); entry["Topic"] = c->topic; list.addEntry(entry); } } std::vector<Anope::string> replies; list.Process(replies); for (unsigned i = 0; i < replies.size(); ++i) source.Reply(replies[i]); source.Reply(_("End of channel list.")); }