I posted the whole functions which incorporate the changes for better readability / understandability and for easier merging
Here we go:
BaseClient.cpp:
void CUpDownClient::InitClientSoftwareVersion() { if (m_pszUsername == NULL){ m_clientSoft = SO_UNKNOWN; return; } int iHashType = GetHashType(); if (m_bEmuleProtocol || iHashType == SO_EMULE){ LPCTSTR pszSoftware; switch(m_byCompatibleClient){ case SO_CDONKEY: m_clientSoft = SO_CDONKEY; pszSoftware = _T("cDonkey"); break; case SO_XMULE: m_clientSoft = SO_XMULE; pszSoftware = _T("xMule"); break; case SO_AMULE: m_clientSoft = SO_AMULE; pszSoftware = _T("aMule"); break; case SO_SHAREAZA: // Spike2 - Enhanced Client Recognition v2 - START // removed "case 40"... this is now integrated here case SO_SHAREAZA2: case SO_SHAREAZA3: case SO_SHAREAZA4: // Spike2 - Enhanced Client Recognition v2 - END m_clientSoft = SO_SHAREAZA; pszSoftware = _T("Shareaza"); break; case SO_LPHANT: m_clientSoft = SO_LPHANT; pszSoftware = _T("lphant"); break; // Spike2 - Enhanced Client Recognition v2 - START case SO_EMULEPLUS: m_clientSoft = SO_EMULEPLUS; pszSoftware = _T("eMule Plus"); break; case SO_HYDRANODE: m_clientSoft = SO_HYDRANODE; pszSoftware = _T("Hydranode"); break; case SO_TRUSTYFILES: m_clientSoft = SO_TRUSTYFILES; pszSoftware = _T("TrustyFiles"); break; // Spike2 - Enhanced Client Recognition v2 - END default: if (m_bIsML || m_byCompatibleClient == SO_MLDONKEY || m_byCompatibleClient == SO_MLDONKEY2 || m_byCompatibleClient == SO_MLDONKEY3){ // Spike2 - Enhanced Client Recognition v2 m_clientSoft = SO_MLDONKEY; pszSoftware = _T("MLdonkey"); } else if ( m_bIsHybrid || m_byCompatibleClient == SO_EDONKEYHYBRID){ // Spike2 - Enhanced Client Recognition v2 m_clientSoft = SO_EDONKEYHYBRID; pszSoftware = _T("eDonkeyHybrid"); } else if (m_byCompatibleClient != 0){ // Spike2 - Enhanced Client Recognition v2 - START // Recognize all eMulePlus - just to be sure ! // Note that the compare is done case-sensitive to avoid false positives. if (StrStr(m_strModVersion,_T("Plus 1"))) { m_clientSoft = SO_EMULEPLUS; pszSoftware = _T("eMule Plus"); } else { // Spike2 - Enhanced Client Recognition v2 - END m_clientSoft = SO_XMULE; // means: 'eMule Compatible' pszSoftware = _T("eMule Compat"); } // Spike2 - Enhanced Client Recognition v2 } else{ m_clientSoft = SO_EMULE; pszSoftware = _T("eMule"); } } int iLen; TCHAR szSoftware[128]; if (m_byEmuleVersion == 0){ m_nClientVersion = MAKE_CLIENT_VERSION(0, 0, 0); iLen = _sntprintf(szSoftware, ARRSIZE(szSoftware), _T("%s"), pszSoftware); } else if (m_byEmuleVersion != 0x99){ UINT nClientMinVersion = (m_byEmuleVersion >> 4)*10 + (m_byEmuleVersion & 0x0f); m_nClientVersion = MAKE_CLIENT_VERSION(0, nClientMinVersion, 0); iLen = _sntprintf(szSoftware, ARRSIZE(szSoftware), _T("%s v0.%u"), pszSoftware, nClientMinVersion); } else{ UINT nClientMajVersion = (m_nClientVersion >> 17) & 0x7f; UINT nClientMinVersion = (m_nClientVersion >> 10) & 0x7f; UINT nClientUpVersion = (m_nClientVersion >> 7) & 0x07; m_nClientVersion = MAKE_CLIENT_VERSION(nClientMajVersion, nClientMinVersion, nClientUpVersion); if (m_clientSoft == SO_EMULE) iLen = _sntprintf(szSoftware, ARRSIZE(szSoftware), _T("%s v%u.%u%c"), pszSoftware, nClientMajVersion, nClientMinVersion, _T('a') + nClientUpVersion); // Spike2 - Enhanced Client Recognition v2 - START else if (m_clientSoft == SO_EMULEPLUS) // Spike2 - Fix by BlueSonicBoy - Thanx! { if(nClientMinVersion == 0) { if(nClientUpVersion == 0) iLen = _sntprintf(szSoftware, ARRSIZE(szSoftware), _T("%s v%u"), pszSoftware, nClientMajVersion); else iLen = _sntprintf(szSoftware, ARRSIZE(szSoftware), _T("%s v%u%c"), pszSoftware, nClientMajVersion, _T('a') + nClientUpVersion - 1); } else { if(nClientUpVersion == 0) iLen = _sntprintf(szSoftware, ARRSIZE(szSoftware), _T("%s v%u.%u"), pszSoftware, nClientMajVersion, nClientMinVersion); else iLen = _sntprintf(szSoftware, ARRSIZE(szSoftware), _T("%s v%u.%u%c"), pszSoftware, nClientMajVersion, nClientMinVersion, _T('a') + nClientUpVersion - 1); } } // Spike2 - Enhanced Client Recognition v2 - END else if (m_clientSoft == SO_AMULE || nClientUpVersion != 0) iLen = _sntprintf(szSoftware, ARRSIZE(szSoftware), _T("%s v%u.%u.%u"), pszSoftware, nClientMajVersion, nClientMinVersion, nClientUpVersion); else if (m_clientSoft == SO_LPHANT) { if (nClientMinVersion < 10) iLen = _sntprintf(szSoftware, ARRSIZE(szSoftware), _T("%s v%u.0%u"), pszSoftware, (nClientMajVersion-1), nClientMinVersion); else iLen = _sntprintf(szSoftware, ARRSIZE(szSoftware), _T("%s v%u.%u"), pszSoftware, (nClientMajVersion-1), nClientMinVersion); } else iLen = _sntprintf(szSoftware, ARRSIZE(szSoftware), _T("%s v%u.%u"), pszSoftware, nClientMajVersion, nClientMinVersion); } if (iLen > 0){ memcpy(m_strClientSoftware.GetBuffer(iLen), szSoftware, iLen*sizeof(TCHAR)); m_strClientSoftware.ReleaseBuffer(iLen); } return; } if (m_bIsHybrid || m_byCompatibleClient == SO_EDONKEYHYBRID){ // Spike2 - Enhanced Client Recognition v2 m_clientSoft = SO_EDONKEYHYBRID; // seen: // 105010 0.50.10 // 10501 0.50.1 // 10405 1.4.5 // Spike2 - Enhanced Client Recognition v2 (this one found by netfinity) // 10300 1.3.0 // 10212 1.2.2 // Spike2 - Enhanced Client Recognition v2 // 10211 1.2.1 // Spike2 - Enhanced Client Recognition v2 // 10201 1.2.1 // 10103 1.1.3 // 10102 1.1.2 // 10100 1.1 // 1051 0.51.0 // 1002 1.0.2 // 1000 1.0 // 501 0.50.1 UINT nClientMajVersion; UINT nClientMinVersion; UINT nClientUpVersion; if (m_nClientVersion > 100000){ UINT uMaj = m_nClientVersion/100000; nClientMajVersion = uMaj - 1; nClientMinVersion = (m_nClientVersion - uMaj*100000) / 100; nClientUpVersion = m_nClientVersion % 100; } // Spike2 - Enhanced Client Recognition v2 else if (m_nClientVersion >= 10100 && m_nClientVersion <= 10409){ // netfinity UINT uMaj = m_nClientVersion/10000; nClientMajVersion = uMaj; nClientMinVersion = (m_nClientVersion - uMaj*10000) / 100; nClientUpVersion = m_nClientVersion % 10; } else if (m_nClientVersion > 10000){ UINT uMaj = m_nClientVersion/10000; nClientMajVersion = uMaj - 1; nClientMinVersion = (m_nClientVersion - uMaj*10000) / 10; nClientUpVersion = m_nClientVersion % 10; } else if (m_nClientVersion >= 1000 && m_nClientVersion < 1020){ UINT uMaj = m_nClientVersion/1000; nClientMajVersion = uMaj; nClientMinVersion = (m_nClientVersion - uMaj*1000) / 10; nClientUpVersion = m_nClientVersion % 10; } else if (m_nClientVersion > 1000){ UINT uMaj = m_nClientVersion/1000; nClientMajVersion = uMaj - 1; nClientMinVersion = m_nClientVersion - uMaj*1000; nClientUpVersion = 0; } else if (m_nClientVersion > 100){ UINT uMin = m_nClientVersion/10; nClientMajVersion = 0; nClientMinVersion = uMin; nClientUpVersion = m_nClientVersion - uMin*10; } else{ nClientMajVersion = 0; nClientMinVersion = m_nClientVersion; nClientUpVersion = 0; } m_nClientVersion = MAKE_CLIENT_VERSION(nClientMajVersion, nClientMinVersion, nClientUpVersion); int iLen; TCHAR szSoftware[128]; if (nClientUpVersion) iLen = _sntprintf(szSoftware, ARRSIZE(szSoftware), _T("eDonkeyHybrid v%u.%u.%u"), nClientMajVersion, nClientMinVersion, nClientUpVersion); else iLen = _sntprintf(szSoftware, ARRSIZE(szSoftware), _T("eDonkeyHybrid v%u.%u"), nClientMajVersion, nClientMinVersion); if (iLen > 0){ memcpy(m_strClientSoftware.GetBuffer(iLen), szSoftware, iLen*sizeof(TCHAR)); m_strClientSoftware.ReleaseBuffer(iLen); } return; } // Spike2 - Enhanced Client Recognition v2 - START (Thanx to WiZaRd for this one !) if (m_bIsML || iHashType == SO_MLDONKEY || iHashType == SO_OLD_MLDONKEY){ // Spike2 - Enhanced Client Recognition v2 - END m_clientSoft = SO_MLDONKEY; UINT nClientMinVersion = m_nClientVersion; m_nClientVersion = MAKE_CLIENT_VERSION(0, nClientMinVersion, 0); TCHAR szSoftware[128]; int iLen = _sntprintf(szSoftware, ARRSIZE(szSoftware), _T("MLdonkey v0.%u"), nClientMinVersion); if (iLen > 0){ memcpy(m_strClientSoftware.GetBuffer(iLen), szSoftware, iLen*sizeof(TCHAR)); m_strClientSoftware.ReleaseBuffer(iLen); } return; } if (iHashType == SO_OLDEMULE){ m_clientSoft = SO_OLDEMULE; UINT nClientMinVersion = m_nClientVersion; m_nClientVersion = MAKE_CLIENT_VERSION(0, nClientMinVersion, 0); TCHAR szSoftware[128]; int iLen = _sntprintf(szSoftware, ARRSIZE(szSoftware), _T("Old eMule v0.%u"), nClientMinVersion); if (iLen > 0){ memcpy(m_strClientSoftware.GetBuffer(iLen), szSoftware, iLen*sizeof(TCHAR)); m_strClientSoftware.ReleaseBuffer(iLen); } return; } m_clientSoft = SO_EDONKEY; UINT nClientMinVersion = m_nClientVersion; m_nClientVersion = MAKE_CLIENT_VERSION(0, nClientMinVersion, 0); TCHAR szSoftware[128]; int iLen = _sntprintf(szSoftware, ARRSIZE(szSoftware), _T("eDonkey v0.%u"), nClientMinVersion); if (iLen > 0){ memcpy(m_strClientSoftware.GetBuffer(iLen), szSoftware, iLen*sizeof(TCHAR)); m_strClientSoftware.ReleaseBuffer(iLen); } } int CUpDownClient::GetHashType() const { if (m_achUserHash[5] == 13 && m_achUserHash[14] == 110) return SO_OLDEMULE; else if (m_achUserHash[5] == 'M' && m_achUserHash[14] == 'L') // Spike2 - Enhanced Client Recognition v2 - START return SO_OLD_MLDONKEY; else if (m_achUserHash[5] == 0x0E && m_achUserHash[14] == 0x6F) return SO_MLDONKEY; // Spike2 - Enhanced Client Recognition v2 - END else if (m_achUserHash[5] == 14 && m_achUserHash[14] == 111) return SO_EMULE; else return SO_UNKNOWN; }
ClientList.cpp:
void CClientList::GetStatistics(uint32 &ruTotalClients, int stats[NUM_CLIENTLIST_STATS], CMap<uint32, uint32, uint32, uint32>& clientVersionEDonkey, CMap<uint32, uint32, uint32, uint32>& clientVersionEDonkeyHybrid, CMap<uint32, uint32, uint32, uint32>& clientVersionEMule, CMap<uint32, uint32, uint32, uint32>& clientVersionAMule) { ruTotalClients = list.GetCount(); memset(stats, 0, sizeof(stats[0]) * NUM_CLIENTLIST_STATS); for (POSITION pos = list.GetHeadPosition(); pos != NULL; ) { const CUpDownClient* cur_client = list.GetNext(pos); if (cur_client->HasLowID()) stats[14]++; switch (cur_client->GetClientSoft()) { case SO_EMULE: case SO_OLDEMULE: stats[2]++; clientVersionEMule[cur_client->GetVersion()]++; break; case SO_EDONKEYHYBRID : stats[4]++; clientVersionEDonkeyHybrid[cur_client->GetVersion()]++; break; case SO_AMULE: stats[10]++; clientVersionAMule[cur_client->GetVersion()]++; break; case SO_EDONKEY: stats[1]++; clientVersionEDonkey[cur_client->GetVersion()]++; break; case SO_MLDONKEY: stats[3]++; break; case SO_SHAREAZA: stats[11]++; break; // all remaining 'eMule Compatible' clients // Spike2 - Enhanced Client Recognition v2 - START case SO_HYDRANODE: case SO_EMULEPLUS: case SO_TRUSTYFILES: // Spike2 - Enhanced Client Recognition v2 - END case SO_CDONKEY: case SO_XMULE: case SO_LPHANT: stats[5]++; break; default: stats[0]++; break; } ....
New function:
//Spike2 - Enhanced Client Recognition v2 - START // ==> Compat Client Stats [Stulle] - Stulle void CClientList::GetCompatClientsStats(CRBMap<CString, uint32> *compatClients) { for (POSITION pos = list.GetHeadPosition(); pos != NULL;) { CUpDownClient* cur_client = list.GetNext(pos); switch (cur_client->GetClientSoft()) { case SO_HYDRANODE: { uint32 count; if (!compatClients->Lookup(_T("Hydranode"), count)) count = 1; else count++; compatClients->SetAt(_T("Hydranode"), count); }break; case SO_EMULEPLUS: { uint32 count; if (!compatClients->Lookup(_T("eMule Plus"), count)) count = 1; else count++; compatClients->SetAt(_T("eMule Plus"), count); }break; case SO_TRUSTYFILES: { uint32 count; if (!compatClients->Lookup(_T("TrustyFiles"), count)) count = 1; else count++; compatClients->SetAt(_T("TrustyFiles"), count); }break; case SO_CDONKEY: { uint32 count; if (!compatClients->Lookup(_T("cDonkey"), count)) count = 1; else count++; compatClients->SetAt(_T("cDonkey"), count); }break; case SO_XMULE: { uint32 count; if (!compatClients->Lookup(_T("xMule"), count)) count = 1; else count++; compatClients->SetAt(_T("xMule"), count); }break; case SO_LPHANT: { uint32 count; if (!compatClients->Lookup(_T("lphant"), count)) count = 1; else count++; compatClients->SetAt(_T("lphant"), count); }break; default: continue; } } } // <== Compat Client Stats [Stulle] - Stulle //Spike2 - Enhanced Client Recognition v2 - END
ClientList.h:
//Spike2 - Enhanced Client Recognition v2 - START public: void GetCompatClientsStats(CRBMap<CString, uint32> *compatClients); // CompatClientStats by Stulle //Spike2 - Enhanced Client Recognition v2 - END
ClientStateDefs.h:
enum EClientSoftware{ SO_EMULE = 0, // default SO_CDONKEY = 1, // ET_COMPATIBLECLIENT SO_XMULE = 2, // ET_COMPATIBLECLIENT SO_AMULE = 3, // ET_COMPATIBLECLIENT SO_SHAREAZA = 4, // ET_COMPATIBLECLIENT SO_EMULEPLUS = 5, // Spike2 - Enhanced Client Recognition v2 SO_HYDRANODE = 6, // Spike2 - Enhanced Client Recognition v2 SO_MLDONKEY = 10, // ET_COMPATIBLECLIENT SO_LPHANT = 20, // ET_COMPATIBLECLIENT SO_SHAREAZA2 = 28, // Spike2 - Enhanced Client Recognition v2 SO_TRUSTYFILES = 30, // Spike2 - Enhanced Client Recognition v2 SO_SHAREAZA3 = 40, // Spike2 - Enhanced Client Recognition v2 // other client types which are not identified with ET_COMPATIBLECLIENT SO_EDONKEYHYBRID = 50, //Spike2 - Enhanced Client Recognition v2 - START SO_EDONKEY = 51, // from aMule SO_MLDONKEY2 = 52, // from aMule SO_OLDEMULE = 53, // from aMule SO_SHAREAZA4 = 68, // from aMule SO_MLDONKEY3 = 152, // from aMule SO_OLD_MLDONKEY, // Enhancement from WiZaRd - these are the MLdonkeys with M and L in the hash :) //Spike2 - Enhanced Client Recognition v2 - END SO_URL, SO_UNKNOWN };
otherfunctions.cpp:
int GetHashType(const uchar* hash) { if (hash[5] == 13 && hash[14] == 110) return SO_OLDEMULE; else if (hash[5] == 'M' && hash[14] == 'L') // Spike2 - Enhanced Client Recognition v2- START // Thanx to WiZaRd for this one return SO_OLD_MLDONKEY; // was: SO_MLDONKEY else if (hash[5] == 0x0E && hash[14] == 0x6F) return SO_MLDONKEY; // Spike2 - Enhanced Client Recognition v2 - END else if (hash[5] == 14 && hash[14] == 111) return SO_EMULE; else return SO_UNKNOWN; } LPCTSTR DbgGetHashTypeString(const uchar* hash) { int iHashType = GetHashType(hash); if (iHashType == SO_EMULE) return _T("eMule"); if (iHashType == SO_MLDONKEY) return _T("MLdonkey"); // Spike2 - Enhanced Client Recognition v2 - START // Thanx to WiZaRd for this one else if (iHashType == SO_OLD_MLDONKEY) return _T("Old MLdonkey"); // Spike2 - Enhanced Client Recognition v2 - END if (iHashType == SO_OLDEMULE) return _T("Old eMule"); ASSERT( iHashType == SO_UNKNOWN ); return _T("Unknown"); }
Preferences.cpp:
void CPreferences::Add2SessionTransferData(UINT uClientID, UINT uClientPort, BOOL bFromPF, BOOL bUpDown, uint32 bytes, bool sentToFriend) { // This function adds the transferred bytes to the appropriate variables, // as well as to the totals for all clients. - Khaos // PARAMETERS: // uClientID - The identifier for which client software sent or received this data, eg SO_EMULE // uClientPort - The remote port of the client that sent or received this data, eg 4662 // bFromPF - Applies only to uploads. True is from partfile, False is from non-partfile. // bUpDown - True is Up, False is Down // bytes - Number of bytes sent by the client. Subtract header before calling. switch (bUpDown){ case true: // Upline Data switch (uClientID){ // Update session client breakdown stats for sent bytes... case SO_EMULE: case SO_OLDEMULE: sesUpData_EMULE+=bytes; break; case SO_EDONKEYHYBRID: sesUpData_EDONKEYHYBRID+=bytes; break; case SO_EDONKEY: sesUpData_EDONKEY+=bytes; break; case SO_MLDONKEY: sesUpData_MLDONKEY+=bytes; break; case SO_AMULE: sesUpData_AMULE+=bytes; break; case SO_SHAREAZA: sesUpData_SHAREAZA+=bytes; break; // Spike2 - Enhanced Client Recognition v2 - START //Fix by Stulle !! case SO_HYDRANODE: case SO_EMULEPLUS: case SO_TRUSTYFILES: // Spike2 - Enhanced Client Recognition v2 - END case SO_CDONKEY: case SO_LPHANT: case SO_XMULE: sesUpData_EMULECOMPAT+=bytes; break; } ....
// Downline Data switch (uClientID){ // Update session client breakdown stats for received bytes... case SO_EMULE: case SO_OLDEMULE: sesDownData_EMULE+=bytes; break; case SO_EDONKEYHYBRID: sesDownData_EDONKEYHYBRID+=bytes;break; case SO_EDONKEY: sesDownData_EDONKEY+=bytes; break; case SO_MLDONKEY: sesDownData_MLDONKEY+=bytes; break; case SO_AMULE: sesDownData_AMULE+=bytes; break; case SO_SHAREAZA: sesDownData_SHAREAZA+=bytes; break; // Spike2 - Enhanced Client Recognition v2 - START // Fix by Stulle !! case SO_HYDRANODE: case SO_EMULEPLUS: case SO_TRUSTYFILES: // Spike2 - Enhanced Client Recognition v2 - END case SO_CDONKEY: case SO_LPHANT: case SO_XMULE: sesDownData_EMULECOMPAT+=bytes; break; case SO_URL: sesDownData_URL+=bytes; break; }
StatisticsDlg.cpp:
AFTER
if (verCount < cli_lastCount[3]) { for (uint32 i = 0; i < cli_lastCount[3] - verCount; i++) { stattree.DeleteItem(cli_versions[cli_lastCount[3] + (MAX_SUB_CLIENT_VERSIONS*3-1) - i]); if (cli_lastCount[3] + (MAX_SUB_CLIENT_VERSIONS*3-1) - i == MAX_SUB_CLIENT_VERSIONS/2) stattree.DeleteItem(cli_other[3]); } } cli_lastCount[3] = verCount; } // End Clients -> Client Software -> aMule Section
ADD
//Spike2 - Enhanced Client Recognition v2 - START // ==> Compat Client Stats [Stulle] - Stulle CRBMap<CString, uint32> compatClients; theApp.clientlist->GetCompatClientsStats(&compatClients); POSITION mpos = compatClients.GetHeadPosition(); if (stattree.ItemHasChildren(clisoft[6])){ HTREEITEM hChild; hChild = stattree.GetChildItem(clisoft[6]); while( hChild != NULL && mpos != NULL ) { CString name; uint32 count; compatClients.GetNextAssoc(mpos, name, count); cbuffer.Format(_T("%s: %i (%1.1f%%)"), name, count, (double)count/myStats[5]*100); stattree.SetItemText(hChild, cbuffer); hChild = stattree.GetNextSiblingItem( hChild ); } while (hChild != NULL){ HTREEITEM hTemp = hChild; hChild = stattree.GetNextSiblingItem( hChild ); stattree.DeleteItem(hTemp); } } while (mpos != NULL){ CString name; uint32 count; compatClients.GetNextAssoc(mpos, name, count); cbuffer.Format(_T("%s: %i (%1.1f%%)"), name, count, (double)count/myStats[5]*100); stattree.InsertItem(cbuffer, clisoft[6]); } // <== Compat Client Stats [Stulle] - Stulle //Spike2 - Enhanced Client Recognition v2 - END
Please note that there is an optimized variant of Stulle's CompatClientStats-code done by WiZaRd, but I don't have it at hand right now... But of course ECR is fully functional in the way I posted it.
Greetz,
Spike2
This post has been edited by Famerlor: 14 September 2009 - 06:36 AM