summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAdam- <Adam-@5417fbe8-f217-4b02-8779-1006273d7864>2010-03-31 04:41:44 +0000
committerAdam- <Adam-@5417fbe8-f217-4b02-8779-1006273d7864>2010-03-31 04:41:44 +0000
commit94822c99c0bc84756ee0870b7d39c6410ed9184a (patch)
treeceef914590a40c3d03973f938b791b01d7dd8fed /src
parenta3347b59a1f103d265c68c5880f9dabee1bbfd6a (diff)
Added last used time to akick view
git-svn-id: http://anope.svn.sourceforge.net/svnroot/anope/trunk@2846 5417fbe8-f217-4b02-8779-1006273d7864
Diffstat (limited to 'src')
-rw-r--r--src/chanserv.c187
-rw-r--r--src/core/cs_akick.c7
-rw-r--r--src/core/db_plain.cpp7
-rw-r--r--src/regchannel.cpp117
-rw-r--r--src/tools/db-convert.c2
5 files changed, 155 insertions, 165 deletions
diff --git a/src/chanserv.c b/src/chanserv.c
index b144df6f3..622f823d7 100644
--- a/src/chanserv.c
+++ b/src/chanserv.c
@@ -119,45 +119,6 @@ void moduleAddChanServCmds() {
/* *INDENT-ON* */
/*************************************************************************/
-/** A timer used to keep the BotServ bot/ChanServ in the channel
- * after kicking the last user in a channel
- */
-class ChanServTimer : public Timer
-{
- private:
- Channel *c;
-
- public:
- ChanServTimer(Channel *chan) : Timer(Config.CSInhabit), c(chan)
- {
- if (c->ci)
- c->ci->SetFlag(CI_INHABIT);
- }
-
- void Tick(time_t)
- {
- if (!c->ci)
- return;
-
- c->ci->UnsetFlag(CI_INHABIT);
-
- /* If the channel has users again, don't part it and halt */
- if (!c->users.empty())
- return;
-
- if (c->ci->bi)
- ircdproto->SendPart(c->ci->bi, c, NULL);
- else
- ircdproto->SendPart(findbot(Config.s_ChanServ), c, NULL);
-
- /* Now delete the channel as it is empty */
- if (!c->HasFlag(CH_PERSIST) && !c->ci->HasFlag(CI_PERSIST))
- delete c;
- }
-};
-
-/*************************************************************************/
-
/* Returns modes for mlock in a nice way. */
char *get_mlock_modes(ChannelInfo * ci, int complete)
@@ -614,114 +575,6 @@ int check_should_protect(User * user, char *chan)
/*************************************************************************/
-/** Check whether a user is permitted to be on this channel
- * @param u The user
- * @return true if they were banned, false if they are allowed
- */
-bool ChannelInfo::CheckKick(User *user)
-{
- AutoKick *akick;
- bool set_modes = false, do_kick = false;
- NickCore *nc;
- char mask[BUFSIZE];
- const char *reason;
-
- if (!user || !this->c)
- return false;
-
- if (user->isSuperAdmin == 1)
- return true;
-
- /* We don't enforce services restrictions on clients on ulined services
- * as this will likely lead to kick/rejoin floods. ~ Viper */
- if (is_ulined(user->server->name))
- return true;
-
- if (this->HasFlag(CI_SUSPENDED) || this->HasFlag(CI_FORBIDDEN))
- {
- if (is_oper(user))
- return 0;
-
- get_idealban(this, user, mask, sizeof(mask));
- reason = this->forbidreason ? this->forbidreason : getstring(user, CHAN_MAY_NOT_BE_USED);
- set_modes = true;
- do_kick = true;
- }
-
- if (user->Account() || user->IsRecognized())
- nc = user->Account();
- else
- nc = NULL;
-
- if (!do_kick && ModeManager::FindChannelModeByName(CMODE_EXCEPT) && is_excepted(this, user) == 1)
- return true;
-
- for (unsigned j = 0; j < this->GetAkickCount(); ++j)
- {
- akick = this->GetAkick(j);
-
- if (!akick->InUse || do_kick)
- continue;
-
- if ((akick->HasFlag(AK_ISNICK) && akick->nc == nc)
- || (!akick->HasFlag(AK_ISNICK)
- && match_usermask(akick->mask.c_str(), user)))
- {
- Alog(LOG_DEBUG_2) << user->nick << " matched akick " << (akick->HasFlag(AK_ISNICK) ? akick->nc->display : akick->mask);
- if (akick->HasFlag(AK_ISNICK))
- get_idealban(this, user, mask, sizeof(mask));
- else
- strlcpy(mask, akick->mask.c_str(), sizeof(mask));
- reason = !akick->reason.empty() ? akick->reason.c_str() : Config.CSAutokickReason;
- do_kick = true;
- }
- }
-
-
- if (!do_kick && check_access(user, this, CA_NOJOIN))
- {
- get_idealban(this, user, mask, sizeof(mask));
- reason = getstring(user, CHAN_NOT_ALLOWED_TO_JOIN);
- do_kick = true;
- }
-
- if (!do_kick)
- return false;
-
- Alog(LOG_DEBUG) << "channel: Autokicking "<< user->GetMask() << " from " << this->name;
-
- /* If the channel doesnt have any users and if a bot isn't already in the channel, join it
- * NOTE: we use usercount == 1 here as there is one user, but they are about to be destroyed
- */
- if (this->c->users.size() == 1 && !this->HasFlag(CI_INHABIT))
- {
- /* If channel was forbidden, etc, set it +si to prevent rejoin */
- if (set_modes)
- {
- c->SetMode(NULL, CMODE_NOEXTERNAL);
- c->SetMode(NULL, CMODE_TOPIC);
- c->SetMode(NULL, CMODE_SECRET);
- c->SetMode(NULL, CMODE_INVITE);
- }
-
- /* This channel has no bot assigned to it, join ChanServ */
- if (!this->bi)
- {
- ircdproto->SendJoin(findbot(Config.s_ChanServ), this->name.c_str(), this->c->creation_time);
- }
-
- /* Set a timer for this channel to part the bots later */
- new ChanServTimer(this->c);
- }
-
- this->c->SetMode(NULL, CMODE_BAN, mask);
- this->c->Kick(NULL, user, "%s", reason);
-
- return true;
-}
-
-/*************************************************************************/
-
/* Record the current channel topic in the ChannelInfo structure. */
void record_topic(const char *chan)
@@ -1263,18 +1116,6 @@ const char *get_xop_level(int level)
/*********************** ChanServ command routines ***********************/
/*************************************************************************/
-/*************************************************************************/
-
-
-/*************************************************************************/
-
-/* `last' is set to the last index this routine was called with
- * `perm' is incremented whenever a permission-denied error occurs
- */
-
-
-/*************************************************************************/
-
/* Is the mask stuck? */
AutoKick *is_stuck(ChannelInfo * ci, const char *mask)
@@ -1347,3 +1188,31 @@ void stick_all(ChannelInfo * ci)
ci->c->SetMode(NULL, CMODE_BAN, akick->mask.c_str());
}
}
+
+ChanServTimer::ChanServTimer(Channel *chan) : Timer(Config.CSInhabit), c(chan)
+{
+ if (c->ci)
+ c->ci->SetFlag(CI_INHABIT);
+}
+
+void ChanServTimer::Tick(time_t)
+{
+ if (!c->ci)
+ return;
+
+ c->ci->UnsetFlag(CI_INHABIT);
+
+ /* If the channel has users again, don't part it and halt */
+ if (!c->users.empty())
+ return;
+
+ if (c->ci->bi)
+ ircdproto->SendPart(c->ci->bi, c, NULL);
+ else
+ ircdproto->SendPart(findbot(Config.s_ChanServ), c, NULL);
+
+ /* Now delete the channel as it is empty */
+ if (!c->HasFlag(CH_PERSIST) && !c->ci->HasFlag(CI_PERSIST))
+ delete c;
+}
+
diff --git a/src/core/cs_akick.c b/src/core/cs_akick.c
index 355dd09ee..f73360769 100644
--- a/src/core/cs_akick.c
+++ b/src/core/cs_akick.c
@@ -114,6 +114,13 @@ int akick_view(User * u, int index, ChannelInfo * ci, int *sent_header)
((akick->HasFlag(AK_ISNICK)) ? akick->nc->display : akick->mask.c_str()),
!akick->creator.empty() ? akick->creator.c_str() : getstring(u, UNKNOWN), timebuf,
(!akick->reason.empty() ? akick->reason.c_str() : getstring(u, NO_REASON)));
+ if (akick->last_used)
+ {
+ char last_used[64];
+ tm = *localtime(&akick->last_used);
+ strftime_lang(last_used, sizeof(last_used), u, STRFTIME_SHORT_DATE_FORMAT, &tm);
+ notice_lang(Config.s_ChanServ, u, CHAN_AKICK_LAST_USED, last_used);
+ }
return 1;
}
diff --git a/src/core/db_plain.cpp b/src/core/db_plain.cpp
index 10e21359c..02dc71b3b 100644
--- a/src/core/db_plain.cpp
+++ b/src/core/db_plain.cpp
@@ -733,9 +733,9 @@ class DBPlain : public Module
}
AutoKick *ak;
if (Nick)
- ak = ci->AddAkick(params[3], nc, params.size() > 5 ? params[5] : "", strtol(params[4].c_str(), NULL, 10));
+ ak = ci->AddAkick(params[3], nc, params.size() > 6 ? params[6] : "", atol(params[4].c_str()), atol(params[5].c_str()));
else
- ak = ci->AddAkick(params[3], params[2], params.size() > 5 ? params[5] : "", strtol(params[4].c_str(), NULL, 10));
+ ak = ci->AddAkick(params[3], params[2], params.size() > 6 ? params[6] : "", atol(params[4].c_str()), atol(params[5].c_str()));
if (Stuck)
ak->SetFlag(AK_STUCK);
if (Nick)
@@ -1016,7 +1016,8 @@ class DBPlain : public Module
<< (ci->GetAkick(k)->HasFlag(AK_STUCK) ? "STUCK " : "UNSTUCK ")
<< (ci->GetAkick(k)->HasFlag(AK_ISNICK) ? "NICK " : "MASK ")
<< (ci->GetAkick(k)->HasFlag(AK_ISNICK) ? ci->GetAkick(k)->nc->display : ci->GetAkick(k)->mask)
- << " " << ci->GetAkick(k)->creator << " " << ci->GetAkick(k)->addtime << " :";
+ << " " << ci->GetAkick(k)->creator << " " << ci->GetAkick(k)->addtime
+ << " " << ci->last_used << " :";
if (!ci->GetAkick(k)->reason.empty())
db << ci->GetAkick(k)->reason;
db << endl;
diff --git a/src/regchannel.cpp b/src/regchannel.cpp
index 1f4542948..1dcf9f515 100644
--- a/src/regchannel.cpp
+++ b/src/regchannel.cpp
@@ -14,6 +14,7 @@
#include "services.h"
#include "modules.h"
+#include "language.h"
/** Default constructor
* @param chname The channel name
@@ -245,9 +246,10 @@ void ChannelInfo::ClearAccess()
* @param akicknc The nickcore being akicked
* @param reason The reason for the akick
* @param t The time the akick was added, defaults to now
+ * @param lu The time the akick was last used, defaults to never
* @return The AutoKick structure
*/
-AutoKick *ChannelInfo::AddAkick(const std::string &user, NickCore *akicknc, const std::string &reason, time_t t)
+AutoKick *ChannelInfo::AddAkick(const std::string &user, NickCore *akicknc, const std::string &reason, time_t t, time_t lu)
{
if (!akicknc)
return NULL;
@@ -259,6 +261,7 @@ AutoKick *ChannelInfo::AddAkick(const std::string &user, NickCore *akicknc, cons
autokick->reason = reason;
autokick->creator = user;
autokick->addtime = t;
+ autokick->last_used = lu;
akick.push_back(autokick);
return autokick;
@@ -269,9 +272,10 @@ AutoKick *ChannelInfo::AddAkick(const std::string &user, NickCore *akicknc, cons
* @param mask The mask of the akick
* @param reason The reason for the akick
* @param t The time the akick was added, defaults to now
+ * @param lu The time the akick was last used, defaults to never
* @return The AutoKick structure
*/
-AutoKick *ChannelInfo::AddAkick(const std::string &user, const std::string &mask, const std::string &reason, time_t t)
+AutoKick *ChannelInfo::AddAkick(const std::string &user, const std::string &mask, const std::string &reason, time_t t, time_t lu)
{
AutoKick *autokick = new AutoKick();
autokick->mask = mask;
@@ -279,6 +283,7 @@ AutoKick *ChannelInfo::AddAkick(const std::string &user, const std::string &mask
autokick->reason = reason;
autokick->creator = user;
autokick->addtime = t;
+ autokick->last_used = lu;
akick.push_back(autokick);
return autokick;
@@ -551,3 +556,111 @@ void ChannelInfo::ClearParams()
Params.clear();
}
+/** Check whether a user is permitted to be on this channel
+ * @param u The user
+ * @return true if they were banned, false if they are allowed
+ */
+bool ChannelInfo::CheckKick(User *user)
+{
+ AutoKick *akick;
+ bool set_modes = false, do_kick = false;
+ NickCore *nc;
+ char mask[BUFSIZE];
+ const char *reason;
+
+ if (!user || !this->c)
+ return false;
+
+ if (user->isSuperAdmin == 1)
+ return true;
+
+ /* We don't enforce services restrictions on clients on ulined services
+ * as this will likely lead to kick/rejoin floods. ~ Viper */
+ if (is_ulined(user->server->name))
+ return true;
+
+ if (this->HasFlag(CI_SUSPENDED) || this->HasFlag(CI_FORBIDDEN))
+ {
+ if (is_oper(user))
+ return 0;
+
+ get_idealban(this, user, mask, sizeof(mask));
+ reason = this->forbidreason ? this->forbidreason : getstring(user, CHAN_MAY_NOT_BE_USED);
+ set_modes = true;
+ do_kick = true;
+ }
+
+ if (user->Account() || user->IsRecognized())
+ nc = user->Account();
+ else
+ nc = NULL;
+
+ if (!do_kick && ModeManager::FindChannelModeByName(CMODE_EXCEPT) && is_excepted(this, user) == 1)
+ return true;
+
+ for (unsigned j = 0; j < this->GetAkickCount(); ++j)
+ {
+ akick = this->GetAkick(j);
+
+ if (!akick->InUse || do_kick)
+ continue;
+
+ if ((akick->HasFlag(AK_ISNICK) && akick->nc == nc)
+ || (!akick->HasFlag(AK_ISNICK)
+ && match_usermask(akick->mask.c_str(), user)))
+ {
+ Alog(LOG_DEBUG_2) << user->nick << " matched akick " << (akick->HasFlag(AK_ISNICK) ?
+akick->nc->display : akick->mask);
+ akick->last_used = time(NULL);
+ if (akick->HasFlag(AK_ISNICK))
+ get_idealban(this, user, mask, sizeof(mask));
+ else
+ strlcpy(mask, akick->mask.c_str(), sizeof(mask));
+ reason = !akick->reason.empty() ? akick->reason.c_str() : Config.CSAutokickReason;
+ do_kick = true;
+ }
+ }
+
+
+ if (!do_kick && check_access(user, this, CA_NOJOIN))
+ {
+ get_idealban(this, user, mask, sizeof(mask));
+ reason = getstring(user, CHAN_NOT_ALLOWED_TO_JOIN);
+ do_kick = true;
+ }
+
+ if (!do_kick)
+ return false;
+
+ Alog(LOG_DEBUG) << "channel: Autokicking "<< user->GetMask() << " from " << this->name;
+
+ /* If the channel doesnt have any users and if a bot isn't already in the channel, join it
+ * NOTE: we use usercount == 1 here as there is one user, but they are about to be destroyed
+ */
+ if (this->c->users.size() == 1 && !this->HasFlag(CI_INHABIT))
+ {
+ /* If channel was forbidden, etc, set it +si to prevent rejoin */
+ if (set_modes)
+ {
+ c->SetMode(NULL, CMODE_NOEXTERNAL);
+ c->SetMode(NULL, CMODE_TOPIC);
+ c->SetMode(NULL, CMODE_SECRET);
+ c->SetMode(NULL, CMODE_INVITE);
+ }
+
+ /* This channel has no bot assigned to it, join ChanServ */
+ if (!this->bi)
+ {
+ ircdproto->SendJoin(findbot(Config.s_ChanServ), this->name.c_str(), this->c->creation_time);
+ }
+
+ /* Set a timer for this channel to part the bots later */
+ new ChanServTimer(this->c);
+ }
+
+ this->c->SetMode(NULL, CMODE_BAN, mask);
+ this->c->Kick(NULL, user, "%s", reason);
+
+ return true;
+}
+
diff --git a/src/tools/db-convert.c b/src/tools/db-convert.c
index 53760771a..8f3c326a2 100644
--- a/src/tools/db-convert.c
+++ b/src/tools/db-convert.c
@@ -827,7 +827,7 @@ int main(int argc, char *argv[])
<< ((ci->akick[j].flags & AK_STUCK) ? "STUCK " : "UNSTUCK " )
<< ((ci->akick[j].flags & AK_ISNICK) ? "NICK " : "MASK ")
<< ((ci->akick[j].flags & AK_ISNICK) ? ci->akick[j].u.nc->display : ci->akick[j].u.mask )
- << " " << ci->akick[j].creator << " " << ci->akick[j].addtime << " :";
+ << " " << ci->akick[j].creator << " " << ci->akick[j].addtime << " 0 :"; // 0 is for last used, added in 1.9.2
if (ci->akick[j].reason)
fs << ci->akick[j].reason;
fs << std::endl;