Преглед на файлове

* Added 'jupenick'. Jupenick is preferred over 'nick' but only 'nick' will be rotated with altchars. Ie, nick_, nick-, etc. (fixes #421)
* The bot will never stay on an old jupenick, .set jupenick - will force the bot to use a variation of its 'nick'
* Attempts to change 'nick' now will rotate until a variation of that nick is found.
* Juped/RESVd nicks are handled better now



svn: 3845

Bryan Drewery преди 18 години
родител
ревизия
c967cf537f
променени са 11 файла, в които са добавени 216 реда и са изтрити 54 реда
  1. 1 0
      doc/UPDATES
  2. 9 3
      misc/help.txt
  3. 1 0
      src/chanprog.c
  4. 1 1
      src/chanprog.h
  5. 6 2
      src/cmds.c
  6. 11 1
      src/misc.c
  7. 6 3
      src/mod/server.mod/server.c
  8. 3 2
      src/mod/server.mod/server.h
  9. 136 36
      src/mod/server.mod/servmsg.c
  10. 39 6
      src/set.c
  11. 3 0
      src/set.h

+ 1 - 0
doc/UPDATES

@@ -11,6 +11,7 @@
 * Fix some various issues with initial setups and new PackConfig format
 * Greatly sped up binary startup - lower resource usage for cron checks, etc.
 * checkchannels now displays server. (fixes #420)
+* Added 'jupenick'. Jupenick is preferred over 'nick' but only 'nick' will be rotated with altchars. Ie, nick_, nick-, etc. (fixes #421)
 
 1.2.15 - http://wraith.botpack.net/milestone/1.2.15
 * Fix a possible segfault when binaries compiled wrong

+ 9 - 3
misc/help.txt

@@ -1534,8 +1534,6 @@ See also: reload, backup
                           matching alias is used. Normal flag checking is done
                           after the alias is expanded. 
                           $bAliases may not reference other aliases.$b
-[S]  $baltchars$b        Define string of characters to cycle when generating alternative
-                          nicks when nick is taken. Ie: _-`[].
 [S]  $bchanset$b         List of default options for when a channel is added. Same format 
                           as 'chanset'.
 [N]  $bserver-port$b     Default port to use for server connections.
@@ -1573,8 +1571,16 @@ See also: reload, backup
  
 [S]  $brealname$b        The bot's "real name" when connecting. (supports '$n' expansion)
 [S]  $busermode$b        The bot's usermode on IRC. (Set on connect/rehash)
-[S]  $bnick$b            The bot's preferred nickname on IRC.
+ 
+[S]  $baltchars$b        Define string of characters to cycle when generating alternative
+                          nicks when nick is taken. Ie: _-`[].
+[S]  $bjupenick$b        The bot will attempt to jupe this nick. It will never use a variation
+                         of the nick though. It will still prefer 'nick' over a variation
+                         of jupenick.
+[S]  $bnick$b            The bot's preferred nickname on IRC. It will auto rotate and append
+                         'altchars' on the end if taken.
 [N]  $bnotify-time$b     The number of seconds between server notify checks for nick.
+ 
 [B]  $birc-autoaway$b    Should the bot go away auto?
  
 [B]  $bident-botnick$b   Send botnick instead of shell username on connect (non-ident)

+ 1 - 0
src/chanprog.c

@@ -58,6 +58,7 @@ struct chanset_t 	*chanset = NULL;	/* Channel list			*/
 char 			admin[121] = "";	/* Admin info			*/
 char			origbotnick[NICKLEN + 1] = "";	/* from -B (placed into conf.bot->nick .. for backup when conf is cleared */
 char 			origbotname[NICKLEN + 1] = "";	/* Nick to regain */
+char                    jupenick[NICKLEN] = "";
 char 			botname[NICKLEN + 1] = "";	/* IRC nickname */
 port_t     		my_port = 0;
 bool			reset_chans = 0;

+ 1 - 1
src/chanprog.h

@@ -31,7 +31,7 @@ bool is_hub(const char*);
 void load_internal_users();
 
 extern struct chanset_t		*chanset;
-extern char			admin[], origbotnick[NICKLEN + 1], origbotname[NICKLEN + 1], botname[];
+extern char			admin[], origbotnick[NICKLEN + 1], origbotname[NICKLEN + 1], jupenick[NICKLEN], botname[];
 extern port_t			my_port;
 extern bool			reset_chans;
 

+ 6 - 2
src/cmds.c

@@ -3867,8 +3867,12 @@ static void rcmd_curnick(char * fbot, char * fhand, char * fidx) {
 
     if (server_online)
       sprintf(tmp, "Currently: %-20s ", botname);
-    if (strncmp(botname, origbotname, strlen(botname)))
-      simple_snprintf(tmp, sizeof(tmp), "%sWant: %s", tmp, origbotname);
+    if (jupenick[0] && strncmp(botname, jupenick, strlen(botname)))
+      simple_snprintf(tmp, sizeof(tmp), "%sJupe: %s", tmp, jupenick);
+    else if (jupenick[0] && strcmp(botname, origbotname))
+      simple_snprintf(tmp, sizeof(tmp), "%sJupe: %s Main: %s", tmp, jupenick, origbotname);
+    else if (strcmp(botname, origbotname))
+      simple_snprintf(tmp, sizeof(tmp), "%sMain: %s", tmp, origbotname);
     if (!server_online)
       simple_snprintf(tmp, sizeof(tmp), "%s(not online)", tmp);
     botnet_send_cmdreply(conf.bot->nick, fbot, fhand, fidx, tmp);

+ 11 - 1
src/misc.c

@@ -602,7 +602,7 @@ readsocks(const char *fname)
     fatal(STR("CANT READ SOCKSFILE"), 0);
   }
 
-  char buf[1024] = "", *nick = NULL, *bufp = NULL, *type = NULL, *buf_ptr = NULL, *ip4 = NULL, *ip6 = NULL;
+  char buf[1024] = "", *nick = NULL, *jnick = NULL, *bufp = NULL, *type = NULL, *buf_ptr = NULL, *ip4 = NULL, *ip6 = NULL;
   time_t old_buildts = 0;
 
   bool enc = 0, first = 1;
@@ -633,6 +633,8 @@ readsocks(const char *fname)
       floodless = 1;
     else if (!strcmp(type, STR("+buildts")))
       old_buildts = strtol(bufp, NULL, 10);
+    else if (!strcmp(type, STR("+jupenick")))
+      jnick = strdup(bufp);
     else if (!strcmp(type, STR("+botname")))
       nick = strdup(bufp);
     else if (!strcmp(type, STR("+ip4")))
@@ -653,6 +655,10 @@ readsocks(const char *fname)
 
   unlink(fname);
   fclose(f);
+  if (jnick) {
+    var_set_by_name(conf.bot->nick, "jupenick", jnick);
+    var_set_userentry(conf.bot->nick, "jupenick", jnick);
+  }
   if (nick) {
     var_set_by_name(conf.bot->nick, "nick", nick);
     var_set_userentry(conf.bot->nick, "nick", nick);
@@ -678,6 +684,8 @@ readsocks(const char *fname)
   }
   if (nick)
     free(nick);
+  if (jnick)
+    free(jnick);
   if (socksfile)
     free(socksfile);
   if (ip4)
@@ -728,6 +736,8 @@ restart(int idx)
   if (server_online) {
     if (botname[0])
       lfprintf(socks->f, STR("+botname %s\n"), botname);
+    if (jupenick[0])
+      lfprintf(socks->f, STR("+jupenick %s\n"), jupenick);
   }
   lfprintf(socks->f, STR("+online_since %li\n"), online_since);
   if (floodless)

+ 6 - 3
src/mod/server.mod/server.c

@@ -70,6 +70,8 @@ char botuserip[UHOSTLEN] = "";		/* bot's user@host with the ip. */
 static bool keepnick = 1;		/* keep trying to regain my intended
 				   nickname? */
 static bool nick_juped = 0;	/* True if origbotname is juped(RPL437) (dw) */
+static bool jnick_juped = 0;    /* True if jupenick is juped */
+bool tried_jupenick = 0;
 static time_t waiting_for_awake;	/* set when i unidle myself, cleared when
 				   i get the response */
 time_t server_online;	/* server connection time */
@@ -995,9 +997,10 @@ void server_report(int idx, int details)
 	    botrealname);
     dprintf(idx, "    My userip: %s!%s\n", botname, botuserip);
     if (nick_juped)
-      dprintf(idx, "    NICK IS JUPED: %s %s\n", origbotname,
-	      keepnick ? "(trying)" : "");
-    nick_juped = 0; /* WHY?? -- drummer */
+      dprintf(idx, "    NICK IS JUPED: %s %s\n", origbotname, keepnick ? "(trying)" : "");
+    if (jnick_juped)
+      dprintf(idx, "    JUPENICK IS JUPED: %s %s\n", jupenick, keepnick ? "(trying)" : "");
+    nick_juped = jnick_juped = 0;
     daysdur(now, server_online, s1);
     simple_snprintf(s, sizeof s, "(connected %s)", s1);
     if (server_lag && !waiting_for_awake) {

+ 3 - 2
src/mod/server.mod/server.h

@@ -46,12 +46,13 @@ enum {
 
 extern bind_table_t	*BT_ctcp, *BT_ctcr, *BT_msgc;
 extern size_t		nick_len;
-extern bool		trigger_on_ignore, floodless;
+extern bool		trigger_on_ignore, floodless, tried_jupenick;
 extern int 		servidx, ctcp_mode, answer_ctcp, serv, curserv, default_alines;
+extern unsigned int     rolls;
 extern port_t		default_port, newserverport, curservport;
 extern time_t		server_online, cycle_time;
 extern char		cursrvname[], botrealname[121], botuserhost[], ctcp_reply[1024],
-			newserver[], newserverpass[], curnetwork[], botuserip[];
+			newserver[], newserverpass[], curnetwork[], botuserip[], altnick_char;
 extern struct server_list *serverlist;
 extern struct dcc_table SERVER_SOCKET;
 extern rate_t		flood_msg, flood_ctcp, flood_g;

+ 136 - 36
src/mod/server.mod/servmsg.c

@@ -30,8 +30,8 @@ char cursrvname[120] = "";
 char curnetwork[120] = "";
 static time_t last_ctcp    = (time_t) 0L;
 static int    count_ctcp   = 0;
-static char   altnick_char = 0;
-static unsigned int rolls = 0;
+char   altnick_char = 0;
+unsigned int rolls = 0;
 #define ROLL_RIGHT
 #undef ROLL_LEFT
 static void rotate_nick(char *nick, char *orignick)
@@ -39,6 +39,9 @@ static void rotate_nick(char *nick, char *orignick)
   size_t len = strlen(nick);
   int use_chr = 1;
 
+#ifdef DEBUG
+  sdprintf("rotate_nick(%s, %s)", nick, orignick);
+#endif
   /* First run? */
   if (altnick_char == 0 && !rolls && altchars[0]) {
     altnick_char = altchars[0];
@@ -107,10 +110,15 @@ static void rotate_nick(char *nick, char *orignick)
   }
 }
 
-static int gotfake433(char *from)
+//This is only called on failed nick on connect
+static int gotfake433(char *nick)
 {
-  rotate_nick(botname, origbotname);
-  putlog(LOG_SERV, "*", "NICK IN USE: Trying '%s'", botname);
+  //Failed to get jupenick on connect, try normal nick
+  if (altnick_char == 0 && jupenick[0] && !rfc_casecmp(botname, jupenick)) {
+    strlcpy(botname, origbotname, NICKLEN);
+  } else //Rotate on failed normal nick
+    rotate_nick(botname, origbotname);
+  putlog(LOG_SERV, "*", "NICK IN USE: '%s' Trying '%s'", nick, botname);
   dprintf(DP_SERVER, "NICK %s\n", botname);
   return 0;
 }
@@ -728,9 +736,13 @@ void server_send_ison()
     /* NOTE: now that botname can but upto NICKLEN bytes long,
      * check that it's not just a truncation of the full nick.
      */
-    if (strncmp(botname, origbotname, strlen(botname))) {
+    // Only check if we're not on jupenick, or there is no jupenick and we're not on the preferred nick
+    if ((jupenick[0] && strncmp(botname, jupenick, strlen(botname))) || (!jupenick[0] && strncmp(botname, origbotname, strlen(botname)))) {
       /* See if my nickname is in use and if if my nick is right.  */
-      dprintf(DP_SERVER, "ISON :%s %s\n", botname, origbotname);
+      if (jupenick[0] && egg_strcasecmp(botname, jupenick))
+        dprintf(DP_SERVER, "ISON :%s %s %s\n", botname, origbotname, jupenick);
+      else if (egg_strcasecmp(botname, origbotname))
+        dprintf(DP_SERVER, "ISON :%s %s\n", botname, origbotname);
     }
   }
 }
@@ -776,11 +788,11 @@ static int gotpong(char *from, char *msg)
   return 0;
 }
 
-/* This is a reply on ISON :<current> <orig> [<alt>]
+/* This is a reply on ISON :<current> <orig> [<jupenick>]
  */
 static void got303(char *from, char *msg)
 {
-  if (!keepnick || !strncmp(botname, origbotname, strlen(botname)))
+  if (!keepnick)
     return;
 
   char *tmp = NULL;
@@ -789,16 +801,27 @@ static void got303(char *from, char *msg)
   fixcolon(msg);
   tmp = newsplit(&msg);
   if (tmp[0] && match_my_nick(tmp)) {
-    bool ison_orig = 0;
+    bool ison_jupe = 0, ison_orig = 0;
 
     while ((tmp = newsplit(&msg))[0]) {
-      if (!rfc_casecmp(tmp, origbotname)) {
+      if (jupenick[0] && !rfc_casecmp(tmp, jupenick)) {
+        ison_jupe = 1;
+        // If some stupid reason they have the same jupenick/nick, make sure to mark it as on
+        if (!rfc_casecmp(tmp, origbotname)) {
+          ison_orig = 1;
+          break;
+        }
+      } else if (!rfc_casecmp(tmp, origbotname)) {
         ison_orig = 1;
-        break; //Take out for alt checks
       }
     }
 
-    if (!ison_orig) {
+    if (jupenick[0] && !ison_jupe && rfc_casecmp(botname, jupenick)) {
+      if (!jnick_juped)
+        putlog(LOG_MISC, "*", "Switching back to jupenick %s", jupenick);
+      tried_jupenick = 1;
+      dprintf(DP_SERVER, "NICK %s\n", jupenick);
+    } else if (!ison_orig && rfc_casecmp(botname, origbotname)) {
       if (!nick_juped)
         putlog(LOG_MISC, "*", "Switching back to nick %s", origbotname);
       dprintf(DP_SERVER, "NICK %s\n", origbotname);
@@ -814,12 +837,24 @@ static int got432(char *from, char *msg)
 
   newsplit(&msg);
   erroneus = newsplit(&msg);
+
+  bool is_jnick = 0;
+
+  if (jupenick[0] && !strcmp(botname, jupenick)) {
+    is_jnick = 1;
+    jnick_juped = 1;
+  } else
+    nick_juped = 1;
+
   if (server_online)
-    putlog(LOG_MISC, "*", "NICK IS INVALID: %s (keeping '%s').", erroneus,
-	   botname);
+    putlog(LOG_MISC, "*", "%sNICK IS INVALID: '%s' (keeping '%s').", is_jnick ? "JUPE" : "", erroneus, botname);
   else {
-    putlog(LOG_MISC, "*", "Server says my nickname '%s' is invalid.", botname);
-    rotate_nick(botname, origbotname);
+    putlog(LOG_MISC, "*", "Server says my %snick '%s' is invalid.", is_jnick ? "jupe" : "", botname);
+    if (jupenick[0] && !strcmp(botname, jupenick))
+      strlcpy(botname, origbotname, NICKLEN);
+    else
+      rotate_nick(botname, origbotname);
+
     dprintf(DP_MODE, "NICK %s\n", botname);
     return 0;
   }
@@ -829,19 +864,46 @@ static int got432(char *from, char *msg)
 /* 433 : Nickname in use
  * Change nicks till we're acceptable or we give up
  */
+static char rnick[NICKLEN] = "";
 static int got433(char *from, char *msg)
 {
+  newsplit(&msg);
+  char *tmp = newsplit(&msg);
+
   /* We are online and have a nickname, we'll keep it */
+  //Also make sure we're not juping the jupenick if we shouldn't be.
+  //Prefer to be on the 'nick'(origbotname) at all times
   if (server_online) {
-    char *tmp = NULL;
 
-    newsplit(&msg);
-    tmp = newsplit(&msg);
-    putlog(LOG_MISC, "*", "NICK IN USE: %s (keeping '%s').", tmp, botname);
-    nick_juped = 0;
-    return 0;
-  }
-  gotfake433(from);
+    if (tried_jupenick)
+      jnick_juped = 0;
+    else if (!rfc_casecmp(tmp, origbotname))
+      nick_juped = 0;
+
+    sdprintf("433: botname: %s tmp: %s rolls: %d tried_jupenick: %d", botname, tmp, rolls, tried_jupenick);
+    // Tried jupenick, but already on origbotname (or a rolled nick), stay on it.
+    if (tried_jupenick && (match_my_nick(origbotname) || rolls)) {
+      putlog(LOG_MISC, "*", "%sNICK IN USE: '%s' (keeping '%s').", tried_jupenick ? "JUPE" : "", tmp, botname);
+    } else {  //Else need to find a new nick
+      // Failed to get jupenick, not on origbotname now, try for origbotname and rotate from there
+      if (tried_jupenick) {
+        strlcpy(rnick, origbotname, NICKLEN);
+        tried_jupenick = 0;
+      } else {
+        // Was a failed attempt at a rotated nick, keep rotating on origbotname
+        strlcpy(rnick, tmp, NICKLEN);
+        rotate_nick(rnick, origbotname);
+      }
+
+      // Make sure not trying to set the nick we're already on
+      if (!match_my_nick(rnick)) {
+        putlog(LOG_MISC, "*", "NICK IN USE: '%s' Trying '%s'", tmp, rnick);
+        dprintf(DP_SERVER, "NICK %s\n", rnick);
+      } else
+        putlog(LOG_MISC, "*", "NICK IN USE: '%s' (keeping '%s')", tmp, botname);
+    }
+  } else
+    gotfake433(tmp);
   return 0;
 }
 
@@ -868,13 +930,18 @@ static int got437(char *from, char *msg)
       }
     }
   } else if (server_online) {
-    if (!nick_juped)
-      putlog(LOG_MISC, "*", "NICK IS JUPED: %s (keeping '%s').", s, botname);
-    if (!rfc_casecmp(s, origbotname))
+    if (!rfc_casecmp(s, origbotname)) {
+      if (!nick_juped)
+        putlog(LOG_MISC, "*", "NICK IS JUPED: %s (keeping '%s').", s, botname);
       nick_juped = 1;
+    } else if (jupenick[0] && !rfc_casecmp(s, jupenick)) {
+      if (!jnick_juped)
+        putlog(LOG_MISC, "*", "JUPENICK IS JUPED: %s (keeping '%s').", s, botname);
+      jnick_juped = 1;
+    }
   } else {
     putlog(LOG_MISC, "*", "%s: %s", "Nickname has been juped", s);
-    gotfake433(from);
+    gotfake433(s);
   }
   return 0;
 }
@@ -924,7 +991,9 @@ static int gotnick(char *from, char *msg)
   char *nick = NULL, *buf = NULL, *buf_ptr = NULL;
   struct userrec *u = NULL;
 
+  //Done to prevent gotnick in irc.mod getting a mangled from
   buf = buf_ptr = strdup(from);
+  //Cache user
   u = get_user_by_host(buf);
   nick = splitnick(&buf);
   fixcolon(msg);
@@ -932,21 +1001,44 @@ static int gotnick(char *from, char *msg)
   if (match_my_nick(nick)) {
     /* Regained nick! */
     strlcpy(botname, msg, NICKLEN);
+
     altnick_char = 0;
-    if (!strcmp(msg, origbotname)) {
+    rolls = 0;
+    tried_jupenick = 0;
+
+    if (jupenick[0] && !rfc_casecmp(msg, jupenick)) {
+      putlog(LOG_SERV | LOG_MISC, "*", "Regained jupenick '%s'.", msg);
+      jnick_juped = 0;
+    } else if (!strcmp(msg, origbotname)) {
       putlog(LOG_SERV | LOG_MISC, "*", "Regained nickname '%s'.", msg);
       nick_juped = 0;
     } else if (keepnick && strcmp(nick, msg)) {
-      putlog(LOG_SERV | LOG_MISC, "*", "Nickname changed to '%s'???", msg);
-      if (!rfc_casecmp(nick, origbotname)) {
-        putlog(LOG_MISC, "*", "Switching back to nick %s", origbotname);
-        dprintf(DP_SERVER, "NICK %s\n", origbotname);
+
+      // Was this an attempt at a nick thru rotation?
+      if (!strcmp(rnick, msg)) {
+        putlog(LOG_MISC, "*", "Nickname changed to '%s'", msg);
+      } else {
+        putlog(LOG_SERV | LOG_MISC, "*", "Nickname changed to '%s'???", msg);
+
+        if (jupenick[0] && !rfc_casecmp(nick, jupenick)) {
+          putlog(LOG_MISC, "*", "Switching back to jupenick %s", jupenick);
+          tried_jupenick = 1;
+          dprintf(DP_SERVER, "NICK %s\n", jupenick);
+        } else if (!rfc_casecmp(nick, origbotname)) {
+          putlog(LOG_MISC, "*", "Switching back to nick %s", origbotname);
+          dprintf(DP_SERVER, "NICK %s\n", origbotname);
+        }
       }
     } else
       putlog(LOG_SERV | LOG_MISC, "*", "Nickname changed to '%s'???", msg);
   } else if ((keepnick) && (rfc_casecmp(nick, msg))) {
     /* Only do the below if there was actual nick change, case doesn't count */
-    if (!rfc_casecmp(nick, origbotname)) {
+    //putlog(LOG_MISC, "*", "UNKNOWN CODE: nick: %s botname: %s", nick, botname);
+    if (jupenick[0] && !rfc_casecmp(nick, jupenick)) {
+      putlog(LOG_MISC, "*", "Switching back to jupenick %s", jupenick);
+      tried_jupenick = 1;
+      dprintf(DP_SERVER, "NICK %s\n", jupenick);
+    } else if (!rfc_casecmp(nick, origbotname)) {
       putlog(LOG_MISC, "*", "Switching back to nick %s", origbotname);
       dprintf(DP_SERVER, "NICK %s\n", origbotname);
     }
@@ -1533,6 +1625,11 @@ static void connect_server(void)
     botuserhost[0] = 0;
 
     nick_juped = 0;
+    jnick_juped = 0;
+    tried_jupenick = 0;
+    rolls = 0;
+    altnick_char = 0;
+
     for (chan = chanset; chan; chan = chan->next)
       chan->status &= ~CHAN_JUPED;
 
@@ -1622,7 +1719,10 @@ static void server_dns_callback(int id, void *client_data, const char *host, cha
     dcc[idx].timeval = now;
     SERVER_SOCKET.timeout_val = &server_timeout;
     /* Another server may have truncated it, so use the original */
-    strcpy(botname, origbotname);
+    if (jupenick[0])
+      strcpy(botname, jupenick);
+    else
+      strcpy(botname, origbotname);
     /* Start alternate nicks from the beginning */
     altnick_char = 0;
     /* reset counter so first ctcp is dumped for tcms */

+ 39 - 6
src/set.c

@@ -10,6 +10,7 @@
 #include "botmsg.h"
 #include "chanprog.h"
 #include "match.h"
+#include "main.h"
 #include "misc.h"
 #include "net.h"
 #include "src/mod/server.mod/server.h"
@@ -22,6 +23,8 @@
 
 #include "set_default.h"
 
+static bool parsing_botset = 0;
+
 char altchars[50] = "";
 char alias[1024] = "";
 bool auth_chan;
@@ -86,6 +89,7 @@ static variable_t vars[] = {
  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"),
+ VAR("jupenick",	jupenick,		VAR_STRING|VAR_NOHUB|VAR_JUPENICK|VAR_NODEF,  	0, 0, NULL),
  VAR("kill-threshold",	&kill_threshold,	VAR_INT|VAR_NOLOC,				0, 0, "0"),
  VAR("lag-threshold",	&lag_threshold,		VAR_INT|VAR_NOLHUB,				0, 0, "15"),
  VAR("login",		&login,			VAR_INT|VAR_DETECTED,				0, 4, "warn"),
@@ -95,7 +99,7 @@ static variable_t vars[] = {
  VAR("msg-invite",	msginvite,		VAR_STRING|VAR_NOLHUB,				0, 0, NULL),
  VAR("msg-op",		msgop,			VAR_STRING|VAR_NOLHUB,				0, 0, NULL),
  VAR("msg-pass",	msgpass,		VAR_STRING|VAR_NOLHUB,				0, 0, NULL),
- VAR("nick",		origbotname,		VAR_STRING|VAR_NOLHUB|VAR_NICK|VAR_NODEF|VAR_NOGHUB,	0, 0, NULL),
+ VAR("nick",		origbotname,		VAR_STRING|VAR_NOHUB|VAR_NICK|VAR_NODEF,	0, 0, NULL),
  VAR("notify-time",	&ison_time,		VAR_INT|VAR_NOLHUB,				1, 30, "10"),
  VAR("oidentd",		&oidentd,		VAR_INT|VAR_BOOL|VAR_NOLHUB,			0, 1, "0"),
  VAR("op-bots",		&op_bots,		VAR_INT|VAR_NOLOC,				1, MAX_BOTS, "1"),
@@ -272,11 +276,38 @@ sdprintf("var (mem): %s -> %s", var->name, datain ? datain : "(NULL)");
     else
       ((char *) var->mem)[0] = 0;
 
-    if (var->flags & VAR_NICK && !conf.bot->hub) {
-       if (!data)
-         strlcpy((char *) var->mem, conf.bot->nick, var->size);
-       if (strcmp(botname, (char *) var->mem))
-         dprintf(DP_SERVER, "NICK %s\n", (char *) var->mem);
+    if (!conf.bot->hub) {
+      if (var->flags & VAR_JUPENICK) {
+        //rolls = 0;
+        //altnick_char = 0;
+        // Don't send nick changes on restart, no need.
+        if (server_online && !parsing_botset) {
+          if (data) {
+            // If not on the new nick, jump to it
+            if (rfc_casecmp(botname, (char *) var->mem)) {
+              tried_jupenick = 1;
+              dprintf(DP_SERVER, "NICK %s\n", (char *) var->mem);
+            }
+          } else {
+            // Unset jupenick, try for 'nick' now
+            if (rfc_casecmp(botname, origbotname))
+              dprintf(DP_SERVER, "NICK %s\n", origbotname);
+          }
+        }
+      } else if (var->flags & VAR_NICK) {
+        // Default to botnick
+        if (!data)
+          strlcpy((char *) var->mem, conf.bot->nick, var->size);
+        // Don't send nick changes on restart, no need.
+        if (server_online && !parsing_botset) {
+          // If not already on jupenick and not on the new nick, jump to the new nick
+          if (jupenick[0] && rfc_casecmp(botname, jupenick) && rfc_casecmp(botname, (char *) var->mem))
+            dprintf(DP_SERVER, "NICK %s\n", (char *) var->mem);
+          // No jupenick set
+          else if (!jupenick[0] && rfc_casecmp(botname, (char *) var->mem))
+            dprintf(DP_SERVER, "NICK %s\n", (char *) var->mem);
+        }
+      }
     }
   } else if (var->flags & VAR_RATE) {
     char *p = NULL;
@@ -605,6 +636,7 @@ void var_parse_my_botset()
 
   /* look for local vars inside our own USERENTRY_SET and set them in our cfg struct */
   set_noshare = 1;                      /* why bother sharing out our LOCAL settings? */
+  parsing_botset = 1;
   xk = x = (struct xtra_key *) get_user(&USERENTRY_SET, conf.bot->u);
   for (i = 0; vars[i].name; i++) {
     xk = x;	/* reset pointer to beginning */
@@ -625,6 +657,7 @@ void var_parse_my_botset()
     }
     vars[i].flagged = 0;
   }
+  parsing_botset = 0;
   set_noshare = 0;
 }
 

+ 3 - 0
src/set.h

@@ -34,6 +34,9 @@
 #define VAR_NOGHUB	BIT17
 /* (short) number */
 #define VAR_SHORT 	BIT18
+#define VAR_JUPENICK    BIT19
+
+#define VAR_NOHUB       VAR_NOLHUB|VAR_NOGHUB
 
 #define VAR_LDATA 	1
 #define VAR_GDATA	2