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
27#ifndef KNOWNFILE_H
28#define KNOWNFILE_H
29
30
31#include "MD4Hash.h"
32#include "SHAHashSet.h"
33
34#include <protocol/ed2k/Constants.h>
35#include <common/Path.h>
36
37#include "kademlia/kademlia/Indexed.h"
38#include <ec/cpp/ECID.h>	// Needed for CECID
39
40
41#ifdef CLIENT_GUI
42#include <ec/cpp/ECSpecialTags.h>
43#include "RLE.h"			// Needed for RLE_Data, PartFileEncoderData
44#endif
45
46#include "Constants.h"		// Needed for PS_*, PR_*
47#include "ClientRef.h"		// Needed for CClientRef
48
49class CFileDataIO;
50class CPacket;
51class CTag;
52
53
54namespace Kademlia
55{
56	class CEntry;
57}
58
59
60typedef vector<CMD4Hash> ArrayOfCMD4Hash;
61
62
63typedef vector<CTag> ArrayOfCTag;
64
65
66class CFileStatistic
67{
68	friend class CKnownFile;
69	friend class CKnownFilesRem;
70
71public:
72	CFileStatistic();
73	void	AddRequest();
74	void	AddAccepted();
75	void    AddTransferred(uint64 bytes);
76	uint16	GetRequests() const			{return requested;}
77	uint16	GetAccepts() const			{return accepted;}
78	uint64  GetTransferred() const			{return transferred;}
79	uint32	GetAllTimeRequests() const		{return alltimerequested;}
80	void	SetAllTimeRequests(uint32 new_value)	{ alltimerequested = new_value; };
81	uint32	GetAllTimeAccepts() const		{return alltimeaccepted;}
82	void	SetAllTimeAccepts(uint32 new_value)	{ alltimeaccepted = new_value; };
83	uint64	GetAllTimeTransferred() const		{return alltimetransferred;}
84	void	SetAllTimeTransferred(uint64 new_value)	{ alltimetransferred = new_value; };
85	CKnownFile* fileParent;
86
87private:
88	uint16 requested;
89	uint64 transferred;
90	uint16 accepted;
91	uint32 alltimerequested;
92	uint64 alltimetransferred;
93	uint32 alltimeaccepted;
94};
95
96/*
97                             CPartFile
98                           /
99                CKnownFile
100              /
101CAbstractFile
102              \
103                CSearchFile
104*/
105class CAbstractFile
106{
107public:
108	CAbstractFile();
109	explicit CAbstractFile(const CAbstractFile& other);
110	virtual ~CAbstractFile() {}
111
112	const CPath&	GetFileName() const	{ return m_fileName; }
113	const CMD4Hash&	GetFileHash() const	{ return m_abyFileHash; }
114
115	uint64	GetFileSize() const	{ return m_nFileSize;}
116	bool	IsLargeFile() const	{ return m_nFileSize > (uint64)OLD_MAX_FILE_SIZE; }
117
118	virtual void SetFileSize(uint64 nFileSize)	{ m_nFileSize = nFileSize; }
119	virtual void SetFileName(const CPath& filename);
120
121	/* Tags and Notes handling */
122	uint32 GetIntTagValue(uint8 tagname) const;
123	uint32 GetIntTagValue(const wxString& tagname) const;
124	bool GetIntTagValue(uint8 tagname, uint32& ruValue) const;
125	const wxString& GetStrTagValue(uint8 tagname) const;
126	const wxString& GetStrTagValue(const wxString& tagname) const;
127	const CTag *GetTag(const wxString& tagname) const;
128	const CTag *GetTag(const wxString& tagname, uint8 tagtype) const;
129	const CTag *GetTag(uint8 tagname) const;
130	const CTag *GetTag(uint8 tagname, uint8 tagtype) const;
131	void AddTagUnique(const CTag &pTag);
132	const ArrayOfCTag& GetTags() const { return m_taglist; }
133	void AddNote(Kademlia::CEntry* pEntry);
134	const CKadEntryPtrList& getNotes() const { return m_kadNotes; }
135
136	/* Comment and rating */
137	virtual const wxString&	GetFileComment() const { return m_strComment; }
138	virtual int8	GetFileRating() 		const { return m_iRating; }
139
140	bool	HasComment() const		{ return m_hasComment; }
141	bool	HasRating() const		{ return (m_iUserRating != 0); }
142	int8	UserRating() const 		{ return m_iUserRating; }
143
144protected:
145	//! CAbstractFile is not assignable.
146	CAbstractFile& operator=(const CAbstractFile);
147
148	CMD4Hash	m_abyFileHash;
149	// comment/rating are read from the config and cached in these variables,
150	// so make the mutable to allow GetFileComment() to be a const method
151	mutable	wxString	m_strComment;
152	mutable	int8		m_iRating;
153	bool		m_hasComment;
154	int8		m_iUserRating;
155	ArrayOfCTag	m_taglist;
156	CKadEntryPtrList m_kadNotes;
157
158private:
159	uint64		m_nFileSize;
160	CPath		m_fileName;
161};
162
163
164class CSearchFile;
165class CFile;
166
167
168class CKnownFile : public CAbstractFile, public CECID
169{
170friend class CHashingTask;
171public:
172	CKnownFile();
173	CKnownFile(uint32 ecid);
174	explicit CKnownFile(const CSearchFile &searchFile);
175
176	virtual ~CKnownFile();
177
178	void SetFilePath(const CPath& filePath);
179	const CPath& GetFilePath() const { return m_filePath; }
180
181	// virtual functions for CKnownFile and CPartFile:
182	virtual	bool	IsPartFile() const	{return false;}		// true if not completed
183	virtual bool	IsCompleted() const	{ return true; }	// true if completed
184	virtual bool	IsCPartFile() const	{ return false; }	// true if it's a CPartFile
185
186	virtual bool	LoadFromFile(const CFileDataIO* file);	//load date, hashset and tags from a .met file
187	virtual uint8	GetStatus(bool WXUNUSED(ignorepause) = false) const { return PS_COMPLETE; }
188	bool	WriteToFile(CFileDataIO* file);
189	time_t GetLastChangeDatetime() const { return m_lastDateChanged; }
190	void SetLastChangeDatetime(time_t t) { m_lastDateChanged = t; }
191
192	virtual void SetFileSize(uint64 nFileSize);
193
194	// local available part hashs
195	size_t	GetHashCount() const	{return m_hashlist.size();}
196	const CMD4Hash&	GetPartHash(uint16 part) const;
197
198	// nr. of part hashs according the file size wrt ED2K protocol
199	uint32	GetED2KPartHashCount() const { return m_iED2KPartHashCount; }
200
201	// nr. of 9MB parts (file data)
202	inline uint16 GetPartCount() const { return m_iPartCount; }
203
204	// nr. of 9MB parts according the file size wrt ED2K protocol (OP_FILESTATUS)
205	inline uint16 GetED2KPartCount() const { return m_iED2KPartCount; }
206
207	// size of a certain part, last is different, all others are PARTSIZE
208	uint32 GetPartSize(uint16 part) const { return part == m_iPartCount - 1 ? m_sizeLastPart : PARTSIZE; }
209
210	// file upload priority
211	uint8	GetUpPriority()	 const		{return m_iUpPriority;}
212	void	SetUpPriority(uint8 newUpPriority, bool bSave=true);
213	bool	IsAutoUpPriority() const		{return m_bAutoUpPriority;}
214	void	SetAutoUpPriority(bool flag)	{m_bAutoUpPriority = flag;}
215	void	UpdateAutoUpPriority();
216#ifdef CLIENT_GUI
217	uint16	GetQueuedCount() const { return m_queuedCount; }
218#else
219	uint16	GetQueuedCount() const { return (uint16) m_ClientUploadList.size(); }
220#endif
221
222	bool	LoadHashsetFromFile(const CFileDataIO* file, bool checkhash);
223	void	AddUploadingClient(CUpDownClient* client);
224	void	RemoveUploadingClient(CUpDownClient* client);
225
226	// comment
227	const wxString&	GetFileComment()	const	{ if (!m_bCommentLoaded) LoadComment(); return m_strComment; }
228	int8	GetFileRating() 			const	{ if (!m_bCommentLoaded) LoadComment(); return m_iRating; }
229
230	void	SetFileCommentRating(const wxString& strNewComment, int8 iNewRating);
231	void	SetPublishedED2K( bool val );
232	bool	GetPublishedED2K() const	{return m_PublishedED2K;}
233
234	/* Kad stuff */
235	uint32	GetKadFileSearchID() const { return kadFileSearchID; }
236	// KAD TODO: This must be used on KadSearchListCtrl too once imported
237	void	SetKadFileSearchID(uint32 id) { kadFileSearchID = id; } // John - Don't use this unless you know what your are DOING!! (Hopefully I do.. :)
238	const Kademlia::WordList& GetKadKeywords() const { return wordlist; }
239	// KAD TODO: If we add the proper column to SharedFilesCtrl, this is the funtion.
240	uint32	GetLastPublishTimeKadSrc() const { return m_lastPublishTimeKadSrc; }
241	void	SetLastPublishTimeKadSrc(uint32 time, uint32 buddyip) { m_lastPublishTimeKadSrc = time; m_lastBuddyIP = buddyip;}
242	// Another unused function, useful for the shared files control column
243	uint32	GetLastPublishBuddy() const { return m_lastBuddyIP; }
244	void	SetLastPublishTimeKadNotes(uint32 time) {m_lastPublishTimeKadNotes = time;}
245	uint32	GetLastPublishTimeKadNotes() const { return m_lastPublishTimeKadNotes; }
246
247	bool	PublishSrc();
248	bool	PublishNotes();
249
250	// TODO: This must be implemented if we ever want to have metadata.
251	uint32	GetMetaDataVer() const { return /*m_uMetaDataVer*/ 0; }
252
253	// file sharing
254	virtual	CPacket*	CreateSrcInfoPacket(const CUpDownClient* forClient, uint8 byRequestedVersion, uint16 nRequestedOptions);
255	void	CreateOfferedFilePacket(CMemFile* files, class CServer* pServer, CUpDownClient* pClient);
256
257	virtual void	UpdatePartsInfo();
258
259
260	CFileStatistic statistic;
261
262	time_t m_nCompleteSourcesTime;
263	uint16 m_nCompleteSourcesCount;
264	uint16 m_nCompleteSourcesCountLo;
265	uint16 m_nCompleteSourcesCountHi;
266
267	// Common for part and known files.
268	typedef std::set<CClientRef> SourceSet;
269	SourceSet m_ClientUploadList;
270	ArrayOfUInts16 m_AvailPartFrequency;
271
272	/**
273 	 * Returns a base-16 encoding of the master hash, or
274 	 * an empty string if no such hash exists.
275 	 */
276	wxString GetAICHMasterHash() const;
277	/** Returns true if the AICH-Hashset is valid, and verified or complete. */
278	bool HasProperAICHHashSet() const;
279
280	/**
281	 * Updates the requency of uploading parts from with the data the client provides.
282	 *
283	 * @param client The clients whoose uploading parts should be considered.
284	 * @param increment If true, the counts are incremented, otherwise they are decremented.
285	 *
286	 * This functions updates the frequency list of file-upparts, using the clients
287	 * upparts-status. This function should be called by clients every time they update their
288	 * upparts-status, or when they are added or removed from the file.
289	 */
290	void UpdateUpPartsFrequency( CUpDownClient* client, bool increment );
291
292	static void CreateHashFromHashlist(const ArrayOfCMD4Hash& hashes, CMD4Hash* Output);
293
294	void	ClearPriority();
295
296	time_t	m_lastDateChanged;
297
298	virtual wxString GetFeedback() const;
299
300	void	SetShowSources( bool val )	{ m_showSources = val; }
301	bool	ShowSources() const			{ return m_showSources; }
302	void	SetShowPeers( bool val )	{ m_showPeers = val; }
303	bool	ShowPeers()	const			{ return m_showPeers; }
304
305#ifdef CLIENT_GUI
306	CKnownFile(CEC_SharedFile_Tag *);
307	friend class CKnownFilesRem;
308	RLE_Data m_partStatus;
309
310private:
311	uint8	m_iUpPriorityEC;
312	uint16	m_queuedCount;
313
314protected:
315	//! The AICH master-hash, if it is known.
316	wxString	m_AICHMasterHash;
317#else
318	virtual void SetFileName(const CPath& filename);
319
320	// AICH
321	CAICHHashSet* GetAICHHashset() const		{ return m_pAICHHashSet; }
322	void SetAICHHashset(CAICHHashSet* val)		{ m_pAICHHashSet = val; }
323
324protected:
325	CAICHHashSet*	m_pAICHHashSet;
326#endif
327
328	bool	LoadTagsFromFile(const CFileDataIO* file);
329	bool	LoadDateFromFile(const CFileDataIO* file);
330	void	LoadComment() const;
331	ArrayOfCMD4Hash m_hashlist;
332	CPath	m_filePath;
333
334	static void CreateHashFromFile(class CFileAutoClose& file, uint64 offset, uint32 Length, CMD4Hash* Output, CAICHHashTree* pShaHashOut);
335	static void CreateHashFromInput(const byte* input, uint32 Length, CMD4Hash* Output, CAICHHashTree* pShaHashOut);
336
337	mutable bool	m_bCommentLoaded;
338	uint16	m_iPartCount;
339	uint16  m_iED2KPartCount;
340	uint16	m_iED2KPartHashCount;
341	uint32	m_sizeLastPart;			// size of the last part
342	uint8	m_iUpPriority;
343	bool	m_bAutoUpPriority;
344	bool	m_PublishedED2K;
345
346	/* Kad stuff */
347	Kademlia::WordList wordlist;
348	uint32	kadFileSearchID;
349	uint32	m_lastPublishTimeKadSrc;
350	uint32	m_lastPublishTimeKadNotes;
351	uint32	m_lastBuddyIP;
352
353	bool	m_showSources;
354	bool	m_showPeers;
355private:
356	/** Common initializations for constructors. */
357	void Init();
358};
359
360#endif // KNOWNFILE_H
361// File_checked_for_headers
362