diff options
author | Adam <adam@sigterm.info> | 2014-02-01 11:12:39 -0800 |
---|---|---|
committer | Adam <adam@sigterm.info> | 2014-02-01 11:12:39 -0800 |
commit | c30fb13a0cb071a1bc74a6c63be318303925e25d (patch) | |
tree | ef05fccf9a359a2c1fb28c28ef3ad62e51dc74e9 | |
parent | 4455d4346c6b806d9b0754c1dffb6adf9e90887a (diff) | |
parent | 7926238fd250ee8d2b5d8ba3118db2520c4a1a40 (diff) |
Merge pull request #43 from ShutterQuick/2.0+ajoinfix
2.0+ajoinfix
-rw-r--r-- | include/anope.h | 2 | ||||
-rw-r--r-- | modules/commands/ns_ajoin.cpp | 119 | ||||
-rw-r--r-- | src/protocol.cpp | 3 |
3 files changed, 92 insertions, 32 deletions
diff --git a/include/anope.h b/include/anope.h index 0f42e6673..354c0bda5 100644 --- a/include/anope.h +++ b/include/anope.h @@ -621,7 +621,7 @@ class commasepstream : public sepstream public: /** Initialize with comma seperator */ - commasepstream(const Anope::string &source) : sepstream(source, ',') { } + commasepstream(const Anope::string &source, bool allowempty = false) : sepstream(source, ',', allowempty) { } }; /** A derived form of sepstream, which seperates on spaces diff --git a/modules/commands/ns_ajoin.cpp b/modules/commands/ns_ajoin.cpp index 54400dd96..62fcd70e7 100644 --- a/modules/commands/ns_ajoin.cpp +++ b/modules/commands/ns_ajoin.cpp @@ -118,51 +118,108 @@ class CommandNSAJoin : public Command } } - void DoAdd(CommandSource &source, NickCore *nc, const Anope::string &chan, const Anope::string &key) + void DoAdd(CommandSource &source, NickCore *nc, const Anope::string &chans, const Anope::string &keys) { AJoinList *channels = nc->Require<AJoinList>("ajoinlist"); - unsigned i = 0; - for (; i < (*channels)->size(); ++i) - if ((*channels)->at(i)->channel.equals_ci(chan)) - break; - - if ((*channels)->size() >= Config->GetModule(this->owner)->Get<unsigned>("ajoinmax")) - source.Reply(_("Sorry, the maximum of %d auto join entries has been reached."), Config->GetModule(this->owner)->Get<unsigned>("ajoinmax")); - else if (i != (*channels)->size()) - source.Reply(_("%s is already on %s's auto join list."), chan.c_str(), nc->display.c_str()); - else if (IRCD->IsChannelValid(chan) == false) - source.Reply(CHAN_X_INVALID, chan.c_str()); - else + Anope::string addedchans; + Anope::string alreadyadded; + Anope::string invalidkey; + commasepstream ksep(keys, true); + commasepstream csep(chans); + for (Anope::string chan, key; csep.GetToken(chan);) + { + ksep.GetToken(key); + + unsigned i = 0; + for (; i < (*channels)->size(); ++i) + if ((*channels)->at(i)->channel.equals_ci(chan)) + break; + + if ((*channels)->size() >= Config->GetModule(this->owner)->Get<unsigned>("ajoinmax")) + { + source.Reply(_("Sorry, the maximum of %d auto join entries has been reached."), Config->GetModule(this->owner)->Get<unsigned>("ajoinmax")); + return; + } + else if (i != (*channels)->size()) + alreadyadded += chan + ", "; + else if (IRCD->IsChannelValid(chan) == false) + source.Reply(CHAN_X_INVALID, chan.c_str()); + else + { + Channel *c = Channel::Find(chan); + Anope::string k; + if (c && c->GetParam("KEY", k) && key != k) + { + invalidkey += chan + ", "; + continue; + } + + AJoinEntry *entry = new AJoinEntry(nc); + entry->owner = nc; + entry->channel = chan; + entry->key = key; + (*channels)->push_back(entry); + addedchans += chan + ", "; + } + } + + if (!alreadyadded.empty()) { - AJoinEntry *entry = new AJoinEntry(nc); - entry->owner = nc; - entry->channel = chan; - entry->key = key; - (*channels)->push_back(entry); - Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to ADD channel " << chan << " to " << nc->display; - source.Reply(_("%s added to %s's auto join list."), chan.c_str(), nc->display.c_str()); + alreadyadded = alreadyadded.substr(0, alreadyadded.length() - 2); + source.Reply(_("%s is already on %s's auto join list."), alreadyadded.c_str(), nc->display.c_str()); } + + if (!invalidkey.empty()) + { + invalidkey = invalidkey.substr(0, invalidkey.length() - 2); + source.Reply(_("%s had an invalid key specified, and was thus ignored."), invalidkey.c_str()); + } + + if (addedchans.empty()) + return; + + addedchans = addedchans.substr(0, addedchans.length() - 2); + Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to ADD channel " << addedchans << " to " << nc->display; + source.Reply(_("%s added to %s's auto join list."), addedchans.c_str(), nc->display.c_str()); } - void DoDel(CommandSource &source, NickCore *nc, const Anope::string &chan) + void DoDel(CommandSource &source, NickCore *nc, const Anope::string &chans) { AJoinList *channels = nc->Require<AJoinList>("ajoinlist"); + Anope::string delchans; + Anope::string notfoundchans; + commasepstream sep(chans); - unsigned i = 0; - for (; i < (*channels)->size(); ++i) - if ((*channels)->at(i)->channel.equals_ci(chan)) - break; + for (Anope::string chan; sep.GetToken(chan);) + { + unsigned i = 0; + for (; i < (*channels)->size(); ++i) + if ((*channels)->at(i)->channel.equals_ci(chan)) + break; - if (i == (*channels)->size()) - source.Reply(_("%s was not found on %s's auto join list."), chan.c_str(), nc->display.c_str()); - else + if (i == (*channels)->size()) + notfoundchans += chan + ", "; + else + { + delete (*channels)->at(i); + delchans += chan + ", "; + } + } + + if (!notfoundchans.empty()) { - delete (*channels)->at(i); - Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to DELETE channel " << chan << " from " << nc->display; - source.Reply(_("%s was removed from %s's auto join list."), chan.c_str(), nc->display.c_str()); + notfoundchans = notfoundchans.substr(0, notfoundchans.length() - 2); + source.Reply(_("%s was not found on %s's auto join list."), notfoundchans.c_str(), nc->display.c_str()); } + if (delchans.empty()) + return; + + delchans = delchans.substr(0, delchans.length() - 2); + Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to DELETE channel " << delchans << " from " << nc->display; + source.Reply(_("%s was removed from %s's auto join list."), delchans.c_str(), nc->display.c_str()); + if ((*channels)->empty()) nc->Shrink<AJoinList>("ajoinlist"); } diff --git a/src/protocol.cpp b/src/protocol.cpp index 2287447b6..01c8d31c8 100644 --- a/src/protocol.cpp +++ b/src/protocol.cpp @@ -322,6 +322,9 @@ bool IRCDProto::IsChannelValid(const Anope::string &chan) if (chan.empty() || chan[0] != '#' || chan.length() > Config->GetBlock("networkinfo")->Get<unsigned>("chanlen")) return false; + if (chan.find_first_of(" ,") != Anope::string::npos) + return false; + return true; } |