/// <summary> /// Runs the <see cref="irc"/> listener in a safe loop /// </summary> void IRCListen() { while (irc != null && Connected()) { try { irc.Listen(); } catch { } } }
/// <summary> /// The main irc listen thread /// </summary> private void IrcListenThread() { try { _irc.Listen(); } catch (Exception ex) { Logger.Error(ex); } }
/// <summary> /// Runs the <see cref="irc"/> listener in a safe loop /// </summary> void IRCListen() { Thread.CurrentThread.Name = "IRC Listener Thread"; while (irc != null && Connected()) { try { irc.Listen(); } catch { } } }
/// <inheritdoc /> public override Task <bool> Connect(CancellationToken cancellationToken) => Task.Factory.StartNew(() => { disconnecting = false; lock (this) try { client.Connect(address, port); cancellationToken.ThrowIfCancellationRequested(); if (passwordType == IrcPasswordType.Server) { client.Login(nickname, nickname, 0, nickname, password); } else { if (passwordType == IrcPasswordType.Sasl) { client.WriteLine("CAP REQ :sasl", Priority.Critical); // needs to be put in the buffer before anything else cancellationToken.ThrowIfCancellationRequested(); } client.Login(nickname, nickname, 0, nickname); } if (passwordType == IrcPasswordType.NickServ) { cancellationToken.ThrowIfCancellationRequested(); client.SendMessage(SendType.Message, "NickServ", String.Format(CultureInfo.InvariantCulture, "IDENTIFY {0}", password)); } else if (passwordType == IrcPasswordType.Sasl) { // wait for the sasl ack or timeout var recievedAck = false; var recievedPlus = false; client.OnReadLine += (sender, e) => { if (e.Line.Contains("ACK :sasl", StringComparison.Ordinal)) { recievedAck = true; } else if (e.Line.Contains("AUTHENTICATE +", StringComparison.Ordinal)) { recievedPlus = true; } }; var startTime = DateTimeOffset.Now; var endTime = DateTimeOffset.Now.AddSeconds(TimeoutSeconds); cancellationToken.ThrowIfCancellationRequested(); var listenTimeSpan = TimeSpan.FromMilliseconds(10); for (; !recievedAck && DateTimeOffset.Now <= endTime; asyncDelayer.Delay(listenTimeSpan, cancellationToken).GetAwaiter().GetResult()) { client.Listen(false); } client.WriteLine("AUTHENTICATE PLAIN", Priority.Critical); cancellationToken.ThrowIfCancellationRequested(); for (; !recievedPlus && DateTimeOffset.Now <= endTime; asyncDelayer.Delay(listenTimeSpan, cancellationToken).GetAwaiter().GetResult()) { client.Listen(false); } // Stolen! https://github.com/znc/znc/blob/1e697580155d5a38f8b5a377f3b1d94aaa979539/modules/sasl.cpp#L196 var authString = String.Format(CultureInfo.InvariantCulture, "{0}{1}{0}{1}{2}", nickname, '\0', password); var b64 = Convert.ToBase64String(Encoding.UTF8.GetBytes(authString)); var authLine = String.Format(CultureInfo.InvariantCulture, "AUTHENTICATE {0}", b64); var chars = authLine.ToCharArray(); client.WriteLine(authLine, Priority.Critical); cancellationToken.ThrowIfCancellationRequested(); client.WriteLine("CAP END", Priority.Critical); } client.Listen(false); listenTask = Task.Factory.StartNew(() => { while (!disconnecting && client.IsConnected && client.Nickname != nickname) { client.ListenOnce(true); if (disconnecting || !client.IsConnected) { break; } client.Listen(false); // ensure we have the correct nick if (client.GetIrcUser(nickname) == null) { client.RfcNick(nickname); } } client.Listen(); }, cancellationToken, TaskCreationOptions.LongRunning, TaskScheduler.Current); } catch (OperationCanceledException) { throw; } catch (Exception e) { Logger.LogWarning("Unable to connect to IRC: {0}", e); return(false); } return(true); }, cancellationToken, TaskCreationOptions.LongRunning, TaskScheduler.Current);