From 91df762e93212958db487d8517addba1a63a4ddd Mon Sep 17 00:00:00 2001 From: danieldg Date: Sun, 13 Sep 2009 20:30:47 +0000 Subject: Membership* changes git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@11697 e03df62e-2008-0410-955e-edbf42e46eb7 --- src/channels.cpp | 276 +++++++++----------------------- src/commands/cmd_invite.cpp | 6 +- src/commands/cmd_nick.cpp | 36 +---- src/commands/cmd_notice.cpp | 15 +- src/commands/cmd_privmsg.cpp | 15 +- src/commands/cmd_who.cpp | 21 +-- src/inspircd.cpp | 4 + src/mode.cpp | 92 ++--------- src/modes/cmode_b.cpp | 2 +- src/modes/cmode_h.cpp | 31 ++-- src/modes/cmode_o.cpp | 29 ++-- src/modes/cmode_v.cpp | 29 ++-- src/modules.cpp | 2 +- src/modules/m_auditorium.cpp | 22 +-- src/modules/m_banredirect.cpp | 2 +- src/modules/m_blockcaps.cpp | 2 +- src/modules/m_blockcolor.cpp | 2 +- src/modules/m_cap.h | 2 +- src/modules/m_censor.cpp | 2 +- src/modules/m_chanfilter.cpp | 2 +- src/modules/m_channelban.cpp | 2 +- src/modules/m_chanprotect.cpp | 163 ++++++------------- src/modules/m_check.cpp | 4 +- src/modules/m_cycle.cpp | 2 +- src/modules/m_dccallow.cpp | 47 +++--- src/modules/m_deaf.cpp | 6 +- src/modules/m_delayjoin.cpp | 115 ++++--------- src/modules/m_delaymsg.cpp | 58 +++---- src/modules/m_httpd_stats.cpp | 7 +- src/modules/m_invisible.cpp | 16 +- src/modules/m_messageflood.cpp | 2 +- src/modules/m_muteban.cpp | 2 +- src/modules/m_nickflood.cpp | 8 +- src/modules/m_noctcp.cpp | 2 +- src/modules/m_nonicks.cpp | 4 +- src/modules/m_nonotice.cpp | 2 +- src/modules/m_ojoin.cpp | 49 ++---- src/modules/m_operprefix.cpp | 118 ++------------ src/modules/m_override.cpp | 22 +-- src/modules/m_redirect.cpp | 2 +- src/modules/m_remove.cpp | 82 +--------- src/modules/m_silence.cpp | 21 +-- src/modules/m_spanningtree/netburst.cpp | 4 +- src/modules/m_spanningtree/utils.cpp | 4 +- src/modules/m_spy.cpp | 2 +- src/modules/m_sslmodes.cpp | 4 +- src/modules/m_stripcolor.cpp | 2 +- src/modules/m_timedbans.cpp | 4 +- src/modules/m_uninvite.cpp | 4 +- src/users.cpp | 35 ++-- 50 files changed, 398 insertions(+), 987 deletions(-) (limited to 'src') diff --git a/src/channels.cpp b/src/channels.cpp index 4915b1614..0a4ef993d 100644 --- a/src/channels.cpp +++ b/src/channels.cpp @@ -81,7 +81,7 @@ int Channel::SetTopic(User *u, std::string &ntopic, bool forceset) u->WriteNumeric(442, "%s %s :You're not on that channel!",u->nick.c_str(), this->name.c_str()); return CMD_FAILURE; } - if ((this->IsModeSet('t')) && (this->GetStatus(u) < STATUS_HOP)) + if ((this->IsModeSet('t')) && (this->GetPrefixValue(u) < HALFOP_VALUE)) { u->WriteNumeric(482, "%s %s :You must be at least a half-operator to change the topic on this channel", u->nick.c_str(), this->name.c_str()); return CMD_FAILURE; @@ -115,98 +115,45 @@ int Channel::SetTopic(User *u, std::string &ntopic, bool forceset) long Channel::GetUserCounter() { - return (this->internal_userlist.size()); + return userlist.size(); } -void Channel::AddUser(User* user) +Membership* Channel::AddUser(User* user) { - internal_userlist[user] = user->nick; + Membership* memb = new Membership(user, this); + userlist[user] = memb; + return memb; } unsigned long Channel::DelUser(User* user) { - CUListIter a = internal_userlist.find(user); + UserMembIter a = userlist.find(user); - if (a != internal_userlist.end()) + if (a != userlist.end()) { - internal_userlist.erase(a); - /* And tidy any others... */ - DelOppedUser(user); - DelHalfoppedUser(user); - DelVoicedUser(user); + delete a->second; + userlist.erase(a); } - return internal_userlist.size(); + return userlist.size(); } bool Channel::HasUser(User* user) { - return (internal_userlist.find(user) != internal_userlist.end()); + return (userlist.find(user) != userlist.end()); } -void Channel::AddOppedUser(User* user) +Membership* Channel::GetUser(User* user) { - internal_op_userlist[user] = user->nick; -} - -void Channel::DelOppedUser(User* user) -{ - CUListIter a = internal_op_userlist.find(user); - if (a != internal_op_userlist.end()) - { - internal_op_userlist.erase(a); - return; - } -} - -void Channel::AddHalfoppedUser(User* user) -{ - internal_halfop_userlist[user] = user->nick; -} - -void Channel::DelHalfoppedUser(User* user) -{ - CUListIter a = internal_halfop_userlist.find(user); - - if (a != internal_halfop_userlist.end()) - { - internal_halfop_userlist.erase(a); - } -} - -void Channel::AddVoicedUser(User* user) -{ - internal_voice_userlist[user] = user->nick; -} - -void Channel::DelVoicedUser(User* user) -{ - CUListIter a = internal_voice_userlist.find(user); - - if (a != internal_voice_userlist.end()) - { - internal_voice_userlist.erase(a); - } -} - -CUList* Channel::GetUsers() -{ - return &internal_userlist; -} - -CUList* Channel::GetOppedUsers() -{ - return &internal_op_userlist; -} - -CUList* Channel::GetHalfoppedUsers() -{ - return &internal_halfop_userlist; + UserMembIter i = userlist.find(user); + if (i == userlist.end()) + return NULL; + return i->second; } -CUList* Channel::GetVoicedUsers() +const UserMembList* Channel::GetUsers() { - return &internal_voice_userlist; + return &userlist; } void Channel::SetDefaultModes() @@ -396,9 +343,7 @@ Channel* Channel::ForceChan(InspIRCd* Instance, Channel* Ptr, User* user, const bool silent = false; Ptr->AddUser(user); - - /* Just in case they have no permissions */ - user->chans[Ptr] = 0; + user->chans.insert(Ptr); for (std::string::const_iterator x = privs.begin(); x != privs.end(); x++) { @@ -407,26 +352,8 @@ Channel* Channel::ForceChan(InspIRCd* Instance, Channel* Ptr, User* user, const if (mh) { /* Set, and make sure that the mode handler knows this mode was now set */ - Ptr->SetPrefix(user, status, mh->GetPrefixRank(), true); + Ptr->SetPrefix(user, mh->GetModeChar(), mh->GetPrefixRank(), true); mh->OnModeChange(Instance->FakeClient, Instance->FakeClient, Ptr, nick, true); - - switch (mh->GetPrefix()) - { - /* These logic ops are SAFE IN THIS CASE because if the entry doesnt exist, - * addressing operator[] creates it. If they do exist, it points to it. - * At all other times where we dont want to create an item if it doesnt exist, we - * must stick to ::find(). - */ - case '@': - user->chans[Ptr] |= UCMODE_OP; - break; - case '%': - user->chans[Ptr] |= UCMODE_HOP; - break; - case '+': - user->chans[Ptr] |= UCMODE_VOICE; - break; - } } } @@ -613,11 +540,11 @@ long Channel::KickUser(User *src, User *user, const char* reason) if (res == MOD_RES_PASSTHRU) { - int them = this->GetStatus(src); - int us = this->GetStatus(user); - if ((them < STATUS_HOP) || (them < us)) + int them = this->GetPrefixValue(src); + int us = this->GetPrefixValue(user); + if ((them < HALFOP_VALUE) || (them < us)) { - src->WriteNumeric(ERR_CHANOPRIVSNEEDED, "%s %s :You must be a channel %soperator",src->nick.c_str(), this->name.c_str(), them == STATUS_HOP ? "" : "half-"); + src->WriteNumeric(ERR_CHANOPRIVSNEEDED, "%s %s :You must be a channel %soperator",src->nick.c_str(), this->name.c_str(), them >= HALFOP_VALUE ? "" : "half-"); return this->GetUserCounter(); } } @@ -674,7 +601,6 @@ void Channel::WriteChannel(User* user, const char* text, ...) void Channel::WriteChannel(User* user, const std::string &text) { - CUList *ulist = this->GetUsers(); char tb[MAXBUF]; if (!user) @@ -683,7 +609,7 @@ void Channel::WriteChannel(User* user, const std::string &text) snprintf(tb,MAXBUF,":%s %s", user->GetFullHost().c_str(), text.c_str()); std::string out = tb; - for (CUList::iterator i = ulist->begin(); i != ulist->end(); i++) + for (UserMembIter i = userlist.begin(); i != userlist.end(); i++) { if (IS_LOCAL(i->first)) i->first->Write(out); @@ -707,13 +633,12 @@ void Channel::WriteChannelWithServ(const char* ServName, const char* text, ...) void Channel::WriteChannelWithServ(const char* ServName, const std::string &text) { - CUList *ulist = this->GetUsers(); char tb[MAXBUF]; snprintf(tb,MAXBUF,":%s %s", ServName ? ServName : ServerInstance->Config->ServerName, text.c_str()); std::string out = tb; - for (CUList::iterator i = ulist->begin(); i != ulist->end(); i++) + for (UserMembIter i = userlist.begin(); i != userlist.end(); i++) { if (IS_LOCAL(i->first)) i->first->Write(out); @@ -766,8 +691,7 @@ void Channel::WriteAllExcept(User* user, bool serversource, char status, CUList void Channel::RawWriteAllExcept(User* user, bool serversource, char status, CUList &except_list, const std::string &out) { - CUList *ulist = this->GetUsers(); - for (CUList::iterator i = ulist->begin(); i != ulist->end(); i++) + for (UserMembIter i = userlist.begin(); i != userlist.end(); i++) { if ((IS_LOCAL(i->first)) && (except_list.find(i->first) == except_list.end())) { @@ -783,7 +707,7 @@ void Channel::RawWriteAllExcept(User* user, bool serversource, char status, CULi void Channel::WriteAllExceptSender(User* user, bool serversource, char status, const std::string& text) { CUList except_list; - except_list[user] = user->nick; + except_list.insert(user); this->WriteAllExcept(user, serversource, status, except_list, std::string(text)); } @@ -794,8 +718,7 @@ void Channel::WriteAllExceptSender(User* user, bool serversource, char status, c int Channel::CountInvisible() { int count = 0; - CUList *ulist= this->GetUsers(); - for (CUList::iterator i = ulist->begin(); i != ulist->end(); i++) + for (UserMembIter i = userlist.begin(); i != userlist.end(); i++) { if (!(i->first->IsModeSet('i'))) count++; @@ -863,7 +786,7 @@ char* Channel::ChanModes(bool showkey) /* compile a userlist of a channel into a string, each nick seperated by * spaces and op, voice etc status shown as @ and +, and send it to 'user' */ -void Channel::UserList(User *user, CUList *ulist) +void Channel::UserList(User *user) { char list[MAXBUF]; size_t dlen, curlen; @@ -872,7 +795,7 @@ void Channel::UserList(User *user, CUList *ulist) if (!IS_LOCAL(user)) return; - FIRST_MOD_RESULT(ServerInstance, OnUserList, call_modules, (user, this, ulist)); + FIRST_MOD_RESULT(ServerInstance, OnUserList, call_modules, (user, this)); if (call_modules != MOD_RES_ALLOW) { @@ -888,15 +811,12 @@ void Channel::UserList(User *user, CUList *ulist) int numusers = 0; char* ptr = list + dlen; - if (!ulist) - ulist = this->GetUsers(); - /* Improvement by Brain - this doesnt change in value, so why was it inside * the loop? */ bool has_user = this->HasUser(user); - for (CUList::iterator i = ulist->begin(); i != ulist->end(); i++) + for (UserMembIter i = userlist.begin(); i != userlist.end(); i++) { if ((!has_user) && (i->first->IsModeSet('i'))) { @@ -984,42 +904,43 @@ void Channel::ResetMaxBans() const char* Channel::GetPrefixChar(User *user) { static char pf[2] = {0, 0}; + *pf = 0; + unsigned int bestrank = 0; - prefixlist::iterator n = prefixes.find(user); - if (n != prefixes.end()) + UserMembIter m = userlist.find(user); + if (m != userlist.end()) { - if (n->second.size()) + for(unsigned int i=0; i < m->second->modes.length(); i++) { - /* If the user has any prefixes, their highest prefix - * will always be at the head of the list, as the list is - * sorted in rank order highest first (see SetPrefix() - * for reasons why) - */ - *pf = n->second.begin()->first; - return pf; + char mchar = m->second->modes[i]; + ModeHandler* mh = ServerInstance->Modes->FindMode(mchar, MODETYPE_CHANNEL); + if (mh && mh->GetPrefixRank() > bestrank) + { + bestrank = mh->GetPrefixRank(); + pf[0] = mh->GetPrefix(); + } } } - - *pf = 0; return pf; } const char* Channel::GetAllPrefixChars(User* user) { - static char prefix[MAXBUF]; + static char prefix[64]; int ctr = 0; - *prefix = 0; - prefixlist::iterator n = prefixes.find(user); - if (n != prefixes.end()) + UserMembIter m = userlist.find(user); + if (m != userlist.end()) { - for (std::vector::iterator x = n->second.begin(); x != n->second.end(); x++) + for(unsigned int i=0; i < m->second->modes.length(); i++) { - prefix[ctr++] = x->first; + char mchar = m->second->modes[i]; + ModeHandler* mh = ServerInstance->Modes->FindMode(mchar, MODETYPE_CHANNEL); + if (mh && mh->GetPrefix()) + prefix[ctr++] = mh->GetPrefix(); } } - prefix[ctr] = 0; return prefix; @@ -1027,92 +948,49 @@ const char* Channel::GetAllPrefixChars(User* user) unsigned int Channel::GetPrefixValue(User* user) { - prefixlist::iterator n = prefixes.find(user); - if (n != prefixes.end()) - { - if (n->second.size()) - return n->second.begin()->second; - } - return 0; -} - -int Channel::GetStatusFlags(User *user) -{ - UCListIter i = user->chans.find(this); - if (i != user->chans.end()) - { - return i->second; - } - return 0; -} - -int Channel::GetStatus(User *user) -{ - if (ServerInstance->ULine(user->server)) - return STATUS_OP; + unsigned int bestrank = 0; - UCListIter i = user->chans.find(this); - if (i != user->chans.end()) + UserMembIter m = userlist.find(user); + if (m != userlist.end()) { - if ((i->second & UCMODE_OP) > 0) - { - return STATUS_OP; - } - if ((i->second & UCMODE_HOP) > 0) - { - return STATUS_HOP; - } - if ((i->second & UCMODE_VOICE) > 0) + for(unsigned int i=0; i < m->second->modes.length(); i++) { - return STATUS_VOICE; + char mchar = m->second->modes[i]; + ModeHandler* mh = ServerInstance->Modes->FindMode(mchar, MODETYPE_CHANNEL); + if (mh && mh->GetPrefixRank() > bestrank) + bestrank = mh->GetPrefixRank(); } - return STATUS_NORMAL; } - return STATUS_NORMAL; + return bestrank; } void Channel::SetPrefix(User* user, char prefix, unsigned int prefix_value, bool adding) { - prefixlist::iterator n = prefixes.find(user); - prefixtype pfx = std::make_pair(prefix,prefix_value); - if (adding) + UserMembIter m = userlist.find(user); + if (m != userlist.end()) { - if (n != prefixes.end()) + for(unsigned int i=0; i < m->second->modes.length(); i++) { - if (std::find(n->second.begin(), n->second.end(), pfx) == n->second.end()) + char mchar = m->second->modes[i]; + ModeHandler* mh = ServerInstance->Modes->FindMode(mchar, MODETYPE_CHANNEL); + if (mh && mh->GetPrefixRank() <= prefix_value) { - n->second.push_back(pfx); - /* We must keep prefixes in rank order, largest first. - * This is for two reasons, firstly because x-chat *ass-u-me's* this - * state, and secondly it turns out to be a benefit to us later. - * See above in GetPrefix(). - */ - std::sort(n->second.begin(), n->second.end(), ModeParser::PrefixComparison); + m->second->modes = + m->second->modes.substr(0,i-1) + + (adding ? std::string(1, prefix) : "") + + m->second->modes.substr(mchar == prefix ? i+1 : i); + return; } } - else - { - pfxcontainer one; - one.push_back(pfx); - prefixes.insert(std::make_pair(user, one)); - } - } - else - { - if (n != prefixes.end()) - { - pfxcontainer::iterator x = std::find(n->second.begin(), n->second.end(), pfx); - if (x != n->second.end()) - n->second.erase(x); - } + m->second->modes += std::string(1, prefix); } } void Channel::RemoveAllPrefixes(User* user) { - prefixlist::iterator n = prefixes.find(user); - if (n != prefixes.end()) + UserMembIter m = userlist.find(user); + if (m != userlist.end()) { - prefixes.erase(n); + m->second->modes.clear(); } } diff --git a/src/commands/cmd_invite.cpp b/src/commands/cmd_invite.cpp index 73b7068e5..79aee9da5 100644 --- a/src/commands/cmd_invite.cpp +++ b/src/commands/cmd_invite.cpp @@ -91,9 +91,11 @@ CmdResult CommandInvite::Handle (const std::vector& parameters, Use { if (IS_LOCAL(user)) { - if (c->GetStatus(user) < STATUS_HOP) + int rank = c->GetPrefixValue(user); + if (rank < HALFOP_VALUE) { - user->WriteNumeric(ERR_CHANOPRIVSNEEDED, "%s %s :You must be a channel %soperator", user->nick.c_str(), c->name.c_str(), c->GetStatus(u) == STATUS_HOP ? "" : "half-"); + user->WriteNumeric(ERR_CHANOPRIVSNEEDED, "%s %s :You must be a channel %soperator", + user->nick.c_str(), c->name.c_str(), rank >= HALFOP_VALUE ? "" : "half-"); return CMD_FAILURE; } } diff --git a/src/commands/cmd_nick.cpp b/src/commands/cmd_nick.cpp index 6a181bda0..52c6a2254 100644 --- a/src/commands/cmd_nick.cpp +++ b/src/commands/cmd_nick.cpp @@ -13,26 +13,6 @@ #include "inspircd.h" #include "xline.h" -/* +------------------------------------+ - * | Inspire Internet Relay Chat Daemon | - * +------------------------------------+ - * - * InspIRCd: (C) 2002-2009 InspIRCd Development Team - * See: http://wiki.inspircd.org/Credits - * - * This program is free but copyrighted software; see - * the file COPYING for details. - * - * --------------------------------------------------- - */ - -#ifndef __CMD_NICK_H__ -#define __CMD_NICK_H__ - -// include the common header files - -#include "users.h" -#include "channels.h" /** Handle /NICK. These command handlers can be reloaded by the core, * and handle basic RFC1459 commands. Commands within modules work @@ -54,9 +34,6 @@ class CommandNick : public Command CmdResult Handle(const std::vector& parameters, User *user); }; -#endif - - /** Handle nick changes from users. * NOTE: If you are used to ircds based on ircd2.8, and are looking * for the client introduction code in here, youre in the wrong place. @@ -145,8 +122,8 @@ CmdResult CommandNick::Handle (const std::vector& parameters, User { for (UCListIter i = user->chans.begin(); i != user->chans.end(); i++) { - Channel *chan = i->first; - if (chan->GetStatus(user) < STATUS_VOICE && chan->IsBanned(user)) + Channel *chan = *i; + if (chan->GetPrefixValue(user) < VOICE_VALUE && chan->IsBanned(user)) { user->WriteNumeric(404, "%s %s :Cannot send to channel (you're banned)", user->nick.c_str(), chan->name.c_str()); return CMD_FAILURE; @@ -208,15 +185,6 @@ CmdResult CommandNick::Handle (const std::vector& parameters, User user->nick.assign(parameters[0], 0, IS_LOCAL(user) ? ServerInstance->Config->Limits.NickMax : MAXBUF); user->InvalidateCache(); - /* Update display nicks */ - for (UCListIter v = user->chans.begin(); v != user->chans.end(); v++) - { - CUList* ulist = v->first->GetUsers(); - CUList::iterator i = ulist->find(user); - if (i != ulist->end()) - i->second = user->nick; - } - if (user->registered < REG_NICKUSER) { user->registered = (user->registered | REG_NICK); diff --git a/src/commands/cmd_notice.cpp b/src/commands/cmd_notice.cpp index c94dbc87a..2028f8c56 100644 --- a/src/commands/cmd_notice.cpp +++ b/src/commands/cmd_notice.cpp @@ -12,15 +12,6 @@ */ #include "inspircd.h" - -#ifndef __CMD_NOTICE_H__ -#define __CMD_NOTICE_H__ - -// include the common header files - -#include "users.h" -#include "channels.h" - /** Handle /NOTICE. These command handlers can be reloaded by the core, * and handle basic RFC1459 commands. Commands within modules work * the same way, however, they can be fully unloaded, where these @@ -41,8 +32,6 @@ class CommandNotice : public Command CmdResult Handle(const std::vector& parameters, User *user); }; -#endif - CmdResult CommandNotice::Handle (const std::vector& parameters, User *user) { @@ -88,7 +77,7 @@ CmdResult CommandNotice::Handle (const std::vector& parameters, Use { chan = ServerInstance->FindChan(target); - exempt_list[user] = user->nick; + exempt_list.insert(user); if (chan) { @@ -99,7 +88,7 @@ CmdResult CommandNotice::Handle (const std::vector& parameters, Use user->WriteNumeric(404, "%s %s :Cannot send to channel (no external messages)", user->nick.c_str(), chan->name.c_str()); return CMD_FAILURE; } - if ((chan->IsModeSet('m')) && (chan->GetStatus(user) < STATUS_VOICE)) + if ((chan->IsModeSet('m')) && (chan->GetPrefixValue(user) < VOICE_VALUE)) { user->WriteNumeric(404, "%s %s :Cannot send to channel (+m)", user->nick.c_str(), chan->name.c_str()); return CMD_FAILURE; diff --git a/src/commands/cmd_privmsg.cpp b/src/commands/cmd_privmsg.cpp index 5861bd086..e05366fa0 100644 --- a/src/commands/cmd_privmsg.cpp +++ b/src/commands/cmd_privmsg.cpp @@ -13,14 +13,6 @@ #include "inspircd.h" -#ifndef __CMD_PRIVMSG_H__ -#define __CMD_PRIVMSG_H__ - -// include the common header files - -#include "users.h" -#include "channels.h" - /** Handle /PRIVMSG. These command handlers can be reloaded by the core, * and handle basic RFC1459 commands. Commands within modules work * the same way, however, they can be fully unloaded, where these @@ -41,9 +33,6 @@ class CommandPrivmsg : public Command CmdResult Handle(const std::vector& parameters, User *user); }; -#endif - - CmdResult CommandPrivmsg::Handle (const std::vector& parameters, User *user) { User *dest; @@ -89,11 +78,11 @@ CmdResult CommandPrivmsg::Handle (const std::vector& parameters, Us { chan = ServerInstance->FindChan(target); - except_list[user] = user->nick; + except_list.insert(user); if (chan) { - if (IS_LOCAL(user) && chan->GetStatus(user) < STATUS_VOICE) + if (IS_LOCAL(user) && chan->GetPrefixValue(user) < VOICE_VALUE) { if (chan->IsModeSet('n') && !chan->HasUser(user)) { diff --git a/src/commands/cmd_who.cpp b/src/commands/cmd_who.cpp index 329c0a2d5..ff39c4552 100644 --- a/src/commands/cmd_who.cpp +++ b/src/commands/cmd_who.cpp @@ -13,14 +13,6 @@ #include "inspircd.h" -#ifndef __CMD_WHO_H__ -#define __CMD_WHO_H__ - -// include the common header files - -#include "users.h" -#include "channels.h" - /** Handle /WHO. These command handlers can be reloaded by the core, * and handle basic RFC1459 commands. Commands within modules work * the same way, however, they can be fully unloaded, where these @@ -57,18 +49,17 @@ class CommandWho : public Command bool whomatch(User* cuser, User* user, const char* matchtext); }; -#endif - static const std::string star = "*"; static const std::string& get_first_visible_channel(User *u) { UCListIter i = u->chans.begin(); - if (i != u->chans.end()) + while (i != u->chans.end()) { - if (!i->first->IsModeSet('s')) - return i->first->name; + Channel* c = *i++; + if (!c->IsModeSet('s')) + return c->name; } return star; @@ -334,9 +325,9 @@ CmdResult CommandWho::Handle (const std::vector& parameters, User * bool inside = ch->HasUser(user); /* who on a channel. */ - CUList *cu = ch->GetUsers(); + const UserMembList *cu = ch->GetUsers(); - for (CUList::iterator i = cu->begin(); i != cu->end(); i++) + for (UserMembCIter i = cu->begin(); i != cu->end(); i++) { /* None of this applies if we WHO ourselves */ if (user != i->first) diff --git a/src/inspircd.cpp b/src/inspircd.cpp index 810c477f8..3d80f5250 100644 --- a/src/inspircd.cpp +++ b/src/inspircd.cpp @@ -350,6 +350,10 @@ InspIRCd::InspIRCd(int argc, char** argv) : // Avoid erroneous frees on early exit WindowsIPC = 0; #endif + + Extensible::Register(&User::NICKForced); + Extensible::Register(&User::OperQuit); + FailedPortList pl; int do_version = 0, do_nofork = 0, do_debug = 0, do_nolog = 0, do_root = 0, do_testsuite = 0; /* flag variables */ diff --git a/src/mode.cpp b/src/mode.cpp index 47d59d85a..703aa691c 100644 --- a/src/mode.cpp +++ b/src/mode.cpp @@ -248,66 +248,6 @@ User* ModeParser::SanityChecks(User *user, const char *dest, Channel *chan, int) return d; } -const char* ModeParser::Grant(User *d,Channel *chan,int MASK) -{ - if (!chan) - return ""; - - UCListIter n = d->chans.find(chan); - if (n != d->chans.end()) - { - if (n->second & MASK) - { - return ""; - } - n->second = n->second | MASK; - switch (MASK) - { - case UCMODE_OP: - n->first->AddOppedUser(d); - break; - case UCMODE_HOP: - n->first->AddHalfoppedUser(d); - break; - case UCMODE_VOICE: - n->first->AddVoicedUser(d); - break; - } - return d->nick.c_str(); - } - return ""; -} - -const char* ModeParser::Revoke(User *d,Channel *chan,int MASK) -{ - if (!chan) - return ""; - - UCListIter n = d->chans.find(chan); - if (n != d->chans.end()) - { - if ((n->second & MASK) == 0) - { - return ""; - } - n->second ^= MASK; - switch (MASK) - { - case UCMODE_OP: - n->first->DelOppedUser(d); - break; - case UCMODE_HOP: - n->first->DelHalfoppedUser(d); - break; - case UCMODE_VOICE: - n->first->DelVoicedUser(d); - break; - } - return d->nick.c_str(); - } - return ""; -} - void ModeParser::DisplayCurrentModes(User *user, User* targetuser, Channel* targetchannel, const char* text) { if (targetchannel) @@ -374,10 +314,8 @@ ModeAction ModeParser::TryMode(User* user, User* targetuser, Channel* chan, bool * in NAMES(X) are not in rank order, we know the most powerful mode is listed * first, so we don't need to iterate, we just look up the first instead. */ - std::string modestring = chan->GetAllPrefixChars(user); - char ml = (modestring.empty() ? '\0' : modestring[0]); - ModeHandler* ourmode = FindPrefix(ml); - if (!ourmode || ourmode->GetPrefixRank() < neededrank) + unsigned int ourrank = chan->GetPrefixValue(user); + if (ourrank < neededrank) { /* Bog off */ user->WriteNumeric(ERR_CHANOPRIVSNEEDED, "%s %s :You must have channel privilege %c or above to %sset channel mode %c", @@ -436,11 +374,11 @@ ModeAction ModeParser::TryMode(User* user, User* targetuser, Channel* chan, bool mh->ChangeCount(adding ? 1 : -1); - if (mh->GetPrefix() && chan) + if (mh->GetPrefixRank() && chan) { User* user_to_prefix = ServerInstance->FindNick(parameter); if (user_to_prefix) - chan->SetPrefix(user_to_prefix, mh->GetPrefix(), mh->GetPrefixRank(), adding); + chan->SetPrefix(user_to_prefix, modechar, mh->GetPrefixRank(), adding); } for (ModeWatchIter watchers = modewatchers[handler_id].begin(); watchers != modewatchers[handler_id].end(); watchers++) @@ -635,7 +573,7 @@ void ModeParser::DisplayListModes(User* user, Channel* chan, std::string &mode_s continue; bool display = true; - if (!user->HasPrivPermission("channels/auspex") && ServerInstance->Config->HideModeLists[mletter] && (chan->GetStatus(user) < STATUS_HOP)) + if (!user->HasPrivPermission("channels/auspex") && ServerInstance->Config->HideModeLists[mletter] && (chan->GetPrefixValue(user) < HALFOP_VALUE)) { user->WriteNumeric(ERR_CHANOPRIVSNEEDED, "%s %s :Only half-operators and above may view the +%c list", user->nick.c_str(), chan->name.c_str(), mletter); @@ -925,17 +863,11 @@ std::string ModeParser::GiveModeList(ModeMasks m) return type1 + "," + type2 + "," + type3 + "," + type4; } -bool ModeParser::PrefixComparison(prefixtype one, prefixtype two) -{ - return one.second > two.second; -} - std::string ModeParser::BuildPrefixes() { std::string mletters; std::string mprefixes; - pfxcontainer pfx; - std::map prefix_to_mode; + std::map > prefixes; for (unsigned char mode = 'A'; mode <= 'z'; mode++) { @@ -943,17 +875,15 @@ std::string ModeParser::BuildPrefixes() if ((modehandlers[pos]) && (modehandlers[pos]->GetPrefix())) { - pfx.push_back(std::make_pair(modehandlers[pos]->GetPrefix(), modehandlers[pos]->GetPrefixRank())); - prefix_to_mode[modehandlers[pos]->GetPrefix()] = modehandlers[pos]->GetModeChar(); + prefixes[modehandlers[pos]->GetPrefixRank()] = std::make_pair( + modehandlers[pos]->GetPrefix(), modehandlers[pos]->GetModeChar()); } } - sort(pfx.begin(), pfx.end(), ModeParser::PrefixComparison); - - for (pfxcontainer::iterator n = pfx.begin(); n != pfx.end(); n++) + for(std::map >::iterator n = prefixes.begin(); n != prefixes.end(); n++) { - mletters = mletters + n->first; - mprefixes = mprefixes + prefix_to_mode.find(n->first)->second; + mletters = mletters + n->second.first; + mprefixes = mprefixes + n->second.second; } return "(" + mprefixes + ")" + mletters; diff --git a/src/modes/cmode_b.cpp b/src/modes/cmode_b.cpp index 36078f4b2..9c9c2129c 100644 --- a/src/modes/cmode_b.cpp +++ b/src/modes/cmode_b.cpp @@ -31,7 +31,7 @@ ModeChannelBan::ModeChannelBan(InspIRCd* Instance) : ModeHandler(Instance, NULL, ModeAction ModeChannelBan::OnModeChange(User* source, User*, Channel* channel, std::string ¶meter, bool adding) { - int status = channel->GetStatus(source); + int status = channel->GetPrefixValue(source); /* Call the correct method depending on wether we're adding or removing the mode */ if (adding) { diff --git a/src/modes/cmode_h.cpp b/src/modes/cmode_h.cpp index 54ab139ce..480d69f0a 100644 --- a/src/modes/cmode_h.cpp +++ b/src/modes/cmode_h.cpp @@ -33,13 +33,14 @@ ModePair ModeChannelHalfOp::ModeSet(User*, User*, Channel* channel, const std::s User* x = ServerInstance->FindNick(parameter); if (x) { - if (channel->GetStatusFlags(x) & UCMODE_HOP) + Membership* memb = channel->GetUser(x); + if (memb && memb->hasMode('h')) { return std::make_pair(true, x->nick); } else { - return std::make_pair(false, parameter); + return std::make_pair(false, x->nick); } } return std::make_pair(false, parameter); @@ -47,16 +48,9 @@ ModePair ModeChannelHalfOp::ModeSet(User*, User*, Channel* channel, const std::s void ModeChannelHalfOp::RemoveMode(Channel* channel, irc::modestacker* stack) { - CUList* clist = channel->GetHalfoppedUsers(); - CUList copy; + const UserMembList* clist = channel->GetUsers(); - for (CUList::iterator i = clist->begin(); i != clist->end(); i++) - { - User* n = i->first; - copy.insert(std::make_pair(n,n->nick)); - } - - for (CUList::iterator i = copy.begin(); i != copy.end(); i++) + for (UserMembCIter i = clist->begin(); i != clist->end(); i++) { if (stack) { @@ -64,7 +58,10 @@ void ModeChannelHalfOp::RemoveMode(Channel* channel, irc::modestacker* stack) } else { - std::vector parameters; parameters.push_back(channel->name); parameters.push_back("-h"); parameters.push_back(i->first->nick); + std::vector parameters; + parameters.push_back(channel->name); + parameters.push_back("-h"); + parameters.push_back(i->first->nick); ServerInstance->SendMode(parameters, ServerInstance->FakeClient); } } @@ -77,7 +74,7 @@ void ModeChannelHalfOp::RemoveMode(User*, irc::modestacker* stack) ModeAction ModeChannelHalfOp::OnModeChange(User* source, User*, Channel* channel, std::string ¶meter, bool adding) { - int status = channel->GetStatus(source); + int status = channel->GetPrefixValue(source); /* Call the correct method depending on wether we're adding or removing the mode */ if (adding) @@ -114,7 +111,7 @@ std::string ModeChannelHalfOp::AddHalfOp(User *user,const char* dest,Channel *ch return ""; if (MOD_RESULT == MOD_RES_PASSTHRU) { - if ((status < STATUS_OP) && (!ServerInstance->ULine(user->server))) + if ((status < OP_VALUE) && (!ServerInstance->ULine(user->server))) { user->WriteServ("482 %s %s :You're not a channel operator",user->nick.c_str(), chan->name.c_str()); return ""; @@ -122,7 +119,7 @@ std::string ModeChannelHalfOp::AddHalfOp(User *user,const char* dest,Channel *ch } } - return ServerInstance->Modes->Grant(d,chan,UCMODE_HOP); + return d->nick; } return ""; } @@ -142,7 +139,7 @@ std::string ModeChannelHalfOp::DelHalfOp(User *user,const char *dest,Channel *ch return ""; if (MOD_RESULT == MOD_RES_PASSTHRU) { - if ((user != d) && ((status < STATUS_OP) && (!ServerInstance->ULine(user->server)))) + if ((user != d) && ((status < OP_VALUE) && (!ServerInstance->ULine(user->server)))) { user->WriteServ("482 %s %s :You are not a channel operator",user->nick.c_str(), chan->name.c_str()); return ""; @@ -150,7 +147,7 @@ std::string ModeChannelHalfOp::DelHalfOp(User *user,const char *dest,Channel *ch } } - return ServerInstance->Modes->Revoke(d,chan,UCMODE_HOP); + return d->nick; } return ""; } diff --git a/src/modes/cmode_o.cpp b/src/modes/cmode_o.cpp index 908eb698c..9da9fa478 100644 --- a/src/modes/cmode_o.cpp +++ b/src/modes/cmode_o.cpp @@ -33,7 +33,8 @@ ModePair ModeChannelOp::ModeSet(User*, User*, Channel* channel, const std::strin User* x = ServerInstance->FindNick(parameter); if (x) { - if (channel->GetStatusFlags(x) & UCMODE_OP) + Membership* memb = channel->GetUser(x); + if (memb && memb->hasMode('o')) { return std::make_pair(true, x->nick); } @@ -48,22 +49,18 @@ ModePair ModeChannelOp::ModeSet(User*, User*, Channel* channel, const std::strin void ModeChannelOp::RemoveMode(Channel* channel, irc::modestacker* stack) { - CUList* clist = channel->GetOppedUsers(); - CUList copy; + const UserMembList* clist = channel->GetUsers(); - for (CUList::iterator i = clist->begin(); i != clist->end(); i++) - { - User* n = i->first; - copy.insert(std::make_pair(n,n->nick)); - } - - for (CUList::iterator i = copy.begin(); i != copy.end(); i++) + for (UserMembCIter i = clist->begin(); i != clist->end(); i++) { if (stack) stack->Push(this->GetModeChar(), i->first->nick); else { - std::vector parameters; parameters.push_back(channel->name); parameters.push_back("-o"); parameters.push_back(i->first->nick); + std::vector parameters; + parameters.push_back(channel->name); + parameters.push_back("-o"); + parameters.push_back(i->first->nick); ServerInstance->SendMode(parameters, ServerInstance->FakeClient); } } @@ -75,7 +72,7 @@ void ModeChannelOp::RemoveMode(User*, irc::modestacker* stack) ModeAction ModeChannelOp::OnModeChange(User* source, User*, Channel* channel, std::string ¶meter, bool adding) { - int status = channel->GetStatus(source); + int status = channel->GetPrefixValue(source); /* Call the correct method depending on wether we're adding or removing the mode */ if (adding) @@ -112,7 +109,7 @@ std::string ModeChannelOp::AddOp(User *user,const char* dest,Channel *chan,int s return ""; if (MOD_RESULT == MOD_RES_PASSTHRU) { - if ((status < STATUS_OP) && (!ServerInstance->ULine(user->server))) + if ((status < OP_VALUE) && (!ServerInstance->ULine(user->server))) { user->WriteServ("482 %s %s :You're not a channel operator",user->nick.c_str(), chan->name.c_str()); return ""; @@ -120,7 +117,7 @@ std::string ModeChannelOp::AddOp(User *user,const char* dest,Channel *chan,int s } } - return ServerInstance->Modes->Grant(d,chan,UCMODE_OP); + return d->nick; } return ""; } @@ -140,7 +137,7 @@ std::string ModeChannelOp::DelOp(User *user,const char *dest,Channel *chan,int s return ""; if (MOD_RESULT == MOD_RES_PASSTHRU) { - if ((status < STATUS_OP) && (!ServerInstance->ULine(user->server)) && (IS_LOCAL(user))) + if ((status < OP_VALUE) && (!ServerInstance->ULine(user->server)) && (IS_LOCAL(user))) { user->WriteServ("482 %s %s :You are not a channel operator",user->nick.c_str(), chan->name.c_str()); return ""; @@ -148,7 +145,7 @@ std::string ModeChannelOp::DelOp(User *user,const char *dest,Channel *chan,int s } } - return ServerInstance->Modes->Revoke(d,chan,UCMODE_OP); + return d->nick; } return ""; } diff --git a/src/modes/cmode_v.cpp b/src/modes/cmode_v.cpp index 03dbb5a33..031cefb7f 100644 --- a/src/modes/cmode_v.cpp +++ b/src/modes/cmode_v.cpp @@ -34,7 +34,8 @@ ModePair ModeChannelVoice::ModeSet(User*, User*, Channel* channel, const std::st User* x = ServerInstance->FindNick(parameter); if (x) { - if (channel->GetStatusFlags(x) & UCMODE_VOICE) + Membership* memb = channel->GetUser(x); + if (memb && memb->hasMode('v')) { return std::make_pair(true, x->nick); } @@ -48,22 +49,18 @@ ModePair ModeChannelVoice::ModeSet(User*, User*, Channel* channel, const std::st void ModeChannelVoice::RemoveMode(Channel* channel, irc::modestacker* stack) { - CUList* clist = channel->GetVoicedUsers(); - CUList copy; + const UserMembList* clist = channel->GetUsers(); - for (CUList::iterator i = clist->begin(); i != clist->end(); i++) - { - User* n = i->first; - copy.insert(std::make_pair(n,n->nick)); - } - - for (CUList::iterator i = copy.begin(); i != copy.end(); i++) + for (UserMembCIter i = clist->begin(); i != clist->end(); i++) { if (stack) stack->Push(this->GetModeChar(), i->first->nick); else { - std::vector parameters; parameters.push_back(channel->name); parameters.push_back("-v"); parameters.push_back(i->first->nick); + std::vector parameters; + parameters.push_back(channel->name); + parameters.push_back("-v"); + parameters.push_back(i->first->nick); ServerInstance->SendMode(parameters, ServerInstance->FakeClient); } } @@ -75,7 +72,7 @@ void ModeChannelVoice::RemoveMode(User*, irc::modestacker* stack) ModeAction ModeChannelVoice::OnModeChange(User* source, User*, Channel* channel, std::string ¶meter, bool adding) { - int status = channel->GetStatus(source); + int status = channel->GetPrefixValue(source); /* Call the correct method depending on wether we're adding or removing the mode */ if (adding) @@ -112,7 +109,7 @@ std::string ModeChannelVoice::AddVoice(User *user,const char* dest,Channel *chan return ""; if (MOD_RESULT == MOD_RES_PASSTHRU) { - if ((status < STATUS_HOP) && (!ServerInstance->ULine(user->server))) + if ((status < HALFOP_VALUE) && (!ServerInstance->ULine(user->server))) { user->WriteServ("482 %s %s :You're not a channel (half)operator",user->nick.c_str(), chan->name.c_str()); return ""; @@ -120,7 +117,7 @@ std::string ModeChannelVoice::AddVoice(User *user,const char* dest,Channel *chan } } - return ServerInstance->Modes->Grant(d,chan,UCMODE_VOICE); + return d->nick; } return ""; } @@ -140,7 +137,7 @@ std::string ModeChannelVoice::DelVoice(User *user,const char *dest,Channel *chan return ""; if (MOD_RESULT == MOD_RES_PASSTHRU) { - if ((status < STATUS_HOP) && (!ServerInstance->ULine(user->server))) + if ((status < HALFOP_VALUE) && (!ServerInstance->ULine(user->server))) { user->WriteServ("482 %s %s :You are not a channel (half)operator",user->nick.c_str(), chan->name.c_str()); return ""; @@ -148,7 +145,7 @@ std::string ModeChannelVoice::DelVoice(User *user,const char *dest,Channel *chan } } - return ServerInstance->Modes->Revoke(d,chan,UCMODE_VOICE); + return d->nick; } return ""; } diff --git a/src/modules.cpp b/src/modules.cpp index c7509fad9..2d02bdf6d 100644 --- a/src/modules.cpp +++ b/src/modules.cpp @@ -188,7 +188,7 @@ void Module::OnCleanup(int, void*) { } ModResult Module::OnChannelPreDelete(Channel*) { return MOD_RES_PASSTHRU; } void Module::OnChannelDelete(Channel*) { } ModResult Module::OnSetAway(User*, const std::string &) { return MOD_RES_PASSTHRU; } -ModResult Module::OnUserList(User*, Channel*, CUList*&) { return MOD_RES_PASSTHRU; } +ModResult Module::OnUserList(User*, Channel*) { return MOD_RES_PASSTHRU; } ModResult Module::OnWhoisLine(User*, User*, int&, std::string&) { return MOD_RES_PASSTHRU; } void Module::OnBuildExemptList(MessageType, Channel*, User*, char, CUList&, const std::string&) { } void Module::OnGarbageCollect() { } diff --git a/src/modules/m_auditorium.cpp b/src/modules/m_auditorium.cpp index fda38a885..eb23f7dc8 100644 --- a/src/modules/m_auditorium.cpp +++ b/src/modules/m_auditorium.cpp @@ -84,7 +84,7 @@ class ModuleAuditorium : public Module if (OperOverride && issuer->HasPrivPermission("channels/auspex")) return; - if (ShowOps && (issuer != user) && (channel->GetStatus(user) < STATUS_OP)) + if (ShowOps && (issuer != user) && (channel->GetPrefixValue(user) < OP_VALUE)) { /* Showops is set, hide all non-ops from the user, except themselves */ nick.clear(); @@ -104,11 +104,11 @@ class ModuleAuditorium : public Module if (!OperOverride) return; - CUList *ulist = channel->GetUsers(); - for (CUList::iterator i = ulist->begin(); i != ulist->end(); i++) + const UserMembList *ulist = channel->GetUsers(); + for (UserMembCIter i = ulist->begin(); i != ulist->end(); i++) { if (i->first->HasPrivPermission("channels/auspex") && source != i->first) - if (!ShowOps || (ShowOps && channel->GetStatus(i->first) < STATUS_OP)) + if (!ShowOps || (ShowOps && channel->GetPrefixValue(i->first) < OP_VALUE)) i->first->WriteFrom(source, "%s",text.c_str()); } } @@ -121,7 +121,7 @@ class ModuleAuditorium : public Module /* Because we silenced the event, make sure it reaches the user whos joining (but only them of course) */ user->WriteFrom(user, "JOIN %s", channel->name.c_str()); if (ShowOps) - channel->WriteAllExceptSender(user, false, channel->GetStatus(user) >= STATUS_OP ? 0 : '@', "JOIN %s", channel->name.c_str()); + channel->WriteAllExceptSender(user, false, channel->GetPrefixValue(user) >= OP_VALUE ? 0 : '@', "JOIN %s", channel->name.c_str()); WriteOverride(user, channel, "JOIN "+channel->name); } } @@ -137,7 +137,7 @@ class ModuleAuditorium : public Module partmessage.empty() ? "" : partmessage.c_str()); if (ShowOps) { - channel->WriteAllExceptSender(user, false, channel->GetStatus(user) >= STATUS_OP ? 0 : '@', "PART %s%s%s", channel->name.c_str(), partmessage.empty() ? "" : " :", + channel->WriteAllExceptSender(user, false, channel->GetPrefixValue(user) >= OP_VALUE ? 0 : '@', "PART %s%s%s", channel->name.c_str(), partmessage.empty() ? "" : " :", partmessage.empty() ? "" : partmessage.c_str()); } WriteOverride(user, channel, "PART " + channel->name + (partmessage.empty() ? "" : (" :" + partmessage))); @@ -152,8 +152,8 @@ class ModuleAuditorium : public Module /* Send silenced event only to the user being kicked and the user doing the kick */ source->WriteFrom(source, "KICK %s %s :%s", chan->name.c_str(), user->nick.c_str(), reason.c_str()); if (ShowOps) - chan->WriteAllExceptSender(source, false, chan->GetStatus(user) >= STATUS_OP ? 0 : '@', "KICK %s %s :%s", chan->name.c_str(), user->nick.c_str(), reason.c_str()); - if ((!ShowOps) || (chan->GetStatus(user) < STATUS_OP)) /* make sure the target gets the event */ + chan->WriteAllExceptSender(source, false, chan->GetPrefixValue(user) >= OP_VALUE ? 0 : '@', "KICK %s %s %s", chan->name.c_str(), user->nick.c_str(), reason.c_str()); + if ((!ShowOps) || (chan->GetPrefixValue(user) < OP_VALUE)) /* make sure the target gets the event */ user->WriteFrom(source, "KICK %s %s :%s", chan->name.c_str(), user->nick.c_str(), reason.c_str()); WriteOverride(source, chan, "KICK " + chan->name + " " + user->nick + " :" + reason); } @@ -162,7 +162,7 @@ class ModuleAuditorium : public Module ModResult OnHostCycle(User* user) { for (UCListIter f = user->chans.begin(); f != user->chans.end(); f++) - if (f->first->IsModeSet('u')) + if ((*f)->IsModeSet('u')) return MOD_RES_DENY; return MOD_RES_PASSTHRU; @@ -176,8 +176,8 @@ class ModuleAuditorium : public Module { for (UCListIter f = user->chans.begin(); f != user->chans.end(); f++) { - if (f->first->IsModeSet('u')) - to_leave.push_back(f->first->name); + if ((*f)->IsModeSet('u')) + to_leave.push_back((*f)->name); } /* We cant do this neatly in one loop, as we are modifying the map we are iterating */ for (std::vector::iterator n = to_leave.begin(); n != to_leave.end(); n++) diff --git a/src/modules/m_banredirect.cpp b/src/modules/m_banredirect.cpp index da08d06fb..b7eb6f1ae 100644 --- a/src/modules/m_banredirect.cpp +++ b/src/modules/m_banredirect.cpp @@ -131,7 +131,7 @@ class BanRedirect : public ModeWatcher source->WriteNumeric(690, "%s :Target channel %s must exist to be set as a redirect.",source->nick.c_str(),mask[CHAN].c_str()); return false; } - else if (c->GetStatus(source) < STATUS_OP) + else if (c->GetPrefixValue(source) < OP_VALUE) { source->WriteNumeric(690, "%s :You must be opped on %s to set it as a redirect.",source->nick.c_str(), mask[CHAN].c_str()); return false; diff --git a/src/modules/m_blockcaps.cpp b/src/modules/m_blockcaps.cpp index ca1bc5a2b..135e072b1 100644 --- a/src/modules/m_blockcaps.cpp +++ b/src/modules/m_blockcaps.cpp @@ -60,7 +60,7 @@ public: Channel* c = (Channel*)dest; - if (CHANOPS_EXEMPT(ServerInstance, 'B') && c->GetStatus(user) == STATUS_OP) + if (CHANOPS_EXEMPT(ServerInstance, 'B') && c->GetPrefixValue(user) == OP_VALUE) { return MOD_RES_PASSTHRU; } diff --git a/src/modules/m_blockcolor.cpp b/src/modules/m_blockcolor.cpp index 5bd86bccf..1aa2a1bd9 100644 --- a/src/modules/m_blockcolor.cpp +++ b/src/modules/m_blockcolor.cpp @@ -48,7 +48,7 @@ class ModuleBlockColour : public Module { Channel* c = (Channel*)dest; - if (CHANOPS_EXEMPT(ServerInstance, 'c') && c->GetStatus(user) == STATUS_OP) + if (CHANOPS_EXEMPT(ServerInstance, 'c') && c->GetPrefixValue(user) == OP_VALUE) { return MOD_RES_PASSTHRU; } diff --git a/src/modules/m_cap.h b/src/modules/m_cap.h index 72c7a14a5..a37580126 100644 --- a/src/modules/m_cap.h +++ b/src/modules/m_cap.h @@ -32,7 +32,7 @@ class GenericCap public: LocalIntExt ext; const std::string cap; - GenericCap(Module* parent, const std::string &Cap) : ext("cap_" + cap, parent), cap(Cap) + GenericCap(Module* parent, const std::string &Cap) : ext("cap_" + Cap, parent), cap(Cap) { Extensible::Register(&ext); } diff --git a/src/modules/m_censor.cpp b/src/modules/m_censor.cpp index 6050d49ab..2ffe2ab45 100644 --- a/src/modules/m_censor.cpp +++ b/src/modules/m_censor.cpp @@ -77,7 +77,7 @@ class ModuleCensor : public Module { active = ((Channel*)dest)->IsModeSet('G'); Channel* c = (Channel*)dest; - if (CHANOPS_EXEMPT(ServerInstance, 'G') && c->GetStatus(user) == STATUS_OP) + if (CHANOPS_EXEMPT(ServerInstance, 'G') && c->GetPrefixValue(user) == OP_VALUE) { return MOD_RES_PASSTHRU; } diff --git a/src/modules/m_chanfilter.cpp b/src/modules/m_chanfilter.cpp index 4636d2372..1079505d5 100644 --- a/src/modules/m_chanfilter.cpp +++ b/src/modules/m_chanfilter.cpp @@ -85,7 +85,7 @@ class ModuleChanFilter : public Module virtual ModResult ProcessMessages(User* user,Channel* chan,std::string &text) { - if (!IS_LOCAL(user) || (CHANOPS_EXEMPT(ServerInstance, 'g') && chan->GetStatus(user) == STATUS_OP)) + if (!IS_LOCAL(user) || (CHANOPS_EXEMPT(ServerInstance, 'g') && chan->GetPrefixValue(user) == OP_VALUE)) return MOD_RES_PASSTHRU; modelist* list = cf.extItem.get(chan); diff --git a/src/modules/m_channelban.cpp b/src/modules/m_channelban.cpp index fd5d5d401..727ab15a3 100644 --- a/src/modules/m_channelban.cpp +++ b/src/modules/m_channelban.cpp @@ -39,7 +39,7 @@ class ModuleBadChannelExtban : public Module ModResult rv; for (UCListIter i = user->chans.begin(); i != user->chans.end(); i++) { - rv = rv + c->GetExtBanStatus(i->first->name, 'j'); + rv = rv + c->GetExtBanStatus((*i)->name, 'j'); } return rv; diff --git a/src/modules/m_chanprotect.cpp b/src/modules/m_chanprotect.cpp index bc52a53a1..15481fb7f 100644 --- a/src/modules/m_chanprotect.cpp +++ b/src/modules/m_chanprotect.cpp @@ -24,17 +24,17 @@ class FounderProtectBase { private: - InspIRCd* MyInstance; - std::string extend; - std::string type; - int list; - int end; + InspIRCd* const MyInstance; + const std::string type; + const char mode; + const int list; + const int end; protected: bool& remove_own_privs; bool& remove_other_privs; public: - FounderProtectBase(InspIRCd* Instance, const std::string &ext, const std::string &mtype, int l, int e, bool &remove_own, bool &remove_others) : - MyInstance(Instance), extend(ext), type(mtype), list(l), end(e), remove_own_privs(remove_own), remove_other_privs(remove_others) + FounderProtectBase(InspIRCd* Instance, char Mode, const std::string &mtype, int l, int e, bool &remove_own, bool &remove_others) : + MyInstance(Instance), type(mtype), mode(Mode), list(l), end(e), remove_own_privs(remove_own), remove_other_privs(remove_others) { } @@ -43,14 +43,14 @@ class FounderProtectBase User* x = MyInstance->FindNick(parameter); if (x) { - if (!channel->HasUser(x)) + Membership* memb = channel->GetUser(x); + if (!memb) { return std::make_pair(false, parameter); } else { - std::string item = extend+std::string(channel->name); - if (x->GetExt(item)) + if (memb->hasMode(mode)) { return std::make_pair(true, x->nick); } @@ -63,23 +63,22 @@ class FounderProtectBase return std::make_pair(false, parameter); } - void RemoveMode(Channel* channel, char mc, irc::modestacker* stack) + void RemoveMode(Channel* channel, irc::modestacker* stack) { - CUList* cl = channel->GetUsers(); - std::string item = extend + std::string(channel->name); + const UserMembList* cl = channel->GetUsers(); std::vector mode_junk; mode_junk.push_back(channel->name); irc::modestacker modestack(MyInstance, false); std::deque stackresult; - for (CUList::iterator i = cl->begin(); i != cl->end(); i++) + for (UserMembCIter i = cl->begin(); i != cl->end(); i++) { - if (i->first->GetExt(item)) + if (i->second->hasMode(mode)) { if (stack) - stack->Push(mc, i->first->nick); + stack->Push(mode, i->first->nick); else - modestack.Push(mc, i->first->nick); + modestack.Push(mode, i->first->nick); } } @@ -96,11 +95,10 @@ class FounderProtectBase void DisplayList(User* user, Channel* channel) { - CUList* cl = channel->GetUsers(); - std::string item = extend+std::string(channel->name); - for (CUList::reverse_iterator i = cl->rbegin(); i != cl->rend(); ++i) + const UserMembList* cl = channel->GetUsers(); + for (UserMembCIter i = cl->begin(); i != cl->end(); ++i) { - if (i->first->GetExt(item)) + if (i->second->hasMode(mode)) { user->WriteServ("%d %s %s %s", list, user->nick.c_str(), channel->name.c_str(), i->first->nick.c_str()); } @@ -108,46 +106,10 @@ class FounderProtectBase user->WriteServ("%d %s %s :End of channel %s list", end, user->nick.c_str(), channel->name.c_str(), type.c_str()); } - User* FindAndVerify(std::string ¶meter, Channel* channel) - { - User* theuser = MyInstance->FindNick(parameter); - if ((!theuser) || (!channel->HasUser(theuser))) - { - parameter.clear(); - return NULL; - } - return theuser; - } - - bool CanRemoveOthers(User* u1, User* u2, Channel* c) + bool CanRemoveOthers(User* u1, Channel* c) { - std::string item = extend+std::string(c->name); - return (remove_other_privs && u1->GetExt(item) && u2->GetExt(item)); - } - - ModeAction HandleChange(User* source, User* theuser, bool adding, Channel* channel, std::string ¶meter) - { - std::string item = extend+std::string(channel->name); - - if (adding) - { - if (!theuser->GetExt(item)) - { - theuser->Extend(item); - parameter = theuser->nick; - return MODEACTION_ALLOW; - } - } - else - { - if (theuser->GetExt(item)) - { - theuser->Shrink(item); - parameter = theuser->nick; - return MODEACTION_ALLOW; - } - } - return MODEACTION_DENY; + Membership* m1 = c->GetUser(u1); + return (remove_other_privs && m1 && m1->hasMode(mode)); } }; @@ -158,7 +120,7 @@ class ChanFounder : public ModeHandler, public FounderProtectBase public: ChanFounder(InspIRCd* Instance, Module* Creator, char my_prefix, bool &depriv_self, bool &depriv_others) : ModeHandler(Instance, Creator, 'q', 1, 1, true, MODETYPE_CHANNEL, false, my_prefix, 0, TR_NICK), - FounderProtectBase(Instance, "cm_founder_", "founder", 386, 387, depriv_self, depriv_others) { } + FounderProtectBase(Instance, 'q', "founder", 386, 387, depriv_self, depriv_others) { } unsigned int GetPrefixRank() { @@ -172,7 +134,7 @@ class ChanFounder : public ModeHandler, public FounderProtectBase void RemoveMode(Channel* channel, irc::modestacker* stack) { - FounderProtectBase::RemoveMode(channel, this->GetModeChar(), stack); + FounderProtectBase::RemoveMode(channel, stack); } void RemoveMode(User* user, irc::modestacker* stack) @@ -181,16 +143,16 @@ class ChanFounder : public ModeHandler, public FounderProtectBase ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string ¶meter, bool adding) { - User* theuser = FounderProtectBase::FindAndVerify(parameter, channel); + User* theuser = ServerInstance->FindNick(parameter); if (!theuser) { return MODEACTION_DENY; } - if ((!adding) && FounderProtectBase::CanRemoveOthers(source, theuser, channel)) + if ((!adding) && FounderProtectBase::CanRemoveOthers(source, channel)) { - return FounderProtectBase::HandleChange(source, theuser, adding, channel, parameter); + return MODEACTION_ALLOW; } char isoverride=0; @@ -202,15 +164,14 @@ class ChanFounder : public ModeHandler, public FounderProtectBase isoverride = tmp[0]; } // source is a server, or ulined, we'll let them +-q the user. - if (source == ServerInstance->FakeClient || + if (!IS_LOCAL(source) || ((source == theuser) && (!adding) && (FounderProtectBase::remove_own_privs)) || (ServerInstance->ULine(source->nick.c_str())) || (ServerInstance->ULine(source->server)) || (!*source->server) || - (!IS_LOCAL(source)) || isoverride) { - return FounderProtectBase::HandleChange(source, theuser, adding, channel, parameter); + return MODEACTION_ALLOW; } else { @@ -234,7 +195,7 @@ class ChanProtect : public ModeHandler, public FounderProtectBase public: ChanProtect(InspIRCd* Instance, Module* Creator, char my_prefix, bool &depriv_self, bool &depriv_others) : ModeHandler(Instance, Creator, 'a', 1, 1, true, MODETYPE_CHANNEL, false, my_prefix, 0, TR_NICK), - FounderProtectBase(Instance,"cm_protect_","protected user", 388, 389, depriv_self, depriv_others) { } + FounderProtectBase(Instance,'a',"protected user", 388, 389, depriv_self, depriv_others) { } unsigned int GetPrefixRank() { @@ -248,7 +209,7 @@ class ChanProtect : public ModeHandler, public FounderProtectBase void RemoveMode(Channel* channel, irc::modestacker* stack) { - FounderProtectBase::RemoveMode(channel, this->GetModeChar(), stack); + FounderProtectBase::RemoveMode(channel, stack); } void RemoveMode(User* user, irc::modestacker* stack) @@ -257,16 +218,14 @@ class ChanProtect : public ModeHandler, public FounderProtectBase ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string ¶meter, bool adding) { - User* theuser = FounderProtectBase::FindAndVerify(parameter, channel); + User* theuser = ServerInstance->FindNick(parameter); if (!theuser) return MODEACTION_DENY; - std::string founder = "cm_founder_"+std::string(channel->name); - - if ((!adding) && FounderProtectBase::CanRemoveOthers(source, theuser, channel)) + if ((!adding) && FounderProtectBase::CanRemoveOthers(source, channel)) { - return FounderProtectBase::HandleChange(source, theuser, adding, channel, parameter); + return MODEACTION_ALLOW; } char isoverride=0; @@ -278,17 +237,16 @@ class ChanProtect : public ModeHandler, public FounderProtectBase isoverride = tmp[0]; } // source has +q, is a server, or ulined, we'll let them +-a the user. - if (source == ServerInstance->FakeClient || + if (!IS_LOCAL(source) || ((source == theuser) && (!adding) && (FounderProtectBase::remove_own_privs)) || (ServerInstance->ULine(source->nick.c_str())) || (ServerInstance->ULine(source->server)) || (!*source->server) || - (source->GetExt(founder)) || - (!IS_LOCAL(source)) || + (channel->GetPrefixValue(source) > PROTECT_VALUE) || isoverride ) { - return FounderProtectBase::HandleChange(source, theuser, adding, channel, parameter); + return MODEACTION_ALLOW; } else { @@ -342,20 +300,6 @@ class ModuleChanProtect : public Module ServerInstance->Modules->Attach(eventlist, this, 4); } - virtual void OnUserKick(User* source, User* user, Channel* chan, const std::string &reason, bool &silent) - { - // FIX: when someone gets kicked from a channel we must remove their Extensibles! - user->Shrink("cm_founder_"+std::string(chan->name)); - user->Shrink("cm_protect_"+std::string(chan->name)); - } - - virtual void OnUserPart(User* user, Channel* channel, std::string &partreason, bool &silent) - { - // FIX: when someone parts a channel we must remove their Extensibles! - user->Shrink("cm_founder_"+std::string(channel->name)); - user->Shrink("cm_protect_"+std::string(channel->name)); - } - void LoadSettings() { ConfigReader Conf(ServerInstance); @@ -403,34 +347,33 @@ class ModuleChanProtect : public Module // always allow the action if: // (A) The source is ulined - // firstly, if a ulined nick, or a server, is setting the mode, then allow them to set the mode - // without any access checks, we're not worthy :p if ((ServerInstance->ULine(source->nick.c_str())) || (ServerInstance->ULine(source->server)) || (!*source->server)) - return MOD_RES_ALLOW; + return MOD_RES_PASSTHRU; if (!channel) return MOD_RES_PASSTHRU; - std::string founder("cm_founder_"+channel->name); - std::string protect("cm_protect_"+channel->name); - // Can do anything to yourself if deprotectself is enabled. if (DeprivSelf && source == dest) return MOD_RES_PASSTHRU; - bool candepriv_founder = (DeprivOthers && source->GetExt(founder)); - bool candepriv_protected = (source->GetExt(founder) || (DeprivOthers && source->GetExt(protect))); // Can the source remove +a? + Membership* smemb = channel->GetUser(source); + Membership* dmemb = channel->GetUser(source); + bool candepriv_founder = (DeprivOthers && smemb && smemb->hasMode('q')); + bool candepriv_protect = smemb && (smemb->hasMode('q') || (DeprivOthers && smemb->hasMode('a'))); + bool desthas_founder = dmemb->hasMode('q'); + bool desthas_protect = dmemb->hasMode('a'); switch (access_type) { // a user has been deopped. Do we let them? hmmm... case AC_DEOP: - if (dest->GetExt(founder) && !candepriv_founder) + if (desthas_founder && !candepriv_founder) { source->WriteNumeric(484, source->nick+" "+channel->name+" :Can't deop "+dest->nick+" as they're a channel founder"); return MOD_RES_DENY; } - if ((dest->GetExt(protect)) && !candepriv_protected) + if (desthas_protect && !candepriv_protect) { source->WriteNumeric(484, source->nick+" "+channel->name+" :Can't deop "+dest->nick+" as they're protected (+a)"); return MOD_RES_DENY; @@ -439,12 +382,12 @@ class ModuleChanProtect : public Module // a user is being kicked. do we chop off the end of the army boot? case AC_KICK: - if (dest->GetExt(founder) && !candepriv_founder) + if (desthas_founder && !candepriv_founder) { source->WriteNumeric(484, source->nick+" "+channel->name+" :Can't kick "+dest->nick+" as they're a channel founder"); return MOD_RES_DENY; } - if ((dest->GetExt(protect)) && !candepriv_protected) + if (desthas_protect && !candepriv_protect) { source->WriteNumeric(484, source->nick+" "+channel->name+" :Can't kick "+dest->nick+" as they're protected (+a)"); return MOD_RES_DENY; @@ -453,12 +396,12 @@ class ModuleChanProtect : public Module // a user is being dehalfopped. Yes, we do disallow -h of a +ha user case AC_DEHALFOP: - if (dest->GetExt(founder) && !candepriv_founder) + if (desthas_founder && !candepriv_founder) { source->WriteNumeric(484, source->nick+" "+channel->name+" :Can't de-halfop "+dest->nick+" as they're a channel founder"); return MOD_RES_DENY; } - if ((dest->GetExt(protect)) && !candepriv_protected) + if (desthas_protect && !candepriv_protect) { source->WriteNumeric(484, source->nick+" "+channel->name+" :Can't de-halfop "+dest->nick+" as they're protected (+a)"); return MOD_RES_DENY; @@ -467,12 +410,12 @@ class ModuleChanProtect : public Module // same with devoice. case AC_DEVOICE: - if (dest->GetExt(founder) && !candepriv_founder) + if (desthas_founder && !candepriv_founder) { source->WriteNumeric(484, source->nick+" "+channel->name+" :Can't devoice "+dest->nick+" as they're a channel founder"); return MOD_RES_DENY; } - if ((dest->GetExt(protect)) && !candepriv_protected) + if (desthas_protect && !candepriv_protect) { source->WriteNumeric(484, source->nick+" "+channel->name+" :Can't devoice "+dest->nick+" as they're protected (+a)"); return MOD_RES_DENY; @@ -494,7 +437,7 @@ class ModuleChanProtect : public Module virtual Version GetVersion() { - return Version("$Id$", VF_COMMON | VF_VENDOR, API_VERSION); + return Version("Founder and Protect modes (+qa)", VF_COMMON | VF_VENDOR); } }; diff --git a/src/modules/m_check.cpp b/src/modules/m_check.cpp index 964a8c075..33f950b4c 100644 --- a/src/modules/m_check.cpp +++ b/src/modules/m_check.cpp @@ -140,10 +140,10 @@ class CommandCheck : public Command /* now the ugly bit, spool current members of a channel. :| */ - CUList *ulist= targchan->GetUsers(); + const UserMembList *ulist= targchan->GetUsers(); /* note that unlike /names, we do NOT check +i vs in the channel */ - for (CUList::iterator i = ulist->begin(); i != ulist->end(); i++) + for (UserMembCIter i = ulist->begin(); i != ulist->end(); i++) { char tmpbuf[MAXBUF]; /* diff --git a/src/modules/m_cycle.cpp b/src/modules/m_cycle.cpp index 1348feeb3..8caa07b62 100644 --- a/src/modules/m_cycle.cpp +++ b/src/modules/m_cycle.cpp @@ -50,7 +50,7 @@ class CommandCycle : public Command */ if (IS_LOCAL(user)) { - if (channel->GetStatus(user) < STATUS_VOICE && channel->IsBanned(user)) + if (channel->GetPrefixValue(user) < VOICE_VALUE && channel->IsBanned(user)) { /* banned, boned. drop the message. */ user->WriteServ("NOTICE "+std::string(user->nick)+" :*** You may not cycle, as you are banned on channel " + channel->name); diff --git a/src/modules/m_dccallow.cpp b/src/modules/m_dccallow.cpp index 90c63e30d..a61582629 100644 --- a/src/modules/m_dccallow.cpp +++ b/src/modules/m_dccallow.cpp @@ -43,6 +43,7 @@ typedef std::vector dccallowlist; dccallowlist* dl; typedef std::vector bannedfilelist; bannedfilelist bfl; +SimpleExtItem* ext; class CommandDccallow : public Command { @@ -97,7 +98,8 @@ class CommandDccallow : public Command if (action == '-') { // check if it contains any entries - if (user->GetExt("dccallow_list", dl)) + dl = ext->get(user); + if (dl) { for (dccallowlist::iterator i = dl->begin(); i != dl->end(); ++i) { @@ -110,22 +112,6 @@ class CommandDccallow : public Command } } } - else - { - delete dl; - user->Shrink("dccallow_list"); - - // remove from userlist - for (userlist::iterator j = ul.begin(); j != ul.end(); ++j) - { - User* u = (User*)(*j); - if (u == user) - { - ul.erase(j); - break; - } - } - } } else if (action == '+') { @@ -135,10 +121,11 @@ class CommandDccallow : public Command return CMD_FAILURE; } - if (!user->GetExt("dccallow_list", dl)) + dl = ext->get(user); + if (!dl) { dl = new dccallowlist; - user->Extend("dccallow_list", dl); + ext->set(user, dl); // add this user to the userlist ul.push_back(user); } @@ -233,7 +220,8 @@ class CommandDccallow : public Command // display current DCCALLOW list user->WriteNumeric(990, "%s :Users on your DCCALLOW list:", user->nick.c_str()); - if (user->GetExt("dccallow_list", dl)) + dl = ext->get(user); + if (dl) { for (dccallowlist::const_iterator c = dl->begin(); c != dl->end(); ++c) { @@ -255,6 +243,8 @@ class ModuleDCCAllow : public Module : Module(Me), cmd(Me, this) { Conf = new ConfigReader(ServerInstance); + ext = new SimpleExtItem("dccallow", this); + Extensible::Register(ext); ServerInstance->AddCommand(&cmd); ReadFileConf(); Implementation eventlist[] = { I_OnUserPreMessage, I_OnUserPreNotice, I_OnUserQuit, I_OnUserPreNick, I_OnRehash }; @@ -271,13 +261,11 @@ class ModuleDCCAllow : public Module virtual void OnUserQuit(User* user, const std::string &reason, const std::string &oper_message) { - dccallowlist* udl; + dccallowlist* udl = ext->get(user); // remove their DCCALLOW list if they have one - if (user->GetExt("dccallow_list", udl)) + if (udl) { - delete udl; - user->Shrink("dccallow_list"); RemoveFromUserlist(user); } @@ -286,7 +274,6 @@ class ModuleDCCAllow : public Module RemoveNick(user); } - virtual ModResult OnUserPreNick(User* user, const std::string &newnick) { RemoveNick(user); @@ -320,7 +307,8 @@ class ModuleDCCAllow : public Module if (strncmp(text.c_str(), "\1DCC ", 5) == 0) { - if (u->GetExt("dccallow_list", dl) && dl->size()) + dl = ext->get(u); + if (dl && dl->size()) { for (dccallowlist::const_iterator iter = dl->begin(); iter != dl->end(); ++iter) if (InspIRCd::Match(user->GetFullHost(), iter->hostmask)) @@ -387,7 +375,8 @@ class ModuleDCCAllow : public Module for (userlist::iterator iter = ul.begin(); iter != ul.end(); ++iter) { User* u = (User*)(*iter); - if (u->GetExt("dccallow_list", dl)) + dl = ext->get(u); + if (dl) { if (dl->size()) { @@ -419,7 +408,8 @@ class ModuleDCCAllow : public Module for (userlist::iterator iter = ul.begin(); iter != ul.end(); ++iter) { User *u = (User*)(*iter); - if (u->GetExt("dccallow_list", dl)) + dl = ext->get(u); + if (dl) { if (dl->size()) { @@ -475,6 +465,7 @@ class ModuleDCCAllow : public Module virtual ~ModuleDCCAllow() { delete Conf; + delete ext; Conf = NULL; } diff --git a/src/modules/m_deaf.cpp b/src/modules/m_deaf.cpp index aaa3696b5..caad1feb1 100644 --- a/src/modules/m_deaf.cpp +++ b/src/modules/m_deaf.cpp @@ -105,7 +105,7 @@ class ModuleDeaf : public Module virtual void BuildDeafList(MessageType message_type, Channel* chan, User* sender, char status, const std::string &text, CUList &exempt_list) { - CUList *ulist = chan->GetUsers(); + const UserMembList *ulist = chan->GetUsers(); bool is_a_uline; bool is_bypasschar, is_bypasschar_avail; bool is_bypasschar_uline, is_bypasschar_uline_avail; @@ -131,7 +131,7 @@ class ModuleDeaf : public Module if (!is_bypasschar_uline_avail && is_bypasschar) return; - for (CUList::iterator i = ulist->begin(); i != ulist->end(); i++) + for (UserMembCIter i = ulist->begin(); i != ulist->end(); i++) { /* not +d ? */ if (!i->first->IsModeSet('d')) @@ -152,7 +152,7 @@ class ModuleDeaf : public Module continue; /* don't deliver message! */ - exempt_list[i->first] = i->first->nick; + exempt_list.insert(i->first); } } diff --git a/src/modules/m_delayjoin.cpp b/src/modules/m_delayjoin.cpp index 9ccb89167..c894db124 100644 --- a/src/modules/m_delayjoin.cpp +++ b/src/modules/m_delayjoin.cpp @@ -26,21 +26,20 @@ class DelayJoinMode : public ModeHandler class ModuleDelayJoin : public Module { - private: DelayJoinMode djm; - CUList nl; public: - ModuleDelayJoin(InspIRCd* Me) : Module(Me), djm(Me, this) + LocalIntExt unjoined; + ModuleDelayJoin(InspIRCd* Me) : Module(Me), djm(Me, this), unjoined("delayjoin", this) { if (!ServerInstance->Modes->AddMode(&djm)) throw ModuleException("Could not add new modes!"); Implementation eventlist[] = { I_OnUserJoin, I_OnUserPart, I_OnUserKick, I_OnUserQuit, I_OnNamesListItem, I_OnText, I_OnHostCycle }; ServerInstance->Modules->Attach(eventlist, this, 7); } - virtual ~ModuleDelayJoin(); - virtual Version GetVersion(); - virtual void OnNamesListItem(User* issuer, User* user, Channel* channel, std::string &prefixes, std::string &nick); - virtual void OnUserJoin(User* user, Channel* channel, bool sync, bool &silent, bool created); + ~ModuleDelayJoin(); + Version GetVersion(); + void OnNamesListItem(User* issuer, User* user, Channel* channel, std::string &prefixes, std::string &nick); + void OnUserJoin(User* user, Channel* channel, bool sync, bool &silent, bool created); void CleanUser(User* user); ModResult OnHostCycle(User* user); void OnUserPart(User* user, Channel* channel, std::string &partmessage, bool &silent); @@ -64,8 +63,8 @@ ModeAction DelayJoinMode::OnModeChange(User* source, User* dest, Channel* channe * Make all users visible, as +D is being removed. If we don't do this, * they remain permanently invisible on this channel! */ - CUList* names = channel->GetUsers(); - for (CUListIter n = names->begin(); n != names->end(); ++n) + const UserMembList* names = channel->GetUsers(); + for (UserMembCIter n = names->begin(); n != names->end(); ++n) creator->OnText(n->first, channel, TYPE_CHANNEL, "", 0, empty); } channel->SetMode('D', adding); @@ -79,7 +78,7 @@ ModuleDelayJoin::~ModuleDelayJoin() Version ModuleDelayJoin::GetVersion() { - return Version("$Id$", VF_COMMON | VF_VENDOR, API_VERSION); + return Version("$Id$", VF_COMMON | VF_VENDOR); } void ModuleDelayJoin::OnNamesListItem(User* issuer, User* user, Channel* channel, std::string &prefixes, std::string &nick) @@ -94,8 +93,9 @@ void ModuleDelayJoin::OnNamesListItem(User* issuer, User* user, Channel* channel if (issuer == user) return; + Membership* memb = channel->GetUser(user); /* If the user is hidden by delayed join, hide them from the NAMES list */ - if (user->GetExt("delayjoin_"+channel->name)) + if (memb && unjoined.get(memb)) nick.clear(); } @@ -107,79 +107,55 @@ void ModuleDelayJoin::OnUserJoin(User* user, Channel* channel, bool sync, bool & /* Because we silenced the event, make sure it reaches the user whos joining (but only them of course) */ user->WriteFrom(user, "JOIN %s", channel->name.c_str()); - /* This metadata tells the module the user is delayed join on this specific channel */ - user->Extend("delayjoin_"+channel->name); + Membership* memb = channel->GetUser(user); - /* This metadata tells the module the user is delayed join on at least one (or more) channels. - * It is only cleared when the user is no longer on ANY +D channels. - */ - if (!user->GetExt("delayjoin")) - user->Extend("delayjoin"); + unjoined.set(memb, 1); } } -void ModuleDelayJoin::CleanUser(User* user) -{ - /* Check if the user is hidden on any other +D channels, if so don't take away the - * metadata that says they're hidden on one or more channels - */ - for (UCListIter f = user->chans.begin(); f != user->chans.end(); f++) - if (user->GetExt("delayjoin_" + f->first->name)) - return; - - user->Shrink("delayjoin"); -} - void ModuleDelayJoin::OnUserPart(User* user, Channel* channel, std::string &partmessage, bool &silent) { - if (!channel->IsModeSet('D')) - return; - if (user->GetExt("delayjoin_"+channel->name)) + Membership* memb = channel->GetUser(user); + if (unjoined.set(memb, 0)) { - user->Shrink("delayjoin_"+channel->name); silent = true; /* Because we silenced the event, make sure it reaches the user whos leaving (but only them of course) */ user->WriteFrom(user, "PART %s%s%s", channel->name.c_str(), partmessage.empty() ? "" : " :", partmessage.empty() ? "" : partmessage.c_str()); - CleanUser(user); } } void ModuleDelayJoin::OnUserKick(User* source, User* user, Channel* chan, const std::string &reason, bool &silent) { - if (!chan->IsModeSet('D')) - return; - /* Send silenced event only to the user being kicked and the user doing the kick */ - if (user->GetExt("delayjoin_"+chan->name)) + Membership* memb = chan->GetUser(user); + if (unjoined.set(memb, 0)) { - user->Shrink("delayjoin_"+chan->name); silent = true; user->WriteFrom(source, "KICK %s %s %s", chan->name.c_str(), user->nick.c_str(), reason.c_str()); - CleanUser(user); } } ModResult ModuleDelayJoin::OnHostCycle(User* user) { - return user->GetExt("delayjoin") ? MOD_RES_DENY : MOD_RES_PASSTHRU; + // TODO + return MOD_RES_DENY; } void ModuleDelayJoin::OnUserQuit(User* user, const std::string &reason, const std::string &oper_message) { Command* parthandler = ServerInstance->Parser->GetHandler("PART"); - if (parthandler && user->GetExt("delayjoin")) + if (!parthandler) + return; + for (UCListIter f = user->chans.begin(); f != user->chans.end(); f++) { - for (UCListIter f = user->chans.begin(); f != user->chans.end(); f++) + Channel* chan = *f; + Membership* memb = chan->GetUser(user); + if (memb && unjoined.get(memb)) { - Channel* chan = f->first; - if (user->GetExt("delayjoin_"+chan->name)) - { - std::vector parameters; - parameters.push_back(chan->name); - /* Send a fake PART from the channel, which will be silent */ - parthandler->Handle(parameters, user); - } + std::vector parameters; + parameters.push_back(chan->name); + /* Send a fake PART from the channel, which will be silent */ + parthandler->Handle(parameters, user); } - user->Shrink("delayjoin"); } } @@ -194,43 +170,16 @@ void ModuleDelayJoin::OnText(User* user, void* dest, int target_type, const std: Channel* channel = (Channel*) dest; - if (!user->GetExt("delayjoin_"+channel->name)) + Membership* memb = channel->GetUser(user); + if (!memb || !unjoined.set(memb, 0)) return; /* Display the join to everyone else (the user who joined got it earlier) */ - this->WriteCommonFrom(user, channel, "JOIN %s", channel->name.c_str()); + channel->WriteAllExceptSender(user, false, 0, "JOIN %s", channel->name.c_str()); std::string n = this->ServerInstance->Modes->ModeString(user, channel); if (n.length() > 0) this->WriteCommonFrom(user, channel, "MODE %s +%s", channel->name.c_str(), n.c_str()); - - /* Shrink off the neccessary metadata for a specific channel */ - user->Shrink("delayjoin_"+channel->name); - CleanUser(user); -} - -// .. is there a real need to duplicate WriteCommonExcept? -void ModuleDelayJoin::WriteCommonFrom(User *user, Channel* channel, const char* text, ...) -{ - va_list argsPtr; - char textbuffer[MAXBUF]; - char tb[MAXBUF]; - - va_start(argsPtr, text); - vsnprintf(textbuffer, MAXBUF, text, argsPtr); - va_end(argsPtr); - snprintf(tb,MAXBUF,":%s %s",user->GetFullHost().c_str(), textbuffer); - - CUList *ulist = channel->GetUsers(); - - for (CUList::iterator i = ulist->begin(); i != ulist->end(); i++) - { - /* User doesnt get a JOIN sent to themselves */ - if (user == i->first) - continue; - - i->first->Write(std::string(tb)); - } } MODULE_INIT(ModuleDelayJoin) diff --git a/src/modules/m_delaymsg.cpp b/src/modules/m_delaymsg.cpp index b5fdd8238..5e2bb838c 100644 --- a/src/modules/m_delaymsg.cpp +++ b/src/modules/m_delaymsg.cpp @@ -21,7 +21,8 @@ class DelayMsgMode : public ModeHandler private: CUList empty; public: - DelayMsgMode(InspIRCd* Instance, Module* Parent) : ModeHandler(Instance, Parent, 'd', 1, 0, false, MODETYPE_CHANNEL, false, 0, '@') {}; + LocalIntExt jointime; + DelayMsgMode(InspIRCd* Instance, Module* Parent) : ModeHandler(Instance, Parent, 'd', 1, 0, false, MODETYPE_CHANNEL, false, 0, '@'), jointime("delaymsg", Parent) {}; ModePair ModeSet(User*, User*, Channel* channel, const std::string ¶meter) { @@ -53,11 +54,12 @@ class ModuleDelayMsg : public Module { if (!ServerInstance->Modes->AddMode(&djm)) throw ModuleException("Could not add new modes!"); - Implementation eventlist[] = { I_OnUserJoin, I_OnUserPart, I_OnUserKick, I_OnCleanup, I_OnUserPreMessage}; - ServerInstance->Modules->Attach(eventlist, this, 5); + Extensible::Register(&djm.jointime); + Implementation eventlist[] = { I_OnUserJoin, I_OnUserPreMessage}; + ServerInstance->Modules->Attach(eventlist, this, 2); } - virtual ~ModuleDelayMsg(); - virtual Version GetVersion(); + ~ModuleDelayMsg(); + Version GetVersion(); void OnUserJoin(User* user, Channel* channel, bool sync, bool &silent, bool created); void OnUserPart(User* user, Channel* channel, std::string &partmessage, bool &silent); void OnUserKick(User* source, User* user, Channel* chan, const std::string &reason, bool &silent); @@ -83,9 +85,9 @@ ModeAction DelayMsgMode::OnModeChange(User* source, User* dest, Channel* channel /* * Clean up metadata */ - CUList* names = channel->GetUsers(); - for (CUListIter n = names->begin(); n != names->end(); ++n) - n->first->Shrink("delaymsg_" + channel->name); + const UserMembList* names = channel->GetUsers(); + for (UserMembCIter n = names->begin(); n != names->end(); ++n) + jointime.set(n->second, 0); } channel->SetModeParam('d', adding ? parameter : ""); return MODEACTION_ALLOW; @@ -104,29 +106,9 @@ Version ModuleDelayMsg::GetVersion() void ModuleDelayMsg::OnUserJoin(User* user, Channel* channel, bool sync, bool &silent, bool created) { if (channel->IsModeSet('d')) - user->Extend("delaymsg_"+channel->name, reinterpret_cast(ServerInstance->Time())); -} - -void ModuleDelayMsg::OnUserPart(User* user, Channel* channel, std::string &partmessage, bool &silent) -{ - user->Shrink("delaymsg_"+channel->name); -} - -void ModuleDelayMsg::OnUserKick(User* source, User* user, Channel* chan, const std::string &reason, bool &silent) -{ - user->Shrink("delaymsg_"+chan->name); -} - -void ModuleDelayMsg::OnCleanup(int target_type, void* item) -{ - if (target_type == TYPE_USER) { - User* user = (User*)item; - for (UCListIter f = user->chans.begin(); f != user->chans.end(); f++) - { - Channel* chan = f->first; - user->Shrink("delaymsg_"+chan->name); - } + Membership* memb = channel->GetUser(user); + djm.jointime.set(memb, ServerInstance->Time()); } } @@ -140,19 +122,21 @@ ModResult ModuleDelayMsg::OnUserPreMessage(User* user, void* dest, int target_ty return MOD_RES_PASSTHRU; Channel* channel = (Channel*) dest; + Membership* memb = channel->GetUser(user); - void* jointime_as_ptr; - - if (!user->GetExt("delaymsg_"+channel->name, jointime_as_ptr)) + if (!memb) return MOD_RES_PASSTHRU; + + time_t ts = djm.jointime.get(memb); - time_t jointime = reinterpret_cast(jointime_as_ptr); + if (ts == 0) + return MOD_RES_PASSTHRU; std::string len = channel->GetModeParameter('d'); - if (jointime + atoi(len.c_str()) > ServerInstance->Time()) + if (ts + atoi(len.c_str()) > ServerInstance->Time()) { - if (channel->GetStatus(user) < STATUS_VOICE) + if (channel->GetPrefixValue(user) < VOICE_VALUE) { user->WriteNumeric(404, "%s %s :You must wait %s seconds after joining to send to channel (+d)", user->nick.c_str(), channel->name.c_str(), len.c_str()); @@ -162,7 +146,7 @@ ModResult ModuleDelayMsg::OnUserPreMessage(User* user, void* dest, int target_ty else { /* Timer has expired, we can stop checking now */ - user->Shrink("delaymsg_"+channel->name); + djm.jointime.set(memb, 0); } return MOD_RES_PASSTHRU; } diff --git a/src/modules/m_httpd_stats.cpp b/src/modules/m_httpd_stats.cpp index d31807f59..3222903dc 100644 --- a/src/modules/m_httpd_stats.cpp +++ b/src/modules/m_httpd_stats.cpp @@ -116,18 +116,15 @@ class ModuleHttpStats : public Module data << ""; data << "" << c->GetUsers()->size() << "" << c->name << ""; - data << "" << c->GetOppedUsers()->size() << ""; - data << "" << c->GetHalfoppedUsers()->size() << ""; - data << "" << c->GetVoicedUsers()->size() << ""; data << ""; data << "" << Sanitize(c->topic) << ""; data << "" << Sanitize(c->setby) << ""; data << "" << c->topicset << ""; data << ""; data << "" << Sanitize(c->ChanModes(true)) << ""; - CUList* ulist = c->GetUsers(); + const UserMembList* ulist = c->GetUsers(); - for (CUList::iterator x = ulist->begin(); x != ulist->end(); ++x) + for (UserMembCIter x = ulist->begin(); x != ulist->end(); ++x) { data << "" << x->first->uuid << "" << Sanitize(c->GetAllPrefixChars(x->first)) << ""; } diff --git a/src/modules/m_invisible.cpp b/src/modules/m_invisible.cpp index 678b9cc49..7da3f2934 100644 --- a/src/modules/m_invisible.cpp +++ b/src/modules/m_invisible.cpp @@ -49,21 +49,21 @@ class InvisibleMode : public ModeHandler /* User appears to vanish or appear from nowhere */ for (UCListIter f = dest->chans.begin(); f != dest->chans.end(); f++) { - CUList *ulist = f->first->GetUsers(); + const UserMembList *ulist = (*f)->GetUsers(); char tb[MAXBUF]; - snprintf(tb,MAXBUF,":%s %s %s", dest->GetFullHost().c_str(), adding ? "PART" : "JOIN", f->first->name.c_str()); + snprintf(tb,MAXBUF,":%s %s %s", dest->GetFullHost().c_str(), adding ? "PART" : "JOIN", (*f)->name.c_str()); std::string out = tb; - std::string n = this->ServerInstance->Modes->ModeString(dest, f->first); + std::string n = this->ServerInstance->Modes->ModeString(dest, (*f)); - for (CUList::iterator i = ulist->begin(); i != ulist->end(); i++) + for (UserMembCIter i = ulist->begin(); i != ulist->end(); i++) { /* User only appears to vanish for non-opers */ if (IS_LOCAL(i->first) && !IS_OPER(i->first)) { i->first->Write(out); if (!n.empty() && !adding) - i->first->WriteServ("MODE %s +%s", f->first->name.c_str(), n.c_str()); + i->first->WriteServ("MODE %s +%s", (*f)->name.c_str(), n.c_str()); } } } @@ -186,7 +186,7 @@ void ModuleInvisible::OnUserQuit(User* user, const std::string &reason, const st if (parthandler) { for (UCListIter f = user->chans.begin(); f != user->chans.end(); f++) - to_leave.push_back(f->first->name); + to_leave.push_back((*f)->name); /* We cant do this neatly in one loop, as we are modifying the map we are iterating */ for (std::vector::iterator n = to_leave.begin(); n != to_leave.end(); n++) { @@ -236,9 +236,9 @@ void ModuleInvisible::WriteCommonFrom(User *user, Channel* channel, const char* va_end(argsPtr); snprintf(tb,MAXBUF,":%s %s",user->GetFullHost().c_str(), textbuffer); - CUList *ulist = channel->GetUsers(); + const UserMembList *ulist = channel->GetUsers(); - for (CUList::iterator i = ulist->begin(); i != ulist->end(); i++) + for (UserMembCIter i = ulist->begin(); i != ulist->end(); i++) { /* User only appears to vanish for non-opers */ if (IS_LOCAL(i->first) && IS_OPER(i->first)) diff --git a/src/modules/m_messageflood.cpp b/src/modules/m_messageflood.cpp index 7d0f59481..db17ee09d 100644 --- a/src/modules/m_messageflood.cpp +++ b/src/modules/m_messageflood.cpp @@ -207,7 +207,7 @@ class ModuleMsgFlood : public Module ModResult ProcessMessages(User* user,Channel* dest, const std::string &text) { - if (!IS_LOCAL(user) || (CHANOPS_EXEMPT(ServerInstance, 'f') && dest->GetStatus(user) == STATUS_OP)) + if (!IS_LOCAL(user) || (CHANOPS_EXEMPT(ServerInstance, 'f') && dest->GetPrefixValue(user) == OP_VALUE)) { return MOD_RES_PASSTHRU; } diff --git a/src/modules/m_muteban.cpp b/src/modules/m_muteban.cpp index 0ac2e7ece..d1ba487a6 100644 --- a/src/modules/m_muteban.cpp +++ b/src/modules/m_muteban.cpp @@ -40,7 +40,7 @@ class ModuleQuietBan : public Module return MOD_RES_PASSTHRU; Channel* chan = static_cast(dest); - if (chan->GetExtBanStatus(user, 'm') == MOD_RES_DENY && chan->GetStatus(user) < STATUS_VOICE) + if (chan->GetExtBanStatus(user, 'm') == MOD_RES_DENY && chan->GetPrefixValue(user) < VOICE_VALUE) { user->WriteNumeric(404, "%s %s :Cannot send to channel (you're muted)", user->nick.c_str(), chan->name.c_str()); return MOD_RES_DENY; diff --git a/src/modules/m_nickflood.cpp b/src/modules/m_nickflood.cpp index 898c7358d..e2ec1e3ed 100644 --- a/src/modules/m_nickflood.cpp +++ b/src/modules/m_nickflood.cpp @@ -214,12 +214,12 @@ class ModuleNickFlood : public Module for (UCListIter i = user->chans.begin(); i != user->chans.end(); i++) { - Channel *channel = i->first; + Channel *channel = *i; nickfloodsettings *f = nf.ext.get(channel); if (f) { - if (CHANOPS_EXEMPT(ServerInstance, 'F') && channel->GetStatus(user) == STATUS_OP) + if (CHANOPS_EXEMPT(ServerInstance, 'F') && channel->GetPrefixValue(user) == OP_VALUE) continue; if (f->islocked()) @@ -251,12 +251,12 @@ class ModuleNickFlood : public Module for (UCListIter i = user->chans.begin(); i != user->chans.end(); ++i) { - Channel *channel = i->first; + Channel *channel = *i; nickfloodsettings *f = nf.ext.get(channel); if (f) { - if (CHANOPS_EXEMPT(ServerInstance, 'F') && channel->GetStatus(user) == STATUS_OP) + if (CHANOPS_EXEMPT(ServerInstance, 'F') && channel->GetPrefixValue(user) == OP_VALUE) return; /* moved this here to avoid incrementing the counter for nick diff --git a/src/modules/m_noctcp.cpp b/src/modules/m_noctcp.cpp index 0dc004ee8..ce79a5ff6 100644 --- a/src/modules/m_noctcp.cpp +++ b/src/modules/m_noctcp.cpp @@ -80,7 +80,7 @@ class ModuleNoCTCP : public Module { Channel* c = (Channel*)dest; - if (CHANOPS_EXEMPT(ServerInstance, 'C') && c->GetStatus(user) == STATUS_OP) + if (CHANOPS_EXEMPT(ServerInstance, 'C') && c->GetPrefixValue(user) == OP_VALUE) { return MOD_RES_PASSTHRU; } diff --git a/src/modules/m_nonicks.cpp b/src/modules/m_nonicks.cpp index 029ae9d2e..31839c13a 100644 --- a/src/modules/m_nonicks.cpp +++ b/src/modules/m_nonicks.cpp @@ -84,9 +84,9 @@ class ModuleNoNickChange : public Module for (UCListIter i = user->chans.begin(); i != user->chans.end(); i++) { - Channel* curr = i->first; + Channel* curr = *i; - if (CHANOPS_EXEMPT(ServerInstance, 'N') && curr->GetStatus(user) == STATUS_OP) + if (CHANOPS_EXEMPT(ServerInstance, 'N') && curr->GetPrefixValue(user) == OP_VALUE) continue; if (!curr->GetExtBanStatus(user, 'N').check(!curr->IsModeSet('N'))) diff --git a/src/modules/m_nonotice.cpp b/src/modules/m_nonotice.cpp index 72426646f..fab52ca2e 100644 --- a/src/modules/m_nonotice.cpp +++ b/src/modules/m_nonotice.cpp @@ -52,7 +52,7 @@ class ModuleNoNotice : public Module // ulines are exempt. return MOD_RES_PASSTHRU; } - else if (CHANOPS_EXEMPT(ServerInstance, 'T') && c->GetStatus(user) == STATUS_OP) + else if (CHANOPS_EXEMPT(ServerInstance, 'T') && c->GetPrefixValue(user) == OP_VALUE) { // channel ops are exempt if set in conf. return MOD_RES_PASSTHRU; diff --git a/src/modules/m_ojoin.cpp b/src/modules/m_ojoin.cpp index 4e9477af1..c03f2ad1f 100644 --- a/src/modules/m_ojoin.cpp +++ b/src/modules/m_ojoin.cpp @@ -115,14 +115,14 @@ class NetworkPrefix : public ModeHandler User* x = ServerInstance->FindNick(parameter); if (x) { - if (!channel->HasUser(x)) + Membership* m = channel->GetUser(x); + if (!m) { return std::make_pair(false, parameter); } else { - std::string item = "cm_network_"+std::string(channel->name); - if (x->GetExt(item)) + if (m->hasMode('Y')) { return std::make_pair(true, x->nick); } @@ -137,16 +137,15 @@ class NetworkPrefix : public ModeHandler void RemoveMode(Channel* channel, irc::modestacker* stack) { - CUList* cl = channel->GetUsers(); - std::string item = "cm_network_" + std::string(channel->name); + const UserMembList* cl = channel->GetUsers(); std::vector mode_junk; mode_junk.push_back(channel->name); irc::modestacker modestack(ServerInstance, false); std::deque stackresult; - for (CUList::iterator i = cl->begin(); i != cl->end(); i++) + for (UserMembCIter i = cl->begin(); i != cl->end(); i++) { - if (i->first->GetExt(item)) + if (i->second->hasMode('Y')) { if (stack) stack->Push(this->GetModeChar(), i->first->nick); @@ -179,22 +178,19 @@ class NetworkPrefix : public ModeHandler ModeAction HandleChange(User* source, User* theuser, bool adding, Channel* channel, std::string ¶meter) { - std::string item = "cm_network_" + std::string(channel->name); - - if (adding) + Membership* m = channel->GetUser(theuser); + if (m && adding) { - if (!theuser->GetExt(item)) + if (!m->hasMode('Y')) { - theuser->Extend(item); parameter = theuser->nick; return MODEACTION_ALLOW; } } - else + else if (m && !adding) { - if (theuser->GetExt(item)) + if (m->hasMode('Y')) { - theuser->Shrink(item); parameter = theuser->nick; return MODEACTION_ALLOW; } @@ -271,26 +267,15 @@ class ModuleOjoin : public Module { if (mycommand.active) { - if (NPrefix) - privs += NPrefix; - if (op && privs.find('@') == std::string::npos) - privs += '@'; + privs += 'Y'; + if (op) + privs += 'o'; return MOD_RES_ALLOW; } return MOD_RES_PASSTHRU; } - void OnUserKick(User* source, User* user, Channel* chan, const std::string &reason, bool &silent) - { - user->Shrink("cm_network_"+std::string(chan->name)); - } - - void OnUserPart(User* user, Channel* channel, std::string &partreason, bool &silent) - { - user->Shrink("cm_network_"+std::string(channel->name)); - } - void OnRehash(User* user) { ConfigReader Conf(ServerInstance); @@ -321,12 +306,12 @@ class ModuleOjoin : public Module // If a ulined nickname, or a server is setting the mode, let it // do whatever it wants. if ((ServerInstance->ULine(source->nick.c_str())) || (ServerInstance->ULine(source->server)) || (!*source->server)) - return MOD_RES_ALLOW; + return MOD_RES_PASSTHRU; - std::string network("cm_network_"+channel->name); + Membership* m = channel->GetUser(dest); // Don't do anything if they're not +Y - if (!dest->GetExt(network)) + if (!m || !m->hasMode('Y')) return MOD_RES_PASSTHRU; // Let them do whatever they want to themselves. diff --git a/src/modules/m_operprefix.cpp b/src/modules/m_operprefix.cpp index aeea1ad19..e7a772432 100644 --- a/src/modules/m_operprefix.cpp +++ b/src/modules/m_operprefix.cpp @@ -21,33 +21,6 @@ #define OPERPREFIX_VALUE 1000000 -std::set* SetupExt(User* user) -{ - std::set* ext; - if (!user->GetExt("m_operprefix",ext)) - { - ext=new std::set; - ext->clear(); - user->Extend("m_operprefix",ext); - } - return ext; -} - - -void DelPrefixChan(User* user, Channel* channel) -{ - std::set* chans = SetupExt(user); - chans->erase(channel->name); -} - - -void AddPrefixChan(User* user, Channel* channel) -{ - std::set* chans = SetupExt(user); - chans->insert(channel->name); -} - - class OperPrefixMode : public ModeHandler { public: @@ -73,28 +46,19 @@ class OperPrefixMode : public ModeHandler ModePair ModeSet(User* source, User* dest, Channel* channel, const std::string ¶meter) { User* x = ServerInstance->FindNick(parameter); + Membership* m = channel->GetUser(x); if (x) { - if (!channel->HasUser(x)) + if (!m) { return std::make_pair(false, parameter); } else { - std::set* ext; - if (x->GetExt("m_operprefix",ext)) - { - if (ext->find(channel->name)!=ext->end()) - { - return std::make_pair(true, x->nick); - } - else - return std::make_pair(false, parameter); - } + if (m->hasMode('y')) + return std::make_pair(true, x->nick); else - { - return std::make_pair(false, parameter); - } + return std::make_pair(false, parameter); } } return std::make_pair(false, parameter); @@ -117,19 +81,13 @@ class ModuleOperPrefixMode : public Module if ((!ServerInstance->Modes->AddMode(opm))) throw ModuleException("Could not add a new mode!"); - Implementation eventlist[] = { I_OnPostJoin, I_OnCleanup, I_OnUserQuit, I_OnUserKick, I_OnUserPart, I_OnOper }; - ServerInstance->Modules->Attach(eventlist, this, 6); + Implementation eventlist[] = { I_OnPostJoin, I_OnUserQuit, I_OnUserKick, I_OnUserPart, I_OnOper }; + ServerInstance->Modules->Attach(eventlist, this, 5); } - void PushChanMode(Channel* channel, User* user, bool negate = false) + void PushChanMode(Channel* channel, User* user) { - if (negate) - DelPrefixChan(user, channel); - else - AddPrefixChan(user, channel); char modeline[] = "+y"; - if (negate) - modeline[0] = '-'; std::vector modechange; modechange.push_back(channel->name); modechange.push_back(modeline); @@ -137,7 +95,7 @@ class ModuleOperPrefixMode : public Module ServerInstance->SendMode(modechange,this->ServerInstance->FakeClient); } - virtual void OnPostJoin(User *user, Channel *channel) + void OnPostJoin(User *user, Channel *channel) { if (user && IS_OPER(user)) { @@ -151,7 +109,7 @@ class ModuleOperPrefixMode : public Module } // XXX: is there a better way to do this? - virtual ModResult OnRawMode(User* user, Channel* chan, const char mode, const std::string ¶m, bool adding, int pcnt) + ModResult OnRawMode(User* user, Channel* chan, const char mode, const std::string ¶m, bool adding, int pcnt) { /* force event propagation to its ModeHandler */ if (!IS_FAKE(user) && chan && (mode == 'y')) @@ -159,72 +117,24 @@ class ModuleOperPrefixMode : public Module return MOD_RES_PASSTHRU; } - virtual void OnOper(User *user, const std::string&) + void OnOper(User *user, const std::string&) { if (user && !user->IsModeSet('H')) { for (UCListIter v = user->chans.begin(); v != user->chans.end(); v++) { - PushChanMode(v->first, user); + PushChanMode(*v, user); } } } - virtual ~ModuleOperPrefixMode() + ~ModuleOperPrefixMode() { ServerInstance->Modes->DelMode(opm); delete opm; } - void CleanUser(User* user, bool quitting) - { - - std::set* ext; - if (user->GetExt("m_operprefix",ext)) - { - // Don't want to announce -mode when they're quitting anyway.. - if (!quitting) - { - for (UCListIter v = user->chans.begin(); v != user->chans.end(); v++) - { - ModePair ms = opm->ModeSet(NULL, NULL , v->first, user->nick); - if (ms.first) - { - PushChanMode(v->first, user, true); - } - } - } - ext->clear(); - delete ext; - user->Shrink("m_operprefix"); - } - } - - virtual void OnCleanup(int target_type, void* item) - { - if (target_type == TYPE_USER) - { - User* user = (User*)item; - CleanUser(user, false); - } - } - - virtual void OnUserQuit(User* user, const std::string &reason, const std::string &oper_message) - { - CleanUser(user,true); - } - - virtual void OnUserKick(User* source, User* user, Channel* chan, const std::string &reason, bool &silent) - { - DelPrefixChan(user, chan); - } - - virtual void OnUserPart(User* user, Channel* channel, std::string &partreason, bool &silent) - { - DelPrefixChan(user, channel); - } - - virtual Version GetVersion() + Version GetVersion() { return Version("$Id$", VF_COMMON | VF_VENDOR, API_VERSION); } diff --git a/src/modules/m_override.cpp b/src/modules/m_override.cpp index d0ec5d8fe..0a445eff7 100644 --- a/src/modules/m_override.cpp +++ b/src/modules/m_override.cpp @@ -120,7 +120,7 @@ class ModuleOverride : public Module { if (IS_LOCAL(source) && IS_OPER(source) && CanOverride(source, "TOPIC")) { - if (!channel->HasUser(source) || (channel->IsModeSet('t') && channel->GetStatus(source) < STATUS_HOP)) + if (!channel->HasUser(source) || (channel->IsModeSet('t') && channel->GetPrefixValue(source) < HALFOP_VALUE)) { ServerInstance->SNO->WriteGlobalSno('G',std::string(source->nick)+" used oper override to change a topic on "+std::string(channel->name)); } @@ -137,7 +137,7 @@ class ModuleOverride : public Module if (IS_OPER(source) && CanOverride(source,"KICK")) { // If the kicker's status is less than the target's, or the kicker's status is less than or equal to voice - if ((chan->GetStatus(source) < chan->GetStatus(user)) || (chan->GetStatus(source) <= STATUS_VOICE)) + if ((chan->GetPrefixValue(source) < chan->GetPrefixValue(user)) || (chan->GetPrefixValue(source) <= VOICE_VALUE)) { ServerInstance->SNO->WriteGlobalSno('G',std::string(source->nick)+" used oper override to kick "+std::string(user->nick)+" on "+std::string(chan->name)+" ("+reason+")"); } @@ -153,50 +153,50 @@ class ModuleOverride : public Module if (!source || !channel) return MOD_RES_PASSTHRU; - int mode = STATUS_NORMAL; + int mode = 0; if (channel->HasUser(source)) - mode = channel->GetStatus(source); + mode = channel->GetPrefixValue(source); bool over_this = false; switch (access_type) { case AC_DEOP: - if (mode < STATUS_OP && CanOverride(source,"MODEDEOP")) + if (mode < OP_VALUE && CanOverride(source,"MODEDEOP")) { over_this = true; OverDeops++; } break; case AC_OP: - if (mode < STATUS_OP && CanOverride(source,"MODEOP")) + if (mode < OP_VALUE && CanOverride(source,"MODEOP")) { over_this = true; OverOps++; } break; case AC_VOICE: - if (mode < STATUS_HOP && CanOverride(source,"MODEVOICE")) + if (mode < HALFOP_VALUE && CanOverride(source,"MODEVOICE")) { over_this = true; OverVoices++; } break; case AC_DEVOICE: - if (mode < STATUS_HOP && CanOverride(source,"MODEDEVOICE")) + if (mode < HALFOP_VALUE && CanOverride(source,"MODEDEVOICE")) { over_this = true; OverDevoices++; } break; case AC_HALFOP: - if (mode < STATUS_OP && CanOverride(source,"MODEHALFOP")) + if (mode < OP_VALUE && CanOverride(source,"MODEHALFOP")) { over_this = true; OverHalfops++; } break; case AC_DEHALFOP: - if (mode < STATUS_OP && CanOverride(source,"MODEDEHALFOP")) + if (mode < OP_VALUE && CanOverride(source,"MODEDEHALFOP")) { over_this = true; OverDehalfops++; @@ -207,7 +207,7 @@ class ModuleOverride : public Module std::string modes = ServerInstance->Modes->GetLastParse(); bool ohv_only = (modes.find_first_not_of("+-ohv") == std::string::npos); - if (mode < STATUS_HOP && (ohv_only || CanOverride(source,"OTHERMODE"))) + if (mode < HALFOP_VALUE && (ohv_only || CanOverride(source,"OTHERMODE"))) { over_this = true; if (!ohv_only) diff --git a/src/modules/m_redirect.cpp b/src/modules/m_redirect.cpp index 9d19b0cf0..667ab307f 100644 --- a/src/modules/m_redirect.cpp +++ b/src/modules/m_redirect.cpp @@ -53,7 +53,7 @@ class Redirect : public ModeHandler parameter.clear(); return MODEACTION_DENY; } - else if (c->GetStatus(source) < STATUS_OP) + else if (c->GetPrefixValue(source) < OP_VALUE) { source->WriteNumeric(690, "%s :You must be opped on %s to set it as a redirect.",source->nick.c_str(),parameter.c_str()); parameter.clear(); diff --git a/src/modules/m_remove.cpp b/src/modules/m_remove.cpp index b2763d86a..d17deb742 100644 --- a/src/modules/m_remove.cpp +++ b/src/modules/m_remove.cpp @@ -34,49 +34,12 @@ class RemoveBase : public Command { } - enum ModeLevel { PEON = 0, HALFOP = 1, OP = 2, ADMIN = 3, OWNER = 4, ULINE = 5 }; - - /* This little function just converts a chanmode character (U ~ & @ & +) into an integer (5 4 3 2 1 0) */ - /* XXX - We should probably use the new mode prefix rank stuff - * for this instead now -- Brain */ - ModeLevel chartolevel(const std::string &privs) - { - if(privs.empty()) - { - return PEON; - } - - switch (privs[0]) - { - case 'U': - /* Ulined */ - return ULINE; - case '~': - /* Owner */ - return OWNER; - case '&': - /* Admin */ - return ADMIN; - case '@': - /* Operator */ - return OP; - case '%': - /* Halfop */ - return HALFOP; - default: - /* Peon */ - return PEON; - } - } - CmdResult HandleRMB(const std::vector& parameters, User *user, bool neworder) { const char* channame; const char* username; User* target; Channel* channel; - ModeLevel tlevel; - ModeLevel ulevel; std::string reason; std::string protectkey; std::string founderkey; @@ -109,57 +72,20 @@ class RemoveBase : public Command return CMD_FAILURE; } - /* This is adding support for the +q and +a channel modes, basically if they are enabled, and the remover has them set. - * Then we change the @|%|+ to & if they are +a, or ~ if they are +q */ - protectkey = "cm_protect_" + std::string(channel->name); - founderkey = "cm_founder_" + std::string(channel->name); - - if (ServerInstance->ULine(user->server) || ServerInstance->ULine(user->nick.c_str())) - { - ulevel = chartolevel("U"); - } - if (user->GetExt(founderkey)) - { - ulevel = chartolevel("~"); - } - else if (user->GetExt(protectkey)) - { - ulevel = chartolevel("&"); - } - else - { - ulevel = chartolevel(channel->GetPrefixChar(user)); - } - - /* Now it's the same idea, except for the target. If they're ulined make sure they get a higher level than the sender can */ - if (ServerInstance->ULine(target->server) || ServerInstance->ULine(target->nick.c_str())) - { - tlevel = chartolevel("U"); - } - else if (target->GetExt(founderkey)) - { - tlevel = chartolevel("~"); - } - else if (target->GetExt(protectkey)) - { - tlevel = chartolevel("&"); - } - else - { - tlevel = chartolevel(channel->GetPrefixChar(target)); - } + int ulevel = channel->GetPrefixValue(user); + int tlevel = channel->GetPrefixValue(target); hasnokicks = (ServerInstance->Modules->Find("m_nokicks.so") && channel->IsModeSet('Q')); /* We support the +Q channel mode via. the m_nokicks module, if the module is loaded and the mode is set then disallow the /remove */ - if ((!IS_LOCAL(user)) || (!supportnokicks || !hasnokicks || (ulevel == ULINE))) + if ((!IS_LOCAL(user)) || (!supportnokicks || !hasnokicks)) { /* We'll let everyone remove their level and below, eg: * ops can remove ops, halfops, voices, and those with no mode (no moders actually are set to 1) * a ulined target will get a higher level than it's possible for a /remover to get..so they're safe. * Nobody may remove a founder. */ - if ((!IS_LOCAL(user)) || ((ulevel > PEON) && (ulevel >= tlevel) && (tlevel != OWNER))) + if ((!IS_LOCAL(user)) || ((ulevel > VOICE_VALUE) && (ulevel >= tlevel) && (tlevel != 50000))) { // no you can't just go from a std::ostringstream to a std::string, Om. -nenolod // but you can do this, nenolod -brain diff --git a/src/modules/m_silence.cpp b/src/modules/m_silence.cpp index 779cb541e..3b0709539 100644 --- a/src/modules/m_silence.cpp +++ b/src/modules/m_silence.cpp @@ -298,30 +298,15 @@ class ModuleSilence : public Module void OnBuildExemptList(MessageType message_type, Channel* chan, User* sender, char status, CUList &exempt_list, const std::string &text) { int public_silence = (message_type == MSG_PRIVMSG ? SILENCE_CHANNEL : SILENCE_CNOTICE); - CUList *ulist; - switch (status) - { - case '@': - ulist = chan->GetOppedUsers(); - break; - case '%': - ulist = chan->GetHalfoppedUsers(); - break; - case '+': - ulist = chan->GetVoicedUsers(); - break; - default: - ulist = chan->GetUsers(); - break; - } + const UserMembList *ulist = chan->GetUsers(); - for (CUList::iterator i = ulist->begin(); i != ulist->end(); i++) + for (UserMembCIter i = ulist->begin(); i != ulist->end(); i++) { if (IS_LOCAL(i->first)) { if (MatchPattern(i->first, sender, public_silence) == MOD_RES_ALLOW) { - exempt_list[i->first] = i->first->nick; + exempt_list.insert(i->first); } } } diff --git a/src/modules/m_spanningtree/netburst.cpp b/src/modules/m_spanningtree/netburst.cpp index abefad728..3ed85ea1e 100644 --- a/src/modules/m_spanningtree/netburst.cpp +++ b/src/modules/m_spanningtree/netburst.cpp @@ -96,11 +96,11 @@ void TreeSocket::SendFJoins(TreeServer* Current, Channel* c) char* ptr = list + curlen; bool looped_once = false; - CUList *ulist = c->GetUsers(); + const UserMembList *ulist = c->GetUsers(); std::string modes; std::string params; - for (CUList::iterator i = ulist->begin(); i != ulist->end(); i++) + for (UserMembCIter i = ulist->begin(); i != ulist->end(); i++) { size_t ptrlen = 0; std::string modestr = this->ServerInstance->Modes->ModeString(i->first, c, false); diff --git a/src/modules/m_spanningtree/utils.cpp b/src/modules/m_spanningtree/utils.cpp index 30b9cad3c..1550a1e37 100644 --- a/src/modules/m_spanningtree/utils.cpp +++ b/src/modules/m_spanningtree/utils.cpp @@ -194,9 +194,9 @@ void SpanningTreeUtilities::AddThisServer(TreeServer* server, TreeServerList &li /* returns a list of DIRECT servernames for a specific channel */ void SpanningTreeUtilities::GetListOfServersForChannel(Channel* c, TreeServerList &list, char status, const CUList &exempt_list) { - CUList *ulist = c->GetUsers(); + const UserMembList *ulist = c->GetUsers(); - for (CUList::iterator i = ulist->begin(); i != ulist->end(); i++) + for (UserMembCIter i = ulist->begin(); i != ulist->end(); i++) { if (IS_LOCAL(i->first)) continue; diff --git a/src/modules/m_spy.cpp b/src/modules/m_spy.cpp index 485c104b8..e964cb766 100644 --- a/src/modules/m_spy.cpp +++ b/src/modules/m_spy.cpp @@ -23,7 +23,7 @@ class ModuleSpy : public Module ServerInstance->Modules->Attach(I_OnUserList, this); } - virtual ModResult OnUserList(User* user, Channel* Ptr, CUList* &nameslist) + virtual ModResult OnUserList(User* user, Channel* Ptr) { /* User has priv and is NOT on the channel */ if (user->HasPrivPermission("channels/auspex") && !Ptr->HasUser(user)) diff --git a/src/modules/m_sslmodes.cpp b/src/modules/m_sslmodes.cpp index a07252069..396623eb9 100644 --- a/src/modules/m_sslmodes.cpp +++ b/src/modules/m_sslmodes.cpp @@ -31,8 +31,8 @@ class SSLMode : public ModeHandler { if (IS_LOCAL(source)) { - CUList* userlist = channel->GetUsers(); - for(CUList::iterator i = userlist->begin(); i != userlist->end(); i++) + const UserMembList* userlist = channel->GetUsers(); + for(UserMembCIter i = userlist->begin(); i != userlist->end(); i++) { BufferedSocketCertificateRequest req(i->first, creator, i->first->GetIOHook()); req.Send(); diff --git a/src/modules/m_stripcolor.cpp b/src/modules/m_stripcolor.cpp index cbbef75c6..7abe4f7d2 100644 --- a/src/modules/m_stripcolor.cpp +++ b/src/modules/m_stripcolor.cpp @@ -115,7 +115,7 @@ class ModuleStripColor : public Module // check if we allow ops to bypass filtering, if we do, check if they're opped accordingly. // note: short circut logic here, don't wreck it. -- w00t - if (CHANOPS_EXEMPT(ServerInstance, 'S') && t->GetStatus(user) == STATUS_OP) + if (CHANOPS_EXEMPT(ServerInstance, 'S') && t->GetPrefixValue(user) == OP_VALUE) { return MOD_RES_PASSTHRU; } diff --git a/src/modules/m_timedbans.cpp b/src/modules/m_timedbans.cpp index 17e9cd50e..11ff23a12 100644 --- a/src/modules/m_timedbans.cpp +++ b/src/modules/m_timedbans.cpp @@ -44,8 +44,8 @@ class CommandTban : public Command Channel* channel = ServerInstance->FindChan(parameters[0]); if (channel) { - int cm = channel->GetStatus(user); - if ((cm == STATUS_HOP) || (cm == STATUS_OP)) + int cm = channel->GetPrefixValue(user); + if ((cm == HALFOP_VALUE) || (cm == OP_VALUE)) { if (!ServerInstance->IsValidMask(parameters[2])) { diff --git a/src/modules/m_uninvite.cpp b/src/modules/m_uninvite.cpp index 0e9b991a0..e659ffa23 100644 --- a/src/modules/m_uninvite.cpp +++ b/src/modules/m_uninvite.cpp @@ -47,9 +47,9 @@ class CommandUninvite : public Command if (IS_LOCAL(user)) { - if (c->GetStatus(user) < STATUS_HOP) + if (c->GetPrefixValue(user) < HALFOP_VALUE) { - user->WriteNumeric(ERR_CHANOPRIVSNEEDED, "%s %s :You must be a channel %soperator", user->nick.c_str(), c->name.c_str(), c->GetStatus(u) == STATUS_HOP ? "" : "half-"); + user->WriteNumeric(ERR_CHANOPRIVSNEEDED, "%s %s :You must be a channel %soperator", user->nick.c_str(), c->name.c_str(), c->GetPrefixValue(u) == HALFOP_VALUE ? "" : "half-"); return CMD_FAILURE; } } diff --git a/src/users.cpp b/src/users.cpp index 4940df24e..7f60b2f93 100644 --- a/src/users.cpp +++ b/src/users.cpp @@ -28,11 +28,8 @@ static unsigned long* already_sent = NULL; LocalIntExt User::NICKForced("NICKForced", NULL); LocalStringExt User::OperQuit("OperQuit", NULL); -static bool dummy_init = Extensible::Register(&User::NICKForced) ^ Extensible::Register(&User::OperQuit); - void InitializeAlreadySent(SocketEngine* SE) { - (void)dummy_init; already_sent = new unsigned long[SE->GetMaxFds()]; memset(already_sent, 0, SE->GetMaxFds() * sizeof(unsigned long)); } @@ -1365,8 +1362,8 @@ void User::WriteCommon(const std::string &text) for (UCListIter v = this->chans.begin(); v != this->chans.end(); v++) { - CUList* ulist = v->first->GetUsers(); - for (CUList::iterator i = ulist->begin(); i != ulist->end(); i++) + const UserMembList* ulist = (*v)->GetUsers(); + for (UserMembList::const_iterator i = ulist->begin(); i != ulist->end(); i++) { if ((IS_LOCAL(i->first)) && (already_sent[i->first->fd] != uniq_id)) { @@ -1424,8 +1421,8 @@ void User::WriteCommonQuit(const std::string &normal_text, const std::string &op for (UCListIter v = this->chans.begin(); v != this->chans.end(); v++) { - CUList *ulist = v->first->GetUsers(); - for (CUList::iterator i = ulist->begin(); i != ulist->end(); i++) + const UserMembList* ulist = (*v)->GetUsers(); + for (UserMembList::const_iterator i = ulist->begin(); i != ulist->end(); i++) { if (this != i->first) { @@ -1457,8 +1454,8 @@ void User::WriteCommonExcept(const std::string &text) for (UCListIter v = this->chans.begin(); v != this->chans.end(); v++) { - CUList *ulist = v->first->GetUsers(); - for (CUList::iterator i = ulist->begin(); i != ulist->end(); i++) + const UserMembList* ulist = (*v)->GetUsers(); + for (UserMembList::const_iterator i = ulist->begin(); i != ulist->end(); i++) { if (this != i->first) { @@ -1524,7 +1521,7 @@ bool User::SharesChannelWith(User *other) /* Eliminate the inner loop (which used to be ~equal in size to the outer loop) * by replacing it with a map::find which *should* be more efficient */ - if (i->first->HasUser(other)) + if ((*i)->HasUser(other)) return true; } return false; @@ -1567,7 +1564,7 @@ void User::DoHostCycle(const std::string &quitline) for (UCListIter v = this->chans.begin(); v != this->chans.end(); v++) { - Channel* c = v->first; + Channel* c = *v; snprintf(buffer, MAXBUF, ":%s JOIN %s", GetFullHost().c_str(), c->name.c_str()); std::string joinline(buffer); std::string modeline = this->ServerInstance->Modes->ModeString(this, c); @@ -1577,8 +1574,8 @@ void User::DoHostCycle(const std::string &quitline) modeline = buffer; } - CUList *ulist = c->GetUsers(); - for (CUList::iterator i = ulist->begin(); i != ulist->end(); i++) + const UserMembList *ulist = c->GetUsers(); + for (UserMembList::const_iterator i = ulist->begin(); i != ulist->end(); i++) { User* u = i->first; if (u == this || !IS_LOCAL(u)) @@ -1670,13 +1667,14 @@ std::string User::ChannelList(User* source) for (UCListIter i = this->chans.begin(); i != this->chans.end(); i++) { + Channel* c = *i; /* If the target is the same as the sender, let them see all their channels. * If the channel is NOT private/secret OR the user shares a common channel * If the user is an oper, and the option is set. */ - if ((source == this) || (IS_OPER(source) && ServerInstance->Config->OperSpyWhois) || (((!i->first->IsModeSet('p')) && (!i->first->IsModeSet('s'))) || (i->first->HasUser(source)))) + if ((source == this) || (IS_OPER(source) && ServerInstance->Config->OperSpyWhois) || (((!c->IsModeSet('p')) && (!c->IsModeSet('s'))) || (c->HasUser(source)))) { - list.append(i->first->GetPrefixChar(this)).append(i->first->name).append(" "); + list.append(c->GetPrefixChar(this)).append(c->name).append(" "); } } @@ -1842,13 +1840,14 @@ void User::PurgeEmptyChannels() // firstly decrement the count on each channel for (UCListIter f = this->chans.begin(); f != this->chans.end(); f++) { - f->first->RemoveAllPrefixes(this); - if (f->first->DelUser(this) == 0) + Channel* c = *f; + c->RemoveAllPrefixes(this); + if (c->DelUser(this) == 0) { /* No users left in here, mark it for deletion */ try { - to_delete.push_back(f->first); + to_delete.push_back(c); } catch (...) { -- cgit v1.2.3