📄 uploadclient.cpp
字号:
if (!((CPartFile*)srcfile)->m_FileCompleteMutex.Lock(0)){ // just do a quick test of the mutex's state and return if it's locked.
return;
}
lockFile.m_pObject = &((CPartFile*)srcfile)->m_FileCompleteMutex;
// If it's a part file which we are uploading the file remains locked until we've read the
// current block. This way the file completion thread can not (try to) "move" the file into
// the incoming directory.
fullname = RemoveFileExtension(((CPartFile*)srcfile)->GetFullName());
}
else{
fullname.Format(_T("%s\\%s"),srcfile->GetPath(),srcfile->GetFileName());
}
uint32 togo;
if (currentblock->StartOffset > currentblock->EndOffset){
togo = currentblock->EndOffset + (srcfile->GetFileSize() - currentblock->StartOffset);
}
else{
togo = currentblock->EndOffset - currentblock->StartOffset;
if (srcfile->IsPartFile() && !((CPartFile*)srcfile)->IsComplete(currentblock->StartOffset,currentblock->EndOffset-1))
throw GetResString(IDS_ERR_INCOMPLETEBLOCK);
}
if( togo > EMBLOCKSIZE*3 )
throw GetResString(IDS_ERR_LARGEREQBLOCK);
if (!srcfile->IsPartFile()){
bFromPF = false; // This is not a part file...
if (!file.Open(fullname,CFile::modeRead|CFile::osSequentialScan|CFile::shareDenyNone))
throw GetResString(IDS_ERR_OPEN);
file.Seek(currentblock->StartOffset,0);
filedata = new byte[togo+500];
if (uint32 done = file.Read(filedata,togo) != togo){
file.SeekToBegin();
file.Read(filedata + done,togo-done);
}
file.Close();
}
else{
CPartFile* partfile = (CPartFile*)srcfile;
partfile->m_hpartfile.Seek(currentblock->StartOffset,0);
filedata = new byte[togo+500];
if (uint32 done = partfile->m_hpartfile.Read(filedata,togo) != togo){
partfile->m_hpartfile.SeekToBegin();
partfile->m_hpartfile.Read(filedata + done,togo-done);
}
}
if (lockFile.m_pObject){
lockFile.m_pObject->Unlock(); // Unlock the (part) file as soon as we are done with accessing it.
lockFile.m_pObject = NULL;
}
SetUploadFileID(srcfile);
// check extention to decide whether to compress or not
CString ext = srcfile->GetFileName();
ext.MakeLower();
int pos = ext.ReverseFind(_T('.'));
if (pos>-1)
ext = ext.Mid(pos);
bool compFlag = (ext!=_T(".zip") && ext!=_T(".rar") && ext!=_T(".ace") && ext!=_T(".ogm"));
if (ext==_T(".avi") && thePrefs.GetDontCompressAvi())
compFlag=false;
if (!IsUploadingToPeerCache() && m_byDataCompVer == 1 && compFlag)
CreatePackedPackets(filedata,togo,currentblock,bFromPF);
else
CreateStandartPackets(filedata,togo,currentblock,bFromPF);
// file statistic
srcfile->statistic.AddTransferred(togo);
m_addedPayloadQueueSession += togo;
m_DoneBlocks_list.AddHead(m_BlockRequests_queue.RemoveHead());
delete[] filedata;
filedata = 0;
}
}
catch(CString error)
{
if (thePrefs.GetVerbose())
AddDebugLogLine(false,GetResString(IDS_ERR_CLIENTERRORED),GetUserName(),error.GetBuffer());
theApp.uploadqueue->RemoveFromUploadQueue(this, _T("Client error: ") + error);
if (filedata)
delete[] filedata;
return;
}
catch(CFileException* e)
{
TCHAR szError[MAX_CFEXP_ERRORMSG];
e->GetErrorMessage(szError, ARRSIZE(szError));
if (thePrefs.GetVerbose())
{
AddDebugLogLine(false,_T("Failed to create upload package for %s - %s"),GetUserName(),szError);
}
theApp.uploadqueue->RemoveFromUploadQueue(this, ((CString)_T("Failed to create upload package.")) + szError);
if (filedata)
delete[] filedata;
e->Delete();
return;
}
//if (thePrefs.GetVerbose())
// AddDebugLogLine(false,"Debug: Packet done. Size: %i",blockpack->GetLength());
//return true;
}
void CUpDownClient::ProcessExtendedInfo(CSafeMemFile* data, CKnownFile* tempreqfile)
{
if (m_abyUpPartStatus)
{
delete[] m_abyUpPartStatus;
m_abyUpPartStatus = NULL; // added by jicxicmic
}
m_nUpPartCount = 0;
m_nUpCompleteSourcesCount= 0;
if( GetExtendedRequestsVersion() == 0 )
return;
uint16 nED2KUpPartCount = data->ReadUInt16();
if (!nED2KUpPartCount)
{
m_nUpPartCount = tempreqfile->GetPartCount();
m_abyUpPartStatus = new uint8[m_nUpPartCount];
memset(m_abyUpPartStatus,0,m_nUpPartCount);
}
else
{
if (tempreqfile->GetED2KPartCount() != nED2KUpPartCount)
{
//We already checked if we are talking about the same file.. So if we get here, something really strange happened!
m_nUpPartCount = 0;
return;
}
m_nUpPartCount = tempreqfile->GetPartCount();
m_abyUpPartStatus = new uint8[m_nUpPartCount];
uint16 done = 0;
while (done != m_nUpPartCount)
{
uint8 toread = data->ReadUInt8();
for (sint32 i = 0;i != 8;i++){
m_abyUpPartStatus[done] = ((toread>>i)&1)? 1:0;
// We may want to use this for another feature..
// if (m_abyUpPartStatus[done] && !tempreqfile->IsComplete(done*PARTSIZE,((done+1)*PARTSIZE)-1))
// bPartsNeeded = true;
done++;
if (done == m_nUpPartCount)
break;
}
}
if (GetExtendedRequestsVersion() > 1)
{
uint16 nCompleteCountLast = GetUpCompleteSourcesCount();
uint16 nCompleteCountNew = data->ReadUInt16();
SetUpCompleteSourcesCount(nCompleteCountNew);
if (nCompleteCountLast != nCompleteCountNew)
{
tempreqfile->UpdatePartsInfo();
}
}
}
theApp.emuledlg->transferwnd->queuelistctrl.RefreshClient(this);
}
void CUpDownClient::CreateStandartPackets(byte* data,uint32 togo, Requested_Block_Struct* currentblock, bool bFromPF){
uint32 nPacketSize;
CMemFile memfile((BYTE*)data,togo);
if (togo > 10240)
nPacketSize = togo/(uint32)(togo/10240);
else
nPacketSize = togo;
while (togo){
if (togo < nPacketSize*2)
nPacketSize = togo;
ASSERT( nPacketSize );
togo -= nPacketSize;
uint32 statpos = (currentblock->EndOffset - togo) - nPacketSize;
uint32 endpos = (currentblock->EndOffset - togo);
if (IsUploadingToPeerCache())
{
USES_CONVERSION;
CSafeMemFile dataHttp(10240);
if (m_iHttpSendState == 0)
{
CKnownFile* srcfile = theApp.sharedfiles->GetFileByID(GetUploadFileID());
CStringA str;
str.AppendFormat("HTTP/1.0 206\r\n");
str.AppendFormat("Content-Range: bytes %u-%u/%u\r\n", currentblock->StartOffset, currentblock->EndOffset - 1, srcfile->GetFileSize());
str.AppendFormat("Content-Type: application/octet-stream\r\n");
str.AppendFormat("Content-Length: %u\r\n", currentblock->EndOffset - currentblock->StartOffset);
str.AppendFormat("Server: eMule/%s\r\n", T2CA(theApp.m_strCurVersionLong));
str.AppendFormat("\r\n");
dataHttp.Write((LPCSTR)str, str.GetLength());
theStats.AddUpDataOverheadFileRequest(dataHttp.GetLength());
m_iHttpSendState = 1;
if (thePrefs.GetDebugClientTCPLevel() > 0){
DebugSend("PeerCache-HTTP", this, (char*)GetUploadFileID());
Debug(_T(" %hs\n"), str);
}
}
dataHttp.Write(data, nPacketSize);
data += nPacketSize;
if (thePrefs.GetDebugClientTCPLevel() > 1){
DebugSend("PeerCache-HTTP data", this, (char*)GetUploadFileID());
Debug(_T(" Start=%u End=%u Size=%u\n"), statpos, endpos, nPacketSize);
}
UINT uRawPacketSize = dataHttp.GetLength();
LPBYTE pRawPacketData = dataHttp.Detach();
CRawPacket* packet = new CRawPacket((char*)pRawPacketData, uRawPacketSize, bFromPF);
m_pPCUpSocket->SendPacket(packet, true, false, nPacketSize);
free(pRawPacketData);
}
else
{
Packet* packet = new Packet(OP_SENDINGPART,nPacketSize+24, OP_EDONKEYPROT, bFromPF);
md4cpy(&packet->pBuffer[0],GetUploadFileID());
PokeUInt32(&packet->pBuffer[16], statpos);
PokeUInt32(&packet->pBuffer[20], endpos);
memfile.Read(&packet->pBuffer[24],nPacketSize);
if (thePrefs.GetDebugClientTCPLevel() > 0){
DebugSend("OP__SendingPart", this, (char*)GetUploadFileID());
Debug(_T(" Start=%u End=%u Size=%u\n"), statpos, endpos, nPacketSize);
}
// put packet directly on socket
theStats.AddUpDataOverheadFileRequest(24);
socket->SendPacket(packet,true,false, nPacketSize);
}
}
}
void CUpDownClient::CreatePackedPackets(byte* data,uint32 togo, Requested_Block_Struct* currentblock, bool bFromPF){
BYTE* output = new BYTE[togo+300];
uLongf newsize = togo+300;
uint16 result = compress2(output,&newsize,data,togo,9);
if (result != Z_OK || togo <= newsize){
delete[] output;
CreateStandartPackets(data,togo,currentblock,bFromPF);
return;
}
CMemFile memfile(output,newsize);
uint32 oldSize = togo;
togo = newsize;
uint32 nPacketSize;
if (togo > 10240)
nPacketSize = togo/(uint32)(togo/10240);
else
nPacketSize = togo;
uint32 totalPayloadSize = 0;
while (togo){
if (togo < nPacketSize*2)
nPacketSize = togo;
ASSERT( nPacketSize );
togo -= nPacketSize;
Packet* packet = new Packet(OP_COMPRESSEDPART,nPacketSize+24,OP_EMULEPROT,bFromPF);
md4cpy(&packet->pBuffer[0],GetUploadFileID());
uint32 statpos = currentblock->StartOffset;
PokeUInt32(&packet->pBuffer[16], statpos);
PokeUInt32(&packet->pBuffer[20], newsize);
memfile.Read(&packet->pBuffer[24],nPacketSize);
if (thePrefs.GetDebugClientTCPLevel() > 0){
DebugSend("OP__CompressedPart", this, (char*)GetUploadFileID());
Debug(_T(" Start=%u BlockSize=%u Size=%u\n"), statpos, newsize, nPacketSize);
}
// approximate payload size
uint32 payloadSize = nPacketSize*oldSize/newsize;
if(togo == 0 && totalPayloadSize+payloadSize < oldSize) {
payloadSize = oldSize-totalPayloadSize;
}
totalPayloadSize += payloadSize;
// put packet directly on socket
theStats.AddUpDataOverheadFileRequest(24);
socket->SendPacket(packet,true,false, payloadSize);
}
delete[] output;
}
void CUpDownClient::SetUploadFileID(CKnownFile* newreqfile)
{
CKnownFile* oldreqfile;
//We use the knownfilelist because we may have unshared the file..
//But we always check the download list first because that person may have decided to redownload that file.
//Which will replace the object in the knownfilelist if completed.
if ((oldreqfile = theApp.downloadqueue->GetFileByID(requpfileid)) == NULL )
oldreqfile = theApp.knownfiles->FindKnownFileByID(requpfileid);
if (newreqfile == oldreqfile)
return;
// clear old status
if (m_abyUpPartStatus)
{
delete[] m_abyUpPartStatus;
m_abyUpPartStatus = NULL;
}
m_nUpPartCount = 0;
m_nUpCompleteSourcesCount= 0;
if (newreqfile){
newreqfile->AddUploadingClient(this);
md4cpy(requpfileid, newreqfile->GetFileHash());
}
else
md4clr(requpfileid);
if (oldreqfile)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -