diff options
| author | Adam- <Adam-@5417fbe8-f217-4b02-8779-1006273d7864> | 2009-12-13 19:32:19 +0000 |
|---|---|---|
| committer | Adam- <Adam-@5417fbe8-f217-4b02-8779-1006273d7864> | 2009-12-13 19:32:19 +0000 |
| commit | a7ac6a0ac712892652da6dd8696b94d4c6d3ea84 (patch) | |
| tree | 9bbcf49157cfda0577c34515cb44d4462818c1da /src | |
| parent | 3a956c51be22f1b6f3b6808c9f56fb6b26c7dd1a (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.c | 61 | ||||
| -rw-r--r-- | src/botserv.c | 99 | ||||
| -rw-r--r-- | src/channels.c | 882 | ||||
| -rw-r--r-- | src/chanserv.c | 240 | ||||
| -rw-r--r-- | src/core/cs_ban.c | 6 | ||||
| -rw-r--r-- | src/core/cs_clear.c | 151 | ||||
| -rw-r--r-- | src/core/cs_drop.c | 3 | ||||
| -rw-r--r-- | src/core/cs_modes.c | 14 | ||||
| -rw-r--r-- | src/core/cs_register.c | 6 | ||||
| -rw-r--r-- | src/core/cs_set.c | 6 | ||||
| -rw-r--r-- | src/core/ns_logout.c | 4 | ||||
| -rw-r--r-- | src/core/os_clearmodes.c | 100 | ||||
| -rw-r--r-- | src/core/os_defcon.c | 30 | ||||
| -rw-r--r-- | src/core/os_mode.c | 8 | ||||
| -rw-r--r-- | src/core/os_oline.c | 2 | ||||
| -rw-r--r-- | src/core/os_umode.c | 4 | ||||
| -rw-r--r-- | src/main.c | 3 | ||||
| -rw-r--r-- | src/modes.cpp | 610 | ||||
| -rw-r--r-- | src/modules/cs_enforce.c | 10 | ||||
| -rw-r--r-- | src/modules/cs_tban.c | 19 | ||||
| -rw-r--r-- | src/nickalias.cpp | 6 | ||||
| -rw-r--r-- | src/nickcore.cpp | 1 | ||||
| -rw-r--r-- | src/protocol.cpp | 10 | ||||
| -rw-r--r-- | src/protocol/bahamut.c | 66 | ||||
| -rw-r--r-- | src/protocol/inspircd11.c | 74 | ||||
| -rw-r--r-- | src/protocol/inspircd12.cpp | 85 | ||||
| -rw-r--r-- | src/protocol/ratbox.c | 46 | ||||
| -rw-r--r-- | src/protocol/unreal32.c | 118 | ||||
| -rw-r--r-- | src/regchannel.cpp | 2 | ||||
| -rw-r--r-- | src/users.c | 217 |
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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 |
