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/channels.c | |
| 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/channels.c')
| -rw-r--r-- | src/channels.c | 882 |
1 files changed, 465 insertions, 417 deletions
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(mode))) - { - /* v/h/o/a/q etc */ - if (cm->Type == MODE_STATUS) - { - cms = static_cast<ChannelModeStatus *>(cm); - - if (ac == 0) - { - alog("channel: mode %c%c with no parameter (?) for channel %s", add ? '+' : '-', mode, chan->name); - continue; - } - - ac--; - av++; - - if (cms->ProtectBotServ && !add) - { - if ((bi = findbot(*av))) - { - if (!botmode || botmode != mode) - { - ircdproto->SendMode(bi, chan->name, "+%c %s", mode, bi->nick); - botmode = mode; - continue; - } - else - { - botmode = mode; - continue; - } - } - } - else if ((bi = findbot(*av))) - continue; - - if (!(user = finduser(*av)) && !(ircd->ts6 && (user = find_byuid(*av)))) - { - if (debug) - { - alog("debug: MODE %s %c%c for nonexistent user %s", - chan->name, (add ? '+' : '-'), mode, *av); - } - continue; - } - - if (debug) - alog("debug: Setting %c%c on %s for %s", (add ? '+' : '-'), - mode, chan->name, user->nick); - - if (add) - chan_set_user_status(chan, user, cms->Status); - /* If this does +o, remove any DEOPPED flag */ - else - chan_remove_user_status(chan, user, cms->Status); - } - /* b/e/I etc */ - else if (cm->Type == MODE_LIST) - { - cml = static_cast<ChannelModeList *>(cm); - - if (ac == 0) - { - alog("channel: mode %c%c with no parameter (?) for channel %s", add ? '+' : '-', mode, chan->name); - continue; - } - - ac--; - av++; - - if (add) - cml->AddMask(chan, *av); - else - cml->DelMask(chan, *av); - } - else - { - if (cm->Type == MODE_PARAM) - { - cmp = static_cast<ChannelModeParam *>(cm); - - if (add || !cmp->MinusNoArg) - { - if (ac == 0) - { - alog("channel: mode %c%c with no parameter (?) for channel %s", add ? '+' : '-', mode, chan->name); - continue; - } - - ac--; - av++; - } - - if (!cmp->IsValid(*av)) - continue; - if (add) - { - std::string Param = *av; - chan->SetMode(mode, Param); - } - else - { - chan->RemoveMode(mode); - } - } - else - { - if (add) - chan->SetMode(mode); - else - chan->RemoveMode(mode); - } - } - } - } - - // Don't bounce modes from u:lined clients or servers, bug #1004 - user = finduser(source); - if ((user && is_ulined(user->server->name)) || is_ulined(source)) - return; - - if (check > 0) - { - check_modes(chan); - - if ((check < 2) || (check == 3)) - { - /* Walk through all users we've set modes for and see if they are - * valid. Invalid modes (like +o with SECUREOPS on) will be removed - */ - real_ac--; - real_av++; - - for (i = 0; i < real_ac; i++) - { - if ((user = finduser(*real_av)) && is_on_chan(chan, user)) - { - if (check < 2) - chan_set_correct_modes(user, chan, 0); - else if (chan->ci->HasFlag(CI_SECUREOPS)) - { - /* Fixing bug #1006 oringinally caused by fixing #922 - * we must check for secureops here, not in chan_set_correct_modes - * because chan_set_corret_modes will also check for usercount == 1 - * where it will deop the user, this way we know the channel was not - * just created. (check == 3 from /cs (half)op) - Adam - */ - chan_set_correct_modes(user, chan, 0); - } - } - - real_av++; - } - } - } -} - -/*************************************************************************/ - /* Set the status of an user on a channel */ void chan_set_user_status(Channel * chan, User * user, int16 status) { struct u_chanlist *uc; UserMode *um; - char av[3]; if (debug >= 2) alog("debug: setting user status (%d) on %s for %s", status, @@ -774,9 +876,7 @@ void chan_set_user_status(Channel * chan, User * user, int16 status) user->nick, status, chan->name); } - snprintf(av, sizeof(av), "+%c", um->ModeChar); - - common_svsmode(user, av, NULL); + user->SetMode(um); } for (uc = user->chans; uc; uc = uc->next) { @@ -1210,11 +1310,8 @@ void do_sjoin(const char *source, int ac, const char **av) else if (c->creation_time > ts) { c->creation_time = ts; for (cu = c->users; cu; cu = cu->next) { - /* XXX */ - modes[0] = "-ov"; - modes[1] = cu->user->nick; - modes[2] = cu->user->nick; - chan_set_modes(source, c, 3, modes, 2); + c->RemoveMode(NULL, CMODE_OP, cu->user->nick); + c->RemoveMode(NULL, CMODE_VOICE, cu->user->nick); } if (c->ci) { @@ -1227,8 +1324,7 @@ void do_sjoin(const char *source, int ac, const char **av) /* Make sure +r is set */ if (ModeManager::FindChannelModeByName(CMODE_REGISTERED)) { - c->SetMode(CMODE_REGISTERED); - ircdproto->SendMode(whosends(c->ci), c->name, "+r"); + c->SetMode(NULL, CMODE_REGISTERED); } } /* XXX simple modes and bans */ @@ -1348,8 +1444,8 @@ void do_sjoin(const char *source, int ac, const char **av) for (i = 1; i < end2 - cubuf; i++) modes[i] = user->nick; - chan_set_modes(source, c, 1 + (end2 - cubuf - 1), - modes, 2); + + ChanSetInternalModes(c, 1 + (end2 - cubuf - 1), modes); } if (c->ci && (!serv || is_sync(serv)) @@ -1368,7 +1464,7 @@ void do_sjoin(const char *source, int ac, const char **av) if (c && keep_their_modes) { /* We now update the channel mode. */ - chan_set_modes(source, c, ac - 3, &av[2], 2); + ChanSetInternalModes(c, ac - 3, &av[2]); } /* Unreal just had to be different */ @@ -1434,8 +1530,7 @@ void do_sjoin(const char *source, int ac, const char **av) for (i = 1; i < end2 - cubuf; i++) modes[i] = user->nick; - chan_set_modes(source, c, 1 + (end2 - cubuf - 1), - modes, 2); + ChanSetInternalModes(c, 1 + (end2 - cubuf - 1), modes); } chan_set_correct_modes(user, c, 1); @@ -1510,8 +1605,7 @@ void do_sjoin(const char *source, int ac, const char **av) for (i = 1; i < end2 - cubuf; i++) modes[i] = user->nick; - chan_set_modes(source, c, 1 + (end2 - cubuf - 1), - modes, 2); + ChanSetInternalModes(c, 1 + (end2 - cubuf - 1), modes); } chan_set_correct_modes(user, c, 1); @@ -1564,79 +1658,76 @@ void do_sjoin(const char *source, int ac, const char **av) } } - /*************************************************************************/ -/* Handle a channel MODE command. */ - -/* - * av[0]: channel - * av[1]: (tsmode) channel TS (this should be moved to a protocol module) - * av[2-]: (tsmode) modes and parameters - * - * av[1-]: modes and parameters. - * +/** Process a MODE command from the server, and set the modes on the user/channel + * it was sent for + * @param source The source of the command + * @param ac Number of args in array.. + * @param av Array of args */ void do_cmode(const char *source, int ac, const char **av) { - Channel *chan; - ChannelInfo *ci = NULL; + Channel *c; + ChannelInfo *ci; unsigned int i; const char *t; - if (ircdcap->tsmode) { - /* TSMODE for bahamut - leave this code out to break MODEs. -GD */ - /* if they don't send it in CAPAB check if we just want to enable it */ - if (uplink_capab & ircdcap->tsmode || UseTSMODE) { - for (i = 0; i < strlen(av[1]); i++) { + if (ircdcap->tsmode) + { + if (uplink_capab & ircdcap->tsmode || UseTSMODE) + { + for (i = 0; i < strlen(av[1]); i++) if (!isdigit(av[1][i])) break; - } - if (av[1][i] == '\0') { - /* We have a valid TS field in av[1] now, so we can strip it off */ - /* After we swap av[0] and av[1] ofcourse to not break stuff! :) */ + if (av[1][i] == '\0') + { t = av[0]; av[0] = av[1]; av[1] = t; ac--; av++; - } else { - alog("TSMODE enabled but MODE has no valid TS"); } + else + alog("TSMODE enabled but MODE has no valid TS"); } } /* :42XAAAAAO TMODE 1106409026 #ircops +b *!*@*.aol.com */ - if (ircd->ts6) { - if (isdigit(av[0][0])) { + if (ircd->ts6) + { + if (isdigit(av[0][0])) + { ac--; av++; } } - chan = findchan(av[0]); - if (!chan) { - if (debug) { + c = findchan(av[0]); + if (!c) + { + if (debug) + { ci = cs_findchan(av[0]); - if (!(ci && (ci->HasFlag(CI_FORBIDDEN)))) - alog("debug: MODE %s for nonexistent channel %s", - merge_args(ac - 1, av + 1), av[0]); + if (!ci || ci->HasFlag(CI_FORBIDDEN)) + alog("debug: MODE %s for nonexistant channel %s", merge_args(ac - 1, av + 1), av[0]); } return; } - /* This shouldn't trigger on +o, etc. */ - if (strchr(source, '.') && !av[1][strcspn(av[1], "bovahq")]) { - if (time(NULL) != chan->server_modetime) { - chan->server_modecount = 0; - chan->server_modetime = time(NULL); + if (strchr(source, '.') && !av[1][strcspn(av[1], "bovahq")]) + { + if (time(NULL) != c->server_modetime) + { + c->server_modecount = 0; + c->server_modetime = time(NULL); } - chan->server_modecount++; + c->server_modecount++; } ac--; av++; - chan_set_modes(source, chan, ac, av, 1); + ChanSetInternalModes(c, ac, av); } /*************************************************************************/ @@ -1728,7 +1819,6 @@ void do_topic(const char *source, int ac, const char **av) **/ void chan_set_correct_modes(User * user, Channel * c, int give_modes) { - std::string modebuf, userbuf; int status; int add_modes = 0; int rem_modes = 0; @@ -1801,74 +1891,51 @@ void chan_set_correct_modes(User * user, Channel * c, int give_modes) if (add_modes > 0) { - modebuf += "+"; - if (owner && (add_modes & CUS_OWNER) && !(status & CUS_OWNER)) - { - modebuf += owner->ModeChar; - userbuf += " " + std::string(user->nick); - } + c->SetMode(NULL, CMODE_OWNER, user->nick); else add_modes &= ~CUS_OWNER; if (admin && (add_modes & CUS_PROTECT) && !(status & CUS_PROTECT)) - { - modebuf += admin->ModeChar; - userbuf += " " + std::string(user->nick); - } + c->SetMode(NULL, CMODE_PROTECT, user->nick); else add_modes &= ~CUS_PROTECT; if (op && (add_modes & CUS_OP) && !(status & CUS_OP)) - { - modebuf += op->ModeChar; - userbuf += " " + std::string(user->nick); - } + c->SetMode(NULL, CMODE_OP, user->nick); else add_modes &= ~CUS_OP; if (halfop && (add_modes & CUS_HALFOP) && !(status & CUS_HALFOP)) - { - modebuf += halfop->ModeChar; - userbuf += " " + std::string(user->nick); - } + c->SetMode(NULL, CMODE_HALFOP, user->nick); else add_modes &= ~CUS_HALFOP; if (voice && (add_modes & CUS_VOICE) && !(status & CUS_VOICE)) - { - modebuf += voice->ModeChar; - userbuf += " " + std::string(user->nick); - } + c->SetMode(NULL, CMODE_VOICE, user->nick); else add_modes &= ~CUS_VOICE; } if (rem_modes > 0) { - modebuf += "-"; - if (owner && rem_modes & CUS_OWNER) { - modebuf += owner->ModeChar; - userbuf += " " + std::string(user->nick); + c->RemoveMode(NULL, CMODE_OWNER, user->nick); } if (admin && rem_modes & CUS_PROTECT) { - modebuf += admin->ModeChar; - userbuf += " " + std::string(user->nick); + c->RemoveMode(NULL, CMODE_PROTECT, user->nick); } if (op && rem_modes & CUS_OP) { - modebuf += op->ModeChar; - userbuf += " " + std::string(user->nick); + c->RemoveMode(NULL, CMODE_OP, user->nick); } if (halfop && rem_modes & CUS_HALFOP) { - modebuf += halfop->ModeChar; - userbuf += " " + std::string(user->nick); + c->RemoveMode(NULL, CMODE_HALFOP, user->nick); } } @@ -1878,7 +1945,6 @@ void chan_set_correct_modes(User * user, Channel * c, int give_modes) if (!add_modes && !rem_modes) return; - ircdproto->SendMode(whosends(ci), c->name, "%s%s", modebuf.c_str(), userbuf.c_str()); if (add_modes > 0) chan_set_user_status(c, user, add_modes); if (rem_modes > 0) @@ -1969,16 +2035,12 @@ Channel *join_user_update(User * user, Channel * chan, const char *name, if (chan->creation_time > chants && chants != 0) { struct c_userlist *cu; - const char *modes[6]; chan->creation_time = chants; for (cu = chan->users; cu; cu = cu->next) { - /* XXX */ - modes[0] = "-ov"; - modes[1] = cu->user->nick; - modes[2] = cu->user->nick; - chan_set_modes(Config.s_OperServ, chan, 3, modes, 2); + chan->RemoveMode(NULL, CMODE_OP, cu->user->nick); + chan->RemoveMode(NULL, CMODE_VOICE, cu->user->nick); } if (chan->ci) { @@ -1991,8 +2053,7 @@ Channel *join_user_update(User * user, Channel * chan, const char *name, /* Make sure +r is set */ if (ModeManager::FindChannelModeByName(CMODE_REGISTERED)) { - chan->SetMode(CMODE_REGISTERED); - ircdproto->SendMode(whosends(chan->ci), chan->name, "+r"); + chan->SetMode(NULL, CMODE_REGISTERED); } } /* XXX simple modes and bans */ @@ - |
