added FEAT_CHMODE_A_NOSET to prevent +a from being set by users
[ircu2.10.12-pk.git] / ircd / channel.c
index 7e9bb09d14b05c1fb3a70fad2e850281f2587940..41e2cdb6dda2d6bfd51dcd95e250451ee8361137 100644 (file)
@@ -2513,6 +2513,9 @@ mode_parse_access(struct ParseState *state, ulong64 *flag_p)
         return;
     }
     
+    if(feature_bool(FEAT_CHMODE_A_NOSET) && !(state->flags & MODE_PARSE_FORCE)) /* mode can'T be set. */
+        return;
+    
     if (!(state->flags & MODE_PARSE_WIPEOUT) &&
        (!t_access || t_access == state->chptr->mode.access))
       return;
@@ -2673,8 +2676,9 @@ mode_parse_noflood(struct ParseState *state, ulong64 *flag_p)
         else t_str++; //simply ignore if it's not an opmode
         tmp++;
     }
-    if(tmp[0] == '+' || tmp[0] == '@') {
+    if(tmp[0] == '+' || tmp[0] == '%' || tmp[0] == '@') {
         if(tmp[0] == '+') flags |= FLFL_VOICE;
+        if(tmp[0] == '%') flags |= FLFL_HALFOP;
         if(tmp[0] == '@') flags |= FLFL_CHANOP;
         tmp++;
     }
@@ -2746,7 +2750,7 @@ mode_parse_noflood(struct ParseState *state, ulong64 *flag_p)
     unsigned int noflood_value = time;
     noflood_value <<= 10;
     noflood_value |= count;
-    noflood_value <<= 3;
+    noflood_value <<= 4;
     noflood_value |= flags;
     state->chptr->mode.noflood_value = noflood_value;
   } else {
@@ -4345,7 +4349,7 @@ int ext_amsg_block(struct Client *cptr, struct Channel *chptr, const char *msg)
     int p_pos = 0;
     int is_visible = 1, is_ccode = 0, i = 0, j = 0;
     char codes[5];
-    for(i = 0; p != '\n'; p = stripped_message[++i]) {
+    for(i = 0; p != '\n' && p != 0; p = stripped_message[++i]) {
       if(p == 3) {
         j = 0;
         is_ccode = 1;
@@ -4430,15 +4434,17 @@ int ext_noflood_block(struct Client *cptr, struct Channel *chptr) {
   struct Membership *member = find_member_link(chptr, cptr);
   if(!member) return 0; //TODO: we've no check for -n channels implemented, yet
   //check if this user is really affected by +f
-  unsigned int flags = (chptr->mode.noflood_value & 0x00000007);        //0000 0000 0000 0000 0000 0000 0000 0111 = 0x00000007 >> 0
-  unsigned int count = (chptr->mode.noflood_value & 0x00001ff8) >> 3;   //0000 0000 0000 0000 0001 1111 1111 1000 = 0x00001ff8 >> 3
-  int time           = (chptr->mode.noflood_value & 0x07ffe000) >> 13;  //0000 0111 1111 1111 1110 0000 0000 0000 = 0x07ffe000 >> 13
+  unsigned int flags = (chptr->mode.noflood_value & 0x0000000f);        //0000 0000 0000 0000 0000 0000 0000 1111 = 0x0000000f >> 0
+  unsigned int count = (chptr->mode.noflood_value & 0x00002ff0) >> 4;   //0000 0000 0000 0000 0011 1111 1111 0000 = 0x00002ff0 >> 4
+  int time           = (chptr->mode.noflood_value & 0x0fffc000) >> 14;  //0000 1111 1111 1111 1100 0000 0000 0000 = 0x0fffc000 >> 14
   if(count == 0 || time == 0) return 0;
   if(!(flags & FLFL_NOFLOOD) && HasPriv(cptr, PRIV_FLOOD))
     return 0;
   if(!(flags & FLFL_CHANOP) && (member->status & CHFL_CHANOP)) 
     return 0;
-  if(!(flags & (FLFL_CHANOP | FLFL_VOICE)) && (member->status & CHFL_VOICE)) 
+  if(!(flags & (FLFL_CHANOP | FLFL_HALFOP)) && (member->status & CHFL_HALFOP)) 
+    return 0;
+  if(!(flags & (FLFL_CHANOP | FLFL_HALFOP | FLFL_VOICE)) && (member->status & CHFL_VOICE)) 
     return 0;
   int floodcount = 0;
   struct MemberFlood *floodnode, *prev_floodnode;