summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
authorAdam <Adam@anope.org>2011-01-17 15:46:53 -0500
committerAdam <Adam@anope.org>2011-01-17 15:46:53 -0500
commit8975b52cc3087db9504de7ad6e707234cb158a36 (patch)
treed666c5abe448e5451edbd9c0993a46f28cbc6c04 /modules
parent7acbbbbf5b661fd2d7b42f3e3adaea949f68cbef (diff)
Added ns_ajoin
Diffstat (limited to 'modules')
-rw-r--r--modules/core/cs_ban.cpp2
-rw-r--r--modules/core/ns_ajoin.cpp240
-rw-r--r--modules/extra/cs_tban.cpp2
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> &params)
+ {
+ 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> &params)
+ {
+ 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> &params)
+ {
+ 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> &params)
+ {
+ 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> &params)
+ {
+ 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);