summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam <Adam@anope.org>2013-08-11 17:14:39 -0400
committerAdam <Adam@anope.org>2013-08-11 17:14:39 -0400
commitf1956b039d3c7be38ad03fbb79be6a4eed440cf0 (patch)
tree483b29cf3c67af4742945213eb88a173ae5b6d6a
parent53d5b7c29ea2f0164b562549cef579fe2b276abf (diff)
Remove channels from accesss lists when they expire/drop
-rw-r--r--include/regchannel.h6
-rw-r--r--modules/pseudoclients/chanserv.cpp26
-rw-r--r--src/access.cpp6
-rw-r--r--src/regchannel.cpp25
4 files changed, 63 insertions, 0 deletions
diff --git a/include/regchannel.h b/include/regchannel.h
index 3952e5a54..847e8e317 100644
--- a/include/regchannel.h
+++ b/include/regchannel.h
@@ -47,6 +47,8 @@ class CoreExport AutoKick : public Serializable
*/
class CoreExport ChannelInfo : public Serializable, public Extensible
{
+ /* channels who reference this one */
+ Anope::map<int> references;
private:
Serialize::Reference<NickCore> founder; /* Channel founder */
Serialize::Reference<NickCore> successor; /* Who gets the channel if the founder nick is dropped or expires */
@@ -230,6 +232,10 @@ class CoreExport ChannelInfo : public Serializable, public Extensible
* @return the ChannelInfo associated with the channel
*/
static ChannelInfo* Find(const Anope::string &name);
+
+ void AddChannelReference(const Anope::string &what);
+ void RemoveChannelReference(const Anope::string &what);
+ void GetChannelReferences(std::deque<Anope::string> &chans);
};
/** Is the user the real founder?
diff --git a/modules/pseudoclients/chanserv.cpp b/modules/pseudoclients/chanserv.cpp
index 07d997aa4..e1d98e64c 100644
--- a/modules/pseudoclients/chanserv.cpp
+++ b/modules/pseudoclients/chanserv.cpp
@@ -199,6 +199,32 @@ class ChanServCore : public Module, public ChanServService
}
}
+ void OnDelChan(ChannelInfo *ci) anope_override
+ {
+ /* remove access entries that are this channel */
+
+ std::deque<Anope::string> chans;
+ ci->GetChannelReferences(chans);
+
+ for (unsigned i = 0; i < chans.size(); ++i)
+ {
+ ChannelInfo *c = ChannelInfo::Find(chans[i]);
+ if (!c)
+ continue;
+
+ for (unsigned j = 0; j < c->GetAccessCount(); ++j)
+ {
+ ChanAccess *a = c->GetAccess(j);
+
+ if (a->mask.equals_ci(ci->name))
+ {
+ delete a;
+ break;
+ }
+ }
+ }
+ }
+
EventReturn OnPreHelp(CommandSource &source, const std::vector<Anope::string> &params) anope_override
{
if (!params.empty() || source.c || source.service != *ChanServ)
diff --git a/src/access.cpp b/src/access.cpp
index 173f3c979..985b69390 100644
--- a/src/access.cpp
+++ b/src/access.cpp
@@ -154,6 +154,12 @@ ChanAccess::~ChanAccess()
const NickAlias *na = NickAlias::Find(this->mask);
if (na != NULL)
na->nc->RemoveChannelReference(this->ci);
+ else
+ {
+ ChannelInfo *c = ChannelInfo::Find(this->mask);
+ if (c)
+ c->RemoveChannelReference(this->ci->name);
+ }
}
}
diff --git a/src/regchannel.cpp b/src/regchannel.cpp
index b79d07890..85b1f5b68 100644
--- a/src/regchannel.cpp
+++ b/src/regchannel.cpp
@@ -401,6 +401,12 @@ void ChannelInfo::AddAccess(ChanAccess *taccess)
na->nc->AddChannelReference(this);
taccess->nc = na->nc;
}
+ else
+ {
+ ChannelInfo *ci = ChannelInfo::Find(taccess->mask);
+ if (ci != NULL)
+ ci->AddChannelReference(this->name);
+ }
}
ChanAccess *ChannelInfo::GetAccess(unsigned index) const
@@ -656,3 +662,22 @@ bool IsFounder(const User *user, const ChannelInfo *ci)
return false;
}
+
+void ChannelInfo::AddChannelReference(const Anope::string &what)
+{
+ ++references[what];
+}
+
+void ChannelInfo::RemoveChannelReference(const Anope::string &what)
+{
+ int &i = references[what];
+ if (--i <= 0)
+ references.erase(what);
+}
+
+void ChannelInfo::GetChannelReferences(std::deque<Anope::string> &chans)
+{
+ chans.clear();
+ for (Anope::map<int>::iterator it = references.begin(); it != references.end(); ++it)
+ chans.push_back(it->first);
+}