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 
37 class CSharedFileList;
38 class CSearchFile;
39 class CPartFile;
40 class CUpDownClient;
41 class CServer;
42 class CMemFile;
43 class CKnownFile;
44 class CED2KLink;
45 class CED2KFileLink;
46 class CED2KServerLink;
47 class CED2KServerListLink;
48 class CPath;
49 
50 namespace 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  */
60 class CDownloadQueue : public CObservableQueue<CPartFile*>
61 {
62 public:
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 
SetLastKademliaFileRequest()310 	void	SetLastKademliaFileRequest()	{lastkademliafilerequest = ::GetTickCount();}
311 
GetRareFileThreshold()312 	uint32	GetRareFileThreshold() const { return m_rareFileThreshold; }
GetCommonFileThreshold()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 
320 private:
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