123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167 |
- /*
- * Seven Kingdoms: Ancient Adversaries
- *
- * Copyright 1997,1998 Enlight Software Ltd.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
- // Filename : ODPLAY.CPP
- // Description : MultiPlayerDP, multiplayer class using directPlay
- // Onwer : Gilbert
- #ifndef IMAGICMP
- // #define INITGUID
- // #define INITGUID for dplay.h to define IID_IDirectPlay3A
- #include <dplay.h>
- // #undef INITGUID
- #include <ODPLAY.h>
- #include <ALL.h>
- #include <string.h>
- #include <OVGALOCK.h>
- #include <OBLOB.h>
- #include <winbase.h>
- // Define constant
- GUID GAME_GUID =
- { 0x12f70d44, 0x68be, 0x11d0, { 0xaa, 0xb6, 0x0, 0x0, 0xe9, 0xf9, 0xd, 0x5d } };
- // To enable a lobby to launch a DirectPlay application, the application must add
- // the following entries to the system registry.
- //[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\DirectPlay\Applications\SevenKingdoms]
- //"Guid"="{12F70D44-68BE-11D0-AAB6-0000E9F90D5D}"
- //"File"="7k.exe"
- //"CommandLine"="-!lobby!"
- //"Path"="C:\Seven Kingdoms"
- //"CurrentDirectory"="C:\Seven Kingdoms"
- // note that [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\DirectPlay\Applications]
- // folder may not exist after installed dx5
- HANDLE PLAYER_MESSAGE_HANDLE = NULL; // ???
- DPSessionDesc::DPSessionDesc()
- {
- lpszSessionNameA = session_name;
- lpszPasswordA = pass_word;
- }
- DPSessionDesc::DPSessionDesc(const DPSESSIONDESC2 &dpSessionDesc) : DPSESSIONDESC2(dpSessionDesc)
- {
- after_copy();
- }
- DPSessionDesc::DPSessionDesc(const DPSessionDesc &dpSessionDesc) : DPSESSIONDESC2(dpSessionDesc)
- {
- after_copy();
- }
- DPSessionDesc& DPSessionDesc::operator= (const DPSessionDesc &src)
- {
- memcpy(this, &src, sizeof( DPSessionDesc ) );
- after_copy();
- return *this;
- }
- void DPSessionDesc::after_copy()
- {
- if( lpszSessionNameA )
- {
- strcpy(session_name, lpszSessionNameA);
- session_name[strlen(lpszSessionNameA)] = '\0';
- }
- else
- {
- session_name[0] = '\0';
- }
- lpszSessionNameA = session_name;
- if( lpszPasswordA)
- {
- strcpy(pass_word, lpszPasswordA);
- pass_word[strlen(lpszPasswordA)] = '\0';
- }
- else
- {
- pass_word[0] = '\0';
- }
- lpszPasswordA = pass_word;
- }
- DPSessionDesc *DPSessionDesc::before_use()
- {
- lpszSessionNameA = session_name;
- lpszPasswordA = pass_word;
- return this;
- }
- // to start a multiplayer game, first check if it is called from a
- // lobbied (MultiPlayerDP::is_lobbied)
- // if it is a lobbied, call init_lobbied before create_player
- // if not, call poll_service_provider; display them and let
- // user to select, call init and pass the guid of the selected
- // service; create_session or poll_sessions+join_session;
- // finally create_player.
- // ------- begin of function MultiPlayerDP::MultiPlayerDP -------//
- MultiPlayerDP::MultiPlayerDP() : service_providers(sizeof(DPServiceProvider), 10 ),
- current_sessions(sizeof(DPSessionDesc), 10 ), player_pool(sizeof(DPPlayer), 8 ),
- recv_buffer(new char[MP_RECV_BUFFER_SIZE])
- {
- init_flag = 0;
- direct_play_lobby = NULL;
- direct_play1 = NULL;
- direct_play3 = NULL;
- recv_buffer_size = MP_RECV_BUFFER_SIZE;
- host_flag = 0;
- lobbied_flag = 0;
- connection_string = NULL;
- }
- // ------- end of function MultiPlayerDP::MultiPlayerDP -------//
- // ------- begin of function MultiPlayerDP::~MultiPlayerDP -------//
- MultiPlayerDP::~MultiPlayerDP()
- {
- deinit();
- delete[] recv_buffer;
- }
- // ------- end of function MultiPlayerDP::~MultiPlayerDP -------//
- // ------- begin of function MultiPlayerDP::pre_init -------//
- void MultiPlayerDP::pre_init()
- {
- // nothing, for compatibilities with MultiPlayerIM
- lobbied_flag = 0;
- }
- // ------- begin of function MultiPlayerDP::pre_init -------//
- // ------- begin of function MultiPlayerDP::init -------//
- void MultiPlayerDP::init(GUID serviceProviderGUID)
- {
- VgaFrontLock vlock;
- if( !DirectPlayCreate( &serviceProviderGUID, &direct_play1, NULL) )
- {
- if( !direct_play1->QueryInterface( IID_IDirectPlay3A, (void **)&direct_play3) )
- {
- init_flag = 1;
- }
- else
- {
- direct_play3 = NULL;
- direct_play1->Release();
- direct_play1 = NULL;
- }
- }
- else
- {
- direct_play1 = NULL;
- }
- host_flag = 0;
- // ######## patch begin Gilbert 24/11 ######//
- my_player_id = DPID_ALLPLAYERS; // no player
- // ######## patch end Gilbert 24/11 ######//
- }
- // ------- end of function MultiPlayerDP::init -------//
- // ------- begin of function MultiPlayerDP::deinit -------//
- void MultiPlayerDP::deinit()
- {
- host_flag = 0;
- lobbied_flag = 0;
- if(init_flag)
- {
- // ######## patch begin Gilbert 24/11 ######//
- if( my_player_id != DPID_ALLPLAYERS)
- {
- destroy_player( my_player_id );
- Sleep(2000); // 2 seconds
- }
- // ######## patch end Gilbert 24/11 ######//
- VgaFrontLock vgaLock;
- if( direct_play3 )
- {
- direct_play3->Release();
- direct_play3 = NULL;
- }
- if( direct_play1 )
- {
- direct_play1->Release();
- direct_play1 = NULL;
- }
- // ######## patch begin Gilbert 24/11 ######//
- my_player_id = DPID_ALLPLAYERS; // mark player deleted
- // ######## patch end Gilbert 24/11 ######//
- init_flag = 0;
- }
- if( direct_play_lobby )
- {
- VgaFrontLock vgaLock;
- direct_play_lobby->Release();
- direct_play_lobby = NULL;
- }
- if( connection_string )
- {
- mem_del(connection_string);
- connection_string = NULL;
- }
- }
- // ------- end of function MultiPlayerDP::deinit -------//
- // ----- begin of function MultiPlayerDP::init_lobbied ------//
- void MultiPlayerDP::init_lobbied(int maxPlayers, char *)
- {
- HRESULT hr;
- VgaFrontLock vlock;
- // ------- create DirectPlayLobby, if necessary ------//
- if( direct_play_lobby == NULL)
- {
- LPDIRECTPLAYLOBBYA directPlayLobby = NULL;
- hr = DirectPlayLobbyCreate( NULL, &directPlayLobby, NULL, NULL, 0);
- if( hr == DP_OK )
- {
- hr = directPlayLobby->QueryInterface(IID_IDirectPlayLobby2A, (void **)&direct_play_lobby);
- directPlayLobby->Release();
- if( hr != DP_OK )
- return;
- }
- else
- {
- return;
- }
- }
- // ------ get connection setting ---------//
- DWORD bufferSize = 0;
- hr = direct_play_lobby->GetConnectionSettings(0, NULL, &bufferSize);
- if( hr == DP_OK || hr == DPERR_BUFFERTOOSMALL)
- {
- bufferSize += 0x80; // give them a little more
- connection_string = (DPLCONNECTION *)mem_resize(connection_string, bufferSize);
- hr = direct_play_lobby->GetConnectionSettings(0, connection_string, &bufferSize);
- if( hr == DP_OK )
- {
- // ------ modify connectString.lpSessionDesc here -------//
- connection_string->lpSessionDesc->dwFlags = DPSESSION_KEEPALIVE | DPSESSION_NODATAMESSAGES;
- connection_string->lpSessionDesc->dwMaxPlayers = maxPlayers;
- hr = direct_play_lobby->SetConnectionSettings(0,0, connection_string);
- if( hr != DP_OK )
- return;
- joined_session = *connection_string->lpSessionDesc;
- // ------ obtain direct play interface --------//
- direct_play1 = NULL;
- LPDIRECTPLAY2A directPlay2;
- hr = direct_play_lobby->Connect(0, &directPlay2, NULL);
- if( hr != DP_OK )
- return;
- // query DIRECTPLAY3A interface
- hr = directPlay2->QueryInterface( IID_IDirectPlay3A, (void **)&direct_play3);
- if( hr != DP_OK )
- {
- direct_play3 = NULL;
- directPlay2->Release();
- directPlay2 = NULL;
- return;
- }
- directPlay2->Release();
- directPlay2 = NULL;
- init_flag = 1;
- if( connection_string->dwFlags & DPLCONNECTION_CREATESESSION )
- lobbied_flag = 1; // auto create
- else if( connection_string->dwFlags & DPLCONNECTION_JOINSESSION )
- lobbied_flag = 2; // auto join
- else
- lobbied_flag = 4; // user selectable
- bufferSize = sizeof(DPSESSIONDESC2);
- direct_play3->GetSessionDesc( &joined_session, &bufferSize);
- joined_session.after_copy();
- }
- else
- {
- if( hr != DPERR_NOTLOBBIED )
- err.run("Cannot get connection string from lobby");
- }
- }
- else
- {
- if( hr != DPERR_NOTLOBBIED )
- err.run("Cannot get connection string from lobby");
- }
- }
- // ----- end of function MultiPlayerDP::init_lobbied ------//
- // ----- begin of function MultiPlayerDP::is_lobbied -----//
- // return 0=not lobbied, 1=auto create, 2=auto join, 4=selectable
- int MultiPlayerDP::is_lobbied()
- {
- return lobbied_flag;
- }
- // ----- end of function MultiPlayerDP::is_lobbied -----//
- // ----- begin of function MultiPlayerDP::get_lobbied_name -----//
- char *MultiPlayerDP::get_lobbied_name()
- {
- err_when(!is_lobbied());
- // ------ get connection setting ---------//
- if( connection_string )
- return connection_string->lpPlayerName->lpszShortNameA;
- else
- return NULL;
- }
- // ----- end of function MultiPlayerDP::get_lobbied_name -----//
- // ----- begin of function MultiPlayerDP::poll_service_providers -----//
- //
- // store all possible service provider (TCPIP, IPX, modem, null modem ... )
- // into service_provider_array
- //
- // need not call init before get_service_provider
- //
- // called by DirectPlayEnumerate() for each DirectPlay Service Provider
- static BOOL FAR PASCAL directPlayEnumerateCallback( LPGUID lpSPGuid, LPTSTR lpszSPName,
- DWORD dwMajorVersion, DWORD dwMinorVersion, LPVOID mpPtr)
- {
- DPServiceProvider sp;
- MultiPlayerDP *mpdpPtr = (MultiPlayerDP *)mpPtr;
- sp.guid = *lpSPGuid;
- strncpy(sp.description,lpszSPName, MP_SERVICE_PROVIDER_NAME_LEN);
- sp.description[MP_SERVICE_PROVIDER_NAME_LEN] = '\0';
- mpdpPtr->service_providers.linkin(&sp);
- return TRUE;
- }
- void MultiPlayerDP::poll_service_providers()
- {
- service_providers.zap();
- // ------ allocate spaces for service_provider_array -------//
- VgaFrontLock vgaLock;
- DirectPlayEnumerateA( directPlayEnumerateCallback, this );
- }
- // ----- end of function MultiPlayerDP::poll_service_providers -----//
- // ----- begin of function MultiPlayerDP::get_service_provder -----//
- // return a service provider
- //
- // <int> i i-th service provider (i start from 1)
- // return pointer to a DPServiceProvider, NULL if no more
- DPServiceProvider* MultiPlayerDP::get_service_provider(int i)
- {
- if( i <= 0 || i > service_providers.size() )
- return NULL;
- return (DPServiceProvider *) service_providers.get(i);
- }
- // ----- end of function MultiPlayerDP::get_service_provder -----//
- // ----- begin of function MultiPlayerDP::poll_sessions ------//
- //
- // store all available sessions (TCPIP, IPX, modem, null modem ... )
- // into current_sessions
- //
- static BOOL FAR PASCAL EnumSessionsCallback( LPCDPSESSIONDESC2 lpSessionDesc,
- LPDWORD timeOut, DWORD flags, LPVOID mpPtr)
- {
- if( flags & DPESC_TIMEDOUT )
- return FALSE;
- if( memcmp(&lpSessionDesc->guidApplication, &GAME_GUID, sizeof(GUID)) == 0 )
- {
- MultiPlayerDP *mpdpPtr = (MultiPlayerDP *)mpPtr;
- DPSessionDesc sessionDesc(*lpSessionDesc);
- mpdpPtr->current_sessions.linkin(&sessionDesc);
- }
- return TRUE;
- }
- int MultiPlayerDP::poll_sessions()
- {
- err_when(!init_flag);
- current_sessions.zap();
- DPSESSIONDESC2 sessionDesc;
- memset(&sessionDesc, 0, sizeof( sessionDesc ) );
- sessionDesc.dwSize = sizeof( sessionDesc );
- sessionDesc.guidApplication = GAME_GUID;
- MouseDispCount showMouse;
- // ##### patch begin Gilbert 9/1 #########//
- // VgaFrontLock vgaLock; // MouseDispCount unlock vga_front
- // ##### end begin Gilbert 9/1 #########//
- VgaCustomPalette vgaCPal(DIR_RES"PAL_WIN.RES");
- return DP_OK == direct_play3->EnumSessions(&sessionDesc , 0, EnumSessionsCallback, this,
- DPENUMSESSIONS_AVAILABLE | DPENUMSESSIONS_ASYNC);
- }
- // ----- end of function MultiPlayerDP::poll_sessions ------//
- // ----- begin of function MultiPlayerDP::get_session ------//
- // return a session description
- //
- // <int> i i-th session (i start from 1)
- // return pointer to a session, NULL if no more
- DPSessionDesc *MultiPlayerDP::get_session(int i)
- {
- if( i <= 0 || i > current_sessions.size() )
- return NULL;
- return ((DPSessionDesc *) current_sessions.get(i))->before_use();
- }
- // ----- end of function MultiPlayerDP::get_session ------//
- // ----- begin of function MultiPlayerDP::create_session ----//
- //
- // create a new session
- //
- // <char *> sessionName arbitary name to identify a session, input from user
- // <int> maxPlayers maximum no. of players in a session
- //
- // return TRUE if success
- int MultiPlayerDP::create_session(char *sessionName, int maxPlayers)
- {
- if(!init_flag || maxPlayers < 1)
- return FALSE;
- if( is_lobbied() == 1 )
- {
- host_flag = 1;
- return TRUE;
- }
- memset(&joined_session, 0, sizeof( joined_session) );
- joined_session.dwSize = sizeof( DPSESSIONDESC2 );
- // DPSESSION_NODATAMESSAGES disable personal data
- // remove DPSESSION_MIGRATEHOST
- joined_session.dwFlags = DPSESSION_KEEPALIVE | DPSESSION_NODATAMESSAGES ;
- joined_session.guidApplication = GAME_GUID;
- joined_session.dwMaxPlayers = maxPlayers;
- strncpy(joined_session.session_name, sessionName, MP_SESSION_NAME_LEN );
- joined_session.session_name[MP_SESSION_NAME_LEN]= '\0';
- joined_session.lpszSessionNameA = joined_session.session_name;
- MouseDispCount showMouse;
- // ##### patch begin Gilbert 9/1 #########//
- // VgaFrontLock vgaLock; // MouseDispCount unlock vga_front
- // ##### end begin Gilbert 9/1 #########//
- VgaCustomPalette vgaCPal(DIR_RES"PAL_WIN.RES");
- if( !direct_play3->Open(&joined_session, DPOPEN_CREATE) )
- {
- host_flag = 1;
- return TRUE;
- }
- return FALSE;
- }
- // ----- end of function MultiPlayerDP::create_session ----//
- // ------ begin of function MultiPlayerDP::join_session ------//
- // join a session, by passing the DPSessionDesc pointer
- //
- // <DPSessionDesc *> pointer to a DPSessionDesc
- //
- // return TRUE if success
- int MultiPlayerDP::join_session(DPSessionDesc* sessionDesc)
- {
- if( !init_flag)
- return FALSE;
- if( is_lobbied() == 2 )
- {
- host_flag = 0;
- return TRUE;
- }
- joined_session = *sessionDesc;
- VgaFrontLock vgaLock;
- if(!direct_play3->Open(&joined_session, DPOPEN_JOIN))
- {
- host_flag = 0;
- return TRUE;
- }
- return FALSE;
- }
- // join a session, by passing the index passed into get_session()
- // note : do not call poll_sessions between get_session and join_session
- //
- // <int> currentSessionIndex the index passed into get_session()
- //
- // currentSessionIndex start from 1
- int MultiPlayerDP::join_session(int currentSessionIndex)
- {
- if( !init_flag)
- return FALSE;
- if( is_lobbied() == 2 )
- {
- host_flag = 0;
- return TRUE;
- }
- VgaFrontLock vgaLock;
- joined_session = *get_session(currentSessionIndex);
- if(!direct_play3->Open(&joined_session, DPOPEN_JOIN))
- {
- host_flag = 0;
- return TRUE;
- }
- return FALSE;
- }
- // ------ end of function MultiPlayerDP::join_session ------//
- // ------ begin of function MultiPlayerDP::close_session ------//
- void MultiPlayerDP::close_session()
- {
- VgaFrontLock vgaLock;
- if( init_flag)
- direct_play3->Close();
- host_flag = 0;
- }
- // ------ end of function MultiPlayerDP::close_session ------//
- // ------ begin of function MultiPlayerDP::disable_join_session ------//
- void MultiPlayerDP::disable_join_session()
- {
- // called by host only!
- err_when( !host_flag );
- if( init_flag && host_flag )
- {
- joined_session.dwFlags |= DPSESSION_JOINDISABLED | DPSESSION_NEWPLAYERSDISABLED;
- VgaFrontLock vgaLock;
- direct_play3->SetSessionDesc( &joined_session, 0 );
- }
- }
- // ------ end of function MultiPlayerDP::disable_join_session ------//
- // ------ begin of function MultiPlayerDP::create_player ------//
- // create a local player
- //
- // <char *> friendlyName short name of the player, best to be one word only
- // [char *] formalName long name of the player, take friendlyName if NULL (default: NULL)
- // [void *] lpData, [DWORD] dataSize pointer and size of any data sent the remote (default: NULL, 0)
- // [DWORD] flags not use reserved (default:0)
- //
- // return TRUE if success
- //
- int MultiPlayerDP::create_player(char *friendlyName, char *formalName,
- LPVOID lpData, DWORD dataSize, DWORD flags)
- {
- if(!init_flag)
- return FALSE;
- DPNAME dpName;
- memset(&dpName, 0, sizeof(dpName) );
- dpName.dwSize = sizeof(dpName);
- dpName.lpszShortNameA = friendlyName;
- dpName.lpszLongNameA = formalName ? formalName : friendlyName;
- VgaFrontLock vgaLock;
- return !direct_play3->CreatePlayer(&my_player_id, &dpName, PLAYER_MESSAGE_HANDLE,
- lpData, dataSize, flags);
- }
- // ------ end of function MultiPlayerDP::create_player -----//
- // ------ begin of function MultiPlayerDP::destroy_player ------//
- // destroy player, (for remove from joining a session, before playing)
- //
- void MultiPlayerDP::destroy_player( DPID playerId )
- {
- VgaFrontLock vgaLock;
- direct_play3->DestroyPlayer(playerId);
- }
- // ------ end of function MultiPlayerDP::destroy_player ------//
- // -------- begin of function MultiPlayerDP::poll_players ------//
- // collect all players in the session into player_pool
- // get each player by calling get_player
- //
- static BOOL FAR PASCAL EnumPlayerCallback(DPID dpId, DWORD dwPlayerType,
- LPCDPNAME lpName, DWORD dwFlags, LPVOID mpPtr)
- {
- MultiPlayerDP *mpdpPtr = (MultiPlayerDP *)mpPtr;
- DPPlayer dpPlayer;
- dpPlayer.player_id = dpId;
- strncpy(dpPlayer.friendly_name, lpName->lpszShortNameA, MP_FRIENDLY_NAME_LEN );
- dpPlayer.friendly_name[MP_FRIENDLY_NAME_LEN] = '\0';
- strncpy(dpPlayer.formal_name, lpName->lpszLongNameA, MP_FORMAL_NAME_LEN );
- dpPlayer.formal_name[MP_FORMAL_NAME_LEN] = '\0';
- dpPlayer.connecting = 1;
- mpdpPtr->player_pool.linkin(&dpPlayer);
- return TRUE;
- }
- void MultiPlayerDP::poll_players()
- {
- player_pool.zap();
- VgaFrontLock vgaLock;
- // direct_play3->EnumPlayers(NULL, EnumPlayerCallback, this, DPENUMPLAYERS_LOCAL );
- // direct_play3->EnumPlayers(NULL, EnumPlayerCallback, this, DPENUMPLAYERS_REMOTE);
- if(init_flag)
- direct_play3->EnumPlayers(NULL, EnumPlayerCallback, this, 0 );
- }
- // -------- end of function MultiPlayerDP::poll_players ------//
- // -------- begin of function MultiPlayerDP::get_player -----//
- //
- // return the i-th player in the player_pool
- //
- DPPlayer *MultiPlayerDP::get_player(int i)
- {
- if( i <= 0 || i > player_pool.size() )
- return NULL;
- return (DPPlayer *)player_pool.get(i);
- }
- // -------- end of function MultiPlayerDP::get_player -----//
- // -------- begin of function MultiPlayerDP::search_player -----//
- //
- // search player by playerID
- //
- DPPlayer *MultiPlayerDP::search_player(DPID playerId)
- {
- DPPlayer *player;
- int i = 0;
- while( (player = get_player(++i)) != NULL )
- if( player->player_id == playerId )
- return player;
- return NULL;
- }
- //
- // search player by formal name, case insensitive
- //
- DPPlayer *MultiPlayerDP::search_player(char *name)
- {
- DPPlayer *player;
- int i = 0;
- while( (player = get_player(++i)) != NULL )
- if( strnicmp(player->formal_name, name, MP_FORMAL_NAME_LEN)== 0)
- return player;
- return NULL;
- }
- // -------- end of function MultiPlayerDP::get_player -----//
- // ------- begin of function MultiPlayerDP::is_host --------//
- int MultiPlayerDP::is_host(DPID playerID)
- {
- err_here(); // not supported
- return 0;
- }
- // ------- end of function MultiPlayerDP::is_host --------//
- // ------- begin of function MultiPlayerDP::am_I_host --------//
- int MultiPlayerDP::am_I_host()
- {
- return host_flag;
- }
- // ------- end of function MultiPlayerDP::am_I_host --------//
- // ----- begin of function MultiPlayerDP::is_player_connecting ----//
- //
- // determine whether a player is lost
- //
- // MultiPlayerDP::received must be called (or remote.poll_msg) ,
- // so if a player is really lost, the system message from
- // directPlay is received
- //
- int MultiPlayerDP::is_player_connecting(DPID playerId)
- {
- for( int p = 1; p <= player_pool.size(); ++p)
- {
- DPPlayer *dpPlayer = (DPPlayer *) player_pool.get(p);
- if( dpPlayer->player_id == playerId )
- {
- return dpPlayer->connecting;
- }
- }
- return 0;
- }
- // ----- end of function MultiPlayerDP::is_player_connecting ----//
- // ----- begin of function MultiPlayerDP::update_public_data ----//
- // update a player's public data
- //
- // return TRUE on success
- //
- int MultiPlayerDP::update_public_data(DPID playerId, LPVOID lpData, DWORD dataSize)
- {
- VgaFrontLock vgaLock;
- return !direct_play3->SetPlayerData(playerId, lpData, dataSize, DPSET_REMOTE | DPSET_GUARANTEED);
- }
- // ----- end of function MultiPlayerDP::update_public_data ----//
- // ----- begin of function MultiPlayerDP::retrieve_public_data ----//
- // retrieve a player's public data
- // prepare an allocated memory and pass its address as lpData,
- // store its size in a DWORD, pass the pointer of the DWORD as lpDataSize
- //
- // if lpData is NULL, the function can get the size of the data
- //
- // return TRUE on success, *lpDataSize is updated to the size of the data
- //
- int MultiPlayerDP::retrieve_public_data(DPID playerId, LPVOID lpData, LPDWORD lpDataSize)
- {
- VgaFrontLock vgaLock;
- return !direct_play3->GetPlayerData(playerId, lpData, lpDataSize, DPSET_REMOTE | DPSET_GUARANTEED);
- }
- // ----- end of function MultiPlayerDP::retrieve_public_data ----//
- // ----- begin of function MultiPlayerDP::update_private_data ----//
- // update a player's private data
- //
- // return TRUE on success
- //
- int MultiPlayerDP::update_private_data(DPID playerId, LPVOID lpData, DWORD dataSize)
- {
- VgaFrontLock vgaLock;
- return !direct_play3->SetPlayerData(playerId, lpData, dataSize, DPSET_LOCAL | DPSET_GUARANTEED);
- }
- // ----- end of function MultiPlayerDP::update_private_data ----//
- // ----- begin of function MultiPlayerDP::retrieve_private_data ----//
- // retrieve a player's private data
- // prepare an allocated memory and pass its address as lpData,
- // store its size in a DWORD, pass the pointer of the DWORD as lpDataSize
- //
- // if lpData is NULL, the function can get the size of the data
- //
- // return TRUE on success, *lpDataSize is updated to the size of the data
- //
- int MultiPlayerDP::retrieve_private_data(DPID playerId, LPVOID lpData, LPDWORD lpDataSize)
- {
- VgaFrontLock vgaLock;
- return !direct_play3->GetPlayerData(playerId, lpData, lpDataSize, DPSET_LOCAL | DPSET_GUARANTEED);
- }
- // ----- end of function MultiPlayerDP::retrieve_private_data ----//
- // --------- begin of function MultiPlayerDP::send ---------//
- // send message
- //
- // must not call it between IDirectDrawSurface2::Lock and IDirectDrawSurface2::Unlock,
- // or between IDirectDrawSurface2::GetDC and IDirectDrawSurface2::ReleaseDC
- // pass DPID_ALLPLAYERS as toId to all players
- //
- // return TRUE on success
- //
- int MultiPlayerDP::send(DPID toId, LPVOID lpData, DWORD dataSize)
- {
- err_when(!init_flag);
- HRESULT hr;
- {
- VgaFrontLock vgaLock;
- hr = direct_play3->Send(my_player_id, toId, 0, lpData, dataSize);
- }
- // see if any player lost
- if( hr == DPERR_INVALIDPLAYER )
- {
- for( int p = 1; p <= player_pool.size(); ++p)
- {
- DPPlayer *dpPlayer = (DPPlayer *)player_pool.get(p);
- if( dpPlayer->player_id == toId )
- {
- dpPlayer->connecting = 0;
- }
- }
- }
- err_when(hr == DPERR_SENDTOOBIG);
- return hr == DP_OK;
- }
- // --------- end of function MultiPlayerDP::send ---------//
- // ------- begin of function MultiPlayerDP::begin_stream -----//
- // signal start of a lot of guaranteed messages being sent to this player
- //
- // note : call end_stream to finish begin_stream
- //
- void MultiPlayerDP::begin_stream(DPID toId)
- {
- err_when(!init_flag);
- VgaFrontLock vgaLock;
- direct_play3->Send(my_player_id, toId, DPSEND_GUARANTEED | DPSEND_OPENSTREAM, NULL,0);
- }
- // ------- end of function MultiPlayerDP::begin_stream -----//
- // --------- begin of function MultiPlayerDP::send_stream ---------//
- // send message
- //
- // must not call it between IDirectDrawSurface2::Lock and IDirectDrawSurface2::Unlock,
- // or between IDirectDrawSurface2::GetDC and IDirectDrawSurface2::ReleaseDC
- // pass DPID_ALLPLAYERS as toId to all players
- //
- // return TRUE on success
- //
- int MultiPlayerDP::send_stream(DPID toId, LPVOID lpData, DWORD dataSize)
- {
- err_when(!init_flag);
- HRESULT hr;
- {
- VgaFrontLock vgaLock;
- hr = direct_play3->Send(my_player_id, toId, DPSEND_GUARANTEED, lpData, dataSize);
- }
- // see if any player lost
- if( hr == DPERR_INVALIDPLAYER )
- {
- for( int p = 1; p <= player_pool.size(); ++p)
- {
- DPPlayer *dpPlayer = (DPPlayer *)player_pool.get(p);
- if( dpPlayer->player_id == toId )
- {
- dpPlayer->connecting = 0;
- }
- }
- }
- err_when(hr == DPERR_SENDTOOBIG);
- return hr == DP_OK;
- }
- // --------- end of function MultiPlayerDP::send_stream ---------//
- // ------- begin of function MultiPlayerDP::end_stream -----//
- // signal end of a lot of guaranteed messages being sent to this player
- //
- void MultiPlayerDP::end_stream(DPID toId)
- {
- err_when(!init_flag);
- VgaFrontLock vgaLock;
- direct_play3->Send(my_player_id, toId, DPSEND_GUARANTEED | DPSEND_CLOSESTREAM, NULL,0);
- }
- // ------- end of function MultiPlayerDP::end_stream -----//
- // ------- begin of function MultiPlayerDP::get_msg_count ------//
- //
- // get the number of outstanding message to receive
- //
- // return -1 if fail
- //
- int MultiPlayerDP::get_msg_count()
- {
- err_when(!init_flag);
- DWORD count = 0;
- VgaFrontLock vgaLock;
- if(direct_play3->GetMessageCount(my_player_id, &count))
- return -1;
- return (int)count;
- }
- // ------- end of function MultiPlayerDP::get_msg_count ------//
- // ------- begin of function MultiPlayerDP::receive ------//
- // return NULL if fails
- // sysMsgCount records how many system messages have been handled
- // notice : *sysMsgCount may be != 0, but return NULL
- //
- char *MultiPlayerDP::receive(LPDPID from, LPDPID to, LPDWORD dSize, int *sysMsgCount)
- {
- err_when(!init_flag);
- DPID fromId, toId;
- DWORD dataSize;
- int retryFlag;
- HRESULT hr;
- VgaFrontLock vgaLock;
- if( sysMsgCount )
- *sysMsgCount = 0;
- do
- {
- retryFlag = 0;
- dataSize = recv_buffer_size;
- hr=direct_play3->Receive(&fromId, &toId, DPRECEIVE_ALL, recv_buffer, &dataSize);
- switch(hr)
- {
- case 0:
- if(fromId == DPID_SYSMSG)
- {
- handle_system_msg(recv_buffer, dataSize);
- if( sysMsgCount )
- (*sysMsgCount)++;
- retryFlag = 1;
- }
- else
- {
- *from = fromId;
- *to = toId;
- *dSize = dataSize;
- }
- break;
- case DPERR_BUFFERTOOSMALL: // assume now dataSize > recv_buffer_size
- delete[] recv_buffer;
- recv_buffer_size = dataSize + 0x400;
- recv_buffer = new char[recv_buffer_size];
- retryFlag = 1; // direct_play3->receive may not return the same message, so keep retrying
- break;
- default:
- return NULL;
- }
-
- } while (retryFlag);
- return recv_buffer;
- }
- // ------- end of function MultiPlayerDP::receive ------//
- // ------- begin of function MultiPlayerDP::handle_system_msg ------//
- void MultiPlayerDP::handle_system_msg(LPVOID lpData, DWORD dSize)
- {
- switch( ((DPMSG_GENERIC *)lpData)->dwType )
- {
- case DPSYS_ADDPLAYERTOGROUP:
- {
- DPMSG_ADDPLAYERTOGROUP *dpmsg = (DPMSG_ADDPLAYERTOGROUP *)lpData;
- }
- break;
- case DPSYS_CREATEPLAYERORGROUP:
- {
- DPMSG_CREATEPLAYERORGROUP *dpmsg = (DPMSG_CREATEPLAYERORGROUP *)lpData;
- }
- break;
- case DPSYS_DELETEPLAYERFROMGROUP:
- {
- DPMSG_DELETEPLAYERFROMGROUP *dpmsg = (DPMSG_DELETEPLAYERFROMGROUP *)lpData;
- }
- break;
- case DPSYS_DESTROYPLAYERORGROUP:
- {
- DPMSG_DESTROYPLAYERORGROUP *dpmsg = (DPMSG_DESTROYPLAYERORGROUP *)lpData;
- if( dpmsg->dwPlayerType == DPPLAYERTYPE_PLAYER)
- {
- for( int p = 1; p <= player_pool.size(); ++p)
- {
- DPPlayer *dpPlayer = (DPPlayer *)player_pool.get(p);
- if( dpPlayer->player_id == dpmsg->dpId )
- {
- dpPlayer->connecting = 0;
- }
- }
- }
- }
- break;
- case DPSYS_HOST:
- {
- DPMSG_HOST *dpmsg = (DPMSG_HOST *)lpData;
- }
- break;
- case DPSYS_SESSIONLOST:
- {
- DPMSG_SESSIONLOST *dpmsg = (DPMSG_SESSIONLOST *)lpData;
- }
- break;
- case DPSYS_SETPLAYERORGROUPDATA:
- {
- DPMSG_SETPLAYERORGROUPDATA *dpmsg = (DPMSG_SETPLAYERORGROUPDATA *)lpData;
- }
- break;
- case DPSYS_SETPLAYERORGROUPNAME:
- {
- DPMSG_SETPLAYERORGROUPNAME *dpmsg = (DPMSG_SETPLAYERORGROUPNAME *)lpData;
- }
- break;
- case DPSYS_SETSESSIONDESC:
- {
- DPMSG_SETSESSIONDESC *dpmsg = (DPMSG_SETSESSIONDESC *)lpData;
- joined_session = dpmsg->dpDesc;
- }
- break;
- }
- }
- // ------- end of function MultiPlayerDP::handle_system_msg ------//
- // --------- begin of function MultiPlayerDP::send_lobby ---------//
- // send message
- //
- // must not call it between IDirectDrawSurface2::Lock and IDirectDrawSurface2::Unlock,
- // or between IDirectDrawSurface2::GetDC and IDirectDrawSurface2::ReleaseDC
- //
- // return TRUE on success
- //
- int MultiPlayerDP::send_lobby(LPVOID lpData, DWORD dataSize)
- {
- err_when(!init_flag);
- VgaFrontLock vgaLock;
- return !direct_play_lobby->SendLobbyMessage(0, 0, lpData, dataSize);
- }
- // --------- end of function MultiPlayerDP::send_lobby ---------//
- // ------- begin of function MultiPlayerDP::receive_lobby ------//
- // return NULL if fails
- char *MultiPlayerDP::receive_lobby(LPDWORD dSize)
- {
- err_when(!init_flag);
- DWORD dataSize, msgFlag;
- int retryFlag;
- HRESULT hr;
- VgaFrontLock vgaLock;
- do
- {
- retryFlag = 0;
- dataSize = recv_buffer_size;
- hr=direct_play_lobby->ReceiveLobbyMessage(0,0, &msgFlag, recv_buffer, &dataSize);
- switch(hr)
- {
- case 0:
- if(msgFlag == DPLAD_SYSTEM)
- {
- handle_lobby_system_msg(recv_buffer, dataSize);
- retryFlag = 1;
- }
- else
- {
- *dSize = dataSize;
- }
- break;
- case DPERR_BUFFERTOOSMALL: // assume now dataSize > recv_buffer_size
- delete[] recv_buffer;
- recv_buffer_size = dataSize + 0x400;
- recv_buffer = new char[recv_buffer_size];
- retryFlag = 1; // direct_play3->receive may not return the same message, so keep retrying
- break;
- default:
- return NULL;
- }
-
- } while (retryFlag);
- return recv_buffer;
- }
- // ------- end of function MultiPlayerDP::receive_lobby ------//
- // ------- begin of function MultiPlayerDP::handle_lobby_system_msg ------//
- void MultiPlayerDP::handle_lobby_system_msg(LPVOID lpData, DWORD dSize)
- {
- switch( ((DPLMSG_GENERIC *)lpData)->dwType )
- {
- case DPLSYS_APPTERMINATED:
- {
- // DPLMSG_APPTERMINATED *dplmsg = (DPLMSG_APPTERMINATED *)lpData;
- }
- break;
- case DPLSYS_CONNECTIONSETTINGSREAD:
- {
- // DPLMSG_CONNECTIONSETTINGSREAD *dplmsg = (DPLMSG_CONNECTIONSETTINGREAD *)lpData;
- }
- break;
- case DPLSYS_DPLAYCONNECTFAILED:
- {
- // DPLMSG_DPLAYCONNECTFAILED *dplmsg = (DPLMSG_DPLAYCONNECTFAILED *)lpData;
- }
- break;
- case DPLSYS_DPLAYCONNECTSUCCEEDED:
- {
- // DPLMSG_DPLAYCONNECTSUCCEEDED *dplmsg = (DPLMSG_DPLAYCONNECTSUCCEEDED *)lpData;
- }
- break;
- }
- }
- // ------- end of function MultiPlayerDP::handle_lobby_system_msg ------//
- // ------ Begin of function MultiPlayerDP::sort_sessions -------//
- static int sort_session_id(const void *a, const void *b)
- {
- return memcmp( &((DPSessionDesc *)a)->guidInstance, &((DPSessionDesc *)b)->guidInstance,
- sizeof(GUID) );
- }
- static int sort_session_name(const void *a, const void *b)
- {
- return strcmp( ((DPSessionDesc *)a)->name_str(), ((DPSessionDesc *)b)->name_str() );
- }
- // sort current_sessions
- // <int> sortType, 1=sort by GUID, 2=sort by session name
- void MultiPlayerDP::sort_sessions(int sortType )
- {
- // BUGHERE : quick_sort is a DynArray function but current_sessions is DynArrayB
- switch(sortType)
- {
- case 1:
- current_sessions.quick_sort(sort_session_id);
- break;
- case 2:
- current_sessions.quick_sort(sort_session_name);
- break;
- default:
- err_here();
- }
- for( int s = 1; get_session(s); ++s)
- {
- get_session(s)->before_use(); // let lpszSessionNameA point to its own session_name
- }
- }
- // ------ End of function MultiPlayerDP::sort_sessions -------//
- #endif
|