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 // Copyright (c) 2005-2011 Dévai Tamás ( gonosztopi@amule.org )
7 //
8 // Any parts of this program derived from the xMule, lMule or eMule project,
9 // or contributed by third-party developers are copyrighted by their
10 // respective authors.
11 //
12 // This program is free software; you can redistribute it and/or modify
13 // it under the terms of the GNU General Public License as published by
14 // the Free Software Foundation; either version 2 of the License, or
15 // (at your option) any later version.
16 //
17 // This program is distributed in the hope that it will be useful,
18 // but WITHOUT ANY WARRANTY; without even the implied warranty of
19 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20 // GNU General Public License for more details.
21 //
22 // You should have received a copy of the GNU General Public License
23 // along with this program; if not, write to the Free Software
24 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA
25 //
26 
27 #ifndef STATISTICS_H
28 #define STATISTICS_H
29 
30 #include "Constants.h"		// Needed for StatsGraphType
31 #include "StatTree.h"		// Needed for CStatTreeItem* classes
32 
33 #include <deque>		// Needed for std::deque
34 
35 typedef struct UpdateInfo {
36 	double timestamp;
37 	float downloads[3];
38 	float uploads[3];
39 	float connections[3];
40 	float kadnodes[3];
41 } GraphUpdateInfo;
42 
43 typedef struct HistoryRecord {
44 	double		kBytesSent;
45 	double		kBytesReceived;
46 	float		kBpsUpCur;
47 	float		kBpsDownCur;
48 	double		sTimestamp;
49 	uint16		cntDownloads;
50 	uint16		cntUploads;
51 	uint16		cntConnections;
52 	uint16		kadNodesCur;
53 	uint64		kadNodesTotal;
54 } HR;
55 
56 
57 #ifndef CLIENT_GUI
58 
59 /**
60  * Counts precise rate/average on added bytes/values.
61  *
62  * @note This class is MT-safe.
63  */
64 class CPreciseRateCounter {
65 	friend class CStatistics;	// for playing dirty tricks to compute running average :P
66  public:
67 
68 	/**
69 	 * Constructor
70 	 *
71 	 * @param timespan Desired timespan for rate calculations.
72 	 * @param count_average Counts average instead of rate.
73 	 */
74 	CPreciseRateCounter(uint32_t timespan, bool count_average = false)
m_timespan(timespan)75 		: m_timespan(timespan), m_total(0), m_rate(0.0), m_max_rate(0.0), m_tmp_sum(0), m_count_average(count_average)
76 		{
77 			if (!count_average) {
78 				uint64_t cur_time = GetTickCount64();
79 				uint64_t target_time = cur_time - timespan;
80 				while (cur_time > target_time) {
81 					m_tick_history.push_front(cur_time);
82 					m_byte_history.push_front(0);
83 					cur_time -= 100;	// default update period
84 				}
85 				m_tick_history.push_front(cur_time);
86 			}
87 		}
88 
89 	/**
90 	 * Calculate current rate.
91 	 *
92 	 * This function should be called reasonably often, to
93 	 * keep rates up-to-date, and prevent history growing
94 	 * to the skies.
95 	 */
96 	void	CalculateRate(uint64_t now);
97 
98 	/**
99 	 * Get current rate.
100 	 *
101 	 * @return Current rate in bytes/second.
102 	 */
GetRate()103 	double	GetRate()			{ wxMutexLocker lock(m_mutex); return m_rate; };
104 
105 	/**
106 	 * Gets ever seen maximal rate.
107 	 *
108 	 * @return The maximal rate which occured.
109 	 */
GetMaxRate()110 	double	GetMaxRate()			{ wxMutexLocker lock(m_mutex); return m_max_rate; }
111 
112 	/**
113 	 * Sets desired timespan for rate calculations.
114 	 *
115 	 * If new timespan is greater than the old was, then the change
116 	 * takes effect with time. The exact time needed for the change
117 	 * to take effect is new minus old value of the timespan.
118 	 *
119 	 * If the new timespan is lower than the old, the change takes
120 	 * effect immediately at the next call to CalculateRate().
121 	 */
SetTimespan(uint32_t timespan)122 	void	SetTimespan(uint32_t timespan)	{ wxMutexLocker lock(m_mutex); m_timespan = timespan; }
123 
124 	/**
125 	 * Add bytes to be tracked for rate-counting.
126 	 */
127 	void	operator+=(uint32_t bytes)	{ wxMutexLocker lock(m_mutex); m_tmp_sum += bytes; }
128 
129  protected:
130 
131 	std::deque<uint32>	m_byte_history;
132 	std::deque<uint64>	m_tick_history;
133 	uint32_t	m_timespan;
134 	uint32_t	m_total;
135 	double		m_rate;
136 	double		m_max_rate;
137 	uint32_t	m_tmp_sum;
138 	wxMutex		m_mutex;
139 	bool		m_count_average;
140 };
141 
142 
143 class CECTag;
144 
145 /**
146  * Stat tree item for rates/averages.
147  */
148 class CStatTreeItemRateCounter : public CStatTreeItemBase, public CPreciseRateCounter {
149  public:
150 
151 	/**
152 	 * @see CStatTreeItemBase::CStatTreeItemBase, CPreciseRateCounter::CPreciseRateCounter
153 	 *
154 	 * @param show_maxrate If true, shows max rate instead of current rate.
155 	 */
156 	CStatTreeItemRateCounter(const wxString& label, bool show_maxrate, uint32_t timespan, bool count_average = false)
CStatTreeItemBase(label,stNone)157 		: CStatTreeItemBase(label, stNone), CPreciseRateCounter(timespan, count_average), m_show_maxrate(show_maxrate)
158 		{}
159 
160 #ifndef AMULE_DAEMON
161 	/**
162 	 * @see CStatTreeItemBase::GetDisplayString()
163 	 */
164 	virtual wxString GetDisplayString() const;
165 #endif
166 
167  protected:
168 	/**
169 	 * Add values to EC tag being generated.
170 	 *
171 	 * @param tag The tag to which values should be added.
172 	 *
173 	 * @see CStatTreeItemBase::AddECValues
174 	 */
175 	virtual	void	AddECValues(CECTag* tag) const;
176 
177 	//! Whether to show max rate instead of actual rate.
178 	bool	m_show_maxrate;
179 };
180 
181 
182 /**
183  * Stat tree item for Peak Connections.
184  */
185 class CStatTreeItemPeakConnections : public CStatTreeItemBase {
186  public:
187 
188 	/**
189 	 * @see CStatTreeItemBase::CStatTreeItemBase
190 	 */
CStatTreeItemPeakConnections(const wxString & label)191 	CStatTreeItemPeakConnections(const wxString& label)
192 		: CStatTreeItemBase(label)
193 		{}
194 
195 #ifndef AMULE_DAEMON
196 	/**
197 	 * @see CStatTreeItemBase::GetDisplayString()
198 	 */
199 	virtual wxString GetDisplayString() const;
200 #endif
201 
202  protected:
203 	/**
204 	 * Add values to EC tag being generated.
205 	 *
206 	 * @param tag The tag to which values should be added.
207 	 *
208 	 * @see CStatTreeItemBase::AddECValues
209 	 */
210 	virtual	void	AddECValues(CECTag* tag) const;
211 };
212 
213 
214 class CUpDownClient;
215 
216 class CStatistics {
217 	friend class CStatisticsDlg;	// to access CStatistics::GetTreeRoot()
218  public:
219 	CStatistics();
220 	~CStatistics();
221 
222 	static void	Load();
223 	static void	Save();
224 
225 	/* Statistics graph functions */
226 
227 	void	 RecordHistory();
228 	unsigned GetHistoryForWeb(unsigned cntPoints, double sStep, double *sStart, uint32 **graphData);
229 	unsigned GetHistory(unsigned cntPoints, double sStep, double sFinal, const std::vector<float *> &ppf, StatsGraphType which_graph);
230 	GraphUpdateInfo GetPointsForUpdate();
231 
232 	/* Statistics tree functions */
233 
234 	void UpdateStatsTree();
235 
236 	/* Access to the tree */
237 
238 	// uptime
GetUptimeMillis()239 	static	uint64	GetUptimeMillis()			{ return s_uptime->GetTimerValue(); }
GetUptimeSeconds()240 	static	uint64	GetUptimeSeconds()			{ return s_uptime->GetTimerSeconds(); }
GetStartTime()241 	static	uint64	GetStartTime()				{ return s_uptime->GetTimerStart(); }
242 
243 	// Upload
GetTotalSentBytes()244 	static	uint64	GetTotalSentBytes()			{ return s_totalSent; }
GetSessionSentBytes()245 	static	uint64	GetSessionSentBytes()			{ return (*s_sessionUpload); }
AddUpOverheadFileRequest(uint32 size)246 	static	void	AddUpOverheadFileRequest(uint32 size)	{ (*s_fileReqUpOverhead) += size; (*s_upOverheadRate) += size; }
AddUpOverheadSourceExchange(uint32 size)247 	static	void	AddUpOverheadSourceExchange(uint32 size){ (*s_sourceXchgUpOverhead) += size; (*s_upOverheadRate) += size; }
AddUpOverheadServer(uint32 size)248 	static	void	AddUpOverheadServer(uint32 size)	{ (*s_serverUpOverhead) += size; (*s_upOverheadRate) += size; }
AddUpOverheadKad(uint32 size)249 	static	void	AddUpOverheadKad(uint32 size)		{ (*s_kadUpOverhead) += size; (*s_upOverheadRate) += size; }
AddUpOverheadCrypt(uint32_t size)250 	static	void	AddUpOverheadCrypt(uint32_t size)	{ (*s_cryptUpOverhead) += size; }
AddUpOverheadOther(uint32 size)251 	static	void	AddUpOverheadOther(uint32 size)		{ (*s_totalUpOverhead) += size; (*s_upOverheadRate) += size; }
GetUpOverheadRate()252 	static	double	GetUpOverheadRate()			{ return s_upOverheadRate->GetRate(); }
AddSuccessfulUpload()253 	static	void	AddSuccessfulUpload()			{ ++(*s_totalSuccUploads); }
AddFailedUpload()254 	static	void	AddFailedUpload()			{ ++(*s_totalFailedUploads); }
AddUploadTime(uint32 time)255 	static	void	AddUploadTime(uint32 time)		{ (*s_totalUploadTime) += time; }
AddUploadingClient()256 	static	void	AddUploadingClient()			{ ++(*s_activeUploads); }
RemoveUploadingClient()257 	static	void	RemoveUploadingClient()			{ --(*s_activeUploads); }
GetActiveUploadsCount()258 	static	uint32	GetActiveUploadsCount()			{ return (*s_activeUploads); }
AddWaitingClient()259 	static	void	AddWaitingClient()			{ ++(*s_waitingUploads); }
RemoveWaitingClient()260 	static	void	RemoveWaitingClient()			{ --(*s_waitingUploads); }
GetWaitingUserCount()261 	static	uint32	GetWaitingUserCount()			{ return (*s_waitingUploads); }
GetUploadRate()262 	static	double	GetUploadRate()				{ return s_uploadrate->GetRate(); }
263 
264 	// Download
GetTotalReceivedBytes()265 	static	uint64	GetTotalReceivedBytes()			{ return s_totalReceived; }
GetSessionReceivedBytes()266 	static	uint64	GetSessionReceivedBytes()		{ return (*s_sessionDownload); }
AddDownOverheadFileRequest(uint32 size)267 	static	void	AddDownOverheadFileRequest(uint32 size)	{ (*s_fileReqDownOverhead) += size; (*s_downOverheadRate) += size; }
AddDownOverheadSourceExchange(uint32 size)268 	static	void	AddDownOverheadSourceExchange(uint32 size){ (*s_sourceXchgDownOverhead) += size; (*s_downOverheadRate) += size; }
AddDownOverheadServer(uint32 size)269 	static	void	AddDownOverheadServer(uint32 size)	{ (*s_serverDownOverhead) += size; (*s_downOverheadRate) += size; }
AddDownOverheadKad(uint32 size)270 	static	void	AddDownOverheadKad(uint32 size)		{ (*s_kadDownOverhead) += size; (*s_downOverheadRate) += size; }
AddDownOverheadCrypt(uint32_t size)271 	static	void	AddDownOverheadCrypt(uint32_t size)	{ (*s_cryptDownOverhead) += size; }
AddDownOverheadOther(uint32 size)272 	static	void	AddDownOverheadOther(uint32 size)	{ (*s_totalDownOverhead) += size; (*s_downOverheadRate) += size; }
GetDownOverheadRate()273 	static	double	GetDownOverheadRate()			{ return s_downOverheadRate->GetRate(); }
AddFoundSource()274 	static	void	AddFoundSource()			{ ++(*s_foundSources); }
RemoveFoundSource()275 	static	void	RemoveFoundSource()			{ --(*s_foundSources); }
GetFoundSources()276 	static	uint32	GetFoundSources()			{ return (*s_foundSources); }
277 	static	void	AddSourceOrigin(unsigned origin);
278 	static	void	RemoveSourceOrigin(unsigned origin);
AddDownloadingSource()279 	static	void	AddDownloadingSource()			{ ++(*s_activeDownloads); }
RemoveDownloadingSource()280 	static	void	RemoveDownloadingSource()		{ --(*s_activeDownloads); }
GetDownloadingSources()281 	static	uint32	GetDownloadingSources()			{ return (*s_activeDownloads); }
GetDownloadRate()282 	static	double	GetDownloadRate()			{ return s_downloadrate->GetRate(); }
283 
284 	// Connection
GetServerConnectTimer()285 	static	CStatTreeItemTimer* GetServerConnectTimer()	{ return s_sinceConnected; }
AddReconnect()286 	static	void	AddReconnect()				{ ++(*s_reconnects); }
AddActiveConnection()287 	static	void	AddActiveConnection()			{ ++(*s_activeConnections); }
RemoveActiveConnection()288 	static	void	RemoveActiveConnection()		{ --(*s_activeConnections); }
GetActiveConnections()289 	static	uint32	GetActiveConnections()			{ return s_activeConnections->GetValue(); }
GetPeakConnections()290 	static	uint32	GetPeakConnections()			{ return s_activeConnections->GetMaxValue(); }
AddMaxConnectionLimitReached()291 	static	void	AddMaxConnectionLimitReached()		{ ++(*s_limitReached); }
292 
293 	// Clients
AddFilteredClient()294 	static	void	AddFilteredClient()			{ ++(*s_filtered); }
AddUnknownClient()295 	static	void	AddUnknownClient()			{ ++(*s_unknown); }
RemoveUnknownClient()296 	static	void	RemoveUnknownClient()			{ --(*s_unknown); }
297 	static	void	AddKnownClient(CUpDownClient *pClient);
298 	static	void	RemoveKnownClient(uint32 clientSoft, uint32 clientVersion, const wxString& OSInfo);
299 #ifdef __DEBUG__
SocketAssignedToClient()300 	static	void	SocketAssignedToClient()		{ ++(*s_hasSocket); }
SocketUnassignedFromClient()301 	static	void	SocketUnassignedFromClient()		{ --(*s_hasSocket); }
302 #endif
GetBannedCount()303 	static	uint32	GetBannedCount()			{ return (*s_banned); }
AddBannedClient()304 	static	void	AddBannedClient()			{ ++(*s_banned); }
RemoveBannedClient()305 	static	void	RemoveBannedClient()			{ --(*s_banned); }
306 
307 	// Servers
AddServer()308 	static	void	AddServer()				{ ++(*s_totalServers); }
DeleteServer()309 	static	void	DeleteServer()				{ ++(*s_deletedServers); --(*s_totalServers); }
DeleteAllServers()310 	static	void	DeleteAllServers()			{ (*s_deletedServers) += (*s_totalServers); (*s_totalServers) = 0; }
AddFilteredServer()311 	static	void	AddFilteredServer()			{ ++(*s_filteredServers); }
312 
313 	// Shared files
ClearSharedFilesInfo()314 	static	void	ClearSharedFilesInfo()			{ (*s_numberOfShared) = 0; (*s_sizeOfShare) = 0; }
AddSharedFile(uint64 size)315 	static	void	AddSharedFile(uint64 size)		{ ++(*s_numberOfShared); (*s_sizeOfShare) += size; }
RemoveSharedFile(uint64 size)316 	static	void	RemoveSharedFile(uint64 size)		{ --(*s_numberOfShared); (*s_sizeOfShare) -= size; }
GetSharedFileCount()317 	static	uint32	GetSharedFileCount()			{ return (*s_numberOfShared); }
318 
319 	// Kad nodes
AddKadNode()320 	static void	AddKadNode()				{ ++s_kadNodesCur; }
RemoveKadNode()321 	static void	RemoveKadNode()				{ --s_kadNodesCur; }
GetKadNodes()322 	static uint16_t GetKadNodes()			{ return s_kadNodesCur; }
323 
324 
325 	// Other
326 	static	void	CalculateRates();
327 
AddReceivedBytes(uint32 bytes)328 	static	void	AddReceivedBytes(uint32 bytes)
329 		{
330 			if (!s_sinceFirstTransfer->IsRunning()) {
331 				s_sinceFirstTransfer->StartTimer();
332 			}
333 
334 			(*s_sessionDownload) += bytes;
335 			(*s_downloadrate) += bytes;
336 			s_totalReceived += bytes;
337 			s_statsNeedSave = true;
338 		}
339 
AddSentBytes(uint32 bytes)340 	static	void	AddSentBytes(uint32 bytes)
341 		{
342 			if (!s_sinceFirstTransfer->IsRunning()) {
343 				s_sinceFirstTransfer->StartTimer();
344 			}
345 
346 			(*s_sessionUpload) += bytes;
347 			(*s_uploadrate) += bytes;
348 			s_totalSent += bytes;
349 			s_statsNeedSave = true;
350 		}
351 
352 	static	void	AddDownloadFromSoft(uint8 SoftType, uint32 bytes);
353 	static	void	AddUploadToSoft(uint8 SoftType, uint32 bytes);
354 
355 	// EC
GetECStatTree(uint8 tree_capping_value)356 	static	CECTag*	GetECStatTree(uint8 tree_capping_value)	{ return s_statTree->CreateECTag(tree_capping_value); }
357 
SetAverageMinutes(uint8 minutes)358 	void SetAverageMinutes(uint8 minutes) { average_minutes = minutes; }
359 
360  private:
361 	std::list<HR>	listHR;
362 	typedef std::list<HR>::iterator		listPOS;
363 	typedef std::list<HR>::reverse_iterator	listRPOS;
364 
365 	/* Graph-related functions */
366 
367 	void ComputeAverages(HR **pphr, listRPOS pos, unsigned cntFilled,
368 		double sStep, const std::vector<float *> &ppf, StatsGraphType which_graph);
369 
GetPointsPerRange()370 	int GetPointsPerRange()
371 	{
372 		return (1280/2) - 80; // This used to be a calc. based on GUI width
373 	}
374 
375 	/* Graphs-related vars */
376 
377 	CPreciseRateCounter	m_graphRunningAvgDown;
378 	CPreciseRateCounter	m_graphRunningAvgUp;
379 	CPreciseRateCounter	m_graphRunningAvgKad;
380 
381 
382 	uint8 average_minutes;
383 	int	nHistRanges;
384 	int	bitsHistClockMask;
385 	int	nPointsPerRange;
386 	listPOS*	aposRecycle;
387 
388 	HR hrInit;
389 
390 	/* Rate/Average counters */
391 	static	CPreciseRateCounter*		s_upOverheadRate;
392 	static	CPreciseRateCounter*		s_downOverheadRate;
393 	static	CStatTreeItemRateCounter*	s_uploadrate;
394 	static	CStatTreeItemRateCounter*	s_downloadrate;
395 
396 	/* Tree-related functions */
397 
398 	static	void	InitStatsTree();
399 
GetTreeRoot()400 	static	CStatTreeItemBase*	GetTreeRoot()	{ return s_statTree; }
401 
402 	/* Tree-related vars */
403 
404 	// the tree
405 	static	CStatTreeItemBase*		s_statTree;
406 
407 	// Uptime
408 	static	CStatTreeItemTimer*		s_uptime;
409 
410 	// Upload
411 	static	CStatTreeItemUlDlCounter*	s_sessionUpload;
412 	static	CStatTreeItemPacketTotals*	s_totalUpOverhead;
413 	static	CStatTreeItemPackets*		s_fileReqUpOverhead;
414 	static	CStatTreeItemPackets*		s_sourceXchgUpOverhead;
415 	static	CStatTreeItemPackets*		s_serverUpOverhead;
416 	static	CStatTreeItemPackets*		s_kadUpOverhead;
417 	static	CStatTreeItemCounter*		s_cryptUpOverhead;
418 	static	CStatTreeItemNativeCounter*	s_activeUploads;
419 	static	CStatTreeItemNativeCounter*	s_waitingUploads;
420 	static	CStatTreeItemCounter*		s_totalSuccUploads;
421 	static	CStatTreeItemCounter*		s_totalFailedUploads;
422 	static	CStatTreeItemCounter*		s_totalUploadTime;
423 
424 	// Download
425 	static	CStatTreeItemUlDlCounter*	s_sessionDownload;
426 	static	CStatTreeItemPacketTotals*	s_totalDownOverhead;
427 	static	CStatTreeItemPackets*		s_fileReqDownOverhead;
428 	static	CStatTreeItemPackets*		s_sourceXchgDownOverhead;
429 	static	CStatTreeItemPackets*		s_serverDownOverhead;
430 	static	CStatTreeItemPackets*		s_kadDownOverhead;
431 	static	CStatTreeItemCounter*		s_cryptDownOverhead;
432 	static	CStatTreeItemCounter*		s_foundSources;
433 	static	CStatTreeItemNativeCounter*	s_activeDownloads;
434 
435 	// Connection
436 	static	CStatTreeItemReconnects*	s_reconnects;
437 	static	CStatTreeItemTimer*		s_sinceFirstTransfer;
438 	static	CStatTreeItemTimer*		s_sinceConnected;
439 	static	CStatTreeItemCounterMax*	s_activeConnections;
440 	static	CStatTreeItemMaxConnLimitReached* s_limitReached;
441 	static	CStatTreeItemSimple*		s_avgConnections;
442 
443 	// Clients
444 	static	CStatTreeItemHiddenCounter*	s_clients;
445 	static	CStatTreeItemCounter*		s_unknown;
446 	//static	CStatTreeItem			s_lowID;
447 	//static	CStatTreeItem			s_secIdentOnOff;
448 #ifdef __DEBUG__
449 	static	CStatTreeItemNativeCounter*	s_hasSocket;
450 #endif
451 	static	CStatTreeItemNativeCounter*	s_filtered;
452 	static	CStatTreeItemNativeCounter*	s_banned;
453 
454 	// Servers
455 	static	CStatTreeItemSimple*		s_workingServers;
456 	static	CStatTreeItemSimple*		s_failedServers;
457 	static	CStatTreeItemNativeCounter*	s_totalServers;
458 	static	CStatTreeItemNativeCounter*	s_deletedServers;
459 	static	CStatTreeItemNativeCounter*	s_filteredServers;
460 	static	CStatTreeItemSimple*		s_usersOnWorking;
461 	static	CStatTreeItemSimple*		s_filesOnWorking;
462 	static	CStatTreeItemSimple*		s_totalUsers;
463 	static	CStatTreeItemSimple*		s_totalFiles;
464 	static	CStatTreeItemSimple*		s_serverOccupation;
465 
466 	// Shared files
467 	static	CStatTreeItemCounter*		s_numberOfShared;
468 	static	CStatTreeItemCounter*		s_sizeOfShare;
469 
470 	// Kad nodes
471 	static	uint64_t	s_kadNodesTotal;
472 	static	uint16_t	s_kadNodesCur;
473 
474 	// Total sent/received bytes
475 	static	uint64_t	s_totalSent;
476 	static	uint64_t	s_totalReceived;
477 
478 	static	bool		s_statsNeedSave;
479 };
480 
481 #else /* CLIENT_GUI */
482 
483 class CECPacket;
484 class CRemoteConnect;
485 
486 enum StatDataIndex {
487 	sdUpload,
488 	sdUpOverhead,
489 	sdDownload,
490 	sdDownOverhead,
491 	sdWaitingClients,
492 	sdBannedClients,
493 	sdED2KUsers,
494 	sdKadUsers,
495 	sdED2KFiles,
496 	sdKadFiles,
497 	sdKadFirewalledUDP,
498 	sdKadIndexedSources,
499 	sdKadIndexedKeywords,
500 	sdKadIndexedNotes,
501 	sdKadIndexedLoad,
502 	sdKadIPAdress,
503 	sdKadNodes,
504 	sdBuddyStatus,
505 	sdBuddyIP,
506 	sdBuddyPort,
507 	sdKadInLanMode,
508 	sdTotalSentBytes,
509 	sdTotalReceivedBytes,
510 	sdSharedFileCount,
511 
512 	sdTotalItems
513 };
514 
515 class CStatistics {
516 	friend class CStatisticsDlg;	// to access CStatistics::GetTreeRoot()
517 
518 private:
519 	CRemoteConnect &m_conn;
520 	static CStatTreeItemBase* s_statTree;
521 	static uint64 s_start_time;
522 	static uint64 s_statData[sdTotalItems];
523 	uint8 average_minutes;
524 
525  public:
526 	CStatistics(CRemoteConnect &conn);
527 	~CStatistics();
528 
529 	static	uint64	GetUptimeMillis();
530 	static	uint64	GetUptimeSeconds();
531 
GetTotalSentBytes()532 	static	uint64	GetTotalSentBytes()			{ return s_statData[sdTotalSentBytes]; }
GetUploadRate()533 	static	double	GetUploadRate()				{ return (double)s_statData[sdUpload]; }
GetUpOverheadRate()534 	static	double	GetUpOverheadRate()			{ return (double)s_statData[sdUpOverhead]; }
535 
GetTotalReceivedBytes()536 	static	uint64	GetTotalReceivedBytes()			{ return s_statData[sdTotalReceivedBytes]; }
GetDownloadRate()537 	static	double	GetDownloadRate()			{ return (double)s_statData[sdDownload]; }
GetDownOverheadRate()538 	static	double	GetDownOverheadRate()			{ return (double)s_statData[sdDownOverhead]; }
539 
GetWaitingUserCount()540 	static	uint32	GetWaitingUserCount()			{ return s_statData[sdWaitingClients]; }
GetBannedCount()541 	static	uint32	GetBannedCount()			{ return s_statData[sdBannedClients]; }
542 
GetSharedFileCount()543 	static	uint32	GetSharedFileCount()			{ return s_statData[sdSharedFileCount]; }
544 
GetED2KUsers()545 	static	uint32	GetED2KUsers()			{ return s_statData[sdED2KUsers]; }
GetKadUsers()546 	static	uint32	GetKadUsers()			{ return s_statData[sdKadUsers]; }
GetED2KFiles()547 	static	uint32	GetED2KFiles()			{ return s_statData[sdED2KFiles]; }
GetKadFiles()548 	static	uint32	GetKadFiles()			{ return s_statData[sdKadFiles]; }
549 
IsFirewalledKadUDP()550 	static	bool	IsFirewalledKadUDP()	{ return s_statData[sdKadFirewalledUDP] != 0; }
GetKadIndexedSources()551 	static	uint32	GetKadIndexedSources()	{ return s_statData[sdKadIndexedSources]; }
GetKadIndexedKeywords()552 	static	uint32	GetKadIndexedKeywords()	{ return s_statData[sdKadIndexedKeywords]; }
GetKadIndexedNotes()553 	static	uint32	GetKadIndexedNotes()	{ return s_statData[sdKadIndexedNotes]; }
GetKadIndexedLoad()554 	static	uint32	GetKadIndexedLoad()		{ return s_statData[sdKadIndexedLoad]; }
GetKadIPAdress()555 	static	uint32	GetKadIPAdress()		{ return s_statData[sdKadIPAdress]; }
GetBuddyStatus()556 	static	uint8	GetBuddyStatus()		{ return s_statData[sdBuddyStatus]; }
GetBuddyIP()557 	static	uint32	GetBuddyIP()			{ return s_statData[sdBuddyIP]; }
GetBuddyPort()558 	static	uint32	GetBuddyPort()			{ return s_statData[sdBuddyPort]; }
IsKadRunningInLanMode()559 	static	bool	IsKadRunningInLanMode()	{ return s_statData[sdKadInLanMode] != 0; }
GetKadNodes()560 	static	uint32	GetKadNodes()			{ return s_statData[sdKadNodes]; }
561 
562 	static	void	UpdateStats(const CECPacket* stats);
563 
564 	void	UpdateStatsTree();
565 	void	RebuildStatTreeRemote(const CECTag *);
SetAverageMinutes(uint8 minutes)566 	void	SetAverageMinutes(uint8 minutes)	{ average_minutes = minutes; }
567 
568  private:
GetTreeRoot()569 	static	CStatTreeItemBase*	GetTreeRoot()		{ return s_statTree; }
570 };
571 
572 #endif /* !CLIENT_GUI / CLIENT_GUI */
573 
574 
575 /**
576  * Shortcut for CStatistics
577  */
578 typedef	CStatistics	theStats;
579 
580 #endif // STATISTICS_H
581 // File_checked_for_headers
582