-1

Hello I am trying to create a chat bot for my twitch channel in Visual Basic. I did some research and I found this code:

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

and

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

But I can not succeed to connect using a password because it is simply to hard for me as a beginner. (You can either set a password or use the command /server irc.twitch.tv 6667 oauth:AUTHKEY) so my question is, is there a way to set the password in the code I posted? Or is there another stable way to use IRC in Visual Basic which allows me to set a server password? Let me know, thanks.

Jesse
  • 59
  • 8

1 Answers1

0

Your first stop should be the IRC RFC documents, RFC 1459 and 2812. From the snippet of code you provided, your IRC client does not implement the PASS message -- see section 4.1.1 of RFC 1459.

4.1.1 Password message

  Command: PASS    Parameters: <password>

The PASS command is used to set a 'connection password'. The
password can and must be set before any attempt to register the
connection is made. Currently this requires that clients send a PASS command before sending the NICK/USER combination and servers must
send a PASS command before any SERVER command. The password supplied must match the one contained in the C/N lines (for servers) or I
lines (for clients). It is possible to send multiple PASS commands
before registering but only the last one sent is used for
verification and it may not be changed once registered. Numeric
Replies:

       ERR_NEEDMOREPARAMS              ERR_ALREADYREGISTRED

Example:

       PASS secretpasswordhere

It should be relatively easy to implement:

        **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()

I'll take this opportunity to mention that I wrote an IRC library a while back that may help you, at least as a reference point for how IRC behaves. I implemented a decent portion of RFC 1459 before I lost interest. Interestingly enough, my IRC library doesn't support sending the PASS message either (although it would be similarly easy to add support).

My library could theoretically be of use to you as-is, but I don't think it's production ready, so to speak.

Community
  • 1
  • 1
Daniel Mann
  • 57,011
  • 13
  • 100
  • 120
  • Thanks for the answer. For some reason my PC is struggling to connect at all. The form just freezes. Im going to try and fix that first and let you know. – Jesse Apr 30 '15 at 02:59
  • The form freezes because you're using synchronous methods. Whenever it's trying to connect or send data, it's blocking the UI thread and hanging while it waits for the operation to complete. You can use the Task Async Pattern (async/await) to solve that issue. – Daniel Mann Apr 30 '15 at 03:11
  • Dear I am a beginner and I dont really know how I can use TAP – Jesse Apr 30 '15 at 12:02