diff options
-rw-r--r-- | include/channels.h | 7 | ||||
-rw-r--r-- | include/mode.h | 33 | ||||
-rw-r--r-- | include/modes/cmode_h.h | 1 | ||||
-rw-r--r-- | include/modes/cmode_o.h | 1 | ||||
-rw-r--r-- | include/modes/cmode_v.h | 1 | ||||
-rw-r--r-- | src/channels.cpp | 59 | ||||
-rw-r--r-- | src/mode.cpp | 34 | ||||
-rw-r--r-- | src/modes/cmode_h.cpp | 7 | ||||
-rw-r--r-- | src/modes/cmode_o.cpp | 7 | ||||
-rw-r--r-- | src/modes/cmode_v.cpp | 7 |
10 files changed, 131 insertions, 26 deletions
diff --git a/include/channels.h b/include/channels.h index 8f3b8ba3d..5186822e1 100644 --- a/include/channels.h +++ b/include/channels.h @@ -144,6 +144,9 @@ class ucrec : public classbase class InspIRCd; +typedef std::pair<char, unsigned int> prefixtype; +typedef std::vector<prefixtype> pfxcontainer; +typedef std::map<userrec*, std::vector<prefixtype> > prefixlist; /** Holds all relevent information for a channel. * This class represents a channel, and contains its name, modes, time created, topic, topic set time, @@ -161,6 +164,8 @@ class chanrec : public Extensible */ static chanrec* ForceChan(InspIRCd* Instance, chanrec* Ptr,ucrec *a,userrec* user, int created); + prefixlist prefixes; + public: /** The channels name. */ @@ -468,6 +473,8 @@ class chanrec : public Extensible */ const char* GetStatusChar(userrec *user); + void SetPrefix(userrec* user, char prefix, unsigned int prefix_rank, bool adding); + /** Destructor for chanrec */ virtual ~chanrec() { /* stub */ } diff --git a/include/mode.h b/include/mode.h index f1ef388d3..10b21a6b7 100644 --- a/include/mode.h +++ b/include/mode.h @@ -34,7 +34,8 @@ class InspIRCd; * Holds the values for different type of modes * that can exist, USER or CHANNEL type. */ -enum ModeType { +enum ModeType +{ MODETYPE_USER = 0, MODETYPE_CHANNEL = 1 }; @@ -42,7 +43,8 @@ enum ModeType { /** * Holds mode actions - modes can be allowed or denied. */ -enum ModeAction { +enum ModeAction +{ MODEACTION_DENY = 0, /* Drop the mode change, AND a parameter if its a parameterized mode */ MODEACTION_ALLOW = 1 /* Allow the mode */ }; @@ -52,11 +54,19 @@ enum ModeAction { * array. Used in a simple two instruction hashing function * "(modeletter - 65) OR mask" */ -enum ModeMasks { +enum ModeMasks +{ MASK_USER = 128, /* A user mode */ MASK_CHANNEL = 0 /* A channel mode */ }; +enum PrefixModeValue +{ + VOICE_VALUE = 10000, + HALFOP_VALUE = 20000, + OP_VALUE = 30000 +}; + /** * Used by ModeHandler::ModeSet() to return the state of a mode upon a channel or user. * The pair contains an activity flag, true if the mode is set with the given parameter, @@ -116,6 +126,10 @@ class ModeHandler : public Extensible */ bool oper; + /** Mode prefix, or 0 + */ + char prefix; + public: /** * The constructor for ModeHandler initalizes the mode handler. @@ -128,17 +142,26 @@ class ModeHandler : public Extensible * @param ModeType Set this to MODETYPE_USER for a usermode, or MODETYPE_CHANNEL for a channelmode. * @param operonly Set this to true if only opers should be allowed to set or unset the mode. */ - ModeHandler(InspIRCd* Instance, char modeletter, int parameters_on, int parameters_off, bool listmode, ModeType type, bool operonly); + ModeHandler(InspIRCd* Instance, char modeletter, int parameters_on, int parameters_off, bool listmode, ModeType type, bool operonly, char mprefix = 0); /** * The default destructor does nothing */ virtual ~ModeHandler(); - /** * Returns true if the mode is a list mode */ bool IsListMode(); /** + * Mode prefix or 0 + */ + char GetPrefix(); + /** + * Get the 'value' of this modes prefix. + * determines which to display when there are multiple. + * The mode with the highest value is ranked first. + */ + virtual unsigned int GetPrefixRank(); + /** * Returns the modes type */ ModeType GetModeType(); diff --git a/include/modes/cmode_h.h b/include/modes/cmode_h.h index cf61726da..277d89625 100644 --- a/include/modes/cmode_h.h +++ b/include/modes/cmode_h.h @@ -14,5 +14,6 @@ class ModeChannelHalfOp : public ModeHandler std::string AddHalfOp(userrec *user,const char *dest,chanrec *chan,int status); std::string DelHalfOp(userrec *user,const char *dest,chanrec *chan,int status); ModePair ModeSet(userrec* source, userrec* dest, chanrec* channel, const std::string ¶meter); + unsigned int GetPrefixRank(); }; diff --git a/include/modes/cmode_o.h b/include/modes/cmode_o.h index a308f9903..3fe097ec3 100644 --- a/include/modes/cmode_o.h +++ b/include/modes/cmode_o.h @@ -14,5 +14,6 @@ class ModeChannelOp : public ModeHandler std::string AddOp(userrec *user,const char *dest,chanrec *chan,int status); std::string DelOp(userrec *user,const char *dest,chanrec *chan,int status); ModePair ModeSet(userrec* source, userrec* dest, chanrec* channel, const std::string ¶meter); + unsigned int GetPrefixRank(); }; diff --git a/include/modes/cmode_v.h b/include/modes/cmode_v.h index 51846d11a..b7e9b800e 100644 --- a/include/modes/cmode_v.h +++ b/include/modes/cmode_v.h @@ -14,5 +14,6 @@ class ModeChannelVoice : public ModeHandler std::string AddVoice(userrec *user,const char *dest,chanrec *chan,int status); std::string DelVoice(userrec *user,const char *dest,chanrec *chan,int status); ModePair ModeSet(userrec* source, userrec* dest, chanrec* channel, const std::string ¶meter); + unsigned int GetPrefixRank(); }; diff --git a/src/channels.cpp b/src/channels.cpp index a89b9b2c4..4d68af99c 100644 --- a/src/channels.cpp +++ b/src/channels.cpp @@ -430,6 +430,7 @@ chanrec* chanrec::ForceChan(InspIRCd* Instance, chanrec* Ptr,ucrec *a,userrec* u /* first user in is given ops */ a->uc_modes = UCMODE_OP; Ptr->AddOppedUser(user); + Ptr->SetPrefix(user, '@', OP_VALUE, true); } else { @@ -880,26 +881,26 @@ long chanrec::GetMaxBans() const char* chanrec::GetStatusChar(userrec *user) { - for (std::vector<ucrec*>::const_iterator i = user->chans.begin(); i != user->chans.end(); i++) + static char px[2]; + unsigned int mx = 0; + + *px = 0; + *(px+1) = 0; + + prefixlist::iterator n = prefixes.find(user); + if (n != prefixes.end()) { - if ((*i)->channel == this) + for (std::vector<prefixtype>::iterator x = n->second.begin(); x != n->second.end(); x++) { - if (((*i)->uc_modes & UCMODE_OP) > 0) - { - return "@"; - } - if (((*i)->uc_modes & UCMODE_HOP) > 0) - { - return "%"; - } - if (((*i)->uc_modes & UCMODE_VOICE) > 0) + if (x->second > mx) { - return "+"; + *px = x->first; + mx = x->second; } - return ""; } } - return ""; + + return px; } @@ -944,4 +945,34 @@ int chanrec::GetStatus(userrec *user) return STATUS_NORMAL; } +void chanrec::SetPrefix(userrec* 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) + { + if (n != prefixes.end()) + { + if (std::find(n->second.begin(), n->second.end(), pfx) == n->second.end()) + { + n->second.push_back(pfx); + } + } + else + { + pfxcontainer one; + one.push_back(pfx); + prefixes.insert(std::make_pair<userrec*,pfxcontainer>(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); + } + } +} diff --git a/src/mode.cpp b/src/mode.cpp index f3cf54e6a..790720c6b 100644 --- a/src/mode.cpp +++ b/src/mode.cpp @@ -65,8 +65,8 @@ using namespace std; /* +n (notice mask - our implementation of snomasks) */ #include "modes/umode_n.h" -ModeHandler::ModeHandler(InspIRCd* Instance, char modeletter, int parameters_on, int parameters_off, bool listmode, ModeType type, bool operonly) - : ServerInstance(Instance), mode(modeletter), n_params_on(parameters_on), n_params_off(parameters_off), list(listmode), m_type(type), oper(operonly) +ModeHandler::ModeHandler(InspIRCd* Instance, char modeletter, int parameters_on, int parameters_off, bool listmode, ModeType type, bool operonly, char mprefix) + : ServerInstance(Instance), mode(modeletter), n_params_on(parameters_on), n_params_off(parameters_off), list(listmode), m_type(type), oper(operonly), prefix(mprefix) { } @@ -79,6 +79,11 @@ bool ModeHandler::IsListMode() return list; } +unsigned int ModeHandler::GetPrefixRank() +{ + return 0; +} + ModeType ModeHandler::GetModeType() { return m_type; @@ -89,6 +94,11 @@ bool ModeHandler::NeedsOper() return oper; } +char ModeHandler::GetPrefix() +{ + return prefix; +} + int ModeHandler::GetNumParams(bool adding) { return adding ? n_params_on : n_params_off; @@ -273,9 +283,10 @@ void ModeParser::Process(const char** parameters, int pcnt, userrec *user, bool */ if ((targetchannel) && (pcnt == 2)) { + ServerInstance->Log(DEBUG,"Spool list"); const char* mode = parameters[1]; if (*mode == '+') - mode++; + mode++; unsigned char handler_id = ((*mode) - 65) | MASK_CHANNEL; ModeHandler* mh = modehandlers[handler_id]; if ((mh) && (mh->IsListMode())) @@ -287,10 +298,13 @@ void ModeParser::Process(const char** parameters, int pcnt, userrec *user, bool if (pcnt == 1) { + ServerInstance->Log(DEBUG,"Mode list request"); this->DisplayCurrentModes(user, targetuser, targetchannel, parameters[0]); } else if (pcnt > 1) { + ServerInstance->Log(DEBUG,"More than one parameter"); + if (targetchannel) { type = MODETYPE_CHANNEL; @@ -341,6 +355,8 @@ void ModeParser::Process(const char** parameters, int pcnt, userrec *user, bool { unsigned char modechar = *letter; + ServerInstance->Log(DEBUG,"Process letter %c", modechar); + switch (modechar) { /* NB: @@ -397,7 +413,7 @@ void ModeParser::Process(const char** parameters, int pcnt, userrec *user, bool parameter = parameters[parameter_counter++]; /* Yerk, invalid! */ - if ((parameter.rfind(':') || (parameter.rfind(' ')))) + if ((parameter.rfind(':') != std::string::npos) || (parameter.rfind(' ') != std::string::npos)) parameter = ""; } else @@ -436,7 +452,17 @@ void ModeParser::Process(const char** parameters, int pcnt, userrec *user, bool /* Is there a valid parameter for this mode? If so add it to the parameter list */ if ((modehandlers[handler_id]->GetNumParams(adding)) && (parameter != "")) + { parameter_list << " " << parameter; + /* Does this mode have a prefix? */ + if (modehandlers[handler_id]->GetPrefix() && targetchannel) + { + userrec* user_to_prefix = ServerInstance->FindNick(parameter); + if (user_to_prefix) + targetchannel->SetPrefix(user_to_prefix, modehandlers[handler_id]->GetPrefix(), + modehandlers[handler_id]->GetPrefixRank(), adding); + } + } /* Call all the AfterMode events in the mode watchers for this mode */ for (ModeWatchIter watchers = modewatchers[handler_id].begin(); watchers != modewatchers[handler_id].end(); watchers++) diff --git a/src/modes/cmode_h.cpp b/src/modes/cmode_h.cpp index 21c97cabc..1b0370439 100644 --- a/src/modes/cmode_h.cpp +++ b/src/modes/cmode_h.cpp @@ -14,10 +14,15 @@ #include "hashcomp.h" #include "modes/cmode_h.h" -ModeChannelHalfOp::ModeChannelHalfOp(InspIRCd* Instance) : ModeHandler(Instance, 'h', 1, 1, true, MODETYPE_CHANNEL, false) +ModeChannelHalfOp::ModeChannelHalfOp(InspIRCd* Instance) : ModeHandler(Instance, 'h', 1, 1, true, MODETYPE_CHANNEL, false, '%') { } +unsigned int ModeChannelHalfOp::GetPrefixRank() +{ + return HALFOP_VALUE; +} + ModePair ModeChannelHalfOp::ModeSet(userrec* source, userrec* dest, chanrec* channel, const std::string ¶meter) { userrec* x = ServerInstance->FindNick(parameter); diff --git a/src/modes/cmode_o.cpp b/src/modes/cmode_o.cpp index 0ab3d9d95..c631ec779 100644 --- a/src/modes/cmode_o.cpp +++ b/src/modes/cmode_o.cpp @@ -14,10 +14,15 @@ #include "hashcomp.h" #include "modes/cmode_o.h" -ModeChannelOp::ModeChannelOp(InspIRCd* Instance) : ModeHandler(Instance, 'o', 1, 1, true, MODETYPE_CHANNEL, false) +ModeChannelOp::ModeChannelOp(InspIRCd* Instance) : ModeHandler(Instance, 'o', 1, 1, true, MODETYPE_CHANNEL, false, '@') { } +unsigned int ModeChannelOp::GetPrefixRank() +{ + return OP_VALUE; +} + ModePair ModeChannelOp::ModeSet(userrec* source, userrec* dest, chanrec* channel, const std::string ¶meter) { userrec* x = ServerInstance->FindNick(parameter); diff --git a/src/modes/cmode_v.cpp b/src/modes/cmode_v.cpp index af1fbe22a..7b14d84d4 100644 --- a/src/modes/cmode_v.cpp +++ b/src/modes/cmode_v.cpp @@ -14,10 +14,15 @@ #include "hashcomp.h" #include "modes/cmode_v.h" -ModeChannelVoice::ModeChannelVoice(InspIRCd* Instance) : ModeHandler(Instance, 'v', 1, 1, true, MODETYPE_CHANNEL, false) +ModeChannelVoice::ModeChannelVoice(InspIRCd* Instance) : ModeHandler(Instance, 'v', 1, 1, true, MODETYPE_CHANNEL, false, '+') { } +unsigned int ModeChannelVoice::GetPrefixRank() +{ + return VOICE_VALUE; +} + ModePair ModeChannelVoice::ModeSet(userrec* source, userrec* dest, chanrec* channel, const std::string ¶meter) { userrec* x = ServerInstance->FindNick(parameter); |