Imports Globals
Imports Globals.GlobalResources
Imports System.Security.Cryptography
Imports System.IO
Imports System.Text
Imports System.Net.NetworkInformation
Public Class Main
Private WithEvents ConsoleUpdateTimer As New Timer
Private Sub Main_ClientSizeChanged(sender As Object, e As EventArgs) Handles Me.ClientSizeChanged
For Each ctrl As Control In Output.Controls
ctrl.MaximumSize = New Size(Output.Width - 24, 9999)
Next
If Output.Controls.Count > 0 Then _
Output.ScrollControlIntoView(Output.Controls(Output.Controls.Count - 1))
End Sub
Private Sub Main_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
CloseAllResources()
End Sub
Private Sub Main_Load(sender As Object, e As EventArgs) Handles MyBase.Load
SharedResources.Add(New Resource("Main"))
SharedResources(0).Resources.Add(New ResourceElement("Received Messages", "RecvMsgs", New List(Of String))) \'0,0
SharedResources(0).Resources.Add(New ResourceElement("To Send Messages", "SndMsgs", New List(Of String))) \'0,1
SharedResources(0).Resources.Add(New ResourceElement("Plugins", "Plugins", New List(Of Plgn))) \'0,2
SharedResources(0).Resources.Add(New ResourceElement("Plugin Manager", "PlgnMngr", New PluginManager)) \'0,3
SharedResources(0).Resources.Add(New ResourceElement("IRC Client", "IRCclient", New Client)) \'0,4
SharedResources(0).Resources.Add(New ResourceElement("Configuration", "ConfigLocation", New String(My.Application.Info.DirectoryPath & "\\config.ini"))) \'0,5
SharedResources(0).Resources.Add(New ResourceElement("Console Messages", "Output", New List(Of String))) \'0,6
SharedResources(0).Resources.Add(New ResourceElement("GlobalChan", "Chan", "")) \'0,7
If System.IO.File.Exists(SharedResources(0).Resources(5).Value.ToString) Then
Dim ConfigReader As New StreamReader(SharedResources(0).Resources(5).Value.ToString)
While ConfigReader.Peek <> -1
Dim line As String = ConfigReader.ReadLine.Trim
If line.StartsWith("Owner:") Then
OwnerTxt.Text = line.Remove(0, 6).Trim
ElseIf line.StartsWith("OAuth:") Then
PassTxt.Text = Encryption.decryptString(line.Remove(0, 6).Trim)
ElseIf line.StartsWith("Nick:") Then
NickTxt.Text = line.Remove(0, 5).Trim
ElseIf line.StartsWith("Channel:") Then
ChannelTxt.Text = line.Remove(0, 8).Trim
ElseIf line.StartsWith("Server:") Then
ServerTxt.Text = line.Remove(0, 7).Trim
ElseIf line.StartsWith("Port:") Then
PortTxt.Text = line.Remove(0, 5).Trim
ElseIf line.StartsWith("JMsg:") Then
JoinMsgTxt.Text = line.Remove(0, 5).Trim
End If
End While
ConfigReader.Close()
ConfigReader.Dispose()
End If
ConsoleUpdateTimer.Interval = 1
UpdatePluginsList()
End Sub
Public Sub UpdatePluginsList()
SyncLock SharedResources(0).Resources(2).Value
For Each plgn As Plgn In SharedResources(0).Resources(2).Value
Me.PlgnList.Items.Add(plgn.Name)
Next
End SyncLock
End Sub
Private Sub ConnectBtn_Click(sender As Object, e As EventArgs) Handles ConnectBtn.Click
If sender.Text = "Connect" Then
sender.Enabled = False
Dim ready As Boolean = True
If IsNumeric(PortTxt.Text) = False OrElse _
CInt(PortTxt.Text) < 0 OrElse _
CInt(PortTxt.Text) > 65535 Then
PortTxt.BackColor = Color.Red
ready = False
sender.Enabled = True
Output.Focus()
End If
For Each ctrl As Control In SetupArea.Controls
If ctrl.GetType() Is GetType(TextBox) Then
If ctrl.Text = String.Empty And Not ctrl.Name = "JoinMsgTxt" Then
ctrl.BackColor = Color.Red
ready = False
sender.Enabled = True
Output.Focus()
End If
End If
Next
If ready Then
For Each ctrl As Control In SetupArea.Controls
If ctrl.GetType() Is GetType(TextBox) Then ctrl.Enabled = False
Next
If Not ChannelTxt.Text.StartsWith("#") Then ChannelTxt.Text = "#" & ChannelTxt.Text
If StartConnectionClient(ServerTxt.Text, PortTxt.Text, NickTxt.Text, ChannelTxt.Text, PassTxt.Text, JoinMsgTxt.Text) Then
SetCurrentChan(ChannelTxt.Text)
SaveInfo()
SendTxt.Text = String.Empty
SendTxt.Enabled = True
ConsoleUpdateTimer.Start()
StartPluginManager(OwnerTxt.Text, ServerTxt.Text, NickTxt.Text)
sender.Text = "Disconnect"
sender.Enabled = True
Output.Focus()
Else
MessageBox.Show("Connection could not be established with current settings", "Check your settings", MessageBoxButtons.OK, MessageBoxIcon.Information)
CloseAllResources()
End If
End If
Else
CloseAllResources()
End If
End Sub
Private Sub SaveInfo()
Dim Saver As New StreamWriter(SharedResources(0).Resources(5).Value.ToString, False)
Saver.WriteLine("Owner:" & OwnerTxt.Text.Trim.ToLower)
Saver.WriteLine("OAuth:" & Encryption.encryptString(PassTxt.Text.Trim))
Saver.WriteLine("Nick:" & NickTxt.Text.Trim.ToLower)
Saver.WriteLine("Channel:" & ChannelTxt.Text.Trim.ToLower)
Saver.WriteLine("Server:" & ServerTxt.Text.Trim)
Saver.WriteLine("Port:" & PortTxt.Text.Trim)
Saver.WriteLine("JMsg:" & JoinMsgTxt.Text.Trim)
Saver.Close()
Saver.Dispose()
End Sub
Private Sub CloseAllResources()
On Error Resume Next
StopPluginManager()
StopConnectionClient()
ConsoleUpdateTimer.Stop()
For Each ctrl As Control In SetupArea.Controls
If ctrl.GetType() Is GetType(TextBox) Then ctrl.Enabled = Enabled
Next
SendTxt.Text = " Send: <Connect first>"
SendTxt.Enabled = False
ConnectBtn.Text = "Connect"
ConnectBtn.Enabled = True
System.GC.Collect()
End Sub
Private Sub ConsoleUpdateTimer_Tick(sender As Object, e As EventArgs) Handles ConsoleUpdateTimer.Tick
Dim CrntConsole As String = GetConsoleMsg()
If Not CrntConsole = String.Empty Then
Output.Controls.Add(New AutoLabel(CrntConsole))
Output.Controls.Add(New AutoLabel(" "))
End If
End Sub
Private Sub SendTxt_KeyDown(sender As Object, e As KeyEventArgs) Handles SendTxt.KeyDown
If e.KeyCode = Keys.Return Then
If Not sender.text.trim = "" Then
AddToSend("PRIVMSG " & ChannelTxt.Text & " :" & SendTxt.Text.Trim)
End If
e.SuppressKeyPress = True
SendTxt.Text = String.Empty
End If
End Sub
Private Sub JoinMsgTxt_TextChanged(sender As TextBox, e As EventArgs) Handles JoinMsgTxt.TextChanged
If JoinMsgTxt.Text.Contains(vbCrLf) Then
sender.Text = sender.Text.Replace(vbCrLf, " ")
sender.Select(sender.Text.Length, 0)
End If
End Sub
Private Sub OwnerTxt_TextChanged(sender As TextBox, e As EventArgs) Handles _
OwnerTxt.TextChanged, _
PassTxt.TextChanged, _
NickTxt.TextChanged, _
ChannelTxt.TextChanged, _
ServerTxt.TextChanged, _
PortTxt.TextChanged
If sender.BackColor = Color.Red Then sender.BackColor = Color.White
End Sub
Private Sub Output_ControlAdded(sender As Object, e As ControlEventArgs) Handles Output.ControlAdded
Output.ScrollControlIntoView(e.Control)
While Output.Controls.Count > 100
Output.Controls.RemoveAt(0)
End While
End Sub
Private Sub Output_ControlRemoved(sender As Object, e As ControlEventArgs) Handles Output.ControlRemoved
Output.ScrollControlIntoView(Output.Controls(Output.Controls.Count - 1))
End Sub
Private Sub PlgnList_DrawItem(sender As Object, e As DrawItemEventArgs) Handles PlgnList.DrawItem
e.DrawBackground()
If (e.State And DrawItemState.Selected) = DrawItemState.Selected Then
e.Graphics.FillRectangle(Brushes.White, e.Bounds)
End If
Using b As New SolidBrush(Color.Black)
e.Graphics.DrawString(PlgnList.GetItemText(PlgnList.Items(e.Index)), e.Font, b, e.Bounds)
End Using
e.DrawFocusRectangle()
End Sub
Private Sub PlgnList_MouseDoubleClick(sender As Object, e As MouseEventArgs) Handles PlgnList.MouseDoubleClick
On Error Resume Next
SyncLock SharedResources(0).Resources(2).Value
SharedResources(0).Resources(2).Value(PlgnList.SelectedIndex).config()
End SyncLock
End Sub
Private Sub LinkLabel1_LinkClicked(sender As Object, e As LinkLabelLinkClickedEventArgs) Handles LinkLabel1.LinkClicked
Process.Start("http://www.twitchapps.com/tmi/")
End Sub
Private Sub Output_MouseClick(sender As Object, e As MouseEventArgs) Handles Output.MouseClick
sender.focus()
End Sub
End Class
Module Encryption
Private key As String = NetworkInterface.GetAllNetworkInterfaces(0).GetPhysicalAddress.ToString
Public Function encryptString(ByVal strtext As String) As String
Return Encrypt(strtext, key)
End Function
Public Function decryptString(ByVal strtext As String) As String
Return Decrypt(strtext, key)
End Function
Private Function Encrypt(ByVal strText As String, ByVal strEncrKey As String) As String
Dim byKey() As Byte = {}
Dim IV() As Byte = {&H12, &H34, &H56, &H78, &H90, &HAB, &HCD, &HEF}
Try
byKey = System.Text.Encoding.UTF8.GetBytes(Left(strEncrKey, 8))
Dim des As New DESCryptoServiceProvider()
Dim inputByteArray() As Byte = Encoding.UTF8.GetBytes(strText)
Dim ms As New MemoryStream()
Dim cs As New CryptoStream(ms, des.CreateEncryptor(byKey, IV), CryptoStreamMode.Write)
cs.Write(inputByteArray, 0, inputByteArray.Length)
cs.FlushFinalBlock()
Return Convert.ToBase64String(ms.ToArray())
Catch ex As Exception
Return ex.Message
End Try
End Function
Private Function Decrypt(ByVal strText As String, ByVal sDecrKey As String) As String
Dim byKey() As Byte = {}
Dim IV() As Byte = {&H12, &H34, &H56, &H78, &H90, &HAB, &HCD, &HEF}
Dim inputByteArray(strText.Length) As Byte
Try
byKey = System.Text.Encoding.UTF8.GetBytes(Left(sDecrKey, 8))
Dim des As New DESCryptoServiceProvider()
inputByteArray = Convert.FromBase64String(strText)
Dim ms As New MemoryStream()
Dim cs As New CryptoStream(ms, des.CreateDecryptor(byKey, IV), CryptoStreamMode.Write)
cs.Write(inputByteArray, 0, inputByteArray.Length)
cs.FlushFinalBlock()
Dim encoding As System.Text.Encoding = System.Text.Encoding.UTF8
Return encoding.GetString(ms.ToArray())
Catch ex As Exception
Return ex.Message
End Try
End Function
End Module
Imports System.Net.Sockets
Imports System.Text
Imports System.Net
Imports Globals.GlobalResources
Public Class Client
Private _Server, _Port, _Nick, _Channel, _Pass, _Jmsg As String
Private ClientThread As Threading.Thread
Private EP As IPEndPoint
Private Connection As Socket
Private WithEvents SendingTimer As Timer
Public Function StartConnection(ByVal Server As String, ByVal Port As String, ByVal Nick As String, ByVal Channel As String, ByVal Pass As String, ByVal JoinMsg As String) As Boolean
_Server = Server
_Port = Port
_Nick = Nick.Trim.ToLower
_Channel = Channel
_Pass = Pass
_Jmsg = JoinMsg
Try
EP = New IPEndPoint(Dns.GetHostEntry(_Server).AddressList(0), _Port)
Connection = New Socket(EP.Address.AddressFamily, Net.Sockets.SocketType.Stream, Net.Sockets.ProtocolType.Tcp)
Connection.Connect(_Server, _Port)
Send("PASS " & _Pass, False) : Send("NICK " & _Nick) : Send("JOIN " & _Channel)
Send("PRIVMSG " & _Channel & " :" & _Jmsg)
Catch ex As Exception
Return False
End Try
ClientThread = New Threading.Thread(AddressOf Connect)
ClientThread.Start()
SendingTimer = New Timer
SendingTimer.Interval = 1500
SendingTimer.Start()
Return True
End Function
Public Function ConnectionStatus() As Boolean
Try
SyncLock Connection
Return Connection.Connected
End SyncLock
Catch ex As Exception
Return False
End Try
End Function
Public Sub Close()
On Error Resume Next
SyncLock Connection
Connection.Disconnect(False)
Connection.Close()
End SyncLock
End Sub
Private Sub Connect()
Dim link As Boolean = True
Do While link
recv()
SyncLock Connection
link = Connection.Connected
End SyncLock
Loop
MsgBox("Disconnected") \'add actual disconnect handling
End Sub
Public Sub Send(ByVal msg As String, Optional ByVal show As Boolean = True)
msg = msg.Trim
Dim data() As Byte = ASCIIEncoding.ASCII.GetBytes(msg & vbCrLf)
SyncLock Connection
Connection.Send(data, data.Length, SocketFlags.None)
End SyncLock
If show Then AddToConsole(msg)
End Sub
Private Sub recv()
On Error Resume Next
Dim data(511) As Byte
Connection.Receive(data, 512, SocketFlags.None)
Dim mail As String = System.Text.ASCIIEncoding.ASCII.GetString(data)
mail = mail.TrimEnd(Chr(0)).Remove(mail.LastIndexOf(vbLf), 1).Remove(mail.LastIndexOf(vbCr), 1)
AddToConsole(mail.Trim)
If mail.StartsWith("PING") Then
Dim pserv As String = mail.Substring(mail.IndexOf(" "), mail.Length - mail.IndexOf(" ")).TrimEnd(Chr(0))
Send("PONG" & pserv)
End If
AddToRecv(mail.Trim)
End Sub
Private Sub SendingTimer_Tick(sender As Object, e As EventArgs) Handles SendingTimer.Tick
Dim meh As String = GetToSend()
If Not meh = String.Empty Then Send(meh)
End Sub
End Class
Imports Globals
Imports Globals.GlobalResources
Imports System.Reflection
Public Class PluginManager
Private Running As Boolean = False
Private workingthread As Threading.Thread
Private _Owner, _Server, _BotNick, _Chan, Crnt As String
Public Sub New()
SyncLock SharedResources(0).Resources(2).Value
PluginLoader.LoadPlugins(Of Plgn)(SharedResources(0).Resources(2).Value, My.Application.Info.DirectoryPath & "\\Plugins\\", "Globals.Plgn")
End SyncLock
End Sub
Public Sub Start(ByVal Owner As String, ByVal Server As String, ByVal BotNick As String)
_Owner = Owner : _Server = Server : _BotNick = BotNick
Running = True
workingthread = New Threading.Thread(AddressOf work)
workingthread.Start()
End Sub
Public Sub Close()
Running = False
End Sub
Public Sub work()
While Running
Crnt = GetRecvMsg()
If Crnt IsNot String.Empty Then
Dim ProcdMsg As Message
ProcdMsg = New Message(Crnt, _Owner, _Server, _BotNick)
HandleMessage(ProcdMsg)
End If
Threading.Thread.Sleep(1)
End While
End Sub
Public Sub HandleMessage(ByRef inputMsg As Message)
SyncLock SharedResources(0).Resources(2).Value
For Each plugin As Globals.Plgn In SharedResources(0).Resources(2).Value
If plugin.ProcessMessage(inputMsg) Then Exit For
Next
End SyncLock
End Sub
End Class
Module PluginLoader
Public Sub LoadPlugins(Of PlugType)(ByRef PluginList As ICollection(Of PlugType), ByRef LocationOfPlugins As String, ByVal InterfaceName As String)
PluginList.Clear()
Dim Plugin_DLLs As System.Collections.ObjectModel.ReadOnlyCollection(Of String) = FileIO.FileSystem.GetFiles(LocationOfPlugins, FileIO.SearchOption.SearchTopLevelOnly, "*.dll")
Dim assemblyObj As Reflection.Assembly
Dim aDescAttr As AssemblyDescriptionAttribute
Dim aTitleAttr As AssemblyTitleAttribute
For Each PluginDLL As String In Plugin_DLLs
assemblyObj = Reflection.Assembly.LoadFrom(PluginDLL)
For Each t As Type In assemblyObj.GetTypes
If t.IsPublic Then
For Each ThisParticularType As Type In t.GetInterfaces
Try
If ThisParticularType.FullName = InterfaceName Then
PluginList.Add(CType(assemblyObj.CreateInstance(t.FullName, True), PlugType))
aDescAttr = CType(AssemblyDescriptionAttribute.GetCustomAttribute(assemblyObj, GetType(AssemblyDescriptionAttribute)), AssemblyDescriptionAttribute)
aTitleAttr = CType(AssemblyTitleAttribute.GetCustomAttribute(assemblyObj, GetType(AssemblyTitleAttribute)), AssemblyTitleAttribute)
End If
Catch e As Exception
End Try
Next
End If
Next
Next
End Sub
End Module