From: Ged Murphy Date: Sun, 10 Aug 2008 13:06:58 +0000 (+0000) Subject: Give Techbot the ability to check for and ghost existing bots, then rename itself X-Git-Tag: backups/umode-network-branch@37897~583 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=197cc3f6341f153a0678fe93c85c4f7e6f2d6aa6 Give Techbot the ability to check for and ghost existing bots, then rename itself svn path=/trunk/; revision=35264 --- diff --git a/irc/TechBot/TechBot.IRCLibrary/IRC.cs b/irc/TechBot/TechBot.IRCLibrary/IRC.cs index f125ecea6d1..ca85f08fd7b 100644 --- a/irc/TechBot/TechBot.IRCLibrary/IRC.cs +++ b/irc/TechBot/TechBot.IRCLibrary/IRC.cs @@ -17,10 +17,12 @@ namespace TechBot.IRCLibrary public const string PRIVMSG = "PRIVMSG"; public const string USER = "USER"; public const string PASS = "PASS"; - public const string GHOST = "MSG NICKSERV GHOST"; + public const string GHOST = "NICKSERV GHOST"; + public const string NOTICE = "NOTICE"; public const string RPL_NAMREPLY = "353"; public const string RPL_ENDOFNAMES = "366"; + public const string ERR_NICKNAMEINUSE = "433"; #endregion diff --git a/irc/TechBot/TechBot.IRCLibrary/IrcClient.cs b/irc/TechBot/TechBot.IRCLibrary/IrcClient.cs index 6682bd7c4e4..361071507ce 100644 --- a/irc/TechBot/TechBot.IRCLibrary/IrcClient.cs +++ b/irc/TechBot/TechBot.IRCLibrary/IrcClient.cs @@ -191,6 +191,7 @@ namespace TechBot.IRCLibrary #region Private fields private bool firstPingReceived = false; + private bool awaitingGhostDeath = false; private System.Text.Encoding encoding = System.Text.Encoding.UTF8; private TcpClient tcpClient; private NetworkStream networkStream; @@ -198,6 +199,9 @@ namespace TechBot.IRCLibrary private LineBuffer messageStream; private ArrayList ircCommandEventRegistrations = new ArrayList(); private ArrayList channels = new ArrayList(); + private string reqNickname; + private string curNickname; + private string password; #endregion #region Public events @@ -240,6 +244,16 @@ namespace TechBot.IRCLibrary } } + /// + /// Nickname for the bot. + /// + public string Nickname + { + get + { + return curNickname; + } + } #endregion #region Private methods @@ -361,6 +375,24 @@ namespace TechBot.IRCLibrary firstPingReceived = true; } + /// + /// Send a PONG message when a PING message is received. + /// + /// Received IRC message. + private void NoticeMessageReceived(IrcMessage message) + { + if (awaitingGhostDeath) + { + string str = string.Format("{0} has been ghosted", reqNickname); + if (message.Parameters.Contains(str)) + { + ChangeNick(reqNickname); + SubmitPassword(password); + awaitingGhostDeath = false; + } + } + } + /// /// Process RPL_NAMREPLY message. /// @@ -472,6 +504,31 @@ namespace TechBot.IRCLibrary } } + /// + /// Process ERR_NICKNAMEINUSE message. + /// + /// Received IRC message. + private void ERR_NICKNAMEINUSEMessageReceived(IrcMessage message) + { + try + { + if (message.Parameters == null) + { + System.Diagnostics.Debug.WriteLine(String.Format("Message has no parameters.")); + return; + } + + /* Connect with a different name */ + string[] parameters = message.Parameters.Split(new char[] { ' ' }); + string nickname = parameters[1]; + ChangeNick(nickname + "__"); + } + catch (Exception ex) + { + System.Diagnostics.Debug.WriteLine(String.Format("Ex. {0}", ex)); + } + } + #endregion /// @@ -500,10 +557,14 @@ namespace TechBot.IRCLibrary } /* Install PING message handler */ MonitorCommand(IRC.PING, new MessageReceivedHandler(PingMessageReceived)); + /* Install NOTICE message handler */ + MonitorCommand(IRC.NOTICE, new MessageReceivedHandler(NoticeMessageReceived)); /* Install RPL_NAMREPLY message handler */ MonitorCommand(IRC.RPL_NAMREPLY, new MessageReceivedHandler(RPL_NAMREPLYMessageReceived)); /* Install RPL_ENDOFNAMES message handler */ MonitorCommand(IRC.RPL_ENDOFNAMES, new MessageReceivedHandler(RPL_ENDOFNAMESMessageReceived)); + /* Install ERR_NICKNAMEINUSE message handler */ + MonitorCommand(IRC.ERR_NICKNAMEINUSE, new MessageReceivedHandler(ERR_NICKNAMEINUSEMessageReceived)); /* Start receiving data */ Receive(); } @@ -520,8 +581,6 @@ namespace TechBot.IRCLibrary } else { - - connected = false; tcpClient.Close(); tcpClient = null; @@ -606,10 +665,32 @@ namespace TechBot.IRCLibrary if (nickname == null) throw new ArgumentNullException("nickname", "Nickname cannot be null."); + Console.WriteLine("Changing nick to {0}\n", nickname); + curNickname = nickname; + /* NICK [ ] */ SendMessage(new IrcMessage(IRC.NICK, nickname)); } + /// + /// Ghost nickname. + /// + /// Nickname. + public void GhostNick(string nickname, + string password) + { + if (nickname == null) + throw new ArgumentNullException("nickname", "Nickname cannot be null."); + + if (password == null) + throw new ArgumentNullException("password", "Password cannot be null."); + + awaitingGhostDeath = true; + + /* GHOST */ + SendMessage(new IrcMessage(IRC.GHOST, nickname + " " + password)); + } + /// /// Submit password to identify user. /// @@ -619,6 +700,8 @@ namespace TechBot.IRCLibrary if (password == null) throw new ArgumentNullException("password", "Password cannot be null."); + this.password = password; + /* PASS */ SendMessage(new IrcMessage(IRC.PASS, password)); } @@ -635,12 +718,10 @@ namespace TechBot.IRCLibrary { if (nickname == null) throw new ArgumentNullException("nickname", "Nickname cannot be null."); + reqNickname = nickname; firstPingReceived = false; if (password != null) { - /* First ghost ourself and then register */ - if (nickname != null) - SendMessage(new IrcMessage(IRC.GHOST, nickname + " " + password)); SubmitPassword(password); } ChangeNick(nickname); diff --git a/irc/TechBot/TechBot.Library/TechBotIrcService.cs b/irc/TechBot/TechBot.Library/TechBotIrcService.cs index 238261cec5a..2a51374d330 100644 --- a/irc/TechBot/TechBot.Library/TechBotIrcService.cs +++ b/irc/TechBot/TechBot.Library/TechBotIrcService.cs @@ -88,7 +88,15 @@ namespace TechBot.Library 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) @@ -279,7 +287,7 @@ namespace TechBot.Library injectMessage, GetMessageSource(context))); InjectMessage(context, - injectMessage); + injectMessage); } else {