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

📄 search.cpp

📁 非常难得的eMule(电骡) V0.45b 源码下载 值得研究
💻 CPP
📖 第 1 页 / 共 2 页
字号:
								prepareToStop();
								break;
							}
							CSafeMemFile bio(34);
							bio.WriteUInt128(&m_target);
							if( m_fileIDs.size() != 1)
								throw CString(_T("Kademlia.CSearch.processResponse: m_fileIDs.size() != 1"));
							bio.WriteUInt128(&m_fileIDs.front());
							bio.WriteUInt16(thePrefs.GetPort());
							CKademlia::getUDPListener()->sendPacket( &bio, KADEMLIA_FINDSOURCE_REQ, from->getIPAddress(), from->getUDPPort());
							m_count++;
							theApp.emuledlg->kademliawnd->searchList->SearchRef(this);
							break;
						}
					}
				}
			}
		}
	} 
	catch (...) 
	{
		AddDebugLogLine(false, _T("Exception in CSearch::processResponse"));
	}
	delete results;
}

void CSearch::processResult(uint32 fromIP, uint16 fromPort, const CUInt128 &answer, TagList *info)
{
	switch(m_type)
	{
		case FILE:
			processResultFile(fromIP, fromPort, answer, info);
			break;
		case KEYWORD:
			processResultKeyword(fromIP, fromPort, answer, info);
			break;
		case NOTES:
			processResultNotes(fromIP, fromPort, answer, info);
			break;
	}
	theApp.emuledlg->kademliawnd->searchList->SearchRef(this);
}

void CSearch::processResultFile(uint32 fromIP, uint16 fromPort, const CUInt128 &answer, TagList *info)
{
	CString temp;
	uint8  type = 0;
	uint32 ip = 0;
	uint16 tcp = 0;
	uint16 udp = 0;
	uint32 serverip = 0;
	uint16 serverport = 0;
	uint32 clientid = 0;
	uchar buddyhash[16];
	CUInt128 buddy;

	CTag *tag;
	TagList::const_iterator it;
	for (it = info->begin(); it != info->end(); it++)
	{
		tag = *it;
		if (!tag->m_name.Compare(TAG_SOURCETYPE))
			type		= tag->GetInt();
		else if (!tag->m_name.Compare(TAG_SOURCEIP))
			ip			= tag->GetInt();
		else if (!tag->m_name.Compare(TAG_SOURCEPORT))
			tcp			= tag->GetInt();
		else if (!tag->m_name.Compare(TAG_SOURCEUPORT))
			udp			= tag->GetInt();
		else if (!tag->m_name.Compare(TAG_SERVERIP))
			serverip	= tag->GetInt();
		else if (!tag->m_name.Compare(TAG_SERVERPORT))
			serverport	= tag->GetInt();
		else if (!tag->m_name.Compare(TAG_CLIENTLOWID))
			clientid	= tag->GetInt();
		else if (!tag->m_name.Compare(TAG_BUDDYHASH))
		{
			strmd4(CStringA(tag->GetStr()), buddyhash);
			md4cpy(buddy.getDataPtr(), buddyhash);
		}

		delete tag;
	}
	delete info;

	switch( type )
	{
		case 1:
		case 3:
		{
			m_count++;
			theApp.downloadqueue->KademliaSearchFile(m_searchID, &answer, &buddy, type, ip, tcp, udp, serverip, serverport, clientid);
			break;
		}
		case 2:
		{
			//Don't use this type, some clients will process it wrong..
			break;
		}
	}
}

void CSearch::processResultNotes(uint32 fromIP, uint16 fromPort, const CUInt128 &answer, TagList *info)
{
	CEntry* entry = new CEntry();
	entry->keyID.setValue(m_target);
	entry->sourceID.setValue(answer);

	CTag *tag;
	TagList::const_iterator it;
	for (it = info->begin(); it != info->end(); it++)
	{
		tag = *it;
		if (!tag->m_name.Compare(TAG_SOURCEIP))
		{
            entry->ip		= tag->GetInt();
			delete tag;
		}
		else if (!tag->m_name.Compare(TAG_SOURCEPORT))
		{
			entry->tcpport	= tag->GetInt();
			delete tag;
		}
		else if (!tag->m_name.Compare(TAG_FILENAME))
		{
			entry->fileName	= tag->GetStr();
			delete tag;
		}
		else if (!tag->m_name.Compare(TAG_DESCRIPTION))
			entry->taglist.push_front(tag);
		else if (!tag->m_name.Compare(TAG_FILERATING))
			entry->taglist.push_front(tag);
		else 
			delete tag;
	}
	delete info;
	uchar fileid[16];
	m_target.toByteArray(fileid);
	CKnownFile* file = theApp.sharedfiles->GetFileByID(fileid);
	if(!file)
		file = (CKnownFile*)theApp.downloadqueue->GetFileByID(fileid);

	if(file)
	{
		m_count++;
		file->AddNote(entry);
	}
}

void CSearch::processResultKeyword(uint32 fromIP, uint16 fromPort, const CUInt128 &answer, TagList *info)
{
	bool interested = false;
	CString name;
	uint32 size = 0;
	CString type;
	CString format;
	CString artist;
	CString album;
	CString title;
	uint32 length = 0;
	CString codec;
	uint32 bitrate = 0;
	uint32 availability = 0;

	CTag *tag;
	TagList::const_iterator it;
	for (it = info->begin(); it != info->end(); it++)
	{
		tag = *it;

		if (!tag->m_name.Compare(TAG_FILENAME))
		{
			name			= tag->GetStr();
			if( name != "" )
			{
				interested = true;
			}
		}
		else if (!tag->m_name.Compare(TAG_FILESIZE))
			size			= tag->GetInt();
		else if (!tag->m_name.Compare(TAG_FILETYPE))
			type			= tag->GetStr();
		else if (!tag->m_name.Compare(TAG_FILEFORMAT))
			format			= tag->GetStr();
		else if (!tag->m_name.Compare(TAG_MEDIA_ARTIST))
			artist			= tag->GetStr();
		else if (!tag->m_name.Compare(TAG_MEDIA_ALBUM))
			album			= tag->GetStr();
		else if (!tag->m_name.Compare(TAG_MEDIA_TITLE))
			title			= tag->GetStr();
		else if (!tag->m_name.Compare(TAG_MEDIA_LENGTH))
			length			= tag->GetInt();
		else if (!tag->m_name.Compare(TAG_MEDIA_BITRATE))
			bitrate			= tag->GetInt();
		else if (!tag->m_name.Compare(TAG_MEDIA_CODEC))
			codec			= tag->GetStr();
		else if (!tag->m_name.Compare(TAG_SOURCES))
		{
			availability	= tag->GetInt();
			if( availability > 65500 )
				availability = 0;
		}
		delete tag;
	}
	delete info;

	if( !interested )
		return;

	// Check that it matches original criteria
	// generally this is ok, but with the transition of Kad from ACP to Unicode we may receive 'wrong' results in the next months which are
	// actually not 'wrong' (don't ask for a detailed explanation)
	//WordList testWords;
	//CSearchManager::getWords(name.GetBuffer(0), &testWords);
	//
	//WordList::const_iterator mine;
	//WordList::const_iterator test;
	//CStringW keyword;
	//for (mine = m_words.begin(); mine != m_words.end(); mine++)
	//{
	//	keyword = *mine;
	//	interested = false;
	//	for (test = testWords.begin(); test != testWords.end(); test++)
	//	{
	//		if (!keyword.CompareNoCase(*test))
	//		{
	//			interested = true;
	//			break;
	//		}
	//	}
	//	if (!interested)
	//		return;
	//}

	if (interested)
	{
		m_count++;
		theApp.searchlist->KademliaSearchKeyword(m_searchID, &answer, name, size, type, 8, 
				2, TAG_FILEFORMAT, (LPCTSTR)format, 
				2, TAG_MEDIA_ARTIST, (LPCTSTR)artist, 
				2, TAG_MEDIA_ALBUM, (LPCTSTR)album, 
				2, TAG_MEDIA_TITLE, (LPCTSTR)title, 
				3, TAG_MEDIA_LENGTH, length, 
				3, TAG_MEDIA_BITRATE, bitrate, 
				2, TAG_MEDIA_CODEC, (LPCTSTR)codec, 
				3, TAG_SOURCES, availability);
	}
}

void CSearch::sendFindValue(const CUInt128 &check, uint32 ip, uint16 port)
{
	try
	{
		if(m_stoping)
			return;
		CSafeMemFile bio(33);
		switch(m_type){
			case NODE:
			case NODECOMPLETE:
				bio.WriteUInt8(KADEMLIA_FIND_NODE);
				break;
			case FILE:
			case KEYWORD:
			case FINDSOURCE:
			case NOTES:
				bio.WriteUInt8(KADEMLIA_FIND_VALUE);
				break;
			case FINDBUDDY:
			case STOREFILE:
			case STOREKEYWORD:
			case STORENOTES:
				bio.WriteUInt8(KADEMLIA_STORE);
				break;
			default:
				AddDebugLogLine(false, _T("Invalid search type. (CSearch::sendFindValue)"));
				return;
		}
		bio.WriteUInt128(&m_target);
		bio.WriteUInt128(&check);
		m_countSent++;
		theApp.emuledlg->kademliawnd->searchList->SearchRef(this);
		if (thePrefs.GetDebugClientKadUDPLevel() > 0)
		{
			switch(m_type)
			{
			case NODE:
				DebugSend("KadReqFindNode", ip, port);
				break;
			case NODECOMPLETE:
				DebugSend("KadReqFindNodeCompl", ip, port);
				break;
			case FILE:
				DebugSend("KadReqFindFile", ip, port);
				break;
			case KEYWORD:
				DebugSend("KadReqFindKeyw", ip, port);
				break;
			case STOREFILE:
				DebugSend("KadReqStoreFile", ip, port);
				break;
			case STOREKEYWORD:
				DebugSend("KadReqStoreKeyw", ip, port);
				break;
			case STORENOTES:
				DebugSend("KadReqStoreNotes", ip, port);
				break;
			case NOTES:
				DebugSend("KadReqNotes", ip, port);
				break;
			default:
				DebugSend("KadReqUnknown", ip, port);
			}
		}

		CKademlia::getUDPListener()->sendPacket(&bio, KADEMLIA_REQ, ip, port);
	} 
	catch ( CIOException *ioe )
	{
		AddDebugLogLine( false, _T("Exception in CSearch::sendFindValue (IO error(%i))"), ioe->m_cause);
		ioe->Delete();
	}
	catch (...) 
	{
		AddDebugLogLine(false, _T("Exception in CSearch::sendFindValue"));
	}
}

void CSearch::addFileID(const CUInt128& id)
{
	m_fileIDs.push_back(id);
}

void CSearch::PreparePacketForTags( CByteIO *bio, CKnownFile *file)
{
	try
	{
		if( file && bio )
		{
			TagList taglist;
			
			// Name, Size
			taglist.push_back(new CTagStr(TAG_FILENAME, file->GetFileName()));
			taglist.push_back(new CTagUInt(TAG_FILESIZE, file->GetFileSize()));
			taglist.push_back(new CTagUInt(TAG_SOURCES, (uint32)file->m_nCompleteSourcesCount));
			
			// eD2K file type (Audio, Video, ...)
			// NOTE: Archives and CD-Images are published with file type "Pro"
			CString strED2KFileType(GetED2KFileTypeSearchTerm(GetED2KFileTypeID(file->GetFileName())));
			if (!strED2KFileType.IsEmpty())
				taglist.push_back(new CTagStr(TAG_FILETYPE, strED2KFileType));
			
			// file format (filename extension)
			int iExt = file->GetFileName().ReverseFind(_T('.'));
			if (iExt != -1)
			{
				CString strExt(file->GetFileName().Mid(iExt));
				if (!strExt.IsEmpty())
				{
					strExt = strExt.Mid(1);
					if (!strExt.IsEmpty())
						taglist.push_back(new CTagStr(TAG_FILEFORMAT, strExt));
				}
			}

			// additional meta data (Artist, Album, Codec, Length, ...)
			// only send verified meta data to nodes
			if (file->GetMetaDataVer() > 0)
			{
				static const struct{
					uint8	nName;
					uint8	nType;
				} _aMetaTags[] = 
				{
					{ FT_MEDIA_ARTIST,  2 },
					{ FT_MEDIA_ALBUM,   2 },
					{ FT_MEDIA_TITLE,   2 },
					{ FT_MEDIA_LENGTH,  3 },
					{ FT_MEDIA_BITRATE, 3 },
					{ FT_MEDIA_CODEC,   2 }
				};
				for (int i = 0; i < ARRSIZE(_aMetaTags); i++)
				{
					const ::CTag* pTag = file->GetTag(_aMetaTags[i].nName, _aMetaTags[i].nType);
					if (pTag)
					{
						// skip string tags with empty string values
						if (pTag->IsStr() && pTag->GetStr().IsEmpty())
							continue;
						// skip integer tags with '0' values
						if (pTag->IsInt() && pTag->GetInt() == 0)
							continue;
						char szKadTagName[2];
						szKadTagName[0] = pTag->GetNameID();
						szKadTagName[1] = '\0';
						if (pTag->IsStr())
							taglist.push_back(new CTagStr(szKadTagName, pTag->GetStr()));
						else
							taglist.push_back(new CTagUInt(szKadTagName, pTag->GetInt()));
					}
				}
			}
			bio->writeTagList(taglist);
			TagList::const_iterator it;
			for (it = taglist.begin(); it != taglist.end(); it++)
				delete *it;
		}
		else
		{
			//If we get here.. Bad things happen.. Will fix this later if it is a real issue.
			ASSERT(0);
		}
	}
	catch ( CIOException *ioe )
	{
		AddDebugLogLine( false, _T("Exception in CSearch::PreparePacketForTags (IO error(%i))"), ioe->m_cause);
		ioe->Delete();
	}
	catch (...) 
	{
		AddDebugLogLine(false, _T("Exception in CSearch::PreparePacketForTags"));
	}
}

//Can't clean these up until Taglist works with CSafeMemFiles.
void CSearch::PreparePacket(void)
{
	try
	{
		int count = m_fileIDs.size();
		uchar fileid[16];
		CKnownFile* file = NULL;
		if( count > 150 )
			count = 150;
		if( count > 100 )
		{
			bio3 = new CByteIO(packet3,sizeof(packet3));
			bio3->writeByte(OP_KADEMLIAHEADER);
			bio3->writeByte(KADEMLIA_PUBLISH_REQ);
			bio3->writeUInt128(m_target);
			bio3->writeUInt16(count-100);
			while ( count > 100 )
			{
				count--;
				bio3->writeUInt128(m_fileIDs.front());
				m_fileIDs.front().toByteArray(fileid);
				m_fileIDs.pop_front();
				file = theApp.sharedfiles->GetFileByID(fileid);
				PreparePacketForTags( bio3, file );
			}
		}
		if( count > 50 )
		{
			bio2 = new CByteIO(packet2,sizeof(packet2));
			bio2->writeByte(OP_KADEMLIAHEADER);
			bio2->writeByte(KADEMLIA_PUBLISH_REQ);
			bio2->writeUInt128(m_target);
			bio2->writeUInt16(count-50);
			while ( count > 50 )
			{
				count--;
				bio2->writeUInt128(m_fileIDs.front());
				m_fileIDs.front().toByteArray(fileid);
				m_fileIDs.pop_front();
				file = theApp.sharedfiles->GetFileByID(fileid);
				PreparePacketForTags( bio2, file );
			}
		}
		if( count > 0 )
		{
			bio1 = new CByteIO(packet1,sizeof(packet1));
			bio1->writeByte(OP_KADEMLIAHEADER);
			bio1->writeByte(KADEMLIA_PUBLISH_REQ);
			bio1->writeUInt128(m_target);
			bio1->writeUInt16(count);
			while ( count > 0 )
			{
				count--;
				bio1->writeUInt128(m_fileIDs.front());
				m_fileIDs.front().toByteArray(fileid);
				m_fileIDs.pop_front();
				file = theApp.sharedfiles->GetFileByID(fileid);
				PreparePacketForTags( bio1, file );
			}
		}
	}
	catch ( CIOException *ioe )
	{
		AddDebugLogLine( false, _T("Exception in CSearch::PreparePacket (IO error(%i))"), ioe->m_cause);
		ioe->Delete();
	}
	catch (...) 
	{
		AddDebugLogLine(false, _T("Exception in CSearch::PreparePacket"));
	}
}

uint32 CSearch::getNodeLoad() const
{
	if( m_totalLoadResponses == 0 )
	{
		return 0;
	}
	return m_totalLoad/m_totalLoadResponses;
}

⌨️ 快捷键说明

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