//this file is part of NeoMule
//Copyright (C)2006 David Xanatos ( Xanatos@Lycos.at / http://neomule.sourceforge.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

#ifdef VOODOO // NEO: VOODOO - [UniversalPartfileInterface] -- Xanatos -->

#include "EMSocket.h"


class CSafeMemFile;
class CUpDownClient;
enum EDebugLogPriority;
// NEO: VOODOOs - [VoodooSearchForwarding]
struct SSearchParams;
enum ESearchType;
// NEO: VOODOOs END
struct PartFileBufferedData;
struct Gap_Struct;

///////////////////
// OpCode List

#define OP_VOODOOPROT				0xF7 // Protocol ID
#define VOODOOVERSION				0x02 // Version
//#define VOODOOVERSION_OLD			0x00 // Old version not compatible

#define OP_VOODOO_HELLO				0x01 // Handshake
#define OP_VOODOO_GOODBY			0x02 // Disconnect, avoid reconnect try

#define OP_SPELL					0x00 // Inicialisation
#define OP_SPELL_RESULT				0xFF

#define OP_DOWNLOAD_QUEUE			0x10 // Sends download queue to synchronize

#define OP_NEW_DOWNLOAD_ORDER		0x11 // Order new download by transfering temp files, not longer supported
#define OP_DOWNLOAD_ORDER			0x20 // Order new download
#define OP_SHARE_ORDER				0x21 // Add new shared file

#define OP_FILE_UNAVALIBLE			0x12 // this voodoo file is not avalibly on this clinet
//#define OP_DOWNLOAD_UNAVALIBLE		0x13

#define OP_GAP_LIST_REQUEST			0x14 // Request gaplist
#define OP_GAP_LIST					0x15 // send gap list

#define OP_SHARED_FILE_LIST			0x16 // Sends shared file list to synchronize

#define OP_DOWNLOAD_INSTRUCTION		0x17 // Basic Download instructions
#define OP_SHARE_INSTRUCTION		0x18 // Basic share instructions

// NEO: VOODOOn - [VoodooExtensionForNeo]
#define	OP_DOWNLOAD_COMMAND			0x40 // Extended commands, batch format 
#define	OP_FILE_PREFERENCES			0x41 // Neo file preferences
// NEO: VOODOOn END

#define	OP_DOWNLOAD_DATA			0xA0 // Data DownLink
#define	OP_THROTTLE_CHUNK			0xA1 // trothled chunk

#define	OP_CORRUPT_SENDER			0xAF // Corupted source to ban

#define	OP_DATA_REQUEST				0xB0 // Data UpLink
#define	OP_UPLOAD_DATA				0xB1

// stats
#define	OP_STATISTICS				0x25 // ul/dl speed statistic
#define	OP_FILE_STATISTICS			0x26 // ul/dl speed statistic

// Source exchange
#define	OP_SOURCE_LIST_REQUEST		0x30 // request source list
#define	OP_SOURCE_LIST				0x31 // on initialisation exported source packet
#define	OP_SINGLE_SOURCE			0x32 // new source exchange

// NEO: VOODOOs - [VoodooSearchForwarding]
// voodoo search forwarding
#define	OP_SEARCH_REQUEST			0x35 // forwarded search request
#define	OP_SEARCH_STATE				0x36 // state, succes fail, error, progress
#define	OP_SEARCH_COMMAND			0x37 // stop, cacel, more
#define	OP_SEARCH_RESULT			0x38 // forwarded search response
// NEO: VOODOOs END

/////////////////////////
// Tags

// Hello tags
#define VT_NAME						0x01
#define VT_TYPE						0x02
#define VT_PORT						0x03
#define VT_ED2K						0x04
#define VT_USABLE					0x05
//#define VT_NEO						0x06
#define VT_FEATURES					0x08
#define VT_FEATURES_EX				0x07

// Hello operators
#define VH_QUERY					0x00
#define	VH_HELLO					0x01
#define	VH_ANSWER					0x02

// client software
#define	CT_UNKNOWN					0x00
#define	CT_ED2K						0x01
#define	CT_BITTORRENT				0x02

// stats
#define	ST_DOWN_DATARATE			0x01
#define	ST_UP_DATARATE				0x02

////////////////////////
// Value Definitions

// download instructions
#define INST_RESUME					0x01 // Resume Download
#define INST_PAUSE					0x02 // Pause Download
#define INST_STOP					0x03 // Stop Download
#define INST_DELETE					0x04 // Delete Download
#define INST_COMPLETE				0x05 // Complete download

// share instructions
#define INST_UNSHARE				0x06 // Unshare this file
#define INST_SHARE					0x07 // Share this file

// extended instructions
#define	INST_SUSPEND				0x08 // set suspended flag
#define	INST_STANDBY				0x09 // set standby flag
#define	INST_FORCE					0x0A // set force flag

// file priority
#define	INST_DL_PRIO				0x0B // Set download priority Flag
#define	INST_UL_PRIO				0x0C // Set upload priority Flag

// A4AF commands
#define	INST_FORCE_ALL_A4AF			0x0D
#define	INST_GET_ALL_A4AF			0x0E
#define	INST_DROP_ALL_A4AF			0x0F

// action operator
#define	VA_NONE						0x00
#define	VA_SLAVE					0x01 // Try to slave
#define	VA_MASTER					0x02 // Ask to be master
#define	VA_PARTNER					0x03 // booth slave and master
#define	VA_BLOCK					0x04 // block this client
#define	VA_QUERY					0x10 // Request only hellp packet

// file unavalibly reasons
#define RET_NONE					0x00
#define RET_REAL					0x01 // File is already present as real
#define RET_NEW						0x02 // Faild to add new file
#define RET_UNAVALIBLY				0x03 // File is not present on master
#define RET_UNKNOWN					0x04 // slave does not know this file
#define RET_BADSIZE					0x05 // file size dies not match, id association failed
#define RET_EXIST					0x06 // File already exist

// file type operators
#define	OP_TEMP						0x01 // Voodoo temp file
#define	OP_SHARE					0x02 // Voodoo share file

// NEO: VOODOOs - [VoodooSearchForwarding]
// voodoo search forwarding
#define SS_ERROR					0x00
#define SS_OFFLINE					0x01
#define SS_FINISH					0x02

#define	SF_DONE						0x00
//#define	SF_MORE						0x01
#define	SF_HALTED					0x02
#define	SF_END						0x03
#define	SF_KAD						0x04
#define	SF_ERROR					0x05

#define SE_GENERIC					0x00
#define SE_INVALID					0x01
#define SE_KAD						0x02

#define	SC_HOLD						0x00
#define	SC_CANCEL					0x01
#define	SC_MORE						0x02
// NEO: VOODOOs END


//////////////////////////
// Hierarchy Exception

class CHierarchyExceptio : public CException
{
	DECLARE_DYNAMIC(CHierarchyExceptio)
public:
	CHierarchyExceptio(uint8 uOpCode, uint8 uTagCode = 0)
	{
		m_uOpCode = uOpCode;
		m_uTagCode = uTagCode;
	}

	uint8 m_uOpCode;
	uint8 m_uTagCode;
};

/////////////////////////
// Structs

#pragma pack(1)
struct FileID{
	FileID() {Size = 0;}
	FileID(CSafeMemFile &packet, bool b64);
	uchar	Hash[16];
	uint64	Size;
	bool operator!=(FileID& ID)	{return Size != ID.Size || md4cmp(Hash,ID.Hash);}
};
#pragma pack()

bool WriteFileID(CSafeMemFile &packet, CKnownFile* file, bool b64);
void WriteFileID(CSafeMemFile &packet, FileID& file, bool b64);

#pragma pack(1)
struct sDataRequest{
	uint32	IdKey;
	uint64	StartOffset;
	uint64	EndOffset;
	// NEO: RBT - [ReadBlockThread]
	uint32	togo;
	FileID	ID;
	uint32	Client;
	// NEO: RBT END
};
#pragma pack()

#pragma pack(1)
struct SVoodooClient{
	CString m_sName;

	uint8	m_uAction;

	CString	clientAddress;
	DWORD	clientIP;
	uint16	clientPort;
	uint16	socketPort;

	CString m_sSpell;

	uint8	m_uType;
	bool	m_bUsable;
};
#pragma pack()

// NEO: VOODOOs - [VoodooSearchForwarding]
class CVoodooSocket;
#pragma pack(1)
struct SSearchMaster{
	CVoodooSocket*	MasterSocket;
	DWORD			MasterID;
	DWORD			KillTimer;
};
#pragma pack()
// NEO: VOODOOs END

// stats
#pragma pack(1)
struct SVoodooStats{
	SVoodooStats(){
		uLastStatUpdate = 0;
		uUpDatarate = 0;
		uDownDatarate = 0;
	}
	uint32 uLastStatUpdate;
	uint32 uUpDatarate;
	uint32 uDownDatarate;
};
typedef SVoodooStats SFileVoodooStats;
#pragma pack()


//////////////////////
// CMasterDatas

class CMasterDatas
{
public:
	CMasterDatas();
	~CMasterDatas();

	bool	HaveGapList(){ return gaplist != NULL; }
	bool	IsComplete(uint64 start, uint64 end) const;

	CTypedPtrList<CPtrList, Gap_Struct*>* gaplist;
};


//////////////////////
// CVoodooSocket

class CVoodooSocket : public CEMSocket
{
	friend class CVoodoo;
	friend class CVoodooListDlg;
	DECLARE_DYNCREATE(CVoodooSocket)

public:
	CVoodooSocket();
	virtual ~CVoodooSocket();

	void	Disconnect(LPCTSTR pszReason);

	void	SendGoodBy();
	virtual void SendPacket(CSafeMemFile &data, uint8 opcode, bool bControlPacket = true);

	void	SetAddress(LPCTSTR Address) { if(Address) clientAddress = Address;}
	CString& GetAddress()	{return clientAddress;}
	void	SetIP(DWORD dwIP) {clientIP = dwIP;}
	DWORD	GetIP()			{return clientIP;}
	void	SetPort(uint16 uPort) {clientPort = uPort;}
	uint16	GetPort()		{return clientPort;}
	void	SetSocketPort(uint16 uPort) {socketPort = uPort;}
	uint16	GetSocketPort()	{return socketPort;}
	uint16	GetED2KPort()	{return m_nPortED2K;}

	CString& GetName() {return m_sName;}

	// NEO: NLC - [NeoLanCast]
	bool	IsLanSocket() { return true; }
	void	SetOnLan();
	// NEO: NLC END
	void	ConfigSocket();

	bool	IsVoodooSocket() { return true; }
	
	// DownLink
	void	SplitPart(CPartFile* pFile, PartFileBufferedData *item);
	void	TransferFileData(CPartFile* pFile, PartFileBufferedData *item, DWORD dwIP);
	void	SendThrottleChunk(CPartFile* pFile, uint16 partNumber, bool bRelease);

	void	SendCorruptedSenderWarning(DWORD dwIP);

	// UpLink
	void	RequestFileData(CKnownFile* kFile, sDataRequest &DataRequest);
	void	SendFileData(sDataRequest* DataRequest, byte* Data); // NEO: RBT - [ReadBlockThread]

	// stats
	uint32	GetUpDatarate()		{return m_Stats.uUpDatarate;}
	uint32	GetDownDatarate()	{return m_Stats.uDownDatarate;}

	// NEO: VOODOOs - [VoodooSearchForwarding]
	// voodoo search forwarding
	void	SendSearchState(DWORD dwSearchID, uint8 uState, uint32 uValue = 0);
	void	SendSearchCommand(DWORD dwSearchID, uint8 uCommand);
	void	SendSearchResult(DWORD dwSearchID,ESearchType eType,CSafeMemFile &packet, uint32 nServerIP = 0, uint16 nServerPort = 0);

	bool	m_bHaveMoreResults;
	// NEO: VOODOOs END

protected:
	// Socket members
	//bool	CheckTimeOut();
	void	Delete_Timed();
	virtual void Safe_Delete();
	void	Reconect();
	void	SetReconnect() {if(GetAction() != VA_NONE && GetPort() != 0) reconect = true;}
	void	Process();

	virtual void OnConnect(int nErrorCode);
	void		 OnClose(int nErrorCode);
	void		 OnSend(int nErrorCode);
	void		 OnReceive(int nErrorCode);
	void		 OnError(int nErrorCode);

	virtual bool PacketReceived(Packet* packet);

	// Voodoo members
	bool	IsMaster() {return m_bIsMaster;}
	bool	IsSlave() {return m_bIsSlave;}

	bool	IsUsable() {return m_bUsable;}
	CString& GetSpell() {return m_sSpell;}
	bool	IsED2K() {return m_uType == CT_ED2K;}

	void	SetAction(uint8 uAction) {m_uAction = uAction;}
	uint8	GetAction() {if(m_uAction == VA_QUERY) return VA_NONE; return m_uAction;}

	uint8	GetType() {return m_uType;}

	void	SendVoodooHello(uint8 uHello = VH_HELLO);
	void	RecivedVoodooHello(CSafeMemFile &packet);
	void	ConnectionEstablished();

	void	SendSpell();
	void	SpellRecived(CSafeMemFile &packet);
	void	SendSpellResult(uint8 uResult);
	void	SpellResultRecived(CSafeMemFile &packet);

	void	SendDownloadQueue();
	void	SynchronizeDownloadQueue(CSafeMemFile &packet);
	void	SendDownloadQueueV2();

	void	SendDownloadOrder(CPartFile* pFile);
	void	DownloadOrderRecived(CSafeMemFile &packet);

	void	SendShareOrder(CKnownFile* kFile);
	void	ShareOrderRecived(CSafeMemFile &packet);

	void	SendFileUnavalible(FileID &newID, uint8 uErr);
	void	FileUnavalibleRecived(CSafeMemFile &packet);

	void	RequestGapList(CPartFile* pFile);
	void	GapListRequestRecived(CSafeMemFile &packet);
	void	SendGapList(CPartFile* pFile);
	void	GapListRecived(CSafeMemFile &packet);

	void	SendSharedFilesList();
	void	SynchronizeSharedFileList(CSafeMemFile &packet);
	void	SendSharedFilesListV2();

	void	SendDownloadInstruction(CPartFile* pFile, uint8 uInstruction, uint32 Flag1 = NULL, uint32 Flag2 = NULL);
	void	DownloadInstructionRecived(CSafeMemFile &packet);

	void	SendShareInstruction(CKnownFile* kFile, uint8 uInstruction, uint32 Flag1 = NULL, uint32 Flag2 = NULL);
	void	ShareInstructionRecived(CSafeMemFile &packet);

	void	SendDownloadCommand(CTypedPtrList<CPtrList, CPartFile*>& ServerReqQueue, uint8 uCommand, uint32 Flag1 = NULL, uint32 Flag2 = NULL);
	void	DownloadCommandRecived(CSafeMemFile &packet);

	void	SendFilePreferences(CKnownFile* kFile);
	void	FilePreferencesRecived(CSafeMemFile &packet);

	// stats
	void	SendStatistics();
	void	SendFileStatistics(CMap<CKnownFile*,CKnownFile*,SFileVoodooStats,SFileVoodooStats> &FileStats);
	void	StatisticsRecived(CSafeMemFile &packet);
	void	FileStatisticsRecived(CSafeMemFile &packet);

	// NEO: VOODOOx - [VoodooSourceExchange]
	// Source exchange
	void	RequestSourceList(CPartFile* pFile);
	void	SourceListRequestRecived(CSafeMemFile &packet);

	void	SendSourceList(CPartFile* pFile);
	void	SourceListRecived(CSafeMemFile &packet);

	void	SendSingleSource(CPartFile* pFile, CUpDownClient* sClient);
	void	SingleSourceRecived(CSafeMemFile &packet);
	// NEO: VOODOOx END

	// NEO: VOODOOs - [VoodooSearchForwarding]
	// voodoo search forwarding
	void	SendNewSearch(SSearchParams* pParams);
	void	NewSearchRecived(CSafeMemFile &packet);
	void	SearchStateRecived(CSafeMemFile &packet);
	void	SearchCommandRecived(CSafeMemFile &packet);
	void	SearchResultRecived(CSafeMemFile &packet);
	// NEO: VOODOOs END

	// packet processor
	bool	ProcessVoodooPacket(const BYTE* packet, uint32 size, UINT opcode);

	// Debug Members
	void	PacketToDebugLogLine(LPCTSTR protocol, const uchar* packet, uint32 size, UINT opcode);
	CString DbgGetClientInfo();
	CString GetClientDesc();


	uint8	GetVoodooVersion()				{return m_uVoodooVersion;}
	bool	Use64Size()						{return m_u64FileSizeSupport;}
	uint8	GetCorruptionHandlingVersion()	{return m_uCorruptionHandling;}
	uint8	GetAdvDownloadSyncVersion()		{return m_uAdvDownloadSync;}

	uint8	GetSupportsStatisticsVersion()	{return m_uSupportsStatistics;}
	// NEO: VOODOOx - [VoodooSourceExchange]
	uint8	GetNeoSourceExportVersion()		{if(m_uType != CT_ED2K) return FALSE; return m_uNeoSourceExport;}
	uint8	GetNeoSourceExchangeVersion()	{if(m_uType != CT_ED2K) return FALSE; return m_uNeoSourceExchange;}
	// NEO: VOODOOx
	bool	GetExtendedStatesSupport()		{return m_uExtendedStates;}
	uint8	GetPriorityInstructionsVersion(){return m_uPriorityInstructions;}
	uint8	GetA4AFCommandsVersion()		{return m_uA4AFCommands;}
	bool	IsInstructionSupported(uint8 uInstruction, UINT Flag1){
			if ((uInstruction >= INST_SUSPEND && uInstruction <= INST_FORCE) && !m_uExtendedStates)
				return false;
			if ((uInstruction == INST_DL_PRIO) && m_uPriorityInstructions < 1)
				return false;
			if (uInstruction == INST_UL_PRIO){
				if(m_uPriorityInstructions < 2)
					return false;
				if(Flag1 == 6/*PR_RELEASE*/ && m_uPriorityInstructions < 3 )
					return false;
			}
			if ((uInstruction >= INST_FORCE_ALL_A4AF && uInstruction <= INST_DROP_ALL_A4AF) && !m_uA4AFCommands)
				return false;
			return true;
		}
	bool	IsVoodooSearchSupported()		{if(m_uType != CT_ED2K) return false; return m_uVoodooSearch;} // NEO: VOODOOs - [VoodooSearchForwarding]
	// NEO: VOODOOn - [VoodooExtensionForNeo]
	uint8	GetExtendedComandsVersion()		{return m_uExtendedComands;}
	bool	IsCommandSupported(uint8 uCommand);
	uint8	GetNeoFilePreferencesVersion()	{return m_uNeoFilePreferences;}
	// NEO: VOODOOn END

	// stats
	SVoodooStats m_Stats;
	CMap<CKnownFile*,CKnownFile*,SFileVoodooStats,SFileVoodooStats> m_FileStats;

private:
	CPartFile*	GetDownloadingFile(CSafeMemFile &packet, bool bRequest = true, bool bLogUnknown = true);
	CKnownFile*	GetSharedFile(CSafeMemFile &packet);

	void	ExecuteDownloadInstruction(CPartFile* pFile, uint8 uInstruction, uint32 Flag1 = NULL, uint32 Flag2 = NULL);

	// DownLink
	void	RecivedFileData(CSafeMemFile &packet);
	void	RecivedThrottleChunk(CSafeMemFile &packet);

	void	RecivedCorruptedSenderWarning(CSafeMemFile &packet);

	// UpLink
	void	FileDataRequestRecived(CSafeMemFile &packet);
	void	GetFileData(CKnownFile* kFile, sDataRequest* DataRequest);
	void	FileDataAnswerRecived(CSafeMemFile &packet);

	// socket properitys
	bool	deletethis;
	uint32	deltimer;
	bool	reconect;
	CString	clientAddress;
	DWORD	clientIP;
	uint16	clientPort;
	uint16	socketPort;

	// voodoo status
	uint8	m_uAction;
	bool	m_bIsMaster;
	bool	m_bIsSlave;

	// voodoo version and supported features
	uint8	m_uVoodooVersion;
	UINT	m_u64FileSizeSupport	: 1, // Large File support
			m_uCorruptionHandling	: 4, // corruption handling
			m_uAdvDownloadSync		: 3; // prevent 2 nodes downloading the same part at one time

	UINT	m_uSupportsStatistics	: 2, // transfer stats version 1 global, future version 2 also per file stats
			m_uNeoSourceExport		: 4, // initial source export to slaves, thay may be future versions // NEO: VOODOOx - [VoodooSourceExchange]
			m_uNeoSourceExchange	: 4, // activ runtume source exchange bidirectional, thay may be future versions // NEO: VOODOOx - [VoodooSourceExchange]
		    m_uExtendedStates		: 1, // additional file states, forced/suspendes/standby
		    m_uPriorityInstructions	: 2, // UL/DL priority instructions, one reserved
			m_uVoodooSearch			: 1, // voodoo search forwarding 	// NEO: VOODOOs - [VoodooSearchForwarding]
			m_uA4AFCommands			: 2, // A4AF instructions may be different versions 
		    m_uExtendedComands		: 4, // Extended commands: collecting, droping, reask and one flag reserved // NEO: VOODOOn - [VoodooExtensionForNeo]
			m_uNeoFilePreferences	: 4; // Neo File Configuration settings, thay may be future versions // NEO: VOODOOn - [VoodooExtensionForNeo]
		

	// voodoo properties
	CString m_sName;
	uint16	m_nVoodoPort;
	uint16	m_nPortED2K;
	uint8	m_uType;
	bool	m_bUsable;
	CString m_sSpell;

	// stats
	uint32	m_uLastStatUpdate;

	FileID	m_LastErrFile; // we may send a operation request directly it must be ignorred or we will request the file again, and the whole storry repeads iself endles for ever
};

//////////////////////
// CVoodoo

class CVoodoo : public CAsyncSocketEx
{
	friend class CVoodooSocket;
	friend class CVoodooListDlg;

public:
	CVoodoo();
	virtual ~CVoodoo();

	void	ConnectVoodooClient(LPCTSTR lpszHostAddress, uint16 nHostPort, uint8 uAction = VA_SLAVE);
	void	ConnectVoodooClient(DWORD nHostAddress, uint16 nHostPort, uint8 uAction = VA_SLAVE, LPCTSTR lpszHostAddress = NULL);

	void	ManifestGapList(CPartFile* pFile);
	void	ManifestDownloadOrder(CPartFile* pFile);
	void	ManifestDownloadInstruction(CPartFile* pFile, uint8 uInstruction, uint32 Flag1 = NULL, uint32 Flag2 = NULL);
	void	ManifestShareInstruction(CKnownFile* kFile, uint8 uInstruction, uint32 Flag1 = NULL, uint32 Flag2 = NULL); 
	// NEO: VOODOOx - [VoodooSourceExchange]
	void	ManifestSingleSource(CPartFile* pFile, CUpDownClient* sClient);
	void	ManifestSourceListRequest(CPartFile* pFile); 
	// NEO: VOODOOx END
	// NEO: VOODOOn - [VoodooExtensionForNeo]
	void	ManifestDownloadCommand(CTypedPtrList<CPtrList, CPartFile*>& FileQueue, uint8 uCommand, uint32 Flag1 = NULL, uint32 Flag2 = NULL);
	void	ManifestFilePreferences(CKnownFile* kFile);
	// NEO: VOODOOn END
	// NEO: VOODOOs - [VoodooSearchForwarding]
	// Search forwarding
	void	ManifestNewSearch(SSearchParams* pParams);
	void	ManifestSearchCommand(DWORD dwSearchID, uint8 uCommand);
	// NEO: VOODOOs END
	void	ManifestThrottleChunk(CPartFile* pFile, uint16 partNumber, CVoodooSocket* source = NULL, bool bRelease = false);
	void	ManifestCorruptedSenderWarning(DWORD dwIP);

	bool	IsVoodooClient(DWORD dwIP, uint16 uPort);
	void	AddVoodooClient(DWORD dwIP, uint16 uPort, uint8 uAction = VA_QUERY);
	CVoodooSocket* GetVoodooSocket(DWORD dwIP, uint16 uPort, uint16 uSockPort = 0, bool bOld = false);
	CVoodooSocket* GetAnySlave(bool bED2K = false);

	bool	Start();
	void	Stop();
	bool	StartListening();
	bool	IsListening() {return bListening;}
	bool	IsStarted() {return bStarted;}

	virtual void OnAccept(int nErrorCode);
	bool    IsValidSocket(CVoodooSocket* totest);
	void	Process();
	bool	Rebind();

	void	TryToConnect();

	// voodoo search forwarding
	CMap<DWORD,DWORD,SSearchMaster,SSearchMaster> m_SearchMasterMap; // NEO: VOODOOs - [VoodooSearchForwarding]

	// stats
	uint32	GetUpDatarate();
	uint32	GetDownDatarate();
	//uint32	GetUpDatarate(CKnownFile* File);
	uint32	GetDownDatarate(CKnownFile* File);

protected:
	void	RemoveSocket(CVoodooSocket* todel);
	void	AddSocket(CVoodooSocket* toadd);
	void	KillAllSockets();

	void	ClearKnown();
	SVoodooClient* GetClientByAddress(LPCTSTR address, uint16 port);
	SVoodooClient* GetClientByIP(uint32 nIP, uint16 nPort, uint16 uSockPort = 0);
	bool	AddKnown(CVoodooSocket* VoodooClient);
	void	CleanUpKnown(CVoodooSocket* VoodooClient);
	bool	IsValudKnownClinet(SVoodooClient* VoodooClient);

	void	LoadKnownFile();
	void	SaveKnownToFile();

	CTypedPtrList<CPtrList, CVoodooSocket*> socket_list;
	CTypedPtrList<CPtrList, SVoodooClient*> known_list;

private:
	bool	bListening;
	bool	bStarted;
	uint32	uLastSearch;

	uint16  m_port;
};

#endif // VOODOO // NEO: VOODOO END <-- Xanatos --
