1 //
2 // This file is part of the aMule Project.
3 //
4 // Copyright (c) 2003-2011 Angel Vidal ( kry@amule.org )
5 // Copyright (c) 2003-2011 aMule Team ( admin@amule.org / http://www.amule.org )
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 #include <ec/cpp/ECTag.h>		// Needed for CECTag
28 #include <ec/cpp/ECSpecialTags.h>	// Needed for special EC tag creator classes
29 
30 
31 // Since there are only constructors defined here,
32 // removing everything from non-local builds.
33 
34 #include "amule.h"
35 #include "Server.h"		// Needed for CServer
36 #include "PartFile.h"		// Needed for CPartFile
37 #include "ServerConnect.h"	// Needed for CServerConnect
38 #include "updownclient.h"	// Needed for CUpDownClient
39 #include "UploadQueue.h"	// Needed for CUploadQueue
40 #include "SharedFileList.h"
41 #include "SearchList.h"
42 #include "Friend.h"
43 
44 #include "kademlia/kademlia/Kademlia.h"
45 
46 
47 // used for webserver, amulecmd
CEC_Server_Tag(const CServer * server,EC_DETAIL_LEVEL detail_level)48 CEC_Server_Tag::CEC_Server_Tag(const CServer *server, EC_DETAIL_LEVEL detail_level) :
49 	CECTag(EC_TAG_SERVER, EC_IPv4_t(server->GetIP(), server->GetPort()))
50 {
51 	wxString tmpStr;
52 	uint32 tmpInt;
53 	uint8 tmpShort;
54 
55 	switch (detail_level) {
56 		case EC_DETAIL_INC_UPDATE:
57 			// should not get here
58 			wxFAIL;
59 			break;
60 		case EC_DETAIL_UPDATE:
61 			if ((tmpInt = server->GetPing()) != 0) {
62 				AddTag(CECTag(EC_TAG_SERVER_PING, tmpInt));
63 			}
64 			if ((tmpShort = (uint8)server->GetFailedCount()) != 0) {
65 				AddTag(CECTag(EC_TAG_SERVER_FAILED, tmpShort));
66 			}
67 			break;
68 		case EC_DETAIL_WEB:
69 		case EC_DETAIL_FULL:
70 			if ((tmpInt = server->GetPing()) != 0) {
71 				AddTag(CECTag(EC_TAG_SERVER_PING, tmpInt));
72 			}
73 			if ((tmpShort = (uint8)server->GetPreferences()) != SRV_PR_NORMAL) {
74 				AddTag(CECTag(EC_TAG_SERVER_PRIO, tmpShort));
75 			}
76 			if ((tmpShort = (uint8)server->GetFailedCount()) != 0) {
77 				AddTag(CECTag(EC_TAG_SERVER_FAILED, tmpShort));
78 			}
79 			if ((tmpShort = (server->IsStaticMember() ? 1 : 0)) != 0) {
80 				AddTag(CECTag(EC_TAG_SERVER_STATIC, tmpShort));
81 			}
82 			if (!(tmpStr = server->GetVersion()).IsEmpty()) {
83 				AddTag(CECTag(EC_TAG_SERVER_VERSION, tmpStr));
84 			}
85 			if (!(tmpStr = server->GetDescription()).IsEmpty()) {
86 				AddTag(CECTag(EC_TAG_SERVER_DESC, tmpStr));
87 			}
88 			if ((tmpInt = server->GetUsers()) != 0) {
89 				AddTag(CECTag(EC_TAG_SERVER_USERS, tmpInt));
90 			}
91 			if ((tmpInt = server->GetMaxUsers()) != 0) {
92 				AddTag(CECTag(EC_TAG_SERVER_USERS_MAX, tmpInt));
93 			}
94 			if ((tmpInt = server->GetFiles()) != 0) {
95 				AddTag(CECTag(EC_TAG_SERVER_FILES, tmpInt));
96 			}
97 		/* fall through */
98 		case EC_DETAIL_CMD:
99 			if (!(tmpStr = server->GetListName()).IsEmpty()) {
100 				AddTag(CECTag(EC_TAG_SERVER_NAME, tmpStr));
101 			}
102 	}
103 }
104 
105 // used for amulegui (EC_DETAIL_INC_UPDATE)
CEC_Server_Tag(const CServer * server,CValueMap * valuemap)106 CEC_Server_Tag::CEC_Server_Tag(const CServer *server, CValueMap *valuemap) :
107 	CECTag(EC_TAG_SERVER, server->ECID())
108 {
109 	AddTag(EC_TAG_SERVER_NAME, server->GetListName(), valuemap);
110 	AddTag(EC_TAG_SERVER_DESC, server->GetDescription(), valuemap);
111 	AddTag(EC_TAG_SERVER_VERSION, server->GetVersion(), valuemap);
112 	AddTag(EC_TAG_SERVER_IP, server->GetIP(), valuemap);
113 	AddTag(EC_TAG_SERVER_PORT, server->GetPort(), valuemap);
114 	AddTag(EC_TAG_SERVER_PING, server->GetPing(), valuemap);
115 	AddTag(EC_TAG_SERVER_PRIO, server->GetPreferences(), valuemap);
116 	AddTag(EC_TAG_SERVER_FAILED, server->GetFailedCount(), valuemap);
117 	AddTag(EC_TAG_SERVER_STATIC, server->IsStaticMember(), valuemap);
118 	AddTag(EC_TAG_SERVER_USERS, server->GetUsers(), valuemap);
119 	AddTag(EC_TAG_SERVER_USERS_MAX, server->GetMaxUsers(), valuemap);
120 	AddTag(EC_TAG_SERVER_FILES, server->GetFiles(), valuemap);
121 }
122 
123 
CEC_ConnState_Tag(EC_DETAIL_LEVEL detail_level)124 CEC_ConnState_Tag::CEC_ConnState_Tag(EC_DETAIL_LEVEL detail_level) : CECTag(EC_TAG_CONNSTATE,
125 	(uint8)(
126 			(theApp->IsConnectedED2K() ? 0x01 : 0x00)
127 			|
128 			(theApp->serverconnect->IsConnecting() ? 0x02 : 0x00)
129 			|
130 			(theApp->IsConnectedKad() ? 0x04 : 0x00)
131 			|
132 			(Kademlia::CKademlia::IsFirewalled() ? 0x08 : 0x00)
133 			|
134 			(Kademlia::CKademlia::IsRunning() ? 0x10 : 0x00)
135 		))
136 {
137 	if (theApp->IsConnectedED2K()) {
138 		if ( theApp->serverconnect->GetCurrentServer() ) {
139 			if (detail_level == EC_DETAIL_INC_UPDATE) {
140 				// Send no full server tag, just the ECID of the connected server
141 				AddTag(CECTag(EC_TAG_SERVER, theApp->serverconnect->GetCurrentServer()->ECID()));
142 			} else {
143 				AddTag(CEC_Server_Tag(theApp->serverconnect->GetCurrentServer(), detail_level));
144 			}
145 		}
146 		AddTag(CECTag(EC_TAG_ED2K_ID, theApp->GetED2KID()));
147 	} else if (theApp->serverconnect->IsConnecting()) {
148 		AddTag(CECTag(EC_TAG_ED2K_ID, 0xffffffff));
149 	}
150 
151 	AddTag(CECTag(EC_TAG_CLIENT_ID, theApp->GetID()));
152 
153 	if (Kademlia::CKademlia::IsRunning()) {
154 		AddTag(CECTag(EC_TAG_KAD_ID, Kademlia::CKademlia::GetKadID()));
155 	}
156 }
157 
CEC_PartFile_Tag(const CPartFile * file,EC_DETAIL_LEVEL detail_level,CValueMap * valuemap)158 CEC_PartFile_Tag::CEC_PartFile_Tag(const CPartFile *file, EC_DETAIL_LEVEL detail_level, CValueMap *valuemap)
159 :
160 CEC_SharedFile_Tag(file, detail_level, valuemap, EC_TAG_PARTFILE)
161 {
162 	AddTag(EC_TAG_PARTFILE_STATUS, file->GetStatus(), valuemap);
163 	AddTag(EC_TAG_PARTFILE_STOPPED, file->IsStopped(), valuemap);
164 
165 	AddTag(EC_TAG_PARTFILE_SOURCE_COUNT, file->GetSourceCount(), valuemap);
166 	AddTag(EC_TAG_PARTFILE_SOURCE_COUNT_NOT_CURRENT, file->GetNotCurrentSourcesCount(), valuemap);
167 	AddTag(EC_TAG_PARTFILE_SOURCE_COUNT_XFER, file->GetTransferingSrcCount(), valuemap);
168 	AddTag(EC_TAG_PARTFILE_SOURCE_COUNT_A4AF, file->GetSrcA4AFCount(), valuemap);
169 
170 	if ( (file->GetTransferingSrcCount() > 0) || (detail_level != EC_DETAIL_UPDATE) || valuemap) {
171 
172 		AddTag(EC_TAG_PARTFILE_SIZE_XFER, file->GetTransferred(), valuemap);
173 		AddTag(EC_TAG_PARTFILE_SIZE_DONE, file->GetCompletedSize(), valuemap);
174 		AddTag(EC_TAG_PARTFILE_SPEED, (uint64_t)(file->GetKBpsDown()*1024), valuemap);
175 	}
176 
177 	AddTag(EC_TAG_PARTFILE_PRIO, (file->IsAutoDownPriority() ?
178 		file->GetDownPriority() + 10 : file->GetDownPriority()), valuemap);
179 
180 	AddTag(EC_TAG_PARTFILE_CAT, file->GetCategory(), valuemap);
181 	AddTag(EC_TAG_PARTFILE_LAST_SEEN_COMP, file->lastseencomplete, valuemap);
182 	AddTag(EC_TAG_PARTFILE_LAST_RECV, file->GetLastChangeDatetime(), valuemap);
183 	AddTag(EC_TAG_PARTFILE_DOWNLOAD_ACTIVE, file->GetDlActiveTime(), valuemap);
184 	AddTag(EC_TAG_PARTFILE_AVAILABLE_PARTS, file->GetAvailablePartCount(), valuemap);
185 	AddTag(EC_TAG_PARTFILE_HASHED_PART_COUNT, file->GetHashingProgress(), valuemap);
186 
187 	AddTag(EC_TAG_PARTFILE_LOST_CORRUPTION, file->GetLostDueToCorruption(), valuemap);
188 	AddTag(EC_TAG_PARTFILE_GAINED_COMPRESSION, file->GetGainDueToCompression(), valuemap);
189 	AddTag(EC_TAG_PARTFILE_SAVED_ICH, file->TotalPacketsSavedDueToICH(), valuemap);
190 	AddTag(EC_TAG_PARTFILE_A4AFAUTO, file->IsA4AFAuto(), valuemap);
191 
192 	// Tag for comments
193 	CECEmptyTag sc(EC_TAG_PARTFILE_COMMENTS);
194 
195 	FileRatingList list;
196 	file->GetRatingAndComments(list);
197 	for (FileRatingList::const_iterator it = list.begin(); it != list.end(); ++it) {
198 		// Tag children are evaluated by index, not by name
199 		sc.AddTag(CECTag(EC_TAG_PARTFILE_COMMENTS, it->UserName));
200 		sc.AddTag(CECTag(EC_TAG_PARTFILE_COMMENTS, it->FileName));
201 		sc.AddTag(CECTag(EC_TAG_PARTFILE_COMMENTS, (uint64) it->Rating));
202 		sc.AddTag(CECTag(EC_TAG_PARTFILE_COMMENTS, it->Comment));
203 	}
204 	AddTag(sc, valuemap);
205 
206 	if (detail_level == EC_DETAIL_UPDATE) {
207 		return;
208 	}
209 
210 	AddTag(EC_TAG_PARTFILE_PARTMETID, file->GetPartMetNumber(), valuemap);
211 
212 	// A4AF sources
213 	CECEmptyTag a4afTag(EC_TAG_PARTFILE_A4AF_SOURCES);
214 	const CKnownFile::SourceSet& a4afSources = file->GetA4AFList();
215 	for (CKnownFile::SourceSet::const_iterator it = a4afSources.begin(); it != a4afSources.end(); ++it) {
216 		a4afTag.AddTag(CECTag(EC_TAG_ECID, it->ECID()));
217 	}
218 	AddTag(a4afTag, valuemap);
219 }
220 
CEC_SharedFile_Tag(const CKnownFile * file,EC_DETAIL_LEVEL detail_level,CValueMap * valuemap,ec_tagname_t name)221 CEC_SharedFile_Tag::CEC_SharedFile_Tag(const CKnownFile *file, EC_DETAIL_LEVEL detail_level,
222 									   CValueMap *valuemap, ec_tagname_t name)
223 : CECTag(name, file->ECID())
224 {
225 	AddTag(EC_TAG_KNOWNFILE_REQ_COUNT, file->statistic.GetRequests(), valuemap);
226 	AddTag(EC_TAG_KNOWNFILE_REQ_COUNT_ALL, file->statistic.GetAllTimeRequests(), valuemap);
227 
228 	AddTag(EC_TAG_KNOWNFILE_ACCEPT_COUNT, file->statistic.GetAccepts(), valuemap);
229 	AddTag(EC_TAG_KNOWNFILE_ACCEPT_COUNT_ALL, file->statistic.GetAllTimeAccepts(), valuemap);
230 
231 	AddTag(EC_TAG_KNOWNFILE_XFERRED, file->statistic.GetTransferred(), valuemap);
232 	AddTag(EC_TAG_KNOWNFILE_XFERRED_ALL, file->statistic.GetAllTimeTransferred(), valuemap);
233 	AddTag(EC_TAG_KNOWNFILE_AICH_MASTERHASH, file->GetAICHMasterHash(), valuemap);
234 
235 	AddTag(EC_TAG_KNOWNFILE_PRIO,
236 		(uint8)(file->IsAutoUpPriority() ? file->GetUpPriority() + 10 : file->GetUpPriority()), valuemap);
237 
238 	AddTag(EC_TAG_KNOWNFILE_COMPLETE_SOURCES_LOW, file->m_nCompleteSourcesCountLo, valuemap);
239 	AddTag(EC_TAG_KNOWNFILE_COMPLETE_SOURCES_HIGH, file->m_nCompleteSourcesCountHi, valuemap);
240 	AddTag(EC_TAG_KNOWNFILE_COMPLETE_SOURCES, file->m_nCompleteSourcesCount, valuemap);
241 
242 	AddTag(EC_TAG_KNOWNFILE_ON_QUEUE, file->GetQueuedCount(), valuemap);
243 
244 	if (detail_level == EC_DETAIL_UPDATE) {
245 			return;
246 	}
247 
248 	AddTag(EC_TAG_PARTFILE_NAME,file->GetFileName().GetPrintable(), valuemap);
249 	AddTag(EC_TAG_PARTFILE_HASH, file->GetFileHash(), valuemap);
250 	AddTag(EC_TAG_KNOWNFILE_FILENAME,
251 		file->IsPartFile()	? wxString(CFormat(wxT("%s")) % static_cast<const CPartFile*>(file)->GetPartMetFileName().RemoveExt())
252 							: file->GetFilePath().GetPrintable(),
253 		valuemap);
254 
255 	AddTag(EC_TAG_PARTFILE_SIZE_FULL, file->GetFileSize(), valuemap);
256 
257 	AddTag(EC_TAG_PARTFILE_ED2K_LINK,
258 			theApp->CreateED2kLink(file, (theApp->IsConnectedED2K() && !theApp->serverconnect->IsLowID())), valuemap);
259 
260 	AddTag(EC_TAG_KNOWNFILE_COMMENT, file->GetFileComment(), valuemap);
261 	AddTag(EC_TAG_KNOWNFILE_RATING, file->GetFileRating(), valuemap);
262 }
263 
CEC_UpDownClient_Tag(const CUpDownClient * client,EC_DETAIL_LEVEL detail_level,CValueMap * valuemap)264 CEC_UpDownClient_Tag::CEC_UpDownClient_Tag(const CUpDownClient* client, EC_DETAIL_LEVEL detail_level, CValueMap *valuemap) :
265 	CECTag(EC_TAG_CLIENT, client->ECID())
266 {
267 	// General
268 	AddTag(CECTag(EC_TAG_CLIENT_NAME, client->GetUserName()), valuemap);
269 	AddTag(CECTag(EC_TAG_CLIENT_HASH, client->GetUserHash()), valuemap);
270 	AddTag(CECTag(EC_TAG_CLIENT_USER_ID, client->GetUserIDHybrid()), valuemap);
271 	AddTag(CECTag(EC_TAG_CLIENT_SCORE, client->GetScore()), valuemap);
272 	AddTag(CECTag(EC_TAG_CLIENT_SOFTWARE, client->GetClientSoft()), valuemap);
273 	AddTag(CECTag(EC_TAG_CLIENT_SOFT_VER_STR, client->GetSoftVerStr()), valuemap);
274 	AddTag(CECTag(EC_TAG_CLIENT_USER_IP, client->GetIP()), valuemap);
275 	AddTag(CECTag(EC_TAG_CLIENT_USER_PORT, client->GetUserPort()), valuemap);
276 	AddTag(CECTag(EC_TAG_CLIENT_FROM, (uint64)client->GetSourceFrom()), valuemap);
277 	AddTag(CECTag(EC_TAG_CLIENT_SERVER_IP, client->GetServerIP()), valuemap);
278 	AddTag(CECTag(EC_TAG_CLIENT_SERVER_PORT, client->GetServerPort()), valuemap);
279 	AddTag(CECTag(EC_TAG_CLIENT_SERVER_NAME, client->GetServerName()), valuemap);
280 
281 	// Transfers to Client
282 	AddTag(CECTag(EC_TAG_CLIENT_UP_SPEED, client->GetUploadDatarate()), valuemap);
283 	if (client->GetDownloadState() == DS_DOWNLOADING || valuemap) {
284 		AddTag(CECTag(EC_TAG_CLIENT_DOWN_SPEED, (double)(client->GetKBpsDown())), valuemap);
285 	}
286 	AddTag(CECTag(EC_TAG_CLIENT_UPLOAD_SESSION, client->GetSessionUp()), valuemap);
287 	AddTag(CECTag(EC_TAG_PARTFILE_SIZE_XFER, client->GetTransferredDown()), valuemap);
288 	AddTag(CECTag(EC_TAG_CLIENT_UPLOAD_TOTAL, client->GetUploadedTotal()), valuemap);
289 	AddTag(CECTag(EC_TAG_CLIENT_DOWNLOAD_TOTAL, client->GetDownloadedTotal()), valuemap);
290 
291 	AddTag(CECTag(EC_TAG_CLIENT_UPLOAD_STATE, client->GetUploadState()), valuemap);
292 	AddTag(CECTag(EC_TAG_CLIENT_DOWNLOAD_STATE, client->GetDownloadState()), valuemap);
293 	AddTag(CECTag(EC_TAG_CLIENT_IDENT_STATE, (uint64) client->GetCurrentIdentState()), valuemap);
294 	AddTag(CECTag(EC_TAG_CLIENT_EXT_PROTOCOL, client->ExtProtocolAvailable()), valuemap);
295 	// These are not needed atm. Keep them for now, maybe columns get reintroduced in client view.
296 	//AddTag(CECTag(EC_TAG_CLIENT_WAIT_TIME, client->GetWaitTime()), valuemap);
297 	//AddTag(CECTag(EC_TAG_CLIENT_XFER_TIME, client->GetUpStartTimeDelay()), valuemap);
298 	//AddTag(CECTag(EC_TAG_CLIENT_QUEUE_TIME, (uint64)(::GetTickCount() - client->GetWaitStartTime())), valuemap);
299 	//AddTag(CECTag(EC_TAG_CLIENT_LAST_TIME, (uint64)(::GetTickCount() - client->GetLastUpRequest())), valuemap);
300 	AddTag(CECTag(EC_TAG_CLIENT_WAITING_POSITION, client->GetUploadQueueWaitingPosition()), valuemap);
301 	AddTag(CECTag(EC_TAG_CLIENT_REMOTE_QUEUE_RANK, client->IsRemoteQueueFull() ? (uint16)0xffff : client->GetRemoteQueueRank()), valuemap);
302 	AddTag(CECTag(EC_TAG_CLIENT_OLD_REMOTE_QUEUE_RANK, client->GetOldRemoteQueueRank()), valuemap);
303 	AddTag(CECTag(EC_TAG_CLIENT_OBFUSCATION_STATUS, client->GetObfuscationStatus()), valuemap);
304 	AddTag(CECTag(EC_TAG_CLIENT_KAD_PORT, client->GetKadPort()), valuemap);
305 	AddTag(CECTag(EC_TAG_CLIENT_FRIEND_SLOT, client->GetFriendSlot()), valuemap);
306 
307 	if (detail_level == EC_DETAIL_UPDATE) {
308 		return;
309 	}
310 	const CKnownFile* file = client->GetUploadFile();
311 	if (file) {
312 		AddTag(CECTag(EC_TAG_PARTFILE_NAME, file->GetFileName().GetPrintable()), valuemap);
313 		AddTag(CECTag(EC_TAG_CLIENT_UPLOAD_FILE, file->ECID()), valuemap);
314 	} else {
315 		AddTag(CECIntTag(EC_TAG_CLIENT_UPLOAD_FILE, 0), valuemap);
316 	}
317 	const CPartFile* pfile = client->GetRequestFile();
318 	AddTag(CECTag(EC_TAG_CLIENT_REQUEST_FILE, pfile ? pfile->ECID() : 0), valuemap);
319 	AddTag(CECTag(EC_TAG_CLIENT_REMOTE_FILENAME, client->GetClientFilename()), valuemap);
320 
321 	if (detail_level != EC_DETAIL_INC_UPDATE) {
322 		return;
323 	}
324 	AddTag(CECTag(EC_TAG_CLIENT_DISABLE_VIEW_SHARED, client->HasDisabledSharedFiles()), valuemap);
325 	AddTag(CECTag(EC_TAG_CLIENT_VERSION, client->GetVersion()), valuemap);
326 	AddTag(CECTag(EC_TAG_CLIENT_MOD_VERSION, client->GetClientModString()), valuemap);
327 	AddTag(CECTag(EC_TAG_CLIENT_OS_INFO, client->GetClientOSInfo()), valuemap);
328 	AddTag(CECTag(EC_TAG_CLIENT_AVAILABLE_PARTS, client->GetAvailablePartCount()), valuemap);
329 	if (pfile) {
330 		const BitVector & partStatus = client->GetPartStatus();
331 		if (partStatus.size() == pfile->GetPartCount()) {
332 			if (partStatus.AllTrue()) {
333 				// send just an empty tag for a full source
334 				AddTag(CECEmptyTag(EC_TAG_CLIENT_PART_STATUS), valuemap);
335 			} else {
336 				AddTag(CECTag(EC_TAG_CLIENT_PART_STATUS, partStatus.SizeBuffer(), partStatus.GetBuffer()), valuemap);
337 			}
338 		}
339 		AddTag(CECTag(EC_TAG_CLIENT_NEXT_REQUESTED_PART, client->GetNextRequestedPart()), valuemap);
340 		AddTag(CECTag(EC_TAG_CLIENT_LAST_DOWNLOADING_PART, client->GetLastDownloadingPart()), valuemap);
341 	}
342 	if (file) {
343 		const BitVector & upPartStatus = client->GetUpPartStatus();
344 		if (upPartStatus.size() == file->GetPartCount()) {
345 			AddTag(CECTag(EC_TAG_CLIENT_UPLOAD_PART_STATUS, upPartStatus.SizeBuffer(), upPartStatus.GetBuffer()), valuemap);
346 		}
347 	}
348 }
349 
350 //
351 // Search reply
352 //
CEC_SearchFile_Tag(const CSearchFile * file,EC_DETAIL_LEVEL detail_level,CValueMap * valuemap)353 CEC_SearchFile_Tag::CEC_SearchFile_Tag(const CSearchFile *file, EC_DETAIL_LEVEL detail_level, CValueMap *valuemap) : CECTag(EC_TAG_SEARCHFILE, file->ECID())
354 {
355 	AddTag(CECTag(EC_TAG_PARTFILE_SOURCE_COUNT, file->GetSourceCount()), valuemap);
356 	AddTag(CECTag(EC_TAG_PARTFILE_SOURCE_COUNT_XFER, file->GetCompleteSourceCount()), valuemap);
357 	AddTag(CECTag(EC_TAG_PARTFILE_STATUS, (uint32)file->GetDownloadStatus()), valuemap);
358 
359 	if (detail_level == EC_DETAIL_UPDATE) {
360 			return;
361 	}
362 
363 	AddTag(CECTag(EC_TAG_PARTFILE_NAME, file->GetFileName().GetPrintable()), valuemap);
364 	AddTag(CECTag(EC_TAG_PARTFILE_SIZE_FULL, file->GetFileSize()), valuemap);
365 	AddTag(EC_TAG_PARTFILE_HASH, file->GetFileHash(), valuemap);
366 	if (file->GetParent()) {
367 		AddTag(EC_TAG_SEARCH_PARENT, file->GetParent()->ECID(), valuemap);
368 	}
369 }
370 
371 //
372 // Friend
373 //
CEC_Friend_Tag(const CFriend * Friend,CValueMap * valuemap)374 CEC_Friend_Tag::CEC_Friend_Tag(const CFriend* Friend, CValueMap* valuemap) : CECTag(EC_TAG_FRIEND, Friend->ECID())
375 {
376 	AddTag(EC_TAG_FRIEND_NAME,	Friend->GetName(), valuemap);
377 	AddTag(EC_TAG_FRIEND_HASH,	Friend->GetUserHash(), valuemap);
378 	AddTag(EC_TAG_FRIEND_IP,	Friend->GetIP(), valuemap);
379 	AddTag(EC_TAG_FRIEND_PORT,	Friend->GetPort(), valuemap);
380 	const CClientRef& linkedClient = Friend->GetLinkedClient();
381 	AddTag(EC_TAG_FRIEND_CLIENT, linkedClient.IsLinked() ? linkedClient.ECID() : 0, valuemap);
382 }
383 
384 // File_checked_for_headers
385