@@ -338,6 +338,18 @@ CONNECTION LESS MESSAGES
338338 of the PROTMESSID_CLM_REGISTER_SERVER message is used
339339
340340
341+ - PROTMESSID_CLM_RED_SERVER_LIST: Reduced server list message (to have less UDP fragmentation)
342+
343+ for each registered server append following data:
344+
345+ +--------------------+------------------------------+ ...
346+ | 4 bytes IP address | 2 bytes server internal port | ...
347+ +--------------------+------------------------------+ ...
348+ ... -----------------+----------------------------------+
349+ ... 1 byte number n | n bytes UTF-8 string server name |
350+ ... -----------------+----------------------------------+
351+
352+
341353- PROTMESSID_CLM_REQ_SERVER_LIST: Request server list
342354
343355 note: does not have any data -> n = 0
@@ -883,6 +895,10 @@ if ( rand() < ( RAND_MAX / 2 ) ) return false;
883895 EvaluateCLServerListMes ( InetAddr, vecbyMesBodyData );
884896 break ;
885897
898+ case PROTMESSID_CLM_RED_SERVER_LIST:
899+ EvaluateCLRedServerListMes ( InetAddr, vecbyMesBodyData );
900+ break ;
901+
886902 case PROTMESSID_CLM_REQ_SERVER_LIST:
887903 EvaluateCLReqServerListMes ( InetAddr );
888904 break ;
@@ -2323,6 +2339,103 @@ bool CProtocol::EvaluateCLServerListMes ( const CHostAddress& InetAddr,
23232339 return false ; // no error
23242340}
23252341
2342+ void CProtocol::CreateCLRedServerListMes ( const CHostAddress& InetAddr,
2343+ const CVector<CServerInfo> vecServerInfo )
2344+ {
2345+ const int iNumServers = vecServerInfo.Size ();
2346+
2347+ // build data vector
2348+ CVector<uint8_t > vecData ( 0 );
2349+ int iPos = 0 ; // init position pointer
2350+
2351+ for ( int i = 0 ; i < iNumServers; i++ )
2352+ {
2353+ // convert server list strings to utf-8
2354+ const QByteArray strUTF8Name = vecServerInfo[i].strName .toUtf8 ();
2355+
2356+ // size of current list entry
2357+ const int iCurListEntrLen =
2358+ 4 /* IP address */ +
2359+ 2 /* port number */ +
2360+ 1 /* name utf-8 string size */ + strUTF8Name.size ();
2361+
2362+ // make space for new data
2363+ vecData.Enlarge ( iCurListEntrLen );
2364+
2365+ // IP address (4 bytes)
2366+ // note the Server List manager has put the internal details in HostAddr where required
2367+ PutValOnStream ( vecData, iPos, static_cast <uint32_t > (
2368+ vecServerInfo[i].HostAddr .InetAddr .toIPv4Address () ), 4 );
2369+
2370+ // port number (2 bytes)
2371+ // note the Server List manager has put the internal details in HostAddr where required
2372+ PutValOnStream ( vecData, iPos,
2373+ static_cast <uint32_t > ( vecServerInfo[i].HostAddr .iPort ), 2 );
2374+
2375+ // name (note that the string length indicator is 1 in this special case)
2376+ PutStringUTF8OnStream ( vecData, iPos, strUTF8Name, 1 );
2377+ }
2378+
2379+ CreateAndImmSendConLessMessage ( PROTMESSID_CLM_RED_SERVER_LIST,
2380+ vecData,
2381+ InetAddr );
2382+ }
2383+
2384+ bool CProtocol::EvaluateCLRedServerListMes ( const CHostAddress& InetAddr,
2385+ const CVector<uint8_t >& vecData )
2386+ {
2387+ int iPos = 0 ; // init position pointer
2388+ const int iDataLen = vecData.Size ();
2389+ CVector<CServerInfo> vecServerInfo ( 0 );
2390+
2391+ while ( iPos < iDataLen )
2392+ {
2393+ // check size (the next 6 bytes)
2394+ if ( ( iDataLen - iPos ) < 6 )
2395+ {
2396+ return true ; // return error code
2397+ }
2398+
2399+ // IP address (4 bytes)
2400+ const quint32 iIpAddr = static_cast <quint32> ( GetValFromStream ( vecData, iPos, 4 ) );
2401+
2402+ // port number (2 bytes)
2403+ const quint16 iPort = static_cast <quint16> ( GetValFromStream ( vecData, iPos, 2 ) );
2404+
2405+ // server name (note that the string length indicator is 1 in this special case)
2406+ QString strName;
2407+ if ( GetStringFromStream ( vecData,
2408+ iPos,
2409+ MAX_LEN_SERVER_NAME,
2410+ strName,
2411+ 1 ) )
2412+ {
2413+ return true ; // return error code
2414+ }
2415+
2416+ // add server information to vector
2417+ vecServerInfo.Add (
2418+ CServerInfo ( CHostAddress ( QHostAddress ( iIpAddr ), iPort ),
2419+ CHostAddress ( QHostAddress ( iIpAddr ), iPort ),
2420+ strName,
2421+ QLocale::AnyCountry, // set to any country since the information is not transmitted
2422+ " " , // empty city name since the information is not transmitted
2423+ 0 , // per definition: if max. num. client is zero, we ignore the value in the server list
2424+ false ) ); // assume not permanent since the information is not transmitted
2425+ }
2426+
2427+ // check size: all data is read, the position must now be at the end
2428+ if ( iPos != iDataLen )
2429+ {
2430+ return true ; // return error code
2431+ }
2432+
2433+ // invoke message action
2434+ emit CLRedServerListReceived ( InetAddr, vecServerInfo );
2435+
2436+ return false ; // no error
2437+ }
2438+
23262439void CProtocol::CreateCLReqServerListMes ( const CHostAddress& InetAddr )
23272440{
23282441 CreateAndImmSendConLessMessage ( PROTMESSID_CLM_REQ_SERVER_LIST,
@@ -2883,21 +2996,22 @@ uint32_t CProtocol::GetValFromStream ( const CVector<uint8_t>& vecIn,
28832996bool CProtocol::GetStringFromStream ( const CVector<uint8_t >& vecIn,
28842997 int & iPos,
28852998 const int iMaxStringLen,
2886- QString& strOut )
2999+ QString& strOut,
3000+ const int iNumberOfBytsLen )
28873001{
28883002/*
28893003 note: iPos is automatically incremented in this function
28903004*/
28913005 const int iInLen = vecIn.Size ();
28923006
2893- // check if at least two bytes are available
2894- if ( ( iInLen - iPos ) < 2 )
3007+ // check if at least iNumberOfBytsLen bytes are available
3008+ if ( ( iInLen - iPos ) < iNumberOfBytsLen )
28953009 {
28963010 return true ; // return error code
28973011 }
28983012
2899- // number of bytes for utf-8 string (2 bytes)
2900- const int iStrUTF8Len = static_cast <int > ( GetValFromStream ( vecIn, iPos, 2 ) );
3013+ // number of bytes for utf-8 string (1 or 2 bytes)
3014+ const int iStrUTF8Len = static_cast <int > ( GetValFromStream ( vecIn, iPos, iNumberOfBytsLen ) );
29013015
29023016 // (note that iPos was incremented by 2 in the above code!)
29033017 if ( ( iInLen - iPos ) < iStrUTF8Len )
@@ -3034,13 +3148,14 @@ void CProtocol::PutValOnStream ( CVector<uint8_t>& vecIn,
30343148
30353149void CProtocol::PutStringUTF8OnStream ( CVector<uint8_t >& vecIn,
30363150 int & iPos,
3037- const QByteArray& sStringUTF8 )
3151+ const QByteArray& sStringUTF8 ,
3152+ const int iNumberOfBytsLen )
30383153{
30393154 // get the utf-8 string size
30403155 const int iStrUTF8Len = sStringUTF8 .size ();
30413156
3042- // number of bytes for utf-8 string (2 bytes)
3043- PutValOnStream ( vecIn, iPos, static_cast <uint32_t > ( iStrUTF8Len ), 2 );
3157+ // number of bytes for utf-8 string (iNumberOfBytsLen bytes)
3158+ PutValOnStream ( vecIn, iPos, static_cast <uint32_t > ( iStrUTF8Len ), iNumberOfBytsLen );
30443159
30453160 // actual utf-8 string (n bytes)
30463161 for ( int j = 0 ; j < iStrUTF8Len; j++ )
0 commit comments