IRC-клиент в Visual Basic
Здравствуйте! Я пытаюсь создать чат-бота для своего канала с твиками в 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
) так что мой вопрос, есть ли способ установить пароль в коде, который я разместил? Или есть другой стабильный способ использовать IRC в Visual Basic, который позволяет мне установить пароль сервера? Дайте мне знать, спасибо.
1 ответ
Ваша первая остановка должна быть документами IRC RFC, RFC 1459 и 2812. Из предоставленного вами фрагмента кода IRC-клиент не реализует PASS
сообщение - см. раздел 4.1.1 RFC 1459.
4.1.1. Пароль
Command: PASS Parameters: <password>
Команда PASS используется для установки "пароля подключения".
пароль может и должен быть установлен перед любой попыткой регистрации
соединение установлено. В настоящее время это требует, чтобы клиенты отправляли команду PASS перед отправкой комбинации NICK/USER, а серверы должны
отправить команду PASS перед любой командой SERVER. Предоставленный пароль должен совпадать с паролем, содержащимся в строках 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, которая может вам помочь, по крайней мере, в качестве ориентира для поведения IRC. Я реализовал приличную часть RFC 1459, прежде чем потерял интерес. Интересно, что моя библиотека IRC не поддерживает отправку PASS
сообщение либо (хотя было бы так же легко добавить поддержку).
Моя библиотека теоретически может быть полезна вам как есть, но я не думаю, что она готова к производству, так сказать.