📄 search.cpp
字号:
}
else*/
{
m_pfileSearchTerms->WriteUInt128(&CKademlia::GetPrefs()->GetKadID());
if (thePrefs.GetDebugClientKadUDPLevel() > 0)
DebugSend("KADEMLIA_SEARCH_NOTES_REQ", pFromContact->GetIPAddress(), pFromContact->GetUDPPort());
CKademlia::GetUDPListener()->SendPacket(m_pfileSearchTerms->GetBuffer(), (UINT)m_pfileSearchTerms->GetLength(), KADEMLIA_SEARCH_NOTES_REQ, pFromContact->GetIPAddress(), pFromContact->GetUDPPort());
}
// Inc total request answers
m_uTotalRequestAnswers++;
// Update search in the GUI
theApp.emuledlg->kademliawnd->searchList->SearchRef(this);
break;
}
case STOREFILE:
{
// Try to store yourself as a source to a Node.
// As a safe guard, check to see if we already stored to the Max Nodes
if( m_uAnswers > SEARCHSTOREFILE_TOTAL )
{
PrepareToStop();
break;
}
// Find the file we are trying to store as a source too.
uchar ucharFileid[16];
m_uTarget.ToByteArray(ucharFileid);
CKnownFile* pFile = theApp.sharedfiles->GetFileByID(ucharFileid);
if (pFile)
{
// We set this mostly for GUI resonse.
m_sFileName = pFile->GetFileName();
// Get our clientID for the packet.
CUInt128 uID(CKademlia::GetPrefs()->GetClientHash());
//We can use type for different types of sources.
//1 HighID Sources..
//2 cannot be used as older clients will not work.
//3 Firewalled Kad Source.
//4 >4GB file HighID Source.
//5 >4GB file Firewalled Kad source.
TagList listTag;
if( theApp.IsFirewalled() )
{
// We are firewalled, make sure we have a buddy.
if( theApp.clientlist->GetBuddy() )
{
// We send the ID to our buddy so they can do a callback.
CUInt128 uBuddyID(true);
uBuddyID.Xor(CKademlia::GetPrefs()->GetKadID());
if(pFile->GetFileSize() > OLD_MAX_EMULE_FILE_SIZE)
listTag.push_back(new CKadTagUInt8(TAG_SOURCETYPE, 5));
else
listTag.push_back(new CKadTagUInt8(TAG_SOURCETYPE, 3));
listTag.push_back(new CKadTagUInt(TAG_SERVERIP, theApp.clientlist->GetBuddy()->GetIP()));
listTag.push_back(new CKadTagUInt(TAG_SERVERPORT, theApp.clientlist->GetBuddy()->GetUDPPort()));
listTag.push_back(new CKadTagStr(TAG_BUDDYHASH, CStringW(md4str(uBuddyID.GetData()))));
listTag.push_back(new CKadTagUInt(TAG_SOURCEPORT, thePrefs.GetPort()));
}
else if(theVnnCtrl.IsConnected())
{
CUInt128 uBuddyID(true);
uBuddyID.Xor(CKademlia::GetPrefs()->GetKadID());
if(pFile->GetFileSize() > OLD_MAX_EMULE_FILE_SIZE)
listTag.push_back(new CKadTagUInt8(TAG_SOURCETYPE, 5));
else
listTag.push_back(new CKadTagUInt8(TAG_SOURCETYPE, 3));
listTag.push_back(new CKadTagUInt(TAG_SOURCEPORT, thePrefs.GetPort()));
}
else
{
PrepareToStop();
break;
}
}
else
{
// We are not firewalled..
if(pFile->GetFileSize() > OLD_MAX_EMULE_FILE_SIZE)
listTag.push_back(new CKadTagUInt(TAG_SOURCETYPE, 4));
else
listTag.push_back(new CKadTagUInt(TAG_SOURCETYPE, 1));
listTag.push_back(new CKadTagUInt(TAG_SOURCEPORT, thePrefs.GetPort()));
/*if(bKad2)
{
listTag.push_back(new CKadTagUInt(TAG_FILESIZE, pFile->GetFileSize()));
}*/
}
// Send packet
CKademlia::GetUDPListener()->SendPublishSourcePacket(pFromContact->GetIPAddress(), pFromContact->GetUDPPort(),m_uTarget,uID, listTag);
// 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;
}
break;
}
case STOREKEYWORD:
{
//JOHNTODO -- We cannot precreate these packets as we do not know
// before hand if we are talking to Kad1.0 or Kad2.0..
// Try to store keywords to a Node.
// As a safe guard, check to see if we already stored to the Max Nodes
if( m_uAnswers > SEARCHSTOREKEYWORD_TOTAL )
{
PrepareToStop();
break;
}
// The store can be up to 3 packets, 50 keywords each.
if( pbyIO1 )
{
if (thePrefs.GetDebugClientKadUDPLevel() > 0)
DebugSend("KADEMLIA_PUBLISH_REQ(packet1)", pFromContact->GetIPAddress(), pFromContact->GetUDPPort());
CKademlia::GetUDPListener()->SendPacket( byPacket1, ((1024*50)-pbyIO1->GetAvailable()), pFromContact->GetIPAddress(), pFromContact->GetUDPPort() );
}
if( pbyIO2 )
{
if (thePrefs.GetDebugClientKadUDPLevel() > 0)
DebugSend("KADEMLIA_PUBLISH_REQ(packet2)", pFromContact->GetIPAddress(), pFromContact->GetUDPPort());
CKademlia::GetUDPListener()->SendPacket( byPacket2, ((1024*50)-pbyIO2->GetAvailable()), pFromContact->GetIPAddress(), pFromContact->GetUDPPort() );
}
if( pbyIO3 )
{
if (thePrefs.GetDebugClientKadUDPLevel() > 0)
DebugSend("KADEMLIA_PUBLISH_REQ(packet3)", pFromContact->GetIPAddress(), pFromContact->GetUDPPort());
CKademlia::GetUDPListener()->SendPacket( byPacket3, ((1024*50)-pbyIO3->GetAvailable()), pFromContact->GetIPAddress(), pFromContact->GetUDPPort() );
}
// Inc total request answers
m_uTotalRequestAnswers++;
// Update search in the GUI
theApp.emuledlg->kademliawnd->searchList->SearchRef(this);
break;
}
case STORENOTES:
{
// JOHNTODO - Need to add Kad2.0 support
// Find file we are storing info about.
uchar ucharFileid[16];
m_uTarget.ToByteArray(ucharFileid);
CKnownFile* pFile = theApp.sharedfiles->GetFileByID(ucharFileid);
if (pFile)
{
byte byPacket[1024*2];
CByteIO byIO(byPacket,sizeof(byPacket));
// Send the Hash of the file we are storing info about.
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()));
byIO.WriteTagList(listTag);
// Send packet
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;
}
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;
}
// Do a keyword/source search request to this Node.
if (thePrefs.GetDebugClientKadUDPLevel() > 0)
{
DebugSend("KADEMLIA_FINDBUDDY_REQ", pFromContact->GetIPAddress(), pFromContact->GetUDPPort());
}
// Send packet
CKademlia::GetUDPListener()->SendPacket(m_pfileSearchTerms->GetBuffer(), (UINT)m_pfileSearchTerms->GetLength(), 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
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;
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);
}
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);
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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -