//#warning Experimental: Construct a CKnownFile from a CSearchFile CKnownFile::CKnownFile(const CSearchFile &searchFile) : // This will copy the file hash CAbstractFile(static_cast<const CAbstractFile &>(searchFile)) { Init(); // Use CKnownFile::SetFileName() SetFileName(searchFile.GetFileName()); // Use CKnownFile::SetFileSize() SetFileSize(searchFile.GetFileSize()); }
bool CSearchList::AddToList(CSearchFile* toadd, bool bClientResponse) { if (!bClientResponse && !m_strResultFileType.IsEmpty() && _tcscmp(m_strResultFileType, toadd->GetFileType()) != 0) { delete toadd; return false; } // search for a 'parent' with same filehash and search-id as the new search result entry for (POSITION pos = list.GetHeadPosition(); pos != NULL; ) { CSearchFile* parent = list.GetNext(pos); if ( parent->GetListParent() == NULL && parent->GetSearchID() == toadd->GetSearchID() && md4cmp(parent->GetFileHash(), toadd->GetFileHash()) == 0) { // if this parent does not yet have any child entries, create one child entry // which is equal to the current parent entry (needed for GUI when expanding the child list). if (parent->GetListChildCount() == 0) { CSearchFile* child = new CSearchFile(parent); child->SetListParent(parent); int iSources = parent->GetIntTagValue(FT_SOURCES); if (iSources == 0) iSources = 1; child->SetListChildCount(iSources); list.AddTail(child); parent->SetListChildCount(1); } // get the 'Availability' of the new search result entry 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); // add the 'Availability' of the new search result entry to the total search result count for this search AddResultCount(parent->GetSearchID(), parent->GetFileHash(), uAvail); // get 'Complete Sources' of the new search result entry uint32 uCompleteSources = (uint32)-1; bool bHasCompleteSources = toadd->GetIntTagValue(FT_COMPLETE_SOURCES, uCompleteSources); bool bFound = false; if (thePrefs.GetDebugSearchResultDetailLevel() >= 1) { ; // for debugging: do not merge search results } else { // check if that parent already has a child with same filename as the new search result entry for (POSITION pos2 = list.GetHeadPosition(); pos2 != NULL && !bFound; ) { CSearchFile* child = list.GetNext(pos2); if ( child != toadd // not the same object && child->GetListParent() == parent // is a child of our result (one filehash) && toadd->GetFileName().CompareNoCase(child->GetFileName()) == 0) // same name { bFound = true; // add properties of new search result entry to the already available child entry (with same filename) // ed2k: use the sum of all values, kad: use the max. values if (toadd->IsKademlia()) { if (uAvail > child->GetListChildCount()) child->SetListChildCount(uAvail); } else { child->AddListChildCount(uAvail); } child->AddSources(uAvail); if (bHasCompleteSources) child->AddCompleteSources(uCompleteSources); break; } } } if (!bFound) { // the parent which we had found does not yet have a child with that new search result's entry name, // add the new entry as a new child // toadd->SetListParent(parent); toadd->SetListChildCount(uAvail); parent->AddListChildCount(1); list.AddHead(toadd); } // copy possible available sources from new search result entry to parent if (toadd->GetClientID() && toadd->GetClientPort()) { if (IsValidSearchResultClientIPPort(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 (parent->GetClients().Find(client) == -1) parent->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()); } } } // copy possible available servers from new search result entry to parent // will be used in future if (toadd->GetClientServerIP() && toadd->GetClientServerPort()) { CSearchFile::SServer server(toadd->GetClientServerIP(), toadd->GetClientServerPort()); int iFound = parent->GetServers().Find(server); if (iFound == -1) { server.m_uAvail = uAvail; parent->AddServer(server); } else parent->GetServerAt(iFound).m_uAvail += uAvail; } UINT uAllChildsSourceCount = 0; // ed2k: sum of all sources, kad: the max. sources found UINT uAllChildsCompleteSourceCount = 0; // ed2k: sum of all sources, kad: the max. sources found const CSearchFile* bestEntry = NULL; for (POSITION pos2 = list.GetHeadPosition(); pos2 != NULL; ) { const CSearchFile* child = list.GetNext(pos2); if (child->GetListParent() == parent) { if (parent->IsKademlia()) { if (child->GetListChildCount() > uAllChildsSourceCount) uAllChildsSourceCount = child->GetListChildCount(); /*if (child->GetCompleteSourceCount() > uAllChildsCompleteSourceCount) // not yet supported uAllChildsCompleteSourceCount = child->GetCompleteSourceCount();*/ } else { uAllChildsSourceCount += child->GetListChildCount(); uAllChildsCompleteSourceCount += child->GetCompleteSourceCount(); } if (bestEntry == NULL) bestEntry = child; else if (child->GetListChildCount() > bestEntry->GetListChildCount()) bestEntry = child; } } if (bestEntry) { parent->SetFileSize(bestEntry->GetFileSize()); parent->SetFileName(bestEntry->GetFileName()); parent->SetFileType(bestEntry->GetFileType()); parent->ClearTags(); parent->CopyTags(bestEntry->GetTags()); parent->SetIntTagValue(FT_SOURCES, uAllChildsSourceCount); parent->SetIntTagValue(FT_COMPLETE_SOURCES, uAllChildsCompleteSourceCount); } // update parent in GUI if (outputwnd && !m_MobilMuleSearch) outputwnd->UpdateSources(parent); if (bFound) delete toadd; return true; } } // no bounded result found yet -> add as parent to list toadd->SetListParent(NULL); if (list.AddTail(toadd)) { UINT tempValue = 0; VERIFY( m_foundFilesCount.Lookup(toadd->GetSearchID(), tempValue) ); m_foundFilesCount.SetAt(toadd->GetSearchID(), tempValue + 1); // get the 'Availability' of this new search result entry 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); // add the 'Availability' of this new search result entry to the total search result count for this search AddResultCount(toadd->GetSearchID(), toadd->GetFileHash(), uAvail); } if (thePrefs.GetDebugSearchResultDetailLevel() >= 1) toadd->SetListExpanded(true); // add parent in GUI if (outputwnd && !m_MobilMuleSearch) outputwnd->AddResult(toadd); return true; }
UINT CSearchList::ProcessSearchAnswer(const uchar* in_packet, uint32 size, CUpDownClient* Sender, bool* pbMoreResultsAvailable, LPCTSTR pszDirectory) { ASSERT( Sender != NULL ); uint32 nSearchID = (uint32)Sender; SSearchParams* pParams = new SSearchParams; pParams->strExpression = Sender->GetUserName(); pParams->dwSearchID = nSearchID; pParams->bClientSharedFiles = true; if (theApp.emuledlg->searchwnd->CreateNewTab(pParams)){ m_foundFilesCount.SetAt(nSearchID, 0); m_foundSourcesCount.SetAt(nSearchID, 0); } else{ delete pParams; pParams = NULL; } CSafeMemFile packet(in_packet, size); UINT results = packet.ReadUInt32(); for (UINT i = 0; i < results; i++){ CSearchFile* toadd = new CSearchFile(&packet, Sender ? Sender->GetUnicodeSupport()!=utf8strNone : false, nSearchID, 0, 0, pszDirectory); if (Sender){ toadd->SetClientID(Sender->GetIP()); toadd->SetClientPort(Sender->GetUserPort()); toadd->SetClientServerIP(Sender->GetServerIP()); toadd->SetClientServerPort(Sender->GetServerPort()); if (Sender->GetServerIP() && Sender->GetServerPort()){ CSearchFile::SServer server(Sender->GetServerIP(), Sender->GetServerPort()); server.m_uAvail = 1; toadd->AddServer(server); } toadd->SetPreviewPossible( Sender->GetPreviewSupport() && ED2KFT_VIDEO == GetED2KFileTypeID(toadd->GetFileName()) ); } AddToList(toadd, true); } 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 = ucMore!=0; if (thePrefs.GetDebugClientTCPLevel() > 0) Debug(_T(" Client search answer(%s): More=%u\n"), Sender->GetUserName(), ucMore); } else{ if (thePrefs.GetDebugClientTCPLevel() > 0) 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(in_packet + packet.GetPosition(), iAddData); } } packet.Close(); return GetResultCount(nSearchID); }