diff options
author | Adam <Adam@anope.org> | 2011-01-17 15:46:53 -0500 |
---|---|---|
committer | Adam <Adam@anope.org> | 2011-01-17 15:46:53 -0500 |
commit | 8975b52cc3087db9504de7ad6e707234cb158a36 (patch) | |
tree | d666c5abe448e5451edbd9c0993a46f28cbc6c04 /modules | |
parent | 7acbbbbf5b661fd2d7b42f3e3adaea949f68cbef (diff) |
Added ns_ajoin
Diffstat (limited to 'modules')
-rw-r--r-- | modules/core/cs_ban.cpp | 2 | ||||
-rw-r--r-- | modules/core/ns_ajoin.cpp | 240 | ||||
-rw-r--r-- | modules/extra/cs_tban.cpp | 2 |
3 files changed, 242 insertions, 2 deletions
diff --git a/modules/core/cs_ban.cpp b/modules/core/cs_ban.cpp index dc56bb995..8ff5319fb 100644 --- a/modules/core/cs_ban.cpp +++ b/modules/core/cs_ban.cpp @@ -47,7 +47,7 @@ class CommandCSBan : public Command * Dont ban/kick the user on channels where he is excepted * to prevent services <-> server wars. */ - else if (ModeManager::FindChannelModeByName(CMODE_EXCEPT) && is_excepted(ci, u2)) + else if (matches_list(ci->c, u2, CMODE_EXCEPT)) source.Reply(CHAN_EXCEPTED, u2->nick.c_str(), ci->name.c_str()); else if (u2->IsProtected()) source.Reply(ACCESS_DENIED); diff --git a/modules/core/ns_ajoin.cpp b/modules/core/ns_ajoin.cpp new file mode 100644 index 000000000..9b1de33d3 --- /dev/null +++ b/modules/core/ns_ajoin.cpp @@ -0,0 +1,240 @@ +/* NickServ core functions + * + * (C) 2003-2011 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + * Based on the original code of Epona by Lara. + * Based on the original code of Services by Andy Church. + */ + +/*************************************************************************/ + +#include "module.h" + +class CommandNSAJoin : public Command +{ + void DoList(CommandSource &source, const std::vector<Anope::string> ¶ms) + { + std::vector<std::pair<Anope::string, Anope::string> > channels; + source.u->Account()->GetExtRegular("ns_ajoin_channels", channels); + + if (channels.empty()) + source.Reply(NICK_AJOIN_LIST_EMPTY); + else + { + source.Reply(NICK_AJOIN_LIST_HEAD); + for (unsigned i = 0; i < channels.size(); ++i) + source.Reply(" %3d %-23s %s", i + 1, channels[i].first.c_str(), channels[i].second.c_str()); + } + } + + void DoAdd(CommandSource &source, const std::vector<Anope::string> ¶ms) + { + std::vector<std::pair<Anope::string, Anope::string> > channels; + source.u->Account()->GetExtRegular("ns_ajoin_channels", channels); + + if (channels.size() >= Config->AJoinMax) + source.Reply(NICK_AJOIN_LIST_FULL); + else if (ircdproto->IsChannelValid(params[1]) == false) + source.Reply(CHAN_X_INVALID, params[1].c_str()); + else + { + channels.push_back(std::make_pair(params[1], params.size() > 2 ? params[2] : "")); + source.Reply(NICK_AJOIN_ADDED, params[1].c_str()); + source.u->Account()->Extend("ns_ajoin_channels", new ExtensibleItemRegular<std::vector< + std::pair<Anope::string, Anope::string> > >(channels)); + } + } + + void DoDel(CommandSource &source, const std::vector<Anope::string> ¶ms) + { + std::vector<std::pair<Anope::string, Anope::string> > channels; + source.u->Account()->GetExtRegular("ns_ajoin_channels", channels); + + unsigned i; + for (i = 0; i < channels.size(); ++i) + if (channels[i].first.equals_ci(params[1])) + break; + + if (i == channels.size()) + source.Reply(NICK_AJOIN_NOTFOUND, params[1].c_str()); + else + { + channels.erase(channels.begin() + i); + source.Reply(NICK_AJOIN_DELETED, params[1].c_str()); + } + } + + public: + CommandNSAJoin() : Command("AJOIN", 1, 3) + { + } + + CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) + { + if (params[0].equals_ci("LIST")) + this->DoList(source, params); + else if (params.size() < 2) + this->OnSyntaxError(source, ""); + else if (params[0].equals_ci("ADD")) + this->DoAdd(source, params); + else if (params[0].equals_ci("DEL")) + this->DoDel(source, params); + else + this->OnSyntaxError(source, ""); + + return MOD_CONT; + } + + bool OnHelp(CommandSource &source, const Anope::string &subcommand) + { + source.Reply(NICK_HELP_AJOIN); + return true; + } + + void OnSyntaxError(CommandSource &source, const Anope::string &subcommand) + { + SyntaxError(source, "AJOIN", NICK_AJOIN_SYNTAX); + } + + void OnServHelp(CommandSource &source) + { + source.Reply(NICK_HELP_CMD_AJOIN); + } +}; + +class NSAJoin : public Module +{ + CommandNSAJoin commandnsajoin; + + public: + NSAJoin(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator) + { + this->SetAuthor("Anope"); + this->SetType(CORE); + + this->AddCommand(NickServ, &commandnsajoin); + + Implementation i[] = { I_OnNickIdentify, I_OnDatabaseWriteMetadata, I_OnDatabaseReadMetadata }; + ModuleManager::Attach(i, this, 3); + } + + void OnNickIdentify(User *u) + { + std::vector<std::pair<Anope::string, Anope::string> > channels; + u->Account()->GetExtRegular("ns_ajoin_channels", channels); + + for (unsigned i = 0; i < channels.size(); ++i) + { + Channel *c = findchan(channels[i].first); + ChannelInfo *ci = c != NULL? c->ci : cs_findchan(channels[i].first); + if (c == NULL && ci != NULL) + c = ci->c; + + bool need_invite = false; + Anope::string key = channels[i].second; + + if (ci != NULL) + { + if (ci->HasFlag(CI_SUSPENDED) || ci->HasFlag(CI_FORBIDDEN)) + continue; + } + if (c != NULL) + { + if (c->FindUser(u) != NULL) + continue; + else if (c->HasMode(CMODE_OPERONLY) && !u->HasMode(UMODE_OPER)) + continue; + else if (c->HasMode(CMODE_ADMINONLY) && !u->HasMode(UMODE_ADMIN)) + continue; + else if (c->HasMode(CMODE_SSL) && !u->HasMode(UMODE_SSL)) + continue; + else if (matches_list(c, u, CMODE_BAN) == true && matches_list(c, u, CMODE_EXCEPT) == false) + need_invite = true; + else if (c->HasMode(CMODE_INVITE) && matches_list(c, u, CMODE_INVITEOVERRIDE) == false) + need_invite = true; + + if (c->HasMode(CMODE_KEY)) + { + Anope::string k; + if (c->GetParam(CMODE_KEY, k)) + { + if (check_access(u, ci, CA_GETKEY)) + key = k; + else if (key != k) + need_invite = true; + } + } + if (c->HasMode(CMODE_LIMIT)) + { + Anope::string l; + if (c->GetParam(CMODE_LIMIT, l)) + { + try + { + unsigned limit = convertTo<unsigned>(l); + if (c->users.size() >= limit) + need_invite = true; + } + catch (const ConvertException &) { } + } + } + } + + if (need_invite) + { + if (!check_access(u, ci, CA_INVITE)) + continue; + ircdproto->SendInvite(NickServ, channels[i].first, u->nick); + } + + ircdproto->SendSVSJoin(NickServ->nick, u->nick, channels[i].first, key); + } + } + + void OnDatabaseWriteMetadata(void (*WriteMetadata)(const Anope::string &, const Anope::string &), NickCore *nc) + { + std::vector<std::pair<Anope::string, Anope::string> > channels; + nc->GetExtRegular("ns_ajoin_channels", channels); + + Anope::string chans; + for (unsigned i = 0; i < channels.size(); ++i) + chans += " " + channels[i].first + "," + channels[i].second; + + if (!chans.empty()) + { + chans.erase(chans.begin()); + WriteMetadata("NS_AJOIN", chans); + } + } + + EventReturn OnDatabaseReadMetadata(NickCore *nc, const Anope::string &key, const std::vector<Anope::string> ¶ms) + { + if (key == "NS_AJOIN") + { + std::vector<std::pair<Anope::string, Anope::string> > channels; + bool valid = nc->GetExtRegular("ns_ajoin_channels", channels); + + for (unsigned i = 0; i < params.size(); ++i) + { + Anope::string chan, chankey; + commasepstream sep(params[0]); + sep.GetToken(chan); + sep.GetToken(chankey); + + channels.push_back(std::make_pair(chan, chankey)); + } + + nc->Extend("ns_ajoin_channels", new ExtensibleItemRegular<std::vector< + std::pair<Anope::string, Anope::string> > >(channels)); + + return EVENT_STOP; + } + + return EVENT_CONTINUE; + } +}; + +MODULE_INIT(NSAJoin) diff --git a/modules/extra/cs_tban.cpp b/modules/extra/cs_tban.cpp index e40e16bc7..35757ff1e 100644 --- a/modules/extra/cs_tban.cpp +++ b/modules/extra/cs_tban.cpp @@ -41,7 +41,7 @@ static bool CanBanUser(Channel *c, User *u, User *u2) bool ok = false; if (!check_access(u, ci, CA_BAN)) u->SendMessage(ChanServ, ACCESS_DENIED); - else if (is_excepted(ci, u2)) + else if (matches_list(c, u2, CMODE_EXCEPT)) u->SendMessage(ChanServ, CHAN_EXCEPTED, u2->nick.c_str(), ci->name.c_str()); else if (u2->IsProtected()) u->SendMessage(ChanServ, ACCESS_DENIED); |