⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 search.cpp

📁 电驴下载工具eMule0.47aVeryCD的源代码,可作分析测试也可用于P2P软件的开发研究.
💻 CPP
📖 第 1 页 / 共 3 页
字号:
				}
				else*/
				{
					m_pfileSearchTerms->WriteUInt128(&CKademlia::GetPrefs()->GetKadID());
					if (thePrefs.GetDebugClientKadUDPLevel() > 0)
						DebugSend("KADEMLIA_SEARCH_NOTES_REQ", pFromContact->GetIPAddress(), pFromContact->GetUDPPort());
					CKademlia::GetUDPListener()->SendPacket(m_pfileSearchTerms->GetBuffer(), (UINT)m_pfileSearchTerms->GetLength(), KADEMLIA_SEARCH_NOTES_REQ, pFromContact->GetIPAddress(), pFromContact->GetUDPPort());
				}
				// Inc total request answers
				m_uTotalRequestAnswers++;
				// Update search in the GUI
				theApp.emuledlg->kademliawnd->searchList->SearchRef(this);
				break;
			}
		case STOREFILE:
			{
				// Try to store yourself as a source to a Node.
				// As a safe guard, check to see if we already stored to the Max Nodes
				if( m_uAnswers > SEARCHSTOREFILE_TOTAL )
				{
					PrepareToStop();
					break;
				}

				// Find the file we are trying to store as a source too.
				uchar ucharFileid[16];
				m_uTarget.ToByteArray(ucharFileid);
				CKnownFile* pFile = theApp.sharedfiles->GetFileByID(ucharFileid);

				if (pFile)
				{
					// We set this mostly for GUI resonse.
					m_sFileName = pFile->GetFileName();

					// Get our clientID for the packet.
					CUInt128 uID(CKademlia::GetPrefs()->GetClientHash());

					//We can use type for different types of sources.
					//1 HighID Sources..
					//2 cannot be used as older clients will not work.
					//3 Firewalled Kad Source.
					//4 >4GB file HighID Source.
					//5 >4GB file Firewalled Kad source.

					TagList listTag;
					if( theApp.IsFirewalled() )
					{
						// We are firewalled, make sure we have a buddy.
						if( theApp.clientlist->GetBuddy() )
						{
							// We send the ID to our buddy so they can do a callback.
							CUInt128 uBuddyID(true);
							uBuddyID.Xor(CKademlia::GetPrefs()->GetKadID());
							if(pFile->GetFileSize() > OLD_MAX_EMULE_FILE_SIZE)
								listTag.push_back(new CKadTagUInt8(TAG_SOURCETYPE, 5));
							else
								listTag.push_back(new CKadTagUInt8(TAG_SOURCETYPE, 3));
							listTag.push_back(new CKadTagUInt(TAG_SERVERIP, theApp.clientlist->GetBuddy()->GetIP()));
							listTag.push_back(new CKadTagUInt(TAG_SERVERPORT, theApp.clientlist->GetBuddy()->GetUDPPort()));
							listTag.push_back(new CKadTagStr(TAG_BUDDYHASH, CStringW(md4str(uBuddyID.GetData()))));
							listTag.push_back(new CKadTagUInt(TAG_SOURCEPORT, thePrefs.GetPort()));
						}
						else if(theVnnCtrl.IsConnected())
						{
							CUInt128 uBuddyID(true);
							uBuddyID.Xor(CKademlia::GetPrefs()->GetKadID());
							if(pFile->GetFileSize() > OLD_MAX_EMULE_FILE_SIZE)
								listTag.push_back(new CKadTagUInt8(TAG_SOURCETYPE, 5));
							else
								listTag.push_back(new CKadTagUInt8(TAG_SOURCETYPE, 3));
							
							listTag.push_back(new CKadTagUInt(TAG_SOURCEPORT, thePrefs.GetPort()));
						}
						else
						{
							PrepareToStop();
							break;
						}
					}
					else
					{
						// We are not firewalled..
						if(pFile->GetFileSize() > OLD_MAX_EMULE_FILE_SIZE)
							listTag.push_back(new CKadTagUInt(TAG_SOURCETYPE, 4));
						else
							listTag.push_back(new CKadTagUInt(TAG_SOURCETYPE, 1));
						listTag.push_back(new CKadTagUInt(TAG_SOURCEPORT, thePrefs.GetPort()));
						/*if(bKad2)
						{
							listTag.push_back(new CKadTagUInt(TAG_FILESIZE, pFile->GetFileSize()));
						}*/
					}

					// Send packet
					CKademlia::GetUDPListener()->SendPublishSourcePacket(pFromContact->GetIPAddress(), pFromContact->GetUDPPort(),m_uTarget,uID, listTag);
					// Inc total request answers
					m_uTotalRequestAnswers++;
					// Update search in the GUI
					theApp.emuledlg->kademliawnd->searchList->SearchRef(this);
					// Delete all tags.
					for (TagList::const_iterator itTagList = listTag.begin(); itTagList != listTag.end(); ++itTagList)
						delete *itTagList;
				}
				break;
			}
		case STOREKEYWORD:
			{
				//JOHNTODO -- We cannot precreate these packets as we do not know
				// before hand if we are talking to Kad1.0 or Kad2.0..

				// Try to store keywords to a Node.
				// As a safe guard, check to see if we already stored to the Max Nodes
				if( m_uAnswers > SEARCHSTOREKEYWORD_TOTAL )
				{
					PrepareToStop();
					break;
				}

				// The store can be up to 3 packets, 50 keywords each.
				if( pbyIO1 )
				{
					if (thePrefs.GetDebugClientKadUDPLevel() > 0)
						DebugSend("KADEMLIA_PUBLISH_REQ(packet1)", pFromContact->GetIPAddress(), pFromContact->GetUDPPort());
					CKademlia::GetUDPListener()->SendPacket( byPacket1, ((1024*50)-pbyIO1->GetAvailable()), pFromContact->GetIPAddress(), pFromContact->GetUDPPort() );
				}
				if( pbyIO2 )
				{
					if (thePrefs.GetDebugClientKadUDPLevel() > 0)
						DebugSend("KADEMLIA_PUBLISH_REQ(packet2)", pFromContact->GetIPAddress(), pFromContact->GetUDPPort());
					CKademlia::GetUDPListener()->SendPacket( byPacket2, ((1024*50)-pbyIO2->GetAvailable()), pFromContact->GetIPAddress(), pFromContact->GetUDPPort() );
				}
				if( pbyIO3 )
				{
					if (thePrefs.GetDebugClientKadUDPLevel() > 0)
						DebugSend("KADEMLIA_PUBLISH_REQ(packet3)", pFromContact->GetIPAddress(), pFromContact->GetUDPPort());
					CKademlia::GetUDPListener()->SendPacket( byPacket3, ((1024*50)-pbyIO3->GetAvailable()), pFromContact->GetIPAddress(), pFromContact->GetUDPPort() );
				}
				// Inc total request answers
				m_uTotalRequestAnswers++;
				// Update search in the GUI
				theApp.emuledlg->kademliawnd->searchList->SearchRef(this);
				break;
			}
		case STORENOTES:
			{
				// JOHNTODO - Need to add Kad2.0 support

				// Find file we are storing info about.
				uchar ucharFileid[16];
				m_uTarget.ToByteArray(ucharFileid);
				CKnownFile* pFile = theApp.sharedfiles->GetFileByID(ucharFileid);

				if (pFile)
				{
					byte byPacket[1024*2];
					CByteIO byIO(byPacket,sizeof(byPacket));

					// Send the Hash of the file we are storing info about.
					byIO.WriteUInt128(m_uTarget);
					// Send our ID with the info.
					byIO.WriteUInt128(CKademlia::GetPrefs()->GetKadID());

					// Create our taglist
					TagList listTag;
					listTag.push_back(new CKadTagStr(TAG_FILENAME, pFile->GetFileName()));
					if(pFile->GetFileRating() != 0)
						listTag.push_back(new CKadTagUInt(TAG_FILERATING, pFile->GetFileRating()));
					if(pFile->GetFileComment() != "")
						listTag.push_back(new CKadTagStr(TAG_DESCRIPTION, pFile->GetFileComment()));
					byIO.WriteTagList(listTag);

					// Send packet
					CKademlia::GetUDPListener()->SendPacket( byPacket, sizeof(byPacket)-byIO.GetAvailable(), KADEMLIA_PUBLISH_NOTES_REQ, pFromContact->GetIPAddress(), pFromContact->GetUDPPort());
					// Inc total request answers
					m_uTotalRequestAnswers++;
					// Update search in the GUI
					theApp.emuledlg->kademliawnd->searchList->SearchRef(this);
					// Delete all tags.
					for (TagList::const_iterator itTagList = listTag.begin(); itTagList != listTag.end(); ++itTagList)
						delete *itTagList;
				}
				break;
			}
		case FINDBUDDY:
			{
				// Send a buddy request as we are firewalled.
				// As a safe guard, check to see if we already requested the Max Nodes
				if( m_uAnswers > SEARCHFINDBUDDY_TOTAL )
				{
					PrepareToStop();
					break;
				}
				// Do a keyword/source search request to this Node.
				if (thePrefs.GetDebugClientKadUDPLevel() > 0)
				{
					DebugSend("KADEMLIA_FINDBUDDY_REQ", pFromContact->GetIPAddress(), pFromContact->GetUDPPort());
				}
				// Send packet
				CKademlia::GetUDPListener()->SendPacket(m_pfileSearchTerms->GetBuffer(), (UINT)m_pfileSearchTerms->GetLength(), KADEMLIA_FINDBUDDY_REQ, pFromContact->GetIPAddress(), pFromContact->GetUDPPort());
				// Inc total request answers
				m_uAnswers++;
				// Update search in the GUI
				theApp.emuledlg->kademliawnd->searchList->SearchRef(this);
				break;
			}
		case FINDSOURCE:
			{
				// Try to find if this is a buddy to someone we want to contact.
				// As a safe guard, check to see if we already requested the Max Nodes
				if( m_uAnswers > SEARCHFINDSOURCE_TOTAL )
				{
					PrepareToStop();
					break;
				}

				CSafeMemFile fileIO(34);
				// This is the ID the the person we want to contact used to find a buddy.
				fileIO.WriteUInt128(&m_uTarget);
				if( m_listFileIDs.size() != 1)
					throw CString(_T("Kademlia.CSearch.ProcessResponse: m_listFileIDs.size() != 1"));
				// Currently, we limit they type of callbacks for sources.. We must know a file it person has for it to work.
				fileIO.WriteUInt128(&m_listFileIDs.front());
				// Send our port so the callback works.
				fileIO.WriteUInt16(thePrefs.GetPort());
				// Send packet
				CKademlia::GetUDPListener()->SendPacket( &fileIO, KADEMLIA_CALLBACK_REQ, pFromContact->GetIPAddress(), pFromContact->GetUDPPort());
				// Inc total request answers
				m_uAnswers++;
				// Update search in the GUI
				theApp.emuledlg->kademliawnd->searchList->SearchRef(this);
				break;
			}
	}
}

void CSearch::ProcessResult(const CUInt128 &uAnswer, TagList *plistInfo)
{
	// We received a result, process it based on type.
	switch(m_uType)
	{
		case FILE:
			ProcessResultFile(uAnswer, plistInfo);
			break;
		case KEYWORD:
			ProcessResultKeyword(uAnswer, plistInfo);
			break;
		case NOTES:
			ProcessResultNotes(uAnswer, plistInfo);
			break;
	}
	// Update search for the GUI
	theApp.emuledlg->kademliawnd->searchList->SearchRef(this);
}

void CSearch::ProcessResultFile(const CUInt128 &uAnswer, TagList *plistInfo)
{
	// Process a possible source to a file.
	// Set of data we could receive from the result.
	uint8 uType = 0;
	uint32 uIP = 0;
	uint16 uTCPPort = 0;
	uint16 uUDPPort = 0;
	uint32 uServerIP = 0;
	uint16 uServerPort = 0;
	//    uint32 uClientID = 0;
	uchar ucharBuddyHash[16];
	CUInt128 uBuddy;

	for (TagList::const_iterator itTagList = plistInfo->begin(); itTagList != plistInfo->end(); ++itTagList)
	{
		CKadTag* pTag = *itTagList;
		if (!pTag->m_name.Compare(TAG_SOURCETYPE))
			uType = (uint8)pTag->GetInt();
		else if (!pTag->m_name.Compare(TAG_SOURCEIP))
			uIP = (uint32)pTag->GetInt();
		else if (!pTag->m_name.Compare(TAG_SOURCEPORT))
			uTCPPort = (uint16)pTag->GetInt();
		else if (!pTag->m_name.Compare(TAG_SOURCEUPORT))
			uUDPPort = (uint16)pTag->GetInt();
		else if (!pTag->m_name.Compare(TAG_SERVERIP))
			uServerIP = (uint32)pTag->GetInt();
		else if (!pTag->m_name.Compare(TAG_SERVERPORT))
			uServerPort = (uint16)pTag->GetInt();
		//        else if (!pTag->m_name.Compare(TAG_CLIENTLOWID))
		//            uClientID = pTag->GetInt();
		else if (!pTag->m_name.Compare(TAG_BUDDYHASH))
		{
			strmd4(pTag->GetStr(), ucharBuddyHash);
			md4cpy(uBuddy.GetDataPtr(), ucharBuddyHash);
		}

		delete pTag;
	}
	delete plistInfo;

	// Process source based on it's type. Currently only one method is needed to process all types.
	switch( uType )
	{
		case 1:
		case 3:
		case 4:
		case 5:
			m_uAnswers++;
			theApp.emuledlg->kademliawnd->searchList->SearchRef(this);
			theApp.downloadqueue->KademliaSearchFile(m_uSearchID, &uAnswer, &uBuddy, uType, uIP, uTCPPort, uUDPPort, uServerIP, uServerPort);
			break;
	}
}

void CSearch::ProcessResultNotes(const CUInt128 &uAnswer, TagList *plistInfo)
{
	// Process a received Note to a file.
	// Create a Note and set the ID's.
	CEntry* pEntry = new CEntry();
	pEntry->m_uKeyID.SetValue(m_uTarget);
	pEntry->m_uSourceID.SetValue(uAnswer);
	// Create flag to determine if we keep this note.
	bool bFilterComment = false;

	// Loops through tags and pull wanted into. Currently we only keep Filename, Rating, Comment.
	for (TagList::const_iterator itTagList = plistInfo->begin(); itTagList != plistInfo->end(); ++itTagList)
	{
		CKadTag* pTag = *itTagList;
		if (!pTag->m_name.Compare(TAG_SOURCEIP))
		{
			pEntry->m_uIP = (uint32)pTag->GetInt();
			delete pTag;
		}
		else if (!pTag->m_name.Compare(TAG_SOURCEPORT))
		{
			pEntry->m_uTCPPort = (uint16)pTag->GetInt();
			delete pTag;
		}
		else if (!pTag->m_name.Compare(TAG_FILENAME))
		{
			pEntry->m_fileName = pTag->GetStr();
			delete pTag;
		}
		else if (!pTag->m_name.Compare(TAG_DESCRIPTION))
		{
			pEntry->m_listTag.push_front(pTag);

			// Test if comment sould be filtered
			if (!thePrefs.GetCommentFilter().IsEmpty())
			{
				CString strCommentLower(pTag->GetStr());
				strCommentLower.MakeLower();

				int iPos = 0;
				CString strFilter(thePrefs.GetCommentFilter().Tokenize(_T("|"), iPos));
				while (!strFilter.IsEmpty())
				{
					// comment filters are already in lowercase, compare with temp. lowercased received comment
					if (strCommentLower.Find(strFilter) >= 0)
					{
						bFilterComment = true;
						break;
					}
					strFilter = thePrefs.GetCommentFilter().Tokenize(_T("|"), iPos);
				}
			}
		}
		else if (!pTag->m_name.Compare(TAG_FILERATING))
			pEntry->m_listTag.push_front(pTag);
		else
			delete pTag;
	}
	delete plistInfo;

	// If we think this should be filtered, delete the note.
	if(bFilterComment)
	{
		delete pEntry;
		return;
	}

	uchar ucharFileid[16];
	m_uTarget.ToByteArray(ucharFileid);

	// Add notes to any searches we have done.
	// The returned entry object will never be attached
	// to anything. So you can delete the entry object
	// at any time after this call..
	bool bFlag = theApp.searchlist->AddNotes(pEntry, ucharFileid);

	// Check if this hash is in our shared files..
	CAbstractFile* pFile = (CAbstractFile*)theApp.sharedfiles->GetFileByID(ucharFileid);

	// If we didn't find a file in the shares check if it's in our download queue.
	if(!pFile)
		pFile = (CAbstractFile*)theApp.downloadqueue->GetFileByID(ucharFileid);

	// If we found a file try to add the Note to the file.
	if( pFile && pFile->AddNote(pEntry) )
	{
		// Inc the number of answers.
		m_uAnswers++;
		// Update the search in the GUI
		theApp.emuledlg->kademliawnd->searchList->SearchRef(this);
		// We do note delete the NOTE in this case.
		return;
	}

	// It is possible that pFile->AddNote can fail even if we found a File.
	if (bFlag)
	{
		// Inc the number of answers.
		m_uAnswers++;
		// Update the search in the GUI
		theApp.emuledlg->kademliawnd->searchList->SearchRef(this);
	}

	// We always delete the entry object if pFile->AddNote fails..
	delete pEntry;
}

void CSearch::ProcessResultKeyword(const CUInt128 &uAnswer, TagList *plistInfo)
{
	// Process a keyword that we received.
	// Set of data we can use for a keyword result
	CString sName;
	uint64 uSize = 0;
	CString sType;
	CString sFormat;
	CString sArtist;
	CString sAlbum;
	CString sTitle;
	uint32 uLength = 0;
	CString sCodec;
	uint32 uBitrate = 0;
	uint32 uAvailability = 0;
	// Flag that is set if we want this keyword.
	bool bFileName = false;
	bool bFileSize = false;

	for (TagList::const_iterator itTagList = plistInfo->begin(); itTagList != plistInfo->end(); ++itTagList)
	{
		CKadTag* pTag = *itTagList;

		if (!pTag->m_name.Compare(TAG_FILENAME))
		{
			// Set flag based on last tag we saw.
			sName = pTag->GetStr();
			if( sName != "" )
				bFileName = true;
			else
				bFileName = false;
		}
		else if (!pTag->m_name.Compare(TAG_FILESIZE))
		{
			if(pTag->IsBsob() && pTag->GetBsobSize() == 8)
				uSize = *((uint64*)pTag->GetBsob());
			else
				uSize = pTag->GetInt();

			// Set flag based on last tag we saw.
			if(uSize)
				bFileSize = true;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -