📄 uploadclient.cpp
字号:
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;
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;
if (newreqfile){
newreqfile->AddUploadingClient(this);
md4cpy(requpfileid, newreqfile->GetFileHash());
}
else
md4clr(requpfileid);
if (oldreqfile)
oldreqfile->RemoveUploadingClient(this);
}
void CUpDownClient::AddReqBlock(Requested_Block_Struct* reqblock)
{
for (POSITION pos = m_DoneBlocks_list.GetHeadPosition(); pos != 0; ){
const Requested_Block_Struct* cur_reqblock = m_DoneBlocks_list.GetNext(pos);
if (reqblock->StartOffset == cur_reqblock->StartOffset && reqblock->EndOffset == cur_reqblock->EndOffset){
delete reqblock;
return;
}
}
for (POSITION pos = m_BlockRequests_queue.GetHeadPosition(); pos != 0; ){
const Requested_Block_Struct* cur_reqblock = m_BlockRequests_queue.GetNext(pos);
if (reqblock->StartOffset == cur_reqblock->StartOffset && reqblock->EndOffset == cur_reqblock->EndOffset){
delete reqblock;
return;
}
}
m_BlockRequests_queue.AddTail(reqblock);
}
uint32 CUpDownClient::SendBlockData(){
DWORD curTick = ::GetTickCount();
uint64 sentBytesCompleteFile = 0;
uint64 sentBytesPartFile = 0;
uint64 sentBytesPayload = 0;
if(socket || m_pPCUpSocket && IsUploadingToPeerCache()) {
CEMSocket* s = (m_pPCUpSocket && IsUploadingToPeerCache()) ? m_pPCUpSocket : socket;
// Extended statistics information based on which client software and which port we sent this data to...
// This also updates the grand total for sent bytes, etc. And where this data came from.
sentBytesCompleteFile = s->GetSentBytesCompleteFileSinceLastCallAndReset();
sentBytesPartFile = s->GetSentBytesPartFileSinceLastCallAndReset();
thePrefs.Add2SessionTransferData(GetClientSoft(), GetUserPort(), false, true, sentBytesCompleteFile, (IsFriend()&& GetFriendSlot()));
thePrefs.Add2SessionTransferData(GetClientSoft(), GetUserPort(), true, true, sentBytesPartFile, (IsFriend()&& GetFriendSlot()));
m_nTransferedUp += sentBytesCompleteFile + sentBytesPartFile;
credits->AddUploaded(sentBytesCompleteFile + sentBytesPartFile, GetIP());
sentBytesPayload = s->GetSentPayloadSinceLastCallAndReset();
m_nCurQueueSessionPayloadUp += sentBytesPayload;
if(!GetFriendSlot() && theApp.uploadqueue->CheckForTimeOver(this)) {
theApp.uploadqueue->RemoveFromUploadQueue(this, _T("Completed transfer"), true);
theApp.uploadqueue->AddClientToQueue(this,true);
}
else {
// read blocks from file and put on socket
CreateNextBlockPackage();
}
}
if(sentBytesCompleteFile + sentBytesPartFile > 0 ||
m_AvarageUDR_list.GetCount() == 0 || (curTick - m_AvarageUDR_list.GetTail().timestamp) > 1*1000) {
// Store how much data we've transfered this round,
// to be able to calculate average speed later
// keep sum of all values in list up to date
TransferredData newitem = {sentBytesCompleteFile + sentBytesPartFile, curTick};
m_AvarageUDR_list.AddTail(newitem);
sumavgUDR += sentBytesCompleteFile + sentBytesPartFile;
}
// remove to old values in list
while (m_AvarageUDR_list.GetCount() > 0 && (curTick - m_AvarageUDR_list.GetHead().timestamp) > 10*1000) {
// keep sum of all values in list up to date
sumavgUDR -= m_AvarageUDR_list.RemoveHead().datalen;
}
// Calculate average speed for this slot
if(m_AvarageUDR_list.GetCount() > 0 && (curTick - m_AvarageUDR_list.GetHead().timestamp) > 0 && GetUpStartTimeDelay() > 2*1000) {
m_nUpDatarate = ((ULONGLONG)sumavgUDR*1000) / (curTick-m_AvarageUDR_list.GetHead().timestamp);
} else {
// not enough values to calculate trustworthy speed. Use -1 to tell this
m_nUpDatarate = 0; //-1;
}
// Check if it's time to update the display.
if (curTick-m_lastRefreshedULDisplay > MINWAIT_BEFORE_ULDISPLAY_WINDOWUPDATE+(uint32)(rand()*800/RAND_MAX)) {
// Update display
theApp.emuledlg->transferwnd->uploadlistctrl.RefreshClient(this);
theApp.emuledlg->transferwnd->clientlistctrl.RefreshClient(this);
m_lastRefreshedULDisplay = curTick;
}
return sentBytesCompleteFile + sentBytesPartFile;
}
void CUpDownClient::FlushSendBlocks(){ // call this when you stop upload, or the socket might be not able to send
if (socket) //socket may be NULL...
socket->TruncateQueues();
}
void CUpDownClient::SendHashsetPacket(char* forfileid){
CKnownFile* file = theApp.sharedfiles->GetFileByID((uchar*)forfileid);
if (!file){
CheckFailedFileIdReqs((uchar*)forfileid);
throw GetResString(IDS_ERR_REQ_FNF) + _T(" (SendHashsetPacket)");
}
CSafeMemFile data(1024);
data.WriteHash16(file->GetFileHash());
UINT parts = file->GetHashCount();
data.WriteUInt16(parts);
for (UINT i = 0; i < parts; i++)
data.WriteHash16(file->GetPartHash(i));
if (thePrefs.GetDebugClientTCPLevel() > 0)
DebugSend("OP__HashSetAnswer", this, forfileid);
Packet* packet = new Packet(&data);
packet->opcode = OP_HASHSETANSWER;
theStats.AddUpDataOverheadFileRequest(packet->size);
socket->SendPacket(packet,true,true);
}
void CUpDownClient::ClearUploadBlockRequests()
{
FlushSendBlocks();
for (POSITION pos = m_BlockRequests_queue.GetHeadPosition();pos != 0;)
delete m_BlockRequests_queue.GetNext(pos);
m_BlockRequests_queue.RemoveAll();
for (POSITION pos = m_DoneBlocks_list.GetHeadPosition();pos != 0;)
delete m_DoneBlocks_list.GetNext(pos);
m_DoneBlocks_list.RemoveAll();
}
void CUpDownClient::SendRankingInfo(){
if (!ExtProtocolAvailable())
return;
uint16 nRank = theApp.uploadqueue->GetWaitingPosition(this);
if (!nRank)
return;
Packet* packet = new Packet(OP_QUEUERANKING,12,OP_EMULEPROT);
PokeUInt16(packet->pBuffer+0, nRank);
memset(packet->pBuffer+2, 0, 10);
if (thePrefs.GetDebugClientTCPLevel() > 0)
DebugSend("OP__QueueRank", this);
theStats.AddUpDataOverheadFileRequest(packet->size);
socket->SendPacket(packet,true,true);
}
void CUpDownClient::SendCommentInfo(/*const*/ CKnownFile *file)
{
if (!m_bCommentDirty || file == NULL || !ExtProtocolAvailable() || m_byAcceptCommentVer < 1)
return;
m_bCommentDirty = false;
uint8 rating = file->GetFileRate();
CStringA desc(file->GetFileComment());
if (file->GetFileRate() == 0 && desc.IsEmpty())
return;
CSafeMemFile data(256);
data.WriteUInt8(rating);
int length = desc.GetLength();
if (length > MAXFILECOMMENTLEN)
length = MAXFILECOMMENTLEN;
data.WriteUInt32(length);
if (length > 0)
data.Write(desc, length);
if (thePrefs.GetDebugClientTCPLevel() > 0)
DebugSend("OP__FileDesc", this, (char*)file->GetFileHash());
Packet *packet = new Packet(&data,OP_EMULEPROT);
packet->opcode = OP_FILEDESC;
theStats.AddUpDataOverheadFileRequest(packet->size);
socket->SendPacket(packet,true);
}
void CUpDownClient::AddRequestCount(const uchar* fileid)
{
for (POSITION pos = m_RequestedFiles_list.GetHeadPosition(); pos != 0; ){
Requested_File_Struct* cur_struct = m_RequestedFiles_list.GetNext(pos);
if (!md4cmp(cur_struct->fileid,fileid)){
if (::GetTickCount() - cur_struct->lastasked < MIN_REQUESTTIME && !GetFriendSlot()){
if (GetDownloadState() != DS_DOWNLOADING)
cur_struct->badrequests++;
if (cur_struct->badrequests == BADCLIENTBAN){
Ban();
}
}
else{
if (cur_struct->badrequests)
cur_struct->badrequests--;
}
cur_struct->lastasked = ::GetTickCount();
return;
}
}
Requested_File_Struct* new_struct = new Requested_File_Struct;
md4cpy(new_struct->fileid,fileid);
new_struct->lastasked = ::GetTickCount();
new_struct->badrequests = 0;
m_RequestedFiles_list.AddHead(new_struct);
}
void CUpDownClient::UnBan()
{
theApp.clientlist->AddTrackClient(this);
theApp.clientlist->RemoveBannedClient(GetIP());
SetUploadState(US_NONE);
ClearWaitStartTime();
theApp.emuledlg->transferwnd->ShowQueueCount(theApp.uploadqueue->GetWaitingUserCount());
for (POSITION pos = m_RequestedFiles_list.GetHeadPosition();pos != 0;)
{
Requested_File_Struct* cur_struct = m_RequestedFiles_list.GetNext(pos);
cur_struct->badrequests = 0;
cur_struct->lastasked = 0;
}
}
void CUpDownClient::Ban(LPCTSTR pszReason)
{
theApp.clientlist->AddTrackClient(this);
if (!IsBanned()){
if (thePrefs.GetLogBannedClients())
AddDebugLogLine(false,_T("Banned: %s; %s"), pszReason==NULL ? _T("Aggressive behaviour") : pszReason, DbgGetClientInfo());
}
#ifdef _DEBUG
else{
if (thePrefs.GetLogBannedClients())
AddDebugLogLine(false,_T("Banned: (refreshed): %s; %s"), pszReason==NULL ? _T("Aggressive behaviour") : pszReason, DbgGetClientInfo());
}
#endif
theApp.clientlist->AddBannedClient(GetIP());
SetUploadState(US_BANNED);
theApp.emuledlg->transferwnd->ShowQueueCount(theApp.uploadqueue->GetWaitingUserCount());
theApp.emuledlg->transferwnd->queuelistctrl.RefreshClient(this);
}
uint32 CUpDownClient::GetWaitStartTime() const
{
if (credits == NULL){
ASSERT ( false );
return 0;
}
uint32 dwResult = credits->GetSecureWaitStartTime(GetIP());
if (dwResult > m_dwUploadTime && IsDownloading()){
//this happens only if two clients with invalid securehash are in the queue - if at all
dwResult = m_dwUploadTime-1;
if (thePrefs.GetVerbose())
DEBUG_ONLY(AddDebugLogLine(false,_T("Warning: CUpDownClient::GetWaitStartTime() waittime Collision (%s)"),GetUserName()));
}
return dwResult;
}
void CUpDownClient::SetWaitStartTime(){
if (credits == NULL){
return;
}
credits->SetSecWaitStartTime(GetIP());
}
void CUpDownClient::ClearWaitStartTime(){
if (credits == NULL){
return;
}
credits->ClearWaitStartTime();
}
bool CUpDownClient::GetFriendSlot() const
{
if (credits && theApp.clientcredits->CryptoAvailable()){
switch(credits->GetCurrentIdentState(GetIP())){
case IS_IDFAILED:
case IS_IDNEEDED:
case IS_IDBADGUY:
return false;
}
}
return m_bFriendSlot;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -