diff -Naur a/configure.ac b/configure.ac
--- a/configure.ac	2016-10-06 19:01:54.000000000 +0800
+++ b/configure.ac	2016-10-14 12:33:51.660347919 +0800
@@ -89,6 +89,14 @@
 KDE_CONFIG_OPTIONS
 QT_CONFIG_OPTIONS
 
+#Dynamic Leecher Protection - Bill Lee
+AC_ARG_ENABLE(
+	[dlp],
+	[AS_HELP_STRING(
+		[--disable-dlp],
+		[Do not compile DLP.])],
+	[ENABLE_DLP=$enableval], [ENABLE_DLP=yes])
+
 # Default is yes, because they're most likely compatible.
 # However, this is only used when cross-compiling.
 AC_ARG_WITH(
@@ -457,6 +465,8 @@
 AM_CONDITIONAL(GENERATE_FLEX_HEADER, test x$HAVE_FLEX_EXTENDED = xyes)
 AM_CONDITIONAL(INSTALL_SKINS, test MULE_IS_ENABLED_ANY([monolithic, amule-gui]))
 AM_CONDITIONAL(PLASMAMULE, test MULE_IS_ENABLED([plasmamule]))
+#Dynamic Leech Protection - Bill Lee
+AM_CONDITIONAL(ENABLE_DLP, test x$ENABLE_DLP = xyes)
 
 AM_CONDITIONAL([COMPILE_LIB_COMMON],	[test MULE_IS_ENABLED_ANY([monolithic, amule-daemon, amulecmd, webserver, amule-gui, fileview])])
 AM_CONDITIONAL([COMPILE_LIB_EC],	[test MULE_IS_ENABLED_ANY([monolithic, amule-daemon, amulecmd, webserver, amule-gui])])
diff -Naur a/po/zh_CN.po b/po/zh_CN.po
--- a/po/zh_CN.po	2016-10-06 19:01:54.000000000 +0800
+++ b/po/zh_CN.po	2016-10-14 12:33:51.662347964 +0800
@@ -5,6 +5,7 @@
 # xiaoqiao <29551030@qq.com>, 2007, 2008.
 # JimHu <jimhuyiwei@gmail.com>, 2009.
 # Xiaoqiao <wo@xiaoqiao.me>, 2010.
+# Bill Lee <bill.lee.y@gmail.com>, 2010, 2011.
 # Yi Qi <u4781098@anu.edu.au>,2011.
 #
 msgid ""
@@ -467,6 +468,12 @@
 msgid "http://kademlia.scs.cs.nyu.edu\n"
 msgstr "http://kademlia.scs.cs.nyu.edu\n"
 
+msgid "\nDynamic Leech Protection\n"
+msgstr "\n动态吸血保护\n"
+
+msgid " Homepage: http://amule-dlp.googlecode.com \n"
+msgstr " 主页：http://amule-dlp.googlecode.com \n"
+
 #: src/amuleDlg.cpp:512 src/KadDlg.cpp:193 src/PartFile.cpp:918
 #: src/PartFile.cpp:926 src/PrefsUnifiedDlg.cpp:629
 #: src/PrefsUnifiedDlg.cpp:734 src/PrefsUnifiedDlg.cpp:847
@@ -3856,6 +3863,9 @@
 msgid "Click on this button to update the nodes list from URL ..."
 msgstr "按此更新节点列表自网址..."
 
+msgid "DLP Info"
+msgstr "动态反吸血信息"
+
 #: src/muuli_wdr.cpp:2649
 msgid "Nodes (0)"
 msgstr "节点（0）"
@@ -7682,6 +7692,48 @@
 #~ "\n"
 #~ "此外，浏览器设定已经被重设为系统默认值。如有必要，请重新配置浏览器选项。\n"
 
+msgid "Dynamic Leecher Protection Options"
+msgstr "动态反吸血保护选项"
+
+msgid "Reload antiLeech"
+msgstr "重新装载 antiLeech"
+
+msgid "Check bad modstring"
+msgstr "根据 Mod 名字检测吸血驴"
+
+msgid "Check bad username"
+msgstr "根据用户名字检测吸血驴"
+
+msgid "Check bad userhash"
+msgstr "检测错误的用户哈希值"
+
+msgid "Check bad hello tag"
+msgstr "根据握手标签(HelloTag)检测吸血驴"
+
+msgid "Check bad info tag"
+msgstr "根据 InfoTag 检测吸血驴"
+
+msgid "Check ghost mod"
+msgstr "检测幽灵客户端(Ghost Mod)"
+
+#~ msgid "Ban VeryCD easyMule2"
+#~ msgstr "屏蔽 VeryCD easyMule2"
+
+msgid "Ban eMule VeryCD mod(Please consider carefully whether to use)"
+msgstr "屏蔽 VeryCD eMule（请慎重考虑是否使用）"
+
+#~ msgid "Ban VeryCD miniMule"
+#~ msgstr "屏蔽 VeryCD miniMule"
+
+msgid "Trying to load antiLeech..."
+msgstr "尝试加载 antiLeech..."
+
+msgid "No antiLeech available!"
+msgstr "未找到 antiLeech!"
+
+msgid "Succeed loading antiLeech! Version: %d"
+msgstr "成功加载 antiLeech! 版本： %d"
+
 #~ msgid "Fetching status..."
 #~ msgstr "正在获取状态..."
 
diff -Naur a/src/BaseClient.cpp b/src/BaseClient.cpp
--- a/src/BaseClient.cpp	2016-10-06 19:01:54.000000000 +0800
+++ b/src/BaseClient.cpp	2016-10-14 12:35:45.793953665 +0800
@@ -1,4 +1,3 @@
-//
 // This file is part of the aMule Project.
 //
 // Copyright (c) 2003-2011 aMule Team ( admin@amule.org / http://www.amule.org )
@@ -23,6 +22,11 @@
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA
 //
 
+//Dynamic Leech Protect - Bill Lee
+#ifdef AMULE_DLP
+#include "DLP.h"
+#endif
+
 #include <wx/wx.h>
 #include <wx/mstream.h>
 #include <wx/tokenzr.h>
@@ -83,10 +87,8 @@
 #include "kademlia/kademlia/UDPFirewallTester.h"
 #include "kademlia/routing/RoutingZone.h"
 
-
 //#define __PACKET_DEBUG__
 
-
 // some client testing variables
 static wxString crash_name = wxT("[Invalid User Name]");
 static wxString empty_name = wxT("[Empty User Name]");
@@ -290,6 +292,10 @@
 	m_cMessagesReceived = 0;
 	m_cMessagesSent = 0;
 
+	#ifdef AMULE_DLP
+	dlp_nonofficialopcodes = false; //Dynamic Leecher Protect
+	#endif
+
 }
 
 
@@ -635,6 +641,15 @@
 				m_fSharedDirectories = 1;
 				dwEmuleTags |= 4;
 				break;
+			//Bill Lee start
+			//Dynamic Leecher Protection
+			#ifdef AMULE_DLP
+			default:	//if tag isn't those above, it may be used by leecher.
+				theDLP->CheckHelloTag(this, temptag.GetNameID());
+				dlp_nonofficialopcodes = true; //to detect Ghost Mod
+					break;
+			//Bill Lee end
+			#endif
 		}
 	}
 
@@ -717,6 +732,11 @@
 		Kademlia::CKademlia::Bootstrap(wxUINT32_SWAP_ALWAYS(GetIP()), GetKadPort());
 	}
 
+	//Dynamic Leecher Protection - Bill Lee
+	#ifdef AMULE_DLP
+	theDLP->DLPCheck(this);
+	#endif
+
 	return bIsMule;
 }
 
@@ -966,6 +986,14 @@
 							% GetClientFullInfo()
 					);
 
+					//Bill Lee start
+					//Dynamic Leecher Protection
+					#ifdef AMULE_DLP
+					theDLP->CheckInfoTag(this, temptag.GetNameID());
+					dlp_nonofficialopcodes = true;
+					#endif
+					//Bill Lee end
+
 					break;
 			}
 		}
@@ -1003,6 +1031,11 @@
 		m_byInfopacketsReceived |= IP_EMULEPROTPACK;
 	}
 
+	//Dynamic Leecher Protection - Added by Bill Lee
+	#ifdef AMULE_DLP
+	theDLP->DLPCheck(this);
+	#endif
+	
 	return (protocol_version == 0xFF); // This was a OS_Info?
 }
 
@@ -2302,7 +2335,7 @@
 }
 
 
-#ifdef __DEBUG__
+#if defined (__DEBUG__) || defined (AMULE_DLP)
 wxString CUpDownClient::GetClientFullInfo()
 {
 	if (m_clientVerString.IsEmpty()) {
diff -Naur a/src/CString_wx.h b/src/CString_wx.h
--- a/src/CString_wx.h	1970-01-01 08:00:00.000000000 +0800
+++ b/src/CString_wx.h	2016-10-14 12:33:51.664348010 +0800
@@ -0,0 +1,59 @@
+/**
+ * Author:	Bill Lee<bill.lee.y@gmail.com>
+ * License:	GNU GPL
+ */
+//---------------------
+#ifndef CSTRING_WX_H
+#define CSTRING_WX_H
+
+//#include <wx/wx.h>
+#include <wx/string.h>
+
+class CString : public wxString{
+	public:
+		CString(){}
+		CString(wxChar c, size_t n=1): wxString(c, n){}
+		CString(const wxChar* str): wxString(str){}
+		CString(const wxString& str): wxString(str){}
+		CString(const CString& str): wxString(str){}
+		//---------------------
+		CString& operator=(const wxChar* str){
+			wxString::operator=(str);
+			return *this;
+		}
+		//operator*() from wxString;
+		size_t GetLength()const{	return Length();	}
+		wxChar GetAt(size_t nIndex)const{	return GetChar(nIndex);	}
+		//IsEmpty() from wxString;
+		CString& TrimLeft(wxChar c){
+			size_t pos = find_first_not_of(c);
+			if(pos == 0)
+				return *this;
+			erase(0, pos);
+			return *this;
+		}
+		CString& TrimRight(wxChar c){
+			size_t pos = find_last_not_of(c) + 1;
+			if(pos == Length())
+				return *this;
+			erase(pos, Length() - pos);
+			return *this;
+		}
+		CString Trim(){
+			CString ret(*this);
+			ret.wxString::Trim(false);        /* wxString::Trim(bool fromright = true) */
+			ret.wxString::Trim(true);
+			return ret;
+		}
+		//Find(wxChar) and Find(wxChar*) from wxString;
+		int Find(const CString& str)const{	return wxString::Find(str.c_str());	}
+		int ReverseFind(const wxChar c)const{	return wxString::Find(c, true);	}
+		int ReverseFind(const wxChar* str)const{	return rfind(str);	}
+		int ReverseFind(const CString& str)const{	return rfind(str);	}
+		CString Right(size_t len)const{	return wxString::Right(len);	}
+		CString Left(size_t len)const{	return wxString::Left(len);	}
+		CString Mid(size_t first, size_t count = wxSTRING_MAXLEN)const{
+			return wxString::Mid(first, count);
+		}
+};
+#endif
diff -Naur a/src/DLP.cpp b/src/DLP.cpp
--- a/src/DLP.cpp	1970-01-01 08:00:00.000000000 +0800
+++ b/src/DLP.cpp	2016-10-14 12:33:51.664348010 +0800
@@ -0,0 +1,190 @@
+// Copyright (C) 2011 Bill Lee <bill.lee.y@gmail.com>
+//
+// 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA
+//
+#include "Logger.h"
+
+#include "DLP.h"
+#include "antiLeech.h"
+#include <wx/dynlib.h>                          /* Needed for wxDynamicLibrary */
+
+#include "DLPPref.h"
+#include "Preferences.h"	// Needed for CPreferences
+#include "amule.h"		// Needed for theApp
+
+#include <wx/stdpaths.h>                        /* Needed for wxStandardPaths */
+
+#define PRE_CHECK(tag)	if( (!c->IsBanned()) && antiLeech && (thePrefs::GetDLPCheckMask() & tagn) )
+
+void DLP::CheckHelloTag(CUpDownClient* c, UINT tagn){
+	PRE_CHECK(PF_HELLOTAG){
+		const wxChar* dlp_result = antiLeech->DLPCheckHelloTag(tagn);
+		if(dlp_result != NULL) {
+			wxString ret;
+			ret.Printf(_("[HelloTag %s] %s"), dlp_result, c->GetClientFullInfo().c_str());
+			//ret.Printf(_("[HelloTag %s] %s"), dlp_result, c->GetClientShortInfo().c_str());
+			c->Ban();
+			theApp->AddDLPMessageLine(ret);
+		}
+	}
+}
+
+void DLP::CheckInfoTag(CUpDownClient* c, UINT tagn){
+	PRE_CHECK(PF_INFOTAG){
+		const wxChar* dlp_result = antiLeech->DLPCheckInfoTag(tagn);
+		if(dlp_result != NULL) {
+			wxString ret;
+			ret.Printf(_("[InfoTag %s] %s"), dlp_result, c->GetClientFullInfo().c_str());
+			//ret.Printf(_("[InfoTag %s] %s"), dlp_result, c->GetClientShortInfo().c_str());
+			c->Ban();
+			theApp->AddDLPMessageLine(ret);
+		}
+	}
+}
+
+bool DLP::DLPCheck(CUpDownClient* c){
+	const wxChar* tmp = NULL;
+	wxString ret;
+	
+	unsigned int prefs = thePrefs::GetDLPCheckMask();
+
+	CString modver(c->GetClientModString());
+	CString clientver(c->GetClientVerString());
+	CString uname(c->GetUserName());
+	CString uhash(wxString(c->GetUserHash().EncodeSTL().c_str(), wxConvUTF8));
+	
+	//CheckGhostMod
+	if(prefs & PF_GHOSTMOD) {
+		if(c->HasNonOfficialOpCodes() && (modver.IsEmpty())) {
+			ret = _("GhostMod");
+			tmp = ret.c_str(); //char pointer
+		}
+	}
+
+	// Check bad modstring
+	if ((prefs & PF_MODSTRING) && (tmp == NULL)) {
+		if((tmp = antiLeech->DLPCheckModstring_Soft(modver.c_str(), clientver.c_str())) == NULL)
+			tmp = antiLeech->DLPCheckModstring_Hard(modver.c_str(), clientver.c_str());
+	}
+	/*
+	if ((prefs & PF_USERHASH) && (tmp == NULL)) {
+		// not finished
+	}
+	*/
+	// Check bad username
+	if ((prefs & PF_USERNAME) && (tmp == NULL)) {
+		if ((tmp = antiLeech->DLPCheckNameAndHashAndMod(uname, uhash, modver)) == NULL){
+			if( (tmp = antiLeech->DLPCheckUsername_Hard(uname.c_str())) == NULL )
+				tmp = antiLeech->DLPCheckUsername_Soft(uname.c_str());
+		}
+	}
+	
+
+	// Check VeryCD eMule
+	if ((prefs & PF_VERYCDEMULE) && (tmp == NULL)) {
+		if(modver.Find(wxT("VeryCD")) != wxNOT_FOUND){
+			ret = _("VeryCD Mod");
+			tmp = ret.c_str();
+		}
+	}
+	
+	if (tmp != NULL) {
+		ret = tmp;
+		wxString wxInfo;
+		wxInfo.Printf(wxT("[%s] %s"), ret.c_str(), c->GetClientFullInfo().c_str());
+		//wxInfo.Printf(wxT("[%s] %s"), ret.c_str(), c->GetClientShortInfo().c_str());
+		c->Ban();
+		theApp->AddDLPMessageLine(wxInfo);
+		return true;
+	}
+
+	return false;
+
+}
+
+int DLP::ReloadAntiLeech(){
+	//Unloading
+	AddLogLineN(  _("Checking if there is a antiLeech working..."));
+	if(antiLeechLib.IsLoaded()){
+		Destoryer fn = (Destoryer)(antiLeechLib.GetSymbol( wxT("destoryAntiLeechInstant")));
+		wxASSERT(fn);
+		AddLogLineN(  _("Unload previous antiLeech..."));
+		fn(antiLeech);
+		antiLeech = NULL;
+		antiLeechLib.Unload();
+	}
+	else
+		AddLogLineN(  _("No working antiLeech exists."));
+	//Get lib's location
+	wxStandardPathsBase &spb(wxStandardPaths::Get());
+#ifdef __WXMSW__
+	wxString dataDir(spb.GetPluginsDir());
+#elif defined(__WXMAC__)
+	wxString dataDir(spb.GetDataDir());
+#else
+	wxString dataDir(spb.GetDataDir().BeforeLast(wxT('/')) + wxT("/amule"));
+#endif
+	wxString localName = wxDynamicLibrary::CanonicalizeName(wxT("antiLeech"));
+	wxString systemwideFile(JoinPaths(dataDir, localName));
+	//wxString userFile(theApp->ConfigDir + localName);
+	wxString userFile(thePrefs::GetConfigDir() + localName);
+	wxString fallbackFile(wxT("antiLeech"));
+	//Try to load lib;
+	AddLogLineN(  _("Trying to load antiLeech..."));
+	if( !LoadFrom(userFile) ){
+		if( !LoadFrom(systemwideFile) ){
+			if( !LoadFrom(fallbackFile) ){
+				AddLogLineC(  _("No antiLeech available!"));
+				return 1;	//Not found
+			}
+		}
+	}
+	//Searching symbol "createAntiLeechInstant"
+	Creator fn = (Creator)(antiLeechLib.GetSymbol( wxT("createAntiLeechInstant") ));
+	if(!fn){
+		antiLeechLib.Unload();
+		AddLogLineC(  _("antiLeech found, but it seems not to be a valid antiLeech!"));
+		return 2;	//Found, but isn't antiLeech
+	}
+	//Try to create antiLeech
+	antiLeech = fn();
+	if(antiLeech){
+		wxString logline;
+		logline.Printf(_("Succeed loading antiLeech! Version: %d"), antiLeech->GetDLPVersion());
+		AddLogLineC( logline);
+		return 0;
+	}
+	//else
+	antiLeechLib.Unload();
+	AddLogLineC(  _("FAIL! An error occur when setting up antiLeech."));
+	return 3;	//Fail to create antiLeech instant
+
+}
+
+DLP::~DLP(){
+	if(antiLeechLib.IsLoaded()){
+		Destoryer fn = (Destoryer)(antiLeechLib.GetSymbol( wxT("destoryAntiLeechInstant")));
+		wxASSERT(fn);
+		AddLogLineN(  _("Unload previous antiLeech..."));
+		fn(antiLeech);
+		//antiLeech = NULL;
+		//antiLeechLib.Unload();
+	}
+}
+
+bool DLP::LoadFrom(wxString& file){
+	antiLeechLib.Load(file);
+	return antiLeechLib.IsLoaded();
+}
diff -Naur a/src/DLP.h b/src/DLP.h
--- a/src/DLP.h	1970-01-01 08:00:00.000000000 +0800
+++ b/src/DLP.h	2016-10-14 12:33:51.665348032 +0800
@@ -0,0 +1,45 @@
+// Copyright (C) 2011 Bill Lee <bill.lee.y@gmail.com>
+//
+// 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA
+//
+
+class IantiLeech;	//forward declaretion
+
+#include "updownclient.h"	// Needed for CUpDownClient
+#include "antiLeech_wx.h"
+
+#include <wx/dynlib.h>
+
+class DLP
+{
+public:
+	DLP() : antiLeech(NULL) {	ReloadAntiLeech();	}
+	~DLP();
+
+	void CheckHelloTag(CUpDownClient*, UINT tagnumber);
+	void CheckInfoTag(CUpDownClient*, UINT tagnumber);
+	bool DLPCheck(CUpDownClient*);
+
+	int ReloadAntiLeech();
+
+private:
+	typedef IantiLeech* (*Creator)();
+	typedef int (*Destoryer)(IantiLeech*);
+
+	wxDynamicLibrary antiLeechLib;
+	IantiLeech* antiLeech;
+
+	bool LoadFrom(wxString& file);
+};
diff -Naur a/src/DLPPref.h b/src/DLPPref.h
--- a/src/DLPPref.h	1970-01-01 08:00:00.000000000 +0800
+++ b/src/DLPPref.h	2016-10-14 12:33:51.665348032 +0800
@@ -0,0 +1,15 @@
+#ifndef ANTILEECH_AMULE_H
+#define ANTILEECH_AMULE_H
+
+/* Define DLPCheck prefs arg */
+#define PF_MODSTRING	0x1
+#define PF_USERHASH		0x2
+#define PF_USERNAME		0x4
+#define PF_HELLOTAG		0x8
+#define PF_INFOTAG		0x10
+#define PF_VERYCDEMULE	0x20
+//#define PF_EASYMULE		0x40
+//#define PF_MINIMULE	0x80
+#define PF_GHOSTMOD	0x100
+
+#endif
diff -Naur a/src/DownloadQueue.cpp b/src/DownloadQueue.cpp
--- a/src/DownloadQueue.cpp	2016-10-06 19:01:54.000000000 +0800
+++ b/src/DownloadQueue.cpp	2016-10-14 12:33:51.665348032 +0800
@@ -623,6 +623,15 @@
 		return;
 	}
 
+	//Dynamic Leecher Protect - Bill Lee
+	#ifdef AMULE_DLP
+	if ( source->IsBanned() ){
+		source->Safe_Delete();
+		return;
+	}
+	#endif
+	//Bill Lee end
+
 	// Filter sources which are known to be dead/useless
 	if ( theApp->clientlist->IsDeadSource( source ) || sender->IsDeadSource(source) ) {
 		source->Safe_Delete();
diff -Naur a/src/ExternalConn.cpp b/src/ExternalConn.cpp
--- a/src/ExternalConn.cpp	2016-10-06 19:01:54.000000000 +0800
+++ b/src/ExternalConn.cpp	2016-10-14 12:33:51.666348055 +0800
@@ -57,6 +57,9 @@
 #include "kademlia/kademlia/UDPFirewallTester.h"
 #include "Statistics.h"
 
+#ifdef AMULE_DLP
+#include "DLP.h"
+#endif
 
 //-------------------- File_Encoder --------------------
 
@@ -1384,6 +1387,15 @@
 				}
 			}
 			break;
+		//Dynamic Leech Protect - Bill Lee
+		#ifdef AMULE_DLP
+		case EC_OP_ANTILEECH_RELOAD:
+			if( theDLP->ReloadAntiLeech() )
+				response = new CECPacket(EC_OP_FAILED);
+			else
+				response = new CECPacket(EC_OP_NOOP);
+			break;
+		#endif
 		//
 		// Status requests
 		//
diff -Naur a/src/Logger.cpp b/src/Logger.cpp
--- a/src/Logger.cpp	2016-10-06 19:01:54.000000000 +0800
+++ b/src/Logger.cpp	2016-10-14 12:40:22.827322335 +0800
@@ -297,6 +297,8 @@
 }
 
 CLogger theLogger;
+//Dynamic Leech Protect - persmule
+CLogger dlpLogger;
 
 BEGIN_EVENT_TABLE(CLogger, wxEvtHandler)
 	EVT_MULE_LOGGING(CLogger::OnLoggingEvent)
diff -Naur a/src/Logger.h b/src/Logger.h
--- a/src/Logger.h	2016-10-06 19:01:54.000000000 +0800
+++ b/src/Logger.h	2016-10-14 12:41:14.694519856 +0800
@@ -310,6 +310,8 @@
 };
 
 extern CLogger theLogger;
+//Dynamic Leech Protect - persmule
+extern CLogger dlpLogger;
 
 /**
  * This class forwards log-lines from wxWidgets to CLogger.
@@ -456,5 +458,8 @@
 	#define AddLogLineF(string) theLogger.AddLogLine(__TFILE__, __LINE__, false, logStandard, string, false, false)
 #endif
 
+//Dynamic Leech Protect - persmule
+#define DlpAddLogLine(string) dlpLogger.AddLogLine(__TFILE__, __LINE__, false, logStandard, string, false, false)
+
 #endif
 // File_checked_for_headers
diff -Naur a/src/LoggerConsole.cpp b/src/LoggerConsole.cpp
--- a/src/LoggerConsole.cpp	2016-10-06 19:01:54.000000000 +0800
+++ b/src/LoggerConsole.cpp	2016-10-14 12:41:54.805446813 +0800
@@ -85,6 +85,8 @@
 }
 
 CLogger theLogger;
+//Dynamic Leech Protect - persmule
+CLogger dlpLogger;
 
 BEGIN_EVENT_TABLE(CLogger, wxEvtHandler)
 END_EVENT_TABLE()
diff -Naur a/src/Makefile.am b/src/Makefile.am
--- a/src/Makefile.am	2016-10-06 19:01:54.000000000 +0800
+++ b/src/Makefile.am	2016-10-14 12:33:51.666348055 +0800
@@ -179,6 +179,13 @@
 	kademlia/routing/RoutingZone.cpp
 
 
+#Dynamic Leecher Protection - Bill Lee
+if ENABLE_DLP
+core_sources += \
+	DLP.cpp
+AM_CPPFLAGS += -DAMULE_DLP
+endif
+
 gui_sources = \
 	amule-gui.cpp \
 	amuleDlg.cpp \
diff -Naur a/src/Preferences.cpp b/src/Preferences.cpp
--- a/src/Preferences.cpp	2016-10-06 19:01:54.000000000 +0800
+++ b/src/Preferences.cpp	2016-10-14 12:33:51.667348078 +0800
@@ -51,6 +51,11 @@
 
 #include "UserEvents.h"
 
+#ifdef AMULE_DLP
+#include "DLPPref.h"
+#include "antiLeech.h"
+#endif
+
 #ifndef AMULE_DAEMON
 #include <wx/valgen.h>
 #include "muuli_wdr.h"
@@ -344,6 +349,19 @@
 	wxWindow*	m_widget;
 };
 
+/* Dynamic Leecher Protection */
+#ifdef AMULE_DLP
+bool CPreferences::s_DLPCheckModString;
+bool CPreferences::s_DLPCheckUsername;
+bool CPreferences::s_DLPCheckUserHash;
+bool CPreferences::s_DLPCheckHelloTag;
+bool CPreferences::s_DLPCheckInfoTag;
+//bool CPreferences::s_DLPCheckEasyMule;
+bool CPreferences::s_DLPCheckVeryCDMod;
+//bool CPreferences::s_DLPCheckminiMule; //Added by Bill Lee
+bool CPreferences::s_DLPCheckGhostMod;
+unsigned int CPreferences::s_DLPCheckMask;
+#endif
 
 /** Cfg class for wxStrings. */
 class Cfg_Str : public Cfg_Tmpl<wxString>
@@ -953,6 +971,11 @@
 	s_userhash[5] = 14;
 	s_userhash[14] = 111;
 
+	// Dynamic Leecher Protection
+	#ifdef AMULE_DLP
+	CalcDLPCheckMask();
+	#endif
+
 #ifndef CLIENT_GUI
 	LoadPreferences();
 	ReloadSharedFolders();
@@ -1062,6 +1085,20 @@
 	NewCfgItem( IDC_NETWORKKAD, (new Cfg_Bool( wxT("/eMule/ConnectToKad"),	s_ConnectToKad, true )) );
 	NewCfgItem( IDC_NETWORKED2K, ( new Cfg_Bool( wxT("/eMule/ConnectToED2K"),	s_ConnectToED2K, true ) ));
 
+	/**
+	 * Dynamic Leecher Protection
+	 **/
+	#ifdef AMULE_DLP
+	NewCfgItem(IDC_CHECKMODSTRING, 		(new Cfg_Bool( wxT("/DLP/CheckModString"), s_DLPCheckModString, true )));
+	NewCfgItem(IDC_CHECKUSERNAME, 		(new Cfg_Bool( wxT("/DLP/CheckUsername"), s_DLPCheckUsername, true )));
+	NewCfgItem(IDC_CHECKUSERHASH, 		(new Cfg_Bool( wxT("/DLP/CheckUserHash"), s_DLPCheckUserHash, true )));
+	NewCfgItem(IDC_CHECKHELLOTAG, 		(new Cfg_Bool( wxT("/DLP/CheckHelloTag"), s_DLPCheckHelloTag, true )));
+	NewCfgItem(IDC_CHECKINFOTAG, 		(new Cfg_Bool( wxT("/DLP/CheckInfoTag"), s_DLPCheckInfoTag, true )));
+	//NewCfgItem(IDC_CHECKEASYMULE, 		(new Cfg_Bool( wxT("/DLP/CheckEasyMule"), s_DLPCheckEasyMule, true ))); //Modified by Bill Lee
+	NewCfgItem(IDC_CHECKVERYCDMOD, 		(new Cfg_Bool( wxT("/DLP/CheckVeryCDMod"), s_DLPCheckVeryCDMod, false )));
+	//NewCfgItem(IDC_CHECKMINIMULE,		(new Cfg_Bool( wxT("/DLP/CheckminiMule"), s_DLPCheckminiMule, true))); //Added by Bill Lee
+	NewCfgItem(IDC_CHECKGHOSTMOD, 		(new Cfg_Bool( wxT("/DLP/CheckGhostMod"), s_DLPCheckGhostMod, true ))); //Added by Bill Lee.
+	#endif
 
 	/**
 	 * Files
@@ -1471,6 +1508,11 @@
 	}
 
 	SavePreferences();
+	
+	// Dynamic Leecher Protection
+	#ifdef AMULE_DLP
+	CalcDLPCheckMask();
+	#endif
 
 	#ifndef CLIENT_GUI
 	CTextFile sdirfile;
@@ -1483,6 +1525,21 @@
 	#endif
 }
 
+#ifdef AMULE_DLP
+void CPreferences::CalcDLPCheckMask()
+{
+	s_DLPCheckMask = 0;
+	if (s_DLPCheckModString) s_DLPCheckMask |= PF_MODSTRING;
+	if (s_DLPCheckUsername) s_DLPCheckMask |= PF_USERNAME;
+	if (s_DLPCheckUserHash) s_DLPCheckMask |= PF_USERHASH;
+	if (s_DLPCheckHelloTag) s_DLPCheckMask |= PF_HELLOTAG;
+	if (s_DLPCheckInfoTag) s_DLPCheckMask |= PF_INFOTAG;
+	if (s_DLPCheckGhostMod) s_DLPCheckMask |= PF_GHOSTMOD;
+	//if (s_DLPCheckEasyMule) s_DLPCheckMask |= PF_EASYMULE;
+	if (s_DLPCheckVeryCDMod) s_DLPCheckMask |= PF_VERYCDEMULE;
+	//if (s_DLPCheckminiMule) s_DLPCheckMask |= PF_MINIMULE; //Added by Bill Lee
+}
+#endif
 
 CPreferences::~CPreferences()
 {
diff -Naur a/src/Preferences.h b/src/Preferences.h
--- a/src/Preferences.h	2016-10-06 19:01:54.000000000 +0800
+++ b/src/Preferences.h	2016-10-14 12:33:51.667348078 +0800
@@ -579,6 +579,11 @@
 	// Sleep
 	static bool		GetPreventSleepWhileDownloading() { return s_preventSleepWhileDownloading; }
 	static void		SetPreventSleepWhileDownloading(bool status) { s_preventSleepWhileDownloading = status; }
+	
+	// Dynamic Leecher Protection
+	#ifdef AMULE_DLP
+	static unsigned int GetDLPCheckMask()		{return s_DLPCheckMask;}
+	#endif
 protected:
 	static	int32 GetRecommendedMaxConnections();
 
@@ -599,6 +604,11 @@
 private:
 	void LoadPreferences();
 	void SavePreferences();
+	
+	// Dynamic Leecher Protection
+	#ifdef AMULE_DLP
+	void CalcDLPCheckMask();
+	#endif
 
 protected:
 	static wxString	s_configDir;
@@ -813,6 +823,20 @@
 	// Stats server
 	static wxString s_StatsServerName;
 	static wxString s_StatsServerURL;
+		
+	// Dynamic Leecher Protection
+	#ifdef AMULE_DLP
+	static bool s_DLPCheckModString;
+	static bool s_DLPCheckUsername;
+	static bool s_DLPCheckUserHash;
+	static bool s_DLPCheckHelloTag;
+	static bool s_DLPCheckInfoTag;
+	//static bool s_DLPCheckEasyMule;
+	static bool s_DLPCheckVeryCDMod;
+	//static bool s_DLPCheckminiMule; //Added by Bill Lee
+	static bool s_DLPCheckGhostMod; //Added by Bill Lee
+	static unsigned int s_DLPCheckMask;
+	#endif
 };
 
 
diff -Naur a/src/PrefsUnifiedDlg.cpp b/src/PrefsUnifiedDlg.cpp
--- a/src/PrefsUnifiedDlg.cpp	2016-10-06 19:01:54.000000000 +0800
+++ b/src/PrefsUnifiedDlg.cpp	2016-10-14 12:33:51.668348101 +0800
@@ -53,6 +53,11 @@
 #include "UserEvents.h"
 #include "PlatformSpecific.h"		// Needed for PLATFORMSPECIFIC_CAN_PREVENT_SLEEP_MODE
 
+//Dynamic Leech Protect - Bill Lee
+#ifdef AMULE_DLP
+#include "DLP.h"
+#endif
+
 BEGIN_EVENT_TABLE(PrefsUnifiedDlg,wxDialog)
 	// Events
 #define USEREVENTS_EVENT(ID, NAME, VARS) \
@@ -114,6 +119,11 @@
 	EVT_CHOICE(IDC_COLORSELECTOR,		PrefsUnifiedDlg::OnColorCategorySelected)
 	EVT_LIST_ITEM_SELECTED(ID_PREFSLISTCTRL,PrefsUnifiedDlg::OnPrefsPageChange)
 
+	//Dynamic Leech Protect - Bill Lee
+	#ifdef AMULE_DLP
+	EVT_BUTTON(IDC_RELOADANTILEECH,		PrefsUnifiedDlg::OnButtonReloadAntiLeech)
+	#endif
+
 	EVT_INIT_DIALOG(PrefsUnifiedDlg::OnInitDialog)
 
 	EVT_COMMAND_SCROLL(IDC_SLIDER,		PrefsUnifiedDlg::OnScrollBarChange)
@@ -187,6 +197,9 @@
 	{ wxTRANSLATE("Online Signature"),	PreferencesOnlineSigTab,	21 },
 	{ wxTRANSLATE("Advanced"),			PreferencesaMuleTweaksTab,	12 },
 	{ wxTRANSLATE("Events"),			PreferencesEventsTab,		5 }
+#ifdef AMULE_DLP
+	,{ wxTRANSLATE("DLP"),				PreferencesDLPTab,			5}
+#endif
 #ifdef __DEBUG__
 	,{ wxTRANSLATE("Debugging"),		PreferencesDebug,			25 }
 #endif
@@ -1076,6 +1089,21 @@
 	theApp->ipfilter->Update( CastChild( IDC_IPFILTERURL, wxTextCtrl )->GetValue() );
 }
 
+//Bill Lee
+#ifdef AMULE_DLP
+void PrefsUnifiedDlg::OnButtonReloadAntiLeech(wxCommandEvent& WXUNUSED(event)){
+	#ifndef CLIENT_GUI
+	if( theDLP->ReloadAntiLeech() )
+		wxMessageBox(_("Cannot load antiLeech!"), _("Message"), wxOK | wxICON_EXCLAMATION, this);
+	else
+		wxMessageBox(_("Succeed loading antiLeech!"), _("Message"), wxOK | wxICON_INFORMATION, this);
+	#else
+	AddLogLineN(_("Reload antiLeech from remote GUI has not been implemented."));
+	wxMessageBox(_("Sorry, it has not been implemented yet!"));
+	#endif
+}
+#endif
+
 
 void PrefsUnifiedDlg::OnPrefsPageChange(wxListEvent& event)
 {
diff -Naur a/src/PrefsUnifiedDlg.h b/src/PrefsUnifiedDlg.h
--- a/src/PrefsUnifiedDlg.h	2016-10-06 19:01:54.000000000 +0800
+++ b/src/PrefsUnifiedDlg.h	2016-10-14 12:33:51.668348101 +0800
@@ -124,6 +124,9 @@
 	void OnUserEventSelected(wxListEvent& event);
 	void OnLanguageChoice(wxCommandEvent &event);
 	void CreateEventPanels(const int idx, const wxString& vars, wxWindow* parent);
+	#ifdef AMULE_DLP
+	void OnButtonReloadAntiLeech(wxCommandEvent &event); /* Dynamic Leech Protect - Bill Lee */
+	#endif
 
 	void OnInitDialog( wxInitDialogEvent& evt );
 
diff -Naur a/src/ServerWnd.cpp b/src/ServerWnd.cpp
--- a/src/ServerWnd.cpp	2016-10-06 19:01:54.000000000 +0800
+++ b/src/ServerWnd.cpp	2016-10-14 12:33:51.668348101 +0800
@@ -46,6 +46,7 @@
 	EVT_BUTTON(ID_BTN_RESET, CServerWnd::OnBnClickedResetLog)
 	EVT_BUTTON(ID_BTN_RESET_SERVER, CServerWnd::OnBnClickedResetServerLog)
 	EVT_SPLITTER_SASH_POS_CHANGED(ID_SRV_SPLITTER,CServerWnd::OnSashPositionChanged)
+	EVT_BUTTON(ID_BTN_RESET_DLP, CServerWnd::OnBnClickedResetDLPLog)
 END_EVENT_TABLE()
 
 
@@ -152,6 +153,11 @@
 	theApp->GetServerLog(true); // Reset it
 }
 
+void CServerWnd::OnBnClickedResetDLPLog(wxCommandEvent& WXUNUSED(evt))
+{
+	wxTextCtrl* cv= CastByID( ID_DLPINFO, this, wxTextCtrl );
+	cv->Clear();
+}
 
 void CServerWnd::UpdateED2KInfo()
 {
diff -Naur a/src/ServerWnd.h b/src/ServerWnd.h
--- a/src/ServerWnd.h	2016-10-06 19:01:54.000000000 +0800
+++ b/src/ServerWnd.h	2016-10-14 12:33:51.668348101 +0800
@@ -50,6 +50,7 @@
 	void OnBnClickedUpdateservermetfromurl(wxCommandEvent& evt);
 	void OnBnClickedResetLog(wxCommandEvent& evt);
 	void OnBnClickedResetServerLog(wxCommandEvent& evt);
+	void OnBnClickedResetDLPLog(wxCommandEvent& evt);
 
 	DECLARE_EVENT_TABLE()
 };
diff -Naur a/src/TextClient.cpp b/src/TextClient.cpp
--- a/src/TextClient.cpp	2016-10-06 19:01:54.000000000 +0800
+++ b/src/TextClient.cpp	2016-10-14 12:33:51.669348124 +0800
@@ -73,6 +73,7 @@
 	CMD_ID_RELOAD_SHARED,
 	CMD_ID_RELOAD_IPFILTER_LOCAL,
 	CMD_ID_RELOAD_IPFILTER_NET,
+	CMD_ID_RELOAD_ANTILEECH, /* Only used internally - Dynamic Leech Protect - Bill Lee */
 	CMD_ID_SET_IPFILTER_ON,
 	CMD_ID_SET_IPFILTER_OFF,
 	CMD_ID_SET_IPFILTER_CLIENTS_ON,
@@ -106,7 +107,6 @@
 	CMD_ID_DOWNLOAD,
 	// IDs for deprecated commands
 	CMD_ID_SET_IPFILTER
-
 };
 
 // method to create a SearchFile
@@ -240,6 +240,12 @@
 		case CMD_ID_DISCONNECT_KAD:
 			request_list.push_back(new CECPacket(EC_OP_KAD_STOP));
 			break;
+		//Dynamic Leech Protect - Bill Lee
+		#ifdef AMULE_DLP
+		case CMD_ID_RELOAD_ANTILEECH:
+			request_list.push_back(new CECPacket(EC_OP_ANTILEECH_RELOAD));
+			break;
+		#endif
 
 		case CMD_ID_RELOAD_SHARED:
 			request_list.push_back(new CECPacket(EC_OP_SHAREDFILES_RELOAD));
@@ -903,6 +909,9 @@
 	tmp2->AddCommand(wxT("Net"), CMD_ID_RELOAD_IPFILTER_NET, wxTRANSLATE("Update IP filtering table from URL."),
 					wxTRANSLATE("If URL is omitted the URL from the preferences is used."), CMD_PARAM_OPTIONAL);
 
+	#ifdef AMULE_DLP
+	tmp->AddCommand(wxT("AntiLeech"), CMD_ID_RELOAD_ANTILEECH, wxTRANSLATE("Reloads antiLeech."), wxEmptyString, CMD_PARAM_NEVER); //Bill Lee
+	#endif
 	tmp = m_commands.AddCommand(wxT("Connect"), CMD_ID_CONNECT, wxTRANSLATE("Connect to the network."),
 				    wxTRANSLATE("This will connect to all networks that are enabled in Preferences.\nYou may also optionally specify a server address in IP:Port form, to connect to\nthat server only. The IP must be a dotted decimal IPv4 address,\nor a resolvable DNS name."), CMD_PARAM_OPTIONAL);
 	tmp->AddCommand(wxT("ED2K"), CMD_ID_CONNECT_ED2K, wxTRANSLATE("Connect to eD2k only."), wxEmptyString, CMD_PARAM_NEVER);
diff -Naur a/src/UploadQueue.cpp b/src/UploadQueue.cpp
--- a/src/UploadQueue.cpp	2016-10-06 19:01:54.000000000 +0800
+++ b/src/UploadQueue.cpp	2016-10-14 12:33:51.669348124 +0800
@@ -390,6 +390,11 @@
 		return;
 	}
 
+	//Dynamic Leecher Protect - Bill Lee
+	#if defined AMULE_DLP && defined __DEBUG__
+	AddLogLineN(client->GetClientFullInfo());
+	#endif
+
 	client->AddAskedCount();
 	client->SetLastUpRequest();
 
diff -Naur a/src/amule-gui.cpp b/src/amule-gui.cpp
--- a/src/amule-gui.cpp	2016-10-06 19:01:54.000000000 +0800
+++ b/src/amule-gui.cpp	2016-10-14 12:33:51.669348124 +0800
@@ -333,6 +333,21 @@
 	return CamuleApp::GetLog(reset);
 }
 
+#ifdef AMULE_DLP
+void CamuleGuiApp::AddDLPMessageLine(const wxString &msg)
+{
+	wxString message;
+	time_t rawtime;
+	struct tm *timeinfo;
+	char tbuf[101];
+	time(&rawtime);
+	timeinfo = localtime(&rawtime);
+	strftime(tbuf, 100, "%Y-%m-%d %X: ", timeinfo);
+	
+	message = wxString(tbuf, wxConvUTF8) + msg;
+	amuledlg->AddDLPMessageLine(message);
+}
+#endif
 
 wxString CamuleGuiApp::GetServerLog(bool reset)
 {
diff -Naur a/src/amule.cpp b/src/amule.cpp
--- a/src/amule.cpp	2016-10-06 19:01:54.000000000 +0800
+++ b/src/amule.cpp	2016-10-14 12:33:51.670348146 +0800
@@ -23,7 +23,6 @@
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA
 //
 
-
 #include "amule.h"			// Interface declarations.
 
 #include <csignal>
@@ -90,6 +89,11 @@
 #include <wx/sysopt.h>			// Do_not_auto_remove
 #endif
 
+//Dynamic Leecher Protection - Bill Lee
+#ifdef AMULE_DLP
+#include "DLP.h"
+#endif
+
 #ifndef AMULE_DAEMON
 	#ifdef __WXMAC__
 		#include <CoreFoundation/CFBundle.h>  // Do_not_auto_remove
@@ -520,6 +524,11 @@
 	uploadqueue	= new CUploadQueue();
 	ipfilter	= new CIPFilter();
 
+	//DLP initialization - Bill Lee
+	#ifdef AMULE_DLP
+	theDLP = new DLP();
+	#endif
+
 	// Creates all needed listening sockets
 	wxString msg;
 	if (!ReinitializeNetwork(&msg)) {
@@ -2062,3 +2071,8 @@
 DEFINE_LOCAL_EVENT_TYPE(wxEVT_CORE_UDP_DNS_DONE)
 DEFINE_LOCAL_EVENT_TYPE(wxEVT_CORE_SERVER_DNS_DONE)
 // File_checked_for_headers
+
+//Dynamic Leech Protect - Bill Lee
+#ifdef AMULE_DLP
+DLP* theDLP;
+#endif
diff -Naur a/src/amule.h b/src/amule.h
--- a/src/amule.h	2016-10-06 19:01:54.000000000 +0800
+++ b/src/amule.h	2016-10-14 12:42:22.776093625 +0800
@@ -135,6 +135,8 @@
 	bool		m_geometryEnabled;
 	wxString	m_geometryString;
 	wxString	m_logFile;
+        //Dynamic Leech Protect - persmule
+	wxString	m_dlplogFile;
 	wxString	m_appName;
 	wxString	m_PidFile;
 
@@ -410,6 +412,7 @@
 	wxString GetLog(bool reset = false);
 	wxString GetServerLog(bool reset = false);
 	void AddServerMessageLine(wxString &msg);
+	void AddDLPMessageLine(const wxString &msg);
 	DECLARE_EVENT_TABLE()
 };
 
@@ -573,6 +576,8 @@
 
 	virtual int ShowAlert(wxString msg, wxString title, int flags);
 
+	void AddDLPMessageLine(const wxString &msg);
+	
 	DECLARE_EVENT_TABLE()
 };
 
@@ -583,3 +588,8 @@
 
 #endif // AMULE_H
 // File_checked_for_headers
+
+#ifdef AMULE_DLP
+class DLP;	//forward declaretion
+extern DLP* theDLP;
+#endif
diff -Naur a/src/amuleAppCommon.cpp b/src/amuleAppCommon.cpp
--- a/src/amuleAppCommon.cpp	2016-10-06 19:01:54.000000000 +0800
+++ b/src/amuleAppCommon.cpp	2016-10-14 12:44:08.981552362 +0800
@@ -65,6 +65,9 @@
 		m_configFile	= wxT("amule.conf");
 		m_logFile		= wxT("logfile");
 
+		//Dynamic Leech Protect - persmule
+		m_dlplogFile = wxT("antileech.log");
+
 		if (IsDaemon()) {
 			m_appName	= wxT("aMuleD");
 		} else {
@@ -443,6 +446,21 @@
 		return false;
 	}
 
+	// Open the dlp log file - Dynamic Leech Protect - persmule
+	if (!IsRemoteGui()){
+	  CPath dlplogfileName = CPath(thePrefs::GetConfigDir() + m_dlplogFile);
+	  if (dlplogfileName.FileExists()) {
+	    CPath::BackupFile(dlplogfileName, wxT(".bak"));
+	  }
+
+	  if (!dlpLogger.OpenLogfile(dlplogfileName.GetRaw())) {
+	    // use std err as last resolt to indicate problem
+	    fputs("ERROR: unable to open dlp log file\n", stderr);
+	    // failure to open log is serious problem
+	    return false;
+	  }
+	}
+
 	// Load Preferences
 	CPreferences::BuildItemList(thePrefs::GetConfigDir());
 	CPreferences::LoadAllItems( wxConfigBase::Get() );
diff -Naur a/src/amuleDlg.cpp b/src/amuleDlg.cpp
--- a/src/amuleDlg.cpp	2016-10-06 19:01:54.000000000 +0800
+++ b/src/amuleDlg.cpp	2016-10-14 12:44:47.637582726 +0800
@@ -315,7 +315,7 @@
 	wxNotebook* logs_notebook = CastChild( ID_SRVLOG_NOTEBOOK, wxNotebook);
 	wxNotebook* networks_notebook = CastChild( ID_NETNOTEBOOK, wxNotebook);
 
-	wxASSERT(logs_notebook->GetPageCount() == 4);
+	wxASSERT(logs_notebook->GetPageCount() == 5);
 	wxASSERT(networks_notebook->GetPageCount() == 2);
 
 	for (uint32 i = 0; i < logs_notebook->GetPageCount(); ++i) {
@@ -507,7 +507,12 @@
 		_("Part of aMule is based on \n") <<
 		_("Kademlia: Peer-to-peer routing based on the XOR metric.\n") <<
                 _(" Copyright (c) 2002-2011 Petar Maymounkov ( petar@post.harvard.edu )\n") <<
-		_("http://kademlia.scs.cs.nyu.edu\n");
+		_("http://kademlia.scs.cs.nyu.edu\n") <<
+		_("\nDynamic Leech Protection\n") <<
+		_(" Homepage: http://amule-dlp.googlecode.com \n") <<
+		_(" Copyright (C) 2002-2007 Xtreme-Mod \n") <<
+		_(" Copyright (C) 2009 greensea \n") <<
+		_(" Copyright (C) 2009-2011 Bill Lee \n");
 
 	if (m_is_safe_state) {
 		wxMessageBox(msg, _("Message"), wxOK | wxICON_INFORMATION, this);
@@ -659,8 +664,24 @@
 		}
 		cv->ShowPosition(cv->GetLastPosition()-1);
 	}
+	//Dynamic Leech Protect - persmule
+	DlpAddLogLine(msg);
 }
 
+#ifdef AMULE_DLP
+void CamuleDlg::AddDLPMessageLine(const wxString& msg) /* modified by Bill Lee */
+{
+	wxTextCtrl* cv = CastByID( ID_DLPINFO, m_serverwnd, wxTextCtrl );
+	if(cv) {
+		if (msg.Length() > 500) {
+			cv->AppendText(msg.Left(500) + wxT("\n"));
+		} else {
+			cv->AppendText(msg + wxT("\n"));
+		}
+		cv->ShowPosition(cv->GetLastPosition()-1);
+	}
+}
+#endif
 
 void CamuleDlg::ShowConnectionState(bool skinChanged)
 {
@@ -1456,7 +1477,9 @@
 	if (thePrefs::GetNetworkKademlia()) {
 		logs_notebook->AddPage(m_logpages[3].page, m_logpages[3].name);
 	}
-
+	
+	logs_notebook->AddPage(m_logpages[4].page, m_logpages[4].name);
+	
 	// Set the main window.
 	// If we have both networks active, activate a notebook to select between them.
 	// If only one is active, show the window directly without a surrounding one tab notebook.
diff -Naur a/src/amuleDlg.h b/src/amuleDlg.h
--- a/src/amuleDlg.h	2016-10-06 19:01:54.000000000 +0800
+++ b/src/amuleDlg.h	2016-10-14 12:33:51.671348169 +0800
@@ -114,6 +114,9 @@
 
 	void AddLogLine(const wxString& line);
 	void AddServerMessageLine(wxString& message);
+	#ifdef AMULE_DLP
+	void AddDLPMessageLine(const wxString& msg); /* Modified by Bill Lee */
+	#endif
 	void ResetLog(int id);
 
 	void ShowUserCount(const wxString& info = wxEmptyString);
@@ -231,7 +234,7 @@
 	WX_DECLARE_STRING_HASH_MAP(wxZipEntry*, ZipCatalog);
 	ZipCatalog cat;
 
-	PageType m_logpages[4];
+	PageType m_logpages[5];
 	PageType m_networkpages[2];
 
 	bool LoadGUIPrefs(bool override_pos, bool override_size);
diff -Naur a/src/amuled.cpp b/src/amuled.cpp
--- a/src/amuled.cpp	2016-10-06 19:01:54.000000000 +0800
+++ b/src/amuled.cpp	2016-10-14 12:45:23.506600119 +0800
@@ -749,4 +749,10 @@
 	return 0;	// That's neither yes nor no, ok, cancel
 }
 
+void CamuleDaemonApp::AddDLPMessageLine(const wxString &msg)
+{
+	//Dynamic Leech Protect - persmule
+	DlpAddLogLine(msg);
+}
+
 // File_checked_for_headers
diff -Naur a/src/antiLeech.h b/src/antiLeech.h
--- a/src/antiLeech.h	1970-01-01 08:00:00.000000000 +0800
+++ b/src/antiLeech.h	2016-10-14 12:33:51.672348192 +0800
@@ -0,0 +1,48 @@
+#ifndef ANTILEECH_H
+#define ANTILEECH_H
+
+
+#pragma once
+
+#include "antiLeech_wx.h"
+#include "CString_wx.h"
+
+class IantiLeech 
+{
+public:
+	virtual ~IantiLeech(){};                /* Bill Lee: Not be used currently */
+	//BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD,LPVOID);
+	virtual DWORD GetDLPVersion() = 0;
+	//old versions to keep compatible
+	/* //drop old version support
+	virtual LPCTSTR DLPCheckModstring(LPCTSTR modversion, LPCTSTR clientversion);
+	virtual LPCTSTR DLPCheckUsername(LPCTSTR username);
+	virtual LPCTSTR DLPCheckNameAndHash(CString username, CString& userhash);
+	*/
+	//new versions
+	virtual LPCTSTR DLPCheckModstring_Hard(LPCTSTR modversion, LPCTSTR clientversion) = 0;
+	virtual LPCTSTR DLPCheckModstring_Soft(LPCTSTR modversion, LPCTSTR clientversion) = 0;
+	virtual LPCTSTR DLPCheckUsername_Hard(LPCTSTR username) = 0;
+	virtual LPCTSTR DLPCheckUsername_Soft(LPCTSTR username) = 0;
+	virtual LPCTSTR DLPCheckNameAndHashAndMod(const CString& username, const CString& userhash, const CString& modversion) = 0;
+	virtual LPCTSTR DLPCheckMessageSpam(LPCTSTR messagetext) = 0;
+
+
+	virtual LPCTSTR DLPCheckUserhash(const PBYTE userhash) = 0;
+
+
+	virtual LPCTSTR DLPCheckHelloTag(UINT tagnumber) = 0;
+	virtual LPCTSTR DLPCheckInfoTag(UINT tagnumber) = 0;
+
+	//void  TestFunc();
+
+//Bill Lee: no need in interface abstract class
+//private:
+//	static bool IsTypicalHex (const CString& addon);
+};
+
+//Bill Lee: never call delete on IantiLeech, use destoryAntiLeechInstat instead.
+extern "C" IantiLeech* createAntiLeechInstant();
+extern "C" int destoryAntiLeechInstant(IantiLeech*);
+
+#endif
diff -Naur a/src/antiLeech_wx.h b/src/antiLeech_wx.h
--- a/src/antiLeech_wx.h	1970-01-01 08:00:00.000000000 +0800
+++ b/src/antiLeech_wx.h	2016-10-14 12:33:51.672348192 +0800
@@ -0,0 +1,49 @@
+#ifndef ANTILEECH_WX_H
+#define ANTILEECH_WX_H
+
+#include <wx/defs.h>
+#include <string.h>
+
+#define LPCTSTR		const wxChar* 
+#define BOOL		bool
+//#define _T(var)		wxT(var)	//defined in wxWidgets
+#define DWORD		wxUint32
+#define UINT		wxUint16
+#define WINAPI
+#define HINSTANCE
+#define LPVOID		void*
+#define PBYTE		unsigned char*
+#define TCHAR		wxChar
+#define _TINT		wxInt32
+
+#define StrCmpI _tcsicmp
+
+#define _istdigit(var)		iswdigit(var)
+#define _istcntrl(var)		iswcntrl(var)
+#define _istpunct(var)		iswpunct(var)
+#define _istspace(var)		iswspace(var)
+#define _istxdigit(var)		iswxdigit(var)
+inline float _tstof(const wchar_t* str){
+	wchar_t** ptail = NULL;
+	return wcstof(str, ptail);
+}
+//This function is not used. by Orzogc Lee
+//But I think there is no need to removing, linker will remove it.
+/*
+inline void tolowers(wxChar* str){
+	int i = 0;
+	do{
+		str[i] = towlower(str[i]);
+	}while(str[++i]);
+}
+*/
+#define _tcsstr(haystack, needle)	wcsstr(haystack, needle)
+#define _tcslen(var)		wcslen(var)
+#define StrStr(a, b)		wcsstr(a, b)
+
+LPCTSTR StrStrI(LPCTSTR haystack, LPCTSTR needle);
+//Bill Lee: I think inlining this function make no senses, because it is a very large operation.
+
+#define _tcsicmp(a, b)		wcscasecmp(a, b)
+
+#endif
diff -Naur a/src/libs/ec/abstracts/ECCodes.abstract b/src/libs/ec/abstracts/ECCodes.abstract
--- a/src/libs/ec/abstracts/ECCodes.abstract	2016-10-06 19:01:54.000000000 +0800
+++ b/src/libs/ec/abstracts/ECCodes.abstract	2016-10-14 12:33:51.672348192 +0800
@@ -148,6 +148,8 @@
 
 EC_OP_FRIEND                        0x57
 
+EC_OP_ANTILEECH_RELOAD              0x80	
+
 [/Section]
 
 [Section Content]
diff -Naur a/src/libs/ec/cpp/ECCodes.h b/src/libs/ec/cpp/ECCodes.h
--- a/src/libs/ec/cpp/ECCodes.h	2016-10-06 19:01:54.000000000 +0800
+++ b/src/libs/ec/cpp/ECCodes.h	2016-10-14 12:33:51.673348215 +0800
@@ -121,7 +121,8 @@
 	EC_OP_CLIENT_SWAP_TO_ANOTHER_FILE   = 0x54,
 	EC_OP_SHARED_FILE_SET_COMMENT       = 0x55,
 	EC_OP_SERVER_SET_STATIC_PRIO        = 0x56,
-	EC_OP_FRIEND                        = 0x57
+	EC_OP_FRIEND                        = 0x57,
+	EC_OP_ANTILEECH_RELOAD              = 0x80	
 };
 
 enum ECTagNames {
@@ -556,6 +557,7 @@
 		case 0x55: return wxT("EC_OP_SHARED_FILE_SET_COMMENT");
 		case 0x56: return wxT("EC_OP_SERVER_SET_STATIC_PRIO");
 		case 0x57: return wxT("EC_OP_FRIEND");
+		case 0x80	: return wxT("EC_OP_ANTILEECH_RELOAD");
 		default: return CFormat(wxT("unknown %d 0x%x")) % arg % arg;
 	}
 }
diff -Naur a/src/libs/ec/java/ECCodes.java b/src/libs/ec/java/ECCodes.java
--- a/src/libs/ec/java/ECCodes.java	2016-10-06 19:01:54.000000000 +0800
+++ b/src/libs/ec/java/ECCodes.java	2016-10-14 12:33:51.673348215 +0800
@@ -112,6 +112,7 @@
 public final static byte EC_OP_SHARED_FILE_SET_COMMENT       = 0x55;
 public final static byte EC_OP_SERVER_SET_STATIC_PRIO        = 0x56;
 public final static byte EC_OP_FRIEND                        = 0x57;
+public final static byte EC_OP_ANTILEECH_RELOAD              = 0x80	;
 
 public final static short EC_TAG_STRING                             = 0x0000;
 public final static short EC_TAG_PASSWD_HASH                        = 0x0001;
diff -Naur a/src/muuli_wdr.cpp b/src/muuli_wdr.cpp
--- a/src/muuli_wdr.cpp	2016-10-06 19:01:54.000000000 +0800
+++ b/src/muuli_wdr.cpp	2016-10-14 12:33:51.676348283 +0800
@@ -1769,6 +1769,51 @@
     return item0;
 }
 
+#ifdef AMULE_DLP
+wxSizer *PreferencesDLPTab( wxWindow *parent, bool call_fit, bool set_sizer )
+{
+	wxBoxSizer *item0 = new wxBoxSizer( wxVERTICAL );
+
+	wxButton* btnReload = new wxButton( parent, IDC_RELOADANTILEECH, _("Reload antiLeech"), wxDefaultPosition, wxDefaultSize, 0 ); //Bill Lee
+
+	wxStaticBox *item2 = new wxStaticBox( parent, -1, _("Dynamic Leecher Protection Options") );
+	wxStaticBoxSizer *item1 = new wxStaticBoxSizer( item2, wxVERTICAL );
+
+	wxCheckBox *item4 = new wxCheckBox( parent, IDC_CHECKMODSTRING, _("Check bad modstring"), wxDefaultPosition, wxDefaultSize, 0 );
+	item1->Add( item4, 0, wxALIGN_CENTER_VERTICAL, 5 );
+
+	wxCheckBox *item5 = new wxCheckBox( parent, IDC_CHECKUSERNAME, _("Check bad username"), wxDefaultPosition, wxDefaultSize, 0 );
+	item1->Add( item5, 0, wxALIGN_CENTER_VERTICAL, 5 );
+
+	wxCheckBox *item6 = new wxCheckBox( parent, IDC_CHECKUSERHASH, _("Check bad userhash"), wxDefaultPosition, wxDefaultSize, 0 );
+	item1->Add( item6, 0, wxALIGN_CENTER_VERTICAL, 5 );
+
+	wxCheckBox *item7 = new wxCheckBox( parent, IDC_CHECKHELLOTAG, _("Check bad hello tag"), wxDefaultPosition, wxDefaultSize, 0 );
+	item1->Add( item7, 0, wxALIGN_CENTER_VERTICAL, 5 );
+
+	wxCheckBox *item8 = new wxCheckBox( parent, IDC_CHECKINFOTAG, _("Check bad info tag"), wxDefaultPosition, wxDefaultSize, 0 );
+	item1->Add( item8, 0, wxALIGN_CENTER_VERTICAL, 5 );
+
+	wxCheckBox *item9 = new wxCheckBox( parent, IDC_CHECKGHOSTMOD, _("Check ghost mod"), wxDefaultPosition, wxDefaultSize, 0);
+	item1->Add( item9, 0, wxALIGN_CENTER_VERTICAL, 5 );
+
+	wxCheckBox *item10 = new wxCheckBox( parent, IDC_CHECKVERYCDMOD, _("Ban eMule VeryCD mod(Please consider carefully whether to use)"), wxDefaultPosition, wxDefaultSize, 0 ); //Modified by Bill Lee
+	item1->Add( item10, 0, wxALIGN_CENTER_VERTICAL, 5 );
+
+	item0->Add( btnReload, 0, wxGROW|wxALL, 5); //Bill Lee
+	item0->Add( item1, 0, wxGROW|wxALL, 5 );
+
+	if (set_sizer)
+	{
+	parent->SetSizer( item0 );
+	if (call_fit)
+	    item0->SetSizeHints( parent );
+	}
+
+	return item0;
+}
+#endif
+
 wxSizer *PreferencesFilesTab( wxWindow *parent, bool call_fit, bool set_sizer )
 {
     wxBoxSizer *item0 = new wxBoxSizer( wxVERTICAL );
@@ -2587,6 +2632,42 @@
     return item0;
 }
 
+wxSizer *DLPInfoLog( wxWindow *parent, bool call_fit, bool set_sizer )
+{
+    wxBoxSizer *item0 = new wxBoxSizer( wxVERTICAL );
+
+    wxBoxSizer *item1 = new wxBoxSizer( wxHORIZONTAL );
+
+    wxStaticBitmap *item2 = new wxStaticBitmap( parent, -1, amuleDlgImages( 3 ), wxDefaultPosition, wxDefaultSize );
+    item2->SetToolTip( _("Display DLP log") );
+    item1->Add( item2, 0, wxALIGN_CENTER|wxALL, 5 );
+
+    wxStaticText *item3 = new wxStaticText( parent, -1, _("DLP Info"), wxDefaultPosition, wxDefaultSize, 0 );
+    item1->Add( item3, 0, wxALIGN_CENTER|wxALL, 5 );
+
+    item0->Add( item1, 0, wxALIGN_CENTER_VERTICAL, 5 );
+
+    wxBoxSizer *item4 = new wxBoxSizer( wxHORIZONTAL );
+
+    CMuleTextCtrl *item5 = new CMuleTextCtrl( parent, ID_DLPINFO, wxT(""), wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxTE_READONLY|wxVSCROLL );
+    item4->Add( item5, 1, wxGROW|wxALIGN_CENTER_HORIZONTAL, 5 );
+
+    wxButton *item6 = new wxButton( parent, ID_BTN_RESET_DLP, _("Reset"), wxDefaultPosition, wxDefaultSize, 0 );
+    item6->SetToolTip( _("Click this button to reset the log.") );
+    item4->Add( item6, 0, wxGROW|wxALIGN_CENTER_HORIZONTAL|wxALL, 5 );
+
+    item0->Add( item4, 1, wxGROW|wxALIGN_CENTER_VERTICAL, 5 );
+
+    if (set_sizer)
+    {
+        parent->SetSizer( item0 );
+        if (call_fit)
+            item0->SetSizeHints( parent );
+    }
+    
+    return item0;
+}
+
 wxSizer *serverListDlgDown( wxWindow *parent, bool call_fit, bool set_sizer )
 {
     wxStaticBox *item1 = new wxStaticBox( parent, -1, wxT("") );
@@ -2602,7 +2683,7 @@
     wxPanel *item4 = new wxPanel( item3, -1 );
     aMuleLog( item4, FALSE );
     item3->AddPage( item4, _("aMule Log") );
-
+	
     wxPanel *item5 = new wxPanel( item3, -1 );
     ServerInfoLog( item5, FALSE );
     item3->AddPage( item5, _("Server Info") );
@@ -2614,6 +2695,10 @@
     wxPanel *item7 = new wxPanel( item3, -1 );
     Kad_Info( item7, FALSE );
     item3->AddPage( item7, _("Kad Info") );
+	
+	wxPanel *item8 = new wxPanel( item3, -1);
+	DLPInfoLog( item8, FALSE);
+	item3->AddPage(item8, _("DLP Info"));
 
     item0->Add( item2, 1, wxGROW|wxALIGN_CENTER_VERTICAL, 5 );
 
diff -Naur a/src/muuli_wdr.h b/src/muuli_wdr.h
--- a/src/muuli_wdr.h	2016-10-06 19:01:54.000000000 +0800
+++ b/src/muuli_wdr.h	2016-10-14 12:33:51.676348283 +0800
@@ -335,6 +335,10 @@
 #define ID_BTN_RESET_SERVER 10240
 wxSizer *ServerInfoLog( wxWindow *parent, bool call_fit = TRUE, bool set_sizer = TRUE );
 
+#define ID_DLPINFO 22001
+#define ID_BTN_RESET_DLP 22002
+wxSizer *DLPInfoLog( wxWindow *parent, bool call_fit = TRUE, bool set_sizer = TRUE );
+
 #define ID_LOGVIEW 10241
 #define ID_BTN_RESET 10242
 wxSizer *aMuleLog( wxWindow *parent, bool call_fit = TRUE, bool set_sizer = TRUE );
@@ -424,6 +428,21 @@
 #define ID_DEBUGCATS 10307
 wxSizer *PreferencesDebug( wxWindow *parent, bool call_fit = TRUE, bool set_sizer = TRUE );
 
+/* Dynamic Leecher Protection */
+#define IDC_CHECKMODSTRING 11001
+#define IDC_CHECKUSERNAME 11002
+#define IDC_CHECKUSERHASH 11003
+#define IDC_CHECKHELLOTAG 11004
+#define IDC_CHECKINFOTAG 11005
+#define IDC_CHECKEASYMULE 11006
+#define IDC_CHECKVERYCDMOD 11007
+#define IDC_CHECKMINIMULE 11008
+#define IDC_CHECKGHOSTMOD 11009
+#ifdef AMULE_DLP
+#define IDC_RELOADANTILEECH 11010 //Bill Lee
+wxSizer *PreferencesDLPTab( wxWindow *parent, bool call_fit = TRUE, bool set_sizer = TRUE );
+#endif
+
 extern wxSizer *IDC_CURJOB;
 #define IDC_CONV_PB_LABEL 10308
 #define IDC_CONV_PROZENT 10309
diff -Naur a/src/updownclient.h b/src/updownclient.h
--- a/src/updownclient.h	2016-10-06 19:01:54.000000000 +0800
+++ b/src/updownclient.h	2016-10-14 12:37:03.224728226 +0800
@@ -408,7 +408,13 @@
 	bool		GetSentCancelTransfer() const	{ return m_fSentCancelTransfer; }
 	void		SetSentCancelTransfer(bool bVal)	{ m_fSentCancelTransfer = bVal; }
 
-	DEBUG_ONLY( wxString	GetClientFullInfo(); )
+#if defined (__DEBUG__) || defined (AMULE_DLP)
+	/* 
+	 * This function is essential for dlp to produce ban log.
+	 * So I decide to retain it when dlp is enabled.
+	 */
+	wxString	GetClientFullInfo();
+#endif
 	wxString	GetClientShortInfo();
 
 	const wxString& GetClientOSInfo() const		{ return m_sClientOSInfo; }
@@ -581,7 +587,10 @@
 	bool		ShouldReceiveCryptUDPPackets() const;
 
 	bool		HasDisabledSharedFiles() const { return m_fNoViewSharedFiles; }
-
+	#ifdef AMULE_DLP
+	bool		HasNonOfficialOpCodes() const { return dlp_nonofficialopcodes; }	 //Dynamic Leecher Protection - Bill Lee
+	#endif
+	
 private:
 
 	CClientCredits	*credits;
@@ -842,6 +851,10 @@
 #ifdef __DEBUG__
 	wxString	connection_reason;
 #endif
+
+	#ifdef AMULE_DLP
+	bool dlp_nonofficialopcodes; //Dynamic Leecher Protect - Bill Lee
+	#endif
 };
 
 
