Переглянути джерело

* Added .botjoin and .botpart
*** HUBS CURRENTLY NOT SAVING THE CHANNELS ***


svn: 1024

Bryan Drewery 22 роки тому
батько
коміт
5a9409fc60

+ 2 - 0
doc/UPDATES

@@ -16,6 +16,8 @@ This is a summary of ChangeLog basically.
 12.cfg: cmdprefix is now working as intended.
 12.cfg: cmdprefix is now working as intended.
 13.Fixed a very obscure bug in auth/share that would corrupt the memory.
 13.Fixed a very obscure bug in auth/share that would corrupt the memory.
 14.Now only perm owners may change cfg settings: authkey, cmdprefix, hijack, bad-cookie, manop
 14.Now only perm owners may change cfg settings: authkey, cmdprefix, hijack, bad-cookie, manop
+15.Hubs weren't saving userflie on remote -chan.
+16.Bot specific channels (cmd_botjoin/cmd_botpart)
 
 
 1.1.7
 1.1.7
 
 

+ 11 - 0
misc/help.txt

@@ -286,6 +286,12 @@ See also: botconfig
    channels, and uptime.
    channels, and uptime.
  
  
 See also: %{+n}bottree %{-}%{+m}, bots%{-}
 See also: %{+n}bottree %{-}%{+m}, bots%{-}
+::botjoin
+###  %bbotjoin%b <bot> <channel> [options]
+    Adds a channel to the bot's channel list. If options are specified, the 
+    channel will be configured with the options.
+ 
+See also: botpart, +chan, -chan, chanset, chaninfo
 ::botjump:
 ::botjump:
 ###  %bbotjump%b <bot> [server [port [pass]]]
 ###  %bbotjump%b <bot> [server [port [pass]]]
    Makes the bot jump to another server. If you don't specify a
    Makes the bot jump to another server. If you don't specify a
@@ -307,6 +313,11 @@ See also: msg%{+n}, netmsg%{-}
    The bot will display it's current nick over DCC.
    The bot will display it's current nick over DCC.
  
  
 See also: netnick
 See also: netnick
+::botpart
+###  %bbotjoin%b <bot> <channel> [options]
+    Removes bot from the specified channel
+ 
+See also: botjoin, +chan, -chan, chanset, chaninfo
 :hub:bots
 :hub:bots
 ###  %bbots%b
 ###  %bbots%b
    Shows the list of bots currently on the botnet.
    Shows the list of bots currently on the botnet.

+ 19 - 9
src/chanprog.c

@@ -643,21 +643,31 @@ int isowner(char *name)
   }
   }
 }
 }
 
 
+
+int 
+botshouldjoin(struct userrec *u, struct chanset_t *chan)
+{
+  /* just return 1 for now */
+  return 1;
+}
+
 int shouldjoin(struct chanset_t *chan)
 int shouldjoin(struct chanset_t *chan)
 {
 {
-  if (!strncmp(conf.bot->nick, "wtest", 5) && !strcmp(chan->dname, "#wraith"))
-    return 1;
-  else if (!strncmp(conf.bot->nick, "wtest", 4)) /* use 5 for all */
-    return 0; 
+//  if (!strncmp(conf.bot->nick, "wtest", 5) && !strcmp(chan->dname, "#wraith"))
+//    return 1;
+//  else if (!strncmp(conf.bot->nick, "wtest", 4)) /* use 5 for all */
+//    return 0; 
 #ifdef G_BACKUP
 #ifdef G_BACKUP
-  struct flag_record fr = { FR_CHAN | FR_ANYWH | FR_GLOBAL, 0, 0};
+  struct flag_record fr = { FR_CHAN | FR_GLOBAL, 0, 0};
+  struct userrec *u = NULL;
  
  
-  if (!chan || (chan && !chan->name || (chan->name && !chan->name[0])))
+  if (!chan || !chan->dname || !chan->dname[0])
     return 0;
     return 0;
 
 
-  get_user_flagrec(get_user_by_handle(userlist, conf.bot->nick), &fr, chan->name);
-  return (!channel_inactive(chan)
-          && (channel_backup(chan) || !glob_backupbot(fr)));
+  if ((u = get_user_by_handle(userlist, conf.bot->nick)))
+    get_user_flagrec(u, &fr, chan->dname);
+
+  return (!channel_inactive(chan) && (channel_backup(chan) || !glob_backupbot(fr)));
 #else /* !G_BACKUP */
 #else /* !G_BACKUP */
   return !channel_inactive(chan);
   return !channel_inactive(chan);
 #endif /* G_BACKUP */
 #endif /* G_BACKUP */

+ 1 - 0
src/chanprog.h

@@ -21,6 +21,7 @@ void rmspace(char *s);
 void set_chanlist(const char *host, struct userrec *rec);
 void set_chanlist(const char *host, struct userrec *rec);
 void clear_chanlist(void);
 void clear_chanlist(void);
 void clear_chanlist_member(const char *nick);
 void clear_chanlist_member(const char *nick);
+int botshouldjoin(struct userrec *u, struct chanset_t *);
 int shouldjoin(struct chanset_t *);
 int shouldjoin(struct chanset_t *);
 
 
 
 

+ 72 - 14
src/mod/channels.mod/channels.c

@@ -161,43 +161,101 @@ static void got_cset(char *botnick, char *code, char *par)
   }
   }
 }
 }
 
 
+/* returns 1 if botn is in bots */
+
+static int
+parsebots(char *bots, char *botn) {
+  if (!strcmp(bots, "*")) {
+    return 1;
+  } else {
+    char *list = NULL, *bot = NULL;
+
+    list = strdup(bots);
+    bot = strtok(list, ",");
+    while(bot && *bot) {
+      if (!egg_strcasecmp(bot, botn))
+        return 1;
+      bot = strtok((char*) NULL, ",");
+    }
+    free(list);
+  }
+  return 0;
+}
+
 static void got_cpart(char *botnick, char *code, char *par)
 static void got_cpart(char *botnick, char *code, char *par)
 {
 {
-  char *chname = NULL;
+  char *chname = NULL, *bots = NULL;
   struct chanset_t *chan = NULL;
   struct chanset_t *chan = NULL;
+  int match = 0;
 
 
   if (!par[0])
   if (!par[0])
    return;
    return;
 
 
   chname = newsplit(&par);
   chname = newsplit(&par);
-  chan = findchan_by_dname(chname);
-  if (!chan)
+  if (!(chan = findchan_by_dname(chname)))
    return;
    return;
-  remove_channel(chan);
+
+  bots = newsplit(&par);
+  match = parsebots(bots, conf.bot->nick);
+ 
+  if (match)
+    do_chanset(NULL, chan, "+inactive", DO_LOCAL);
+  else
+    remove_channel(chan);
+
+#ifdef HUB
+  write_userfile(-1);
+#endif /* HUB */
 }
 }
 
 
 static void got_cjoin(char *botnick, char *code, char *par)
 static void got_cjoin(char *botnick, char *code, char *par)
 {
 {
-  char *chname = NULL;
+  char *chname = NULL, *options = NULL;
+#ifdef LEAF 
+  char *bots = NULL;
+  int match = 0, inactive = 0;
+#endif /* LEAF */
   struct chanset_t *chan = NULL;
   struct chanset_t *chan = NULL;
 
 
   if (!par[0])
   if (!par[0])
    return;
    return;
 
 
   chname = newsplit(&par);
   chname = newsplit(&par);
-  if (findchan_by_dname(chname)) {
-   return;
-  } else if ((chan = findchan(chname))) {
-   return;
-  }
-
-  if (channel_add(NULL, chname, par) == ERROR) /* drummer */
+  chan = findchan_by_dname(chname);
+  
+  /* ALL hubs should add the channel, leaf should check the list for a match */
+#ifdef LEAF
+  bots = newsplit(&par);
+  if (strstr(par, "+inactive"))
+    inactive = 1;
+  match = parsebots(bots, conf.bot->nick);
+  if (chan && !match)
+    return;
+  if (!match) {
+    size_t size = strlen(par) + 12 + 1;
+
+    options = calloc(1, size);
+    egg_snprintf(options, size, "%s +inactive", par);
+  } else if (match && chan && !shouldjoin(chan)) {
+    if (!inactive)
+      do_chanset(NULL, chan, "-inactive", DO_LOCAL);
+    return;
+  } else
+#endif /* LEAF */
+    options = par;
+  if (chan)
+    return;
+sdprintf("OPTIONS: %s", options);
+  if (channel_add(NULL, chname, options) == ERROR) /* drummer */
     putlog(LOG_BOTS, "@", "Invalid channel or channel options from %s for %s", botnick, chname);
     putlog(LOG_BOTS, "@", "Invalid channel or channel options from %s for %s", botnick, chname);
-  else {
 #ifdef HUB
 #ifdef HUB
+  else
     write_userfile(-1);
     write_userfile(-1);
 #endif /* HUB */
 #endif /* HUB */
-  }
+#ifdef LEAF
+  if (!match)
+    free(options);
+#endif /* LEAF */
 }
 }
 
 
 #ifdef LEAF
 #ifdef LEAF

+ 94 - 35
src/mod/channels.mod/cmdschan.c

@@ -941,12 +941,13 @@ static void cmd_down(struct userrec *u, int idx, char *par)
   
   
 }
 }
 
 
-static void cmd_pls_chan(struct userrec *u, int idx, char *par)
+static void pls_chan(struct userrec *u, int idx, char *par, char *bot)
 {
 {
   char *chname = NULL, result[1024] = "", buf[2048] = "";
   char *chname = NULL, result[1024] = "", buf[2048] = "";
   struct chanset_t *chan = NULL;
   struct chanset_t *chan = NULL;
 
 
-  putlog(LOG_CMDS, "*", "#%s# +chan %s", dcc[idx].nick, par);
+  if (!bot)
+    putlog(LOG_CMDS, "*", "#%s# +chan %s", dcc[idx].nick, par);
 
 
   if (!par[0]) {
   if (!par[0]) {
     dprintf(idx, "Usage: +chan [%s]<channel> [options]\n", CHANMETA);
     dprintf(idx, "Usage: +chan [%s]<channel> [options]\n", CHANMETA);
@@ -954,13 +955,13 @@ static void cmd_pls_chan(struct userrec *u, int idx, char *par)
   }
   }
 
 
   chname = newsplit(&par);
   chname = newsplit(&par);
-  sprintf(buf, "cjoin %s %s", chname, par);
+  sprintf(buf, "cjoin %s %s %s", chname, bot ? bot : "*", par);		/* +chan makes all bots join */
 
 
-  if (findchan_by_dname(chname)) {
+  if (!bot && findchan_by_dname(chname)) {
     putallbots(buf);
     putallbots(buf);
     dprintf(idx, "That channel already exists!\n");
     dprintf(idx, "That channel already exists!\n");
     return;
     return;
-  } else if ((chan = findchan(chname))) {
+  } else if ((chan = findchan(chname)) && !bot) {
     putallbots(buf);
     putallbots(buf);
     dprintf(idx, "That channel already exists as %s!\n", chan->dname);
     dprintf(idx, "That channel already exists as %s!\n", chan->dname);
     return;
     return;
@@ -971,25 +972,26 @@ static void cmd_pls_chan(struct userrec *u, int idx, char *par)
     dprintf(idx, "Invalid channel name.\n");
     dprintf(idx, "Invalid channel name.\n");
     return;
     return;
   }
   }
-  if (channel_add(result, chname, par) == ERROR) {
+  if (!chan && !findchan_by_dname(chname) && channel_add(result, chname, par) == ERROR) {
     dprintf(idx, "Invalid channel or channel options.\n");
     dprintf(idx, "Invalid channel or channel options.\n");
-    if (result && result[0])
+    if (result[0])
       dprintf(idx, "%s\n", result);
       dprintf(idx, "%s\n", result);
   } else {
   } else {
     if ((chan = findchan_by_dname(chname))) {
     if ((chan = findchan_by_dname(chname))) {
-      char *tmp = NULL;
+      if (!bot) {
+        char tmp[51] = "";
 
 
+        sprintf(tmp, "addedby %s addedts %li", dcc[idx].nick, now);
+        if (buf[0])
+          sprintf(buf, "%s %s", buf, tmp);
+        else
+          sprintf(buf, "%s", tmp);
+        do_chanset(NULL, chan, tmp, DO_LOCAL);
+        dprintf(idx, "Channel %s added to the botnet.\n", chname);
+      } else {
+        dprintf(idx, "Channel %s added to the bot: %s\n", chname, bot);
+      }
       putallbots(buf);
       putallbots(buf);
-
-      tmp = calloc(1, 7 + 1 + strlen(dcc[idx].nick) + 1);
-      sprintf(tmp, "addedby %s", dcc[idx].nick);
-      do_chanset(NULL, chan, tmp, DO_LOCAL | DO_NET );
-      free(tmp);
-
-      tmp = calloc(1, 7 + 1 + 10 + 1);
-      sprintf(tmp, "addedts %li", now);
-      do_chanset(NULL, chan, tmp, DO_LOCAL | DO_NET );
-      free(tmp);
     }
     }
 #ifdef HUB
 #ifdef HUB
     write_userfile(-1);
     write_userfile(-1);
@@ -997,13 +999,39 @@ static void cmd_pls_chan(struct userrec *u, int idx, char *par)
   }
   }
 }
 }
 
 
-static void cmd_mns_chan(struct userrec *u, int idx, char *par)
+static void cmd_pls_chan(struct userrec *u, int idx, char *par)
+{
+  pls_chan(u, idx, par, NULL);
+}
+
+static void cmd_botjoin(struct userrec *u, int idx, char *par)
+{
+  char *bot = NULL;
+  struct userrec *botu = NULL;
+
+  putlog(LOG_CMDS, "*", "#%s# botjoin %s", dcc[idx].nick, par);
+
+  if (!par[0]) {
+    dprintf(idx, "Usage: botjoin <bot> [%s]<channel> [options]\n", CHANMETA);
+    return;
+  }
+  bot = newsplit(&par);
+  botu = get_user_by_handle(userlist, bot);
+  if (botu && botu->flags && (botu->flags & USER_BOT)) {
+    pls_chan(u, idx, par, bot);
+  } else {
+    dprintf(idx, "Error: '%s' is not a bot.\n", bot);
+  }
+}
+
+static void mns_chan(struct userrec *u, int idx, char *par, char *bot)
 {
 {
   char *chname = NULL, buf2[1024] = "";
   char *chname = NULL, buf2[1024] = "";
   struct chanset_t *chan = NULL;
   struct chanset_t *chan = NULL;
   int i;
   int i;
 
 
-  putlog(LOG_CMDS, "*", "#%s# -chan %s", dcc[idx].nick, par);
+  if (!bot)
+    putlog(LOG_CMDS, "*", "#%s# -chan %s", dcc[idx].nick, par);
 
 
   if (!par[0]) {
   if (!par[0]) {
     dprintf(idx, "Usage: -chan [%s]<channel>\n", CHANMETA);
     dprintf(idx, "Usage: -chan [%s]<channel>\n", CHANMETA);
@@ -1011,32 +1039,61 @@ static void cmd_mns_chan(struct userrec *u, int idx, char *par)
   }
   }
   chname = newsplit(&par);
   chname = newsplit(&par);
 
 
-  sprintf(buf2, "cpart %s", chname);
-  putallbots(buf2);
+  sprintf(buf2, "cpart %s %s", chname, bot ? bot : "*");
+  if (bot)		/* bot will just set it +inactive */
+    putbot(bot, buf2);
+  else
+    putallbots(buf2);
 
 
   chan = findchan_by_dname(chname);
   chan = findchan_by_dname(chname);
   if (!chan) {
   if (!chan) {
     if ((chan = findchan(chname)))
     if ((chan = findchan(chname)))
-      dprintf(idx, "That channel exists with a short name of %s, use that.\n",
-              chan->dname);
+      dprintf(idx, "That channel exists with a short name of %s, use that.\n", chan->dname);
     else
     else
       dprintf(idx, "That channel doesn't exist!\n");
       dprintf(idx, "That channel doesn't exist!\n");
     return;
     return;
   }
   }
 
 
-  for (i = 0; i < dcc_total; i++)
-    if ((dcc[i].type->flags & DCT_CHAT) &&
-	!rfc_casecmp(dcc[i].u.chat->con_chan, chan->dname)) {
-      dprintf(i, "%s is no longer a valid channel, changing your console to '*'\n",
-	      chname);
-      strcpy(dcc[i].u.chat->con_chan, "*");
-    }
-  remove_channel(chan);
+  if (!bot) {
+    for (i = 0; i < dcc_total; i++)
+      if ((dcc[i].type->flags & DCT_CHAT) && !rfc_casecmp(dcc[i].u.chat->con_chan, chan->dname)) {
+        dprintf(i, "%s is no longer a valid channel, changing your console to '*'\n", chname);
+        strcpy(dcc[i].u.chat->con_chan, "*");
+      } 
+    remove_channel(chan);
 #ifdef HUB
 #ifdef HUB
-  write_userfile(-1);
+    write_userfile(-1);
 #endif /* HUB */
 #endif /* HUB */
-  dprintf(idx, "Channel %s removed from the bot.\n", chname);
-  dprintf(idx, "This includes any channel specific bans, invites, exemptions and user records that you set.\n");
+    dprintf(idx, "Channel %s removed from the botnet.\n", chname);
+    dprintf(idx, "This includes any channel specific bans, invites, exemptions and user records that you set.\n");
+  } else
+    dprintf(idx, "Channel %s removed from the bot: %s\n", chname, bot);
+}
+
+static void cmd_mns_chan(struct userrec *u, int idx, char *par)
+{
+  mns_chan(u, idx, par, NULL);
+}
+
+static void cmd_botpart(struct userrec *u, int idx, char *par)
+{
+  char *bot = NULL;
+  struct userrec *botu = NULL;
+
+  putlog(LOG_CMDS, "*", "#%s# botpart %s", dcc[idx].nick, par);
+  
+  if (!par[0]) {
+    dprintf(idx, "Usage: botpart <bot> [%s]<channel> [options]\n", CHANMETA);
+    return;
+  }
+
+  bot = newsplit(&par);
+  botu = get_user_by_handle(userlist, bot);
+  if (botu && botu->flags && (botu->flags & USER_BOT)) {
+    mns_chan(u, idx, par, bot);
+  } else {
+    dprintf(idx, "Error: '%s' is not a bot.\n", bot);
+  }
 }
 }
 
 
 /* thanks Excelsior */
 /* thanks Excelsior */
@@ -1306,6 +1363,8 @@ static cmd_t C_dcc_irc[] =
   {"-exempt",	"o|o",	(Function) cmd_mns_exempt,	NULL},
   {"-exempt",	"o|o",	(Function) cmd_mns_exempt,	NULL},
   {"-invite",	"o|o",	(Function) cmd_mns_invite,	NULL},
   {"-invite",	"o|o",	(Function) cmd_mns_invite,	NULL},
   {"bans",	"o|o",	(Function) cmd_bans,		NULL},
   {"bans",	"o|o",	(Function) cmd_bans,		NULL},
+  {"botjoin",	"n",	(Function) cmd_botjoin,		NULL},
+  {"botpart",	"n",	(Function) cmd_botpart,		NULL},
   {"exempts",	"o|o",	(Function) cmd_exempts,		NULL},
   {"exempts",	"o|o",	(Function) cmd_exempts,		NULL},
   {"invites",	"o|o",	(Function) cmd_invites,		NULL},
   {"invites",	"o|o",	(Function) cmd_invites,		NULL},
   {"chaninfo",	"m|m",	(Function) cmd_chaninfo,	NULL},
   {"chaninfo",	"m|m",	(Function) cmd_chaninfo,	NULL},

+ 16 - 19
src/mod/channels.mod/tclchan.c

@@ -602,24 +602,22 @@ int channel_modify(char *result, struct chanset_t *chan, int items, char **item)
     }
     }
   }
   }
 #ifdef LEAF
 #ifdef LEAF
-  if (1 || loading) {
-    if ((old_status ^ chan->status) & CHAN_INACTIVE) {
-      if (!shouldjoin(chan) && (chan->status & (CHAN_ACTIVE | CHAN_PEND)))
-        dprintf(DP_SERVER, "PART %s\n", chan->name);
-      if (shouldjoin(chan) && !(chan->status & (CHAN_ACTIVE | CHAN_PEND)))
-	dprintf(DP_SERVER, "JOIN %s %s\n", (chan->name[0]) ?
-					   chan->name : chan->dname,
-					   chan->channel.key[0] ?
-					   chan->channel.key : chan->key_prot);
-    }
-    if ((old_status ^ chan->status) & (CHAN_ENFORCEBANS | CHAN_BITCH)) {
-      recheck_channel(chan, 1);
-    /* if we -take, recheck the chan for modes and shit */
-    } else if ((chan->status ^ old_status) & (CHAN_TAKE)) {
-      recheck_channel(chan, 1);
-    } else if (old_mode_pls_prot != chan->mode_pls_prot || old_mode_mns_prot != chan->mode_mns_prot) {
-      recheck_channel_modes(chan);
-    }
+  if ((old_status ^ chan->status) & CHAN_INACTIVE) {
+    if (!shouldjoin(chan) && (chan->status & (CHAN_ACTIVE | CHAN_PEND)))
+      dprintf(DP_SERVER, "PART %s\n", chan->name);
+    if (shouldjoin(chan) && !(chan->status & (CHAN_ACTIVE | CHAN_PEND)))
+      dprintf(DP_SERVER, "JOIN %s %s\n", (chan->name[0]) ?
+			   chan->name : chan->dname,
+			   chan->channel.key[0] ?
+			   chan->channel.key : chan->key_prot);
+  }
+  if ((old_status ^ chan->status) & (CHAN_ENFORCEBANS | CHAN_BITCH)) {
+    recheck_channel(chan, 1);
+  /* if we -take, recheck the chan for modes and shit */
+  } else if ((chan->status ^ old_status) & (CHAN_TAKE)) {
+    recheck_channel(chan, 1);
+  } else if (old_mode_pls_prot != chan->mode_pls_prot || old_mode_mns_prot != chan->mode_mns_prot) {
+    recheck_channel_modes(chan);
   }
   }
 #endif /* LEAF */
 #endif /* LEAF */
   if (x > 0)
   if (x > 0)
@@ -725,7 +723,6 @@ int channel_add(char *result, char *newname, char *options)
   strcat(buf, options);
   strcat(buf, options);
   buf[strlen(buf)] = 0;
   buf[strlen(buf)] = 0;
 
 
-
   if (SplitList(result, buf, &items, &item) != OK)
   if (SplitList(result, buf, &items, &item) != OK)
     return ERROR;
     return ERROR;
 
 

+ 10 - 1
src/mod/channels.mod/userchan.c

@@ -998,9 +998,18 @@ int write_chans(FILE *f, int idx)
     return 0;
     return 0;
 
 
   for (chan = chanset; chan; chan = chan->next) {
   for (chan = chanset; chan; chan = chan->next) {
+    char inactive = 0;
+
     putlog(LOG_DEBUG, "*", "writing channel %s to userfile..", chan->dname);
     putlog(LOG_DEBUG, "*", "writing channel %s to userfile..", chan->dname);
     get_mode_protect(chan, w);
     get_mode_protect(chan, w);
 
 
+    /* if a bot should explicitly NOT join, just set it +inactive ... */
+    if (idx > 0 && !botshouldjoin(dcc[idx].user, chan))
+      inactive = '+';
+    /* ... otherwise give the bot the *actual* setting */
+    else
+      inactive = PLSMNS(channel_inactive(chan));
+
     if (lfprintf(f, "\
     if (lfprintf(f, "\
 + channel add %s { chanmode { %s } addedby %s addedts %lu idle-kick %d \
 + channel add %s { chanmode { %s } addedby %s addedts %lu idle-kick %d \
 limit %d stopnethack-mode %d revenge-mode %d flood-chan %d:%d \
 limit %d stopnethack-mode %d revenge-mode %d flood-chan %d:%d \
@@ -1046,7 +1055,7 @@ exempt-time %d invite-time %d %cenforcebans %cdynamicbans %cuserbans \
 	PLSMNS(channel_revengebot(chan)),
 	PLSMNS(channel_revengebot(chan)),
 	PLSMNS(channel_private(chan)),
 	PLSMNS(channel_private(chan)),
 	PLSMNS(channel_cycle(chan)),
 	PLSMNS(channel_cycle(chan)),
-	PLSMNS(channel_inactive(chan)),
+        inactive,
 	PLSMNS(channel_dynamicexempts(chan)),
 	PLSMNS(channel_dynamicexempts(chan)),
 	PLSMNS(!channel_nouserexempts(chan)),
 	PLSMNS(!channel_nouserexempts(chan)),
  	PLSMNS(channel_dynamicinvites(chan)),
  	PLSMNS(channel_dynamicinvites(chan)),