| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381 |
- #include "std.h"
- #include "bbsys.h"
- #include "resource.h"
- #include "multiplay_setup.h"
- IDirectPlay4 *dirPlay;
- struct Connection{
- GUID guid;
- string name;
- void *data;
- Connection( const GUID &g,const string &n,void *d,int sz ):guid(g),name(n){
- data=d_new char[sz];memcpy( data,d,sz );
- }
- ~Connection(){
- delete[] data;
- }
- };
- struct Session{
- GUID guid;
- string name;
- int max_players,curr_players,data1,data2;
- Session( const DPSESSIONDESC2 *desc ){
- guid=desc->guidInstance;
- name=string( desc->lpszSessionNameA );
- max_players=desc->dwMaxPlayers;
- curr_players=desc->dwCurrentPlayers;
- data1=desc->dwUser1;data2=desc->dwUser2;
- }
- };
- static int timer;
- static vector<Connection*> connections;
- static vector<Session*> sessions;
- static void clearSessions(){
- for( ;sessions.size();sessions.pop_back() ) delete sessions.back();
- }
- static void clearConnections(){
- for( ;connections.size();connections.pop_back() ) delete connections.back();
- }
- static bool openDirPlay( HWND hwnd ){
- if( dirPlay ) return true;
- if( CoCreateInstance( CLSID_DirectPlay,0,CLSCTX_ALL,IID_IDirectPlay4A,(void**)&dirPlay )>=0 ) return true;
- MessageBox( hwnd,"Error opening DirectPlay","DirectPlay Error",MB_ICONWARNING );
- return false;
- }
- static bool closeDirPlay( HWND hwnd ){
- if( hwnd && timer ) KillTimer( hwnd,timer );
- timer=0;if( !dirPlay ) return true;
- dirPlay->Close();
- int n=dirPlay->Release();
- dirPlay=0;return n==0;
- }
- static BOOL FAR PASCAL enumConnection( LPCGUID guid,LPVOID conn,DWORD size,LPCDPNAME name,DWORD flags,LPVOID context ){
- IDirectPlay4 *dp;
- if( CoCreateInstance( CLSID_DirectPlay,0,CLSCTX_ALL,IID_IDirectPlay4A,(void**)&dp )<0 ) return FALSE;
- int n=dp->InitializeConnection( conn,0 );
- dp->Release();if( n<0 ) return TRUE;
- Connection *c=d_new Connection( *guid,string( strdup( name->lpszShortNameA ) ),conn,size );
- connections.push_back( c );
- return TRUE;
- }
- static BOOL FAR PASCAL enumSession( LPCDPSESSIONDESC2 desc,LPDWORD timeout,DWORD flags,LPVOID lpContext ){
- if( !desc ) return FALSE;
- sessions.push_back( d_new Session( desc ) );
- return TRUE;
- }
- static bool startGame( HWND hwnd ){
- if( !dirPlay ) return false;
- char buff[MAX_PATH];
- int n=GetWindowText( GetDlgItem( hwnd,IDC_GAMENAME ),buff,MAX_PATH );
- if( !n ){
- MessageBox( hwnd,"Please enter a name for the new game","DirectPlay Request",MB_SETFOREGROUND|MB_TOPMOST|MB_ICONINFORMATION|MB_OK );
- return false;
- }
- string name=string( buff )+'\0';
- DPSESSIONDESC2 desc;
- memset(&desc,0,sizeof(desc));
- desc.dwSize=sizeof(desc);
- desc.guidApplication=GUID_NULL;
- desc.dwFlags=
- DPSESSION_KEEPALIVE|
- DPSESSION_MIGRATEHOST|
- DPSESSION_NOMESSAGEID|
- DPSESSION_OPTIMIZELATENCY|
- DPSESSION_DIRECTPLAYPROTOCOL;
- desc.lpszSessionNameA=(char*)name.data();
- if( dirPlay->Open( &desc,DPOPEN_CREATE )<0 ){
- MessageBox( hwnd,"Unable to create new game","DirPlay Error",MB_ICONWARNING );
- return false;
- }
- return true;
- }
- static bool joinGame( HWND hwnd ){
- if( !dirPlay ) return false;
- int ses=SendDlgItemMessage( hwnd,IDC_GAMELIST,LB_GETCURSEL,0,0 );
- if( ses<0 || ses>=sessions.size() ) return false;
- DPSESSIONDESC2 desc;
- memset(&desc,0,sizeof(desc));
- desc.dwSize=sizeof(desc);
- desc.guidInstance=sessions[ses]->guid;
- if( dirPlay->Open( &desc,DPOPEN_JOIN )<0 ){
- MessageBox( hwnd,"Unable to join game","DirPlay Error",MB_ICONWARNING );
- return false;
- }
- return true;
- }
- static bool enumSessions( HWND hwnd ){
- if( !dirPlay ) return false;
- clearSessions();
- EnableWindow( GetDlgItem( hwnd,IDC_GAMELIST ),true );
- SendDlgItemMessage( hwnd,IDC_GAMELIST,LB_RESETCONTENT,0,0 );
- DPSESSIONDESC2 desc;
- memset(&desc,0,sizeof(desc));
- desc.dwSize=sizeof(desc);
- desc.guidApplication=GUID_NULL;
- int n=dirPlay->EnumSessions( &desc,0,enumSession,0,DPENUMSESSIONS_ASYNC );
- if( n>=0 ){
- if( !timer ) SetTimer( hwnd,timer=1,1000,0 );
- for( int k=0;k<sessions.size();++k ){
- SendDlgItemMessage( hwnd,IDC_GAMELIST,LB_ADDSTRING,0,(LPARAM)strdup( sessions[k]->name.c_str() ) );
- }
- if( !sessions.size() ){
- SendDlgItemMessage( hwnd,IDC_GAMELIST,LB_ADDSTRING,0,(LPARAM)"<no games found>" );
- EnableWindow( GetDlgItem( hwnd,IDC_GAMELIST ),false );
- }
- return true;
- }
- closeDirPlay( hwnd );
- if( n==DPERR_USERCANCEL ) return false;
- MessageBox( hwnd,"Unable to enumerate sessions","DirPlay Error",MB_ICONWARNING );
- return false;
- }
- static bool connect( HWND hwnd ){
- int con=SendDlgItemMessage( hwnd,IDC_CONNECTIONS,CB_GETCURSEL,0,0 );
- if( con<1 || con>=connections.size() ) return false;
- closeDirPlay( hwnd );
- if( openDirPlay( hwnd ) ){
- int n=dirPlay->InitializeConnection( connections[con]->data,0 );
- if( n>=0 ){
- if( enumSessions( hwnd ) ) return true;
- }else{
- if( n!=DPERR_USERCANCEL ){
- string t="Unable to open "+connections[con]->name;
- MessageBox( hwnd,t.c_str(),"DirPlay Error",MB_ICONWARNING );
- }
- }
- closeDirPlay( hwnd );
- }
- return false;
- }
- static void endDialog( HWND hwnd,int rc ){
- if( timer ) KillTimer( hwnd,timer );
- timer=0;
- if( !rc ) closeDirPlay( hwnd );
- EndDialog( hwnd,rc );
- }
- static BOOL CALLBACK dialogProc( HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam ){
- int k,lo=LOWORD(wparam),hi=HIWORD(wparam);
- bool reset=false;
- switch( msg ){
- case WM_INITDIALOG:
- SetForegroundWindow( hwnd );
- clearConnections();
- connections.push_back( d_new Connection( GUID_NULL,"<no connection>","",0 ) );
- if( openDirPlay( hwnd ) ){
- if( dirPlay->EnumConnections( 0,enumConnection,0,0 )<0 ){
- MessageBox( hwnd,"Failed to enumerate connections","DirectPlay Error",MB_SETFOREGROUND|MB_TOPMOST|MB_ICONWARNING|MB_OK );
- }
- closeDirPlay( hwnd );
- }
- for( k=0;k<connections.size();++k ){
- string t=connections[k]->name;
- SendDlgItemMessage( hwnd,IDC_CONNECTIONS,CB_ADDSTRING,0,(LPARAM)t.c_str() );
- }
- timer=0;
- reset=true;
- break;
- case WM_TIMER: //refresh sessions list!
- if( timer && wparam==timer && !enumSessions( hwnd ) ) reset=true;
- break;
- case WM_CLOSE:
- endDialog( hwnd,0 );
- break;
- case WM_COMMAND:
- switch( hi ){
- case BN_CLICKED:
- switch( lo ){
- case IDC_CANCEL:
- endDialog( hwnd,0 );
- break;
- case IDC_GAMENAME:case IDC_HOSTGAME:
- if( startGame( hwnd ) ){
- endDialog( hwnd,2 );
- }
- break;
- }
- break;
- case LBN_DBLCLK:
- switch( lo ){
- case IDC_GAMELIST:
- if( joinGame( hwnd ) ){
- endDialog( hwnd,1 );
- }
- break;
- }
- break;
- case CBN_SELCHANGE:
- switch( lo ){
- case IDC_CONNECTIONS:
- if( connect( hwnd ) ){
- EnableWindow( GetDlgItem( hwnd,IDC_GAMENAME ),true );
- EnableWindow( GetDlgItem( hwnd,IDC_HOSTGAME ),true );
- break;
- }else{
- reset=true;
- }
- break;
- }
- break;
- }
- break;
- default:
- return 0;
- }
- if( reset ){
- closeDirPlay( hwnd );
- SendDlgItemMessage( hwnd,IDC_CONNECTIONS,CB_SETCURSEL,0,0 );
- EnableWindow( GetDlgItem( hwnd,IDC_GAMELIST ),false );
- EnableWindow( GetDlgItem( hwnd,IDC_HOSTGAME ),false );
- EnableWindow( GetDlgItem( hwnd,IDC_GAMENAME ),false );
- SetWindowText( GetDlgItem( hwnd,IDC_GAMENAME ),"" );
- SendDlgItemMessage( hwnd,IDC_GAMELIST,LB_RESETCONTENT,0,0 );
- }
- return 1;
- }
- void multiplay_setup_create(){
- dirPlay=0;
- }
- void multiplay_setup_destroy(){
- multiplay_setup_close();
- }
- int multiplay_setup_open(){
- gx_runtime->idle();
- int n=DialogBox( GetModuleHandle( "runtime" ),MAKEINTRESOURCE( IDD_MULTIPLAYER ),GetDesktopWindow(),dialogProc );
- if( n!=1 && n!=2 ) n=0;
- clearSessions();
- clearConnections();
- //NAUGHTY!
- gx_runtime->asyncRun();
- gx_runtime->idle();
- return n;
- }
- void multiplay_setup_close(){
- closeDirPlay( 0 );
- }
- int multiplay_setup_host( const string &game_name ){
- int ret=0;
- IDirectPlayLobby *lobby;
- IDirectPlayLobby3 *lobby3;
- if( CoCreateInstance( CLSID_DirectPlay,0,CLSCTX_ALL,IID_IDirectPlay4A,(void**)&dirPlay )>=0 ){
- if( DirectPlayLobbyCreate( 0,&lobby,0,0,0 )>=0 ){
- if( lobby->QueryInterface( IID_IDirectPlayLobby3,(void**)&lobby3 )>=0 ){
- //ok, create an address for initializeconnection
- string ip( "\0" );
- char address[256];DWORD sz=256;
- if( lobby3->CreateAddress( DPSPGUID_TCPIP,DPAID_INet,ip.data(),ip.size(),address,&sz )>=0 ){
- if( dirPlay->InitializeConnection( address,0 )>=0 ){
- string name=game_name+'\0';
- DPSESSIONDESC2 desc;
- memset(&desc,0,sizeof(desc));
- desc.dwSize=sizeof(desc);
- desc.guidApplication=GUID_NULL;
- desc.dwFlags=
- DPSESSION_KEEPALIVE|
- DPSESSION_MIGRATEHOST|
- DPSESSION_NOMESSAGEID|
- DPSESSION_OPTIMIZELATENCY|
- DPSESSION_DIRECTPLAYPROTOCOL;
- desc.lpszSessionNameA=(char*)name.data();
- if( dirPlay->Open( &desc,DPOPEN_CREATE )>=0 ){
- ret=2;
- }
- }
- }
- lobby3->Release();
- }
- lobby->Release();
- }
- if( !ret ){
- dirPlay->Release();
- dirPlay=0;
- }
- }
- return ret;
- }
- int multiplay_setup_join( const string &game_name,const string &ip_add ){
- int ret=0;
- IDirectPlayLobby *lobby;
- IDirectPlayLobby3 *lobby3;
- if( CoCreateInstance( CLSID_DirectPlay,0,CLSCTX_ALL,IID_IDirectPlay4A,(void**)&dirPlay )>=0 ){
- if( DirectPlayLobbyCreate( 0,&lobby,0,0,0 )>=0 ){
- if( lobby->QueryInterface( IID_IDirectPlayLobby3,(void**)&lobby3 )>=0 ){
- //ok, create an address for initializeconnection
- string ip=ip_add+'\0';
- char address[256];DWORD sz=256;
- if( lobby3->CreateAddress( DPSPGUID_TCPIP,DPAID_INet,ip.data(),ip.size(),address,&sz )>=0 ){
- if( dirPlay->InitializeConnection( address,0 )>=0 ){
- DPSESSIONDESC2 desc;
- memset(&desc,0,sizeof(desc));
- desc.dwSize=sizeof(desc);
- desc.guidApplication=GUID_NULL;
- if( dirPlay->EnumSessions( &desc,0,enumSession,0,0 )>=0 ){
- for( int k=0;k<sessions.size();++k ){
- if( sessions[k]->name!=game_name ) continue;
- desc.guidInstance=sessions[k]->guid;
- if( dirPlay->Open( &desc,DPOPEN_JOIN )>=0 ){
- ret=1;
- }
- break;
- }
- }
- clearSessions();
- }
- }
- lobby3->Release();
- }
- lobby->Release();
- }
- if( !ret ){
- dirPlay->Release();
- dirPlay=0;
- }
- }
- return ret;
- }
|