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

📄 search.cpp

📁 一个关于电驴的源码,大家有需要可以下载
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	switch(m_type)
	{
		case FILE:
			processResultFile(target, fromIP, fromPort, answer, info);
			break;
		case KEYWORD:
			processResultKeyword(target, fromIP, fromPort, answer, info);
			break;
	}
	theApp.emuledlg->kademliawnd->searchList->SearchRef(this);
}

void CSearch::processResultFile(const CUInt128 &target, 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;
	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();

		delete tag;
	}
	delete info;

	switch( type )
	{
		case 1:
		{
			m_count++;
			theApp.downloadqueue->KademliaSearchFile(m_searchID, &answer, type, ip, tcp, udp, serverip, serverport, clientid);
			break;
		}
/*		case 2:
		{
			//Don't use this type, some clients will process it wrong..
			break;
		}
		case 3:
		{
			//This will be a firewaled client connected to Kad only.
			break;
		}
*/	}
}

void CSearch::processResultKeyword(const CUInt128 &target, 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_NAME))
		{
			name			= tag->GetStr();
			if( name != "" )
			{
				interested = true;
			}
		}
		else if (!tag->m_name.Compare(TAG_SIZE))
			size			= tag->GetInt();
		else if (!tag->m_name.Compare(TAG_TYPE))
			type			= tag->GetStr();
		else if (!tag->m_name.Compare(TAG_FORMAT))
			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_AVAILABILITY))
		{
			availability	= tag->GetInt();
			if( availability > 65500 )
				availability = 0;
		}
		delete tag;
	}
	delete info;

	if( !interested )
		return;

	// Check that it matches original criteria
	WordList testWords;
	CSearchManager::getWords(name.GetBuffer(0), &testWords);
	
	WordList::const_iterator mine;
	WordList::const_iterator test;
	CString keyword;
	for (mine = m_words.begin(); mine != m_words.end(); mine++)
	{
		keyword = *mine;
		if (keyword.GetAt(0) == '-')
		{
			if (type.CompareNoCase(keyword.GetBuffer(0) + 1))
			{
				interested = false;
				break;
			}
		}
		else
		{
			interested = false;
			for (test = testWords.begin(); test != testWords.end(); test++)
			{
				if (!keyword.CompareNoCase(*test))
				{
					interested = true;
					break;
				}
			}
		}
		if (!interested)
			return;
	}

	if (interested)
	{
		m_count++;
		if (format.GetLength() == 0)
		{
			theApp.searchlist->KademliaSearchKeyword(m_searchID, &answer, name.GetBuffer(0), size, type.GetBuffer(0), 0);
		}
		else if (length != 0 || !codec.IsEmpty() || bitrate != 0)
		{
			theApp.searchlist->KademliaSearchKeyword(m_searchID, &answer, name.GetBuffer(0), size, type.GetBuffer(0), 8, 
					2, TAG_FORMAT, format.GetBuffer(0), 
					2, TAG_MEDIA_ARTIST, artist, 
					2, TAG_MEDIA_ALBUM, album, 
					2, TAG_MEDIA_TITLE, title, 
					3, TAG_MEDIA_LENGTH, length, 
					3, TAG_MEDIA_BITRATE, bitrate, 
					2, TAG_MEDIA_CODEC, codec, 
					3, TAG_AVAILABILITY, availability);
		}
		else if ((!type.Compare("Image")) && (artist.GetLength() > 0))
		{
			theApp.searchlist->KademliaSearchKeyword(m_searchID, &answer, name.GetBuffer(0), size, type.GetBuffer(0), 3, 
					2, TAG_FORMAT, format.GetBuffer(0), 
					2, TAG_MEDIA_ARTIST, artist, 
					3, TAG_AVAILABILITY, availability);
		}
		else
		{
			theApp.searchlist->KademliaSearchKeyword(m_searchID, &answer, name.GetBuffer(0), size, type.GetBuffer(0), 2, 
					2, TAG_FORMAT, format.GetBuffer(0), 
					3, TAG_AVAILABILITY, availability);
		}
	}
}

void CSearch::sendFindValue(const CUInt128 &target, 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:
				bio.WriteUInt8(KADEMLIA_FIND_VALUE);
				break;
			case STOREFILE:
			case STOREKEYWORD:
				bio.WriteUInt8(KADEMLIA_STORE);
				break;
			default:
				CKademlia::debugLine("Invalid search type. (CSearch::sendFindValue)");
				return;
		}
		bio.WriteUInt128(&target);
		bio.WriteUInt128(&check);
//		CKademlia::debugMsg("Sent UDP OpCode KADEMLIA_REQUEST(%u)", ip);
		CKademliaUDPListener *udpListner = CKademlia::getUDPListener();
		ASSERT(udpListner != NULL); 
		m_countSent++;
		theApp.emuledlg->kademliawnd->searchList->SearchRef(this);
		if (thePrefs.GetDebugClientKadUDPLevel() > 0)
		{
			if (m_type == NODE)
				DebugSend("KadReqFindNode", ip, port);
			else if (m_type == NODECOMPLETE)
				DebugSend("KadReqFindNodeCompl", ip, port);
			else if (m_type == FILE)
				DebugSend("KadReqFindFile", ip, port);
			else if (m_type == KEYWORD)
				DebugSend("KadReqFindKeyw", ip, port);
			else if (m_type == STOREFILE)
				DebugSend("KadReqStoreFile", ip, port);
			else
				DebugSend("KadReqStoreKeyw", ip, port);
		}

		udpListner->sendPacket(&bio, KADEMLIA_REQ, ip, port);
	} 
	catch ( CIOException *ioe )
	{
		CKademlia::debugMsg("Exception in CSearch::sendFindValue (IO error(%i))", ioe->m_cause);
		ioe->Delete();
	}
	catch (...) 
	{
		CKademlia::debugLine("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_NAME, file->GetFileName()));
			taglist.push_back(new CTagUInt(TAG_SIZE, file->GetFileSize()));
			taglist.push_back(new CTagUInt(TAG_AVAILABILITY, (uint32)file->m_nCompleteSourcesCount));
			
			// eD2K file type (Audio, Video, ...)
			CString strED2KFileType(GetED2KFileTypeSearchTerm(GetED2KFileTypeID(file->GetFileName())));
			if (!strED2KFileType.IsEmpty())
				taglist.push_back(new CTagStr(TAG_TYPE, 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_FORMAT, 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->tag.type == 2 && (pTag->tag.stringvalue == NULL || pTag->tag.stringvalue[0] == '\0'))
							continue;
						// skip integer tags with '0' values
						if (pTag->tag.type == 3 && pTag->tag.intvalue == 0)
							continue;
						char szKadTagName[2];
						szKadTagName[0] = pTag->tag.specialtag;
						szKadTagName[1] = '\0';
						if (pTag->tag.type == 2)
							taglist.push_back(new CTagStr(szKadTagName, pTag->tag.stringvalue));
						else
							taglist.push_back(new CTagUInt(szKadTagName, pTag->tag.intvalue));
					}
				}
			}
			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 )
	{
		CKademlia::debugMsg("Exception in CSearch::PreparePacketForTags (IO error(%i))", ioe->m_cause);
		ioe->Delete();
	}
	catch (...) 
	{
		CKademlia::debugLine("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 )
	{
		CKademlia::debugMsg("Exception in CSearch::PreparePacket (IO error(%i))", ioe->m_cause);
		ioe->Delete();
	}
	catch (...) 
	{
		CKademlia::debugLine("Exception in CSearch::PreparePacket");
	}
}

⌨️ 快捷键说明

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