📄 downloadclient.cpp
字号:
}
int CUpDownClient::unzip(Pending_Block_Struct* block, BYTE* zipped, uint32 lenZipped, BYTE** unzipped, uint32* lenUnzipped, int iRecursion)
{
#define TRACE_UNZIP /*TRACE*/
TRACE_UNZIP("unzip: Zipd=%6u Unzd=%6u Rcrs=%d", lenZipped, *lenUnzipped, iRecursion);
int err = Z_DATA_ERROR;
try
{
// Save some typing
z_stream *zS = block->zStream;
// Is this the first time this block has been unzipped
if (zS == NULL)
{
// Create stream
block->zStream = new z_stream;
zS = block->zStream;
// Initialise stream values
zS->zalloc = (alloc_func)0;
zS->zfree = (free_func)0;
zS->opaque = (voidpf)0;
// Set output data streams, do this here to avoid overwriting on recursive calls
zS->next_out = (*unzipped);
zS->avail_out = (*lenUnzipped);
// Initialise the z_stream
err = inflateInit(zS);
if (err != Z_OK){
TRACE_UNZIP("; Error: new stream failed: %d\n", err);
return err;
}
ASSERT( block->totalUnzipped == 0 );
}
// Use whatever input is provided
zS->next_in = zipped;
zS->avail_in = lenZipped;
// Only set the output if not being called recursively
if (iRecursion == 0)
{
zS->next_out = (*unzipped);
zS->avail_out = (*lenUnzipped);
}
// Try to unzip the data
TRACE_UNZIP("; inflate(ain=%6u tin=%6u aout=%6u tout=%6u)", zS->avail_in, zS->total_in, zS->avail_out, zS->total_out);
err = inflate(zS, Z_SYNC_FLUSH);
// Is zip finished reading all currently available input and writing all generated output
if (err == Z_STREAM_END)
{
// Finish up
err = inflateEnd(zS);
if (err != Z_OK){
TRACE_UNZIP("; Error: end stream failed: %d\n", err);
return err;
}
TRACE_UNZIP("; Z_STREAM_END\n");
// Got a good result, set the size to the amount unzipped in this call (including all recursive calls)
(*lenUnzipped) = (zS->total_out - block->totalUnzipped);
block->totalUnzipped = zS->total_out;
}
else if ((err == Z_OK) && (zS->avail_out == 0) && (zS->avail_in != 0))
{
// Output array was not big enough, call recursively until there is enough space
TRACE_UNZIP("; output array not big enough (ain=%u)\n", zS->avail_in);
// What size should we try next
uint32 newLength = (*lenUnzipped) *= 2;
if (newLength == 0)
newLength = lenZipped * 2;
// Copy any data that was successfully unzipped to new array
BYTE *temp = new BYTE[newLength];
ASSERT( zS->total_out - block->totalUnzipped <= newLength );
memcpy(temp, (*unzipped), (zS->total_out - block->totalUnzipped));
delete [] (*unzipped);
(*unzipped) = temp;
(*lenUnzipped) = newLength;
// Position stream output to correct place in new array
zS->next_out = (*unzipped) + (zS->total_out - block->totalUnzipped);
zS->avail_out = (*lenUnzipped) - (zS->total_out - block->totalUnzipped);
// Try again
err = unzip(block, zS->next_in, zS->avail_in, unzipped, lenUnzipped, iRecursion + 1);
}
else if ((err == Z_OK) && (zS->avail_in == 0))
{
TRACE_UNZIP("; all input processed\n");
// All available input has been processed, everything ok.
// Set the size to the amount unzipped in this call (including all recursive calls)
(*lenUnzipped) = (zS->total_out - block->totalUnzipped);
block->totalUnzipped = zS->total_out;
}
else
{
// Should not get here unless input data is corrupt
if (thePrefs.GetVerbose())
{
CString strZipError;
if (zS->msg)
strZipError.Format(_T(" %d: '%hs'"), err, zS->msg);
else if (err != Z_OK)
strZipError.Format(_T(" %d"), err);
TRACE_UNZIP("; Error: %s\n", strZipError);
AddDebugLogLine(false, _T("Unexpected zip error%s in file \"%s\""), strZipError, reqfile ? reqfile->GetFileName() : NULL);
}
}
if (err != Z_OK)
(*lenUnzipped) = 0;
}
catch (...){
if (thePrefs.GetVerbose())
AddDebugLogLine(false, _T("Unknown exception in %hs: file \"%s\""), __FUNCTION__, reqfile ? reqfile->GetFileName() : NULL);
err = Z_DATA_ERROR;
ASSERT(0);
}
return err;
}
uint32 CUpDownClient::CalculateDownloadRate(){
// Patch By BadWolf - Accurate datarate Calculation
TransferredData newitem = {m_nDownDataRateMS,::GetTickCount()};
m_AvarageDDR_list.AddTail(newitem);
m_nSumForAvgDownDataRate += m_nDownDataRateMS;
m_nDownDataRateMS = 0;
while (m_AvarageDDR_list.GetCount()>500)
m_nSumForAvgDownDataRate -= m_AvarageDDR_list.RemoveHead().datalen;
if(m_AvarageDDR_list.GetCount() > 1){
DWORD dwDuration = m_AvarageDDR_list.GetTail().timestamp - m_AvarageDDR_list.GetHead().timestamp;
if (dwDuration)
m_nDownDatarate = (UINT)(1000U * (ULONGLONG)m_nSumForAvgDownDataRate / dwDuration);
}
else
m_nDownDatarate = 0;
// END Patch By BadWolf
m_cShowDR++;
if (m_cShowDR == 30){
m_cShowDR = 0;
UpdateDisplayedInfo();
}
return m_nDownDatarate;
}
void CUpDownClient::CheckDownloadTimeout()
{
if (IsDownloadingFromPeerCache() && m_pPCDownSocket && m_pPCDownSocket->IsConnected())
{
ASSERT( DOWNLOADTIMEOUT < m_pPCDownSocket->GetTimeOut() );
if (GetTickCount() - m_dwLastBlockReceived > DOWNLOADTIMEOUT)
{
OnPeerCacheDownSocketTimeout();
}
}
else
{
if ((::GetTickCount() - m_dwLastBlockReceived) > DOWNLOADTIMEOUT)
{
ASSERT( socket != NULL );
if (socket != NULL)
{
ASSERT( !socket->IsRawDataMode() );
if (!socket->IsRawDataMode())
SendCancelTransfer();
}
SetDownloadState(DS_ONQUEUE);
}
}
}
UINT CUpDownClient::GetAvailablePartCount() const
{
UINT result = 0;
for (int i = 0;i < m_nPartCount;i++){
if (IsPartAvailable(i))
result++;
}
return result;
}
void CUpDownClient::SetRemoteQueueRank(uint16 nr){
m_nRemoteQueueRank = nr;
UpdateDisplayedInfo();
}
void CUpDownClient::UDPReaskACK(uint16 nNewQR){
m_bUDPPending = false;
SetRemoteQueueRank(nNewQR);
SetLastAskedTime(); // ZZ:DownloadManager
}
void CUpDownClient::UDPReaskFNF(){
m_bUDPPending = false;
if (GetDownloadState() != DS_DOWNLOADING){ // avoid premature deletion of 'this' client
if (thePrefs.GetVerbose())
AddDebugLogLine(DLP_LOW, false, _T("UDP ANSWER FNF : %s - %s"),DbgGetClientInfo(), DbgGetFileInfo(reqfile ? reqfile->GetFileHash() : NULL));
if (reqfile)
reqfile->m_DeadSourceList.AddDeadSource(this);
switch (GetDownloadState()) {
case DS_ONQUEUE:
case DS_NONEEDEDPARTS:
DontSwapTo(reqfile); // ZZ:DownloadManager
if (SwapToAnotherFile(_T("Source says it doesn't have the file. CUpDownClient::UDPReaskFNF()"), true, true, true, NULL, false, false))
break;
/*fall through*/
default:
theApp.downloadqueue->RemoveSource(this);
if (!socket){
if (Disconnected(_T("UDPReaskFNF socket=NULL")))
delete this;
}
}
}
else
{
if (thePrefs.GetVerbose())
AddDebugLogLine(false,_T("UDP ANSWER FNF : %s - did not remove client because of current download state"),GetUserName());
}
}
void CUpDownClient::UDPReaskForDownload()
{
ASSERT ( reqfile );
if(!reqfile || m_bUDPPending)
return;
if( m_nTotalUDPPackets > 3 && ((float)(m_nFailedUDPPackets/m_nTotalUDPPackets) > .3))
return;
//the line "m_bUDPPending = true;" use to be here
// deadlake PROXYSUPPORT
const ProxySettings& proxy = thePrefs.GetProxy();
if(m_nUDPPort != 0 && thePrefs.GetUDPPort() != 0 &&
!theApp.IsFirewalled() && !(socket && socket->IsConnected())&& (!proxy.UseProxy))
{
if( !HasLowID() )
{
//don't use udp to ask for sources
if(IsSourceRequestAllowed())
return;
if(SwapToAnotherFile(_T("A4AF check before OP__ReaskFilePing. CUpDownClient::UDPReaskForDownload()"), true, false, false, NULL, true, true)) {
return; // we swapped, so need to go to tcp
}
m_bUDPPending = true;
CSafeMemFile data(128);
data.WriteHash16(reqfile->GetFileHash());
if (GetUDPVersion() > 3)
{
if (reqfile->IsPartFile())
((CPartFile*)reqfile)->WritePartStatus(&data);
else
data.WriteUInt16(0);
}
if (GetUDPVersion() > 2)
data.WriteUInt16(reqfile->m_nCompleteSourcesCount);
if (thePrefs.GetDebugClientUDPLevel() > 0)
DebugSend("OP__ReaskFilePing", this, (char*)reqfile->GetFileHash());
Packet* response = new Packet(&data, OP_EMULEPROT);
response->opcode = OP_REASKFILEPING;
theStats.AddUpDataOverheadFileRequest(response->size);
theApp.downloadqueue->AddUDPFileReasks();
theApp.clientudp->SendPacket(response,GetIP(),GetUDPPort());
m_nTotalUDPPackets++;
}
else if (HasLowID() && GetBuddyIP() && GetBuddyPort() && HasValidBuddyID())
{
m_bUDPPending = true;
CSafeMemFile data(128);
data.WriteHash16(GetBuddyID());
data.WriteHash16(reqfile->GetFileHash());
if (GetUDPVersion() > 3)
{
if (reqfile->IsPartFile())
((CPartFile*)reqfile)->WritePartStatus(&data);
else
data.WriteUInt16(0);
}
if (GetUDPVersion() > 2)
data.WriteUInt16(reqfile->m_nCompleteSourcesCount);
if (thePrefs.GetDebugClientUDPLevel() > 0)
DebugSend("OP__ReaskFilePing", this, (char*)reqfile->GetFileHash());
Packet* response = new Packet(&data, OP_EMULEPROT);
response->opcode = OP_REASKCALLBACKUDP;
theStats.AddUpDataOverheadFileRequest(response->size);
theApp.downloadqueue->AddUDPFileReasks();
theApp.clientudp->SendPacket(response, GetBuddyIP(), GetBuddyPort() );
m_nTotalUDPPackets++;
}
}
}
void CUpDownClient::UpdateDisplayedInfo(bool force)
{
#ifdef _DEBUG
force = true;
#endif
DWORD curTick = ::GetTickCount();
if(force || curTick-m_lastRefreshedDLDisplay > MINWAIT_BEFORE_DLDISPLAY_WINDOWUPDATE+m_random_update_wait) {
theApp.emuledlg->transferwnd->downloadlistctrl.UpdateItem(this);
theApp.emuledlg->transferwnd->clientlistctrl.RefreshClient(this);
m_lastRefreshedDLDisplay = curTick;
}
}
// ZZ:DownloadManager -->
const bool CUpDownClient::IsInNoNeededList(const CPartFile* fileToCheck) const {
for (POSITION pos = m_OtherNoNeeded_list.GetHeadPosition();pos != 0;m_OtherNoNeeded_list.GetNext(pos)) {
if(m_OtherNoNeeded_list.GetAt(pos) == fileToCheck) {
return true;
}
}
return false;
}
// <-- ZZ:DownloadManager
// ZZ:DownloadManager -->
const bool CUpDownClient::SwapToRightFile(CPartFile* SwapTo, CPartFile* cur_file, bool ignoreSuspensions, bool SwapToIsNNPFile, bool curFileisNNPFile, bool& wasSkippedDueToSourceExchange, bool doAgressiveSwapping, bool debug) {
bool printDebug = debug && thePrefs.GetLogA4AF();
if(printDebug) {
AddDebugLogLine(DLP_LOW, false, _T("oooo Debug: SwapToRightFile. Start compare SwapTo: %s and cur_file %s"), SwapTo?SwapTo->GetFileName():_T("null"), cur_file->GetFileName());
AddDebugLogLine(DLP_LOW, false, _T("oooo Debug: doAgressiveSwapping: %s"), doAgressiveSwapping?_T("true"):_T("false"));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -