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

📄 searchlist.cpp

📁 另外一款开放源码的高质量p2p源码软件
💻 CPP
📖 第 1 页 / 共 2 页
字号:
				Debug(_T("*** NOTE: Client ProcessSearchanswer(%s): ***AddData: 1 byte: 0x%02x\n"), Sender->GetUserName(), ucMore);
		}
	}
	else if (iAddData > 0){
		if (thePrefs.GetDebugClientTCPLevel() > 0){
			Debug(_T("*** NOTE: Client ProcessSearchanswer(%s): ***AddData: %u bytes\n"), Sender->GetUserName(), iAddData);
			DebugHexDump((uint8*)in_packet + packet.GetPosition(), iAddData);
		}
	}

	packet.Close();
	return GetResultCount(nSearchID);
}

uint16 CSearchList::ProcessSearchanswer(char* in_packet, uint32 size, 
										uint32 nServerIP, uint16 nServerPort, bool* pbMoreResultsAvailable)
{
	CSafeMemFile packet((BYTE*)in_packet,size);
	UINT results = packet.ReadUInt32();
	for (UINT i = 0; i < results; i++){
		CSearchFile* toadd = new CSearchFile(&packet, m_nCurrentSearch);
		toadd->SetClientServerIP(nServerIP);
		toadd->SetClientServerPort(nServerPort);
		if (nServerIP && nServerPort){
			CSearchFile::SServer server(nServerIP, nServerPort);
			server.m_uAvail = toadd->GetIntTagValue(FT_SOURCES);
			toadd->AddServer(server);
		}
		AddToList(toadd, false);
	}
	if (m_MobilMuleSearch)
		theApp.mmserver->SearchFinished(false);
	m_MobilMuleSearch = false;

	if (pbMoreResultsAvailable)
		*pbMoreResultsAvailable = false;
	int iAddData = (int)(packet.GetLength() - packet.GetPosition());
	if (iAddData == 1){
		uint8 ucMore = packet.ReadUInt8();
		if (ucMore == 0x00 || ucMore == 0x01){
			if (pbMoreResultsAvailable)
				*pbMoreResultsAvailable = (bool)ucMore;
			if (thePrefs.GetDebugServerTCPLevel() > 0)
				Debug(_T("  Search answer(Server %s:%u): More=%u\n"), ipstr(nServerIP), nServerPort, ucMore);
		}
		else{
			if (thePrefs.GetDebugServerTCPLevel() > 0)
				Debug(_T("*** NOTE: ProcessSearchanswer(Server %s:%u): ***AddData: 1 byte: 0x%02x\n"), ipstr(nServerIP), nServerPort, ucMore);
		}
	}
	else if (iAddData > 0){
		if (thePrefs.GetDebugServerTCPLevel() > 0){
			Debug(_T("*** NOTE: ProcessSearchanswer(Server %s:%u): ***AddData: %u bytes\n"), ipstr(nServerIP), nServerPort, iAddData);
			DebugHexDump((uint8*)in_packet + packet.GetPosition(), iAddData);
		}
	}

	packet.Close();
	return GetResultCount();
}

uint16 CSearchList::ProcessUDPSearchanswer(CFileDataIO& packet, uint32 nServerIP, uint16 nServerPort)
{
	CSearchFile* toadd = new CSearchFile(&packet, m_nCurrentSearch, nServerIP, nServerPort);
	AddToList(toadd);
	return GetResultCount();
}

uint16 CSearchList::GetResultCount(uint32 nSearchID) const
{
	uint16 nSources = 0;
	VERIFY( m_foundSourcesCount.Lookup(nSearchID, nSources) );
	return nSources;
}

uint16 CSearchList::GetResultCount() const {
	return GetResultCount(m_nCurrentSearch);
}

CString CSearchList::GetWebList(CString linePattern,int sortby,bool asc) const {
	CString buffer;
	CString temp;
	CArray<CSearchFile*, CSearchFile*> sortarray;
	int swap = 0;
	bool inserted;

	// insertsort
	CSearchFile* sf1;
	CSearchFile* sf2;
	for (POSITION pos = list.GetHeadPosition(); pos !=0;) {
		inserted=false;
		sf1 = list.GetNext(pos);
		
		if (sf1->GetListParent()!=NULL) continue;
		
		for (uint16 i1=0;i1<sortarray.GetCount();++i1) {
			sf2 = sortarray.GetAt(i1);
			
			switch (sortby) {
				case 0: swap=sf1->GetFileName().CompareNoCase(sf2->GetFileName()); break;
				case 1: swap=sf1->GetFileSize()-sf2->GetFileSize();break;
				case 2: swap=CString(sf1->GetFileHash()).CompareNoCase(CString(sf2->GetFileHash())); break;
				case 3: swap=sf1->GetSourceCount()-sf2->GetSourceCount(); break;
			}
			if (!asc) swap=0-swap;
			if (swap<0) {inserted=true; sortarray.InsertAt(i1,sf1);break;}
		}
		if (!inserted) sortarray.Add(sf1);
	}
	
	for (uint16 i=0;i<sortarray.GetCount();++i) {
		const CSearchFile* sf = sortarray.GetAt(i);

		// colorize
		CString coloraddon;
		CString coloraddonE;
		CKnownFile* sameFile = theApp.sharedfiles->GetFileByID(sf->GetFileHash());
		if (!sameFile)
			sameFile = theApp.downloadqueue->GetFileByID(sf->GetFileHash());

		if (sameFile) {
			if (sameFile->IsPartFile())
				coloraddon = _T("<font color=\"#FF0000\">");
			else
				coloraddon = _T("<font color=\"#00FF00\">");
		}
		if (coloraddon.GetLength()>0)
			coloraddonE = _T("</font>");

		CString strHash(EncodeBase16(sf->GetFileHash(),16));
		temp.Format(linePattern,
					coloraddon + StringLimit(sf->GetFileName(),70) + coloraddonE,
					CastItoXBytes(sf->GetFileSize()),
					strHash,
					sf->GetSourceCount(),
					strHash);
		buffer.Append(temp);
	}
	return buffer;
}

void CSearchList::AddFileToDownloadByHash(const uchar* hash, uint8 cat)
{
	for (POSITION pos = list.GetHeadPosition(); pos != 0; )
	{
		CSearchFile* sf = list.GetNext(pos);
		if (!md4cmp(hash, sf->GetFileHash()))
		{
			theApp.downloadqueue->AddSearchToDownload(sf, 2, cat);
			break;
		}
	}
}

// mobilemule

CSearchFile* CSearchList::DetachNextFile(uint32 nSearchID) {
	// the files are NOT deleted, make sure you do this if you call this function
	// find, removes and returns the searchresult with most Sources	
	uint32 nHighSource = 0;
	POSITION resultpos = 0;
	for (POSITION pos = list.GetHeadPosition(); pos != NULL; ){
		POSITION cur_pos = pos;
		CSearchFile* cur_file = list.GetNext(pos);
		if( cur_file->GetSearchID() == nSearchID ){
			if(cur_file->GetIntTagValue(FT_SOURCES) >= nHighSource){
				nHighSource = cur_file->GetIntTagValue(FT_SOURCES);
				resultpos = cur_pos;
			}
		}
	}
	if (resultpos == 0){
		ASSERT ( false );
		return NULL;
	}
	CSearchFile* result = list.GetAt(resultpos);
	list.RemoveAt(resultpos);
	return result;
}

bool CSearchList::AddToList(CSearchFile* toadd, bool bClientResponse)
{
	if (!bClientResponse && !m_strResultFileType.IsEmpty() && strcmp(m_strResultFileType, toadd->GetFileType()) != 0)
	{
		delete toadd;
		return false;
	}

	for (POSITION pos = list.GetHeadPosition(); pos != NULL; )
	{
		CSearchFile* cur_file = list.GetNext(pos);
		if ( (!md4cmp(toadd->GetFileHash(), cur_file->GetFileHash())) 
			&& cur_file->GetSearchID() == toadd->GetSearchID()
			&& cur_file->GetListParent() == NULL
			)
		{
			UINT uAvail;
			if (bClientResponse)
			{
				// If this is a response from a client ("View Shared Files"), we set the "Availability" at least to 1.
				if (!toadd->GetIntTagValue(FT_SOURCES, uAvail) || uAvail==0)
					uAvail = 1;
			}
			else
				uAvail = toadd->GetIntTagValue(FT_SOURCES);
			
			// already a result in list (parent exists)
			cur_file->AddSources(uAvail);
			AddResultCount(cur_file->GetSearchID(), toadd->GetFileHash(), uAvail);

			uint32 uCompleteSources = -1;
			if (toadd->GetIntTagValue(FT_COMPLETE_SOURCES, uCompleteSources))
				cur_file->AddCompleteSources(uCompleteSources);

			// check if child with same filename exists
			bool found = false;
			for (POSITION pos2 = list.GetHeadPosition(); pos2 != NULL && !found; )
			{
				CSearchFile* cur_file2 = list.GetNext(pos2);
				if ( cur_file2 != toadd													// not the same object
					 && cur_file2->GetListParent() == cur_file							// is a child of our result (one filehash)
					 && !toadd->GetFileName().CompareNoCase(cur_file2->GetFileName()))	// same name
				{
					if (toadd->IsKademlia())
					{
						if (uAvail == cur_file2->GetIntTagValue(FT_SOURCES))
						{
							delete toadd;
							return false;
						}
					}
					else
					{
						// yes: add the counter of that child
						found = true;
						cur_file2->SetListAddChildCount(uAvail);
						cur_file2->AddSources(uAvail);
						if (uCompleteSources != -1)
							cur_file2->AddCompleteSources(uCompleteSources);
	
						// copy servers to child item -- this is not really needed because the servers are also stored
						// in the parent item, but it gives a correct view of the server list within the server property page
						for (int s = 0; s < toadd->GetServers().GetSize(); s++)
						{
							CSearchFile::SServer server = toadd->GetServerAt(s);
							int iFound = cur_file2->GetServers().Find(server);
							if (iFound == -1)
								cur_file2->AddServer(server);
							else
								cur_file2->GetServerAt(iFound).m_uAvail += server.m_uAvail;
						}
						break;
					}
				}
			}
			if (!found) 
			{
				// no:  add child
				toadd->SetListParent(cur_file);
				toadd->SetListChildCount(uAvail);
				cur_file->SetListAddChildCount(1);
				list.AddHead(toadd);
			}
			outputwnd->UpdateSources(cur_file);

			if ((toadd->GetClientID() && toadd->GetClientPort()))
			{
				if (IsValidClientIPPort(toadd->GetClientID(), toadd->GetClientPort()))
				{
					// pre-filter sources which would be dropped in CPartFile::AddSources
					if (CPartFile::CanAddSource(toadd->GetClientID(), toadd->GetClientPort(), toadd->GetClientServerIP(), toadd->GetClientServerPort()))
					{
						CSearchFile::SClient client(toadd->GetClientID(), toadd->GetClientPort(),
													toadd->GetClientServerIP(), toadd->GetClientServerPort());
						if (cur_file->GetClients().Find(client) == -1)
							cur_file->AddClient(client);
					}
				}
				else
				{
					if (thePrefs.GetDebugServerSearchesLevel() > 1)
					{
						uint32 nIP = toadd->GetClientID();
						Debug(_T("Filtered source from search result %s:%u\n"), DbgGetClientID(nIP), toadd->GetClientPort());
					}
				}

			}
			// will be used in future
			if (toadd->GetClientServerIP() && toadd->GetClientServerPort())
			{
				CSearchFile::SServer server(toadd->GetClientServerIP(), toadd->GetClientServerPort());
				int iFound = cur_file->GetServers().Find(server);
				if (iFound == -1)
				{
					server.m_uAvail = uAvail;
					cur_file->AddServer(server);
				}
				else
					cur_file->GetServerAt(iFound).m_uAvail += uAvail;
			}
			if (outputwnd && !m_MobilMuleSearch)
				outputwnd->UpdateSources(cur_file);

			if (found)
				delete toadd;
			return true;
		}
	}
	
	// no bounded result found yet -> add as parent to list
	toadd->SetListParent(NULL);
	if (list.AddTail(toadd))
	{
		uint16 tempValue = 0;
		VERIFY( m_foundFilesCount.Lookup(toadd->GetSearchID(),tempValue) );
		m_foundFilesCount.SetAt(toadd->GetSearchID(),tempValue+1);

		// new search result entry (no parent); add to result count for search result limit
		UINT uAvail;
		if (bClientResponse)
		{
			// If this is a response from a client ("View Shared Files"), we set the "Availability" at least to 1.
			if (!toadd->GetIntTagValue(FT_SOURCES, uAvail) || uAvail==0)
				uAvail = 1;
			toadd->AddSources(uAvail);
		}
		else
			uAvail = toadd->GetIntTagValue(FT_SOURCES);
		AddResultCount(toadd->GetSearchID(), toadd->GetFileHash(), uAvail);

		CSearchFile* neu = new CSearchFile(toadd);
		neu->SetListParent(toadd);
		neu->SetListChildCount(uAvail);
		list.AddTail(neu);
		toadd->SetListChildCount(1);
	}
	if (outputwnd && !m_MobilMuleSearch)
		outputwnd->AddResult(toadd);
	return true;
}

CSearchFile* CSearchList::GetSearchFileByHash(const uchar* hash) const
{
	for (POSITION pos = list.GetHeadPosition(); pos != 0; )
	{
		CSearchFile* sf = list.GetNext(pos);
		if (!md4cmp(hash, sf->GetFileHash()))
			return sf;
	}
	return NULL;
}

void CSearchList::AddResultCount(uint32 nSearchID, const uchar* hash, UINT nCount)
{
	// do not count already available or downloading files for the search result limit
	if (theApp.sharedfiles->GetFileByID(hash) || theApp.downloadqueue->GetFileByID(hash))
		return;

	uint16 tempValue = 0;
	VERIFY( m_foundSourcesCount.Lookup(nSearchID, tempValue) );
	m_foundSourcesCount.SetAt(nSearchID, tempValue + nCount);
}

void CSearchList::KademliaSearchKeyword(uint32 searchID, const Kademlia::CUInt128* fileID, 
										LPCTSTR name, uint32 size, LPCTSTR type, uint16 numProperties, ...)
{
	va_list args;
	va_start(args, numProperties);

	CSafeMemFile* temp = new CSafeMemFile(250);
	uchar fileid[16];
	fileID->toByteArray(fileid);
	temp->WriteHash16(fileid);
	
	temp->WriteUInt32(0);	// client IP
	temp->WriteUInt16(0);	// client port
	
	// write tag list
	UINT uFilePosTagCount = temp->GetPosition();
	uint32 tagcount = 0;
	temp->WriteUInt32(tagcount); // dummy tag count, will be filled later

	// standard tags
	CTag tagName(FT_FILENAME, name);
	tagName.WriteTagToFile(temp);
	tagcount++;

	CTag tagSize(FT_FILESIZE, size);
	tagSize.WriteTagToFile(temp);
	tagcount++;

	if (type != NULL && type[0] != _T('\0'))
	{
		CTag tagType(FT_FILETYPE, type);
		tagType.WriteTagToFile(temp);
		tagcount++;
	}

	// additional tags
	while (numProperties-- > 0)
	{
		UINT uPropType = va_arg(args, UINT);
		LPCSTR pszPropName = va_arg(args, LPCSTR);
		LPVOID pvPropValue = va_arg(args, LPVOID);
		if (uPropType == 2 /*TAGTYPE_STRING*/)
		{
			if ((LPCTSTR)pvPropValue != NULL && ((LPCTSTR)pvPropValue)[0] != _T('\0'))
			{
				if (strlen(pszPropName) == 1)
				{
					CTag tagProp((uint8)*pszPropName, (LPCTSTR)pvPropValue);
					tagProp.WriteTagToFile(temp);
				}
				else
				{
					CTag tagProp(pszPropName, (LPCTSTR)pvPropValue);
					tagProp.WriteTagToFile(temp);
				}
				tagcount++;
			}
		}
		else if (uPropType == 3 /*TAGTYPE_UINT32*/)
		{
			if ((uint32)pvPropValue != 0)
			{
				CTag tagProp(pszPropName, (uint32)pvPropValue);
				tagProp.WriteTagToFile(temp);
				tagcount++;
			}
		}
		else
		{
			ASSERT(0);
		}
	}
	va_end(args);
	temp->Seek(uFilePosTagCount, SEEK_SET);
	temp->WriteUInt32(tagcount);
	
	temp->SeekToBegin();
	CSearchFile* tempFile = new CSearchFile(temp, searchID, 0, 0, 0, true);
	AddToList(tempFile);
	
	delete temp;
}

⌨️ 快捷键说明

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