#include <GUIConstantsEx.au3>
Global Const $IP = @IPAddress1
Global Const $PORT = 5393
Global Const $MAXCON = 50;Maximal 50 Verbindungen

Global $aClients[$MAXCON + 1][3]
$aClients[0][0] = $MAXCON

Opt("GuiOnEventMode", 1)


TCPStartup()

$hListen = TCPListen($IP, $PORT, $MAXCON)


AdlibRegister("TCPAcc", 100)


;Hat nicht zu interessieren, ist nur GUI
GUICreate("Server", 400, 150)
GUISetOnEvent(-3, "_Exit")

$hListV = GUICtrlCreateListView("ID|Client|IP", 0, 0, 200, 150)
$hEdit = GUICtrlCreateEdit("Text zum Senden", 200, 0, 200, 80,0)
$hSendToAll = GUICtrlCreateRadio("An alle Senden",200,80,200,15)
GUICtrlSetOnEvent(-1,"_gui_radio")
GUICtrlSetState(-1,$GUI_CHECKED)
GUICtrlCreateRadio("Nur an folgende ID senden:",200,95,200,15)
GUICtrlSetOnEvent(-1,"_gui_radio")
$hInput = GUICtrlCreateInput("",200,110,200,20)
GUICtrlSetState(-1,$GUI_DISABLE)
GUICtrlCreateButton("SEND", 200, 130, 200, 20)
GUICtrlSetOnEvent(-1, "_gui_send")
GUISetState()

;Main Schleife: Hier wird das, was in den Server reinkommt abgefangen
While 1
	For $i = 1 To $aClients[0][0]
		If $aClients[$i][0] Then
			$sRecv = TCPRecv($aClients[$i][0], 1024)
			If $sRecv Then TrayTip("Neue Nachricht von " & $aClients[$i][1], $sRecv, 2)
		EndIf
	Next
	Sleep(100)
WEnd

;GUI Krimskrams
Func _gui_radio()
	ConsoleWrite(@GUI_CtrlId & @CRLF)
	If @GUI_CtrlId = $hSendToAll Then
		GUICtrlSetState($hInput,$GUI_DISABLE)
	Else
		GUICtrlSetState($hInput,$GUI_ENABLE)
	EndIf

EndFunc

;GUI Krimskrams
Func _gui_send()
	Local $sText = GUICtrlRead($hEdit)
	If BitAND(GUICtrlRead($hSendToAll), $GUI_CHECKED) Then
		ConsoleWrite("--" & @CRLF)
		_TCP_ServerBroadcast($sText)
	Else
		Local $iID = GUICtrlRead($hInput)
		ConsoleWrite($iID & @CRLF)
		If $iID < 1 Or $iID > $MAXCON Then Return MsgBox(16,"","ID muss zwischen 1 und "&$MAXCON&" sein!")
		TCPSend($aClients[$iID][0],$sText)
		If @error Then _DelClient($aClients[$iID][0])
	EndIf
EndFunc   ;==>_gui_send

;Adlib funktion, hier wird alle 100ms nach einem neuen Client gesucht
Func TCPAcc()
	$hAcc = TCPAccept($hListen)
	If $hAcc > 0 Then _AddClient($hAcc)
EndFunc   ;==>TCPAcc

;Hier wird der Client hinzugefügt
Func _AddClient($hSocket)
	Local $i
	For $i = 1 To $aClients[0][0]
		If Not $aClients[$i][0] Then ExitLoop
	Next
	$aClients[$i][0] = $hSocket
	$aClients[$i][1] = SocketToIP($hSocket)
	$aClients[$i][2] = GUICtrlCreateListViewItem($i&"|"&$aClients[$i][0] & "|" & $aClients[$i][1],$hListV)
	Return TCPSend($hSocket, "welcome")
EndFunc   ;==>_AddClient

;Hier wird er ggf. wieder gelöscht
Func _DelClient($hSocket)
	Local $i
	For $i = 1 To $aClients[0][0]
		If $aClients[$i][0] = $hSocket Then
			TCPCloseSocket($aClients[$i][0])
			$aClients[$i][0] = '' ;Entferne Client
			GUICtrlDelete($aClients[$i - 1][2])
			Return True
		EndIf
	Next
	Return False
EndFunc   ;==>_DelClient

;Sendet einen String an alle verbundenen Clients
Func _TCP_ServerBroadcast($sText)
	Local $i
	For $i = 1 To $aClients[0][0]
		If $aClients[$i][0] Then
			TCPSend($aClients[$i][0], $sText)
			If @error Then _DelClient($aClients[$i][0])
		EndIf
	Next
EndFunc   ;==>_TCP_ServerBroadcast

Func _Exit()
	Local $i
	For $i = 1 To $aClients[0][0]
		If $aClients[$i][0] Then
			TCPCloseSocket($aClients[$i][0])
			GUICtrlDelete($aClients[$i - 1][2])
		EndIf
	Next
	TCPShutdown()
	Exit
EndFunc   ;==>_Exit


; Function to return IP Address from a connected socket.
;----------------------------------------------------------------------
Func SocketToIP($SHOCKET)
	Local $sockaddr, $aRet

	$sockaddr = DllStructCreate("short;ushort;uint;char[8]")

	$aRet = DllCall("Ws2_32.dll", "int", "getpeername", "int", $SHOCKET, _
			"ptr", DllStructGetPtr($sockaddr), "int*", DllStructGetSize($sockaddr))
	If Not @error And $aRet[0] = 0 Then
		$aRet = DllCall("Ws2_32.dll", "str", "inet_ntoa", "int", DllStructGetData($sockaddr, 3))
		If Not @error Then $aRet = $aRet[0]
	Else
		$aRet = 0
	EndIf

	$sockaddr = 0

	Return $aRet
EndFunc   ;==>SocketToIP
