Ver Fonte

Merge branch '39-dynamic-roles' into next

* 39-dynamic-roles:
  Can't rebalance roles in .reset until after WHO is done due to PENDING channel.
  Limit more actions per role.
  Record features in bot's own userrec when adding itself.
  Only consider bots for roles if they have the FEATURE_ROLES feature.
  Store the FFLAGS in the user file and cache it in the userrec.
  Send FEATURE_ROLES on link.
  Add basic infrastructure for tracking feature flags on the botlink.
Bryan Drewery há 10 anos atrás
pai
commit
5c57faac86
14 ficheiros alterados com 125 adições e 35 exclusões
  1. 9 5
      src/botcmd.cc
  2. 6 5
      src/botmsg.cc
  3. 18 2
      src/botnet.cc
  4. 2 2
      src/botnet.h
  5. 5 1
      src/chanprog.cc
  6. 16 6
      src/dcc.cc
  7. 3 2
      src/eggdrop.h
  8. 1 1
      src/flags.cc
  9. 7 3
      src/mod/irc.mod/chan.cc
  10. 4 1
      src/mod/irc.mod/irc.cc
  11. 4 4
      src/mod/share.mod/share.cc
  12. 2 1
      src/tandem.h
  13. 44 0
      src/userent.cc
  14. 4 2
      src/users.h

+ 9 - 5
src/botcmd.cc

@@ -612,7 +612,7 @@ static void bot_unlink(int idx, char *par)
 static void bot_update(int idx, char *par)
 {
   char *bot = NULL, x, *vversion = NULL, *vcommit = NULL;
-  int vlocalhub = 0;
+  int vlocalhub = 0, fflags = -1;
   time_t vbuildts = 0L;
 
   bot = newsplit(&par);
@@ -630,9 +630,11 @@ static void bot_update(int idx, char *par)
     vcommit = newsplit(&par);
   if (par[0])
     vversion = newsplit(&par);
+  if (par[0])
+    fflags = atoi(newsplit(&par));
 
   if (in_chain(bot))
-    updatebot(idx, bot, x, vlocalhub, vbuildts, vcommit, vversion);
+    updatebot(idx, bot, x, vlocalhub, vbuildts, vcommit, vversion, fflags);
 }
 
 /* Newbot next share?
@@ -640,7 +642,7 @@ static void bot_update(int idx, char *par)
 static void bot_nlinked(int idx, char *par)
 {
   char *newbot = NULL, *next = NULL, *p = NULL, s[1024] = "", x = 0, *vversion = NULL, *vcommit = NULL;
-  int i, vlocalhub = 0;
+  int i, vlocalhub = 0, fflags = -1;
   time_t vbuildts = 0L;
   bool bogus = 0;
 
@@ -696,7 +698,9 @@ static void bot_nlinked(int idx, char *par)
     vcommit = newsplit(&par);
   if (par[0])
     vversion = newsplit(&par);
-  botnet_send_nlinked(idx, newbot, next, x, vlocalhub, vbuildts, vcommit, vversion);
+  if (par[0])
+    fflags = atoi(newsplit(&par));
+  botnet_send_nlinked(idx, newbot, next, x, vlocalhub, vbuildts, vcommit, vversion, fflags);
   
   if (x == '!') {
     if (conf.bot->hub)
@@ -705,7 +709,7 @@ static void bot_nlinked(int idx, char *par)
       chatout("*** %s linked to botnet.\n", newbot);
     x = '-';
   }
-  addbot(newbot, dcc[idx].nick, next, x, vlocalhub, vbuildts, vcommit, vversion ? vversion : (char *) "");
+  addbot(newbot, dcc[idx].nick, next, x, vlocalhub, vbuildts, vcommit, vversion ? vversion : (char *) "", fflags);
 }
 
 static void bot_unlinked(int idx, char *par)

+ 6 - 5
src/botmsg.cc

@@ -240,11 +240,11 @@ void botnet_send_unlinked(int idx, char *bot, char *args)
   }
 }
 
-void botnet_send_nlinked(int idx, char *bot, char *next, char flag, int vlocalhub, time_t vbuildts, char *vcommit, char *vversion)
+void botnet_send_nlinked(int idx, char *bot, char *next, char flag, int vlocalhub, time_t vbuildts, char *vcommit, char *vversion, int fflags)
 {
   if (tands > 0) {
-    const size_t len = simple_snprintf(OBUF, sizeof(OBUF), "n %s %s %cD0gc %d %d %s %s\n", bot, next, flag,
-                                       vlocalhub, (int) vbuildts, vcommit, vversion ? vversion : "");
+    const size_t len = simple_snprintf(OBUF, sizeof(OBUF), "n %s %s %cD0gc %d %d %s %s %d\n", bot, next, flag,
+                                       vlocalhub, (int) vbuildts, vcommit, vversion ? vversion : "", fflags);
     send_tand_but(idx, OBUF, len);
   }
 }
@@ -267,8 +267,9 @@ void botnet_send_update(int idx, tand_t * ptr)
 {
   if (tands > 0) {
     /* the D0gc is a lingering hack which probably will never be able to come out. */
-    const size_t len = simple_snprintf(OBUF, sizeof(OBUF), "u %s %cD0gc %d %d %s %s\n", ptr->bot, ptr->share, ptr->localhub,
-                                                          (int) ptr->buildts, ptr->commit, ptr->version);
+    const size_t len = simple_snprintf(OBUF, sizeof(OBUF), "u %s %cD0gc %d %d %s %s %d\n", ptr->bot, ptr->share, ptr->localhub,
+                                                          (int) ptr->buildts, ptr->commit, ptr->version,
+                                                          ptr->fflags);
     send_tand_but(idx, OBUF, len);
   }
 }

+ 18 - 2
src/botnet.cc

@@ -83,7 +83,7 @@ extern void counter_clear(const char* botnick);
 
 /* Add a tandem bot to our chain list
  */
-void addbot(char *who, char *from, char *next, char flag, int vlocalhub, time_t vbuildts, char *vcommit, char *vversion)
+void addbot(char *who, char *from, char *next, char flag, int vlocalhub, time_t vbuildts, char *vcommit, char *vversion, int fflags)
 {
   tand_t **ptr = &tandbot, *ptr2 = NULL;
 
@@ -109,6 +109,13 @@ void addbot(char *who, char *from, char *next, char flag, int vlocalhub, time_t
   ptr2->hub = is_hub(who);
   /* Cache user record */
   ptr2->u = userlist ? get_user_by_handle(userlist, who) : NULL;
+  ptr2->fflags = fflags;
+  if (fflags != -1) {
+    char buf[15];
+
+    simple_snprintf(buf, sizeof(buf), "%d", ptr2->fflags);
+    set_user(&USERENTRY_FFLAGS, ptr2->u ? ptr2->u : get_user_by_handle(userlist, who), buf);
+  }
   if (!strcasecmp(next, conf.bot->nick))
     ptr2->uplink = (tand_t *) 1;
   else
@@ -132,7 +139,7 @@ void check_should_backup()
 }
 #endif /* G_BACKUP */
 
-void updatebot(int idx, char *who, char share, int vlocalhub, time_t vbuildts, char *vcommit, char *vversion)
+void updatebot(int idx, char *who, char share, int vlocalhub, time_t vbuildts, char *vcommit, char *vversion, int fflags)
 {
   tand_t *ptr = findbot(who);
 
@@ -147,6 +154,15 @@ void updatebot(int idx, char *who, char share, int vlocalhub, time_t vbuildts, c
       strlcpy(ptr->commit, vcommit, sizeof(ptr->commit));
     if (vversion && vversion[0])
       strlcpy(ptr->version, vversion, 121);
+    /* -1 = unknown (do not modify) */
+    if (fflags != -1) {
+      char buf[15];
+
+      ptr->fflags = fflags;
+      simple_snprintf(buf, sizeof(buf), "%d", ptr->fflags);
+      set_user(&USERENTRY_FFLAGS, ptr->u ? ptr->u : get_user_by_handle(userlist, who), buf);
+    }
+    /* Assign flags here */
     botnet_send_update(idx, ptr);
   }
 }

+ 2 - 2
src/botnet.h

@@ -21,8 +21,8 @@ void tell_bottree(int);
 void dump_links(int);
 int botlink(char *, int, char *);
 int botunlink(int, const char *, const char *);
-void addbot(char *, char *, char *, char, int, time_t, char *, char *);
-void updatebot(int, char *, char, int, time_t, char *, char *);
+void addbot(char *, char *, char *, char, int, time_t, char *, char *, int);
+void updatebot(int, char *, char, int, time_t, char *, char *, int);
 void rembot(const char *);
 tand_t *findbot(const char *);
 void unvia(int, struct tand_t_struct *);

+ 5 - 1
src/chanprog.cc

@@ -502,7 +502,12 @@ static struct userrec* add_bot_userlist(char* bot) {
 }
 
 void add_myself_to_userlist() {
+  char buf[15];
+
   conf.bot->u = add_bot_userlist(conf.bot->nick);
+
+  simple_snprintf(buf, sizeof(buf), "%d", ALL_FEATURE_FLAGS);
+  set_user(&USERENTRY_FFLAGS, conf.bot->u, buf);
 }
 
 void add_child_bots() {
@@ -583,7 +588,6 @@ void chanprog()
 {
   struct utsname un;
 
-
   sdprintf("I am: %s", conf.bot->nick);
 
   /* Add the 'default' virtual channel.

+ 16 - 6
src/dcc.cc

@@ -242,7 +242,9 @@ greet_new_bot(int idx)
     dcc[idx].status |= STAT_LEAF;
   dcc[idx].status |= STAT_LINKING;
 
-  dprintf(idx, "v 1001500 9 Wraith %s <%s> %d %li %s %s\n", egg_version, "-", conf.bot->localhub, (long)buildts, commit, egg_version);
+  dprintf(idx, "v 1001500 9 Wraith %s %d %d %li %s %s\n", egg_version,
+      conf.bot->u->fflags, conf.bot->localhub, (long)buildts, commit,
+      egg_version);
 
   for (int i = 0; i < dcc_total; i++) {
     if (dcc[i].type && dcc[i].type == &DCC_FORK_BOT) {
@@ -255,6 +257,8 @@ greet_new_bot(int idx)
 static void
 bot_version(int idx, char *par)
 {
+  char *work;
+
   dcc[idx].timeval = now;
   if (in_chain(dcc[idx].nick)) {
     dprintf(idx, "error Sorry, already connected.\n");
@@ -265,8 +269,6 @@ bot_version(int idx, char *par)
   }
 
   if ((par[0] >= '0') && (par[0] <= '9')) {
-    char *work = NULL;
-
     work = newsplit(&par);
     dcc[idx].u.bot->numver = atoi(work);
     /* old numver crap */
@@ -293,11 +295,19 @@ bot_version(int idx, char *par)
   char x[1024] = "", *vversion = NULL, *vcommit = NULL;
   int vlocalhub = -1;
   time_t vbuildts = 0;
+  int fflags = -1;
 
   strlcpy(dcc[idx].u.bot->version, par, 120);
   newsplit(&par);               /* 'ver' */
   newsplit(&par);               /* handlen */
-  newsplit(&par);               /* network */
+  /* fflags / (backward compat: network) */
+  if (par[0]) {
+    work = newsplit(&par);
+    /* Must support older bots which sent '<->' here for network. */
+    if (strcmp(work, "<->")) {
+      fflags = atoi(work);
+    }
+  }
   if (par[0])
     vlocalhub = atoi(newsplit(&par));
   if (par[0])
@@ -334,7 +344,7 @@ bot_version(int idx, char *par)
       dcc[idx].hub = 1;
     }
 
-    botnet_send_nlinked(idx, dcc[idx].nick, conf.bot->nick, '!', vlocalhub, vbuildts, vcommit, vversion);
+    botnet_send_nlinked(idx, dcc[idx].nick, conf.bot->nick, '!', vlocalhub, vbuildts, vcommit, vversion, fflags);
   } else {
         // This is now done in share_endstartup
         //have_linked_to_hub = 1;
@@ -346,7 +356,7 @@ bot_version(int idx, char *par)
 
   touch_laston(dcc[idx].user, "linked", now);
   dcc[idx].type = &DCC_BOT;
-  addbot(dcc[idx].nick, dcc[idx].nick, conf.bot->nick, '-', vlocalhub, vbuildts, vcommit, vversion);
+  addbot(dcc[idx].nick, dcc[idx].nick, conf.bot->nick, '-', vlocalhub, vbuildts, vcommit, vversion, fflags);
   simple_snprintf(x, sizeof x, "v 1001500");
   bot_share(idx, x);
   dprintf(idx, "el\n");

+ 3 - 2
src/eggdrop.h

@@ -144,6 +144,7 @@ enum {		/* TAKE A GUESS */
 #define have_cmd(name, flags) ((!is_restricted_cmd(name)) && (!(flags & (HUB|LEAF)) || (flags & HUB && conf.bot->hub) || (flags & LEAF && !conf.bot->hub)))
 
 
-#endif				/* _EGG_EGGDROP_H */
-
+#define FEATURE_ROLES		BIT0
+#define ALL_FEATURE_FLAGS	(FEATURE_ROLES)
 
+#endif				/* _EGG_EGGDROP_H */

+ 1 - 1
src/flags.cc

@@ -40,7 +40,7 @@ flag_t FLAG[128];
 
 struct rolecount role_counts[] = {
   {"voice",	ROLE_VOICE,	1},
-  {"flood",	ROLE_FLOOD,	2},
+  {"flood",	ROLE_FLOOD,	3},
   {"op",	ROLE_OP,	1},
   {"deop",	ROLE_DEOP,	1},
   {"kick",	ROLE_KICK,	2},

+ 7 - 3
src/mod/irc.mod/chan.cc

@@ -562,7 +562,8 @@ static bool detect_chan_flood(memberlist* m, const char *from, struct chanset_t
   /* Do not punish non-existant channel members and IRC services like
    * ChanServ
    */
-  if (!chan || (which < 0) || (which >= FLOOD_CHAN_MAX) || !m)
+  if (!chan || (which < 0) || (which >= FLOOD_CHAN_MAX) || !m ||
+      !(chan->role & ROLE_FLOOD))
     return 0;
 
   /* Okay, make sure i'm not flood-checking myself */
@@ -2149,6 +2150,7 @@ static int got315(char *from, char *msg)
   } else {
     me->is_me = 1;
     me->joined = now;				/* set this to keep the whining masses happy */
+    rebalance_roles_chan(chan);
     if (me_op(chan))
       recheck_channel(chan, 2);
     else if (chan->channel.members == 1)
@@ -2820,7 +2822,8 @@ static int gotjoin(char *from, char *chname)
         bool is_op = chk_op(fr, chan);
 
         /* Check for a mass join */
-        if (!splitjoin && chan->flood_mjoin_time && chan->flood_mjoin_thr && !is_op) {
+        if (chan->role & ROLE_FLOOD &&
+            !splitjoin && chan->flood_mjoin_time && chan->flood_mjoin_thr && !is_op) {
           if (chan->channel.drone_jointime < now - chan->flood_mjoin_time) {      //expired, reset counter
             chan->channel.drone_joins = 0;
           }
@@ -2842,7 +2845,8 @@ static int gotjoin(char *from, char *chname)
 	    u_match_mask(chan->invites, from))
 	  refresh_invite(chan, from);
 
-	if (!(use_exempts && (u_match_mask(global_exempts,from) || u_match_mask(chan->exempts, from)))) {
+	if (chan->role & ROLE_BAN &&
+            !(use_exempts && (u_match_mask(global_exempts,from) || u_match_mask(chan->exempts, from)))) {
           if (channel_enforcebans(chan) && !chan_sentkick(m) && !is_op &&
               !(use_exempts && (isexempted(chan, from) || (chan->ircnet_status & CHAN_ASKED_EXEMPTS)))) {
             for (masklist* b = chan->channel.ban; b->mask[0]; b = b->next) {

+ 4 - 1
src/mod/irc.mod/irc.cc

@@ -1316,7 +1316,6 @@ reset_chan_info(struct chanset_t *chan)
     send_chan_who(DP_MODE, chan, 1);
     /* clear_channel nuked the data...so */
     dprintf(DP_HELP, "TOPIC %s\n", chan->name);//Topic is very low priority
-    rebalance_roles_chan(chan);
   }
 }
 
@@ -1793,6 +1792,10 @@ static void rebalance_roles_chan(struct chanset_t* chan)
     if (!chk_op(fr, chan)) {
       continue;
     }
+    /* Only consider bots that have the roles feature. */
+    if (!(m->user->fflags & FEATURE_ROLES)) {
+      continue;
+    }
     bots << m->user->handle;
   }
   botcount = bots.length();

+ 4 - 4
src/mod/share.mod/share.cc

@@ -929,7 +929,7 @@ share_ufyes(int idx, char *par)
         dcc[idx].u.bot->uff_flags |= UFF_CHDEFAULT;
 
     if (strstr(par, "stream")) {
-      updatebot(-1, dcc[idx].nick, '+', 0, 0, 0, NULL);
+      updatebot(-1, dcc[idx].nick, '+', 0, 0, 0, NULL, -1);
       /* Start up a tbuf to queue outgoing changes for this bot until the
        * userlist is done transferring.
        */
@@ -1444,7 +1444,7 @@ static void share_read_stream(int idx, bd::Stream& stream) {
   checkchans(1);                /* remove marked channels */
   var_parse_my_botset();
   reaffirm_owners();            /* Make sure my owners are +a   */
-  updatebot(-1, dcc[idx].nick, '+', 0, 0, 0, NULL);
+  updatebot(-1, dcc[idx].nick, '+', 0, 0, 0, NULL, -1);
   send_sysinfo();
 
   if (restarting && !keepnick) {
@@ -1554,7 +1554,7 @@ start_sending_users(int idx)
            i == DCCSEND_BADFN ? "BAD FILE" : i == DCCSEND_FEMPTY ? "EMPTY FILE" : "UNKNOWN REASON!");
     dcc[idx].status &= ~(STAT_SHARE | STAT_SENDING | STAT_AGGRESSIVE);
   } else {
-    updatebot(-1, dcc[idx].nick, '+', 0, 0, 0, NULL);
+    updatebot(-1, dcc[idx].nick, '+', 0, 0, 0, NULL, -1);
     dcc[idx].status |= STAT_SENDING;
     strlcpy(dcc[j].host, dcc[idx].nick, sizeof(dcc[j].host)); /* Store bot's nick */
     dprintf(idx, "s us %lu %d %lu\n", iptolong(getmyip()), dcc[j].port, dcc[j].u.xfer->length);
@@ -1579,7 +1579,7 @@ cancel_user_xfer(int idx, void *x)
   int i, j = -1;
   if (cancel_user_xfer_staylinked) {
     /* turn off sharing flag */
-    updatebot(-1, dcc[idx].nick, '-', 0, 0, 0, NULL);
+    updatebot(-1, dcc[idx].nick, '-', 0, 0, 0, NULL, -1);
   }
   flush_tbuf(dcc[idx].nick);
 

+ 2 - 1
src/tandem.h

@@ -13,6 +13,7 @@ typedef struct tand_t_struct {
   struct tand_t_struct *next;
   time_t buildts;
   int localhub;
+  int fflags;
   struct userrec* u;
   char commit[10];
   char bot[HANDLEN + 1];
@@ -58,7 +59,7 @@ void botnet_send_trace(int, char *, char *, char *);
 void botnet_send_unlink(int, char *, char *, char *, char *);
 void botnet_send_link(int, char *, char *, char *);
 void botnet_send_update(int, tand_t *);
-void botnet_send_nlinked(int, char *, char *, char, int, time_t, char *, char *);
+void botnet_send_nlinked(int, char *, char *, char, int, time_t, char *, char *, int);
 void botnet_send_reject(int, char *, char *, char *, char *, char *);
 void botnet_send_log(int, const char *, int, const char *, bool = 0);
 void botnet_send_zapf(int, const char *, const char *, const char *);

+ 44 - 0
src/userent.cc

@@ -62,6 +62,7 @@ void init_userent()
   add_entry_type(&USERENTRY_ADDED);
   add_entry_type(&USERENTRY_MODIFIED);
   add_entry_type(&USERENTRY_SET);
+  add_entry_type(&USERENTRY_FFLAGS);
 }
 
 void list_type_kill(struct list_type *t)
@@ -467,6 +468,49 @@ struct user_entry_type USERENTRY_ARCH = {
  "ARCH"
 };
 
+bool fflags_unpack(struct userrec *u, struct user_entry *e)
+{
+  bool ret = def_unpack(u, e);
+  /* Cache the value in the user record. */
+  u->fflags = atoi((char *) def_get(u, e));
+  return ret;
+}
+
+bool fflags_set(struct userrec *u, struct user_entry *e, void *buf)
+{
+  bool ret;
+
+  /* No need to share since it is sent over the tandem/botlink. */
+  noshare = 1;
+  ret = def_set(u, e, buf);
+  noshare = 0;
+  /* Cache the value in the user record. */
+  u->fflags = atoi((char *) def_get(u, e));
+  return ret;
+}
+
+bool fflags_gotshare(struct userrec *u, struct user_entry *e, char *data,
+    int idx)
+{
+  /* Don't let another bot dictate our features. */
+  if (u == conf.bot->u) {
+    return false;
+  }
+  return def_gotshare(u, e, data, idx);
+}
+
+struct user_entry_type USERENTRY_FFLAGS = {
+ 0,
+ fflags_gotshare,
+ fflags_unpack,
+ def_write_userfile,
+ def_kill,
+ def_get,
+ fflags_set,
+ botmisc_display,
+ "FFLAGS"
+};
+
 void stats_add(struct userrec *u, int islogin, int op)
 {
   if (!u || u->bot)

+ 4 - 2
src/users.h

@@ -49,8 +49,9 @@ struct user_entry_type {
 extern struct user_entry_type USERENTRY_COMMENT, USERENTRY_LASTON,
  USERENTRY_INFO, USERENTRY_BOTADDR, USERENTRY_HOSTS,
  USERENTRY_PASS, USERENTRY_STATS, USERENTRY_ADDED, USERENTRY_MODIFIED,
- USERENTRY_SET, USERENTRY_SECPASS, USERENTRY_USERNAME, USERENTRY_NODENAME, USERENTRY_OS,
- USERENTRY_PASS1, USERENTRY_ARCH, USERENTRY_OSVER;
+ USERENTRY_SET, USERENTRY_SECPASS, USERENTRY_USERNAME, USERENTRY_NODENAME,
+ USERENTRY_OS, USERENTRY_PASS1, USERENTRY_ARCH, USERENTRY_OSVER,
+ USERENTRY_FFLAGS;
 
 struct laston_info {
   time_t laston;
@@ -126,6 +127,7 @@ struct userrec {
   struct chanuserrec *chanrec;
   struct userrec *next;
   flag_t flags;
+  int fflags;
   char handle[HANDLEN + 1];
   char bot;
 };