• <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>
            posts - 12,  comments - 16,  trackbacks - 0

             

            一般用Ghost主機(jī)游戲名字XXXXX #2,當(dāng)此我想顯示當(dāng)前加入游戲中的人數(shù),例如Dota,XXXXX #2(2/10),表示當(dāng)前有2個(gè)人加入.

            首先對于戰(zhàn)網(wǎng)PVPGN不支持修改游戲名字,因此我還修改pvpgn,使得支持修改游戲名字,閑話少說,先看一下我的效果。


            (在http://cid-4b5bdf2f7fd33dee.office.live.com/browse.aspx/pvpgn,可以下載我win32 x86環(huán)境下編譯好的ghostcb,pvpgn1.99)
            下面開始開工了
            修改ghost
            (1)下載ghost源碼了http://www.codelain.com/forum/index.php?topic=13083.0
            (2)bnet.h中,修改函數(shù)QueueGameRefresh,這個(gè)方法用于游戲創(chuàng)建,游戲更新的,我在這方法加入一個(gè)參數(shù),player_num:游戲人數(shù)
            void QueueGameRefresh( unsigned char state, string gameName, string hostName, CMap *map, CSaveGame *saveGame, uint32_t upTime, uint32_t hostCounter ,uint32_t player_num=0);
              bnet.cpp修改QueueGameRefresh

             void CBNET :: QueueGameRefresh( unsigned char state, string gameName, string hostName, CMap *map, CSaveGame *saveGame, uint32_t upTime, uint32_t hostCounter ,uint32_t player_num/*=0*/)
            {
                
            if( hostName.empty( ) )
                
            {
                    BYTEARRAY UniqueName 
            = m_Protocol->GetUniqueName( );
                    hostName 
            = string( UniqueName.begin( ), UniqueName.end( ) );
                }

                
                      
                         //moidfy gameName with player_num    
                gameName=gameName+"("+UTIL_ToString(player_num)+"/10)";//在游戲名字中顯示人數(shù)
                       //下面的就不用改了

            (3)game_base.cpp中,修改函數(shù)   function CBaseGame :: Update( void *fd, void *send_fd )

             for( vector<CBNET *> :: iterator i = m_GHost->m_BNETs.begin( ); i != m_GHost->m_BNETs.end( ); i++ )
                    
            {
                        
            // don't queue a game refresh message if the queue contains more than 1 packet because they're very low priority

                        
            if( (*i)->GetOutPacketsQueued( ) <= 1 )
                        
            {

                                //add m_players.size() in parmeter list 傳入?yún)?shù)當(dāng)前加入游戲的人數(shù)
                            (*i)->QueueGameRefresh( m_GameState, m_GameName, string( ), m_Map, m_SaveGame, GetTime( ) - m_CreationTime, m_HostCounter ,m_Players.size());

                            Refreshed 
            = true;
                        }

                    }

            4 在game_base.cpp中,函數(shù)CBaseGame :: EventPlayerJoined和函數(shù)CBaseGame :: EventPlayerLeft的末尾添加以下代碼,即當(dāng)有玩家加入或者退出游戲時(shí),更新游戲名字

            for( vector<CBNET *> :: iterator i = m_GHost->m_BNETs.begin( ); i != m_GHost->m_BNETs.end( ); i++ )
                
            {
                    
            // don't queue a game refresh message if the queue contains more than 1 packet because they're very low priority

                    
            if( (*i)->GetOutPacketsQueued( ) <= 1 )
                    
            {

                        (
            *i)->QueueGameRefresh( m_GameState, m_GameName, string( ), m_Map, m_SaveGame, GetTime( ) - m_CreationTime, m_HostCounter ,m_Players.size());
                    }

                }

            ghost就修改好了,下面則是要改pvpgn,支持游戲名字的修改。

            (1)還是去下載pvpgn的源碼包
            pvpgn-199.r577.tar.gz
            http://pvpgn.berlios.de/index.php?page=files
            至于pvpgn的編譯,我用的vs平臺(tái),在pvpgn包內(nèi)doc文件夾下有個(gè)編譯方法,還是比較麻煩的,在這里我就不多說了,網(wǎng)上也有文章說編譯1.99的http://yjfyy.spaces.live.com/blog/cns!B6AD95965E3A9326!550.entry()
            (2)在game.h里添加一個(gè)修改游戲名字的方法申明,
            void game_set_name(t_game * game,const char * name);
            如下

                extern t_game_flag game_get_flag(t_game const * game);
            extern int game_get_count_by_clienttag(t_clienttag ct);
            extern int game_is_ladder(t_game *game);
            extern int game_discisloss(t_game *game);
            extern int game_set_channel(t_game * game, t_channel * channel);
            extern t_channel * game_get_channel(t_game * game);
            //add function game_set_name
            extern void game_set_name(t_game * game,const char * name);


                     添加一個(gè)CRITICAL_SECTION 臨界區(qū)變量(注這個(gè)只是在windows下的,對于linux可以linux下互斥變量替換),用于多線程game_list的互斥訪問。在這里只是申明,至于定義和初始化,我把它放在winmain.cpp中,這個(gè)在后面我再細(xì)講

            #ifndef INCLUDED_GAME_TYPES
            #define INCLUDED_GAME_TYPES
            //add a CRITICAL_SECTION
            #ifdef _USE_SECTION
            #include 
            <Windows.h>
            extern CRITICAL_SECTION  gamelist_section; 
            #endif


                  (3) game.cpp中,在#inlcude "game.h",前定義_USE_SECTION

            #define _USE_SECTION
            #include 
            "game.h"
            #undef  _USE_SECTION

             在這里說明一下,為什么 要用_USE_SECTION。
            若直接在game.h不用#ifdef _USE_SECTION,那不就省事了。
            事實(shí)上這么弄會(huì)出很多編譯錯(cuò)誤,主要就是 windows.h惹的禍,因?yàn)檫@樣別的地方#include  "game.h",把windows.h也包含去了,會(huì)發(fā)生很多編譯錯(cuò)誤。
                  添加 game_set_name函數(shù)的定義
               

            extern void game_set_name(t_game * game,const char * name)
            {
                EnterCriticalSection(
            &gamelist_section);//臨界區(qū),互斥訪問,以免產(chǎn)生讀寫沖突
                
            if(stricmp(game->name,name)!=0)
                
            {
                    
                    xfree((
            void *)game->name);
                    game
            ->name=xstrdup(name);
                
                }

                LeaveCriticalSection(
            &gamelist_section);
            }

            (4)CRITICAL_SECTION  gamelist_section變量的定義及初始化(注在game.h只是申明,extern)
            在winmain.cpp中 添加#include "bnet/game.h"

            #define  _USE_SECTION
            #include 
            "bnetd/game.h"
            #ifdef _USE_SECTION
            CRITICAL_SECTION  gamelist_section; 
            #endif


                 
            在int CALLBACK WinMain函數(shù)中添加 gamelist_section的初始化

            int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE reserved, LPSTR lpCmdLine, int nCmdShow)
            {
                
                
            #ifdef _USE_SECTION
                InitializeCriticalSection(
            &gamelist_section);//初始化....
            #endif
                
                
            int result;
                Console     console;

                
            if (cmdline_load(__argc, __argv) != 1{
                    
            return -1;
                }

            (5)準(zhǔn)備工作已經(jīng)做好了,現(xiàn)在就可以更新游戲名字了
            static int _client_startgame4(t_connection * c, t_packet const *const packet)這個(gè)方法用于處理游戲建立以及游戲更新,我們就在這個(gè)方法里面更新游戲名字
            hanlde_bnet.cpp中static int _client_startgame4(t_connection * c, t_packet const *const packet)函數(shù)加入一行代碼

             

            if ((currgame = conn_get_game(c))) {
            #ifdef _SLOTS
                    
            //update the game name  ########加入這行,要使得這個(gè)生效,在編譯宏中加入_SLOTS,或者直接在game.cpp加入一行#define _SLOTS
                                    game_set_name(currgame,gamename); 
            #endif
                    
            if ((status & CLIENT_STARTGAME4_STATUSMASK_OPEN_VALID) == status) {
                    
            if (status & CLIENT_STARTGAME4_STATUS_START)
                        game_set_status(currgame, game_status_started);
                    
            else if (status & CLIENT_STARTGAME4_STATUS_FULL)
                        game_set_status(currgame, game_status_full);
                    
            else
                        game_set_status(currgame, game_status_open);
                    }
             else {
                    eventlog(eventlog_level_error, __FUNCTION__, 
            "[%d] unknown startgame4 status %d (clienttag: %s)", conn_get_socket(c), status, clienttag_uint_to_str(conn_get_clienttag(c)));
                    }


            (6) 至此因該基本完成,不過還有一個(gè)bug,處理pvpgan服務(wù)端與客戶端游戲更新不一致的情況
            例如服務(wù)端游戲名字是XXXXX #1(1/10),而客戶端沒有及時(shí)更新游戲列表,XXXXX #1(0/10),此時(shí)客戶端加入游戲時(shí),就會(huì)出錯(cuò). 修改gamelist_find_game方法,修改游戲名字查找游戲方法,我只匹配'('前面的部分,XXXXX #1(1/10)與XXXXX #1(0/10)認(rèn)為是同一個(gè)游戲。
              添加一個(gè)游戲名字匹配的輔助方法,這個(gè)只在game.cpp中添加就可以了,為內(nèi)部函數(shù)。

                bool prefix_string(const char * str,const char * prex)
            {
                
            int i=0;
                
            if(strlen(str)<strlen(prex))
                
            {
                    
            return false;
                }

                
            while(prex[i]!=0 && prex[i]!='(')
                
            {
                    
            if(prex[i]!=str[i])
                        
            return false;
                    i
            ++;
                }

                
            return true;

            }

              修改gamelist_find_game方法

            extern t_game * gamelist_find_game(char const * name, t_clienttag ctag, t_game_type type)
            {
                t_elist 
            *curr;
                t_game 
            *game;
                //臨界區(qū)
                EnterCriticalSection(
            &gamelist_section);
                elist_for_each(curr,
            &gamelist_head)
                
            {
                game 
            = elist_entry(curr,t_game,glist_link);
                
            if ((type==game_type_all || game->type==type)
                    
            && ctag == game->clienttag
                    
            && game->name
                    
            && 
                       //主要修改部分,游戲名字不一致時(shí),只匹配(前面的部分
                       (!
            strcasecmp(name,game->name) || prefix_string(game->name,name))) 
                    
            {
                        LeaveCriticalSection(
            &gamelist_section);
                        
            return game;
                    }

                }
                 //退出臨界區(qū)
                LeaveCriticalSection(
            &gamelist_section);

                
            return NULL;
            }

               
              修改 gamelist_find_game_available方法,同上
              
              

            extern t_game * gamelist_find_game_available(char const * name, t_clienttag ctag, t_game_type type)
            {
                t_elist 
            *curr;
                t_game 
            *game;
                t_game_status status;
                EnterCriticalSection(
            &gamelist_section);
                elist_for_each(curr,
            &gamelist_head)
                
            {
                    game 
            = elist_entry(curr,t_game,glist_link);
                    status 
            = game->status;

                    
            if ((type==game_type_all || game->type==type) && (ctag == game->clienttag) && (game->name)
                        
            && [color=red]
                          //主要修改部分
                          ((
            !strcasecmp(name,game->name) || prefix_string(game->name,name))) [/color] && (game->status != game_status_started) &&
                         (game
            ->status != game_status_done))
                    
            {
                        LeaveCriticalSection(
            &gamelist_section);
                        
            return game;
                    }

                }

                LeaveCriticalSection(
            &gamelist_section);

                
            return NULL;
            }


               最后說明一下,pvpgn要使得顯示游戲人數(shù)這一功能生效,需要在譯編譯宏中加入_SLOTS的定義,或者直接在在hanlde_bnet.cpp最前面,加上
            #define _SLOTS。
                
               ok,完成


            個(gè)人聯(lián)系方式:
            email :kuramawzw@163.com
            qq:370180103
            如有問題請pm我.






             

            posted on 2010-07-01 12:56 kuramawzw 閱讀(2171) 評論(4)  編輯 收藏 引用 所屬分類: 戰(zhàn)網(wǎng) PVPGN & GHOST

            FeedBack:
            # 這是評論
            2010-07-12 18:54 | winter boots
            這個(gè)原來是靠軟件實(shí)現(xiàn)的啊,哪里可以下載到呢?  回復(fù)  更多評論
              
            # re: Ghost自動(dòng)主機(jī)在游戲名字中顯示當(dāng)前加入游戲的人數(shù)!
            # re: Ghost自動(dòng)主機(jī)在游戲名字中顯示當(dāng)前加入游戲的人數(shù)!
            2010-09-15 11:17 | verlock
            請問如何將其移植到linux系統(tǒng),具體怎么修改,謝謝  回復(fù)  更多評論
              
            # re: Ghost自動(dòng)主機(jī)在游戲名字中顯示當(dāng)前加入游戲的人數(shù)![未登錄]
            2010-10-11 11:13 | kuramawzw
            我使用了windows的臨界區(qū),把臨界區(qū)相關(guān)的代碼改成linux下的mutex之類就可以  回復(fù)  更多評論
              
            <2010年10月>
            262728293012
            3456789
            10111213141516
            17181920212223
            24252627282930
            31123456

            常用鏈接

            留言簿(5)

            隨筆分類

            隨筆檔案

            文章檔案

            Algorithm

            搜索

            •  

            最新評論

            閱讀排行榜

            評論排行榜

            色欲综合久久中文字幕网| 99久久综合国产精品免费| 久久乐国产综合亚洲精品| 国产福利电影一区二区三区久久老子无码午夜伦不 | 久久久久99这里有精品10 | 久久综合亚洲色HEZYO国产| 国产激情久久久久影院老熟女| 久久国产精品77777| 久久久亚洲欧洲日产国码aⅴ| 伊人色综合久久天天人手人婷| 亚洲综合精品香蕉久久网| 亚洲AV无码1区2区久久| 亚洲国产另类久久久精品黑人| 亚洲精品乱码久久久久66| 久久综合香蕉国产蜜臀AV| 漂亮人妻被黑人久久精品| 国产一级持黄大片99久久| 亚洲一区二区三区日本久久九| 99久久亚洲综合精品网站| 久久国产精品一区| 伊人久久大香线蕉综合5g| 少妇高潮惨叫久久久久久| 99久久精品国产麻豆| 国产精品99久久久久久猫咪| 久久久久97国产精华液好用吗| 久久亚洲高清综合| 久久天天躁狠狠躁夜夜96流白浆| 久久国产精品99国产精| 93精91精品国产综合久久香蕉| 日本亚洲色大成网站WWW久久| 亚洲AV无码久久精品成人| 亚洲国产精品久久66| 人妻丰满?V无码久久不卡| 日产精品99久久久久久| 91久久国产视频| 亚洲va久久久噜噜噜久久| 久久久久国产一级毛片高清版| 久久久午夜精品福利内容| 91视频国产91久久久| 欧美精品九九99久久在观看| 久久99精品久久久久婷婷|