예제 #1
0
        internal async Task Connect(IConnectionFactory connectionFactory, IIrcIdentity identity)
        {
            lock (this)
            {
                State state = _state;
                if (state == State.Connected)
                    throw new InvalidOperationException("Already connected");
                else if (state == State.Connecting)
                    throw new InvalidOperationException("Already connecting");

                _state = State.Connecting;
            }

            ClearAll();
            _logger.Debug("Initializing connection");
            _stream = await connectionFactory.Connect(_hostname, _port, _useSsl);

            if (_stream == null)
                throw new IrcException(Resources.ConnectionIsNull);
            _logger.Debug("Connected to server");

            var encoding = new UTF8Encoding(false);
            _reader = new StreamReader(_stream, encoding);
            _writer = new StreamWriter(_stream, encoding);
            _writer.NewLine = CRLF;

            StartOutboundThread();
            if (_password != null)
                await SendCommand("PASS", _password);

            await SendCommand("NICK", identity.Nick);
            await SendCommand("USER", identity.Login, "8", "*", VERSION.AsMultiParameter());
            _nick = identity.Nick;
            _login = identity.Login;

            //OnRawMessageIn(await _reader.ReadLineAsync());
            //await Task.Delay(TimeSpan.FromSeconds(10));

            // Read stuff back from the server to see if we connected.
            string line;
            int tries = 0;
            Command cmd = default(Command);

            while ((line = await _reader.ReadLineAsync()) != null)
            {
                OnRawMessageIn(line);
                cmd = ParseCmd(line);
                switch (cmd._command)
                {
                    //Check for both a successful connection. Inital connection (001-4), user stats (251-5), or MOTD (375-6)
                    case "001":
                    case "002":
                    case "003":
                    case "004":
                    case "005":
                    case "251":
                    case "252":
                    case "253":
                    case "254":
                    case "255":
                    case "375":
                    case "376":
                        goto end;

                    case "433":
                        var tmpNick = identity.Nick + (++tries);
                        await SendCommand("NICK", tmpNick);
                        _nick = tmpNick;
                        break;

                    case "439":
                        //EXAMPLE: PircBotX: Target change too fast. Please wait 104 seconds
                        // No action required.
                        break;

                    default:
                        if (cmd._command.StartsWith("5") || cmd._command.EndsWith("4"))
                        {
                            _stream.Dispose();
                            throw new IrcException(String.Format(Resources.CouldNotConnect, cmd));
                        }
                        break;
                }
            }

            _stream.Dispose();
            throw new IrcException(String.Format(Resources.CouldNotConnect, cmd));

        end:
            _logger.Debug("Logged in");

            lock (this)
                _state = State.Connected;

            if (cmd._parameters != null)
                await HandleCmd(cmd);

            StartInboundThread();

        }
예제 #2
0
        internal async Task Connect(IConnectionFactory connectionFactory, IIrcIdentity identity)
        {
            lock (this)
            {
                State state = _state;
                if (state == State.Connected)
                {
                    throw new InvalidOperationException("Already connected");
                }
                else if (state == State.Connecting)
                {
                    throw new InvalidOperationException("Already connecting");
                }

                _state = State.Connecting;
            }

            ClearAll();
            _logger.Debug("Initializing connection");
            _stream = await connectionFactory.Connect(_hostname, _port, _useSsl);

            if (_stream == null)
            {
                throw new IrcException(Resources.ConnectionIsNull);
            }
            _logger.Debug("Connected to server");

            var encoding = new UTF8Encoding(false);

            _reader         = new StreamReader(_stream.InputStream, encoding);
            _writer         = new StreamWriter(_stream.OutputStream, encoding);
            _writer.NewLine = CRLF;

            StartOutboundThread();
            if (_password != null)
            {
                await SendCommand("PASS", _password);
            }

            await SendCommand("NICK", identity.Nick);
            await SendCommand("USER", identity.Login, "8", "*", VERSION.AsMultiParameter());

            _nick  = identity.Nick;
            _login = identity.Login;

            //OnRawMessageIn(await _reader.ReadLineAsync());
            //await Task.Delay(TimeSpan.FromSeconds(10));

            // Read stuff back from the server to see if we connected.
            string  line;
            int     tries = 0;
            Command cmd   = default(Command);

            while ((line = await _reader.ReadLineAsync()) != null)
            {
                OnRawMessageIn(line);
                cmd = ParseCmd(line);
                switch (cmd._command)
                {
                //Check for both a successful connection. Inital connection (001-4), user stats (251-5), or MOTD (375-6)
                case "001":
                case "002":
                case "003":
                case "004":
                case "005":
                case "251":
                case "252":
                case "253":
                case "254":
                case "255":
                case "375":
                case "376":
                    goto end;

                case "433":
                    var tmpNick = identity.Nick + (++tries);
                    await SendCommand("NICK", tmpNick);

                    _nick = tmpNick;
                    break;

                case "439":
                    //EXAMPLE: PircBotX: Target change too fast. Please wait 104 seconds
                    // No action required.
                    break;

                default:
                    if (cmd._command.StartsWith("5") || cmd._command.EndsWith("4"))
                    {
                        _stream.Dispose();
                        throw new IrcException(String.Format(Resources.CouldNotConnect, cmd));
                    }
                    break;
                }
            }

            _stream.Dispose();
            throw new IrcException(String.Format(Resources.CouldNotConnect, cmd));

end:
            _logger.Debug("Logged in");

            lock (this)
                _state = State.Connected;

            if (cmd._parameters != null)
            {
                await HandleCmd(cmd);
            }

            StartInboundThread();
        }