Add full support for +a (owner) and +h (halfop) chmodes.
This commit is contained in:
parent
fc5ba33325
commit
82f8e812f5
|
@ -147,10 +147,14 @@ typedef int (*ExtbanFunc)(const char *data, struct Client *client_p,
|
|||
#define CHFL_BANNED 0x0008 /* cached as banned */
|
||||
#define CHFL_QUIETED 0x0010 /* cached as being +q victim */
|
||||
#define ONLY_SERVERS 0x0020
|
||||
#define CHFL_HALFOP 0x0040
|
||||
#define CHFL_OWNER 0x0080
|
||||
#define ALL_MEMBERS CHFL_PEON
|
||||
#define ONLY_CHANOPS CHFL_CHANOP
|
||||
#define ONLY_CHANOPSVOICED (CHFL_CHANOP|CHFL_VOICE)
|
||||
|
||||
#define is_chmode_h(x) ((x) && (x)->flags & CHFL_HALFOP) /* does not check if halfop is enabled, should typically not be used */
|
||||
#define is_chmode_a(x) ((x) && (x)->flags & CHFL_OWNER) /* does not check if owner is enabled, should typically not be used */
|
||||
#define is_chanop(x) ((x) && (x)->flags & CHFL_CHANOP)
|
||||
#define is_voiced(x) ((x) && (x)->flags & CHFL_VOICE)
|
||||
#define can_send_banned(x) ((x) && (x)->flags & (CHFL_BANNED|CHFL_QUIETED))
|
||||
|
|
|
@ -66,9 +66,15 @@ extern void chm_limit(struct Client *source_p, struct Channel *chptr,
|
|||
extern void chm_regonly(struct Client *source_p, struct Channel *chptr,
|
||||
int alevel, int parc, int *parn,
|
||||
const char **parv, int *errors, int dir, char c, long mode_type);
|
||||
extern void chm_owner(struct Client *source_p, struct Channel *chptr,
|
||||
int alevel, int parc, int *parn,
|
||||
const char **parv, int *errors, int dir, char c, long mode_type);
|
||||
extern void chm_op(struct Client *source_p, struct Channel *chptr,
|
||||
int alevel, int parc, int *parn,
|
||||
const char **parv, int *errors, int dir, char c, long mode_type);
|
||||
extern void chm_halfop(struct Client *source_p, struct Channel *chptr,
|
||||
int alevel, int parc, int *parn,
|
||||
const char **parv, int *errors, int dir, char c, long mode_type);
|
||||
extern void chm_voice(struct Client *source_p, struct Channel *chptr,
|
||||
int alevel, int parc, int *parn,
|
||||
const char **parv, int *errors, int dir, char c, long mode_type);
|
||||
|
|
|
@ -490,11 +490,21 @@ ms_sjoin(struct Client *client_p, struct Client *source_p, int parc, const char
|
|||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
if(*s == '@')
|
||||
if(*s == '!')
|
||||
{
|
||||
fl |= CHFL_OWNER;
|
||||
s++;
|
||||
}
|
||||
else if(*s == '@')
|
||||
{
|
||||
fl |= CHFL_CHANOP;
|
||||
s++;
|
||||
}
|
||||
else if(*s == '%')
|
||||
{
|
||||
fl |= CHFL_HALFOP;
|
||||
s++;
|
||||
}
|
||||
else if(*s == '+')
|
||||
{
|
||||
fl |= CHFL_VOICE;
|
||||
|
@ -520,12 +530,24 @@ ms_sjoin(struct Client *client_p, struct Client *source_p, int parc, const char
|
|||
|
||||
if(keep_new_modes)
|
||||
{
|
||||
if(fl & CHFL_OWNER)
|
||||
{
|
||||
*ptr_uid++ = '!';
|
||||
len_nick++;
|
||||
len_uid++;
|
||||
}
|
||||
if(fl & CHFL_CHANOP)
|
||||
{
|
||||
*ptr_uid++ = '@';
|
||||
len_nick++;
|
||||
len_uid++;
|
||||
}
|
||||
if(fl & CHFL_HALFOP)
|
||||
{
|
||||
*ptr_uid++ = '%';
|
||||
len_nick++;
|
||||
len_uid++;
|
||||
}
|
||||
if(fl & CHFL_VOICE)
|
||||
{
|
||||
*ptr_uid++ = '+';
|
||||
|
@ -551,12 +573,108 @@ ms_sjoin(struct Client *client_p, struct Client *source_p, int parc, const char
|
|||
joins++;
|
||||
}
|
||||
|
||||
/* If anyone can think of a way to do this that doesn't make babies cry
|
||||
* I would love to hear it - Taros */
|
||||
|
||||
if(fl & CHFL_OWNER)
|
||||
{
|
||||
*mbuf++ = 'a';
|
||||
para[pargs++] = target_p->name;
|
||||
|
||||
if(fl & CHFL_CHANOP)
|
||||
{
|
||||
/* its possible the +a has filled up MAXMODEPARAMS, if so, start
|
||||
* a new buffer
|
||||
*/
|
||||
if(pargs >= MAXMODEPARAMS)
|
||||
{
|
||||
*mbuf = '\0';
|
||||
sendto_channel_local(ALL_MEMBERS, chptr,
|
||||
":%s MODE %s %s %s %s %s %s",
|
||||
fakesource_p->name, chptr->chname,
|
||||
modebuf,
|
||||
para[0], para[1], para[2], para[3]);
|
||||
mbuf = modebuf;
|
||||
*mbuf++ = '+';
|
||||
para[0] = para[1] = para[2] = para[3] = NULL;
|
||||
pargs = 0;
|
||||
}
|
||||
|
||||
*mbuf++ = 'o';
|
||||
para[pargs++] = target_p->name;
|
||||
}
|
||||
if(fl & CHFL_HALFOP)
|
||||
{
|
||||
/* its possible the +a has filled up MAXMODEPARAMS, if so, start
|
||||
* a new buffer
|
||||
*/
|
||||
if(pargs >= MAXMODEPARAMS)
|
||||
{
|
||||
*mbuf = '\0';
|
||||
sendto_channel_local(ALL_MEMBERS, chptr,
|
||||
":%s MODE %s %s %s %s %s %s",
|
||||
fakesource_p->name, chptr->chname,
|
||||
modebuf,
|
||||
para[0], para[1], para[2], para[3]);
|
||||
mbuf = modebuf;
|
||||
*mbuf++ = '+';
|
||||
para[0] = para[1] = para[2] = para[3] = NULL;
|
||||
pargs = 0;
|
||||
}
|
||||
|
||||
*mbuf++ = 'h';
|
||||
para[pargs++] = target_p->name;
|
||||
}
|
||||
if(fl & CHFL_VOICE)
|
||||
{
|
||||
/* its possible the +a has filled up MAXMODEPARAMS, if so, start
|
||||
* a new buffer
|
||||
*/
|
||||
if(pargs >= MAXMODEPARAMS)
|
||||
{
|
||||
*mbuf = '\0';
|
||||
sendto_channel_local(ALL_MEMBERS, chptr,
|
||||
":%s MODE %s %s %s %s %s %s",
|
||||
fakesource_p->name, chptr->chname,
|
||||
modebuf,
|
||||
para[0], para[1], para[2], para[3]);
|
||||
mbuf = modebuf;
|
||||
*mbuf++ = '+';
|
||||
para[0] = para[1] = para[2] = para[3] = NULL;
|
||||
pargs = 0;
|
||||
}
|
||||
|
||||
*mbuf++ = 'v';
|
||||
para[pargs++] = target_p->name;
|
||||
}
|
||||
}
|
||||
if(fl & CHFL_CHANOP)
|
||||
{
|
||||
*mbuf++ = 'o';
|
||||
para[pargs++] = target_p->name;
|
||||
|
||||
/* a +ov user.. bleh */
|
||||
if(fl & CHFL_HALFOP)
|
||||
{
|
||||
/* its possible the +o has filled up MAXMODEPARAMS, if so, start
|
||||
* a new buffer
|
||||
*/
|
||||
if(pargs >= MAXMODEPARAMS)
|
||||
{
|
||||
*mbuf = '\0';
|
||||
sendto_channel_local(ALL_MEMBERS, chptr,
|
||||
":%s MODE %s %s %s %s %s %s",
|
||||
fakesource_p->name, chptr->chname,
|
||||
modebuf,
|
||||
para[0], para[1], para[2], para[3]);
|
||||
mbuf = modebuf;
|
||||
*mbuf++ = '+';
|
||||
para[0] = para[1] = para[2] = para[3] = NULL;
|
||||
pargs = 0;
|
||||
}
|
||||
|
||||
*mbuf++ = 'h';
|
||||
para[pargs++] = target_p->name;
|
||||
}
|
||||
if(fl & CHFL_VOICE)
|
||||
{
|
||||
/* its possible the +o has filled up MAXMODEPARAMS, if so, start
|
||||
|
@ -580,6 +698,34 @@ ms_sjoin(struct Client *client_p, struct Client *source_p, int parc, const char
|
|||
para[pargs++] = target_p->name;
|
||||
}
|
||||
}
|
||||
if(fl & CHFL_HALFOP)
|
||||
{
|
||||
*mbuf++ = 'h';
|
||||
para[pargs++] = target_p->name;
|
||||
|
||||
if(fl & CHFL_VOICE)
|
||||
{
|
||||
/* its possible the +h has filled up MAXMODEPARAMS, if so, start
|
||||
* a new buffer
|
||||
*/
|
||||
if(pargs >= MAXMODEPARAMS)
|
||||
{
|
||||
*mbuf = '\0';
|
||||
sendto_channel_local(ALL_MEMBERS, chptr,
|
||||
":%s MODE %s %s %s %s %s %s",
|
||||
fakesource_p->name, chptr->chname,
|
||||
modebuf,
|
||||
para[0], para[1], para[2], para[3]);
|
||||
mbuf = modebuf;
|
||||
*mbuf++ = '+';
|
||||
para[0] = para[1] = para[2] = para[3] = NULL;
|
||||
pargs = 0;
|
||||
}
|
||||
|
||||
*mbuf++ = 'v';
|
||||
para[pargs++] = target_p->name;
|
||||
}
|
||||
}
|
||||
else if(fl & CHFL_VOICE)
|
||||
{
|
||||
*mbuf++ = 'v';
|
||||
|
@ -798,13 +944,152 @@ remove_our_modes(struct Channel *chptr, struct Client *source_p)
|
|||
{
|
||||
msptr = ptr->data;
|
||||
|
||||
if(is_chanop(msptr))
|
||||
/* If anyone can think of a way to do this that doesn't make babies cry
|
||||
* I would love to hear it - Taros */
|
||||
|
||||
if(is_owner(msptr))
|
||||
{
|
||||
msptr->flags &= ~CHFL_OWNER;
|
||||
lpara[count++] = msptr->client_p->name;
|
||||
*mbuf++ = 'a';
|
||||
|
||||
/* Make sure it fits if +h, +o, or +v are involved */
|
||||
if(is_chanop(msptr))
|
||||
{
|
||||
if(count >= MAXMODEPARAMS)
|
||||
{
|
||||
*mbuf = '\0';
|
||||
sendto_channel_local(ALL_MEMBERS, chptr,
|
||||
":%s MODE %s %s %s %s %s %s",
|
||||
source_p->name, chptr->chname,
|
||||
lmodebuf, lpara[0], lpara[1],
|
||||
lpara[2], lpara[3]);
|
||||
|
||||
/* preserve the initial '-' */
|
||||
mbuf = lmodebuf;
|
||||
*mbuf++ = '-';
|
||||
count = 0;
|
||||
|
||||
for(i = 0; i < MAXMODEPARAMS; i++)
|
||||
lpara[i] = NULL;
|
||||
}
|
||||
|
||||
msptr->flags &= ~CHFL_CHANOP;
|
||||
lpara[count++] = msptr->client_p->name;
|
||||
*mbuf++ = 'o';
|
||||
}
|
||||
if(is_halfop(msptr))
|
||||
{
|
||||
if(count >= MAXMODEPARAMS)
|
||||
{
|
||||
*mbuf = '\0';
|
||||
sendto_channel_local(ALL_MEMBERS, chptr,
|
||||
":%s MODE %s %s %s %s %s %s",
|
||||
source_p->name, chptr->chname,
|
||||
lmodebuf, lpara[0], lpara[1],
|
||||
lpara[2], lpara[3]);
|
||||
|
||||
/* preserve the initial '-' */
|
||||
mbuf = lmodebuf;
|
||||
*mbuf++ = '-';
|
||||
count = 0;
|
||||
|
||||
for(i = 0; i < MAXMODEPARAMS; i++)
|
||||
lpara[i] = NULL;
|
||||
}
|
||||
|
||||
msptr->flags &= ~CHFL_HALFOP;
|
||||
lpara[count++] = msptr->client_p->name;
|
||||
*mbuf++ = 'h';
|
||||
}
|
||||
if(is_voiced(msptr))
|
||||
{
|
||||
if(count >= MAXMODEPARAMS)
|
||||
{
|
||||
*mbuf = '\0';
|
||||
sendto_channel_local(ALL_MEMBERS, chptr,
|
||||
":%s MODE %s %s %s %s %s %s",
|
||||
source_p->name, chptr->chname,
|
||||
lmodebuf, lpara[0], lpara[1],
|
||||
lpara[2], lpara[3]);
|
||||
|
||||
/* preserve the initial '-' */
|
||||
mbuf = lmodebuf;
|
||||
*mbuf++ = '-';
|
||||
count = 0;
|
||||
|
||||
for(i = 0; i < MAXMODEPARAMS; i++)
|
||||
lpara[i] = NULL;
|
||||
}
|
||||
|
||||
msptr->flags &= ~CHFL_VOICE;
|
||||
lpara[count++] = msptr->client_p->name;
|
||||
*mbuf++ = 'v';
|
||||
}
|
||||
}
|
||||
else if(is_chanop(msptr))
|
||||
{
|
||||
msptr->flags &= ~CHFL_CHANOP;
|
||||
lpara[count++] = msptr->client_p->name;
|
||||
*mbuf++ = 'o';
|
||||
|
||||
/* +ov, might not fit so check. */
|
||||
/* Make sure it fits if +h or +v are involved */
|
||||
if(is_halfop(msptr))
|
||||
{
|
||||
if(count >= MAXMODEPARAMS)
|
||||
{
|
||||
*mbuf = '\0';
|
||||
sendto_channel_local(ALL_MEMBERS, chptr,
|
||||
":%s MODE %s %s %s %s %s %s",
|
||||
source_p->name, chptr->chname,
|
||||
lmodebuf, lpara[0], lpara[1],
|
||||
lpara[2], lpara[3]);
|
||||
|
||||
/* preserve the initial '-' */
|
||||
mbuf = lmodebuf;
|
||||
*mbuf++ = '-';
|
||||
count = 0;
|
||||
|
||||
for(i = 0; i < MAXMODEPARAMS; i++)
|
||||
lpara[i] = NULL;
|
||||
}
|
||||
|
||||
msptr->flags &= ~CHFL_HALFOP;
|
||||
lpara[count++] = msptr->client_p->name;
|
||||
*mbuf++ = 'h';
|
||||
}
|
||||
if(is_voiced(msptr))
|
||||
{
|
||||
if(count >= MAXMODEPARAMS)
|
||||
{
|
||||
*mbuf = '\0';
|
||||
sendto_channel_local(ALL_MEMBERS, chptr,
|
||||
":%s MODE %s %s %s %s %s %s",
|
||||
source_p->name, chptr->chname,
|
||||
lmodebuf, lpara[0], lpara[1],
|
||||
lpara[2], lpara[3]);
|
||||
|
||||
/* preserve the initial '-' */
|
||||
mbuf = lmodebuf;
|
||||
*mbuf++ = '-';
|
||||
count = 0;
|
||||
|
||||
for(i = 0; i < MAXMODEPARAMS; i++)
|
||||
lpara[i] = NULL;
|
||||
}
|
||||
|
||||
msptr->flags &= ~CHFL_VOICE;
|
||||
lpara[count++] = msptr->client_p->name;
|
||||
*mbuf++ = 'v';
|
||||
}
|
||||
}
|
||||
else if(is_halfop(msptr))
|
||||
{
|
||||
msptr->flags &= ~CHFL_HALFOP;
|
||||
lpara[count++] = msptr->client_p->name;
|
||||
*mbuf++ = 'h';
|
||||
|
||||
/* +hv, might not fit so check. */
|
||||
if(is_voiced(msptr))
|
||||
{
|
||||
if(count >= MAXMODEPARAMS)
|
||||
|
|
|
@ -219,9 +219,10 @@ find_channel_status(struct membership *msptr, int combine)
|
|||
int
|
||||
is_halfop(struct membership *msptr)
|
||||
{
|
||||
/* will do something other than return 0 when owner is implemented */
|
||||
if(!ConfigChannel.use_halfop)
|
||||
return 0;
|
||||
if(is_chmode_h(msptr))
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
@ -237,9 +238,10 @@ is_halfop(struct membership *msptr)
|
|||
int
|
||||
is_owner(struct membership *msptr)
|
||||
{
|
||||
/* will do something other than return 0 when owner is implemented */
|
||||
if(!ConfigChannel.use_owner)
|
||||
return 0;
|
||||
if(is_chmode_a(msptr))
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
|
226
src/chmode.c
226
src/chmode.c
|
@ -89,7 +89,9 @@ construct_noparam_modes(void)
|
|||
!(chmode_table[i].set_func == chm_throttle) &&
|
||||
!(chmode_table[i].set_func == chm_key) &&
|
||||
!(chmode_table[i].set_func == chm_limit) &&
|
||||
!(chmode_table[i].set_func == chm_owner) &&
|
||||
!(chmode_table[i].set_func == chm_op) &&
|
||||
!(chmode_table[i].set_func == chm_halfop) &&
|
||||
!(chmode_table[i].set_func == chm_voice))
|
||||
{
|
||||
chmode_flags[i] = chmode_table[i].mode_type;
|
||||
|
@ -175,8 +177,12 @@ find_cflag_slot(void)
|
|||
static int
|
||||
get_channel_access(struct Client *source_p, struct membership *msptr)
|
||||
{
|
||||
if(!MyClient(source_p) || is_chanop(msptr))
|
||||
if(!MyClient(source_p) || is_owner(msptr))
|
||||
return CHFL_OWNER;
|
||||
else if(is_chanop(msptr))
|
||||
return CHFL_CHANOP;
|
||||
else if(is_halfop(msptr))
|
||||
return CHFL_HALFOP;
|
||||
|
||||
return CHFL_PEON;
|
||||
}
|
||||
|
@ -492,7 +498,7 @@ chm_simple(struct Client *source_p, struct Channel *chptr,
|
|||
int alevel, int parc, int *parn,
|
||||
const char **parv, int *errors, int dir, char c, long mode_type)
|
||||
{
|
||||
if(alevel != CHFL_CHANOP)
|
||||
if(alevel != CHFL_CHANOP && alevel != CHFL_OWNER && alevel != CHFL_HALFOP)
|
||||
{
|
||||
if(!(*errors & SM_ERR_NOOPS))
|
||||
sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
|
||||
|
@ -706,7 +712,7 @@ chm_ban(struct Client *source_p, struct Channel *chptr,
|
|||
*errors |= errorval;
|
||||
|
||||
/* non-ops cant see +eI lists.. */
|
||||
if(alevel != CHFL_CHANOP && mode_type != CHFL_BAN &&
|
||||
if(alevel != CHFL_CHANOP && alevel != CHFL_OWNER && alevel != CHFL_HALFOP && mode_type != CHFL_BAN &&
|
||||
mode_type != CHFL_QUIET)
|
||||
{
|
||||
if(!(*errors & SM_ERR_NOOPS))
|
||||
|
@ -730,7 +736,7 @@ chm_ban(struct Client *source_p, struct Channel *chptr,
|
|||
return;
|
||||
}
|
||||
|
||||
if(alevel != CHFL_CHANOP)
|
||||
if(alevel != CHFL_CHANOP && alevel != CHFL_OWNER && alevel != CHFL_HALFOP)
|
||||
{
|
||||
if(!(*errors & SM_ERR_NOOPS))
|
||||
sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
|
||||
|
@ -809,6 +815,103 @@ chm_ban(struct Client *source_p, struct Channel *chptr,
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
chm_owner(struct Client *source_p, struct Channel *chptr,
|
||||
int alevel, int parc, int *parn,
|
||||
const char **parv, int *errors, int dir, char c, long mode_type)
|
||||
{
|
||||
struct membership *mstptr;
|
||||
const char *ownernick;
|
||||
struct Client *targ_p;
|
||||
|
||||
if(!ConfigChannel.use_owner)
|
||||
{
|
||||
if(*errors & SM_ERR_UNKNOWN)
|
||||
return;
|
||||
*errors |= SM_ERR_UNKNOWN;
|
||||
sendto_one(source_p, form_str(ERR_UNKNOWNMODE), me.name, source_p->name, c);
|
||||
return;
|
||||
}
|
||||
|
||||
if(alevel != CHFL_OWNER)
|
||||
{
|
||||
if(!(*errors & SM_ERR_NOOPS))
|
||||
sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
|
||||
me.name, source_p->name, chptr->chname);
|
||||
*errors |= SM_ERR_NOOPS;
|
||||
return;
|
||||
}
|
||||
|
||||
if((dir == MODE_QUERY) || (parc <= *parn))
|
||||
return;
|
||||
|
||||
ownernick = parv[(*parn)];
|
||||
(*parn)++;
|
||||
|
||||
/* empty nick */
|
||||
if(EmptyString(ownernick))
|
||||
{
|
||||
sendto_one_numeric(source_p, ERR_NOSUCHNICK, form_str(ERR_NOSUCHNICK), "*");
|
||||
return;
|
||||
}
|
||||
|
||||
if((targ_p = find_chasing(source_p, ownernick, NULL)) == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
mstptr = find_channel_membership(chptr, targ_p);
|
||||
|
||||
if(mstptr == NULL)
|
||||
{
|
||||
if(!(*errors & SM_ERR_NOTONCHANNEL) && MyClient(source_p))
|
||||
sendto_one_numeric(source_p, ERR_USERNOTINCHANNEL,
|
||||
form_str(ERR_USERNOTINCHANNEL), ownernick, chptr->chname);
|
||||
*errors |= SM_ERR_NOTONCHANNEL;
|
||||
return;
|
||||
}
|
||||
|
||||
if(MyClient(source_p) && (++mode_limit > MAXMODEPARAMS))
|
||||
return;
|
||||
|
||||
if(dir == MODE_ADD)
|
||||
{
|
||||
if(targ_p == source_p)
|
||||
return;
|
||||
|
||||
mode_changes[mode_count].letter = c;
|
||||
mode_changes[mode_count].dir = MODE_ADD;
|
||||
mode_changes[mode_count].caps = 0;
|
||||
mode_changes[mode_count].nocaps = 0;
|
||||
mode_changes[mode_count].mems = ALL_MEMBERS;
|
||||
mode_changes[mode_count].id = targ_p->id;
|
||||
mode_changes[mode_count].arg = targ_p->name;
|
||||
mode_changes[mode_count++].client = targ_p;
|
||||
|
||||
mstptr->flags |= CHFL_OWNER;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(MyClient(source_p) && IsService(targ_p))
|
||||
{
|
||||
sendto_one(source_p, form_str(ERR_ISCHANSERVICE),
|
||||
me.name, source_p->name, targ_p->name, chptr->chname);
|
||||
return;
|
||||
}
|
||||
|
||||
mode_changes[mode_count].letter = c;
|
||||
mode_changes[mode_count].dir = MODE_DEL;
|
||||
mode_changes[mode_count].caps = 0;
|
||||
mode_changes[mode_count].nocaps = 0;
|
||||
mode_changes[mode_count].mems = ALL_MEMBERS;
|
||||
mode_changes[mode_count].id = targ_p->id;
|
||||
mode_changes[mode_count].arg = targ_p->name;
|
||||
mode_changes[mode_count++].client = targ_p;
|
||||
|
||||
mstptr->flags &= ~CHFL_OWNER;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
chm_op(struct Client *source_p, struct Channel *chptr,
|
||||
int alevel, int parc, int *parn,
|
||||
|
@ -818,7 +921,7 @@ chm_op(struct Client *source_p, struct Channel *chptr,
|
|||
const char *opnick;
|
||||
struct Client *targ_p;
|
||||
|
||||
if(alevel != CHFL_CHANOP)
|
||||
if(alevel != CHFL_CHANOP && alevel != CHFL_OWNER)
|
||||
{
|
||||
if(!(*errors & SM_ERR_NOOPS))
|
||||
sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
|
||||
|
@ -897,6 +1000,103 @@ chm_op(struct Client *source_p, struct Channel *chptr,
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
chm_halfop(struct Client *source_p, struct Channel *chptr,
|
||||
int alevel, int parc, int *parn,
|
||||
const char **parv, int *errors, int dir, char c, long mode_type)
|
||||
{
|
||||
struct membership *mstptr;
|
||||
const char *halfopnick;
|
||||
struct Client *targ_p;
|
||||
|
||||
if(!ConfigChannel.use_halfop)
|
||||
{
|
||||
if(*errors & SM_ERR_UNKNOWN)
|
||||
return;
|
||||
*errors |= SM_ERR_UNKNOWN;
|
||||
sendto_one(source_p, form_str(ERR_UNKNOWNMODE), me.name, source_p->name, c);
|
||||
return;
|
||||
}
|
||||
|
||||
if(alevel != CHFL_CHANOP && alevel != CHFL_OWNER && alevel != CHFL_HALFOP)
|
||||
{
|
||||
if(!(*errors & SM_ERR_NOOPS))
|
||||
sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
|
||||
me.name, source_p->name, chptr->chname);
|
||||
*errors |= SM_ERR_NOOPS;
|
||||
return;
|
||||
}
|
||||
|
||||
if((dir == MODE_QUERY) || (parc <= *parn))
|
||||
return;
|
||||
|
||||
halfopnick = parv[(*parn)];
|
||||
(*parn)++;
|
||||
|
||||
/* empty nick */
|
||||
if(EmptyString(halfopnick))
|
||||
{
|
||||
sendto_one_numeric(source_p, ERR_NOSUCHNICK, form_str(ERR_NOSUCHNICK), "*");
|
||||
return;
|
||||
}
|
||||
|
||||
if((targ_p = find_chasing(source_p, halfopnick, NULL)) == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
mstptr = find_channel_membership(chptr, targ_p);
|
||||
|
||||
if(mstptr == NULL)
|
||||
{
|
||||
if(!(*errors & SM_ERR_NOTONCHANNEL) && MyClient(source_p))
|
||||
sendto_one_numeric(source_p, ERR_USERNOTINCHANNEL,
|
||||
form_str(ERR_USERNOTINCHANNEL), halfopnick, chptr->chname);
|
||||
*errors |= SM_ERR_NOTONCHANNEL;
|
||||
return;
|
||||
}
|
||||
|
||||
if(MyClient(source_p) && (++mode_limit > MAXMODEPARAMS))
|
||||
return;
|
||||
|
||||
if(dir == MODE_ADD)
|
||||
{
|
||||
if(targ_p == source_p)
|
||||
return;
|
||||
|
||||
mode_changes[mode_count].letter = c;
|
||||
mode_changes[mode_count].dir = MODE_ADD;
|
||||
mode_changes[mode_count].caps = 0;
|
||||
mode_changes[mode_count].nocaps = 0;
|
||||
mode_changes[mode_count].mems = ALL_MEMBERS;
|
||||
mode_changes[mode_count].id = targ_p->id;
|
||||
mode_changes[mode_count].arg = targ_p->name;
|
||||
mode_changes[mode_count++].client = targ_p;
|
||||
|
||||
mstptr->flags |= CHFL_HALFOP;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(MyClient(source_p) && IsService(targ_p))
|
||||
{
|
||||
sendto_one(source_p, form_str(ERR_ISCHANSERVICE),
|
||||
me.name, source_p->name, targ_p->name, chptr->chname);
|
||||
return;
|
||||
}
|
||||
|
||||
mode_changes[mode_count].letter = c;
|
||||
mode_changes[mode_count].dir = MODE_DEL;
|
||||
mode_changes[mode_count].caps = 0;
|
||||
mode_changes[mode_count].nocaps = 0;
|
||||
mode_changes[mode_count].mems = ALL_MEMBERS;
|
||||
mode_changes[mode_count].id = targ_p->id;
|
||||
mode_changes[mode_count].arg = targ_p->name;
|
||||
mode_changes[mode_count++].client = targ_p;
|
||||
|
||||
mstptr->flags &= ~CHFL_HALFOP;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
chm_voice(struct Client *source_p, struct Channel *chptr,
|
||||
int alevel, int parc, int *parn,
|
||||
|
@ -906,7 +1106,7 @@ chm_voice(struct Client *source_p, struct Channel *chptr,
|
|||
const char *opnick;
|
||||
struct Client *targ_p;
|
||||
|
||||
if(alevel != CHFL_CHANOP)
|
||||
if(alevel != CHFL_CHANOP && alevel != CHFL_OWNER && alevel != CHFL_HALFOP)
|
||||
{
|
||||
if(!(*errors & SM_ERR_NOOPS))
|
||||
sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
|
||||
|
@ -984,7 +1184,7 @@ chm_limit(struct Client *source_p, struct Channel *chptr,
|
|||
static char limitstr[30];
|
||||
int limit;
|
||||
|
||||
if(alevel != CHFL_CHANOP)
|
||||
if(alevel != CHFL_CHANOP && alevel != CHFL_OWNER && alevel != CHFL_HALFOP)
|
||||
{
|
||||
if(!(*errors & SM_ERR_NOOPS))
|
||||
sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
|
||||
|
@ -1043,7 +1243,7 @@ chm_throttle(struct Client *source_p, struct Channel *chptr,
|
|||
{
|
||||
int joins = 0, timeslice = 0;
|
||||
|
||||
if(alevel != CHFL_CHANOP)
|
||||
if(alevel != CHFL_CHANOP && alevel != CHFL_OWNER && alevel != CHFL_HALFOP)
|
||||
{
|
||||
if(!(*errors & SM_ERR_NOOPS))
|
||||
sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
|
||||
|
@ -1126,7 +1326,7 @@ chm_forward(struct Client *source_p, struct Channel *chptr,
|
|||
}
|
||||
|
||||
#ifndef FORWARD_OPERONLY
|
||||
if(alevel != CHFL_CHANOP)
|
||||
if(alevel != CHFL_CHANOP && alevel != CHFL_OWNER && alevel != CHFL_HALFOP)
|
||||
{
|
||||
if(!(*errors & SM_ERR_NOOPS))
|
||||
sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
|
||||
|
@ -1218,7 +1418,7 @@ chm_key(struct Client *source_p, struct Channel *chptr,
|
|||
{
|
||||
char *key;
|
||||
|
||||
if(alevel != CHFL_CHANOP)
|
||||
if(alevel != CHFL_CHANOP && alevel != CHFL_OWNER && alevel != CHFL_HALFOP)
|
||||
{
|
||||
if(!(*errors & SM_ERR_NOOPS))
|
||||
sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
|
||||
|
@ -1295,7 +1495,7 @@ chm_regonly(struct Client *source_p, struct Channel *chptr,
|
|||
int alevel, int parc, int *parn,
|
||||
const char **parv, int *errors, int dir, char c, long mode_type)
|
||||
{
|
||||
if(alevel != CHFL_CHANOP)
|
||||
if(alevel != CHFL_CHANOP && alevel != CHFL_OWNER && alevel != CHFL_HALFOP)
|
||||
{
|
||||
if(!(*errors & SM_ERR_NOOPS))
|
||||
sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
|
||||
|
@ -1429,14 +1629,14 @@ struct ChannelMode chmode_table[256] =
|
|||
{chm_nosuch, 0 },
|
||||
{chm_nosuch, 0 },
|
||||
{chm_nosuch, 0 },
|
||||
{chm_nosuch, 0 }, /* a */
|
||||
{chm_owner, 0 }, /* a */
|
||||
{chm_ban, CHFL_BAN }, /* b */
|
||||
{chm_simple, MODE_NOCOLOR }, /* c */
|
||||
{chm_nosuch, 0 }, /* d */
|
||||
{chm_ban, CHFL_EXCEPTION }, /* e */
|
||||
{chm_forward, 0 }, /* f */
|
||||
{chm_simple, MODE_FREEINVITE }, /* g */
|
||||
{chm_nosuch, 0 }, /* h */
|
||||
{chm_halfop, 0 }, /* h */
|
||||
{chm_simple, MODE_INVITEONLY }, /* i */
|
||||
{chm_throttle, 0 }, /* j */
|
||||
{chm_key, 0 }, /* k */
|
||||
|
|
|
@ -584,7 +584,7 @@ sendto_channel_opmod(struct Client *one, struct Client *source_p,
|
|||
if(IsIOError(target_p->from) || target_p->from == one)
|
||||
continue;
|
||||
|
||||
if((msptr->flags & CHFL_CHANOP) == 0)
|
||||
if(!is_any_op(msptr))
|
||||
continue;
|
||||
|
||||
if(IsDeaf(target_p))
|
||||
|
|
Loading…
Reference in New Issue