2 // This file is part of the aMule Project.
4 // Copyright (c) 2003-2008 aMule Team ( admin@amule.org / http://www.amule.org )
5 // Copyright (c) 2002-2008 Merkur ( devs@emule-project.net / http://www.emule-project.net )
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
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.
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.
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
30 #include "KnownFile.h" // Needed for CKnownFile
31 #include "CFile.h" // Needed for CFile
33 #include "OtherStructs.h" // Needed for Gap_Struct
34 #include "DeadSourceList.h" // Needed for CDeadSourceList
44 //#define BUFFER_SIZE_LIMIT 500000 // Max bytes before forcing a flush
45 #define BUFFER_TIME_LIMIT 60000 // Max milliseconds before forcing a flush
47 #define STATES_COUNT 13
49 // Ok, eMule and aMule are building incompatible backup files because
50 // of the different name. aMule was using ".BAK" and eMule ".bak".
51 // This should fix it.
52 #define PARTMET_BAK_EXT wxT(".bak")
54 enum EPartFileFormat
{
63 struct PartFileBufferedData
65 byte
*data
; // Barry - This is the data to be written
66 uint64 start
; // Barry - This is the start offset of the data
67 uint64 end
; // Barry - This is the end offset of the data
68 Requested_Block_Struct
*block
; // Barry - This is the requested block that this data relates to
80 SFileRating(const wxString
&u
, const wxString
&f
, sint16 r
, const wxString
&c
);
81 SFileRating(const SFileRating
&fr
);
82 SFileRating(const CUpDownClient
&client
);
86 typedef std::list
<SFileRating
> FileRatingList
;
94 SourcenameItem(const wxString
&n
, long c
)
99 typedef std::list
<SourcenameItem
> SourcenameItemList
;
101 class CPartFile
: public CKnownFile
{
103 typedef std::list
<Requested_Block_Struct
*> CReqBlockPtrList
;
107 CPartFile(CEC_PartFile_Tag
*tag
);
109 virtual void SetFileName(const CPath
& filename
);
111 CPartFile(CSearchFile
* searchresult
); //used when downloading a new file
112 CPartFile(const CED2KFileLink
* fileLink
);
113 virtual ~CPartFile();
115 bool CreateFromFile(wxString
WXUNUSED(directory
), wxString
WXUNUSED(filename
), void* WXUNUSED(pvProgressParam
)) {return false;}// not supported in this class
116 void SetPartFileStatus(uint8 newstatus
);
117 virtual bool LoadFromFile(const CFileDataIO
* WXUNUSED(file
)) { return false; }
118 bool WriteToFile(CFileDataIO
* WXUNUSED(file
)) { return false; }
119 bool IsPartFile() const { return !(status
== PS_COMPLETE
); }
120 uint32
Process(uint32 reducedownload
, uint8 m_icounter
);
121 uint8
LoadPartFile(const CPath
& in_directory
, const CPath
& filename
, bool from_backup
= false, bool getsizeonly
= false);
122 bool SavePartFile(bool Initial
= false);
123 void PartFileHashFinished(CKnownFile
* result
);
124 bool HashSinglePart(uint16 partnumber
); // true = ok , false = corrupted
126 bool CheckShowItemInGivenCat(int inCategory
);
128 bool IsComplete(uint64 start
, uint64 end
) { return m_gaplist
.IsComplete(start
, end
); }
129 bool IsComplete(uint16 part
) { return m_gaplist
.IsComplete(part
); }
131 void UpdateCompletedInfos();
133 bool GetNextRequestedBlock(CUpDownClient
* sender
, std::vector
<Requested_Block_Struct
*>& toadd
, uint16
& count
);
134 void WritePartStatus(CMemFile
* file
);
135 void WriteCompleteSourcesCount(CMemFile
* file
);
136 static bool CanAddSource(uint32 userid
, uint16 port
, uint32 serverip
, uint16 serverport
, uint8
* pdebug_lowiddropped
= NULL
, bool ed2kID
= true);
137 void AddSources(CMemFile
& sources
, uint32 serverip
, uint16 serverport
, unsigned origin
, bool bWithObfuscationAndHash
);
139 uint8
GetStatus() const { return status
; }
140 uint8
GetStatus(bool /*ignorepause = false*/) const { return status
; }
142 uint8
GetStatus(bool ignorepause
= false) const;
144 virtual void UpdatePartsInfo();
145 const CPath
& GetPartMetFileName() const { return m_partmetfilename
; }
146 uint64
GetTransferred() const { return transferred
; }
147 const CPath
& GetFullName() const { return m_fullname
; }
148 float GetKBpsDown() const { return kBpsDown
; }
149 double GetPercentCompleted() const { return percentcompleted
; }
152 uint16
GetSourceCount() const { return (uint16
)m_SrcList
.size(); }
153 uint16
GetSrcA4AFCount() const { return (uint16
)m_A4AFsrclist
.size(); }
155 uint16 m_source_count
, m_a4af_source_count
;
156 uint16
GetSourceCount() const { return m_source_count
; }
157 uint16
GetSrcA4AFCount() const { return m_a4af_source_count
; }
159 uint16
GetTransferingSrcCount() const { return transferingsrc
; }
160 uint16
GetNotCurrentSourcesCount() const { return m_notCurrentSources
; };
161 void SetNotCurrentSourcesCount(uint16 new_count
) { m_notCurrentSources
= new_count
; };
162 uint16
GetValidSourcesCount() const { return m_validSources
; };
164 uint64
GetNeededSpace();
166 virtual wxString
GetFeedback() const;
168 wxString
getPartfileStatus() const; //<<--9/21/02
169 sint32
getTimeRemaining() const; //<<--9/21/02
170 time_t lastseencomplete
;
171 int getPartfileStatusRang() const;
173 // Barry - Added as replacement for BlockReceived to buffer data before writing to disk
174 uint32
WriteToBuffer(uint32 transize
, byte
*data
, uint64 start
, uint64 end
, Requested_Block_Struct
*block
);
175 void FlushBuffer(bool fromAICHRecoveryDataAvailable
= false);
177 // Barry - Is archive recovery in progress
178 volatile bool m_bRecoveringArchive
;
180 // Barry - Added to prevent list containing deleted blocks on shutdown
181 void RemoveAllRequestedBlocks(void);
183 void RemoveBlockFromList(uint64 start
,uint64 end
);
184 void RemoveAllSources(bool bTryToSwap
);
186 void StopFile(bool bCancel
= false);
187 void PauseFile(bool bInsufficient
= false);
190 virtual CPacket
* CreateSrcInfoPacket(const CUpDownClient
* forClient
, uint8 byRequestedVersion
, uint16 nRequestedOptions
);
191 void AddClientSources(CMemFile
* sources
, unsigned nSourceFrom
, uint8 uClientSXVersion
, bool bSourceExchange2
, const CUpDownClient
* pClient
= NULL
);
193 bool PreviewAvailable();
194 uint16
GetAvailablePartCount() const { return m_availablePartsCount
; }
195 uint32
GetLastAnsweredTime() const { return m_ClientSrcAnswered
; }
196 void SetLastAnsweredTime();
197 void SetLastAnsweredTimeTimeout();
198 uint64
GetLostDueToCorruption() const { return m_iLostDueToCorruption
; }
199 uint64
GetGainDueToCompression() const { return m_iGainDueToCompression
; }
200 uint32
TotalPacketsSavedDueToICH()const{ return m_iTotalPacketsSavedDueToICH
; }
201 bool IsStopped() const { return this ? m_stopped
: true; }
202 bool IsPaused() const { return m_paused
; }
203 void UpdateFileRatingCommentAvail();
204 bool m_CommentUpdated
;
206 int GetCommonFilePenalty();
207 void UpdateDisplayedInfo(bool force
= false);
209 uint8
GetCategory() const { return m_category
; }
210 void SetCategory(uint8 cat
);
212 volatile bool m_bPreviewing
;
213 void SetDownPriority(uint8 newDownPriority
, bool bSave
= true, bool bRefresh
= true);
214 bool IsAutoDownPriority() const { return m_bAutoDownPriority
; }
215 void SetAutoDownPriority(bool flag
) { m_bAutoDownPriority
= flag
; }
216 void UpdateAutoDownPriority();
217 uint8
GetDownPriority() const { return m_iDownPriority
; }
218 void SetActive(bool bActive
);
219 uint32
GetDlActiveTime() const;
220 bool GetInsufficient() const { return m_insufficient
; }
222 void CompleteFileEnded(bool errorOccured
, const CPath
& newname
);
224 bool RemoveSource(CUpDownClient
* toremove
, bool updatewindow
= true, bool bDoStatsUpdate
= true);
226 void RequestAICHRecovery(uint16 nPart
);
227 void AICHRecoveryDataAvailable(uint16 nPart
);
230 * This function is used to update source-counts.
232 * @param oldState The old state of the client, or -1 to ignore.
233 * @param newState The new state of the client, or -1 to ignore.
235 * Call this function for a client belonging to this file, which has changed
236 * its state. The value -1 can be used to make the function ignore one of
239 * AddSource and DelSource takes care of calling this function when a source is
240 * removed, so there's no need to call this function when calling either of those.
242 void ClientStateChanged( int oldState
, int newState
);
244 bool AddSource( CUpDownClient
* client
);
245 bool DelSource( CUpDownClient
* client
);
248 * Updates the requency of avilable parts from with the data the client provides.
250 * @param client The clients whoose available parts should be considered.
251 * @param increment If true, the counts are incremented, otherwise they are decremented.
253 * This functions updates the frequency list of file-parts, using the clients
254 * parts-status. This function should be called by clients every time they update their
255 * parts-status, or when they are added or removed from the file.
257 void UpdatePartsFrequency( CUpDownClient
* client
, bool increment
);
259 ArrayOfUInts16 m_SrcpartFrequency
;
261 void SetShowSources( bool val
) { m_showSources
= val
; }
262 bool ShowSources() const { return m_showSources
; }
264 typedef std::set
<CUpDownClient
*> SourceSet
;
266 const SourceSet
& GetSourceList() const { return m_SrcList
; }
267 const SourceSet
& GetA4AFList() const { return m_A4AFsrclist
; }
269 const CReqBlockPtrList
GetRequestedBlockList() const { return m_requestedblocks_list
; }
271 // LEGACY - to be removed when possible
274 void Init(const CGapList
* gaplist
) { m_gaplist
= gaplist
; }
275 class const_iterator
{
276 CGapList::const_iterator m_it
;
280 const_iterator(const CGapList::const_iterator
& it
) { m_it
= it
; };
281 bool operator != (const const_iterator
& it
) { return m_it
!= it
.m_it
; }
282 const_iterator
& operator ++ () { ++ m_it
; return *this; }
283 Gap_Struct
* operator * () {
284 m_gap
.start
= m_it
.start();
285 m_gap
.end
= m_it
.end();
289 const_iterator
begin() const { return const_iterator(m_gaplist
->begin()); }
290 const_iterator
end() const { return const_iterator(m_gaplist
->end()); }
291 bool empty() const { return m_gaplist
->IsComplete(); }
292 uint32
size() const { return m_gaplist
->size(); }
295 const CGapList
* m_gaplist
;
297 // this function must stay, but return the m_gaplist instead
298 const CGapPtrList
& GetGapList() const { return m_gapptrlist
; }
300 const CGapList
& GetNewGapList() const { return m_gaplist
; }
302 CGapPtrList m_gapptrlist
;
307 * Adds a source to the list of dead sources.
309 * @param client The source to be recorded as dead for this file.
311 void AddDeadSource(const CUpDownClient
* client
);
314 * Checks if a source is recorded as being dead for this file.
316 * @param client The client to evaluate.
317 * @return True if dead, false otherwise.
319 * Sources that are dead are not to be considered valid
320 * sources and should not be added to the partfile.
322 bool IsDeadSource(const CUpDownClient
* client
);
325 uint16
GetMaxSources() const;
326 uint16
GetMaxSourcePerFileSoft() const;
327 uint16
GetMaxSourcePerFileUDP() const;
329 const FileRatingList
&GetRatingAndComments();
331 void AllocationFinished();
333 CFile m_hpartfile
; //permanent opened handle to avoid write conflicts
334 //! A local list of sources that are invalid for this file.
336 CDeadSourceList m_deadSources
;
339 uint16 m_notCurrentSources
;
343 uint32 m_validSources
;
345 void AddGap(uint64 start
, uint64 end
);
346 void AddGap(uint16 part
);
347 void FillGap(uint64 start
, uint64 end
);
348 void FillGap(uint16 part
);
349 bool GetNextEmptyBlockInPart(uint16 partnumber
,Requested_Block_Struct
* result
);
350 bool IsAlreadyRequested(uint64 start
, uint64 end
);
351 void CompleteFile(bool hashingdone
);
352 void CreatePartFile();
355 bool CheckFreeDiskSpace( uint64 neededSpace
= 0 );
357 bool IsCorruptedPart(uint16 partnumber
);
359 uint32 m_iLastPausePurge
;
361 uint16 m_anStates
[STATES_COUNT
];
362 uint16 transferingsrc
;
363 uint64 completedsize
;
366 uint64 m_iLostDueToCorruption
;
367 uint64 m_iGainDueToCompression
;
368 uint32 m_iTotalPacketsSavedDueToICH
;
370 CPath m_fullname
; // path/name of the met file
371 CPath m_partmetfilename
; // name of the met file
372 CPath m_PartPath
; // path/name of the partfile
376 uint8 m_iDownPriority
;
377 bool m_bAutoDownPriority
;
379 uint32 lastpurgetime
;
380 uint32 m_LastNoNeededCheck
;
382 CReqBlockPtrList m_requestedblocks_list
;
383 double percentcompleted
;
384 std::list
<uint16
> m_corrupted_list
;
385 uint16 m_availablePartsCount
;
386 uint32 m_ClientSrcAnswered
;
387 bool m_bPercentUpdated
;
389 void PerformFileComplete();
391 uint32 m_lastRefreshedDLDisplay
;
393 // Barry - Buffered data to be written
394 std::list
<PartFileBufferedData
*> m_BufferedData_list
;
396 uint32 m_nTotalBufferData
;
397 uint32 m_nLastBufferFlushTime
;
400 uint32 m_nDlActiveTime
;
405 SourceSet m_A4AFsrclist
;
406 bool m_hashsetneeded
;
407 uint32 m_lastsearchtime
;
408 bool m_localSrcReqQueued
;
410 FileRatingList m_FileRatingList
;
412 SourcenameItemList m_SourcenameItem_list
;
414 const SourcenameItemList
&GetSourcenameItemList() { return m_SourcenameItem_list
; }
415 void ClearSourcenameItemList() { m_SourcenameItem_list
.clear(); }
416 void AddSourcenameItemList(const wxString
&name
, long count
) { m_SourcenameItem_list
.push_back(SourcenameItem(name
, count
)); }
419 const FileRatingList
&GetFileRatingList() { return m_FileRatingList
; }
420 void ClearFileRatingList() { m_FileRatingList
.clear(); }
421 void AddFileRatingList(const wxString
& u
, const wxString
& f
, sint16 r
, const wxString
& c
) {
422 m_FileRatingList
.push_back(SFileRating(u
, f
, r
, c
)); }
424 bool IsHashSetNeeded() const { return m_hashsetneeded
; }
425 void SetHashSetNeeded(bool value
) { m_hashsetneeded
= value
; }
427 uint64
GetCompletedSize() const { return completedsize
; }
428 void SetCompletedSize(uint64 size
) { completedsize
= size
; }
430 bool IsLocalSrcRequestQueued() const { return m_localSrcReqQueued
; }
431 void SetLocalSrcRequestQueued(bool value
) { m_localSrcReqQueued
= value
; }
433 void AddA4AFSource(CUpDownClient
* src
) { m_A4AFsrclist
.insert(src
); }
434 bool RemoveA4AFSource(CUpDownClient
* src
) { return (m_A4AFsrclist
.erase(src
) > 0); }
436 uint32
GetLastSearchTime() const { return m_lastsearchtime
; }
437 void SetLastSearchTime(uint32 time
) { m_lastsearchtime
= time
; }
439 // void CleanUpSources( bool noNeeded, bool fullQueue = false, bool highQueue = false );
441 void AddDownloadingSource(CUpDownClient
* client
);
443 void RemoveDownloadingSource(CUpDownClient
* client
);
444 void SetStatus(uint8 in
);
445 void StopPausedFile();
447 // [sivka / Tarod] Imported from eMule 0.30c (Creteil) ...
448 void SetA4AFAuto(bool in
) { m_is_A4AF_auto
= in
; }
449 bool IsA4AFAuto() const { return m_is_A4AF_auto
; }
451 // Kry -Sources seeds
452 void SaveSourceSeeds();
453 void LoadSourceSeeds();
455 // Dropping slow sources
456 CUpDownClient
* GetSlowerDownloadingClient(uint32 speed
, CUpDownClient
* caller
);
458 // Read data for sharing
459 bool ReadData(class CFileArea
& area
, uint64 offset
, uint32 toread
);
462 /* downloading sources list */
463 CClientPtrList m_downloadingSourcesList
;
466 uint32 m_LastSearchTimeKad
;
467 uint8 m_TotalSearchesKad
;
469 friend class CDownQueueRem
;
470 friend class CPartFileConvert
;
474 // File_checked_for_headers