ICQ - Client

  • Bei dem Versuch einen ICQ - Client auf Basis der _TocLib zu erstellen, bekomme ich immer wieder folgenden Fehler:

    C:\Dokumente und Einstellungen\MasterOne\Desktop\_TocLib.au3 (658 ) : ==> Recursion level has been exceeded - AutoIt will quit to prevent stack overflow.:
    $ret[1] = _BinaryNumberDecode( BinaryMid($bPacket, 2, 1) )

    Das heißt ja vom Prinzip nichts anderes, eine Funktion zu oft verschachtelt aufgerufen wird?!

    Sieht jemand den Grund dafür???

    Spoiler anzeigen
    [autoit]


    #include "_TocLib.au3"
    #include <Timers.au3>
    #include <GUIConstants.au3>

    [/autoit] [autoit][/autoit] [autoit]

    OnAutoItExitRegister("_Exit")

    [/autoit] [autoit][/autoit] [autoit]

    Global $User = "123456789"
    Global $Pass = "passwort"

    [/autoit] [autoit][/autoit] [autoit]

    $hWnd = GUICreate("ICQ - Ersatz", 280, 300)
    $hUser = GUICtrlCreateInput($User, 10, 10, 80, 20)
    $hPass = GUICtrlCreateInput($Pass, 100, 10, 80, 20)
    $hLogin = GUICtrlCreateButton("Login", 190, 10, 80, 20)
    $hList = GUICtrlCreateListView("Nummer|Nickname", 140, 40, 130, 250)

    [/autoit] [autoit][/autoit] [autoit]

    GUISetState(@SW_SHOW)
    While 1
    $msg = GUIGetMsg()
    If $msg = $GUI_EVENT_CLOSE Then Exit
    If $msg = $hLogin Then Login()
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    Func HandleRecv($packet)
    _DebugPrint("Recieved message: " & $packet)
    $msg = _TocParseIm($packet)
    ;~ If (_Timer_GetIdleTime() > 2000 * 60) Then ;Ist man länger als 2 Minuten abwesend, wird diese Nachricht gesendet:
    _TocSendIM($msg[0], "Bin gerade nicht am PC, versuche es bitte später nochmal.", True)
    _TocSetAway("PC nicht besetzt!")
    ;~ EndIf
    EndFunc ;==>HandleRecv

    [/autoit] [autoit][/autoit] [autoit]

    Func Config($packet)
    _DebugPrint("Config:" & $packet)
    $Userlist = _TocParseConfig($packet)
    For $i = 0 To UBound($Userlist) - 1
    GUICtrlCreateListViewItem($Userlist[$i], $hList)
    Next
    EndFunc ;==>Config

    [/autoit] [autoit][/autoit] [autoit]

    Func Login()
    $login = _TocLogin(GUICtrlRead($hUser), GUICtrlRead($hPass))
    If Not $login Then
    If @error == $TOC_ERROR Then
    _DebugPrint("TOC Error: code " & $login)
    Else
    _DebugPrint("_TocLogin @error = " & @error)
    EndIf
    Else
    _DebugPrint("Logged in successfully")
    GUICtrlSetState($hLogin, $GUI_DISABLE)
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    _TocRegisterFunc($TOC_CMD_CONFIG, "Config")
    _TocRegisterFunc($TOC_CMD_IMRECV, "HandleRecv")
    _TocInitLoop()
    EndFunc ;==>Login

    [/autoit] [autoit][/autoit] [autoit]

    Func _Exit()
    _TocCleanup()
    EndFunc ;==>_Exit

    [/autoit]

    _TocLib:

    Spoiler anzeigen
    [autoit]


    #cs ----------------------------------------------------------------------------

    [/autoit] [autoit][/autoit] [autoit]

    AutoIt Version: 3.2.1.12 (beta)
    Script Version: 2.1.1.0
    Author: Daniel "Falcone88" Leong

    [/autoit] [autoit][/autoit] [autoit]

    Script Function:
    My own UDF for the TOC (Talk To Oscar) Protocol

    [/autoit] [autoit][/autoit] [autoit]

    Documentation for the protocol itself may be found in the following:
    http://terraim.cvs.sourceforge.net/*checkout*/ter…rc/toc/TOC1.txt
    http://terraim.cvs.sourceforge.net/*checkout*/ter…rc/toc/TOC2.txt

    [/autoit] [autoit][/autoit] [autoit]

    The following, though a bit dated, was still very helpful:
    http://www2.sys-con.com/ITSG/virtualcd…aton/index.html

    [/autoit] [autoit][/autoit] [autoit]

    If something isn't in the TOC2 docs, it is the same asin TOC1. Note, of course,
    that the most recent things (IE: as shown in TOC2) must be used.

    [/autoit] [autoit][/autoit] [autoit]

    List of functions:
    _TocLogin
    _TocFinalizeLogin
    _TocSendIM
    _TocSetAway
    _TocParseIm
    _TocParseConfig <- doesn't do anything yet
    _TocCleanup

    [/autoit] [autoit][/autoit] [autoit]

    _TocRegisterFunc
    _TocIsRegistered
    _TocInitLoop
    _TocStopLoop
    _TocDoLoop

    [/autoit] [autoit][/autoit] [autoit]

    _TocRoastPass
    _TocNormalizeName
    _TocNormalizeString
    _TocMakeSigninCode
    _TocMakeFlapPacket
    _TocDecodeFlap
    _TocSendFlap
    _TocSendRaw
    _TocWaitFlap
    _TocGetFlap

    [/autoit] [autoit][/autoit] [autoit]

    _BinaryNumber
    _BinaryNumberDecode

    [/autoit] [autoit][/autoit] [autoit]

    #ce ----------------------------------------------------------------------------

    [/autoit] [autoit][/autoit] [autoit]

    #include <Array.au3>

    [/autoit] [autoit][/autoit] [autoit]

    ; @error codes
    Global Const $TOC_TCP_FAIL = 1 ; could not init TCP
    Global Const $TOC_CONNECT_FAIL = 2 ; could not connect to toc server
    Global Const $TOC_SEND_FAIL = 3 ; could not send over TCP for some reason
    Global Const $TOC_ERROR = 4 ; TOC server sent an error code
    Global Const $TOC_NO_HANDLERS = 5 ; no functions to handle inputs defined
    Global Const $TOC_CMD_TOOLONG = 6 ; attempted to send a string to TOC longer than max

    [/autoit] [autoit][/autoit] [autoit]

    ; TOC errors
    #cs
    * General Errors *
    901 - $1 not currently available
    902 - Warning of $1 not currently available
    903 - A message has been dropped, you are exceeding
    the server speed limit

    [/autoit] [autoit][/autoit] [autoit]

    ;* Admin Errors *
    911 - Error validating input
    912 - Invalid account
    913 - Error encountered while processing request
    914 - Service unavailable

    [/autoit] [autoit][/autoit] [autoit]

    * Chat Errors *
    950 - Chat in $1 is unavailable.

    [/autoit] [autoit][/autoit] [autoit]

    * IM & Info Errors *
    960 - You are sending message too fast to $1
    961 - You missed an im from $1 because it was too big.
    962 - You missed an im from $1 because it was sent too fast.

    [/autoit] [autoit][/autoit] [autoit]

    * Dir Errors *
    970 - Failure
    971 - Too many matches
    972 - Need more qualifiers
    973 - Dir service temporarily unavailable
    974 - Email lookup restricted
    975 - Keyword Ignored
    976 - No Keywords
    977 - Language not supported
    -Update: 977 can also mean no directory information available
    978 - Country not supported
    979 - Failure unknown $1

    [/autoit] [autoit][/autoit] [autoit]

    * Auth errors *
    980 - Incorrect nickname or password.
    981 - The service is temporarily unavailable.
    982 - Your warning level is currently too high to sign on.
    983 - You have been connecting and
    disconnecting too frequently. Wait 10 minutes and try again.
    If you continue to try, you will need to wait even longer.
    989 - An unknown signon error has occurred $1
    #ce

    [/autoit] [autoit][/autoit] [autoit]

    ; TOC Server -> Client commands
    Global Const $TOC_CMD_SIGNON = "SIGN_ON"
    Global Const $TOC_CMD_IMRECV = "IM_IN_ENC2"
    Global Const $TOC_CMD_CONFIG = "CONFIG2"
    Global Const $TOC_CMD_BUDDY_ACCEPTED = "NEW_BUDDY_REPLY2"
    Global Const $TOC_CMD_CHATRECV = "CHAT_IN_ENC"
    Global Const $TOC_CMD_BUDDY_UPDATE = "UPDATE_BUDDY2"
    Global Const $TOC_CMD_CHAT_UPDATE = "CHAT_UPDATE_BUDDY"
    Global Const $TOC_CMD_CHATINVITE = "CHAT_INVITE"
    Global Const $TOC_CMD_ERROR = "ERROR"
    Global Const $TOC_CMD_ANY = "~ANY~" ; catches anything not registered otherwise

    [/autoit] [autoit][/autoit] [autoit]

    ; FLAP constant crap
    $TOC_FLAP_ON = "FLAPON"&@CRLF&@CRLF
    $TOC_ROAST_STRING = "Tic/Toc"
    $TOC_LANGUAGE = "english"
    $TOC_VERSION = "TIC:TOCLib for Autoit by Dan Leong"
    $TOC_COUNTRY = "US"
    $TOC_MAX_CHAR_LENGTH = 2048
    $TOC_MAX_CHAR_RECV = 8192
    $TOC_SIGNON_TYPE = 1
    $TOC_DATA_TYPE = 2

    [/autoit] [autoit][/autoit] [autoit]

    ; global vars
    Global $currSequence = 0
    Global $tocTcpSocket
    Global $tocVersion = ""
    Global $handleRecvCmd[1]
    Global $handleRecvFunc[1] ; func called on recieved new message
    Global $recvCmdBuffer[1] ; in case we recieve messages too fast, we'll throw extra ones into a buffer

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ;
    ; Description: Login to the TOC Server
    ; Parameter(s): $sUser - Username for AIM
    ; $sPass - Password for AIM
    ; $fFinalize - Whether or not to finalize connection (see notes)
    ; $sTocServer - TOC Servername. The default should be fine, but
    ; localhost may be used for testing...
    ; $iTocPort - TOC port to connect to. Again, default should be fine
    ; $sAuthServer - Authentication server. (Allows you to login to AIM)
    ; $iAuthPort - Port of the Auth Server
    ; Requirement(s): None
    ; Return Value(s): On Success - true
    ; On Failure - false and Set
    ; @ERROR to: $TOC_CONNECT_FAIL - Could not connect to TOC server
    ; $TOC_SEND_FAIL - Could not send data to the server
    ; $TOC_ERROR - Recieved an ERROR message from the TOC server
    ; The error number will be set in @extended
    ; Author(s): Dan "Falcone88" Leong
    ; Note(s): If you want to send configurations to the TOC server (say, you're making an AIM client),
    ; you will want to set this to false, send your config, then use _TocFinalizeLogin(). Note
    ; that this must be sent within 30 seconds of _TocLogin()'s return, or the server will drop
    ; the connection.
    ;
    ; The comments on the format of the packets were taken from one of the websites at the top
    ; of this file.
    ;
    ;===============================================================================
    Func _TocLogin( $sUser, $sPass, $fFinalize=true, $sTocServer="toc.oscar.aol.com", $iTocPort=9898, $sAuthServer="login.oscar.aol.com", $iAuthPort=5190)
    If not TCPStartUp() Then
    SetError($TOC_TCP_FAIL)
    return false
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    $tocTcpSocket = TCPConnect( TCPNameToIP($sTocServer), $iTocPort )

    [/autoit] [autoit][/autoit] [autoit]

    if $tocTcpSocket == -1 Then
    SetError($TOC_CONNECT_FAIL)
    return false
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    ; initialize FLAP
    $bytes = _TocSendRaw($TOC_FLAP_ON)
    if $bytes == 0 Then
    SetError($TOC_SEND_FAIL)
    return false
    EndIf
    _DebugPrint( "Sent FLAPON" )

    [/autoit] [autoit][/autoit] [autoit]

    ; wait for TOC version
    $tocVersion = _TocWaitFlap()
    _DebugPrint( "Recieved TOC Version" )

    [/autoit] [autoit][/autoit] [autoit]

    ; send "signon" packet
    #cs
    First, the version numbers, then a word of 0x0001. This indicates that a user name will follow.
    The next word represents the length of the screen name. Following the length is the normalized
    representation of the screen name - all spaces are removed and the entire name is converted to lowercase.
    #ce
    $bytes = _TocSendFlap($tocVersion & BinaryString( "0x0001" ) & ( _BinaryNumber(StringLen($sUser)) ) & _TocNormalizeName($sUser), $TOC_SIGNON_TYPE )
    if $bytes == 0 Then
    SetError($TOC_SEND_FAIL)
    return false
    EndIf
    _DebugPrint( "Sent SIGNON" )

    [/autoit] [autoit][/autoit] [autoit]

    ; login
    #cs
    toc2_login <address> <port> <screenname> <roasted pw> <language> <version*> 160 US "" "" 3 0 30303 -kentucky -utf8 76144224***

    [/autoit] [autoit][/autoit] [autoit]

    * The version string MUST start with "TIC:" otherwise, no dice. For example, "TIC:AIMM" is ok, but "AIMM2" would be rejected.
    ** I have no idea what the parameters after the version are. Put them in verbatim and logging in works.
    *** See _TocMakeSigninCode()
    #ce
    $loginStr = 'toc2_login '&$sAuthServer&' '&$iAuthPort&' "'&$sUser&'" '&_TocRoastPass($sPass)&' "'
    $loginStr &= $TOC_LANGUAGE&'" "'&$TOC_VERSION&'" 160 '&$TOC_COUNTRY&' "" "" 3 0 30303 -kentucky -utf8 '
    $loginStr &= _TocMakeSigninCode($sUser, ($sPass))

    [/autoit] [autoit][/autoit] [autoit]

    $bytes = _TocSendFlap($loginStr)
    if $bytes == 0 Then
    SetError($TOC_SEND_FAIL)
    return false
    EndIf
    _DebugPrint( "Sent LOGIN" )

    [/autoit] [autoit][/autoit] [autoit]

    $response = _TocWaitFlap(2)
    _DebugPrint( _ArrayToString($response, " ") )
    if $response[1] = $TOC_CMD_ERROR Then
    SetError($TOC_ERROR, StringLeft($response[2], 3), false)

    [/autoit] [autoit][/autoit] [autoit]

    ElseIf $response[1] = $TOC_CMD_SIGNON Then
    _DebugPrint("Logged on successfully")

    [/autoit] [autoit][/autoit] [autoit]

    If $fFinalize Then _TocFinalizeLogin()

    [/autoit] [autoit][/autoit] [autoit]

    return true
    Else
    _DebugPrint("Weird.. I see ("&$response[1]&")")
    SetError($TOC_ERROR)
    return false
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    return false ; just in case
    EndFunc ;==>_TocLogin

    [/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ;
    ; Description: Finalize login to AIM server
    ; Parameter(s): None
    ; Requirement(s): A successful call to _TocLogin()
    ; Return Value(s): Number of bytes sent via TCP
    ;
    ; Author(s): Dan "Falcone88" Leong
    ; Note(s): See _TocLogin()
    ;
    ;===============================================================================
    Func _TocFinalizeLogin()
    return _TocSendFlap("toc_init_done")
    EndFunc ;==>_TocFinalizeLogin()

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ;
    ; Description: Send an IM to specified user via AIM
    ; Parameter(s): $sUser - Target user's AIM screenname
    ; $sMsg - The message to send
    ; $fAuto - Whether or not to specify the message as an auto response
    ; Requirement(s): A successful call to _TocLogin()
    ; Return Value(s): Number of bytes sent via TCP
    ;
    ; Author(s): Dan "Falcone88" Leong
    ; Note(s): None.
    ;
    ;===============================================================================
    Func _TocSendIM($sUser, $sMsg, $fAuto=false)
    Local $packet = 'toc2_send_im '&_TocNormalizeName($sUser)&' "'

    [/autoit] [autoit][/autoit] [autoit]

    $packet &= _TocNormalizeString($sMsg)&'"'

    [/autoit] [autoit][/autoit] [autoit]

    if $fAuto Then $packet &= ' auto'
    return _TocSendFlap($packet)
    EndFunc ;==>_TocSendIM

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ;
    ; Description: Set your away message
    ; Parameter(s): $sMsg - The away message to set
    ;
    ; Requirement(s): A successful call to _TocLogin()
    ; Return Value(s): Number of bytes sent via TCP
    ;
    ; Author(s): Dan "Falcone88" Leong
    ; Note(s): If you call without any arguments, it will set status to
    ; available.
    ;
    ;===============================================================================
    Func _TocSetAway($sMsg = "")
    return _TocSendFlap('toc_set_away "' & _TocNormalizeString($sMsg) & '"')
    EndFunc ;==>_TocSetAway

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ;
    ; Description: Parse in IM_IN packet from TOC2 into something useful
    ; Parameter(s): $sPacket - The packet data from IM_IN (Just the data part, not FLAP)
    ; Requirement(s): Array.au3
    ; Return Value(s): On Success - An array as follows:
    ; $ret[0] = username from
    ; $ret[1] = auto or not (String "T"/"F")
    ; $ret[2] = buddy status
    ; $ret[3] = message
    ; On Failure - "" and Set @ERROR to 1
    ; Author(s): Dan "Falcone88" Leong
    ; Note(s): $sPacket SHOULD look like this: (I think)
    ; <user>:<auto>:<???>:<???>:<buddy status>:<???>:<???>:en:<message>
    ; Note the omission of IM_IN_ENC2... That's because it's omitted in
    ; the way _TocDoLoop() calls registered functions ;)
    ; Alternatively, it can be an array as returned by _TocGetFlap(2)
    ;
    ;===============================================================================
    Func _TocParseIm( $sPacket )
    Local $ret[4], $iMod = 0
    if not IsArray($sPacket) Then
    $sPacket = StringSplit($sPacket, ":")
    Else
    $iMod = 1
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    If not IsArray($sPacket) or UBound($sPacket) < 9+$iMod Then
    SetError(1)
    return ""
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    $ret[0] = $sPacket[1 + $iMod]
    $ret[1] = $sPacket[2 + $iMod]
    $ret[2] = $sPacket[5 + $iMod]
    $ret[3] = _ArrayToString ( $sPacket, ":", 9 + $iMod )

    [/autoit] [autoit][/autoit] [autoit]

    return $ret
    EndFunc ;==>_TocParseIm

    [/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ;
    ; Description: Parse a CONFIG2 packet from TOC2 into something useful
    ; Parameter(s): $sPacket - The packet data from CONFIG2 (Just the data part, not FLAP)
    ; Requirement(s): none
    ; Return Value(s): On Success - An array as follows:
    ; $ret[0] = 1. Usernumber | Username
    ; $ret[1] = 2. Usernumber | Username
    ; $ret[2] = 3. Usernumber | Username
    ; ...
    ; Author(s): Dan "Falcone88" Leong
    ; Note(s): Obviously, this does nothing at the moment. Looking at samples,
    ; It so far seems pointless to include this, as there's no really
    ; good way that I can see implementing this as a helpful function
    ; without using some strange 3d array
    ;
    ;===============================================================================
    Func _TocParseConfig( $sPacket )
    Local $aUsers, $i, $reg
    $aUsers = StringRegExp($sPacket, "b:(.*?)" & @LF, 3)
    Local $ret[UBound($aUsers)]
    For $i = 0 To UBound($aUsers) - 1
    $reg = StringRegExp($aUsers[$i] & @LF, "(.*?):(.*?)(?::*)" & @LF, 3)
    $ret[$i] = $reg[0] & "|" & BinaryToString(StringToBinary($reg[1], 1), 4) ; User Number & "|" & User Name (UTF8 -> ASCII)
    Next
    Return $ret
    EndFunc ;==>_TocParseConfig

    [/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ;
    ; Description: Cleanup the TCP connections and such
    ; Parameter(s): None
    ; Requirement(s): None
    ; Return Value(s): None
    ;
    ; Author(s): Dan "Falcone88" Leong
    ; Note(s): None
    ;
    ;===============================================================================
    Func _TocCleanup()
    _TocStopLoop()
    TCPCloseSocket( $tocTcpSocket )
    TCPShutdown()
    EndFunc ;==> _TocCleanup

    [/autoit] [autoit][/autoit] [autoit]

    ;
    ; _TocDoLoop() related functions
    ;

    [/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ;
    ; Description: Register a function to be called upon receiving a given command
    ; Parameter(s): $sCmd - The TOC command to trigger the function
    ; $sFuncName - Name of the user's function to be called upon recieve
    ; Requirement(s): Array.au3
    ; Return Value(s): Always returns true...
    ; Author(s): Dan "Falcone88" Leong
    ; Note(s): The function to be called should expect a single argument,
    ; which will be the exact string arguments provided in the FLAP packet.
    ;
    ;===============================================================================
    Func _TocRegisterFunc($sCmd, $sFuncName)
    $key = _ArraySearch($handleRecvCmd, $sCmd)

    [/autoit] [autoit][/autoit] [autoit]

    if $key == -1 Then
    _ArrayAdd($handleRecvCmd, $sCmd)
    _ArrayAdd($handleRecvFunc, $sFuncName)
    $handleRecvCmd[0] += 1
    $handleRecvFunc[0] += 1
    Else
    $handleRecvFunc[ $key ] = $sFuncName
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    return true
    EndFunc ;==>_TocRegisterFunc

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ;
    ; Description: Check if a particular cmd has a function registered with it
    ; Parameter(s): $sCmd - The TOC command to trigger the function
    ; $fReturnIndex - whether to return the index of the cmd (if found)
    ; instead of a boolean
    ; Requirement(s): Array.au3
    ; Return Value(s): On Success - if $fReturnIndex=false, returns TRUE
    ; if $fReturnIndex=true, returns the index of the func
    ; On Failure - FALSE
    ;
    ; Author(s): Dan "Falcone88" Leong
    ; Note(s): $fReturnIndex=true is probably not necessary for the casual
    ; user. I use it as a utility for other functions, though
    ;
    ;===============================================================================
    Func _TocIsRegistered($sCmd, $fReturnIndex=false)
    $key = _ArraySearch($handleRecvCmd, $sCmd)

    [/autoit] [autoit][/autoit] [autoit]

    if $key == -1 Then
    return false
    Else
    if $fReturnIndex Then
    return $key
    Else
    return True
    EndIf
    EndIf
    EndFunc ;==>_TocIsRegistered

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ;
    ; Description: Initialize the AdLib loop that checks for server input and calls
    ; the appropriate registered functions.
    ; Parameter(s): $iDelay - Time in ms between function calls (See definition of AdlibEnable)
    ; Requirement(s): At least one call to _TocRegisterFunc
    ; Return Value(s): On Success - true
    ; On Failure - false and Set @ERROR to $TOC_NO_HANDLERS (No functions registered)
    ; Author(s): Dan "Falcone88" Leong
    ; Note(s): none
    ;
    ;===============================================================================
    Func _TocInitLoop($iDelay=250)
    if $handleRecvCmd[0] < 1 Then
    SetError( $TOC_NO_HANDLERS )
    return false
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    AdlibRegister("_TocDoLoop", $iDelay)
    return true
    EndFunc ;==>_TocInitLoop

    [/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ;
    ; Description: Stop the AdLib loop. That's about it ;)
    ; Parameter(s): none
    ; Requirement(s): A previous call to _TocInitLoop()... if you want it to do something
    ; Return Value(s): none
    ; Author(s): Dan "Falcone88" Leong
    ; Note(s): none
    ;
    ;===============================================================================
    Func _TocStopLoop()
    AdlibUnRegister()
    EndFunc ;==>_TocStopLoop

    [/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ;
    ; Description: The function called in each loop to parse packets.
    ; Parameter(s): $iDelay - Time in ms between function calls (See definition of AdlibEnable)
    ; Requirement(s): Array.au3
    ; Return Value(s): none
    ; Author(s): Dan "Falcone88" Leong
    ; Note(s): When it finds a handled command, it sends the whole
    ; argument string to that function. The command itself is,
    ; of course, omitted, as you should know what command it's handling.
    ;
    ;===============================================================================
    Func _TocDoLoop()
    Local $packet, $cmdIndex

    [/autoit] [autoit][/autoit] [autoit]

    $packet = _TocGetFlap(2)
    if $packet == -1 Then Return ; nothing
    ConsoleWrite("!-- " & $packet[1] & @CRLF)
    ;~ _DebugPrint( "Recieved: " & _ArrayToString($packet, ":") &@LF& "Looking for: "& $packet[1] )
    $cmdIndex = _ArraySearch($handleRecvCmd, $packet[1])
    if $cmdIndex == -1 Then
    $cmdIndex = _TocIsRegistered($TOC_CMD_ANY, true)

    [/autoit] [autoit][/autoit] [autoit]

    if $cmdIndex == 0 Then Return 0; unhandled cmd, ignore
    EndIf
    If $cmdIndex == False Then Return 0
    Call($handleRecvFunc[$cmdIndex], _ArrayToString($packet,":",2) )
    If @error Then MsgBox(0, $cmdIndex, $handleRecvFunc[$cmdIndex])
    EndFunc

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;
    ; Util Funcs
    ;

    [/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ;
    ; Description: "Roast" a password. Basically it's a really simple encryption
    ; that TOC requires
    ; Parameter(s): $sOldPass - The unencrypted password
    ; Requirement(s): none
    ; Return Value(s): The "roasted" password
    ; Author(s): Dan "Falcone88" Leong
    ; Note(s): none
    ;
    ;===============================================================================
    Func _TocRoastPass($sOldPass)
    Local $roasted = "0x", $xor_i = 1

    [/autoit] [autoit][/autoit] [autoit]

    for $i=1 to StringLen($sOldPass)
    $roasted &= hex( BitXOR( Asc(StringMid($TOC_ROAST_STRING, $xor_i, 1)), Asc(StringMid($sOldPass, $i, 1)) ), 2 )

    [/autoit] [autoit][/autoit] [autoit]

    $xor_i += 1
    if ( $xor_i > StringLen($TOC_ROAST_STRING) ) Then $xor_i=1
    Next

    [/autoit] [autoit][/autoit] [autoit]

    return $roasted
    EndFunc ;==>_TocRoastPass

    [/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ;
    ; Description: "Normalize" a name
    ; Parameter(s): $sString - The string to "normalize"
    ; Requirement(s): none
    ; Return Value(s): The "normalized" name
    ; Author(s): Dan "Falcone88" Leong
    ; Note(s): As you can see, this just removes spaces and puts it in lower
    ; case. This is mostly used for usernames when communicating
    ; with TOC
    ;
    ;===============================================================================
    Func _TocNormalizeName($sString)
    return StringReplace(StringLower($sString), " ", "")
    EndFunc ;==>_TocNormalizeName

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ;
    ; Description: "Normalize" a string.
    ; Parameter(s): $sString - The string to "normalize"
    ; Requirement(s): none
    ; Return Value(s): The "normalized" string
    ; Author(s): Dan "Falcone88" Leong
    ; Note(s): This changes some characters to something more acceptable to
    ; TOC. This is another function that received help from
    ; BlueTOC
    ;
    ;===============================================================================
    Func _TocNormalizeString($sString)
    $sString = StringReplace( $sString, "\", "\\" )
    $sString = StringReplace( $sString, "$", "\$" )
    $sString = StringReplace( $sString, '"', '\"' )
    $sString = StringReplace( $sString, "(", "\(" )
    $sString = StringReplace( $sString, ")", "\)" )
    $sString = StringReplace( $sString, "[", "\[" )
    $sString = StringReplace( $sString, "]", "\]" )
    $sString = StringReplace( $sString, "{", "\{" )
    $sString = StringReplace( $sString, "}", "\}" )

    [/autoit] [autoit][/autoit] [autoit]

    return $sString
    EndFunc ;==>_TocNormalizeString

    [/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ;
    ; Description: Create the wierd authentication code needed to login with TOC2
    ; Parameter(s): $sUser - the username being used to log in
    ; $sPass - the password
    ; Requirement(s): none
    ; Return Value(s): The code
    ; Author(s): Ahnugslos (optimized)
    ; Note(s): Original by Dan "Falcone88" Leong
    ;
    ;===============================================================================
    Func _TocMakeSigninCode($sUser, $sPass)
    return 7696 * Asc(StringLeft($sUser, 1)) * Asc(StringLeft($sPass, 1))
    EndFunc ;==>_TocMakeSigninCode

    [/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ;
    ; Description: Take a TOC command and prepend a FLAP header to it :)
    ; Parameter(s): $iType - The type of packet. Can be:
    ; $TOC_SIGNON_TYPE - used for the signon packet... rarely used
    ; $TOC_DATA_TYPE - used for nearly everything. Default :)
    ; $sData - the command string
    ; Requirement(s): none
    ; Return Value(s): The created packet
    ; Author(s): Dan "Falcone88" Leong
    ; Note(s): This took me FOREVER to figure out. The most annoying
    ; part of this whole library, easily
    ;
    ;===============================================================================
    Func _TocMakeFlapPacket($iType, $sData)
    $currSequence += 1
    if $iType == $TOC_DATA_TYPE Then $sData &= chr(0)

    [/autoit] [autoit][/autoit] [autoit]

    $btype = _BinaryNumber( $iType, 1 )
    $bseq = _BinaryNumber( ($currSequence) )
    $blen = _BinaryNumber( StringLen($sData) )

    [/autoit] [autoit][/autoit] [autoit]

    $header = "*" & $btype & $bseq & $blen

    [/autoit] [autoit][/autoit] [autoit]

    return $header & $sData
    EndFunc ;==>_TocMakeFlapPacket

    [/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ;
    ; Description: Decode a raw FLAP packet
    ; Parameter(s): $bPacket - The packet
    ;
    ; Requirement(s): none
    ; Return Value(s): Success - An array formated as follows:
    ; $ret[0] = "*"
    ; $ret[1] = type
    ; $ret[2] = sequence number
    ; $ret[3] = length of the packet
    ; $ret[4] = the packet itself
    ; $ret[5] = any excess stuff after reading $ret[3] characters
    ; Failure - The original packet, and sets @ERROR = 1
    ; Author(s): Dan "Falcone88" Leong
    ; Note(s): This removes any Chr(0) found in the strings. The fifth index
    ; is included because sometimes packets are sent quickly and
    ; become mixed up. This helps to ensure that all packets
    ; are recieved properly.
    ;
    ;===============================================================================
    Func _TocDecodeFlap( $bPacket )
    If BinaryLen($bPacket) < 1 or Binary( BinaryMid( $bPacket, 1, 1 ) ) <> Binary("*") Then
    SetError(1) ; not a proper flap packet, returns full packet
    return $bPacket
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    Local $ret[6]

    [/autoit] [autoit][/autoit] [autoit]

    $ret[0] = "*"
    $ret[1] = _BinaryNumberDecode( BinaryMid($bPacket, 2, 1) )
    $ret[2] = _BinaryNumberDecode( BinaryMid($bPacket, 3, 2) )
    $ret[3] = _BinaryNumberDecode( BinaryMid($bPacket, 5, 2) )
    $ret[4] = StringMid( BinaryToString($bPacket), 7, $ret[3] )
    $ret[5] = StringMid( BinaryToString($bPacket), 7 + $ret[3] )

    [/autoit] [autoit][/autoit] [autoit]

    ;~ FileWriteLine(@ScriptDir&"\parsed.txt", "--------")
    ;~ FileWriteLine(@ScriptDir&"\parsed.txt", " PacketRaw: " & $bPacket)
    ;~ FileWriteLine(@ScriptDir&"\parsed.txt", "PacketRead: " & $ret[4])
    ;~ FileWriteLine(@ScriptDir&"\parsed.txt", "Proposed Length: " & $ret[3])

    [/autoit] [autoit][/autoit] [autoit]

    return $ret
    EndFunc ;==>_TocDecodeFlap

    [/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ;
    ; Description: Send a packet to TOC with a FLAP header.
    ; Parameter(s): $sData - The data string to send
    ; $iType - type of packet (See _TocMakeFlapPacket)
    ; $fTruncate - See _TocSendRaw()
    ;
    ; Requirement(s): none
    ; Return Value(s): Number of bytes sent via TCP
    ; Author(s): Dan "Falcone88" Leong
    ; Note(s): $iType is second so it can be optional and default to $TOC_DATA_TYPE,
    ; as that is the most common type
    ;
    ;===============================================================================
    Func _TocSendFlap( $sData, $iType = 2, $fTruncate=false )
    _DebugPrint("SENT: " & $sData)
    return _TocSendRaw( _TocMakeFlapPacket($iType, $sData) )
    EndFunc ;==>_TocSendFlap

    [/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ;
    ; Description: Send a raw packet to TOC server
    ; Parameter(s): $bData - The data string to send
    ; $fTruncate - Silently clip $bData if it's too long or not
    ;
    ; Requirement(s): Previous successful call to _TocLogin()
    ; Return Value(s): Success - Number of bytes sent via TCP
    ; Failure - 0, and set @ERROR = $TOC_CMD_TOOLONG
    ; Author(s): Dan "Falcone88" Leong
    ; Note(s): Failure condition only ever occurs if $fTruncate = false. If
    ; $fTruncate = true, this will not issue any errors even if
    ; the string is longer than allowed ($TOC_MAX_CHAR_LENGTH). It
    ; will simply truncate the string to the allowed length
    ;
    ;===============================================================================
    Func _TocSendRaw( $bData, $fTruncate=false )
    if not $fTruncate and StringLen($bData) > $TOC_MAX_CHAR_LENGTH Then
    SetError($TOC_CMD_TOOLONG)
    return 0
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    return TCPSend($tocTcpSocket, StringLeft($bData, $TOC_MAX_CHAR_LENGTH))
    EndFunc ;==>_TocSendRaw

    [/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ;
    ; Description: Wait until a packet is recieved from the TOC server
    ; Parameter(s): $iRetType - Return format; See _TocGetFlap
    ;
    ; Requirement(s): Previous successful call to _TocLogin()
    ; Return Value(s): See _TocGetFlap
    ; Author(s): Dan "Falcone88" Leong
    ; Note(s): none
    ;
    ;===============================================================================
    Func _TocWaitFlap($iRetType=1)
    Local $packet = ""
    Do
    $packet = _TocGetFlap($iRetType)

    [/autoit] [autoit][/autoit] [autoit]

    Until $packet <> -1

    [/autoit] [autoit][/autoit] [autoit]

    return $packet
    EndFunc ;==>_TocWaitFlap

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ;
    ; Description: Instantaneous (non-blocking) check for a flap packet
    ; Parameter(s): $iRetType - Format for the return value
    ;
    ; Requirement(s): Previous successful call to _TocLogin()
    ; Return Value(s): Success - Returns the packet, depending on $iRetType:
    ; 0 - Full packet, raw (including FLAP header)
    ; 1 - The data part (everything BUT header), raw
    ; 2 - The data part (everything BUT header), split into
    ; an array using ":" as the delimeter
    ; Failure - (No new packet) returns -1
    ; Author(s): Dan "Falcone88" Leong
    ; Note(s): This function looks about 25 lines longer than it needs to be,
    ; but that's because it takes into account packets sent in
    ; really close proximity that consequently might be interpretted as a single packet.
    ; Extra packets are added to $recvCmdBuffer and are inserted before the next recieved
    ; packet in order recieved. (Obviously, there could be a backup if a packet wasn't split up,
    ; which this method accounts for. However, this is not a problem, as the new packet will
    ; be found and added to the end of the buffer.
    ;
    ;===============================================================================
    Func _TocGetFlap($iRetType=0, $fCalledFromLoop=false)
    Local $decoded, $extraString, $newPacket

    [/autoit] [autoit][/autoit] [autoit]

    Local $packet = TCPRecv($tocTcpSocket, $TOC_MAX_CHAR_RECV)
    ;~ FileWriteLine(@ScriptDir&"\buffer.txt", $packet)
    ;~ FileWriteLine(@ScriptDir&"\buffer.txt", "---------")
    if $recvCmdBuffer[0] > 0 Then
    ;~ _ArrayAdd( $recvCmdBuffer, )
    $packet = $recvCmdBuffer[1] & $packet
    _ArrayDelete( $recvCmdBuffer, 1 )
    $recvCmdBuffer[0] -= 1
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    $decoded = _TocDecodeFlap($packet)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ; first, see if we got the whole packet
    If IsArray($decoded) Then
    If $decoded[3] <> StringLen($decoded[4]) Then
    ; if not, enqueue it
    _ArrayAdd( $recvCmdBuffer, $packet )
    $recvCmdBuffer[0] += 1

    [/autoit] [autoit][/autoit] [autoit]

    ;~ _DebugPrint( "Doin' a loop to get the whole packet :)" )
    ; call ourself again to get the rest of the packet
    return _TocGetFlap($iRetType)
    EndIf
    Else
    ; not a flap packet, ignore for now
    return -1
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    ; now process
    if StringLen($packet) > 0 Then
    ; check for extra commands
    if BinaryLen($decoded[5]) > 0 Then
    $extraString = $decoded[5]
    Do ; loop through, enqueing all COMPLETE packets as separate entries
    $newPacket = _TocDecodeFlap( $extraString )
    FileWriteLine(@ScriptDir&"\buffer.txt", $extraString)
    FileWriteLine(@ScriptDir&"\buffer.txt", "---------")
    if IsArray($newPacket) Then
    if $newPacket[0] == "*" Then ; make sure it's actually flap
    _ArrayAdd( $recvCmdBuffer, StringLeft( $extraString, 6 + $newPacket[3]) )
    $recvCmdBuffer[0] += 1

    [/autoit] [autoit][/autoit] [autoit]

    $extraString = $newPacket[5]
    EndIf
    Else
    $extraString = ""
    EndIf
    Until $extraString == ""
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    ;~ FileWriteLine(@ScriptDir&".\buffer.txt", "-------")
    ;~ FileWriteLine(@ScriptDir&".\buffer.txt", "Current packet: "&$packet)
    ;~ FileWriteLine(@ScriptDir&".\buffer.txt", "Excess: " & $decoded[5])
    ;~ FileWriteLine(@ScriptDir&".\buffer.txt", "Buffer: ")
    ;~
    ;~ for $i=1 to $recvCmdBuffer[0]
    ;~ FileWriteLine(@ScriptDir&".\buffer.txt", $recvCmdBuffer[$i] & @CRLF&"<>"&@CRLF )
    ;~ Next
    ;~
    ;~ FileWriteLine(@ScriptDir&".\buffer.txt", "-------")

    [/autoit] [autoit][/autoit] [autoit]

    _DebugPrint("Received: " & $decoded[4])
    Switch $iRetType
    case 0
    return $packet
    case 1
    return $decoded[4]
    case 2
    return StringSplit($decoded[4], ":")
    EndSwitch
    Else
    return -1
    EndIf
    EndFunc ;==>_TocGetFlap

    [/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ;
    ; Description: Convert a number to the necessary binary format, padding the
    ; beginning with Chr(0) until it's the appropriate $iLength
    ; Parameter(s): $iNum - The number to be converted
    ; $iLength - The desired length
    ; Requirement(s): none
    ; Return Value(s): The converted number
    ; Author(s): Dan "Falcone88" Leong
    ; Note(s): It took me forever to figure out how I was supposed to do this!
    ; For $iLength:
    ; byte = 1
    ; word = 2
    ; dword = 4
    ; qword = 8
    ;
    ;===============================================================================
    Func _BinaryNumber($iNum, $iLength=2)
    Local $b, $numStarted=false, $out="", $prepend=""

    [/autoit] [autoit][/autoit] [autoit]

    $b = Binary($iNum)
    for $i=BinaryLen($b) to 1 Step -1
    if Chr( BinaryMid($b, $i, 1) ) <> Chr(0) or $numStarted Then
    if not $numStarted then $numStarted = true
    $out &= Chr( BinaryMid($b, $i, 1) )
    EndIf
    Next

    [/autoit] [autoit][/autoit] [autoit]

    if BinaryLen($out) < $iLength Then
    for $i=1 to $iLength-BinaryLen($out)
    $prepend &= Chr(0)
    Next
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    return $prepend&$out

    [/autoit] [autoit][/autoit] [autoit]

    EndFunc ;==>_BinaryNumber

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func BinaryString ($sData)
    Local $b = Binary($sData)
    Local $out = ""

    [/autoit] [autoit][/autoit] [autoit]

    for $i=1 to BinaryLen($b)
    $out &= Chr( BinaryMid($b, $i, 1) )
    Next

    [/autoit] [autoit][/autoit] [autoit]

    return $out
    EndFunc

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ;
    ; Description: Convert a number from the necessary binary format to a
    ; usable number
    ; Parameter(s): $iNum - The number to be converted

    [/autoit] [autoit][/autoit] [autoit]

    ;
    ; Requirement(s): none
    ; Return Value(s): The converted number
    ; Author(s): Dan "Falcone88" Leong
    ; Note(s): It took me forever to figure out how I was supposed to do this.
    ; I finally made this magical. Hopefully it still works
    ; properly....
    ;
    ;===============================================================================
    Func _BinaryNumberDecode($iNum)

    [/autoit] [autoit][/autoit] [autoit]

    ; A shortcut!
    if StringInStr(String($iNum), "0x") Then
    $iNum = StringMid(String($iNum),3)
    return dec($iNum)
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    $iOffset = 1
    While StringMid(String($iNum),$iOffset,2) == "00"
    $iOffset+=2
    WEnd
    $sTrim = StringMid($iNum, $iOffset)
    $iLength = StringLen( $sTrim )
    $iVal = 0

    [/autoit] [autoit][/autoit] [autoit]

    for $i=1 to $iLength
    $iVal += Number( String( Asc( StringMid($sTrim,$i,1) ) ) ) * (16^ (2*($iLength-$i)))
    Next

    [/autoit] [autoit][/autoit] [autoit]

    return $iVal
    EndFunc ;==>_BinaryNumberDecode

    [/autoit] [autoit][/autoit] [autoit]

    ;
    ; This is not my method, but was very helpful, and I don't want to delete all of the calls
    ; to it... just in case. So there :P
    ;
    Func _DebugPrint($s_text)
    $s_text = StringReplace($s_text,@LF,@LF & "-->")
    ConsoleWrite("!===========================================================" & @LF & _
    "+===========================================================" & @LF & _
    "-->" & $s_text & @LF & _
    "+===========================================================" & @LF)
    EndFunc ;==>_DebugPrint

    [/autoit]
  • also aích hab auch erst den error bekommen hab dann aber mal nen anderen account ausprobiert und da ging alles perfekt...

  • ja klingt logisch..mit dem account mit 60 kontakten ist es abgestürzt mein anderes mit 3en ging dagegen..

  • Lag wahrscheinlich wirklich an der zu langen Adlib Funktion.
    Hier die geänderte Variante, bitte mal testen.

    Danke an alle :)

    Spoiler anzeigen
    [autoit]


    #include "_TocLib.au3"
    #include <Timers.au3>
    #include <GUIConstants.au3>

    [/autoit] [autoit][/autoit] [autoit]

    OnAutoItExitRegister("_Exit")

    [/autoit] [autoit][/autoit] [autoit]

    Global $User = "123456789"
    Global $Pass = "passwort"

    [/autoit] [autoit][/autoit] [autoit]

    $hWnd = GUICreate("ICQ - Ersatz", 280, 300)
    $hUser = GUICtrlCreateInput($User, 10, 10, 80, 20)
    $hPass = GUICtrlCreateInput($Pass, 100, 10, 80, 20)
    $hLogin = GUICtrlCreateButton("Login", 190, 10, 80, 20)
    $hList = GUICtrlCreateListView("Nummer|Nickname", 140, 40, 130, 250)

    [/autoit] [autoit][/autoit] [autoit]

    GUISetState(@SW_SHOW)
    While 1
    $msg = GUIGetMsg()
    Switch $msg
    Case $GUI_EVENT_CLOSE
    Exit
    Case $hLogin
    Login()
    EndSwitch

    [/autoit] [autoit][/autoit] [autoit]

    $msg = _TOCGetMsg()
    If $msg == $TOC_CMD_IMRECV Then
    $msg = _TocParseIm()
    If (_Timer_GetIdleTime() > 2000 * 60) Then ;Ist man länger als 2 Minuten abwesend, wird diese Nachricht gesendet:
    _TocSendIM($msg[0], "Bin gerade nicht am PC, versuche es bitte später nochmal.", True)
    _TocSetAway("PC nicht besetzt!")
    EndIf
    EndIf
    If $msg == $TOC_CMD_CONFIG Then
    $msg = _TocParseConfig()
    For $i = 0 To UBound($msg) - 1
    GUICtrlCreateListViewItem($msg[$i], $hList)
    Next
    EndIf
    _TOCClearMsg()
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    Func Login()
    $login = _TocLogin(GUICtrlRead($hUser), GUICtrlRead($hPass))
    If Not $login Then
    If @error == $TOC_ERROR Then
    _DebugPrint("TOC Error: code " & $login)
    Else
    _DebugPrint("_TocLogin @error = " & @error)
    EndIf
    Else
    _DebugPrint("Logged in successfully")
    GUICtrlSetState($hLogin, $GUI_DISABLE)
    _TocInitLoop()
    EndIf
    EndFunc ;==>Login

    [/autoit] [autoit][/autoit] [autoit]

    Func _Exit()
    _TocCleanup()
    EndFunc ;==>_Exit

    [/autoit]

    _TocLib:

    Spoiler anzeigen
    [autoit]


    #cs ----------------------------------------------------------------------------

    AutoIt Version: 3.2.1.12 (beta)
    Script Version: 2.1.1.0
    Author: Daniel "Falcone88" Leong

    Script Function:
    My own UDF for the TOC (Talk To Oscar) Protocol

    Documentation for the protocol itself may be found in the following:
    http://terraim.cvs.sourceforge.net/*checkout*/ter…rc/toc/TOC1.txt
    http://terraim.cvs.sourceforge.net/*checkout*/ter…rc/toc/TOC2.txt

    The following, though a bit dated, was still very helpful:
    http://www2.sys-con.com/ITSG/virtualcd…aton/index.html

    If something isn't in the TOC2 docs, it is the same asin TOC1. Note, of course,
    that the most recent things (IE: as shown in TOC2) must be used.

    List of functions:
    _TocLogin
    _TocFinalizeLogin
    _TocSendIM
    _TocSetAway
    _TocParseIm
    _TocParseConfig <- doesn't do anything yet
    _TocCleanup

    _TocRegisterFunc
    _TocIsRegistered
    _TocInitLoop
    _TocStopLoop
    _TocDoLoop

    _TocRoastPass
    _TocNormalizeName
    _TocNormalizeString
    _TocMakeSigninCode
    _TocMakeFlapPacket
    _TocDecodeFlap
    _TocSendFlap
    _TocSendRaw
    _TocWaitFlap
    _TocGetFlap

    _BinaryNumber
    _BinaryNumberDecode

    #ce ----------------------------------------------------------------------------

    [/autoit] [autoit][/autoit] [autoit]

    #include <Array.au3>

    [/autoit] [autoit][/autoit] [autoit]

    ; @error codes
    Global Const $TOC_TCP_FAIL = 1 ; could not init TCP
    Global Const $TOC_CONNECT_FAIL = 2 ; could not connect to toc server
    Global Const $TOC_SEND_FAIL = 3 ; could not send over TCP for some reason
    Global Const $TOC_ERROR = 4 ; TOC server sent an error code
    Global Const $TOC_NO_HANDLERS = 5 ; no functions to handle inputs defined
    Global Const $TOC_CMD_TOOLONG = 6 ; attempted to send a string to TOC longer than max

    [/autoit] [autoit][/autoit] [autoit]

    ; TOC errors
    #cs
    * General Errors *
    901 - $1 not currently available
    902 - Warning of $1 not currently available
    903 - A message has been dropped, you are exceeding
    the server speed limit

    ;* Admin Errors *
    911 - Error validating input
    912 - Invalid account
    913 - Error encountered while processing request
    914 - Service unavailable

    * Chat Errors *
    950 - Chat in $1 is unavailable.

    * IM & Info Errors *
    960 - You are sending message too fast to $1
    961 - You missed an im from $1 because it was too big.
    962 - You missed an im from $1 because it was sent too fast.

    * Dir Errors *
    970 - Failure
    971 - Too many matches
    972 - Need more qualifiers
    973 - Dir service temporarily unavailable
    974 - Email lookup restricted
    975 - Keyword Ignored
    976 - No Keywords
    977 - Language not supported
    -Update: 977 can also mean no directory information available
    978 - Country not supported
    979 - Failure unknown $1

    * Auth errors *
    980 - Incorrect nickname or password.
    981 - The service is temporarily unavailable.
    982 - Your warning level is currently too high to sign on.
    983 - You have been connecting and
    disconnecting too frequently. Wait 10 minutes and try again.
    If you continue to try, you will need to wait even longer.
    989 - An unknown signon error has occurred $1
    #ce

    [/autoit] [autoit][/autoit] [autoit]

    ; TOC Server -> Client commands
    Global Const $TOC_CMD_SIGNON = "SIGN_ON"
    Global Const $TOC_CMD_IMRECV = "IM_IN_ENC2"
    Global Const $TOC_CMD_CONFIG = "CONFIG2"
    Global Const $TOC_CMD_BUDDY_ACCEPTED = "NEW_BUDDY_REPLY2"
    Global Const $TOC_CMD_CHATRECV = "CHAT_IN_ENC"
    Global Const $TOC_CMD_BUDDY_UPDATE = "UPDATE_BUDDY2"
    Global Const $TOC_CMD_CHAT_UPDATE = "CHAT_UPDATE_BUDDY"
    Global Const $TOC_CMD_CHATINVITE = "CHAT_INVITE"
    Global Const $TOC_CMD_ERROR = "ERROR"
    Global Const $TOC_CMD_ANY = "~ANY~" ; catches anything not registered otherwise

    [/autoit] [autoit][/autoit] [autoit]

    ; FLAP constant crap
    $TOC_FLAP_ON = "FLAPON" & @CRLF & @CRLF
    $TOC_ROAST_STRING = "Tic/Toc"
    $TOC_LANGUAGE = "english"
    $TOC_VERSION = "TIC:TOCLib for Autoit by Dan Leong"
    $TOC_COUNTRY = "US"
    $TOC_MAX_CHAR_LENGTH = 2048
    $TOC_MAX_CHAR_RECV = 8192
    $TOC_SIGNON_TYPE = 1
    $TOC_DATA_TYPE = 2

    [/autoit] [autoit][/autoit] [autoit]

    ; global vars
    Global $currSequence = 0
    Global $tocTcpSocket
    Global $tocVersion = ""
    Global $handleRecvCmd[1]
    Global $handleRecvFunc[1] ; func called on recieved new message
    Global $recvCmdBuffer[1] ; in case we recieve messages too fast, we'll throw extra ones into a buffer
    Global $recvMsgBuffer[1]

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ;
    ; Description: Login to the TOC Server
    ; Parameter(s): $sUser - Username for AIM
    ; $sPass - Password for AIM
    ; $fFinalize - Whether or not to finalize connection (see notes)
    ; $sTocServer - TOC Servername. The default should be fine, but
    ; localhost may be used for testing...
    ; $iTocPort - TOC port to connect to. Again, default should be fine
    ; $sAuthServer - Authentication server. (Allows you to login to AIM)
    ; $iAuthPort - Port of the Auth Server
    ; Requirement(s): None
    ; Return Value(s): On Success - true
    ; On Failure - false and Set
    ; @ERROR to: $TOC_CONNECT_FAIL - Could not connect to TOC server
    ; $TOC_SEND_FAIL - Could not send data to the server
    ; $TOC_ERROR - Recieved an ERROR message from the TOC server
    ; The error number will be set in @extended
    ; Author(s): Dan "Falcone88" Leong
    ; Note(s): If you want to send configurations to the TOC server (say, you're making an AIM client),
    ; you will want to set this to false, send your config, then use _TocFinalizeLogin(). Note
    ; that this must be sent within 30 seconds of _TocLogin()'s return, or the server will drop
    ; the connection.
    ;
    ; The comments on the format of the packets were taken from one of the websites at the top
    ; of this file.
    ;
    ;===============================================================================
    Func _TocLogin($sUser, $sPass, $fFinalize = True, $sTocServer = "toc.oscar.aol.com", $iTocPort = 9898, $sAuthServer = "login.oscar.aol.com", $iAuthPort = 5190)
    If Not TCPStartup() Then
    SetError($TOC_TCP_FAIL)
    Return False
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    $tocTcpSocket = TCPConnect(TCPNameToIP($sTocServer), $iTocPort)

    [/autoit] [autoit][/autoit] [autoit]

    If $tocTcpSocket == -1 Then
    SetError($TOC_CONNECT_FAIL)
    Return False
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    ; initialize FLAP
    $bytes = _TocSendRaw($TOC_FLAP_ON)
    If $bytes == 0 Then
    SetError($TOC_SEND_FAIL)
    Return False
    EndIf
    _DebugPrint("Sent FLAPON")

    [/autoit] [autoit][/autoit] [autoit]

    ; wait for TOC version
    $tocVersion = _TocWaitFlap()
    _DebugPrint("Recieved TOC Version")

    [/autoit] [autoit][/autoit] [autoit]

    ; send "signon" packet
    #cs
    First, the version numbers, then a word of 0x0001. This indicates that a user name will follow.
    The next word represents the length of the screen name. Following the length is the normalized
    representation of the screen name - all spaces are removed and the entire name is converted to lowercase.
    #ce
    $bytes = _TocSendFlap($tocVersion & BinaryString("0x0001") & ( _BinaryNumber(StringLen($sUser))) & _TocNormalizeName($sUser), $TOC_SIGNON_TYPE)
    If $bytes == 0 Then
    SetError($TOC_SEND_FAIL)
    Return False
    EndIf
    _DebugPrint("Sent SIGNON")

    [/autoit] [autoit][/autoit] [autoit]

    ; login
    #cs
    toc2_login <address> <port> <screenname> <roasted pw> <language> <version*> 160 US "" "" 3 0 30303 -kentucky -utf8 76144224***

    * The version string MUST start with "TIC:" otherwise, no dice. For example, "TIC:AIMM" is ok, but "AIMM2" would be rejected.
    ** I have no idea what the parameters after the version are. Put them in verbatim and logging in works.
    *** See _TocMakeSigninCode()
    #ce
    $loginStr = 'toc2_login ' & $sAuthServer & ' ' & $iAuthPort & ' "' & $sUser & '" ' & _TocRoastPass($sPass) & ' "'
    $loginStr &= $TOC_LANGUAGE & '" "' & $TOC_VERSION & '" 160 ' & $TOC_COUNTRY & ' "" "" 3 0 30303 -kentucky -utf8 '
    $loginStr &= _TocMakeSigninCode($sUser, ($sPass))

    [/autoit] [autoit][/autoit] [autoit]

    $bytes = _TocSendFlap($loginStr)
    If $bytes == 0 Then
    SetError($TOC_SEND_FAIL)
    Return False
    EndIf
    _DebugPrint("Sent LOGIN")

    [/autoit] [autoit][/autoit] [autoit]

    $response = _TocWaitFlap(2)
    _DebugPrint(_ArrayToString($response, " "))
    If $response[1] = $TOC_CMD_ERROR Then
    SetError($TOC_ERROR, StringLeft($response[2], 3), False)

    [/autoit] [autoit][/autoit] [autoit]

    ElseIf $response[1] = $TOC_CMD_SIGNON Then
    _DebugPrint("Logged on successfully")

    [/autoit] [autoit][/autoit] [autoit]

    If $fFinalize Then _TocFinalizeLogin()

    [/autoit] [autoit][/autoit] [autoit]

    Return True
    Else
    _DebugPrint("Weird.. I see (" & $response[1] & ")")
    SetError($TOC_ERROR)
    Return False
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    Return False ; just in case
    EndFunc ;==>_TocLogin

    [/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ;
    ; Description: Finalize login to AIM server
    ; Parameter(s): None
    ; Requirement(s): A successful call to _TocLogin()
    ; Return Value(s): Number of bytes sent via TCP
    ;
    ; Author(s): Dan "Falcone88" Leong
    ; Note(s): See _TocLogin()
    ;
    ;===============================================================================
    Func _TocFinalizeLogin()
    Return _TocSendFlap("toc_init_done")
    EndFunc ;==>_TocFinalizeLogin

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ;
    ; Description: Send an IM to specified user via AIM
    ; Parameter(s): $sUser - Target user's AIM screenname
    ; $sMsg - The message to send
    ; $fAuto - Whether or not to specify the message as an auto response
    ; Requirement(s): A successful call to _TocLogin()
    ; Return Value(s): Number of bytes sent via TCP
    ;
    ; Author(s): Dan "Falcone88" Leong
    ; Note(s): None.
    ;
    ;===============================================================================
    Func _TocSendIM($sUser, $sMsg, $fAuto = False)
    Local $packet = 'toc2_send_im ' & _TocNormalizeName($sUser) & ' "'

    [/autoit] [autoit][/autoit] [autoit]

    $packet &= _TocNormalizeString($sMsg) & '"'

    [/autoit] [autoit][/autoit] [autoit]

    If $fAuto Then $packet &= ' auto'
    Return _TocSendFlap($packet)
    EndFunc ;==>_TocSendIM

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ;
    ; Description: Set your away message
    ; Parameter(s): $sMsg - The away message to set
    ;
    ; Requirement(s): A successful call to _TocLogin()
    ; Return Value(s): Number of bytes sent via TCP
    ;
    ; Author(s): Dan "Falcone88" Leong
    ; Note(s): If you call without any arguments, it will set status to
    ; available.
    ;
    ;===============================================================================
    Func _TocSetAway($sMsg = "")
    Return _TocSendFlap('toc_set_away "' & _TocNormalizeString($sMsg) & '"')
    EndFunc ;==>_TocSetAway

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ;
    ; Description: Parse in IM_IN packet from TOC2 into something useful
    ; Parameter(s): $sPacket - The packet data from IM_IN (Just the data part, not FLAP)
    ; Requirement(s): Array.au3
    ; Return Value(s): On Success - An array as follows:
    ; $ret[0] = username from
    ; $ret[1] = auto or not (String "T"/"F")
    ; $ret[2] = buddy status
    ; $ret[3] = message
    ; On Failure - "" and Set @ERROR to 1
    ; Author(s): Dan "Falcone88" Leong
    ; Note(s): $sPacket SHOULD look like this: (I think)
    ; <user>:<auto>:<???>:<???>:<buddy status>:<???>:<???>:en:<message>
    ; Note the omission of IM_IN_ENC2... That's because it's omitted in
    ; the way _TocDoLoop() calls registered functions ;)
    ; Alternatively, it can be an array as returned by _TocGetFlap(2)
    ;
    ;===============================================================================
    Func _TocParseIm()
    Local $ret[4]
    Local $sPacket = StringSplit($recvMsgBuffer[1], ":")
    If @error Then
    SetError(1)
    Return 0
    EndIf
    _ArrayDelete($recvMsgBuffer, 1)
    $recvMsgBuffer[0] -= 1

    [/autoit] [autoit][/autoit] [autoit]

    $ret[0] = $sPacket[1]
    $ret[1] = $sPacket[2]
    $ret[2] = $sPacket[5]
    $ret[3] = _ArrayToString($sPacket, ":", 9)

    [/autoit] [autoit][/autoit] [autoit]

    Return $ret
    EndFunc ;==>_TocParseIm

    [/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ;
    ; Description: Parse a CONFIG2 packet from TOC2 into something useful
    ; Parameter(s): $sPacket - The packet data from CONFIG2 (Just the data part, not FLAP)
    ; Requirement(s): none
    ; Return Value(s): On Success - An array as follows:
    ; $ret[0] = 1. Usernumber | Username
    ; $ret[1] = 2. Usernumber | Username
    ; $ret[2] = 3. Usernumber | Username
    ; ...
    ; Author(s): Dan "Falcone88" Leong
    ; Note(s): Obviously, this does nothing at the moment. Looking at samples,
    ; It so far seems pointless to include this, as there's no really
    ; good way that I can see implementing this as a helpful function
    ; without using some strange 3d array
    ;
    ;===============================================================================
    Func _TocParseConfig()
    Local $aUsers, $i, $reg, $ret[1]
    $aUsers = StringRegExp($recvMsgBuffer[1], "b:(.*?)" & @LF, 3)
    If @error Then
    SetError(1)
    Return 0
    EndIf
    _ArrayDelete($recvMsgBuffer, 1)
    $recvMsgBuffer[0] -= 1
    ;~ ConsoleWrite("-" & $aUsers[0] & @CRLF)
    Local $size = UBound($aUsers)
    ReDim $ret[$size]
    For $i = 0 To UBound($aUsers) - 1
    $reg = StringRegExp($aUsers[$i] & @LF, "(.*?):(.*?)(?::*)" & @LF, 3)
    $ret[$i] = $reg[0] & "|" & BinaryToString(StringToBinary($reg[1], 1), 4) ; User Number & "|" & User Name (UTF8 -> ASCII)
    Next

    [/autoit] [autoit][/autoit] [autoit]

    Return $ret
    EndFunc ;==>_TocParseConfig

    [/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ;
    ; Description: Cleanup the TCP connections and such
    ; Parameter(s): None
    ; Requirement(s): None
    ; Return Value(s): None
    ;
    ; Author(s): Dan "Falcone88" Leong
    ; Note(s): None
    ;
    ;===============================================================================
    Func _TocCleanup()
    _TocStopLoop()
    TCPCloseSocket($tocTcpSocket)
    TCPShutdown()
    EndFunc ;==>_TocCleanup

    [/autoit] [autoit][/autoit] [autoit]

    ;
    ; _TocDoLoop() related functions
    ;

    [/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ;
    ; Description: Register a function to be called upon receiving a given command
    ; Parameter(s): $sCmd - The TOC command to trigger the function
    ; $sFuncName - Name of the user's function to be called upon recieve
    ; Requirement(s): Array.au3
    ; Return Value(s): Always returns true...
    ; Author(s): Dan "Falcone88" Leong
    ; Note(s): The function to be called should expect a single argument,
    ; which will be the exact string arguments provided in the FLAP packet.
    ;
    ;===============================================================================
    Func _TocRegisterFunc($sCmd, $sFuncName)
    $key = _ArraySearch($handleRecvCmd, $sCmd)

    [/autoit] [autoit][/autoit] [autoit]

    If $key == -1 Then
    _ArrayAdd($handleRecvCmd, $sCmd)
    _ArrayAdd($handleRecvFunc, $sFuncName)
    $handleRecvCmd[0] += 1
    $handleRecvFunc[0] += 1
    Else
    $handleRecvFunc[$key] = $sFuncName
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    Return True
    EndFunc ;==>_TocRegisterFunc

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ;
    ; Description: Check if a particular cmd has a function registered with it
    ; Parameter(s): $sCmd - The TOC command to trigger the function
    ; $fReturnIndex - whether to return the index of the cmd (if found)
    ; instead of a boolean
    ; Requirement(s): Array.au3
    ; Return Value(s): On Success - if $fReturnIndex=false, returns TRUE
    ; if $fReturnIndex=true, returns the index of the func
    ; On Failure - FALSE
    ;
    ; Author(s): Dan "Falcone88" Leong
    ; Note(s): $fReturnIndex=true is probably not necessary for the casual
    ; user. I use it as a utility for other functions, though
    ;
    ;===============================================================================
    Func _TocIsRegistered($sCmd, $fReturnIndex = False)
    $key = _ArraySearch($handleRecvCmd, $sCmd)

    [/autoit] [autoit][/autoit] [autoit]

    If $key == -1 Then
    Return False
    Else
    If $fReturnIndex Then
    Return $key
    Else
    Return True
    EndIf
    EndIf
    EndFunc ;==>_TocIsRegistered

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ;
    ; Description: Initialize the AdLib loop that checks for server input and calls
    ; the appropriate registered functions.
    ; Parameter(s): $iDelay - Time in ms between function calls (See definition of AdlibEnable)
    ; Requirement(s): At least one call to _TocRegisterFunc
    ; Return Value(s): On Success - true
    ; On Failure - false and Set @ERROR to $TOC_NO_HANDLERS (No functions registered)
    ; Author(s): Dan "Falcone88" Leong
    ; Note(s): none
    ;
    ;===============================================================================
    Func _TocInitLoop($iDelay = 250)
    ;~ If $handleRecvCmd[0] < 1 Then
    ;~ SetError($TOC_NO_HANDLERS)
    ;~ Return False
    ;~ EndIf

    [/autoit] [autoit][/autoit] [autoit]

    AdlibRegister("_TocDoLoop", $iDelay)
    Return True
    EndFunc ;==>_TocInitLoop

    [/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ;
    ; Description: Stop the AdLib loop. That's about it ;)
    ; Parameter(s): none
    ; Requirement(s): A previous call to _TocInitLoop()... if you want it to do something
    ; Return Value(s): none
    ; Author(s): Dan "Falcone88" Leong
    ; Note(s): none
    ;
    ;===============================================================================
    Func _TocStopLoop()
    AdlibUnRegister()
    EndFunc ;==>_TocStopLoop

    [/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ;
    ; Description: The function called in each loop to parse packets.
    ; Parameter(s): $iDelay - Time in ms between function calls (See definition of AdlibEnable)
    ; Requirement(s): Array.au3
    ; Return Value(s): none
    ; Author(s): Dan "Falcone88" Leong
    ; Note(s): When it finds a handled command, it sends the whole
    ; argument string to that function. The command itself is,
    ; of course, omitted, as you should know what command it's handling.
    ;
    ;===============================================================================
    Func _TocDoLoop()
    Local $packet = TCPRecv($tocTcpSocket, $TOC_MAX_CHAR_RECV)
    ;~ ConsoleWrite($packet & @CRLF)
    If $recvCmdBuffer[0] > 0 Then
    $packet = $recvCmdBuffer[1] & $packet
    _ArrayDelete($recvCmdBuffer, 1)
    $recvCmdBuffer[0] -= 1
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    $decoded = _TocDecodeFlap($packet)
    ;~ If $decoded <> -1 Then ConsoleWrite($decoded[4] & @CRLF)
    ; first, see if we got the whole packet
    If IsArray($decoded) Then
    If $decoded[3] <> StringLen($decoded[4]) Then
    ; if not, enqueue it
    _ArrayAdd($recvCmdBuffer, $packet)
    $recvCmdBuffer[0] += 1
    ; call ourself again to get the rest of the packet
    Else
    _ArrayAdd($recvMsgBuffer, $decoded[4])
    $recvMsgBuffer[0] += 1
    ConsoleWrite("!" & $recvMsgBuffer[1] & @CRLF)
    If StringLen($decoded[5]) Then
    _ArrayAdd($recvCmdBuffer, $decoded[5])
    $recvCmdBuffer[0] += 1
    EndIf
    EndIf
    EndIf
    EndFunc ;==>_TocDoLoop

    [/autoit] [autoit][/autoit] [autoit]

    Func _TOCGetMsg()
    If $recvMsgBuffer[0] > 0 Then
    Local $ret = StringSplit($recvMsgBuffer[1], ":")
    ConsoleWrite($ret[1] & @CRLF)
    Return $ret[1]
    EndIf
    Return ""
    EndFunc ;==>_TOCGetMsg

    [/autoit] [autoit][/autoit] [autoit]

    Func _TOCClearMsg()
    If $recvMsgBuffer[0] > 0 Then
    _ArrayDelete($recvMsgBuffer, 1)
    $recvMsgBuffer[0] -= 1
    Return 1
    EndIf
    Return 0
    EndFunc ;==>_TOCClearMsg
    ;
    ; Util Funcs
    ;

    [/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ;
    ; Description: "Roast" a password. Basically it's a really simple encryption
    ; that TOC requires
    ; Parameter(s): $sOldPass - The unencrypted password
    ; Requirement(s): none
    ; Return Value(s): The "roasted" password
    ; Author(s): Dan "Falcone88" Leong
    ; Note(s): none
    ;
    ;===============================================================================
    Func _TocRoastPass($sOldPass)
    Local $roasted = "0x", $xor_i = 1

    [/autoit] [autoit][/autoit] [autoit]

    For $i = 1 To StringLen($sOldPass)
    $roasted &= Hex(BitXOR(Asc(StringMid($TOC_ROAST_STRING, $xor_i, 1)), Asc(StringMid($sOldPass, $i, 1))), 2)

    [/autoit] [autoit][/autoit] [autoit]

    $xor_i += 1
    If ($xor_i > StringLen($TOC_ROAST_STRING)) Then $xor_i = 1
    Next

    [/autoit] [autoit][/autoit] [autoit]

    Return $roasted
    EndFunc ;==>_TocRoastPass

    [/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ;
    ; Description: "Normalize" a name
    ; Parameter(s): $sString - The string to "normalize"
    ; Requirement(s): none
    ; Return Value(s): The "normalized" name
    ; Author(s): Dan "Falcone88" Leong
    ; Note(s): As you can see, this just removes spaces and puts it in lower
    ; case. This is mostly used for usernames when communicating
    ; with TOC
    ;
    ;===============================================================================
    Func _TocNormalizeName($sString)
    Return StringReplace(StringLower($sString), " ", "")
    EndFunc ;==>_TocNormalizeName

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ;
    ; Description: "Normalize" a string.
    ; Parameter(s): $sString - The string to "normalize"
    ; Requirement(s): none
    ; Return Value(s): The "normalized" string
    ; Author(s): Dan "Falcone88" Leong
    ; Note(s): This changes some characters to something more acceptable to
    ; TOC. This is another function that received help from
    ; BlueTOC
    ;
    ;===============================================================================
    Func _TocNormalizeString($sString)
    $sString = StringReplace($sString, "\", "\\")
    $sString = StringReplace($sString, "$", "\$")
    $sString = StringReplace($sString, '"', '\"')
    $sString = StringReplace($sString, "(", "\(")
    $sString = StringReplace($sString, ")", "\)")
    $sString = StringReplace($sString, "[", "\[")
    $sString = StringReplace($sString, "]", "\]")
    $sString = StringReplace($sString, "{", "\{")
    $sString = StringReplace($sString, "}", "\}")

    [/autoit] [autoit][/autoit] [autoit]

    Return $sString
    EndFunc ;==>_TocNormalizeString

    [/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ;
    ; Description: Create the wierd authentication code needed to login with TOC2
    ; Parameter(s): $sUser - the username being used to log in
    ; $sPass - the password
    ; Requirement(s): none
    ; Return Value(s): The code
    ; Author(s): Ahnugslos (optimized)
    ; Note(s): Original by Dan "Falcone88" Leong
    ;
    ;===============================================================================
    Func _TocMakeSigninCode($sUser, $sPass)
    Return 7696 * Asc(StringLeft($sUser, 1)) * Asc(StringLeft($sPass, 1))
    EndFunc ;==>_TocMakeSigninCode

    [/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ;
    ; Description: Take a TOC command and prepend a FLAP header to it :)
    ; Parameter(s): $iType - The type of packet. Can be:
    ; $TOC_SIGNON_TYPE - used for the signon packet... rarely used
    ; $TOC_DATA_TYPE - used for nearly everything. Default :)
    ; $sData - the command string
    ; Requirement(s): none
    ; Return Value(s): The created packet
    ; Author(s): Dan "Falcone88" Leong
    ; Note(s): This took me FOREVER to figure out. The most annoying
    ; part of this whole library, easily
    ;
    ;===============================================================================
    Func _TocMakeFlapPacket($iType, $sData)
    $currSequence += 1
    If $iType == $TOC_DATA_TYPE Then $sData &= Chr(0)

    [/autoit] [autoit][/autoit] [autoit]

    $btype = _BinaryNumber($iType, 1)
    $bseq = _BinaryNumber(($currSequence))
    $blen = _BinaryNumber(StringLen($sData))

    [/autoit] [autoit][/autoit] [autoit]

    $header = "*" & $btype & $bseq & $blen

    [/autoit] [autoit][/autoit] [autoit]

    Return $header & $sData
    EndFunc ;==>_TocMakeFlapPacket

    [/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ;
    ; Description: Decode a raw FLAP packet
    ; Parameter(s): $bPacket - The packet
    ;
    ; Requirement(s): none
    ; Return Value(s): Success - An array formated as follows:
    ; $ret[0] = "*"
    ; $ret[1] = type
    ; $ret[2] = sequence number
    ; $ret[3] = length of the packet
    ; $ret[4] = the packet itself
    ; $ret[5] = any excess stuff after reading $ret[3] characters
    ; Failure - The original packet, and sets @ERROR = 1
    ; Author(s): Dan "Falcone88" Leong
    ; Note(s): This removes any Chr(0) found in the strings. The fifth index
    ; is included because sometimes packets are sent quickly and
    ; become mixed up. This helps to ensure that all packets
    ; are recieved properly.
    ;
    ;===============================================================================
    Func _TocDecodeFlap($bPacket)
    If BinaryLen($bPacket) < 1 Or Binary(BinaryMid($bPacket, 1, 1)) <> Binary("*") Then
    SetError(1) ; not a proper flap packet, returns -1
    Return -1
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    Local $ret[6]

    [/autoit] [autoit][/autoit] [autoit]

    $ret[0] = "*"
    $ret[1] = _BinaryNumberDecode(BinaryMid($bPacket, 2, 1))
    $ret[2] = _BinaryNumberDecode(BinaryMid($bPacket, 3, 2))
    $ret[3] = _BinaryNumberDecode(BinaryMid($bPacket, 5, 2))
    $ret[4] = StringMid(BinaryToString($bPacket), 7, $ret[3])
    $ret[5] = StringMid(BinaryToString($bPacket), 7 + $ret[3])

    [/autoit] [autoit][/autoit] [autoit]

    Return $ret
    EndFunc ;==>_TocDecodeFlap

    [/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ;
    ; Description: Send a packet to TOC with a FLAP header.
    ; Parameter(s): $sData - The data string to send
    ; $iType - type of packet (See _TocMakeFlapPacket)
    ; $fTruncate - See _TocSendRaw()
    ;
    ; Requirement(s): none
    ; Return Value(s): Number of bytes sent via TCP
    ; Author(s): Dan "Falcone88" Leong
    ; Note(s): $iType is second so it can be optional and default to $TOC_DATA_TYPE,
    ; as that is the most common type
    ;
    ;===============================================================================
    Func _TocSendFlap($sData, $iType = 2, $fTruncate = False)
    _DebugPrint("SENT: " & $sData)
    Return _TocSendRaw( _TocMakeFlapPacket($iType, $sData))
    EndFunc ;==>_TocSendFlap

    [/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ;
    ; Description: Send a raw packet to TOC server
    ; Parameter(s): $bData - The data string to send
    ; $fTruncate - Silently clip $bData if it's too long or not
    ;
    ; Requirement(s): Previous successful call to _TocLogin()
    ; Return Value(s): Success - Number of bytes sent via TCP
    ; Failure - 0, and set @ERROR = $TOC_CMD_TOOLONG
    ; Author(s): Dan "Falcone88" Leong
    ; Note(s): Failure condition only ever occurs if $fTruncate = false. If
    ; $fTruncate = true, this will not issue any errors even if
    ; the string is longer than allowed ($TOC_MAX_CHAR_LENGTH). It
    ; will simply truncate the string to the allowed length
    ;
    ;===============================================================================
    Func _TocSendRaw($bData, $fTruncate = False)
    If Not $fTruncate And StringLen($bData) > $TOC_MAX_CHAR_LENGTH Then
    SetError($TOC_CMD_TOOLONG)
    Return 0
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    Return TCPSend($tocTcpSocket, StringLeft($bData, $TOC_MAX_CHAR_LENGTH))
    EndFunc ;==>_TocSendRaw

    [/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ;
    ; Description: Wait until a packet is recieved from the TOC server
    ; Parameter(s): $iRetType - Return format; See _TocGetFlap
    ;
    ; Requirement(s): Previous successful call to _TocLogin()
    ; Return Value(s): See _TocGetFlap
    ; Author(s): Dan "Falcone88" Leong
    ; Note(s): none
    ;
    ;===============================================================================
    Func _TocWaitFlap($iRetType = 1)
    Local $packet = ""
    Do
    $packet = _TocGetFlap($iRetType)

    [/autoit] [autoit][/autoit] [autoit]

    Until $packet <> -1

    [/autoit] [autoit][/autoit] [autoit]

    Return $packet
    EndFunc ;==>_TocWaitFlap

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ;
    ; Description: Instantaneous (non-blocking) check for a flap packet
    ; Parameter(s): $iRetType - Format for the return value
    ;
    ; Requirement(s): Previous successful call to _TocLogin()
    ; Return Value(s): Success - Returns the packet, depending on $iRetType:
    ; 0 - Full packet, raw (including FLAP header)
    ; 1 - The data part (everything BUT header), raw
    ; 2 - The data part (everything BUT header), split into
    ; an array using ":" as the delimeter
    ; Failure - (No new packet) returns -1
    ; Author(s): Dan "Falcone88" Leong
    ; Note(s): This function looks about 25 lines longer than it needs to be,
    ; but that's because it takes into account packets sent in
    ; really close proximity that consequently might be interpretted as a single packet.
    ; Extra packets are added to $recvCmdBuffer and are inserted before the next recieved
    ; packet in order recieved. (Obviously, there could be a backup if a packet wasn't split up,
    ; which this method accounts for. However, this is not a problem, as the new packet will
    ; be found and added to the end of the buffer.
    ;
    ;===============================================================================
    Func _TocGetFlap($iRetType = 0, $fCalledFromLoop = False)
    Local $decoded, $extraString, $newPacket

    [/autoit] [autoit][/autoit] [autoit]

    Local $packet = TCPRecv($tocTcpSocket, $TOC_MAX_CHAR_RECV)
    ;~ FileWriteLine(@ScriptDir&"\buffer.txt", $packet)
    ;~ FileWriteLine(@ScriptDir&"\buffer.txt", "---------")
    If $recvCmdBuffer[0] > 0 Then
    ;~ _ArrayAdd( $recvCmdBuffer, )
    $packet = $recvCmdBuffer[1] & $packet
    _ArrayDelete($recvCmdBuffer, 1)
    $recvCmdBuffer[0] -= 1
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    $decoded = _TocDecodeFlap($packet)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ; first, see if we got the whole packet
    If IsArray($decoded) Then
    If $decoded[3] <> StringLen($decoded[4]) Then
    ; if not, enqueue it
    _ArrayAdd($recvCmdBuffer, $packet)
    $recvCmdBuffer[0] += 1

    [/autoit] [autoit][/autoit] [autoit]

    ;~ _DebugPrint( "Doin' a loop to get the whole packet :)" )
    ; call ourself again to get the rest of the packet
    Return _TocGetFlap($iRetType)
    EndIf
    Else
    ; not a flap packet, ignore for now
    Return -1
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    ; now process
    If StringLen($packet) > 0 Then
    ; check for extra commands
    If BinaryLen($decoded[5]) > 0 Then
    $extraString = $decoded[5]
    Do ; loop through, enqueing all COMPLETE packets as separate entries
    $newPacket = _TocDecodeFlap($extraString)
    ; FileWriteLine(@ScriptDir&"\buffer.txt", $extraString)
    ; FileWriteLine(@ScriptDir&"\buffer.txt", "---------")
    If IsArray($newPacket) Then
    If $newPacket[0] == "*" Then ; make sure it's actually flap
    _ArrayAdd($recvCmdBuffer, StringLeft($extraString, 6 + $newPacket[3]))
    $recvCmdBuffer[0] += 1

    [/autoit] [autoit][/autoit] [autoit]

    $extraString = $newPacket[5]
    EndIf
    Else
    $extraString = ""
    EndIf
    Until $extraString == ""
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    ;~ FileWriteLine(@ScriptDir&".\buffer.txt", "-------")
    ;~ FileWriteLine(@ScriptDir&".\buffer.txt", "Current packet: "&$packet)
    ;~ FileWriteLine(@ScriptDir&".\buffer.txt", "Excess: " & $decoded[5])
    ;~ FileWriteLine(@ScriptDir&".\buffer.txt", "Buffer: ")
    ;~
    ;~ for $i=1 to $recvCmdBuffer[0]
    ;~ FileWriteLine(@ScriptDir&".\buffer.txt", $recvCmdBuffer[$i] & @CRLF&"<>"&@CRLF )
    ;~ Next
    ;~
    ;~ FileWriteLine(@ScriptDir&".\buffer.txt", "-------")

    [/autoit] [autoit][/autoit] [autoit]

    _DebugPrint("Received: " & $decoded[4])
    Switch $iRetType
    Case 0
    Return $packet
    Case 1
    Return $decoded[4]
    Case 2
    Return StringSplit($decoded[4], ":")
    EndSwitch
    Else
    Return -1
    EndIf
    EndFunc ;==>_TocGetFlap

    [/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ;
    ; Description: Convert a number to the necessary binary format, padding the
    ; beginning with Chr(0) until it's the appropriate $iLength
    ; Parameter(s): $iNum - The number to be converted
    ; $iLength - The desired length
    ; Requirement(s): none
    ; Return Value(s): The converted number
    ; Author(s): Dan "Falcone88" Leong
    ; Note(s): It took me forever to figure out how I was supposed to do this!
    ; For $iLength:
    ; byte = 1
    ; word = 2
    ; dword = 4
    ; qword = 8
    ;
    ;===============================================================================
    Func _BinaryNumber($iNum, $iLength = 2)
    Local $b, $numStarted = False, $out = "", $prepend = ""

    [/autoit] [autoit][/autoit] [autoit]

    $b = Binary($iNum)
    For $i = BinaryLen($b) To 1 Step -1
    If Chr(BinaryMid($b, $i, 1)) <> Chr(0) Or $numStarted Then
    If Not $numStarted Then $numStarted = True
    $out &= Chr(BinaryMid($b, $i, 1))
    EndIf
    Next

    [/autoit] [autoit][/autoit] [autoit]

    If BinaryLen($out) < $iLength Then
    For $i = 1 To $iLength - BinaryLen($out)
    $prepend &= Chr(0)
    Next
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    Return $prepend & $out

    [/autoit] [autoit][/autoit] [autoit]

    EndFunc ;==>_BinaryNumber

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func BinaryString($sData)
    Local $b = Binary($sData)
    Local $out = ""

    [/autoit] [autoit][/autoit] [autoit]

    For $i = 1 To BinaryLen($b)
    $out &= Chr(BinaryMid($b, $i, 1))
    Next

    [/autoit] [autoit][/autoit] [autoit]

    Return $out
    EndFunc ;==>BinaryString

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ;
    ; Description: Convert a number from the necessary binary format to a
    ; usable number
    ; Parameter(s): $iNum - The number to be converted

    [/autoit] [autoit][/autoit] [autoit]

    ;
    ; Requirement(s): none
    ; Return Value(s): The converted number
    ; Author(s): Dan "Falcone88" Leong
    ; Note(s): It took me forever to figure out how I was supposed to do this.
    ; I finally made this magical. Hopefully it still works
    ; properly....
    ;
    ;===============================================================================
    Func _BinaryNumberDecode($iNum)

    [/autoit] [autoit][/autoit] [autoit]

    ; A shortcut!
    If StringInStr(String($iNum), "0x") Then
    $iNum = StringMid(String($iNum), 3)
    Return Dec($iNum)
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    $iOffset = 1
    While StringMid(String($iNum), $iOffset, 2) == "00"
    $iOffset += 2
    WEnd
    $sTrim = StringMid($iNum, $iOffset)
    $iLength = StringLen($sTrim)
    $iVal = 0

    [/autoit] [autoit][/autoit] [autoit]

    For $i = 1 To $iLength
    $iVal += Number(String(Asc(StringMid($sTrim, $i, 1)))) * (16 ^ (2 * ($iLength - $i)))
    Next

    [/autoit] [autoit][/autoit] [autoit]

    Return $iVal
    EndFunc ;==>_BinaryNumberDecode

    [/autoit] [autoit][/autoit] [autoit]

    ;
    ; This is not my method, but was very helpful, and I don't want to delete all of the calls
    ; to it... just in case. So there :P
    ;
    Func _DebugPrint($s_text)
    $s_text = StringReplace($s_text, @LF, @LF & "-->")
    ConsoleWrite("!===========================================================" & @LF & _
    "+===========================================================" & @LF & _
    "-->" & $s_text & @LF & _
    "+===========================================================" & @LF)
    EndFunc ;==>_DebugPrint

    [/autoit]
  • also bei mir kommt immer folgender Fehler:

    Code
    C:\Users\Marcel\Desktop\_TocLib.au3 (369) : ==> Subscript used with non-Array variable.:
    $ret[$i] = $reg[0] & "|" & BinaryToString(StringToBinary($reg[1], 1), 4)
    $ret[$i] = $reg^ ERROR
    ->16:44:02 AutoIT3.exe ended.rc:1
    >Exit code: 1	Time: 11.975