📄 baseclient.cpp
字号:
uint32 dwIP;
uint16 nPort;
if (theApp.serverconnect->IsConnected()){
dwIP = theApp.serverconnect->GetCurrentServer()->GetIP();
nPort = theApp.serverconnect->GetCurrentServer()->GetPort();
#ifdef _DEBUG
if (dwIP == theApp.serverconnect->GetLocalIP()){
dwIP = 0;
nPort = 0;
}
#endif
}
else{
nPort = 0;
dwIP = 0;
}
data->WriteUInt32(dwIP);
data->WriteUInt16(nPort);
// data->WriteUInt32(dwIP); //The Hybrid added some bits here, what ARE THEY FOR?
}
void CUpDownClient::ProcessMuleCommentPacket(char* pachPacket, uint32 nSize){
if( reqfile ){
if( reqfile->IsPartFile()){
UINT length;
if (nSize>(sizeof(m_iRate)+sizeof(length)-1)){
CSafeMemFile data((BYTE*)pachPacket,nSize);
m_iRate = data.ReadUInt8();
length = data.ReadUInt32();
reqfile->SetHasRating(true);
if (thePrefs.GetLogRatingDescReceived())
AddDebugLogLine(false,GetResString(IDS_RATINGRECV),m_strClientFilename,m_iRate);
if ( length > data.GetLength() - data.GetPosition() ){
length = data.GetLength() - data.GetPosition();
}
if (length > MAXFILECOMMENTLEN)
length = MAXFILECOMMENTLEN;
if (length>0){
#ifdef _UNICODE
CStringA strCommentA;
data.Read(strCommentA.GetBuffer(length),length);
strCommentA.ReleaseBuffer(length);
m_strComment = strCommentA;
#else
data.Read(m_strComment.GetBuffer(length),length);
m_strComment.ReleaseBuffer(length);
#endif
if (thePrefs.GetLogRatingDescReceived())
AddDebugLogLine(false,GetResString(IDS_DESCRIPTIONRECV), m_strClientFilename, m_strComment);
reqfile->SetHasComment(true);
// test if comment is filtered
if (thePrefs.GetCommentFilter().GetLength()>0) {
CString resToken;
CString strlink=thePrefs.GetCommentFilter();
strlink.MakeLower();
int curPos=0;
resToken= strlink.Tokenize(_T("|"),curPos);
while (!resToken.IsEmpty()) {
if (m_strComment.MakeLower().Find(resToken)>-1) {
m_strComment.Empty();
m_iRate=0;
reqfile->SetHasRating(false);
reqfile->SetHasComment(false);
break;
}
resToken= strlink.Tokenize(_T("|"),curPos);
}
}
}
}
if (reqfile->HasRating() || reqfile->HasComment())
theApp.emuledlg->transferwnd->downloadlistctrl.UpdateItem(reqfile);
}
}
}
bool CUpDownClient::Disconnected(LPCTSTR pszReason, bool bFromSocket){
//If this is a KAD client object, just delete it!
ASSERT(theApp.clientlist->IsValidClient(this));
SetKadState(KS_NONE);
if (GetUploadState() == US_UPLOADING)
theApp.uploadqueue->RemoveFromUploadQueue(this, pszReason);
// 28-Jun-2004 [bc]: re-applied this patch which was in 0.30b-0.30e. it does not seem to solve the bug but
// it does not hurt either...
if (m_BlockRequests_queue.GetCount() > 0 || m_DoneBlocks_list.GetCount()){
// Although this should not happen, it seems(?) to happens sometimes. The problem we may run into here is as follows:
//
// 1.) If we do not clear the block send requests for that client, we will send those blocks next time the client
// gets an upload slot. But because we are starting to send any available block send requests right _before_ the
// remote client had a chance to prepare to deal with them, the first sent blocks will get dropped by the client.
// Worst thing here is, because the blocks are zipped and can therefore only be uncompressed when the first block
// was received, all of those sent blocks will create a lot of uncompress errors at the remote client.
//
// 2.) The remote client may have already received those blocks from some other client when it gets the next
// upload slot.
AddDebugLogLine(DLP_LOW, false, _T("***NOTE: Disconnected client with non empty block send queue; %s"), DbgGetClientInfo());
ClearUploadBlockRequests();
}
if (GetDownloadState() == DS_DOWNLOADING){
if (m_ePeerCacheDownState == PCDS_WAIT_CACHE_REPLY || m_ePeerCacheDownState == PCDS_DOWNLOADING)
theApp.m_pPeerCache->DownloadAttemptFailed();
if (thePrefs.GetLogUlDlEvents())
AddDebugLogLine(DLP_VERYLOW, false,_T("Download session ended. User: %s Reason: %s"), GetUserName(), pszReason);
SetDownloadState(DS_ONQUEUE);
}
else{
// ensure that all possible block requests are removed from the partfile
ClearDownloadBlockRequests();
if(GetDownloadState() == DS_CONNECTED){
// client didn't responsed to our request for some reasons (remotely banned?)
// or it just doesn't has this file, so try to swap first
if (!SwapToAnotherFile(_T("No response from client. CUpDownClient::Disconnected()"), true, true, true, NULL, false, false)){ // ZZ:DownloadManager
theApp.downloadqueue->RemoveSource(this);
//DEBUG_ONLY(AddDebugLogLine(false, "Removed %s from downloadqueue - didn't responsed to filerequests",GetUserName()));
}
}
}
// The remote client does not have to answer with OP_HASHSETANSWER *immediatly*
// after we've sent OP_HASHSETREQUEST. It may occure that a (buggy) remote client
// is sending use another OP_FILESTATUS which would let us change to DL-state to DS_ONQUEUE.
if (((GetDownloadState() == DS_REQHASHSET) || m_fHashsetRequesting) && (reqfile))
reqfile->hashsetneeded = true;
ASSERT(theApp.clientlist->IsValidClient(this));
//check if this client is needed in any way, if not delete it
bool bDelete = true;
switch(m_nUploadState){
case US_ONUPLOADQUEUE:
bDelete = false;
break;
};
switch(m_nDownloadState){
case DS_ONQUEUE:
case DS_TOOMANYCONNS:
case DS_NONEEDEDPARTS:
case DS_LOWTOLOWIP:
bDelete = false;
};
switch(m_nUploadState){
case US_CONNECTING:
if (thePrefs.GetLogUlDlEvents())
AddDebugLogLine(DLP_VERYLOW, true,_T("---- %s: Removing connecting client from upload list. Reason: %s ----"), GetUserName(), pszReason);
case US_WAITCALLBACK:
case US_ERROR:
bDelete = true;
};
switch(m_nDownloadState){
case DS_CONNECTING:
case DS_WAITCALLBACK:
case DS_ERROR:
bDelete = true;
};
if (GetChatState() != MS_NONE){
bDelete = false;
theApp.emuledlg->chatwnd->chatselector.ConnectingResult(this,false);
}
if (!bFromSocket && socket){
ASSERT (theApp.listensocket->IsValidSocket(socket));
socket->Safe_Delete();
}
socket = 0;
if (m_iFileListRequested){
AddLogLine(true,GetResString(IDS_SHAREDFILES_FAILED),GetUserName());
m_iFileListRequested = 0;
}
if (m_Friend)
theApp.friendlist->RefreshFriend(m_Friend);
theApp.emuledlg->transferwnd->clientlistctrl.RefreshClient(this);
if (bDelete){
if (thePrefs.GetDebugClientTCPLevel() > 0)
Debug(_T("--- Deleted client %s; Reason=%s\n"), DbgGetClientInfo(true), pszReason);
return true;
}
else{
if (thePrefs.GetDebugClientTCPLevel() > 0)
Debug(_T("--- Disconnected client %s; Reason=%s\n"), DbgGetClientInfo(true), pszReason);
m_fHashsetRequesting = 0;
SetSentCancelTransfer(0);
m_bHelloAnswerPending = false;
m_fQueueRankPending = 0;
m_fFailedFileIdReqs = 0;
m_fUnaskQueueRankRecv = 0;
m_uPeerCacheDownloadPushId = 0;
m_uPeerCacheUploadPushId = 0;
m_uPeerCacheRemoteIP = 0;
SetPeerCacheDownState(PCDS_NONE);
SetPeerCacheUpState(PCUS_NONE);
if (m_pPCDownSocket){
m_pPCDownSocket->client = NULL;
m_pPCDownSocket->Safe_Delete();
}
if (m_pPCUpSocket){
m_pPCUpSocket->client = NULL;
m_pPCUpSocket->Safe_Delete();
}
return false;
}
}
//Returned bool is not if the TryToConnect is successful or not..
//false means the client was deleted!
//true means the client was not deleted!
bool CUpDownClient::TryToConnect(bool bIgnoreMaxCon, CRuntimeClass* pClassSocket)
{
if (theApp.listensocket->TooManySockets() && !bIgnoreMaxCon && !(socket && socket->IsConnected()))
{
if(Disconnected(_T("Too many connections")))
{
delete this;
return false;
}
return true;
}
uint32 uClientIP = GetIP();
if (uClientIP == 0)
uClientIP = ntohl(m_nUserIDHybrid);
if (!IsLowID(uClientIP))
{
// although we filter all received IPs (server sources, source exchange) and all incomming connection attempts,
// we do have to filter outgoing connection attempts here too, because we may have updated the ip filter list
if (theApp.ipfilter->IsFiltered(uClientIP))
{
theApp.stat_filteredclients++;
if (thePrefs.GetLogFilteredIPs())
AddDebugLogLine(true, GetResString(IDS_IPFILTERED), ipstr(uClientIP), theApp.ipfilter->GetLastHit());
if (Disconnected(_T("IPFilter")))
{
delete this;
return false;
}
return true;
}
// for safety: check again whether that IP is banned
if (theApp.clientlist->IsBannedClient(uClientIP))
{
if (thePrefs.GetLogBannedClients())
AddDebugLogLine(false, _T("Refused to connect to banned client %s"), DbgGetClientInfo());
if (Disconnected(_T("Banned IP")))
{
delete this;
return false;
}
return true;
}
}
if( GetKadState() == KS_QUEUED_FWCHECK )
SetKadState(KS_CONNECTING_FWCHECK);
if ( HasLowID() && !theApp.DoCallback(this))
{
if (GetDownloadState() == DS_CONNECTING)
SetDownloadState(DS_LOWTOLOWIP);
else if (GetDownloadState() == DS_REQHASHSET)
{
SetDownloadState(DS_ONQUEUE);
reqfile->hashsetneeded = true;
}
if (GetUploadState() == US_CONNECTING)
{
if(Disconnected(_T("LowID->LowID and US_CONNECTING")))
{
delete this;
return false;
}
}
return true;
}
if (!socket || !socket->IsConnected())
{
if (socket)
socket->Safe_Delete();
if (pClassSocket == NULL)
pClassSocket = RUNTIME_CLASS(CClientReqSocket);
socket = static_cast<CClientReqSocket*>(pClassSocket->CreateObject());
socket->SetClient(this);
if (!socket->Create())
{
socket->Safe_Delete();
return true;
}
}
else
{
ConnectionEstablished();
return true;
}
// MOD Note: Do not change this part - Merkur
if (HasLowID())
{
if (GetDownloadState() == DS_CONNECTING)
SetDownloadState(DS_WAITCALLBACK);
if (GetUploadState() == US_CONNECTING)
{
if(Disconnected(_T("LowID and US_CONNECTING")))
{
delete this;
return false;
}
return true;
}
if (theApp.serverconnect->IsLocalServer(m_dwServerIP,m_nServerPort))
{
Packet* packet = new Packet(OP_CALLBACKREQUEST,4);
PokeUInt32(packet->pBuffer, m_nUserIDHybrid);
if (thePrefs.GetDebugServerTCPLevel() > 0)
DebugSend("OP__CallBackRequest", this);
theStats.AddUpDataOverheadServer(packet->size);
theApp.serverconnect->SendPacket(packet);
}
else
{
if (GetUploadState() == US_NONE && (!GetRemoteQueueRank() || m_bReaskPending) )
{
theApp.downloadqueue->RemoveSource(this);
if(Disconnected(_T("LowID and US_NONE and QR=0")))
{
delete this;
return false;
}
return true;
}
else
{
if (GetDownloadState() == DS_WAITCALLBACK)
{
m_bReaskPending = true;
SetDownloadState(DS_ONQUEUE);
}
}
}
}
// MOD Note - end
else
{
if (!Connect())
return false; // client was deleted!
}
return true;
}
bool CUpDownClient::Connect()
{
SOCKADDR_IN sockAddr = {0};
sockAddr.sin_family = AF_INET;
sockAddr.sin_port = htons(GetUserPort());
sockAddr.sin_addr.S_un.S_addr = GetConnectIP();
socket->Connect((SOCKADDR*)&sockAddr, sizeof sockAddr);
if (!SendHelloPacket())
return false; // client was deleted!
return true;
}
void CUpDownClient::ConnectionEstablished()
{
// ok we have a connection, lets see if we want anything from this client
// check if we should use this client to retrieve our public IP
if (theApp.GetPublicIP() == 0 && theApp.serverconnect->IsConnected() && m_fPeerCache)
SendPublicIPRequest();
switch(GetKadState())
{
case KS_CONNECTING_FWCHECK:
SetKadState(KS_CONNECTED_FWCHECK);
break;
case KS_QUEUED_BUDDY:
SetKadState(KS_CONNECTED_BUDDY);
break;
}
if (GetChatState() == MS_CONNECTING || GetChatState() == MS_CHATTING)
theApp.emuledlg->chatwnd->chatselector.ConnectingResult(this,true);
switch(GetDownloadState())
{
case DS_CONNECTING:
case DS_WAITCALLBACK:
m_bReaskPending = false;
SetDownloadState(DS_CONNECTED);
SendFileRequest();
}
if (m_bReaskPending)
{
m_bReaskPending = false;
if (GetDownloadState() != DS_NONE && GetDownloadState() != DS_DOWNLOADING)
{
SetDownloadState(DS_CONNECTED);
SendFileRequest();
}
}
switch(GetUploadState())
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -