UINT CUploadQueue::GetWaitingPosition(CUpDownClient* client) { if (!IsOnUploadQueue(client)) return 0; UINT rank = 1; UINT myscore = client->GetScore(false); for (POSITION pos = waitinglist.GetHeadPosition(); pos != 0; ){ if (waitinglist.GetNext(pos)->GetScore(false) > myscore) rank++; } return rank; }
uint16 CUploadQueue::GetWaitingPosition(const CUpDownClient *client) const { if ( !IsOnUploadQueue(client) ) { return 0; } uint16 rank = 1; const uint32 myscore = client->GetScore(false); CClientPtrList::const_iterator it = m_waitinglist.begin(); for (; it != m_waitinglist.end(); ++it) { if ((*it)->GetScore(false) > myscore) { rank++; } } return rank; }
void CUploadQueue::AddClientToQueue(CUpDownClient* client) { if (theApp->serverconnect->IsConnected() && theApp->serverconnect->IsLowID() && !theApp->serverconnect->IsLocalServer(client->GetServerIP(),client->GetServerPort()) && client->GetDownloadState() == DS_NONE && !client->IsFriend() && theStats::GetWaitingUserCount() > 50) { // Well, all that issues finish in the same: don't allow to add to the queue return; } if ( client->IsBanned() ) { return; } client->AddAskedCount(); client->SetLastUpRequest(); // Find all clients with the same user-hash CClientList::SourceList found = theApp->clientlist->GetClientsByHash( client->GetUserHash() ); CClientList::SourceList::iterator it = found.begin(); while (it != found.end()) { CUpDownClient* cur_client = *it++; if ( IsOnUploadQueue( cur_client ) ) { if ( cur_client == client ) { // This is where LowID clients get their upload slot assigned. // They can't be contacted if they reach top of the queue, so they are just marked for uploading. // When they reconnect next time AddClientToQueue() is called, and they get their slot // through the connection they initiated. // Since at that time no slot is free they get assigned an extra slot, // so then the number of slots exceeds the configured number by one. // To prevent a further increase no more LowID clients get a slot, until // - a HighID client has got one (which happens only after two clients // have been kicked so a slot is free again) // - or there is a free slot, which means there is no HighID client on queue if (client->m_bAddNextConnect) { uint16 maxSlots = GetMaxSlots(); if (lastupslotHighID) { maxSlots++; } if (m_uploadinglist.size() < maxSlots) { client->m_bAddNextConnect = false; RemoveFromWaitingQueue(client); AddUpNextClient(client); lastupslotHighID = false; // LowID alternate return; } } client->SendRankingInfo(); Notify_QlistRefreshClient(client); return; } else { // Hash-clash, remove unidentified clients (possibly both) if ( !cur_client->IsIdentified() ) { // Cur_client isn't identifed, remove it theApp->clientlist->AddTrackClient( cur_client ); RemoveFromWaitingQueue( cur_client ); if ( !cur_client->GetSocket() ) { if (cur_client->Disconnected( wxT("AddClientToQueue - same userhash") ) ) { cur_client->Safe_Delete(); } } } if ( !client->IsIdentified() ) { // New client isn't identified, remove it theApp->clientlist->AddTrackClient( client ); if ( !client->GetSocket() ) { if ( client->Disconnected( wxT("AddClientToQueue - same userhash") ) ) { client->Safe_Delete(); } } return; } } } } // Count the number of clients with the same IP-address found = theApp->clientlist->GetClientsByIP( client->GetIP() ); int ipCount = 0; for ( it = found.begin(); it != found.end(); it++ ) { if ( ( *it == client ) || IsOnUploadQueue( *it ) ) { ipCount++; } } // We do not accept more than 3 clients from the same IP if ( ipCount > 3 ) { return; } else if ( theApp->clientlist->GetClientsFromIP(client->GetIP()) >= 3 ) { return; } // statistic values CKnownFile* reqfile = (CKnownFile*) client->GetUploadFile(); if (reqfile) { reqfile->statistic.AddRequest(); } // TODO find better ways to cap the list if (m_waitinglist.size() >= (thePrefs::GetQueueSize())) { return; } if (client->IsDownloading()) { // he's already downloading and wants probably only another file CPacket* packet = new CPacket(OP_ACCEPTUPLOADREQ, 0, OP_EDONKEYPROT); theStats::AddUpOverheadFileRequest(packet->GetPacketSize()); AddDebugLogLineM( false, logLocalClient, wxT("Local Client: OP_ACCEPTUPLOADREQ to ") + client->GetFullIP() ); client->SendPacket(packet,true); return; } uint32 tick = GetTickCount(); client->ClearWaitStartTime(); // if possible start upload right away if (m_waitinglist.empty() && tick - m_nLastStartUpload >= 1000 && m_uploadinglist.size() < GetMaxSlots()) { AddUpNextClient(client); m_nLastStartUpload = tick; } else { m_waitinglist.push_back(client); theStats::AddWaitingClient(); client->ClearAskedCount(); client->SetUploadState(US_ONUPLOADQUEUE); client->SendRankingInfo(); Notify_QlistAddClient(client); Notify_ShowQueueCount(m_waitinglist.size()); } }