Forward port of delayed-join.patch from Quakenet's "Asuka" patch set
[ircu2.10.12-pk.git] / ircd / m_burst.c
index 289c93efb390414a3b05bb033bb8c9648ec470ca..3354a0461d3eb54207853131beb2d5fef260edcd 100644 (file)
@@ -238,7 +238,7 @@ int ms_burst(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
     modebuf_mode(mbuf, MODE_DEL | chptr->mode.mode); /* wipeout modes */
     chptr->mode.mode &= ~(MODE_ADD | MODE_DEL | MODE_PRIVATE | MODE_SECRET |
                          MODE_MODERATED | MODE_TOPICLIMIT | MODE_INVITEONLY |
-                         MODE_NOPRIVMSGS);
+                         MODE_NOPRIVMSGS | MODE_DELJOINS);
 
     parse_flags |= (MODE_PARSE_SET | MODE_PARSE_WIPEOUT); /* wipeout keys */
 
@@ -340,12 +340,16 @@ int ms_burst(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
       {
        struct Client *acptr;
        char *nicklist = parv[param], *p = 0, *nick, *ptr;
-       int current_mode = CHFL_DEOPPED | CHFL_BURST_JOINED;
-       int last_mode = CHFL_DEOPPED | CHFL_BURST_JOINED;
+       int current_mode, last_mode, base_mode;
        int oplevel = -1;       /* Mark first field with digits: means the same as 'o' (but with level). */
        int last_oplevel = 0;
        struct Membership* member;
 
+        base_mode = CHFL_DEOPPED | CHFL_BURST_JOINED;
+        if (chptr->mode.mode & MODE_DELJOINS)
+            base_mode |= CHFL_DELAYED;
+        current_mode = last_mode = base_mode;
+
        for (nick = ircd_strtok(&p, nicklist, ","); nick;
             nick = ircd_strtok(&p, 0, ",")) {
 
@@ -363,29 +367,29 @@ int ms_burst(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
                   */
                  oplevel = MAXOPLEVEL;
                  if (current_mode_needs_reset) {
-                   current_mode = CHFL_DEOPPED | CHFL_BURST_JOINED;
+                   current_mode = base_mode;
                    current_mode_needs_reset = 0;
                  }
-                 current_mode = (current_mode & ~CHFL_DEOPPED) | CHFL_CHANOP;
+                 current_mode = (current_mode & ~(CHFL_DEOPPED | CHFL_DELAYED)) | CHFL_CHANOP;
                }
                else if (*ptr == 'v') { /* has voice status */
                  if (current_mode_needs_reset) {
-                   current_mode = CHFL_DEOPPED | CHFL_BURST_JOINED;
+                    current_mode = base_mode;
                    current_mode_needs_reset = 0;
                  }
-                 current_mode |= CHFL_VOICE;
+                 current_mode = (current_mode & ~CHFL_DELAYED) | CHFL_VOICE;
                  oplevel = -1; /* subsequential digits are an absolute op-level value. */
                 }
                else if (isdigit(*ptr)) {
                  int level_increment = 0;
                  if (oplevel == -1) { /* op-level is absolute value? */
                    if (current_mode_needs_reset) {
-                     current_mode = CHFL_DEOPPED | CHFL_BURST_JOINED;
+                     current_mode = base_mode;
                      current_mode_needs_reset = 0;
                    }
                    oplevel = 0;
                  }
-                 current_mode = (current_mode & ~CHFL_DEOPPED) | CHFL_CHANOP;
+                 current_mode = (current_mode & ~(CHFL_DEOPPED | CHFL_DELAYED)) | CHFL_CHANOP;
                  do {
                    level_increment = 10 * level_increment + *ptr++ - '0';
                  } while(isdigit(*ptr));
@@ -425,7 +429,8 @@ int ms_burst(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
          if (IsBurst(sptr) || !(member = find_member_link(chptr, acptr)))
          {
            add_user_to_channel(chptr, acptr, current_mode, oplevel);
-           sendcmdto_channel_butserv_butone(acptr, CMD_JOIN, chptr, NULL, "%H", chptr);
+            if (!(current_mode & CHFL_DELAYED))
+              sendcmdto_channel_butserv_butone(acptr, CMD_JOIN, chptr, NULL, "%H", chptr);
          }
          else
          {