Need a simple way to store all received packets and then pass them to the correct Player object?

Started by
2 comments, last by Heelp 7 years, 7 months ago

Hello, guys.

This is more of a code-design question, but it's tightly connected to networking, that's why I decided to post the question here.

I'm wondering how to deal with packets when I receive them and how to pass them to the correct player. Right now I have only one player and I do the packet receiving like this:


void NetworkManager::serverReceivePackets( Player& player )
{
    for( packet = peer->Receive(); packet; peer->DeallocatePacket( packet ), packet = peer->Receive() )
    {
        if( packet->data[ 0 ] == PLAYER_MOVE_FORWARD )
        { player.mainCam.setCurrentPosition( player.mainCam.getCurrentPosition() - player.moveHelperCam.getDirection() ); }

        else if( packet->data[ 0 ] == PLAYER_MOVE_BACKWARD )
        { player.mainCam.setCurrentPosition( player.mainCam.getCurrentPosition() + player.moveHelperCam.getDirection() ); }

        else if( packet->data[ 0 ] == PLAYER_MOVE_LEFT )
        { player.mainCam.setCurrentPosition( player.mainCam.getCurrentPosition() + player.mainCam.getDirectionRight() ); }

        else if( packet->data[ 0 ] == PLAYER_MOVE_RIGHT )
        { player.mainCam.setCurrentPosition( player.mainCam.getCurrentPosition() - player.mainCam.getDirectionRight() ); }

        else if( packet->data[ 0 ] == ID_CONNECTION_REQUEST_ACCEPTED )
        {
            printf( "Connection request accepted.\n" );
        }
        else if( packet->data[ 0 ] == ID_NEW_INCOMING_CONNECTION )
        {
            printf( "New connection incoming\n" );
        }
    }
}

This way of using the received packets is very problematic due to two reasons:

The first reason is that I update the simulation logic in my NetworkManager class, which is not good in my opinion because the logic is scattered all over the place. The logic should only be updated when I call player.updateMovement(), and not in class NetworkManager's functions, because it gets really hard for me to follow what's happening.

Second reason is that I get a circular dependency because I need to pass the Player object as an argument to the NetworkManager in order to update its position, and then I need to pass a NetworkManager object as an argument to some of the Player's functions.

I need somehow to store all the received data in the NetworkManager without updating anything or passing any objects as arguments.

Then I need to use that stored data and pass it into the correct Player object.( I want to have 2 or more players )

Guys,

First, thanks for taking the time to read this. ^_^

Second, what do you suggest? :huh:

Advertisement
Typically, you will have a hash table (or map, or dictionary) that uses the remote IP address/port as key, and uses the player ID (or player object) as value.
Then, you can look up which player it is, from the source of the incoming data.

There are some session hijacking risks involved, so using a secondary method to authenticate the connection (using encryption keys and signatures) is useful for bigger games with more risk, but you don't need to worry about that for now.
enum Bool { True, False, FileNotFound };

The simple answer is - the networking code should handle the part related to networking - nothing more.

In this case, that means:

  1. Receive the packet from the network
  2. Extract game-related data from it
  3. Forward that data to the game

If I remember Raknet correctly then there is one 'peer' per remote connection, so that tells you which player it is, which you can look up with the hash/map/dict like hplus0603 said.

Moving the logic is trivial. Instead of reaching into player and into the camera, you call a method on the player to say what message it received, and it does the work.

So this:

player.mainCam.setCurrentPosition( player.mainCam.getCurrentPosition() - player.moveHelperCam.getDirection() );

Becomes this:

player.receivedInputMessage(PLAYER_MOVE_FORWARD)

And the player class handles moving its camera accordingly.

I need somehow to store all the received data in the NetworkManager without updating anything or passing any objects as arguments.

No you don't. Why do you think so? A circular dependency is not the end of the world. If you really want, we could introduce a 3rd class, a PlayerNetworkHandler, which knows about a Player and the NetworkManager, and the NetworkManager could call it after each message, and that would call functions on a Player. Or you could have some sort of message queue. But why bother?

Typically, you will have a hash table (or map, or dictionary) that uses the remote IP address/port as key, and uses the player ID (or player object) as value.

So this: player.mainCam.setCurrentPosition( player.mainCam.getCurrentPosition() - player.moveHelperCam.getDirection() ); Becomes this: player.receivedInputMessage(PLAYER_MOVE_FORWARD)

This is exactly what I needed.

hplus and kylotan, thanks a lot for the great solutions, as always.

This topic is closed to new replies.

Advertisement