📄 searchmanager.cpp
字号:
//// This file is part of the aMule Project.//// Copyright (c) 2004-2008 Angel Vidal (Kry) ( kry@amule.org )// Copyright (c) 2004-2008 aMule Team ( admin@amule.org / http://www.amule.org )// Copyright (c) 2003 Barry Dunne (http://www.emule-project.net)//// Any parts of this program derived from the xMule, lMule or eMule project,// or contributed by third-party developers are copyrighted by their// respective authors.//// This program is free software; you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation; either version 2 of the License, or// (at your option) any later version.//// This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the// GNU General Public License for more details.// // You should have received a copy of the GNU General Public License// along with this program; if not, write to the Free Software// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA//// Note To Mods ///*Please do not change anything here and release it..There is going to be a new forum created just for the Kademlia side of the client..If you feel there is an error or a way to improve something, pleasepost it in the forum first and let us look at it.. If it is a real improvement,it will be added to the offical client.. Changing something without knowingwhat all it does can cause great harm to the network if released in mass form..Any mod that changes anything within the Kademlia side will not be allowed to advertisethere client on the eMule forum..*/#include <wx/wx.h>#include "Search.h"#include <common/Macros.h>#include "Indexed.h"#include "Defines.h"#include "../routing/Contact.h"#include "../../MemFile.h"#include "../../Logger.h"#include <wx/tokenzr.h>#if defined(__SUNPRO_CC)#define __FUNCTION__ __FILE__+__LINE__#endif////////////////////////////////////////using namespace Kademlia;////////////////////////////////////////uint32_t CSearchManager::m_nextID = 0;SearchMap CSearchManager::m_searches;bool CSearchManager::IsSearching(uint32_t searchID) throw(){ // Check if this searchID is within the searches for (SearchMap::const_iterator it = m_searches.begin(); it != m_searches.end(); ++it) { if (it->second->GetSearchID() == searchID) { return true; } } return false;}void CSearchManager::StopSearch(uint32_t searchID, bool delayDelete){ // Stop a specific searchID for (SearchMap::iterator it = m_searches.begin(); it != m_searches.end(); ++it) { if (it->second->GetSearchID() == searchID) { // Do not delete as we want to get a chance for late packets to be processed. if (delayDelete) { it->second->PrepareToStop(); } else { // Delete this search now. // If this method is changed to continue looping, take care of the iterator as we will already // be pointing to the next entry and the for-loop could cause you to iterate past the end. delete it->second; m_searches.erase(it++); } return; } }}void CSearchManager::StopAllSearches(){ // Stop and delete all searches. for (SearchMap::iterator it = m_searches.begin(); it != m_searches.end(); ++it) { delete it->second; } m_searches.clear();}bool CSearchManager::StartSearch(CSearch* search){ // A search object was created, now try to start the search. if (AlreadySearchingFor(search->GetTarget())) { // There was already a search in progress with this target. delete search; return false; } // Add to the search map m_searches[search->GetTarget()] = search; // Start the search. search->Go(); return true;}CSearch* CSearchManager::PrepareFindKeywords(const wxString& keyword, uint32_t searchTermsDataSize, const uint8_t *searchTermsData, uint32_t searchid){ // Create a keyword search object. CSearch *s = new CSearch; try { // Set search to a keyword type. s->SetSearchTypes(CSearch::KEYWORD); // Make sure we have a keyword list GetWords(keyword, &s->m_words); if (s->m_words.size() == 0) { throw wxString(_("Kademlia: search keyword too short")); } wxString wstrKeyword = s->m_words.front(); printf("Keyword for search: %s\n",(const char*)unicode2char(wstrKeyword)); // Kry - I just decided to assume everyone is unicoded // GonoszTopi - seconded KadGetKeywordHash(wstrKeyword, &s->m_target); // Verify that we are not already searching for this target. if (AlreadySearchingFor(s->m_target)) { throw wxT("Kademlia: Search keyword is already on search list: ") + wstrKeyword; } s->SetSearchTermData(searchTermsDataSize, searchTermsData); // Inc our searchID // If called from external client use predefined search id s->SetSearchID((searchid & 0xffffff00) == 0xffffff00 ? searchid : ++m_nextID); // Insert search into map m_searches[s->GetTarget()] = s; // Start search s->Go(); } catch (const CEOFException& err) { delete s; wxString strError = wxT("CEOFException in ") + wxString::FromAscii(__FUNCTION__) + wxT(": ") + err.what(); throw strError; } catch (const CInvalidPacket& err) { delete s; wxString strError = wxT("CInvalidPacket exception in ") + wxString::FromAscii(__FUNCTION__) + wxT(": ") + err.what(); throw strError; } catch (...) { delete s; throw; } return s;}CSearch* CSearchManager::PrepareLookup(uint32_t type, bool start, const CUInt128& id){ // Prepare a kad lookup. // Make sure this target is not already in progress. if (AlreadySearchingFor(id)) { return NULL; } // Create a new search. CSearch *s = new CSearch; // Set type and target. s->SetSearchTypes(type); s->SetTargetID(id); try { switch(type) { case CSearch::STOREKEYWORD: if (!Kademlia::CKademlia::GetIndexed()->SendStoreRequest(id)) { delete s; return NULL; } break; } s->SetSearchID(++m_nextID); if (start) { m_searches[id] = s; s->Go(); } }catch (const CEOFException& err) { delete s; AddDebugLogLineM( false, logKadSearch, wxT("CEOFException in ") + wxString::FromAscii(__FUNCTION__) + wxT(": ") + err.what()); return NULL; } catch (...) { AddDebugLogLineM(false, logKadSearch, wxT("Exception in CSearchManager::prepareLookup")); delete s; throw; } return s;}void CSearchManager::FindNode(const CUInt128& id, bool complete){ // Do a node lookup. CSearch *s = new CSearch; if (complete) { s->SetSearchTypes(CSearch::NODECOMPLETE); } else { s->SetSearchTypes(CSearch::NODE); } s->SetTargetID(id); StartSearch(s);}bool CSearchManager::IsFWCheckUDPSearch(const CUInt128& target){ // Check if this target is in the search map. SearchMap::const_iterator it = m_searches.find(target); if (it != m_searches.end()) { return (it->second->GetSearchTypes() == CSearch::NODEFWCHECKUDP); } return false;}void CSearchManager::GetWords(const wxString& str, WordList *words){ size_t len = 0; wxString current_word; wxStringTokenizer tkz(str, GetInvalidKeywordChars()); while (tkz.HasMoreTokens()) { current_word = tkz.GetNextToken(); if ((len = current_word.Length()) > 2) { current_word.MakeLower(); words->remove(current_word); words->push_back(current_word); } } // If the last word is 3 bytes long, chances are it's a file extension. if(words->size() > 1 && len == 3) { words->pop_back(); }}void CSearchManager::JumpStart(){ // Find any searches that has stalled and jumpstart them. // This will also prune all searches. time_t now = time(NULL); SearchMap::iterator next_it = m_searches.begin(); while (next_it != m_searches.end()) { SearchMap::iterator current_it = next_it++; /* don't change this to a ++next_it! */ switch(current_it->second->GetSearchTypes()){ case CSearch::FILE: { if (current_it->second->m_created + SEARCHFILE_LIFETIME < now) { delete current_it->second; m_searches.erase(current_it); } else if (current_it->second->GetAnswers() > SEARCHFILE_TOTAL || current_it->second->m_created + SEARCHFILE_LIFETIME - SEC(20) < now) { current_it->second->PrepareToStop(); } else { current_it->second->JumpStart(); } break; } case CSearch::KEYWORD: { if (current_it->second->m_created + SEARCHKEYWORD_LIFETIME < now) { delete current_it->second; m_searches.erase(current_it); } else if (current_it->second->GetAnswers() > SEARCHKEYWORD_TOTAL || current_it->second->m_created + SEARCHKEYWORD_LIFETIME - SEC(20) < now) { current_it->second->PrepareToStop(); } else { current_it->second->JumpStart(); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -