Author | Message | Time |
---|---|---|
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 |