//this file is part of eMule
//Copyright (C)2002 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.
#pragma once
#include "BarShader.h"
#include "MapKey.h"	// NEO: SCFS - [SmartClientFileStatus] <-- Xanatos --
#ifdef IP2COUNTRY // NEO: IP2C - [IPtoCountry] -- Xanatos -->
#include "Neo\GUI\IP2Country.h"
#endif // IP2COUNTRY // NEO: IP2C END <-- Xanatos --
#ifdef WEBCACHE // NEO: WC - [WebCache] -- Xanatos -->
#include "Neo\WebCache\WebCacheCryptography.h"
#include "Neo\WebCache\WebCacheMFRList.h"
#endif // NEO: WC END <-- Xanatos --

class CClientReqSocket;
class CPeerCacheDownSocket;
class CPeerCacheUpSocket;
class CFriend;
class CPartFile;
class CClientCredits;
class CAbstractFile;
class CKnownFile;
class Packet;
class CxImage;
struct Requested_Block_Struct;
class CSafeMemFile;
class CEMSocket;
class CAICHHash;
enum EUtf8Str;
class CClientDetailDialogInterface; // NEO: MLD - [ModelesDialogs] <-- Xanatos --
class CSearchFile; // NEO: XSF - [ExtendedSharedFiles] <-- Xanatos --
class CEdt; // NEO: EDT - [EstimatedDownloadTime] <-- Xanatos --
#ifdef NEO_SS // NEO: NSS - [NeoSourceStorage] -- Xanatos -->
class CFileDataIO;
class CTag;
#endif // NEO_SS // NEO: NSS END <-- Xanatos --
#ifdef NEO_CD // NEO: NCD - [NeoClientDatabase] -- Xanatos -->
class CKnownSource;
#endif // NEO_CD // NEO: NCD END <-- Xanatos --
class CClientFileStatus; // NEO: SCFS - [SmartClientFileStatus] <-- Xanatos --
#ifdef WEBCACHE // NEO: WC - [WebCache] -- Xanatos -->
class CWebCacheDownSocket;
class CWebCacheUpSocket;
#endif // NEO: WC END <-- Xanatos --
#ifdef ISPBYPASS // NEO: SCC - [SecureClinetConnection] -- Xanatos -->
class CSocketCryptor; // for nat
#endif // ISPBYPASS // NEO: SCC END <-- Xanatos --

struct Pending_Block_Struct{
	Pending_Block_Struct()
	{
		block = NULL;
		zStream = NULL;
		totalUnzipped = 0;
		fZStreamError = 0;
		//fRecovered = 0;
		fRequested = 0; // NEO: DBR - [DynamicBlockRequest] <-- Xanatos --
		//fQueued = 0;
	}
	Requested_Block_Struct*	block;
	struct z_stream_s*      zStream;       // Barry - Used to unzip packets
	UINT					totalUnzipped; // Barry - This holds the total unzipped bytes for all packets so far
	UINT					fZStreamError : 1,
							//fRecovered    : 1,
							fRequested	  : 1; // NEO: DBR - [DynamicBlockRequest] <-- Xanatos --
							//fQueued		  : 3; 
};

#pragma pack(1)
struct Requested_File_Struct{
	uchar	  fileid[16];
	uint32	  lastasked;
	uint8	  badrequests;
};
#pragma pack()

// NEO: NXI - [NeoExtraInfo] -- Xanatos -->
#pragma pack(1)
struct Extra_Info_Struct{
	uint8  SUIState;	// My SUI State, is all OK?

	// File Priorities
	uint8  FileULPriority; // What priority have the file I want?
	uint8  FileULReleasePriority; // Are you a releaser?
	uint8  FileDLPriority; // What priority have the file you want?

	// Credit system
	float  CreditScore; // What is my real score?
	uint8  CreditSystem; // What credit system do you use?

	// Score Informations
	uint32 QueueSystem; // What kind of queue?: one per file, Probabilistic, exponential (neo)
	uint32 WaitingTime; // How long does I wait, dows you saved my wait time from yesturday?
	uint32 QueueRating; // What ranking do I have
	uint32 QueueScore; // What score do I have
	uint8  PrivatSlot; // Dows I have a friendslot or friend boost
	uint32 WaitingUsers; // How many other users are waiting in your queue

	// Bandwidth infos ;)
	uint16 UploadCapacity; // How fast can you upload
	uint16 DownloadCapacity; // How fast can you download

	// Other File infos
	uint32  lastseencompletereqfile; // Does you have seen this file complete?

	uint16 ReqFileSources; // How many sources for the file i want do you know?
	uint16 ReqFileCompleteSources; // How many fo your sources are complete?

	uint16 UpReqFileSources; // How many sources do you know for the fil you want?
	uint16 UpReqFileCompleteSources; // How many fo your sources are complete?

	// Other infos
	uint32 UpTime; // How long does your mule Run?
	uint32 IDAge; // Halw long aho does your ID changed the last time?

	int SomeInfosLen; // Some custom infos you want tell to other users? eg. Adress of your FTP server, or ICQ number would you like to share some think via ICQ, or simply talk? 
};
#pragma pack()
// NEO: NXI END <-- Xanatos --

enum EUploadState{
	US_UPLOADING,
	US_ONUPLOADQUEUE,
	US_NONEEDEDPARTS, // NEO: SCT - [SubChunkTransfer] <-- Xanatos --
	US_WAITCALLBACK,
#ifdef NATTUNNELING // NEO: LUC - [LowIDUplaodCallBack] -- Xanatos -->
	US_WAITCALLBACKKAD,
//	US_TOOMANYCONNSKAD,
#endif //NATTUNNELING // NEO: LUC END <-- Xanatos --
	US_CONNECTING,
	US_PENDING,
	US_LOWTOLOWIP,
	US_BANNED,
	US_ERROR,
	US_NONE
};

enum EDownloadState{
	DS_DOWNLOADING,
	DS_ONQUEUE,
	DS_CONNECTED,
	DS_CONNECTINGWAITING, // NEO: MDR - [ManualDownloadReask] <-- Xanatos --
#ifdef NEO_SS // NEO: NSS - [NeoSourceStorage] -- Xanatos -->
	DS_LOADEDWAITING,
	DS_LOADED,
	DS_RESERVE,
	DS_RETIRED,
#endif // NEO_SS // NEO: NSS END <-- Xanatos --
	DS_CONNECTING,
	DS_HALTED, // NEO: SD - [StandByDL] <-- Xanatos --
#if defined(NEO_SK) || defined(NEO_SS) // NEO: NSK - [NeoSourceKeeper] // NEO: NSS - [NeoSourceStorage] -- Xanatos -->
	DS_REVIVAL,
#endif // NEO_SK // NEO_SS // NEO: NSK END // NEO: NSS END <-- Xanatos --
	DS_CACHED, // NEO: XSC - [ExtremeSourceCache] <-- Xanatos --
	DS_CONNECTIONRETRY, // NEO: TCR - [TCPConnectionRetry] <-- Xanatos --
	DS_WAITCALLBACK,
	DS_WAITCALLBACKKAD,
	DS_REQHASHSET,
	DS_NONEEDEDPARTS,
	DS_TOOMANYCONNS,
	DS_TOOMANYCONNSKAD,
#ifdef NEO_SK // NEO: NSK - [NeoSourceKeeper] -- Xanatos -->
	DS_UNREACHABLE,
#endif // NEO_SK // NEO: NSK END <-- Xanatos --
	DS_LOWTOLOWIP,
	DS_BANNED,
	DS_ERROR,
	DS_NONE,
	DS_REMOTEQUEUEFULL,  // not used yet, except in statistics
};

enum EPeerCacheDownState{
	PCDS_NONE = 0,
	PCDS_WAIT_CLIENT_REPLY,
	PCDS_WAIT_CACHE_REPLY,
	PCDS_DOWNLOADING
};

enum EPeerCacheUpState{
	PCUS_NONE = 0,
	PCUS_WAIT_CACHE_REPLY,
	PCUS_UPLOADING
};

#ifdef WEBCACHE // NEO: WC - [WebCache] -- Xanatos -->
enum EWebCacheDownState{
	WCDS_NONE = 0,
	WCDS_WAIT_CLIENT_REPLY,
	WCDS_WAIT_CACHE_REPLY,
	WCDS_DOWNLOADINGVIA,
	WCDS_DOWNLOADINGFROM
};

enum EWebCacheUpState{
	WCUS_NONE = 0,
	WCUS_UPLOADING
};
#endif // NEO: WC END <-- Xanatos --

enum EChatState{
	MS_NONE,
	MS_CHATTING,
	MS_CONNECTING,
	MS_UNABLETOCONNECT
};

enum EKadState{
	KS_NONE,
	KS_QUEUED_FWCHECK,
	KS_CONNECTING_FWCHECK,
	KS_CONNECTED_FWCHECK,
	KS_QUEUED_BUDDY,
	KS_INCOMING_BUDDY,
	KS_CONNECTING_BUDDY,
	KS_CONNECTED_BUDDY
};

enum EClientSoftware{
	SO_EMULE			= 0,	// default
	SO_CDONKEY			= 1,	// ET_COMPATIBLECLIENT
	SO_XMULE			= 2,	// ET_COMPATIBLECLIENT
	SO_AMULE			= 3,	// ET_COMPATIBLECLIENT
	SO_SHAREAZA			= 4,	// ET_COMPATIBLECLIENT
	SO_EMULEPLUS		= 5,	// NEO: ECR - [EnhancedClientRecognization] <-- Xanatos --
	SO_HYDRANODE		= 6,	// NEO: ECR - [EnhancedClientRecognization] <-- Xanatos --
	SO_MLDONKEY			= 10,	// ET_COMPATIBLECLIENT
	SO_LPHANT			= 20,	// ET_COMPATIBLECLIENT
	// NEO: ECR - [EnhancedClientRecognization] -- Xanatos -->
	SO_SHAREAZA2		= 28,
	SO_TRUSTYFILES		= 30,
	SO_SHAREAZA3		= 40,
	// NEO: ECR END <-- Xanatos --
	// other client types which are not identified with ET_COMPATIBLECLIENT
	SO_EDONKEYHYBRID	= 50,
	// NEO: ECR - [EnhancedClientRecognization] -- Xanatos -->
	SO_EDONKEY			= 51,
	SO_MLDONKEY2		= 52,
	SO_OLDEMULE			= 53,
	SO_SHAREAZA4		= 68,
	SO_MLDONKEY3		= 152,
	 // NEO: ECR END <-- Xanatos --
	SO_URL,
#ifdef WEBCACHE // NEO: WC - [WebCache] -- Xanatos -->
	SO_WEBCACHE, // Superlexx - webcache - statistics
#endif // NEO: WC END <-- Xanatos --
	SO_UNKNOWN
};

// NEO: MID - [NeoID] -- Xanatos -->
#define SO_NULL		0
#define SO_NEO		1
// NEO: MID END <-- Xanatos --

enum ESecureIdentState{
	IS_UNAVAILABLE		= 0,
	IS_ALLREQUESTSSEND  = 0,
	IS_SIGNATURENEEDED	= 1,
	IS_KEYANDSIGNEEDED	= 2,
};

enum EInfoPacketState{
	IP_NONE				= 0,
	IP_EDONKEYPROTPACK  = 1,
	IP_EMULEPROTPACK	= 2,
	IP_BOTH				= 3,
};

// NEO: FCCP - [FixConnectionCollision] -- Xanatos -->
enum EHelloPacketState{
	HP_NONE			= 0,
	HP_HELLO		= 1,
	HP_HELLOANSWER  = 2,
	HP_BOTH			= 3,
};
// NEO: FCCP END <-- Xanatos --

// NEO: USPS - [UnSolicitedPartStatus] -- Xanatos -->
enum EFileRequestState{
	FR_NONE			= 0,
	FR_INPROGRES	= 1,
	FR_COMPLETED	= 2,
	FR_STANDBY		= 3, // NEO: SD - [StandByDL] -- Xanatos --
};
// NEO: USPS END <-- Xanatos --

#ifdef NATTUNNELING // NEO: NATT - [NatTraversal] -- Xanatos -->
enum ENatTraversalState{
	NT_NONE			= 0,  // __ __ __ __

	NT_TUNEL		= 1,  // 10 __ __ __ // this means we got a direct packet from the remote cleint so the tunel is open
	//NT_			= 2,  // 01 __ __ __

	NT_CONF_SND		= 4,  // __ 10 __ __
	NT_CONF_RCV		= 8,  // __ 01 __ __
	NT_COMPLETE		= 12, // __ 11 __ __ = NT_CONF_SND | NT_CONF_RCV

	NT_INITIALIZER	= 16, // __ __ 10 __
	//NT_REASK_PING	= 32, // __ __ 01 __ // we make a tunel but don't switch to user mode TCP we remain in UDP and make a regular file reask ping
	//NT_			= 64, // __ __ __ 10
	NT_ACCEPTOR		= 128 // __ __ __ 01 // dummy state just to have one and pass the CheckNatState
};
#endif //NATTUNNELING // NEO: NATT END <-- Xanatos --

enum ESourceFrom{
	SF_SERVER			= 0,
	SF_KADEMLIA			= 1,
	SF_SOURCE_EXCHANGE	= 2,
	SF_PASSIVE			= 3,
#ifdef NEO_SS // NEO: NSS - [NeoSourceStorage] -- Xanatos -->
	SF_STORAGE			= 4,
#endif // NEO_SS // NEO: NSS END <-- Xanatos --
#ifdef LANCAST // NEO: NLC - [NeoLanCast] -- Xanatos -->
	SF_LANCAST			= 5,
#endif //LANCAST // NEO: NLC END <-- Xanatos --
#ifdef VOODOO // NEO: VOODOOx - [VoodooSourceExchange] -- Xanatos -->
	SF_VOODOO			= 6,
#endif // VOODOO // NEO: VOODOOx END <-- Xanatos --
	SF_LINK				= 7
};

#ifdef _DEBUG
	// use the 'Enums' only for debug builds, each enum costs 4 bytes (3 unused)
#define _EClientSoftware	EClientSoftware
#define _EChatState			EChatState
#define _EKadState			EKadState
#define _ESecureIdentState	ESecureIdentState
#define _EUploadState		EUploadState
#define _EDownloadState		EDownloadState
#define _ESourceFrom		ESourceFrom
#else
#define _EClientSoftware	uint8
#define _EChatState			uint8
#define _EKadState			uint8
#define _ESecureIdentState	uint8
#define _EUploadState		uint8
#define _EDownloadState		uint8
#define _ESourceFrom		uint8
#endif

struct PartFileStamp{
	CPartFile*	file;
	DWORD		timestamp;
};

#define	MAKE_CLIENT_VERSION(mjr, min, upd) \
	((UINT)(mjr)*100U*10U*100U + (UINT)(min)*100U*10U + (UINT)(upd)*100U)

//#pragma pack(2)
class CUpDownClient : public CObject
{
	DECLARE_DYNAMIC(CUpDownClient)

	friend class CEdt; // NEO: EDT - [EstimatedDownloadTime] <-- Xanatos --
	friend class CUploadQueue;
	friend class CemuleDlg; // NEO: RBT - [ReadBlockThread] <-- Xanatos --
#ifdef VOODOO // NEO: VOODOO - [UniversalPartfileInterface] -- Xanatos -->
	friend class CVoodooSocket; // NEO: RBT - [ReadBlockThread]
#endif // VOODOO // NEO: VOODOO END <-- Xanatos --
	friend class CQueueListCtrl; // NEO: UPC - [UploadingProblemClient] -- Xanatos -->
#ifdef ISPBYPASS // NEO: SCC - [SecureClinetConnection] -- Xanatos -->
	friend class CClientUDPSocket; // for nat
#endif // ISPBYPASS // NEO: SCC END <-- Xanatos --

public:
    void PrintUploadStatus();

	//base
	CUpDownClient(CClientReqSocket* sender = 0);
	CUpDownClient(CPartFile* in_reqfile, uint16 in_port, uint32 in_userid, uint32 in_serverup, uint16 in_serverport, bool ed2kID = false);
	virtual ~CUpDownClient();

	void			StartDownload();
	virtual void	CheckDownloadTimeout();
	virtual void	SendCancelTransfer(Packet* packet = NULL);
	virtual bool	IsEd2kClient() const							{ return true; }
	virtual bool	Disconnected(LPCTSTR pszReason, bool bFromSocket = false);
	virtual bool	TryToConnect(bool bIgnoreMaxCon = false, CRuntimeClass* pClassSocket = NULL);

#ifdef ISPBYPASS // NEO: CHS - [ConnectionHotSwap] -- Xanatos -->
	bool			SwapSocket();
	virtual bool	Connect(bool bSwap = false);
	void			RequestSecureCallback();
	CSafeMemFile*	SecureConnection(bool bXorOnly); // PK // NEO: SCC - [SecureClinetConnection]
#else
	virtual bool	Connect();
#endif // ISPBYPASS // NEO: CHS END <-- Xanatos --

#ifdef NATTUNNELING // NEO: NATT - [NatTraversal] -- Xanatos -->
	void			TryToSyncOverBuddy(bool bPasive = false);
 #ifdef ISPBYPASS // NEO: SCC - [SecureClinetConnection]
	void			PrepareNATEncryption(bool bNoTrash = true);
	void			SendPacketUDP(Packet* packet, bool bKad = false, uint16 port = 0);
	void			SendSecurePing();
	void			SendDummyPing();
 #endif // ISPBYPASS // NEO: SCC END
	void			SendNatPing();
	void			SendNatConfig();
	void			ProcessNatConfigPacket(const uchar* pachPacket, uint32 nSize);

	uint8			GetNatTraversalState()	const { return m_byNatTraversalState; }
	void			SetLastNatTraversalTry() { m_uLastNatTraversalTry = ::GetTickCount(); }
	void			AddNatTraversalState(ENatTraversalState add) { m_byNatTraversalState |= add; }
	bool			ResetNatTraversalState(bool bFromSocket = false);
	bool			CheckNatTraversalState(uint16 port = 0);
#endif //NATTUNNELING // NEO: NATT END <-- Xanatos --

	virtual void	ConnectionEstablished();
	virtual void	OnSocketConnected(int nErrorCode);
	bool			CheckHandshakeFinished() const;
	void			CheckFailedFileIdReqs(const uchar* aucFileHash);
	uint32			GetUserIDHybrid() const							{ return m_nUserIDHybrid; }
	void			SetUserIDHybrid(uint32 val)						{ m_nUserIDHybrid = val; }
	const CString&	GetUserName() const								{ return m_strUsername; } // NEO: FIX - [StabilityFix] <-- Xanatos --
	void			SetUserName(LPCTSTR pszNewName)					{ m_strUsername = pszNewName; }  // NEO: FIX - [StabilityFix] <-- Xanatos --
	//LPCTSTR			GetUserName() const								{ return m_pszUsername; }
	//void			SetUserName(LPCTSTR pszNewName);
	uint32			GetIP() const									{ return m_dwUserIP; }
	void			SetIP( uint32 val ) //Only use this when you know the real IP or when your clearing it.
						{
							m_dwUserIP = val;
							m_nConnectIP = val;
#ifdef LANCAST // NEO: NLC - [NeoLanCast] -- Xanatos -->
							CheckOnLAN(val);
#endif //LANCAST // NEO: NLC END <-- Xanatos --
						}
#ifdef LANCAST // NEO: NLC - [NeoLanCast] -- Xanatos -->
	void			CheckOnLAN( uint32 val );
#endif //LANCAST // NEO: NLC END <-- Xanatos --
	__inline bool	HasLowID() const								{ return (m_nUserIDHybrid < 16777216); }
	void			SetConnectIP( uint32 val )						{ m_nConnectIP = val; } // NEO: MOD <-- Xanatos --
	uint32			GetConnectIP() const							{ return m_nConnectIP; }
	uint16			GetUserPort() const								{ return m_nUserPort; }
	void			SetUserPort(uint16 val)							{ m_nUserPort = val; }
	UINT			GetTransferredUp() const						{ return m_nTransferredUp; }
	UINT			GetTransferredDown() const						{ return m_nTransferredDown; }
	uint32			GetServerIP() const								{ return m_dwServerIP; }
	void			SetServerIP(uint32 nIP)							{ m_dwServerIP = nIP; }
	uint16			GetServerPort() const							{ return m_nServerPort; }
	void			SetServerPort(uint16 nPort)						{ m_nServerPort = nPort; }
	const uchar*	GetUserHash() const								{ return (uchar*)m_achUserHash; }
	void			SetUserHash(const uchar* pUserHash);
	bool			HasValidHash() const
						{
							return ((const int*)m_achUserHash[0]) != 0 || ((const int*)m_achUserHash[1]) != 0 || ((const int*)m_achUserHash[2]) != 0 || ((const int*)m_achUserHash[3]) != 0;
						}
	int				GetHashType() const;
	const uchar*	GetBuddyID() const								{ return (uchar*)m_achBuddyID; }
	void			SetBuddyID(const uchar* m_achTempBuddyID);
	bool			HasValidBuddyID() const							{ return m_bBuddyIDValid; }
	void			SetBuddyIP( uint32 val )						{ m_nBuddyIP = val; }
	uint32			GetBuddyIP() const								{ return m_nBuddyIP; }
	void			SetBuddyPort( uint16 val )						{ m_nBuddyPort = val; }
	uint16			GetBuddyPort() const							{ return m_nBuddyPort; }
	EClientSoftware	GetClientSoft() const							{ return (EClientSoftware)m_clientSoft; }
	const CString&	GetClientSoftVer() const						{ return m_strClientSoftware; }
	const CString&	GetClientModVer() const							{ return m_strModVersion; }
	// NEO: MID - [ModID] -- Xanatos -->
	const bool		IsClientMod() const								{ return (m_strModVersion.GetLength()!=0); } 
	const int		IsNeoMod() const								{ return m_iIsNeoMod; } 
#ifdef ARGOS // NEO: NA - [NeoArgos]
	void			SetModThief()									{ m_iIsNeoMod = SO_NULL; }
#endif // ARGOS // NEO: NA END
	// NEO: MID END <-- Xanatos --
	void			InitClientSoftwareVersion();
	UINT			GetVersion() const								{ return m_nClientVersion; }
	uint8			GetMuleVersion() const							{ return m_byEmuleVersion; }
	bool			ExtProtocolAvailable() const					{ return m_bEmuleProtocol; }
	bool			SupportMultiPacket() const						{ return m_bMultiPacket; }
	bool			SupportExtMultiPacket() const					{ return m_fExtMultiPacket; }
	bool			SupportPeerCache() const						{ return m_fPeerCache; }
	bool			SupportsLargeFiles() const						{ return m_fSupportsLargeFiles; }
	bool			IsEmuleClient() const							{ return m_byEmuleVersion!=0; }
	uint8			GetSourceExchangeVersion() const				{ return m_bySourceExchangeVer; }
	CClientCredits* Credits() const									{ return credits; }
	bool			IsBanned() const;
	const CString	GetClientFilename() const; // NEO: SCFS - [SmartClientFileStatus] -- Xanatos --
	//const CString&	GetClientFilename() const						{ return m_strClientFilename; }
	//void			SetClientFilename(const CString& fileName)		{ m_strClientFilename = fileName; }
	uint16			GetUDPPort() const								{ return m_nUDPPort; }
	void			SetUDPPort(uint16 nPort)						{ m_nUDPPort = nPort; }
	uint8			GetUDPVersion() const							{ return m_byUDPVer; }
	bool			SupportsUDP() const								{ return GetUDPVersion() != 0 && m_nUDPPort != 0; }
	uint16			GetKadPort() const								{ return m_nKadPort; }
	void			SetKadPort(uint16 nPort)						{ m_nKadPort = nPort; }
	uint8			GetExtendedRequestsVersion() const				{ return m_byExtendedRequestsVer; }
	uint8			GetCommentVersion() const						{ return m_byAcceptCommentVer; } // NEO: MOD <-- Xanatos --
	//void			RequestSharedFileList();
	//void			ProcessSharedFileList(const uchar* pachPacket, uint32 nSize, LPCTSTR pszDirectory = NULL);
	// NEO: XSF - [ExtendedSharedFiles] -- Xanatos -->
	bool 			RequestSharedFileList(bool bForce = false);
	bool			SendDirRequest(CString path, bool bForce = false);
	void			ProcessSharedFileList(const uchar* pachPacket, UINT nSize, LPCTSTR pszDirectory = NULL);
	void			ProcessSharedDirsList(const uchar* pachPacket, uint32 nSize);
	CRBMap<CString, bool>	*GetListDirs() { return &m_listDirs; }
	CList<CSearchFile*>	*GetListFiles() { return &m_listFiles; }
	void			SetDeniesShare(bool in = true, bool updateTree = true);
	bool			GetDeniesShare() { return m_bDeniesShare; }
	// NEO: XSF END <-- Xanatos --

	void			ClearHelloProperties();
	bool			ProcessHelloAnswer(const uchar* pachPacket, UINT nSize);
	bool			ProcessHelloPacket(const uchar* pachPacket, UINT nSize);
	void			SendHelloAnswer();
	virtual bool	SendHelloPacket();
	void			SendMuleInfoPacket(bool bAnswer);
	void			ProcessMuleInfoPacket(const uchar* pachPacket, UINT nSize);
	void			ProcessMuleCommentPacket(const uchar* pachPacket, UINT nSize);
	void			ProcessEmuleQueueRank(const uchar* packet, UINT size);
	void			ProcessEdonkeyQueueRank(const uchar* packet, UINT size);
	void			CheckQueueRankFlood();
	bool			Compare(const CUpDownClient* tocomp, bool bIgnoreUserhash = false) const;
	void			ResetFileStatusInfo();
	uint32			GetLastSrcReqTime() const						{ return m_dwLastSourceRequest; }
	void			SetLastSrcReqTime()								{ m_dwLastSourceRequest = ::GetTickCount(); }
	uint32			GetLastSrcAnswerTime() const					{ return m_dwLastSourceAnswer; }
	void			SetLastSrcAnswerTime()							{ m_dwLastSourceAnswer = ::GetTickCount(); }
	uint32			GetLastAskedForSources() const					{ return m_dwLastAskedForSources; }
	void			SetLastAskedForSources()						{ m_dwLastAskedForSources = ::GetTickCount(); }
#ifdef ARGOS // NEO: NA - [NeoArgos] -- Xanatos -->
	uint32			GetLastSourcesSent() const						{ return m_dwLastSourcesSent; }
	void			SetLastSourcesSent()							{ m_dwLastSourcesSent = ::GetTickCount(); }
#endif // ARGOS // NEO: NA END <-- Xanatos --
	bool			GetFriendSlot(bool bIntern = false) const;		// NEO: NMFS - [NiceMultiFriendSlots] <-- Xanatos --
	void			SetFriendSlot(bool bNV)							{m_bFriendSlot = bNV;}
	bool			GetReleaseSlot(bool bPS = false); // NEO: RT - [ReleaseTweaks] <-- Xanatos --
	bool			IsFriend() const;//								{ return m_Friend != NULL; } // NEO: MOD <-- Xanatos --
	bool			IsCommunity() const; // NEO: NC - [NiceCommunity] <-- Xanatos --
	// NEO: PTM - [PrivatTransferManagement] -- Xanatos -->
	uint8			IsPrivatUpload();
	uint8			IsPrivatDownload();
	// NEO: PTM END <-- Xanatos --
	void			SetCommentDirty(bool bDirty = true)				{ m_bCommentDirty = bDirty; }
	bool			GetSentCancelTransfer() const					{ return m_fSentCancelTransfer; }
	void			SetSentCancelTransfer(bool bVal)				{ m_fSentCancelTransfer = bVal; }
	void			ProcessPublicIPAnswer(const BYTE* pbyData, UINT uSize);
	void			SendPublicIPRequest();
	uint8			GetKadVersion()									{ return m_byKadVersion; }
	bool			SendBuddyPingPong()								{ return m_dwLastBuddyPingPongTime < ::GetTickCount(); }
	bool			AllowIncomeingBuddyPingPong()					{ return m_dwLastBuddyPingPongTime < (::GetTickCount()-(3*60*1000)); }
	void			SetLastBuddyPingPongTime()						{ m_dwLastBuddyPingPongTime = (::GetTickCount()+(10*60*1000)); }
	// secure ident
	void			SendPublicKeyPacket();
	void			SendSignaturePacket();
	void			ProcessPublicKeyPacket(const uchar* pachPacket, UINT nSize);
	void			ProcessSignaturePacket(const uchar* pachPacket, UINT nSize);
	uint8			GetSecureIdentState() const						{ return (uint8)m_SecureIdentState; }
	void			SendSecIdentStatePacket();
	void			ProcessSecIdentStatePacket(const uchar* pachPacket, UINT nSize);
	uint8			GetInfoPacketsReceived() const					{ return m_byInfopacketsReceived; }
	uint8			SupportSecIdent() const							{ return m_bySupportSecIdent; } // NEO: MOD <-- Xanatos --
	void			InfoPacketsReceived();
#ifdef ISPBYPASS // NEO: MP - [MultiPort] -- Xanatos -->
	void			SendAUXPortWhenNeeded(bool bOnProcess = false);
	void			SendAUXPort();
	void			ProcessAUXPort(const uchar* pachPacket, UINT nSize);
#endif // ISPBYPASS // NEO: MP END <-- Xanatos --
	// NEO: FSUR - [FixStartupLoadReq] -- Xanatos -->
	void			SetActiveUpReqFlag(UINT val) { m_fActiveUpReqFlag = val; }
	UINT			GetActiveUpReqFlag() const { return m_fActiveUpReqFlag; }
	// NEO: FSUR END <-- Xanatos --
	// preview
	void			SendPreviewRequest(const CAbstractFile* pForFile);
	void			SendPreviewAnswer(const CKnownFile* pForFile, CxImage** imgFrames, uint8 nCount);
	void			ProcessPreviewReq(const uchar* pachPacket, UINT nSize);
	void			ProcessPreviewAnswer(const uchar* pachPacket, UINT nSize);
	bool			GetPreviewSupport() const						{ return m_fSupportsPreview && GetViewSharedFilesSupport(); }
	bool			GetViewSharedFilesSupport() const				{ return m_fNoViewSharedFiles==0; }
	bool			SafeSendPacket(Packet* packet);
#ifndef ARGOS // NEO: NA -- Xanatos -->
	void			CheckForGPLEvilDoer();
#endif // ARGOS // NEO: NA END <-- Xanatos --
	//upload
	EUploadState	GetUploadState() const							{ return (EUploadState)m_nUploadState; }
	void			SetUploadState(EUploadState news);
	uint32			GetWaitStartTime() const;
	void 			SetWaitStartTime();
	void 			ClearWaitStartTime();
	uint32			GetWaitTime() const								{ return m_dwUploadTime - GetWaitStartTime(); }
	// NEO: SQ - [SaveUploadQueue] -- Xanatos -->
	void			SaveQueueWaitTime();
	void			ClearQueueWaitTime();
	// NEO: SQ END <-- Xanatos --
	bool			IsDownloading() const							{ return (m_nUploadState == US_UPLOADING); }
	bool			HasBlocks() const								{ return !m_BlockRequests_queue.IsEmpty(); }
	UINT			GetDatarate() const								{ return m_nUpDatarate; }	
	UINT			GetScore(bool sysvalue, bool isdownloading = false, bool onlybasevalue = false, bool forceTimeScore = true, bool noRelease = false, CKnownFile* UpFile = NULL) const; // NEO: RQ - [RandomQueue] // NEO: RT - [ReleaseTweaks] <-- Xanatos --
	void			AddReqBlock(Requested_Block_Struct* reqblock);
	void			CreateNextBlockPackage();
	uint32			GetUpStartTimeDelay() const						{ return ::GetTickCount() - m_dwUploadTime; }
#ifdef NEO_UBT // NEO: NUBT - [NeoUploadBandwidthThrottler] -- Xanatos -->
	void 			SetUpStartTime()								{ m_dwUploadTime = ::GetTickCount();  m_dwShieldTime = 0;}
#else
	void 			SetUpStartTime()								{ m_dwUploadTime = ::GetTickCount(); }
#endif // NEO_UBT // NEO: NUBT END <-- Xanatos --
	void			SendHashsetPacket(const uchar* fileid);
	const uchar*	GetUploadFileID() const							{ return requpfileid; }
	void			SetUploadFileID(CKnownFile* newreqfile);
	// NEO: MOD - [UploadingFile] -- Xanatos -->
	CKnownFile*		GetUploadingFile()								{ return accupfile; }
	void			SetUploadingFile(CKnownFile* upfile)			{ accupfile = upfile; }
	// NEO: MOD END <-- Xanatos --
	UINT			SendBlockData();
	void			ClearUploadBlockRequests();
	void			SendRankingInfo();
	void			SendAcceptUpload(); // NEO: PTM - [PrivatTransferManagement] <-- Xanatos --
	void			SendCommentInfo(/*const*/ CKnownFile *file);
	void			AddRequestCount(const uchar* fileid);
	// NEO: MFSB - [MultiFileStatusBars] -- Xanatos -->
	Requested_File_Struct*	AddRequestStruct(const uchar* fileid); 
	Requested_File_Struct*	GetRequestStruct(const uchar* fileid); 
	CTypedPtrList<CPtrList, Requested_File_Struct*>* GetRequestedFilesList()	{return &m_RequestedFiles_list;}
	Requested_File_Struct*	GetCurrentRequestStruct() const				{ return requpfile; }
	// NEO: MFSB END <-- Xanatos --
	void			UnBan();
	void			Ban(LPCTSTR pszReason = NULL);
	UINT			GetAskedCount() const							{ return m_cAsked; }
	void			AddAskedCount()									{ m_cAsked++; }
	void			SetAskedCount(UINT m_cInAsked)					{ m_cAsked = m_cInAsked; }
	void			FlushSendBlocks(); // call this when you stop upload, or the socket might be not able to send
	uint32			GetLastUpRequest() const						{ return m_dwLastUpRequest; }
	void			SetLastUpRequest()								{ m_dwLastUpRequest = ::GetTickCount(); }
	void			SetCollectionUploadSlot(bool bValue);
	bool			HasCollectionUploadSlot() const					{ return m_bCollectionUploadSlot; }
#ifdef ARGOS // NEO: NA - [NeoArgos] -- Xanatos -->
	bool			IsHotFileSwapAllowed(const uchar* reqfilehash);
	bool			CheckUDPFileReaskPing();
	void			CheckFileNotFound();
	bool			CheckFileRequest(CKnownFile* file);
#endif // ARGOS // NEO: NA END <-- Xanatos --

	UINT			GetSessionUp() const							{ return m_nTransferredUp - m_nCurSessionUp; }
	void			ResetSessionUp() {
						m_nCurSessionUp = m_nTransferredUp;
						m_addedPayloadQueueSession = 0;
						m_nCurQueueSessionPayloadUp = 0;
					}

	UINT			GetSessionDown() const							{ return m_nTransferredDown - m_nCurSessionDown; }
	void			ResetSessionDown() {
						m_nCurSessionDown = m_nTransferredDown;
					}
	UINT			GetQueueSessionPayloadUp() const				{ return m_nCurQueueSessionPayloadUp; }
    UINT			GetPayloadInBuffer() const						{ return m_addedPayloadQueueSession - GetQueueSessionPayloadUp(); }

	bool			ProcessExtendedInfo(CSafeMemFile* packet, CClientFileStatus* status, CKnownFile* tempreqfile, bool bUDP = false); // NEO: SCFS - [SmartClientFileStatus] <-- Xanatos --
	//bool			ProcessExtendedInfo(CSafeMemFile* packet, CKnownFile* tempreqfile);

	void			DrawUpStatusBar(CDC* dc, RECT* rect, Requested_File_Struct* file, bool  bFlat) const; // NEO: MFSB - [MultiFileStatusBars] <-- Xanatos --
	// NEO: SCFS - [SmartClientFileStatus] -- Xanatos --
	/*
	uint16			GetUpPartCount() const							{ return m_nUpPartCount; }
	bool			IsUpPartAvailable(UINT iPart) const {
						return (iPart>=m_nUpPartCount || !m_abyUpPartStatus) ? false : m_abyUpPartStatus[iPart]!=0;
					}
	uint8*			GetUpPartStatus() const							{ return m_abyUpPartStatus; }
	*/
    float           GetCombinedFilePrioAndCredit();

	//download
	UINT			GetAskedCountDown() const						{ return m_cDownAsked; }
	void			AddAskedCountDown()								{ m_cDownAsked++; }
	void			SetAskedCountDown(UINT cInDownAsked)			{ m_cDownAsked = cInDownAsked; }
	EDownloadState	GetDownloadState() const						{ return (EDownloadState)m_nDownloadState; }
	EDownloadState	GetDownloadStateEx() const						{ if (m_nDownloadState == DS_ONQUEUE && IsRemoteQueueFull()) return DS_REMOTEQUEUEFULL; return (EDownloadState)m_nDownloadState; } // NEO: MOD <-- Xanatos --
	// NEO: XSC - [ExtremeSourceCache] -- Xanatos -->
	bool			IsSurceSuspended(bool bAlsoError = true, bool bAlsoCached = true) const { 
						return (
#if defined(NEO_SK) || defined(NEO_SS) // NEO: NSK - [NeoSourceKeeper] // NEO: NSS - [NeoSourceStorage]
#ifdef NEO_SK
							(m_nDownloadState == DS_UNREACHABLE) ||
#endif // NEO_SK
#ifdef NEO_SS 
							(m_nDownloadState == DS_LOADED) ||
							(m_nDownloadState == DS_RESERVE) ||
							(m_nDownloadState == DS_RETIRED) ||
#endif // NEO_SS
							(bAlsoError && m_nDownloadState == DS_ERROR) ||
#endif // NEO_SK // NEO_SS // NEO: NSK END // NEO: NSS END
							(bAlsoCached && m_nDownloadState == DS_CACHED));
					}
	// NEO: XSC END <-- Xanatos --
	void			SetDownloadState(EDownloadState nNewState, LPCTSTR pszReason = _T("Unspecified"));
	void			EndDownloadStats(bool bError = false); // NEO: DKA - [DownloadKeepAlive] <-- Xanatos --
	uint32			GetLastAskedTime(const CPartFile* partFile = NULL) const;
    void            SetLastAskedTime();
	void            SetSpreadReaskModyfier(); // NEO: SR - [SpreadReask] <-- Xanatos --
	// NEO: DR - [DownloadReask] -- Xanatos -->
	uint32			GetReqFileReaskIntervals();
	void            SetNextAskedTime(uint32 uNextReask = 0);
	bool			SetSafeReAskTime(bool bManual = false);
	// NEO: DR END <-- Xanatos --

	// NEO: SCFS - [SmartClientFileStatus] -- Xanatos -->
	CClientFileStatus* GetFileStatus(const CKnownFile* File, bool bAdd = false) const;
	void			ClearFileStatus(const CKnownFile* File);
	bool			IsCompleteSource(CKnownFile* file) const;
	// NEO: SCFS END <-- Xanatos --
	/*
	bool			IsPartAvailable(UINT iPart) const {
						return (iPart>=m_nPartCount || !m_abyPartStatus) ? false : m_abyPartStatus[iPart]!=0;
					}
	uint8*			GetPartStatus() const							{ return m_abyPartStatus; }
	uint16			GetPartCount() const							{ return m_nPartCount; }
	*/
	UINT			GetDownloadDatarate() const						{ return m_nDownDatarate; }
	UINT			GetRemoteQueueRank() const						{ return m_nRemoteQueueRank; }
	// NEO: CQR - [CollorQueueRank] -- Xanatos -->
	int				GetDeltaRemoteQueueRank() const					{ return m_nDeltaRemoteQueueRank; }
	UINT			GetInitialRemoteQueueRank() const				{ return m_nInitialRemoteQueueRank; }
	// NEO: CQR END <-- Xanatos --
	void			SetRemoteQueueRank(UINT nr, bool bUpdateDisplay = false);
	bool			IsRemoteQueueFull() const						{ return m_bRemoteQueueFull; }
	void			SetRemoteQueueFull(bool flag)					{ m_bRemoteQueueFull = flag; }
	void			DrawStatusBar(CDC* dc, LPCRECT rect, CPartFile* file, bool  bFlat) const;  // NEO: MFSB - [MultiFileStatusBars] <-- Xanatos --
	bool			AskForDownload(bool bIgnoreConLimit = false); // NEO: MCH - [ManualClientHandling] <-- Xanatos --
	virtual void	SendFileRequest();
	void			SendFileAdvertisement(CKnownFile* file); // NEO: ASP - [ActiveSpreading] <-- Xanatos --
	void			RequestHashset(); // NEO: MOD - [SFSafeHash] <-- Xanaots --
	void			SendStartupLoadReq();
	void			ProcessFileInfo(CSafeMemFile* data, CPartFile* file);
	// NEO: SCFS - [SmartClientFileStatus] -- Xanatos -->
	void			ProcessFileStatus(bool bUdpPacket, CSafeMemFile* data, CClientFileStatus* status, CPartFile* file);
	void			ProcessModFileStatus(bool bUdpPacket, CClientFileStatus* status, CPartFile* file, bool bCheckPassive = false, bool bOnlySCT = false, bool bOnlyCatch = false);
	void			HandleFileStatus(CPartFile* file, bool bUdpPacket, bool bPartsNeeded, bool bCheckPassive = false);
	// NEO: SCFS END <-- Xanatos --

	void			ProcessHashSet(const uchar* data, UINT size);
	void			ProcessAcceptUpload();
	bool			AddRequestForAnotherFile(CPartFile* file);
	void			CreateBlockRequests(int iMaxBlocks);
	virtual void	SendBlockRequests();
	POSITION		SendBlockRequestsPacket(POSITION startPos); // NEO: DBR - [DynamicBlockRequest] <-- Xanatos --
	virtual bool	SendHttpBlockRequests();
	virtual void	ProcessBlockPacket(const uchar* packet, UINT size, bool packed, bool bI64Offsets);
	virtual void	ProcessHttpBlockPacket(const BYTE* pucData, UINT uSize);
	void			ClearDownloadBlockRequests();
	void			SendOutOfPartReqsAndAddToWaitingQueue();
	// NEO: ASM - [AccurateSpeedMeasure] -- Xanatos -->
	void			AddDownloadSize(uint64 size)	{m_nSumForAvgDownDataRate += (UINT)size;}
	void			AddUploadedSize(uint64 size)	{m_nSumForAvgUpDataRate += (UINT)size;}
	UINT			CalculateDownloadRate();
	UINT			CalculateUploadRate(); 
	UINT			CheckUploadRate(int dataratestocheck);
	UINT			CheckDownloadRate(int dataratestocheck);
	// NEO: ASM END <-- Xanatos --
	uint16			GetAvailablePartCount() const;
	bool			SwapToAnotherFile(LPCTSTR pszReason, bool bIgnoreNoNeeded, bool ignoreSuspensions, bool bRemoveCompletely, CPartFile* toFile = NULL, bool allowSame = true, bool isAboutToAsk = false, bool debug = false); // ZZ:DownloadManager
	bool			DoSwap(CPartFile* SwapTo, bool bRemoveCompletely, LPCTSTR reason, bool bHandleClientReq = false); // ZZ:DownloadManager // NEO: MCM - [ManualClientManagement] <-- Xanatos --
	void			DontSwapTo(/*const*/ CPartFile* file);
	bool			IsSwapSuspended(const CPartFile* file, const bool allowShortReaskTime = false, const bool fileIsNNP = false) /*const*/; // ZZ:DownloadManager
	// NEO: MCM - [ManualClientManagement] -- Xanatos -->
	void			DisableSwaping(bool bDisable)	{m_bDisableSwaping = bDisable;}
	bool			IsSwapingDisabled() const		{return m_bDisableSwaping;}
	// NEO: MCM END <-- Xanatos --
    uint32          GetTimeUntilReask() const;
    uint32          GetTimeUntilReask(const CPartFile* file) const;
    uint32			GetTimeUntilReask(const CPartFile* file, const bool allowShortReaskTime, const bool useGivenNNP = false, const bool givenNNP = false) const;
	void			UDPReaskACK(uint16 nNewQR);
	void			UDPReaskFNF();
	void			UDPReaskForDownload();
	bool			IsSourceRequestAllowed() const;
    bool            IsSourceRequestAllowed(CPartFile* partfile, bool sourceExchangeCheck = false) const; // ZZ:DownloadManager

	bool			IsValidSource() const;
	ESourceFrom		GetSourceFrom() const							{ return (ESourceFrom)m_nSourceFrom; }
	void			SetSourceFrom(ESourceFrom val)					{ m_nSourceFrom = (_ESourceFrom)val; }

	void			SetDownStartTime()								{ m_dwDownStartTime = ::GetTickCount(); }
	uint32			GetDownTimeDifference(boolean clear = true)	{
						uint32 myTime = m_dwDownStartTime;
						if(clear) m_dwDownStartTime = 0;
						return ::GetTickCount() - myTime;
					}
	bool			GetTransferredDownMini() const					{ return m_bTransferredDownMini; }
	void			SetTransferredDownMini()						{ m_bTransferredDownMini = true; }
	void			InitTransferredDownMini()						{ m_bTransferredDownMini = false; }
	UINT			GetA4AFCount() const							{ return m_OtherRequests_list.GetCount(); }

	// NEO: SCFS - [SmartClientFileStatus] -- Xanatos --
	//uint16			GetUpCompleteSourcesCount() const				{ return m_nUpCompleteSourcesCount; }
	//void			SetUpCompleteSourcesCount(uint16 n)				{ m_nUpCompleteSourcesCount = n; }

	//chat
	EChatState		GetChatState() const							{ return (EChatState)m_nChatstate; }
	void			SetChatState(EChatState nNewS)					{ m_nChatstate = (_EChatState)nNewS; }

	//KadIPCheck
	EKadState		GetKadState() const								{ return (EKadState)m_nKadState; }
	void			SetKadState(EKadState nNewS)					{ m_nKadState = (_EKadState)nNewS; }

	// NEO: SCFS - [SmartClientFileStatus] -- Xanatos --
	//File Comment
	//bool			HasFileComment() const							{ return !m_strFileComment.IsEmpty(); }
    //const CString&	GetFileComment() const							{ return m_strFileComment; } 
    //void			SetFileComment(LPCTSTR pszComment)				{ m_strFileComment = pszComment; }

	//bool			HasFileRating() const							{ return m_uFileRating > 0; }
    //uint8			GetFileRating() const							{ return m_uFileRating; }
    //void			SetFileRating(uint8 uRating)					{ m_uFileRating = uRating; }

	// Barry - Process zip file as it arrives, don't need to wait until end of block
	int				unzip(Pending_Block_Struct *block, const BYTE *zipped, UINT lenZipped, BYTE **unzipped, UINT *lenUnzipped, int iRecursion = 0);
	void			UpdateDisplayedInfo(bool force = false);
	int             GetFileListRequested() const					{ return m_iFileListRequested; }
    void            SetFileListRequested(int iFileListRequested)	{ m_iFileListRequested = iFileListRequested; }

	// message filtering
	uint8			GetMessagesReceived() const						{ return m_cMessagesReceived; }
	void			SetMessagesReceived(uint8 nCount)				{ m_cMessagesReceived = nCount; }
	void			IncMessagesReceived()							{ m_cMessagesReceived++; }
	uint8			GetMessagesSent() const							{ return m_cMessagesSent; }
	void			SetMessagesSent(uint8 nCount)					{ m_cMessagesSent = nCount; }
	void			IncMessagesSent()								{ m_cMessagesSent++; }
	bool			IsSpammer() const								{ return m_fIsSpammer; }
	void			SetSpammer(bool bVal);
	bool			GetMessageFiltered() const						{ return m_fMessageFiltered; }
	void			SetMessageFiltered(bool bVal);

	virtual void	SetRequestFile(CPartFile* pReqFile);
	CPartFile*		GetRequestFile() const							{ return reqfile; }

	void			RequestSourceList(); // NEO: MCH - [ManualClientHandling] <-- Xanatos --

	// NEO: RIC - [ReaskOnIDChange] -- Xanatos -->
	bool			NotifyIdChage(); 
	bool			WaitingNotifyIdChage()									{ return m_bWainingNotifyIdChage; }
	// NEO: RIC END <-- Xanatos --

	// AICH Stuff
	void			SetReqFileAICHHash(CAICHHash* val);
	CAICHHash*		GetReqFileAICHHash() const						{ return m_pReqFileAICHHash; }
	bool			IsSupportingAICH() const						{ return m_fSupportsAICH & 0x01; }
	void			SendAICHRequest(CPartFile* pForFile, uint16 nPart);
	bool			IsAICHReqPending() const						{ return m_fAICHRequested; }
	void			ProcessAICHAnswer(const uchar* packet, UINT size);
	void			ProcessAICHRequest(const uchar* packet, UINT size);
	void			ProcessAICHFileHash(CSafeMemFile* data, CPartFile* file);

	EUtf8Str		GetUnicodeSupport() const;

	CString			GetDownloadStateDisplayString() const;
	CString			GetUploadStateDisplayString() const;

	LPCTSTR			DbgGetDownloadState() const;
	LPCTSTR			DbgGetUploadState() const;
	LPCTSTR			DbgGetKadState() const;
	CString			DbgGetClientInfo(bool bFormatIP = false) const;
	CString			DbgGetFullClientSoftVer() const;
	const CString&	DbgGetHelloInfo() const							{ return m_strHelloInfo; }
	const CString&	DbgGetMuleInfo() const							{ return m_strMuleInfo; }

// ZZ:DownloadManager -->
    const bool      IsInNoNeededList(const CPartFile* fileToCheck) const;
    const bool      SwapToRightFile(CPartFile* SwapTo, CPartFile* cur_file, bool ignoreSuspensions, bool SwapToIsNNPFile, bool isNNPFile, bool& wasSkippedDueToSourceExchange, bool doAgressiveSwapping = false, bool debug = false);
    const DWORD     getLastTriedToConnectTime() { return m_dwLastTriedToConnect; }
// <-- ZZ:DownloadManager

	void			ClearWhenNeeded(); // NEO: MOD <-- Xanatos --

	bool			IsPartAvailable(UINT part, int iMode = 0, bool bAll = false, CPartFile* file = NULL); // NEO: NPC - [NeoPartCatch] <-- Xanatos --

	uint8			GetIncompletePartVersion() const				{ return m_IncompletePartVer; } // NEO: ICS - [InteligentChunkSelection] <-- Xanatos --
	uint8			GetSubChunksVer() const							{ return m_SubChunksVer; } // NEO: SCT - [SubChunkTransfer] <-- Xanatos --
	// NEO: RPS - [RealPartStatus] -- Xanatos -->
	uint8			GetHidenPartStatusVersion() const				{ return m_HidenPartStatusVer; } 
	uint8			GetBlockedPartStatusVersion() const				{ return m_BlockedPartStatusVer; }
	// NEO: RPS END <-- Xanatos --
	bool			GetUDPxSupport() const							{ return (m_IncompletePartVer > 1 || m_SubChunksVer || m_HidenPartStatusVer || m_BlockedPartStatusVer || m_SubChunksVer) && GetNeoModProtVersion() == 0; } // NEO: XUDP - [UDPExtensions] <-- Xanatos --
	// NEO: NMP - [NeoModProt] -- Xanatos -->
	uint8			GetNeoModProtVersion() const					{ return m_NeoModProtVersion; } 
	uint8			GetNeoXSVersion() const							{ return m_NeoXSVersion; } // NEO: NMPx - [NeoModProtXS]
	uint8			IsLowIDUDPPingSupport() const					{ return m_LowIDUDPPingSupport; } 
	//uint8			SupportUnsolicitedPartStatus() const			{ return m_UnsolicitedPartStatus; } 
	// NEO: NMP END <-- Xanatos --
	uint8			GetExtraInfoVersion() const						{ return m_ExtraInfoVer; } // NEO: NXI - [NeoExtraInfo] <-- Xanatos --

	// NEO: NMPi - [NeoModProtInfo] -- Xanatos -->
	void			SendModInfoPacket();
	void			ProcessModInfoPacket(const uchar* pachPacket, uint32 nSize);
	// NEO: NMPi END <-- Xanatos --
	void			SendExtendedFileStatus(CKnownFile* file, bool bReq); // NEO: XCFS - [ExtendedClientFileStatus] <-- Xanatos --
	// NEO: NMPm - [WriteModMultiPacket] -- Xanatos -->
	void			WriteModMultiPacket(CSafeMemFile* data_out, CKnownFile* file, CClientFileStatus* status, bool bReq, bool bUDP = false);
	void			ReadModMultiPacket(CSafeMemFile* data_in, CKnownFile* file, CClientFileStatus* status, uint8 opcode = 0);
	// NEO: NMPm END <-- Xanatos --
	// NEO: NMPx - [NeoModProtXS] -- Xanatos -->
	void			WriteNeoXSTags(CSafeMemFile* data, const CUpDownClient* forClient) const;
	static struct tNeoXSTags {
		tNeoXSTags();
		void Attach(CUpDownClient* newcleint);

		uint32 dwServerIP;
		uint16 nServerPort;

		uchar abyBuddyID[16];
		bool bBuddyID;

		uint32 dwBuddyIP;
		uint16 nBuddyPort;

#ifdef NATTUNNELING // NEO: NATT - [NatTraversal]
		uint8 uNatTraversalVersion;
		uint8 uNatCharacteristic;
		uint8 uNatPortRelaiable;
		uint16 nNatPort;
#endif //NATTUNNELING // NEO: NATT END

#ifdef ISPBYPASS // NEO: SCC - [SecureClinetConnection]
		uint8 uIspTraversalVersion;
		uint8 uEncryptionNeeded;
		uint8 uSupportSecureCallback;
 #ifdef NATTUNNELING // NEO: NATT - [NatTraversal]
		uint8 uUseNATEncrpytion;
 #endif //NATTUNNELING // NEO: NATT END
		uint16 uSecurePort;
		byte abyRemoteDHPrime[32];
		byte abyRemoteDHBase;
#endif // ISPBYPASS // NEO: SCC END
	}				*ReadNeoXSTags(CSafeMemFile* data, const CUpDownClient* pClient);
	// NEO: NMPx END <-- Xanatos --

#ifdef ISPBYPASS // NEO: SCC - [SecureClinetConnection] -- Xanatos -->
	void			SetSecureCommunicationSupport(uint8 uSet = 3) 	{ m_SecureCommunicationVer = uSet; }
	uint8			GetSecureCommunicationVersion() const			{ return m_SecureCommunicationVer; }
	void			SetRequierEncryption(uint8 uSet = 2) 			{ m_uRequierEncryption = uSet; }
	uint8			DoRequierEncryption() const						{ return m_uRequierEncryption; }
	uint8			SupportSecureCallback() const					{ return m_uSupportSecureCallback; }
	void			SetSupportSecureCallback(uint8 uSet = 1)		{ m_uSupportSecureCallback = uSet; }
	uint8			PreferUnencryptedPayload() const				{ return m_uPreferUnEnCryptedPayload; }
	uint8			UseSimpleXOREncryption() const					{ return m_uSimpleXOREncryption; }
	uint8			UsePKEncrpytion() const							{ return m_uPKEncrpytion; }
	// NEO: MP - [MultiPort]
	uint16			GetRemoteSecurePort() const						{ return m_nRemoteSecurePort; }
	void			SetRemoteSecurePort(uint16 uSet) 				{ m_nRemoteSecurePort = uSet; }
	byte*			GetRemoteDHPrime() const						{ return m_abyRemoteDHPrime; }
	void			SetRemoteDHPrime(const byte* abyRemoteDHPrime);
	byte			GetRemoteDHBase() const							{ return m_abyRemoteDHBase; }
	void			SetRemoteDHBase(const byte abyRemoteDHBase)		{ m_abyRemoteDHBase = abyRemoteDHBase; }
	uint16			GetLocalSecurePort() const						{ return m_nLocalSecurePort; }
	// NEO: MP END
 #ifdef NATTUNNELING // NEO: NATT - [NatTraversal]
	void			SetNATEncrpytion(uint8 uSet = 1) 				{ m_uUseNATEncrpytion = uSet; }
	uint8			UseNATEncrpytion() const						{ return m_uUseNATEncrpytion && m_SecureCommunicationVer >= 3; }
 #endif //NATTUNNELING // NEO: NATT END
	uint8			UseUDPSecurity() const							{ return m_uUseUDPSecurity; } // NEO: SUC - [SafeUCPCommunication]
#endif // ISPBYPASS // NEO: SCC END <-- Xanatos --

#ifdef NATTUNNELING // NEO: NATT - [NatTraversal] -- Xanatos -->
	void			SetNatTraversalSupport(uint8 uSet = 1) 			{ m_uNatTraversalVersion = uSet; }
	uint8			GetNatTraversalVersion() const					{ return m_uNatTraversalVersion; }
	void			SetNatPortRelaiable(uint8 set) 					{ m_uNatPortRelaiable = set; }
	// when the port is relaialable it must be known
	uint8			IsNATPortRelaiable() const						{ return m_uNatPortRelaiable && GetNatPort(); }
	void			SetNatType(uint8 set) 							{ m_uNatCharacteristic = set; }
	uint8			GetNatType() const								{ return m_uNatCharacteristic; }
	// A full cone cleint must have a NAT port
	bool			IsFullConeNat() const							{ return m_uNatCharacteristic == 1 && GetNatPort(); }
	bool			IsSymetricNat() const							{ return m_uNatCharacteristic == 2; }
	void			SetNatPort(uint16 port) 						{ m_nNatPort = port; }
	// For establishing the connection we *always* select the ports in this order: NAT, KAD, UDP
	uint16			GetNatPort() const								{ return m_nNatPort ? m_nNatPort : GetKadPort() ? GetKadPort() : GetUDPPort(); }
#endif //NATTUNNELING // NEO: NATT END <-- Xanatos --

	// NEO: NXI - [NeoExtraInfo] -- Xanatos -->
	void			ProcessExtraInfoPacket(CSafeMemFile* data, bool bFromUDP = false);
	void			SendExtraInfoPacket(DWORD dwInfos, bool bViaUDP = false, uint32 dwIP = 0, uint16 nPort = 0);
	// NEO: NXI END <-- Xanatos --

	// NEO: EDT - [EstimatedDownloadTime] -- Xanatos -->
	uint8			GetDownloadTimeVersion()  const						{ return m_DownloadTimeVer;	}
	const CTime &	GetDownloadTime() const								{ return m_DownloadTime; }
	uint32			GetDownloadTimeVal() const							{ return m_DownloadTimeVal; }
	uint32			GetDownloadTimeErr() const							{ return m_DownloadTimeErr;	}
	void			EstimateDownloadTime(uint32 &avg_time, uint32 &err_time);
	void			SetRemoteEDT(uint32 avg, uint32 err);
	// NEO: EDT END <-- Xanatos --

	// NEO: L2H - [LowID2HighIDAutoCallback] -- Xanatos -->
	bool			GetL2HACSupport() const								{ return m_L2HAC_support; }
	uint32			GetL2HACTime() const;

	void			SetLastL2HACExecution(uint32 m_set_to = 0)			{ m_last_l2hac_exec = m_set_to ? m_set_to : ::GetTickCount(); }
	uint32			GetLastL2HACExecution()								{ return m_last_l2hac_exec; }

	void			EnableL2HAC()										{ m_l2hac_enabled = true; } 
	void			DisableL2HAC()										{ m_l2hac_enabled = false; } 
	bool			IsL2HACEnabled()									{ return m_l2hac_enabled; }
	// NEO: L2H END <-- Xanatos --

	// NEO: TCR - [TCPConnectionRetry] -- Xanatos -->
	void			SetForDelete()										{ m_uFaildCount = (uint16)-1; }

	void			IncrementFaildCount()								{ m_uFaildCount++; } 
	void			ResetFaildCount()									{ m_uFaildCount = 0; } 
	uint16			GetFaildCount()										{ return m_uFaildCount; } 

	bool			IsSourceConfirmed()									{ return (m_dwUserIP != 0); }
#ifdef NEO_SS // NEO: NSS - [NeoSourceStorage] -- Xanatos -->
	bool			IsActive(bool bNewActive = false);
#endif // NEO_SS // NEO: NSS END <-- Xanatos --
	// NEO: TCR END <-- Xanatos --
	// NEO: NSS - [NeoSourceStorage] -- Xanatos -->
	uint32			GetLastSeen() const									{ return m_uLastSeen; }
	void			SetLastSeen()										{ m_uLastSeen = time(NULL); }
	// NEO: NSS END <-- Xanatos --

#ifdef NEO_SS // NEO: NSS - [NeoSourceStorage] -- Xanatos -->
	void			StoreToFile(CFileDataIO* file, bool bFullData = false);
	bool			CreateFromFile(CFileDataIO* file);

	void			WriteToFile(CFileDataIO* file, CPartFile* owner);
	CPartFile*		LoadFromFile(CFileDataIO* file, CPartFile* owner);

	void			SetLastLoadProcessTime()							{ m_uLastLoadTime = ::GetTickCount(); }
	uint32			GetLastLoadProcessTime()							{ return m_uLastLoadTime; }

	bool			IsOutOfDate(bool bSmooth, UINT MaxFaildCount, UINT OutOfDateTime, UINT SourcesCount);
	bool			IsLinkedLastSeen();
#endif // NEO_SS // NEO: NSS END <-- Xanatos --

	uint32			GetCacheStartTime()									{ return m_uCacheStartTime; } // NEO: XSC - [ExtremeSourceCache] <-- Xanatos --

#ifdef NEO_CD // NEO: NCD - [NeoClientDatabase] -- Xanatos -->
	CKnownSource*	Source()											{ return source; }
	void			LinkSource(CKnownSource* Source);
	void			AttachSource(CKnownSource* Source, bool bAssimilate);
#endif // NEO_CD // NEO: NCD END <-- Xanatos --

#ifdef LANCAST // NEO: NLC - [NeoLanCast] -- Xanatos -->
	bool			IsLanClient() const									{ return m_bLanClient; }
#endif //LANCAST // NEO: NLC END <-- Xanatos --

#ifdef ARGOS // NEO: NA - [NeoArgos] -- Xanatos -->
	void			IncXSReqs();
	void			IncXSAnswer();
	bool			CheckXSAsk();
#endif // ARGOS // NEO: NA END <-- Xanatos --

	bool			SUIFaild() const; // NEO: MOD <-- Xanatos --

	CClientDetailDialogInterface*	GetDetailDialogInterface() const { return m_detailDialogInterface; }	// NEO: MLD - [ModelesDialogs] <-- Xanatos --

#ifdef IP2COUNTRY // NEO: IP2C - [IPtoCountry] -- Xanatos -->
	CString			GetCountryName(bool longName = false) const;
	int				GetCountryFlagIndex() const;
	void			ResetIP2Country(uint32 dwIP = 0);
#endif // IP2COUNTRY // NEO: IP2C END <-- Xanatos --

#ifdef _DEBUG
	// Diagnostic Support
	virtual void AssertValid() const;
	virtual void Dump(CDumpContext& dc) const;
#endif

	CClientReqSocket* socket;
#ifdef ISPBYPASS // NEO: CHS - [ConnectionHotSwap] -- Xanatos -->
	CClientReqSocket* oldsocket;
#endif // ISPBYPASS // NEO: CHS END <-- Xanatos --
	CClientCredits*	credits;
	CFriend*		m_Friend;
	uint8			m_FreeDownload; // NEO: PTM - [PrivatTransferManagement] <-- Xanatos --
	//uint8*			m_abyUpPartStatus; // NEO: SCFS - [SmartClientFileStatus] <-- Xanatos --
	CTypedPtrList<CPtrList, CPartFile*> m_OtherRequests_list;
	CTypedPtrList<CPtrList, CPartFile*> m_OtherNoNeeded_list;
	uint16			m_lastPartAsked;
	//bool			m_bAddNextConnect; // NEO: MOD - [NewUploadState] <-- Xanatos --

	Extra_Info_Struct* m_ExtraInfo; // NEO: NXI - [NeoExtraInfo] <-- Xanatos --

#ifdef NEO_DBT // NEO: NDBT - [NeoDownloadBandwidthThrottler] -- Xanatos -->
	CClientReqSocket* GetFileDownloadSocket(bool bLog = false);
#endif // NEO_DBT // NEO: NDBT END <-- Xanatos --
#ifdef NEO_UBT // NEO: NUBT - [NeoUploadBandwidthThrottler] -- Xanatos -->
    CClientReqSocket* GetFileUploadSocket(bool bLog = false);

	uint32			MinToMB() const;

	bool			HaveTrickleSlot() const;
	bool			IsPriorityClient() const;
	float			GetSocketRatio() const;
#else
    void			SetSlotNumber(UINT newValue)					{ m_slotNumber = newValue; }
    UINT			GetSlotNumber() const							{ return m_slotNumber; }

    CEMSocket*		GetFileUploadSocket(bool bLog = false);
#endif // NEO_UBT // NEO: NUBT END <-- Xanatos --

	void			SetAdvertiseFile()								{ m_bAdvertisementPending = true; } // NEO: ASP - [ActiveSpreading] <-- Xanatos --

	// NEO: NTT - [NewToolTips] -- Xanatos -->
	void GetTooltipBaseInfo(CString &info);
	void GetTooltipDownloadInfo(CString &info, bool a4af, CPartFile* file = NULL, bool base = true);
	void GetTooltipUploadInfo(CString &info, bool base = true);
	void GetTooltipQueueInfo(CString &info, bool base = true);
	void GetTooltipClientInfo(CString &info);
	// NEO: NTT END <-- Xanatos --

	///////////////////////////////////////////////////////////////////////////
	// PeerCache client
	//
	bool IsDownloadingFromPeerCache() const;
	bool IsUploadingToPeerCache() const;
	void SetPeerCacheDownState(EPeerCacheDownState eState);
	void SetPeerCacheUpState(EPeerCacheUpState eState);
#ifdef NEO_UBT // NEO: NUBT - [NeoUploadBandwidthThrottler] -- Xanatos -->
 #ifdef WEBCACHE // NEO: WC - [WebCache]
	bool HasCacheState() {return m_ePeerCacheUpState == PCUS_WAIT_CACHE_REPLY || m_ePeerCacheUpState == PCUS_UPLOADING || m_eWebCacheUpState == WCUS_UPLOADING;} 
 #else
	bool HasCacheState() {return m_ePeerCacheUpState == PCUS_WAIT_CACHE_REPLY || m_ePeerCacheUpState == PCUS_UPLOADING;} 
 #endif // WEBCACHE // NEO: WC END
#endif // NEO_UBT // NEO: NUBT END <-- Xanatos --

	int  GetHttpSendState() const									{ return m_iHttpSendState; }
	void SetHttpSendState(int iState)								{ m_iHttpSendState = iState; }

	bool SendPeerCacheFileRequest();
	bool ProcessPeerCacheQuery(const uchar* packet, UINT size);
	bool ProcessPeerCacheAnswer(const uchar* packet, UINT size);
	bool ProcessPeerCacheAcknowledge(const uchar* packet, UINT size);
	void OnPeerCacheDownSocketClosed(int nErrorCode);
	bool OnPeerCacheDownSocketTimeout();
	
	bool ProcessPeerCacheDownHttpResponse(const CStringAArray& astrHeaders);
	bool ProcessPeerCacheDownHttpResponseBody(const BYTE* pucData, UINT uSize);
	void ProcessPeerCacheUpHttpResponse(const CStringAArray& astrHeaders);
	UINT ProcessPeerCacheUpHttpRequest(const CStringAArray& astrHeaders);

	virtual bool ProcessHttpDownResponse(const CStringAArray& astrHeaders);
	virtual bool ProcessHttpDownResponseBody(const BYTE* pucData, UINT uSize);

	CPeerCacheDownSocket* m_pPCDownSocket;
	CPeerCacheUpSocket* m_pPCUpSocket;

protected:
	int		m_iHttpSendState;
	uint32	m_uPeerCacheDownloadPushId;
	uint32	m_uPeerCacheUploadPushId;
	uint32	m_uPeerCacheRemoteIP;
	bool	m_bPeerCacheDownHit;
	bool	m_bPeerCacheUpHit;
	EPeerCacheDownState m_ePeerCacheDownState;
	EPeerCacheUpState m_ePeerCacheUpState;

protected:
	// base
	void	Init();
	bool	ProcessHelloTypePacket(CSafeMemFile* data);
	void	SendHelloTypePacket(CSafeMemFile* data);
	void	CreateStandartPackets(byte* data, UINT togo, Requested_Block_Struct* currentblock, bool bFromPF = true);
	void	CreatePackedPackets(byte* data, UINT togo, Requested_Block_Struct* currentblock, bool bFromPF = true);

	uint32	m_nConnectIP;		// holds the supposed IP or (after we had a connection) the real IP
	uint32	m_dwUserIP;			// holds 0 (real IP not yet available) or the real IP (after we had a connection)
	uint32	m_dwServerIP;
	uint32	m_nUserIDHybrid;
	uint16	m_nUserPort;
	uint16	m_nServerPort;
	UINT	m_nClientVersion;
	//--group to aligned int32
	uint8	m_byEmuleVersion;
	uint8	m_byDataCompVer;
	bool	m_bEmuleProtocol;
	bool	m_bIsHybrid;
	//--group to aligned int32
	// TCHAR*	m_pszUsername;
	CString	m_strUsername; // NEO: FIX - [StabilityFix] <-- Xanatos --
	uchar	m_achUserHash[16];
	uint16	m_nUDPPort;
	uint16	m_nKadPort;
	//--group to aligned int32
	uint8	m_byUDPVer;
	uint8	m_bySourceExchangeVer;
	uint8	m_byAcceptCommentVer;
	uint8	m_byExtendedRequestsVer;
	uint8	m_IncompletePartVer; // NEO: ICS - [InteligentChunkSelection] <-- Xanatos --
	uint8	m_SubChunksVer; // NEO: SCT - [SubChunkTransfer] <-- Xanatos --
	// NEO: RPS - [RealPartStatus] -- Xanatos -->
	uint8	m_HidenPartStatusVer;
	uint8	m_BlockedPartStatusVer;
	// NEO: RPS END <-- Xanatos --
	uint8	m_ExtraInfoVer; // NEO: NXI - [NeoExtraInfo] <-- Xanatos --
	//--group to aligned int32
	uint8	m_byCompatibleClient;
	bool	m_bFriendSlot;
	bool	m_bCommentDirty;
	bool	m_bIsML;
	//--group to aligned int32
#ifndef ARGOS // NEO: NA -- Xanatos -->
	bool	m_bGPLEvildoer;
#endif // ARGOS // NEO: NA END <-- Xanatos --
	//bool	m_bHelloAnswerPending;
	uint8	m_byHelloPacketState; // NEO: FCCP - [FixConnectionCollision] <-- Xanatos --
	uint8	m_byInfopacketsReceived;	// have we received the edonkeyprot and emuleprot packet already (see InfoPacketsReceived() )
	uint8	m_byFileRequestState; // NEO: USPS - [UnSolicitedPartStatus] <-- Xanatos --
#ifdef NATTUNNELING // NEO: NATT - [NatTraversal] -- Xanatos -->
	uint8	m_byNatTraversalState;
	uint32	m_uLastNatTraversalTry;
#endif //NATTUNNELING // NEO: NATT END <-- Xanatos --
	uint8	m_bySupportSecIdent;
	//--group to aligned int32
	uint32	m_dwLastSignatureIP;
	CString m_strClientSoftware;
	CString m_strModVersion;
	int		m_iIsNeoMod; // NEO: MID - [NeoID] <-- Xanatos --
	uint32	m_dwLastSourceRequest;
	uint32	m_dwLastSourceAnswer;
	uint32	m_dwLastAskedForSources;
#ifdef ARGOS // NEO: NA - [NeoArgos] -- Xanatos -->
	uint32	m_dwLastSourcesSent;
#endif // ARGOS // NEO: NA END <-- Xanatos --
    int     m_iFileListRequested;
	// NEO: XSF - [ExtendedSharedFiles] -- Xanatos -->
	bool	m_bRequestingFileList;
	bool	m_bFileListRequested;
	bool	m_bDeniesShare;
	CRBMap<CString, bool>	m_listDirs;
	CList<CSearchFile *>	m_listFiles;
	// NEO: XSF END <-- Xanatos --
	int		m_iSourceListRequested; // NEO: MCH - [ManualClientHandling] <-- Xanatos --
	// NEO: RIC - [ReaskOnIDChange] -- Xanatos -->
	bool	m_bNotifyIdChage; 
	bool	m_bWainingNotifyIdChage;
	// NEO: RIC END <-- Xanatos --
	//CString	m_strFileComment; // NEO: XC - [ExtendedComments] <-- Xanatos --
	//--group to aligned int32
	//uint8	m_uFileRating; // NEO: XC - [ExtendedComments] <-- Xanatos --
	uint8	m_cMessagesReceived;		// count of chatmessages he sent to me
	uint8	m_cMessagesSent;			// count of chatmessages I sent to him
	bool	m_bMultiPacket;
	//--group to aligned int32
	bool	m_bUnicodeSupport;
	bool	m_bBuddyIDValid;
	uint16	m_nBuddyPort;
	//--group to aligned int32
	uint32	m_nBuddyIP;
	uint32	m_dwLastBuddyPingPongTime;
	uchar	m_achBuddyID[16];
	CString m_strHelloInfo;
	CString m_strMuleInfo;
	uint8	m_byKadVersion;

	// NEO: NMP - [NeoModProt] -- Xanatos -->
	uint8	m_NeoModProtVersion;
	uint8	m_NeoXSVersion; // NEO: NMPx - [NeoModProtXS]
	uint8	m_LowIDUDPPingSupport;
	//uint8	m_UnsolicitedPartStatus;
	// NEO: NMP END <-- Xanatos --

#ifdef ISPBYPASS // NEO: SCC - [SecureClinetConnection] -- Xanatos -->
	uint8	m_SecureCommunicationVer;
	uint8	m_uRequierEncryption;
	uint8	m_uSupportSecureCallback;
	uint8	m_uPreferUnEnCryptedPayload;
	uint8	m_uSimpleXOREncryption;
	uint8	m_uPKEncrpytion;
	// NEO: MP - [MultiPort]
	uint16	m_nRemoteSecurePort;
	byte*	m_abyRemoteDHPrime;
	byte	m_abyRemoteDHBase;
	uint16	m_nLocalSecurePort;
	// NEO: MP END
 #ifdef NATTUNNELING // NEO: NATT - [NatTraversal]
	uint8	m_uUseNATEncrpytion;
	CSafeMemFile*	m_KeyDataOut;
 #endif //NATTUNNELING // NEO: NATT END
	// NEO: SUC - [SafeUCPCommunication]
	uint8	m_uUseUDPSecurity;
	CSocketCryptor* m_UDPEncryption; 
	// NEO: SUC END
#endif // ISPBYPASS // NEO: SCC END <-- Xanatos --

#ifdef NATTUNNELING // NEO: NATT - [NatTraversal] -- Xanatos -->
	uint8	m_uNatTraversalVersion;
	uint8	m_uNatPortRelaiable;
	uint8	m_uNatCharacteristic;
	uint16	m_nNatPort;
#endif //NATTUNNELING // NEO: NATT END <-- Xanatos --

	// NEO: EDT - [EstimatedDownloadTime] -- Xanatos -->
	uint8	m_DownloadTimeVer;
	CTime	m_DownloadTime;
	uint32	m_DownloadTimeVal;
	uint32	m_DownloadTimeErr;
	// NEO: EDT END <-- Xanatos --

	// NEO: L2H - [LowID2HighIDAutoCallback] -- Xanatos -->
	uint32	m_L2HAC_time;
	bool	m_L2HAC_support;
	uint32	m_last_l2hac_exec;
	bool	m_l2hac_enabled;
	// NEO: L2H END <-- Xanatos --

	uint16	m_uFaildCount; // NEO: TCR - [TCPConnectionRetry] <-- Xanatos --
	uint32	m_uLastSeen; // NEO: NSS - [NeoSourceStorage] <-- Xanatos --

#ifdef NEO_SS // NEO: NSS - [NeoSourceStorage] -- Xanatos -->
	uint32	m_uLastLoadTime;
#endif // NEO_SS // NEO: NSS END <-- Xanatos --

	uint32	m_uCacheStartTime; // NEO: XSC - [ExtremeSourceCache] <-- Xanatos --

#ifdef NEO_CD // NEO: NCD - [NeoClientDatabase] -- Xanatos -->
	CKnownSource* source;
#endif // NEO_CD // NEO: NCD END <-- Xanatos --

#ifdef LANCAST // NEO: NLC - [NeoLanCast] -- Xanatos -->
	bool	m_bLanClient;
#endif //LANCAST // NEO: NLC END <-- Xanatos --

	// States
	_EClientSoftware	m_clientSoft;
	_EChatState			m_nChatstate;
	_EKadState			m_nKadState;
	_ESecureIdentState	m_SecureIdentState;
	_EUploadState		m_nUploadState;
	_EDownloadState		m_nDownloadState;
	_ESourceFrom		m_nSourceFrom;

	CTypedPtrList<CPtrList, Packet*> m_WaitingPackets_list;
	CList<PartFileStamp> m_DontSwap_list;

	////////////////////////////////////////////////////////////////////////
	// Upload
	//
    int GetFilePrioAsNumber() const;

	uint32	GetFileScore(bool isDownloading, uint32 downloadingTime) const; // NEO: MQ - [MultiQueue] <-- Xanatos --

	// NEO: PRSF - [PushSmallRareFiles] -- Xanatos -->
	float	GetRareFilePushRatio(CKnownFile* currequpfile) const;
	float	GetSmallFilePushRatio(CKnownFile* currequpfile) const;
	float	GetRatioFilePushRatio(CKnownFile* currequpfile) const;
	// NEO: PRSF END <-- Xanatos --

	Requested_File_Struct* requpfile; // NEO: MFSB - [MultiFileStatusBars] <-- Xanatos --
	UINT		m_nTransferredUp;
	uint32		m_dwUploadTime;
	UINT		m_cAsked;
	uint32		m_dwLastUpRequest;
	UINT		m_nCurSessionUp;
	UINT		m_nCurSessionDown;
    UINT		m_nCurQueueSessionPayloadUp;
    UINT		m_addedPayloadQueueSession;
	// NEO: SCFS - [SmartClientFileStatus] -- Xanatos --
	//uint16		m_nUpPartCount;
	//uint16		m_nUpCompleteSourcesCount;
	uchar		requpfileid[16];
#ifdef NEO_UBT // NEO: NUBT - [NeoUploadBandwidthThrottler] -- Xanatos -->
	uint32		m_dwShieldTime;
	bool		m_bUpEndSoon;
#else
    UINT		m_slotNumber;
#endif // NEO_UBT // NEO: NUBT END <-- Xanatos --
	CKnownFile*	accupfile; // NEO: MOD - [UploadingFile] <-- Xanatos --
#ifdef ARGOS // NEO: NA - [NeoArgos] -- Xanatos -->
	uint8		m_faileddownloads;

	CPartFile*	m_fileFNF;

	uint16		m_uFastUDPCounter;

	uint16		m_uFastXSCounter;
	uint16		m_uXSReqs;
	uint16		m_uXSAnswer;

	uint16		m_uNickChanges;
	uint32		m_uLastNickChage;

	uint16		m_uModChanges;
	uint32		m_uLastModChage;
#endif // ARGOS // NEO: NA END <-- Xanatos --
	bool		m_bCollectionUploadSlot;

	typedef struct TransferredData {
		uint32	datalen;
		DWORD	timestamp;
	};
	CTypedPtrList<CPtrList, Requested_Block_Struct*> m_BlockRequests_queue;
	CTypedPtrList<CPtrList, Requested_Block_Struct*> m_DoneBlocks_list;
	CTypedPtrList<CPtrList, Requested_File_Struct*>	 m_RequestedFiles_list;

	//////////////////////////////////////////////////////////
	// Download
	//
	CPartFile*	reqfile;
	CAICHHash*  m_pReqFileAICHHash; 
	UINT		m_cDownAsked;
	//uint8*		m_abyPartStatus; // NEO: SCFS - [SmartClientFileStatus] <-- Xanatos --
	//CString		m_strClientFilename; // NEO: SCFS - [SmartClientFileStatus] <-- Xanatos --
	UINT		m_nTransferredDown;
	uint32		m_dwDownStartTime;
	uint64		m_nLastBlockOffset;
	uint32		m_dwLastBlockReceived;
	UINT		m_nTotalUDPPackets;
	UINT		m_nFailedUDPPackets;
	//--group to aligned int32
	//uint16		m_cShowDR; // NEO: ASM - [AccurateSpeedMeasure] <-- Xanatos --
	UINT		m_nRemoteQueueRank;
	// NEO: CQR - [CollorQueueRank] -- Xanatos -->
	UINT		m_nInitialRemoteQueueRank;
	int			m_nDeltaRemoteQueueRank;
	// NEO: CQR END <-- Xanatos --
	//--group to aligned int32
	bool		m_bRemoteQueueFull;
	//bool		m_bCompleteSource; // NEO: SCFS - [SmartClientFileStatus] -- Xanatos --
	//uint16		m_nPartCount; // NEO: SCFS - [SmartClientFileStatus] -- Xanatos --
	//--group to aligned int32
	uint16		m_cShowDR;
	bool		m_bReaskPending;
	bool		m_bUDPPending;
	bool		m_bTransferredDownMini;
	uint32		m_uSpreadReaskModyfier; // NEO: SR - [SpreadReask] <-- Xanatos --
	bool		m_bAdvertisementPending; // NEO: ASP - [ActiveSpreading] <-- Xanatos --

	// Download from URL
	CStringA	m_strUrlPath;
	uint64		m_uReqStart;
	uint64		m_uReqEnd;
	uint64		m_nUrlStartPos;


	//////////////////////////////////////////////////////////
	// Upload data rate computation
	//
	UINT		m_nUpDatarate;
	UINT		m_nSumForAvgUpDataRate;
	CList<TransferredData> m_AvarageUDR_list;

	//////////////////////////////////////////////////////////
	// Download data rate computation
	//
	UINT		m_nDownDatarate;
	//UINT		m_nDownDataRateMS;
	UINT		m_nSumForAvgDownDataRate;
	CList<TransferredData> m_AvarageDDR_list;

	//////////////////////////////////////////////////////////
	// GUI helpers
	//
	static CBarShader s_StatusBar;
	static CBarShader s_UpStatusBar;
	DWORD		m_lastRefreshedDLDisplay;
    DWORD		m_lastRefreshedULDisplay;
    uint32      m_random_update_wait;

	// using bitfield for less important flags, to save some bytes
	UINT m_fHashsetRequesting : 1, // we have sent a hashset request to this client in the current connection
		 m_fSharedDirectories : 1, // client supports OP_ASKSHAREDIRS opcodes
		 m_fSentCancelTransfer: 1, // we have sent an OP_CANCELTRANSFER in the current connection
		 m_fNoViewSharedFiles : 1, // client has disabled the 'View Shared Files' feature, if this flag is not set, we just know that we don't know for sure if it is enabled
		 m_fSupportsPreview   : 1,
		 m_fPreviewReqPending : 1,
		 m_fPreviewAnsPending : 1,
		 m_fIsSpammer		  : 1,
		 m_fMessageFiltered   : 1,
		 m_fPeerCache		  : 1,
		 m_fQueueRankPending  : 1,
		 m_fUnaskQueueRankRecv: 2,
		 m_fFailedFileIdReqs  : 4, // nr. of failed file-id related requests per connection
		 m_fNeedOurPublicIP	  : 1, // we requested our IP from this client
		 // NEO: FSUR - [FixStartupLoadReq] -- Xanatos -->
		 m_fActiveUpReqFlag	  : 3, // NEO: NMPm - [NeoModProtMultiPacket] // one bit mor to can signalise also FNF
		 m_fActiveDownReqFlag : 1,
		 // NEO: FSUR END <-- Xanatos --
		 m_fUpIsProblematic   : 1, // NEO: UPC - [UploadingProblemClient] <-- Xanatos --
		 m_fKeepAlivePending  : 1, // NEO: DKA - [DownloadKeepAlive] <-- Xanatos --
		 m_fSupportsAICH	  : 3,
		 m_fAICHRequested     : 1,
		 m_fSentOutOfPartReqs : 1,
		 m_fSupportsLargeFiles: 1,
		 m_fExtMultiPacket	  : 1;

	CTypedPtrList<CPtrList, Pending_Block_Struct*>	 m_PendingBlocks_list;
	//CTypedPtrList<CPtrList, Requested_Block_Struct*> m_DownloadBlocks_list; // NEO: DBR - [DynamicBlockRequest] <-- Xanatos --

    DWORD   lastSwapForSourceExchangeTick; // ZZ:DownloadManaager
    CMap<CPartFile*, CPartFile*, DWORD, DWORD> m_fileReaskTimes; // ZZ:DownloadManager (one resk timestamp for each file)
	CMap<const CKnownFile*, const CKnownFile*, CClientFileStatus*, CClientFileStatus*> m_fileStatusMap; // NEO: SCFS - [SmartClientFileStatus] <-- Xanatos --
    DWORD   m_dwLastTriedToConnect; // ZZ:DownloadManager (one resk timestamp for each file)
    bool    RecentlySwappedForSourceExchange() { return ::GetTickCount()-lastSwapForSourceExchangeTick < 30*1000; } // ZZ:DownloadManager
    void    SetSwapForSourceExchangeTick() { lastSwapForSourceExchangeTick = ::GetTickCount(); } // ZZ:DownloadManager
	bool	m_bDisableSwaping; // NEO: MCM - [ManualClientManagement] <-- Xanatos --

#ifdef NEO_SS // NEO: NSS - [NeoSourceStorage] -- Xanatos -->
	void ClearTags();

	CArray<CTag*, CTag*> taglist1;
	CArray<CTag*, CTag*> taglist2;
#endif // NEO_SS // NEO: NSS END <-- Xanatos --

#ifdef IP2COUNTRY // NEO: IP2C - [IPtoCountry] -- Xanatos -->
	struct	IPRange_Struct2* m_structUserCountry;
#endif // IP2COUNTRY // NEO: IP2C END <-- Xanatos --

#ifdef WEBCACHE // NEO: WC - [WebCache] -- Xanatos -->
private:
	bool m_bIsTrustedOHCBSender;
	bool m_bIsAllowedToSendOHCBs;
	uint32 m_uWebCacheFlags;
	EWebCacheDownState m_eWebCacheDownState;
	EWebCacheUpState m_eWebCacheUpState;
	bool b_webcacheInfoNeeded;

protected:
	bool m_bProxy;

public:
	bool m_bIsAcceptingOurOhcbs; // default - true, set to false on OP_DONT_SEND_OHCBS
	CWebCacheDownSocket* m_pWCDownSocket;
	CWebCacheUpSocket* m_pWCUpSocket;

	bool SupportsWebCacheUDP() const		{return (m_uWebCacheFlags & WC_FLAGS_UDP) != NULL && SupportsUDP();}
	bool SupportsOhcbSuppression() const	{return (m_uWebCacheFlags & WC_FLAGS_NO_OHCBS) != NULL;}
	bool SupportsWebCacheProtocol() const	{return SupportsOhcbSuppression();} // this is the first version that supports that
	bool IsProxy() const {return m_bProxy;}
	bool IsUploadingToWebCache() const;
	bool IsDownloadingFromWebCache() const;
	bool ProcessWebCacheDownHttpResponse(const CStringAArray& astrHeaders);
	bool ProcessWebCacheDownHttpResponseBody(const BYTE* pucData, UINT uSize);
	bool ProcessWebCacheUpHttpResponse(const CStringAArray& astrHeaders);
	UINT ProcessWebCacheUpHttpRequest(const CStringAArray& astrHeaders);
	void OnWebCacheDownSocketClosed(int nErrorCode);
	void OnWebCacheDownSocketTimeout();
	void SetWebCacheDownState(EWebCacheDownState eState);
	EWebCacheDownState CUpDownClient::GetWebCacheDownState() const {return m_eWebCacheDownState;}
	void SetWebCacheUpState(EWebCacheUpState eState);
	EWebCacheUpState CUpDownClient::GetWebCacheUpState() const {return m_eWebCacheUpState;}
	virtual bool SendWebCacheBlockRequests();
	void PublishWebCachedBlock( const Requested_Block_Struct* block );
	bool IsWebCacheUpSocketConnected() const;
	bool IsWebCacheDownSocketConnected() const;
	//	uint16 blocksLoaded;	// Superlexx - block transfer limiter //JP blocks are counted in the socket code now
	uint16 GetNumberOfClientsBehindOurWebCacheAskingForSameFile();	// what a name ;)
	uint16 GetNumberOfClientsBehindOurWebCacheHavingSameFileAndNeedingThisBlock(Pending_Block_Struct* pending); // Superlexx - COtN - it's getting better all the time...
	bool WebCacheInfoNeeded() {return b_webcacheInfoNeeded;}
	void SetWebCacheInfoNeeded(bool value) {b_webcacheInfoNeeded = value;}
	//JP trusted-OHCB-senders START
	uint32 WebCachedBlockRequests;
	uint32 SuccessfulWebCachedBlockDownloads;
	bool IsTrustedOHCBSender() const {return m_bIsTrustedOHCBSender;}
	void AddWebCachedBlockToStats( bool IsGood );
	//JP trusted-OHCB-senders END
	//JP stop sendig OHCBs START
	void SendStopOHCBSending();
	void SendResumeOHCBSendingTCP();
	void SendResumeOHCBSendingUDP();
	//JP stop sendig OHCBs END
	CWebCacheCryptography Crypt; // Superlexx - encryption
	uint32 lastMultiOHCBPacketSent;
	void SendOHCBsNow();
	bool a(uint32 a) {return a <= WC_MAX_OHCBS_IN_UDP_PACKET;}
	bool b(uint32 a, uint32 b) { return a * 100.0F / (b + 1) < 0.2F; }
	bool c(uint32 a, uint32 b) { return a > 4 && (b * 100) / a < 20; }

	// Squid defaults..
	bool			UsesCachedTCPPort() { return ( (GetUserPort()==80)
		|| (GetUserPort()==21)
		|| (GetUserPort()==443)
		|| (GetUserPort()==563)
		|| (GetUserPort()==70)
		|| (GetUserPort()==210)
		|| ((GetUserPort()>=1025) && (GetUserPort()<=65535)));}
	bool			SupportsWebCache() const { return m_bWebCacheSupport; }
	bool			SupportsMultiOHCBs() const {return m_bWebCacheSupportsMultiOHCBs;}
	bool			IsBehindOurWebCache() const;
	// jp webcache
	CString			GetWebCacheName() const 
	{ 
		if (SupportsWebCache())
			return WebCacheIndex2Name(m_WA_webCacheIndex);
		else
			return _T("");
	}
	bool			m_bWebCacheSupport;
	bool			m_bWebCacheSupportsMultiOHCBs;
	// Superlexx - webcache
	bool			m_bWebcacheFailedTry; //MORPH - Added by SiRoB, New ResolveWebCachename
	int		m_WA_webCacheIndex;	// index of the webcache name
	uint16	m_WA_HTTPPort;		// remote webserver port
	uint32	m_uWebCacheDownloadId;	// we must attach this ID when sending HTTP download request to the remote client.
	uint32	m_uWebCacheUploadId;	// incoming HTTP requests are identified as WC-requests,
	// if the header contains this ID and there is a known client with same ID in downloading state.
	// used for client authorization, should be substituted by a HttpIdList? later
	// for efficiency reasons.

	// Superlexx - MFR
	CWebCacheMFRList	requestedFiles; // the files this client requested from us
	Packet*	CreateMFRPacket();		// builds a separate MFR-packet
	bool	AttachMultiOHCBsRequest(CSafeMemFile &data); // Superlexx - attaches a multiple files request
	uint8	IsPartAvailable(UINT iPart, const byte* fileHash) {return requestedFiles.IsPartAvailable((uint16)iPart, fileHash);}
#endif // NEO: WC END <-- Xanatos --

	CClientDetailDialogInterface*	m_detailDialogInterface; // NEO: MLD - [ModelesDialogs] <-- Xanatos --
};
//#pragma pack()
