Valhalla Legends Forums Archive | Battle.net Bot Development | VB6 Developers Bot v1.0

AuthorMessageTime
FrOzeN
I originally started writing this (4 days) trying to learn how to utilize the Winsock API. Though, I've decided I'm going to turn it into a full bot similar to LoRd[nK]'s [u]BBBB[/u] (Basic Battle.net Binary Bot). Starting off, I tried something simply so at the moment it only supports logging on as a CHAT client.

The downsides I currently see with the coding is having two imagelists (eww) which I'm soon going to replace to a dymanic imagelist with just the necessary images for a Chat Client and do the rest via reading .bni files.

The only actual bug in the bot that I'm aware of is when you unsquelch a user it sets there product to Unknown as the flag update doesn't return there previous product value. I'll fix this up later when I get around making a temporary database in the bot which will store information for all the users in the channel.

As for the winsock, the [u]tutorials[/u] didn't get as far as determining when events are received so for temporary use I've put in a timer which checks if data has arrived every 300 milliseconds. I'm currently going through the CSocket Class and determining what API calls are necessary to do this, so I can Register the Socket and use WindowProc to capture it's events and handle them correctly. Also because of this there may be a numerous amount of winsock errors occur due to lack of handling. So before connecting just check you don't have a chat client already logged on and that you have an active internet connection.

Being the very early stages of development I'm trying to make the code as proficient as possible and welcome all feedback for coding improvements / suggestions to do.

You can download the source [u]here[/u]. ;)

Credits to [u]vbip.com[/u] for the Winsock API tutorials, Grok for the [u]AddChat[/u] and Arta for the [u]Flag Specification[/u].
Also credits to Stealth as you'll notice some of the events such as JoinChannel display the same message in the RichTextBox. I like the way it's been setup in StealthBot. :)

[EDIT] Also, I'm going to document all the subs probably by next version. By adding full comments explaining what each sub does, it's purpose and how the code works.
January 30, 2006, 6:45 AM
MyStiCaL

  Sounds good. i thought you were writting a C++ bot or somthing..
Did that project discontinue?
January 30, 2006, 8:08 AM
FrOzeN
Sidetracked from learning C++ atm. Though, this will probably make understanding Winsock in C++ alot easier for me. :)
January 30, 2006, 8:09 AM
JoeTheOdd
Downloaded, I'll take a look when I get home.
January 30, 2006, 1:15 PM
UserLoser
[quote author=FrOzeN link=topic=14056.msg143780#msg143780 date=1138608594]
Sidetracked from learning C++ atm. Though, this will probably make understanding Winsock in C++ alot easier for me. :)
[/quote]

How is learning it "in C++" any different from learning it in Visual Basic?
January 30, 2006, 9:09 PM
rabbit
VB6 is more englishy.  For someone unfamiliar with C++, it is definately easier to read.
January 30, 2006, 9:47 PM
JoeTheOdd
[quote author=UserLoser link=topic=14056.msg143800#msg143800 date=1138655376]
[quote author=FrOzeN link=topic=14056.msg143780#msg143780 date=1138608594]
Sidetracked from learning C++ atm. Though, this will probably make understanding Winsock in C++ alot easier for me. :)
[/quote]

How is learning it "in C++" any different from learning it in Visual Basic?
[/quote]

IIRC, the C++ version of Winsock (CSocket) is not event oriented, and makes recieving stuff rather hard (infinite loop, breaking out, etc), not to mention checking if you're still connected.
January 30, 2006, 10:04 PM
l2k-Shadow
I put together this code long time ago. It is the simplest form of implementing Winsock API into VB. Should help you:
[code]
'Winsock Implementation Example for VB6
'Code taken from public resources and stripped down/edited by l2k-Shadow

Option Base 0
Option Explicit
Option Compare Text

Private Const AF_INET = &H2
Private Const FD_READ = &H1
Private Const FD_WRITE = &H2
Private Const FD_CONNECT = &H10
Private Const FD_CLOSE = &H20
Private Const PF_INET = &H2
Private Const SOCK_STREAM = &H1
Private Const IPPROTO_TCP = &H6
Private Const GWL_WNDPROC = (-4)
Private Const WINSOCKMSG = &H401
Private Const sockaddr_size = &H10
Private Type WSADataType
    wVersion As Integer
    wHighVersion As Integer
    szDescription As String * 256
    szSystemStatus As String * 128
    iMaxSockets As Integer
    iMaxUdpDg As Integer
    lpVendorInfo As Long
End Type
Private Type HostEnt
    h_name As Long
    h_aliases As Long
    h_addrtype As Integer
    h_length As Integer
    h_addr_list As Long
End Type
Private Type sockaddr
    sin_family As Integer
    sin_port As Integer
    sin_addr As Long
    sin_zero As String * 8
End Type
Private Declare Function SetWindowLongA Lib "user32" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Private Declare Function CallWindowProcA Lib "user32" (ByVal lpPrevWndFunc As Long, ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Private Declare Function sSend Lib "ws2_32" Alias "send" (ByVal s As Long, buf As Any, ByVal BufLen As Long, ByVal Flags As Long) As Long
Private Declare Function recv Lib "ws2_32" (ByVal s As Long, buf As Any, ByVal BufLen As Long, ByVal Flags As Long) As Long
Private Declare Function WSAStartup Lib "ws2_32" (ByVal wVR As Long, lpWSAD As WSADataType) As Long
Private Declare Function socket Lib "ws2_32" (ByVal af As Long, ByVal s_type As Long, ByVal protocol As Long) As Long
Private Declare Function ConnectSock Lib "ws2_32" Alias "connect" (ByVal s As Long, addr As sockaddr, ByVal namelen As Long) As Long
Private Declare Function WSAAsyncSelect Lib "ws2_32" (ByVal s As Long, ByVal hWnd As Long, ByVal wMsg As Long, ByVal lEvent As Long) As Long
Private Declare Function WSACleanup Lib "ws2_32" () As Long
Private Declare Function htons Lib "ws2_32" (ByVal hostshort As Long) As Integer
Private Declare Function inet_addr Lib "ws2_32" (ByVal addr As String) As Long
Private Declare Function gethostbyname Lib "ws2_32" (ByVal host_name As String) As Long
Private Declare Function CloseSock Lib "ws2_32" Alias "closesocket" (ByVal s As Long) As Long
Private saZero As sockaddr
Private PrevProc As Long

Public Sub HookWindow(ByVal hWnd As Long)
'You must hook the window to which the socket belongs so Windows would know where to send the socket events
    Dim StartupData As WSADataType
    PrevProc = SetWindowLongA(hWnd, GWL_WNDPROC, AddressOf WndProc)
    WSAStartup &H101, StartupData
End Sub

Public Sub UnHookWindow(ByVal hWnd As Long)
'UnHook after you are done using the winsock
    If PrevProc <> 0 Then
        WSACleanup
        SetWindowLongA hWnd, GWL_WNDPROC, PrevProc
        PrevProc = 0
    End If
End Sub

Private Function WndProc(ByVal hWnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
'The Callback function
    If uMsg = WINSOCKMSG Then
        Select Case lParam
            Case FD_CONNECT
                'Ignore this event, use FD_WRITE
            Case FD_WRITE
                'Call WS_CONNECTED()
            Case FD_READ
                Dim Length As Long, Data As String, ReadBuffer(1023) As Byte
                Length = recv(wParam, ReadBuffer(0), 1023, 0)
                Data = Left$(StrConv(ReadBuffer, vbUnicode), Length)
                'Call WS_DATAARRIVAL(DATA)
            Case FD_CLOSE
                'Call WS_CLOSE()
            Case Else
                'Call WS_ERROR()
        End Select
    Else
        WndProc = CallWindowProcA(PrevProc, hWnd, uMsg, wParam, lParam)
    End If
End Function

Public Sub SendData(ByVal SocketID As Long, ByVal vMessage As Variant)
'Equivalent to WS.SendData()
'The SocketID returned by the ConnectSocket() function
    Dim TheMsg() As Byte
    TheMsg = StrConv(vMessage, vbFromUnicode)
    sSend SocketID, TheMsg(0), UBound(TheMsg) + 1, 0
End Sub

Public Sub CloseSocket(ByRef SocketID As Long)
'Equivalent to WS.Close
'Automatically sets your SocketID to 0
    CloseSock SocketID
    SocketID = 0
End Sub

Public Function ConnectSocket(ByVal Host As String, ByVal Port As Long) As Long
'Equivalent to WS.Connect(Host, Port)
'Connect socket function
'Returns your Socket ID
    Dim s As Long, sockin As sockaddr
    sockin = saZero
    sockin.sin_family = AF_INET
    sockin.sin_port = htons(Port)
    sockin.sin_addr = inet_addr(GetIPAddress(Host))
    s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)
    WSAAsyncSelect s, frmMain.hWnd, WINSOCKMSG, &H33
    ConnectSock s, sockin, sockaddr_size
    ConnectSocket = s
End Function

Private Function GetIPAddress(ByVal Host As String) As String
Dim hAddr As Long, hEnt As HostEnt, IPBytes(3) As Byte
    hAddr = gethostbyname(Host)
    CopyMemory hEnt, ByVal hAddr, 16
    CopyMemory hAddr, ByVal hEnt.h_addr_list, 4
    CopyMemory IPBytes(0), ByVal hAddr, 4
    GetIPAddress = IPBytes(0) & "." & IPBytes(1) & "." & IPBytes(2) & "." & IPBytes(3)
End Function
[/code]
January 30, 2006, 11:40 PM
UserLoser
[quote author=Joe link=topic=14056.msg143806#msg143806 date=1138658662]
[quote author=UserLoser link=topic=14056.msg143800#msg143800 date=1138655376]
[quote author=FrOzeN link=topic=14056.msg143780#msg143780 date=1138608594]
Sidetracked from learning C++ atm. Though, this will probably make understanding Winsock in C++ alot easier for me. :)
[/quote]

How is learning it "in C++" any different from learning it in Visual Basic?
[/quote]

IIRC, the C++ version of Winsock (CSocket) is not event oriented, and makes recieving stuff rather hard (infinite loop, breaking out, etc), not to mention checking if you're still connected.
[/quote]

wtf is CSocket
January 31, 2006, 12:11 AM
LoRd
[quote author=UserLoser link=topic=14056.msg143826#msg143826 date=1138666315]
[quote author=Joe link=topic=14056.msg143806#msg143806 date=1138658662]
[quote author=UserLoser link=topic=14056.msg143800#msg143800 date=1138655376]
[quote author=FrOzeN link=topic=14056.msg143780#msg143780 date=1138608594]
Sidetracked from learning C++ atm. Though, this will probably make understanding Winsock in C++ alot easier for me. :)
[/quote]

How is learning it "in C++" any different from learning it in Visual Basic?
[/quote]

IIRC, the C++ version of Winsock (CSocket) is not event oriented, and makes recieving stuff rather hard (infinite loop, breaking out, etc), not to mention checking if you're still connected.
[/quote]

wtf is CSocket
[/quote]

It's a Visual Basic socket (IIRC, asynchronous) class which directly utilizes the Winsock API.  It's just another way to complicate things giving it's users the illusion that it's going to drastically increase performance.

Edit: Click
January 31, 2006, 12:15 AM
Myndfyr
[quote author=Lord[nK] link=topic=14056.msg143827#msg143827 date=1138666556]
It's a Visual Basic socket (IIRC, asynchronous) class which directly utilizes the Winsock API.  It's just another way to complicate things giving it's users the illusion that it's going to drastically increase performance.

Edit: Click
[/quote]

In context to the discussion (since C++ was what was brought up), CSocket is the Microsoft Foundation Classes (MFC) implementation of a high-level, blocking I/O object around the Winsock API.  CSocket allows interaction with CArchive for quick serialization over the network, or CSocketFile as an implementation of a file stream over a socket (much like how NetworkStream functions in .NET).

CAsyncSocket is the parent class to CSocket and implements nonblocking asynchronous calls not suitable for use with CArchive.
January 31, 2006, 12:35 AM
FrOzeN
[quote author=Joe link=topic=14056.msg143806#msg143806 date=1138658662]
[quote author=UserLoser link=topic=14056.msg143800#msg143800 date=1138655376]
[quote author=FrOzeN link=topic=14056.msg143780#msg143780 date=1138608594]
Sidetracked from learning C++ atm. Though, this will probably make understanding Winsock in C++ alot easier for me. :)
[/quote]

How is learning it "in C++" any different from learning it in Visual Basic?
[/quote]

IIRC, the C++ version of Winsock (CSocket) is not event oriented, and makes recieving stuff rather hard (infinite loop, breaking out, etc), not to mention checking if you're still connected.
[/quote]
Erm, at the moment that's kind of way I have it setup. It has a timer checking every 300 milliseconds if it's connected, then if data has arrived and if so it calls the appropriate event. (In a way the timer is acting as what a loop statement would...)

---
I'll hopefully have v1.1 within the next 2 weeks, probably sooner.

Also thanks for that code l2k-Shadow, that helps alot. I've done Subclassing/Hooking with the Keyboard and Mouse before so I can understand that perfectly as is. :)
January 31, 2006, 5:07 AM
JoeTheOdd
[quote]It has a timer checking every 300 milliseconds if it's connected[/quote]

Use the gift given to you through Winsock_Close =p
January 31, 2006, 10:32 PM
Myndfyr
[quote author=FrOzeN link=topic=14056.msg143863#msg143863 date=1138684034]
It has a timer checking every 300 milliseconds if it's connected[/quote]
You'll never know if it's disconnected if you never send data.  That's why many protocols have things like SID_NULL (keepalive packets) to ensure that a connection doesn't just last forever.
January 31, 2006, 10:40 PM
Yegg
[quote author=MyndFyre link=topic=14056.msg143978#msg143978 date=1138747201]
[quote author=FrOzeN link=topic=14056.msg143863#msg143863 date=1138684034]
It has a timer checking every 300 milliseconds if it's connected[/quote]
You'll never know if it's disconnected if you never send data.  That's why many protocols have things like SID_NULL (keepalive packets) to ensure that a connection doesn't just last forever.
[/quote]

Just out of curiosity, can sending Battle.net the SID_NULL packet, lets say every 15 seconds, be at all dangerous?
January 31, 2006, 10:42 PM
Myndfyr
[quote author=Yegg link=topic=14056.msg143979#msg143979 date=1138747340]
[quote author=MyndFyre link=topic=14056.msg143978#msg143978 date=1138747201]
[quote author=FrOzeN link=topic=14056.msg143863#msg143863 date=1138684034]
It has a timer checking every 300 milliseconds if it's connected[/quote]
You'll never know if it's disconnected if you never send data.  That's why many protocols have things like SID_NULL (keepalive packets) to ensure that a connection doesn't just last forever.
[/quote]

Just out of curiosity, can sending Battle.net the SID_NULL packet, lets say every 15 seconds, be at all dangerous?
[/quote]

Not generally, but IIRC it does count against you on the flood meter.
January 31, 2006, 10:44 PM
Kp
[quote author=MyndFyre link=topic=14056.msg143978#msg143978 date=1138747201]
[quote author=FrOzeN link=topic=14056.msg143863#msg143863 date=1138684034]
It has a timer checking every 300 milliseconds if it's connected[/quote]
You'll never know if it's disconnected if you never send data.  That's why many protocols have things like SID_NULL (keepalive packets) to ensure that a connection doesn't just last forever.
[/quote]

Not entirely true.  If you've enabled the TCP_KEEPALIVE option on the socket, you never need to (explicitly) send data.  The protocol stack will do it for you.  That said, it's not particularly aggressive about doing so, so I wouldn't rely on that behavior for anything more pruning connections on a low traffic network.
February 1, 2006, 12:40 AM
FrOzeN
[quote author=Joe link=topic=14056.msg143972#msg143972 date=1138746721]
[quote]It has a timer checking every 300 milliseconds if it's connected[/quote]

Use the gift given to you through Winsock_Close =p
[/quote]
I am not using the Winsock control, I'm using the API. I have to create the Winsock_Close by capturing in returned events via hooking.

[quote author=MyndFyre link=topic=14056.msg143978#msg143978 date=1138747201]
[quote author=FrOzeN link=topic=14056.msg143863#msg143863 date=1138684034]
It has a timer checking every 300 milliseconds if it's connected[/quote]
You'll never know if it's disconnected if you never send data.  That's why many protocols have things like SID_NULL (keepalive packets) to ensure that a connection doesn't just last forever.
[/quote]
Sorry, ment to say ".. if data has arrived." The IsConnected() function just determines if the socket has been closed or not.
February 1, 2006, 4:52 AM

Search