Give Techbot the ability to check for and ghost existing bots, then rename itself
authorGed Murphy <gedmurphy@reactos.org>
Sun, 10 Aug 2008 13:06:58 +0000 (13:06 +0000)
committerGed Murphy <gedmurphy@reactos.org>
Sun, 10 Aug 2008 13:06:58 +0000 (13:06 +0000)
svn path=/trunk/; revision=35264

irc/TechBot/TechBot.IRCLibrary/IRC.cs
irc/TechBot/TechBot.IRCLibrary/IrcClient.cs
irc/TechBot/TechBot.Library/TechBotIrcService.cs

index f125ece..ca85f08 100644 (file)
@@ -17,10 +17,12 @@ namespace TechBot.IRCLibrary
                public const string PRIVMSG = "PRIVMSG";\r
                public const string USER = "USER";\r
                public const string PASS = "PASS";\r
                public const string PRIVMSG = "PRIVMSG";\r
                public const string USER = "USER";\r
                public const string PASS = "PASS";\r
-               public const string GHOST = "MSG NICKSERV GHOST";\r
+               public const string GHOST = "NICKSERV GHOST";\r
+               public const string NOTICE = "NOTICE";\r
 \r
                public const string RPL_NAMREPLY = "353";\r
                public const string RPL_ENDOFNAMES = "366";\r
 \r
                public const string RPL_NAMREPLY = "353";\r
                public const string RPL_ENDOFNAMES = "366";\r
+               public const string ERR_NICKNAMEINUSE = "433";\r
 \r
                #endregion\r
 \r
 \r
                #endregion\r
 \r
index 6682bd7..3610715 100644 (file)
@@ -191,6 +191,7 @@ namespace TechBot.IRCLibrary
 \r
                #region Private fields\r
                private bool firstPingReceived = false;\r
 \r
                #region Private fields\r
                private bool firstPingReceived = false;\r
+               private bool awaitingGhostDeath = false;\r
                private System.Text.Encoding encoding = System.Text.Encoding.UTF8;\r
                private TcpClient tcpClient;\r
                private NetworkStream networkStream;\r
                private System.Text.Encoding encoding = System.Text.Encoding.UTF8;\r
                private TcpClient tcpClient;\r
                private NetworkStream networkStream;\r
@@ -198,6 +199,9 @@ namespace TechBot.IRCLibrary
                private LineBuffer messageStream;\r
                private ArrayList ircCommandEventRegistrations = new ArrayList();\r
                private ArrayList channels = new ArrayList();\r
                private LineBuffer messageStream;\r
                private ArrayList ircCommandEventRegistrations = new ArrayList();\r
                private ArrayList channels = new ArrayList();\r
+               private string reqNickname;\r
+               private string curNickname;\r
+               private string password;\r
                #endregion\r
 \r
                #region Public events\r
                #endregion\r
 \r
                #region Public events\r
@@ -240,6 +244,16 @@ namespace TechBot.IRCLibrary
                        }\r
                }\r
 \r
                        }\r
                }\r
 \r
+               /// <summary>\r
+               /// Nickname for the bot.\r
+               /// </summary>\r
+               public string Nickname\r
+               {\r
+                       get\r
+                       {\r
+                               return curNickname;\r
+                       }\r
+               }\r
                #endregion\r
 \r
                #region Private methods\r
                #endregion\r
 \r
                #region Private methods\r
@@ -361,6 +375,24 @@ namespace TechBot.IRCLibrary
                        firstPingReceived = true;\r
                }\r
 \r
                        firstPingReceived = true;\r
                }\r
 \r
+                       /// <summary>\r
+               /// Send a PONG message when a PING message is received.\r
+               /// </summary>\r
+               /// <param name="message">Received IRC message.</param>\r
+               private void NoticeMessageReceived(IrcMessage message)\r
+               {\r
+                       if (awaitingGhostDeath)\r
+                       {\r
+                               string str = string.Format("\ 2{0}\ 2 has been ghosted", reqNickname);\r
+                               if (message.Parameters.Contains(str))\r
+                               {\r
+                                       ChangeNick(reqNickname);\r
+                                       SubmitPassword(password);\r
+                                       awaitingGhostDeath = false;\r
+                               }\r
+                       }\r
+               }\r
+\r
                /// <summary>\r
                /// Process RPL_NAMREPLY message.\r
                /// </summary>\r
                /// <summary>\r
                /// Process RPL_NAMREPLY message.\r
                /// </summary>\r
@@ -472,6 +504,31 @@ namespace TechBot.IRCLibrary
                        }\r
                }\r
 \r
                        }\r
                }\r
 \r
+               /// <summary>\r
+               /// Process ERR_NICKNAMEINUSE message.\r
+               /// </summary>\r
+               /// <param name="message">Received IRC message.</param>\r
+               private void ERR_NICKNAMEINUSEMessageReceived(IrcMessage message)\r
+               {\r
+                       try\r
+                       {\r
+                               if (message.Parameters == null)\r
+                               {\r
+                                       System.Diagnostics.Debug.WriteLine(String.Format("Message has no parameters."));\r
+                                       return;\r
+                               }\r
+                               \r
+                               /* Connect with a different name */\r
+                               string[] parameters = message.Parameters.Split(new char[] { ' ' });\r
+                               string nickname = parameters[1];\r
+                               ChangeNick(nickname + "__");\r
+                       }\r
+                       catch (Exception ex)\r
+                       {\r
+                               System.Diagnostics.Debug.WriteLine(String.Format("Ex. {0}", ex));\r
+                       }\r
+               }\r
+\r
                #endregion\r
 \r
                /// <summary>\r
                #endregion\r
 \r
                /// <summary>\r
@@ -500,10 +557,14 @@ namespace TechBot.IRCLibrary
                                }\r
                                /* Install PING message handler */\r
                                MonitorCommand(IRC.PING, new MessageReceivedHandler(PingMessageReceived));\r
                                }\r
                                /* Install PING message handler */\r
                                MonitorCommand(IRC.PING, new MessageReceivedHandler(PingMessageReceived));\r
+                               /* Install NOTICE message handler */\r
+                               MonitorCommand(IRC.NOTICE, new MessageReceivedHandler(NoticeMessageReceived));\r
                                /* Install RPL_NAMREPLY message handler */\r
                                MonitorCommand(IRC.RPL_NAMREPLY, new MessageReceivedHandler(RPL_NAMREPLYMessageReceived));\r
                                /* Install RPL_ENDOFNAMES message handler */\r
                                MonitorCommand(IRC.RPL_ENDOFNAMES, new MessageReceivedHandler(RPL_ENDOFNAMESMessageReceived));\r
                                /* Install RPL_NAMREPLY message handler */\r
                                MonitorCommand(IRC.RPL_NAMREPLY, new MessageReceivedHandler(RPL_NAMREPLYMessageReceived));\r
                                /* Install RPL_ENDOFNAMES message handler */\r
                                MonitorCommand(IRC.RPL_ENDOFNAMES, new MessageReceivedHandler(RPL_ENDOFNAMESMessageReceived));\r
+                               /* Install ERR_NICKNAMEINUSE message handler */\r
+                               MonitorCommand(IRC.ERR_NICKNAMEINUSE, new MessageReceivedHandler(ERR_NICKNAMEINUSEMessageReceived));\r
                                /* Start receiving data */\r
                                Receive();\r
                        }\r
                                /* Start receiving data */\r
                                Receive();\r
                        }\r
@@ -520,8 +581,6 @@ namespace TechBot.IRCLibrary
                        }\r
                        else\r
                        {\r
                        }\r
                        else\r
                        {\r
-                               \r
-\r
                                connected = false;\r
                                tcpClient.Close();\r
                                tcpClient = null;\r
                                connected = false;\r
                                tcpClient.Close();\r
                                tcpClient = null;\r
@@ -606,10 +665,32 @@ namespace TechBot.IRCLibrary
                        if (nickname == null)\r
                                throw new ArgumentNullException("nickname", "Nickname cannot be null.");\r
 \r
                        if (nickname == null)\r
                                throw new ArgumentNullException("nickname", "Nickname cannot be null.");\r
 \r
+                       Console.WriteLine("Changing nick to {0}\n", nickname);\r
+                       curNickname = nickname;\r
+\r
                        /* NICK <nickname> [ <hopcount> ] */\r
                        SendMessage(new IrcMessage(IRC.NICK, nickname));\r
                }\r
 \r
                        /* NICK <nickname> [ <hopcount> ] */\r
                        SendMessage(new IrcMessage(IRC.NICK, nickname));\r
                }\r
 \r
+        /// <summary>\r
+        /// Ghost nickname.\r
+        /// </summary>\r
+        /// <param name="nickname">Nickname.</param>\r
+        public void GhostNick(string nickname,\r
+                              string password)\r
+        {\r
+            if (nickname == null)\r
+                throw new ArgumentNullException("nickname", "Nickname cannot be null.");\r
+\r
+            if (password == null)\r
+                throw new ArgumentNullException("password", "Password cannot be null.");\r
+\r
+            awaitingGhostDeath = true;\r
+\r
+            /* GHOST <nickname> <password> */\r
+            SendMessage(new IrcMessage(IRC.GHOST, nickname + " " + password));\r
+        }\r
+\r
                /// <summary>\r
                /// Submit password to identify user.\r
                /// </summary>\r
                /// <summary>\r
                /// Submit password to identify user.\r
                /// </summary>\r
@@ -619,6 +700,8 @@ namespace TechBot.IRCLibrary
                        if (password == null)\r
                                throw new ArgumentNullException("password", "Password cannot be null.");\r
 \r
                        if (password == null)\r
                                throw new ArgumentNullException("password", "Password cannot be null.");\r
 \r
+                       this.password = password;\r
+\r
                        /* PASS <password> */\r
                        SendMessage(new IrcMessage(IRC.PASS, password));\r
                }\r
                        /* PASS <password> */\r
                        SendMessage(new IrcMessage(IRC.PASS, password));\r
                }\r
@@ -635,12 +718,10 @@ namespace TechBot.IRCLibrary
                {\r
                        if (nickname == null)\r
                                throw new ArgumentNullException("nickname", "Nickname cannot be null.");\r
                {\r
                        if (nickname == null)\r
                                throw new ArgumentNullException("nickname", "Nickname cannot be null.");\r
+                       reqNickname = nickname;\r
                        firstPingReceived = false;\r
                        if (password != null)\r
                        {\r
                        firstPingReceived = false;\r
                        if (password != null)\r
                        {\r
-                               /* First ghost ourself and then register */\r
-                               if (nickname != null)\r
-                                       SendMessage(new IrcMessage(IRC.GHOST, nickname + " " + password));\r
                                SubmitPassword(password);\r
                        }\r
                        ChangeNick(nickname);\r
                                SubmitPassword(password);\r
                        }\r
                        ChangeNick(nickname);\r
index 238261c..2a51374 100644 (file)
@@ -88,7 +88,15 @@ namespace TechBot.Library
             m_IrcClient.Connect(hostname, port);
             
             m_IrcClient.Register(botname, password, null);
             m_IrcClient.Connect(hostname, port);
             
             m_IrcClient.Register(botname, password, null);
-            Console.WriteLine("Registered as {0}...", botname);
+            Console.WriteLine("Registered as {0}...", m_IrcClient.Nickname);
+
+            /* Did we get the nick we wanted? */
+            if (m_IrcClient.Nickname != botname)
+            {
+                /* there must have been an existing one, kill it */
+                m_IrcClient.GhostNick(botname, password);;
+            }
+
             JoinChannels();
 
             while (!isStopped)
             JoinChannels();
 
             while (!isStopped)
@@ -279,7 +287,7 @@ namespace TechBot.Library
                                                                                injectMessage,
                                                                                GetMessageSource(context)));
                                                InjectMessage(context,
                                                                                injectMessage,
                                                                                GetMessageSource(context)));
                                                InjectMessage(context,
-                                                                     injectMessage);
+                                                             injectMessage);
                                        }
                                        else
                                        {
                                        }
                                        else
                                        {