diff --git a/ChangeLog b/ChangeLog index 0248fca4..675ca6ab 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,9 @@ 3.3.12 +TODO: + - on request show the names of the connected clients in the server list + 3.3.11 diff --git a/src/protocol.cpp b/src/protocol.cpp index 1d94a27f..13847434 100755 --- a/src/protocol.cpp +++ b/src/protocol.cpp @@ -281,6 +281,26 @@ CONNECTION LESS MESSAGES note: does not have any data -> n = 0 + +- PROTMESSID_CLM_CONN_CLIENTS_LIST: Information about connected clients + + for each connected client append the PROTMESSID_CONN_CLIENTS_LIST: + + +--------------------+------------------------------+ ... + | 4 bytes request ID | PROTMESSID_CONN_CLIENTS_LIST | ... + +--------------------+------------------------------+ ... + +------------------------------+ ... + | PROTMESSID_CONN_CLIENTS_LIST | ... + +------------------------------+ ... + + +- PROTMESSID_CLM_REQ_CONN_CLIENTS_LIST: Request the connected clients list + + +--------------------+ + | 4 bytes request ID | + +--------------------+ + + ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under @@ -647,6 +667,14 @@ if ( rand() < ( RAND_MAX / 2 ) ) return false; case PROTMESSID_CLM_REQ_VERSION_AND_OS: bRet = EvaluateCLReqVersionAndOSMes ( InetAddr ); break; + + case PROTMESSID_CLM_CONN_CLIENTS_LIST: + bRet = EvaluateCLConnClientsListMes ( InetAddr, vecbyMesBodyData ); + break; + + case PROTMESSID_CLM_REQ_CONN_CLIENTS_LIST: + bRet = EvaluateCLReqConnClientsListMes ( InetAddr, vecbyMesBodyData ); + break; } } else @@ -1939,6 +1967,192 @@ bool CProtocol::EvaluateCLReqVersionAndOSMes ( const CHostAddress& InetAddr ) return false; // no error } +void CProtocol::CreateCLConnClientsListMes ( const CHostAddress& InetAddr, + const int iRequestID, + const CVector& vecChanInfo ) +{ + const int iNumClients = vecChanInfo.Size(); + + // build data vector + CVector vecData ( 4 ); // 4 bytes of data for request ID + int iPos = 0; // init position pointer + + // request ID (4 bytes) + PutValOnStream ( vecData, iPos, static_cast ( iRequestID ), 4 ); + + for ( int i = 0; i < iNumClients; i++ ) + { + // convert strings to utf-8 + const QByteArray strUTF8Name = vecChanInfo[i].strName.toUtf8(); + const QByteArray strUTF8City = vecChanInfo[i].strCity.toUtf8(); + + // size of current list entry + const int iCurListEntrLen = + 1 /* chan ID */ + 2 /* country */ + + 4 /* instrument */ + 1 /* skill level */ + + 4 /* IP address */ + + 2 /* utf-8 str. size */ + strUTF8Name.size() + + 2 /* utf-8 str. size */ + strUTF8City.size(); + + // make space for new data + vecData.Enlarge ( iCurListEntrLen ); + + // channel ID (1 byte) + PutValOnStream ( vecData, iPos, + static_cast ( vecChanInfo[i].iChanID ), 1 ); + + // country (2 bytes) + PutValOnStream ( vecData, iPos, + static_cast ( vecChanInfo[i].eCountry ), 2 ); + + // instrument (4 bytes) + PutValOnStream ( vecData, iPos, + static_cast ( vecChanInfo[i].iInstrument ), 4 ); + + // skill level (1 byte) + PutValOnStream ( vecData, iPos, + static_cast ( vecChanInfo[i].eSkillLevel ), 1 ); + + // IP address (4 bytes) + PutValOnStream ( vecData, iPos, + static_cast ( vecChanInfo[i].iIpAddr ), 4 ); + + // name + PutStringUTF8OnStream ( vecData, iPos, strUTF8Name ); + + // city + PutStringUTF8OnStream ( vecData, iPos, strUTF8City ); + } + + CreateAndImmSendConLessMessage ( PROTMESSID_CLM_CONN_CLIENTS_LIST, + vecData, + InetAddr ); +} + +bool CProtocol::EvaluateCLConnClientsListMes ( const CHostAddress& InetAddr, + const CVector& vecData ) +{ + int iPos = 0; // init position pointer + const int iDataLen = vecData.Size(); + CVector vecChanInfo ( 0 ); + + // check size (the first 4 bytes) + if ( iDataLen < 4 ) + { + return true; // return error code + } + + // request ID (4 bytes) + const int iRequestID = + static_cast ( GetValFromStream ( vecData, iPos, 4 ) ); + + while ( iPos < iDataLen ) + { + // check size (the next 12 bytes) + if ( ( iDataLen - iPos ) < 12 ) + { + return true; // return error code + } + + // channel ID (1 byte) + const int iChanID = + static_cast ( GetValFromStream ( vecData, iPos, 1 ) ); + + // country (2 bytes) + const QLocale::Country eCountry = + static_cast ( GetValFromStream ( vecData, iPos, 2 ) ); + + // instrument (4 bytes) + const int iInstrument = + static_cast ( GetValFromStream ( vecData, iPos, 4 ) ); + + // skill level (1 byte) + const ESkillLevel eSkillLevel = + static_cast ( GetValFromStream ( vecData, iPos, 1 ) ); + + // IP address (4 bytes) + const int iIpAddr = + static_cast ( GetValFromStream ( vecData, iPos, 4 ) ); + + // name + QString strCurName; + if ( GetStringFromStream ( vecData, + iPos, + MAX_LEN_FADER_TAG, + strCurName ) ) + { + return true; // return error code + } + + // city + QString strCurCity; + if ( GetStringFromStream ( vecData, + iPos, + MAX_LEN_SERVER_CITY, + strCurCity ) ) + { + return true; // return error code + } + + // add channel information to vector + vecChanInfo.Add ( CChannelInfo ( iChanID, + iIpAddr, + strCurName, + eCountry, + strCurCity, + iInstrument, + eSkillLevel ) ); + } + + // check size: all data is read, the position must now be at the end + if ( iPos != iDataLen ) + { + return true; // return error code + } + + // invoke message action + emit CLConnClientsListMesReceived ( InetAddr, iRequestID, vecChanInfo ); + + return false; // no error +} + +void CProtocol::CreateCLReqConnClientsListMes ( const CHostAddress& InetAddr, + const int iRequestID ) +{ + int iPos = 0; // init position pointer + + // build data vector (4 bytes long) + CVector vecData ( 4 ); + + // request ID (4 bytes) + PutValOnStream ( vecData, iPos, static_cast ( iRequestID ), 4 ); + + CreateAndImmSendConLessMessage ( PROTMESSID_CLM_REQ_CONN_CLIENTS_LIST, + vecData, + InetAddr ); +} + +bool CProtocol::EvaluateCLReqConnClientsListMes ( const CHostAddress& InetAddr, + const CVector& vecData ) +{ + int iPos = 0; // init position pointer + + // check size + if ( vecData.Size() != 4 ) + { + return true; // return error code + } + + // request ID (4 bytes) + const int iRequestID = + static_cast ( GetValFromStream ( vecData, iPos, 4 ) ); + + // invoke message action + emit CLReqConnClientsList ( InetAddr, iRequestID ); + + return false; // no error +} + /******************************************************************************\ * Message generation and parsing * diff --git a/src/protocol.h b/src/protocol.h index 940bd7bf..62ad9e4b 100755 --- a/src/protocol.h +++ b/src/protocol.h @@ -70,6 +70,8 @@ #define PROTMESSID_CLM_DISCONNECTION 1010 // disconnection #define PROTMESSID_CLM_VERSION_AND_OS 1011 // version number and operating system #define PROTMESSID_CLM_REQ_VERSION_AND_OS 1012 // request version number and operating system +#define PROTMESSID_CLM_CONN_CLIENTS_LIST 1013 // channel infos for connected clients +#define PROTMESSID_CLM_REQ_CONN_CLIENTS_LIST 1014 // request the connected clients list // lengths of message as defined in protocol.cpp file #define MESS_HEADER_LENGTH_BYTE 7 // TAG (2), ID (2), cnt (1), length (2) @@ -121,6 +123,11 @@ public: void CreateCLDisconnection ( const CHostAddress& InetAddr ); void CreateCLVersionAndOSMes ( const CHostAddress& InetAddr ); void CreateCLReqVersionAndOSMes ( const CHostAddress& InetAddr ); + void CreateCLConnClientsListMes ( const CHostAddress& InetAddr, + const int iRequestID, + const CVector& vecChanInfo ); + void CreateCLReqConnClientsListMes ( const CHostAddress& InetAddr, + const int iRequestID ); static bool ParseMessageFrame ( const CVector& vecbyData, const int iNumBytesIn, @@ -236,6 +243,10 @@ protected: bool EvaluateCLVersionAndOSMes ( const CHostAddress& InetAddr, const CVector& vecData ); bool EvaluateCLReqVersionAndOSMes ( const CHostAddress& InetAddr ); + bool EvaluateCLConnClientsListMes ( const CHostAddress& InetAddr, + const CVector& vecData ); + bool EvaluateCLReqConnClientsListMes ( const CHostAddress& InetAddr, + const CVector& vecData ); int iOldRecID; int iOldRecCnt; @@ -291,6 +302,11 @@ signals: COSUtil::EOpSystemType eOSType, QString strVersion ); void CLReqVersionAndOS ( CHostAddress InetAddr ); + void CLConnClientsListMesReceived ( CHostAddress InetAddr, + int iRequestID, + CVector vecChanInfo ); + void CLReqConnClientsList ( CHostAddress InetAddr, + int iRequestID ); }; #endif /* !defined ( PROTOCOL_H__3B123453_4344_BB2392354455IUHF1912__INCLUDED_ ) */ diff --git a/src/server.cpp b/src/server.cpp index 53d160cc..53602165 100755 --- a/src/server.cpp +++ b/src/server.cpp @@ -434,6 +434,10 @@ CServer::CServer ( const int iNewMaxNumChan, SIGNAL ( CLReqVersionAndOS ( CHostAddress ) ), this, SLOT ( OnCLReqVersionAndOS ( CHostAddress ) ) ); + QObject::connect ( &ConnLessProtocol, + SIGNAL ( CLReqConnClientsList ( CHostAddress, int ) ), + this, SLOT ( OnCLReqConnClientsList ( CHostAddress, int ) ) ); + // CODE TAG: MAX_NUM_CHANNELS_TAG // make sure we have MAX_NUM_CHANNELS connections!!! // send message diff --git a/src/server.h b/src/server.h index 74dedd9a..19ae34a1 100755 --- a/src/server.h +++ b/src/server.h @@ -332,6 +332,10 @@ public slots: void OnCLReqVersionAndOS ( CHostAddress InetAddr ) { ConnLessProtocol.CreateCLVersionAndOSMes ( InetAddr ); } + void OnCLReqConnClientsList ( CHostAddress InetAddr, + int iRequestID ) + { ConnLessProtocol.CreateCLConnClientsListMes ( InetAddr, iRequestID, CreateChannelList() ); } + void OnCLRegisterServerReceived ( CHostAddress InetAddr, CServerCoreInfo ServerInfo ) {