diff options
Diffstat (limited to 'src')
32 files changed, 1869 insertions, 3127 deletions
diff --git a/src/Makefile b/src/Makefile index a54d194c4..2f8845b4d 100644 --- a/src/Makefile +++ b/src/Makefile @@ -2,7 +2,7 @@ OBJS = actions.o base64.o bots.o botserv.o channels.o chanserv.o command.o comm config.o datafiles.o encrypt.o hashcomp.o hostserv.o init.o ircd.o language.o log.o mail.o main.o \ memory.o memoserv.o messages.o misc.o modules.o news.o nickserv.o operserv.o \ process.o protocol.o send.o servers.o sessions.o slist.o sockutil.o opertype.o users.o module.o modulemanager.o configreader.o \ - wildcard.o nickcore.o nickalias.o timers.o + wildcard.o nickcore.o nickalias.o timers.o modes.o INCLUDES = ../include/commands.h ../include/defs.h ../include/language.h \ ../include/pseudo.h ../include/sysconf.h ../include/config.h \ @@ -33,6 +33,7 @@ services: $(OBJS) $(MAKEBIN) $(CC) $(CFLAGS) $(OBJS) $(ANOPELIBS) $(MLIBS) -o $@ $(LDFLAGS) $(OBJS): Makefile +modes.o: modes.cpp $(INCLUDES) timers.o: timers.cpp $(INCLUDES) nickcore.o: nickcore.cpp $(INCLUDES) nickalias.o: nickalias.cpp $(INCLUDES) diff --git a/src/botserv.c b/src/botserv.c index 3fc4c5c11..0e4f37600 100644 --- a/src/botserv.c +++ b/src/botserv.c @@ -772,12 +772,19 @@ void bot_join(ChannelInfo * ci) } } + std::string Limit; + int limit = 0; + if (ci->c->GetParam(CMODE_LIMIT, &Limit)) + { + limit = atoi(Limit.c_str()); + } + /* Should we be invited? */ - if ((ci->c->mode & anope_get_invite_mode()) - || (ci->c->limit && ci->c->usercount >= ci->c->limit)) + if (ci->c->HasMode(CMODE_INVITE) + || (limit && ci->c->usercount >= limit)) ircdproto->SendNoticeChanops(NULL, ci->c->name, - "%s invited %s into the channel.", - ci->bi->nick, ci->bi->nick); + "%s invited %s into the channel.", + 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); @@ -877,7 +884,8 @@ void bot_raw_ban(User * requester, ChannelInfo * ci, char *nick, if (!u) return; - if (ircd->protectedumode) { + if ((ModeManager::FindUserModeByName(UMODE_PROTECTED))) + { if (is_protected(u) && (requester != u)) { ircdproto->SendPrivmsg(ci->bi, ci->name, "%s", getstring(ACCESS_DENIED)); @@ -889,7 +897,8 @@ void bot_raw_ban(User * requester, ChannelInfo * ci, char *nick, && (get_access(u, ci) >= get_access(requester, ci))) return; - if (ircd->except) { + if (ModeManager::FindChannelModeByName(CMODE_EXCEPT)) + { if (is_excepted(ci, u) == 1) { ircdproto->SendPrivmsg(ci->bi, ci->name, "%s", getstring(BOT_EXCEPT)); @@ -953,7 +962,8 @@ void bot_raw_kick(User * requester, ChannelInfo * ci, char *nick, if (!u || !is_on_chan(ci->c, u)) return; - if (ircd->protectedumode) { + if ((ModeManager::FindUserModeByName(UMODE_PROTECTED))) + { if (is_protected(u) && (requester != u)) { ircdproto->SendPrivmsg(ci->bi, ci->name, "%s", getstring(ACCESS_DENIED)); @@ -1007,7 +1017,7 @@ void bot_raw_mode(User * requester, ChannelInfo * ci, const char *mode, snprintf(buf, BUFSIZE - 1, "%ld", static_cast<long>(time(NULL))); - if (ircd->protectedumode) { + if ((ModeManager::FindUserModeByName(UMODE_PROTECTED))) { if (is_protected(u) && *mode == '-' && (requester != u)) { ircdproto->SendPrivmsg(ci->bi, ci->name, "%s", getstring(ACCESS_DENIED)); diff --git a/src/channels.c b/src/channels.c index f41219109..5984065e0 100644 --- a/src/channels.c +++ b/src/channels.c @@ -20,7 +20,279 @@ Channel *chanlist[1024]; #define HASH(chan) ((chan)[1] ? ((chan)[1]&31)<<5 | ((chan)[2]&31) : 0) -/**************************** External Calls *****************************/ +/*************************************************************************/ + +/** + * See if a channel has a mode + * @param Name The mode name + * @return true or false + */ +bool Channel::HasMode(ChannelModeName Name) +{ + return modes[(size_t)Name]; +} + +/** + * Set a mode on a channel + * @param Name The mode name + */ +void Channel::SetMode(ChannelModeName Name) +{ + modes[(size_t)Name] = true; +} + +/** + * Set a mode on a channel + * @param Mode The mode + */ +void Channel::SetMode(char Mode) +{ + ChannelMode *cm; + + if ((cm = ModeManager::FindChannelModeByChar(Mode))) + { + SetMode(cm->Name); + } +} + +/** + * Remove a mode from a channel + * @param Name The mode name + */ +void Channel::RemoveMode(ChannelModeName Name) +{ + modes[(size_t)Name] = false; +} + +/** + * Remove a mode from a channel + * @param Mode The mode + */ +void Channel::RemoveMode(char Mode) +{ + ChannelMode *cm; + + if ((cm = ModeManager::FindChannelModeByChar(Mode))) + { + RemoveMode(cm->Name); + } +} + +/** Set a channel mode param on the channel + * @param Name The mode + * @param param The param + * @param true on success + */ +bool Channel::SetParam(ChannelModeName Name, std::string &Value) +{ + return Params.insert(std::make_pair(Name, Value)).second; +} + +/** Unset a param from the channel + * @param Name The mode + */ +void Channel::UnsetParam(ChannelModeName Name) +{ + std::map<ChannelModeName, std::string>::iterator it = Params.find(Name); + + if (it != Params.end()) + { + Params.erase(it); + } +} + +/** Get a param from the channel + * @param Name The mode + * @param Target a string to put the param into + * @return true on success + */ +const bool Channel::GetParam(ChannelModeName Name, std::string *Target) +{ + std::map<ChannelModeName, std::string>::iterator it = Params.find(Name); + + (*Target).clear(); + + if (it != Params.end()) + { + *Target = it->second; + return true; + } + + return false; +} + +/** Check if a mode is set and has a param + * @param Name The mode + */ +const bool Channel::HasParam(ChannelModeName Name) +{ + std::map<ChannelModeName, std::string>::iterator it = Params.find(Name); + + if (it != Params.end()) + { + return true; + } + + return false; +} + +/*************************************************************************/ + +/** Clear all the modes from the channel + * @param client The client unsetting the modes + */ +void Channel::ClearModes(char *client) +{ + 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) + { + cm = ModeManager::FindChannelModeByName((ChannelModeName)n); + + if (cm && this->HasMode(cm->Name)) + { + 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); + } + 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); + } + else + { + argv[1] = NULL; + + ircdproto->SendMode(sender, this->name, "-%c", cm->ModeChar); + chan_set_modes(sender->nick, this, 1, argv, 0); + } + } + } + } + + modes.reset(); +} + +/** Clear all the bans from the channel + * @param client The client unsetting the modes + */ +void Channel::ClearBans(char *client) +{ + 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]; + } + } +} + +/** Clear all the excepts from the channel + * @param client The client unsetting the modes + */ +void Channel::ClearExcepts(char *client) +{ + 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]; + } + } +} + +/** Clear all the invites from the channel + * @param client The client unsetting the modes + */ +void Channel::ClearInvites(char *client) +{ + 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]; + } + } +} + /*************************************************************************/ void chan_deluser(User * user, Channel * c) @@ -66,33 +338,50 @@ void chan_deluser(User * user, Channel * c) char *chan_get_modes(Channel * chan, int complete, int plus) { static char res[BUFSIZE]; - char *end = res; - - if (chan->mode) { - unsigned int n = 0; - CBModeInfo *cbmi = cbmodeinfos; - - do { - if (chan->mode & cbmi->flag) - *end++ = cbmi->mode; - } while ((++cbmi)->flag != 0 && ++n < sizeof(res) - 1); - - if (complete) { - cbmi = cbmodeinfos; + char params[BUFSIZE]; + char *end = res, *value, *pend = params, *pend2 = params; + std::string param; + ChannelMode *cm; + ChannelModeParam *cmp; + std::map<char, ChannelMode *>::iterator it; + + if (!chan->modes.count()) + { + for (it = ModeManager::ChannelModesByChar.begin(); it != ModeManager::ChannelModesByChar.end(); ++it) + { + cm = it->second; - do { - if (cbmi->getvalue && (chan->mode & cbmi->flag) && - (plus || !(cbmi->flags & CBM_MINUS_NO_ARG))) { - char *value = cbmi->getvalue(chan); + if (chan->HasMode(cm->Name)) + { + *end++ = it->first; - if (value) { - *end++ = ' '; - while (*value) - *end++ = *value++; + if (complete) + { + if (cm->Type == MODE_PARAM) + { + cmp = static_cast<ChannelModeParam *>(cm); + + if (plus || !cmp->MinusNoArg) + { + chan->GetParam(cmp->Name, ¶m); + + if (!param.empty()) + { + value = const_cast<char *>(param.c_str()); + + *pend++ = ' '; + + while (*value) + *pend++ = *value++; + } + } } } - } while ((++cbmi)->flag != 0 && ++n < sizeof(res) - 1); + } } + + while (*pend2) + *end++ = *pend2++; } *end = 0; @@ -156,128 +445,158 @@ 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) +void chan_set_modes(const char *source, Channel *chan, int ac, const char **av, int check) { - int add = 1; - const char *modes = av[0]; + int add = 1, i, real_ac = ac; + ChannelMode *cm; + ChannelModeStatus *cms; + ChannelModeList *cml; + ChannelModeParam *cmp; + const char *modes, **real_av = av; char mode; - CBMode *cbm; - CMMode *cmm; - CUMode *cum; - unsigned char botmode = 0; BotInfo *bi; + unsigned char botmode = 0; User *user; - int i, real_ac = ac; - const char **real_av = av; + + modes = av[0]; if (debug) - alog("debug: Changing modes for %s to %s", chan->name, - merge_args(ac, av)); + 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; + while ((mode = *modes++)) + { + switch (mode) + { + case '+': + add = 1; + continue; + case '-': + add = 0; + continue; } - if (static_cast<int>(mode) < 0) { - if (debug) - alog("Debug: Malformed mode detected on %s.", chan->name); - continue; - } + if ((cm = ModeManager::FindChannelModeByChar(mode))) + { + /* v/h/o/a/q etc */ + if (cm->Type == MODE_STATUS) + { + cms = static_cast<ChannelModeStatus *>(cm); - if ((cum = &cumodes[static_cast<int>(mode)])->status != 0) { - if (ac == 0) { - alog("channel: mode %c%c with no parameter (?) for channel %s", add ? '+' : '-', mode, chan->name); - continue; - } - ac--; - av++; + if (ac == 0) + { + alog("channel: mode %c%c with no parameter (?) for channel %s", add ? '+' : '-', mode, chan->name); + continue; + } - if ((cum->flags & CUF_PROTECT_BOTSERV) && !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; + 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))) { + 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); + 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; } - continue; - } - if (debug) - alog("debug: Setting %c%c on %s for %s", (add ? '+' : '-'), - mode, chan->name, user->nick); + 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, cum->status); - /* If this does +o, remove any DEOPPED flag */ - } else { - chan_remove_user_status(chan, user, cum->status); + 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++; - } else if ((cbm = &cbmodes[static_cast<int>(mode)])->flag != 0) { - if (check >= 0) { if (add) - chan->mode |= cbm->flag; + cml->AddMask(chan, *av); else - chan->mode &= ~cbm->flag; + cml->DelMask(chan, *av); } + else + { + if (check >= 0) + { + if (add) + chan->SetMode(mode); + else + chan->RemoveMode(mode); + } + + 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 (cbm->setvalue) { - if (add || !(cbm->flags & CBM_MINUS_NO_ARG)) { - if (ac == 0) { - alog("channel: mode %c%c with no parameter (?) for channel %s", add ? '+' : '-', mode, chan->name); + if (*av && !cmp->IsValid(*av)) continue; + if (add) + { + std::string Param = *av; + chan->SetParam(cmp->Name, Param); } - ac--; - av++; + else + chan->UnsetParam(cmp->Name); } - cbm->setvalue(chan, add ? *av : NULL); - } - if (check < 0) { - if (add) - chan->mode |= cbm->flag; - else - chan->mode &= ~cbm->flag; - } - } else if ((cmm = &cmmodes[static_cast<int>(mode)])->addmask) { - if (ac == 0) { - alog("channel: mode %c%c with no parameter (?) for channel %s", add ? '+' : '-', mode, chan->name); - continue; + if (check < 0) + { + if (add) + chan->SetMode(mode); + else + chan->RemoveMode(mode); + } } - - ac--; - av++; - if (add) - cmm->addmask(chan, *av); - else - cmm->delmask(chan, *av); } } @@ -297,6 +616,7 @@ void chan_set_modes(const char *source, Channel * chan, int ac, const char **av, */ real_ac--; real_av++; + for (i = 0; i < real_ac; i++) { if ((user = finduser(*real_av)) && is_on_chan(chan, user)) @@ -328,19 +648,24 @@ void chan_set_modes(const char *source, Channel * chan, int ac, const char **av, 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, user->nick, chan->name); - if (HelpChannel && ircd->supporthelper && (status & CUS_OP) + if (HelpChannel && ((um = ModeManager::FindUserModeByName(UMODE_HELPOP))) && (status & CUS_OP) && (stricmp(chan->name, HelpChannel) == 0) && (!chan->ci || check_access(user, chan->ci, CA_AUTOOP))) { if (debug) { - alog("debug: %s being given +h for having %d status in %s", + alog("debug: %s being given helpop for having %d status in %s", user->nick, status, chan->name); } - common_svsmode(user, "+h", NULL); + + snprintf(av, sizeof(av), "+%c", um->ModeChar); + + common_svsmode(user, av, NULL); } for (uc = user->chans; uc; uc = uc->next) { @@ -429,6 +754,7 @@ void get_channel_stats(long *nrec, long *memuse) struct c_userlist *cu; BanData *bd; int i; + std::string buf; for (i = 0; i < 1024; i++) { for (chan = chanlist[i]; chan; chan = chan->next) { @@ -436,23 +762,17 @@ void get_channel_stats(long *nrec, long *memuse) mem += sizeof(*chan); if (chan->topic) mem += strlen(chan->topic) + 1; - if (chan->key) - mem += strlen(chan->key) + 1; - if (ircd->fmode) { - if (chan->flood) - mem += strlen(chan->flood) + 1; - } - if (ircd->Lmode) { - if (chan->redirect) - mem += strlen(chan->redirect) + 1; - } + if (chan->GetParam(CMODE_KEY, &buf)) + mem += buf.length() + 1; + if (chan->GetParam(CMODE_FLOOD, &buf)) + mem += buf.length() + 1; + if (chan->GetParam(CMODE_REDIRECT, &buf)) + mem += buf.length() + 1; mem += get_memuse(chan->bans); - if (ircd->except) { + if (ModeManager::FindChannelModeByName(CMODE_EXCEPT)) mem += get_memuse(chan->excepts); - } - if (ircd->invitemode) { + if (ModeManager::FindChannelModeByName(CMODE_INVITEOVERRIDE)) mem += get_memuse(chan->invites); - } for (cu = chan->users; cu; cu = cu->next) { mem += sizeof(*cu); if (cu->ud) { @@ -756,12 +1076,13 @@ void do_sjoin(const char *source, int ac, const char **av) Server *serv; struct c_userlist *cu; const char *s = NULL; - char *buf, *end, cubuf[7], *end2; + char *buf, *end, cubuf[7], *end2, value; const char *modes[6]; int is_sqlined = 0; int ts = 0; int is_created = 0; int keep_their_modes = 1; + ChannelModeList *cml; serv = findserver(servlist, source); @@ -792,9 +1113,9 @@ void do_sjoin(const char *source, int ac, const char **av) bot_join(c->ci); } /* Make sure +r is set */ - if (ircd->chanreg && ircd->regmode) + if (ModeManager::FindChannelModeByName(CMODE_REGISTERED)) { - c->mode |= ircd->regmode; + c->SetMode(CMODE_REGISTERED); ircdproto->SendMode(whosends(c->ci), c->name, "+r"); } } @@ -827,8 +1148,12 @@ void do_sjoin(const char *source, int ac, const char **av) if (ircd->sjoinbanchar) { if (*s == ircd->sjoinbanchar && keep_their_modes) { - buf = myStrGetToken(s, ircd->sjoinbanchar, 1); - add_ban(c, buf); + buf = myStrGetToken(s, ircd->sjoinbanchar, 1); + + cml = static_cast<ChannelModeList *>(ModeManager::FindChannelModeByName(CMODE_BAN)); + if (cml->IsValid(buf)) + cml->AddMask(c, buf); + delete [] buf; if (!end) break; @@ -839,7 +1164,11 @@ void do_sjoin(const char *source, int ac, const char **av) if (ircd->sjoinexchar) { if (*s == ircd->sjoinexchar && keep_their_modes) { buf = myStrGetToken(s, ircd->sjoinexchar, 1); - add_exception(c, buf); + + cml = static_cast<ChannelModeList *>(ModeManager::FindChannelModeByName(CMODE_EXCEPT)); + if (cml->IsValid(buf)) + cml->AddMask(c, buf); + delete [] buf; if (!end) break; @@ -851,7 +1180,11 @@ void do_sjoin(const char *source, int ac, const char **av) if (ircd->sjoininvchar) { if (*s == ircd->sjoininvchar && keep_their_modes) { buf = myStrGetToken(s, ircd->sjoininvchar, 1); - add_invite(c, buf); + + cml = static_cast<ChannelModeList *>(ModeManager::FindChannelModeByName(CMODE_INVITEOVERRIDE)); + if (cml->IsValid(buf)) + cml->AddMask(c, buf); + delete [] buf; if (!end) break; @@ -860,11 +1193,13 @@ void do_sjoin(const char *source, int ac, const char **av) } } - while (csmodes[static_cast<int>(*s)] != 0) - *end2++ = csmodes[static_cast<int>(*s++)]; + while ((value = ModeManager::GetStatusChar(*s))) + { + *end2++ = value; + *s++; + } *end2 = 0; - if (ircd->ts6) { user = find_byuid(s); if (!user) @@ -944,8 +1279,11 @@ void do_sjoin(const char *source, int ac, const char **av) end2 = cubuf + 1; - while (csmodes[static_cast<int>(*s)] != 0) - *end2++ = csmodes[static_cast<int>(*s++)]; + while ((value = ModeManager::GetStatusChar(*s))) + { + *end2++ = value; + *s++; + } *end2 = 0; if (ircd->ts6) { @@ -1017,8 +1355,11 @@ void do_sjoin(const char *source, int ac, const char **av) end2 = cubuf + 1; - while (csmodes[static_cast<int>(*s)] != 0) - *end2++ = csmodes[static_cast<int>(*s++)]; + while ((value = ModeManager::GetStatusChar(*s))) + { + *end2++ = value; + *s++; + } *end2 = 0; if (ircd->ts6) { @@ -1264,95 +1605,6 @@ void do_topic(const char *source, int ac, const char **av) /**************************** Internal Calls *****************************/ /*************************************************************************/ -void add_ban(Channel * chan, const char *mask) -{ - Entry *ban; - /* check for NULL values otherwise we will segfault */ - if (!chan || !mask) { - if (debug) { - alog("debug: add_ban called with NULL values"); - } - return; - } - - /* Check if the list already exists, if not create it. - * Create a new ban and add it to the list.. ~ Viper */ - if (!chan->bans) - chan->bans = list_create(); - ban = entry_add(chan->bans, mask); - - if (!ban) - fatal("Creating new ban entry failed"); - - /* Check whether it matches a botserv bot after adding internally - * and parsing it through cidr support. ~ Viper */ - if (s_BotServ && BSSmartJoin && chan->ci && chan->ci->bi - && chan->usercount >= BSMinUsers) { - BotInfo *bi = chan->ci->bi; - - if (entry_match(ban, bi->nick, bi->user, bi->host, 0)) { - ircdproto->SendMode(bi, chan->name, "-b %s", mask); - entry_delete(chan->bans, ban); - return; - } - } - - if (debug) - alog("debug: Added ban %s to channel %s", mask, chan->name); -} - -/*************************************************************************/ - -void add_exception(Channel * chan, const char *mask) -{ - Entry *exception; - - if (!chan || !mask) { - if (debug) - alog("debug: add_exception called with NULL values"); - return; - } - - /* Check if the list already exists, if not create it. - * Create a new exception and add it to the list.. ~ Viper */ - if (!chan->excepts) - chan->excepts = list_create(); - exception = entry_add(chan->excepts, mask); - - if (!exception) - fatal("Creating new exception entry failed"); - - if (debug) - alog("debug: Added except %s to channel %s", mask, chan->name); -} - -/*************************************************************************/ - -void add_invite(Channel * chan, const char *mask) -{ - Entry *invite; - - if (!chan || !mask) { - if (debug) - alog("debug: add_invite called with NULL values"); - return; - } - - /* Check if the list already exists, if not create it. - * Create a new invite and add it to the list.. ~ Viper */ - if (!chan->invites) - chan->invites = list_create(); - invite = entry_add(chan->invites, mask); - - if (!invite) - fatal("Creating new exception entry failed"); - - if (debug) - alog("debug: Added invite %s to channel %s", mask, chan->name); -} - -/*************************************************************************/ - /** * Set the correct modes, or remove the ones granted without permission, * for the specified user on ths specified channel. This doesn't give @@ -1364,13 +1616,16 @@ void add_invite(Channel * chan, const char *mask) **/ void chan_set_correct_modes(User * user, Channel * c, int give_modes) { - char *tmp; char modebuf[BUFSIZE]; char userbuf[BUFSIZE]; int status; int add_modes = 0; int rem_modes = 0; ChannelInfo *ci; + ChannelMode *owner, *admin; + + owner = ModeManager::FindChannelModeByName(CMODE_OWNER); + admin = ModeManager::FindChannelModeByName(CMODE_PROTECT); if (!c || !(ci = c->ci)) return; @@ -1390,14 +1645,13 @@ void chan_set_correct_modes(User * user, Channel * c, int give_modes) */ if (give_modes && (get_ignore(user->nick) == NULL) && (!user->nc || !(user->nc->flags & NI_AUTOOP))) { - if (ircd->owner && is_founder(user, ci)) + if (owner && is_founder(user, ci)) add_modes |= CUS_OWNER; - else if ((ircd->protect || ircd->admin) - && check_access(user, ci, CA_AUTOPROTECT)) + else if (admin && check_access(user, ci, CA_AUTOPROTECT)) add_modes |= CUS_PROTECT; if (check_access(user, ci, CA_AUTOOP)) add_modes |= CUS_OP; - else if (ircd->halfop && check_access(user, ci, CA_AUTOHALFOP)) + else if (ModeManager::FindChannelModeByName(CMODE_HALFOP) && check_access(user, ci, CA_AUTOHALFOP)) add_modes |= CUS_HALFOP; else if (check_access(user, ci, CA_AUTOVOICE)) add_modes |= CUS_VOICE; @@ -1412,16 +1666,16 @@ void chan_set_correct_modes(User * user, Channel * c, int give_modes) if (((ci->flags & CI_SECUREOPS) || (c->usercount == 1) || check_access(user, ci, CA_AUTODEOP)) && !is_ulined(user->server->name)) { - if (ircd->owner && (status & CUS_OWNER) && !is_founder(user, ci)) + if (owner && (status & CUS_OWNER) && !is_founder(user, ci)) rem_modes |= CUS_OWNER; - if ((ircd->protect || ircd->admin) && (status & CUS_PROTECT) + if (admin && (status & CUS_PROTECT) && !check_access(user, ci, CA_AUTOPROTECT) && !check_access(user, ci, CA_PROTECTME)) rem_modes |= CUS_PROTECT; if ((status & CUS_OP) && !check_access(user, ci, CA_AUTOOP) && !check_access(user, ci, CA_OPDEOPME)) rem_modes |= CUS_OP; - if (ircd->halfop && (status & CUS_HALFOP) + if (ModeManager::FindChannelModeByName(CMODE_HALFOP) && (status & CUS_HALFOP) && !check_access(user, ci, CA_AUTOHALFOP) && !check_access(user, ci, CA_HALFOPME)) rem_modes |= CUS_HALFOP; @@ -1439,18 +1693,14 @@ void chan_set_correct_modes(User * user, Channel * c, int give_modes) if (add_modes > 0) { strcat(modebuf, "+"); if ((add_modes & CUS_OWNER) && !(status & CUS_OWNER)) { - tmp = stripModePrefix(ircd->ownerset); - strcat(modebuf, tmp); - delete [] tmp; + strcat(modebuf, &owner->ModeChar); strcat(userbuf, " "); strcat(userbuf, user->nick); } else { add_modes &= ~CUS_OWNER; } if ((add_modes & CUS_PROTECT) && !(status & CUS_PROTECT)) { - tmp = stripModePrefix(ircd->adminset); - strcat(modebuf, tmp); - delete [] tmp; + strcat(modebuf, &admin->ModeChar); strcat(userbuf, " "); strcat(userbuf, user->nick); } else { @@ -1481,16 +1731,12 @@ void chan_set_correct_modes(User * user, Channel * c, int give_modes) if (rem_modes > 0) { strcat(modebuf, "-"); if (rem_modes & CUS_OWNER) { - tmp = stripModePrefix(ircd->ownerset); - strcat(modebuf, tmp); - delete [] tmp; + strcat(modebuf, &owner->ModeChar); strcat(userbuf, " "); strcat(userbuf, user->nick); } if (rem_modes & CUS_PROTECT) { - tmp = stripModePrefix(ircd->adminset); - strcat(modebuf, tmp); - delete [] tmp; + strcat(modebuf, &admin->ModeChar); strcat(userbuf, " "); strcat(userbuf, user->nick); } @@ -1607,8 +1853,6 @@ Channel *chan_create(const char *chan, time_t ts) c->topic = NULL; *c->topic_setter = 0; c->topic_time = 0; - c->mode = c->limit = 0; - c->key = c->redirect = c->flood = NULL; c->bans = c->excepts = c->invites = NULL; c->users = NULL; c->usercount = 0; @@ -1656,24 +1900,14 @@ void chan_delete(Channel * c) if (c->topic) delete [] c->topic; - if (c->key) - delete [] c->key; - if (ircd->fmode) { - if (c->flood) - delete [] c->flood; - } - if (ircd->Lmode) { - if (c->redirect) - delete [] c->redirect; - } - if (c->bans && c->bans->count) { while (c->bans->entries) { entry_delete(c->bans, c->bans->entries); } } - if (ircd->except) { + if (ModeManager::FindChannelModeByName(CMODE_EXCEPT)) + { if (c->excepts && c->excepts->count) { while (c->excepts->entries) { entry_delete(c->excepts, c->excepts->entries); @@ -1681,7 +1915,8 @@ void chan_delete(Channel * c) } } - if (ircd->invitemode) { + if (ModeManager::FindChannelModeByName(CMODE_INVITEOVERRIDE)) + { if (c->invites && c->invites->count) { while (c->invites->entries) { entry_delete(c->invites, c->invites->entries); @@ -1701,109 +1936,6 @@ void chan_delete(Channel * c) /*************************************************************************/ -void del_ban(Channel * chan, const char *mask) -{ - AutoKick *akick; - Entry *ban; - - /* Sanity check as it seems some IRCD will just send -b without a mask */ - if (!mask || !chan->bans || (chan->bans->count == 0)) - return; - - ban = elist_find_mask(chan->bans, mask); - - if (ban) { - entry_delete(chan->bans, ban); - - if (debug) - alog("debug: Deleted ban %s from channel %s", mask, - chan->name); - } - - if (chan->ci && (akick = is_stuck(chan->ci, mask))) - stick_mask(chan->ci, akick); -} - -/*************************************************************************/ - -void del_exception(Channel * chan, const char *mask) -{ - Entry *exception; - - /* Sanity check as it seems some IRCD will just send -e without a mask */ - if (!mask || !chan->excepts || (chan->excepts->count == 0)) - return; - - exception = elist_find_mask(chan->excepts, mask); - - if (exception) { - entry_delete(chan->excepts, exception); - - if (debug) - alog("debug: Deleted except %s to channel %s", mask, - chan->name); - } -} - -/*************************************************************************/ - -void del_invite(Channel * chan, const char *mask) -{ - Entry *invite; - - /* Sanity check as it seems some IRCD will just send -I without a mask */ - if (!mask || !chan->invites || (chan->invites->count == 0)) { - return; - } - - invite = elist_find_mask(chan->invites, mask); - - if (invite) { - entry_delete(chan->invites, invite); - - if (debug) - alog("debug: Deleted invite %s to channel %s", mask, - chan->name); - } -} - - -/*************************************************************************/ - -char *get_flood(Channel * chan) -{ - return chan->flood; -} - -/*************************************************************************/ - -char *get_key(Channel * chan) -{ - return chan->key; -} - -/*************************************************************************/ - -char *get_limit(Channel * chan) -{ - static char limit[16]; - - if (chan->limit == 0) - return NULL; - - snprintf(limit, sizeof(limit), "%lu", static_cast<unsigned long>(chan->limit)); - return limit; -} - -/*************************************************************************/ - -char *get_redirect(Channel * chan) -{ - return chan->redirect; -} - -/*************************************************************************/ - Channel *join_user_update(User * user, Channel * chan, const char *name, time_t chants) { @@ -1838,9 +1970,9 @@ Channel *join_user_update(User * user, Channel * chan, const char *name, bot_join(chan->ci); } /* Make sure +r is set */ - if (ircd->chanreg && ircd->regmode) + if (ModeManager::FindChannelModeByName(CMODE_REGISTERED)) { - chan->mode |= ircd->regmode; + chan->SetMode(CMODE_REGISTERED); ircdproto->SendMode(whosends(chan->ci), chan->name, "+r"); } } @@ -1867,53 +1999,6 @@ Channel *join_user_update(User * user, Channel * chan, const char *name, /*************************************************************************/ -void set_flood(Channel * chan, const char *value) -{ - if (chan->flood) - delete [] chan->flood; - chan->flood = value ? sstrdup(value) : NULL; - - if (debug) - alog("debug: Flood mode for channel %s set to %s", chan->name, - chan->flood ? chan->flood : "no flood settings"); -} - -/*************************************************************************/ - -void chan_set_key(Channel * chan, const char *value) -{ - if (chan->key) - delete [] chan->key; - chan->key = value ? sstrdup(value) : NULL; - - if (debug) - alog("debug: Key of channel %s set to %s", chan->name, - chan->key ? chan->key : "no key"); -} - -/*************************************************************************/ - -void set_limit(Channel * chan, const char *value) -{ - chan->limit = value ? strtoul(value, NULL, 10) : 0; - - if (debug) - alog("debug: Limit of channel %s set to %u", chan->name, - chan->limit); -} - -/*************************************************************************/ - -void set_redirect(Channel * chan, const char *value) -{ - if (chan->redirect) - delete [] chan->redirect; - chan->redirect = value ? sstrdup(value) : NULL; - - if (debug) - alog("debug: Redirect of channel %s set to %s", chan->name, - chan->redirect ? chan->redirect : "no redirect"); -} void do_mass_mode(char *modes) { diff --git a/src/chanserv.c b/src/chanserv.c index 819d3c03e..a581ded69 100644 --- a/src/chanserv.c +++ b/src/chanserv.c @@ -104,21 +104,6 @@ LevelInfo levelinfo[] = { }; int levelinfo_maxwidth = 0; -CSModeUtil csmodeutils[] = { - { "DEOP", "deop", "-o", CI_OPNOTICE, CA_OPDEOP, CA_OPDEOPME }, - { "OP", "op", "+o", CI_OPNOTICE, CA_OPDEOP, CA_OPDEOPME }, - { "DEVOICE", "devoice", "-v", 0, CA_VOICE, CA_VOICEME }, - { "VOICE", "voice", "+v", 0, CA_VOICE, CA_VOICEME }, - { "DEHALFOP", "dehalfop", "-h", 0, CA_HALFOP, CA_HALFOPME }, - { "HALFOP", "halfop", "+h", 0, CA_HALFOP, CA_HALFOPME }, - /* These get set later */ - { "DEPROTECT", "", "", 0, CA_PROTECT, CA_PROTECTME }, - { "PROTECT", "", "", 0, CA_PROTECT, CA_PROTECTME }, - { "DEOWNER", "", "", 0, ACCESS_FOUNDER, ACCESS_FOUNDER}, - { "OWNER", "", "", 0, ACCESS_FOUNDER, ACCESS_FOUNDER}, - { NULL } -}; - /*************************************************************************/ void moduleAddChanServCmds() { @@ -156,54 +141,68 @@ class ChanServTimer : public Timer char *get_mlock_modes(ChannelInfo * ci, int complete) { static char res[BUFSIZE]; + char *end, *value; + ChannelMode *cm; + ChannelModeParam *cmp; + std::map<char, ChannelMode *>::iterator it; + std::string param; - char *end = res; - - if (ci->mlock_on || ci->mlock_off) { - unsigned int n = 0; - CBModeInfo *cbmi = cbmodeinfos; + memset(&res, '\0', sizeof(res)); + end = res; - if (ci->mlock_on) { + if (ci->mlock_on.count() || ci->mlock_off.count()) + { + if (ci->mlock_on.count()) + { *end++ = '+'; - n++; - do { - if (ci->mlock_on & cbmi->flag) - *end++ = cbmi->mode; - } while ((++cbmi)->flag != 0 && ++n < sizeof(res) - 1); + for (it = ModeManager::ChannelModesByChar.begin(); it != ModeManager::ChannelModesByChar.end(); ++it) + { + cm = it->second; - cbmi = cbmodeinfos; + if (ci->HasMLock(cm->Name, true)) + *end++ = it->first; + } } - if (ci->mlock_off) { + if (ci->mlock_off.count()) + { *end++ = '-'; - n++; - do { - if (ci->mlock_off & cbmi->flag) - *end++ = cbmi->mode; - } while ((++cbmi)->flag != 0 && ++n < sizeof(res) - 1); + for (it = ModeManager::ChannelModesByChar.begin(); it != ModeManager::ChannelModesByChar.end(); ++it) + { + cm = it->second; - cbmi = cbmodeinfos; + if (ci->HasMLock(cm->Name, false)) + *end++ = it->first; + } } - if (ci->mlock_on && complete) { - do { - if (cbmi->csgetvalue && (ci->mlock_on & cbmi->flag)) { - char *value = cbmi->csgetvalue(ci); + if (ci->mlock_on.count() && complete) + { + for (it = ModeManager::ChannelModesByChar.begin(); it != ModeManager::ChannelModesByChar.end(); ++it) + { + cm = it->second; + + if (cm->Type == MODE_PARAM) + { + cmp = static_cast<ChannelModeParam *>(cm); + + ci->GetParam(cmp->Name, ¶m); + + if (!param.empty()) + { + value = const_cast<char *>(param.c_str()); - if (value) { *end++ = ' '; while (*value) *end++ = *value++; } } - } while ((++cbmi)->flag != 0 && ++n < sizeof(res) - 1); + } } } - *end = 0; - return res; } @@ -216,6 +215,7 @@ void get_chanserv_stats(long *nrec, long *memuse) long count = 0, mem = 0; unsigned i, j; ChannelInfo *ci; + std::string param; for (i = 0; i < 256; i++) { for (ci = chanlists[i]; ci; ci = ci->next) { @@ -239,16 +239,16 @@ void get_chanserv_stats(long *nrec, long *memuse) if (ci->akick[j].creator) mem += strlen(ci->akick[j].creator) + 1; } - if (ci->mlock_key) - mem += strlen(ci->mlock_key) + 1; - if (ircd->fmode) { - if (ci->mlock_flood) - mem += strlen(ci->mlock_flood) + 1; - } - if (ircd->Lmode) { - if (ci->mlock_redirect) - mem += strlen(ci->mlock_redirect) + 1; - } + + if (ci->GetParam(CMODE_KEY, ¶m)) + mem += param.length() + 1; + + if (ci->GetParam(CMODE_FLOOD, ¶m)) + mem += param.length() + 1; + + if (ci->GetParam(CMODE_REDIRECT, ¶m)) + mem += param.length() + 1; + if (ci->last_topic) mem += strlen(ci->last_topic) + 1; if (ci->entry_message) @@ -477,12 +477,40 @@ void load_cs_dbase() ci->akick = NULL; } - SAFE(read_int32(&ci->mlock_on, f)); - SAFE(read_int32(&ci->mlock_off, f)); - SAFE(read_int32(&ci->mlock_limit, f)); - SAFE(read_string(&ci->mlock_key, f)); - SAFE(read_string(&ci->mlock_flood, f)); - SAFE(read_string(&ci->mlock_redirect, f)); + //SAFE(read_int32(&ci->mlock_on, f)); + //SAFE(read_int32(&ci->mlock_off, f)); + // Clearly this doesn't work + SAFE(read_int32(&tmp32, f)); + SAFE(read_int32(&tmp32, f)); + + SAFE(read_int32(&tmp32, f)); + if (tmp32) + { + std::ostringstream limit; + limit << tmp32; + ci->SetParam(CMODE_LIMIT, limit.str()); + } + + SAFE(read_string(&s, f)); + if (s) + { + ci->SetParam(CMODE_KEY, std::string(s)); + delete [] s; + } + + SAFE(read_string(&s, f)); + if (s) + { + ci->SetParam(CMODE_FLOOD, std::string(s)); + delete [] s; + } + + SAFE(read_string(&s, f)); + if (s) + { + ci->SetParam(CMODE_REDIRECT, std::string(s)); + delete [] s; + } SAFE(read_int16(&tmp16, f)); if (tmp16) ci->memos.memos.resize(tmp16); @@ -598,6 +626,7 @@ void save_cs_dbase() unsigned i, j; ChannelInfo *ci; static time_t lastwarn = 0; + std::string param; if (!(f = open_db(s_ChanServ, ChanDBName, "w", CHAN_VERSION))) return; @@ -661,12 +690,24 @@ void save_cs_dbase() } } - SAFE(write_int32(ci->mlock_on, f)); - SAFE(write_int32(ci->mlock_off, f)); - SAFE(write_int32(ci->mlock_limit, f)); - SAFE(write_string(ci->mlock_key, f)); - SAFE(write_string(ci->mlock_flood, f)); - SAFE(write_string(ci->mlock_redirect, f)); + //SAFE(write_int32(ci->mlock_on, f)); + //SAFE(write_int32(ci->mlock_off, f)); + // Clearly this doesnt work + SAFE(write_int32(NULL, f)); + SAFE(write_int32(NULL, f)); + + ci->GetParam(CMODE_LIMIT, ¶m); + SAFE(write_int32(param.empty() ? NULL : atoi(param.c_str()), f)); + + ci->GetParam(CMODE_KEY, ¶m); + SAFE(write_string(param.empty() ? NULL : param.c_str(), f)); + + ci->GetParam(CMODE_FLOOD, ¶m); + SAFE(write_string(param.empty() ? NULL : param.c_str(), f)); + + ci->GetParam(CMODE_REDIRECT, ¶m); + SAFE(write_string(param.empty() ? NULL : param.c_str(), f)); + SAFE(write_int16(ci->memos.memos.size(), f)); SAFE(write_int16(ci->memos.memomax, f)); for (j = 0; j < ci->memos.memos.size(); j++) { @@ -730,16 +771,18 @@ void save_cs_dbase() void check_modes(Channel * c) { - char modebuf[64], argbuf[BUFSIZE], *end = modebuf, *end2 = argbuf; - uint32 modes = 0; + time_t t = time(NULL); ChannelInfo *ci; - CBModeInfo *cbmi; - CBMode *cbm; + ChannelMode *cm; + ChannelModeParam *cmp; + char modebuf[64], argbuf[BUFSIZE], *end = modebuf, *end2 = argbuf, *value, *csvalue; + std::map<char, ChannelMode *>::iterator it; + std::string param, ciparam; - if (!c) { - if (debug) { + if (!c) + { + if (debug) alog("debug: check_modes called with NULL values"); - } return; } @@ -747,148 +790,136 @@ void check_modes(Channel * c) return; /* Check for mode bouncing */ - if (c->server_modecount >= 3 && c->chanserv_modecount >= 3) { - ircdproto->SendGlobops(NULL, - "Warning: unable to set modes on channel %s. " - "Are your servers' U:lines configured correctly?", - c->name); + if (c->server_modecount >= 3 && c->chanserv_modecount >= 3) + { + ircdproto->SendGlobops(NULL, "Warning: unable to set modes on channel %s. Are your servers' U:lines configured correctly?", c->name); alog("%s: Bouncy modes on channel %s", s_ChanServ, c->name); c->bouncy_modes = 1; return; } - if (c->chanserv_modetime != time(NULL)) { + if (c->chanserv_modetime != time(NULL)) + { c->chanserv_modecount = 0; - c->chanserv_modetime = time(NULL); + c->chanserv_modetime = t; } c->chanserv_modecount++; /* Check if the channel is registered; if not remove mode -r */ - if (!(ci = c->ci)) { - if (ircd->regmode) { - if (c->mode & ircd->regmode) { - c->mode &= ~ircd->regmode; - ircdproto->SendMode(whosends(ci), c->name, "-r"); - } + if (!(ci = c->ci)) + { + if (c->HasMode(CMODE_REGISTERED)) + { + c->RemoveMode(CMODE_REGISTERED); + ircdproto->SendMode(whosends(ci), c->name, "-r"); } /* Channels that are not regged also need the defcon modes.. ~ Viper */ /* return; */ } - /* Initialize the modes-var to set all modes not set yet but which should - * be set as by mlock and defcon. - */ - if (ci) - modes = ~c->mode & ci->mlock_on; - if (DefConModesSet) - modes |= (~c->mode & DefConModesOn); - - /* Initialize the buffers */ *end++ = '+'; - cbmi = cbmodeinfos; - do { - if (modes & cbmi->flag) { - *end++ = cbmi->mode; - c->mode |= cbmi->flag; + for (it = ModeManager::ChannelModesByChar.begin(); it != ModeManager::ChannelModesByChar.end(); ++it) + { + cm = it->second; + + /* If this channel does not have the mode and the mode is mlocked/defcon'd */ + if (!c->HasMode(cm->Name) && (ci && ci->HasMLock(cm->Name, true)) || (DefConModesSet && DefConModesCI.HasMLock(cm->Name, true))) + { + *end++ = it->first; + c->SetMode(cm->Name); /* Add the eventual parameter and modify the Channel structure */ - if (cbmi->getvalue && cbmi->csgetvalue) { - char *value; - /* Check if it's a defcon or mlock mode */ - if (DefConModesOn & cbmi->flag) - value = cbmi->csgetvalue(&DefConModesCI); + if (cm->Type == MODE_PARAM) + { + cmp = static_cast<ChannelModeParam *>(cm); + + param.clear(); + if (DefConModesSet && DefConModesCI.HasMLock(cm->Name, true)) + DefConModesCI.GetParam(cmp->Name, ¶m); else if (ci) - value = cbmi->csgetvalue(ci); - else { - value = NULL; - if (debug) - alog ("Warning: setting modes with unknown origin."); - } + ci->GetParam(cmp->Name, ¶m); + else + alog("Warning: Got no param for mode %c on channel %s but was expecting one", cmp->ModeChar, c->name); - cbm = &cbmodes[static_cast<int>(cbmi->mode)]; - cbm->setvalue(c, value); + if (!param.empty()) + { + value = const_cast<char *>(param.c_str()); - if (value) { *end2++ = ' '; while (*value) *end2++ = *value++; } } - } else if (cbmi->getvalue && cbmi->csgetvalue - && ((ci && (ci->mlock_on & cbmi->flag)) - || (DefConModesOn & cbmi->flag)) - && (c->mode & cbmi->flag)) { - char *value = cbmi->getvalue(c); - char *csvalue; - - /* Check if it's a defcon or mlock mode */ - if (DefConModesOn & cbmi->flag) - csvalue = cbmi->csgetvalue(&DefConModesCI); + } + /* If this is a param mode and its mlocked or defcon has it set negative */ + else if (cm->Type == MODE_PARAM && c->HasMode(cm->Name) && (ci && ci->HasMLock(cm->Name, true) || (DefConModesSet && DefConModesCI.HasMLock(cm->Name, true)))) + { + cmp = static_cast<ChannelModeParam *>(cm); + + c->GetParam(cmp->Name, ¶m); + + if (DefConModesSet && DefConModesCI.HasMLock(cm->Name, true)) + DefConModesCI.GetParam(cmp->Name, &ciparam); else if (ci) - csvalue = cbmi->csgetvalue(ci); - else { - csvalue = NULL; - if (debug) - alog ("Warning: setting modes with unknown origin."); - } + ci->GetParam(cmp->Name, &ciparam); + else + alog("Warning: Got no param for mode %c on channel %s but was expecting one", cmp->ModeChar, c->name); + + if (!param.empty() && !ciparam.empty() && param != ciparam) + { + value = const_cast<char *>(param.c_str()); + csvalue = const_cast<char *>(ciparam.c_str()); - /* Lock and actual values don't match, so fix the mode */ - if (value && csvalue && strcmp(value, csvalue)) { - *end++ = cbmi->mode; + *end++ = it->first; - cbm = &cbmodes[static_cast<int>(cbmi->mode)]; - cbm->setvalue(c, csvalue); + c->SetParam(cmp->Name, ciparam); *end2++ = ' '; while (*csvalue) *end2++ = *csvalue++; } } - } while ((++cbmi)->flag != 0); + } - if (*(end - 1) == '+') - end--; + *end++ = '-'; - modes = 0; - if (ci) { - modes = c->mode & ci->mlock_off; - /* Make sure we don't remove a mode just set by defcon.. ~ Viper */ - if (DefConModesSet) - modes &= ~(modes & DefConModesOn); - } - if (DefConModesSet) - modes |= c->mode & DefConModesOff; + for (it = ModeManager::ChannelModesByChar.begin(); it != ModeManager::ChannelModesByChar.end(); ++it) + { + cm = it->second; - if (modes) { - *end++ = '-'; - cbmi = cbmodeinfos; + /* If the channel has the mode */ + if (c->HasMode(cm->Name) && (ci && ci->HasMLock(cm->Name, false)) || (DefConModesSet && DefConModesCI.HasMLock(cm->Name, false))) + { + *end++ = it->first; + c->RemoveMode(cm->Name); - do { - if (modes & cbmi->flag) { - *end++ = cbmi->mode; - c->mode &= ~cbmi->flag; + /* Add the eventual parameter */ + if (cm->Type == MODE_PARAM) + { + cmp = static_cast<ChannelModeParam *>(cm); - /* Add the eventual parameter and clean up the Channel structure */ - if (cbmi->getvalue) { - cbm = &cbmodes[static_cast<int>(cbmi->mode)]; + if (!cmp->MinusNoArg) + { + c->GetParam(cmp->Name, ¶m); - if (!(cbm->flags & CBM_MINUS_NO_ARG)) { - char *value = cbmi->getvalue(c); + if (!param.empty()) + { + value = const_cast<char *>(param.c_str()); - if (value) { - *end2++ = ' '; - while (*value) - *end2++ = *value++; - } - } + *end2++ = ' '; - cbm->setvalue(c, NULL); + while (*value) + *end++ = *value++; + } } } - } while ((++cbmi)->flag != 0); + } } + if (*(end - 1) == '-') + end--; + if (end == modebuf) return; @@ -903,12 +934,13 @@ void check_modes(Channel * c) int check_valid_admin(User * user, Channel * chan, int servermode) { + ChannelMode *cm; + if (!chan || !chan->ci) return 1; - if (!ircd->admin) { + if (!(cm = ModeManager::FindChannelModeByName(CMODE_PROTECT))) return 0; - } /* They will be kicked; no need to deop, no need to update our internal struct too */ if (chan->ci->flags & CI_FORBIDDEN) @@ -916,14 +948,14 @@ int check_valid_admin(User * user, Channel * chan, int servermode) if (servermode && !check_access(user, chan->ci, CA_AUTOPROTECT)) { notice_lang(s_ChanServ, user, CHAN_IS_REGISTERED, s_ChanServ); - ircdproto->SendMode(whosends(chan->ci), chan->name, "%s %s", - ircd->adminunset, user->nick); + ircdproto->SendMode(whosends(chan->ci), chan->name, "-%s %s", + cm->ModeChar, user->nick); return 0; } if (check_access(user, chan->ci, CA_AUTODEOP)) { - ircdproto->SendMode(whosends(chan->ci), chan->name, "%s %s", - ircd->adminunset, user->nick); + ircdproto->SendMode(whosends(chan->ci), chan->name, "-%s %s", + cm->ModeChar, user->nick); return 0; } @@ -938,7 +970,7 @@ int check_valid_admin(User * user, Channel * chan, int servermode) int check_valid_op(User * user, Channel * chan, int servermode) { - char *tmp; + ChannelMode *owner, *protect, *halfop; if (!chan || !chan->ci) return 1; @@ -946,34 +978,37 @@ int check_valid_op(User * user, Channel * chan, int servermode) if (chan->ci->flags & CI_FORBIDDEN) return 0; + owner = ModeManager::FindChannelModeByName(CMODE_OWNER); + protect = ModeManager::FindChannelModeByName(CMODE_PROTECT); + halfop = ModeManager::FindChannelModeByName(CMODE_HALFOP); + if (servermode && !check_access(user, chan->ci, CA_AUTOOP)) { notice_lang(s_ChanServ, user, CHAN_IS_REGISTERED, s_ChanServ); - if (ircd->halfop) { - if (ircd->owner && ircd->protect) { + if (halfop) + { + if (owner && protect) + { if (check_access(user, chan->ci, CA_AUTOHALFOP)) { - tmp = stripModePrefix(ircd->ownerunset); ircdproto->SendMode(whosends(chan->ci), chan->name, - "%so%s %s %s %s", ircd->adminunset, - tmp, user->nick, + "-%so%s %s %s %s", protect->ModeChar, + owner->ModeChar, user->nick, user->nick, user->nick); - delete [] tmp; } else { - tmp = stripModePrefix(ircd->ownerunset); ircdproto->SendMode(whosends(chan->ci), chan->name, - "%sho%s %s %s %s %s", - ircd->adminunset, tmp, + "-%sho%s %s %s %s %s", + protect->ModeChar, + owner->ModeChar, user->nick, user->nick, user->nick, user->nick); - delete [] tmp; } - } else if (!ircd->owner && ircd->protect) { + } else if (!owner && protect) { if (check_access(user, chan->ci, CA_AUTOHALFOP)) { ircdproto->SendMode(whosends(chan->ci), chan->name, - "%so %s %s", ircd->adminunset, + "-%so %s %s", protect->ModeChar, user->nick, user->nick); } else { ircdproto->SendMode(whosends(chan->ci), chan->name, - "%soh %s %s %s", ircd->adminunset, + "-%soh %s %s %s", protect->ModeChar, user->nick, user->nick, user->nick); } } else { @@ -993,14 +1028,12 @@ int check_valid_op(User * user, Channel * chan, int servermode) } if (check_access(user, chan->ci, CA_AUTODEOP)) { - if (ircd->halfop) { - if (ircd->owner && ircd->protect) { - tmp = stripModePrefix(ircd->ownerunset); + if (halfop) { + if (owner && protect) { ircdproto->SendMode(whosends(chan->ci), chan->name, - "%sho%s %s %s %s %s", ircd->adminunset, - tmp, user->nick, user->nick, + "-%sho%s %s %s %s %s", protect->ModeChar, + owner->ModeChar, user->nick, user->nick, user->nick, user->nick); - delete [] tmp; } else { ircdproto->SendMode(whosends(chan->ci), chan->name, "-ho %s %s", user->nick, user->nick); @@ -1083,18 +1116,16 @@ int check_should_halfop(User * user, char *chan) int check_should_owner(User * user, char *chan) { - char *tmp; ChannelInfo *ci = cs_findchan(chan); + ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_OWNER); if (!ci || (ci->flags & CI_FORBIDDEN) || *chan == '+') return 0; if (((ci->flags & CI_SECUREFOUNDER) && is_real_founder(user, ci)) || (!(ci->flags & CI_SECUREFOUNDER) && is_founder(user, ci))) { - tmp = stripModePrefix(ircd->ownerset); - ircdproto->SendMode(whosends(ci), chan, "+o%s %s %s", tmp, user->nick, + ircdproto->SendMode(whosends(ci), chan, "+o%s %s %s", cm->ModeChar, user->nick, user->nick); - delete [] tmp; return 1; } @@ -1105,17 +1136,15 @@ int check_should_owner(User * user, char *chan) int check_should_protect(User * user, char *chan) { - char *tmp; ChannelInfo *ci = cs_findchan(chan); + ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_PROTECT); if (!ci || (ci->flags & CI_FORBIDDEN) || *chan == '+') return 0; if (check_access(user, ci, CA_AUTOPROTECT)) { - tmp = stripModePrefix(ircd->adminset); - ircdproto->SendMode(whosends(ci), chan, "+o%s %s %s", tmp, user->nick, + ircdproto->SendMode(whosends(ci), chan, "+o%s %s %s", cm->ModeChar, user->nick, user->nick); - delete [] tmp; return 1; } @@ -1181,7 +1210,7 @@ int check_kick(User * user, const char *chan, time_t chants) * * UltimateIRCd 3.x at least informs channel staff when a joining user is matching an exempt. */ - if (ircd->except && is_excepted(ci, user) == 1) { + if (ModeManager::FindChannelModeByName(CMODE_EXCEPT) && is_excepted(ci, user) == 1) { return 0; } @@ -1460,10 +1489,13 @@ void cs_remove_nick(const NickCore * nc) } } else { alog("%s: Deleting channel %s owned by deleted nick %s", s_ChanServ, ci->name, nc->display); - if (ircd->regmode) { + + if ((ModeManager::FindChannelModeByName(CMODE_REGISTERED))) + { /* Maybe move this to delchan() ? */ - if ((ci->c) && (ci->c->mode & ircd->regmode)) { - ci->c->mode &= ~ircd->regmode; + if (ci->c && ci->c->HasMode(CMODE_REGISTERED)) + { + ci->c->RemoveMode(CMODE_REGISTERED); ircdproto->SendMode(whosends(ci), ci->name, "-r"); } } @@ -1752,16 +1784,6 @@ int delchan(ChannelInfo * ci) if (ci->entry_message) delete [] ci->entry_message; - if (ci->mlock_key) - delete [] ci->mlock_key; - if (ircd->fmode) { - if (ci->mlock_flood) - delete [] ci->mlock_flood; - } - if (ircd->Lmode) { - if (ci->mlock_redirect) - delete [] ci->mlock_redirect; - } if (ci->last_topic) delete [] ci->last_topic; if (ci->forbidby) @@ -1999,137 +2021,9 @@ int get_idealban(ChannelInfo * ci, User * u, char *ret, int retlen) } } -/*************************************************************************/ - -char *cs_get_flood(ChannelInfo * ci) -{ - if (!ci) { - return NULL; - } else { - if (ircd->fmode) - return ci->mlock_flood; - else - return NULL; - } -} - -/*************************************************************************/ - -char *cs_get_key(ChannelInfo * ci) -{ - if (!ci) { - return NULL; - } else { - return ci->mlock_key; - } -} - -/*************************************************************************/ - -char *cs_get_limit(ChannelInfo * ci) -{ - static char limit[16]; - - if (!ci) { - return NULL; - } - - if (ci->mlock_limit == 0) - return NULL; - - snprintf(limit, sizeof(limit), "%lu", - static_cast<unsigned long>(ci->mlock_limit)); - return limit; -} - -/*************************************************************************/ - -char *cs_get_redirect(ChannelInfo * ci) -{ - if (!ci) { - return NULL; - } else { - if (ircd->Lmode) - return ci->mlock_redirect; - else - return NULL; - } -} /*************************************************************************/ -void cs_set_flood(ChannelInfo * ci, const char *value) -{ - if (!ci) { - return; - } - - if (ci->mlock_flood) - delete [] ci->mlock_flood; - - /* This looks ugly, but it works ;) */ - if (ircdproto->IsFloodModeParamValid(value)) { - ci->mlock_flood = sstrdup(value); - } else { - ci->mlock_on &= ~ircd->chan_fmode; - ci->mlock_flood = NULL; - } -} - -/*************************************************************************/ - -void cs_set_key(ChannelInfo * ci, const char *value) -{ - if (!ci) { - return; - } - - if (ci->mlock_key) - delete [] ci->mlock_key; - - /* Don't allow keys with a coma */ - if (value && *value != ':' && !strchr(value, ',')) { - ci->mlock_key = sstrdup(value); - } else { - ci->mlock_on &= ~anope_get_key_mode(); - ci->mlock_key = NULL; - } -} - -/*************************************************************************/ - -void cs_set_limit(ChannelInfo * ci, const char *value) -{ - if (!ci) { - return; - } - - ci->mlock_limit = value ? strtoul(value, NULL, 10) : 0; - - if (ci->mlock_limit <= 0) - ci->mlock_on &= ~anope_get_limit_mode(); -} - -/*************************************************************************/ - -void cs_set_redirect(ChannelInfo * ci, const char *value) -{ - if (!ci) { - return; - } - - if (ci->mlock_redirect) - delete [] ci->mlock_redirect; - - /* Don't allow keys with a coma */ - if (value && *value == '#') { - ci->mlock_redirect = sstrdup(value); - } else { - ci->mlock_on &= ~ircd->chan_lmode; - ci->mlock_redirect = NULL; - } -} - int get_access_level(ChannelInfo * ci, NickAlias * na) { ChanAccess *access; @@ -2150,13 +2044,15 @@ int get_access_level(ChannelInfo * ci, NickAlias * na) const char *get_xop_level(int level) { + ChannelMode *halfop = ModeManager::FindChannelModeByName(CMODE_HALFOP); + if (level < ACCESS_VOP) { return "Err"; - } else if (ircd->halfop && level < ACCESS_HOP) { + } else if (halfop && level < ACCESS_HOP) { return "VOP"; - } else if (!ircd->halfop && level < ACCESS_AOP) { + } else if (!halfop && level < ACCESS_AOP) { return "VOP"; - } else if (ircd->halfop && level < ACCESS_AOP) { + } else if (halfop && level < ACCESS_AOP) { return "HOP"; } else if (level < ACCESS_SOP) { return "AOP"; diff --git a/src/core/cs_access.c b/src/core/cs_access.c index 59f772dee..2fbca088a 100644 --- a/src/core/cs_access.c +++ b/src/core/cs_access.c @@ -112,7 +112,7 @@ class CommandCSAccess : public Command /* We still allow LIST in xOP mode, but not others */ else if ((ci->flags & CI_XOP) && !is_list) { - if (ircd->halfop) + if (ModeManager::FindChannelModeByName(CMODE_HALFOP)) notice_lang(s_ChanServ, u, CHAN_ACCESS_XOP_HOP, s_ChanServ); else notice_lang(s_ChanServ, u, CHAN_ACCESS_XOP, s_ChanServ); diff --git a/src/core/cs_akick.c b/src/core/cs_akick.c index bd928b316..a9e38fbd2 100644 --- a/src/core/cs_akick.c +++ b/src/core/cs_akick.c @@ -229,7 +229,8 @@ class CommandCSAKick : public Command } /* Check excepts BEFORE we get this far */ - if (ircd->except) { + if (ModeManager::FindChannelModeByName(CMODE_EXCEPT)) + { if (is_excepted_mask(ci, mask) == 1) { notice_lang(s_ChanServ, u, CHAN_EXCEPTED, mask, chan); if (freemask) diff --git a/src/core/cs_ban.c b/src/core/cs_ban.c index bd65f1ac8..9901479ae 100644 --- a/src/core/cs_ban.c +++ b/src/core/cs_ban.c @@ -62,9 +62,9 @@ class CommandCSBan : public Command * Dont ban/kick the user on channels where he is excepted * to prevent services <-> server wars. */ - } else if (ircd->except && is_excepted(ci, u2)) { + } else if (ModeManager::FindChannelModeByName(CMODE_EXCEPT) && is_excepted(ci, u2)) { notice_lang(s_ChanServ, u, CHAN_EXCEPTED, u2->nick, ci->name); - } else if (ircd->protectedumode && is_protected(u2)) { + } else if (is_protected(u2)) { notice_lang(s_ChanServ, u, ACCESS_DENIED); } else { const char *av[3]; diff --git a/src/core/cs_clear.c b/src/core/cs_clear.c index f9e9ab8bd..699c70a2f 100644 --- a/src/core/cs_clear.c +++ b/src/core/cs_clear.c @@ -29,6 +29,11 @@ class CommandCSClear : public Command ci::string what = params[1]; Channel *c = findchan(chan); ChannelInfo *ci; + ChannelMode *owner, *admin; + std::string modebuf; + + owner = ModeManager::FindChannelModeByName(CMODE_OWNER); + admin = ModeManager::FindChannelModeByName(CMODE_PROTECT); if (c) ci = c->ci; @@ -38,90 +43,22 @@ class CommandCSClear : public Command } else if (!u || !check_access(u, ci, CA_CLEAR)) { notice_lang(s_ChanServ, u, ACCESS_DENIED); } else if (what == "bans") { - const char *av[2]; - Entry *ban, *bnext; - - if (c->bans && c->bans->count) { - for (ban = c->bans->entries; ban; ban = bnext) { - bnext = ban->next; - av[0] = "-b"; - av[1] = ban->mask; - ircdproto->SendMode(whosends(ci), chan, "-b %s", ban->mask); - chan_set_modes(whosends(ci)->nick, c, 2, av, 0); - } - } + c->ClearBans(); notice_lang(s_ChanServ, u, CHAN_CLEARED_BANS, chan); - } else if (ircd->except && what == "excepts") { - const char *av[2]; - Entry *except, *bnext; - - if (c->excepts && c->excepts->count) { - for (except = c->excepts->entries; except; except = bnext) { - bnext = except->next; - av[0] = "-e"; - av[1] = except->mask; - ircdproto->SendMode(whosends(ci), chan, "-e %s", except->mask); - chan_set_modes(whosends(ci)->nick, c, 2, av, 0); - } - } + } else if (ModeManager::FindChannelModeByName(CMODE_EXCEPT) && what == "excepts") { + c->ClearExcepts(); + notice_lang(s_ChanServ, u, CHAN_CLEARED_EXCEPTS, chan); - } else if (ircd->invitemode && what == "invites") { - const char *av[2]; - Entry *invite, *bnext; - - if (c->invites && c->invites->count) { - for (invite = c->invites->entries; invite; invite = bnext) { - bnext = invite->next; - av[0] = "-I"; - av[1] = invite->mask; - ircdproto->SendMode(whosends(ci), chan, "-I %s", invite->mask); - chan_set_modes(whosends(ci)->nick, c, 2, av, 0); - } - } + } else if (ModeManager::FindChannelModeByName(CMODE_INVITE) && what == "invites") { + c->ClearInvites(); + notice_lang(s_ChanServ, u, CHAN_CLEARED_INVITES, chan); } else if (what == "modes") { - const char *argv[2]; - - if (c->mode) { - /* Clear modes the bulk of the modes */ - ircdproto->SendMode(whosends(ci), c->name, "%s", - ircd->modestoremove); - argv[0] = ircd->modestoremove; - chan_set_modes(whosends(ci)->nick, c, 1, argv, 0); - - /* to prevent the internals from complaining send -k, -L, -f by themselves if we need - to send them - TSL */ - if (c->key) { - ircdproto->SendMode(whosends(ci), c->name, "-k %s", c->key); - argv[0] = "-k"; - argv[1] = c->key; - chan_set_modes(whosends(ci)->nick, c, 2, argv, 0); - } - if (ircd->Lmode && c->redirect) { - ircdproto->SendMode(whosends(ci), c->name, "-L %s", - c->redirect); - argv[0] = "-L"; - argv[1] = c->redirect; - chan_set_modes(whosends(ci)->nick, c, 2, argv, 0); - } - if (ircd->fmode && c->flood) { - if (flood_mode_char_remove) { - ircdproto->SendMode(whosends(ci), c->name, "%s %s", - flood_mode_char_remove, c->flood); - argv[0] = flood_mode_char_remove; - argv[1] = c->flood; - chan_set_modes(whosends(ci)->nick, c, 2, argv, 0); - } else { - if (debug) { - alog("debug: flood_mode_char_remove was not set unable to remove flood/throttle modes"); - } - } - } - check_modes(c); - } + c->ClearModes(); + check_modes(c); notice_lang(s_ChanServ, u, CHAN_CLEARED_MODES, chan); } else if (what == "ops") { @@ -133,11 +70,17 @@ class CommandCSClear : public Command if (ircd->svsmode_ucmode) { av[0] = chan; ircdproto->SendSVSModeChan(av[0], "-o", NULL); - if (ircd->owner) { - ircdproto->SendSVSModeChan(av[0], ircd->ownerunset, NULL); + if (owner) { + modebuf = '-'; + modebuf += owner->ModeChar; + + ircdproto->SendSVSModeChan(av[0], modebuf.c_str(), NULL); } - if (ircd->protect || ircd->admin) { - ircdproto->SendSVSModeChan(av[0], ircd->adminunset, NULL); + if (admin) { + modebuf = '-'; + modebuf += admin->ModeChar; + + ircdproto->SendSVSModeChan(av[0], modebuf.c_str(), NULL); } for (cu = c->users; cu; cu = bnext) { bnext = cu->next; @@ -150,7 +93,7 @@ class CommandCSClear : public Command continue; snprintf(tmp, BUFSIZE, "-%s%s%s", (isop ? "o" : ""), (isadmin ? - ircd->adminunset+1 : ""), (isown ? ircd->ownerunset+1 : "")); + &admin->ModeChar : ""), (isown ? &owner->ModeChar : "")); if (ircdcap->tsmode) { snprintf(buf, BUFSIZE - 1, "%ld", static_cast<long>(time(NULL))); @@ -183,7 +126,7 @@ class CommandCSClear : public Command continue; snprintf(tmp, BUFSIZE, "-%s%s%s", (isop ? "o" : ""), (isadmin ? - ircd->adminunset+1 : ""), (isown ? ircd->ownerunset+1 : "")); + &admin->ModeChar : ""), (isown ? &owner->ModeChar : "")); /* We need to send the IRCd a nick for every mode.. - Viper */ snprintf(tmp2, BUFSIZE, "%s %s %s", (isop ? cu->user->nick : ""), (isadmin ? cu->user->nick : ""), (isown ? cu->user->nick : "")); @@ -212,7 +155,7 @@ class CommandCSClear : public Command } } notice_lang(s_ChanServ, u, CHAN_CLEARED_OPS, chan); - } else if (ircd->halfop && what == "hops") { + } else if (ModeManager::FindChannelModeByName(CMODE_HALFOP) && what == "hops") { const char *av[4]; int ac; char buf[BUFSIZE]; diff --git a/src/core/cs_drop.c b/src/core/cs_drop.c index 13534232d..a8b838f1f 100644 --- a/src/core/cs_drop.c +++ b/src/core/cs_drop.c @@ -59,9 +59,9 @@ class CommandCSDrop : public Command if (ci->c) { - if (ircd->regmode) + if (ModeManager::FindChannelModeByName(CMODE_REGISTERED)) { - ci->c->mode &= ~ircd->regmode; + ci->c->RemoveMode(CMODE_REGISTERED); ircdproto->SendMode(whosends(ci), ci->name, "-r"); } } diff --git a/src/core/cs_forbid.c b/src/core/cs_forbid.c index d1ce0d119..587232794 100644 --- a/src/core/cs_forbid.c +++ b/src/core/cs_forbid.c @@ -29,7 +29,6 @@ class CommandCSForbid : public Command const char *reason = params.size() > 1 ? params[1].c_str() : NULL; Channel *c; - Entry *cur, *enext; if (ForceForbidReason && !reason) { @@ -78,24 +77,8 @@ class CommandCSForbid : public Command /* Before banning everyone, it might be prudent to clear +e and +I lists.. * to prevent ppl from rejoining.. ~ Viper */ - if (ircd->except && c->excepts && c->excepts->count) { - for (cur = c->excepts->entries; cur; cur = enext) { - enext = cur->next; - av[0] = "-e"; - av[1] = cur->mask; - ircdproto->SendMode(whosends(ci), chan, "-e %s", cur->mask); - chan_set_modes(whosends(ci)->nick, c, 2, av, 0); - } - } - if (ircd->invitemode && c->invites && c->invites->count) { - for (cur = c->invites->entries; cur; cur = enext) { - enext = cur->next; - av[0] = "-I"; - av[1] = cur->mask; - ircdproto->SendMode(whosends(ci), chan, "-I %s", cur->mask); - chan_set_modes(whosends(ci)->nick, c, 2, av, 0); - } - } + c->ClearExcepts(); + c->ClearInvites(); for (cu = c->users; cu; cu = nextu) { diff --git a/src/core/cs_getkey.c b/src/core/cs_getkey.c index 7d1fa8637..8c1e127ee 100644 --- a/src/core/cs_getkey.c +++ b/src/core/cs_getkey.c @@ -26,6 +26,7 @@ class CommandCSGetKey : public Command { const char *chan = params[0].c_str(); ChannelInfo *ci; + std::string key; ci = cs_findchan(chan); @@ -35,13 +36,13 @@ class CommandCSGetKey : public Command return MOD_CONT; } - if (!ci->c || !ci->c->key) + if (!ci->c || !ci->c->GetParam(CMODE_KEY, &key)) { notice_lang(s_ChanServ, u, CHAN_GETKEY_NOKEY, chan); return MOD_CONT; } - notice_lang(s_ChanServ, u, CHAN_GETKEY_KEY, chan, ci->c->key); + notice_lang(s_ChanServ, u, CHAN_GETKEY_KEY, chan, key.c_str()); return MOD_CONT; } diff --git a/src/core/cs_info.c b/src/core/cs_info.c index 77e840d36..8a13b73a2 100644 --- a/src/core/cs_info.c +++ b/src/core/cs_info.c @@ -47,6 +47,7 @@ class CommandCSInfo : public Command bool has_auspex = u->nc && u->nc->HasPriv("chanserv/auspex"); int show_all = 0; time_t expt; + ChannelMode *cm; ci = cs_findchan(chan); @@ -80,10 +81,12 @@ class CommandCSInfo : public Command tm = localtime(&ci->last_used); strftime_lang(buf, sizeof(buf), u, STRFTIME_DATE_TIME_FORMAT, tm); notice_lang(s_ChanServ, u, CHAN_INFO_LAST_USED, buf); + + cm = ModeManager::FindChannelModeByName(CMODE_SECRET); // XXX: yuck. if (ci->last_topic && - (show_all || (!(ci->mlock_on & anope_get_secret_mode()) - && (!ci->c || !(ci->c->mode & anope_get_secret_mode()))))) + (show_all || (!ci->HasMLock(cm->Name, true)) + && (!ci->c || !(ci->c->HasMode(CMODE_SECRET))))) { notice_lang(s_ChanServ, u, CHAN_INFO_LAST_TOPIC, ci->last_topic); notice_lang(s_ChanServ, u, CHAN_INFO_TOPIC_SET_BY, ci->last_topic_setter); diff --git a/src/core/cs_modes.c b/src/core/cs_modes.c index 13f2f0f82..4e8162c02 100644 --- a/src/core/cs_modes.c +++ b/src/core/cs_modes.c @@ -15,14 +15,24 @@ #include "module.h" -/* do_util: not a command, but does the job of other */ - -static CommandReturn do_util(User *u, CSModeUtil *util, const char *chan, const char *nick) +/** do_util: not a command, but does the job of others + * @param u The user doing the command + * @param cm A channel mode class + * @param chan The channel its being set on + * @param nick The nick the modes being set on + * @param set Is the mode being set or removed + * @param level The acecss level required to set this mode on someone else + * @param levelself The access level required to set this mode on yourself + * @param name The name, eg "OP" or "HALFOP" + * @param notice Flag required on a channel to send a notice + */ +static CommandReturn do_util(User *u, ChannelMode *cm, const char *chan, const char *nick, bool set, int level, int levelself, const std::string &name, int32 notice) { const char *av[2]; Channel *c = findchan(chan); ChannelInfo *ci; User *u2; + char modebuf[3]; int is_same; @@ -35,32 +45,34 @@ static CommandReturn do_util(User *u, CSModeUtil *util, const char *chan, const if (c) ci = c->ci; - if (!c) { + if (!c) notice_lang(s_ChanServ, u, CHAN_X_NOT_IN_USE, chan); - } else if (is_same ? !(u2 = u) : !(u2 = finduser(nick))) { + else if (is_same ? !(u2 = u) : !(u2 = finduser(nick))) notice_lang(s_ChanServ, u, NICK_X_NOT_IN_USE, nick); - } else if (!is_on_chan(c, u2)) { + else if (!is_on_chan(c, u2)) notice_lang(s_ChanServ, u, NICK_X_NOT_ON_CHAN, u2->nick, c->name); - } else if (is_same ? !check_access(u, ci, util->levelself) : - !check_access(u, ci, util->level)) { + else if (is_same ? !check_access(u, ci, levelself) : !check_access(u, ci, level)) notice_lang(s_ChanServ, u, ACCESS_DENIED); - } else if (*util->mode == '-' && !is_same && (ci->flags & CI_PEACE) - && (get_access(u2, ci) >= get_access(u, ci))) { + else if (!set && !is_same && (ci->flags & CI_PEACE) && (get_access(u2, ci) >= get_access(u, ci))) notice_lang(s_ChanServ, u, ACCESS_DENIED); - } else if (*util->mode == '-' && is_protected(u2) && !is_same) { + else if (!set && is_protected(u2) && !is_same) notice_lang(s_ChanServ, u, ACCESS_DENIED); - } else { - ircdproto->SendMode(whosends(ci), c->name, "%s %s", util->mode, - u2->nick); + else + { + snprintf(modebuf, sizeof(modebuf), "%c%c", (set ? '+' : '-'), cm->ModeChar); - av[0] = util->mode; + ircdproto->SendMode(whosends(ci), c->name, "%s %s", modebuf, u2->nick); + + av[0] = modebuf; av[1] = u2->nick; + chan_set_modes(s_ChanServ, c, 2, av, 3); - if (util->notice && ci->flags & util->notice) + if (notice && ci->flags & notice) ircdproto->SendMessage(whosends(ci), c->name, "%s command used for %s by %s", - util->name, u2->nick, u->nick); + name.c_str(), u2->nick, u->nick); } + return MOD_CONT; } @@ -75,7 +87,9 @@ class CommandCSOp : public Command CommandReturn Execute(User *u, std::vector<ci::string> ¶ms) { - return do_util(u, &csmodeutils[MUT_OP], (params.size() > 0 ? params[0].c_str() : NULL), (params.size() > 1 ? params[1].c_str() : NULL)); + ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_OP); + + return do_util(u, cm, (params.size() > 0 ? params[0].c_str() : NULL), (params.size() > 1 ? params[1].c_str() : NULL), true, CA_OPDEOP, CA_OPDEOPME, "OP", CI_OPNOTICE); } bool OnHelp(User *u, const ci::string &subcommand) @@ -100,7 +114,9 @@ class CommandCSDeOp : public Command CommandReturn Execute(User *u, std::vector<ci::string> ¶ms) { - return do_util(u, &csmodeutils[MUT_DEOP], (params.size() > 0 ? params[0].c_str() : NULL), (params.size() > 1 ? params[1].c_str() : NULL)); + ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_OP); + + return do_util(u, cm, (params.size() > 0 ? params[0].c_str() : NULL), (params.size() > 1 ? params[1].c_str() : NULL), false, CA_OPDEOP, CA_OPDEOPME, "DEOP", CI_OPNOTICE); } bool OnHelp(User *u, const ci::string &subcommand) @@ -125,7 +141,9 @@ class CommandCSVoice : public Command CommandReturn Execute(User *u, std::vector<ci::string> ¶ms) { - return do_util(u, &csmodeutils[MUT_VOICE], (params.size() > 0 ? params[0].c_str() : NULL), (params.size() > 1 ? params[1].c_str() : NULL)); + ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_VOICE); + + return do_util(u, cm, (params.size() > 0 ? params[0].c_str() : NULL), (params.size() > 1 ? params[1].c_str() : NULL), true, CA_VOICE, CA_VOICEME, "VOICE", 0); } bool OnHelp(User *u, const ci::string &subcommand) @@ -150,7 +168,9 @@ class CommandCSDeVoice : public Command CommandReturn Execute(User *u, std::vector<ci::string> ¶ms) { - return do_util(u, &csmodeutils[MUT_DEVOICE], (params.size() > 0 ? params[0].c_str() : NULL), (params.size() > 1 ? params[1].c_str() : NULL)); + ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_VOICE); + + return do_util(u, cm, (params.size() > 0 ? params[0].c_str() : NULL), (params.size() > 1 ? params[1].c_str() : NULL), false, CA_VOICE, CA_VOICEME, "DEVOICE", 0); } bool OnHelp(User *u, const ci::string &subcommand) @@ -175,12 +195,14 @@ class CommandCSHalfOp : public Command CommandReturn Execute(User *u, std::vector<ci::string> ¶ms) { - if (!ircd->halfop) + ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_HALFOP); + + if (!cm) { return MOD_CONT; } - return do_util(u, &csmodeutils[MUT_HALFOP], (params.size() > 0 ? params[0].c_str() : NULL), (params.size() > 1 ? params[1].c_str() : NULL)); + return do_util(u, cm, (params.size() > 0 ? params[0].c_str() : NULL), (params.size() > 1 ? params[1].c_str() : NULL), true, CA_HALFOP, CA_HALFOPME, "HALFOP", 0); } bool OnHelp(User *u, const ci::string &subcommand) @@ -205,12 +227,15 @@ class CommandCSDeHalfOp : public Command CommandReturn Execute(User *u, std::vector<ci::string> ¶ms) { - if (!ircd->halfop) + ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_HALFOP); + + if (!cm) { return MOD_CONT; + } - return do_util(u, &csmodeutils[MUT_DEHALFOP], (params.size() > 0 ? params[0].c_str() : NULL), (params.size() > 1 ? params[1].c_str() : NULL)); + return do_util(u, cm, (params.size() > 0 ? params[0].c_str() : NULL), (params.size() > 1 ? params[1].c_str() : NULL), false, CA_HALFOP, CA_HALFOPME, "DEHALFOP", 0); } bool OnHelp(User *u, const ci::string &subcommand) @@ -235,12 +260,14 @@ class CommandCSProtect : public Command CommandReturn Execute(User *u, std::vector<ci::string> ¶ms) { - if (!ircd->protect && !ircd->admin) + ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_PROTECT); + + if (!cm) { return MOD_CONT; } - return do_util(u, &csmodeutils[MUT_PROTECT], (params.size() > 0 ? params[0].c_str() : NULL), (params.size() > 1 ? params[1].c_str() : NULL)); + return do_util(u, cm, (params.size() > 0 ? params[0].c_str() : NULL), (params.size() > 1 ? params[1].c_str() : NULL), true, CA_PROTECT, CA_PROTECTME, "PROTECT", 0); } bool OnHelp(User *u, const ci::string &subcommand) @@ -255,8 +282,6 @@ class CommandCSProtect : public Command } }; -/*************************************************************************/ - class CommandCSDeProtect : public Command { public: @@ -266,12 +291,14 @@ class CommandCSDeProtect : public Command CommandReturn Execute(User *u, std::vector<ci::string> ¶ms) { - if (!ircd->protect && !ircd->admin) + ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_PROTECT); + + if (!cm) { return MOD_CONT; } - return do_util(u, &csmodeutils[MUT_DEPROTECT], (params.size() > 0 ? params[0].c_str() : NULL), (params.size() > 1 ? params[1].c_str() : NULL)); + return do_util(u, cm, (params.size() > 0 ? params[0].c_str() : NULL), (params.size() > 1 ? params[1].c_str() : NULL), false, CA_PROTECT, CA_PROTECTME, "DEPROTECT", 0); } bool OnHelp(User *u, const ci::string &subcommand) @@ -286,8 +313,6 @@ class CommandCSDeProtect : public Command } }; -/*************************************************************************/ - class CommandCSOwner : public Command { public: @@ -297,7 +322,14 @@ class CommandCSOwner : public Command CommandReturn Execute(User *u, std::vector<ci::string> ¶ms) { - return do_util(u, &csmodeutils[MUT_OWNER], (params.size() > 0 ? params[0].c_str() : NULL), NULL); + ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_OWNER); + + if (!cm) + { + return MOD_CONT; + } + + return do_util(u, cm, (params.size() > 0 ? params[0].c_str() : NULL), NULL, true, ACCESS_FOUNDER, ACCESS_FOUNDER, "OWNER", 0); } bool OnHelp(User *u, const ci::string &subcommand) @@ -312,8 +344,6 @@ class CommandCSOwner : public Command } }; -/*************************************************************************/ - class CommandCSDeOwner : public Command { public: @@ -323,7 +353,14 @@ class CommandCSDeOwner : public Command CommandReturn Execute(User *u, std::vector<ci::string> ¶ms) { - return do_util(u, &csmodeutils[MUT_DEOWNER], (params.size() > 0 ? params[0].c_str() : NULL), NULL); + ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_OWNER); + + if (!cm) + { + return MOD_CONT; + } + + return do_util(u, cm, (params.size() > 0 ? params[0].c_str() : NULL), NULL, false, ACCESS_FOUNDER, ACCESS_FOUNDER, "OWNER", 0); } bool OnHelp(User *u, const ci::string &subcommand) @@ -353,25 +390,19 @@ class CSModes : public Module this->AddCommand(CHANSERV, new CommandCSVoice()); this->AddCommand(CHANSERV, new CommandCSDeVoice()); - if (ircd->halfop) + if (ModeManager::FindChannelModeByName(CMODE_HALFOP)) { this->AddCommand(CHANSERV, new CommandCSHalfOp()); this->AddCommand(CHANSERV, new CommandCSDeHalfOp()); } - if (ircd->protect) - { - this->AddCommand(CHANSERV, new CommandCSProtect()); - this->AddCommand(CHANSERV, new CommandCSDeProtect()); - } - - if (ircd->admin) + if (ModeManager::FindChannelModeByName(CMODE_PROTECT)) { this->AddCommand(CHANSERV, new CommandCSProtect()); this->AddCommand(CHANSERV, new CommandCSDeProtect()); } - if (ircd->owner) + if (ModeManager::FindChannelModeByName(CMODE_OWNER)) { this->AddCommand(CHANSERV, new CommandCSOwner()); this->AddCommand(CHANSERV, new CommandCSDeOwner()); @@ -379,24 +410,27 @@ class CSModes : public Module } void ChanServHelp(User *u) { - if (ircd->owner) { + if (ModeManager::FindChannelModeByName(CMODE_OWNER)) + { notice_lang(s_ChanServ, u, CHAN_HELP_CMD_OWNER); notice_lang(s_ChanServ, u, CHAN_HELP_CMD_DEOWNER); } - if (ircd->protect) { + + if (ModeManager::FindChannelModeByName(CMODE_PROTECT)) + { notice_lang(s_ChanServ, u, CHAN_HELP_CMD_PROTECT); notice_lang(s_ChanServ, u, CHAN_HELP_CMD_DEPROTECT); - } else if (ircd->admin) { - notice_lang(s_ChanServ, u, CHAN_HELP_CMD_ADMIN); - notice_lang(s_ChanServ, u, CHAN_HELP_CMD_DEADMIN); } notice_lang(s_ChanServ, u, CHAN_HELP_CMD_OP); notice_lang(s_ChanServ, u, CHAN_HELP_CMD_DEOP); - if (ircd->halfop) { + + if (ModeManager::FindChannelModeByName(CMODE_HALFOP)) + { notice_lang(s_ChanServ, u, CHAN_HELP_CMD_HALFOP); notice_lang(s_ChanServ, u, CHAN_HELP_CMD_DEHALFOP); } + notice_lang(s_ChanServ, u, CHAN_HELP_CMD_VOICE); notice_lang(s_ChanServ, u, CHAN_HELP_CMD_DEVOICE); } diff --git a/src/core/cs_register.c b/src/core/cs_register.c index 5726859b6..89985fb93 100644 --- a/src/core/cs_register.c +++ b/src/core/cs_register.c @@ -33,6 +33,7 @@ class CommandCSRegister : public Command struct u_chaninfolist *uc; char founderpass[PASSMAX]; char tmp_pass[PASSMAX]; + ChannelMode *cm; if (readonly) { @@ -83,7 +84,7 @@ class CommandCSRegister : public Command ci->c = c; ci->bantype = CSDefBantype; ci->flags = CSDefFlags; - ci->mlock_on = ircd->defmlock; + ci->mlock_on = ircd->DefMLock; ci->memos.memomax = MSMaxMemos; ci->last_used = ci->time_registered; ci->founder = u->nc; @@ -116,10 +117,10 @@ class CommandCSRegister : public Command /* Implement new mode lock */ check_modes(c); /* On most ircds you do not receive the admin/owner mode till its registered */ - if (ircd->admin) - ircdproto->SendMode(findbot(s_ChanServ), chan, "%s %s", ircd->adminset, u->nick); - if (ircd->owner && ircd->ownerset) - ircdproto->SendMode(findbot(s_ChanServ), chan, "%s %s", ircd->ownerset, u->nick); + if ((cm = ModeManager::FindChannelModeByName(CMODE_OWNER))) + ircdproto->SendMode(findbot(s_ChanServ), chan, "+%c %s", cm->ModeChar, u->nick); + else if ((cm = ModeManager::FindChannelModeByName(CMODE_PROTECT))) + ircdproto->SendMode(findbot(s_ChanServ), chan, "+%c %s", cm->ModeChar, u->nick); FOREACH_MOD(I_OnChanRegistered, OnChanRegistered(ci)); } diff --git a/src/core/cs_set.c b/src/core/cs_set.c index eed1e535a..0036a752a 100644 --- a/src/core/cs_set.c +++ b/src/core/cs_set.c @@ -190,27 +190,20 @@ class CommandCSSet : public Command { int add = -1; /* 1 if adding, 0 if deleting, -1 if neither */ unsigned char mode; - CBMode *cbm; + ChannelMode *cm; + ChannelModeParam *cmp; if (checkDefCon(DEFCON_NO_MLOCK_CHANGE)) { notice_lang(s_ChanServ, u, OPER_DEFCON_DENIED); return MOD_CONT; } - /* Reinitialize everything */ - if (ircd->chanreg) { - ci->mlock_on = ircd->regmode; - } else { - ci->mlock_on = 0; - } - ci->mlock_off = ci->mlock_limit = 0; - ci->mlock_key = NULL; - if (ircd->fmode) { - ci->mlock_flood = NULL; - } - if (ircd->Lmode) { - ci->mlock_redirect = NULL; - } + ci->ClearMLock(); + + if (ModeManager::FindChannelModeByName(CMODE_REGISTERED)) + ci->SetMLock(CMODE_REGISTERED, true); + + ci->ClearParams(); std::string params(modes ? modes : ""), param; unsigned space = params.find(' '); @@ -235,48 +228,67 @@ class CommandCSSet : public Command continue; } - if (static_cast<int>(mode) < 128 && (cbm = &cbmodes[static_cast<int>(mode)])->flag != 0) { - if ((cbm->flags & CBM_NO_MLOCK) - || ((cbm->flags & CBM_NO_USER_MLOCK) && !is_oper(u))) { - notice_lang(s_ChanServ, u, CHAN_SET_MLOCK_IMPOSSIBLE_CHAR, - mode); - } else if (add) { - ci->mlock_on |= cbm->flag; - ci->mlock_off &= ~cbm->flag; - if (cbm->cssetvalue) + if ((cm = ModeManager::FindChannelModeByChar(mode))) + { + if (!cm->CanSet(u)) + { + notice_lang(s_ChanServ, u, CHAN_SET_MLOCK_IMPOSSIBLE_CHAR, mode); + } + else if (add) + { + if (cm->Type == MODE_PARAM) { - modeparams.GetToken(param); - cbm->cssetvalue(ci, param.c_str()); + cmp = static_cast<ChannelModeParam *>(cm); + + if (!modeparams.GetToken(param)) + continue; + + if (!cmp->IsValid(param.c_str())) + continue; + + ci->SetParam(cmp->Name, param); } - } else { - ci->mlock_off |= cbm->flag; - if (ci->mlock_on & cbm->flag) { - ci->mlock_on &= ~cbm->flag; - if (cbm->cssetvalue) - cbm->cssetvalue(ci, NULL); + + ci->SetMLock(cm->Name, true); + ci->RemoveMLock(cm->Name, false); + } + else + { + ci->SetMLock(cm->Name, false); + + if (ci->HasMLock(cm->Name, true)) + { + ci->RemoveMLock(cm->Name, true); + + if (cm->Type == MODE_PARAM) + { + cmp = static_cast<ChannelModeParam *>(cm); + + ci->UnsetParam(cmp->Name); + } } } - } else { - notice_lang(s_ChanServ, u, CHAN_SET_MLOCK_UNKNOWN_CHAR, mode); } + else + notice_lang(s_ChanServ, u, CHAN_SET_MLOCK_UNKNOWN_CHAR, mode); } /* while (*modes) */ - if (ircd->Lmode) { + if (ModeManager::FindChannelModeByName(CMODE_REDIRECT)) { /* We can't mlock +L if +l is not mlocked as well. */ - if ((ci->mlock_on & ircd->chan_lmode) - && !(ci->mlock_on & anope_get_limit_mode())) { - ci->mlock_on &= ~ircd->chan_lmode; - delete [] ci->mlock_redirect; + if (ci->HasMLock(CMODE_REDIRECT, true) && !ci->HasMLock(CMODE_LIMIT, true)) + { + ci->RemoveMLock(CMODE_REDIRECT, true); + ci->UnsetParam(CMODE_REDIRECT); notice_lang(s_ChanServ, u, CHAN_SET_MLOCK_L_REQUIRED); } } /* Some ircd we can't set NOKNOCK without INVITE */ /* So check if we need there is a NOKNOCK MODE and that we need INVITEONLY */ - if (ircd->noknock && ircd->knock_needs_i) { - if ((ci->mlock_on & ircd->noknock) - && !(ci->mlock_on & anope_get_invite_mode())) { - ci->mlock_on &= ~ircd->noknock; + if (ModeManager::FindChannelModeByName(CMODE_NOKNOCK) && ircd->knock_needs_i) { + if (ci->HasMLock(CMODE_NOKNOCK, true) && !ci->HasMLock(CMODE_INVITE, true)) + { + ci->RemoveMLock(CMODE_NOKNOCK, true); notice_lang(s_ChanServ, u, CHAN_SET_MLOCK_K_REQUIRED); } } @@ -474,7 +486,7 @@ class CommandCSSet : public Command } else if (CHECKLEV(CA_AUTOOP) || CHECKLEV(CA_OPDEOP) || CHECKLEV(CA_OPDEOPME)) { access->level = ACCESS_AOP; - } else if (ircd->halfop) { + } else if (ModeManager::FindChannelModeByName(CMODE_HALFOP)) { if (CHECKLEV(CA_AUTOHALFOP) || CHECKLEV(CA_HALFOP) || CHECKLEV(CA_HALFOPME)) { access->level = ACCESS_HOP; diff --git a/src/core/cs_xop.c b/src/core/cs_xop.c index 3c077e1f1..4fd3bcd7a 100644 --- a/src/core/cs_xop.c +++ b/src/core/cs_xop.c @@ -498,7 +498,7 @@ class CSXOP : public Module this->SetType(CORE); this->AddCommand(CHANSERV, new CommandCSAOP()); - if (ircd->halfop) + if (ModeManager::FindChannelModeByName(CMODE_HALFOP)) this->AddCommand(CHANSERV, new CommandCSHOP()); this->AddCommand(CHANSERV, new CommandCSSOP()); this->AddCommand(CHANSERV, new CommandCSVOP()); @@ -507,7 +507,7 @@ class CSXOP : public Module { notice_lang(s_ChanServ, u, CHAN_HELP_CMD_SOP); notice_lang(s_ChanServ, u, CHAN_HELP_CMD_AOP); - if (ircd->halfop) + if (ModeManager::FindChannelModeByName(CMODE_HALFOP)) notice_lang(s_ChanServ, u, CHAN_HELP_CMD_HOP); notice_lang(s_ChanServ, u, CHAN_HELP_CMD_VOP); } diff --git a/src/core/os_chanlist.c b/src/core/os_chanlist.c index 8eb5a5f77..e92e4ca8d 100644 --- a/src/core/os_chanlist.c +++ b/src/core/os_chanlist.c @@ -26,12 +26,14 @@ class CommandOSChanList : public Command { const char *pattern = params.size() > 0 ? params[0].c_str() : NULL; ci::string opt = params.size() > 1 ? params[1] : ""; - - int modes = 0; + std::list<ChannelModeName> Modes; User *u2; if (!opt.empty() && opt == "SECRET") - modes |= (anope_get_secret_mode() | anope_get_private_mode()); + { + Modes.push_back(CMODE_SECRET); + Modes.push_back(CMODE_PRIVATE); + } if (pattern && (u2 = finduser(pattern))) { @@ -41,8 +43,15 @@ class CommandOSChanList : public Command for (uc = u2->chans; uc; uc = uc->next) { - if (modes && !(uc->chan->mode & modes)) - continue; + if (!Modes.empty()) + { + for (std::list<ChannelModeName>::iterator it = Modes.begin(); it != Modes.end(); ++it) + { + if (!uc->chan->HasMode(*it)) + continue; + } + } + notice_lang(s_OperServ, u, OPER_CHANLIST_RECORD, uc->chan->name, uc->chan->usercount, chan_get_modes(uc->chan, 1, 1), uc->chan->topic ? uc->chan->topic : ""); } } @@ -59,8 +68,14 @@ class CommandOSChanList : public Command { if (pattern && !Anope::Match(c->name, pattern, false)) continue; - if (modes && !(c->mode & modes)) - continue; + if (!Modes.empty()) + { + for (std::list<ChannelModeName>::iterator it = Modes.begin(); it != Modes.end(); ++it) + { + if (!c->HasMode(*it)) + continue; + } + } notice_lang(s_OperServ, u, OPER_CHANLIST_RECORD, c->name, c->usercount, chan_get_modes(c, 1, 1), c->topic ? c->topic : ""); } } diff --git a/src/core/os_clearmodes.c b/src/core/os_clearmodes.c index 26deb8ce9..5af54d8be 100644 --- a/src/core/os_clearmodes.c +++ b/src/core/os_clearmodes.c @@ -29,7 +29,8 @@ class CommandOSClearModes : public Command Channel *c; int all = 0; struct c_userlist *cu, *next; - Entry *entry, *nexte; + ChannelMode *cm; + std::string buf; if (!(c = findchan(chan))) { @@ -88,7 +89,7 @@ class CommandOSClearModes : public Command } /* Clear mode +h */ - if (ircd->halfop) + if (ModeManager::FindChannelModeByName(CMODE_HALFOP)) { if (ircd->svsmode_ucmode) ircdproto->SendSVSModeChan(c->name, "-h", NULL); @@ -106,120 +107,54 @@ class CommandOSClearModes : public Command } /* Clear mode Owners */ - if (ircd->owner) + if ((cm = ModeManager::FindChannelModeByName(CMODE_OWNER))) { + buf = '-'; + buf += cm->ModeChar; + if (ircd->svsmode_ucmode) - ircdproto->SendSVSModeChan(c->name, ircd->ownerunset, NULL); + ircdproto->SendSVSModeChan(c->name, buf.c_str(), NULL); for (cu = c->users; cu; cu = next) { next = cu->next; if (!chan_has_user_status(c, cu->user, CUS_OWNER)) continue; - argv[0] = ircd->ownerunset; + argv[0] = buf.c_str(); argv[1] = cu->user->nick; if (!ircd->svsmode_ucmode) - ircdproto->SendMode(findbot(s_OperServ), c->name, "%s %s", ircd->ownerunset, cu->user->nick); + ircdproto->SendMode(findbot(s_OperServ), c->name, "%s %s", buf.c_str(), cu->user->nick); chan_set_modes(s_OperServ, c, 2, argv, 0); } } /* Clear mode protected or admins */ - if (ircd->protect || ircd->admin) + if ((cm = ModeManager::FindChannelModeByName(CMODE_PROTECT))) { + buf = '-'; + buf += cm->ModeChar; + if (ircd->svsmode_ucmode) - ircdproto->SendSVSModeChan(c->name, ircd->adminunset, NULL); + ircdproto->SendSVSModeChan(c->name, buf.c_str(), NULL); for (cu = c->users; cu; cu = next) { next = cu->next; if (!chan_has_user_status(c, cu->user, CUS_PROTECT)) continue; - argv[0] = ircd->adminunset; + argv[0] = buf.c_str(); argv[1] = cu->user->nick; if (!ircd->svsmode_ucmode) - ircdproto->SendMode(findbot(s_OperServ), c->name, "%s %s", ircd->adminunset, cu->user->nick); - chan_set_modes(s_OperServ, c, 2, argv, 0); - } - } - } - - if (c->mode) - { - /* Clear modes the bulk of the modes */ - ircdproto->SendMode(findbot(s_OperServ), c->name, "%s", ircd->modestoremove); - argv[0] = ircd->modestoremove; - chan_set_modes(s_OperServ, c, 1, argv, 0); - - /* to prevent the internals from complaining send -k, -L, -f by themselves if we need - to send them - TSL */ - if (c->key) - { - ircdproto->SendMode(findbot(s_OperServ), c->name, "-k %s", c->key); - argv[0] = "-k"; - argv[1] = c->key; - chan_set_modes(s_OperServ, c, 2, argv, 0); - } - if (ircd->Lmode && c->redirect) - { - ircdproto->SendMode(findbot(s_OperServ), c->name, "-L %s", c->redirect); - argv[0] = "-L"; - argv[1] = c->redirect; - chan_set_modes(s_OperServ, c, 2, argv, 0); - } - if (ircd->fmode && c->flood) - { - if (flood_mode_char_remove) - { - ircdproto->SendMode(findbot(s_OperServ), c->name, "%s %s", flood_mode_char_remove, c->flood); - argv[0] = flood_mode_char_remove; - argv[1] = c->flood; + ircdproto->SendMode(findbot(s_OperServ), c->name, "%s %s", buf.c_str(), cu->user->nick); chan_set_modes(s_OperServ, c, 2, argv, 0); } - else - { - if (debug) - alog("debug: flood_mode_char_remove was not set unable to remove flood/throttle modes"); - } } } - /* Clear bans */ - if (c->bans && c->bans->count) - { - for (entry = c->bans->entries; entry; entry = nexte) - { - nexte = entry->next; - argv[0] = "-b"; - argv[1] = entry->mask; - ircdproto->SendMode(findbot(s_OperServ), c->name, "-b %s", entry->mask); - chan_set_modes(s_OperServ, c, 2, argv, 0); - } - } - /* Clear excepts */ - if (ircd->except && c->excepts && c->excepts->count) - { - for (entry = c->excepts->entries; entry; entry = nexte) - { - nexte = entry->next; - argv[0] = "-e"; - argv[1] = entry->mask; - ircdproto->SendMode(findbot(s_OperServ), c->name, "-e %s", entry->mask); - chan_set_modes(s_OperServ, c, 2, argv, 0); - } - } + c->ClearModes(s_OperServ); - /* Clear invites */ - if (ircd->invitemode && c->invites && c->invites->count) - { - for (entry = c->invites->entries; entry; entry = nexte) - { - nexte = entry->next; - argv[0] = "-I"; - argv[1] = entry->mask; - ircdproto->SendMode(findbot(s_OperServ), c->name, "-I %s", entry->mask); - chan_set_modes(s_OperServ, c, 2, argv, 0); - } - } + c->ClearBans(s_OperServ); + c->ClearExcepts(s_OperServ); + c->ClearInvites(s_OperServ); } if (all) diff --git a/src/core/os_userlist.c b/src/core/os_userlist.c index 9b1e9ffe6..d5abff8b3 100644 --- a/src/core/os_userlist.c +++ b/src/core/os_userlist.c @@ -26,12 +26,13 @@ class CommandOSUserList : public Command { const char *pattern = params.size() > 0 ? params[0].c_str() : NULL; ci::string opt = params.size() > 1 ? params[1] : ""; - Channel *c; - int modes = 0; + std::list<UserModeName> Modes; if (!opt.empty() && opt == "INVISIBLE") - modes |= anope_get_invis_mode(); + { + Modes.push_back(UMODE_INVIS); + } if (pattern && (c = findchan(pattern))) { @@ -41,8 +42,14 @@ class CommandOSUserList : public Command for (cu = c->users; cu; cu = cu->next) { - if (modes && !(cu->user->mode & modes)) - continue; + if (!Modes.empty()) + { + for (std::list<UserModeName>::iterator it = Modes.begin(); it != Modes.end(); ++it) + { + if (!cu->user->HasMode(*it)) + continue; + } + } notice_lang(s_OperServ, u, OPER_USERLIST_RECORD, cu->user->nick, cu->user->GetIdent().c_str(), cu->user->GetDisplayedHost().c_str()); } } @@ -63,8 +70,14 @@ class CommandOSUserList : public Command snprintf(mask, sizeof(mask), "%s!%s@%s", u2->nick, u2->GetIdent().c_str(), u2->GetDisplayedHost().c_str()); if (!Anope::Match(mask, pattern, false)) continue; - if (modes && !(u2->mode & modes)) - continue; + if (!Modes.empty()) + { + for (std::list<UserModeName>::iterator it = Modes.begin(); it != Modes.end(); ++it) + { + if (!u2->HasMode(*it)) + continue; + } + } } notice_lang(s_OperServ, u, OPER_USERLIST_RECORD, u2->nick, u2->GetIdent().c_str(), u2->GetDisplayedHost().c_str()); } diff --git a/src/ircd.c b/src/ircd.c index 13e1ed2dc..89866fc06 100644 --- a/src/ircd.c +++ b/src/ircd.c @@ -16,7 +16,6 @@ #include "extern.h" IRCDProto *ircdproto; -IRCDModes ircd_modes; /** * Globals we want from the protocol file @@ -24,13 +23,6 @@ IRCDModes ircd_modes; IRCDVar *ircd; IRCDCAPAB *ircdcap; char *version_protocol; -CBModeInfo *cbmodeinfos; -CUMode cumodes[128]; -char *flood_mode_char_set; -char *flood_mode_char_remove; -CBMode cbmodes[128]; -CMMode cmmodes[128]; -char csmodes[128]; int UseTSMODE; void pmodule_ircd_proto(IRCDProto *proto) @@ -68,126 +60,7 @@ void pmodule_ircd_version(const char *version) version_protocol = sstrdup(version); } -void pmodule_ircd_cbmodeinfos(CBModeInfo * modeinfos) -{ - cbmodeinfos = modeinfos; -} - -void pmodule_ircd_cumodes(CUMode modes[128]) -{ - int i = 0; - for (i = 0; i < 128; i++) { - cumodes[i] = modes[i]; - } -} - -void pmodule_ircd_flood_mode_char_set(const char *mode) -{ - flood_mode_char_set = sstrdup(mode); -} - -void pmodule_ircd_flood_mode_char_remove(const char *mode) -{ - flood_mode_char_remove = sstrdup(mode); -} - -void pmodule_ircd_cbmodes(CBMode modes[128]) -{ - int i = 0; - for (i = 0; i < 128; i++) { - cbmodes[i] = modes[i]; - } -} - -void pmodule_ircd_cmmodes(CMMode modes[128]) -{ - int i = 0; - for (i = 0; i < 128; i++) { - cmmodes[i] = modes[i]; - } -} - -void pmodule_ircd_csmodes(char mode[128]) -{ - int i = 0; - for (i = 0; i < 128; i++) { - csmodes[i] = mode[i]; - } -} - void pmodule_ircd_useTSMode(int use) { UseTSMODE = use; } - -/** mode stuff */ - -void pmodule_invis_umode(int mode) -{ - ircd_modes.user_invis = mode; -} - -void pmodule_oper_umode(int mode) -{ - ircd_modes.user_oper = mode; -} - -void pmodule_invite_cmode(int mode) -{ - ircd_modes.chan_invite = mode; -} - -void pmodule_secret_cmode(int mode) -{ - ircd_modes.chan_secret = mode; -} - -void pmodule_private_cmode(int mode) -{ - ircd_modes.chan_private = mode; -} - -void pmodule_key_mode(int mode) -{ - ircd_modes.chan_key = mode; -} - -void pmodule_limit_mode(int mode) -{ - ircd_modes.chan_limit = mode; -} - -int anope_get_invis_mode() -{ - return ircd_modes.user_invis; -} - -int anope_get_oper_mode() -{ - return ircd_modes.user_oper; -} - -int anope_get_invite_mode() -{ - return ircd_modes.chan_invite; -} - -int anope_get_secret_mode() -{ - return ircd_modes.chan_secret; -} - -int anope_get_private_mode() -{ - return ircd_modes.chan_private; -} - -int anope_get_key_mode() -{ - return ircd_modes.chan_key; -} - -int anope_get_limit_mode() -{ - return ircd_modes.chan_limit; -} diff --git a/src/modes.cpp b/src/modes.cpp new file mode 100644 index 000000000..948eee97f --- /dev/null +++ b/src/modes.cpp @@ -0,0 +1,364 @@ +/* Mode support + * + * (C) 2009 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + * $Id$ + * + */ + +#include "services.h" + +std::map<char, UserMode *> ModeManager::UserModesByChar; +std::map<UserModeName, UserMode *> ModeManager::UserModesByName; +/* Channel modes */ +std::map<char, ChannelMode *> ModeManager::ChannelModesByChar; +std::map<ChannelModeName, ChannelMode *> ModeManager::ChannelModesByName; +/* Although there are two different maps for UserModes and ChannelModes + * the pointers in each are the same. This is used to increase + * efficiency. + */ + +/** Add a user mode to Anope + * @param Mode The mode + * @param um A UserMode or UserMode derived class + * @return true on success, false on error + */ +bool ModeManager::AddUserMode(char Mode, UserMode *um) +{ + bool ret = ModeManager::UserModesByChar.insert(std::make_pair(Mode, um)).second; + if (ret) + ret = ModeManager::UserModesByName.insert(std::make_pair(um->Name, um)).second; + + return ret; +} + +/** Add a channel mode to Anope + * @param Mode The mode + * @param cm A ChannelMode or ChannelMode derived class + * @return true on success, false on error + */ +bool ModeManager::AddChannelMode(char Mode, ChannelMode *cm) +{ + bool ret = ModeManager::ChannelModesByChar.insert(std::make_pair(Mode, cm)).second; + if (ret) + ret = ModeManager::ChannelModesByName.insert(std::make_pair(cm->Name, cm)).second; + + return ret; +} + +/** Find a channel mode + * @param Mode The mode + * @return The mode class + */ +ChannelMode *ModeManager::FindChannelModeByChar(char Mode) +{ + std::map<char, ChannelMode *>::iterator it = ModeManager::ChannelModesByChar.find(Mode); + + if (it != ModeManager::ChannelModesByChar.end()) + { + return it->second; + } + + return NULL; +} + +/** Find a user mode + * @param Mode The mode + * @return The mode class + */ +UserMode *ModeManager::FindUserModeByChar(char Mode) +{ + std::map<char, UserMode *>::iterator it = ModeManager::UserModesByChar.find(Mode); + + if (it != ModeManager::UserModesByChar.end()) + { + return it->second; + } + + return NULL; +} + +/** Find a channel mode + * @param Mode The modename + * @return The mode class + */ +ChannelMode *ModeManager::FindChannelModeByName(ChannelModeName Name) +{ + std::map<ChannelModeName, ChannelMode *>::iterator it = ModeManager::ChannelModesByName.find(Name); + + if (it != ModeManager::ChannelModesByName.end()) + { + return it->second; + } + + return NULL; +} + +/** Find a user mode + * @param Mode The modename + * @return The mode class + */ +UserMode *ModeManager::FindUserModeByName(UserModeName Name) +{ + std::map<UserModeName, UserMode *>::iterator it = ModeManager::UserModesByName.find(Name); + + if (it != ModeManager::UserModesByName.end()) + { + return it->second; + } + + return NULL; +} + +/** Gets the channel mode char for a symbol (eg + returns v) + * @param Value The symbol + * @return The char + */ +char ModeManager::GetStatusChar(char Value) +{ + std::map<char, ChannelMode *>::iterator it; + ChannelMode *cm; + ChannelModeStatus *cms; + + for (it = ModeManager::ChannelModesByChar.begin(); it != ModeManager::ChannelModesByChar.end(); ++it) + { + cm = it->second; + + if (cm->Type == MODE_STATUS) + { + cms = static_cast<ChannelModeStatus *>(cm); + + if (Value == cms->Symbol) + { + return it->first; + } + } + } + + return 0; +} + +/** Is the key valid + * @param value The key + * @return true or false + */ +bool ChannelModeKey::IsValid(const char *value) +{ + if (value && *value != ':' && !strchr(value, ',')) + return true; + + return false; +} + +/** Can admin only mode be set by the user + * @param u The user - can be NULL if defcon is checking + * @return true or false + */ +bool ChannelModeAdmin::CanSet(User *u) +{ + if (u && is_oper(u)) + return true; + + return false; +} + +/** Can oper only mode be set by the user + * @param u The user - can be NULL if defcon is checking + * @return true or false + */ +bool ChannelModeOper::CanSet(User *u) +{ + if (u && is_oper(u)) + return true; + + return false; +} + +/** Can the user set the registerd mode? + * No. + * @return false + */ +bool ChannelModeRegistered::CanSet(User *u) +{ + return false; +} + +/** Add a ban to the channel + * @param chan The channel + * @param mask The ban + */ +void ChannelModeBan::AddMask(Channel *chan, const char *mask) +{
+ Entry *ban;
+
+ /* check for NULL values otherwise we will segfault */
+ if (!chan || !mask)
+ {
+ if (debug)
+ alog("debug: add_ban called with NULL values");
+ return;
+ }
+
+ /* Check if the list already exists, if not create it.
+ * Create a new ban and add it to the list.. ~ Viper */
+ if (!chan->bans)
+ chan->bans = list_create();
+ ban = entry_add(chan->bans, mask);
+
+ if (!ban)
+ fatal("Creating new ban entry failed");
+
+ /* Check whether it matches a botserv bot after adding internally
+ * and parsing it through cidr support. ~ Viper */
+ if (s_BotServ && BSSmartJoin && chan->ci && chan->ci->bi
+ && chan->usercount >= BSMinUsers)
+ {
+ BotInfo *bi = chan->ci->bi;
+
+ if (entry_match(ban, bi->nick, bi->user, bi->host, 0))
+ {
+ ircdproto->SendMode(bi, chan->name, "-b %s", mask);
+ entry_delete(chan->bans, ban);
+ return;
+ }
+ }
+
+ if (debug)
+ alog("debug: Added ban %s to channel %s", mask, chan->name);
+} + +/** Remove a ban from the channel + * @param chan The channel + * @param mask The ban + */ +void ChannelModeBan::DelMask(Channel *chan, const char *mask) +{ + AutoKick *akick;
+ Entry *ban;
+
+ /* Sanity check as it seems some IRCD will just send -b without a mask */
+ if (!mask || !chan->bans || (chan->bans->count == 0))
+ return;
+
+ ban = elist_find_mask(chan->bans, mask);
+
+ if (ban)
+ {
+ entry_delete(chan->bans, ban);
+
+ if (debug)
+ alog("debug: Deleted ban %s from channel %s", mask,
+ chan->name);
+ }
+
+ if (chan->ci && (akick = is_stuck(chan->ci, mask)))
+ stick_mask(chan->ci, akick);
+ +} + +/** Add an except to the channel + * @param chan The channel + * @param mask The except + */ +void ChannelModeExcept::AddMask(Channel *chan, const char *mask) +{ + Entry *exception;
+
+ if (!chan || !mask)
+ {
+ if (debug)
+ alog("debug: add_exception called with NULL values");
+ return;
+ }
+
+ /* Check if the list already exists, if not create it.
+ * Create a new exception and add it to the list.. ~ Viper */
+ if (!chan->excepts)
+ chan->excepts = list_create();
+ exception = entry_add(chan->excepts, mask);
+
+ if (!exception)
+ fatal("Creating new exception entry failed");
+
+ if (debug)
+ alog("debug: Added except %s to channel %s", mask, chan->name); +} + +/** Remove an except from the channel + * @param chan The channel + * @param mask The except + */ +void ChannelModeExcept::DelMask(Channel *chan, const char *mask) +{ + Entry *exception;
+
+ /* Sanity check as it seems some IRCD will just send -e without a mask */
+ if (!mask || !chan->excepts || (chan->excepts->count == 0))
+ return;
+
+ exception = elist_find_mask(chan->excepts, mask);
+
+ if (exception)
+ {
+ entry_delete(chan->excepts, exception);
+
+ if (debug)
+ alog("debug: Deleted except %s to channel %s", mask, chan->name);
+ } +} + +/** Add an invex to the channel + * @param chan The channel + * @param mask The invex + */ +void ChannelModeInvite::AddMask(Channel *chan, const char *mask) +{ + Entry *invite;
+
+ if (!chan || !mask)
+ {
+ if (debug)
+ alog("debug: add_invite called with NULL values");
+ return;
+ }
+
+ /* Check if the list already exists, if not create it.
+ * Create a new invite and add it to the list.. ~ Viper */
+ if (!chan->invites)
+ chan->invites = list_create();
+ invite = entry_add(chan->invites, mask);
+
+ if (!invite)
+ fatal("Creating new exception entry failed");
+
+ if (debug)
+ alog("debug: Added invite %s to channel %s", mask, chan->name);
+ +} + +/** Remove an invex from the channel + * @param chan The channel + * @param mask The index + */ +void ChannelModeInvite::DelMask(Channel *chan, const char *mask) +{ + Entry *invite;
+
+ /* Sanity check as it seems some IRCD will just send -I without a mask */
+ if (!mask || !chan->invites || (chan->invites->count == 0))
+ return;
+
+ invite = elist_find_mask(chan->invites, mask);
+
+ if (invite)
+ {
+ entry_delete(chan->invites, invite);
+
+ if (debug)
+ alog("debug: Deleted invite %s to channel %s", mask,
+ chan->name);
+ } +} diff --git a/src/modules.c b/src/modules.c index b7af6acf5..1757cfcef 100644 --- a/src/modules.c +++ b/src/modules.c @@ -732,64 +732,6 @@ bool moduleMinVersion(int major, int minor, int patch, int build) return ret; } -/** - * Allow ircd protocol files to update the protect level info tables. - **/ -void updateProtectDetails(const char *level_info_protect_word, - const char *level_info_protectme_word, - const char *fant_protect_add, const char *fant_protect_del, - const char *level_protect_word, const char *protect_set_mode, - const char *protect_unset_mode) -{ - int i = 0; - CSModeUtil ptr; - LevelInfo l_ptr; - - ptr = csmodeutils[i]; - while (ptr.name) { - if (strcmp(ptr.name, "PROTECT") == 0) { - csmodeutils[i].bsname = sstrdup(fant_protect_add); - csmodeutils[i].mode = sstrdup(protect_set_mode); - } else if (strcmp(ptr.name, "DEPROTECT") == 0) { - csmodeutils[i].bsname = sstrdup(fant_protect_del); - csmodeutils[i].mode = sstrdup(protect_unset_mode); - } - ptr = csmodeutils[++i]; - } - - i = 0; - l_ptr = levelinfo[i]; - while (l_ptr.what != -1) { - if (l_ptr.what == CA_PROTECT) { - levelinfo[i].name = sstrdup(level_info_protect_word); - } else if (l_ptr.what == CA_PROTECTME) { - levelinfo[i].name = sstrdup(level_info_protectme_word); - } else if (l_ptr.what == CA_AUTOPROTECT) { - levelinfo[i].name = sstrdup(level_protect_word); - } - l_ptr = levelinfo[++i]; - } -} - -void updateOwnerDetails(const char *fant_owner_add, const char *fant_owner_del, const char *owner_set_mode, const char *owner_del_mode) -{ - CSModeUtil ptr; - int i = 0; - - ptr = csmodeutils[i]; - while (ptr.name) { - if (!strcmp(ptr.name, "OWNER")) { - csmodeutils[i].bsname = sstrdup(fant_owner_add); - csmodeutils[i].mode = sstrdup(owner_set_mode); - } - else if (!strcmp(ptr.name, "DEOWNER")) { - csmodeutils[i].bsname = sstrdup(fant_owner_del); - csmodeutils[i].mode = sstrdup(owner_del_mode); - } - ptr = csmodeutils[++i]; - } -} - void Module::NoticeLang(char *source, User * u, int number, ...) { va_list va; diff --git a/src/modules/cs_enforce.c b/src/modules/cs_enforce.c index 2c3a09dea..65807c6e4 100644 --- a/src/modules/cs_enforce.c +++ b/src/modules/cs_enforce.c @@ -47,9 +47,7 @@ class CommandCSEnforce : public Command void DoModes(Channel *c) { - CBMode *cbm; - - if ((cbm = &cbmodes[static_cast<int>('R')])->flag && (c->mode & cbm->flag)) + if (c->HasMode(CMODE_REGISTEREDONLY)) this->DoCModeR(c); } @@ -140,7 +138,6 @@ class CommandCSEnforce : public Command const char *reason; const char *av[3]; User *u; - CBMode *cbm; if (!(ci = c->ci)) return; @@ -159,7 +156,7 @@ class CommandCSEnforce : public Command get_idealban(ci, u, mask, sizeof(mask)); av[1] = mask; reason = getstring(u, CHAN_NOT_ALLOWED_TO_JOIN); - if (!(cbm = &cbmodes[static_cast<int>('R')])->flag || !(c->mode & cbm->flag)) + if (!c->HasMode(CMODE_REGISTERED)) { ircdproto->SendMode(whosends(ci), ci->name, "+b %s %lu", mask, time(NULL)); chan_set_modes(s_ChanServ, c, 2, av, 1); @@ -234,7 +231,7 @@ class CommandCSEnforce : public Command ircdproto->SendMessage(findbot(s_ChanServ), u->nick, " "); me->NoticeLang(s_ChanServ, u, LNG_CHAN_HELP_ENFORCE); ircdproto->SendMessage(findbot(s_ChanServ), u->nick, " "); - if (cbmodes[static_cast<int>('R')].flag) + if (ModeManager::FindChannelModeByName(CMODE_REGISTERED)) me->NoticeLang(s_ChanServ, u, LNG_CHAN_HELP_ENFORCE_R_ENABLED); else me->NoticeLang(s_ChanServ, u, LNG_CHAN_HELP_ENFORCE_R_DISABLED); diff --git a/src/modules/cs_tban.c b/src/modules/cs_tban.c index 78b1b5fbf..e0ab66db4 100644 --- a/src/modules/cs_tban.c +++ b/src/modules/cs_tban.c @@ -214,9 +214,9 @@ int canBanUser(Channel * c, User * u, User * u2) int ok = 0; if (!check_access(u, ci, CA_BAN)) notice_lang(s_ChanServ, u, ACCESS_DENIED); - else if (ircd->except && is_excepted(ci, u2)) + else if (is_excepted(ci, u2)) notice_lang(s_ChanServ, u, CHAN_EXCEPTED, u2->nick, ci->name); - else if (ircd->protectedumode && is_protected(u2)) + else if (is_protected(u2)) notice_lang(s_ChanServ, u, ACCESS_DENIED); else ok = 1; diff --git a/src/nickserv.c b/src/nickserv.c index a20a0b8b1..110c52e29 100644 --- a/src/nickserv.c +++ b/src/nickserv.c @@ -1408,7 +1408,7 @@ int should_mode_change(int16 status, int16 mode) return 1; break; case CUS_OWNER: - if (ircd->owner) + if (ModeManager::FindChannelModeByName(CMODE_OWNER)) { if (status & CUS_OWNER) { @@ -1417,7 +1417,7 @@ int should_mode_change(int16 status, int16 mode) } break; case CUS_PROTECT: - if (ircd->protect) + if (ModeManager::FindChannelModeByName(CMODE_PROTECT)) { if (status & CUS_PROTECT) { diff --git a/src/operserv.c b/src/operserv.c index 754da67ef..84c5dd366 100644 --- a/src/operserv.c +++ b/src/operserv.c @@ -1275,17 +1275,14 @@ int defconParseModeString(const char *str) { int add = -1; /* 1 if adding, 0 if deleting, -1 if neither */ unsigned char mode; - CBMode *cbm; + ChannelMode *cm; + ChannelModeParam *cmp; char *str_copy = sstrdup(str); /* We need this copy as str is const -GD */ char *param; /* Store parameters during mode parsing */ /* Reinitialize everything */ DefConModesOn = 0; DefConModesOff = 0; - DefConModesCI.mlock_limit = 0; - DefConModesCI.mlock_key = NULL; - DefConModesCI.mlock_flood = NULL; - DefConModesCI.mlock_redirect = NULL; /* Initialize strtok() internal buffer */ strtok(str_copy, " "); @@ -1304,32 +1301,55 @@ int defconParseModeString(const char *str) continue; } - if (static_cast<int>(mode) < 128 && (cbm = &cbmodes[static_cast<int>(mode)])->flag != 0) { - if (cbm->flags & CBM_NO_MLOCK) { - alog("DefConChanModes mode character '%c' cannot be locked", mode); + if ((cm = ModeManager::FindChannelModeByChar(mode))) + { + if (!cm->CanSet(NULL)) + { + alog("DefConCHanModes mode character '%c' cannot be locked", mode); delete [] str_copy; return 0; - } else if (add) { - DefConModesOn |= cbm->flag; - DefConModesOff &= ~cbm->flag; - if (cbm->cssetvalue) { - if (!(param = strtok(NULL, " "))) { + } + else if (add) + { + DefConModesCI.SetMLock(cm->Name, true); + DefConModesCI.RemoveMLock(cm->Name, false); + + if (cm->Type == MODE_PARAM) + { + cmp = static_cast<ChannelModeParam *>(cm); + + if (!(param = strtok(NULL, " "))) + { alog("DefConChanModes mode character '%c' has no parameter while one is expected", mode); delete [] str_copy; return 0; } - cbm->cssetvalue(&DefConModesCI, param); + + if (!cmp->IsValid(param)) + continue; + + DefConModesCI.SetParam(cmp->Name, param); } - } else { - DefConModesOff |= cbm->flag; - if (DefConModesOn & cbm->flag) { - DefConModesOn &= ~cbm->flag; - if (cbm->cssetvalue) { - cbm->cssetvalue(&DefConModesCI, NULL); + } + else + { + DefConModesCI.RemoveMLock(cm->Name, true); + + if (DefConModesCI.HasMLock(cm->Name, true)) + { + DefConModesCI.RemoveMLock(cm->Name, true); + + if (cm->Type == MODE_PARAM) + { + cmp = static_cast<ChannelModeParam *>(cm); + + DefConModesCI.UnsetParam(cmp->Name); } } } - } else { + } + else + { alog("DefConChanModes unknown mode character '%c'", mode); delete [] str_copy; return 0; @@ -1338,13 +1358,13 @@ int defconParseModeString(const char *str) delete [] str_copy; - if (ircd->Lmode) { + if ((cm = ModeManager::FindChannelModeByName(CMODE_REDIRECT))) + { /* We can't mlock +L if +l is not mlocked as well. */ - if ((DefConModesOn & ircd->chan_lmode) - && !(DefConModesOn & anope_get_limit_mode())) { - DefConModesOn &= ~ircd->chan_lmode; - delete [] DefConModesCI.mlock_redirect; - DefConModesCI.mlock_redirect = NULL; + if (DefConModesCI.HasMLock(cm->Name, true) && !DefConModesCI.HasMLock(CMODE_LIMIT, true)) + { + DefConModesCI.RemoveMLock(CMODE_REDIRECT, true); + DefConModesCI.UnsetParam(CMODE_REDIRECT); alog("DefConChanModes must lock mode +l as well to lock mode +L"); return 0; } @@ -1352,10 +1372,11 @@ int defconParseModeString(const char *str) /* Some ircd we can't set NOKNOCK without INVITE */ /* So check if we need there is a NOKNOCK MODE and that we need INVITEONLY */ - if (ircd->noknock && ircd->knock_needs_i) { - if ((DefConModesOn & ircd->noknock) - && !(DefConModesOn & anope_get_invite_mode())) { - DefConModesOn &= ~ircd->noknock; + if (ircd->knock_needs_i && (cm = ModeManager::FindChannelModeByName(CMODE_NOKNOCK))) + { + if (DefConModesCI.HasMLock(cm->Name, true) && !DefConModesCI.HasMLock(CMODE_INVITE, true)) + { + DefConModesCI.RemoveMLock(CMODE_NOKNOCK, true); alog("DefConChanModes must lock mode +i as well to lock mode +K"); return 0; } diff --git a/src/protocol/bahamut.c b/src/protocol/bahamut.c index 5aa704100..143cb07a0 100644 --- a/src/protocol/bahamut.c +++ b/src/protocol/bahamut.c @@ -16,85 +16,26 @@ #include "services.h" #include "pseudo.h" -#define UMODE_a 0x00000001 /* umode +a - Services Admin */ -#define UMODE_h 0x00000002 /* umode +h - Helper */ -#define UMODE_i 0x00000004 /* umode +i - Invisible */ -#define UMODE_o 0x00000008 /* umode +o - Oper */ -#define UMODE_r 0x00000010 /* umode +r - registered nick */ -#define UMODE_w 0x00000020 /* umode +w - Get wallops */ -#define UMODE_A 0x00000040 /* umode +A - Server Admin */ -#define UMODE_x 0x00000080 /* umode +x - Squelch with notice */ -#define UMODE_X 0x00000100 /* umode +X - Squelch without notice */ -#define UMODE_F 0x00000200 /* umode +F - no cptr->since message rate throttle */ -#define UMODE_j 0x00000400 /* umode +j - client rejection notices */ -#define UMODE_K 0x00000800 /* umode +K - U: lined server kill messages */ -#define UMODE_O 0x00001000 /* umode +O - Local Oper */ -#define UMODE_s 0x00002000 /* umode +s - Server notices */ -#define UMODE_c 0x00004000 /* umode +c - Client connections/exits */ -#define UMODE_k 0x00008000 /* umode +k - Server kill messages */ -#define UMODE_f 0x00010000 /* umode +f - Server flood messages */ -#define UMODE_y 0x00020000 /* umode +y - Stats/links */ -#define UMODE_d 0x00040000 /* umode +d - Debug info */ -#define UMODE_g 0x00080000 /* umode +g - Globops */ -#define UMODE_b 0x00100000 /* umode +b - Chatops */ -#define UMODE_n 0x00200000 /* umode +n - Routing Notices */ -#define UMODE_m 0x00400000 /* umode +m - spambot notices */ -#define UMODE_e 0x00800000 /* umode +e - oper notices for the above +D */ -#define UMODE_D 0x01000000 /* umode +D - Hidden dccallow umode */ -#define UMODE_I 0x02000000 /* umode +I - invisible oper (masked) */ -#define UMODE_R 0x80000000 /* unmode +R - No non registered msgs */ - -#define CMODE_i 0x00000001 -#define CMODE_m 0x00000002 -#define CMODE_n 0x00000004 -#define CMODE_p 0x00000008 -#define CMODE_s 0x00000010 -#define CMODE_t 0x00000020 -#define CMODE_k 0x00000040 /* These two used only by ChanServ */ -#define CMODE_l 0x00000080 -#define CMODE_R 0x00000100 /* Only identified users can join */ -#define CMODE_r 0x00000200 /* Set for all registered channels */ -#define CMODE_c 0x00000400 /* Colors can't be used */ -#define CMODE_M 0x00000800 /* Non-regged nicks can't send messages */ -#define CMODE_j 0x00001000 /* join throttle */ -#define CMODE_O 0x00008000 /* Only opers can join */ - -#define DEFAULT_MLOCK CMODE_n | CMODE_t | CMODE_r - - IRCDVar myIrcd[] = { {"Bahamut 1.8.x", /* ircd name */ "+", /* Modes used by pseudoclients */ 2, /* Chan Max Symbols */ - "-cilmnpstOR", /* Modes to Remove */ "+o", /* Channel Umode used by Botserv bots */ 1, /* SVSNICK */ 0, /* Vhost */ - 0, /* Has Owner */ - NULL, /* Mode to set for an owner */ - NULL, /* Mode to unset for an owner */ - NULL, /* Mode to set for channel admin */ - NULL, /* Mode to unset for channel admin */ "-r+d", /* Mode on UnReg */ 1, /* Supports SGlines */ 1, /* Supports SQlines */ 1, /* Supports SZlines */ - 0, /* Supports Halfop +h */ 3, /* Number of server args */ 0, /* Join 2 Set */ 0, /* Join 2 Message */ - 1, /* Has exceptions +e */ 0, /* TS Topic Forward */ 0, /* TS Topci Backward */ - 0, /* Protected Umode */ - 0, /* Has Admin */ 1, /* Chan SQlines */ 1, /* Quit on Kill */ 1, /* SVSMODE unban */ - 0, /* Has Protect */ 0, /* Reverse */ - 1, /* Chan Reg */ - CMODE_r, /* Channel Mode */ 0, /* vidents */ 1, /* svshold */ 1, /* time stamp on mode */ @@ -103,28 +44,18 @@ IRCDVar myIrcd[] = { 1, /* UMODE */ 0, /* VHOST ON NICK */ 0, /* Change RealName */ - 0, /* No Knock */ - 0, /* Admin Only */ - DEFAULT_MLOCK, /* Default MLOCK */ - 0, /* Vhost Mode */ - 1, /* +f */ - 0, /* +L */ - CMODE_j, /* Mode */ - 0, /* Mode */ + 0, 1, 1, /* No Knock requires +i */ NULL, /* CAPAB Chan Modes */ 0, /* We support TOKENS */ 0, /* TIME STAMPS are BASE64 */ - 1, /* +I support */ 0, /* SJOIN ban char */ 0, /* SJOIN except char */ 0, /* SJOIN invite char */ 0, /* Can remove User Channel Modes with SVSMODE */ 0, /* Sglines are not enforced until user reconnects */ - NULL, /* vhost char */ 0, /* ts6 */ - 1, /* support helper umode */ 0, /* p10 */ NULL, /* character set */ 0, /* CIDR channelbans */ @@ -168,258 +99,6 @@ IRCDCAPAB myIrcdcap[] = { }; -unsigned long umodes[128] = { - 0, 0, 0, /* Unused */ - 0, 0, 0, /* Unused */ - 0, 0, 0, /* Unused, Unused, Horzontal Tab */ - 0, 0, 0, /* Line Feed, Unused, Unused */ - 0, 0, 0, /* Carriage Return, Unused, Unused */ - 0, 0, 0, /* Unused */ - 0, 0, 0, /* Unused */ - 0, 0, 0, /* Unused */ - 0, 0, 0, /* Unused */ - 0, 0, 0, /* Unused */ - 0, 0, 0, /* Unused, Unused, Space */ - 0, 0, 0, /* ! " # */ - 0, 0, 0, /* $ % & */ - 0, 0, 0, /* ! ( ) */ - 0, 0, 0, /* * + , */ - 0, 0, 0, /* - . / */ - 0, 0, /* 0 1 */ - 0, 0, /* 2 3 */ - 0, 0, /* 4 5 */ - 0, 0, /* 6 7 */ - 0, 0, /* 8 9 */ - 0, 0, /* : ; */ - 0, 0, 0, /* < = > */ - 0, 0, /* ? @ */ - UMODE_A, 0, 0, /* A B C */ - UMODE_D, 0, UMODE_F, /* D E F */ - 0, 0, UMODE_I, /* G H I */ - 0, UMODE_K, 0, /* J K L */ - 0, 0, UMODE_O, /* M N O */ - 0, 0, UMODE_R, /* P Q R */ - 0, 0, 0, /* S T U */ - 0, 0, UMODE_X, /* V W X */ - 0, /* Y */ - 0, /* Z */ - 0, 0, 0, /* [ \ ] */ - 0, 0, 0, /* ^ _ ` */ - UMODE_a, UMODE_b, UMODE_c, /* a b c */ - UMODE_d, UMODE_e, UMODE_f, /* d e f */ - UMODE_g, UMODE_h, UMODE_i, /* g h i */ - UMODE_j, UMODE_k, 0, /* j k l */ - UMODE_m, UMODE_n, UMODE_o, /* m n o */ - 0, 0, UMODE_r, /* p q r */ - UMODE_s, 0, 0, /* s t u */ - 0, UMODE_w, UMODE_x, /* v w x */ - UMODE_y, /* y */ - 0, /* z */ - 0, 0, 0, /* { | } */ - 0, 0 /* ~ � */ -}; - -char myCsmodes[128] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - 0, - 0, - 0, 0, 0, - 0, - 0, 0, 0, 0, - 0, - - 'v', 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - 'o', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - - -CMMode myCmmodes[128] = { - {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, /* BCD */ - {NULL}, {NULL}, {NULL}, /* EFG */ - {NULL}, /* H */ - {add_invite, del_invite}, /* I */ - {NULL}, /* J */ - {NULL}, {NULL}, {NULL}, /* KLM */ - {NULL}, {NULL}, {NULL}, /* NOP */ - {NULL}, {NULL}, {NULL}, /* QRS */ - {NULL}, {NULL}, {NULL}, /* TUV */ - {NULL}, {NULL}, {NULL}, /* WXY */ - {NULL}, /* Z */ - {NULL}, {NULL}, /* (char 91 - 92) */ - {NULL}, {NULL}, {NULL}, /* (char 93 - 95) */ - {NULL}, /* ` (char 96) */ - {NULL}, /* a (char 97) */ - {add_ban, del_ban}, /* b */ - {NULL}, {NULL}, /* cd */ - {add_exception, del_exception}, - {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL} -}; - -CBMode myCbmodes[128] = { - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, - {0}, /* A */ - {0}, /* B */ - {0}, /* C */ - {0}, /* D */ - {0}, /* E */ - {0}, /* F */ - {0}, /* G */ - {0}, /* H */ - {0}, /* I */ - {0}, /* J */ - {0}, /* K */ - {0}, /* L */ - {CMODE_M, 0, NULL, NULL}, /* M */ - {0}, /* N */ - {CMODE_O, CBM_NO_USER_MLOCK, NULL, NULL}, - {0}, /* P */ - {0}, /* Q */ - {CMODE_R, 0, NULL, NULL}, /* R */ - {0}, /* S */ - {0}, /* T */ - {0}, /* U */ - {0}, /* V */ - {0}, /* W */ - {0}, /* X */ - {0}, /* Y */ - {0}, /* Z */ - {0}, {0}, {0}, {0}, {0}, {0}, - {0}, /* a */ - {0}, /* b */ - {CMODE_c, 0, NULL, NULL}, - {0}, /* d */ - {0}, /* e */ - {0}, /* f */ - {0}, /* g */ - {0}, /* h */ - {CMODE_i, 0, NULL, NULL}, - {CMODE_j, 0, set_flood, cs_set_flood}, /* j */ - {CMODE_k, 0, chan_set_key, cs_set_key}, - {CMODE_l, CBM_MINUS_NO_ARG, set_limit, cs_set_limit}, - {CMODE_m, 0, NULL, NULL}, - {CMODE_n, 0, NULL, NULL}, - {0}, /* o */ - {CMODE_p, 0, NULL, NULL}, - {0}, /* q */ - {CMODE_r, CBM_NO_MLOCK, NULL, NULL}, - {CMODE_s, 0, NULL, NULL}, - {CMODE_t, 0, NULL, NULL}, - {0}, - {0}, /* v */ - {0}, /* w */ - {0}, /* x */ - {0}, /* y */ - {0}, /* z */ - {0}, {0}, {0}, {0} -}; - -CBModeInfo myCbmodeinfos[] = { - {'c', CMODE_c, 0, NULL, NULL}, - {'i', CMODE_i, 0, NULL, NULL}, - {'j', CMODE_j, 0, get_flood, cs_get_flood}, - {'k', CMODE_k, 0, get_key, cs_get_key}, - {'l', CMODE_l, CBM_MINUS_NO_ARG, get_limit, cs_get_limit}, - {'m', CMODE_m, 0, NULL, NULL}, - {'n', CMODE_n, 0, NULL, NULL}, - {'p', CMODE_p, 0, NULL, NULL}, - {'r', CMODE_r, 0, NULL, NULL}, - {'s', CMODE_s, 0, NULL, NULL}, - {'t', CMODE_t, 0, NULL, NULL}, - {'M', CMODE_M, 0, NULL, NULL}, - {'O', CMODE_O, 0, NULL, NULL}, - {'R', CMODE_R, 0, NULL, NULL}, - {0} -}; - -CUMode myCumodes[128] = { - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - - {0}, - {0}, /* a */ - {0}, /* b */ - {0}, /* c */ - {0}, /* d */ - {0}, /* e */ - {0}, /* f */ - {0}, /* g */ - {0}, /* h */ - {0}, /* i */ - {0}, /* j */ - {0}, /* k */ - {0}, /* l */ - {0}, /* m */ - {0}, /* n */ - {CUS_OP, CUF_PROTECT_BOTSERV, check_valid_op}, - {0}, /* p */ - {0}, /* q */ - {0}, /* r */ - {0}, /* s */ - {0}, /* t */ - {0}, /* u */ - {CUS_VOICE, 0, NULL}, - {0}, /* w */ - {0}, /* x */ - {0}, /* y */ - {0}, /* z */ - {0}, {0}, {0}, {0}, {0} -}; - - - void bahamut_cmd_burst() { send_cmd(NULL, "BURST"); @@ -471,10 +150,11 @@ class BahamutIRCdProto : public IRCDProto --ac; if (debug) alog("debug: Changing mode for %s to %s", user->nick, modes); while (*modes) { - /* This looks better, much better than "add ? (do_add) : (do_remove)". - * At least this is readable without paying much attention :) -GD */ - if (add) user->mode |= umodes[static_cast<int>(*modes)]; - else user->mode &= ~umodes[static_cast<int>(*modes)]; + if (add) + user->SetMode(*modes); + else + user->RemoveMode(*modes); + switch (*modes++) { case '+': add = 1; @@ -501,7 +181,7 @@ class BahamutIRCdProto : public IRCDProto case 'r': if (add && !nick_identified(user)) { common_svsmode(user, "-r", NULL); - user->mode &= ~UMODE_r; + user->RemoveMode(CMODE_REGISTERED); } } } @@ -685,13 +365,6 @@ class BahamutIRCdProto : public IRCDProto common_svsmode(u, "+d", "1"); } - int IsFloodModeParamValid(const char *value) - { - char *dp, *end; - if (value && *value != ':' && strtoul((*value == '*' ? value + 1 : value), &dp, 10) > 0 && *dp == ':' && *(++dp) && strtoul(dp, &end, 10) > 0 && !*end) return 1; - else return 0; - } - /* SERVER */ void SendServer(Server *server) { @@ -999,14 +672,18 @@ int anope_event_burst(const char *source, int ac, const char **av) return MOD_CONT; } +bool ChannelModeFlood::IsValid(const char *value) +{ + char *dp, *end; -/* *INDENT-OFF* */ -void moduleAddIRCDMsgs() { - Message *m; + if (value && *value != ':' && strtoul((*value == '*' ? value + 1 : value), &dp, 10) > 0 && *dp == ':' && *(++dp) && strtoul(dp, &end, 10) > 0 && !*end) + return true; + return false; +} - /* first update the cs protect info about this ircd */ - updateProtectDetails("PROTECT","PROTECTME","protect","deprotect","AUTOPROTECT","+","-"); +void moduleAddIRCDMsgs() { + Message *m; /* now add the commands */ m = createMessage("436", anope_event_436); addCoreMessage(IRCD,m); @@ -1037,7 +714,41 @@ void moduleAddIRCDMsgs() { m = createMessage("BURST", anope_event_burst); addCoreMessage(IRCD,m); } -/* *INDENT-ON* */ +void moduleAddModes() +{ + /* Add user modes */ + ModeManager::AddUserMode('A', new UserMode(UMODE_SERV_ADMIN)); + ModeManager::AddUserMode('R', new UserMode(UMODE_REGPRIV)); + ModeManager::AddUserMode('a', new UserMode(UMODE_ADMIN)); + ModeManager::AddUserMode('i', new UserMode(UMODE_INVIS)); + ModeManager::AddUserMode('o', new UserMode(UMODE_OPER)); + ModeManager::AddUserMode('r', new UserMode(UMODE_REGISTERED)); + ModeManager::AddUserMode('s', new UserMode(UMODE_SNOMASK)); + ModeManager::AddUserMode('w', new UserMode(UMODE_WALLOPS)); + + /* b/e/I */ + ModeManager::AddChannelMode('b', new ChannelModeBan()); + + /* v/h/o/a/q */ + ModeManager::AddChannelMode('v', new ChannelModeStatus(CMODE_VOICE, CUS_VOICE, '+')); + ModeManager::AddChannelMode('o', new ChannelModeStatus(CMODE_OP, CUS_OP, '@', true)); + + /* Add channel modes */ + ModeManager::AddChannelMode('c', new ChannelMode(CMODE_BLOCKCOLOR)); + ModeManager::AddChannelMode('i', new ChannelMode(CMODE_INVITE)); + ModeManager::AddChannelMode('j', new ChannelModeFlood()); + ModeManager::AddChannelMode('k', new ChannelModeKey()); + ModeManager::AddChannelMode('l', new ChannelModeParam(CMODE_LIMIT)); + ModeManager::AddChannelMode('m', new ChannelMode(CMODE_MODERATED)); + ModeManager::AddChannelMode('n', new ChannelMode(CMODE_NOEXTERNAL)); + ModeManager::AddChannelMode('p', new ChannelMode(CMODE_PRIVATE)); + ModeManager::AddChannelMode('r', new ChannelModeRegistered()); + ModeManager::AddChannelMode('s', new ChannelMode(CMODE_SECRET)); + ModeManager::AddChannelMode('t', new ChannelMode(CMODE_TOPIC)); + ModeManager::AddChannelMode('M', new ChannelMode(CMODE_REGMODERATED)); + ModeManager::AddChannelMode('O', new ChannelModeOper()); + ModeManager::AddChannelMode('R', new ChannelMode(CMODE_REGISTEREDONLY)); +} class ProtoBahamut : public Module { @@ -1051,23 +762,13 @@ class ProtoBahamut : public Module pmodule_ircd_version("BahamutIRCd 1.4.*/1.8.*"); pmodule_ircd_cap(myIrcdcap); pmodule_ircd_var(myIrcd); - pmodule_ircd_cbmodeinfos(myCbmodeinfos); - pmodule_ircd_cumodes(myCumodes); - pmodule_ircd_flood_mode_char_set("+j"); - pmodule_ircd_flood_mode_char_remove("-j"); - pmodule_ircd_cbmodes(myCbmodes); - pmodule_ircd_cmmodes(myCmmodes); - pmodule_ircd_csmodes(myCsmodes); pmodule_ircd_useTSMode(0); - /** Deal with modes anope _needs_ to know **/ - pmodule_invis_umode(UMODE_i); - pmodule_oper_umode(UMODE_o); - pmodule_invite_cmode(CMODE_i); - pmodule_secret_cmode(CMODE_s); - pmodule_private_cmode(CMODE_p); - pmodule_key_mode(CMODE_k); - pmodule_limit_mode(CMODE_l); + moduleAddModes(); + + ircd->DefMLock[(size_t)CMODE_NOEXTERNAL] = true; + ircd->DefMLock[(size_t)CMODE_TOPIC] = true; + ircd->DefMLock[(size_t)CMODE_REGISTERED] = true; pmodule_ircd_proto(&ircd_proto); moduleAddIRCDMsgs(); diff --git a/src/protocol/inspircd11.c b/src/protocol/inspircd11.c index 93574f8df..7d2044706 100644 --- a/src/protocol/inspircd11.c +++ b/src/protocol/inspircd11.c @@ -17,44 +17,6 @@ #include "pseudo.h" #include "hashcomp.h" -#define UMODE_a 0x00000001 -#define UMODE_h 0x00000002 -#define UMODE_i 0x00000004 -#define UMODE_o 0x00000008 -#define UMODE_r 0x00000010 -#define UMODE_w 0x00000020 -#define UMODE_A 0x00000040 -#define UMODE_g 0x80000000 -#define UMODE_x 0x40000000 - -#define CMODE_i 0x00000001 -#define CMODE_m 0x00000002 -#define CMODE_n 0x00000004 -#define CMODE_p 0x00000008 -#define CMODE_s 0x00000010 -#define CMODE_t 0x00000020 -#define CMODE_k 0x00000040 /* These two used only by ChanServ */ -#define CMODE_l 0x00000080 -#define CMODE_c 0x00000400 -#define CMODE_A 0x00000800 -#define CMODE_H 0x00001000 -#define CMODE_K 0x00002000 -#define CMODE_L 0x00004000 -#define CMODE_O 0x00008000 -#define CMODE_Q 0x00010000 -#define CMODE_S 0x00020000 -#define CMODE_V 0x00040000 -#define CMODE_f 0x00080000 -#define CMODE_G 0x00100000 -#define CMODE_C 0x00200000 -#define CMODE_u 0x00400000 -#define CMODE_z 0x00800000 -#define CMODE_N 0x01000000 -#define CMODE_R 0x00000100 /* Only identified users can join */ -#define CMODE_r 0x00000200 /* Set for all registered channels */ - -#define DEFAULT_MLOCK CMODE_n | CMODE_t | CMODE_r - #ifndef _WIN32 #include <sys/socket.h> #include <netinet/in.h> @@ -75,35 +37,22 @@ IRCDVar myIrcd[] = { {"InspIRCd 1.1", /* ircd name */ "+I", /* Modes used by pseudoclients */ 5, /* Chan Max Symbols */ - "-cilmnpstuzACGHKNOQRSV", /* Modes to Remove */ "+ao", /* Channel Umode used by Botserv bots */ 1, /* SVSNICK */ 1, /* Vhost */ - 1, /* Has Owner */ - "+q", /* Mode to set for an owner */ - "-q", /* Mode to unset for an owner */ - "+a", /* Mode to set for channel admin */ - "-a", /* Mode to unset for channel admin */ "-r", /* Mode on UnReg */ 1, /* Supports SGlines */ 1, /* Supports SQlines */ 1, /* Supports SZlines */ - 1, /* Supports Halfop +h */ 4, /* Number of server args */ 0, /* Join 2 Set */ 1, /* Join 2 Message */ - 0, /* Has exceptions +e */ 1, /* TS Topic Forward */ 0, /* TS Topci Backward */ - 0, /* Protected Umode */ - 0, /* Has Admin */ 0, /* Chan SQlines */ 0, /* Quit on Kill */ 0, /* SVSMODE unban */ - 1, /* Has Protect */ 1, /* Reverse */ - 1, /* Chan Reg */ - CMODE_r, /* Channel Mode */ 1, /* vidents */ 1, /* svshold */ 0, /* time stamp on mode */ @@ -112,28 +61,18 @@ IRCDVar myIrcd[] = { 1, /* UMODE */ 1, /* VHOST ON NICK */ 0, /* Change RealName */ - CMODE_K, /* No Knock */ - 0, /* Admin Only */ - DEFAULT_MLOCK, /* Default MLOCK */ - UMODE_x, /* Vhost Mode */ - 0, /* +f */ - 1, /* +L */ - CMODE_f, - CMODE_L, + 0, 0, 1, /* No Knock requires +i */ NULL, /* CAPAB Chan Modes */ 0, /* We support inspircd TOKENS */ 0, /* TIME STAMPS are BASE64 */ - 0, /* +I support */ 0, /* SJOIN ban char */ 0, /* SJOIN except char */ 0, /* SJOIN invite char */ 0, /* Can remove User Channel Modes with SVSMODE */ 0, /* Sglines are not enforced until user reconnects */ - "x", /* vhost char */ 0, /* ts6 */ - 1, /* support helper umode */ 0, /* p10 */ NULL, /* character set */ 1, /* CIDR channelbans */ @@ -178,221 +117,6 @@ IRCDCAPAB myIrcdcap[] = { 0, 0} }; -unsigned long umodes[128] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, UMODE_A, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, - 0, - 0, - 0, 0, 0, 0, 0, 0, 0, - 0, - 0, 0, 0, 0, 0, - 0, UMODE_a, 0, 0, 0, 0, 0, - UMODE_g, - UMODE_h, UMODE_i, 0, 0, 0, 0, 0, UMODE_o, - 0, - 0, UMODE_r, 0, 0, 0, 0, UMODE_w, - UMODE_x, - 0, - 0, - 0, 0, 0, 0, 0 -}; - - -char myCsmodes[128] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - 0, - 0, - 0, 0, 0, - 'h', /* (37) % Channel halfops */ - 'a', - 0, 0, 0, 0, - - 'v', 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - 'o', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'q', 0 -}; - -CMMode myCmmodes[128] = { - {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, - {NULL}, - {NULL}, - {add_ban, del_ban}, - {NULL}, - {NULL}, - {NULL, NULL}, - {NULL}, - {NULL}, - {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL} -}; - - - -CBMode myCbmodes[128] = { - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, - {CMODE_A, CBM_NO_USER_MLOCK, NULL, NULL}, - {0}, /* B */ - {CMODE_C, 0, NULL, NULL}, /* C */ - {0}, /* D */ - {0}, /* E */ - {0}, /* F */ - {CMODE_G, 0, NULL, NULL}, /* G */ - {CMODE_H, CBM_NO_USER_MLOCK, NULL, NULL}, - {0}, /* I */ - {0}, /* J */ - {CMODE_K, 0, NULL, NULL}, /* K */ - {CMODE_L, 0, set_redirect, cs_set_redirect}, - {0}, /* M */ - {CMODE_N, 0, NULL, NULL}, /* N */ - {CMODE_O, CBM_NO_USER_MLOCK, NULL, NULL}, - {0}, /* P */ - {CMODE_Q, 0, NULL, NULL}, /* Q */ - {CMODE_R, 0, NULL, NULL}, /* R */ - {CMODE_S, 0, NULL, NULL}, /* S */ - {0}, /* T */ - {0}, /* U */ - {CMODE_V, 0, NULL, NULL}, /* V */ - {0}, /* W */ - {0}, /* X */ - {0}, /* Y */ - {0}, /* Z */ - {0}, {0}, {0}, {0}, {0}, {0}, - {0}, /* a */ - {0}, /* b */ - {CMODE_c, 0, NULL, NULL}, - {0}, /* d */ - {0}, /* e */ - {0}, /* f */ - {0}, /* g */ - {0}, /* h */ - {CMODE_i, 0, NULL, NULL}, - {0}, /* j */ - {CMODE_k, 0, chan_set_key, cs_set_key}, - {CMODE_l, CBM_MINUS_NO_ARG, set_limit, cs_set_limit}, - {CMODE_m, 0, NULL, NULL}, - {CMODE_n, 0, NULL, NULL}, - {0}, /* o */ - {CMODE_p, 0, NULL, NULL}, - {0}, /* q */ - {CMODE_r, CBM_NO_MLOCK, NULL, NULL}, - {CMODE_s, 0, NULL, NULL}, - {CMODE_t, 0, NULL, NULL}, - {CMODE_u, 0, NULL, NULL}, - {0}, /* v */ - {0}, /* w */ - {0}, /* x */ - {0}, /* y */ - {CMODE_z, 0, NULL, NULL}, - {0}, {0}, {0}, {0} -}; - -CBModeInfo myCbmodeinfos[] = { - {'f', CMODE_f, 0, NULL, NULL}, - {'c', CMODE_c, 0, NULL, NULL}, - {'i', CMODE_i, 0, NULL, NULL}, - {'k', CMODE_k, 0, get_key, cs_get_key}, - {'l', CMODE_l, CBM_MINUS_NO_ARG, get_limit, cs_get_limit}, - {'m', CMODE_m, 0, NULL, NULL}, - {'n', CMODE_n, 0, NULL, NULL}, - {'p', CMODE_p, 0, NULL, NULL}, - {'r', CMODE_r, 0, NULL, NULL}, - {'s', CMODE_s, 0, NULL, NULL}, - {'t', CMODE_t, 0, NULL, NULL}, - {'u', CMODE_u, 0, NULL, NULL}, - {'z', CMODE_z, 0, NULL, NULL}, - {'A', CMODE_A, 0, NULL, NULL}, - {'C', CMODE_C, 0, NULL, NULL}, - {'G', CMODE_G, 0, NULL, NULL}, - {'H', CMODE_H, 0, NULL, NULL}, - {'K', CMODE_K, 0, NULL, NULL}, - {'L', CMODE_L, 0, get_redirect, cs_get_redirect}, - {'N', CMODE_N, 0, NULL, NULL}, - {'O', CMODE_O, 0, NULL, NULL}, - {'Q', CMODE_Q, 0, NULL, NULL}, - {'R', CMODE_R, 0, NULL, NULL}, - {'S', CMODE_S, 0, NULL, NULL}, - {'V', CMODE_V, 0, NULL, NULL}, - {0} -}; - -CUMode myCumodes[128] = { - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - - {0}, - - {CUS_PROTECT, CUF_PROTECT_BOTSERV, check_valid_op}, - {0}, /* b */ - {0}, /* c */ - {0}, /* d */ - {0}, /* e */ - {0}, /* f */ - {0}, /* g */ - {CUS_HALFOP, 0, check_valid_op}, - {0}, /* i */ - {0}, /* j */ - {0}, /* k */ - {0}, /* l */ - {0}, /* m */ - {0}, /* n */ - {CUS_OP, CUF_PROTECT_BOTSERV, check_valid_op}, - {0}, /* p */ - {CUS_OWNER, 0, check_valid_op}, - {0}, /* r */ - {0}, /* s */ - {0}, /* t */ - {0}, /* u */ - {CUS_VOICE, 0, NULL}, - {0}, /* w */ - {0}, /* x */ - {0}, /* y */ - {0}, /* z */ - {0}, {0}, {0}, {0}, {0} -}; - static int has_servicesmod = 0; static int has_globopsmod = 0; static int has_svsholdmod = 0; @@ -444,10 +168,11 @@ class InspIRCdProto : public IRCDProto --ac; if (debug) alog("debug: Changing mode for %s to %s", user->nick, modes); while (*modes) { - /* This looks better, much better than "add ? (do_add) : (do_remove)". - * At least this is readable without paying much attention :) -GD */ - if (add) user->mode |= umodes[static_cast<int>(*modes)]; - else user->mode &= ~umodes[static_cast<int>(*modes)]; + if (add) + user->SetMode(*modes); + else + user->RemoveMode(*modes); + switch (*modes++) { case '+': add = 1; @@ -466,7 +191,7 @@ class InspIRCdProto : public IRCDProto case 'r': if (add && !nick_identified(user)) { common_svsmode(user, "-r", NULL); - user->mode &= ~UMODE_r; + user->RemoveMode(UMODE_REGISTERED); } break; case 'x': @@ -504,7 +229,10 @@ class InspIRCdProto : public IRCDProto void SendVhostDel(User *u) { - inspircd_cmd_chghost(u->nick, (u->mode & umodes[static_cast<int>('x')] ? u->GetCloakedHost().c_str() : u->host)); + if (u->HasMode(UMODE_CLOAK)) + inspircd_cmd_chghost(u->nick, u->chost.c_str()); + else + inspircd_cmd_chghost(u->nick, u->host); if (has_chgidentmod && u->GetIdent() != u->GetVIdent()) { @@ -683,13 +411,6 @@ class InspIRCdProto : public IRCDProto send_cmd(NULL, "ENDBURST"); } - int IsFloodModeParamValid(const char *value) - { - char *dp, *end; - if (value && *value != ':' && strtoul((*value == '*' ? value + 1 : value), &dp, 10) > 0 && *dp == ':' && *(++dp) && strtoul(dp, &end, 10) > 0 && !*end) return 1; - else return 0; - } - void SetAutoIdentificationToken(User *u) { char svidbuf[15], *c; @@ -1183,7 +904,6 @@ int anope_event_whois(const char *source, int ac, const char **av) int anope_event_capab(const char *source, int ac, const char **av) { int argc; - CBModeInfo *cbmi; if (strcasecmp(av[0], "START") == 0) { /* reset CAPAB */ @@ -1254,52 +974,16 @@ int anope_event_capab(const char *source, int ac, const char **av) ircdproto->SendGlobops(s_OperServ, "CHGIDENT missing, Usage disabled until module is loaded."); } if (has_messagefloodmod) { - cbmi = myCbmodeinfos; - - /* Find 'f' in myCbmodeinfos and add the relevant bits to myCbmodes and myCbmodeinfos - * to enable +f support if found. This is needed because we're really not set up to - * handle modular ircds which can have modes enabled/disabled as they please :( - mark - */ - while ((cbmi->mode != 'f')) { - cbmi++; - } - if (cbmi) { - cbmi->getvalue = get_flood; - cbmi->csgetvalue = cs_get_flood; - - myCbmodes[static_cast<int>('f')].flag = CMODE_f; - myCbmodes[static_cast<int>('f')].flags = 0; - myCbmodes[static_cast<int>('f')].setvalue = set_flood; - myCbmodes[static_cast<int>('f')].cssetvalue = cs_set_flood; - - pmodule_ircd_cbmodeinfos(myCbmodeinfos); - pmodule_ircd_cbmodes(myCbmodes); - - ircd->fmode = 1; - } - else { - alog("Support for channelmode +f can not be enabled"); - if (debug) { - alog("debug: 'f' missing from myCbmodeinfos"); - } - } + ModeManager::AddChannelMode('f', new ChannelModeFlood()); } if (has_banexceptionmod) { - myCmmodes[static_cast<int>('e')].addmask = add_exception; - myCmmodes[static_cast<int>('e')].delmask = del_exception; - ircd->except = 1; + ModeManager::AddChannelMode('e', new ChannelModeExcept()); } if (has_inviteexceptionmod) { - myCmmodes[static_cast<int>('I')].addmask = add_invite; - myCmmodes[static_cast<int>('I')].delmask = del_invite; - ircd->invitemode = 1; + ModeManager::AddChannelMode('e', new ChannelModeInvite()); } ircd->svshold = has_svsholdmod; - if (has_banexceptionmod || has_inviteexceptionmod) { - pmodule_ircd_cmmodes(myCmmodes); - } - /* Generate a fake capabs parsing call so things like NOQUIT work * fine. It's ugly, but it works.... */ @@ -1321,9 +1005,6 @@ int anope_event_endburst(const char *source, int ac, const char **av) void moduleAddIRCDMsgs() { Message *m; - updateProtectDetails("PROTECT","PROTECTME","protect","deprotect","AUTOPROTECT","+a","-a"); - updateOwnerDetails("OWNER", "DEOWNER", ircd->ownerset, ircd->ownerunset); - m = createMessage("ENDBURST", anope_event_endburst); addCoreMessage(IRCD, m); m = createMessage("436", anope_event_436); addCoreMessage(IRCD,m); m = createMessage("AWAY", anope_event_away); addCoreMessage(IRCD,m); @@ -1357,6 +1038,62 @@ void moduleAddIRCDMsgs() { m = createMessage("IDLE", anope_event_idle); addCoreMessage(IRCD,m); } +bool ChannelModeFlood::IsValid(const char *value) +{ + char *dp, *end; + + if (value && *value != ':' && strtoul((*value == '*' ? value + 1 : value), &dp, 10) > 0 && *dp == ':' && *(++dp) && strtoul(dp, &end, 10) > 0 && !*end) + return true; + + return false; +} + +void moduleAddModes() +{ + /* Add user modes */ + ModeManager::AddUserMode('g', new UserMode(UMODE_CALLERID)); + ModeManager::AddUserMode('h', new UserMode(UMODE_HELPOP)); + ModeManager::AddUserMode('i', new UserMode(UMODE_INVIS)); + ModeManager::AddUserMode('o', new UserMode(UMODE_OPER)); + ModeManager::AddUserMode('r', new UserMode(UMODE_REGISTERED)); + ModeManager::AddUserMode('w', new UserMode(UMODE_WALLOPS)); + ModeManager::AddUserMode('x', new UserMode(UMODE_CLOAK)); + + /* b/e/I */ + ModeManager::AddChannelMode('b', new ChannelModeBan()); + + /* v/h/o/a/q */ + ModeManager::AddChannelMode('v', new ChannelModeStatus(CMODE_VOICE, CUS_VOICE, '+')); + ModeManager::AddChannelMode('h', new ChannelModeStatus(CMODE_HALFOP, CUS_HALFOP, '%')); + ModeManager::AddChannelMode('o', new ChannelModeStatus(CMODE_OP, CUS_OP, '@', true)); + ModeManager::AddChannelMode('a', new ChannelModeStatus(CMODE_PROTECT, CUS_PROTECT, '&', true)); + ModeManager::AddChannelMode('q', new ChannelModeStatus(CMODE_OWNER, CUS_OWNER, '~')); + + /* Add channel modes */ + ModeManager::AddChannelMode('c', new ChannelMode(CMODE_BLOCKCOLOR)); + ModeManager::AddChannelMode('i', new ChannelMode(CMODE_INVITE)); + ModeManager::AddChannelMode('k', new ChannelModeKey()); + ModeManager::AddChannelMode('l', new ChannelModeParam(CMODE_LIMIT)); + ModeManager::AddChannelMode('m', new ChannelMode(CMODE_MODERATED)); + ModeManager::AddChannelMode('n', new ChannelMode(CMODE_NOEXTERNAL)); + ModeManager::AddChannelMode('p', new ChannelMode(CMODE_PRIVATE)); + ModeManager::AddChannelMode('r', new ChannelModeRegistered()); + ModeManager::AddChannelMode('s', new ChannelMode(CMODE_SECRET)); + ModeManager::AddChannelMode('t', new ChannelMode(CMODE_TOPIC)); + ModeManager::AddChannelMode('u', new ChannelMode(CMODE_AUDITORIUM)); + ModeManager::AddChannelMode('z', new ChannelMode(CMODE_SSL)); + ModeManager::AddChannelMode('A', new ChannelMode(CMODE_ALLINVITE)); + ModeManager::AddChannelMode('C', new ChannelMode(CMODE_NOCTCP)); + ModeManager::AddChannelMode('G', new ChannelMode(CMODE_FILTER)); + ModeManager::AddChannelMode('K', new ChannelMode(CMODE_NOKNOCK)); + ModeManager::AddChannelMode('L', new ChannelModeParam(CMODE_REDIRECT)); + ModeManager::AddChannelMode('N', new ChannelMode(CMODE_NONICK)); + ModeManager::AddChannelMode('O', new ChannelModeOper()); + ModeManager::AddChannelMode('Q', new ChannelMode(CMODE_NOKICK)); + ModeManager::AddChannelMode('R', new ChannelMode(CMODE_REGISTEREDONLY)); + ModeManager::AddChannelMode('S', new ChannelMode(CMODE_STRIPCOLOR)); + ModeManager::AddChannelMode('V', new ChannelMode(CMODE_NOINVITE)); +} class ProtoInspIRCd : public Module { @@ -1370,23 +1107,13 @@ class ProtoInspIRCd : public Module pmodule_ircd_version("inspircdIRCd 1.1"); pmodule_ircd_cap(myIrcdcap); pmodule_ircd_var(myIrcd); - pmodule_ircd_cbmodeinfos(myCbmodeinfos); - pmodule_ircd_cumodes(myCumodes); - pmodule_ircd_flood_mode_char_set("+f"); - pmodule_ircd_flood_mode_char_remove("-f"); - pmodule_ircd_cbmodes(myCbmodes); - pmodule_ircd_cmmodes(myCmmodes); - pmodule_ircd_csmodes(myCsmodes); pmodule_ircd_useTSMode(0); - /** Deal with modes anope _needs_ to know **/ - pmodule_invis_umode(UMODE_i); - pmodule_oper_umode(UMODE_o); - pmodule_invite_cmode(CMODE_i); - pmodule_secret_cmode(CMODE_s); - pmodule_private_cmode(CMODE_p); - pmodule_key_mode(CMODE_k); - pmodule_limit_mode(CMODE_l); + moduleAddModes(); + + ircd->DefMLock[(size_t)CMODE_NOEXTERNAL] = true; + ircd->DefMLock[(size_t)CMODE_TOPIC] = true; + ircd->DefMLock[(size_t)CMODE_REGISTERED] = true; pmodule_ircd_proto(&ircd_proto); moduleAddIRCDMsgs(); diff --git a/src/protocol/inspircd12.cpp b/src/protocol/inspircd12.cpp index 09aeaa5ac..5545e2132 100644 --- a/src/protocol/inspircd12.cpp +++ b/src/protocol/inspircd12.cpp @@ -17,44 +17,6 @@ #include "pseudo.h" #include "hashcomp.h" -#define UMODE_a 0x00000001 -#define UMODE_h 0x00000002 -#define UMODE_i 0x00000004 -#define UMODE_o 0x00000008 -#define UMODE_r 0x00000010 -#define UMODE_w 0x00000020 -#define UMODE_A 0x00000040 -#define UMODE_g 0x80000000 -#define UMODE_x 0x40000000 - -#define CMODE_i 0x00000001 -#define CMODE_m 0x00000002 -#define CMODE_n 0x00000004 -#define CMODE_p 0x00000008 -#define CMODE_s 0x00000010 -#define CMODE_t 0x00000020 -#define CMODE_k 0x00000040 /* These two used only by ChanServ */ -#define CMODE_l 0x00000080 -#define CMODE_c 0x00000400 -#define CMODE_A 0x00000800 -#define CMODE_H 0x00001000 -#define CMODE_K 0x00002000 -#define CMODE_L 0x00004000 -#define CMODE_O 0x00008000 -#define CMODE_Q 0x00010000 -#define CMODE_S 0x00020000 -#define CMODE_V 0x00040000 -#define CMODE_f 0x00080000 -#define CMODE_G 0x00100000 -#define CMODE_C 0x00200000 -#define CMODE_u 0x00400000 -#define CMODE_z 0x00800000 -#define CMODE_N 0x01000000 -#define CMODE_R 0x00000100 /* Only identified users can join */ -#define CMODE_r 0x00000200 /* Set for all registered channels */ - -#define DEFAULT_MLOCK CMODE_n | CMODE_t | CMODE_r - #ifndef _WIN32 #include <sys/socket.h> #include <netinet/in.h> @@ -75,35 +37,22 @@ IRCDVar myIrcd[] = { {"InspIRCd 1.2", /* ircd name */ "+I", /* Modes used by pseudoclients */ 5, /* Chan Max Symbols */ - "-cilmnpstuzACGHKNOQRSV", /* Modes to Remove */ "+ao", /* Channel Umode used by Botserv bots */ 1, /* SVSNICK */ 1, /* Vhost */ - 1, /* Has Owner */ - "+q", /* Mode to set for an owner */ - "-q", /* Mode to unset for an owner */ - "+a", /* Mode to set for channel admin */ - "-a", /* Mode to unset for channel admin */ "-r", /* Mode on UnReg */ 0, /* Supports SGlines */ 1, /* Supports SQlines */ 1, /* Supports SZlines */ - 1, /* Supports Halfop +h */ 4, /* Number of server args */ 0, /* Join 2 Set */ 0, /* Join 2 Message */ - 0, /* Has exceptions +e */ 1, /* TS Topic Forward */ 0, /* TS Topci Backward */ - 0, /* Protected Umode */ - 0, /* Has Admin */ 0, /* Chan SQlines */ 0, /* Quit on Kill */ 0, /* SVSMODE unban */ - 1, /* Has Protect */ 1, /* Reverse */ - 1, /* Chan Reg */ - CMODE_r, /* Channel Mode */ 1, /* vidents */ 1, /* svshold */ 0, /* time stamp on mode */ @@ -112,28 +61,18 @@ IRCDVar myIrcd[] = { 1, /* UMODE */ 1, /* VHOST ON NICK */ 0, /* Change RealName */ - CMODE_K, /* No Knock */ - 0, /* Admin Only */ - DEFAULT_MLOCK, /* Default MLOCK */ - UMODE_x, /* Vhost Mode */ - 0, /* +f */ - 1, /* +L */ - CMODE_f, - CMODE_L, + 0, 0, 1, /* No Knock requires +i */ NULL, /* CAPAB Chan Modes */ 0, /* We support inspircd TOKENS */ 0, /* TIME STAMPS are BASE64 */ - 0, /* +I support */ 0, /* SJOIN ban char */ 0, /* SJOIN except char */ 0, /* SJOIN invite char */ 0, /* Can remove User Channel Modes with SVSMODE */ 0, /* Sglines are not enforced until user reconnects */ - "x", /* vhost char */ 1, /* ts6 */ - 1, /* support helper umode */ 0, /* p10 */ NULL, /* character set */ 1, /* CIDR channelbans */ @@ -178,221 +117,6 @@ IRCDCAPAB myIrcdcap[] = { 0, 0} }; -unsigned long umodes[128] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, UMODE_A, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, - 0, - 0, - 0, 0, 0, 0, 0, 0, 0, - 0, - 0, 0, 0, 0, 0, - 0, UMODE_a, 0, 0, 0, 0, 0, - UMODE_g, - UMODE_h, UMODE_i, 0, 0, 0, 0, 0, UMODE_o, - 0, - 0, UMODE_r, 0, 0, 0, 0, UMODE_w, - UMODE_x, - 0, - 0, - 0, 0, 0, 0, 0 -}; - - -char myCsmodes[128] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - 0, - 0, - 0, 0, 0, - 'h', /* (37) % Channel halfops */ - 'a', - 0, 0, 0, 0, - - 'v', 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - 'o', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'q', 0 -}; - -CMMode myCmmodes[128] = { - {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, - {NULL}, - {NULL}, - {add_ban, del_ban}, - {NULL}, - {NULL}, - {NULL, NULL}, - {NULL}, - {NULL}, - {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL} -}; - - - -CBMode myCbmodes[128] = { - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, - {CMODE_A, CBM_NO_USER_MLOCK, NULL, NULL}, - {0}, /* B */ - {CMODE_C, 0, NULL, NULL}, /* C */ - {0}, /* D */ - {0}, /* E */ - {0}, /* F */ - {CMODE_G, 0, NULL, NULL}, /* G */ - {CMODE_H, CBM_NO_USER_MLOCK, NULL, NULL}, - {0}, /* I */ - {0}, /* J */ - {CMODE_K, 0, NULL, NULL}, /* K */ - {CMODE_L, 0, set_redirect, cs_set_redirect}, - {0}, /* M */ - {CMODE_N, 0, NULL, NULL}, /* N */ - {CMODE_O, CBM_NO_USER_MLOCK, NULL, NULL}, - {0}, /* P */ - {CMODE_Q, 0, NULL, NULL}, /* Q */ - {CMODE_R, 0, NULL, NULL}, /* R */ - {CMODE_S, 0, NULL, NULL}, /* S */ - {0}, /* T */ - {0}, /* U */ - {CMODE_V, 0, NULL, NULL}, /* V */ - {0}, /* W */ - {0}, /* X */ - {0}, /* Y */ - {0}, /* Z */ - {0}, {0}, {0}, {0}, {0}, {0}, - {0}, /* a */ - {0}, /* b */ - {CMODE_c, 0, NULL, NULL}, - {0}, /* d */ - {0}, /* e */ - {0}, /* f */ - {0}, /* g */ - {0}, /* h */ - {CMODE_i, 0, NULL, NULL}, - {0}, /* j */ - {CMODE_k, 0, chan_set_key, cs_set_key}, - {CMODE_l, CBM_MINUS_NO_ARG, set_limit, cs_set_limit}, - {CMODE_m, 0, NULL, NULL}, - {CMODE_n, 0, NULL, NULL}, - {0}, /* o */ - {CMODE_p, 0, NULL, NULL}, - {0}, /* q */ - {CMODE_r, CBM_NO_MLOCK, NULL, NULL}, - {CMODE_s, 0, NULL, NULL}, - {CMODE_t, 0, NULL, NULL}, - {CMODE_u, 0, NULL, NULL}, - {0}, /* v */ - {0}, /* w */ - {0}, /* x */ - {0}, /* y */ - {CMODE_z, 0, NULL, NULL}, - {0}, {0}, {0}, {0} -}; - -CBModeInfo myCbmodeinfos[] = { - {'f', CMODE_f, 0, NULL, NULL}, - {'c', CMODE_c, 0, NULL, NULL}, - {'i', CMODE_i, 0, NULL, NULL}, - {'k', CMODE_k, 0, get_key, cs_get_key}, - {'l', CMODE_l, CBM_MINUS_NO_ARG, get_limit, cs_get_limit}, - {'m', CMODE_m, 0, NULL, NULL}, - {'n', CMODE_n, 0, NULL, NULL}, - {'p', CMODE_p, 0, NULL, NULL}, - {'r', CMODE_r, 0, NULL, NULL}, - {'s', CMODE_s, 0, NULL, NULL}, - {'t', CMODE_t, 0, NULL, NULL}, - {'u', CMODE_u, 0, NULL, NULL}, - {'z', CMODE_z, 0, NULL, NULL}, - {'A', CMODE_A, 0, NULL, NULL}, - {'C', CMODE_C, 0, NULL, NULL}, - {'G', CMODE_G, 0, NULL, NULL}, - {'H', CMODE_H, 0, NULL, NULL}, - {'K', CMODE_K, 0, NULL, NULL}, - {'L', CMODE_L, 0, get_redirect, cs_get_redirect}, - {'N', CMODE_N, 0, NULL, NULL}, - {'O', CMODE_O, 0, NULL, NULL}, - {'Q', CMODE_Q, 0, NULL, NULL}, - {'R', CMODE_R, 0, NULL, NULL}, - {'S', CMODE_S, 0, NULL, NULL}, - {'V', CMODE_V, 0, NULL, NULL}, - {0} -}; - -CUMode myCumodes[128] = { - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - - {0}, - - {CUS_PROTECT, CUF_PROTECT_BOTSERV, check_valid_op}, - {0}, /* b */ - {0}, /* c */ - {0}, /* d */ - {0}, /* e */ - {0}, /* f */ - {0}, /* g */ - {CUS_HALFOP, 0, check_valid_op}, - {0}, /* i */ - {0}, /* j */ - {0}, /* k */ - {0}, /* l */ - {0}, /* m */ - {0}, /* n */ - {CUS_OP, CUF_PROTECT_BOTSERV, check_valid_op}, - {0}, /* p */ - {CUS_OWNER, 0, check_valid_op}, - {0}, /* r */ - {0}, /* s */ - {0}, /* t */ - {0}, /* u */ - {CUS_VOICE, 0, NULL}, - {0}, /* w */ - {0}, /* x */ - {0}, /* y */ - {0}, /* z */ - {0}, {0}, {0}, {0}, {0} -}; - static int has_servicesmod = 0; static int has_globopsmod = 0; static int has_svsholdmod = 0; @@ -449,10 +173,11 @@ class InspIRCdProto : public IRCDProto --ac; if (debug) alog("debug: Changing mode for %s to %s", user->nick, modes); while (*modes) { - /* This looks better, much better than "add ? (do_add) : (do_remove)". - * At least this is readable without paying much attention :) -GD */ - if (add) user->mode |= umodes[static_cast<int>(*modes)]; - else user->mode &= ~umodes[static_cast<int>(*modes)]; + if (add) + user->SetMode(*modes); + else + user->RemoveMode(*modes); + switch (*modes++) { case '+': add = 1; @@ -476,7 +201,7 @@ class InspIRCdProto : public IRCDProto break; if (add && !nick_identified(user)) { common_svsmode(user, "-r", NULL); - user->mode &= ~UMODE_r; + user->RemoveMode(UMODE_REGISTERED); } break; case 'x': @@ -515,7 +240,10 @@ class InspIRCdProto : public IRCDProto void SendVhostDel(User *u) { - inspircd_cmd_chghost(u->nick, (u->mode & umodes[static_cast<int>('x')] ? u->GetCloakedHost().c_str() : u->host)); + if (u->HasMode(UMODE_CLOAK)) + inspircd_cmd_chghost(u->nick, u->chost.c_str()); + else + inspircd_cmd_chghost(u->nick, u->host); if (has_chgidentmod && u->GetIdent() != u->GetVIdent()) { @@ -1293,7 +1021,6 @@ int anope_event_metadata(const char *source, int ac, const char **av) int anope_event_capab(const char *source, int ac, const char **av) { int argc; - CBModeInfo *cbmi; if (strcasecmp(av[0], "START") == 0) { /* reset CAPAB */ @@ -1367,52 +1094,16 @@ int anope_event_capab(const char *source, int ac, const char **av) ircdproto->SendGlobops(s_OperServ, "CHGIDENT missing, Usage disabled until module is loaded."); } if (has_messagefloodmod) { - cbmi = myCbmodeinfos; - - /* Find 'f' in myCbmodeinfos and add the relevant bits to myCbmodes and myCbmodeinfos - * to enable +f support if found. This is needed because we're really not set up to - * handle modular ircds which can have modes enabled/disabled as they please :( - mark - */ - while ((cbmi->mode != 'f')) { - cbmi++; - } - if (cbmi) { - cbmi->getvalue = get_flood; - cbmi->csgetvalue = cs_get_flood; - - myCbmodes[static_cast<int>('f')].flag = CMODE_f; - myCbmodes[static_cast<int>('f')].flags = 0; - myCbmodes[static_cast<int>('f')].setvalue = set_flood; - myCbmodes[static_cast<int>('f')].cssetvalue = cs_set_flood; - - pmodule_ircd_cbmodeinfos(myCbmodeinfos); - pmodule_ircd_cbmodes(myCbmodes); - - ircd->fmode = 1; - } - else { - alog("Support for channelmode +f can not be enabled"); - if (debug) { - alog("debug: 'f' missing from myCbmodeinfos"); - } - } + ModeManager::AddChannelMode('f', new ChannelModeFlood()); } if (has_banexceptionmod) { - myCmmodes[static_cast<int>('e')].addmask = add_exception; - myCmmodes[static_cast<int>('e')].delmask = del_exception; - ircd->except = 1; + ModeManager::AddChannelMode('e', new ChannelModeExcept()); } if (has_inviteexceptionmod) { - myCmmodes[static_cast<int>('I')].addmask = add_invite; - myCmmodes[static_cast<int>('I')].delmask = del_invite; - ircd->invitemode = 1; + ModeManager::AddChannelMode('I', new ChannelModeInvite()); } ircd->svshold = has_svsholdmod; - if (has_banexceptionmod || has_inviteexceptionmod) { - pmodule_ircd_cmmodes(myCmmodes); - } - /* Generate a fake capabs parsing call so things like NOQUIT work * fine. It's ugly, but it works.... */ @@ -1453,9 +1144,6 @@ int anope_event_endburst(const char *source, int ac, const char **av) void moduleAddIRCDMsgs() { Message *m; - updateProtectDetails("PROTECT","PROTECTME","protect","deprotect","AUTOPROTECT","+a","-a"); - updateOwnerDetails("OWNER", "DEOWNER", ircd->ownerset, ircd->ownerunset); - m = createMessage("ENDBURST", anope_event_endburst); addCoreMessage(IRCD, m); m = createMessage("436", anope_event_436); addCoreMessage(IRCD,m); m = createMessage("AWAY", anope_event_away); addCoreMessage(IRCD,m); @@ -1492,6 +1180,52 @@ void moduleAddIRCDMsgs() { m = createMessage("METADATA", anope_event_metadata); addCoreMessage(IRCD,m); } +void moduleAddModes() +{ + /* Add user modes */ + ModeManager::AddUserMode('g', new UserMode(UMODE_CALLERID)); + ModeManager::AddUserMode('h', new UserMode(UMODE_HELPOP)); + ModeManager::AddUserMode('i', new UserMode(UMODE_INVIS)); + ModeManager::AddUserMode('o', new UserMode(UMODE_OPER)); + ModeManager::AddUserMode('r', new UserMode(UMODE_REGISTERED)); + ModeManager::AddUserMode('w', new UserMode(UMODE_WALLOPS)); + ModeManager::AddUserMode('x', new UserMode(UMODE_CLOAK)); + + /* b/e/I */ + ModeManager::AddChannelMode('b', new ChannelModeBan()); + + /* v/h/o/a/q */ + ModeManager::AddChannelMode('v', new ChannelModeStatus(CMODE_VOICE, CUS_VOICE, '+')); + ModeManager::AddChannelMode('h', new ChannelModeStatus(CMODE_HALFOP, CUS_HALFOP, '%')); + ModeManager::AddChannelMode('o', new ChannelModeStatus(CMODE_OP, CUS_OP, '@', true)); + ModeManager::AddChannelMode('a', new ChannelModeStatus(CMODE_PROTECT, CUS_PROTECT, '&', true)); + ModeManager::AddChannelMode('q', new ChannelModeStatus(CMODE_OWNER, CUS_OWNER, '~')); + + /* Add channel modes */ + ModeManager::AddChannelMode('c', new ChannelMode(CMODE_BLOCKCOLOR)); + ModeManager::AddChannelMode('i', new ChannelMode(CMODE_INVITE)); + ModeManager::AddChannelMode('k', new ChannelModeKey()); + ModeManager::AddChannelMode('l', new ChannelModeParam(CMODE_LIMIT)); + ModeManager::AddChannelMode('m', new ChannelMode(CMODE_MODERATED)); + ModeManager::AddChannelMode('n', new ChannelMode(CMODE_NOEXTERNAL)); + ModeManager::AddChannelMode('p', new ChannelMode(CMODE_PRIVATE)); + ModeManager::AddChannelMode('r', new ChannelModeRegistered()); + ModeManager::AddChannelMode('s', new ChannelMode(CMODE_SECRET)); + ModeManager::AddChannelMode('t', new ChannelMode(CMODE_TOPIC)); + ModeManager::AddChannelMode('u', new ChannelMode(CMODE_AUDITORIUM)); + ModeManager::AddChannelMode('z', new ChannelMode(CMODE_SSL)); + ModeManager::AddChannelMode('A', new ChannelMode(CMODE_ALLINVITE)); + ModeManager::AddChannelMode('C', new ChannelMode(CMODE_NOCTCP)); + ModeManager::AddChannelMode('G', new ChannelMode(CMODE_FILTER)); + ModeManager::AddChannelMode('K', new ChannelMode(CMODE_NOKNOCK)); + ModeManager::AddChannelMode('L', new ChannelModeParam(CMODE_REDIRECT)); + ModeManager::AddChannelMode('N', new ChannelMode(CMODE_NONICK)); + ModeManager::AddChannelMode('O', new ChannelModeOper()); + ModeManager::AddChannelMode('Q', new ChannelMode(CMODE_NOKICK)); + ModeManager::AddChannelMode('R', new ChannelMode(CMODE_REGISTEREDONLY)); + ModeManager::AddChannelMode('S', new ChannelMode(CMODE_STRIPCOLOR)); +} + class ProtoInspIRCd : public Module { public: @@ -1507,23 +1241,13 @@ class ProtoInspIRCd : public Module pmodule_ircd_version("InspIRCd 1.2"); pmodule_ircd_cap(myIrcdcap); pmodule_ircd_var(myIrcd); - pmodule_ircd_cbmodeinfos(myCbmodeinfos); - pmodule_ircd_cumodes(myCumodes); - pmodule_ircd_flood_mode_char_set("+f"); - pmodule_ircd_flood_mode_char_remove("-f"); - pmodule_ircd_cbmodes(myCbmodes); - pmodule_ircd_cmmodes(myCmmodes); - pmodule_ircd_csmodes(myCsmodes); pmodule_ircd_useTSMode(0); - /** Deal with modes anope _needs_ to know **/ - pmodule_invis_umode(UMODE_i); - pmodule_oper_umode(UMODE_o); - pmodule_invite_cmode(CMODE_i); - pmodule_secret_cmode(CMODE_s); - pmodule_private_cmode(CMODE_p); - pmodule_key_mode(CMODE_k); - pmodule_limit_mode(CMODE_l); + moduleAddModes(); + + ircd->DefMLock[(size_t)CMODE_NOEXTERNAL] = true; + ircd->DefMLock[(size_t)CMODE_TOPIC] = true; + ircd->DefMLock[(size_t)CMODE_REGISTERED] = true; pmodule_ircd_proto(&ircd_proto); moduleAddIRCDMsgs(); diff --git a/src/protocol/ratbox.c b/src/protocol/ratbox.c index 58efa0cc2..131279049 100644 --- a/src/protocol/ratbox.c +++ b/src/protocol/ratbox.c @@ -14,72 +14,26 @@ #include "services.h" #include "pseudo.h" -#define UMODE_a 0x00000001 -#define UMODE_C 0x00000002 -#define UMODE_i 0x00000004 -#define UMODE_o 0x00000008 -#define UMODE_z 0x00000010 -#define UMODE_w 0x00000020 -#define UMODE_s 0x00000040 -#define UMODE_c 0x00000080 -#define UMODE_r 0x00000100 -#define UMODE_k 0x00000200 -#define UMODE_f 0x00000400 -#define UMODE_y 0x00000800 -#define UMODE_d 0x00001000 -#define UMODE_n 0x00002000 -#define UMODE_x 0x00004000 -#define UMODE_u 0x00008000 -#define UMODE_b 0x00010000 -#define UMODE_l 0x00020000 -#define UMODE_g 0x00040000 -#define UMODE_Z 0x00080000 - -#define CMODE_i 0x00000001 -#define CMODE_m 0x00000002 -#define CMODE_n 0x00000004 -#define CMODE_p 0x00000008 -#define CMODE_s 0x00000010 -#define CMODE_t 0x00000020 -#define CMODE_k 0x00000040 -#define CMODE_l 0x00000080 - - -#define DEFAULT_MLOCK CMODE_n | CMODE_t - IRCDVar myIrcd[] = { {"Ratbox 2.0+", /* ircd name */ "+oi", /* Modes used by pseudoclients */ 2, /* Chan Max Symbols */ - "-acilmnpst", /* Modes to Remove */ "+o", /* Channel Umode used by Botserv bots */ 0, /* SVSNICK */ 0, /* Vhost */ - 0, /* Has Owner */ - NULL, /* Mode to set for an owner */ - NULL, /* Mode to unset for an owner */ - NULL, /* Mode to set for chan admin */ - NULL, /* Mode to unset for chan admin */ NULL, /* Mode on UnReg */ 1, /* Supports SGlines */ 1, /* Supports SQlines */ 0, /* Supports SZlines */ - 0, /* Supports Halfop +h */ 3, /* Number of server args */ 1, /* Join 2 Set */ 1, /* Join 2 Message */ - 1, /* Has exceptions +e */ 0, /* TS Topic Forward */ 0, /* TS Topci Backward */ - 0, /* Protected Umode */ - 0, /* Has Admin */ 1, /* Chan SQlines */ 0, /* Quit on Kill */ 0, /* SVSMODE unban */ - 0, /* Has Protect */ 0, /* Reverse */ - 0, /* Chan Reg */ - 0, /* Channel Mode */ 0, /* vidents */ 0, /* svshold */ 0, /* time stamp on mode */ @@ -88,28 +42,18 @@ IRCDVar myIrcd[] = { 0, /* O:LINE */ 0, /* VHOST ON NICK */ 0, /* Change RealName */ - CMODE_p, /* No Knock */ - 0, /* Admin Only */ - DEFAULT_MLOCK, /* Default MLOCK */ - 0, /* Vhost Mode */ - 0, /* +f */ - 0, /* +L */ - 0, /* +f Mode */ - 0, /* +L Mode */ + 0, 0, /* On nick change check if they could be identified */ 0, /* No Knock requires +i */ NULL, /* CAPAB Chan Modes */ 0, /* We support TOKENS */ 0, /* TIME STAMPS are BASE64 */ - 1, /* +I support */ 0, /* SJOIN ban char */ 0, /* SJOIN except char */ 0, /* SJOIN invite char */ 0, /* Can remove User Channel Modes with SVSMODE */ 0, /* Sglines are not enforced until user reconnects */ - NULL, /* vhost char */ 1, /* ts6 */ - 0, /* support helper umode */ 0, /* p10 */ NULL, /* character set */ 0, /* CIDR channelbans */ @@ -152,257 +96,6 @@ IRCDCAPAB myIrcdcap[] = { 0, 0, 0} }; -unsigned long umodes[128] = { - 0, 0, 0, /* Unused */ - 0, 0, 0, /* Unused */ - 0, 0, 0, /* Unused, Unused, Horzontal Tab */ - 0, 0, 0, /* Line Feed, Unused, Unused */ - 0, 0, 0, /* Carriage Return, Unused, Unused */ - 0, 0, 0, /* Unused */ - 0, 0, 0, /* Unused */ - 0, 0, 0, /* Unused */ - 0, 0, 0, /* Unused */ - 0, 0, 0, /* Unused */ - 0, 0, 0, /* Unused, Unused, Space */ - 0, 0, 0, /* ! " # */ - 0, 0, 0, /* $ % & */ - 0, 0, 0, /* ! ( ) */ - 0, 0, 0, /* * + , */ - 0, 0, 0, /* - . / */ - 0, 0, /* 0 1 */ - 0, 0, /* 2 3 */ - 0, 0, /* 4 5 */ - 0, 0, /* 6 7 */ - 0, 0, /* 8 9 */ - 0, 0, /* : ; */ - 0, 0, 0, /* < = > */ - 0, 0, /* ? @ */ - 0, 0, 0, /* A B C */ - 0, 0, 0, /* D E F */ - 0, 0, 0, /* G H I */ - 0, 0, 0, /* J K L */ - 0, 0, 0, /* M N O */ - 0, 0, 0, /* P Q R */ - 0, 0, 0, /* S T U */ - 0, 0, 0, /* V W X */ - 0, /* Y */ - 0, /* Z */ - 0, 0, 0, /* [ \ ] */ - 0, 0, 0, /* ^ _ ` */ - UMODE_a, UMODE_b, 0, /* a b c */ - UMODE_d, 0, 0, /* d e f */ - UMODE_g, 0, UMODE_i, /* g h i */ - 0, 0, UMODE_l, /* j k l */ - 0, UMODE_n, UMODE_o, /* m n o */ - 0, 0, 0, /* p q r */ - 0, 0, UMODE_u, /* s t u */ - 0, UMODE_w, UMODE_x, /* v w x */ - 0, /* y */ - 0, /* z */ - 0, 0, 0, /* { | } */ - 0, 0 /* ~ � */ -}; - - -char myCsmodes[128] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - 0, - 0, - 0, 0, 0, - 0, - 0, 0, 0, 0, - 0, - - 'v', 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - 'o', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -CMMode myCmmodes[128] = { - {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, /* BCD */ - {NULL}, {NULL}, {NULL}, /* EFG */ - {NULL}, /* H */ - {add_invite, del_invite}, - {NULL}, /* J */ - {NULL}, {NULL}, {NULL}, /* KLM */ - {NULL}, {NULL}, {NULL}, /* NOP */ - {NULL}, {NULL}, {NULL}, /* QRS */ - {NULL}, {NULL}, {NULL}, /* TUV */ - {NULL}, {NULL}, {NULL}, /* WXY */ - {NULL}, /* Z */ - {NULL}, {NULL}, /* (char 91 - 92) */ - {NULL}, {NULL}, {NULL}, /* (char 93 - 95) */ - {NULL}, /* ` (char 96) */ - {NULL}, /* a (char 97) */ - {add_ban, del_ban}, - {NULL}, - {NULL}, - {add_exception, del_exception}, - {NULL}, - {NULL}, - {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL} -}; - - -CBMode myCbmodes[128] = { - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, - {0}, /* A */ - {0}, /* B */ - {0}, /* C */ - {0}, /* D */ - {0}, /* E */ - {0}, /* F */ - {0}, /* G */ - {0}, /* H */ - {0}, /* I */ - {0}, /* J */ - {0}, /* K */ - {0}, /* L */ - {0}, /* M */ - {0}, /* N */ - {0}, /* O */ - {0}, /* P */ - {0}, /* Q */ - {0}, /* R */ - {0}, /* S */ - {0}, /* T */ - {0}, /* U */ - {0}, /* V */ - {0}, /* W */ - {0}, /* X */ - {0}, /* Y */ - {0}, /* Z */ - {0}, {0}, {0}, {0}, {0}, {0}, - {0}, - {0}, /* b */ - {0}, /* c */ - {0}, /* d */ - {0}, /* e */ - {0}, /* f */ - {0}, /* g */ - {0}, /* h */ - {CMODE_i, 0, NULL, NULL}, - {0}, /* j */ - {CMODE_k, 0, chan_set_key, cs_set_key}, - {CMODE_l, CBM_MINUS_NO_ARG, set_limit, cs_set_limit}, - {CMODE_m, 0, NULL, NULL}, - {CMODE_n, 0, NULL, NULL}, - {0}, /* o */ - {CMODE_p, 0, NULL, NULL}, - {0}, /* q */ - {0}, - {CMODE_s, 0, NULL, NULL}, - {CMODE_t, 0, NULL, NULL}, - {0}, - {0}, /* v */ - {0}, /* w */ - {0}, /* x */ - {0}, /* y */ - {0}, /* z */ - {0}, {0}, {0}, {0} -}; - -CBModeInfo myCbmodeinfos[] = { - {'i', CMODE_i, 0, NULL, NULL}, - {'k', CMODE_k, 0, get_key, cs_get_key}, - {'l', CMODE_l, CBM_MINUS_NO_ARG, get_limit, cs_get_limit}, - {'m', CMODE_m, 0, NULL, NULL}, - {'n', CMODE_n, 0, NULL, NULL}, - {'p', CMODE_p, 0, NULL, NULL}, - {'s', CMODE_s, 0, NULL, NULL}, - {'t', CMODE_t, 0, NULL, NULL}, - {0} -}; - - -CUMode myCumodes[128] = { - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - - {0}, - - {0}, /* a */ - {0}, /* b */ - {0}, /* c */ - {0}, /* d */ - {0}, /* e */ - {0}, /* f */ - {0}, /* g */ - {0}, - {0}, /* i */ - {0}, /* j */ - {0}, /* k */ - {0}, /* l */ - {0}, /* m */ - {0}, /* n */ - {CUS_OP, CUF_PROTECT_BOTSERV, check_valid_op}, - {0}, /* p */ - {0}, /* q */ - {0}, /* r */ - {0}, /* s */ - {0}, /* t */ - {0}, /* u */ - {CUS_VOICE, 0, NULL}, - {0}, /* w */ - {0}, /* x */ - {0}, /* y */ - {0}, /* z */ - {0}, {0}, {0}, {0}, {0} -}; - - - /* * SVINFO @@ -481,10 +174,11 @@ class RatboxProto : public IRCDTS6Proto --ac; if (debug) alog("debug: Changing mode for %s to %s", user->nick, modes); while (*modes) { - /* This looks better, much better than "add ? (do_add) : (do_remove)". - * At least this is readable without paying much attention :) -GD */ - if (add) user->mode |= umodes[static_cast<int>(*modes)]; - else user->mode &= ~umodes[static_cast<int>(*modes)]; + if (add) + user->SetMode(*modes); + else + user->RemoveMode(*modes); + switch (*modes++) { case '+': add = 1; @@ -1084,6 +778,7 @@ int anope_event_bmask(const char *source, int ac, const char **av) char *bans; char *b; int count, i; + ChannelModeList *cms; /* :42X BMASK 1106409026 #ircops b :*!*@*.aol.com */ /* 0 1 2 3 */ @@ -1095,13 +790,16 @@ int anope_event_bmask(const char *source, int ac, const char **av) for (i = 0; i <= count - 1; i++) { b = myStrGetToken(bans, ' ', i); if (!stricmp(av[2], "b")) { - add_ban(c, b); + cms = static_cast<ChannelModeList *>(ModeManager::FindChannelModeByChar('b')); + cms->AddMask(c, b); } if (!stricmp(av[2], "e")) { - add_exception(c, b); + cms = static_cast<ChannelModeList *>(ModeManager::FindChannelModeByChar('e')); + cms->AddMask(c, b); } if (!stricmp(av[2], "I")) { - add_invite(c, b); + cms = static_cast<ChannelModeList *>(ModeManager::FindChannelModeByChar('I')); + cms->AddMask(c, b); } if (b) delete [] b; @@ -1125,8 +823,6 @@ void moduleAddIRCDMsgs() { Message *m; - updateProtectDetails("PROTECT","PROTECTME","protect","deprotect","AUTOPROTECT","+","-"); - m = createMessage("436", anope_event_436); addCoreMessage(IRCD,m); m = createMessage("AWAY", anope_event_away); addCoreMessage(IRCD,m); m = createMessage("JOIN", anope_event_join); addCoreMessage(IRCD,m); @@ -1154,6 +850,36 @@ void moduleAddIRCDMsgs() m = createMessage("SID", anope_event_sid); addCoreMessage(IRCD,m); } +void moduleAddModes() +{ + /* Add user modes */ + ModeManager::AddUserMode('a', new UserMode(UMODE_ADMIN)); + ModeManager::AddUserMode('i', new UserMode(UMODE_INVIS)); + ModeManager::AddUserMode('o', new UserMode(UMODE_OPER)); + ModeManager::AddUserMode('r', new UserMode(UMODE_REGISTERED)); + ModeManager::AddUserMode('s', new UserMode(UMODE_SNOMASK)); + ModeManager::AddUserMode('w', new UserMode(UMODE_WALLOPS)); + + /* b/e/I */ + ModeManager::AddChannelMode('b', new ChannelModeBan()); + ModeManager::AddChannelMode('e', new ChannelModeExcept()); + ModeManager::AddChannelMode('I', new ChannelModeInvite()); + + /* v/h/o/a/q */ + ModeManager::AddChannelMode('v', new ChannelModeStatus(CMODE_VOICE, CUS_VOICE, '+')); + ModeManager::AddChannelMode('o', new ChannelModeStatus(CMODE_OP, CUS_OP, '@', true)); + + /* Add channel modes */ + ModeManager::AddChannelMode('i', new ChannelMode(CMODE_INVITE)); + ModeManager::AddChannelMode('k', new ChannelModeKey()); + ModeManager::AddChannelMode('l', new ChannelModeParam(CMODE_LIMIT)); + ModeManager::AddChannelMode('m', new ChannelMode(CMODE_MODERATED)); + ModeManager::AddChannelMode('n', new ChannelMode(CMODE_NOEXTERNAL)); + ModeManager::AddChannelMode('p', new ChannelMode(CMODE_PRIVATE)); + ModeManager::AddChannelMode('s', new ChannelMode(CMODE_SECRET)); + ModeManager::AddChannelMode('t', new ChannelMode(CMODE_TOPIC)); +} + class ProtoRatbox : public Module { public: @@ -1170,23 +896,12 @@ class ProtoRatbox : public Module pmodule_ircd_version("Ratbox IRCD 2.0+"); pmodule_ircd_cap(myIrcdcap); pmodule_ircd_var(myIrcd); - pmodule_ircd_cbmodeinfos(myCbmodeinfos); - pmodule_ircd_cumodes(myCumodes); - pmodule_ircd_flood_mode_char_set(""); - pmodule_ircd_flood_mode_char_remove(""); - pmodule_ircd_cbmodes(myCbmodes); - pmodule_ircd_cmmodes(myCmmodes); - pmodule_ircd_csmodes(myCsmodes); pmodule_ircd_useTSMode(1); - /** Deal with modes anope _needs_ to know **/ - pmodule_invis_umode(UMODE_i); - pmodule_oper_umode(UMODE_o); - pmodule_invite_cmode(CMODE_i); - pmodule_secret_cmode(CMODE_s); - pmodule_private_cmode(CMODE_p); - pmodule_key_mode(CMODE_k); - pmodule_limit_mode(CMODE_l); + moduleAddModes(); + + ircd->DefMLock[(size_t)CMODE_NOEXTERNAL] = true; + ircd->DefMLock[(size_t)CMODE_TOPIC] = true; pmodule_ircd_proto(&ircd_proto); moduleAddIRCDMsgs(); diff --git a/src/protocol/unreal32.c b/src/protocol/unreal32.c index 2223cd162..81404b909 100644 --- a/src/protocol/unreal32.c +++ b/src/protocol/unreal32.c @@ -16,107 +16,26 @@ #include "services.h" #include "pseudo.h" - -/* User Modes */ -#define UMODE_a 0x00000001 /* a Services Admin */ -#define UMODE_h 0x00000002 /* h Available for help (HelpOp) */ -#define UMODE_i 0x00000004 /* i Invisible (not shown in /who) */ -#define UMODE_o 0x00000008 /* o Global IRC Operator */ -#define UMODE_r 0x00000010 /* r Identifies the nick as being registered */ -#define UMODE_w 0x00000020 /* w Can listen to wallop messages */ -#define UMODE_A 0x00000040 /* A Server Admin */ -#define UMODE_N 0x00000080 /* N Network Administrator */ -#define UMODE_O 0x00000100 /* O Local IRC Operator */ -#define UMODE_C 0x00000200 /* C Co-Admin */ -#define UMODE_d 0x00000400 /* d Makes it so you can not receive channel PRIVMSGs */ -#define UMODE_p 0x00000800 /* Hides the channels you are in in a /whois reply */ -#define UMODE_q 0x00001000 /* q Only U:Lines can kick you (Services Admins Only) */ -#define UMODE_s 0x00002000 /* s Can listen to server notices */ -#define UMODE_t 0x00004000 /* t Says you are using a /vhost */ -#define UMODE_v 0x00008000 /* v Receives infected DCC Send Rejection notices */ -#define UMODE_z 0x00010000 /* z Indicates that you are an SSL client */ -#define UMODE_B 0x00020000 /* B Marks you as being a Bot */ -#define UMODE_G 0x00040000 /* G Filters out all the bad words per configuration */ -#define UMODE_H 0x00080000 /* H Hide IRCop Status (IRCop Only) */ -#define UMODE_S 0x00100000 /* S services client */ -#define UMODE_V 0x00200000 /* V Marks you as a WebTV user */ -#define UMODE_W 0x00400000 /* W Lets you see when people do a /whois on you */ -#define UMODE_T 0x00800000 /* T Prevents you from receiving CTCPs */ -#define UMODE_g 0x20000000 /* g Can send & read globops and locops */ -#define UMODE_x 0x40000000 /* x Gives user a hidden hostname */ -#define UMODE_R 0x80000000 /* Allows you to only receive PRIVMSGs/NOTICEs from registered (+r) users */ - - -/*************************************************************************/ - -/* Channel Modes */ - -#define CMODE_i 0x00000001 -#define CMODE_m 0x00000002 -#define CMODE_n 0x00000004 -#define CMODE_p 0x00000008 -#define CMODE_s 0x00000010 -#define CMODE_t 0x00000020 -#define CMODE_k 0x00000040 /* These two used only by ChanServ */ -#define CMODE_l 0x00000080 -#define CMODE_R 0x00000100 /* Only identified users can join */ -#define CMODE_r 0x00000200 /* Set for all registered channels */ -#define CMODE_c 0x00000400 -#define CMODE_A 0x00000800 -/* #define CMODE_H 0x00001000 Was now +I may not join, but Unreal Removed it and it will not set in 3.2 */ -#define CMODE_K 0x00002000 -#define CMODE_L 0x00004000 -#define CMODE_O 0x00008000 -#define CMODE_Q 0x00010000 -#define CMODE_S 0x00020000 -#define CMODE_V 0x00040000 -#define CMODE_f 0x00080000 -#define CMODE_G 0x00100000 -#define CMODE_C 0x00200000 -#define CMODE_u 0x00400000 -#define CMODE_z 0x00800000 -#define CMODE_N 0x01000000 -#define CMODE_T 0x02000000 -#define CMODE_M 0x04000000 - - -/* Default Modes with MLOCK */ - -#define DEFAULT_MLOCK CMODE_n | CMODE_t | CMODE_r - IRCDVar myIrcd[] = { {"UnrealIRCd 3.2.x", /* ircd name */ "+Soi", /* Modes used by pseudoclients */ 5, /* Chan Max Symbols */ - "-cilmnpstuzACGHKMNOQRSTV", /* Modes to Remove */ "+ao", /* Channel Umode used by Botserv bots */ 1, /* SVSNICK */ 1, /* Vhost */ - 1, /* Has Owner */ - "+q", /* Mode to set for an owner */ - "-q", /* Mode to unset for an owner */ - "+a", /* Mode to set for channel admin */ - "-a", /* Mode to unset for channel admin */ "-r+d", /* Mode on UnReg */ 1, /* Supports SGlines */ 1, /* Supports SQlines */ 1, /* Supports SZlines */ - 1, /* Supports Halfop +h */ 3, /* Number of server args */ 0, /* Join 2 Set */ 0, /* Join 2 Message */ - 1, /* Has exceptions +e */ 1, /* TS Topic Forward */ 0, /* TS Topci Backward */ - UMODE_S, /* Protected Umode */ - 0, /* Has Admin */ 0, /* Chan SQlines */ 0, /* Quit on Kill */ 1, /* SVSMODE unban */ - 1, /* Has Protect */ 1, /* Reverse */ - 1, /* Chan Reg */ - CMODE_r, /* Channel Mode */ 1, /* vidents */ 1, /* svshold */ 1, /* time stamp on mode */ @@ -125,28 +44,18 @@ IRCDVar myIrcd[] = { 1, /* UMODE */ 1, /* VHOST ON NICK */ 1, /* Change RealName */ - CMODE_K, /* No Knock */ - CMODE_A, /* Admin Only */ - DEFAULT_MLOCK, /* Default MLOCK */ - UMODE_x, /* Vhost Mode */ - 1, /* +f */ - 1, /* +L */ - CMODE_f, /* +f Mode */ - CMODE_L, /* +L Mode */ + 0, 0, /* On nick change check if they could be identified */ 1, /* No Knock requires +i */ NULL, /* CAPAB Chan Modes */ 1, /* We support Unreal TOKENS */ 1, /* TIME STAMPS are BASE64 */ - 1, /* +I support */ '&', /* SJOIN ban char */ '\"', /* SJOIN except char */ '\'', /* SJOIN invite char */ 1, /* Can remove User Channel Modes with SVSMODE */ 0, /* Sglines are not enforced until user reconnects */ - "x", /* vhost char */ 0, /* ts6 */ - 1, /* support helper umode */ 0, /* p10 */ NULL, /* character set */ 0, /* CIDR channelbans */ @@ -192,271 +101,6 @@ IRCDCAPAB myIrcdcap[] = { } }; - -unsigned long umodes[128] = { - 0, 0, 0, /* Unused */ - 0, 0, 0, /* Unused */ - 0, 0, 0, /* Unused, Unused, Horzontal Tab */ - 0, 0, 0, /* Line Feed, Unused, Unused */ - 0, 0, 0, /* Carriage Return, Unused, Unused */ - 0, 0, 0, /* Unused */ - 0, 0, 0, /* Unused */ - 0, 0, 0, /* Unused */ - 0, 0, 0, /* Unused */ - 0, 0, 0, /* Unused */ - 0, 0, 0, /* Unused, Unused, Space */ - 0, 0, 0, /* ! " # */ - 0, 0, 0, /* $ % & */ - 0, 0, 0, /* ! ( ) */ - 0, 0, 0, /* * + , */ - 0, 0, 0, /* - . / */ - 0, 0, /* 0 1 */ - 0, 0, /* 2 3 */ - 0, 0, /* 4 5 */ - 0, 0, /* 6 7 */ - 0, 0, /* 8 9 */ - 0, 0, /* : ; */ - 0, 0, 0, /* < = > */ - 0, 0, /* ? @ */ - UMODE_A, UMODE_B, UMODE_C, /* A B C */ - 0, 0, 0, /* D E F */ - UMODE_G, UMODE_H, 0, /* G H I */ - 0, 0, 0, /* J K L */ - 0, UMODE_N, UMODE_O, /* M N O */ - 0, 0, UMODE_R, /* P Q R */ - UMODE_S, UMODE_T, 0, /* S T U */ - UMODE_V, UMODE_W, 0, /* V W X */ - 0, /* Y */ - 0, /* Z */ - 0, 0, 0, /* [ \ ] */ - 0, 0, 0, /* ^ _ ` */ - UMODE_a, 0, 0, /* a b c */ - UMODE_d, 0, 0, /* d e f */ - UMODE_g, UMODE_h, UMODE_i, /* g h i */ - 0, 0, 0, /* j k l */ - 0, 0, UMODE_o, /* m n o */ - UMODE_p, UMODE_q, UMODE_r, /* p q r */ - UMODE_s, UMODE_t, 0, /* s t u */ - UMODE_v, UMODE_w, UMODE_x, /* v w x */ - 0, /* y */ - UMODE_z, /* z */ - 0, 0, 0, /* { | } */ - 0, 0 /* ~ � */ -}; - -char myCsmodes[128] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - 0, - 0, - 0, 0, 0, - 'h', /* (37) % Channel halfops */ - 'b', /* (38) & bans */ - 0, 0, 0, - 'q', - - 'v', 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - 'o', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'a', 0 -}; - -CMMode myCmmodes[128] = { - {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, /* BCD */ - {NULL}, {NULL}, {NULL}, /* EFG */ - {NULL}, /* H */ - {add_invite, del_invite}, /* I */ - {NULL}, /* J */ - {NULL}, {NULL}, {NULL}, /* KLM */ - {NULL}, {NULL}, {NULL}, /* NOP */ - {NULL}, {NULL}, {NULL}, /* QRS */ - {NULL}, {NULL}, {NULL}, /* TUV */ - {NULL}, {NULL}, {NULL}, /* WXY */ - {NULL}, /* Z */ - {NULL}, {NULL}, /* (char 91 - 92) */ - {NULL}, {NULL}, {NULL}, /* (char 93 - 95) */ - {NULL}, /* ` (char 96) */ - {NULL}, /* a (char 97) */ - {add_ban, del_ban}, /* b */ - {NULL}, {NULL}, /* cd */ - {add_exception, del_exception}, - {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, - {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL} -}; - -CBMode myCbmodes[128] = { - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, - {CMODE_A, CBM_NO_USER_MLOCK, NULL, NULL}, - {0}, /* B */ - {CMODE_C, 0, NULL, NULL}, /* C */ - {0}, /* D */ - {0}, /* E */ - {0}, /* F */ - {CMODE_G, 0, NULL, NULL}, /* G */ - {0}, /* H */ - {0}, /* I */ - {0}, /* J */ - {CMODE_K, 0, NULL, NULL}, /* K */ - {CMODE_L, 0, set_redirect, cs_set_redirect}, - {CMODE_M, 0, NULL, NULL}, /* M */ - {CMODE_N, 0, NULL, NULL}, /* N */ - {CMODE_O, CBM_NO_USER_MLOCK, NULL, NULL}, - {0}, /* P */ - {CMODE_Q, 0, NULL, NULL}, /* Q */ - {CMODE_R, 0, NULL, NULL}, /* R */ - {CMODE_S, 0, NULL, NULL}, /* S */ - {CMODE_T, 0, NULL, NULL}, /* T */ - {0}, /* U */ - {CMODE_V, 0, NULL, NULL}, /* V */ - {0}, /* W */ - {0}, /* X */ - {0}, /* Y */ - {0}, /* Z */ - {0}, {0}, {0}, {0}, {0}, {0}, - {0}, /* a */ - {0}, /* b */ - {CMODE_c, 0, NULL, NULL}, - {0}, /* d */ - {0}, /* e */ - {CMODE_f, 0, set_flood, cs_set_flood}, - {0}, /* g */ - {0}, /* h */ - {CMODE_i, 0, NULL, NULL}, - {0}, /* j */ - {CMODE_k, 0, chan_set_key, cs_set_key}, - {CMODE_l, CBM_MINUS_NO_ARG, set_limit, cs_set_limit}, - {CMODE_m, 0, NULL, NULL}, - {CMODE_n, 0, NULL, NULL}, - {0}, /* o */ - {CMODE_p, 0, NULL, NULL}, - {0}, /* q */ - {CMODE_r, CBM_NO_MLOCK, NULL, NULL}, - {CMODE_s, 0, NULL, NULL}, - {CMODE_t, 0, NULL, NULL}, - {CMODE_u, 0, NULL, NULL}, - {0}, /* v */ - {0}, /* w */ - {0}, /* x */ - {0}, /* y */ - {CMODE_z, 0, NULL, NULL}, - {0}, {0}, {0}, {0} -}; - -CBModeInfo myCbmodeinfos[] = { - {'c', CMODE_c, 0, NULL, NULL}, - {'f', CMODE_f, 0, get_flood, cs_get_flood}, - {'i', CMODE_i, 0, NULL, NULL}, - {'k', CMODE_k, 0, get_key, cs_get_key}, - {'l', CMODE_l, CBM_MINUS_NO_ARG, get_limit, cs_get_limit}, - {'m', CMODE_m, 0, NULL, NULL}, - {'n', CMODE_n, 0, NULL, NULL}, - {'p', CMODE_p, 0, NULL, NULL}, - {'r', CMODE_r, 0, NULL, NULL}, - {'s', CMODE_s, 0, NULL, NULL}, - {'t', CMODE_t, 0, NULL, NULL}, - {'u', CMODE_u, 0, NULL, NULL}, - {'z', CMODE_z, 0, NULL, NULL}, - {'A', CMODE_A, 0, NULL, NULL}, - {'C', CMODE_C, 0, NULL, NULL}, - {'G', CMODE_G, 0, NULL, NULL}, - {'K', CMODE_K, 0, NULL, NULL}, - {'L', CMODE_L, 0, get_redirect, cs_get_redirect}, - {'M', CMODE_M, 0, NULL, NULL}, - {'N', CMODE_N, 0, NULL, NULL}, - {'O', CMODE_O, 0, NULL, NULL}, - {'Q', CMODE_Q, 0, NULL, NULL}, - {'R', CMODE_R, 0, NULL, NULL}, - {'S', CMODE_S, 0, NULL, NULL}, - {'T', CMODE_T, 0, NULL, NULL}, - {'V', CMODE_V, 0, NULL, NULL}, - {0} -}; - -CUMode myCumodes[128] = { - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, - - {0}, - - {CUS_PROTECT, CUF_PROTECT_BOTSERV, check_valid_op}, - {0}, /* b */ - {0}, /* c */ - {0}, /* d */ - {0}, /* e */ - {0}, /* f */ - {0}, /* g */ - {CUS_HALFOP, 0, check_valid_op}, - {0}, /* i */ - {0}, /* j */ - {0}, /* k */ - {0}, /* l */ - {0}, /* m */ - {0}, /* n */ - {CUS_OP, CUF_PROTECT_BOTSERV, check_valid_op}, - {0}, /* p */ - {CUS_OWNER, 0, check_valid_op}, - {0}, /* r */ - {0}, /* s */ - {0}, /* t */ - {0}, /* u */ - {CUS_VOICE, 0, NULL}, - {0}, /* w */ - {0}, /* x */ - {0}, /* y */ - {0}, /* z */ - {0}, {0}, {0}, {0}, {0} -}; - - /* svswatch * parv[0] - sender * parv[1] - target nick @@ -535,14 +179,10 @@ class UnrealIRCdProto : public IRCDProto if (debug) alog("debug: Changing mode for %s to %s", user->nick, modes); while (*modes) { - uint32 backup = user->mode; - - /* This looks better, much better than "add ? (do_add) : (do_remove)". - * At least this is readable without paying much attention :) -GD */ if (add) - user->mode |= umodes[static_cast<int>(*modes)]; + user->SetMode(*modes); else - user->mode &= ~umodes[static_cast<int>(*modes)]; + user->RemoveMode(*modes); switch (*modes++) { @@ -557,9 +197,11 @@ class UnrealIRCdProto : public IRCDProto break; if (isdigit(*av[1])) { - //user->svid = strtoul(av[1], NULL, 0); - user->mode = backup; /* Ugly fix, but should do the job ~ Viper */ - continue; // +d was setting a service stamp, ignore the usermode +-d. + /* +d was setting a service stamp, ignore the usermode +d */ + if (add) + user->RemoveMode('d'); + else + user->SetMode('d'); } break; case 'o': @@ -573,7 +215,7 @@ class UnrealIRCdProto : public IRCDProto case 'r': if (add && !nick_identified(user)) { common_svsmode(user, "-r", NULL); - user->mode &= ~UMODE_r; + user->RemoveMode('r'); } break; case 't': @@ -874,38 +516,6 @@ class UnrealIRCdProto : public IRCDProto send_cmd(ServerName, "ES"); } - - /* check if +f mode is valid for the ircd */ - /* borrowed part of the new check from channels.c in Unreal */ - int IsFloodModeParamValid(const char *value) - { - char *dp, *end; - /* NEW +F */ - char xbuf[256], *p, *p2, *x = xbuf + 1; - int v; - if (!value) return 0; - if (*value != ':' && strtoul((*value == '*' ? value + 1 : value), &dp, 10) > 0 && *dp == ':' && *(++dp) && strtoul(dp, &end, 10) > 0 && !*end) return 1; - else { - /* '['<number><1 letter>[optional: '#'+1 letter],[next..]']'':'<number> */ - strncpy(xbuf, value, sizeof(xbuf)); - p2 = strchr(xbuf + 1, ']'); - if (!p2) return 0; - *p2 = '\0'; - if (*(p2 + 1) != ':') return 0; - for (x = strtok(xbuf + 1, ","); x; x = strtok(NULL, ",")) { - /* <number><1 letter>[optional: '#'+1 letter] */ - p = x; - while (isdigit(*p)) ++p; - if (!*p || !(*p == 'c' || *p == 'j' || *p == 'k' || *p == 'm' || *p == 'n' || *p == 't')) continue; /* continue instead of break for forward compatability. */ - *p = '\0'; - v = atoi(x); - if (v < 1 || v > 999) return 0; - ++p; - } - return 1; - } - } - /* 1 = valid nick 0 = nick is in valid @@ -1216,7 +826,7 @@ int anope_event_sethost(const char *source, int ac, const char **av) * to the sethost value (which really is their vhost) and clear the chost. * The chost will be request later (if needed) - Adam */ - if (u->mode & UMODE_t) + if (u->HasMode(UMODE_VHOST)) { u->SetDisplayedHost(av[0]); u->chost.clear(); @@ -1440,9 +1050,6 @@ int anope_event_sjoin(const char *source, int ac, const char **av) void moduleAddIRCDMsgs() { Message *m; - updateProtectDetails("PROTECT","PROTECTME","protect","deprotect","AUTOPROTECT","+a","-a"); - updateOwnerDetails("OWNER", "DEOWNER", ircd->ownerset, ircd->ownerunset); - m = createMessage("436", anope_event_436); addCoreMessage(IRCD,m); m = createMessage("AWAY", anope_event_away); addCoreMessage(IRCD,m); m = createMessage("6", anope_event_away); addCoreMessage(IRCD,m); @@ -1512,6 +1119,106 @@ void moduleAddIRCDMsgs() { m = createMessage("+", m_version); addCoreMessage(IRCD,m); } +/* Borrowed part of this check from UnrealIRCd */ +bool ChannelModeFlood::IsValid(const char *value) +{ + char *dp, *end; + /* NEW +F */ + char xbuf[256], *p, *p2, *x = xbuf + 1; + int v; + if (!value) return 0; + if (*value != ':' && strtoul((*value == '*' ? value + 1 : value), &dp, 10) > 0 && *dp == ':' && *(++dp) && strtoul(dp, &end, 10) > 0 && !*end) return 1; + else { + /* '['<number><1 letter>[optional: '#'+1 letter],[next..]']'':'<number> */ + strncpy(xbuf, value, sizeof(xbuf)); + p2 = strchr(xbuf + 1, ']'); + if (!p2) return 0; + *p2 = '\0'; + if (*(p2 + 1) != ':') return 0; + for (x = strtok(xbuf + 1, ","); x; x = strtok(NULL, ",")) { + /* <number><1 letter>[optional: '#'+1 letter] */ + p = x; + while (isdigit(*p)) ++p; + if (!*p || !(*p == 'c' || *p == 'j' || *p == 'k' || *p == 'm' || *p == 'n' || *p == 't')) continue; /* continue instead of break for forward compatability. */ + *p = '\0'; + v = atoi(x); + if (v < 1 || v > 999) return 0; + ++p; + } + return 1; + } +} + +void moduleAddModes() +{ + /* Add user modes */ + ModeManager::AddUserMode('A', new UserMode(UMODE_SERV_ADMIN)); + ModeManager::AddUserMode('B', new UserMode(UMODE_BOT)); + ModeManager::AddUserMode('C', new UserMode(UMODE_CO_ADMIN)); + ModeManager::AddUserMode('G', new UserMode(UMODE_FILTER)); + ModeManager::AddUserMode('H', new UserMode(UMODE_HIDEOPER)); + ModeManager::AddUserMode('N', new UserMode(UMODE_NETADMIN)); + ModeManager::AddUserMode('R', new UserMode(UMODE_REGPRIV)); + ModeManager::AddUserMode('S', new UserMode(UMODE_PROTECTED)); + ModeManager::AddUserMode('T', new UserMode(UMODE_NO_CTCP)); + ModeManager::AddUserMode('V', new UserMode(UMODE_WEBTV)); + ModeManager::AddUserMode('W', new UserMode(UMODE_WHOIS)); + ModeManager::AddUserMode('a', new UserMode(UMODE_ADMIN)); + ModeManager::AddUserMode('d', new UserMode(UMODE_DEAF)); + ModeManager::AddUserMode('g', new UserMode(UMODE_GLOBOPS)); + ModeManager::AddUserMode('h', new UserMode(UMODE_HELPOP)); + ModeManager::AddUserMode('i', new UserMode(UMODE_INVIS)); + ModeManager::AddUserMode('o', new UserMode(UMODE_OPER)); + ModeManager::AddUserMode('p', new UserMode(UMODE_PRIV)); + ModeManager::AddUserMode('q', new UserMode(UMODE_GOD)); + ModeManager::AddUserMode('r', new UserMode(UMODE_REGISTERED)); + ModeManager::AddUserMode('s', new UserMode(UMODE_SNOMASK)); + ModeManager::AddUserMode('t', new UserMode(UMODE_VHOST)); + ModeManager::AddUserMode('w', new UserMode(UMODE_WALLOPS)); + ModeManager::AddUserMode('x', new UserMode(UMODE_CLOAK)); + ModeManager::AddUserMode('z', new UserMode(UMODE_SSL)); + + /* b/e/I */ + ModeManager::AddChannelMode('b', new ChannelModeBan()); + ModeManager::AddChannelMode('e', new ChannelModeExcept()); + ModeManager::AddChannelMode('I', new ChannelModeInvite()); + + /* v/h/o/a/q */ + ModeManager::AddChannelMode('v', new ChannelModeStatus(CMODE_VOICE, CUS_VOICE, '+')); + ModeManager::AddChannelMode('h', new ChannelModeStatus(CMODE_HALFOP, CUS_HALFOP, '%')); + ModeManager::AddChannelMode('o', new ChannelModeStatus(CMODE_OP, CUS_OP, '@', true)); + ModeManager::AddChannelMode('a', new ChannelModeStatus(CMODE_PROTECT, CUS_PROTECT, '&', true)); + /* Unreal sends +q as * */ + ModeManager::AddChannelMode('q', new ChannelModeStatus(CMODE_OWNER, CUS_OWNER, '*')); + + /* Add channel modes */ + ModeManager::AddChannelMode('c', new ChannelMode(CMODE_BLOCKCOLOR)); + ModeManager::AddChannelMode('f', new ChannelModeFlood()); + ModeManager::AddChannelMode('i', new ChannelMode(CMODE_INVITE)); + ModeManager::AddChannelMode('k', new ChannelModeKey()); + ModeManager::AddChannelMode('l', new ChannelModeParam(CMODE_LIMIT)); + ModeManager::AddChannelMode('m', new ChannelMode(CMODE_MODERATED)); + ModeManager::AddChannelMode('n', new ChannelMode(CMODE_NOEXTERNAL)); + ModeManager::AddChannelMode('p', new ChannelMode(CMODE_PRIVATE)); + ModeManager::AddChannelMode('r', new ChannelModeRegistered()); + ModeManager::AddChannelMode('s', new ChannelMode(CMODE_SECRET)); + ModeManager::AddChannelMode('t', new ChannelMode(CMODE_TOPIC)); + ModeManager::AddChannelMode('u', new ChannelMode(CMODE_AUDITORIUM)); + ModeManager::AddChannelMode('z', new ChannelMode(CMODE_SSL)); + ModeManager::AddChannelMode('A', new ChannelModeAdmin()); + ModeManager::AddChannelMode('C', new ChannelMode(CMODE_NOCTCP)); + ModeManager::AddChannelMode('G', new ChannelMode(CMODE_FILTER)); + ModeManager::AddChannelMode('K', new ChannelMode(CMODE_NOKNOCK)); + ModeManager::AddChannelMode('L', new ChannelModeParam(CMODE_REDIRECT)); + ModeManager::AddChannelMode('M', new ChannelMode(CMODE_REGMODERATED)); + ModeManager::AddChannelMode('N', new ChannelMode(CMODE_NONICK)); + ModeManager::AddChannelMode('O', new ChannelModeOper()); + ModeManager::AddChannelMode('Q', new ChannelMode(CMODE_NOKICK)); + ModeManager::AddChannelMode('R', new ChannelMode(CMODE_REGISTEREDONLY)); + ModeManager::AddChannelMode('S', new ChannelMode(CMODE_STRIPCOLOR)); + ModeManager::AddChannelMode('T', new ChannelMode(CMODE_NONOTICE)); + ModeManager::AddChannelMode('V', new ChannelMode(CMODE_NOINVITE)); +} class ProtoUnreal : public Module { @@ -1525,23 +1232,13 @@ class ProtoUnreal : public Module pmodule_ircd_version("UnrealIRCd 3.2+"); pmodule_ircd_cap(myIrcdcap); pmodule_ircd_var(myIrcd); - pmodule_ircd_cbmodeinfos(myCbmodeinfos); - pmodule_ircd_cumodes(myCumodes); - pmodule_ircd_flood_mode_char_set("+f"); - pmodule_ircd_flood_mode_char_remove("-f"); - pmodule_ircd_cbmodes(myCbmodes); - pmodule_ircd_cmmodes(myCmmodes); - pmodule_ircd_csmodes(myCsmodes); pmodule_ircd_useTSMode(0); - /** Deal with modes anope _needs_ to know **/ - pmodule_invis_umode(UMODE_i); - pmodule_oper_umode(UMODE_o); - pmodule_invite_cmode(CMODE_i); - pmodule_secret_cmode(CMODE_s); - pmodule_private_cmode(CMODE_p); - pmodule_key_mode(CMODE_k); - pmodule_limit_mode(CMODE_l); + moduleAddModes(); + + ircd->DefMLock[(size_t)CMODE_NOEXTERNAL] = true; + ircd->DefMLock[(size_t)CMODE_TOPIC] = true; + ircd->DefMLock[(size_t)CMODE_REGISTERED] = true; pmodule_ircd_proto(&ircd_proto); moduleAddIRCDMsgs(); diff --git a/src/users.c b/src/users.c index 55981d995..54712d089 100644 --- a/src/users.c +++ b/src/users.c @@ -44,9 +44,9 @@ User::User(const std::string &snick, const std::string &suid) nc = NULL; chans = NULL; founder_chans = NULL; - invalid_pw_count = timestamp = my_signon = mode = invalid_pw_time = lastmemosend = lastnickreg = lastmail = 0; + invalid_pw_count = timestamp = my_signon = invalid_pw_time = lastmemosend = lastnickreg = lastmail = 0; OnAccess = false; - + strscpy(this->nick, snick.c_str(), NICKMAX); this->uid = suid; list = &userlist[HASH(this->nick)]; @@ -130,7 +130,7 @@ const std::string User::GetDisplayedHost() const { if (ircd->vhost && this->vhost) return this->vhost; - else if (ircd->vhostmode && (this->mode & ircd->vhostmode) && !this->GetCloakedHost().empty()) + else if (this->HasMode(UMODE_CLOAK) && !this->GetCloakedHost().empty()) return this->GetCloakedHost(); else return this->host; @@ -178,7 +178,7 @@ void User::SetVIdent(const std::string &sident) const std::string &User::GetVIdent() const { - if (ircd->vhostmode && (this->mode & ircd->vhostmode)) + if (this->HasMode(UMODE_CLOAK)) return this->vident; else if (ircd->vident && !this->vident.empty()) return this->vident; @@ -201,7 +201,6 @@ const std::string &User::GetIdent() const return this->ident; } - void User::SetRealname(const std::string &srealname) { if (srealname.empty()) @@ -476,6 +475,57 @@ User *finduser(const char *nick) return user; } +/** Check if the user has a mode
+ * @param Name Mode name
+ * @return true or false
+ */ +const bool User::HasMode(UserModeName Name) const +{ + return modes[(size_t)Name]; +} + +/** Set a mode on the user
+ * @param Name The mode name
+ */ +void User::SetMode(UserModeName Name) +{ + modes[(size_t)Name] = true; +} + +/* Set a mode on the user
+ * @param ModeChar The mode char + */ +void User::SetMode(char ModeChar) +{ + UserMode *um; + + if ((um = ModeManager::FindUserModeByChar(ModeChar))) + { + SetMode(um->Name); + } +} + +/** Remove a mode from the user
+ * @param Name The mode name
+ */ +void User::RemoveMode(UserModeName Name) +{ + modes[(size_t)Name] = false; +} + +/** Remove a mode from the user
+ * @param ModeChar The mode char
+ */ +void User::RemoveMode(char ModeChar) +{ + UserMode *um; + + if ((um = ModeManager::FindUserModeByChar(ModeChar))) + { + RemoveMode(um->Name); + } +} + /*************************************************************************/ @@ -944,11 +994,10 @@ void do_kill(const char *nick, const char *msg) int is_protected(User * user) { - if (ircd->protectedumode) { - return (user->mode & ircd->protectedumode); - } else { - return 0; - } + if (user && user->HasMode(UMODE_PROTECTED)) + return 1; + + return 0; } /*************************************************************************/ @@ -957,11 +1006,10 @@ int is_protected(User * user) int is_oper(User * user) { - if (user) { - return (user->mode & anope_get_oper_mode()); - } else { - return 0; - } + if (user && user->HasMode(UMODE_OPER)) + return 1; + + return 0; } /*************************************************************************/ @@ -970,7 +1018,7 @@ int is_oper(User * user) /* Is the given user ban-excepted? */ int is_excepted(ChannelInfo * ci, User * user) { - if (!ci->c || !ircd->except) + if (!ci->c || !ModeManager::FindChannelModeByName(CMODE_EXCEPT)) return 0; if (elist_match_user(ci->c->excepts, user)) @@ -984,7 +1032,7 @@ int is_excepted(ChannelInfo * ci, User * user) /* Is the given MASK ban-excepted? */ int is_excepted_mask(ChannelInfo * ci, const char *mask) { - if (!ci->c || !ircd->except) + if (!ci->c || !ModeManager::FindChannelModeByName(CMODE_EXCEPT)) return 0; if (elist_match_mask(ci->c->excepts, mask, 0)) |