//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(); }