D:/Zythum/DinoKod/Client/NetClient.cpp

00001 #include "Common/Ini.h"
00002 #include "Common/Error.h"
00003 #include "Common/Console.h"
00004 #include "Common/Time.h"
00005 #include "Common/Md5.h"
00006 #include "Common/Command.h"
00007 #include "Protocol/ProtocolDefs.h"
00008 #include "Game/ClientGameManager.h"
00009 #include "Interface/Interface.h"
00010 #include "Mod/Mod.h"
00011 #include "Game/ServerInfo.h"
00012 #include "Client/GameClient.h"
00013 #include "Client/NetClient.h"
00014 
00015 //---------------------------------------------------------------------------------------------------------------------
00016 KNetClient::KNetClient()
00017 : KUDPClientSocket()
00018 {
00019         m_LastStatsTime = 0;
00020         m_bShowStats    = false;
00021         m_pLocalAddr    = NULL;
00022         m_nLocalAddr    = 0;
00023 }
00024 
00025 //---------------------------------------------------------------------------------------------------------------------
00026 bool KNetClient::Init()
00027 {
00028         // Demarrage de  WINSOCK
00029         if( !KSocket::StartNetwork() )
00030                 return false;
00031 
00032         if( !Create() )
00033                 return false;
00034 
00035         // Initialise la socket Lobby
00036         if( !m_LobbySocket.Create( KNST_UDP ) )
00037                 return false;
00038 
00039         const char*     pLobbyRequestHost       = g_pGame->GetpIniFile()->ReadString( "NETWORK", "LobbyRequestHost", "localhost" );
00040         u16                     LobbyRequestPort        = (u16)g_pGame->GetpIniFile()->ReadInt( "NETWORK", "LobbyRequestPort", 28001 );
00041 
00042         if( !KSocket::GetAddrByName( KStr( pLobbyRequestHost ), m_LobbyAddr ) )
00043         {
00044                 KError::Error( NULL, "KNetClient::Init() : GetHostByName [%s] failed", pLobbyRequestHost );
00045                 return false;
00046         }
00047 
00048         m_LobbyAddr.SetPort( LobbyRequestPort );
00049 
00050         // Récupere l'IP locale
00051         char            pHostName[1024];
00052         hostent*        pHostent;
00053         
00054         KSocket::GetHostName( pHostName, sizeof( pHostName ) );
00055         if( pHostent = KSocket::GetHostByName( pHostName ) )
00056         {
00057                 char*   pAddrList;
00058 
00059                 m_nLocalAddr = 0;
00060                 while( pHostent->h_addr_list[m_nLocalAddr] )
00061                 {
00062                         m_nLocalAddr ++;
00063                 }
00064 
00065                 if( m_nLocalAddr )
00066                 {
00067                         m_pLocalAddr = new KInetAddr[m_nLocalAddr];
00068                         for( u32 h = 0; h < m_nLocalAddr; h ++ )
00069                         {
00070                                 pAddrList = pHostent->h_addr_list[h];
00071 
00072                                 m_pLocalAddr[h].SetInAddr( *((in_addr*)&pAddrList[h]) );
00073                         }
00074                 }
00075         }
00076 
00077         // Active le broadcast
00078         GetSocket().EnableBroadcast( true );
00079 
00080         g_pGame->GetpCommand()->RegisterCommand( "getserverslist", CommandGetServersList, "Ask to lobby the servers list", this );
00081 
00082         return true;
00083 }
00084 
00085 //---------------------------------------------------------------------------------------------------------------------
00086 bool KNetClient::Connect( KStr sHostName, u16 Port )
00087 {
00088         //
00089         // Lance la procedure de connection au server
00090         //
00091         const char*     pServerHost;
00092         u16                     ServerPort;
00093         u32                     ServerAddr;
00094 
00095         g_Console << "Starting connection..." << KENDL;
00096 
00097         if( sHostName.GetLength() )
00098                 pServerHost = sHostName.GetpString();
00099         else
00100                 pServerHost = g_pGame->GetpIniFile()->ReadString( "NETWORK", "ServerHost", "localhost" );
00101 
00102         if( Port )
00103                 ServerPort      = Port;
00104         else
00105                 ServerPort      = (u16)g_pGame->GetpIniFile()->ReadInt( "NETWORK", "ServerPort", 28100 );
00106 
00107         // Recupere l'IP de l'host
00108         HOSTENT*        pHostent;
00109 
00110         pHostent = KSocket::GetHostByName( (char*)pServerHost );
00111         if( !pHostent || !pHostent->h_addr_list[0] )
00112         {
00113                 KError::Error( NULL, "KNetClient::Init() : GetHostByName() failed [%s]", pServerHost );
00114                 return false;
00115         }
00116         
00117         ServerAddr = *((u32*)(pHostent->h_addr_list[0]));
00118 
00119         // Connection au server
00120         if( !KUDPClientSocket::Connect( KInetAddr( ServerAddr, ServerPort ) ) )
00121                 return false;
00122 
00123         return true;
00124 }
00125 
00126 //---------------------------------------------------------------------------------------------------------------------
00127 bool KNetClient::Disconnect()
00128 {
00129         g_Console << "Disconnection..." << KENDL;
00130 
00131         return KUDPClientSocket::Disconnect();
00132 }
00133 
00134 //---------------------------------------------------------------------------------------------------------------------
00135 bool KNetClient::End()
00136 {
00137         g_pGame->GetpCommand()->UnregisterCommand( "getserverslist" );
00138 
00139         // Ferme la connection au server
00140         if( IsConnected() )
00141         {
00142                 if( !Disconnect() )
00143                         return false;
00144         }
00145 
00146         if( !Close() )
00147                 return false;
00148                 
00149         if( !m_LobbySocket.Close() )
00150                 return false;
00151                 
00152         // Arret de WINSOCK
00153         if( !KSocket::StopNetwork() )
00154                 return false;
00155 
00156         SafeDeletev( m_pLocalAddr );
00157 
00158         return true;
00159 }
00160 
00161 //---------------------------------------------------------------------------------------------------------------------
00162 void KNetClient::OnConnect( KInetAddr& Addr )
00163 {
00164         KUDPClientSocket::OnConnect( Addr );
00165 }
00166 
00167 //---------------------------------------------------------------------------------------------------------------------
00168 void KNetClient::OnDisconnect( KInetAddr& Addr )
00169 {
00170         KUDPClientSocket::OnDisconnect( Addr );
00171 
00172         if( ((KGameClient*)g_pGame)->GetClientGameManager() )
00173                 ((KGameClient*)g_pGame)->GetClientGameManager()->OnDisconnect();
00174 }
00175 
00176 //---------------------------------------------------------------------------------------------------------------------
00177 bool KNetClient::Manage()
00178 {
00179         if( !KUDPClientSocket::Manage() )
00180                 return false;
00181 
00182         bool    bStats                  = false;
00183         u32             nBytesSent              = 0;
00184         u32             nBytesReceived  = 0;
00185 
00186         if( m_LastStatsTime + 1000 < g_Time.GetTime() )
00187         {
00188                 bStats = true;
00189                 m_LastStatsTime = g_Time.GetTime();
00190         }       
00191         
00192         if( bStats )
00193         {
00194                 nBytesSent              += GetnBytesSent();
00195                 nBytesReceived  += GetnBytesReceived();
00196                 ResetStats();
00197         }
00198 
00199         if( bStats && m_bShowStats )
00200                 g_Console << "SENT : " << nBytesSent << " RECEIVED : " << nBytesReceived << KENDL;
00201 
00202         if( !ManageLobbySocket() )
00203                 return false;
00204 
00205         return true;
00206 }
00207 
00208 //---------------------------------------------------------------------------------------------------------------------
00209 void KNetClient::OnMessage( KInetAddr& Addr, KNetMsg& Msg )
00210 {
00211         KPGENERALMESSAGE        MsgType;
00212         KGameClient*            pGameClient = (KGameClient*)g_pGame;
00213 
00214         MsgType = KP_ReadGM( Msg );
00215 
00216         switch( MsgType )
00217         {
00218         case KPGM_GETAUTHENTICITY:
00219                 {
00220                         // Envoie l'authentification
00221                         KNetMsg Msg2;
00222                         KP_WriteGM( Msg2, KPGM_AUTHENTICITY );
00223 
00224                         const char*             pLogin  = g_pGame->GetpIniFile()->ReadString( "LOGIN", "login", "" );
00225                         const char*             pPass   = g_pGame->GetpIniFile()->ReadString( "LOGIN", "password", "" );
00226 
00227                         KStr    sCryptedPass = md5( KStr( pPass ) );
00228 
00229                         Msg2.WriteString( KStr( pLogin ) );
00230                         Msg2.WriteString( sCryptedPass );
00231                         SendMessage( Msg2 );
00232                         g_Console << "Checking authenticity..." << KENDL;
00233                         return;
00234                 }
00235 
00236         case KPGM_AUTHENTICITYRESULT:
00237                 {
00238                         // Resultat de l'authentification
00239                         bool    bResult;
00240                         Msg >> bResult;
00241 
00242                         if( bResult )
00243                                 g_Console << "Authenticity succeded!" << KENDL;
00244                         else
00245                                 g_Console << "Authenticity failed!" << KENDL;
00246                         return;
00247                 }
00248 
00249         case KPGM_GETCLIENTINFOS:
00250                 {
00251                         // Envoie les infos clients
00252                         KNetMsg         Msg2;
00253                         KP_WriteGM( Msg2, KPGM_CLIENTINFOS );
00254                         // Nom
00255                         Msg2.WriteString( KStr( pGameClient->GetpName() ) );
00256                         SendMessage( Msg2 );
00257                         g_Console << "Sending client infos." << KENDL;
00258                         return;
00259                 }
00260 
00261         case KPGM_STARTGAMEENGINE:
00262                 {
00263                         // Demarre le game manager
00264                         if( pGameClient->GetClientGameManager() )
00265                                 pGameClient->GetClientGameManager()->OnConnect();
00266                         g_Console << "Starting game manager..." << KENDL;
00267                         return;
00268                 }
00269 
00270         case KPGM_GAMEMESSAGE:
00271                 {
00272                         KGAMEMSGTYPE    MsgType;
00273                         u8                              Byte;
00274                         Msg >> Byte;
00275                         MsgType = (KGAMEMSGTYPE)Byte;
00276                         if( pGameClient->GetClientGameManager() )
00277                                 pGameClient->GetClientGameManager()->OnMessage( MsgType, Msg );
00278                         return;
00279                 }
00280 
00281         case KPGM_TEXTMESSAGE:
00282                 {
00283                         KStr    sText;
00284                         KStr    sChat;
00285 
00286                         Msg.ReadString( sText );
00287                         sChat = sText;
00288 
00289                         g_Console << sChat << KENDL;
00290                         if( pGameClient->GetInterface() )
00291                                 pGameClient->GetInterface()->AddChatLine( sChat.GetpString(), KRGB( 150, 25, 107 ) );
00292                         return;
00293                 }
00294 
00295         default:
00296                 KError::Warning( NULL, "KNetClient::OnMessage() : Unknown KPGENERALMESSAGE type %i", MsgType );
00297                 return;
00298         }
00299 }
00300 
00301 //---------------------------------------------------------------------------------------------------------------------
00302 bool KNetClient::RequestServersList()
00303 {
00304         if( g_pInterface )
00305                 g_pInterface->OnFlushServersList();
00306 
00307         // Requete Lobby
00308         KLobbyRequest   Request( KPGM_GETSERVERSLIST );
00309 
00310         m_LobbyRequestId = Request.m_RequestId;
00311 
00312         if( !m_LobbySocket.SendTo( m_LobbyAddr, &Request, sizeof( Request ) ) )
00313         {
00314                 KError::Error( NULL, GetLastError(), "KNetClient::RequestServersList() : SendTo failed" );
00315                 return false;
00316         }
00317 
00318         // Requete Broadcast
00319         KNetMsg         Msg;
00320         KInetAddr       Addr;
00321 
00322         Msg << m_LobbyRequestId;
00323 
00324         u16     ServerPort      = (u16)g_pGame->GetpIniFile()->ReadInt( "NETWORK", "ServerPort", 28100 );
00325 //      for( u32 Host = 0; Host < m_nLocalAddr; Host ++ )
00326         {
00327 /*              u32     Address = m_pLocalAddr[Host].GetAddress();
00328                 u8      Addr1 = u8( Address );
00329                 u8      Addr2 = u8( Address >> 8 );
00330                 u8      Addr3 = u8( Address >> 16 );
00331                 u8      Addr4 = 255;
00332 */
00333         //      Addr.SetAddress( Addr1, Addr2, Addr3, Addr4 );
00334                 Addr.SetAddress( "255.255.255.255" );
00335                 Addr.SetPort( ServerPort );
00336                 BroadCastMessage( Addr, Msg );
00337         }
00338 
00339         return true;
00340 }
00341 
00342 //---------------------------------------------------------------------------------------------------------------------
00343 bool KNetClient::ManageLobbySocket()
00344 {
00345         // Lecture depuis la socket lobby
00346         while( m_LobbySocket.SelectRead() )
00347         {
00348                 u32                     ByteRead = 0;
00349                 char            pBuffer[1024];
00350 
00351                 if( !m_LobbySocket.ReceiveFrom( m_LobbyAddr, pBuffer, sizeof( pBuffer ), &ByteRead ) )
00352                         return false;
00353 
00354                 KNetMsg Msg;
00355                 Msg.WriteBuffer( pBuffer, ByteRead );
00356                 ReadServerInfo( Msg );
00357         }
00358 
00359         return true;
00360 }
00361 
00362 //---------------------------------------------------------------------------------------------------------------------
00363 void KNetClient::ReadServerInfo( KNetMsg& Msg )
00364 {
00365         u16             RequestId;
00366         KStr    sHostName;
00367         u16             Port;
00368         u32             Players;
00369         u32             MaxPlayers;
00370         u32             Version;
00371         KStr    sName;
00372 
00373         Msg >> RequestId;
00374         Msg.ReadString( sHostName );// Address
00375         Msg >> Port                                     // Port
00376                 >> Players                              // Players
00377                 >> MaxPlayers                   // Max players
00378                 >> Version;                             // Version
00379         Msg.ReadString( sName );        // Name
00380         
00381         if( RequestId == m_LobbyRequestId )
00382         {
00383                 KServerInfo             ServerInfo;
00384 
00385                 ServerInfo.SetsHostName( sHostName );
00386                 ServerInfo.SetListenPort( Port );
00387                 ServerInfo.SetsName( sName );
00388                 ServerInfo.SetPlayers( Players );
00389                 ServerInfo.SetMaxPlayers( MaxPlayers );
00390                 ServerInfo.SetVersion( Version );
00391 
00392                 if( g_pInterface )
00393                         g_pInterface->OnAddServersList( ServerInfo );
00394         }
00395 }
00396 
00397 //---------------------------------------------------------------------------------------------------------------------
00398 void KNetClient::CommandGetServersList( KStr Argument, void* pContext )
00399 {
00400         ((KNetClient*)&((KGameClient*)g_pGame)->GetNet())->RequestServersList();
00401 }
00402 
00403 //---------------------------------------------------------------------------------------------------------------------
00404 void KNetClient::OnUCMessage( KInetAddr& Addr, char* pBuffer, u32 Size )
00405 {
00406         KNetMsg         Msg;
00407 
00408         Msg.WriteBuffer( pBuffer, Size );
00409         
00410         ReadServerInfo( Msg );
00411 }
00412 

Generated on Sun Mar 25 20:02:10 2007 for Zythum Project by  doxygen 1.5.1-p1