Procházet zdrojové kódy

* Port [3491] to 1.2.14
* More mmode work (now supports local only [floodless])



svn: 3492

Bryan Drewery před 19 roky
rodič
revize
4349aaa3e7

+ 6 - 2
misc/help.txt

@@ -1234,11 +1234,13 @@ See also: randstring, sha1, encrypt, decrypt
    Performs an action on the party line. This appears as "* Wcc is leaving",
    etc.
 :leaf:mmode:
-###  $bmmode$b <(+|-)MODE> <#channel> <a|o|v|d|r> [bots=n] [alines=n] [slines=n] [overlap=n] [bitch] [simul]
+###  $bmmode$b <(+|-)MODE> <#channel> <a|o|v|d|r> [bots=n] [alines=n] [slines=n] [overlap=n] [bitch] [simul] [local]
    For those of us who do not wish to be rocket scientists in the mass mode department, 
    a simple '%dmmode -o #channel o' will suffice.
  
-   **Remember, the bot you mmode on will never participate in the modes**
+   This is a distributed mass mode command.
+   The modes will be distributed among the necesary bots to accomplish the task.
+   **Remember, unless specificed, the bot you mmode on will never participate.**
  
    options:
  
@@ -1252,6 +1254,8 @@ See also: randstring, sha1, encrypt, decrypt
      $bbitch$b   - set +bitch after finished with mmode.
      $bsimul$b   - Simulates the mmode. IE: Gives you a practice run, will show who 
                    does what in the dcc chat window.
+     $blocal$b   - Modes will not be distributed: Ran on local bot only.
+                   Use this with caution, and do not expect good results.
  
      =============================================================================
      don't bother setting the following options unless you REALLY know what you're 

+ 1 - 1
src/mod/irc.mod/chan.c

@@ -1175,7 +1175,7 @@ do_take(struct chanset_t *chan)
   size_t deops_len = 0;
   size_t work_len = 0;
   register short lines = 0;
-  register const unsigned short max_lines = floodless ? 15 : 5;
+  register const unsigned short max_lines = floodless ? 15 : default_alines;
   char work[2048] = "", *op = NULL, *modeline = NULL, deops[2048] = "";
   register unsigned int deopn;
 

+ 119 - 94
src/mod/irc.mod/cmdsirc.c

@@ -525,11 +525,56 @@ static void cmd_op(int idx, char *par)
 
 }
 
+void mass_mode_request(char *botnick, char *code, char *par)
+{
+  char* mode = newsplit(&par);
+
+  if (strlen(mode) > 2 || !strchr("+-", mode[0]))
+    return;
+
+  char* chname = newsplit(&par);
+
+  char list[101] = "", buf[2048] = "";
+  size_t list_len = 0, buf_len = 0;
+
+  while (par[0]) {
+    size_t cnt = 0;
+
+    *(buf + buf_len++) = 'M';
+    *(buf + buf_len++) = 'O';
+    *(buf + buf_len++) = 'D';
+    *(buf + buf_len++) = 'E';
+    *(buf + buf_len++) = ' ';
+    buf_len += strlcpy(buf + buf_len, chname, sizeof(buf) - buf_len);
+    *(buf + buf_len++) = ' ';
+
+    while ((cnt < modesperline) && par[0]) {
+      /* add +mode into irc cmd */
+      buf_len += strlcpy(buf + buf_len, mode, sizeof(buf) - buf_len);
+
+      /* Make list of nicks */
+      const char* nick = newsplit(&par);
+      list_len += strlcpy(list + list_len, nick, sizeof(list) - list_len); 
+      if ((++cnt < modesperline) && par[0])
+        *(list + list_len++) = ' ';
+    }
+
+    /* buf is so far: 'MODE #chan +o+o+o+o' */
+    *(buf + buf_len++) = ' ';
+    buf_len += strlcpy(buf + buf_len, list, sizeof(buf) - buf_len);
+    *(buf + buf_len++) = '\r';
+    *(buf + buf_len++) = '\n';
+    list[0] = list_len = 0;
+  }
+  buf[buf_len] = 0;
+  tputs(serv, buf, buf_len);
+}
+
 static void cmd_mmode(int idx, char *par)
 {
   char *mode = newsplit(&par);
   if (strlen(mode) > 2 || !strchr("+-", mode[0]) || !par[0]) {
-    dprintf(idx, "Usage: mmode <(+|-)MODE> <#channel> <a|o|v|d|r> [bots=n] [alines=n] [slines=n] [overlap=n] [bitch] [simul]\n");
+    dprintf(idx, "Usage: mmode <(+|-)MODE> <#channel> <a|o|v|d|r> [bots=n] [alines=n] [slines=n] [overlap=n] [bitch] [simul] [local]\n");
     dprintf(idx, "Ie. mmode -o #chan a\n");
     return;
   }
@@ -562,7 +607,7 @@ static void cmd_mmode(int idx, char *par)
     }
   }
   if (!chan || !chname[0]) {
-    dprintf(idx, "Usage: mmode <(+|-)MODE> <#channel> <a|o|v|d|r> [bots=n] [alines=n] [slines=n] [overlap=n] [bitch] [simul]\n");
+    dprintf(idx, "Usage: mmode <(+|-)MODE> <#channel> <a|o|v|d|r> [bots=n] [alines=n] [slines=n] [overlap=n] [bitch] [simul] [local]\n");
     dprintf(idx, "Ie. mmode -o #chan a\n");
     return;
   }
@@ -570,7 +615,7 @@ static void cmd_mmode(int idx, char *par)
   char *who = newsplit(&par);
 
   if (strlen(who) > 1 || !strchr("aovdr", who[0])) {
-    dprintf(idx, "Usage: mmode <(+|-)MODE> <#channel> <a|o|v|d|r> [bots=n] [alines=n] [slines=n] [overlap=n] [bitch] [simul]\n");
+    dprintf(idx, "Usage: mmode <(+|-)MODE> <#channel> <a|o|v|d|r> [bots=n] [alines=n] [slines=n] [overlap=n] [bitch] [simul] [local]\n");
     dprintf(idx, "Ie. mmode -o #chan a\n");
     dprintf(idx, "a = all.\n");
     dprintf(idx, "o = ops.\n");
@@ -617,24 +662,8 @@ static void cmd_mmode(int idx, char *par)
       targets[targetcount++] = m;
   }
 
-  if (!chanbotcount) {
-    dprintf(idx, "No bots opped on %s\n", chan->name);
-    free(targets);
-    free(overlaps);
-    free(chanbots);
-    return;
-  }
-
-  if (!targetcount) {
-    dprintf(idx, "No one to mode on %s\n", chan->name);
-    free(targets);
-    free(overlaps);
-    free(chanbots);
-    return;
-  }
-
   int force_bots = 0, force_alines = 0, force_slines = 0, force_overlap = 0;
-  bool bitch = 0, simul = 0;
+  bool bitch = 0, simul = 0, local = 0;
 
   while (par && par[0]) {
     char *p = newsplit(&par);
@@ -651,9 +680,11 @@ static void cmd_mmode(int idx, char *par)
     } else if (!egg_strncasecmp(p, "alines=", 7)) {
       p += 7;
       force_alines = atoi(p);
-      if ((force_alines < 1) || (force_alines > 20)) {
-	dprintf(idx, "alines must be within 1-20\n");
-        dprintf(idx, ">5 will fail without a floodless.\n");
+      if (force_alines > 5)
+        dprintf(idx, "alines >5 will fail without a floodless.\n");
+
+      if ((force_alines < 1) || (force_alines > 100)) {
+	dprintf(idx, "alines must be within 1-100\n");
 	free(targets);
 	free(overlaps);
 	free(chanbots);
@@ -680,10 +711,12 @@ static void cmd_mmode(int idx, char *par)
 	free(chanbots);
 	return;
       }
-    } else if (!strcmp(p, "bitch")) {
+    } else if (!egg_strncasecmp(p, "bitch", 5)) {
       bitch = 1;
-    } else if (!strcmp(p, "simul")) {
+    } else if (!egg_strncasecmp(p, "simul", 5)) {
       simul = 1;
+    } else if (!egg_strncasecmp(p, "local", 5)) {
+      local = 1;
     } else {
       dprintf(idx, "Unrecognized option %s\n", p);
       free(targets);
@@ -693,9 +726,31 @@ static void cmd_mmode(int idx, char *par)
     }
   }
 
+  if (!targetcount) {
+    dprintf(idx, "No targets found on %s\n", chan->name);
+    free(targets);
+    free(overlaps);
+    free(chanbots);
+    return;
+  }
+
+  if ((!chanbotcount && !local) || (local && !me_op(chan))) {
+    dprintf(idx, "No bots opped on %s\n", chan->name);
+    free(targets);
+    free(overlaps);
+    free(chanbots);
+    return;
+  }
+
+  if (local)
+    force_bots = 1;
+
+  if (local && floodless)
+    force_alines = force_slines = 100;
+
   int overlap = (force_overlap ? force_overlap : 1);
   int needed_modes = (overlap * targetcount);
-  int max_modes = ((force_bots ? force_bots : chanbotcount) * (force_alines ? force_alines : 5) * modesperline);
+  int max_modes = ((force_bots ? force_bots : chanbotcount) * (force_alines ? force_alines : default_alines) * modesperline);
 
   if (needed_modes > max_modes) {
     dprintf(idx, "Need to make %d modes, but the max is %d.\n", needed_modes, max_modes);
@@ -711,35 +766,42 @@ static void cmd_mmode(int idx, char *par)
   }
 
 
-  int bots, modes;
+  double bots = 0;
+  int amodes = 0;
 
   /* ok it's possible... now let's figure out how */
   if (force_bots && force_alines) {
     /* not much choice... overlap should not autochange */
     bots = force_bots;
-    modes = force_alines * modesperline;
+    amodes = force_alines * modesperline;
   } else {
     if (force_bots) {
       /* calc needed modes per bot */
       bots = force_bots;
-      modes = (needed_modes + (bots - 1)) / bots;
+      amodes = (needed_modes + ((int)bots - 1)) / (int)bots;
     } else if (force_alines) {
-      modes = force_alines * modesperline;
-      bots = (needed_modes + (modes - 1)) / modes;
+      amodes = force_alines * modesperline;
+      bots = (double) needed_modes / amodes;
+      if (bots > (int)bots) bots = (int)bots+1; /* ceil(bots) */
     } else {
       /* Try minimizing alines, 1,2,3,4,5 against bots needed */
-      modes = 1 * modesperline;
-      bots = (needed_modes + (modes - 1)) / modes;
+      amodes = 1 * modesperline;
+      bots = (double) needed_modes / amodes;
+      if (bots > (int)bots) bots = (int)bots+1; /* ceil(bots) */
 
       for (int min_alines = 2; min_alines <= 5; ++min_alines) {
-        if (bots > chanbotcount) {
-          modes = min_alines * modesperline;
-          bots = (needed_modes + (modes - 1)) / modes;
+        if ((int)bots > chanbotcount) {
+          amodes = min_alines * modesperline;
+          bots = (double) needed_modes / amodes;
+          if (bots > (int)bots) bots = (int)bots+1; /* ceil(bots) */
         } else
           break;
       }
 
-      if (bots > chanbotcount) {
+      force_slines = (amodes / modesperline);
+
+      /* lol einride is dumb */
+      if ((int)bots > chanbotcount) {
         putlog(LOG_MISC, "*", "Totally fucked calculations in cmd_mmode. this CAN'T happen.");
         dprintf(idx, "Something's wrong... bug the coder\n");
         free(targets);
@@ -756,15 +818,17 @@ static void cmd_mmode(int idx, char *par)
   if (force_slines)
     smodes = force_slines * modesperline;
   else
-    smodes = 5 * modesperline;
-  if (smodes < modes)
-    smodes = modes;
+    smodes = default_alines * modesperline;
+  if (smodes < amodes)
+    smodes = amodes;
 
   dprintf(idx, "Mass %s of %s\n", mode, chan->dname);
-  dprintf(idx, "  %d bots used.\n", bots);
+  dprintf(idx, "  %d bots used.\n", (int)bots);
   dprintf(idx, "  %d targets.\n", targetcount);
-  dprintf(idx, "  %d assumed modes per participating bot.\n", modes);
+  dprintf(idx, "  %d assumed modes per participating bot.\n", amodes);
+  dprintf(idx, "  %d assumed mode lines per participating bot.\n", amodes / modesperline);
   dprintf(idx, "  %d max modes per participating bot.\n", smodes);
+  dprintf(idx, "  %d max mode lines per participating bot.\n", smodes / modesperline);
   dprintf(idx, "  %d assumed modes per target nick.\n", overlap);
 
   int tpos = 0, bpos = 0, i = 0;
@@ -772,12 +836,15 @@ static void cmd_mmode(int idx, char *par)
 
   /* now use bots/modes to distribute nicks to MODE on */
   while (bots) {
-    if (!simul)
+    if (local)
+      simple_snprintf(work, sizeof(work), "%s %s", mode, chan->dname);
+    else if (!simul)
       simple_snprintf(work, sizeof(work), "dp %s %s", mode, chan->dname);
     else
       work[0] = 0;
+
     /* Make list of assumed lines (alines) */
-    for (i = 0; i < modes; i++) {
+    for (i = 0; i < amodes; ++i) {
       if (overlaps[tpos]++ < overlap) {
         strcat(work, " ");
         strcat(work, targets[tpos]->nick);
@@ -785,11 +852,12 @@ static void cmd_mmode(int idx, char *par)
       if (++tpos >= targetcount)
         tpos = 0;
     }
-    /* Now make lines of throttled modes (slines) */
-    if (smodes > modes) {
+
+    /* Now make lines of throttled modes (send lines) (slines) */
+    if (smodes > amodes) {
       int atpos = tpos;
-      for (i = 0; i < (smodes - modes); i++) {
-        if (overlaps[tpos]++ < overlap) {
+      for (i = 0; i < (smodes - amodes); ++i) {
+        if (overlaps[atpos]++ < overlap) {
           strcat(work, " ");
           strcat(work, targets[atpos]->nick);
         }
@@ -799,7 +867,9 @@ static void cmd_mmode(int idx, char *par)
     }
 
     if (simul)
-      dprintf(idx, "%s MODE %s %s\n", chanbots[bpos]->nick, mode, work);
+      dprintf(idx, "%-10s MODE %s %s\n", local ? botname : chanbots[bpos]->nick, mode, work);
+    else if (local)
+      mass_mode_request(conf.bot->nick, "dp", work);
     else
       putbot(chanbots[bpos]->user->handle, work);
     --bots;
@@ -815,51 +885,6 @@ static void cmd_mmode(int idx, char *par)
   return;
 }
 
-void mass_mode_request(char *botnick, char *code, char *par)
-{
-  char* mode = newsplit(&par);
-
-  if (strlen(mode) > 2 || !strchr("+-", mode[0]))
-    return;
-
-  char* chname = newsplit(&par);
-
-  char list[101] = "", buf[2048] = "";
-  size_t list_len = 0, buf_len = 0;
-
-  while (par[0]) {
-    int cnt = 0;
-
-    *(buf + buf_len++) = 'M';
-    *(buf + buf_len++) = 'O';
-    *(buf + buf_len++) = 'D';
-    *(buf + buf_len++) = 'E';
-    *(buf + buf_len++) = ' ';
-    buf_len += strlcpy(buf + buf_len, chname, sizeof(buf) - buf_len);
-    *(buf + buf_len++) = ' ';
-
-    while ((cnt < 4) && par[0]) {
-      /* add +mode into irc cmd */
-      buf_len += strlcpy(buf + buf_len, mode, sizeof(buf) - buf_len);
-
-      /* Make list of nicks */
-      char* nick = newsplit(&par);
-      list_len += strlcpy(list + list_len, nick, sizeof(list) - list_len); 
-      if (++cnt < 4 && par[0])
-        *(list + list_len++) = ' ';
-    }
-
-    /* buf is so far: 'MODE #chan +o+o+o+o' */
-    *(buf + buf_len++) = ' ';
-    buf_len += strlcpy(buf + buf_len, list, sizeof(buf) - buf_len);
-    *(buf + buf_len++) = '\r';
-    *(buf + buf_len++) = '\n';
-    list[0] = list_len = 0;
-  }
-  buf[buf_len] = 0;
-  tputs(serv, buf, buf_len);
-}
-
 static void cmd_deop(int idx, char *par)
 {
   struct chanset_t *chan = NULL;

+ 1 - 0
src/mod/server.mod/server.c

@@ -29,6 +29,7 @@
 #include "server.h"
 #include <stdarg.h>
 
+int default_alines = 5;		/* How many mode lines are assumed will work before throttling */
 bool floodless = 0;		/* floodless iline? */
 int ctcp_mode;
 int serv = -1;		/* sock # of server currently */

+ 1 - 1
src/mod/server.mod/server.h

@@ -47,7 +47,7 @@ enum {
 extern bind_table_t	*BT_ctcp, *BT_ctcr, *BT_msgc;
 extern size_t		nick_len;
 extern bool		trigger_on_ignore, floodless;
-extern int 		servidx, ctcp_mode, answer_ctcp, serv, curserv;
+extern int 		servidx, ctcp_mode, answer_ctcp, serv, curserv, default_alines;
 extern port_t		default_port, newserverport, curservport;
 extern time_t		server_online, cycle_time;
 extern char		cursrvname[], botrealname[121], botuserhost[], ctcp_reply[],