Ver código fonte

Merge branch 'homechan-user'

* homechan-user:
  Add homechan-user.
  Refactor chk_voice into an actual function.
  chk_autoop: Refactor slightly to allow expanding for homechan op.
Bryan Drewery 7 anos atrás
pai
commit
c5290a3d6b

+ 2 - 0
doc/UPDATES.md

@@ -7,6 +7,8 @@
     will properly assign roles out to bots to not cause overlap. Only leaf
     bots know which bots have which roles. (#39)
   * Add cmd_roles (leaf only) to display roles for a channel. (#39)
+  * Add 'chanset homechan-user [nothing/voice/op]' to auto-voice or auto-op
+    clients who are opped in 'set homechan'.
 
 # maint
   * Clear FiSH keys when a client quits.

+ 7 - 0
doc/help.txt

@@ -453,6 +453,13 @@ See also: link%{+a}, newhub%{-}
       $bmdop$b                Mass deop.
       $bmop$b                 Mass op.
       $brevenge$b             Client kicking/banning/deopping another bot.
+
+   The following are only used if '%dset homechan' is configured.
+     $bhomechan-user$b         Set to treat clients who are in the homechan
+                           special in non-homechan channels.
+                              nothing/0      Do nothing special.
+                              voice/1        Voice clients who are in homechan.
+                              op/2           Op clients who are in homechan.
  
    The following can be set + or - (e.g. '%dchanset #channel -enforcebans')
         $bautoop$b         Bots that are +y will auto-op all users with 

+ 7 - 0
src/chan.h

@@ -111,6 +111,12 @@ enum deflag_t {
   DEFLAG_REACT = 4,
 };
 
+enum homechan_user_t {
+  HOMECHAN_USER_NONE = 0,
+  HOMECHAN_USER_VOICE = 1,
+  HOMECHAN_USER_OP = 2,
+};
+
 /* Why duplicate this struct for exempts and invites only under another
  * name? <cybah>
  */
@@ -244,6 +250,7 @@ struct chanset_t {
   deflag_t mdop;
   deflag_t mop;
   deflag_t revenge;
+  homechan_user_t homechan_user;
   int voice_non_ident;
   int ban_type;
   interval_t auto_delay;

+ 51 - 3
src/flags.cc

@@ -475,18 +475,52 @@ real_chk_op(const struct flag_record fr, const struct chanset_t *chan, bool botb
   return 0;
 }
 
+static int
+chk_homechan_user_op(const memberlist *m, const struct chanset_t *chan)
+{
+  struct chanset_t *homechan_chan = NULL;
+  memberlist *homechan_m = NULL;
+
+  if (!homechan[0] || channel_take(chan))
+    return 0;
+  if (!(homechan_chan = findchan_by_dname(homechan)))
+    return 0;
+  if (homechan_chan == chan)
+    return 0;
+  if (!(homechan_m = ismember(homechan_chan, m->nick)))
+    return 0;
+  if (chan_hasop(homechan_m))
+    return 1;
+  return 0;
+}
+
+
 int
-chk_autoop(memberlist *m, const struct flag_record fr, const struct chanset_t *chan)
+chk_autoop(const memberlist *m, const struct flag_record fr, const struct chanset_t *chan)
 {
-  if (glob_bot(fr) || !chan || !m->user || u_pass_match(m->user, "-"))
+  if (glob_bot(fr) || !chan || (m->user && u_pass_match(m->user, "-")) ||
+      channel_take(chan) || privchan(fr, chan, PRIV_OP) || chk_deop(fr, chan))
     return 0;
-  if (!channel_take(chan) && !privchan(fr, chan, PRIV_OP) && chk_op(fr, chan) && !chk_deop(fr, chan)) {
+  if (chk_op(fr, chan) || (chan->homechan_user == HOMECHAN_USER_OP &&
+        chk_homechan_user_op(m, chan))) {
     if (channel_autoop(chan) || chan_autoop(fr) || glob_autoop(fr))
       return 1;
   }
   return 0;
 }
 
+int
+chk_voice(const memberlist *m, const struct flag_record fr, const struct chanset_t *chan)
+{
+  if (!chan || privchan(fr, chan, PRIV_VOICE) || chk_devoice(fr))
+    return 0;
+  if (chan_voice(fr) || (glob_voice(fr) && !chan_quiet(fr)) ||
+      (chan->homechan_user == HOMECHAN_USER_VOICE &&
+       chk_homechan_user_op(m, chan)))
+    return 1;
+  return 0;
+}
+
 int
 real_chk_deop(const struct flag_record fr, const struct chanset_t *chan, bool botbitch)
 {
@@ -596,6 +630,20 @@ whois_access(struct userrec *user, struct userrec *whois_user)
   return 1;
 }
 
+homechan_user_t homechan_user_translate(const char *buf)
+{
+  if (str_isdigit(buf))
+    return (static_cast<homechan_user_t>(atoi(buf)));
+
+  if (!strcasecmp(buf, "none"))
+    return HOMECHAN_USER_NONE;
+  else if (!strcasecmp(buf, "voice"))
+    return HOMECHAN_USER_VOICE;
+  else if (!strcasecmp(buf, "op"))
+    return HOMECHAN_USER_OP;
+  return HOMECHAN_USER_NONE;
+}
+
 deflag_t deflag_translate(const char *buf)
 {
   if (str_isdigit(buf))

+ 3 - 6
src/flags.h

@@ -175,14 +175,10 @@ char geticon(int);
 int privchan(const struct flag_record, const struct chanset_t *, int);
 #define chk_op(fr, chan) real_chk_op(fr, chan, 1)
 int real_chk_op(const struct flag_record, const struct chanset_t *, bool);
-int chk_autoop(memberlist *, const struct flag_record, const struct chanset_t *);
+int chk_autoop(const memberlist *, const struct flag_record, const struct chanset_t *);
 #define chk_deop(fr, chan) real_chk_deop(fr, chan, 1)
 int real_chk_deop(const struct flag_record, const struct chanset_t *, bool);
-#define chk_voice(fr, chan) (\
-    (\
-     (!chan || (!privchan(fr, chan, PRIV_VOICE) && !chk_devoice(fr))) \
-     && (chan_voice(fr) || (glob_voice(fr) && !chan_quiet(fr))) \
-    ) ? 1 : 0)
+int chk_voice(const memberlist *, const struct flag_record, const struct chanset_t *);
 #define chk_noflood(fr) (chan_noflood(fr) || glob_noflood(fr))
 #define chk_devoice(fr) ((chan_quiet(fr) || (glob_quiet(fr) && !chan_voice(fr))) ? 1 : 0)
 #define isupdatehub() ((conf.bot->hub && conf.bot->u && (conf.bot->u->flags & BOT_UPDATEHUB)) ? 1 : 0)
@@ -192,6 +188,7 @@ int dovoice(const struct chanset_t *);
 int doflood(const struct chanset_t *);
 int dolimit(const struct chanset_t *);
 int whois_access(struct userrec *, struct userrec *);
+homechan_user_t homechan_user_translate(const char *);
 void deflag_user(struct userrec *, deflag_event_t, const char *, const struct chanset_t *);
 deflag_t deflag_translate(const char *);
 

+ 8 - 0
src/mod/channels.mod/chanmisc.cc

@@ -627,6 +627,14 @@ int channel_modify(char *result, struct chanset_t *chan, int items, char **item,
         return ERROR;
       }
       chan->ban_type = atoi(item[i]);
+    } else if (!strcmp(item[i], "homechan-user")) {
+      i++;
+      if (i >= items) {
+        if (result)
+          strlcpy(result, "channel homechan-user needs argument", RESULT_LEN);
+        return ERROR;
+      }
+      chan->homechan_user = homechan_user_translate(item[i]);
     } else if (!strcmp(item[i], "protect-backup")) {
       i++;
       if (i >= items) {

+ 4 - 0
src/mod/channels.mod/cmdschan.cc

@@ -1136,6 +1136,7 @@ static void show_int(int idx, char *work, int *cnt, const char *desc, int state,
 #define SHOW_FLAG(name, state) show_flag(idx, work, &cnt, name, state, sizeof(work))
 #define SHOW_INT(desc, state, yes, no) show_int(idx, work, &cnt, desc, state, yes, no, sizeof(work))
 #define DEFLAG_STR deflag == DEFLAG_KICK ? "Kick" : (deflag == DEFLAG_DEOP ? "Deop" : (deflag == DEFLAG_DELETE ? "Remove" : (deflag == DEFLAG_REACT ? "React" : NULL)))
+#define HOMECHAN_USER_STR homechan_user == HOMECHAN_USER_NONE ? "None" : (homechan_user == HOMECHAN_USER_VOICE ? "Voice" : (homechan_user == HOMECHAN_USER_OP ? "Op" : NULL))
 #define F_STR(x) x == CHAN_FLAG_OP ? "Op" : (x == CHAN_FLAG_VOICE ? "Voice" : (x == CHAN_FLAG_USER ? "User" : NULL))
 static void cmd_chaninfo(int idx, char *par)
 {
@@ -1167,6 +1168,7 @@ static void cmd_chaninfo(int idx, char *par)
   } else {
     char nick[HANDLEN + 1] = "", date[81] = "";
     int deflag = 0;
+    int homechan_user = 0;
 
     if (chan->added_ts) {
       strftime(date, sizeof date, "%c %Z", gmtime(&(chan->added_ts)));
@@ -1244,6 +1246,8 @@ static void cmd_chaninfo(int idx, char *par)
     SHOW_INT("Flood-lock-time: ", chan->flood_lock_time, NULL, "Don't");
     SHOW_INT("Caps-Limit(%): ", chan->capslimit, NULL, "None");
     SHOW_INT("Color-Limit: ", chan->colorlimit, NULL, "None");
+    homechan_user = chan->homechan_user;
+    SHOW_INT("Homechan-User:" , chan->homechan_user, HOMECHAN_USER_STR, "None");
     SHOW_INT("Invite-time: ", chan->invite_time, NULL, "Forever");
     SHOW_INT("Knock: ", chan->knock_flags, F_STR(chan->knock_flags), "None");
     SHOW_INT("Limit raise (limit): ", chan->limitraise, NULL, "Disabled");

+ 2 - 0
src/mod/channels.mod/userchan.cc

@@ -710,6 +710,7 @@ bd::String channel_to_string(struct chanset_t* chan, bool force_inactive) {
   get_mode_protect(chan, w, sizeof(w));
   return bd::String::printf("\
 chanmode { %s } groups { %s } bad-cookie %d manop %d mdop %d mop %d limit %d revenge %d ban-type %d \
+homechan-user %d \
 flood-chan %d:%d flood-bytes %d:%d flood-ctcp %d:%d flood-join %d:%d \
 flood-kick %d:%d flood-deop %d:%d flood-nick %d:%d flood-mjoin %d:%d \
 flood-mpub %d:%d flood-mbytes %d:%d flood-mctcp %d:%d \
@@ -733,6 +734,7 @@ flood-exempt %d flood-lock-time %d knock %d fish-key { %s } \
         chan->limitraise,
 	chan->revenge,
         chan->ban_type,
+	chan->homechan_user,
 	chan->flood_pub_thr, chan->flood_pub_time,
 	chan->flood_bytes_thr, chan->flood_bytes_time,
         chan->flood_ctcp_thr, chan->flood_ctcp_time,

+ 5 - 5
src/mod/irc.mod/chan.cc

@@ -1234,11 +1234,11 @@ static void check_this_member(struct chanset_t *chan, memberlist *m,
   if (dovoice(chan)) {
     if (chan_hasvoice(m) && !chan_hasop(m)) {
       /* devoice +q users .. */
-      if (chk_devoice(*fr) || (channel_voicebitch(chan) && !chk_voice(*fr, chan)))
+      if (chk_devoice(*fr) || (channel_voicebitch(chan) && !chk_voice(m, *fr, chan)))
         add_mode(chan, '-', 'v', m);
     } else if (!chan_hasvoice(m) && !chan_hasop(m)) {
       /* voice +v users */
-      if (chk_voice(*fr, chan)) {
+      if (chk_voice(m, *fr, chan)) {
         add_mode(chan, '+', 'v', m);
         if (m->flags & EVOICE)
           m->flags &= ~EVOICE;
@@ -1808,7 +1808,7 @@ static int got710(char *from, char *msg)
 
   // PASSING: +o and op || +v and op/voice || user
   if (!((chan->knock_flags == CHAN_FLAG_OP && chk_op(fr, chan)) ||
-       (chan->knock_flags == CHAN_FLAG_VOICE && (chk_op(fr, chan) || chk_voice(fr, chan))) ||
+       (chan->knock_flags == CHAN_FLAG_VOICE && (chk_op(fr, chan) || chk_voice(NULL, fr, chan))) ||
        (chan->knock_flags == CHAN_FLAG_USER)) ||
       chan_kick(fr) || glob_kick(fr)) {
     return 0;
@@ -2903,9 +2903,9 @@ static int gotjoin(char *from, char *chname)
               if (!(m->flags & EVOICE) &&
                   (
                    /* +voice: Voice all clients who are not flag:+q. If the chan is +voicebitch, only op flag:+v clients */
-                   (channel_voice(chan) && !chk_devoice(fr) && (!channel_voicebitch(chan) || (channel_voicebitch(chan) && chk_voice(fr, chan)))) ||
+                   (channel_voice(chan) && !chk_devoice(fr) && (!channel_voicebitch(chan) || (channel_voicebitch(chan) && chk_voice(m, fr, chan)))) ||
                    /* Or, if the channel is -voice but they still qualify to be voiced */
-                   (!channel_voice(chan) && !privchan(fr, chan, PRIV_VOICE) && chk_voice(fr, chan))
+                   (!channel_voice(chan) && !privchan(fr, chan, PRIV_VOICE) && chk_voice(m, fr, chan))
                   )
                  ) {
                 m->delay = now + chan->auto_delay;

+ 2 - 2
src/mod/irc.mod/cmdsirc.cc

@@ -371,7 +371,7 @@ static void cmd_voice(int idx, char *par)
       dprintf(idx, "No such channel.\n");
       return;
     }
-    else if (!chk_voice(user, chan) && !chk_op(user, chan)) {
+    else if (!chk_voice(NULL, user, chan) && !chk_op(user, chan)) {
       if (all) goto next;
       dprintf(idx, "You don't have access to voice on %s\n", chan->dname);
       return;
@@ -435,7 +435,7 @@ static void cmd_devoice(int idx, char *par)
     dprintf(idx, "No such channel.\n");
     return;
   }
-  else if (!chk_voice(user, chan) && !chk_op(user, chan)) {
+  else if (!chk_voice(NULL, user, chan) && !chk_op(user, chan)) {
     if (all) goto next;
     dprintf(idx, "You don't have access to devoice on %s\n", chan->dname);
     return;

+ 2 - 2
src/mod/irc.mod/irc.cc

@@ -1607,9 +1607,9 @@ check_expired_chanstuff(struct chanset_t *chan)
               if (!(m->flags & EVOICE) &&
                   (
                    /* +voice: Voice all clients who are not flag:+q. If the chan is +voicebitch, only op flag:+v clients */
-                   (channel_voice(chan) && !chk_devoice(fr) && (!channel_voicebitch(chan) || (channel_voicebitch(chan) && chk_voice(fr, chan)))) ||
+                   (channel_voice(chan) && !chk_devoice(fr) && (!channel_voicebitch(chan) || (channel_voicebitch(chan) && chk_voice(m, fr, chan)))) ||
                    /* Or, if the channel is -voice but they still qualify to be voiced */
-                   (!channel_voice(chan) && !privchan(fr, chan, PRIV_VOICE) && chk_voice(fr, chan))
+                   (!channel_voice(chan) && !privchan(fr, chan, PRIV_VOICE) && chk_voice(m, fr, chan))
                   )
                  ) {
                 add_mode(chan, '+', 'v', m);

+ 3 - 3
src/mod/irc.mod/mode.cc

@@ -1463,7 +1463,7 @@ gotmode(char *from, char *msg)
 
               if (msign == '+') {
                 if (mv->flags & EVOICE) {
-                  if (!chk_op(user, chan) && !chk_voice(victim, chan)) {
+                  if (!chk_op(user, chan) && !chk_voice(mv, victim, chan)) {
                     dv = 1;
                   } else {
                     mv->flags &= ~EVOICE;
@@ -1472,7 +1472,7 @@ gotmode(char *from, char *msg)
                 mv->flags &= ~SENTVOICE;
                 mv->flags |= CHANVOICE;
                 if (channel_active(chan) && dovoice(chan)) {
-                  if (dv || chk_devoice(victim) || (channel_voicebitch(chan) && !chk_voice(victim, chan))) {
+                  if (dv || chk_devoice(victim) || (channel_voicebitch(chan) && !chk_voice(mv, victim, chan))) {
                     add_mode(chan, '-', 'v', mv);
                   } else if (reversing) {
                     add_mode(chan, '-', 'v', mv);
@@ -1483,7 +1483,7 @@ gotmode(char *from, char *msg)
                 mv->flags &= ~CHANVOICE;
                 if (channel_active(chan) && dovoice(chan) && !chan_hasop(mv)) {
                   /* revoice +v users */
-                  if (chk_voice(victim, chan)) {
+                  if (chk_voice(mv, victim, chan)) {
                     add_mode(chan, '+', 'v', mv);
                   } else if (reversing) {
                     add_mode(chan, '+', 'v', mv);

+ 1 - 1
src/set.cc

@@ -102,7 +102,7 @@ static variable_t vars[] = {
  VAR("flood-msg",	&flood_msg,		VAR_RATE|VAR_NOLHUB,				0, 0, "5:60"),
  VAR("groups",		groups,			VAR_STRING|VAR_LIST|VAR_NOLHUB,			0, 0, "main"),
  VAR("hijack",		&hijack,		VAR_INT|VAR_DETECTED|VAR_PERM,			0, 4, "die"),
- VAR("homechan",	homechan,		VAR_WORD|VAR_NOLOC|VAR_HIDE,			0, 0, NULL),
+ VAR("homechan",	homechan,		VAR_WORD|VAR_NOLOC,				0, 0, NULL),
  VAR("ident-botnick",   &ident_botnick,		VAR_INT|VAR_BOOL|VAR_NOLHUB,			0, 1, "0"),
  VAR("in-bots",		&in_bots,		VAR_INT|VAR_NOLOC,				1, MAX_BOTS, "2"),
  VAR("irc-autoaway",	&irc_autoaway,		VAR_INT|VAR_NOLHUB|VAR_BOOL,			0, 1, "1"),