void CClientPacketRecorder::RecordPacket(unsigned char ucPacketID, NetBitStreamInterface& bitStream) { if (m_bRecording && m_szFilename) { // Open our file FILE* pFile = fopen(m_szFilename, "ab+"); if (pFile) { // Write our timestamp if (m_bFrameBased) { long lFrameStamp = m_lFrames - m_lRelative; fwrite(&lFrameStamp, sizeof(long), 1, pFile); } else { long lTimeStamp = CClientTime::GetTime() - m_lRelative; fwrite(&lTimeStamp, sizeof(long), 1, pFile); } // fwrite ( &ulTimeStamp, sizeof ( unsigned long), 1, pFile ); // Write the packet ID fputc(ucPacketID, pFile); // Write the size of the bitstream unsigned long ulSize = static_cast<unsigned long>(bitStream.GetNumberOfBytesUsed()); fwrite(&ulSize, sizeof(unsigned long), 1, pFile); // Write the content of the bitstream to the file char c = 0; for (unsigned long i = 0; i < ulSize; i++) { bitStream.Read(c); fputc(c, pFile); } // Reset the readpointer so the client can use it bitStream.ResetReadPointer(); // Close the file fclose(pFile); } } }
bool CConnectManager::StaticProcessPacket ( unsigned char ucPacketID, NetBitStreamInterface& BitStream ) { // We're working on connecting? if ( g_pConnectManager->m_bIsConnecting ) { // The packet we're expecting? if ( ucPacketID == PACKET_ID_MOD_NAME ) { // Read out the mod to load char* szModName = new char [ BitStream.GetNumberOfBytesUsed () + 1 ]; memset ( szModName, 0, BitStream.GetNumberOfBytesUsed () + 1 ); if ( BitStream.Read ( szModName, BitStream.GetNumberOfBytesUsed () ) ) { // Backward compatibly examine the bytes following the mod name BitStream.ResetReadPointer (); BitStream.Read ( szModName, strlen ( szModName ) ); char cPad; BitStream.Read ( cPad ); unsigned short usServerBitStreamVersion = 0x01; BitStream.Read ( usServerBitStreamVersion ); // This will silently fail for < 1.0.2 and leave the bitstream version at 0x01 CCore::GetSingleton ().GetNetwork ()->SetServerBitStreamVersion ( usServerBitStreamVersion ); // Limit the nick length for servers that have a problem with max length nicks if ( usServerBitStreamVersion < 0x06 ) g_pConnectManager->m_strNick = g_pConnectManager->m_strNick.substr ( 0, MAX_PLAYER_NICK_LENGTH - 1 ); // Populate the arguments to pass it (-c host port nick) SString strArguments ( "%s %s", g_pConnectManager->m_strNick.c_str(), g_pConnectManager->m_strPassword.c_str() ); // Hide the messagebox we're currently showing CCore::GetSingleton ().RemoveMessageBox (); // If we connected from quick-connect, get rid of it CQuickConnect * pQuickConnect = CCore::GetSingleton ().GetLocalGUI ()->GetMainMenu ()->GetQuickConnectWindow (); if ( pQuickConnect->IsVisible () ) pQuickConnect->SetVisible ( false ); // Save the connection details into the config CVARS_SET ( "host", g_pConnectManager->m_strHost ); CVARS_SET ( "port", g_pConnectManager->m_usPort ); CVARS_SET ( "password", g_pConnectManager->m_strPassword ); //Conver the Address to an unsigned long unsigned long ulAddr = inet_addr( g_pConnectManager->m_strHost.c_str() ); //Create an instance of the in_addr structure to store the address in_addr Address; //Set the address to the unsigned long we just created Address.S_un.S_addr = ulAddr; //Set the current server info and Add the ASE Offset to the Query port) CCore::GetSingleton().SetCurrentServer ( Address, g_pConnectManager->m_usPort + 123 ); // Kevuwk: Forced the config to save here so that the IP/Port isn't lost on crash CCore::GetSingleton ().SaveConfig (); // Reset our variables g_pConnectManager->m_strNick = ""; g_pConnectManager->m_strHost = ""; g_pConnectManager->m_strPassword = ""; g_pConnectManager->m_usPort = 0; g_pConnectManager->m_bIsConnecting = false; g_pConnectManager->m_tConnectStarted = 0; // Load the mod if ( !CModManager::GetSingleton ().Load ( szModName, strArguments ) ) { // Failed loading the mod strArguments.Format ( "No such mod installed (%s)", szModName ); CCore::GetSingleton ().ShowMessageBox ( "Error", strArguments, MB_BUTTON_OK | MB_ICON_ERROR ); g_pConnectManager->Abort (); } } else { // Show failed message and abort the attempt CCore::GetSingleton ().ShowMessageBox ( "Error", "Bad server response (2)", MB_BUTTON_OK | MB_ICON_ERROR ); g_pConnectManager->Abort (); } delete [] szModName; } else { // Not the player joined packet? if ( ucPacketID != PACKET_ID_SERVER_JOIN && ucPacketID != PACKET_ID_SERVER_JOIN_DATA ) { // Show failed message and abort the attempt CCore::GetSingleton ().ShowMessageBox ( "Error", "Bad server response (1)", MB_BUTTON_OK | MB_ICON_ERROR ); g_pConnectManager->Abort (); } } return true; } return false; }
/////////////////////////////////////////////////////////////// // // CLatentReceiver::OnReceive // // // /////////////////////////////////////////////////////////////// void CLatentReceiver::OnReceive ( NetBitStreamInterface* pBitStream ) { // // Read header // ushort usId = 0; bool bIsHead = false; bool bIsTail = false; bool bIsCancel = false; ushort usCategory = 0; ushort usResourceNetId = 0xFFFF; uint uiFinalSize = 0; uint uiRate = 0; pBitStream->ReadBits ( &usId, 15 ); if ( pBitStream->ReadBit () ) { // Special type uchar ucSpecialFlag; pBitStream->Read ( ucSpecialFlag ); if ( ucSpecialFlag == FLAG_HEAD ) { bIsHead = true; pBitStream->Read ( usCategory ); pBitStream->Read ( uiFinalSize ); pBitStream->Read ( uiRate ); if ( pBitStream->Version () >= 0x31 ) pBitStream->Read ( usResourceNetId ); } else if ( ucSpecialFlag == FLAG_TAIL ) { bIsTail = true; } else if ( ucSpecialFlag == FLAG_CANCEL ) { bIsCancel = true; } else { return OnReceiveError ( "Invalid special type" ); } } pBitStream->AlignReadToByteBoundary (); ushort usSizeSent = 0; pBitStream->Read ( usSizeSent ); // // Process header // if ( bIsHead ) { // If head, check no previous transfer if ( activeRx.bReceiveStarted ) return OnReceiveError ( "bIsHead && activeRx.bReceiveActive" ); if ( uiFinalSize > 100 * 1024 * 1024 ) return OnReceiveError ( "uiFinalSize too large" ); activeRx.usId = usId; activeRx.bReceiveStarted = true; activeRx.usCategory = usCategory; activeRx.uiRate = uiRate; activeRx.usResourceNetId = usResourceNetId; activeRx.buffer.SetSize ( uiFinalSize ); activeRx.uiWritePosition = 0; } if ( activeRx.usId != usId ) return OnReceiveError ( "usId wrong" ); if ( bIsCancel ) { // Reset for next receive activeRx = SReceiveItem (); return; } // // Read body // if ( activeRx.uiWritePosition + usSizeSent > activeRx.buffer.GetSize () ) return OnReceiveError ( "Buffer would overflow" ); if ( bIsTail && activeRx.uiWritePosition + usSizeSent != activeRx.buffer.GetSize () ) return OnReceiveError ( "Buffer size wrong" ); pBitStream->Read ( activeRx.buffer.GetData () + activeRx.uiWritePosition, usSizeSent ); activeRx.uiWritePosition += usSizeSent; // // Process tail // if ( bIsTail ) { if ( activeRx.usCategory == CATEGORY_PACKET ) { // Recreate the packet data NetBitStreamInterface* pBitStream = DoAllocateNetBitStream ( m_RemoteId, m_usBitStreamVersion ); uchar ucPacketId = 0; uint uiBitStreamBitsUsed = 0; CBufferReadStream stream ( activeRx.buffer ); stream.Read ( ucPacketId ); stream.Read ( uiBitStreamBitsUsed ); uint uiBitStreamBytesUsed = ( uiBitStreamBitsUsed + 7 ) >> 3; if ( uiBitStreamBytesUsed != activeRx.buffer.GetSize () - 5 ) return OnReceiveError ( "Buffer size mismatch" ); pBitStream->WriteBits ( activeRx.buffer.GetData () + 5, uiBitStreamBitsUsed ); pBitStream->ResetReadPointer (); DoStaticProcessPacket ( ucPacketId, m_RemoteId, pBitStream, activeRx.usResourceNetId ); DoDeallocateNetBitStream ( pBitStream ); } else {
bool CConnectManager::StaticProcessPacket ( unsigned char ucPacketID, NetBitStreamInterface& BitStream ) { // We're working on connecting? if ( g_pConnectManager->m_bIsConnecting ) { // The packet we're expecting? if ( ucPacketID == PACKET_ID_MOD_NAME ) { // Read out the mod to load char* szModName = new char [ BitStream.GetNumberOfBytesUsed () + 1 ]; memset ( szModName, 0, BitStream.GetNumberOfBytesUsed () + 1 ); if ( BitStream.Read ( szModName, BitStream.GetNumberOfBytesUsed () ) ) { // Backward compatibly examine the bytes following the mod name BitStream.ResetReadPointer (); BitStream.Read ( szModName, strlen ( szModName ) ); char cPad; BitStream.Read ( cPad ); unsigned short usServerBitStreamVersion = 0x01; BitStream.Read ( usServerBitStreamVersion ); // This will silently fail for < 1.0.2 and leave the bitstream version at 0x01 CCore::GetSingleton ().GetNetwork ()->SetServerBitStreamVersion ( usServerBitStreamVersion ); // Populate the arguments to pass it (-c host port nick) SString strArguments ( "%s %s", g_pConnectManager->m_strNick.c_str(), g_pConnectManager->m_strPassword.c_str() ); // Hide the messagebox we're currently showing CCore::GetSingleton ().RemoveMessageBox (); // If we connected from quick-connect, get rid of it CQuickConnect * pQuickConnect = CCore::GetSingleton ().GetLocalGUI ()->GetMainMenu ()->GetQuickConnectWindow (); if ( pQuickConnect->IsVisible () ) pQuickConnect->SetVisible ( false ); // Save the connection details into the config CVARS_SET ( "host", g_pConnectManager->m_strHost ); CVARS_SET ( "port", g_pConnectManager->m_usPort ); CVARS_SET ( "password", g_pConnectManager->m_strPassword ); // Save the connection details into the recently played servers list in_addr Address; if ( CServerListItem::Parse ( g_pConnectManager->m_strHost.c_str (), Address ) ) { CServerBrowser* pServerBrowser = CCore::GetSingleton ().GetLocalGUI ()->GetMainMenu ()->GetServerBrowser (); CServerList* pRecentList = pServerBrowser->GetRecentList (); CServerListItem RecentServer ( Address, g_pConnectManager->m_usPort + SERVER_LIST_QUERY_PORT_OFFSET ); if ( !pRecentList->Exists ( RecentServer ) ) { pRecentList->Add ( RecentServer ); } // Set as our current server for xfire if ( XfireIsLoaded () ) { const char *szKey[2], *szValue[2]; szKey[0] = "Gamemode"; szValue[0] = RecentServer.strType.c_str(); szKey[1] = "Map"; szValue[1] = RecentServer.strMap.c_str(); XfireSetCustomGameData ( 2, szKey, szValue ); } } // Kevuwk: Forced the config to save here so that the IP/Port isn't lost on crash CCore::GetSingleton ().SaveConfig (); // Reset our variables g_pConnectManager->m_strNick = ""; g_pConnectManager->m_strHost = ""; g_pConnectManager->m_strPassword = ""; g_pConnectManager->m_usPort = 0; g_pConnectManager->m_bIsConnecting = false; g_pConnectManager->m_tConnectStarted = 0; // Load the mod if ( !CModManager::GetSingleton ().Load ( szModName, strArguments ) ) { // Failed loading the mod strArguments.Format ( "No such mod installed (%s)", szModName ); CCore::GetSingleton ().ShowMessageBox ( "Error", strArguments, MB_BUTTON_OK | MB_ICON_ERROR ); g_pConnectManager->Abort (); } } else { // Show failed message and abort the attempt CCore::GetSingleton ().ShowMessageBox ( "Error", "Bad server response (2)", MB_BUTTON_OK | MB_ICON_ERROR ); g_pConnectManager->Abort (); } delete [] szModName; } else { // Not the player joined packet? if ( ucPacketID != PACKET_ID_SERVER_JOIN && ucPacketID != PACKET_ID_SERVER_JOIN_DATA ) { // Show failed message and abort the attempt CCore::GetSingleton ().ShowMessageBox ( "Error", "Bad server response (1)", MB_BUTTON_OK | MB_ICON_ERROR ); g_pConnectManager->Abort (); } } return true; } return false; }