Add HIS_MODEWHO feature.
[ircu2.10.12-pk.git] / ircd / channel.c
index 57839aa6c6c3fcbf095245f6e2c85c7a9ee4e6ef..dbdd53453082e59450f2b4bd075453962037907e 100644 (file)
@@ -287,6 +287,22 @@ int sub1_from_channel(struct Channel* chptr)
       free_ban(link);
     }
     chptr->banlist = NULL;
+     
+#if 1 /* Temporary code */
+    /* Immediately destruct empty -A channels if ZANNELS is FALSE.
+       When OPLEVELS is true, ZANNELS should be TRUE too. Test for
+       that error. This is done to avoid the DESTRUCT message to
+       occur, which is necessary on a network with mixed versions
+       of 2.10.12.x, with x < 04 *and* 2.10.11 servers. Because
+       servers prior to 2.10.12.04 can cause a BURST message outside
+       the normal net.burst as a result of a DESTRUCT message, and
+       2.10.11 SQUIT servers when they do that. */
+    if (!(feature_bool(FEAT_ZANNELS) || feature_bool(FEAT_OPLEVELS)))
+    {
+      destruct_channel(chptr);
+      return 0;
+    }
+#endif
   }
   if (TStime() - chptr->creationtime < 172800) /* Channel younger than 48 hours? */
     schedule_destruct_event_1m(chptr);         /* Get rid of it in approximately 4-5 minutes */
@@ -666,7 +682,7 @@ int has_voice(struct Client* cptr, struct Channel* chptr)
  *
  * @param member       The membership of the user
  * @param reveal       If true, the user will be "revealed" on a delayed
- *                     joined channel. 
+ *                     joined channel.
  *
  * @returns True if the client can speak on the channel.
  */
@@ -674,10 +690,22 @@ int member_can_send_to_channel(struct Membership* member, int reveal)
 {
   assert(0 != member);
 
-  /* Discourage using the Apass to get op.  They should use the upass. */
+  /* Do not check for users on other servers: This should be a
+   * temporary desynch, or maybe they are on an older server, but
+   * we do not want to send ERR_CANNOTSENDTOCHAN more than once.
+   */
+  if (!MyUser(member->user))
+  {
+    if (IsDelayedJoin(member) && reveal)
+      RevealDelayedJoin(member);
+    return 1;
+  }
+
+  /* Discourage using the Apass to get op.  They should use the Upass. */
   if (IsChannelManager(member) && member->channel->mode.apass[0])
     return 0;
 
+  /* If you have voice or ops, you can speak. */
   if (IsVoicedOrOpped(member))
     return 1;
 
@@ -687,15 +715,13 @@ int member_can_send_to_channel(struct Membership* member, int reveal)
    */
   if (member->channel->mode.mode & MODE_MODERATED)
     return 0;
+
   /* If only logged in users may join and you're not one, you can't speak. */
   if (member->channel->mode.mode & MODE_REGONLY && !IsAccount(member->user))
     return 0;
-  /*
-   * If you're banned then you can't speak either.
-   * but because of the amount of CPU time that is_banned chews
-   * we only check it for our clients.
-   */
-  if (MyUser(member->user) && is_banned(member))
+
+  /* If you're banned then you can't speak either. */
+  if (is_banned(member))
     return 0;
 
   if (IsDelayedJoin(member) && reveal)
@@ -1565,7 +1591,10 @@ modebuf_flush_int(struct ModeBuf *mbuf, int all)
 
   /* Ok, if we were given the OPMODE flag, or its a server, hide the source.
    */
-  if (mbuf->mb_dest & MODEBUF_DEST_OPMODE || IsServer(mbuf->mb_source) || IsMe(mbuf->mb_source))
+  if (feature_bool(FEAT_HIS_MODEWHO) &&
+      (mbuf->mb_dest & MODEBUF_DEST_OPMODE ||
+       IsServer(mbuf->mb_source) ||
+       IsMe(mbuf->mb_source)))
     app_source = &his;
   else
     app_source = mbuf->mb_source;
@@ -1771,7 +1800,7 @@ modebuf_flush_int(struct ModeBuf *mbuf, int all)
      * limit is supressed if we're removing it; we have to figure out which
      * direction is the direction for it to be removed, though...
      */
-    limitdel |= (mbuf->mb_dest & MODEBUF_DEST_HACK2) ? MODE_DEL : MODE_ADD;
+    limitdel |= (mbuf->mb_dest & MODEBUF_DEST_BOUNCE) ? MODE_DEL : MODE_ADD;
 
     for (i = 0; i < mbuf->mb_count; i++) {
       if (MB_TYPE(mbuf, i) & MODE_SAVE)
@@ -1968,7 +1997,7 @@ modebuf_mode_uint(struct ModeBuf *mbuf, unsigned int mode, unsigned int uint)
   assert(0 != mbuf);
   assert(0 != (mode & (MODE_ADD | MODE_DEL)));
 
-  if (mode == (MODE_LIMIT | MODE_DEL)) {
+  if (mode == (MODE_LIMIT | ((mbuf->mb_dest & MODEBUF_DEST_BOUNCE) ? MODE_ADD : MODE_DEL))) {
       mbuf->mb_rem |= mode;
       return;
   }