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