Jump to content
Sign in to follow this  
delme

LANChat

Recommended Posts

delme

Hey guys, I havn't been coding in Autoit much lately, except when I just recently made the client for my C++ chat server in Autoit. But I needed a bit of a distraction from my homework so I whipped this up in a few mins and thought I'd share it as it may be interesting for some people. It isn't very well developed as I was just playing around with it to see how fast the chat would run but hey, I think it could be pretty cool. If something like this has been posted before (and I'm 100% sure there has) I apologize :mellow:

So this is a chat program that works without a server by scanning all the IP addresses on the LAN (Local Area Network - so it will not work over the internet) and sending the messages when it makes a connection. This would be good for school and such as most schools usually have a LAN set up between their computers, or one LAN per computer lab etc.

I also didn't use TCP, I used UDP instead as it seemed better for the job to me as it is making a lot of fast connections and this way it wouldn't have to go through the TCP handshake.

So anyway, heres the code:

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

 DELmE's LanChat

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

;include files
#include <GuiConstants.au3>
#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <WindowsConstants.au3>
#include <GuiEdit.au3>

;define variables
Global $hGui, $hEdit, $hInp, $hBtn, $username, $rsock, $ssock, $recv
Global $port = 7892
Global $Broadcast = StringLeft(@IPAddress1, StringInStr(@IPAddress1, ".", 0, 3)) & "255"

;start main function
_main()
Func _main()
    ;get username
    $username = InputBox("LanChat","Please enter your username.")
    If $username = "" Then
        MsgBox(16,"Error","A username must be entered.")
        Exit
    EndIf
    ;create gui
    $hGui = GUICreate("LanChat",500,500)
    $hEdit = GUICtrlCreateEdit("Welcome to DELmE's LanChat",0,0,500,480,BitOR($ES_READONLY,$ES_WANTRETURN,$WS_VSCROLL,$ES_AUTOVSCROLL))
    _GUICtrlEdit_SetLimitText($hEdit,99999999999999)
    $hInp = GUICtrlCreateInput("",0,480,470,20)
    $hBtn = GUICtrlCreateButton("Send",470,480,30,20,$BS_DEFPUSHBUTTON)
    ;display gui
    GUISetState()
    ;start winsock for udp
    UDPStartup()
    ;bind a socket to the port for listening
    $rsock = UDPBind(@IpAddress1,$port)
    If @error <> 0 Then Exit
    ;send message informing of online status
    SendMsg("-"&$username&" has come online.")
    ;start gui loop
    Do
        $recv = UDPRecv($rsock,1024)
        If $recv <> "" Then
            Print($recv)
        EndIf
        $msg = GUIGetMsg()
        If $msg = $hBtn Then
            $buffer = GUICtrlRead($hInp)
            If $buffer <> "" Then
                GUICtrlSetData($hInp,"")
                SendMsg("<"&$username&">: "&$buffer)
            EndIf
        EndIf
    Until $msg = $GUI_EVENT_CLOSE
    Exit
EndFunc ;==> _main

Func SendMsg($txtMsg)
        $ssock = UDPOpen($Broadcast,$port)
        If @error = 0 Then
            UDPSend($ssock,$txtMsg)
        EndIf
        UDPCloseSocket($ssock)
EndFunc ;==> SendMsg

Func Print($txtMsg)
    _GUICtrlEdit_AppendText($hEdit,@CRLF&$txtMsg)
EndFunc ;==> Print

Func OnAutoItExit()
    ;send message informing of offline status
    SendMsg("-"&$username&" has gone offline.")
    UDPShutdown()
EndFunc ;==> OnAutoItExit

Hope you guys find this usefull, I think it could be made into a cool little application with the right improvements :(

Post your comments, I'll try to check this post but I do have a lot of homework...

Thanks

DELmE

Change Log:

10/03/10 - Updated code to use the broadcast method that Apzo suggested also added an attachment with the code
11/03/10 - Fixed an error with the broadcast ip

LanChat_1.1.au3

Edited by DELmE

Share this post


Link to post
Share on other sites
Apzo

Hello DELmE

It's a good idea to use UDP, but you should use its broadcast abilities too :mellow:

When you network is 192.168.1.X, the best way to broadcast an UDP packet is to send it to 192.168.1.255

You can use this :

Global $Broadcast = StringLeft(@IPAddress1, StringInStr(@IPAddress1, ".", 0, 3)) & ".255"

Then

Func SendMsg($txtMsg)
        $ssock = UDPOpen($Broadcast,$port)
        If @error = 0 Then
            UDPSend($ssock,$txtMsg)
        EndIf
        UDPCloseSocket($ssock)
EndFunc ;==> SendMsg

Apzo.

Share this post


Link to post
Share on other sites
delme

Hello DELmE

It's a good idea to use UDP, but you should use its broadcast abilities too :mellow:

When you network is 192.168.1.X, the best way to broadcast an UDP packet is to send it to 192.168.1.255

You can use this :

Global $Broadcast = StringLeft(@IPAddress1, StringInStr(@IPAddress1, ".", 0, 3)) & ".255"

Then

Func SendMsg($txtMsg)
        $ssock = UDPOpen($Broadcast,$port)
        If @error = 0 Then
            UDPSend($ssock,$txtMsg)
        EndIf
        UDPCloseSocket($ssock)
EndFunc ;==> SendMsg

Apzo.

Hey, thanks for the advice, I didn't even know there was a broadcast ability, that's cool. Ill update the code :(

Edit: Hmm.. with the broadcast method it doesn't seem to be working, does this method also send the data to the computer that has sent it out?

Edited by DELmE

Share this post


Link to post
Share on other sites
delme

I think you might find that the broadcast IP address has an extra '.' - try:

Global $Broadcast = StringLeft(@IPAddress1, StringInStr(@IPAddress1, ".", 0, 3)) & "255"

(leave out the '.' before the 255)

Hey thanks, that's fixed it, I'll update the code, I guess I should have checked that aye?

Share this post


Link to post
Share on other sites
twitchyliquid64

I think you might find that the broadcast IP address has an extra '.' - try:

Global $Broadcast = StringLeft(@IPAddress1, StringInStr(@IPAddress1, ".", 0, 3)) & "255"

(leave out the '.' before the 255)

Does this also work for TCP? (Although I doubt it)

EG:

$newcon = TCPconnect( "192.168.1255", 88)

???

  • Like 1

ongoing projects:-firestorm: Largescale P2P Social NetworkCompleted Autoit Programs/Scripts: Variable Pickler | Networked Streaming Audio (in pure autoIT) | firenet p2p web messenger | Proxy Checker | Dynamic Execute() Code Generator | P2P UDF | Graph Theory Proof of Concept - Breadth First search

Share this post


Link to post
Share on other sites
delme

Does this also work for TCP? (Although I doubt it)

EG:

$newcon = TCPconnect( "192.168.1255", 88)

???

Don't think it works with TCP connections. Also the IP would be, "192.168.1.255", he told me to leave out the "." because I had one extra..

Share this post


Link to post
Share on other sites
magace

Thanks for the code delme.  I updated it some to use around the workplace.

To run it we put the lchat folder on our server and shared the folder over the network.

Then we just run the exe over the network.  

The reason for this is it reads/writes to the users file to determine who is online. 

Im sure the code is not the best but it is working.

Main changes:

Online User list

Checks if username is already in use

Beep on new msg

Sound on/off button

Change beep frequency

Install/uninstall to startup registry

Sends encrypted data

 

You must have _Startup.au3 to compile/run the script

You must have users.txt in ur script directory

#AutoIt3Wrapper_icon=chat.ico;include files
#include <GuiConstants.au3>
#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <WindowsConstants.au3>
#include <GuiEdit.au3>
#include '_Startup.au3'
#Include <Array.au3>
#Include <File.au3>
#include <ProgressConstants.au3>
#include <SendMessage.au3>
#include <crypt.au3>


Global $hGui, $hEdit, $hEdit2, $hInp, $hInp1, $hBtn, $username, $rsock, $ssock, $hBtn1, $hBtn2, $hBtn3, $hBtn4, $hBtn5, $recv
Global $port = 7892
Global $Broadcast = StringLeft(@IPAddress1, StringInStr(@IPAddress1, ".", 0, 3)) & "255"
Global $beep = "500"
Global $sound = "0"
Global $_Array
Global $file = @ScriptDir & "\users.txt"






_main()
Func _main()
;get username
$username = InputBox("LanChat","Please enter your username.")
If $username = "" Then
MsgBox(16,"Error","A username must be entered.")
Exit
EndIf
    ;checks username
_FileReadToArray ($file, $_Array )
$_Array = _ReadArrayElementWithStringInstr ( $_Array, $username )
_FileWriteFromArray ($file, $_Array, 1 )
ToLog($username)


;;progress bar gui;;
$hGUI = GUICreate("Welcome", 300, 200)
GUICtrlCreateLabel("Loading Chat", 10, 30)
GUICtrlCreateLabel("Username :" & $username, 10, 50)
GUICtrlCreateLabel("V4.20", 260, 180)
GUICtrlCreateProgress(10, 10, 200, 20, $PBS_MARQUEE)
_SendMessage(GUICtrlGetHandle(-1), $PBM_SETMARQUEE, True, 50)
GUISetState()
sleep(3000)
Switch GUIGetMsg()
Case $GUI_EVENT_CLOSE
EndSwitch
GuiDelete($hGUI)
;;progress bar gui;;


;create gui
$hGui = GUICreate("LanChat",600,500)
$hEdit = GUICtrlCreateEdit("Welcome",0,0,500,480,BitOR($ES_READONLY,$ES_WANTRETURN,$WS_VSCROLL,$ES_AUTOVSCROLL))
$hEdit2 = GUICtrlCreateEdit("Online Users",501,21,400,300,BitOR($ES_READONLY,$ES_WANTRETURN,$WS_VSCROLL,$ES_AUTOVSCROLL))
_GUICtrlEdit_SetLimitText($hEdit,99999999999999)
_GUICtrlEdit_SetLimitText($hEdit2,99999999999999)
$hInp = GUICtrlCreateInput("",0,480,470,20)
$hBtn = GUICtrlCreateButton("Send",470,480,30,20,$BS_DEFPUSHBUTTON)
$hBtn1 = GUICtrlCreateButton("Install",501,0,50,20)
$hBtn2 = GUICtrlCreateButton("Uninstall",551,0,50,20 )
$hInp1 = GUICtrlCreateInput("",535,480,70,490)
$hBtn3 = GUICtrlCreateButton("beep",505,480,30,20)
$hBtn4 = GUICtrlCreateButton("SOUND ON",505,460,65,20)
$hBtn5 = GUICtrlCreateButton("OFF",570,460,30,20)
;display gui
GUISetState()
;start winsock for udp
UDPStartup()
;bind a socket to the port for listening
$rsock = UDPBind(@IpAddress1,$port)
If @error <> 0 Then Exit
;send message informing of online status
SendMsg("-"&$username&" has come online.")




;start gui loop
Do
$recv = UDPRecv($rsock,1024)
If $recv <> "" Then
If $sound = 1 Then
Beep($beep,500)
   EndIf
   $xzy = _Crypter($recv, 1)
Print($xzy)
;READS FILE LINE FOR LINE
$hEdit2 = GUICtrlCreateEdit("Online Users",501,21,400,400,BitOR($ES_READONLY,$ES_WANTRETURN,$WS_VSCROLL,$ES_AUTOVSCROLL))
FileOpen($file, 0)
For $i = 1 to _FileCountLines($file)
$line = FileReadLine($file, $i)
print2($line)
Next
FileClose($file)
EndIf
$msg = GUIGetMsg()
If $msg = $hBtn Then
$buffer = GUICtrlRead($hInp)
If $buffer <> "" Then
GUICtrlSetData($hInp,"")
SendMsg("<"&$username&">: "&$buffer)
EndIf
EndIf
If $msg = $hBtn3 Then
$buffer = GUICtrlRead($hInp1)
If $buffer <> "" Then
GUICtrlSetData($hInp1,"")
  $beep = $buffer
Beep($beep,500)
EndIf
EndIf
If $msg = $hBtn4 Then
$sound = 1
MsgBox(4096, "SOUND", "TURNED ON", 2)
EndIf
If $msg = $hBtn5 Then
MsgBox(4096, "SOUND", "TURNED OFF", 2)
$sound = 0
EndIf
If $msg = $hBtn1 Then
_StartupRegistry_Install()
MsgBox (1,"INSTALLED","INSTALLED TO STARTUP REGISTRY")
EndIf
If $msg = $hBtn2 Then
_StartupRegistry_Uninstall()
MsgBox (1,"UNINSTALLED","UNINSTALLED FROM STARTUP REGISTRY")
EndIf
Until $msg = $GUI_EVENT_CLOSE
_FileReadToArray ($file, $_Array )
    $_Array = _DeleteArrayElementWithStringInstr ( $_Array, $username )
    _FileWriteFromArray ($file, $_Array, 1 )
SendMsg("-"&$username&" has gone offline.")
Exit
EndFunc ;==> _main


Func SendMsg($txtMsg)
        $ssock = UDPOpen($Broadcast,$port)
        If @error = 0 Then
$xz = _Crypter($txtMsg, 0)
            UDPSend($ssock,$xz)
        EndIf
        UDPCloseSocket($ssock)
EndFunc ;==> SendMsg


Func Print($txtMsg)
_GUICtrlEdit_AppendText($hEdit,@CRLF&$txtMsg)
 EndFunc ;==> Print


Func Print2($txtMsg)
_GUICtrlEdit_AppendText($hEdit2,@CRLF&$txtMsg)
 EndFunc ;==> Print


Func LogUsr()
   $Log = FileOpen(@ScriptDir & "users.txt", 2)
   FileWriteLine($Log, "" & $username & "")
   FileClose($Log)
EndFunc


Func OnAutoItExit()
;send message informing of offline status
SendMsg("-"&$username&" has gone offline.")
_FileReadToArray ($file, $_Array )
    $_Array = _DeleteArrayElementWithStringInstr ( $_Array, $username )
    _FileWriteFromArray ($file, $_Array, 1 )
UDPShutdown()
 EndFunc ;==> OnAutoItExit


 Func ToLog($Text)
   $Log = FileOpen(@ScriptDir & "\users.txt", 1)
   FileWrite($Log, "" & $Text & "")
   FileClose($Log)
EndFunc


Func _DeleteArrayElementWithStringInstr ( $_Array, $_String )
    Local $_Item
    For $_Element In $_Array
        If StringInStr ( $_Element, $_String ) <> 0 Then
            _ArrayDelete ( $_Array, $_Item )
        Else
            $_Item+=1
        EndIf
    Next
    Return ( $_Array )
 EndFunc


Func _ReadArrayElementWithStringInstr ( $_Array, $_String )
    For $_Element In $_Array
        If StringInStr ( $_Element, $_String ) <> 0 Then
MsgBox(4096, "Sorry", "Name already in use" , 3)
Exit
        Else


        EndIf
    Next
    Return ( $_Array )
 EndFunc ;==> _DeleteArrayElementWithStringInstr ( )


Func _Crypter($String, $Operation)
    _Crypt_Startup()
    Switch $Operation
        Case 0
            $x = _Crypt_EncryptData($String, "tester", $CALG_RC4)
            Return $x
        Case 1
            $x = BinaryToString(_Crypt_DecryptData($String, "tester", $CALG_RC4)) ; <<<<<<<<<<<<<<<<< the function returns a binary string
            Return $x
    EndSwitch
    _Crypt_Shutdown()
 EndFunc

Thanks again delme!

Edited by magace

Share this post


Link to post
Share on other sites
zelles

delme, Thank you for sharing this script. Most scripts I've seen using UDP have been longer and more complex. There is a lot of simple TCP examples, but your script is a great UDP example.

Share this post


Link to post
Share on other sites

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
Sign in to follow this  

×