Visual Basic中的IRC客户端

时间:2015-04-30 01:38:31

标签: vb.net irc

您好我正在尝试在Visual Basic中为我的抽搐频道创建一个聊天机器人。我做了一些研究,我发现了这段代码:

Public Class My_IRC
    Private _sServer As String = String.Empty '-- IRC server name
    Private _sChannel As String = String.Empty '-- the channel you want to join (prefex with #)
    Private _sNickName As String = String.Empty '-- the nick name you want show up in the side bar
    Private _lPort As Int32 = 6667 '-- the port to connect to.  Default is 6667
    Private _bInvisible As Boolean = False '-- shows up as an invisible user.  Still working on this.
    Private _sRealName As String = "nodibot" '-- More naming
    Private _sUserName As String = "nodi_the_bot" '-- Unique name so of the IRC network has a unique handle to you regardless of the nickname.

    Private _tcpclientConnection As TcpClient = Nothing '-- main connection to the IRC network.
    Private _networkStream As NetworkStream = Nothing '-- break that connection down to a network stream.
    Private _streamWriter As StreamWriter = Nothing '-- provide a convenient access to writing commands.
    Private _streamReader As StreamReader = Nothing '-- provide a convenient access to reading commands.

    Public Sub New(ByVal server As String, ByVal channel As String, ByVal nickname As String, ByVal port As Int32, ByVal invisible As Boolean)
        _sServer = server
        _sChannel = channel
        _sNickName = nickname
        _lPort = port
        _bInvisible = invisible
    End Sub

    Public Sub Connect()

        '-- IDENT explained: 
        '-- -- When connecting to the IRC server they will send a response to your 113 port.  
        '-- -- It wants your user name and a response code back.  If you don't some servers 
        '-- -- won't let you in or will boot you.  Once verified it drastically speeds up 
        '-- -- the connecting time.
        '-- -- -- http://en.wikipedia.org/wiki/Ident
        '-- Heads up - when sending a command you need to flush the writer each time.  That's key.

        Dim sIsInvisible As String = String.Empty
        Dim sCommand As String = String.Empty '-- commands to process from the room.

        '-- objects used for the IDENT response.
        Dim identListener As TcpListener = Nothing
        Dim identClient As TcpClient = Nothing
        Dim identNetworkStream As NetworkStream = Nothing
        Dim identStreamReader As StreamReader = Nothing
        Dim identStreamWriter As StreamWriter = Nothing
        Dim identResponseString As String = String.Empty

        Try
            '-- Start the main connection to the IRC server.
            Console.WriteLine("**Creating Connection**")
            _tcpclientConnection = New TcpClient(_sServer, _lPort)
            _networkStream = _tcpclientConnection.GetStream
            _streamReader = New StreamReader(_networkStream)
            _streamWriter = New StreamWriter(_networkStream)

            '-- Yeah, questionable if this works all the time.
            If _bInvisible Then
                sIsInvisible = 8
            Else
                sIsInvisible = 0
            End If

            '-- Send in your information
            Console.WriteLine("**Setting up name**")
            _streamWriter.WriteLine(String.Format("USER {0} {1} * :{2}", _sUserName, sIsInvisible, _sRealName))
            _streamWriter.Flush()

            '-- Create your nickname.
            Console.WriteLine("**Setting Nickname**")
            _streamWriter.WriteLine(String.Format(String.Format("NICK {0}", _sNickName)))
            _streamWriter.Flush()

            '-- Tell the server you want to connect to a specific room.
            Console.WriteLine("**Joining Room**")
            _streamWriter.WriteLine(String.Format("JOIN {0}", _sChannel))
            _streamWriter.Flush()

            '-- By now the IDENT should be sent to your port 113.  Listen to it, grab the text, 
            '-- and send a response.
            '-- Idents are usually #### , ####
            '-- That is four digits, a space, a comma, and four more digits.  You need to send 
            '-- this back with your user name you connected with and your system.
            identListener = New TcpListener(IPAddress.Any, 113)
            identListener.Start()
            identClient = identListener.AcceptTcpClient
            identListener.Stop()
            Console.WriteLine("ident connection?")
            identNetworkStream = identClient.GetStream
            identStreamReader = New StreamReader(identNetworkStream)

            identResponseString = identStreamReader.ReadLine
            Console.WriteLine("ident got: " + identResponseString)
            identStreamWriter = New StreamWriter(identNetworkStream)
            '-- The general format for the IDENT response.  You can use UNIX, WINDOWS VISTA, WINDOWS XP, or what ever your system is.
            identStreamWriter.WriteLine(String.Format("{0} : USERID : WINDOWS 7 : {1}", identResponseString, _sUserName))
            identStreamWriter.Flush()

            '-- By now you should be connected to your room and visible to anyone else.  
            '-- If you are receiving errors they are pretty explicit and you can maneuver 
            '-- to debuggin them.
            '-- 
            '-- What happens here is the command processing.  In an infinite loop the bot 
            '-- read in commands and act on them.
            While True
                sCommand = _streamReader.ReadLine
                Console.WriteLine(sCommand)

                '-- Not the best method but for the time being it works.  
                '-- 
                '-- Example of a command it picks up
                ' :nodi123!nodi12312@ipxxx-xx.net PRIVMSG #nodi123_test :? hola!
                '-- You can extend the program to better read the lines!
                Dim sCommandParts(sCommand.Split(" ").Length) As String
                sCommandParts = sCommand.Split(" ")

                '-- Occasionally the IRC server will ping the app.  If it doesn't respond in an 
                '-- appropriate amount of time the connection is closed.
                '-- How does one respond to a ping, but with a pong! (and the hash it sends)
                If sCommandParts(0) = "PING" Then
                    Dim sPing As String = String.Empty
                    For i As Int32 = 1 To sCommandParts.Length - 1
                        sPing += sCommandParts(i) + " "
                    Next
                    _streamWriter.WriteLine("PONG " + sPing)
                    _streamWriter.Flush()
                    Console.WriteLine("PONG " + sPing)
                End If

                '-- With my jank split command we want to look for specific commands sent and react to them!
                '-- In theory this should be dumped to a method, but for this small tutorial you can see them here.
                '-- Also any user can input this.  If you want to respond to commands from you only you would 
                '-- have to extend the program to look for your non-bot-id in the sCommandParts(0)
                If sCommandParts.Length >= 4 Then
                    '-- If a statement is proceeded by a question mark (the semi colon's there automatically) 
                    '-- then repeat the rest of the string!
                    If sCommandParts(3).StartsWith(":?") Then
                        Dim sVal As String = String.Empty
                        Dim sOut As String = String.Empty
                        '-- the text might have other spaces in them so concatenate the rest of the parts 
                        '-- because it's all text.
                        For i As Int32 = 3 To sCommandParts.Length - 1
                            sVal += sCommandParts(i)
                            sVal += " "
                        Next
                        '-- remove the :? part.
                        sVal = sVal.Substring(2, sVal.Length - 2)
                        '-- Trim for good measure.
                        sVal = sVal.Trim
                        '-- Send the text back out.  The format is they command to send the text and the room you are in.
                        sOut = String.Format("PRIVMSG {0} : You said '{1}'", _sChannel, sVal)
                        _streamWriter.WriteLine(sOut)
                        _streamWriter.Flush()
                    End If
                    '-- If you don't quit the bot correctly the connection will be active until a ping/pong is failed.  
                    '-- Even if your programming isn't running!
                    '-- To stop that here's a command to have the bot quit!
                    If sCommandParts(3).Contains(":!Q") Then
                        ' Stop
                        _streamWriter.WriteLine("QUIT")
                        _streamWriter.Flush()
                        Exit Sub
                    End If
                End If
            End While

        Catch ex As Exception
            '-- Any exception quits the bot gracefully.
            Console.WriteLine("Error in Connecting.  " + ex.Message)
            _streamWriter.WriteLine("QUIT")
            _streamWriter.Flush()
        Finally
            '-- close your connections
            _streamReader.Dispose()
            _streamWriter.Dispose()
            _networkStream.Dispose()
        End Try

    End Sub
    End Class

Imports System
Imports System.Net
Imports System.Net.Sockets
Imports System.IO

    Public Sub Main()

        Dim foo As New My_IRC("irc.freenode.net", "#nodi123_test", "nodime", 6667, False)
        foo.Connect()

    End Sub

但是我无法使用密码成功连接,因为对于初学者来说,这对我来说很难。 (您可以设置密码或使用命令/server irc.twitch.tv 6667 oauth:AUTHKEY)所以我的问题是,有没有办法在我发布的代码中设置密码?或者是否有另一种在Visual Basic中使用IRC的稳定方法,它允许我设置服务器密码?让我知道,谢谢。

1 个答案:

答案 0 :(得分:0)

您的第一站应该是IRC RFC文档,RFC 14592812。从您提供的代码片段中,您的IRC客户端未实现PASS消息 - 请参阅RFC 1459的4.1.1节。

  

4.1.1密码信息

  Command: PASS    Parameters: <password>
     

PASS命令用于设置连接密码&#39;。该
  在尝试注册之前,可以且必须设置密码   连接。目前,这要求客户发送通行证   发送NICK / USER组合之前的命令和服务器必须
  在任何SERVER命令之前发送PASS命令。提供的密码   必须匹配C / N行(服务器)或I
中包含的那个   线(对于客户)。可以发送多个PASS命令   在注册之前,只有最后一个发送用于
  验证,一旦注册,可能不会更改。数字
  回复:

       ERR_NEEDMOREPARAMS              ERR_ALREADYREGISTRED
     

示例:

       PASS secretpasswordhere

实施起来应该相对容易:

        **Console.WriteLine("**Setting Password**")
        _streamWriter.WriteLine(String.Format(String.Format("PASS {0}", whateverVariableYouChooseToHoldThePassword)))
        _streamWriter.Flush()**

        '-- Send in your information
        Console.WriteLine("**Setting up name**")
        _streamWriter.WriteLine(String.Format("USER {0} {1} * :{2}", _sUserName, sIsInvisible, _sRealName))
        _streamWriter.Flush()

我借此机会提到我写了IRC library一段时间可以帮助你,至少作为IRC行为的参考点。在失去兴趣之前,我实施了RFC 1459的相当一部分。有趣的是,我的IRC库也不支持发送PASS消息(尽管添加支持也同样容易)。

我的图书馆理论上可以对你有用,但我不认为它的制作准备就绪,可以这么说。