summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAdam- <Adam-@5417fbe8-f217-4b02-8779-1006273d7864>2009-12-13 19:32:19 +0000
committerAdam- <Adam-@5417fbe8-f217-4b02-8779-1006273d7864>2009-12-13 19:32:19 +0000
commita7ac6a0ac712892652da6dd8696b94d4c6d3ea84 (patch)
tree9bbcf49157cfda0577c34515cb44d4462818c1da /src
parent3a956c51be22f1b6f3b6808c9f56fb6b26c7dd1a (diff)
Added in a modestacker and rewrote almost all of the remaining old mode code
git-svn-id: http://anope.svn.sourceforge.net/svnroot/anope/trunk@2696 5417fbe8-f217-4b02-8779-1006273d7864
Diffstat (limited to 'src')
-rw-r--r--src/actions.c61
-rw-r--r--src/botserv.c99
-rw-r--r--src/channels.c882
-rw-r--r--src/chanserv.c240
-rw-r--r--src/core/cs_ban.c6
-rw-r--r--src/core/cs_clear.c151
-rw-r--r--src/core/cs_drop.c3
-rw-r--r--src/core/cs_modes.c14
-rw-r--r--src/core/cs_register.c6
-rw-r--r--src/core/cs_set.c6
-rw-r--r--src/core/ns_logout.c4
-rw-r--r--src/core/os_clearmodes.c100
-rw-r--r--src/core/os_defcon.c30
-rw-r--r--src/core/os_mode.c8
-rw-r--r--src/core/os_oline.c2
-rw-r--r--src/core/os_umode.c4
-rw-r--r--src/main.c3
-rw-r--r--src/modes.cpp610
-rw-r--r--src/modules/cs_enforce.c10
-rw-r--r--src/modules/cs_tban.c19
-rw-r--r--src/nickalias.cpp6
-rw-r--r--src/nickcore.cpp1
-rw-r--r--src/protocol.cpp10
-rw-r--r--src/protocol/bahamut.c66
-rw-r--r--src/protocol/inspircd11.c74
-rw-r--r--src/protocol/inspircd12.cpp85
-rw-r--r--src/protocol/ratbox.c46
-rw-r--r--src/protocol/unreal32.c118
-rw-r--r--src/regchannel.cpp2
-rw-r--r--src/users.c217
30 files changed, 1457 insertions, 1426 deletions
diff --git a/src/actions.c b/src/actions.c
index 9ed6b3b72..37bf95798 100644
--- a/src/actions.c
+++ b/src/actions.c
@@ -130,10 +130,7 @@ void sqline(char *mask, char *reason)
*/
void common_unban(ChannelInfo * ci, char *nick)
{
- const char *av[4];
char *host = NULL;
- char buf[BUFSIZE];
- int ac;
uint32 ip = 0;
User *u;
Entry *ban, *next;
@@ -163,63 +160,21 @@ void common_unban(ChannelInfo * ci, char *nick)
if (host)
ip = str_is_ip(host);
- if (ircd->svsmode_unban) {
+ if (ircd->svsmode_unban)
ircdproto->SendBanDel(ci->name, nick);
- } else {
- if (ircdcap->tsmode) {
- snprintf(buf, BUFSIZE - 1, "%ld", static_cast<long>(time(NULL)));
- av[0] = ci->name;
- av[1] = buf;
- av[2] = "-b";
- ac = 4;
- } else {
- av[0] = ci->name;
- av[1] = "-b";
- ac = 3;
- }
-
- for (ban = ci->c->bans->entries; ban; ban = next) {
+ else
+ {
+ for (ban = ci->c->bans->entries; ban; ban = next)
+ {
next = ban->next;
if (entry_match(ban, u->nick, u->GetIdent().c_str(), u->host, ip) ||
- entry_match(ban, u->nick, u->GetIdent().c_str(), u->GetDisplayedHost().c_str(), ip)) {
- ircdproto->SendMode(whosends(ci), ci->name, "-b %s", ban->mask);
- if (ircdcap->tsmode)
- av[3] = ban->mask;
- else
- av[2] = ban->mask;
-
- do_cmode(whosends(ci)->nick, ac, av);
- }
+ entry_match(ban, u->nick, u->GetIdent().c_str(), u->GetDisplayedHost().c_str(), ip))
+ ci->c->RemoveMode(NULL, CMODE_BAN, ban->mask);
}
}
/* host_resolve() sstrdup us this info so we gotta free it */
- if (host) {
+ if (host)
delete [] host;
- }
-}
-
-/*************************************************************************/
-
-/**
- * Prepare to set SVSMODE and update internal user modes
- * @param u user to apply modes to
- * @param modes the modes to set on the user
- * @param arg the arguments for the user modes
- * @return void
- */
-void common_svsmode(User * u, const char *modes, const char *arg)
-{
- int ac = 1;
- const char *av[2];
-
- av[0] = modes;
- if (arg) {
- av[1] = arg;
- ac++;
- }
-
- ircdproto->SendSVSMode(u, ac, av);
- ircdproto->ProcessUsermodes(u, ac, av);
}
/*************************************************************************/
diff --git a/src/botserv.c b/src/botserv.c
index cbd3ccfc2..ab20b0852 100644
--- a/src/botserv.c
+++ b/src/botserv.c
@@ -736,38 +736,20 @@ void bot_join(ChannelInfo * ci)
if (!ci || !ci->c || !ci->bi)
return;
- if (Config.BSSmartJoin) {
+ if (Config.BSSmartJoin)
+ {
/* We check for bans */
- if (ci->c->bans && ci->c->bans->count) {
- char buf[BUFSIZE];
- const char *av[4];
+ if (ci->c->bans && ci->c->bans->count)
+ {
Entry *ban, *next;
- int ac;
-
- if (ircdcap->tsmode) {
- snprintf(buf, BUFSIZE - 1, "%ld", static_cast<long>(time(NULL)));
- av[0] = ci->c->name;
- av[1] = buf;
- av[2] = "-b";
- ac = 4;
- } else {
- av[0] = ci->c->name;
- av[1] = "-b";
- ac = 3;
- }
- for (ban = ci->c->bans->entries; ban; ban = next) {
+ for (ban = ci->c->bans->entries; ban; ban = next)
+ {
next = ban->next;
- if (entry_match
- (ban, ci->bi->nick, ci->bi->user, ci->bi->host, 0)) {
- ircdproto->SendMode(whosends(ci), ci->name, "-b %s",
- ban->mask);
- if (ircdcap->tsmode)
- av[3] = ban->mask;
- else
- av[2] = ban->mask;
- do_cmode(whosends(ci)->nick, ac, av);
+ if (entry_match(ban, ci->bi->nick, ci->bi->user, ci->bi->host, 0))
+ {
+ ci->c->RemoveMode(NULL, CMODE_BAN, ban->mask);
}
}
}
@@ -787,7 +769,8 @@ void bot_join(ChannelInfo * ci)
ci->bi->nick, ci->bi->nick);
}
ircdproto->SendJoin(ci->bi, ci->c->name, ci->c->creation_time);
- ircdproto->SendBotOp(ci->bi->nick, ci->c->name);
+ ci->c->SetMode(NULL, CMODE_PROTECT, ci->bi->nick);
+ ci->c->SetMode(NULL, CMODE_OP, ci->bi->nick);
FOREACH_MOD(I_OnBotJoin, OnBotJoin(ci, ci->bi));
}
@@ -809,31 +792,14 @@ static void check_ban(ChannelInfo * ci, User * u, int ttbtype)
/* Should not use == here because bd->ttb[ttbtype] could possibly be > ci->ttb[ttbtype]
* if the TTB was changed after it was not set (0) before and the user had already been
* kicked a few times. Bug #1056 - Adam */
- const char *av[4];
- int ac;
char mask[BUFSIZE];
- char buf[BUFSIZE];
bd->ttb[ttbtype] = 0;
get_idealban(ci, u, mask, sizeof(mask));
- if (ircdcap->tsmode) {
- snprintf(buf, BUFSIZE - 1, "%ld", static_cast<long>(time(NULL)));
- av[0] = ci->name;
- av[1] = buf;
- av[2] = "+b";
- av[3] = mask;
- ac = 4;
- } else {
- av[0] = ci->name;
- av[1] = "+b";
- av[2] = mask;
- ac = 3;
- }
-
- ircdproto->SendMode(ci->bi, ci->name, "+b %s", mask);
- do_cmode(ci->bi->nick, ac, av);
+ if (ci->c)
+ ci->c->SetMode(NULL, CMODE_BAN, mask);
FOREACH_MOD(I_OnBotBan, OnBotBan(u, ci, mask));
}
}
@@ -874,11 +840,8 @@ static void bot_kick(ChannelInfo * ci, User * u, int message, ...)
void bot_raw_ban(User * requester, ChannelInfo * ci, char *nick,
const char *reason)
{
- int ac;
- const char *av[4];
const char *kav[4]; // seperate as not everything is constified XXX -- w00t
char mask[BUFSIZE];
- char buf[BUFSIZE];
User *u = finduser(nick);
if (!u)
@@ -907,22 +870,7 @@ void bot_raw_ban(User * requester, ChannelInfo * ci, char *nick,
get_idealban(ci, u, mask, sizeof(mask));
- if (ircdcap->tsmode) {
- snprintf(buf, BUFSIZE - 1, "%ld", static_cast<long>(time(NULL)));
- av[0] = ci->name;
- av[1] = buf;
- av[2] = "+b";
- av[3] = mask;
- ac = 4;
- } else {
- av[0] = ci->name;
- av[1] = "+b";
- av[2] = mask;
- ac = 3;
- }
-
- ircdproto->SendMode(ci->bi, ci->name, "+b %s", mask);
- do_cmode(ci->bi->nick, ac, av);
+ ci->c->SetMode(NULL, CMODE_BAN, mask);
kav[0] = ci->name;
kav[1] = nick;
@@ -998,8 +946,6 @@ void bot_raw_kick(User * requester, ChannelInfo * ci, char *nick,
void bot_raw_mode(User * requester, ChannelInfo * ci, const char *mode,
char *nick)
{
- const char *av[4];
- int ac;
char buf[BUFSIZE];
User *u;
@@ -1024,22 +970,7 @@ void bot_raw_mode(User * requester, ChannelInfo * ci, const char *mode,
&& (get_access(u, ci) >= get_access(requester, ci)))
return;
- if (ircdcap->tsmode) {
- av[0] = ci->name;
- av[1] = buf;
- av[2] = mode;
- av[3] = nick;
- ac = 4;
- ircdproto->SendMode(ci->bi, av[0], "%s %s", av[2], av[3]);
- } else {
- av[0] = ci->name;
- av[1] = mode;
- av[2] = nick;
- ac = 3;
- ircdproto->SendMode(ci->bi, av[0], "%s %s", av[1], av[2]);
- }
-
- do_cmode(ci->bi->nick, ac, av);
+ ci->c->SetModes(NULL, "%s %s", mode, nick);
}
/*************************************************************************/
diff --git a/src/channels.c b/src/channels.c
index b9d276a49..2115d2658 100644
--- a/src/channels.c
+++ b/src/channels.c
@@ -133,58 +133,189 @@ bool Channel::HasMode(ChannelModeName Name)
return modes[Name];
}
-/**
- * Set a mode on a channel
- * @param Name The mode name
+/** Set a mode internally on a channel, this is not sent out to the IRCd
+ * @param cm The mode
+ * @param param The param
+ * @param EnforeMLock true if mlocks should be enforced, false to override mlock
*/
-void Channel::SetMode(ChannelModeName Name, const std::string param)
+void Channel::SetModeInternal(ChannelMode *cm, const std::string &param, bool EnforceMLock)
{
- modes[Name] = true;
+ if (!cm)
+ return;
+
+ /* Setting v/h/o/a/q etc */
+ if (cm->Type == MODE_STATUS)
+ {
+ if (param.empty())
+ {
+ alog("Channel::SetModeInternal() mode %c with no parameter for channel %s", cm->ModeChar, this->name);
+ return;
+ }
+
+ /* We don't track bots */
+ if (findbot(param.c_str()))
+ return;
+
+ User *u = finduser(param.c_str());
+ if (!u)
+ {
+ if (debug)
+ alog("debug: MODE %s +%c for nonexistant user %s", this->name, cm->ModeChar, param.c_str());
+ return;
+ }
+
+ if (debug)
+ alog("debug: Setting +%c on %s for %s", cm->ModeChar, this->name, u->nick);
+
+ ChannelModeStatus *cms = static_cast<ChannelModeStatus *>(cm);
+ /* Set the new status on the user */
+ chan_set_user_status(this, u, cms->Status);
+ /* Enforce secureops, etc */
+ chan_set_correct_modes(u, this, 0);
+ return;
+ }
+ /* Setting b/e/I etc */
+ else if (cm->Type == MODE_LIST)
+ {
+ if (param.empty())
+ {
+ alog("Channel::SetModeInternal() mode %c with no parameter for channel %s", cm->ModeChar, this->name);
+ return;
+ }
+
+ ChannelModeList *cml = static_cast<ChannelModeList *>(cm);
+ cml->AddMask(this, param.c_str());
+ return;
+ }
+
+ modes[cm->Name] = true;
/* Channel mode +P or so was set, mark this channel as persistant */
- if (Name == CMODE_PERM && ci)
+ if (cm->Name == CMODE_PERM && ci)
{
ci->SetFlag(CI_PERSIST);
}
if (!param.empty())
{
+ if (cm->Type != MODE_PARAM)
+ {
+ alog("Channel::SetModeInternal() mode %c for %s with a paramater, but its not a param mode", cm->ModeChar, this->name);
+ return;
+ }
+
/* They could be resetting the mode to change its params */
- std::map<ChannelModeName, std::string>::iterator it = Params.find(Name);
+ std::map<ChannelModeName, std::string>::iterator it = Params.find(cm->Name);
if (it != Params.end())
{
Params.erase(it);
}
- Params.insert(std::make_pair(Name, param));
+ Params.insert(std::make_pair(cm->Name, param));
}
- FOREACH_MOD(I_OnChannelModeSet, OnChannelModeSet(this, Name));
-}
+ FOREACH_MOD(I_OnChannelModeSet, OnChannelModeSet(this, cm->Name));
-/**
- * Set a mode on a channel
- * @param Mode The mode
- */
-void Channel::SetMode(char Mode, const std::string param)
-{
- ChannelMode *cm;
+ /* Check for mlock */
+
+ /* Non registered channel, no mlock */
+ if (!ci || !EnforceMLock)
+ return;
- if ((cm = ModeManager::FindChannelModeByChar(Mode)))
+ /* If this channel has this mode locked negative */
+ if (ci->HasMLock(cm->Name, false))
{
- SetMode(cm->Name, param);
+ /* Remove the mode */
+ if (cm->Type == MODE_PARAM)
+ {
+ ChannelModeParam *cmp = static_cast<ChannelModeParam *>(cmp);
+
+ if (!cmp->MinusNoArg)
+ {
+ /* Get the current param set on the channel and send it with the mode */
+ std::string cparam;
+ if (GetParam(cmp->Name, &cparam))
+ RemoveMode(NULL, cm, cparam);
+ }
+ else
+ RemoveMode(NULL, cm);
+ }
+ else if (cm->Type == MODE_REGULAR)
+ RemoveMode(NULL, cm);
+ }
+ /* If this is a param mode and its mlocked +, check to ensure someone didn't reset it with the wrong param */
+ else if (cm->Type == MODE_PARAM && ci->HasMLock(cm->Name, true))
+ {
+ ChannelModeParam *cmp = static_cast<ChannelModeParam *>(cm);
+ std::string cparam, ciparam;
+ /* Get the param currently set on this channel */
+ GetParam(cmp->Name, &cparam);
+ /* Get the param set in mlock */
+ ci->GetParam(cmp->Name, &ciparam);
+
+ /* We have the wrong param set */
+ if (cparam.empty() || ciparam.empty() || cparam != ciparam)
+ {
+ /* Reset the mode with the correct param */
+ SetMode(NULL, cm, ciparam);
+ }
}
}
-/**
- * Remove a mode from a channel
- * @param Name The mode name
+/** Remove a mode internally on a channel, this is not sent out to the IRCd
+ * @param cm The mode
+ * @param param The param
+ * @param EnforceMLock true if mlocks should be enforced, false to override mlock
*/
-void Channel::RemoveMode(ChannelModeName Name)
+void Channel::RemoveModeInternal(ChannelMode *cm, const std::string &param, bool EnforceMLock)
{
- modes[Name] = false;
+ if (!cm)
+ return;
- if (Name == CMODE_PERM && ci)
+ /* Setting v/h/o/a/q etc */
+ if (cm->Type == MODE_STATUS)
+ {
+ if (param.empty())
+ {
+ alog("Channel::RemoveModeInternal() mode %c with no parameter for channel %s", cm->ModeChar, this->name);
+ return;
+ }
+
+ /* We don't track bots */
+ if (findbot(param.c_str()))
+ return;
+
+ User *u = finduser(param.c_str());
+ if (!u)
+ {
+ alog("Channel::RemoveModeInternal() MODE %s +%c for nonexistant user %s", this->name, cm->ModeChar, param.c_str());
+ return;
+ }
+
+ if (debug)
+ alog("debug: Setting +%c on %s for %s", cm->ModeChar, this->name, u->nick);
+
+ ChannelModeStatus *cms = static_cast<ChannelModeStatus *>(cm);
+ chan_remove_user_status(this, u, cms->Status);
+ return;
+ }
+ /* Setting b/e/I etc */
+ else if (cm->Type == MODE_LIST)
+ {
+ if (param.empty())
+ {
+ alog("Channel::SetModeInternal() mode %c with no parameter for channel %s", cm->ModeChar, this->name);
+ return;
+ }
+
+ ChannelModeList *cml = static_cast<ChannelModeList *>(cm);
+ cml->DelMask(this, param.c_str());
+ return;
+ }
+
+ modes[cm->Name] = false;
+
+ if (cm->Name == CMODE_PERM && ci)
{
ci->UnsetFlag(CI_PERSIST);
if (Config.s_BotServ && ci->bi && usercount == Config.BSMinUsers - 1)
@@ -193,27 +324,118 @@ void Channel::RemoveMode(ChannelModeName Name)
delete this;
}
- std::map<ChannelModeName, std::string>::iterator it = Params.find(Name);
- if (it != Params.end())
+ if (cm->Type == MODE_PARAM)
{
- Params.erase(it);
+ std::map<ChannelModeName, std::string>::iterator it = Params.find(cm->Name);
+ if (it != Params.end())
+ {
+ Params.erase(it);
+ }
}
- FOREACH_MOD(I_OnChannelModeUnset, OnChannelModeUnset(this, Name));
+ FOREACH_MOD(I_OnChannelModeUnset, OnChannelModeUnset(this, cm->Name));
+
+ /* Check for mlock */
+
+ /* Non registered channel, no mlock */
+ if (!ci || !EnforceMLock)
+ return;
+
+ /* This channel has this the mode locked on */
+ if (ci->HasMLock(cm->Name, true))
+ {
+ if (cm->Type == MODE_REGULAR)
+ {
+ /* Set the mode */
+ SetMode(NULL, cm);
+ }
+ /* This is a param mode */
+ else if (cm->Type == MODE_PARAM)
+ {
+ std::string cparam;
+ /* Get the param stored in mlock for this mode */
+ if (ci->GetParam(cm->Name, &cparam))
+ SetMode(NULL, cm, cparam);
+ }
+ }
+}
+
+/** Set a mode on a channel
+ * @param bi The client setting the modes
+ * @param cm The mode
+ * @param param Optional param arg for the mode
+ * @param EnforceMLock true if mlocks should be enforced, false to override mlock
+ */
+void Channel::SetMode(BotInfo *bi, ChannelMode *cm, const std::string &param, bool EnforceMLock)
+{
+ if (!cm)
+ return;
+
+ ModeManager::StackerAdd(bi, this, cm, true, param);
+ SetModeInternal(cm, param, EnforceMLock);
}
/**
- * Remove a mode from a channel
+ * Set a mode on a channel
+ * @param bi The client setting the modes
+ * @param Name The mode name
+ * @param param Optional param arg for the mode
+ * @param EnforceMLock true if mlocks should be enforced, false to override mlock
+ */
+void Channel::SetMode(BotInfo *bi, ChannelModeName Name, const std::string &param, bool EnforceMLock)
+{
+ SetMode(bi, ModeManager::FindChannelModeByName(Name), param, EnforceMLock);
+}
+
+/**
+ * Set a mode on a channel
+ * @param bi The client setting the modes
* @param Mode The mode
+ * @param param Optional param arg for the mode
+ * @param EnforceMLock true if mlocks should be enforced, false to override mlock
*/
-void Channel::RemoveMode(char Mode)
+void Channel::SetMode(BotInfo *bi, char Mode, const std::string &param, bool EnforceMLock)
{
- ChannelMode *cm;
+ SetMode(bi, ModeManager::FindChannelModeByChar(Mode), param, EnforceMLock);
+}
- if ((cm = ModeManager::FindChannelModeByChar(Mode)))
- {
- RemoveMode(cm->Name);
- }
+/** Remove a mode from a channel
+ * @param bi The client setting the modes
+ * @param cm The mode
+ * @param param Optional param arg for the mode
+ * @param EnforceMLock true if mlocks should be enforced, false to override mlock
+ */
+void Channel::RemoveMode(BotInfo *bi, ChannelMode *cm, const std::string &param, bool EnforceMLock)
+{
+ if (!cm)
+ return;
+
+ ModeManager::StackerAdd(bi, this, cm, false, param);
+ RemoveModeInternal(cm, param, EnforceMLock);
+}
+
+/**
+ * Remove a mode from a channel
+ * @param bi The client setting the modes
+ * @param Name The mode name
+ * @param param Optional param arg for the mode
+ * @param EnforceMLock true if mlocks should be enforced, false to override mlock
+ */
+void Channel::RemoveMode(BotInfo *bi, ChannelModeName Name, const std::string &param, bool EnforceMLock)
+{
+ RemoveMode(bi, ModeManager::FindChannelModeByName(Name), param, EnforceMLock);
+}
+
+/**
+ * Remove a mode from a channel
+ * @param bi The client setting the modes
+ * @param Mode The mode
+ * @param param Optional param arg for the mode
+ * @param EnforceMLock true if mlocks should be enforced, false to override mlock
+ */
+void Channel::RemoveMode(BotInfo *bi, char Mode, const std::string &param, bool EnforceMLock)
+{
+ RemoveMode(bi, ModeManager::FindChannelModeByChar(Mode), param, EnforceMLock);
}
/** Get a param from the channel
@@ -254,15 +476,12 @@ const bool Channel::HasParam(ChannelModeName Name)
/*************************************************************************/
/** Clear all the modes from the channel
- * @param client The client unsetting the modes
+ * @param bi The client setting the modes
*/
-void Channel::ClearModes(char *client)
+void Channel::ClearModes(BotInfo *bi)
{
ChannelMode *cm;
ChannelModeParam *cmp;
- std::string buf, buf2;
- const char *argv[2];
- BotInfo *sender = (client ? findbot(client) : whosends(ci));
for (size_t n = CMODE_BEGIN + 1; n != CMODE_END; ++n)
{
@@ -272,41 +491,21 @@ void Channel::ClearModes(char *client)
{
if (cm->Type == MODE_REGULAR)
{
- buf = '-';
- buf += cm->ModeChar;
-
- argv[0] = buf.c_str();
-
- ircdproto->SendMode(sender, this->name, "-%c", cm->ModeChar);
- chan_set_modes(sender->nick, this, 1, argv, 0);
+ this->RemoveMode(NULL, cm);
}
else if (cm->Type == MODE_PARAM)
{
cmp = static_cast<ChannelModeParam *>(cm);
- buf = '-';
- buf += cmp->ModeChar;
- buf2.clear();
-
if (!cmp->MinusNoArg)
{
- buf2 = this->GetParam(cmp->Name, &buf2);
- }
-
- argv[0] = buf.c_str();
- if (!buf2.empty())
- {
- argv[1] = buf2.c_str();
-
- ircdproto->SendMode(sender, this->name, "-%c %s", cm->ModeChar, buf2.c_str());
- chan_set_modes(sender->nick, this, 2, argv, 0);
+ std::string buf;
+ if (this->GetParam(cmp->Name, &buf))
+ this->RemoveMode(NULL, cm, buf);
}
else
{
- argv[1] = NULL;
-
- ircdproto->SendMode(sender, this->name, "-%c", cm->ModeChar);
- chan_set_modes(sender->nick, this, 1, argv, 0);
+ this->RemoveMode(NULL, cm);
}
}
}
@@ -316,100 +515,195 @@ void Channel::ClearModes(char *client)
}
/** Clear all the bans from the channel
- * @param client The client unsetting the modes
+ * @param bi The client setting the modes
*/
-void Channel::ClearBans(char *client)
+void Channel::ClearBans(BotInfo *bi)
{
Entry *entry, *nexte;
- BotInfo *sender = (client ? findbot(client) : whosends(ci));
ChannelModeList *cml;
- std::string buf;
- const char *argv[2];
cml = static_cast<ChannelModeList *>(ModeManager::FindChannelModeByName(CMODE_BAN));
if (cml && this->bans && this->bans->count)
{
- buf = '-';
- buf += cml->ModeChar;
-
for (entry = this->bans->entries; entry; entry = nexte)
{
nexte = entry->next;
- argv[0] = buf.c_str();
- argv[1] = sstrdup(entry->mask);
- ircdproto->SendMode(sender, this->name, "%s %s", buf.c_str(), entry->mask);
- chan_set_modes(sender->nick, this, 2, argv, 0);
- delete [] argv[1];
+ this->RemoveMode(bi, CMODE_BAN, entry->mask);
}
}
}
/** Clear all the excepts from the channel
- * @param client The client unsetting the modes
+ * @param bi The client setting the modes
*/
-void Channel::ClearExcepts(char *client)
+void Channel::ClearExcepts(BotInfo *bi)
{
Entry *entry, *nexte;
- BotInfo *sender = (client ? findbot(client) : whosends(ci));
ChannelModeList *cml;
- std::string buf;
- const char *argv[2];
cml = static_cast<ChannelModeList *>(ModeManager::FindChannelModeByName(CMODE_EXCEPT));
if (cml && this->excepts && this->excepts->count)
{
- buf = '+';
- buf += cml->ModeChar;
-
for (entry = this->excepts->entries; entry; entry = nexte)
{
nexte = entry->next;
- argv[0] = buf.c_str();
- argv[1] = sstrdup(entry->mask);
- ircdproto->SendMode(sender, this->name, "%s %s", buf.c_str(), entry->mask);
- chan_set_modes(sender->nick, this, 2, argv, 0);
- delete [] argv[1];
+ this->RemoveMode(bi, CMODE_EXCEPT, entry->mask);
}
}
}
/** Clear all the invites from the channel
- * @param client The client unsetting the modes
+ * @param bi The client setting the modes
*/
-void Channel::ClearInvites(char *client)
+void Channel::ClearInvites(BotInfo *bi)
{
Entry *entry, *nexte;
- BotInfo *sender = (client ? findbot(client) : whosends(ci));
ChannelModeList *cml;
- std::string buf;
- const char *argv[2];
cml = static_cast<ChannelModeList *>(ModeManager::FindChannelModeByName(CMODE_INVITEOVERRIDE));
if (cml && this->invites && this->invites->count)
{
- buf = '-';
- buf += cml->ModeChar;
-
for (entry = this->invites->entries; entry; entry = nexte)
{
nexte = entry->next;
- argv[0] = buf.c_str();
- argv[1] = sstrdup(entry->mask);
- ircdproto->SendMode(sender, this->name, "%s %s", buf.c_str(), entry->mask);
- chan_set_modes(sender->nick, this, 2, argv, 0);
- delete [] argv[1];
+ this->RemoveMode(bi, CMODE_INVITEOVERRIDE, entry->mask);
+ }
+ }
+}
+
+/** Set a string of modes on the channel
+ * @param bi The client setting the modes
+ * @param EnforceMLock Should mlock be enforced on this mode change
+ * @param cmodes The modes to set
+ */
+void Channel::SetModes(BotInfo *bi, bool EnforceMLock, const std::string &cmodes, ...)
+{
+ char buf[BUFSIZE] = "";
+ va_list args;
+ std::string modebuf, sbuf;
+ int add = -1;
+ va_start(args, cmodes.c_str());
+ vsnprintf(buf, BUFSIZE - 1, cmodes.c_str(), args);
+ va_end(args);
+
+ spacesepstream sep(buf);
+ sep.GetToken(modebuf);
+ for (unsigned i = 0; i < modebuf.size(); ++i)
+ {
+ ChannelMode *cm;
+
+ switch (modebuf[i])
+ {
+ case '+':
+ add = 1;
+ continue;
+ case '-':
+ add = 0;
+ continue;
+ default:
+ if (add == -1)
+ continue;
+ cm = ModeManager::FindChannelModeByChar(modebuf[i]);
+ if (!cm)
+ continue;
+ }
+
+ if (add)
+ {
+ if (cm->Type == MODE_PARAM && sep.GetToken(sbuf))
+ this->SetMode(bi, cm, sbuf, EnforceMLock);
+ else
+ this->SetMode(bi, cm, "", EnforceMLock);
+ }
+ else if (add == 0)
+ {
+ if (cm->Type == MODE_PARAM && sep.GetToken(sbuf))
+ this->RemoveMode(bi, cm, sbuf, EnforceMLock);
+ else
+ this->RemoveMode(bi, cm, "", EnforceMLock);
}
}
}
/*************************************************************************/
+/** Set modes internally on the channel
+ * @param c The channel
+ * @param ac Number of args
+ * @param av args
+ */
+void ChanSetInternalModes(Channel *c, int ac, const char **av)
+{
+ if (!ac)
+ return;
+
+ int k = 0, j = 0, add = -1;
+ for (unsigned int i = 0; i < strlen(av[0]); ++i)
+ {
+ ChannelMode *cm;
+
+ switch (av[0][i])
+ {
+ case '+':
+ add = 1;
+ continue;
+ case '-':
+ add = 0;
+ continue;
+ default:
+ if (add == -1)
+ continue;
+ cm = ModeManager::FindChannelModeByChar(av[0][i]);
+ if (!cm)
+ continue;
+ }
+
+ if (cm->Type == MODE_REGULAR)
+ {
+ if (add)
+ c->SetModeInternal(cm);
+ else
+ c->RemoveModeInternal(cm);
+ continue;
+ }
+ else if (cm->Type == MODE_PARAM)
+ {
+ ChannelModeParam *cmp = static_cast<ChannelModeParam *>(cm);
+
+ if (!add && cmp->MinusNoArg)
+ {
+ c->RemoveModeInternal(cm);
+ ++k;
+ continue;
+ }
+ }
+ if (++j < ac)
+ {
+ if (add)
+ c->SetModeInternal(cm, av[j]);
+ else
+ c->RemoveModeInternal(cm, av[j]);
+ }
+ else
+ {
+ alog("warning: ChanSetInternalModes() recieved more modes requiring params than params, modes: %s, ac: %d, j: %d", merge_args(ac, av), ac, j);
+ }
+ }
+
+ if (j + k + 1 < ac)
+ {
+ alog("warning: ChanSetInternalModes() recieved more params than modes requiring them, modes: %s, ac: %d, j: %d k: %d", merge_args(ac, av), ac, j, k);
+ }
+}
+
+/*************************************************************************/
+
void chan_deluser(User * user, Channel * c)
{
struct c_userlist *u;
@@ -563,204 +857,12 @@ void chan_remove_user_status(Channel * chan, User * user, int16 status)
/*************************************************************************/
-void chan_set_modes(const char *source, Channel *chan, int ac, const char **av, int check)
-{
- int add = 1, i, real_ac = ac;
- ChannelMode *cm;
- ChannelModeStatus *cms;
- ChannelModeList *cml;
- ChannelModeParam *cmp;
- const char *modes, **real_av = av;
- char mode;
- BotInfo *bi;
- unsigned char botmode = 0;
- User *user;
-
- modes = av[0];
-
- if (debug)
- alog("debug: Changing modes for %s to %s", chan->name, merge_args(ac, av));
-
- ac--;
-
- while ((mode = *modes++))
- {
- switch (mode)
- {
- case '+':
- add = 1;
- continue;
- case '-':
- add = 0;
- continue;
- }
-
- if ((cm = ModeManager::FindChannelModeByChar