📄 search.cpp
字号:
byIO.WriteUInt128(m_uTarget);
// Send our ID with the info.
byIO.WriteUInt128(CKademlia::GetPrefs()->GetKadID());
// Create our taglist
TagList listTag;
listTag.push_back(new CKadTagStr(TAG_FILENAME, pFile->GetFileName()));
if(pFile->GetFileRating() != 0)
listTag.push_back(new CKadTagUInt(TAG_FILERATING, pFile->GetFileRating()));
if(pFile->GetFileComment() != "")
listTag.push_back(new CKadTagStr(TAG_DESCRIPTION, pFile->GetFileComment()));
if (pFromContact->GetVersion() >= 2/*47a*/)
listTag.push_back(new CKadTagUInt(TAG_FILESIZE, pFile->GetFileSize()));
byIO.WriteTagList(listTag);
// Send packet
if (pFromContact->GetVersion() >= 2/*47a*/)
{
if (thePrefs.GetDebugClientKadUDPLevel() > 0)
DebugSend("KADEMLIA2_PUBLISH_NOTES_REQ", pFromContact->GetIPAddress(), pFromContact->GetUDPPort());
CKademlia::GetUDPListener()->SendPacket( byPacket, sizeof(byPacket)-byIO.GetAvailable(), KADEMLIA2_PUBLISH_NOTES_REQ, pFromContact->GetIPAddress(), pFromContact->GetUDPPort());
}
else
{
if (thePrefs.GetDebugClientKadUDPLevel() > 0)
DebugSend("KADEMLIA_PUBLISH_NOTES_REQ", pFromContact->GetIPAddress(), pFromContact->GetUDPPort());
CKademlia::GetUDPListener()->SendPacket( byPacket, sizeof(byPacket)-byIO.GetAvailable(), KADEMLIA_PUBLISH_NOTES_REQ, pFromContact->GetIPAddress(), pFromContact->GetUDPPort());
}
// Inc total request answers
m_uTotalRequestAnswers++;
// Update search in the GUI
theApp.emuledlg->kademliawnd->searchList->SearchRef(this);
// Delete all tags.
for (TagList::const_iterator itTagList = listTag.begin(); itTagList != listTag.end(); ++itTagList)
delete *itTagList;
}
else
PrepareToStop();
break;
}
case FINDBUDDY:
{
// Send a buddy request as we are firewalled.
// As a safe guard, check to see if we already requested the Max Nodes
if( m_uAnswers > SEARCHFINDBUDDY_TOTAL )
{
PrepareToStop();
break;
}
CSafeMemFile m_pfileSearchTerms;
// Send the ID we used to find our buddy. Used for checks later and allows users to callback someone if they change buddies.
m_pfileSearchTerms.WriteUInt128(&m_uTarget);
// Send client hash so they can do a callback.
m_pfileSearchTerms.WriteUInt128(&CKademlia::GetPrefs()->GetClientHash());
// Send client port so they can do a callback
m_pfileSearchTerms.WriteUInt16(thePrefs.GetPort());
// Do a keyword/source search request to this Node.
// Send packet
#ifdef _DEBUG_KAD_
Debug( _T("StorePacket:KADEMLIA_FINDBUDDY_REQ. \r\n") );
#endif
if (thePrefs.GetDebugClientKadUDPLevel() > 0)
DebugSend("KADEMLIA_FINDBUDDY_REQ", pFromContact->GetIPAddress(), pFromContact->GetUDPPort());
CKademlia::GetUDPListener()->SendPacket(&m_pfileSearchTerms, KADEMLIA_FINDBUDDY_REQ, pFromContact->GetIPAddress(), pFromContact->GetUDPPort());
// Inc total request answers
m_uAnswers++;
// Update search in the GUI
theApp.emuledlg->kademliawnd->searchList->SearchRef(this);
break;
}
case FINDSOURCE:
{
// Try to find if this is a buddy to someone we want to contact.
// As a safe guard, check to see if we already requested the Max Nodes
if( m_uAnswers > SEARCHFINDSOURCE_TOTAL )
{
PrepareToStop();
break;
}
CSafeMemFile fileIO(34);
// This is the ID the the person we want to contact used to find a buddy.
fileIO.WriteUInt128(&m_uTarget);
if( m_listFileIDs.size() != 1)
throw CString(_T("Kademlia.CSearch.ProcessResponse: m_listFileIDs.size() != 1"));
// Currently, we limit they type of callbacks for sources.. We must know a file it person has for it to work.
fileIO.WriteUInt128(&m_listFileIDs.front());
// Send our port so the callback works.
fileIO.WriteUInt16(thePrefs.GetPort());
// Send packet
if (thePrefs.GetDebugClientKadUDPLevel() > 0)
DebugSend("KADEMLIA_CALLBACK_REQ", pFromContact->GetIPAddress(), pFromContact->GetUDPPort());
CKademlia::GetUDPListener()->SendPacket( &fileIO, KADEMLIA_CALLBACK_REQ, pFromContact->GetIPAddress(), pFromContact->GetUDPPort());
// Inc total request answers
m_uAnswers++;
// Update search in the GUI
theApp.emuledlg->kademliawnd->searchList->SearchRef(this);
break;
}
}
}
void CSearch::ProcessResult(const CUInt128 &uAnswer, TagList *plistInfo)
{
// We received a result, process it based on type.
switch(m_uType)
{
case FILE:
ProcessResultFile(uAnswer, plistInfo);
break;
case KEYWORD:
ProcessResultKeyword(uAnswer, plistInfo);
break;
case NOTES:
ProcessResultNotes(uAnswer, plistInfo);
break;
}
// Update search for the GUI
theApp.emuledlg->kademliawnd->searchList->SearchRef(this);
}
void CSearch::ProcessResultFile(const CUInt128 &uAnswer, TagList *plistInfo)
{
// Process a possible source to a file.
// Set of data we could receive from the result.
uint8 uType = 0;
uint32 uIP = 0;
uint16 uTCPPort = 0;
uint16 uUDPPort = 0;
uint32 uServerIP = 0;
uint16 uServerPort = 0;
// uint32 uClientID = 0;
uchar ucharBuddyHash[16];
CUInt128 uBuddy;
uint8 byCryptOptions = 0; // 0 = not supported
for (TagList::const_iterator itTagList = plistInfo->begin(); itTagList != plistInfo->end(); ++itTagList)
{
CKadTag* pTag = *itTagList;
if (!pTag->m_name.Compare(TAG_SOURCETYPE))
uType = (uint8)pTag->GetInt();
else if (!pTag->m_name.Compare(TAG_SOURCEIP))
uIP = (uint32)pTag->GetInt();
else if (!pTag->m_name.Compare(TAG_SOURCEPORT))
uTCPPort = (uint16)pTag->GetInt();
else if (!pTag->m_name.Compare(TAG_SOURCEUPORT))
uUDPPort = (uint16)pTag->GetInt();
else if (!pTag->m_name.Compare(TAG_SERVERIP))
uServerIP = (uint32)pTag->GetInt();
else if (!pTag->m_name.Compare(TAG_SERVERPORT))
uServerPort = (uint16)pTag->GetInt();
// else if (!pTag->m_name.Compare(TAG_CLIENTLOWID))
// uClientID = pTag->GetInt();
else if (!pTag->m_name.Compare(TAG_BUDDYHASH))
{
strmd4(pTag->GetStr(), ucharBuddyHash);
md4cpy(uBuddy.GetDataPtr(), ucharBuddyHash);
}
else if (!pTag->m_name.Compare(TAG_ENCRYPTION))
byCryptOptions = (uint8)pTag->GetInt();
delete pTag;
}
delete plistInfo;
// Process source based on it's type. Currently only one method is needed to process all types.
switch( uType )
{
case 1:
case 3:
case 4:
case 5:
m_uAnswers++;
theApp.emuledlg->kademliawnd->searchList->SearchRef(this);
theApp.downloadqueue->KademliaSearchFile(m_uSearchID, &uAnswer, &uBuddy, uType, uIP, uTCPPort, uUDPPort, uServerIP, uServerPort, byCryptOptions);
break;
}
}
void CSearch::ProcessResultNotes(const CUInt128 &uAnswer, TagList *plistInfo)
{
// Process a received Note to a file.
// Create a Note and set the ID's.
CEntry* pEntry = new CEntry();
pEntry->m_uKeyID.SetValue(m_uTarget);
pEntry->m_uSourceID.SetValue(uAnswer);
// Create flag to determine if we keep this note.
bool bFilterComment = false;
// Loops through tags and pull wanted into. Currently we only keep Filename, Rating, Comment.
for (TagList::const_iterator itTagList = plistInfo->begin(); itTagList != plistInfo->end(); ++itTagList)
{
CKadTag* pTag = *itTagList;
if (!pTag->m_name.Compare(TAG_SOURCEIP))
{
pEntry->m_uIP = (uint32)pTag->GetInt();
delete pTag;
}
else if (!pTag->m_name.Compare(TAG_SOURCEPORT))
{
pEntry->m_uTCPPort = (uint16)pTag->GetInt();
delete pTag;
}
else if (!pTag->m_name.Compare(TAG_FILENAME))
{
pEntry->m_fileName = pTag->GetStr();
delete pTag;
}
else if (!pTag->m_name.Compare(TAG_DESCRIPTION))
{
pEntry->m_listTag.push_front(pTag);
// Test if comment sould be filtered
if (!thePrefs.GetCommentFilter().IsEmpty())
{
CString strCommentLower(pTag->GetStr());
strCommentLower.MakeLower();
int iPos = 0;
CString strFilter(thePrefs.GetCommentFilter().Tokenize(_T("|"), iPos));
while (!strFilter.IsEmpty())
{
// comment filters are already in lowercase, compare with temp. lowercased received comment
if (strCommentLower.Find(strFilter) >= 0)
{
bFilterComment = true;
break;
}
strFilter = thePrefs.GetCommentFilter().Tokenize(_T("|"), iPos);
}
}
}
else if (!pTag->m_name.Compare(TAG_FILERATING))
pEntry->m_listTag.push_front(pTag);
else
delete pTag;
}
delete plistInfo;
// If we think this should be filtered, delete the note.
if(bFilterComment)
{
delete pEntry;
return;
}
uchar ucharFileid[16];
m_uTarget.ToByteArray(ucharFileid);
// Add notes to any searches we have done.
// The returned entry object will never be attached
// to anything. So you can delete the entry object
// at any time after this call..
bool bFlag = theApp.searchlist->AddNotes(pEntry, ucharFileid);
// Check if this hash is in our shared files..
CAbstractFile* pFile = (CAbstractFile*)theApp.sharedfiles->GetFileByID(ucharFileid);
// If we didn't find a file in the shares check if it's in our download queue.
if(!pFile)
pFile = (CAbstractFile*)theApp.downloadqueue->GetFileByID(ucharFileid);
// If we found a file try to add the Note to the file.
if( pFile && pFile->AddNote(pEntry) )
{
// Inc the number of answers.
m_uAnswers++;
// Update the search in the GUI
theApp.emuledlg->kademliawnd->searchList->SearchRef(this);
// We do note delete the NOTE in this case.
return;
}
// It is possible that pFile->AddNote can fail even if we found a File.
if (bFlag)
{
// Inc the number of answers.
m_uAnswers++;
// Update the search in the GUI
theApp.emuledlg->kademliawnd->searchList->SearchRef(this);
}
// We always delete the entry object if pFile->AddNote fails..
delete pEntry;
}
void CSearch::ProcessResultKeyword(const CUInt128 &uAnswer, TagList *plistInfo)
{
// Process a keyword that we received.
// Set of data we can use for a keyword result
CString sName;
uint64 uSize = 0;
CString sType;
CString sFormat;
CString sArtist;
CString sAlbum;
CString sTitle;
uint32 uLength = 0;
CString sCodec;
uint32 uBitrate = 0;
uint32 uAvailability = 0;
// Flag that is set if we want this keyword.
bool bFileName = false;
bool bFileSize = false;
for (TagList::const_iterator itTagList = plistInfo->begin(); itTagList != plistInfo->end(); ++itTagList)
{
CKadTag* pTag = *itTagList;
if (!pTag->m_name.Compare(TAG_FILENAME))
{
// Set flag based on last tag we saw.
sName = pTag->GetStr();
if( sName != "" )
bFileName = true;
else
bFileName = false;
}
else if (!pTag->m_name.Compare(TAG_FILESIZE))
{
if(pTag->IsBsob() && pTag->GetBsobSize() == 8)
uSize = *((uint64*)pTag->GetBsob());
else
uSize = pTag->GetInt();
// Set flag based on last tag we saw.
if(uSize)
bFileSize = true;
else
bFileSize = false;
}
else if (!pTag->m_name.Compare(TAG_FILETYPE))
sType = pTag->GetStr();
else if (!pTag->m_name.Compare(TAG_FILEFORMAT))
sFormat = pTag->GetStr();
else if (!pTag->m_name.Compare(TAG_MEDIA_ARTIST))
sArtist = pTag->GetStr();
else if (!pTag->m_name.Compare(TAG_MEDIA_ALBUM))
sAlbum = pTag->GetStr();
else if (!pTag->m_name.Compare(TAG_MEDIA_TITLE))
sTitle = pTag->GetStr();
else if (!pTag->m_name.Compare(TAG_MEDIA_LENGTH))
uLength = (uint32)pTag->GetInt();
else if (!pTag->m_name.Compare(TAG_MEDIA_BITRATE))
uBitrate = (uint32)pTag->GetInt();
else if (!pTag->m_name.Compare(TAG_MEDIA_CODEC))
sCodec = pTag->GetStr();
else if (!pTag->m_name.Compare(TAG_SOURCES))
{
// Some rouge client was setting a invalid availability, just set it to 0
uAvailability = (uint32)pTag->GetInt();
if( uAvailability > 65500 )
uAvailability = 0;
}
delete pTag;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -