2 // This file is part of the aMule Project.
4 // Copyright (c) 2008 Dévai Tamás ( gonosztopi@amule.org )
5 // Copyright (c) 2008 aMule Team ( admin@amule.org / http://www.amule.org )
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
27 #include <wx/datetime.h>
28 #include <tags/FileTags.h>
29 #include <tags/ServerTags.h>
30 #include <tags/TagTypes.h>
31 #include <protocol/ed2k/Client2Server/UDP.h>
32 #include "../../OtherFunctions.h"
33 #include "../../Friend.h" // Needed for FF_NAME
34 #include ".././KnownFile.h" // Needed for PR_*
40 SDMODE g_stringDecodeMode
;
42 wxString
MakePrintableString(const wxString
& s
)
46 for (unsigned i
= 0; i
< str
.length(); i
++) {
49 if (GetStringsMode() != SD_NONE
) {
51 // check for utf-8 -- wx conversion sucks
52 char* buf
= new char[str
.length() + 1];
53 for (unsigned i
= 0; i
< str
.length(); i
++) {
56 buf
[str
.length()] = '\0';
57 wxString tmp
= UTF82unicode(buf
);
59 if (tmp
.empty() || tmp
== str
) {
64 for (unsigned i
= 0; i
< str
.length(); i
++) {
70 wxString retval
= wxT("\"");
72 if (GetStringsMode() == SD_DISPLAY
) {
74 } else if (GetStringsMode() == SD_UTF8
) {
75 str
= wxString::From8BitData((const char *)str
.utf8_str());
79 if (GetStringsMode() != SD_DISPLAY
) {
80 for (unsigned i
= 0; i
< str
.length(); i
++) {
81 if (GetStringsMode() == SD_NONE
? ((unsigned)str
[i
] >= ' ' && (unsigned)str
[i
] <= 0x7f) : std::isprint(str
[i
])) {
83 } else if (c
<= 0xff) {
84 retval
+= wxString::Format(wxT("\\x%02x"), str
[i
]);
86 retval
+= wxString::Format(wxT("\\u%04x"), str
[i
]);
95 static inline wxString
Uint32toStringIP(uint32_t ip
)
97 return wxString::Format(wxT("%u.%u.%u.%u"), (uint8_t)ip
, (uint8_t)(ip
>>8), (uint8_t)(ip
>>16), (uint8_t)(ip
>>24));
100 std::ostream
& operator<<(std::ostream
& x
, const CTimeT
& y
)
102 if ((time_t)y
!= 0) {
103 wxDateTime
dt((time_t)y
);
104 return x
<< (time_t)y
<< " (" << dt
.Format(wxDefaultDateTimeFormat
, wxDateTime::UTC
) << " UTC)";
106 return x
<< "0 (Never)";
110 std::ostream
& operator<<(std::ostream
& x
, const CKadIP
& ip
)
112 return x
<< hex(ip
) << " (" << Uint32toStringIP(wxUINT32_SWAP_ALWAYS(ip
)) << ')';
115 std::ostream
& operator<<(std::ostream
& x
, const CeD2kIP
& ip
)
117 return x
<< hex(ip
) << " (" << Uint32toStringIP(ip
) << ')';
120 static inline wxString
TagNameString(const wxString
& name
)
122 if (name
.length() == 1) {
123 return wxString::Format(wxT("\"\\x%02x\""), name
[0]);
124 } else if (name
.length() > 1) {
125 if (name
[0] == FT_GAPSTART
|| name
[0] == FT_GAPEND
) {
126 return wxString::Format(wxT("\"\\x%02x"), name
[0]) + name
.substr(1) + wxT("\"");
129 return wxT("\"") + name
+ wxT("\"");
132 #define TEST_VALUE(VALUE) if (value == VALUE) return #VALUE; else
134 const char* DecodeTagNameID(uint8_t value
)
136 TEST_VALUE(FT_FILENAME
)
137 TEST_VALUE(FT_FILESIZE
)
138 TEST_VALUE(FT_FILESIZE_HI
)
139 TEST_VALUE(FT_FILETYPE
)
140 TEST_VALUE(FT_FILEFORMAT
)
141 TEST_VALUE(FT_LASTSEENCOMPLETE
)
142 TEST_VALUE(FT_TRANSFERRED
)
143 TEST_VALUE(FT_GAPSTART
)
144 TEST_VALUE(FT_GAPEND
)
145 TEST_VALUE(FT_PARTFILENAME
)
146 TEST_VALUE(FT_OLDDLPRIORITY
)
147 TEST_VALUE(FT_STATUS
)
148 TEST_VALUE(FT_SOURCES
)
149 TEST_VALUE(FT_PERMISSIONS
)
150 TEST_VALUE(FT_OLDULPRIORITY
)
151 TEST_VALUE(FT_DLPRIORITY
)
152 TEST_VALUE(FT_ULPRIORITY
)
153 TEST_VALUE(FT_KADLASTPUBLISHKEY
)
154 TEST_VALUE(FT_KADLASTPUBLISHSRC
)
156 TEST_VALUE(FT_DL_ACTIVE_TIME
)
157 TEST_VALUE(FT_CORRUPTEDPARTS
)
158 TEST_VALUE(FT_DL_PREVIEW
)
159 TEST_VALUE(FT_KADLASTPUBLISHNOTES
)
160 TEST_VALUE(FT_AICH_HASH
)
161 TEST_VALUE(FT_COMPLETE_SOURCES
)
162 TEST_VALUE(FT_PUBLISHINFO
)
163 TEST_VALUE(FT_ATTRANSFERRED
)
164 TEST_VALUE(FT_ATREQUESTED
)
165 TEST_VALUE(FT_ATACCEPTED
)
166 TEST_VALUE(FT_CATEGORY
)
167 TEST_VALUE(FT_ATTRANSFERREDHI
)
168 TEST_VALUE(FT_MEDIA_ARTIST
)
169 TEST_VALUE(FT_MEDIA_ALBUM
)
170 TEST_VALUE(FT_MEDIA_TITLE
)
171 TEST_VALUE(FT_MEDIA_LENGTH
)
172 TEST_VALUE(FT_MEDIA_BITRATE
)
173 TEST_VALUE(FT_MEDIA_CODEC
)
174 TEST_VALUE(FT_FILERATING
)
178 const char* DecodeTagName(const wxString
& value
)
180 TEST_VALUE(TAG_FILENAME
)
181 TEST_VALUE(TAG_FILESIZE
)
182 TEST_VALUE(TAG_FILESIZE_HI
)
183 TEST_VALUE(TAG_FILETYPE
)
184 TEST_VALUE(TAG_FILEFORMAT
)
185 TEST_VALUE(TAG_COLLECTION
)
186 TEST_VALUE(TAG_PART_PATH
)
187 TEST_VALUE(TAG_PART_HASH
)
188 TEST_VALUE(TAG_COPIED
)
189 TEST_VALUE(TAG_GAP_START
)
190 TEST_VALUE(TAG_GAP_END
)
191 TEST_VALUE(TAG_DESCRIPTION
)
194 TEST_VALUE(TAG_PREFERENCE
)
196 TEST_VALUE(TAG_IP_ADDRESS
)
197 TEST_VALUE(TAG_VERSION
)
198 TEST_VALUE(TAG_TEMPFILE
)
199 TEST_VALUE(TAG_PRIORITY
)
200 TEST_VALUE(TAG_STATUS
)
201 TEST_VALUE(TAG_SOURCES
)
202 TEST_VALUE(TAG_AVAILABILITY
)
203 TEST_VALUE(TAG_PERMISSIONS
)
204 TEST_VALUE(TAG_QTIME
)
205 TEST_VALUE(TAG_PARTS
)
206 TEST_VALUE(TAG_PUBLISHINFO
)
207 TEST_VALUE(TAG_MEDIA_ARTIST
)
208 TEST_VALUE(TAG_MEDIA_ALBUM
)
209 TEST_VALUE(TAG_MEDIA_TITLE
)
210 TEST_VALUE(TAG_MEDIA_LENGTH
)
211 TEST_VALUE(TAG_MEDIA_BITRATE
)
212 TEST_VALUE(TAG_MEDIA_CODEC
)
213 TEST_VALUE(TAG_ENCRYPTION
)
214 TEST_VALUE(TAG_FILERATING
)
215 TEST_VALUE(TAG_BUDDYHASH
)
216 TEST_VALUE(TAG_CLIENTLOWID
)
217 TEST_VALUE(TAG_SERVERPORT
)
218 TEST_VALUE(TAG_SERVERIP
)
219 TEST_VALUE(TAG_SOURCEUPORT
)
220 TEST_VALUE(TAG_SOURCEPORT
)
221 TEST_VALUE(TAG_SOURCEIP
)
222 TEST_VALUE(TAG_SOURCETYPE
)
226 const char* DecodeTagType(uint8_t value
)
228 TEST_VALUE(TAGTYPE_HASH16
)
229 TEST_VALUE(TAGTYPE_STRING
)
230 TEST_VALUE(TAGTYPE_UINT32
)
231 TEST_VALUE(TAGTYPE_FLOAT32
)
232 TEST_VALUE(TAGTYPE_BOOL
)
233 TEST_VALUE(TAGTYPE_BOOLARRAY
)
234 TEST_VALUE(TAGTYPE_BLOB
)
235 TEST_VALUE(TAGTYPE_UINT16
)
236 TEST_VALUE(TAGTYPE_UINT8
)
237 TEST_VALUE(TAGTYPE_BSOB
)
238 TEST_VALUE(TAGTYPE_UINT64
)
239 TEST_VALUE(TAGTYPE_STR1
)
240 TEST_VALUE(TAGTYPE_STR2
)
241 TEST_VALUE(TAGTYPE_STR3
)
242 TEST_VALUE(TAGTYPE_STR4
)
243 TEST_VALUE(TAGTYPE_STR5
)
244 TEST_VALUE(TAGTYPE_STR6
)
245 TEST_VALUE(TAGTYPE_STR7
)
246 TEST_VALUE(TAGTYPE_STR8
)
247 TEST_VALUE(TAGTYPE_STR9
)
248 TEST_VALUE(TAGTYPE_STR10
)
249 TEST_VALUE(TAGTYPE_STR11
)
250 TEST_VALUE(TAGTYPE_STR12
)
251 TEST_VALUE(TAGTYPE_STR13
)
252 TEST_VALUE(TAGTYPE_STR14
)
253 TEST_VALUE(TAGTYPE_STR15
)
254 TEST_VALUE(TAGTYPE_STR16
)
255 TEST_VALUE(TAGTYPE_STR17
)
256 TEST_VALUE(TAGTYPE_STR18
)
257 TEST_VALUE(TAGTYPE_STR19
)
258 TEST_VALUE(TAGTYPE_STR20
)
259 TEST_VALUE(TAGTYPE_STR21
)
260 TEST_VALUE(TAGTYPE_STR22
)
264 const char* DecodeServerTagNameID(uint8_t value
)
266 TEST_VALUE(ST_SERVERNAME
)
267 TEST_VALUE(ST_DESCRIPTION
)
270 TEST_VALUE(ST_PREFERENCE
)
272 TEST_VALUE(ST_LASTPING_DEPRECATED
)
273 TEST_VALUE(ST_MAXUSERS
)
274 TEST_VALUE(ST_SOFTFILES
)
275 TEST_VALUE(ST_HARDFILES
)
276 TEST_VALUE(ST_LASTPING
)
277 TEST_VALUE(ST_VERSION
)
278 TEST_VALUE(ST_UDPFLAGS
)
279 TEST_VALUE(ST_AUXPORTSLIST
)
280 TEST_VALUE(ST_LOWIDUSERS
)
281 TEST_VALUE(ST_UDPKEY
)
282 TEST_VALUE(ST_UDPKEYIP
)
283 TEST_VALUE(ST_TCPPORTOBFUSCATION
)
284 TEST_VALUE(ST_UDPPORTOBFUSCATION
)
288 const char* DecodeFriendTagNameID(uint8_t value
)
294 typedef std::map
<uint32_t, const char*> FlagMap
;
299 void AddFlag(uint32_t bit
, const char* name
)
304 wxString
DecodeFlags(uint32_t flags
)
306 uint32_t cur_flag
= 1;
310 if (!result
.empty()) {
311 result
+= wxT(" | ");
313 FlagMap::const_iterator it
= m_flags
.find(cur_flag
);
314 if (it
!= m_flags
.end()) {
315 result
+= wxString::FromAscii(it
->second
);
317 result
+= wxString::Format(wxT("%#x"), cur_flag
);
330 #define ADD_DECODER_FLAG(decoder, FLAG) decoder.AddFlag(FLAG, #FLAG)
332 std::ostream
& operator<<(std::ostream
& out
, const CTag
& tag
)
335 if (tag
.GetName().empty()) {
336 out
<< hex(tag
.GetNameID()) << ' ' << DecodeTagNameID(tag
.GetNameID());
338 out
<< TagNameString(tag
.GetName()) << ' ';
339 bool name_decoded
= false;
340 if (tag
.IsInt() && tag
.GetName().length() > 1) {
341 wxCharBuffer ascii_name
= tag
.GetName().ToAscii();
342 char gap_mark
= ascii_name
? ascii_name
[(size_t)0] : 0;
343 if (gap_mark
== FT_GAPSTART
|| gap_mark
== FT_GAPEND
) {
344 unsigned long gapkey
;
345 if (tag
.GetName().Mid(1).ToULong(&gapkey
)) {
346 out
<< DecodeTagNameID(gap_mark
) << wxString::Format(wxT("[%lu]"), gapkey
);
352 out
<< DecodeTagName(tag
.GetName());
355 out
<< ", " << (unsigned)tag
.GetType() << ' ' << DecodeTagType(tag
.GetType()) << ", ";
357 if (tag
.GetName() == TAG_SOURCEIP
) {
358 out
<< CKadIP(tag
.GetInt());
359 } else if (tag
.GetName() == TAG_SERVERIP
) {
360 out
<< CeD2kIP(tag
.GetInt());
361 } else if (tag
.GetName() == TAG_ENCRYPTION
) {
362 uint8_t enc
= tag
.GetInt();
365 CFlagDecoder decoder
;
366 decoder
.AddFlag(0x01, "CryptSupported");
367 decoder
.AddFlag(0x02, "CryptRequested");
368 decoder
.AddFlag(0x04, "CryptRequired");
369 decoder
.AddFlag(0x08, "SupportsDirectCallback");
370 out
<< " (" << decoder
.DecodeFlags(enc
) << ')';
372 } else if (tag
.GetNameID() == FT_LASTSEENCOMPLETE
373 || tag
.GetNameID() == FT_KADLASTPUBLISHSRC
374 || tag
.GetNameID() == FT_KADLASTPUBLISHNOTES
375 || tag
.GetNameID() == FT_KADLASTPUBLISHKEY
377 out
<< CTimeT(tag
.GetInt());
378 } else if (tag
.GetName() == TAG_FILESIZE
379 || tag
.GetNameID() == FT_FILESIZE
380 || tag
.GetNameID() == FT_TRANSFERRED
381 || tag
.GetNameID() == FT_ATTRANSFERRED
383 out
<< tag
.GetInt() << " (" << CastItoXBytes(tag
.GetInt()) << ')';
384 } else if (tag
.GetNameID() == FT_ULPRIORITY
385 || tag
.GetNameID() == FT_DLPRIORITY
386 || tag
.GetNameID() == FT_OLDULPRIORITY
387 || tag
.GetNameID() == FT_OLDDLPRIORITY
389 out
<< tag
.GetInt() << ' ';
390 switch (tag
.GetInt()) {
391 case PR_VERYLOW
: out
<< "PR_VERYLOW"; break;
392 case PR_LOW
: out
<< "PR_LOW"; break;
393 case PR_NORMAL
: out
<< "PR_NORMAL"; break;
394 case PR_HIGH
: out
<< "PR_HIGH"; break;
395 case PR_VERYHIGH
: out
<< "PR_VERYHIGH"; break;
396 case PR_AUTO
: out
<< "PR_AUTO"; break;
397 case PR_POWERSHARE
: out
<< "PR_POWERSHARE"; break;
402 } else if (tag
.IsStr()) {
403 out
<< MakePrintableString(tag
.GetStr());
404 } else if (tag
.IsFloat()) {
405 out
<< tag
.GetFloat();
406 } else if (tag
.IsHash()) {
407 out
<< tag
.GetHash();
408 } else if (tag
.IsBlob()) {
409 out
<< wxString::Format(wxT("(size = %u)"), tag
.GetBlobSize());
410 } else if (tag
.IsBsob()) {
411 out
<< wxString::Format(wxT("(size = %u)"), tag
.GetBsobSize());
419 std::ostream
& operator<<(std::ostream
& out
, const CServerTag
& tag
)
422 if (tag
.GetName().empty()) {
423 out
<< hex(tag
.GetNameID()) << ' ' << DecodeServerTagNameID(tag
.GetNameID());
425 out
<< TagNameString(tag
.GetName());
427 out
<< ", " << (unsigned)tag
.GetType() << ' ' << DecodeTagType(tag
.GetType()) << ", ";
429 if (tag
.GetNameID() == ST_DYNIP
|| tag
.GetNameID() == ST_UDPKEYIP
) {
430 out
<< CeD2kIP(tag
.GetInt());
431 } else if (tag
.GetNameID() == ST_UDPKEY
) {
432 out
<< hex((uint32_t)tag
.GetInt());
433 } else if (tag
.GetNameID() == ST_UDPFLAGS
) {
434 uint32_t flags
= tag
.GetInt();
437 CFlagDecoder decoder
;
438 ADD_DECODER_FLAG(decoder
, SRV_UDPFLG_EXT_GETSOURCES
);
439 ADD_DECODER_FLAG(decoder
, SRV_UDPFLG_EXT_GETFILES
);
440 ADD_DECODER_FLAG(decoder
, SRV_UDPFLG_NEWTAGS
);
441 ADD_DECODER_FLAG(decoder
, SRV_UDPFLG_UNICODE
);
442 ADD_DECODER_FLAG(decoder
, SRV_UDPFLG_EXT_GETSOURCES2
);
443 ADD_DECODER_FLAG(decoder
, SRV_UDPFLG_LARGEFILES
);
444 ADD_DECODER_FLAG(decoder
, SRV_UDPFLG_UDPOBFUSCATION
);
445 ADD_DECODER_FLAG(decoder
, SRV_UDPFLG_TCPOBFUSCATION
);
446 out
<< " (" << decoder
.DecodeFlags(flags
) << ')';
448 } else if (tag
.GetNameID() == ST_PREFERENCE
) {
449 out
<< tag
.GetInt() << ' ';
450 switch (tag
.GetInt()) {
451 case 0: out
<< "SRV_PR_NORMAL"; break;
452 case 1: out
<< "SRV_PR_HIGH"; break;
453 case 2: out
<< "SRV_PR_LOW"; break;
454 default: out
<< "??";
459 } else if (tag
.IsStr()) {
460 out
<< MakePrintableString(tag
.GetStr());
461 } else if (tag
.IsFloat()) {
462 out
<< tag
.GetFloat();
463 } else if (tag
.IsHash()) {
464 out
<< tag
.GetHash();
465 } else if (tag
.IsBlob()) {
466 out
<< wxString::Format(wxT("(size = %u)"), tag
.GetBlobSize());
467 } else if (tag
.IsBsob()) {
468 out
<< wxString::Format(wxT("(size = %u)"), tag
.GetBsobSize());
476 std::ostream
& operator<<(std::ostream
& out
, const CFriendTag
& tag
)
479 if (tag
.GetName().empty()) {
480 out
<< hex(tag
.GetNameID()) << ' ' << DecodeFriendTagNameID(tag
.GetNameID());
482 out
<< TagNameString(tag
.GetName());
484 out
<< ", " << (unsigned)tag
.GetType() << ' ' << DecodeTagType(tag
.GetType()) << ", ";
487 } else if (tag
.IsStr()) {
488 out
<< MakePrintableString(tag
.GetStr());
489 } else if (tag
.IsFloat()) {
490 out
<< tag
.GetFloat();
491 } else if (tag
.IsHash()) {
492 out
<< tag
.GetHash();
493 } else if (tag
.IsBlob()) {
494 out
<< wxString::Format(wxT("(size = %u)"), tag
.GetBlobSize());
495 } else if (tag
.IsBsob()) {
496 out
<< wxString::Format(wxT("(size = %u)"), tag
.GetBsobSize());