Jump to content

Multiclient chat server!


Coolw
 Share

Recommended Posts

For something my teacher asked me to do on my own time, this has actually worked out pretty well.

It uses Kip's event based TCP UDF. (http://www.autoitscript.com/forum/index.php?showtopic=74325&hl=tcp)

The use of this program in class will allow teachers to start the server, allow the students to connect to the server, and they can get help from the teacher from across the room.

Features:

-Infinite number of clients

-Simple and easy to use

-Name is based off your (windows) login name

-Timestamps!

-Client list on both server and client

-Server can see client name and corresponding IP

Things I am working on:

-Kick feature for server

-The server owner name is colored (so it stands out)

-Screen view feature for the currently selected client

-Better way to do the clients client list

Ok here it is:

Server:

CODE
#Include <Array.au3>

#include <ButtonConstants.au3>

#include <EditConstants.au3>

#include <GUIConstantsEx.au3>

#Include <GuiEdit.au3>

#Include <GuiListView.au3>

#Include <GuiMenu.au3>

#include <TCP.au3>

#include <WindowsConstants.au3>

$clientdisconnect = 0

Dim $clients[10]

Dim $clientname[10]

$clientsconnected = 1

$clients[0] = @UserName & " | " & @IPAddress1

$clientname[0] = @UserName & " - Host"

GUICreate("Server", 600, 500)

$clist = GUICtrlCreateListView("Client Name|IP", 10, 10, 230, 400)

$kick = GUICtrlCreateButton("Kick", 10, 420, 115)

;GUICtrlCreateButton("TEST", 130, 420, 110)

$chatboxlabel = GUICtrlCreateLabel("Chat Box", 250, 10)

$chatbox = GUICtrlCreateEdit("", 250, 30, 230, 350, BitOR($ES_READONLY, $ES_AUTOVSCROLL, $WS_VSCROLL), $WS_EX_CLIENTEDGE)

$chatinput = GUICtrlCreateEdit("", 250, 390, 230, 95, BitOR($ES_MULTILINE, $WS_VSCROLL), $WS_EX_CLIENTEDGE)

$send = GUICtrlCreateButton("Send", 490, 455, 100, 30, $BS_DEFPUSHBUTTON )

GUICtrlCreateListViewItem($clients[0], $clist)

$filemenu = GUICtrlCreateMenu("File")

$exit = GUICtrlCreateMenuItem("Exit", $filemenu)

$optionmenu = GUICtrlCreateMenu("Options")

$timestamp = GUICtrlCreateMenuItem("Timestamp", $optionmenu, 0 , 1)

GUISetState()

$hServer = _TCP_Server_Create(12345, @IPAddress1) ;Create a server on port

_TCP_RegisterEvent($hServer, $TCP_NEWCLIENT, "NewClient") ;NewClient get's called when a new client connects to the server.

_TCP_RegisterEvent($hServer, $TCP_DISCONNECT, "Disconnect") ;Disconnect will get called when a client disconnects.

_TCP_RegisterEvent($hServer, $TCP_RECEIVE, "Received"); Function "Received" will get called when something is received

$msg = GUIGetMsg()

$time = TimerInit()

While $msg <> -3 or $msg <> $exit

$msg = GUIGetMsg()

Select

Case $msg = $send

If GUICtrlRead($chatinput) <> "" Then

_TCP_Server_Broadcast(@UserName & GUICtrlRead($chatinput))

If BitAnd(GUICtrlRead($timestamp),$GUI_CHECKED) = $GUI_CHECKED Then

_GUICtrlEdit_AppendText($chatbox, @CRLF & "[" &@HOUR & ":" & @MIN & ":" & @SEC & "] " & @UserName & ": " & GUICtrlRead($chatinput))

Else

_GUICtrlEdit_AppendText($chatbox, @CRLF & @UserName & ": " & GUICtrlRead($chatinput))

EndIf

GUICtrlSetData($chatinput, "")

EndIf

Case $msg = $kick

;$selected = _GUICtrlListView_GetSelectedIndices($clist, True)

;$kickname = _GUICtrlListView_GetItemText($clist, $selected)

;$kickip = _GUICtrlListView_GetItemText($clist, $selected, 1)

;MsgBox(0, "", $kickname & @CRLF & $kickip)

Case $msg = -3 or $msg = $exit

Exit

EndSelect

If TimerDiff($time) >= 5000 Then

$clientlist = "##list" & $clientsconnected & _ArrayToString($clientname, "|", 0, $clientsconnected)

$time = TimerInit()

_TCP_Server_Broadcast($clientlist)

EndIf

WEnd

Func Received($hServer, $sReceived, $iError); And we also registered this! Our homemade do-it-yourself function gets called when something is received.

If StringLeft($sReceived, 10) = "##username" Then

If BitAnd(GUICtrlRead($timestamp),$GUI_CHECKED) = $GUI_CHECKED Then

_GUICtrlEdit_AppendText($chatbox, @CRLF & "[" &@HOUR & ":" & @MIN & ":" & @SEC & "] Client Connected!")

Else

_GUICtrlEdit_AppendText($chatbox, @CRLF & "Client Connected!")

EndIf

$clientnamestripped = StringMid($sReceived, 11)

$clients[$clientsconnected] = GUICtrlCreateListViewItem($clientnamestripped & "|" & _TCP_Server_ClientIP($hServer), $clist)

$clientname[$clientsconnected] = $clientnamestripped

$clientsconnected = $clientsconnected + 1

ReDim $clients[$clientsconnected + 1]

ReDim $clientname[$clientsconnected + 1]

ElseIf StringLeft($sReceived, 12) = "##disconnect" Then

If BitAnd(GUICtrlRead($timestamp),$GUI_CHECKED) = $GUI_CHECKED Then

_GUICtrlEdit_AppendText($chatbox, @CRLF & "[" &@HOUR & ":" & @MIN & ":" & @SEC & "] Client Disconnected!")

Else

_GUICtrlEdit_AppendText($chatbox, @CRLF & "Client Disconnected!")

EndIf

For $i = 0 To $clientsconnected - 1 Step 1

If StringMid($sReceived, 13) = $clientname[$i] Then

GUICtrlDelete($clients[$i])

$clientsconnected = $clientsconnected - 1

_ArrayDelete($clientname, $i)

ReDim $clients[$clientsconnected + 1]

ReDim $clientname[$clientsconnected + 1]

EndIf

Next

Else

If BitAnd(GUICtrlRead($timestamp),$GUI_CHECKED) = $GUI_CHECKED Then

_GUICtrlEdit_AppendText($chatbox, @CRLF & "[" &@HOUR & ":" & @MIN & ":" & @SEC & "] " & $sReceived)

Else

_GUICtrlEdit_AppendText($chatbox, @CRLF & $sReceived)

EndIf

_TCP_Server_Broadcast($sReceived)

EndIf

EndFunc

Func OnAutoItExit()

_TCP_Server_Broadcast("##serversd")

_TCP_Server_Stop()

EndFunc

Client:

CODE
#Region ;**** Directives created by AutoIt3Wrapper_GUI ****

#AutoIt3Wrapper_outfile=Client.exe

#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****

#Include <Array.au3>

#include <ButtonConstants.au3>

#include <EditConstants.au3>

#include <GUIConstantsEx.au3>

#Include <GuiEdit.au3>

#Include <GuiListView.au3>

#include <TCP.au3>

#include <WindowsConstants.au3>

Dim $clientlist[1]

$name = @UserName

GUICreate("Client - " & $name, 600, 500)

$clist = GUICtrlCreateListView("Client names", 10, 10, 230, 480)

$chatboxlabel = GUICtrlCreateLabel("Chat Box", 250, 10)

$chatbox = GUICtrlCreateEdit("", 250, 30, 230, 350, BitOR($ES_READONLY, $WS_VSCROLL), $WS_EX_CLIENTEDGE)

$chatinput = GUICtrlCreateEdit("", 250, 390, 230, 95, BitOR($ES_MULTILINE, $WS_VSCROLL), $WS_EX_CLIENTEDGE)

$send = GUICtrlCreateButton("Send", 490, 455, 100, 30, $BS_DEFPUSHBUTTON)

$filemenu = GUICtrlCreateMenu("File")

$exit = GUICtrlCreateMenuItem("Exit", $filemenu)

$optionmenu = GUICtrlCreateMenu("Options")

$timestamp = GUICtrlCreateMenuItem("Timestamp", $optionmenu, 0 , 1)

GUISetState()

$hClient = _TCP_Client_Create(@IPAddress1, 12345)

_TCP_RegisterEvent($hClient, $TCP_RECEIVE, "Received"); Function "Received" will get called when something is received

_TCP_RegisterEvent($hClient, $TCP_CONNECT, "Connected"); And func "Connected" will get called when the client is connected.

_TCP_RegisterEvent($hClient, $TCP_DISCONNECT, "Disconnected"); And "Disconnected" will get called when the server disconnects us, or when the connection is lost.

$msg = GUIGetMsg()

While $msg <> -3 Or $msg <> $exit

$msg = GUIGetMsg()

Select

Case $msg = $send

If GUICtrlRead($chatinput) <> "" Then

_TCP_Send($hClient, $name & ": " & GUICtrlRead($chatinput))

GUICtrlSetData($chatinput, "")

EndIf

Case $msg = -3 Or $msg = $exit

Exit

EndSelect

WEnd

Func Received($hClient, $sReceived, $iError); And we also registered this! Our homemade do-it-yourself function gets called when something is received.

If $sReceived == "##serversd" Then

If BitAnd(GUICtrlRead($timestamp),$GUI_CHECKED) = $GUI_CHECKED Then

_GUICtrlEdit_AppendText($chatbox, @CRLF & "[" &@HOUR & ":" & @MIN & ":" & @SEC & "] Lost connection to server or disconnected!")

Else

_GUICtrlEdit_AppendText($chatbox, @CRLF & "Lost connection to server or disconnected!")

EndIf

ElseIf StringLeft($sReceived, 6) = "##list" Then

_GUICtrlListView_DeleteAllItems($clist)

ReDim $clientlist[stringMid($sReceived, 7, 1)]

$clientlist = StringSplit(StringMid($sReceived, 8), "|")

For $i = 1 To ($clientlist[0] - 1)

GUICtrlCreateListViewItem($clientlist[$i], $clist)

Next

Else

If BitAnd(GUICtrlRead($timestamp),$GUI_CHECKED) = $GUI_CHECKED Then

_GUICtrlEdit_AppendText($chatbox, @CRLF & "[" &@HOUR & ":" & @MIN & ":" & @SEC & "] " & $sReceived)

Else

_GUICtrlEdit_AppendText($chatbox, @CRLF & $sReceived)

EndIf

EndIf

EndFunc

Func Connected($hClient, $iError); We registered this (you see?), When we're connected (or not) this function will be called.

If not $iError Then; If there is no error...

Sleep(1000)

_TCP_Send($hClient, "##username" & $name)

If BitAnd(GUICtrlRead($timestamp),$GUI_CHECKED) = $GUI_CHECKED Then

_GUICtrlEdit_AppendText($chatbox, @CRLF & "[" &@HOUR & ":" & @MIN & ":" & @SEC & "] Connected to server!")

Else

_GUICtrlEdit_AppendText($chatbox, "Connected to server!")

EndIf

Else; ,else...

MsgBox(0, "Error", "Could not connect to server!")

EndIf

EndFunc

Func Disconnect($hClient, $iError) ;Client Left

Sleep(1000)

_TCP_Send($hClient, "##disconnect" & $name)

If BitAnd(GUICtrlRead($timestamp),$GUI_CHECKED) = $GUI_CHECKED Then

_GUICtrlEdit_AppendText($chatbox, @CRLF & "[" &@HOUR & ":" & @MIN & ":" & @SEC & "] Lost connection to server or disconnected!")

Else

_GUICtrlEdit_AppendText($chatbox, "Lost connection to server or disconnected!")

EndIf

EndFunc

Func OnAutoItExit()

Sleep(500)

_TCP_Send($hClient, "##disconnect" & $name)

_TCP_Client_Stop($hClient)

EndFunc

TCP.au3:

CODE
#cs ----------------------------------------------------------------------------

AutoIt Version: 3.3.0.0

Author: Kip

Script Function:

TCP UDF v3

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

#cs

Functions:

_TCP_Server_Create($iPort, $sIP="0.0.0.0")

_TCP_Server_Broadcast($sData)

_TCP_Server_ClientList()

_TCP_Server_ClientIP($hSocket)

_TCP_Server_DisconnectClient($hSocket)

_TCP_Server_Stop()

_TCP_Client_Create($sIP , $iPort)

_TCP_Client_Stop($hSocket)

_TCP_Send($hSocket, $sText)

_TCP_RegisterEvent($hSocket, $iEvent, $sFunction)

Register event values:

$TCP_SEND ; Function ($hSocket, $iError)

$TCP_RECEIVE ; Function ($hSocket, $sReceived, $iError)

$TCP_CONNECT ; Function ($hSocket, $iError) => Client only

$TCP_DISCONNECT ; Function ($hSocket, $iError)

$TCP_NEWCLIENT ; Function ($hSocket, $iError) => Server only

#ce

Global Const $FD_READ = 1

Global Const $FD_WRITE = 2

Global Const $FD_OOB = 4

Global Const $FD_ACCEPT = 8

Global Const $FD_CONNECT = 16

Global Const $FD_CLOSE = 32

Local $hWs2_32 = -1

Global Const $TCP_SEND = 1

Global Const $TCP_RECEIVE = 2

Global Const $TCP_CONNECT = 4

Global Const $TCP_DISCONNECT = 8

Global Const $TCP_NEWCLIENT = 16

TCPStartup()

Global Const $__TCP_WINDOW = GUICreate("Async Sockets UDF")

Global $__TCP_SOCKETS[1][7]

Func _TCP_Server_Create($iPort, $sIP="0.0.0.0")

$hListenSocket = _ASocket( )

_ASockSelect( $hListenSocket, $__TCP_WINDOW, 0x0400, $FD_ACCEPT)

GUIRegisterMsg( 0x0400, "__TCP_OnAccept" )

_ASockListen( $hListenSocket, $sIP, $iPort )

$__TCP_SOCKETS[0][0] = $hListenSocket

$__TCP_SOCKETS[0][1] = 0x0400

Return $hListenSocket

EndFunc

Func __TCP_OnAccept($hWnd, $iMsgID, $WParam, $LParam)

Local $hSocket = $WParam

Local $iError = _HiWord( $LParam )

Local $iEvent = _LoWord( $LParam )

If $iMsgID = $__TCP_SOCKETS[0][1] Then

If $iEvent = $FD_ACCEPT Then

If Not $iError Then

ReDim $__TCP_SOCKETS[uBound($__TCP_SOCKETS)+1][7]

$uBound = UBound($__TCP_SOCKETS)

$hClient = TCPAccept($hSocket)

_ASockSelect($hClient, $__TCP_WINDOW, 0x0400 + $uBound - 1, BitOR($FD_READ, $FD_WRITE, $FD_CLOSE))

GUIRegisterMsg(0x0400 + $uBound - 1, "__TCP_Server_OnSocketEvent" )

$__TCP_SOCKETS[uBound($__TCP_SOCKETS)-1][0] = $hClient

$__TCP_SOCKETS[uBound($__TCP_SOCKETS)-1][1] = 0x0400 + $uBound - 1

Call($__TCP_SOCKETS[0][6], $hClient, $iError)

Else

Call($__TCP_SOCKETS[0][6], 0, $iError)

EndIf

ElseIf $iEvent = $FD_CONNECT Then

Call($__TCP_SOCKETS[0][4], $hSocket, $iError)

EndIf

EndIf

EndFunc

Func _TCP_Client_Stop($hSocket)

$iElement = 0

For $i = 1 to UBound($__TCP_SOCKETS)-1

If $__TCP_SOCKETS[$i][0] = $hSocket Then

$iElement = $i

ExitLoop

EndIf

Next

If $iElement Then

_ASockShutdown($__TCP_SOCKETS[$iElement][0])

TCPCloseSocket($__TCP_SOCKETS[$iElement][0])

___ArrayDelete($__TCP_SOCKETS, $iElement)

Return 1

EndIf

Return 0

EndFunc

Func _TCP_Server_Stop()

_ASockShutdown($__TCP_SOCKETS[0][0])

TCPCloseSocket($__TCP_SOCKETS[0][0])

$__TCP_SOCKETS[0][0] = ""

$__TCP_SOCKETS[0][1] = ""

$__TCP_SOCKETS[0][2] = ""

$__TCP_SOCKETS[0][3] = ""

$__TCP_SOCKETS[0][4] = ""

$__TCP_SOCKETS[0][5] = ""

$__TCP_SOCKETS[0][6] = ""

For $i = UBound($__TCP_SOCKETS)-1 to 1 Step -1

___ArrayDelete($__TCP_SOCKETS, $i)

Next

Return 1

EndFunc

Func __TCP_Server_OnSocketEvent( $hWnd, $iMsgID, $WParam, $LParam )

Local $hSocket = $WParam

Local $iError = _HiWord( $LParam )

Local $iEvent = _LoWord( $LParam )

Local $sDataBuff

$hSocket = 0

$iElement = 0

For $i = 1 to UBound($__TCP_SOCKETS)-1

If $__TCP_SOCKETS[$i][1] = $iMsgID Then

$hSocket = $__TCP_SOCKETS[$i][0]

$iElement = $i

ExitLoop

EndIf

Next

If $hSocket Then

Switch $iEvent

Case $FD_READ

$sDataBuff = TCPRecv($hSocket, 1024)

Call($__TCP_SOCKETS[0][2], $hSocket, $sDataBuff, $iError)

Case $FD_WRITE

Call($__TCP_SOCKETS[0][3], $hSocket, $iError)

Case $FD_CLOSE

_ASockShutdown($hSocket)

TCPCloseSocket($hSocket)

Call($__TCP_SOCKETS[0][5], $hSocket, $iError)

___ArrayDelete($__TCP_SOCKETS, $iElement)

EndSwitch

EndIf

EndFunc

Func _TCP_Server_DisconnectClient($hSocket)

$iElement = 0

For $i = 1 to UBound($__TCP_SOCKETS)-1

If $__TCP_SOCKETS[$i][0] = $hSocket Then

$iElement = $i

ExitLoop

EndIf

Next

If $iElement Then

_ASockShutdown($hSocket)

TCPCloseSocket($hSocket)

___ArrayDelete($__TCP_SOCKETS, $iElement)

Return 1

EndIf

Return 0

EndFunc

Func _TCP_Server_ClientList()

Local $aReturn[1]

For $i = 1 to UBound($__TCP_SOCKETS)-1

If $__TCP_SOCKETS[$i][0] Then

ReDim $aReturn[uBound($aReturn)+1]

$aReturn[uBound($aReturn)-1] = $__TCP_SOCKETS[$i][0]

EndIf

Next

$aReturn[0] = UBound($aReturn)-1

Return $aReturn

EndFunc

Func _TCP_Server_Broadcast($sData)

For $i = 1 to UBound($__TCP_SOCKETS)-1

If $__TCP_SOCKETS[$i][0] Then TCPSend($__TCP_SOCKETS[$i][0], $sData)

Next

EndFunc

Func _TCP_Client_Create($sIP , $iPort)

ReDim $__TCP_SOCKETS[uBound($__TCP_SOCKETS)+1][7]

$uBound = UBound($__TCP_SOCKETS)

$hSocket = _ASocket()

$__TCP_SOCKETS[uBound($__TCP_SOCKETS)-1][0] = $hSocket

$__TCP_SOCKETS[uBound($__TCP_SOCKETS)-1][1] = 0x0400 + (UBound($__TCP_SOCKETS)-1)

_ASockSelect( $hSocket, $__TCP_WINDOW, 0x0400 + (UBound($__TCP_SOCKETS)-1), BitOR( $FD_READ, $FD_WRITE, $FD_CONNECT, $FD_CLOSE ) )

GUIRegisterMsg( 0x0400 + (UBound($__TCP_SOCKETS)-1), "__TCP_Client_OnSocketEvent" )

_ASockConnect( $hSocket, $sIP, $iPort )

Return $hSocket

EndFunc

Func _TCP_RegisterEvent($hSocket, $iEvent, $sFunction)

Local $iSelected = 0

If $__TCP_SOCKETS[0][0] Then

$iSelected = 0

Else

For $i = 0 to UBound($__TCP_SOCKETS)-1

If $__TCP_SOCKETS[$i][0] = $hSocket Then

$iSelected = $i

ExitLoop

EndIf

Next

If Not $iSelected Then Return 0

EndIf

Switch $iEvent

Case $TCP_SEND

$__TCP_SOCKETS[$iSelected][3] = $sFunction

Case $TCP_RECEIVE

$__TCP_SOCKETS[$iSelected][2] = $sFunction

Case $TCP_CONNECT

$__TCP_SOCKETS[$iSelected][4] = $sFunction

Case $TCP_DISCONNECT

$__TCP_SOCKETS[$iSelected][5] = $sFunction

Case $TCP_NEWCLIENT

$__TCP_SOCKETS[$iSelected][6] = $sFunction

Case Else

Return 0

EndSwitch

Return 1

EndFunc

Func _TCP_Server_ClientIP($hSocket)

Local $pSocketAddress, $aReturn

$pSocketAddress = DllStructCreate("short;ushort;uint;char[8]")

$aReturn = DllCall("Ws2_32.dll", "int", "getpeername", "int", $hSocket, "ptr", DllStructGetPtr($pSocketAddress), "int*", DllStructGetSize($pSocketAddress))

If @error Or $aReturn[0] <> 0 Then Return 0

$aReturn = DllCall("Ws2_32.dll", "str", "inet_ntoa", "int", DllStructGetData($pSocketAddress, 3))

If @error Then Return 0

$pSocketAddress = 0

Return $aReturn[0]

EndFunc

Func _TCP_Send($hSocket, $sText)

Return TCPSend($hSocket, $sText)

EndFunc

Func __TCP_Client_OnSocketEvent( $hWnd, $iMsgID, $WParam, $LParam )

Local $iError = _HiWord( $LParam )

Local $iEvent = _LoWord( $LParam )

$hSocket = 0

$iElement = 0

For $i = 1 to UBound($__TCP_SOCKETS)-1

If $__TCP_SOCKETS[$i][1] = $iMsgID Then

$hSocket = $__TCP_SOCKETS[$i][0]

$iElement = $i

ExitLoop

EndIf

Next

If $hSocket Then

Switch $iEvent

Case $FD_READ; Data has arrived!

$sDataBuff = TCPRecv( $hSocket, 1024)

Call($__TCP_SOCKETS[$i][2], $hSocket, $sDataBuff, $iError)

$sDataBuff = ""

Case $FD_WRITE

Call($__TCP_SOCKETS[$i][3], $hSocket, $iError)

Case $FD_CONNECT

Call($__TCP_SOCKETS[$i][4], $hSocket, $iError)

Case $FD_CLOSE

_ASockShutdown( $hSocket )

TCPCloseSocket( $hSocket )

Call($__TCP_SOCKETS[$i][5], $hSocket, $iError)

___ArrayDelete($__TCP_SOCKETS, $iElement)

EndSwitch

EndIf

EndFunc

;===================================================================================================

===============

;

; Zatorg's Asynchronous Sockets UDF Starts from here.

;

;===================================================================================================

===============

Func _ASocket($iAddressFamily = 2, $iType = 1, $iProtocol = 6)

If $hWs2_32 = -1 Then $hWs2_32 = DllOpen( "Ws2_32.dll" )

Local $hSocket = DllCall($hWs2_32, "uint", "socket", "int", $iAddressFamily, "int", $iType, "int", $iProtocol)

If @error Then

SetError(1, @error)

Return -1

EndIf

If $hSocket[ 0 ] = -1 Then

SetError(2, _WSAGetLastError())

Return -1

EndIf

Return $hSocket[ 0 ]

EndFunc ;==>_ASocket

Func _ASockShutdown($hSocket)

If $hWs2_32 = -1 Then $hWs2_32 = DllOpen( "Ws2_32.dll" )

Local $iRet = DllCall($hWs2_32, "int", "shutdown", "uint", $hSocket, "int", 2)

If @error Then

SetError(1, @error)

Return False

EndIf

If $iRet[ 0 ] <> 0 Then

SetError(2, _WSAGetLastError())

Return False

EndIf

Return True

EndFunc ;==>_ASockShutdown

Func _ASockClose($hSocket)

If $hWs2_32 = -1 Then $hWs2_32 = DllOpen( "Ws2_32.dll" )

Local $iRet = DllCall($hWs2_32, "int", "closesocket", "uint", $hSocket)

If @error Then

SetError(1, @error)

Return False

EndIf

If $iRet[ 0 ] <> 0 Then

SetError(2, _WSAGetLastError())

Return False

EndIf

Return True

EndFunc ;==>_ASockClose

Func _ASockSelect($hSocket, $hWnd, $uiMsg, $iEvent)

If $hWs2_32 = -1 Then $hWs2_32 = DllOpen( "Ws2_32.dll" )

Local $iRet = DllCall( _

$hWs2_32, _

"int", "WSAAsyncSelect", _

"uint", $hSocket, _

"hwnd", $hWnd, _

"uint", $uiMsg, _

"int", $iEvent _

)

If @error Then

SetError(1, @error)

Return False

EndIf

If $iRet[ 0 ] <> 0 Then

SetError(2, _WSAGetLastError())

Return False

EndIf

Return True

EndFunc ;==>_ASockSelect

; Note: you can see that $iMaxPending is set to 5 by default.

; IT DOES NOT MEAN THAT DEFAULT = 5 PENDING CONNECTIONS

; 5 == SOMAXCONN, so don't worry be happy

Func _ASockListen($hSocket, $sIP, $uiPort, $iMaxPending = 5); 5 == SOMAXCONN => No need to change it.

Local $iRet

Local $stAddress

If $hWs2_32 = -1 Then $hWs2_32 = DllOpen( "Ws2_32.dll" )

$stAddress = __SockAddr($sIP, $uiPort)

If @error Then

SetError(@error, @extended)

Return False

EndIf

$iRet = DllCall($hWs2_32, "int", "bind", "uint", $hSocket, "ptr", DllStructGetPtr($stAddress), "int", DllStructGetSize($stAddress))

If @error Then

SetError(3, @error)

Return False

EndIf

If $iRet[ 0 ] <> 0 Then

$stAddress = 0; Deallocate

SetError(4, _WSAGetLastError())

Return False

EndIf

$iRet = DllCall($hWs2_32, "int", "listen", "uint", $hSocket, "int", $iMaxPending)

If @error Then

SetError(5, @error)

Return False

EndIf

If $iRet[ 0 ] <> 0 Then

$stAddress = 0; Deallocate

SetError(6, _WSAGetLastError())

Return False

EndIf

Return True

EndFunc ;==>_ASockListen

Func _ASockConnect($hSocket, $sIP, $uiPort)

Local $iRet

Local $stAddress

If $hWs2_32 = -1 Then $hWs2_32 = DllOpen( "Ws2_32.dll" )

$stAddress = __SockAddr($sIP, $uiPort)

If @error Then

SetError(@error, @extended)

Return False

EndIf

$iRet = DllCall($hWs2_32, "int", "connect", "uint", $hSocket, "ptr", DllStructGetPtr($stAddress), "int", DllStructGetSize($stAddress))

If @error Then

SetError(3, @error)

Return False

EndIf

$iRet = _WSAGetLastError()

If $iRet = 10035 Then; WSAEWOULDBLOCK

Return True; Asynchronous connect attempt has been started.

EndIf

SetExtended(1); Connected immediately

Return True

EndFunc ;==>_ASockConnect

; A wrapper function to ease all the pain in creating and filling the sockaddr struct

Func __SockAddr($sIP, $iPort, $iAddressFamily = 2)

Local $iRet

Local $stAddress

If $hWs2_32 = -1 Then $hWs2_32 = DllOpen( "Ws2_32.dll" )

$stAddress = DllStructCreate("short; ushort; uint; char[8]")

If @error Then

SetError(1, @error)

Return False

EndIf

DllStructSetData($stAddress, 1, $iAddressFamily)

$iRet = DllCall($hWs2_32, "ushort", "htons", "ushort", $iPort)

DllStructSetData($stAddress, 2, $iRet[ 0 ])

$iRet = DllCall($hWs2_32, "uint", "inet_addr", "str", $sIP)

If $iRet[ 0 ] = 0xffffffff Then; INADDR_NONE

$stAddress = 0; Deallocate

SetError(2, _WSAGetLastError())

Return False

EndIf

DllStructSetData($stAddress, 3, $iRet[ 0 ])

Return $stAddress

EndFunc ;==>__SockAddr

Func _WSAGetLastError()

If $hWs2_32 = -1 Then $hWs2_32 = DllOpen( "Ws2_32.dll" )

Local $iRet = DllCall($hWs2_32, "int", "WSAGetLastError")

If @error Then

ConsoleWrite("+> _WSAGetLastError(): WSAGetLastError() failed. Script line number: " & @ScriptLineNumber & @CRLF)

SetExtended(1)

Return 0

EndIf

Return $iRet[ 0 ]

EndFunc ;==>_WSAGetLastError

; Got these here:

; http://www.autoitscript.com/forum/index.ph...amp;hl=MAKELONG

Func _MakeLong($LoWord, $HiWord)

Return BitOR($HiWord * 0x10000, BitAND($LoWord, 0xFFFF)); Thanks Larry

EndFunc ;==>_MakeLong

Func _HiWord($Long)

Return BitShift($Long, 16); Thanks Valik

EndFunc ;==>_HiWord

Func _LoWord($Long)

Return BitAND($Long, 0xFFFF); Thanks Valik

EndFunc ;==>_LoWord

; ========================================= Array functions

; #FUNCTION# ====================================================================================================

================

; Name...........: _ArrayDelete

; Description ...: Deletes the specified element from the given array.

; Syntax.........: _ArrayDelete(ByRef $avArray, $iElement)

; Parameters ....: $avArray - Array to modify

; $iElement - Element to delete

; Return values .: Success - New size of the array

; Failure - 0, sets @error to:

; |1 - $avArray is not an array

; |3 - $avArray has too many dimensions (only up to 2D supported)

; |(2 - Deprecated error code)

; Author ........: Cephas <cephas at clergy dot net>

; Modified.......: Jos van der Zande <jdeb at autoitscript dot com> - array passed ByRef, Ultima - 2D arrays supported, reworked function (no longer needs temporary array; faster when deleting from end)

; Remarks .......: If the array has one element left (or one row for 2D arrays), it will be set to "" after _ArrayDelete() is used on it.

; Related .......: _ArrayAdd, _ArrayInsert, _ArrayPop, _ArrayPush

; Link ..........;

; Example .......; Yes

; ====================================================================================================

===========================

Func ___ArrayDelete(ByRef $avArray, $iElement)

If Not IsArray($avArray) Then Return SetError(1, 0, 0)

Local $iUBound = UBound($avArray, 1) - 1

If Not $iUBound Then

$avArray = ""

Return 0

EndIf

; Bounds checking

If $iElement < 0 Then $iElement = 0

If $iElement > $iUBound Then $iElement = $iUBound

; Move items after $iElement up by 1

Switch UBound($avArray, 0)

Case 1

For $i = $iElement To $iUBound - 1

$avArray[$i] = $avArray[$i + 1]

Next

ReDim $avArray[$iUBound]

Case 2

Local $iSubMax = UBound($avArray, 2) - 1

For $i = $iElement To $iUBound - 1

For $j = 0 To $iSubMax

$avArray[$i][$j] = $avArray[$i + 1][$j]

Next

Next

ReDim $avArray[$iUBound][$iSubMax + 1]

Case Else

Return SetError(3, 0, 0)

EndSwitch

Return $iUBound

EndFunc ;==>_ArrayDelete

Criticism is welcome!

Chat.zip

Edited by Coolw
My ProgramsMy WIP'sSteam Server Restarter
Link to comment
Share on other sites

Ideas/comments/suggestions?

Found a very little buggie.

In server.au3 when sending the chatmessage, you forgot to add ":" in _TCP_Server_Broadcast(@UserName & GUICtrlRead($chatinput))

It should be _TCP_Server_Broadcast(@UserName & ": " & GUICtrlRead($chatinput)).

Nice clean functional. Just the way i like it ^_^

Nicely done!

Creator

Edited by Creator
Link to comment
Share on other sites

Very nice...can come in handy. ^_^

Thank you!

Found a very little buggie.

In server.au3 when sending the chatmessage, you forgot to add ":" in _TCP_Server_Broadcast(@UserName & GUICtrlRead($chatinput))

It should be _TCP_Server_Broadcast(@UserName & ": " & GUICtrlRead($chatinput)).

Nice clean functional. Just the way i like it ;)

Nicely done!

Creator

Fixed!

Thanks!

Change Window size

GUICreate("Server", 600, 510)

Add

ControlFocus("Server","",$chatinput)

After

GUICtrlSetData($chatinput, "")

So you don't have to keep clicking before you type again

Thank you a lot. I was trying to find a way to do that :D

The GUI was messed up because I added the File menu after I made everything else. Now fixed :(

Edited by Coolw
My ProgramsMy WIP'sSteam Server Restarter
Link to comment
Share on other sites

Ideas/comments/suggestions?

Timestamp doesn't turn off for me

I would change the color of the server name/client names. <-- Sorry just read above that you where working on that.

Maybe red for server name & blue for client name just an idea.

Edited by KenNichols
[topic="21048"]New to AutoIt? Check out AutoIt 1-2-3![/topic] Need to make a GUI? You NEED KODA FormDesigner!
Link to comment
Share on other sites

Timestamp doesn't turn off for me

I would change the color of the server name/client names. <-- Sorry just read above that you where working on that.

Maybe red for server name & blue for client name just an idea.

I took a look at the timestamp issue, and I couldn't find out what is wrong.

Good idea :)

My ProgramsMy WIP'sSteam Server Restarter
Link to comment
Share on other sites

  • 1 month later...

I can't figure out what's wrong with the timestamp item either. One solution that you could use is to replace the menu item with this: $timestamp = GUICtrlCreateMenuItem("Timestamp", $optionmenu)

The menu item will now be a checkbox.

Then add this into your main loop:

Case $timestamp
            If BitAND(GUICtrlRead($timestamp), $GUI_CHECKED) = $GUI_CHECKED Then
                GUICtrlSetState($timestamp, $GUI_UNCHECKED)
            Else
                GUICtrlSetState($timestamp, $GUI_CHECKED)
            EndIf

To make the changes in text colors for certain lines, try out a rich edit control.

Edited by dantay9
Link to comment
Share on other sites

  • 1 year later...

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...