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

📄 serverlist.cpp

📁 非常出名开源客户端下载的程序emule
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//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 "serverlist.h"
#include "emule.h"
#include "HttpDownloadDlg.h"
#include "safefile.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif


CServerList::CServerList(CPreferences* in_prefs){
	servercount = 0;
	version = 0;
	serverpos = 0;
	searchserverpos = 0;
	statserverpos = 0;
	app_prefs = in_prefs;
	udp_timer = 0;
	delservercount = 0;
	m_nLastSaved = ::GetTickCount();
}

void CServerList::AutoUpdate(){
	if (app_prefs->adresses_list.IsEmpty()){
		MessageBox(0,GetResString(IDS_ERR_EMPTYADRESSESDAT),GetResString(IDS_ERR_EMPTYADRESSESDAT_TITLE),64);
		return;
	}
	bool bDownloaded=false;
	CString servermetdownload;
	CString servermetbackup;
	CString servermet;
	CString strURLToDownload; 
	servermetdownload.Format("%sserver_met.download",app_prefs->GetAppDir());
	servermetbackup.Format("%sserver_met.old",app_prefs->GetAppDir());
	servermet.Format("%sserver.met",app_prefs->GetAppDir());
	remove(servermetbackup);
	remove(servermetdownload);
	rename(servermet,servermetbackup);
	
	POSITION Pos = app_prefs->adresses_list.GetHeadPosition(); 
	while ((!bDownloaded) && (Pos != NULL)){
		CHttpDownloadDlg dlgDownload;
		strURLToDownload = app_prefs->adresses_list.GetNext(Pos); 
		dlgDownload.m_sURLToDownload = strURLToDownload.GetBuffer();
		dlgDownload.m_sFileToDownloadInto = servermetdownload;
		if (dlgDownload.DoModal() == IDOK){
			bDownloaded=true;
		}
		else{
			theApp.emuledlg->AddLogLine(true,GetResString(IDS_ERR_FAILEDDOWNLOADMET), strURLToDownload.GetBuffer());
		}
	}
	if (bDownloaded){
		rename(servermet, servermetdownload);
		rename(servermetbackup, servermet);
	}
	else{
		remove(servermet);
		rename(servermetbackup,servermet);
	}
}

bool CServerList::Init(){
	// auto update the list by using an url
	if (app_prefs->AutoServerlist())
		AutoUpdate();
	// Load Metfile
	CString strPath;
	strPath.Format( "%sserver.met", app_prefs->GetAppDir());
	bool bRes = AddServermetToList(strPath, false);
	if( theApp.glob_prefs->AutoServerlist() ){
		strPath.Format( "%sserver_met.download", app_prefs->GetAppDir());
		bool bRes2 = AddServermetToList(strPath);
		if( !bRes && bRes2 )
			bRes = true;
	}
	// insert static servers from textfile
	strPath.Format( "%sstaticservers.dat", app_prefs->GetAppDir());
	AddServersFromTextFile(strPath);
	return bRes;
}

bool CServerList::AddServermetToList(CString strFile, bool merge){
	if (!merge)
	{
		theApp.emuledlg->serverwnd.serverlistctrl.DeleteAllItems();
		this->RemoveAllServers();
	}
	CSafeFile servermet;
	try{
		if (!servermet.Open(strFile,CFile::modeRead|CFile::osSequentialScan)){
			if(!merge)
				theApp.emuledlg->AddLogLine(false,GetResString(IDS_ERR_LOADSERVERMET));
			return false;
		}
		servermet.Read(&version,1);
		if (version != 0xE0 && version != MET_HEADER){
			servermet.Close();
			theApp.emuledlg->AddLogLine(false,GetResString(IDS_ERR_BADSERVERMETVERSION),version);
			return false;
		}
		theApp.emuledlg->serverwnd.serverlistctrl.Hide();
		uint32 fservercount;
		servermet.Read(&fservercount,4);
		
		ServerMet_Struct sbuffer;
		uint32 iAddCount = 0;
		for (uint32 j = 0;j != fservercount;j++){
			// get server
			servermet.Read(&sbuffer,sizeof(ServerMet_Struct));
			CServer* newserver = new CServer(&sbuffer);
			//add tags
			for (uint32 i=0;i != sbuffer.tagcount;i++)
				newserver->AddTagFromFile(&servermet);
			// set listname for server
			if (!newserver->GetListName()){
				char* listname = new char[strlen(newserver->GetAddress())+8];
				sprintf(listname,"Server %s",newserver->GetAddress());
				newserver->SetListName(listname);
				delete listname;
			}
			if (!theApp.emuledlg->serverwnd.serverlistctrl.AddServer(newserver,true) ){
				CServer* update = theApp.serverlist->GetServerByAddress(newserver->GetAddress(), newserver->GetPort());
				if(update){
					update->SetListName( newserver->GetListName());
					if( newserver->GetDescription() )
						update->SetDescription( newserver->GetDescription());
					theApp.emuledlg->serverwnd.serverlistctrl.RefreshServer(update);
				}
				delete newserver;
			}
			else
				iAddCount++;
		}

		if (!merge)
			theApp.emuledlg->AddLogLine(true,GetResString(IDS_SERVERSFOUND),fservercount);
		else
			theApp.emuledlg->AddLogLine(true,GetResString(IDS_SERVERSADDED), iAddCount, fservercount-iAddCount);
		servermet.Close();
	}
	catch(CFileException* error){
		OUTPUT_DEBUG_TRACE();
		if (error->m_cause == CFileException::endOfFile)
			theApp.emuledlg->AddDebugLogLine(true,GetResString(IDS_ERR_BADSERVERLIST));
		else{
			char buffer[150];
			error->GetErrorMessage(buffer,150);
			theApp.emuledlg->AddDebugLogLine(true,GetResString(IDS_ERR_FILEERROR_SERVERMET),buffer);
		}
		error->Delete();	//memleak fix
	}
	theApp.emuledlg->serverwnd.serverlistctrl.Visable();
	return true;
}

bool CServerList::AddServer(CServer* in_server){
	
	if (theApp.glob_prefs->FilterServerByIP())
		if (in_server->HasDynIP() || theApp.ipfilter->IsFiltered(in_server->GetIP())) return false;

	if (theApp.glob_prefs->FilterBadIPs()) 
		if (  !IsGoodServerIP( in_server ))
			return false;

	CServer* test_server = GetServerByAddress(in_server->GetAddress(), in_server->GetPort());
	if (test_server){
		test_server->ResetFailedCount();
		theApp.emuledlg->serverwnd.serverlistctrl.RefreshServer( test_server );		
		return false;
	}
	list.AddTail(in_server);
	return true;
}

void CServerList::ServerStats(){
	if( theApp.serverconnect->IsConnected() && list.GetCount() > 0 ) {
		CServer* ping_server = GetNextStatServer();
		CServer* test = ping_server;
		if( !ping_server )
			return;
        while(ping_server->GetLastPinged() != 0 && (::GetTickCount() - ping_server->GetLastPinged()) < UDPSERVSTATREASKTIME){ 
			ping_server = this->GetNextStatServer();
			if( ping_server == test )
				return;
		}
		if( ping_server->GetFailedCount() >= theApp.glob_prefs->GetDeadserverRetries() && theApp.glob_prefs->DeadServer() ){
			theApp.emuledlg->serverwnd.serverlistctrl.RemoveServer(ping_server);
			return;
		}
		Packet* packet = new Packet( OP_GLOBSERVSTATREQ, 4 );
		srand((unsigned)time(NULL));
		uint32 time = 0x55AA0000 + (uint16)rand();
		ping_server->SetChallenge(time);
		memcpy( packet->pBuffer, &time, 4 );
		ping_server->SetLastPinged( ::GetTickCount() );
		ping_server->AddFailedCount();
		theApp.emuledlg->serverwnd.serverlistctrl.RefreshServer( ping_server );
		theApp.uploadqueue->AddUpDataOverheadServer(packet->size);
		theApp.serverconnect->SendUDPPacket( packet, ping_server, true );
		packet = new Packet( OP_SERVER_DESC_REQ,0);
		theApp.uploadqueue->AddUpDataOverheadServer(packet->size);
		theApp.serverconnect->SendUDPPacket( packet, ping_server, true );
	}
}

/*filter Servers with invalid IP's / Port
0.*
10.*
172.16.0.0 - 172.31.255.255
192.168.0.0 - 192.168.255.255
127.*
*/
bool CServerList::IsGoodServerIP(CServer* in_server){ 
	if (in_server->HasDynIP())
		return true;
	char * pch;

	char ipx[24];
	sprintf(ipx,"%s",in_server->GetFullIP());
	
	// Determine first and second number if the given IP
	pch = strtok (ipx,".");	CString first=pch;pch=strtok(NULL,".");	CString second=pch;

	int secondI=atoi(second);

	if (first=="172" && (secondI>=16 && secondI<=31) ) return false;

	if (first=="192" && secondI==168 ) return false;

	if (first=="0" || first=="10" || first=="127"
		|| in_server->GetPort()==0) return false;

	return true; 
}

void CServerList::RemoveServer(CServer* out_server){
	for(POSITION pos = list.GetHeadPosition(); pos != NULL; )
	{
		POSITION pos2 = pos;
		CServer* test_server = list.GetNext(pos);
		if (test_server == out_server){
			if (theApp.downloadqueue->cur_udpserver == out_server)
				theApp.downloadqueue->cur_udpserver = 0;
			list.RemoveAt(pos2);
			delservercount++;
			delete test_server;
			return;
		}
	}
}

void CServerList::RemoveAllServers(){
	for(POSITION pos = list.GetHeadPosition(); pos != NULL; pos = list.GetHeadPosition()) {
		delete list.GetAt(pos);
		list.RemoveAt(pos);
		delservercount++;
	}
}

void CServerList::GetStatus(uint32 &total, uint32 &failed, uint32 &user, uint32 &file, uint32 &tuser, uint32 &tfile,float &occ){
	total = list.GetCount();
	failed = 0;
	user = 0;
	file = 0;
	tuser=0;
	tfile = 0;
	occ=0;
	uint32 maxusers=0;
	uint32 tuserk = 0;

	CServer* curr;
	for (POSITION pos = list.GetHeadPosition(); pos !=0;list.GetNext(pos)){
		curr = (CServer*)list.GetAt(pos);
		if( curr->GetFailedCount() ){
			failed++;
		}
		else{
			user += curr->GetUsers();
			file += curr->GetFiles();
		}
		tuser += curr->GetUsers();
		tfile += curr->GetFiles();
		
		if (curr->GetMaxUsers()) {
			tuserk += curr->GetUsers(); // total users on servers with known maximum
			maxusers+=curr->GetMaxUsers();
		}
	}
	if (maxusers>0) occ=(float)(tuserk*100)/maxusers;
}

void CServerList::GetUserFileStatus(uint32 &user, uint32 &file){
	user = 0;
	file = 0;
	CServer* curr;
	for (POSITION pos = list.GetHeadPosition(); pos !=0;list.GetNext(pos)){
		curr = (CServer*)list.GetAt(pos);
		if( !curr->GetFailedCount() ){
			user += curr->GetUsers();
			file += curr->GetFiles();
		}
	}
}

CServerList::~CServerList(){
	SaveServermetToFile();
	for(POSITION pos = list.GetHeadPosition(); pos != NULL; pos = list.GetHeadPosition()) {
		delete list.GetAt(pos);
		list.RemoveAt(pos);
	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -