📄 search.cpp
字号:
prepareToStop(); break; } CMemFile bio(34); bio.WriteUInt128(m_target); if( m_fileIDs.size() != 1) { throw wxString(wxT("Kademlia.CSearch.processResponse: m_fileIDs.size() != 1")); } bio.WriteUInt128(m_fileIDs.front()); bio.WriteUInt16(thePrefs::GetPort()); CKademlia::getUDPListener()->sendPacket( &bio, KADEMLIA_CALLBACK_REQ, from->getIPAddress(), from->getUDPPort()); m_answers++; break; } case NODECOMPLETE: AddDebugLogLineM(false, logKadSearch, wxT("Search result type: NodeComplete")); break; case NODE: AddDebugLogLineM(false, logKadSearch, wxT("Search result type: Node")); break; default: AddDebugLogLineM(false, logKadSearch, wxString::Format(wxT("Search result type: Unknown (%i)"),m_type)); break; }}void CSearch::processResult(uint32 fromIP, uint16 fromPort, const CUInt128 &answer, TagList *info){ wxString type = wxT("Unknown"); switch(m_type) { case FILE: type = wxT("File"); processResultFile(fromIP, fromPort, answer, info); break; case KEYWORD: type = wxT("Keyword"); processResultKeyword(fromIP, fromPort, answer, info); break; case NOTES: type = wxT("Notes"); processResultNotes(fromIP, fromPort, answer, info); break; } AddDebugLogLineM(false, logKadSearch, wxT("Got result ") + type + wxT(" from ") + Uint32_16toStringIP_Port(wxUINT32_SWAP_ALWAYS(fromIP),fromPort));}void CSearch::processResultFile(uint32 WXUNUSED(fromIP), uint16 WXUNUSED(fromPort), const CUInt128 &answer, TagList *info){ uint8 type = 0; uint32 ip = 0; uint16 tcp = 0; uint16 udp = 0; uint32 serverip = 0; uint16 serverport = 0; uint32 clientid = 0; CUInt128 buddy; CTag *tag; TagList::const_iterator it; for (it = info->begin(); it != info->end(); ++it) { tag = *it; if (!tag->m_name.Cmp(wxT(TAG_SOURCETYPE))) { type = tag->GetInt(); } else if (!tag->m_name.Cmp(wxT(TAG_SOURCEIP))) { ip = tag->GetInt(); } else if (!tag->m_name.Cmp(wxT(TAG_SOURCEPORT))) { tcp = tag->GetInt(); } else if (!tag->m_name.Cmp(wxT(TAG_SOURCEUPORT))) { udp = tag->GetInt(); } else if (!tag->m_name.Cmp(wxT(TAG_SERVERIP))) { serverip = tag->GetInt(); } else if (!tag->m_name.Cmp(wxT(TAG_SERVERPORT))) { serverport = tag->GetInt(); } else if (!tag->m_name.Cmp(wxT(TAG_CLIENTLOWID))) { clientid = tag->GetInt(); } else if (!tag->m_name.Cmp(wxT(TAG_BUDDYHASH))) { CMD4Hash hash; // TODO: Error handling if (not hash.Decode(tag->GetStr())) {#ifdef __DEBUG__ printf("Invalid buddy-hash: '%s'\n", (const char*)tag->GetStr().fn_str());#endif } buddy.setValueBE(hash.GetHash()); } delete tag; } delete info; switch( type ) { case 1: case 3: { m_answers++; 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 WXUNUSED(fromIP), uint16 WXUNUSED(fromPort), const CUInt128 &answer, TagList *info){ CEntry* entry = new CEntry(); entry->keyID.setValue(m_target); entry->sourceID.setValue(answer); bool bFilterComment = false; CTag *tag; TagList::const_iterator it; for (it = info->begin(); it != info->end(); it++) { tag = *it; if (!tag->m_name.Cmp(wxT(TAG_SOURCEIP))) { entry->ip = tag->GetInt(); delete tag; } else if (!tag->m_name.Cmp(wxT(TAG_SOURCEPORT))) { entry->tcpport = tag->GetInt(); delete tag; } else if (!tag->m_name.Cmp(wxT(TAG_FILENAME))) { entry->fileName = tag->GetStr(); delete tag; } else if (!tag->m_name.Cmp(wxT(TAG_DESCRIPTION))) { wxString strComment(tag->GetStr()); bFilterComment = thePrefs::IsMessageFiltered(strComment); entry->taglist.push_front(tag); } else if (!tag->m_name.Cmp(wxT(TAG_FILERATING))) { entry->taglist.push_front(tag); } else { delete tag; } } delete info; if (bFilterComment) { delete entry; return; } byte 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 (file) { // Ok, found the file. Add the note to it. m_answers++; file->AddNote(entry); } else { AddDebugLogLineM(false, logKadSearch, wxT("Comment received for unknown file")); }}void CSearch::processResultKeyword(uint32 WXUNUSED(fromIP), uint16 WXUNUSED(fromPort), const CUInt128 &answer, TagList *info){ bool interested = false; wxString name; uint32 size = 0; wxString type; wxString format; wxString artist; wxString album; wxString title; uint32 length = 0; wxString codec; uint32 bitrate = 0; uint32 availability = 0; for (TagList::const_iterator it = info->begin(); it != info->end(); ++it) { CTag* tag = *it; if (!tag->m_name.Cmp(wxT(TAG_FILENAME))) { name = tag->GetStr(); interested = !name.IsEmpty(); } else if (!tag->m_name.Cmp(wxT(TAG_FILESIZE))) { size = tag->GetInt(); } else if (!tag->m_name.Cmp(wxT(TAG_FILETYPE))) { type = tag->GetStr(); } else if (!tag->m_name.Cmp(wxT(TAG_FILEFORMAT))) { format = tag->GetStr(); } else if (!tag->m_name.Cmp(wxT(TAG_MEDIA_ARTIST))) { artist = tag->GetStr(); } else if (!tag->m_name.Cmp(wxT(TAG_MEDIA_ALBUM))) { album = tag->GetStr(); } else if (!tag->m_name.Cmp(wxT(TAG_MEDIA_TITLE))) { title = tag->GetStr(); } else if (!tag->m_name.Cmp(wxT(TAG_MEDIA_LENGTH))) { length = tag->GetInt(); } else if (!tag->m_name.Cmp(wxT(TAG_MEDIA_BITRATE))) { bitrate = tag->GetInt(); } else if (!tag->m_name.Cmp(wxT(TAG_MEDIA_CODEC))) { codec = tag->GetStr(); } else if (!tag->m_name.Cmp(wxT(TAG_SOURCES))) { availability = tag->GetInt(); if( availability > 65500 ) { availability = 0; } } delete tag; } delete info; // 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; //} TagPtrList taglist; if (!format.IsEmpty()) { taglist.push_back(new ed2kCTag(TAG_FILEFORMAT, format)); } if (!artist.IsEmpty()) { taglist.push_back(new ed2kCTag(TAG_MEDIA_ARTIST, artist)); } if (!album.IsEmpty()) { taglist.push_back(new ed2kCTag(TAG_MEDIA_ALBUM, album)); } if (!title.IsEmpty()) { taglist.push_back(new ed2kCTag(TAG_MEDIA_TITLE, title)); } if (length) { taglist.push_back(new ed2kCTag(TAG_MEDIA_LENGTH, length)); } if (bitrate) { taglist.push_back(new ed2kCTag(TAG_MEDIA_BITRATE, bitrate)); } if (availability) { taglist.push_back(new ed2kCTag(TAG_SOURCES, availability)); } if (interested) { m_answers++; theApp.searchlist->KademliaSearchKeyword(m_searchID, &answer, name, size, type, taglist); } else { printf("Not adding search results: not interested\n"); } // Free tags memory for (TagPtrList::iterator it = taglist.begin(); it != taglist.end(); ++it) { delete (*it); } }void CSearch::sendFindValue(const CUInt128 &check, uint32 ip, uint16 port){ try { if(m_stoping) { return; } CMemFile 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: AddDebugLogLineM(false, logKadSearch, wxT("Invalid search type. (CSearch::sendFindValue)")); return; } bio.WriteUInt128(m_target); bio.WriteUInt128(check); m_kadPacketSent++; #ifdef __DEBUG__ wxString Type; switch(m_type) { case NODE: Type = wxT("KadReqFindNode"); break; case NODECOMPLETE: Type = wxT("KadReqFindNodeCompl"); break; case FILE: Type = wxT("KadReqFindFile"); break; case KEYWORD: Type = wxT("KadReqFindKeyw"); break; case STOREFILE: Type = wxT("KadReqStoreFile"); break; case STOREKEYWORD: Type = wxT("KadReqStoreKeyw"); break; case STORENOTES: Type = wxT("KadReqStoreNotes"); break; case NOTES: Type = wxT("KadReqNotes"); break; default: Type = wxT("KadReqUnknown"); } AddDebugLogLineM(false, logClientKadUDP, Type + wxT(" to ") + Uint32_16toStringIP_Port(wxUINT32_SWAP_ALWAYS(ip),port)); #endif CKademlia::getUDPListener()->sendPacket(&bio, KADEMLIA_REQ, ip, port); } catch (const CIOException& ioe) { AddDebugLogLineM( false, logKadSearch, wxString::Format(wxT("Exception in CSearch::sendFindValue (IO error(%i))"), ioe.m_cause)); }}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" wxString strED2KFileType(GetED2KFileTypeSearchTerm(GetED2KFileTypeID(file->GetFileName()))); if (!strED2KFileType.IsEmpty()) { taglist.push_back(new CTagStr(TAG_FILETYPE, strED2KFileType)); } // file format (filename extension) int iExt = file->GetFileName().Find(wxT('.'), true); if (iExt != -1) { wxString 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; } wxString szKadTagName = wxString::Format(wxT("%c"),pTag->GetNameID()); 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. wxASSERT(0); } } catch (const CIOException& ioe) { AddDebugLogLineM( false, logKadSearch, wxString::Format(wxT("Exception in CSearch::PreparePacketForTags (IO error(%i))"), ioe.m_cause)); }}//Can't clean these up until Taglist works with CMemFiles.void CSearch::PreparePacket(void){ try { int count = m_fileIDs.size(); byte 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(CMD4Hash(fileid)); if (!file) { printf("File not found on shared when publishing packet!\n"); bio3->writeByte(0); } else { 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(CMD4Hash(fileid)); if (!file) { printf("File not found on shared when publishing packet!\n"); bio2->writeByte(0); } else { 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(CMD4Hash(fileid)); if (!file) { printf("File not found on shared when publishing packet!\n"); bio1->writeByte(0); } else { PreparePacketForTags( bio1, file ); } } } } catch (const CIOException& ioe ) { AddDebugLogLineM( false, logKadSearch, wxString::Format(wxT("Exception in CSearch::PreparePacket (IO error(%i))"), ioe.m_cause)); }}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 + -