AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

IRC Bot example

 
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions
View previous topic :: View next topic  
Author Message
kimbledon



Joined: 28 Sep 2007
Posts: 26

PostPosted: Sun Nov 11, 2007 1:58 am    Post subject: IRC Bot example Reply with quote

The 99 % of the code is copied from Zed Gecko. Credits to him Smile
http://www.autohotkey.com/forum/viewtopic.php?t=13829


The bot just connects to server, joins a channel and says some text in the channel. It's just an example, not a ready bot.


Code:

Network_Address = 194.124.229.58
Network_Port = 6668

Gui, Add, Edit, h20 w80 vChannel, #
Gui, Add, Button, gConnection_Init, Connect
Gui, Show

return


Connection_Init:
OnExit, ExitSub  ; For connection cleanup purposes.

; Connect to any type of server:
socket := ConnectToAddress(Network_Address, Network_Port)
if socket = -1  ; Connection failed (it already displayed the reason).
    ExitApp

; Find this script's main window:
Process, Exist  ; This sets ErrorLevel to this script's PID (it's done this way to support compiled scripts).
DetectHiddenWindows On
ScriptMainWindowId := WinExist("ahk_class AutoHotkey ahk_pid " . ErrorLevel)
DetectHiddenWindows Off

; When the OS notifies the script that there is incoming data waiting to be received,
; the following causes a function to be launched to read the data:
NotificationMsg = 0x5555  ; An arbitrary message number, but should be greater than 0x1000.
OnMessage(NotificationMsg, "ReceiveData")

; Set up the connection to notify this script via message whenever new data has arrived.
; This avoids the need to poll the connection and thus cuts down on resource usage.
FD_READ = 1     ; Received when data is available to be read.
FD_CLOSE = 32   ; Received when connection has been closed.
if DllCall("Ws2_32\WSAAsyncSelect", "UInt", socket, "UInt", ScriptMainWindowId, "UInt", NotificationMsg, "Int", FD_READ|FD_CLOSE)
{
    MsgBox % "WSAAsyncSelect() indicated Winsock error " . DllCall("Ws2_32\WSAGetLastError")
    ExitApp
}


Sleep 1000
;Change nick to AHKBot
SendText = NICK AHKBot`r`n
SendData(socket,SendText)
SendText = USER AHKBot "" "AHKBot" :AHK Bot`r`n
SendData(socket,SendText)
SentText =

return

ConnectToAddress(IPAddress, Port)
; Returns -1 (INVALID_SOCKET) upon failure or the socket ID upon success.
{
    VarSetCapacity(wsaData, 32)  ; The struct is only about 14 in size, so 32 is conservative.
    result := DllCall("Ws2_32\WSAStartup", "UShort", 0x0002, "UInt", &wsaData) ; Request Winsock 2.0 (0x0002)
    ; Since WSAStartup() will likely be the first Winsock function called by this script,
    ; check ErrorLevel to see if the OS has Winsock 2.0 available:
    if ErrorLevel
    {
        MsgBox WSAStartup() could not be called due to error %ErrorLevel%. Winsock 2.0 or higher is required.
        return -1
    }
    if result  ; Non-zero, which means it failed (most Winsock functions return 0 upon success).
    {
        MsgBox % "WSAStartup() indicated Winsock error " . DllCall("Ws2_32\WSAGetLastError")
        return -1
    }

    AF_INET = 2
    SOCK_STREAM = 1
    IPPROTO_TCP = 6
    socket := DllCall("Ws2_32\socket", "Int", AF_INET, "Int", SOCK_STREAM, "Int", IPPROTO_TCP)
    if socket = -1
    {
        MsgBox % "socket() indicated Winsock error " . DllCall("Ws2_32\WSAGetLastError")
        return -1
    }

    ; Prepare for connection:
    SizeOfSocketAddress = 16
    VarSetCapacity(SocketAddress, SizeOfSocketAddress)
    InsertInteger(2, SocketAddress, 0, AF_INET)   ; sin_family
    InsertInteger(DllCall("Ws2_32\htons", "UShort", Port), SocketAddress, 2, 2)   ; sin_port
    InsertInteger(DllCall("Ws2_32\inet_addr", "Str", IPAddress), SocketAddress, 4, 4)   ; sin_addr.s_addr

    ; Attempt connection:
    if DllCall("Ws2_32\connect", "UInt", socket, "UInt", &SocketAddress, "Int", SizeOfSocketAddress)
    {
        MsgBox % "connect() indicated Winsock error " . DllCall("Ws2_32\WSAGetLastError") . "?"
        return -1
    }
    return socket  ; Indicate success by returning a valid socket ID rather than -1.
}



ReceiveData(wParam, lParam)
; By means of OnMessage(), this function has been set up to be called automatically whenever new data
; arrives on the connection.
{
    Critical
    global ShowReceived
    global MyEdit
    global LinesReceived
    global Channel
    socket := wParam
    ReceivedDataSize = 4096  ; Large in case a lot of data gets buffered due to delay in processing previous data.
    VarSetCapacity(ReceivedData, ReceivedDataSize, 0)  ; 0 for last param terminates string for use with recv().

    ReceivedDataLength := DllCall("Ws2_32\recv", "UInt", socket, "Str", ReceivedData, "Int", ReceivedDataSize, "Int", 0)
    if ReceivedDataLength = 0  ; The connection was gracefully closed,
        ExitApp  ; The OnExit routine will call WSACleanup() for us.
    if ReceivedDataLength = -1
    {
        WinsockError := DllCall("Ws2_32\WSAGetLastError")
        if WinsockError = 10035  ; WSAEWOULDBLOCK, which means "no more data to be read".
            return 1  ; Should probably never happen since we were notified there is data on the connection, yet now we're told there's none?
        if WinsockError <> 10054 ; WSAECONNRESET, which happens when Network closes via system shutdown/logoff.
            ; Since it's an unexpected error, report it.  Also exit to avoid infinite loop.
            MsgBox % "recv() indicated Winsock error " . WinsockError
        ExitApp  ; The OnExit routine will call WSACleanup() for us.
    }
   StringLeft, pongcheck, ReceivedData, 4
   if (pongcheck = "PING") ; Send PONG event when PING recieved
   {
   Gui, Submit, NoHide
   StringTrimLeft, pongpaketti, ReceivedData, 6
   StringTrimRight, pongpaketti, pongpaketti, 2
      ;send pong
   SendText = PONG :%pongpaketti%`r`n
   SendData(socket,SendText)
      ;join to channel specified
   SendText = JOIN %Channel%`r`n
   SendData(socket,SendText)
      ;send some text to channel
   SendText = PRIVMSG %Channel% :some text`r`n
   SendData(socket,SendText)
   SendText =
   }
   Loop  ; For each binary-zero-delimited segment in the data.
   {
       Loop, parse, ReceivedData, `n, `r  ; For each line in this segment.
       {
          LinesReceived++               
           if (LinesReceived = 1) {
              ShowReceived = %LinesReceived%: %A_LoopField%
           } else {
              ShowReceived = %ShowReceived%`n%LinesReceived%: %A_LoopField%
          }
       }
       ReceivedDataLengthApparent := strlen(ReceivedData)
       if (ReceivedDataLength-1 <= ReceivedDataLengthApparent)  ; -1 to adjust for the legitimate/last zero-termintor at the end of the last segment.
          break   ; No more binary-zero-delimited segements are present.
      ; Otherwise, there's a binary zero "hiding" more data that lies to its right.
      DllCall("RtlMoveMemory", str, ReceivedData  ; Shift the data leftward to eliminate from consideration the segement that was just processed.
         , UInt, &ReceivedData + ReceivedDataLengthApparent + 1
         , UInt, ReceivedDataLength - ReceivedDataLengthApparent)
      ReceivedDataLength -= ReceivedDataLengthApparent + 1  ; Adjust length to reflect actual NEW length of ReceivedData.
   }

    return 1 ; Tell the program that no further processing of this message is needed.
}

SendData(wParam,SendData)
{
socket := wParam
;MsgBox %socket%  %SendData%
SendDataSize := Strlen(SendData)
;SendDataSize += 1
sendret := DllCall("Ws2_32\send", "UInt", socket, "Str", SendData, "Int", SendDatasize, "Int", 0)
;send( sockConnected,> welcome, strlen(welcome) + 1, NULL);
}
;VarSetCapacity

InsertInteger(pInteger, ByRef pDest, pOffset = 0, pSize = 4)
; The caller must ensure that pDest has sufficient capacity.  To preserve any existing contents in pDest,
; only pSize number of bytes starting at pOffset are altered in it.
{
    Loop %pSize%  ; Copy each byte in the integer into the structure as raw binary data.
        DllCall("RtlFillMemory", "UInt", &pDest + pOffset + A_Index-1, "UInt", 1, "UChar", pInteger >> 8*(A_Index-1) & 0xFF)
}



ExitSub:
DllCall("Ws2_32\WSACleanup")
ExitApp
Back to top
View user's profile Send private message
Chavez



Joined: 20 Aug 2008
Posts: 153

PostPosted: Sat Aug 23, 2008 3:18 pm    Post subject: Reply with quote

Not working to me:

Winsock Error: 10049

EDIT:

Works now.... more or less. I can fill in anything i want in the channel box, nothing happens

EDIT - 10 minutes later

It finally connected, it took AGES
_________________
-Chavez.
Back to top
View user's profile Send private message MSN Messenger
Display posts from previous:   
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions All times are GMT
Page 1 of 1

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group