void QueueItem::getPartialInfo(PartsInfo& partialInfo, int64_t blockSize) const { size_t maxSize = min(done.size() * 2, (size_t)510); partialInfo.reserve(maxSize); SegmentConstIter i = done.begin(); for(; i != done.end() && partialInfo.size() < maxSize; i++) { uint16_t s = (uint16_t)((*i).getStart() / blockSize); uint16_t e = (uint16_t)(((*i).getEnd() - 1) / blockSize + 1); partialInfo.push_back(s); partialInfo.push_back(e); } }
void SearchManager::onPSR(const AdcCommand& cmd, UserPtr from, const string& remoteIp) { uint16_t udpPort = 0; uint32_t partialCount = 0; string tth; string hubIpPort; string nick; PartsInfo partialInfo; for(StringIterC i = cmd.getParameters().begin(); i != cmd.getParameters().end(); ++i) { const string& str = *i; if(str.compare(0, 2, "U4") == 0) { udpPort = static_cast<uint16_t>(Util::toInt(str.substr(2))); } else if(str.compare(0, 2, "NI") == 0) { nick = str.substr(2); } else if(str.compare(0, 2, "HI") == 0) { hubIpPort = str.substr(2); } else if(str.compare(0, 2, "TR") == 0) { tth = str.substr(2); } else if(str.compare(0, 2, "PC") == 0) { partialCount = Util::toUInt32(str.substr(2))*2; } else if(str.compare(0, 2, "PI") == 0) { StringTokenizer<string> tok(str.substr(2), ','); for(StringIter i = tok.getTokens().begin(); i != tok.getTokens().end(); ++i) { partialInfo.push_back((uint16_t)Util::toInt(*i)); } } } string url = ClientManager::getInstance()->findHub(hubIpPort); if(!from || from == ClientManager::getInstance()->getMe()) { // for NMDC support if(nick.empty() || hubIpPort.empty()) { return; } from = ClientManager::getInstance()->findUser(nick, url); if(!from) { // Could happen if hub has multiple URLs / IPs from = ClientManager::getInstance()->findLegacyUser(nick); if(!from) { dcdebug("Search result from unknown user"); return; } } } //ClientManager::getInstance()->setIPUser(from, remoteIp, udpPort); if(partialInfo.size() != partialCount) { // what to do now ? just ignore partial search result :-/ return; } PartsInfo outPartialInfo; QueueItem::PartialSource ps(from->isNMDC() ? ClientManager::getInstance()->getClient(url)->getMyIdentity().getNick() : Util::emptyString, hubIpPort, remoteIp, udpPort); ps.setPartialInfo(partialInfo); QueueManager::getInstance()->handlePartialResult(from, url, TTHValue(tth), ps, outPartialInfo); if((udpPort > 0) && !outPartialInfo.empty()) { try { AdcCommand cmd = SearchManager::getInstance()->toPSR(false, ps.getMyNick(), hubIpPort, tth, outPartialInfo); ClientManager::getInstance()->send(cmd, from->getCID()); } catch(...) { dcdebug("Partial search caught error\n"); } } }