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
{