⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mmserver.cpp

📁 电驴的源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//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 + -