1//
2// This file is part of the aMule Project.
3//
4// Copyright (c) 2003-2011 aMule Team ( admin@amule.org / http://www.amule.org )
5// Copyright (c) 2002-2011 Merkur ( devs@emule-project.net / http://www.emule-project.net )
6//
7// Any parts of this program derived from the xMule, lMule or eMule project,
8// or contributed by third-party developers are copyrighted by their
9// respective authors.
10//
11// This program is free software; you can redistribute it and/or modify
12// it under the terms of the GNU General Public License as published by
13// the Free Software Foundation; either version 2 of the License, or
14// (at your option) any later version.
15//
16// This program is distributed in the hope that it will be useful,
17// but WITHOUT ANY WARRANTY; without even the implied warranty of
18// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19// GNU General Public License for more details.
20//
21// You should have received a copy of the GNU General Public License
22// along with this program; if not, write to the Free Software
23// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA
24//
25
26#ifndef DOWNLOADQUEUE_H
27#define DOWNLOADQUEUE_H
28
29#include "MD4Hash.h"		// Needed for CMD4Hash
30#include "ObservableQueue.h"	// Needed for CObservableQueue
31#include "GetTickCount.h" 	// Needed fot GetTickCount
32
33
34#include <deque>
35
36
37class CSharedFileList;
38class CSearchFile;
39class CPartFile;
40class CUpDownClient;
41class CServer;
42class CMemFile;
43class CKnownFile;
44class CED2KLink;
45class CED2KFileLink;
46class CED2KServerLink;
47class CED2KServerListLink;
48class CPath;
49
50namespace Kademlia {
51	class CUInt128;
52}
53
54/**
55 * The download queue houses all active downloads.
56 *
57 *
58 * This class should be thread-safe.
59 */
60class CDownloadQueue : public CObservableQueue<CPartFile*>
61{
62public:
63	/**
64	 * Constructor.
65	 */
66	CDownloadQueue();
67
68	/**
69	 * Destructor.
70	 */
71	~CDownloadQueue();
72
73	/** Loads met-files from the specified directory. */
74	void	LoadMetFiles(const CPath& path);
75
76	/**
77	 * Main worker function.
78	 */
79	void	Process();
80
81
82	/**
83	 * Returns a pointer to the file with the specified hash, or NULL.
84	 *
85	 * @param filehash The hash to search for.
86	 * @return The corresponding file or NULL.
87	 */
88	CPartFile* GetFileByID(const CMD4Hash& filehash) const;
89
90	/**
91	 * Returns the file at the specified position in the file-list, or NULL if invalid.
92	 *
93	 * @param A valid position in the file-list.
94	 * @return A valid pointer or NULL if the index was invalid.
95	 */
96	CPartFile* GetFileByIndex(unsigned int idx) const;
97
98
99	/**
100	 * Returns true if the file is currently being shared or downloaded
101	 */
102	bool	IsFileExisting(const CMD4Hash& fileid) const;
103
104	/**
105	 * Returns true if the specified file is on the download-queue.
106	 */
107	bool	IsPartFile(const CKnownFile* file) const;
108
109	/**
110	 * Updates the file's download active time
111	 */
112	void OnConnectionState(bool bConnected);
113
114	/**
115	 * Starts a new download based on the specified search-result.
116	 *
117	 * @param toadd The search-result to add.
118	 * @param category The category to assign to the new download.
119	 *
120	 * The download will only be started if no identical files are either
121	 * being downloaded or shared currently.
122	 */
123	void	AddSearchToDownload(CSearchFile* toadd, uint8 category);
124
125
126	/**
127	 * Adds an existing partfile to the queue.
128	 *
129	 * @param newfile The file to add.
130	 * @param paused If the file should be stopped when added.
131	 * @param category The category to assign to the file.
132	 */
133	void	AddDownload(CPartFile* newfile, bool paused, uint8 category);
134
135
136	/**
137	 * Removes the specified file from the queue.
138	 *
139	 * @param toremove A pointer to the file object to be removed.
140	 * @param keepAsCompleted If true add the removed file to the list of completed files.
141	 */
142	void	RemoveFile(CPartFile* toremove, bool keepAsCompleted = false);
143
144
145	/**
146	 * Saves the source-seeds of every file on the queue.
147	 */
148	void	SaveSourceSeeds();
149
150	/**
151	 * Loads the source-seeds of every file on the queue.
152	 */
153	void	LoadSourceSeeds();
154
155
156	/**
157	 * Adds a potiential new client to the specified file.
158	 *
159	 * @param sender The owner of the new source.
160	 * @param source The client in question, might be deleted!
161	 *
162	 * This function will check the new client against the already existing
163	 * clients. The source will then be queued as is appropriate, or deleted
164	 * if it is duplicate of an existing client.
165	 */
166	void    CheckAndAddSource(CPartFile* sender, CUpDownClient* source);
167
168	/**
169	 * This function adds already known source to the specified file.
170	 *
171	 * @param sender The owner fo the new source.
172	 * @param source The client in question.
173	 *
174	 * This function acts like CheckAndAddSource, with the exception that no
175	 * checks are made to see if the client is a duplicate. It is assumed that
176	 * it is in fact a valid client.
177	 */
178	void    CheckAndAddKnownSource(CPartFile* sender, CUpDownClient* source);
179
180
181	/**
182	 * Removes the specified client completly.
183	 *
184	 * @param toremove The client to be removed.
185	 * @param updatewindow NOT USED!
186	 * @param bDoStatsUdpate Specifies if the affected files should update their statistics.
187	 * @return True if the sources was found and removed.
188	 *
189	 * This function will remove the specified source from both normal source
190	 * lists, A4AF lists and the downloadqueue-widget. The requestfile of the
191	 * source is also reset.
192	 */
193	bool	RemoveSource(CUpDownClient* toremove, bool updatewindow = true, bool bDoStatsUpdate = true);
194
195
196	/**
197	 * Finds the queued client by IP and UDP-port, by looking at file-sources.
198	 *
199	 * @param dwIP The IP-address of the client.
200	 * @param nUDPPort The UDP-port of the client.
201	 * @return The matching client or NULL if none was found.
202	 */
203	CUpDownClient* GetDownloadClientByIP_UDP(uint32 dwIP, uint16 nUDPPort) const;
204
205
206	/**
207	 * Queues the specified file for source-requestion from the connected server.
208	 */
209	void	SendLocalSrcRequest(CPartFile* sender);
210
211	/**
212	 * Removes the specified server from the request-queue.
213	 */
214	void	RemoveLocalServerRequest(CPartFile* pFile);
215
216	/**
217	 * Resets all queued server-requests.
218	 */
219	void	ResetLocalServerRequests();
220
221
222	/**
223	 * Starts the next paused file on the queue, going after priority.
224	 * Also checks for categories if enabled on preferences.
225	 */
226	void	StartNextFile(CPartFile* oldfile);
227
228
229	/**
230	 * Resets the category of all files with the specified category.
231	 */
232	void	ResetCatParts(uint8 cat);
233
234	/**
235	 * Sets the priority of all files with the specified category.
236	 */
237	void	SetCatPrio(uint8 cat, uint8 newprio);
238
239	/**
240	 * Sets the status of all files with the specified category.
241	 */
242	void	SetCatStatus(uint8 cat, int newstatus);
243
244	/**
245	 * Returns the current number of queued files.
246	 */
247	uint16	GetFileCount() const;
248
249	/**
250	 * Makes a copy of the file list.
251	 */
252	void	CopyFileList(std::vector<CPartFile*>& out_list, bool includeCompleted = false) const;
253
254	/**
255	 * Returns the current number of downloading files.
256	 */
257	uint16	GetDownloadingFileCount() const;
258
259	/**
260	 * Returns the current number of paused files.
261	 */
262	uint16	GetPausedFileCount() const;
263
264
265	/**
266	 * This function is called when a DNS lookup is finished.
267	 */
268	void	OnHostnameResolved(uint32 ip);
269
270
271	/**
272	 * Adds an ed2k or magnet link to download queue.
273	 */
274	bool	AddLink( const wxString& link, uint8 category = 0 );
275
276	bool	AddED2KLink( const wxString& link, uint8 category = 0 );
277	bool	AddED2KLink( const CED2KLink* link, uint8 category = 0 );
278	bool	AddED2KLink( const CED2KFileLink* link, uint8 category = 0 );
279	bool	AddED2KLink( const CED2KServerLink* link );
280	bool	AddED2KLink( const CED2KServerListLink* link );
281
282
283	/**
284	 * Returns the current server which is beening queried by UDP packets.
285	 */
286	CServer* GetUDPServer() const;
287
288	/**
289	 * Set the server to query through UDP packest.
290	 */
291	void	SetUDPServer( CServer* server );
292
293
294	/**
295	 * Stop the source-requests from non-connected servers.
296	 */
297	void	StopUDPRequests();
298
299	/* Kad Stuff */
300
301	/**
302	 * Add a Kad source to a download
303	 */
304	 void	KademliaSearchFile(uint32_t searchID, const Kademlia::CUInt128* pcontactID, const Kademlia::CUInt128* pkadID, uint8_t type, uint32_t ip, uint16_t tcp, uint16_t udp, uint32_t buddyip, uint16_t buddyport, uint8_t byCryptOptions);
305
306	CPartFile* GetFileByKadFileSearchID(uint32 id) const;
307
308	bool	DoKademliaFileRequest();
309
310	void	SetLastKademliaFileRequest()	{lastkademliafilerequest = ::GetTickCount();}
311
312	uint32	GetRareFileThreshold() const { return m_rareFileThreshold; }
313	uint32	GetCommonFileThreshold() const { return m_commonFileThreshold; }
314
315	/**
316	 * Remove a file from the list of completed downloads.
317	 */
318	void	ClearCompleted(const ListOfUInts32 & ecids);
319
320private:
321	/**
322	 * This function initializes new observers with the current contents of the queue.
323	 */
324	virtual void ObserverAdded( ObserverType* o );
325
326
327	/**
328	 * Helper-function, sorts the filelist so that high-priority files are first.
329	 */
330	void	DoSortByPriority();
331
332	/** Checks that there is enough free spaces for temp-files at that specified path. */
333	void	CheckDiskspace(const CPath& path);
334
335	/**
336	 * Stops performing UDP requests.
337	 */
338	void	DoStopUDPRequests();
339
340
341	void	ProcessLocalRequests();
342
343	bool	SendNextUDPPacket();
344	int		GetMaxFilesPerUDPServerPacket() const;
345	bool	SendGlobGetSourcesUDPPacket(CMemFile& data);
346
347	void 	AddToResolve(const CMD4Hash& fileid, const wxString& pszHostname, uint16 port, const wxString& hash, uint8 cryptoptions);
348
349	//! The mutex assosiated with this class, mutable to allow for const functions.
350	mutable wxMutex m_mutex;
351
352
353	uint32		m_datarate;
354	uint32		m_lastDiskCheck;
355	uint32		m_lastudpsearchtime;
356	uint32		m_lastsorttime;
357	uint32		m_lastudpstattime;
358	uint32		m_nLastED2KLinkCheck;
359	uint8		m_cRequestsSentToServer;
360	uint32		m_dwNextTCPSrcReq;
361	uint8		m_udcounter;
362	CServer*	m_udpserver;
363
364
365	/**
366	 * Structure used to store sources with dynamic hostnames.
367	 */
368	struct Hostname_Entry
369	{
370		//! The ID of the file the source provides.
371		CMD4Hash fileid;
372		//! The dynamic hostname.
373		wxString strHostname;
374		//! The user-port of the source.
375		uint16 port;
376		//! The hash of the source
377		wxString hash;
378		//! The cryptoptions for the source
379		uint8 cryptoptions;
380	};
381
382	std::deque<Hostname_Entry>	m_toresolve;
383
384	typedef std::deque<CPartFile*> FileQueue;
385	FileQueue m_filelist;
386
387	typedef std::list<CPartFile*> FileList;
388	FileList		m_localServerReqQueue;
389
390	//! List of downloads completed and still on display
391	FileList		m_completedDownloads;
392
393	//! Observer used to keep track of which servers have yet to be asked for sources
394	CQueueObserver<CServer*>	m_queueServers;
395
396	//! Observer used to keep track of which file to send UDP requests for
397	CQueueObserver<CPartFile*>	m_queueFiles;
398
399	/* Kad Stuff */
400	uint32		lastkademliafilerequest;
401
402	//! Threshold for rare files, dynamically based on the sources for each.
403	uint32		m_rareFileThreshold;
404
405	//! Threshold for common files, dynamically based on the sources for each.
406	uint32		m_commonFileThreshold;
407};
408
409#endif // DOWNLOADQUEUE_H
410// File_checked_for_headers
411