📄 clientlist.cpp
字号:
//this file is part of eMule
//Copyright (C)2002 Merkur ( devs@emule-project.net / http://www.emule-project.net )
//
//This program is free software; you can redistribute it and/or
//modify it under the terms of the GNU General Public License
//as published by the Free Software Foundation; either
//version 2 of the License, or (at your option) any later version.
//
//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//GNU General Public License for more details.
//
//You should have received a copy of the GNU General Public License
//along with this program; if not, write to the Free Software
//Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#include "stdafx.h"
#include "emule.h"
#include "ClientList.h"
#include "otherfunctions.h"
#include "Kademlia/Kademlia/kademlia.h"
#include "Kademlia/Kademlia/prefs.h"
#include "Kademlia/Kademlia/search.h"
#include "Kademlia/Kademlia/searchmanager.h"
#include "Kademlia/routing/contact.h"
#include "Kademlia/net/kademliaudplistener.h"
#include "kademlia/utils/UInt128.h"
#include "LastCommonRouteFinder.h"
#include "UploadQueue.h"
#include "DownloadQueue.h"
#include "UpDownClient.h"
#include "ClientCredits.h"
#include "ListenSocket.h"
#include "Opcodes.h"
#include "Sockets.h"
#include "emuledlg.h"
#include "TransferWnd.h"
#include "serverwnd.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
CClientList::CClientList(){
m_dwLastBannCleanUp = 0;
m_dwLastTrackedCleanUp = 0;
m_dwLastClientCleanUp = 0;
m_bHaveBuddy = 0;
m_bannedList.InitHashTable(331);
m_trackedClientsList.InitHashTable(2011);
m_globDeadSourceList.Init(true);
m_pBuddy = NULL;
}
CClientList::~CClientList(){
POSITION pos = m_trackedClientsList.GetStartPosition();
uint32 nKey;
CDeletedClient* pResult;
while (pos != NULL){
m_trackedClientsList.GetNextAssoc( pos, nKey, pResult );
m_trackedClientsList.RemoveKey(nKey);
delete pResult;
}
}
void CClientList::GetStatistics(uint32 &totalclient, int 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)
{
totalclient = list.GetCount();
for (int i = 0; i < 19; i++)
stats[i] = 0;
stats[7] = m_bannedList.GetCount();
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]++;
//uint8 version = cur_client->GetMuleVersion();
//if (version == 0xFF || version == 0x66 || version==0x69 || version==0x90 || version==0x33 || version==0x60)
// continue;
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
case SO_CDONKEY:
case SO_XMULE:
case SO_LPHANT:
stats[5]++;
break;
default:
stats[0]++;
break;
}
if (cur_client->Credits() != NULL)
{
switch (cur_client->Credits()->GetCurrentIdentState(cur_client->GetIP()))
{
case IS_IDENTIFIED:
stats[12]++;
break;
case IS_IDFAILED:
case IS_IDNEEDED:
case IS_IDBADGUY:
stats[13]++;
break;
}
}
if (cur_client->GetDownloadState()==DS_ERROR || cur_client->GetUploadState()==US_ERROR)
stats[6]++; // Error
switch (cur_client->GetUserPort())
{
case 4662:
stats[8]++; // Default Port
break;
default:
stats[9]++; // Other Port
}
// Network client stats
if (cur_client->GetServerIP() && cur_client->GetServerPort())
{
stats[15]++; // eD2K
if(cur_client->GetKadPort())
{
stats[17]++; // eD2K/Kad
stats[16]++; // Kad
}
}
else if (cur_client->GetKadPort())
stats[16]++; // Kad
else
stats[18]++; // Unknown
}
}
void CClientList::AddClient(CUpDownClient* toadd, bool bSkipDupTest)
{
// skipping the check for duplicate list entries is only to be done for optimization purposes, if the calling
// function has ensured that this client instance is not already within the list -> there are never duplicate
// client instances in this list.
if (!bSkipDupTest){
if(list.Find(toadd))
return;
}
theApp.emuledlg->transferwnd->clientlistctrl.AddClient(toadd);
list.AddTail(toadd);
}
// ZZ:UploadSpeedSense -->
bool CClientList::GiveClientsForTraceRoute() {
// this is a host that lastCommonRouteFinder can use to traceroute
return theApp.lastCommonRouteFinder->AddHostsToCheck(list);
}
// ZZ:UploadSpeedSense <--
void CClientList::RemoveClient(CUpDownClient* toremove, LPCTSTR pszReason){
POSITION pos = list.Find(toremove);
if (pos){
//just to be sure...
CString strInfo(_T("Client removed from CClientList::RemoveClient()."));
if (pszReason){
strInfo += _T(" Reason: ");
strInfo += pszReason;
}
theApp.uploadqueue->RemoveFromUploadQueue(toremove, strInfo);
theApp.uploadqueue->RemoveFromWaitingQueue(toremove);
theApp.downloadqueue->RemoveSource(toremove);
theApp.emuledlg->transferwnd->clientlistctrl.RemoveClient(toremove);
RemoveFromKadList(toremove);
list.RemoveAt(pos);
}
}
void CClientList::DeleteAll(){
theApp.uploadqueue->DeleteAll();
theApp.downloadqueue->DeleteAll();
POSITION pos1, pos2;
for (pos1 = list.GetHeadPosition();( pos2 = pos1 ) != NULL;){
list.GetNext(pos1);
CUpDownClient* cur_client = list.GetAt(pos2);
list.RemoveAt(pos2);
delete cur_client; // recursiv: this will call RemoveClient
}
}
bool CClientList::AttachToAlreadyKnown(CUpDownClient** client, CClientReqSocket* sender){
POSITION pos1, pos2;
CUpDownClient* tocheck = (*client);
CUpDownClient* found_client = NULL;
CUpDownClient* found_client2 = NULL;
for (pos1 = list.GetHeadPosition();( pos2 = pos1 ) != NULL;){ //
list.GetNext(pos1);
CUpDownClient* cur_client = list.GetAt(pos2);
if (tocheck->Compare(cur_client,false)){ //matching userhash
found_client2 = cur_client;
}
if (tocheck->Compare(cur_client,true)){ //matching IP
found_client = cur_client;
break;
}
}
if (found_client == NULL)
found_client = found_client2;
if (found_client != NULL){
if (tocheck == found_client){
//we found the same client instance (client may have sent more than one OP_HELLO). do not delete that client!
return true;
}
if (sender){
if (found_client->socket){
if (found_client->socket->IsConnected()
&& (found_client->GetIP() != tocheck->GetIP() || found_client->GetUserPort() != tocheck->GetUserPort() ) )
{
// if found_client is connected and has the IS_IDENTIFIED, it's safe to say that the other one is a bad guy
if (found_client->Credits() && found_client->Credits()->GetCurrentIdentState(found_client->GetIP()) == IS_IDENTIFIED){
if (thePrefs.GetLogBannedClients())
AddDebugLogLine(false, _T("Clients: %s (%s), Banreason: Userhash invalid"), tocheck->GetUserName(), ipstr(tocheck->GetConnectIP()));
tocheck->Ban();
return false;
}
//IDS_CLIENTCOL Warning: Found matching client, to a currently connected client: %s (%s) and %s (%s)
if (thePrefs.GetLogBannedClients())
AddDebugLogLine(true,GetResString(IDS_CLIENTCOL), tocheck->GetUserName(), ipstr(tocheck->GetConnectIP()), found_client->GetUserName(), ipstr(found_client->GetConnectIP()));
return false;
}
found_client->socket->client = 0;
found_client->socket->Safe_Delete();
}
found_client->socket = sender;
tocheck->socket = 0;
}
*client = 0;
delete tocheck;
*client = found_client;
return true;
}
return false;
}
CUpDownClient* CClientList::FindClientByIP(uint32 clientip, UINT port) const
{
for (POSITION pos = list.GetHeadPosition(); pos != NULL;)
{
CUpDownClient* cur_client = list.GetNext(pos);
if (cur_client->GetIP() == clientip && cur_client->GetUserPort() == port)
return cur_client;
}
return 0;
}
CUpDownClient* CClientList::FindClientByUserHash(const uchar* clienthash) const
{
for (POSITION pos = list.GetHeadPosition(); pos != NULL;)
{
CUpDownClient* cur_client = list.GetNext(pos);
if (!md4cmp(cur_client->GetUserHash() ,clienthash))
return cur_client;
}
return 0;
}
CUpDownClient* CClientList::FindClientByIP(uint32 clientip) const
{
for (POSITION pos = list.GetHeadPosition(); pos != NULL;)
{
CUpDownClient* cur_client = list.GetNext(pos);
if (cur_client->GetIP() == clientip)
return cur_client;
}
return 0;
}
CUpDownClient* CClientList::FindClientByIP_UDP(uint32 clientip, UINT nUDPport) const
{
for (POSITION pos = list.GetHeadPosition(); pos != NULL;)
{
CUpDownClient* cur_client = list.GetNext(pos);
if (cur_client->GetIP() == clientip && cur_client->GetUDPPort() == nUDPport)
return cur_client;
}
return 0;
}
CUpDownClient* CClientList::FindClientByUserID_KadPort(uint32 clientID, uint16 kadPort) const
{
for (POSITION pos = list.GetHeadPosition(); pos != NULL;)
{
CUpDownClient* cur_client = list.GetNext(pos);
if (cur_client->GetUserIDHybrid() == clientID && cur_client->GetKadPort() == kadPort)
return cur_client;
}
return 0;
}
CUpDownClient* CClientList::FindClientByIP_KadPort(uint32 ip, uint16 port) const
{
for (POSITION pos = list.GetHeadPosition(); pos != NULL;)
{
CUpDownClient* cur_client = list.GetNext(pos);
if (cur_client->GetIP() == ip && cur_client->GetKadPort() == port)
return cur_client;
}
return 0;
}
//TODO: This needs to change to a random Kad user.
CUpDownClient* CClientList::GetRandomKadClient() const
{
for (POSITION pos = list.GetHeadPosition(); pos != NULL;)
{
CUpDownClient* cur_client = list.GetNext(pos);
if (cur_client->GetKadPort())
return cur_client;
}
return 0;
}
CUpDownClient* CClientList::FindClientByServerID(uint32 uServerIP, uint32 uED2KUserID) const
{
uint32 uHybridUserID = ntohl(uED2KUserID);
for (POSITION pos = list.GetHeadPosition(); pos != NULL;)
{
CUpDownClient* cur_client = list.GetNext(pos);
if (cur_client->GetServerIP() == uServerIP && cur_client->GetUserIDHybrid() == uHybridUserID)
return cur_client;
}
return 0;
}
void CClientList::AddBannedClient(uint32 dwIP){
m_bannedList.SetAt(dwIP, ::GetTickCount());
}
bool CClientList::IsBannedClient(uint32 dwIP) const
{
uint32 dwBantime;
if (m_bannedList.Lookup(dwIP, dwBantime)){
if (dwBantime + CLIENTBANTIME > ::GetTickCount())
return true;
//RemoveBannedClient(dwIP);
}
return false;
}
void CClientList::RemoveBannedClient(uint32 dwIP){
m_bannedList.RemoveKey(dwIP);
}
////////////////////////////////////////
/// Tracked clients
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -