• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            天行健 君子當自強而不息

            Getting Online with Multiplayer Gaming(17)

             

            Message Handling

            The client application uses the same message structures as the server, but the client
            has no need for queuing messages. As Figure 19.16 demonstrates, incoming messages
            are immediately parsed by the client.

            Now that you’ve seen the receive function that handles incoming message, it’s time
            to examine each message handling function.

             

            cApp::create_player

            As clients join the game, the server informs other connected clients of those new
            arrivals. The purpose of the following create_player function is to find room in the
            sPlayer structure and store the player data:

            void cApp::create_player(const sMsg* msg)
            {
                sCreatePlayerMsg* create_msg = (sCreatePlayerMsg*) msg;

                
            // do not add local player to list
                if(create_msg->header.player_id == m_players[0].player_id)
                    
            return;

                
            long player_index = -1;

                
            for(long i = 1; i < MAX_PLAYERS; i++)
                {
                    
            if(m_players[i].connected)
                    {
                        
            // makre sure player not already in list
                        if(m_players[i].player_id == create_msg->header.player_id)
                            
            return;
                    }
                    
            else
                        player_index = i;
                }

                
            if(player_index == -1)  // no open slots
                    return;

                EnterCriticalSection(&m_update_cs);

                
            // add player data
                m_players[player_index].connected  = true;
                m_players[player_index].player_id  = create_msg->header.player_id;
                m_players[player_index].x_pos      = create_msg->x_pos;
                m_players[player_index].y_pos      = create_msg->y_pos;
                m_players[player_index].z_pos      = create_msg->z_pos;
                m_players[player_index].direction  = create_msg->direction;
                m_players[player_index].speed      = 0.0f;
                m_players[player_index].last_state = STATE_IDLE;

                m_num_players++;

                LeaveCriticalSection(&m_update_cs);
            }

             

            cApp::destroy_player

            The server notifies clients when a player is leaving a session. The clients, in turn,
            signal the player as being disconnected and skips updating the player during the
            update cycle. The following code determines which client is disconnected and
            takes the appropriate steps:

            void cApp::destroy_player(const sMsg* msg)
            {
                sDestroyPlayerMsg* destroy_msg = (sDestroyPlayerMsg*) msg;

                
            // do not remove local player from list
                if(destroy_msg->header.player_id == m_players[0].player_id)
                    
            return;

                
            long player_index = get_player_index(destroy_msg->header.player_id);
                
            if(player_index == -1)
                    
            return;

                EnterCriticalSection(&m_update_cs);

                m_players[player_index].connected = 
            false;
                m_num_players--;

                LeaveCriticalSection(&m_update_cs);
            }
             

            cApp::change_player_state

            The client processes changes of state in players by pulling out the message data and
            putting it in the player’s structure. If a player isn’t found in the list of players, the
            client requests that player’s information via a MSG_GET_PLAYER_INFO message and exits the
            change_player_state function without further ado.

            This is the only situation in which a player’s coordinates can be directly modified
            by a state change—clients are not allowed to make direct changes to their coordinates
            (to avoid cheating), so it’s up to the server to tell players just where they are
            in the world during the updates:

            void cApp::change_player_state(const sMsg* msg)
            {
                sStateChangeMsg* change_msg = (sStateChangeMsg*) msg;

                
            long player_index = get_player_index(change_msg->header.player_id);

                
            if(player_index == -1)  // unknown player - request information
                {
                    sRequestPlayerInfoMsg request_msg;

                    request_msg.header.type       = MSG_GET_PLAYER_INFO;
                    request_msg.header.size       = 
            sizeof(sRequestPlayerInfoMsg);
                    request_msg.header.player_id  = m_players[0].player_id;
                    request_msg.request_player_id = change_msg->header.player_id;

                    send_network_msg(&request_msg, DPNSEND_NOLOOPBACK);
                    
            return;
                }

                EnterCriticalSection(&m_update_cs);

                
            // store new player state information
                m_players[player_index].last_state = change_msg->state;
                m_players[player_index].x_pos      = change_msg->x_pos;
                m_players[player_index].y_pos      = change_msg->y_pos;
                m_players[player_index].z_pos      = change_msg->z_pos;
                m_players[player_index].direction  = change_msg->direction;
                m_players[player_index].speed      = change_msg->speed;
                m_players[player_index].latency    = change_msg->latency;

                
            // bounds latency to 1 second
                if(m_players[player_index].latency > 1000)
                    m_players[player_index].latency = 1000;

                
            // adjust time based on latency
                m_players[player_index].last_update_time = timeGetTime() - m_players[player_index].latency;

                LeaveCriticalSection(&m_update_cs);
            }

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

            bool cApp::send_network_msg(void* msg, long send_flags)
            {
                sMsgHeader* header = (sMsgHeader*) msg;

                
            if(header->size == 0)
                    
            return false;

                
            return m_client.send_data(msg, header->size, send_flags);
            }

            Just like the server, the client has a send_network_msg to send the game-related
            network messages to the server.

            NOTE
            The client also depends on the latency time to modify
            the timing calculations.The server sends this latency
            time to the client, but to make things safe, the client
            application is allowed to cut the latency down to one
            second if the server states that it is higher.


            posted on 2007-12-19 16:44 lovedday 閱讀(239) 評論(0)  編輯 收藏 引用

            公告

            導航

            統(tǒng)計

            常用鏈接

            隨筆分類(178)

            3D游戲編程相關鏈接

            搜索

            最新評論

            伊人久久大香线蕉综合热线| 久久精品国产亚洲AV嫖农村妇女| 久久综合久久综合久久| 亚洲国产成人久久精品影视| 欧美与黑人午夜性猛交久久久| 亚洲精品99久久久久中文字幕 | 久久久女人与动物群交毛片| 免费观看成人久久网免费观看| 久久久久人妻一区精品果冻| 奇米综合四色77777久久| 国産精品久久久久久久| 久久精品国产亚洲av日韩| 久久久久国产| 久久最近最新中文字幕大全| 亚洲中文精品久久久久久不卡| 久久e热在这里只有国产中文精品99| 99久久这里只精品国产免费| 国产69精品久久久久99| 国产精品无码久久综合| 伊人色综合久久天天人手人婷| 久久久久无码国产精品不卡| 日本久久久久久中文字幕| 无码日韩人妻精品久久蜜桃| 狠狠色丁香婷婷久久综合五月| 国产午夜精品久久久久九九| 99麻豆久久久国产精品免费| 国内精品伊人久久久久777| 色婷婷综合久久久久中文字幕| 国产免费久久精品丫丫| 久久精品国产一区| 久久噜噜电影你懂的| 色综合色天天久久婷婷基地| 国产精品美女久久久| 久久综合久久久| 国产精品99久久久久久宅男| 久久99精品久久久久久野外| 久久中文字幕视频、最近更新 | 久久久久国产视频电影| 久久精品国产国产精品四凭| 久久国产精品一区| 中文字幕久久亚洲一区|