fix
[ircu2.10.12-pk.git] / ircd / channel.c
index fd48bde4b2af4422ff81423b2e86d42f40879f11..1bba9b8e070c89cdd2ec1c2f81ffbb678452a783 100644 (file)
@@ -2727,6 +2727,19 @@ mode_parse_noflood(struct ParseState *state, ulong64 *flag_p)
     noflood_value <<= 3;
     noflood_value |= flags;
     state->chptr->mode.noflood_value = noflood_value;
+  } else {
+    //removed the mode so free all flood objects
+    struct Membership *member;
+    for(member = state->chptr->members; member; member = member->next_member) {
+        struct MemberFlood *floodnode;
+        for(floodnode = member->flood;floodnode ; floodnode = floodnode->next_memberflood) {
+          if(floodnode->next_memberflood == NULL) break;
+        } //simply walk to the end
+        if(!floodnode) continue;
+        floodnode->next_memberflood = free_MemberFlood;
+        free_MemberFlood  = floodnode;
+        member->flood = NULL;
+    }
   }
 }
 
@@ -4295,7 +4308,7 @@ void RevealDelayedJoinIfNeeded(struct Client *sptr, struct Channel *chptr)
 int ext_amsg_block(struct Client *cptr, struct Channel *chptr, const char *msg)
 {
   int amsg_time;
-
+  
   /* First on every message we check whether the mechanism is enabled.
    * If it is enabled, we check:
    *  - whether the channel has MODE_NOAMSGS
@@ -4309,6 +4322,60 @@ int ext_amsg_block(struct Client *cptr, struct Channel *chptr, const char *msg)
    */
   amsg_time = feature_int(FEAT_NOAMSG_TIME);
   if(amsg_time > 0) {
+    /* first of all strip the message (filter out invisible content) */
+    char *stripped_message = MyMalloc(BUFSIZE + 1);
+    strcpy(stripped_message, msg);
+    char p = stripped_message[0];
+    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]) {
+      if(p == 3) {
+        j = 0;
+        is_ccode = 1;
+      } else if(is_ccode) {
+        if((p >= 48 && p <= 57) || p == 44) {
+          if(is_ccode == 1) {
+            if(p == 44) {
+              is_ccode = 2;
+              codes[j++] = 0;
+              j = 0;
+            } else
+              codes[j++] = p;
+          } else {
+            //compare
+            if(p != codes[j++]) {
+             is_ccode = 3;
+            }
+          }
+        } else {
+          //END of color code...
+          is_ccode = 0;
+          if(is_ccode != 1 && codes[j] != 0) is_ccode = 3;
+          if(is_ccode == 1) {
+            codes[j] = 0;
+            int k;
+            for(k = 0; k < j-1; k++) {
+              if(codes[k] != 48) {
+                is_visible = 1;
+                goto normalchar;
+              }
+            }
+            is_visible = 0;
+          } else if(is_ccode == 2) {
+            is_visible = 0;
+          } else if(is_ccode == 3) {
+            is_visible = 1;
+            goto normalchar;
+          }
+        }
+      } else {
+        normalchar:
+        if(is_visible)
+          stripped_message[p_pos++] = p;
+      }
+    }
+    stripped_message[p_pos++] = 0;
     /* Allocate a new buffer if there is none, yet. */
     if(!cli_user(cptr)->lastmsg) {
       cli_user(cptr)->lastmsg = MyMalloc(BUFSIZE + 1);
@@ -4316,16 +4383,18 @@ int ext_amsg_block(struct Client *cptr, struct Channel *chptr, const char *msg)
     }
     if((chptr->mode.mode & MODE_NOAMSGS) &&
        ((cli_user(cptr)->lastmsg_time + amsg_time) >= CurrentTime) &&
-       (strcmp(cli_user(cptr)->lastmsg, msg) == 0)) {
+       (strcmp(cli_user(cptr)->lastmsg, stripped_message) == 0)) {
       cli_user(cptr)->lastmsg_time = CurrentTime;
       cli_user(cptr)->lastmsg_num++;
+      MyFree(stripped_message);
       if(cli_user(cptr)->lastmsg_num >= feature_int(FEAT_NOAMSG_NUM)) return 1;
       else return 0;
     }
     /* Message did not match so update the data. */
     cli_user(cptr)->lastmsg_time = CurrentTime;
     cli_user(cptr)->lastmsg_num = 0;
-    strcpy(cli_user(cptr)->lastmsg, msg);
+    strcpy(cli_user(cptr)->lastmsg, stripped_message);
+    MyFree(stripped_message);
   }
   return 0;
 }
@@ -4341,13 +4410,14 @@ int ext_amsg_block(struct Client *cptr, struct Channel *chptr, const char *msg)
  * --pk910 2011/7/1
  */
 int ext_noflood_block(struct Client *cptr, struct Channel *chptr) {
-  if(!chptr->mode.noflood) return 0;
+  if(chptr->mode.noflood == NULL || !chptr->mode.noflood) return 0;
   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
+  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))