📄 mmserver.cpp
字号:
//this file is part of eMule
//Copyright (C)2003-2004 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 "emule.h"
#include "mmserver.h"
#include "opcodes.h"
#include "md5sum.h"
#include "packets.h"
#include "searchlist.h"
#include "Exceptions.h"
#include "UploadQueue.h"
#include "DownloadQueue.h"
#include "Statistics.h"
#include "MMSocket.h"
#include "OtherFunctions.h"
#include "Sockets.h"
#include "Server.h"
#include "PartFile.h"
#include "KnownFileList.h"
#include "CxImage/xImage.h"
#include "WebServer.h"
#include "otherfunctions.h"
#include "Preferences.h"
#include "SearchParams.h"
#include "kademlia/kademlia/kademlia.h"
#include "emuledlg.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
#ifndef EWX_FORCEIFHUNG
#define EWX_FORCEIFHUNG 0x00000010
#endif
CMMServer::CMMServer(void)
{
m_SendSearchList.SetSize(0);
h_timer = NULL;
m_cPWFailed = 0;
m_dwBlocked = 0;
m_pSocket = NULL;
m_nSessionID = 0;
m_pPendingCommandSocket = NULL;
m_nMaxDownloads = 0;
m_nMaxBufDownloads = 0;
m_bGrabListLogin =false;
}
CMMServer::~CMMServer(void)
{
DeleteSearchFiles();
if (m_pSocket)
delete m_pSocket;
if (h_timer != NULL){
KillTimer(0,h_timer);
}
}
void CMMServer::Init(){
if (thePrefs.IsMMServerEnabled() && !m_pSocket){
m_pSocket = new CListenMMSocket(this);
if (!m_pSocket->Create()){
StopServer();
AddLogLine(false, GetResString(IDS_MMFAILED) );
}
else{
AddLogLine(false, GetResString(IDS_MMSTARTED), thePrefs.GetMMPort(), _T(MM_STRVERSION));
}
}
}
void CMMServer::StopServer(){
if (m_pSocket){
delete m_pSocket;
m_pSocket = NULL;
}
}
void CMMServer::DeleteSearchFiles(){
for (int i = 0; i!= m_SendSearchList.GetSize(); i++){
delete m_SendSearchList[i];
};
m_SendSearchList.SetSize(0);
}
bool CMMServer::PreProcessPacket(char* pPacket, uint32 nSize, CMMSocket* sender){
if (nSize >= 3){
uint16 nSessionID;
memcpy(&nSessionID,pPacket+1,sizeof(nSessionID));
if ( (m_nSessionID && nSessionID == m_nSessionID) || pPacket[0] == MMP_HELLO){
return true;
}
else{
CMMPacket* packet = new CMMPacket(MMP_INVALIDID);
sender->SendPacket(packet);
m_nSessionID = 0;
return false;
}
}
CMMPacket* packet = new CMMPacket(MMP_GENERALERROR);
sender->SendPacket(packet);
return false;
}
void CMMServer::ProcessHelloPacket(CMMData* data, CMMSocket* sender){
CMMPacket* packet = new CMMPacket(MMP_HELLOANS);
if (data->ReadByte() != MM_VERSION){
packet->WriteByte(MMT_WRONGVERSION);
sender->SendPacket(packet);
return;
}
else{
if(m_dwBlocked && m_dwBlocked > ::GetTickCount()){
packet->WriteByte(MMT_WRONGPASSWORD);
sender->SendPacket(packet);
return;
}
CString plainPW = data->ReadString();
CString testValue =MD5Sum(plainPW).GetHash();
if (testValue != thePrefs.GetMMPass() || plainPW.GetLength() == 0 ){
m_dwBlocked = 0;
packet->WriteByte(MMT_WRONGPASSWORD);
sender->SendPacket(packet);
m_cPWFailed++;
if (m_cPWFailed == 3){
AddLogLine(false, GetResString(IDS_MM_BLOCK));
m_cPWFailed = 0;
m_dwBlocked = ::GetTickCount() + MMS_BLOCKTIME;
}
return;
}
else{
m_bUseFakeContent = (data->ReadByte() != 0);
m_nMaxDownloads = data->ReadShort();
m_nMaxBufDownloads = data->ReadShort();
m_bGrabListLogin = (data->ReadByte() != 0);
// everything ok, new sessionid
AddLogLine(false, GetResString(IDS_MM_NEWUSER));
packet->WriteByte(MMT_OK);
m_nSessionID = rand();
packet->WriteShort(m_nSessionID);
packet->WriteString(thePrefs.GetUserNick());
packet->WriteShort((thePrefs.GetMaxUpload() == UNLIMITED) ? 0 : thePrefs.GetMaxUpload());
packet->WriteShort((thePrefs.GetMaxDownload() == UNLIMITED) ? 0 : thePrefs.GetMaxDownload());
ProcessStatusRequest(sender,packet);
//sender->SendPacket(packet);
}
}
}
void CMMServer::ProcessStatusRequest(CMMSocket* sender, CMMPacket* packet){
if (packet == NULL)
packet = new CMMPacket(MMP_STATUSANSWER);
else
packet->WriteByte(MMP_STATUSANSWER);
packet->WriteShort((uint16)theApp.uploadqueue->GetDatarate()/100);
packet->WriteShort((uint16)((thePrefs.GetMaxGraphUploadRate()*1024)/100));
packet->WriteShort((uint16)theApp.downloadqueue->GetDatarate()/100);
packet->WriteShort((uint16)((thePrefs.GetMaxGraphDownloadRate()*1024)/100));
packet->WriteByte((uint8)theApp.downloadqueue->GetDownloadingFileCount());
packet->WriteByte((uint8)theApp.downloadqueue->GetPausedFileCount());
packet->WriteInt(theStats.sessionReceivedBytes/1048576);
packet->WriteShort((uint16)((theStats.GetAvgDownloadRate(0)*1024)/100));
if (theApp.serverconnect->IsConnected()){
if(theApp.serverconnect->IsLowID())
packet->WriteByte(1);
else
packet->WriteByte(2);
if (theApp.serverconnect->GetCurrentServer() != NULL){
packet->WriteInt(theApp.serverconnect->GetCurrentServer()->GetUsers());
packet->WriteString(theApp.serverconnect->GetCurrentServer()->GetListName());
}
else{
packet->WriteInt(0);
packet->WriteString("");
}
}
else{
packet->WriteByte(0);
packet->WriteInt(0);
packet->WriteString("");
}
if(thePrefs.GetNetworkKademlia()){
if ( Kademlia::CKademlia::isConnected() ){
packet->WriteByte(2);
packet->WriteInt(Kademlia::CKademlia::getKademliaUsers());
}
else{
packet->WriteByte(1);
packet->WriteInt(0);
}
}
else{
packet->WriteByte(0);
packet->WriteInt(0);
}
sender->SendPacket(packet);
}
void CMMServer::ProcessFileListRequest(CMMSocket* sender, CMMPacket* packet){
if (packet == NULL)
packet = new CMMPacket(MMP_FILELISTANS);
else
packet->WriteByte(MMP_FILELISTANS);
int nCount = thePrefs.GetCatCount();
packet->WriteByte(nCount);
for (int i = 0; i != nCount; i++){
packet->WriteString(thePrefs.GetCategory(i)->title);
}
nCount = (theApp.downloadqueue->GetFileCount() > m_nMaxDownloads)? m_nMaxDownloads : theApp.downloadqueue->GetFileCount();
m_SentFileList.SetSize(nCount);
packet->WriteByte(nCount);
for (int i = 0; i != nCount; i++){
// while this is not the fastest method the trace this list, it's not timecritical here
CPartFile* cur_file = theApp.downloadqueue->GetFileByIndex(i);
if (cur_file == NULL){
delete packet;
packet = new CMMPacket(MMP_GENERALERROR);
sender->SendPacket(packet);
ASSERT ( false );
return;
}
m_SentFileList[i] = cur_file;
if (cur_file->GetStatus(false) == PS_PAUSED)
packet->WriteByte(MMT_PAUSED);
else{
if (cur_file->GetTransferingSrcCount() > 0)
packet->WriteByte(MMT_DOWNLOADING);
else
packet->WriteByte(MMT_WAITING);
}
packet->WriteString(cur_file->GetFileName());
packet->WriteByte(cur_file->GetCategory());
if (i < m_nMaxBufDownloads){
packet->WriteByte(1);
WriteFileInfo(cur_file,packet);
}
else{
packet->WriteByte(0);
}
}
sender->SendPacket(packet);
}
void CMMServer::ProcessFinishedListRequest(CMMSocket* sender){
CMMPacket* packet = new CMMPacket(MMP_FINISHEDANS);
int nCount = thePrefs.GetCatCount();
packet->WriteByte(nCount);
for (int i = 0; i != nCount; i++){
packet->WriteString(thePrefs.GetCategory(i)->title);
}
nCount = (m_SentFinishedList.GetCount() > 30)? 30 : m_SentFinishedList.GetCount();
packet->WriteByte(nCount);
for (int i = 0; i != nCount; i++){
CKnownFile* cur_file = m_SentFinishedList[i];
packet->WriteByte(0xFF);
packet->WriteString(cur_file->GetFileName());
if (cur_file->IsPartFile())
packet->WriteByte(((CPartFile*)cur_file)->GetCategory());
else
packet->WriteByte(0);
}
sender->SendPacket(packet);
}
void CMMServer::ProcessFileCommand(CMMData* data, CMMSocket* sender){
uint8 byCommand = data->ReadByte();
uint8 byFileIndex = data->ReadByte();
if (byFileIndex >= m_SentFileList.GetSize()
|| !theApp.downloadqueue->IsPartFile(m_SentFileList[byFileIndex]))
{
CMMPacket* packet = new CMMPacket(MMP_GENERALERROR);
sender->SendPacket(packet);
ASSERT ( false );
return;
}
CPartFile* selFile = m_SentFileList[byFileIndex];
switch (byCommand){
case MMT_PAUSE:
selFile->PauseFile();
break;
case MMT_RESUME:
selFile->ResumeFile();
break;
case MMT_CANCEL:{
switch(selFile->GetStatus()) {
case PS_WAITINGFORHASH:
case PS_HASHING:
case PS_COMPLETING:
case PS_COMPLETE:
break;
case PS_PAUSED:
selFile->DeleteFile();
break;
default:
theApp.downloadqueue->StartNextFileIfPrefs(selFile->GetCategory());
selFile->DeleteFile();
}
break;
}
default:
CMMPacket* packet = new CMMPacket(MMP_GENERALERROR);
sender->SendPacket(packet);
return;
}
CMMPacket* packet = new CMMPacket(MMP_FILECOMMANDANS);
ProcessFileListRequest(sender,packet);
}
void CMMServer::ProcessDetailRequest(CMMData* data, CMMSocket* sender){
uint8 byFileIndex = data->ReadByte();
if (byFileIndex >= m_SentFileList.GetSize()
|| !theApp.downloadqueue->IsPartFile(m_SentFileList[byFileIndex]))
{
CMMPacket* packet = new CMMPacket(MMP_GENERALERROR);
sender->SendPacket(packet);
ASSERT ( false );
return;
}
CPartFile* selFile = m_SentFileList[byFileIndex];
CMMPacket* packet = new CMMPacket(MMP_FILEDETAILANS);
WriteFileInfo(selFile, packet);
sender->SendPacket(packet);
}
void CMMServer::ProcessCommandRequest(CMMData* data, CMMSocket* sender){
uint8 byCommand = data->ReadByte();
bool bSuccess = false;
bool bQueueCommand = false;
switch(byCommand){
case MMT_SDEMULE:
case MMT_SDPC:
h_timer = SetTimer(0,0,5000,CommandTimer);
if (h_timer)
bSuccess = true;
bQueueCommand = true;
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -