condition check is not working out as intended, why?

I'm making a small networked game, still learning networking so I might be missing out on something.
I am using Visual Studio Community 2017.
I am using Allegro 5 for inputs and graphics.
I am using SDL_Net for networking.

- The game is supposed to launch, works fine.
- Every game tick, function HandleEvents(...) gets called in my code.
- The game connects to the server if a mouse click was registered between 0-10 px on the screen, both x and y.

that worked fine, except that the client connected multiple times, so I set a condition so that it will only try and connect 1 client. I did this using a condition:

1
2
3
4
if(connected) {
    std::cout << "Already connected.." << std::endl;
    } else
    ...


Here's the actual code, so you can see what I have in the function.
function in MenuState.cpp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
    void MenuState::HandleEvents(Input* input, ClientSocket* cs) {
    	if (input->mouseX >= 0 && input->mouseX <= 10 && input->mouseY >= 0 && input->mouseY <= 10) {
    		if (input->mouseB == MouseLDown) {
    			input->set_mouse_state(MouseNDown);
    
    			if (connected == true) {
    				std::cout << "You're already connected." << std::endl;
    			}
    			else if(connected == false) {
    				switch (cs->connectToServer()) {
    				case Packets::SERVER_NOT_RESOLVED:
    					break;
    				case Packets::SERVER_RESOLVED:
    					break;
    				case Packets::SERVER_DOWN:
    					break;
    				case Packets::SERVER_NOT_FULL:
    				{
    					connected = true;
    					std::cout << "Connected to server" << std::endl;
    					receivedMessage = "";
    
    					// Check if we've received a message
    					receivedMessage = cs->checkForIncomingMessages();
    
    					// If so then...
    					if (receivedMessage != "")
    					{
    						// Display the message and then blank it...
    						cs->displayMessage(receivedMessage);
    
    						// ...and then re-display the prompt along with any typed-but-not-yet-sent input
    						//cs->displayPrompt();
    					}
    
    					// Get and deal with input from the user in a non-blocking manner
    					cs->getUserInput();
    				}
    				break;
    				case Packets::SERVER_FULL:
    					break;
    				case Packets::SERVER_NO_RESPONSE:
    					break;
    				}
    			}
    		}
    	}
    }


As you can see, there is clearly a condition check. The condition check works if I remove all networked code in case Packets::SERVER_NOT_FULL:
Last edited on
I think you need to recognise a mouse click event, not a mouse down event.

Down events are going to happen all the time you hold the button down.
It's how things like drag and drop get implemented.
Hi I used input->set_mouse_state(MouseNDown); after the if(input->mouseB == MouseLDown)
MouseNDown is MouseNoneDown, basically 0, so it only clicks. Not the issue here. sorry I didn't explain that.

The issue is the if else if(connected == false) { not working, it ignores it and it can do the code inside it anyway.
So ignoring all the connection code, does this produce exactly one message for each click?
1
2
3
4
5
6
7
    		if (input->mouseB == MouseLDown) {
    			input->set_mouse_state(MouseNDown);
    
    			if (connected == true) {
    				std::cout << "You're already connected." << std::endl;
    			}
    			connected = true;


Are you sure of the state that cs->connectToServer() returns?

Networking isn't like opening a file (either you open the file, or you don't).
Likely, you'll need at least three states (not a boolean) to cover
- not connected
- connecting
- connected

This is especially true in event driven code, where nothing ever blocks, waiting for something to finish. Especially where the something can take undefined amounts of time to complete.
Here is my connectToServer function

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
int ClientSocket::connectToServer()
{
    // Resolve hostname of server ip and put result in hostResolved integer
    int hostResolved = SDLNet_ResolveHost(&serverIP, serverHostname.c_str(), serverPort);

    // if resolving host fails, else if success.
    if (hostResolved == -1)
    {
        // failed to resolve host, doesn't really matter tho, we got ip.
        return Packets::SERVER_NOT_RESOLVED;
    }
    else // otherwise if we successfully resolved the hostname...
    {
        // get our IP address in dot-quad format (break up 32-bit unsigned host address)
        // split it into an array of four 8-bit unsigned numbers...
        Uint8 * dotQuad = (Uint8*)&serverIP.host;

        dotQuadString  = toString( (unsigned short)dotQuad[0] );
        dotQuadString += ".";
        dotQuadString += toString( (unsigned short)dotQuad[1] );
        dotQuadString += ".";
        dotQuadString += toString( (unsigned short)dotQuad[2] );
        dotQuadString += ".";
        dotQuadString += toString( (unsigned short)dotQuad[3] );

        //Output dotquad string (ip) and output 16bit port
        if (debug)
        {
            cout << "Successfully resolved server to IP: " << dotQuadString;
            cout << ", will use port " << SDLNet_Read16(&serverIP.port) << endl;
        }
    }

    // Open connection between client/server
    clientSocket = SDLNet_TCP_Open(&serverIP);
    if (!clientSocket)
    {
        //Fail, server is down
        return Packets::SERVER_DOWN;
    }
    else // If we successfully opened a connection then check for the server response to our connection
    {
        if (debug) { cout << "Connected, reading status from the server..." << endl; }

        // Add our socket to the socket set for polling
        SDLNet_TCP_AddSocket(socketSet, clientSocket);

        // Wait for up to five seconds for a response from the server.
        int activeSockets = SDLNet_CheckSockets(socketSet, ClientSocket::CONNECTION_TIMEOUT_PERIOD);

        if (debug)
        {
            cout << "There are " << activeSockets << " socket(s) with data on them at the moment." << endl;
        }

        // Check for response from server
        int gotServerResponse = SDLNet_SocketReady(clientSocket);

        if (gotServerResponse != 0)
        {
            // Read the message on the client socket
            int serverResponseByteCount = SDLNet_TCP_Recv(clientSocket, pBuffer, bufferSize);

            if (debug)
            {
                cout << "Message from server: " << pBuffer << "(" << serverResponseByteCount << " bytes)" << endl;
            }

            // Get the contents of the buffer as a string
            string bufferContents = pBuffer;

            // If we got the SERVER_NOT_FULL response from the server then we can join!
            if ( pBuffer == ClientSocket::SERVER_NOT_FULL )
            {
                if (debug) { cout << "Joining server now..." << endl; }
                return Packets::SERVER_NOT_FULL;
            }
            else // Otherwise we must have got the SERVER_FULL response so we can't connect.
            {
                //Tells us server is full
                return Packets::SERVER_FULL;
            }
        }
        else // If there's no activity on the client socket then we've failed to connect
        {
            return Packets::SERVER_NO_RESPONSE;
        }
    }
}


I managed to get a minimal, complete and verifiable example working that produced the same error.
HandleEvents(Input.., ClientSocket..,) function
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void MenuState::HandleEvents(Input* input, ClientSocket* cs) {
    if (input->mouseX >= 0 && input->mouseX <= 10 && input->mouseY >= 0 && input->mouseY <= 10) {
        if (input->mouseB == MouseLDown) {
            //Set mouse state to none, so that it doesn't "hold it down" but just clicks once,
            input->set_mouse_state(MouseNDown);

            if (connected == true) {
                std::cout << "You're already connected." << std::endl;
            }
            else {
                switch (cs->connectToServer()) {
                case Packets::SERVER_NOT_FULL:
                    connected = true;
                    std::cout << "Hello" << std::endl; //This never prints, why?
                    break;
                }
            }
        }
    }
}


Is it stuck inside the while loop executing cs->connectToServer()? Please help me locate where in the function connectToServer() it doesn't return and stall the code.
Help is much appreciated.
Last edited on
What while loop, I see no loops.

I might try this.
1
2
3
4
5
6
7
8
9
int cStatus = cs->connectToServer();
switch (cStatus) {
    case Packets::SERVER_NOT_FULL:
        connected = true;
        std::cout << "Hello" << std::endl; //This never prints, why?
        break;
    default:
        std::cout << "OOPS!!!, cStatus=" << cStatus << std::endl;
    }
Thanks , I had been up all night and did never take into account that it didn't return SERVER_OK || SERVER_NOT_FULL lol
Topic archived. No new replies allowed.