📄 sharedfilelist.cpp
字号:
//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 "sharedfilelist.h"
#include "knownfilelist.h"
#include "packets.h"
#include <time.h>
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
CSharedFileList::CSharedFileList(CPreferences* in_prefs,CServerConnect* in_server,CKnownFileList* in_filelist){
app_prefs = in_prefs;
server = in_server;
filelist = in_filelist;
output = 0;
m_Files_map.InitHashTable(1024);
FindSharedFiles();
}
CSharedFileList::~CSharedFileList(){
}
void CSharedFileList::FindSharedFiles(){
if (!m_Files_map.IsEmpty()){
CSingleLock sLock1(&list_mut,true); // list thread safe
m_Files_map.RemoveAll();
sLock1.Unlock();
theApp.downloadqueue->AddPartFilesToShare(); // read partfiles
}
AddFilesFromDirectory(app_prefs->GetIncomingDir());
if (theApp.glob_prefs->GetCatCount()>1)
for (int ix=1;ix<theApp.glob_prefs->GetCatCount();ix++) {
AddFilesFromDirectory(theApp.glob_prefs->GetCatPath(ix));
}
for (POSITION pos = app_prefs->shareddir_list.GetHeadPosition();pos != 0;app_prefs->shareddir_list.GetNext(pos))
AddFilesFromDirectory(app_prefs->shareddir_list.GetAt(pos).GetBuffer());
if (waitingforhash_list.IsEmpty())
theApp.emuledlg->AddLogLine(false,GetResString(IDS_SHAREDFOUND),m_Files_map.GetCount());
else
theApp.emuledlg->AddLogLine(false,GetResString(IDS_SHAREDFOUNDHASHING),m_Files_map.GetCount(),waitingforhash_list.GetCount());
HashNextFile();
}
void CSharedFileList::AddFilesFromDirectory(char* directory){
CFileFind ff;
char* searchpath = new char[strlen(directory)+3];
sprintf(searchpath,"%s\\*",directory);
bool end = !ff.FindFile(searchpath,0);
delete[] searchpath;
if (end)
return;
while (!end){
end = !ff.FindNextFile();
if (ff.IsDirectory() || ff.IsDots() || ff.IsSystem() || ff.IsTemporary() || ff.GetLength()>=4294967295 )
continue;
CTime lwtime;
ff.GetLastWriteTime(lwtime);
uint32 fdate = mktime(lwtime.GetLocalTm());
CKnownFile* toadd = filelist->FindKnownFile(ff.GetFileName().GetBuffer(),fdate,(uint32)ff.GetLength());
if (toadd){
toadd->SetPath(directory);
CSingleLock sLock(&list_mut,true);
m_Files_map.SetAt(CCKey(toadd->GetFileHash()),toadd);
sLock.Unlock();
}
else{
//not in knownfilelist - start adding thread to hash file
UnknownFile_Struct* tohash = new UnknownFile_Struct;
tohash->directory = nstrdup(directory);
tohash->name = nstrdup(ff.GetFileName().GetBuffer());
waitingforhash_list.AddTail(tohash);
}
}
ff.Close();
}
void CSharedFileList::SafeAddKFile(CKnownFile* toadd, bool bOnlyAdd){
// TODO: Check if the file is already known - only with another date
CSingleLock sLock(&list_mut,true);
m_Files_map.SetAt(CCKey(toadd->GetFileHash()),toadd);
sLock.Unlock();
if (bOnlyAdd)
return;
if (output)
output->ShowFile(toadd);
HashNextFile();
// offer new file to server
if (!server->IsConnected())
return;
CMemFile* files = new CMemFile(100);
uint32 filecount = 1;
files->Write(&filecount,4);
CreateOfferedFilePacket(toadd,files);
Packet* packet = new Packet(files);
packet->opcode = OP_OFFERFILES;
delete files;
theApp.uploadqueue->AddUpDataOverheadServer(packet->size);
server->SendPacket(packet,true);
}
// removes first occurrence of 'toremove' in 'list'
void CSharedFileList::RemoveFile(CKnownFile* toremove){
output->RemoveFile(toremove);
m_Files_map.RemoveKey(CCKey(toremove->GetFileHash()));
}
void CSharedFileList::Reload(bool sendtoserver){
this->FindSharedFiles();
if (output)
output->ShowFileList(this);
if (sendtoserver)
SendListToServer();
}
void CSharedFileList::SetOutputCtrl(CSharedFilesCtrl* in_ctrl){
output = in_ctrl;
output->ShowFileList(this);
}
void CSharedFileList::SendListToServer(){
if (m_Files_map.IsEmpty() || !server->IsConnected())
return;
CMemFile* files = new CMemFile();
uint32 filecount = m_Files_map.GetCount();
files->Write(&filecount,4);
CCKey bufKey;
CKnownFile* cur_file;
for (POSITION pos = m_Files_map.GetStartPosition();pos != 0;){
m_Files_map.GetNextAssoc(pos,bufKey,cur_file);
CreateOfferedFilePacket(cur_file,files);
}
Packet* packet = new Packet(files);
packet->opcode = OP_OFFERFILES;
delete files;
theApp.uploadqueue->AddUpDataOverheadServer(packet->size);
server->SendPacket(packet,true);
}
CKnownFile* CSharedFileList::GetFileByIndex(int index){
int count=0;
CKnownFile* cur_file;
CCKey bufKey;
for (POSITION pos = m_Files_map.GetStartPosition();pos != 0;){
m_Files_map.GetNextAssoc(pos,bufKey,cur_file);
if (index==count) return cur_file;
count++;
}
return 0;
}
void CSharedFileList::CreateOfferedFilePacket(CKnownFile* cur_file,CMemFile* files){
files->Write(cur_file->GetFileHash(),16);
char* buffer = new char[6];
memset(buffer,0,6);
files->Write(buffer,6);
delete[] buffer;
files->Write(cur_file->GetFileTypePtr(),4);
CTag* nametag = new CTag(FT_FILENAME,cur_file->GetFileName());
nametag->WriteTagToFile(files);
delete nametag;
CTag* sizetag = new CTag(FT_FILESIZE,cur_file->GetFileSize());
sizetag->WriteTagToFile(files);
delete sizetag;
//TODO add tags for documents mp3 etc
}
uint64 CSharedFileList::GetDatasize() {
uint64 fsize;
fsize=0;
CCKey bufKey;
CKnownFile* cur_file;
for (POSITION pos = m_Files_map.GetStartPosition();pos != 0;){
m_Files_map.GetNextAssoc(pos,bufKey,cur_file);
fsize+=cur_file->GetFileSize();
}
return fsize;
}
CKnownFile* CSharedFileList::GetFileByID(uchar* filehash){
CKnownFile* result;
CCKey tkey(filehash);
if (m_Files_map.Lookup(tkey,result))
return result;
else
return 0;
}
void CSharedFileList::HashNextFile(){
if (waitingforhash_list.IsEmpty())
return;
UnknownFile_Struct* nextfile = waitingforhash_list.RemoveHead();
CAddFileThread* addfilethread = (CAddFileThread*) AfxBeginThread(RUNTIME_CLASS(CAddFileThread), THREAD_PRIORITY_BELOW_NORMAL,0, CREATE_SUSPENDED);
addfilethread->SetValues(this,nextfile->directory,nextfile->name);
addfilethread->ResumeThread();
delete[] nextfile->directory;
delete[] nextfile->name;
delete nextfile;
}
IMPLEMENT_DYNCREATE(CAddFileThread, CWinThread)
CAddFileThread::CAddFileThread(){
m_pOwner = 0;
filename = 0;
directory = 0;
}
void CAddFileThread::SetValues(CSharedFileList* pOwner, char* in_directory, char* in_filename, CPartFile* in_partfile_Owner){
m_pOwner = pOwner;
directory = nstrdup(in_directory);
filename = nstrdup(in_filename);
partfile_Owner = in_partfile_Owner;
}
int CAddFileThread::Run(){
if (!(m_pOwner || partfile_Owner) || !filename)
AfxEndThread(0,true);
CSingleLock sLock1(&(theApp.hashing_mut)); // only one filehash at a time
sLock1.Lock();
CKnownFile* newrecord = new CKnownFile();
if (newrecord->CreateFromFile(directory,filename)){
PostMessage(theApp.emuledlg->m_hWnd,TM_FINISHEDHASHING,(m_pOwner ? 0:(WPARAM)partfile_Owner),(LPARAM)newrecord);
}
else{
delete newrecord;
}
delete[] filename;
if (directory)
delete[] directory;
sLock1.Unlock();
AfxEndThread(0,true);
return 0;
}
void CSharedFileList::UpdateFile(CKnownFile* toupdate) {output->UpdateFile(toupdate);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -