Sign in to follow this  
Followers 0
Hellouser

Dear all , Need an urgent help in fixing a bug in my Chat program

1 post in this topic

Dear all , Need an urgent help in fixing a bug in my Chat program

I have two main loops , one loop is for controling the GUI related activites and the other one is for receiving the data from the chat clients.

Problem :

If i click any of the buttons/controls/manubar items in the first main loop ( while ) it will take 2-5 minutes to run the curresponding activites in the first loop,eventhough the second loop is not receiving any data's from the clients.

PC config : Dual Core 2.44 with 3 GB RAM

I have included my program code(Two Main Loops) also along with this mail.

While 1

;get Tray menu message

$Tray_Message = TrayGetMsg()

;Handle the message

Switch $Tray_Message

;If the message is to show the console

Case $Tray_Menu_Showconsole

;Then show the console.

GUISetState(@SW_SHOW,$Form1)

;Case it is to shutdown the server.

Case $Tray_Menu_Shutdown

;Safly shut it down

Exit

EndSwitch

;Get Gui Message.

$Gui_Message = GUIGetMsg()

;Handle the gui Message

Switch $Gui_Message

Case $GUI_EVENT_CLOSE

GUISetState(@SW_HIDE,$Form1)

Case $Button1 ;Kick

_Kick(GUICtrlRead($List1))

Case $Button2 ;Ban

_Ban(GUICtrlRead($List1))

Case $Button3 ;Say

_SendAll( "message", GUICtrlRead($Input1) & Chr(2) & "1000,0x0000FF,Lucida Console,14", 'SYSTEM')

GUICtrlSetData($Edit1,GUICtrlRead($Edit1) & 'SYSTEM: ' & GUICtrlRead($Input1) & @CRLF)

GUICtrlSetData($Input1, '')

Case $Button4 ;PM

_PM('SYSTEM',GUICtrlRead($List1),GUICtrlRead($Input1))

Case $Button5 ;Save, saves the changes to the user

_SQLite_Exec($SQL_DB, "UPDATE Accounts SET username = '" & StringUpper(GUICtrlRead($Input2)) & "', password = '" & GUICtrlRead($Input3) & "', ban = " & $Set_Ban & ", Admin = " & $Set_Admin & ", online = 0 WHERE id = " & $Selected_ID & ";")

GUICtrlSetData(GUICtrlRead($Listview1),$Selected_ID & '|' & StringUpper(GUICtrlRead($Input2)) & '|' & GUICtrlRead($Input3) & '|' & $Set_Admin & '|' & $Set_Ban & '|0')

Case $Button6 ;Delete, removes the user

_SQLite_Exec($SQL_DB, 'DELETE FROM Accounts WHERE id = ' & $Selected_ID & ';')

GUICtrlDelete(GUICtrlRead($Listview1))

Case $Button7 ;Create, Creates a new user in a safe maner.

_CreateUser(GUICtrlRead($Input2), GUICtrlRead($Input2),$Set_Ban, $Set_Admin)

EndSwitch

;check if we should update the user info.

;This is to avoid flickering.

If TimerDiff($Refresh_Timer) > 1000 Then

;Update the userinfo

;GUICtrlSetData($Label1,"Users Online: " & $Users_Online)

;GUICtrlSetData($Label2,"Admins Online: " & $Admins_Online)

;Restart the refresh timer.

$Refresh_Timer = TimerInit()

EndIf

;Gather Data and look what should be done with it.

_RecvData()

;Look if a new user is trying to connect

$New_Socket = TCPAccept($MainSocket)

;if not the start while 1 loop over again

If $New_Socket = -1 Then ContinueLoop

;Add the user that is trying to connect.

_AddUser($New_Socket)

WEnd

Func _RecvData()

For $x = 1 To $MaxUsers

If Not $User_List[$x][0] Then ContinueLoop

;Receive data from the users.

$Recv = TCPRecv($User_List[$x][0],4096)

;If you dont get any data then skip the rest of the loop.

If $Recv = "" Then ContinueLoop

;If @error then the user has problerly disconnected.

If @error Then _DelSocket($User_List[$x][0])

$Recv = _StringDecryptRC4( $Recv, $User_List[$x][2])

If StringLeft($Recv,1) <> Chr(3) Then

$Recv = _StringDecryptRC4( $Recv, $User_List[$x][4])

EndIf

If $Update_Key_Time > 0 And TimerDiff($User_List[$x][3]) > $Update_Key_Time Then _KeyGen($x)

;Split the data by when it was sent from the user.

$Data = StringSplit(StringTrimLeft($Recv,1),Chr(1))

If Not IsArray($Data) then ContinueLoop

;Log the data.

_ConsoleWrite("In|" & _TCPSocketToIP($User_List[$x][0]) & "|" & StringReplace(StringTrimLeft(StringTrimRight($Recv,1),1),Chr(2),"|") & @CRLF)

;Loop trought all the data from the user.

For $y = 1 To UBound($Data)-1

;Split that data to the real data we need.

$Real_Data = StringSplit($Data[$y],Chr(2))

;The data looks like this: Command chr(2) Parameter1 chr(2) Parameter2 chr(2) Parameter...

;check and see if we have enought data to work with.

If $Real_data[0] < 2 Then ContinueLoop

Switch $Real_Data[1]

Case "Logon"

;To avoid people sending fake signales in a atempt to crash the server.

If $Real_data[0] = 3 Then

Switch _Login($Real_data[2], $Real_data[3], $x)

Case 0 ;No such user or wrong password

_TCPSend($User_List[$x][0],"Logon" & Chr(2) & "fail",$User_List[$x][2])

_DelSocket($User_List)

Case 1 ;User is banned

_TCPSend($User_List[$x][0],"Logon" & Chr(2) & "Ban",$User_List[$x][2])

_DelSocket($User_List)

Case 2 ;User is already online

_TCPSend($User_List[$x][0],"Logon" & Chr(2) & "online",$User_List[$x][2])

_DelSocket($User_List)

Case 3 ;User can login :D

_TCPSend($User_List[$x][0],"Logon" & Chr(2) & "ok" & Chr(2) & '0',$User_List[$x][2])

_SendAll("Adduser", $User_List[$x][1])

Case 4 ;Admin can login

_TCPSend($User_List[$x][0],"Logon" & Chr(2) & "ok" & Chr(2) & '1',$User_List[$x][2])

_SendAll("Adduser", $User_List[$x][1])

EndSwitch

Else

;send him a message that he had some kind of error.

_TCPSend($User_List[$x][0],"Logon" & Chr(2) & "error", $User_List[$x][2])

_DelSocket($User_List)

EndIf

Case "Register"

;check and see if the $Real_data array is safe to use.

If $Real_data[0] = 3 Then

Switch _CreateUser($Real_data[2], $Real_Data[3])

Case 0

;else send him a message that that user is already in use.

_TCPSend($User_List[$x][0],"Register" & Chr(2) & "fail", $User_List[$x][2])

_DelSocket($User_List[$x][0])

Case 1

;else send him a message that that user is already in use.

_TCPSend($User_List[$x][0],"Register" & Chr(2) & "invalid", $User_List[$x][2])

_DelSocket($User_List[$x][0])

Case 2

;if not the send an ok message to the user.

_TCPSend($User_List[$x][0],"Register" & Chr(2) & "ok", $User_List[$x][2])

_DelSocket($User_List[$x][0])

EndSwitch

Else

;Send him a message that he had some kind of error.

_TCPSend($User_List[$x][0],"Register" & Chr(2) & "error", $User_List[$x][2])

_DelSocket($User_List[$x][0])

EndIf

Case "msg"

;If someone wants to chat then check we have enought options

If $Real_data[0] = 3 Then

GUICtrlSetData($Edit1,GUICtrlRead($Edit1) & $User_List[$x][1] & ': ' & $Real_data[2] & @CRLF)

;send the message to them all.

_SendAll( "message", $Real_data[2] & Chr(2) & $Real_Data[3], $User_List[$x][1])

EndIf

Case "getuser"

_SendUserList($User_List[$x][0],$User_List[$x][2])

Case "Bye"

_DelSocket($User_List[$x][0])

Case "pm"

If $Real_data[0] = 3 Then _Pm($User_List[$x][1],$Real_data[2], $Real_data[3])

Case "kick"

;To avoid people sending fake signales in a atempt to crash the server.

If UBound($Real_Data) > 2 Then

;Check if the user that is trying to kick another user is admin.

If _IsAdmin($User_List[$x][1]) Then

;check if the user we are trying to kick is admin or not.

If Not _IsAdmin($Real_Data[2]) Then

;Kick him if he is not a admin.

_Kick($Real_Data[2])

EndIf

Else

;the user was not a admin, Kick him from the server.

_PM("Console",$User_List[$x][1],"You used a function you are now allowed to use.")

_PM("Console",$User_List[$x][1],"You will now be kicked from the server.")

_Kick($User_List[$x][1])

EndIf

EndIf

Case "Ban"

;To avoid people sending fake signales in a atempt to crash the server.

If $Real_data[0] = 2 Then

;Check if the user that is trying to kick another user is admin.

If _IsAdmin($User_List[$x][1]) Then

;check if the user we are trying to kick is admin or not.

If Not _IsAdmin($Real_Data[2]) Then

;Ban him if he is not a admin.

_Ban($Real_Data[2])

EndIf

Else

;the user was not a admin, Kick him from the server.

_PM("Console",$User_List[$x][1],"You used a function you are now allowed to use.")

_PM("Console",$User_List[$x][1],"You will now be kicked from the server.")

_Kick($User_List[$x][1])

EndIf

EndIf

Case "unban"

;To avoid people sending fake signales in a atempt to crash the server.

If $Real_data[0] = 2 Then

;Check if the user that is trying to kick another user is admin.

If _IsAdmin($User_List[$x][1]) Then

;check if the user we are trying to kick is admin or not.

If Not _IsAdmin($Real_Data[2]) Then

;check if the user that we are trying to ban exists.

_SQLite_Query($SQL_DB, "SELECT id FROM Accounts WHERE username = '" & StringUpper($Real_data[2]) & "';", $Query)

If _SQLite_FetchData($Query,$SQL_Data) = $SQLITE_OK Then

_SQLite_Exec($SQL_DB,"UPDATE Accounts SET ban = 0 WHERE username = '" & StringUpper($Real_Data[2]) & "';")

_TCPSend($User_List[$x][0],"Unban" & Chr(2) & "ok", $User_List[$x][2])

$User_Index = _GUICtrlListView_FindText($Listview1,$SQL_Data[0],-1, False)

If $User_Index> -1 Then _GUICtrlListView_SetItemText($Listview1, $User_Index, '0', 4)

Else

_TCPSend($User_List[$x][0],"Unban" & Chr(2) & "nouser", $User_List[$x][2])

EndIf

EndIf

Else

;the user was not a admin, Kick him from the server.

_PM("Console",$User_List[$x][1],"You used a function you are now allowed to use.")

_PM("Console",$User_List[$x][1],"You will now be kicked from the server.")

_Kick($User_List[$x][1])

EndIf

EndIf

Case Else

;Debug stuff.

If $Real_Data[1] <> "" Then

ConsoleWrite("Unknow Command: " & $Real_Data[1])

If $Real_Data[0] > 1 Then

For $x = 2 To $Real_data[0]

ConsoleWrite($Real_Data[$x] & ',' )

Next

ConsoleWrite(@CRLF)

EndIf

EndIf

EndSwitch

Next

Next

;Safely exit the function.

Return 1

EndFunc

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  
Followers 0