Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

ANetwork.cpp

Go to the documentation of this file.
00001 /*
00002 CS Senior Project 2003
00003 Team : Leftfield
00004 Project : ModernWarfare
00005 Members :
00006 - Russ Christensen              <rchriste@cs.utah.edu>
00007 - Todd Smith                    <tcsmith@cs.utah.edu>
00008 - Usit Duongsaa                 <duongsaa@cs.utah.edu>
00009 Copyright 2003 Russ Christensen, Usit Duongsaa, and Todd Smith. All rights reserved.
00010 
00011 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
00012 
00013 Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 
00014 Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 
00015 THIS SOFTWARE IS PROVIDED BY RUSS CHRISTENSEN, USIT DUONGSAA, AND TODD SMITH ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RUSS, USIT, TODD OR OTHER CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00016 */
00017 
00022 #include "AEngine.h"
00023 #include "AUtil.h"
00024 #include "ASharedFunc.h"
00025 #include "AState.h"
00026 
00027 GUID netGuid =  { 0x809af2bd, 0x7881, 0x468b, { 0xa5, 0x3c, 0x48, 0xd5, 0x48, 0x69, 0x0, 0xd9 } };
00028 
00029 //------------------------------------------------------------------------------------
00030 NDX_Connect& net_direct()
00031 {
00032         return AS.net_ndxConnect;
00033 }
00034 //------------------------------------------------------------------------------------
00035 void net_runAsServer(string myIP, string myName, int maxNumPlayers)
00036 {
00037         NDX_Connect &net = AS.net_ndxConnect;
00038         if(!net.Create(&netGuid)) throw Error("Can't create DirectPlay");
00039 
00040         net.SetGuarenteed(true);
00041         if(!net.ConnectTCPIP( (char*)myIP.c_str() ))  throw Error("Can't connect to Server : " + myIP );
00042         if(!net.CreateGame("Aierra Engine Game", (char*)myName.c_str(), maxNumPlayers ))
00043                 throw Error("Can't Create Game");
00044 
00045         AS.net_isServer = true;
00046         AS.net_myName = myName;
00047         AS.net_serverSendQueue.resize(0);
00048         AS.net_gameFinalized = false;
00049         AS.net_myPlayerNum = -1;
00050         AS.net_isInit = true;
00051         AS.net_isFakeServer = false;
00052 }
00053 //------------------------------------------------------------------------------------
00054 void net_runAsFakeServer(string myName, int maxNumPlayers)
00055 {
00056         AS.net_isServer = true;
00057         AS.net_myName = myName;
00058         AS.net_serverSendQueue.resize(0);
00059         AS.net_gameFinalized = false;
00060         AS.net_myPlayerNum = -1;
00061         AS.net_isInit = true;
00062         AS.net_isFakeServer = true;
00063 }
00064 //------------------------------------------------------------------------------------
00065 bool net_connectToServer(string ip, string myName)
00066 {
00067         NDX_Connect &net = AS.net_ndxConnect;
00068         if(!net.Create(&netGuid))
00069         {
00070                 sys_console() << "Can't create DirectPlay" << endl;
00071                 return false;
00072         }
00073 
00074         net.SetGuarenteed(true);
00075         if(!net.ConnectTCPIP( (char*)ip.c_str() ))
00076         {
00077                 sys_console() << "Can't connect to Server : " << ip << endl;
00078                 return false;
00079         }
00080         
00081         net.ScanForGames(20,false);                     // spend 20 millisec searching for a game
00082         if(net.NumGames>0)      
00083         {               
00084                 if(!net.JoinGame(0, (char*)myName.c_str()))
00085                 {
00086                         sys_console() << "Can't Join Game" << endl;
00087                         return false;
00088                 }
00089         }
00090         else 
00091         {
00092                 sys_console() << "No Game Found on that server" << endl;
00093                 return false;
00094         }
00095 
00096         AS.net_isServer = false;
00097         AS.net_myName = myName;
00098         AS.net_serverSendQueue.resize(0);
00099         AS.net_myPlayerNum = -1;
00100         AS.net_isInit = true;
00101         return true;
00102 }
00103 //------------------------------------------------------------------------------------
00104 void net_acceptMorePlayers()
00105 {
00106         if(AS.net_isFakeServer) return;
00107         if(AS.net_gameFinalized) throw Error("Game already finalized.  Can't accept more players");
00108         AS.net_ndxConnect.ScanForPlayers();
00109 }
00110 //------------------------------------------------------------------------------------
00111 // helper function for net_recv, server mode.  broadcast msg to all players (excluding server itself)
00112 void net_broadcast( string &msg )
00113 {       
00114         if(AS.net_isFakeServer) return;
00115         AS.net_ndxConnect.Send( DPID_ALLPLAYERS, &msg[0], (DWORD)msg.length()+1 );
00116 }
00117 //------------------------------------------------------------------------------------
00118 void net_finalizeGame()
00119 {
00120         NDX_Connect &net = AS.net_ndxConnect;
00121         for( int i=0; i<net.NumPlayers; i++ )
00122         {
00123                 ostringstream strm;
00124                 strm << "Assign <begin_name>" << net.Players[i].Name << "<end_name> " << i;
00125                 net_send( strm.str() );
00126 
00127                 if( AS.net_myName == net.Players[i].Name )  AS.net_myPlayerNum = i;                     // server's own number
00128         }
00129 
00130         // broadcast server DPID
00131         ostringstream strm;
00132         strm << "ServerDPID " << AS.net_ndxConnect.LocalDPID;
00133         net_broadcast( strm.str() );
00134 }
00135 //------------------------------------------------------------------------------------
00136 bool net_amIServer()
00137 {
00138         return AS.net_isServer;
00139 }
00140 //------------------------------------------------------------------------------------
00141 vector<string> net_getAllPlayers()
00142 {
00143         vector<string> result;
00144         
00145         if(AS.net_isFakeServer)
00146         {
00147                 result.push_back(AS.net_myName);
00148                 return result;
00149         }
00150 
00151         NDX_Connect &net = AS.net_ndxConnect;
00152         if(!AS.net_gameFinalized)  net.ScanForPlayers();
00153         
00154         for( int i=0; i<net.NumPlayers; i++ )
00155                 result.push_back( net.Players[i].Name );
00156 
00157         return result;
00158 }
00159 //------------------------------------------------------------------------------------
00160 void net_send( string msg )
00161 {
00162         if(!AS.net_isInit) return;
00163         msg += "\0";
00164         if(AS.net_isServer)             // server, add to send queue
00165         {
00166                 AS.net_serverSendQueue.push_back(msg);
00167         }
00168         else                                    // clients, just send it to server
00169         {
00170                 AS.net_ndxConnect.Send( AS.net_serverDPID, &msg[0], (DWORD)msg.length()+1 );
00171         }
00172 }
00173 //------------------------------------------------------------------------------------
00174 string net_getPlayerName()
00175 {
00176         return AS.net_myName;
00177 }
00178 //------------------------------------------------------------------------------------
00179 int net_getPlayerNumber()
00180 {
00181         return AS.net_myPlayerNum;
00182 }
00183 //------------------------------------------------------------------------------------
00184 void net_disconnect()
00185 {
00187         AS.net_ndxConnect.CloseGame();
00188         AS.net_ndxConnect.CloseConnection();    
00189 }
00190 //------------------------------------------------------------------------------------
00191 string net_recv()
00192 {
00193         if(!AS.net_isInit) return "";
00194         NDX_Connect &net = AS.net_ndxConnect;
00195 
00196         if(AS.net_isServer)             // server, check send queue first
00197         {
00198                 if( AS.net_serverSendQueue.size()>0 )
00199                 {
00200                         string s = *AS.net_serverSendQueue.begin();
00201                         AS.net_serverSendQueue.pop_front();
00202                         net_broadcast(s);
00203                         if( s.find("Assign <begin_name>")==0 )                          // player number assignment
00204                         {
00205 
00206                                 sys_console() << s << endl;
00207 
00208                                 s = s.substr(19);                                       // skip header
00209                                 int i = (int)s.find("<end_name>");      // delete footer
00210                                 string name = s.substr(0,i);
00211                                 
00212 
00213                                 string numStr = s.substr(i+10);         // skip footer
00214                                 istringstream numStrm(numStr.c_str());
00215                                 int num;
00216                                 numStrm >> num;
00217                                 
00218                                 if( name==AS.net_myName )   AS.net_myPlayerNum = num;                   // it's me!  Store my number
00219                                 AS.net_mapNameToNum[name] = num;
00220                                 AS.net_mapNumToName[num]  = name;
00221                                 
00222                                 return net_recv();                                      // grab another msg
00223                         }
00224                         return s;
00225                 }
00226                 else if(!AS.net_isFakeServer)                                                   // if nothing in queue, do actual recv
00227                 {
00228                         if(!net.Receive()) return "";
00229                         if(net.FromDPID==DPID_SYSMSG) return net_recv();        // it's a system msg, try again
00230                         string s((char*)net.RBuffer);                   
00231                         net_broadcast(s);
00232                         return s;
00233 
00234                 }
00235         }
00236         else                                    // clients, just send it to server
00237         {
00238                 if(!net.Receive()) return "";
00239                 if(net.FromDPID==DPID_SYSMSG) return net_recv();        // it's a system msg, try again
00240                 string s((char*)net.RBuffer);
00241                 if( s.find("Assign <begin_name>")==0 )                          // player number assignment
00242                 {
00243 
00244                         sys_console() << s << endl;
00245 
00246                         s = s.substr(19);                                       // skip header
00247                         int i = (int)s.find("<end_name>");      // delete footer
00248                         string name = s.substr(0,i);
00249                         
00250 
00251                         string numStr = s.substr(i+10);         // skip footer
00252                         istringstream numStrm(numStr.c_str());
00253                         int num;
00254                         numStrm >> num;
00255                         
00256                         if( name==AS.net_myName )
00257                         {
00258                                 AS.net_myPlayerNum = num;                       // it's me!  Store my number
00259                                 sys_console() << "My num is " << num << endl;
00260                         }
00261                         AS.net_mapNameToNum[name] = num;
00262                         AS.net_mapNumToName[num]  = name;
00263                         sys_console() << "mapping " << name << " to " << num << endl;
00264                         
00265                         return net_recv();                                      // grab another msg
00266                 }
00267                 else if (s.find("ServerDPID")==0 )
00268                 {
00269                         string tmp;
00270                         istringstream strm(s);
00271                         strm >> tmp >> AS.net_serverDPID;
00272                         return net_recv();
00273                 }
00274                 
00275                 return s;
00276         }
00277 
00278         return "";
00279 }
00280 //------------------------------------------------------------------------------------
00281 int net_getPlayerNumUsingName(string playerName)
00282 {
00283         map<string,int>::iterator iter = AS.net_mapNameToNum.find(playerName);
00284         if( iter==AS.net_mapNameToNum.end() ) return 0;
00285         return (iter)->second;
00286 }
00287 //------------------------------------------------------------------------------------
00288 string net_getPlayerNameUsingNum(int num)
00289 {
00290         map<int,string>::iterator iter = AS.net_mapNumToName.find(num);
00291         if( iter==AS.net_mapNumToName.end() ) return "NoNamePlayer";
00292         return (iter)->second;
00293 }
00294 //------------------------------------------------------------------------------------
00295 string net_getSelfIP()
00296 {
00297         static bool init = false;
00298         if(!init)
00299         {
00300                 init = true;
00301                 WSAData wsa;
00302                 WSAStartup( MAKEWORD(1,1), &wsa );
00303         }
00304 
00305         char hostName[500];     
00306         int rc = gethostname(&hostName[0],499); 
00307         if(rc!=0) rc = WSAGetLastError();
00308         assert(rc != WSAEFAULT);
00309         assert(rc != WSANOTINITIALISED  );
00310         assert(rc != WSAENETDOWN );
00311         assert(rc != WSAEINPROGRESS );  
00312 
00313         struct hostent *phost = gethostbyname(hostName);
00314         char oip[50];
00315         for (int i = 0; phost->h_addr_list[i] != 0; ++i)
00316         {
00317                 struct in_addr addr;
00318                 memcpy(&addr, phost->h_addr_list[i], sizeof(struct in_addr));           
00319                 strcpy(oip,inet_ntoa(addr));            
00320                 break;
00321         }
00322 
00323         return string(oip);
00324 }
00325 //------------------------------------------------------------------------------------

Generated on Wed Apr 23 05:50:13 2003 for Modern Warfare by doxygen1.3-rc2