//this file is part of eMule
//Copyright (C)2002 Merkur ( merkur-@users.sourceforge.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 "clientcredits.h"
#include "opcodes.h"
#include "emule.h"
#include "safefile.h"
#include <math.h>
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
CClientCredits::CClientCredits(CreditStruct* in_credits)
{
m_pCredits = in_credits;
}
CClientCredits::CClientCredits(uchar* key)
{
m_pCredits = new CreditStruct;
memset(m_pCredits, 0, sizeof(CreditStruct));
memcpy(m_pCredits->abyKey, key, 16);
}
CClientCredits::~CClientCredits()
{
delete m_pCredits;
}
float CClientCredits::GetScoreRatio(){
{
if (m_pCredits->nDownloaded < 1000000)
return 1;
float result = 0;
if (!m_pCredits->nUploaded)
result = 10;
else
result = (float)(m_pCredits->nDownloaded*2)/m_pCredits->nUploaded;
float result2 = 0;
result2 = (float)(m_pCredits->nDownloaded/1048576);
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;
if ( (m_pCredits->nUploaded == 0) && ( m_pCredits->nDownloaded == 0 ))
return 9.0f;
if ( (m_pCredits->nUploaded < 100000) && ( m_pCredits->nDownloaded < 100000 ))
return 10.0f;
if ( (m_pCredits->nUploaded < 400000) && ( m_pCredits->nDownloaded < 800000))
return 10.5f;
if ( (m_pCredits->nUploaded < 800000) && ( m_pCredits->nDownloaded < 1200000))
return 12.0f;
if ( (m_pCredits->nUploaded < 1000000) && ( m_pCredits->nDownloaded < 2000000))
return 14.0f;
else
return 5.0f;
}
CClientCreditsList::CClientCreditsList(CPreferences* in_prefs)
{
m_pAppPrefs = in_prefs;
m_nLastSaved = ::GetTickCount();
LoadList();
}
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;
}
m_mapClients.RemoveAll();
}
void CClientCreditsList::LoadList()
{
CSafeFile file;
try{
CString strFileName = m_pAppPrefs->GetAppDir() + CString("clients.met");
if (!file.Open(strFileName, CFile::modeRead)){
theApp.emuledlg->AddLogLine(true, GetResString(IDS_ERR_LOADCREDITFILE));
return;
}
uint8 version;
file.Read(&version, 1);
if (version != CREDITFILE_VERSION){
theApp.emuledlg->AddLogLine(false, GetResString(IDS_ERR_CREDITFILEOLD));
file.Close();
return;
}
// everything is ok, lets see if the backup exist...
CString strBakFileName;
strBakFileName.Format("%sclients.met.BAK", m_pAppPrefs->GetAppDir());
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
BOOL bResult = ::CopyFile(strFileName, strBakFileName, FALSE);
DWORD dwError;
if (!bResult)
{
dwError = ::GetLastError(); // debug
theApp.emuledlg->AddLogLine(false, GetResString(IDS_ERR_MAKEBAKCREDITFILE));
}
// reopen file
if (!file.Open(strFileName, CFile::modeRead))
{
theApp.emuledlg->AddLogLine(true, GetResString(IDS_ERR_LOADCREDITFILE));
return;
}
file.Seek(1, CFile::begin); //set filepointer
}
uint32 count;
file.Read(&count, 4);
m_mapClients.InitHashTable(count+5000); // TODO: should be prime number... and 20% larger
for (uint32 i = 0; i != count; i++){
CreditStruct* newcstruct = new CreditStruct;
memset(newcstruct, 0, sizeof(CreditStruct));
file.Read(newcstruct, sizeof(CreditStruct));
CClientCredits* newcredits = new CClientCredits(newcstruct);
m_mapClients.SetAt(CCKey(newcredits->GetKey()), newcredits);
}
file.Close();
theApp.emuledlg->AddLogLine(false, GetResString(IDS_CREDITFILELOADED), count);
}
catch(CFileException* error){
//OUTPUT_DEBUG_TRACE();
if (error->m_cause == CFileException::endOfFile)
theApp.emuledlg->AddLogLine(true, GetResString(IDS_CREDITFILECORRUPT));
else{
char buffer[150];
error->GetErrorMessage(buffer, 150);
theApp.emuledlg->AddLogLine(true, GetResString(IDS_ERR_CREDITFILEREAD), buffer);
}
error->Delete();
}
}
void CClientCreditsList::SaveList()
{
uint32 count = m_mapClients.GetCount();
BYTE* pBuffer = new BYTE[count*sizeof(CreditStruct)];
CString name = m_pAppPrefs->GetAppDir() + CString("clients.met");
CFile file;
if (!file.Open(name, CFile::modeWrite|CFile::modeCreate))
{
theApp.emuledlg->AddLogLine(true, GetResString(IDS_ERR_FAILED_CREDITSAVE));
return;
}
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->GetDataStruct()->nUploaded + cur_credit->GetDataStruct()->nDownloaded > 0)
{
memcpy(pBuffer+(count*sizeof(CreditStruct)), cur_credit->GetDataStruct(), sizeof(CreditStruct));
count++;
}
}
uint8 version = CREDITFILE_VERSION;
file.Write(&version, 1);
file.Write(&count, 4);
file.Write(pBuffer, count*sizeof(CreditStruct));
file.Close();
delete[] pBuffer;
m_nLastSaved = ::GetTickCount();
}
CClientCredits* CClientCreditsList::GetCredit(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;
}
void CClientCreditsList::Process()
{
if (::GetTickCount() - m_nLastSaved > 70000)
SaveList();
}