📄 clientcredits.cpp
字号:
//this file is part of eMule
//Copyright (C)2002 Merkur ( devs@emule-project.net / http://www.emule-project.net )
//
//This program is free software; you can redistribute it and/or
//modify it under the terms of the GNU General Public License
//as published by the Free Software Foundation; either
//version 2 of the License, or (at your option) any later version.
//
//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//GNU General Public License for more details.
//
//You should have received a copy of the GNU General Public License
//along with this program; if not, write to the Free Software
//Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#include "stdafx.h"
#include <math.h>
#include "emule.h"
#include "ClientCredits.h"
#include "OtherFunctions.h"
#include "Preferences.h"
#include "SafeFile.h"
#include "Opcodes.h"
#include "Sockets.h"
#include <crypto51/base64.h>
#include <crypto51/osrng.h>
#include <crypto51/files.h>
#include <crypto51/sha.h>
#include "emuledlg.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
#define CLIENTS_MET_FILENAME _T("clients.met")
CClientCredits::CClientCredits(CreditStruct* in_credits)
{
m_pCredits = in_credits;
InitalizeIdent();
m_dwUnSecureWaitTime = 0;
m_dwSecureWaitTime = 0;
m_dwWaitTimeIP = 0;
}
CClientCredits::CClientCredits(const uchar* key)
{
m_pCredits = new CreditStruct;
memset(m_pCredits, 0, sizeof(CreditStruct));
md4cpy(m_pCredits->abyKey, key);
InitalizeIdent();
m_dwUnSecureWaitTime = ::GetTickCount();
m_dwSecureWaitTime = ::GetTickCount();
m_dwWaitTimeIP = 0;
}
CClientCredits::~CClientCredits()
{
delete m_pCredits;
}
void CClientCredits::AddDownloaded(uint32 bytes, uint32 dwForIP) {
if ( ( GetCurrentIdentState(dwForIP) == IS_IDFAILED || GetCurrentIdentState(dwForIP) == IS_IDBADGUY || GetCurrentIdentState(dwForIP) == IS_IDNEEDED) && theApp.clientcredits->CryptoAvailable() ){
return;
}
//encode
uint64 current=m_pCredits->nDownloadedHi;
current=(current<<32)+ m_pCredits->nDownloadedLo + bytes ;
//recode
m_pCredits->nDownloadedLo=(uint32)current;
m_pCredits->nDownloadedHi=(uint32)(current>>32);
}
void CClientCredits::AddUploaded(uint32 bytes, uint32 dwForIP) {
if ( ( GetCurrentIdentState(dwForIP) == IS_IDFAILED || GetCurrentIdentState(dwForIP) == IS_IDBADGUY || GetCurrentIdentState(dwForIP) == IS_IDNEEDED) && theApp.clientcredits->CryptoAvailable() ){
return;
}
//encode
uint64 current=m_pCredits->nUploadedHi;
current=(current<<32)+ m_pCredits->nUploadedLo + bytes ;
//recode
m_pCredits->nUploadedLo=(uint32)current;
m_pCredits->nUploadedHi=(uint32)(current>>32);
}
uint64 CClientCredits::GetUploadedTotal() const{
return ( (uint64)m_pCredits->nUploadedHi<<32)+m_pCredits->nUploadedLo;
}
uint64 CClientCredits::GetDownloadedTotal() const{
return ( (uint64)m_pCredits->nDownloadedHi<<32)+m_pCredits->nDownloadedLo;
}
float CClientCredits::GetScoreRatio(uint32 dwForIP) const
{
// check the client ident status
if ( ( GetCurrentIdentState(dwForIP) == IS_IDFAILED || GetCurrentIdentState(dwForIP) == IS_IDBADGUY || GetCurrentIdentState(dwForIP) == IS_IDNEEDED) && theApp.clientcredits->CryptoAvailable() ){
// bad guy - no credits for you
return 1;
}
if (GetDownloadedTotal() < 1000000)
return 1;
float result = 0;
if (!GetUploadedTotal())
result = 10;
else
result = (float)(((double)GetDownloadedTotal()*2.0)/(double)GetUploadedTotal());
float result2 = 0;
result2 = (float)GetDownloadedTotal()/1048576.0;
result2 += 2;
result2 = (double)sqrt((double)result2);
if (result > result2)
result = result2;
if (result < 1)
return 1;
else if (result > 10)
return 10;
return result;
}
CClientCreditsList::CClientCreditsList()
{
m_nLastSaved = ::GetTickCount();
LoadList();
InitalizeCrypting();
}
CClientCreditsList::~CClientCreditsList()
{
SaveList();
CClientCredits* cur_credit;
CCKey tmpkey(0);
POSITION pos = m_mapClients.GetStartPosition();
while (pos){
m_mapClients.GetNextAssoc(pos, tmpkey, cur_credit);
delete cur_credit;
}
delete m_pSignkey;
}
void CClientCreditsList::LoadList()
{
CString strFileName = thePrefs.GetConfigDir() + CString(CLIENTS_MET_FILENAME);
const int iOpenFlags = CFile::modeRead|CFile::osSequentialScan|CFile::typeBinary|CFile::shareDenyWrite;
CSafeBufferedFile file;
CFileException fexp;
if (!file.Open(strFileName, iOpenFlags, &fexp)){
if (fexp.m_cause != CFileException::fileNotFound){
CString strError(GetResString(IDS_ERR_LOADCREDITFILE));
TCHAR szError[MAX_CFEXP_ERRORMSG];
if (fexp.GetErrorMessage(szError, ARRSIZE(szError))){
strError += _T(" - ");
strError += szError;
}
AddLogLine(true, _T("%s"), strError);
}
return;
}
setvbuf(file.m_pStream, NULL, _IOFBF, 16384);
try{
uint8 version = file.ReadUInt8();
if (version != CREDITFILE_VERSION && version != CREDITFILE_VERSION_29){
AddLogLine(false, GetResString(IDS_ERR_CREDITFILEOLD));
file.Close();
return;
}
// everything is ok, lets see if the backup exist...
CString strBakFileName;
strBakFileName.Format(_T("%s") CLIENTS_MET_FILENAME _T(".BAK"), thePrefs.GetConfigDir());
DWORD dwBakFileSize = 0;
BOOL bCreateBackup = TRUE;
HANDLE hBakFile = ::CreateFile(strBakFileName, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hBakFile != INVALID_HANDLE_VALUE)
{
// Ok, the backup exist, get the size
dwBakFileSize = ::GetFileSize(hBakFile, NULL); //debug
if (dwBakFileSize > (DWORD)file.GetLength())
{
// the size of the backup was larger then the org. file, something is wrong here, don't overwrite old backup..
bCreateBackup = FALSE;
}
//else: backup is smaller or the same size as org. file, proceed with copying of file
::CloseHandle(hBakFile);
}
//else: the backup doesn't exist, create it
if (bCreateBackup)
{
file.Close(); // close the file before copying
if (!::CopyFile(strFileName, strBakFileName, FALSE))
AddLogLine(false, GetResString(IDS_ERR_MAKEBAKCREDITFILE));
// reopen file
CFileException fexp;
if (!file.Open(strFileName, iOpenFlags, &fexp)){
CString strError(GetResString(IDS_ERR_LOADCREDITFILE));
TCHAR szError[MAX_CFEXP_ERRORMSG];
if (fexp.GetErrorMessage(szError, ARRSIZE(szError))){
strError += _T(" - ");
strError += szError;
}
AddLogLine(true, _T("%s"), strError);
return;
}
setvbuf(file.m_pStream, NULL, _IOFBF, 16384);
file.Seek(1, CFile::begin); //set filepointer behind file version byte
}
UINT count = file.ReadUInt32();
m_mapClients.InitHashTable(count+5000); // TODO: should be prime number... and 20% larger
const uint32 dwExpired = time(NULL) - 12960000; // today - 150 day
uint32 cDeleted = 0;
for (UINT i = 0; i < count; i++){
CreditStruct* newcstruct = new CreditStruct;
memset(newcstruct, 0, sizeof(CreditStruct));
if (version == CREDITFILE_VERSION_29)
file.Read(newcstruct, sizeof(CreditStruct_29a));
else
file.Read(newcstruct, sizeof(CreditStruct));
if (newcstruct->nLastSeen < dwExpired){
cDeleted++;
delete newcstruct;
continue;
}
CClientCredits* newcredits = new CClientCredits(newcstruct);
m_mapClients.SetAt(CCKey(newcredits->GetKey()), newcredits);
}
file.Close();
if (cDeleted>0) AddLogLine(false, GetResString(IDS_CREDITFILELOADED) + GetResString(IDS_CREDITSEXPIRED), count-cDeleted,cDeleted);
else AddLogLine(false, GetResString(IDS_CREDITFILELOADED), count);
}
catch(CFileException* error){
if (error->m_cause == CFileException::endOfFile)
AddLogLine(true, GetResString(IDS_CREDITFILECORRUPT));
else{
TCHAR buffer[MAX_CFEXP_ERRORMSG];
error->GetErrorMessage(buffer, ARRSIZE(buffer));
AddLogLine(true, GetResString(IDS_ERR_CREDITFILEREAD), buffer);
}
error->Delete();
}
}
void CClientCreditsList::SaveList()
{
if (thePrefs.GetLogFileSaving())
AddDebugLogLine(false, _T("Saving clients credit list file \"%s\""), CLIENTS_MET_FILENAME);
m_nLastSaved = ::GetTickCount();
CString name = thePrefs.GetConfigDir() + CString(CLIENTS_MET_FILENAME);
CFile file;// no buffering needed here since we swap out the entire array
CFileException fexp;
if (!file.Open(name, CFile::modeWrite|CFile::modeCreate|CFile::typeBinary|CFile::shareDenyWrite, &fexp)){
CString strError(GetResString(IDS_ERR_FAILED_CREDITSAVE));
TCHAR szError[MAX_CFEXP_ERRORMSG];
if (fexp.GetErrorMessage(szError, ARRSIZE(szError))){
strError += _T(" - ");
strError += szError;
}
AddLogLine(true, _T("%s"), strError);
return;
}
uint32 count = m_mapClients.GetCount();
BYTE* pBuffer = new BYTE[count*sizeof(CreditStruct)];
CClientCredits* cur_credit;
CCKey tempkey(0);
POSITION pos = m_mapClients.GetStartPosition();
count = 0;
while (pos)
{
m_mapClients.GetNextAssoc(pos, tempkey, cur_credit);
if (cur_credit->GetUploadedTotal() || cur_credit->GetDownloadedTotal())
{
memcpy(pBuffer+(count*sizeof(CreditStruct)), cur_credit->GetDataStruct(), sizeof(CreditStruct));
count++;
}
}
try{
uint8 version = CREDITFILE_VERSION;
file.Write(&version, 1);
file.Write(&count, 4);
file.Write(pBuffer, count*sizeof(CreditStruct));
if (thePrefs.GetCommitFiles() >= 2 || (thePrefs.GetCommitFiles() >= 1 && !theApp.emuledlg->IsRunning()))
file.Flush();
file.Close();
}
catch(CFileException* error){
CString strError(GetResString(IDS_ERR_FAILED_CREDITSAVE));
TCHAR szError[MAX_CFEXP_ERRORMSG];
if (error->GetErrorMessage(szError, ARRSIZE(szError))){
strError += _T(" - ");
strError += szError;
}
AddLogLine(true, _T("%s"), strError);
error->Delete();
}
delete[] pBuffer;
}
CClientCredits* CClientCreditsList::GetCredit(const uchar* key)
{
CClientCredits* result;
CCKey tkey(key);
if (!m_mapClients.Lookup(tkey, result)){
result = new CClientCredits(key);
m_mapClients.SetAt(CCKey(result->GetKey()), result);
}
result->SetLastSeen();
return result;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -