📄 search.cpp
字号:
case 1: case 3: case 4: case 5: case 6: AddDebugLogLineM(false, logKadSearch, wxString::Format(wxT("Trying to add a source type %i, ip "), type) + Uint32_16toStringIP_Port(wxUINT32_SWAP_ALWAYS(ip), udp)); m_answers++; theApp->downloadqueue->KademliaSearchFile(m_searchID, &answer, &buddy, type, ip, tcp, udp, buddyip, buddyport, byCryptOptions); break; case 2: //Don't use this type, some clients will process it wrong. default: break; }}void CSearch::ProcessResultNotes(const CUInt128& answer, TagPtrList *info){ // Process a received Note to a file. // Create a Note and set the IDs. CEntry* entry = new CEntry(); entry->m_uKeyID.SetValue(m_target); entry->m_uSourceID.SetValue(answer); bool bFilterComment = false; // Loop through tags and pull wanted into. Currently we only keep Filename, Rating, Comment. for (TagPtrList::const_iterator it = info->begin(); it != info->end(); ++it) { CTag *tag = *it; if (!tag->GetName().Cmp(TAG_SOURCEIP)) { entry->m_uIP = tag->GetInt(); delete tag; } else if (!tag->GetName().Cmp(TAG_SOURCEPORT)) { entry->m_uTCPport = tag->GetInt(); delete tag; } else if (!tag->GetName().Cmp(TAG_FILENAME)) { entry->SetFileName(tag->GetStr()); delete tag; } else if (!tag->GetName().Cmp(TAG_DESCRIPTION)) { wxString strComment(tag->GetStr()); bFilterComment = thePrefs::IsMessageFiltered(strComment); entry->AddTag(tag); } else if (!tag->GetName().Cmp(TAG_FILERATING)) { entry->AddTag(tag); } else { delete tag; } } delete info; if (bFilterComment) { delete entry; return; } uint8_t fileid[16]; m_target.ToByteArray(fileid); const CMD4Hash fileHash(fileid); //Check if this hash is in our shared files.. CKnownFile* file = theApp->sharedfiles->GetFileByID(fileHash); if (!file) { // If we didn't find anything check if it's in our download queue. file = (CKnownFile*)theApp->downloadqueue->GetFileByID(fileHash); } // If we found a file try to add the note to the file. if (file) { file->AddNote(entry); m_answers++; } else { AddDebugLogLineM(false, logKadSearch, wxT("Comment received for unknown file")); delete entry; }}void CSearch::ProcessResultKeyword(const CUInt128& answer, TagPtrList *info){ // Process a keyword that we received. // Set of data we can use for a keyword result. wxString name; uint64_t size = 0; wxString type; wxString format; wxString artist; wxString album; wxString title; uint32_t length = 0; wxString codec; uint32_t bitrate = 0; uint32_t availability = 0; uint32_t publishInfo = 0; // Flag that is set if we want this keyword bool bFileName = false; bool bFileSize = false; for (TagPtrList::const_iterator it = info->begin(); it != info->end(); ++it) { CTag* tag = *it; if (tag->GetName() == TAG_FILENAME) { name = tag->GetStr(); bFileName = !name.IsEmpty(); } else if (tag->GetName() == TAG_FILESIZE) { if (tag->IsBsob() && (tag->GetBsobSize() == 8)) { // Kad1.0 uint64 type using a BSOB. size = PeekUInt64(tag->GetBsob()); } else { wxASSERT(tag->IsInt()); size = tag->GetInt(); } bFileSize = true; } else if (tag->GetName() == TAG_FILETYPE) { type = tag->GetStr(); } else if (tag->GetName() == TAG_FILEFORMAT) { format = tag->GetStr(); } else if (tag->GetName() == TAG_MEDIA_ARTIST) { artist = tag->GetStr(); } else if (tag->GetName() == TAG_MEDIA_ALBUM) { album = tag->GetStr(); } else if (tag->GetName() == TAG_MEDIA_TITLE) { title = tag->GetStr(); } else if (tag->GetName() == TAG_MEDIA_LENGTH) { length = tag->GetInt(); } else if (tag->GetName() == TAG_MEDIA_BITRATE) { bitrate = tag->GetInt(); } else if (tag->GetName() == TAG_MEDIA_CODEC) { codec = tag->GetStr(); } else if (tag->GetName() == TAG_SOURCES) { availability = tag->GetInt(); // Some rouge client was setting a invalid availability, just set it to 0. if( availability > 65500 ) { availability = 0; } } else if (tag->GetName() == TAG_PUBLISHINFO) { // we don't keep this as tag, but as a member property of the searchfile, as we only need its informations // in the search list and don't want to carry the tag over when downloading the file (and maybe even wrongly publishing it) publishInfo = (uint32_t)tag->GetInt();#ifdef __DEBUG__ uint32_t differentNames = (publishInfo & 0xFF000000) >> 24; uint32_t publishersKnown = (publishInfo & 0x00FF0000) >> 16; uint32_t trustValue = publishInfo & 0x0000FFFF; AddDebugLogLineM(false, logKadSearch, wxString::Format(wxT("Received PublishInfo Tag: %u different names, %u publishers, %.2f trustvalue"), differentNames, publishersKnown, (double)trustValue/ 100.0));#endif } delete tag; } delete info; // If we don't have a valid filename and filesize, drop this keyword. if (!bFileName || !bFileSize) { AddDebugLogLineM(false, logKadSearch, wxString(wxT("No ")) + (!bFileName ? wxT("filename") : wxT("filesize")) + wxT(" on search result, ignoring")); return; } // TODO: Check that this result matches original criteria. TagPtrList taglist; if (!format.IsEmpty()) { taglist.push_back(new CTagString(TAG_FILEFORMAT, format)); } if (!artist.IsEmpty()) { taglist.push_back(new CTagString(TAG_MEDIA_ARTIST, artist)); } if (!album.IsEmpty()) { taglist.push_back(new CTagString(TAG_MEDIA_ALBUM, album)); } if (!title.IsEmpty()) { taglist.push_back(new CTagString(TAG_MEDIA_TITLE, title)); } if (length) { taglist.push_back(new CTagVarInt(TAG_MEDIA_LENGTH, length)); } if (bitrate) { taglist.push_back(new CTagVarInt(TAG_MEDIA_BITRATE, bitrate)); } if (availability) { taglist.push_back(new CTagVarInt(TAG_SOURCES, availability)); } m_answers++; theApp->searchlist->KademliaSearchKeyword(m_searchID, &answer, name, size, type, publishInfo, taglist); // Free tags memory for (TagPtrList::iterator it = taglist.begin(); it != taglist.end(); ++it) { delete (*it); } }void CSearch::SendFindValue(CContact *contact){ // Found a node that we think has contacts closer to our target. try { if (m_stopping) { return; } CMemFile packetdata(33); // The number of returned contacts is based on the type of search. switch(m_type){ case NODE: case NODECOMPLETE: case NODESPECIAL: case NODEFWCHECKUDP: packetdata.WriteUInt8(KADEMLIA_FIND_NODE); break; case FILE: case KEYWORD: case FINDSOURCE: case NOTES: packetdata.WriteUInt8(KADEMLIA_FIND_VALUE); break; case FINDBUDDY: case STOREFILE: case STOREKEYWORD: case STORENOTES: packetdata.WriteUInt8(KADEMLIA_STORE); break; default: AddDebugLogLineM(false, logKadSearch, wxT("Invalid search type. (CSearch::sendFindValue)")); return; } // Put the target we want into the packet. packetdata.WriteUInt128(m_target); // Add the ID of the contact we're contacting for sanity checks on the other end. packetdata.WriteUInt128(contact->GetClientID()); if (contact->GetVersion() >= 2) { if (contact->GetVersion() >= 6) { CUInt128 clientID = contact->GetClientID(); CKademlia::GetUDPListener()->SendPacket(packetdata, KADEMLIA2_REQ, contact->GetIPAddress(), contact->GetUDPPort(), contact->GetUDPKey(), &clientID); } else { CKademlia::GetUDPListener()->SendPacket(packetdata, KADEMLIA2_REQ, contact->GetIPAddress(), contact->GetUDPPort(), 0, NULL); wxASSERT(contact->GetUDPKey() == CKadUDPKey(0)); }#ifdef __DEBUG__ switch (m_type) { case NODE: DebugSendF(wxT("Kad2Req(Node)"), contact->GetIPAddress(), contact->GetUDPPort()); break; case NODECOMPLETE: DebugSendF(wxT("Kad2Req(NodeComplete)"), contact->GetIPAddress(), contact->GetUDPPort()); break; case NODESPECIAL: DebugSendF(wxT("Kad2Req(NodeSpecial)"), contact->GetIPAddress(), contact->GetUDPPort()); break; case NODEFWCHECKUDP: DebugSendF(wxT("Kad2Req(NodeFWCheckUDP)"), contact->GetIPAddress(), contact->GetUDPPort()); break; case FILE: DebugSendF(wxT("Kad2Req(File)"), contact->GetIPAddress(), contact->GetUDPPort()); break; case KEYWORD: DebugSendF(wxT("Kad2Req(Keyword)"), contact->GetIPAddress(), contact->GetUDPPort()); break; case STOREFILE: DebugSendF(wxT("Kad2Req(StoreFile)"), contact->GetIPAddress(), contact->GetUDPPort()); break; case STOREKEYWORD: DebugSendF(wxT("Kad2Req(StoreKeyword)"), contact->GetIPAddress(), contact->GetUDPPort()); break; case STORENOTES: DebugSendF(wxT("Kad2Req(StoreNotes)"), contact->GetIPAddress(), contact->GetUDPPort()); break; case NOTES: DebugSendF(wxT("Kad2Req(Notes)"), contact->GetIPAddress(), contact->GetUDPPort()); break; default: DebugSend(Kad2Req, contact->GetIPAddress(), contact->GetUDPPort()); break; }#endif } else { CKademlia::GetUDPListener()->SendPacket(packetdata, KADEMLIA_REQ, contact->GetIPAddress(), contact->GetUDPPort(), 0, NULL);#ifdef __DEBUG__ switch (m_type) { case NODE: DebugSendF(wxT("KadReq(Node)"), contact->GetIPAddress(), contact->GetUDPPort()); break; case NODECOMPLETE: DebugSendF(wxT("KadReq(NodeComplete)"), contact->GetIPAddress(), contact->GetUDPPort()); break; case NODESPECIAL: DebugSendF(wxT("KadReq(NodeSpecial)"), contact->GetIPAddress(), contact->GetUDPPort()); break; case NODEFWCHECKUDP: DebugSendF(wxT("KadReq(NodeFWCheckUDP)"), contact->GetIPAddress(), contact->GetUDPPort()); break; case FILE: DebugSendF(wxT("KadReq(File)"), contact->GetIPAddress(), contact->GetUDPPort()); break; case KEYWORD: DebugSendF(wxT("KadReq(Keyword)"), contact->GetIPAddress(), contact->GetUDPPort()); break; case STOREFILE: DebugSendF(wxT("KadReq(StoreFile)"), contact->GetIPAddress(), contact->GetUDPPort()); break; case STOREKEYWORD: DebugSendF(wxT("KadReq(StoreKeyword)"), contact->GetIPAddress(), contact->GetUDPPort()); break; case STORENOTES: DebugSendF(wxT("KadReq(StoreNotes)"), contact->GetIPAddress(), contact->GetUDPPort()); break; case NOTES: DebugSendF(wxT("KadReq(Notes)"), contact->GetIPAddress(), contact->GetUDPPort()); break; default: DebugSend(KadReq, contact->GetIPAddress(), contact->GetUDPPort()); break; }#endif } } catch (const CEOFException& err) { AddDebugLogLineM(true, logKadSearch, wxT("CEOFException in CSearch::SendFindValue: ") + err.what()); } catch (const CInvalidPacket& err) { AddDebugLogLineM(true, logKadSearch, wxT("CInvalidPacket Exception in CSearch::SendFindValue: ") + err.what()); } catch (const wxString& e) { AddDebugLogLineM(true, logKadSearch, wxT("Exception in CSearch::SendFindValue: ") + e); }}// TODO: Redundant metadata checksvoid CSearch::PreparePacketForTags(CMemFile *bio, CKnownFile *file){ // We're going to publish a keyword, set up the tag list TagPtrList taglist; try { if (file && bio) { // Name, Size taglist.push_back(new CTagString(TAG_FILENAME, file->GetFileName().GetPrintable())); if (file->IsLargeFile()) { // TODO: As soon as we drop Kad1 support, we should switch to Int64 tags (we could do now already for kad2 nodes only but no advantage in that) uint8_t size64[sizeof(uint64_t)]; PokeUInt64(size64, file->GetFileSize()); taglist.push_back(new CTagBsob(TAG_FILESIZE, size64, sizeof(uint64_t))); } else { taglist.push_back(new CTagVarInt(TAG_FILESIZE, file->GetFileSize())); } taglist.push_back(new CTagVarInt(TAG_SOURCES, file->m_nCompleteSourcesCount)); // eD2K file type (Audio, Video, ...) // NOTE: Archives and CD-Images are published with file type "Pro" wxString strED2KFileType(GetED2KFileTypeSearchTerm(GetED2KFileTypeID(file->GetFileName()))); if (!strED2KFileType.IsEmpty()) { taglist.push_back(new CTagString(TAG_FILETYPE, strED2KFileType)); } // // file format (filename extension)// const wxString strExt = file->GetFileName().GetExt();// if (!strExt.IsEmpty()) {// taglist.push_back(new CTagString(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_t nName; uint8_t 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 (unsigned int i = 0; i < itemsof(_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; } wxString szKadTagName = wxString::Format(wxT("%c"),pTag->GetNameID()); if (pTag->IsStr()) { taglist.push_back(new CTagString(szKadTagName, pTag->GetStr())); } else { taglist.push_back(new CTagVarInt(szKadTagName, pTag->GetInt())); } } } } bio->WriteTagPtrList(taglist); } else { //If we get here.. Bad things happen.. Will fix this later if it is a real issue. wxFAIL; } } catch (const CEOFException& err) { AddDebugLogLineM(true, logKadSearch, wxT("CEOFException in CSearch::PreparePacketForTags: ") + err.what()); } catch (const CInvalidPacket& err) { AddDebugLogLineM(true, logKadSearch, wxT("CInvalidPacket Exception in CSearch::PreparePacketForTags: ") + err.what()); } catch (const wxString& e) { AddDebugLogLineM(true, logKadSearch, wxT("Exception in CSearch::PreparePacketForTags: ") + e); } for (TagPtrList::const_iterator it = taglist.begin(); it != taglist.end(); ++it) { delete *it; }}void CSearch::SetSearchTermData(uint32_t searchTermsDataSize, const uint8_t *searchTermsData){ m_searchTermsDataSize = searchTermsDataSize; m_searchTermsData = new uint8_t [searchTermsDataSize]; memcpy(m_searchTermsData, searchTermsData, searchTermsDataSize);}// File_checked_for_headers
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -