Mode handlers handling listmodes where a listmode item is a nickname can now specify prefixes!!!!!!

This isnt documented yet.


git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@4997 e03df62e-2008-0410-955e-edbf42e46eb7
This commit is contained in:
brain 2006-08-23 20:20:41 +00:00
parent 985169b6ee
commit 8b864c8a82
10 changed files with 131 additions and 26 deletions

View File

@ -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 */ }

View File

@ -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,16 +142,25 @@ 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
*/

View File

@ -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 &parameter);
unsigned int GetPrefixRank();
};

View File

@ -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 &parameter);
unsigned int GetPrefixRank();
};

View File

@ -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 &parameter);
unsigned int GetPrefixRank();
};

View File

@ -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)
if (x->second > mx)
{
return "@";
*px = x->first;
mx = x->second;
}
if (((*i)->uc_modes & UCMODE_HOP) > 0)
{
return "%";
}
if (((*i)->uc_modes & UCMODE_VOICE) > 0)
{
return "+";
}
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);
}
}
}

View File

@ -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++)

View File

@ -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 &parameter)
{
userrec* x = ServerInstance->FindNick(parameter);

View File

@ -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 &parameter)
{
userrec* x = ServerInstance->FindNick(parameter);

View File

@ -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 &parameter)
{
userrec* x = ServerInstance->FindNick(parameter);