Просмотр исходного кода

Merge branch '21-botgroups' into next

* 21-botgroups:
  * Sort cmd_bots output by nodename
  * Add '%group' support to 'bots' command.
  * Specify bot to cmd_groups to show groups for that bot

Conflicts:
	doc/UPDATES
Bryan Drewery 14 лет назад
Родитель
Сommit
5a635675f9
4 измененных файлов с 90 добавлено и 55 удалено
  1. 2 0
      doc/UPDATES
  2. 6 3
      doc/help.txt
  3. 71 46
      src/botnet.c
  4. 11 6
      src/cmds.c

+ 2 - 0
doc/UPDATES

@@ -7,6 +7,8 @@ next
   * 'botjoin' and 'botpart' have been removed. Just use .+chan, .chanset, .botset to control groups.
   * Add command 'groups' to list all groups and which bots are in them.
   * Command 'channels' now accepts a '%group' param to show which channels a group are in.
+  * Add '%group' support to 'bots' command.
+  * Improve output of 'bots' command by displaying and sorting nodename
 
 1.4.0 - http://wraith.botpack.net/milestone/1.4.0
   * Updated server list, 'set -yes servers -' and 'set -yes servers6 -' to get new list.

+ 6 - 3
doc/help.txt

@@ -284,7 +284,7 @@ See also: msg%{+n}
  
 See also: netnick, nick
 :hub:bots
-###  $bbots$b [nodename]
+###  $bbots$b [nodename|%group]
    Shows the list of bots currently on the botnet.
    Example:
       Bots: cEvin, ruthie, Killa1
@@ -292,7 +292,8 @@ See also: netnick, nick
    bot. %{+n}Use $b'%dwho'$b or $b'%dbottree'$b for that information.%{-}
  
    Specifying a nodename will display all bots up/down on that nodename.
-   Bots with a * preceeding its name is down.
+   Bots with a * preceeding its name are down.
+   Specifying a %%group will only show bots in that group.
  
 See also: groups, downbots%{+n}, bottree%{-}
 :hub:botserver:
@@ -1054,8 +1055,10 @@ See also: -exempt, +exempt, console%{+m|m}, chanset, chaninfo%{-}, stick, unstic
  
 See also: console, channels%{+m}, status%{-}
 :hub:groups
-###  $bgroups$b
+###  $bgroups$b [bot]
    Shows the list of groups and which bots are in them.
+
+   Specify a bot to only show which groups it is in.
  
 See also: bots, downbots%{+n}, bottree%{-}
 ::handle

+ 71 - 46
src/botnet.c

@@ -49,6 +49,7 @@
 #include "core_binds.h"
 #include <bdlib/src/String.h>
 #include <bdlib/src/Array.h>
+#include <algorithm>
 
 tand_t			*tandbot = NULL;		/* Keep track of tandem bots on the
 							   botnet */
@@ -522,65 +523,89 @@ void answer_local_whom(int idx, int chan)
   dprintf(idx, "Total users: %d\n", total);
 }
 
+bool sortNodes(const bd::String nodeA, const bd::String nodeB) {
+  // Reverse the domains
+  const bd::Array<bd::String> partsA(nodeA.split("."));
+  const bd::Array<bd::String> partsB(nodeB.split("."));
+  bd::Array<bd::String> reversedPartsA, reversedPartsB;
+  bd::String reversedNodeA, reversedNodeB;
+
+  for (size_t i = partsA.length() - 1; i > 0; --i) {
+    reversedPartsA << partsA[i - 1];
+  }
+  for (size_t i = partsB.length() - 1; i > 0; --i) {
+    reversedPartsB << partsB[i - 1];
+  }
+  reversedNodeA = reversedPartsA.join(".");
+  reversedNodeB = reversedPartsB.join(".");
+  return reversedNodeA < reversedNodeB;
+}
+
 /* Show z a list of all bots connected
  */
 void
 tell_bots(int idx, int up, const char *nodename)
 {
-  struct userrec *u = NULL;
-  int cnt = 0, tot = 0, total = 1, mtot = 0;
-  char work[151] = "", *node = NULL;
-
-  if (up) {
-    if (nodename)
-      node = (char *) get_user(&USERENTRY_NODENAME, conf.bot->u);    
-    if (!nodename || wild_match(nodename, node)) {
-      strlcat(work, conf.bot->nick, sizeof(work));
-      strlcat(work, " ", sizeof(work));
-      cnt++;
-      tot++;
-      if (nodename)
-        mtot++;
-    }
+  size_t total = 0, maxNodeNameLength = 0;;
+  bd::Array<bd::String> nodes;
+  bd::HashTable<bd::String, bd::Array<bd::String> > nodeBots;
+  bd::Array<bd::String> bots;
+  bd::String group;
+
+  if (nodename && nodename[0] == '%') {
+    group = nodename + 1;
   }
 
-  for (u = userlist; u; u = u->next) {
+  // Gather a list of nodes and bots per node, as well as per domain
+  for (struct userrec* u = userlist; u; u = u->next) {
     if (u->bot) {
-      if (strcasecmp(u->handle, conf.bot->nick)) {
-        bool found = 0;
-        
-        if (findbot(u->handle))
-          found = 1;
-        total++;
-        if (nodename || (!nodename && ((!up && !found) || (up && found)))) {
-          if (nodename)
-            node = (char *) get_user(&USERENTRY_NODENAME, u);
-          if (!nodename || wild_match(nodename, node)) {
-            if (nodename && !found)
-              strlcat(work, "*", sizeof(work));
-            strlcat(work, u->handle, sizeof(work));
-            cnt++;
-            if (nodename)
-              mtot++;
-            if (!nodename || (nodename && found))
-              tot++;
-            if (cnt == 11) {
-              dprintf(idx, "%s bots: %s\n", nodename ? "Matching" : up ? "Up" : "Down", work);
-              work[0] = 0;
-              cnt = 0;
-            } else {
-              strlcat(work, " ", sizeof(work));
-            }
+      // If looking for groups, exclude hubs
+      if (group.length() && bot_hublevel(u) != 999) {
+        continue;
+      }
+      ++total;
+      bd::String botnick(u->handle);
+      const bd::Array<bd::String> botgroups(bd::String(var_get_bot_data(u, "groups", true)).split(","));
+
+      // Include this bot?
+      const bool group_match = group.length() && botgroups.find(group) != botgroups.npos;
+      const bd::String node((const char*) get_user(&USERENTRY_NODENAME, u));
+      const bool node_match = ((nodename && node.length() && wild_match(nodename, node.c_str())) || !nodename);
+      const bool bot_found = findbot(u->handle);
+      const bool up_down_match = (nodename || (!nodename && ((up && bot_found) || (!up && !bot_found))));
+      if (group_match || (group.length() == 0 && node_match && up_down_match)) {
+        if (nodes.find(node) == nodes.npos) {
+          nodes << node;
+          if (node.length() > maxNodeNameLength) {
+            maxNodeNameLength = node.length();
           }
         }
+        if ((group.length() || nodename) && !bot_found) {
+          botnick = '*' + botnick;
+        }
+        nodeBots[node] << botnick;
+        bots << botnick;
       }
     }
   }
-  if (work[0])
-    dprintf(idx, "%s bot%s: %s\n", nodename ? "Matching" : up ? "Up" : "Down", cnt > 1 ? "s" : "", work);
-  if (nodename)
-    dprintf(idx, "(Total Matching: %d/%d)\n", mtot, total);
-  dprintf(idx, "(Total %s: %d/%d)\n", nodename ? "up" : up ? "up" : "down", tot, nodename ? mtot : total);
+
+  if (group.length() == 0 && !nodename) {
+    dumplots(idx, nodename ? "Matching: " : (up ? "Up: " : "Down: "), static_cast<bd::String>(bots.join(" ")).c_str());
+  } else {
+    // Sort by nodes
+    std::sort(nodes.begin(), nodes.end(), sortNodes);
+    for (size_t i = 0; i < nodes.length(); ++i) {
+      const bd::String node(nodes[i]);
+      const bd::Array<bd::String> botsInNode(nodeBots[node]);
+      dumplots(idx, bd::String::printf("%*s: ", int(maxNodeNameLength), node.c_str()).c_str(), static_cast<bd::String>(botsInNode.join(" ")).c_str());
+    }
+  }
+
+  if (nodename || group.length()) {
+    dprintf(idx, "(Total Matching: %zu/%zu)\n", bots.length(), total);
+  } else {
+    dprintf(idx, "(Total %s: %zu/%zu)\n", up ? "up" : "down", bots.length(), total);
+  }
 }
 
 /* Show a simpleton bot tree

+ 11 - 6
src/cmds.c

@@ -905,7 +905,8 @@ static void cmd_groups(int idx, char *par)
 {
   struct userrec *u = NULL;
 
-  putlog(LOG_CMDS, "*", "#%s# groups", dcc[idx].nick);
+  putlog(LOG_CMDS, "*", "#%s# groups %s", dcc[idx].nick, par);
+  bd::String botnick(newsplit(&par));
 
   bd::Array<bd::String> globalgroups = bd::String(var_get_gdata("groups")).split(",");
   bd::Array<bd::String> allgroups;
@@ -934,11 +935,15 @@ static void cmd_groups(int idx, char *par)
     }
   }
 
-  // Display all groups and which bots are in them
-  for (size_t i = 0; i < allgroups.length(); ++i) {
-    const bd::String group(allgroups[i]);
-    const bd::Array<bd::String> bots(groupBots[group]);
-    dumplots(idx, bd::String::printf("%-*s: ", int(maxGroupLen), group.c_str()).c_str(), static_cast<bd::String>(bots.join(" ")).c_str());
+  if (botnick.length()) {
+    dprintf(idx, "%s is in groups: %s\n", botnick.c_str(), static_cast<bd::String>(botGroups[botnick].join(" ")).c_str());
+  } else {
+    // Display all groups and which bots are in them
+    for (size_t i = 0; i < allgroups.length(); ++i) {
+      const bd::String group(allgroups[i]);
+      const bd::Array<bd::String> bots(groupBots[group]);
+      dumplots(idx, bd::String::printf("%-*s: ", int(maxGroupLen), group.c_str()).c_str(), static_cast<bd::String>(bots.join(" ")).c_str());
+    }
   }
 
   dprintf(idx, "Total groups: %zu\n", allgroups.length());