Advertisement
mabu

IrcClient

Mar 8th, 2015
318
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
VB.NET 27.01 KB | None | 0 0
  1. Imports System.Collections.Generic
  2. Imports System.IO
  3. Imports System.Net.Sockets
  4. Imports System.Text
  5. Imports System.Text.RegularExpressions
  6. Imports System.Threading
  7.  
  8. Namespace SethiCorporation
  9.     NameSpace Irc
  10.        
  11.         Public Class ServerMessageEventArgs
  12.             Inherits EventArgs
  13.             Private m_Code As String
  14.             Private m_Text As String
  15.             Public Sub New(ByVal Code As String, ByVal MessageText As String)
  16.                 m_Code = Code
  17.                 m_Text = MessageText
  18.             End Sub
  19.            
  20.             Public ReadOnly Property Code()As String
  21.                 Get
  22.                     Return m_Code
  23.                 End Get
  24.             End Property
  25.            
  26.             Public ReadOnly Property MessageText()As String
  27.                 Get
  28.                     Return m_Text
  29.                 End Get
  30.             End Property
  31.            
  32.         End Class
  33.        
  34.         Public Class NoticeEventArgs
  35.             Inherits EventArgs
  36.             Private m_Channel As String
  37.             Private m_Text As String
  38.             Public Sub New(ByVal Channel As String, ByVal NoticeText As String)
  39.                 m_Channel = Channel
  40.                 m_Text = NoticeText
  41.             End Sub
  42.             Public ReadOnly Property Channel()As String
  43.                 Get
  44.                     Return m_Channel
  45.                 End Get
  46.             End Property
  47.             Public ReadOnly Property NoticeText()As String
  48.                 Get
  49.                     Return m_Text
  50.                 End Get
  51.             End Property
  52.         End Class
  53.        
  54.         Public Class ChannelMessageEventArgs
  55.             Inherits EventArgs
  56.             Private m_Channel As String
  57.             Private m_User As String
  58.             Private m_Text As String
  59.             Public Sub New(ByVal Channel As String, ByVal User As String, ByVal MessageText As String)
  60.                 m_Channel = Channel
  61.                 m_User = User
  62.                 m_Text = MessageText
  63.             End Sub
  64.            
  65.             Public ReadOnly Property Channel()As String
  66.                 Get
  67.                     Return m_Channel
  68.                 End Get
  69.             End Property
  70.            
  71.             Public ReadOnly Property UserName()As String
  72.                 Get
  73.                     Return m_User
  74.                 End Get
  75.             End Property
  76.            
  77.             Public ReadOnly Property MessageText()As String
  78.                 Get
  79.                     Return m_Text
  80.                 End Get
  81.             End Property
  82.         End Class
  83.        
  84.         Public Class PrivateMessageEventArgs
  85.             Inherits EventArgs
  86.             Private m_User As String
  87.             Private m_Text As String
  88.             Public Sub New(ByVal User As String, ByVal MessageText As String)
  89.                 m_User = User
  90.                 m_Text = MessageText
  91.             End Sub
  92.            
  93.             Public ReadOnly Property UserName()As String
  94.                 Get
  95.                     Return m_User
  96.                 End Get
  97.             End Property
  98.            
  99.             Public ReadOnly Property MessageText()As String
  100.                 Get
  101.                     Return m_Text
  102.                 End Get
  103.             End Property
  104.         End Class
  105.        
  106.         Public Class DisconnectedEventArgs
  107.             Inherits EventArgs
  108.             Private m_Text As String
  109.             Public Sub New(ByVal ErrorText As String)
  110.                 m_Text = ErrorText
  111.             End Sub
  112.             Public ReadOnly Property ErrorText()As String
  113.                 Get
  114.                     Return m_Text
  115.                 End Get
  116.             End Property
  117.         End Class
  118.        
  119.         Public Class UserJoinedEventArgs
  120.             Inherits EventArgs
  121.             Private m_Channel As String
  122.             Private m_User As String
  123.             Public Sub New(ByVal Channel As String, ByVal UserName As String)
  124.                 m_Channel = Channel
  125.                 m_User = UserName
  126.             End Sub
  127.             Public ReadOnly Property Channel()As String
  128.                 Get
  129.                     Return m_Channel
  130.                 End Get
  131.             End Property
  132.             Public ReadOnly Property UserName()As String
  133.                 Get
  134.                     Return m_User
  135.                 End Get
  136.             End Property
  137.         End Class
  138.        
  139.         Public Class NickChangedEventArgs
  140.             Inherits EventArgs
  141.             Private m_OldNick As String
  142.             Private m_NewNick As String
  143.             Public Sub New(ByVal OldNick As String, ByVal NewNick As String)
  144.                 m_OldNick = OldNick
  145.                 m_NewNick = NewNick
  146.             End Sub
  147.             Public ReadOnly Property OldNick()As String
  148.                 Get
  149.                     Return m_OldNick
  150.                 End Get
  151.             End Property
  152.             Public ReadOnly Property NewNick()As String
  153.                 Get
  154.                     Return m_NewNick
  155.                 End Get
  156.             End Property
  157.         End Class
  158.        
  159.         Public Class InviteEventArgs
  160.             Inherits EventArgs
  161.             Private m_User As String
  162.             Private m_Channel As String
  163.             Public Sub New(ByVal UserName As String, ByVal Channel As String)
  164.                 m_User = UserName
  165.                 m_Channel = Channel
  166.             End Sub
  167.             Public ReadOnly Property UserName()As String
  168.                 Get
  169.                     Return m_User
  170.                 End Get
  171.             End Property
  172.             Public ReadOnly Property Channel()As String
  173.                 Get
  174.                     Return m_Channel
  175.                 End Get
  176.             End Property
  177.         End Class
  178.        
  179.         Public Class KickEventArgs
  180.             Inherits EventArgs
  181.             Private m_Mod As String
  182.             Private m_Channel As String
  183.             Private m_User As String
  184.             Public Sub New(ByVal ModeratorName As String, ByVal Channel As String, ByVal UserName As String)
  185.                 m_Mod = ModeratorName
  186.                 m_Channel = Channel
  187.                 m_User = UserName
  188.             End Sub
  189.             Public ReadOnly Property UserName()As String
  190.                 Get
  191.                     Return m_User
  192.                 End Get
  193.             End Property
  194.             Public ReadOnly Property Channel()As String
  195.                 Get
  196.                     Return m_Channel
  197.                 End Get
  198.             End Property
  199.             Public ReadOnly Property ModeratorName()As String
  200.                 Get
  201.                     Return m_Mod
  202.                 End Get
  203.             End Property
  204.         End Class
  205.        
  206.         Public Class ModeEventArgs
  207.             Inherits EventArgs
  208.             Private m_Mod As String
  209.             Private m_Channel As String
  210.             Private m_Mode As String
  211.             Public Sub New(ByVal ModeratorName As String, ByVal Channel As String, ByVal Mode As String)
  212.                 m_Mod = ModeratorName
  213.                 m_Channel = Channel
  214.                 m_Mode = Mode
  215.             End Sub
  216.             Public ReadOnly Property Channel()As String
  217.                 Get
  218.                     Return m_Channel
  219.                 End Get
  220.             End Property
  221.             Public ReadOnly Property ModeratorName()As String
  222.                 Get
  223.                     Return m_Mod
  224.                 End Get
  225.             End Property
  226.             Public ReadOnly Property Mode()As String
  227.                 Get
  228.                     Return m_Mode
  229.                 End Get
  230.             End Property
  231.            
  232.         End Class
  233.        
  234.         Public Class PartChannelEventArgs
  235.             Inherits EventArgs
  236.             Private m_Channel As String
  237.             Private m_User As String
  238.             Private m_Text As String
  239.             Public Sub New(ByVal Channel As String, ByVal UserName As String, ByVal MessageText As String)
  240.                 m_Channel = Channel
  241.                 m_User = UserName
  242.                 m_Text = MessageText
  243.             End Sub
  244.             Public ReadOnly Property Channel()As String
  245.                 Get
  246.                     Return m_Channel
  247.                 End Get
  248.             End Property
  249.             Public ReadOnly Property UserName()As String
  250.                 Get
  251.                     Return m_User
  252.                 End Get
  253.             End Property
  254.             Public ReadOnly Property MessageText()As String
  255.                 Get
  256.                     Return m_Text
  257.                 End Get
  258.             End Property
  259.            
  260.         End Class
  261.        
  262.         Public Class QuitEventArgs
  263.             Inherits EventArgs
  264.             Private m_User As String
  265.             Private m_Text As String
  266.             Public Sub New(ByVal UserName As String, ByVal MessageText As String)
  267.                 m_User = UserName
  268.                 m_Text = MessageText
  269.             End Sub
  270.             Public ReadOnly Property UserName()As String
  271.                 Get
  272.                     Return m_User
  273.                 End Get
  274.             End Property
  275.             Public ReadOnly Property MessageText()As String
  276.                 Get
  277.                     Return m_Text
  278.                 End Get
  279.             End Property
  280.         End Class
  281.        
  282.         Public Class TopicEventArgs
  283.             Inherits EventArgs
  284.             Private m_Channel As String
  285.             Private m_User As String
  286.             Private m_Topic As String
  287.             Public Sub New(ByVal Channel As String, ByVal UserName As String, ByVal TopicText As String)
  288.                 m_User = UserName
  289.                 m_Channel = Channel
  290.                 m_Topic = TopicText
  291.             End Sub
  292.             Public ReadOnly Property Channel()As String
  293.                 Get
  294.                     Return m_Channel
  295.                 End Get
  296.             End Property
  297.             Public ReadOnly Property UserName()As String
  298.                 Get
  299.                     Return m_User
  300.                 End Get
  301.             End Property
  302.             Public ReadOnly Property TopicText()As String
  303.                 Get
  304.                     Return m_Topic
  305.                 End Get
  306.             End Property
  307.         End Class
  308.        
  309.         Public Class RawMessageEventArgs
  310.             Inherits EventArgs
  311.             Private m_Raw As String
  312.             Public Sub New(ByVal RawMessage As String)
  313.                 m_Raw = RawMessage
  314.             End Sub
  315.            
  316.             Public ReadOnly Property RawMessage()As String
  317.                 Get
  318.                     Return m_Raw
  319.                 End Get
  320.             End Property
  321.         End Class
  322.        
  323.         Public Class PingEventArgs
  324.             Inherits EventArgs
  325.             Private m_Server As String
  326.             Public Sub New(ByVal Server As String)
  327.                 m_Server = Server
  328.             End Sub
  329.             Public ReadOnly Property Server()As String
  330.                 Get
  331.                     Return m_Server
  332.                 End Get
  333.             End Property
  334.         End Class
  335.        
  336.         Public Class PongEventArgs
  337.             Inherits EventArgs
  338.             Private m_Server As String
  339.             Public Sub New(ByVal Server As String)
  340.                 m_Server = Server
  341.             End Sub
  342.             Public ReadOnly Property Server()As String
  343.                 Get
  344.                     Return m_Server
  345.                 End Get
  346.             End Property
  347.         End Class
  348.        
  349.         Public Class ErrorEventArgs
  350.             Inherits EventArgs
  351.             Private m_Text As String
  352.             Public Sub New(ByVal ErrorText As String)
  353.                 m_Text = ErrorText
  354.             End Sub
  355.             Public ReadOnly Property ErrorText()As String
  356.                 Get
  357.                     Return m_Text
  358.                 End Get
  359.             End Property
  360.         End Class
  361.        
  362.         Public Class IrcClient
  363.             Private m_Stream As NetworkStream
  364.             Private m_TcpIrcClient As TcpClient
  365.             Private m_Password As String
  366.             Private m_Nick As String
  367.             Private m_Server As String
  368.             Private m_Port As Integer
  369.             Private m_UserName As String
  370.             Private m_RealName As String
  371.             Private m_Connected As Boolean
  372.             Private m_Encoding As Text.Encoding
  373.             Private m_Invisible As Boolean
  374.             Private m_AutoPong As Boolean
  375.            
  376.         #Region "События"
  377.            
  378.             ''' <summary>
  379.             ''' Сообщение сервера
  380.             ''' </summary>
  381.             Public Event ServerMessage(ByVal sender As Object, ByVal e As ServerMessageEventArgs)
  382.            
  383.             ''' <summary>
  384.             ''' Уведомление
  385.             ''' </summary>
  386.             Public Event Notice(ByVal sender As Object, ByVal e As NoticeEventArgs)
  387.            
  388.             ''' <summary>
  389.             ''' Сообщение с канала
  390.             ''' </summary>
  391.             Public Event ChannelMessage(ByVal sender As Object, ByVal e As ChannelMessageEventArgs)
  392.            
  393.             ''' <summary>
  394.             ''' Личное сообщение
  395.             ''' </summary>
  396.             Public Event PrivateMessage(ByVal sender As Object, ByVal e As PrivateMessageEventArgs)
  397.            
  398.             ''' <summary>
  399.             ''' Принято сырое сообщение
  400.             ''' </summary>
  401.             Public Event ReceivedRawMessage(ByVal sender As Object, ByVal e As RawMessageEventArgs)
  402.            
  403.             ''' <summary>
  404.             ''' Отправлено сырое сообщение
  405.             ''' </summary>
  406.             Public Event SendedRawMessage(ByVal sender As Object, ByVal e As RawMessageEventArgs)
  407.            
  408.             ''' <summary>
  409.             ''' Отключение от сервера
  410.             ''' </summary>
  411.             Public Event Disconnected(ByVal sender As Object, ByVal e As DisconnectedEventArgs)
  412.            
  413.             Public Event Ping(ByVal sender As Object, ByVal e As PingEventArgs)
  414.             Public Event Pong(ByVal sender As Object, ByVal e As PongEventArgs)
  415.             Public Event IrcError(ByVal sender As Object, ByVal e As ErrorEventArgs)
  416.            
  417.             ''' <summary>
  418.             ''' Пользователь присоединился к каналу
  419.             ''' </summary>
  420.             ''' <remarks></remarks>
  421.             Public Event UserJoined(ByVal sender As Object, ByVal e As UserJoinedEventArgs)
  422.            
  423.             ''' <summary>
  424.             ''' Пользователь сменил ник
  425.             ''' </summary>
  426.             Public Event NickChanged(ByVal sender As Object, ByVal e As NickChangedEventArgs)
  427.            
  428.             ''' <summary>
  429.             ''' Приглашение пользователя на канал
  430.             ''' </summary>
  431.             Public Event Invite(ByVal sender As Object, ByVal e As InviteEventArgs)
  432.            
  433.             ''' <summary>
  434.             ''' Удар по пользователю
  435.             ''' </summary>
  436.             Public Event Kick(ByVal sender As Object, ByVal e As KickEventArgs)
  437.            
  438.             ''' <summary>
  439.             ''' Смена режима
  440.             ''' </summary>
  441.             Public Event Mode(ByVal sender As Object, ByVal e As ModeEventArgs)
  442.            
  443.             ''' <summary>
  444.             ''' Пользователь покидает канал
  445.             ''' </summary>
  446.             Public Event PartChannel(ByVal sender As Object, ByVal e As PartChannelEventArgs)
  447.            
  448.             ''' <summary>
  449.             ''' Пользователь покидает сервер
  450.             ''' </summary>
  451.             Public Event Quit(ByVal sender As Object, ByVal e As QuitEventArgs)
  452.            
  453.             ''' <summary>
  454.             ''' Смена темы
  455.             ''' </summary>
  456.             Public Event Topic(ByVal sender As Object, ByVal e As TopicEventArgs)
  457.            
  458.         #End Region
  459.            
  460.         #Region "Свойства"
  461.            
  462.             ''' <summary>
  463.             ''' Возвращает или задёт значение, позволяющее автоматически отвечать на пинг сервера
  464.             ''' </summary>
  465.             ''' <value></value>
  466.             ''' <returns></returns>
  467.             ''' <remarks>При отключении этого свойства отправку команд PONG необходимо производить самостоятельно, иначе сервер закроет соединение</remarks>
  468.             Public Property AutoPong() As Boolean
  469.                 Get
  470.                     Return m_AutoPong
  471.                 End Get
  472.                 Set(ByVal Value As Boolean)
  473.                     m_AutoPong = Value
  474.                 End Set
  475.             End Property
  476.            
  477.             ''' <summary>
  478.             ''' Кодировка для передачи сообщений. По умолчанию используется UTF-8
  479.             ''' </summary>
  480.             ''' <value></value>
  481.             ''' <returns></returns>
  482.             ''' <remarks></remarks>
  483.             Public Property Encoding() As Text.Encoding
  484.                 Get
  485.                     Return m_Encoding
  486.                 End Get
  487.                 Set(ByVal value As Text.Encoding)
  488.                     m_Encoding = value
  489.                 End Set
  490.             End Property
  491.            
  492.             ''' <summary>
  493.             ''' Ник бота
  494.             ''' </summary>
  495.             Public Property Nick() As String
  496.                 Get
  497.                     Return m_nick
  498.                 End Get
  499.                 Set(ByVal Value As String)
  500.                     m_nick = Value
  501.                     If m_Connected Then
  502.                         SendData("NICK " & m_Nick)
  503.                     End If
  504.                 End Set
  505.             End Property
  506.  
  507.             ''' <summary>
  508.             ''' Пароль подключения
  509.             ''' </summary>
  510.             Public Property Password() As String
  511.                 Get
  512.                     Return m_Password
  513.                 End Get
  514.                 Set(ByVal Value As String)
  515.                     m_Password = Value
  516.                 End Set
  517.             End Property
  518.  
  519.             ''' <summary>
  520.             ''' Проверка подключения к серверу
  521.             ''' </summary>
  522.             Public ReadOnly Property Connected() As Boolean
  523.                 Get
  524.                     Return m_Connected
  525.                 End Get
  526.             End Property
  527.            
  528.             ''' <summary>
  529.             ''' Невидимый режим
  530.             ''' </summary>
  531.             Public Property IsInvisible As Boolean
  532.                 Get
  533.                     Return m_Invisible
  534.                 End Get
  535.                 Set(ByVal Value As Boolean)
  536.                     m_Invisible = Value
  537.                 End Set
  538.             End Property
  539.        
  540.         #End Region
  541.            
  542.             Private Sub Initialize()
  543.                 m_AutoPong = True
  544.             End Sub
  545.            
  546.             Public Sub New()
  547.                 Initialize()
  548.             End Sub
  549.            
  550.             ''' <summary>
  551.             ''' Инициализация экземпляра класса Irc и подключение к серверу
  552.             ''' </summary>
  553.             ''' <param name="strServer">Адрес Irc-сервера</param>
  554.             ''' <param name="intPort">Порт Irc-сервера</param>
  555.             ''' <param name="strNick">Ник Irc-пользователя</param>
  556.             ''' <param name="strUserName">Имя пользователя</param>
  557.             ''' <param name="strRealName">Реальное имя пользователя</param>
  558.             ''' <param name="enc">Кодировка текста</param>
  559.             Public Sub New(ByVal strServer As String, ByVal intPort As Integer, ByVal strNick As String, ByVal strUserName As String, ByVal strRealName As String, ByVal enc As Text.Encoding)
  560.                 Initialize()
  561.                 m_Encoding = enc
  562.                 m_Server = strServer
  563.                 m_Port = intPort
  564.                 m_Nick = strNick
  565.                 m_UserName = strUserName
  566.                 m_RealName = strRealName
  567.                 Me.Open()
  568.             End Sub
  569.            
  570.             ''' <summary>
  571.             ''' Инициализация экземпляра класса Irc с кодировкой utf8 и подключение к серверу
  572.             ''' </summary>
  573.             ''' <param name="strServer">Адрес Irc-сервера</param>
  574.             ''' <param name="intPort">Порт Irc-сервера</param>
  575.             ''' <param name="strNick">Ник Irc-пользователя</param>
  576.             ''' <param name="strUserName">Имя пользователя</param>
  577.             Public Sub New(ByVal strServer As String, ByVal intPort As Integer, ByVal strNick As String, ByVal strUserName As String)
  578.                 Initialize()
  579.                 m_Encoding = Encoding.UTF8
  580.                 m_Server = strServer
  581.                 m_Port = intPort
  582.                 m_Nick = strNick
  583.                 m_UserName = strUserName
  584.                 Me.Open()
  585.             End Sub
  586.  
  587.             ''' <summary>
  588.             ''' Открывает соединение с сервером
  589.             ''' </summary>
  590.             Public Function Open()As Boolean
  591.                 ' данные регистрации
  592.                 Dim sb As StringBuilder = New StringBuilder
  593.                 ' пароль
  594.                 If Not String.IsNullOrEmpty(m_Password) Then
  595.                     sb.AppendLine("PASS " & m_Password)
  596.                 End If
  597.                 ' ник
  598.                 sb.AppendLine("NICK " & m_Nick)
  599.                
  600.                 ' Юзер-строка
  601.                 sb.AppendLine(String.Format("USER {0} {1} * :{2}", m_UserName, If(m_Invisible, "8", "0"), If(String.IsNullOrEmpty(m_RealName), m_Nick, m_RealName)))
  602.                 Dim bytes() As Byte = m_Encoding.GetBytes(sb.ToString())
  603.                 ' Новый интернет-клиент
  604.                 Try
  605.                     m_TcpIrcClient = New TcpClient(m_Server, m_Port)
  606.                     m_Stream = m_TcpIrcClient.GetStream()
  607.                     m_Stream.Write(bytes, 0, bytes.Length)
  608.                     ' Ставим флаг, что мы подключились к серверу
  609.                     m_Connected = True
  610.                     RaiseEvent SendedRawMessage(Me, New RawMessageEventArgs(sb.ToString()))
  611.                 Catch ex As Exception
  612.                     If m_Stream IsNot Nothing Then
  613.                         m_Stream.Close()
  614.                     End If
  615.                     If m_TcpIrcClient IsNot Nothing Then
  616.                         m_TcpIrcClient.Close()
  617.                     End If
  618.                 End Try
  619.                
  620.                 If m_Connected Then
  621.                     Dim st As New StateObject With {.NS = m_Stream, .sb = String.Empty}
  622.                     Redim st.buffer(1024 * 1024 - 1)
  623.                     m_Stream.BeginRead(st.buffer, 0, 1024 * 1024, AddressOf EndRead, st)
  624.                 End If
  625.                 Return m_Connected
  626.             End Function
  627.            
  628.             Private Sub EndRead(ByVal ar As IAsyncResult)
  629.                 Dim st As StateObject = CType(ar.AsyncState, StateObject)
  630.                 Dim intBytesCount As Integer
  631.                 Try
  632.                     intBytesCount = st.NS.EndRead(ar)
  633.                 Catch ex As Exception
  634.                     ' закрыть соединение
  635.                     m_Connected = False
  636.                     If m_Stream IsNot Nothing Then
  637.                         m_Stream.Close()
  638.                     End If
  639.                     If m_TcpIrcClient IsNot Nothing Then
  640.                         m_TcpIrcClient.Close()
  641.                     End If
  642.                     RaiseEvent Disconnected(Me, New DisconnectedEventArgs(ex.Message))
  643.                 End Try
  644.                
  645.                 If m_Connected Then
  646.                     Dim st1 As New StateObject With {.NS = m_Stream}
  647.                     Redim st1.buffer(StateObject.BytesCount - 1)
  648.                     ' Теперь получить строку из байт
  649.                     Dim strRet As String = m_Encoding.GetString(st.buffer, 0, intBytesCount)
  650.                    
  651.                     ' Разбить строку построчно
  652.                     Dim strLines() As String = Regex.Split(strRet, "\r\n")'strRet.Split(vbCrLf)
  653.                     If st.sb.Length > 0 Then
  654.                         strLines(0) = st.sb & strLines(0)
  655.                     End If
  656.                    
  657.                     ' Проверить последний элемент в массиве
  658.                     If strLines(strLines.Length - 1).Length = 0 Then
  659.                         st1.sb = String.Empty
  660.                     Else
  661.                         st1.sb = strLines(strLines.Length - 1)
  662.                     End If
  663.                     ' Проходим массив строк за вычетом последнего элемента
  664.                     For i As Integer = 0 To strLines.Length - 2
  665.                         RaiseEvent ReceivedRawMessage(Me, New RawMessageEventArgs(strLines(i)))
  666.                         ParseData(strLines(i))
  667.                     Next
  668.                    
  669.                     Try
  670.                         m_Stream.BeginRead(st1.buffer, 0, StateObject.BytesCount, AddressOf EndRead, st1)
  671.                     Catch ex As Exception
  672.                         ' закрыть соединение
  673.                         m_Connected = False
  674.                         If m_Stream IsNot Nothing Then
  675.                             m_Stream.Close()
  676.                         End If
  677.                         If m_TcpIrcClient IsNot Nothing Then
  678.                             m_TcpIrcClient.Close()
  679.                         End If
  680.                         RaiseEvent Disconnected(Me, New DisconnectedEventArgs(ex.Message))
  681.                     End Try
  682.                 End If
  683.             End Sub
  684.            
  685.             ''' <summary>
  686.             ''' Закрыть соединение
  687.             ''' </summary>
  688.             Public Sub [Close](ByVal strDisconnectText As String)
  689.                 If m_Connected Then
  690.                     Dim strMessage As String
  691.                     If String.IsNullOrEmpty(strDisconnectText) Then
  692.                         strMessage = "QUIT"
  693.                     Else
  694.                         strMessage = "QUIT :" & strDisconnectText
  695.                     End If
  696.                     SendData(strMessage)
  697.                     m_Connected = False
  698.                     RaiseEvent Disconnected(Me, New DisconnectedEventArgs(strDisconnectText))
  699.                 End If
  700.                 If m_Stream IsNot Nothing Then
  701.                     m_Stream.Close()
  702.                 End If
  703.                 If m_TcpIrcClient IsNot Nothing Then
  704.                     m_TcpIrcClient.Close()
  705.                 End If
  706.             End Sub
  707.  
  708.         #Region "Функции отправки команд на сервер"
  709.            
  710.             ''' <summary>
  711.             ''' Отправить низкоуровневое сообщение серверу
  712.             ''' </summary>
  713.             ''' <param name="strMessage">Сообщение</param>
  714.             Public Sub SendRawMessage(ByVal strMessage As String)
  715.                 REM For Each strLine As String In From s In Regex.Split(strMessage, "\r\n") Where s.Length > 0
  716.                     SendData(strMessage)
  717.                 REM Next
  718.             End Sub
  719.  
  720.             ''' <summary>
  721.             ''' Отправка NOTICE пользователю
  722.             ''' </summary>
  723.             ''' <param name="strNick">Ник пользователя, кому отправляется NOTICE</param>
  724.             ''' <param name="strText">Текст сообщения для отправки</param>
  725.             Public Sub SendNotice(ByVal strNick As String, ByVal strText As String)
  726.                 SendData(String.Format("NOTICE {0} :{1}", strNick, strText))
  727.             End Sub
  728.  
  729.             ''' <summary>
  730.             ''' Отправка сообщения в канал
  731.             ''' </summary>
  732.             ''' <param name="strChannel">Канал или имя пользователя</param>
  733.             ''' <param name="strText">Текст сообщения</param>
  734.             Public Sub SendMessage(ByVal strChannel As String, ByVal strText As String)
  735.                 SendData(String.Format("PRIVMSG {0} :{1}", strChannel, strText))
  736.             End Sub
  737.  
  738.             ''' <summary>
  739.             ''' Присоединение к каналу
  740.             ''' </summary>
  741.             ''' <param name="strChannel">Канал для присоединения</param>
  742.             Public Sub JoinChannel(ByVal strChannel As String)
  743.                 SendData("JOIN " & strChannel)
  744.             End Sub
  745.            
  746.             ''' <summary>
  747.             ''' Отсоединение от канала
  748.             ''' </summary>
  749.             ''' <param name="strChannel">Канал для присоединения</param>
  750.             ''' <param name="strExitText">Прощальный текст</param>
  751.             Public Sub LeaveChannel(ByVal strChannel As String, strExitText As String)
  752.                 If String.IsNullOrEmpty(strExitText) Then
  753.                     SendData("PART " & strChannel)
  754.                 Else
  755.                     SendData(String.Format("PART {0} :{1}", strChannel, strExitText))
  756.                 End If
  757.             End Sub
  758.  
  759.         #End Region
  760.            
  761.             ' Разбор данных от сервера
  762.             Private Sub ParseData(ByVal data As String)
  763.                 Const Space As String = " "
  764.                 Dim ircData0 As String = data.Substring(0, data.IndexOf(Space))
  765.                 Select Case ircData0
  766.                     ' Если сообщение начинается с PING, мы должны отправить PONG
  767.                     Case "PING"
  768.                         Dim strServer As String = data.Substring(6)
  769.                         If m_AutoPong Then
  770.                             SendData("PONG " & strServer)
  771.                         End If
  772.                         RaiseEvent Ping(Me, New PingEventArgs(strServer))
  773.                     Case "PONG"
  774.                         ' Получен ответ от сервера
  775.                         RaiseEvent Pong(Me, New PongEventArgs(data.Substring(6)))
  776.                     Case "ERROR"
  777.                         RaiseEvent IrcError(Me, New ErrorEventArgs(data.Substring(6)))
  778.                     Case Else
  779.                         ' Разделить данные по пробелам
  780.                         Dim ircData() As String = data.Split()
  781.                         ' Определяем команду
  782.                         If ircData.Length > 1 Then
  783.                             ' Текст сообщения
  784.                             Dim lMessageText = Function() data.Substring(Math.Max(data.IndexOf(":", 2) + 1, 0))
  785.                             ' Имя пользователя
  786.                             Dim lUserName = Function() ircData0.Substring(1, Math.Max(ircData0.IndexOf("!") - 1, 0))
  787.                             Select Case ircData(1)
  788.                                 Case "INVITE"
  789.                                     If ircData.Length > 3 Then
  790.                                         RaiseEvent Invite(Me, New InviteEventArgs(lUserName(), ircData(3)))
  791.                                     End If
  792.                                 Case "JOIN"
  793.                                     If ircData.Length > 2 Then
  794.                                         RaiseEvent UserJoined(Me, New UserJoinedEventArgs(ircData(2), lUserName()))
  795.                                     End If
  796.                                 Case "KICK"
  797.                                     If ircData.Length > 3 Then
  798.                                         RaiseEvent Kick(Me, New KickEventArgs(lUserName(), ircData(2), ircData(3)))
  799.                                     End If
  800.                                 Case "MODE"
  801.                                     ' TODO Нужно что-то сделать с ircData(4)
  802.                                     If ircData.Length > 3 Then
  803.                                         RaiseEvent Mode(Me, New ModeEventArgs(lUserName(), ircData(2), ircData(3)))
  804.                                     End If
  805.                                 Case "NICK"
  806.                                     RaiseEvent NickChanged(Me, New NickChangedEventArgs(lUserName(), ircData(2)))
  807.                                 Case "NOTICE"
  808.                                     If ircData.Length > 2 Then
  809.                                         If ircData(2) = m_Nick Then
  810.                                             RaiseEvent Notice(Me, New NoticeEventArgs(lUserName(), lMessageText()))
  811.                                         Else
  812.                                             RaiseEvent ServerMessage(Me, New ServerMessageEventArgs(lUserName(), lMessageText()))
  813.                                         End If
  814.                                     End If
  815.                                 Case "PRIVMSG"
  816.                                     If ircData.Length > 2 Then
  817.                                         If ircData(2) = m_Nick Then
  818.                                             RaiseEvent PrivateMessage(Me, New PrivateMessageEventArgs(lUserName(), lMessageText()))
  819.                                         Else
  820.                                             RaiseEvent ChannelMessage(Me, New ChannelMessageEventArgs(ircData(2), lUserName(), lMessageText()))
  821.                                         End If
  822.                                     End If
  823.                                 Case "PART"
  824.                                     If ircData.Length > 2 Then
  825.                                         RaiseEvent PartChannel(Me, New PartChannelEventArgs(ircData(2), lUserName(), lMessageText()))
  826.                                     End If
  827.                                 Case "QUIT"
  828.                                     RaiseEvent Quit(Me, New QuitEventArgs(lUserName(), lMessageText()))
  829.                                 Case "TOPIC"
  830.                                     If ircData.Length > 2 Then
  831.                                         RaiseEvent Topic(Me, New TopicEventArgs(ircData(2), lUserName(), lMessageText()))
  832.                                     End If
  833.                                 Case Else
  834.                                     RaiseEvent ServerMessage(Me, New ServerMessageEventArgs(ircData(1), data.Substring(data.IndexOf(Space))))
  835.                             End Select
  836.                         End If
  837.                 End Select
  838.             End Sub
  839.            
  840.             ' Отправка данных на сервер
  841.             Private Sub SendData(ByVal strMessage As String)
  842.                 If m_Connected Then
  843.                     Dim lNewStr = Function() New StringBuilder(strMessage).AppendLine.ToString()
  844.                     Dim st As New StateObject With {.buffer = m_Encoding.GetBytes(lNewStr()), _
  845.                                                     .NS = m_Stream, _
  846.                                                     .sb = strMessage}
  847.                     Try
  848.                         m_Stream.BeginWrite(st.buffer, 0, st.buffer.Length, AddressOf EndWrite, st)
  849.                     Catch ex As Exception
  850.                         ' закрыть соединение
  851.                         m_Connected = False
  852.                         If m_Stream IsNot Nothing Then
  853.                             m_Stream.Close()
  854.                         End If
  855.                         If m_TcpIrcClient IsNot Nothing Then
  856.                             m_TcpIrcClient.Close()
  857.                         End If
  858.                         RaiseEvent Disconnected(Me, New DisconnectedEventArgs(ex.Message))
  859.                     End Try
  860.                 End If
  861.             End Sub
  862.            
  863.             Private Sub EndWrite(ByVal ar As IAsyncResult)
  864.                 Dim st As StateObject = CType(ar.AsyncState, StateObject)
  865.                 Try
  866.                     st.NS.EndWrite(ar)
  867.                 Catch ex As Exception
  868.                     ' закрыть соединение
  869.                     m_Connected = False
  870.                     If m_Stream IsNot Nothing Then
  871.                         m_Stream.Close()
  872.                     End If
  873.                     If m_TcpIrcClient IsNot Nothing Then
  874.                         m_TcpIrcClient.Close()
  875.                     End If
  876.                     RaiseEvent Disconnected(Me, New DisconnectedEventArgs(ex.Message))
  877.                 End Try
  878.                 If m_Connected Then
  879.                     RaiseEvent SendedRawMessage(Me, New RawMessageEventArgs(st.sb))
  880.                 End If
  881.             End Sub
  882.            
  883.             Private Class StateObject
  884.                 ' Сетевой поток
  885.                 Public NS As NetworkStream
  886.                 ' Буфер приёма данных
  887.                 Public buffer() As Byte
  888.                 ' Строка для отправки
  889.                 Public sb As String
  890.                 ' Размер буфера в один килобайт
  891.                 Public Const BytesCount As Integer = 512
  892.             End Class
  893.         End Class
  894.     End Namespace
  895. End NameSpace
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement