0

我想让 IRC 机器人自动以用户身份加入 IRC 频道(在网络聊天中),然后让机器人保持在线以禁止发送垃圾邮件的用户

我需要什么开始做这个?哪些知识?也许一些API?套接字的使用?

有人可以给我看一个例子或介绍我吗?

我找到了这段代码,我试图检查里面的所有东西以试图理解,但是当我尝试连接到服务器时它没有连接,它不会抛出任何异常,只是用户没有加入房间:

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

Public Class Form1

    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

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Dim a As New My_IRC("irc.freenode.org", "#ircehn", "Elektro_bot", 6667, False)
    End Sub

End Class
4

1 回答 1

1

不要使用低级 TCP 通信,而是看一下这个IRC 库。它使使用托管 .NET 代码编写 IRC 软件变得更加容易,包括渠道和用户操作。

于 2013-06-17T20:31:52.200 回答