std::string ASE::QueryFull ( void ) { std::stringstream reply; std::stringstream temp; reply << "EYE1"; // game reply << ( unsigned char ) 4; reply << "mta"; // port reply << ( unsigned char ) ( m_strPort.length() + 1 ); reply << m_strPort; // server name reply << ( unsigned char ) ( m_pMainConfig->GetServerName ().length() + 1 ); reply << m_pMainConfig->GetServerName (); // game type reply << ( unsigned char ) ( m_strGameType.length() + 1 ); reply << m_strGameType; // map name reply << ( unsigned char ) ( m_strMapName.length() + 1 ); reply << m_strMapName; // version temp << MTA_DM_ASE_VERSION; reply << ( unsigned char ) ( temp.str().length() + 1 ); reply << temp.str(); // passworded reply << ( unsigned char ) 2; reply << ( ( m_pMainConfig->HasPassword () ) ? 1 : 0 ); // players count temp.str ( "" ); temp << m_pPlayerManager->CountJoined (); reply << ( unsigned char ) ( temp.str().length () + 1 ); reply << temp.str(); // players max temp.str ( "" ); temp << m_pMainConfig->GetMaxPlayers (); reply << ( unsigned char ) ( temp.str().length () + 1 ); reply << temp.str(); // rules list < CASERule* > ::iterator rIter = IterBegin (); for ( ; rIter != IterEnd () ; rIter++ ) { // maybe use a map and std strings for rules? reply << ( unsigned char ) ( strlen ( (*rIter)->GetKey () ) + 1 ); reply << (*rIter)->GetKey (); reply << ( unsigned char ) ( strlen ( (*rIter)->GetValue () ) + 1 ); reply << (*rIter)->GetValue (); } reply << ( unsigned char ) 1; // players // the flags that tell what data we carry per player ( apparently we need all set cause of GM atm ) unsigned char ucFlags = 0; ucFlags |= 0x01; // nick ucFlags |= 0x02; // team ucFlags |= 0x04; // skin ucFlags |= 0x08; // score ucFlags |= 0x16; // ping ucFlags |= 0x32; // time char szTemp[256] = { '\0' }; CPlayer* pPlayer = NULL; list < CPlayer* > ::const_iterator pIter = m_pPlayerManager->IterBegin (); for ( ; pIter != m_pPlayerManager->IterEnd (); pIter++ ) { pPlayer = *pIter; if ( pPlayer->IsJoined () ) { reply << ucFlags; // nick std::string strPlayerName = RemoveColorCodes ( pPlayer->GetNick () ); if ( strPlayerName.length () == 0 ) strPlayerName = pPlayer->GetNick (); reply << ( unsigned char ) ( strPlayerName.length () + 1 ); reply << strPlayerName.c_str (); // team (skip) reply << ( unsigned char ) 1; // skin (skip) reply << ( unsigned char ) 1; // score const std::string& strScore = pPlayer->GetAnnounceValue ( "score" ); reply << ( unsigned char ) ( strScore.length () + 1 ); reply << strScore.c_str (); // ping snprintf ( szTemp, 255, "%u", pPlayer->GetPing () ); reply << ( unsigned char ) ( strlen ( szTemp ) + 1 ); reply << szTemp; // time (skip) reply << ( unsigned char ) 1; } } return reply.str(); }
std::string ASE::QueryLight ( void ) { std::stringstream reply; int iJoinedPlayers = m_pPlayerManager->CountJoined (); int iMaxPlayers = m_pMainConfig->GetMaxPlayers (); SString strPlayerCount = SString ( "%d/%d", iJoinedPlayers, iMaxPlayers ); SString strBuildType = SString ( "%d", MTASA_VERSION_TYPE ); SString strBuildNumber = SString ( "%d", MTASA_VERSION_BUILD ); SFixedString < 32 > strPingStatusFixed; SFixedString < 32 > strNetRouteFixed; g_pNetServer->GetPingStatus ( &strPingStatusFixed ); g_pNetServer->GetNetRoute ( &strNetRouteFixed ); SString strPingStatus = (const char*)strPingStatusFixed; SString strNetRoute = (const char*)strNetRouteFixed; reply << "EYE2"; // game reply << ( unsigned char ) 4; reply << "mta"; // port reply << ( unsigned char ) ( m_strPort.length() + 1 ); reply << m_strPort; // server name reply << ( unsigned char ) ( m_pMainConfig->GetServerName ().length() + 1 ); reply << m_pMainConfig->GetServerName (); // game type reply << ( unsigned char ) ( m_strGameType.length() + 1 ); reply << m_strGameType; // map name with backwardly compatible large player count, build type and build number reply << ( unsigned char ) ( m_strMapName.length() + 1 + strPlayerCount.length () + 1 + strBuildType.length () + 1 + strBuildNumber.length () + 1 + strPingStatus.length () + 1 + strNetRoute.length () + 1 ); reply << m_strMapName; reply << ( unsigned char ) 0; reply << strPlayerCount; reply << ( unsigned char ) 0; reply << strBuildType; reply << ( unsigned char ) 0; reply << strBuildNumber; reply << ( unsigned char ) 0; reply << strPingStatus; reply << ( unsigned char ) 0; reply << strNetRoute; // version std::string temp = MTA_DM_ASE_VERSION; reply << ( unsigned char ) ( temp.length() + 1 ); reply << temp; // passworded reply << ( unsigned char ) ( ( m_pMainConfig->HasPassword () ) ? 1 : 0 ); // serial verification? reply << ( unsigned char ) ( ( m_pMainConfig->GetSerialVerificationEnabled() ) ? 1 : 0 ); // players count reply << ( unsigned char ) Min ( iJoinedPlayers, 255 ); // players max reply << ( unsigned char ) Min ( iMaxPlayers, 255 ); // players CPlayer* pPlayer = NULL; // Keep the packet under 1350 bytes to try to avoid fragmentation int iBytesLeft = 1340 - reply.tellp (); int iPlayersLeft = iJoinedPlayers; list < CPlayer* > ::const_iterator pIter = m_pPlayerManager->IterBegin (); for ( ; pIter != m_pPlayerManager->IterEnd (); pIter++ ) { pPlayer = *pIter; if ( pPlayer->IsJoined () ) { // nick std::string strPlayerName = RemoveColorCodes ( pPlayer->GetNick () ); if ( strPlayerName.length () == 0 ) strPlayerName = pPlayer->GetNick (); // Check if we can fit more names iBytesLeft -= strPlayerName.length () + 1; if ( iBytesLeft < iPlayersLeft-- ) strPlayerName = ""; reply << ( unsigned char ) ( strPlayerName.length () + 1 ); reply << strPlayerName.c_str (); } } return reply.str(); }
TEST_VARS const char* a; const char* result; TEST_DATA { "!*'();:@", "%21%2A%27%28%29%3B%3A%40" }, { "&=+$,/?#", "%26%3D%2B%24%2C%2F%3F%23" }, { "[] \"%<>\\", "%5B%5D%20%22%25%3C%3E%5C" }, { "^`{|}", "%5E%60%7B%7C%7D" }, { "AZaz09-_.~", "AZaz09-_.~" }, TEST_END } // RemoveColorCodes { TEST_FUNCTION SString strRemoved = RemoveColorCodes( a ); assert ( strRemoved == result ); TEST_VARS const char* a; const char* result; TEST_DATA { "aa #0f0F34 bb", "aa bb" }, { "aa #0f0F34#AABBBB bb", "aa bb" }, { "aa #0f0F3G#AABBBB bb", "aa #0f0F3G bb" }, { "aa #0f0F34#AABBB bb", "aa #AABBB bb" }, { "#0f0F34#AABBB1", "" }, { "#0f0F34 x #AABBB1", " x " }, { "#0f0F34#0f0F34 x #AABBB1#AABBB1", " x " }, { "#123456#12345G#123456#12345G", "#12345G#12345G" }, { "#123456#12345#123456#125G", "#12345#125G" }, { "##123456#125G##123456#12345", "##125G##12345" },