Getting Online with Multiplayer Gaming(12)

Getting Online with Multiplayer Gaming(12)

 

Processing Game Messages

Now that the game messages have made their way into the message queue, the next
step is to remove the messages at each frame and process them. To keep things
running quickly, only 64 messages at a time are processed (as defined by the
MESSAGE_PER_FRAME macro in the server source code).

Message processing takes place within the cApp::process_queued_msg function:

void  cApp::process_queue_msg()
{
    
long  count = 0;

    
// pull out messages to process
     while (count != MESSAGES_PER_FRAME && m_msg_head != m_msg_tail)
    {
        
// get pointer to 'tail' message
        EnterCriticalSection(&m_msg_cs);
        sMsg* msg = &m_msgs[m_msg_tail];
        LeaveCriticalSection(&m_msg_cs);

        
// process a single message based on type
         switch (msg->header.type)
        {
        
case  MSG_SEND_PLAYER_INFO:
            send_player_info(msg, msg->header.player_id);
            
break ;

        
case  MSG_CREATE_PLAYER:
            add_player(msg);
            
break ;

        
case  MSG_DESTROY_PLAYER:
            remove_player(msg);
            
break ;

        
case  MSG_STATE_CHANGE:
            player_state_change(msg);
            
break ;
        }

        count++;    
// increase processed message count

        // goto next message in list
        EnterCriticalSection(&m_msg_cs);
        m_msg_tail = (m_msg_tail + 1) % MAX_MESSAGES;
        LeaveCriticalSection(&m_msg_cs);
    }
}

As process_queue_msg iterates through the next 64 messages, it calls upon a separate
set of functions to handle the various game messages. Those message-handling
functions are described in the following sections.

 

cApp::add_player

Let’s face it—your game is going to be cool, and before long you’ll have players joining
the game left and right. When a player joins the game (or at least tries to join), a player
message is added to the queue, and when that message is processed, the add_player function
is called to find room for the player. If no room exists, that player is disconnected.

bool  cApp::add_player( const  sMsg* msg)
{
    DPNID player_id = msg->header.player_id;
    DWORD size = 0;
    DPN_PLAYER_INFO* player_info = NULL;

    
// get the player information
    HRESULT hr = m_server.get_server()->GetClientInfo(player_id, player_info, &size, 0);
    
if (FAILED(hr) && hr != DPNERR_BUFFERTOOSMALL)
        
return   false ;

    
// allocate player data buffer and try again
    player_info = (DPN_PLAYER_INFO*)  new   byte [size];
    
if (player_info == NULL)
        
return   false ;

    ZeroMemory(player_info, size);

    player_info->dwSize = 
sizeof (DPN_PLAYER_INFO);

    
if (FAILED(m_server.get_server()->GetClientInfo(player_id, player_info, &size, 0)))
    {
        delete[] player_info;
        
return   false ;
    }
    
    
// make sure not already in list
     for ( long  i = 0; i < MAX_PLAYERS; i++)
    {
        
if (m_players[i].player_id == player_id && m_players[i].connected)
        {
            delete[] player_info;
            m_server.disconnect_player(player_id);
            
return   false ;
        }
    }

    
// search for an empty slot to put player
     for ( long  i = 0; i < MAX_PLAYERS; i++)
    {
        
if (! m_players[i].connected)
        {
            m_players[i].connected  = 
true ;
            m_players[i].player_id  = player_id;
            m_players[i].x_pos      = 0.0f;
            m_players[i].y_pos      = 0.0f;
            m_players[i].z_pos      = 0.0f;
            m_players[i].direction  = 0.0f;
            m_players[i].speed      = 512.0f;
            m_players[i].last_state = STATE_IDLE;
            m_players[i].latency    = 0;

            wcstombs(m_players[i].name, player_info->pwszName, 
sizeof (m_players[i].name));

            
// send add player information to all players in area

            sCreatePlayerMsg create_msg;

            create_msg.header.type      = MSG_CREATE_PLAYER;
            create_msg.header.size      = 
sizeof (sCreatePlayerMsg);
            create_msg.header.player_id = player_id;
            create_msg.x_pos            = m_players[i].x_pos;
            create_msg.y_pos            = m_players[i].y_pos;
            create_msg.z_pos            = m_players[i].z_pos;
            create_msg.direction        = m_players[i].direction;

            send_network_msg(&create_msg, DPNSEND_NOLOOPBACK, ALL_CLIENT_PLAYERS);

            m_connected_player_num++;
            list_players();
            delete[] player_info;

            
return   true ;
        }   
    }

    delete[] player_info;
    m_server.disconnect_player(player_id);

    
return   false ;
}

///////////////////////////////////////////////////////////////////////////////////////

void  cApp::list_players()
{
    
// clear player list
    reset_listbox(m_controls[CONTROL_PLAYER_LIST]);

    
// count alll players and add names to list
     for ( long  i = 0; i < MAX_PLAYERS; i++)
    {
        
if (m_players[i].connected)
            add_string_to_listbox(m_controls[CONTROL_PLAYER_LIST], m_players[i].name);
    }

    
// display player count
     if (m_connected_player_num == 0)
        SetWindowText(m_controls[CONTROL_PLAYER_NUM], "No Connected Players");
    
else
    {
        
char  text[256];
        sprintf(text, "%lu players connected", m_connected_player_num);

        SetWindowText(m_controls[CONTROL_PLAYER_NUM], text);
    }
}
 

你可能感兴趣的:(Getting Online with Multiplayer Gaming(12))