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_*
35 #include "../../NetworkFunctions.h" // Needed for Uint32toStringIP
41 SDMODE g_stringDecodeMode
;
43 wxString
MakePrintableString(const wxString
& s
)
47 for (unsigned i
= 0; i
< str
.length(); i
++) {
51 if (c
<= 0xff && GetStringsMode() != SD_NONE
) {
52 wxCharBuffer buf
= str
.To8BitData();
53 wxString test
= UTF82unicode(buf
.data());
57 for (unsigned i
= 0; i
< str
.length(); i
++) {
63 wxString retval
= wxT("\"");
65 if (GetStringsMode() == SD_DISPLAY
) {
67 } else if (GetStringsMode() == SD_UTF8
) {
68 str
= wxString::From8BitData((const char *)str
.utf8_str());
72 if (GetStringsMode() != SD_DISPLAY
) {
73 for (unsigned i
= 0; i
< str
.length(); i
++) {
74 if (GetStringsMode() == SD_NONE
? ((unsigned)str
[i
] >= ' ' && (unsigned)str
[i
] <= 0x7f) : std::isprint(str
[i
])) {
76 } else if (c
<= 0xff) {
77 retval
+= wxString::Format(wxT("\\x%02x"), str
[i
]);
79 retval
+= wxString::Format(wxT("\\u%04x"), str
[i
]);
88 std::ostream
& operator<<(std::ostream
& x
, const CTimeT
& y
)
91 wxDateTime
dt((time_t)y
);
92 return x
<< (time_t)y
<< " (" << dt
.Format(wxDefaultDateTimeFormat
, wxDateTime::UTC
) << " UTC)";
94 return x
<< "0 (Never)";
98 std::ostream
& operator<<(std::ostream
& x
, const CKadIP
& ip
)
100 return x
<< hex(ip
) << " (" << Uint32toStringIP(wxUINT32_SWAP_ALWAYS(ip
)) << ')';
103 std::ostream
& operator<<(std::ostream
& x
, const CeD2kIP
& ip
)
105 return x
<< hex(ip
) << " (" << Uint32toStringIP(ip
) << ')';
108 static inline wxString
TagNameString(const wxString
& name
)
110 if (name
.length() == 1) {
111 return wxString::Format(wxT("\"\\x%02x\""), name
[0]);
112 } else if (name
.length() > 1) {
113 if (name
[0] == FT_GAPSTART
|| name
[0] == FT_GAPEND
) {
114 return wxString::Format(wxT("\"\\x%02x"), name
[0]) + name
.substr(1) + wxT("\"");
117 return wxT("\"") + name
+ wxT("\"");
120 #define TEST_VALUE(VALUE) if (value == VALUE) return #VALUE; else
122 const char* DecodeTagNameID(uint8_t value
)
124 TEST_VALUE(FT_FILENAME
)
125 TEST_VALUE(FT_FILESIZE
)
126 TEST_VALUE(FT_FILESIZE_HI
)
127 TEST_VALUE(FT_FILETYPE
)
128 TEST_VALUE(FT_FILEFORMAT
)
129 TEST_VALUE(FT_LASTSEENCOMPLETE
)
130 TEST_VALUE(FT_TRANSFERRED
)
131 TEST_VALUE(FT_GAPSTART
)
132 TEST_VALUE(FT_GAPEND
)
133 TEST_VALUE(FT_PARTFILENAME
)
134 TEST_VALUE(FT_OLDDLPRIORITY
)
135 TEST_VALUE(FT_STATUS
)
136 TEST_VALUE(FT_SOURCES
)
137 TEST_VALUE(FT_PERMISSIONS
)
138 TEST_VALUE(FT_OLDULPRIORITY
)
139 TEST_VALUE(FT_DLPRIORITY
)
140 TEST_VALUE(FT_ULPRIORITY
)
141 TEST_VALUE(FT_KADLASTPUBLISHKEY
)
142 TEST_VALUE(FT_KADLASTPUBLISHSRC
)
144 TEST_VALUE(FT_DL_ACTIVE_TIME
)
145 TEST_VALUE(FT_CORRUPTEDPARTS
)
146 TEST_VALUE(FT_DL_PREVIEW
)
147 TEST_VALUE(FT_KADLASTPUBLISHNOTES
)
148 TEST_VALUE(FT_AICH_HASH
)
149 TEST_VALUE(FT_COMPLETE_SOURCES
)
150 TEST_VALUE(FT_PUBLISHINFO
)
151 TEST_VALUE(FT_ATTRANSFERRED
)
152 TEST_VALUE(FT_ATREQUESTED
)
153 TEST_VALUE(FT_ATACCEPTED
)
154 TEST_VALUE(FT_CATEGORY
)
155 TEST_VALUE(FT_ATTRANSFERREDHI
)
156 TEST_VALUE(FT_MEDIA_ARTIST
)
157 TEST_VALUE(FT_MEDIA_ALBUM
)
158 TEST_VALUE(FT_MEDIA_TITLE
)
159 TEST_VALUE(FT_MEDIA_LENGTH
)
160 TEST_VALUE(FT_MEDIA_BITRATE
)
161 TEST_VALUE(FT_MEDIA_CODEC
)
162 TEST_VALUE(FT_FILERATING
)
166 const char* DecodeTagName(const wxString
& value
)
168 TEST_VALUE(TAG_FILENAME
)
169 TEST_VALUE(TAG_FILESIZE
)
170 TEST_VALUE(TAG_FILESIZE_HI
)
171 TEST_VALUE(TAG_FILETYPE
)
172 TEST_VALUE(TAG_FILEFORMAT
)
173 TEST_VALUE(TAG_COLLECTION
)
174 TEST_VALUE(TAG_PART_PATH
)
175 TEST_VALUE(TAG_PART_HASH
)
176 TEST_VALUE(TAG_COPIED
)
177 TEST_VALUE(TAG_GAP_START
)
178 TEST_VALUE(TAG_GAP_END
)
179 TEST_VALUE(TAG_DESCRIPTION
)
182 TEST_VALUE(TAG_PREFERENCE
)
184 TEST_VALUE(TAG_IP_ADDRESS
)
185 TEST_VALUE(TAG_VERSION
)
186 TEST_VALUE(TAG_TEMPFILE
)
187 TEST_VALUE(TAG_PRIORITY
)
188 TEST_VALUE(TAG_STATUS
)
189 TEST_VALUE(TAG_SOURCES
)
190 TEST_VALUE(TAG_AVAILABILITY
)
191 TEST_VALUE(TAG_PERMISSIONS
)
192 TEST_VALUE(TAG_QTIME
)
193 TEST_VALUE(TAG_PARTS
)
194 TEST_VALUE(TAG_PUBLISHINFO
)
195 TEST_VALUE(TAG_MEDIA_ARTIST
)
196 TEST_VALUE(TAG_MEDIA_ALBUM
)
197 TEST_VALUE(TAG_MEDIA_TITLE
)
198 TEST_VALUE(TAG_MEDIA_LENGTH
)
199 TEST_VALUE(TAG_MEDIA_BITRATE
)
200 TEST_VALUE(TAG_MEDIA_CODEC
)
201 TEST_VALUE(TAG_ENCRYPTION
)
202 TEST_VALUE(TAG_FILERATING
)
203 TEST_VALUE(TAG_BUDDYHASH
)
204 TEST_VALUE(TAG_CLIENTLOWID
)
205 TEST_VALUE(TAG_SERVERPORT
)
206 TEST_VALUE(TAG_SERVERIP
)
207 TEST_VALUE(TAG_SOURCEUPORT
)
208 TEST_VALUE(TAG_SOURCEPORT
)
209 TEST_VALUE(TAG_SOURCEIP
)
210 TEST_VALUE(TAG_SOURCETYPE
)
214 const char* DecodeTagType(uint8_t value
)
216 TEST_VALUE(TAGTYPE_HASH16
)
217 TEST_VALUE(TAGTYPE_STRING
)
218 TEST_VALUE(TAGTYPE_UINT32
)
219 TEST_VALUE(TAGTYPE_FLOAT32
)
220 TEST_VALUE(TAGTYPE_BOOL
)
221 TEST_VALUE(TAGTYPE_BOOLARRAY
)
222 TEST_VALUE(TAGTYPE_BLOB
)
223 TEST_VALUE(TAGTYPE_UINT16
)
224 TEST_VALUE(TAGTYPE_UINT8
)
225 TEST_VALUE(TAGTYPE_BSOB
)
226 TEST_VALUE(TAGTYPE_UINT64
)
227 TEST_VALUE(TAGTYPE_STR1
)
228 TEST_VALUE(TAGTYPE_STR2
)
229 TEST_VALUE(TAGTYPE_STR3
)
230 TEST_VALUE(TAGTYPE_STR4
)
231 TEST_VALUE(TAGTYPE_STR5
)
232 TEST_VALUE(TAGTYPE_STR6
)
233 TEST_VALUE(TAGTYPE_STR7
)
234 TEST_VALUE(TAGTYPE_STR8
)
235 TEST_VALUE(TAGTYPE_STR9
)
236 TEST_VALUE(TAGTYPE_STR10
)
237 TEST_VALUE(TAGTYPE_STR11
)
238 TEST_VALUE(TAGTYPE_STR12
)
239 TEST_VALUE(TAGTYPE_STR13
)
240 TEST_VALUE(TAGTYPE_STR14
)
241 TEST_VALUE(TAGTYPE_STR15
)
242 TEST_VALUE(TAGTYPE_STR16
)
243 TEST_VALUE(TAGTYPE_STR17
)
244 TEST_VALUE(TAGTYPE_STR18
)
245 TEST_VALUE(TAGTYPE_STR19
)
246 TEST_VALUE(TAGTYPE_STR20
)
247 TEST_VALUE(TAGTYPE_STR21
)
248 TEST_VALUE(TAGTYPE_STR22
)
252 const char* DecodeServerTagNameID(uint8_t value
)
254 TEST_VALUE(ST_SERVERNAME
)
255 TEST_VALUE(ST_DESCRIPTION
)
258 TEST_VALUE(ST_PREFERENCE
)
260 TEST_VALUE(ST_LASTPING_DEPRECATED
)
261 TEST_VALUE(ST_MAXUSERS
)
262 TEST_VALUE(ST_SOFTFILES
)
263 TEST_VALUE(ST_HARDFILES
)
264 TEST_VALUE(ST_LASTPING
)
265 TEST_VALUE(ST_VERSION
)
266 TEST_VALUE(ST_UDPFLAGS
)
267 TEST_VALUE(ST_AUXPORTSLIST
)
268 TEST_VALUE(ST_LOWIDUSERS
)
269 TEST_VALUE(ST_UDPKEY
)
270 TEST_VALUE(ST_UDPKEYIP
)
271 TEST_VALUE(ST_TCPPORTOBFUSCATION
)
272 TEST_VALUE(ST_UDPPORTOBFUSCATION
)
276 const char* DecodeFriendTagNameID(uint8_t value
)
282 typedef std::map
<uint32_t, const char*> FlagMap
;
287 void AddFlag(uint32_t bit
, const char* name
)
292 wxString
DecodeFlags(uint32_t flags
)
294 uint32_t cur_flag
= 1;
298 if (!result
.empty()) {
299 result
+= wxT(" | ");
301 FlagMap::const_iterator it
= m_flags
.find(cur_flag
);
302 if (it
!= m_flags
.end()) {
303 result
+= wxString::FromAscii(it
->second
);
305 result
+= wxString::Format(wxT("%#x"), cur_flag
);
318 #define ADD_DECODER_FLAG(decoder, FLAG) decoder.AddFlag(FLAG, #FLAG)
320 std::ostream
& operator<<(std::ostream
& out
, const CTag
& tag
)
323 if (tag
.GetName().empty()) {
324 out
<< hex(tag
.GetNameID()) << ' ' << DecodeTagNameID(tag
.GetNameID());
326 out
<< TagNameString(tag
.GetName()) << ' ';
327 bool name_decoded
= false;
328 if (tag
.IsInt() && tag
.GetName().length() > 1) {
329 wxCharBuffer ascii_name
= tag
.GetName().ToAscii();
330 char gap_mark
= ascii_name
? ascii_name
[(size_t)0] : 0;
331 if (gap_mark
== FT_GAPSTART
|| gap_mark
== FT_GAPEND
) {
332 unsigned long gapkey
;
333 if (tag
.GetName().Mid(1).ToULong(&gapkey
)) {
334 out
<< DecodeTagNameID(gap_mark
) << wxString::Format(wxT("[%lu]"), gapkey
);
340 out
<< DecodeTagName(tag
.GetName());
343 out
<< ", " << (unsigned)tag
.GetType() << ' ' << DecodeTagType(tag
.GetType()) << ", ";
345 if (tag
.GetName() == TAG_SOURCEIP
) {
346 out
<< CKadIP(tag
.GetInt());
347 } else if (tag
.GetName() == TAG_SERVERIP
) {
348 out
<< CeD2kIP(tag
.GetInt());
349 } else if (tag
.GetName() == TAG_ENCRYPTION
) {
350 uint8_t enc
= tag
.GetInt();
353 CFlagDecoder decoder
;
354 decoder
.AddFlag(0x01, "CryptSupported");
355 decoder
.AddFlag(0x02, "CryptRequested");
356 decoder
.AddFlag(0x04, "CryptRequired");
357 decoder
.AddFlag(0x08, "SupportsDirectCallback");
358 out
<< " (" << decoder
.DecodeFlags(enc
) << ')';
360 } else if (tag
.GetNameID() == FT_LASTSEENCOMPLETE
361 || tag
.GetNameID() == FT_KADLASTPUBLISHSRC
362 || tag
.GetNameID() == FT_KADLASTPUBLISHNOTES
363 || tag
.GetNameID() == FT_KADLASTPUBLISHKEY
365 out
<< CTimeT(tag
.GetInt());
366 } else if (tag
.GetName() == TAG_FILESIZE
367 || tag
.GetNameID() == FT_FILESIZE
368 || tag
.GetNameID() == FT_TRANSFERRED
369 || tag
.GetNameID() == FT_ATTRANSFERRED
371 out
<< tag
.GetInt() << " (" << CastItoXBytes(tag
.GetInt()) << ')';
372 } else if (tag
.GetNameID() == FT_ULPRIORITY
373 || tag
.GetNameID() == FT_DLPRIORITY
374 || tag
.GetNameID() == FT_OLDULPRIORITY
375 || tag
.GetNameID() == FT_OLDDLPRIORITY
377 out
<< tag
.GetInt() << ' ';
378 switch (tag
.GetInt()) {
379 case PR_VERYLOW
: out
<< "PR_VERYLOW"; break;
380 case PR_LOW
: out
<< "PR_LOW"; break;
381 case PR_NORMAL
: out
<< "PR_NORMAL"; break;
382 case PR_HIGH
: out
<< "PR_HIGH"; break;
383 case PR_VERYHIGH
: out
<< "PR_VERYHIGH"; break;
384 case PR_AUTO
: out
<< "PR_AUTO"; break;
385 case PR_POWERSHARE
: out
<< "PR_POWERSHARE"; break;
390 } else if (tag
.IsStr()) {
391 out
<< MakePrintableString(tag
.GetStr());
392 } else if (tag
.IsFloat()) {
393 out
<< tag
.GetFloat();
394 } else if (tag
.IsHash()) {
395 out
<< tag
.GetHash();
396 } else if (tag
.IsBlob()) {
397 out
<< wxString::Format(wxT("(size = %u)"), tag
.GetBlobSize());
398 } else if (tag
.IsBsob()) {
399 out
<< wxString::Format(wxT("(size = %u)"), tag
.GetBsobSize());
407 std::ostream
& operator<<(std::ostream
& out
, const CServerTag
& tag
)
410 if (tag
.GetName().empty()) {
411 out
<< hex(tag
.GetNameID()) << ' ' << DecodeServerTagNameID(tag
.GetNameID());
413 out
<< TagNameString(tag
.GetName());
415 out
<< ", " << (unsigned)tag
.GetType() << ' ' << DecodeTagType(tag
.GetType()) << ", ";
417 if (tag
.GetNameID() == ST_DYNIP
|| tag
.GetNameID() == ST_UDPKEYIP
) {
418 out
<< CeD2kIP(tag
.GetInt());
419 } else if (tag
.GetNameID() == ST_UDPKEY
) {
420 out
<< hex((uint32_t)tag
.GetInt());
421 } else if (tag
.GetNameID() == ST_UDPFLAGS
) {
422 uint32_t flags
= tag
.GetInt();
425 CFlagDecoder decoder
;
426 ADD_DECODER_FLAG(decoder
, SRV_UDPFLG_EXT_GETSOURCES
);
427 ADD_DECODER_FLAG(decoder
, SRV_UDPFLG_EXT_GETFILES
);
428 ADD_DECODER_FLAG(decoder
, SRV_UDPFLG_NEWTAGS
);
429 ADD_DECODER_FLAG(decoder
, SRV_UDPFLG_UNICODE
);
430 ADD_DECODER_FLAG(decoder
, SRV_UDPFLG_EXT_GETSOURCES2
);
431 ADD_DECODER_FLAG(decoder
, SRV_UDPFLG_LARGEFILES
);
432 ADD_DECODER_FLAG(decoder
, SRV_UDPFLG_UDPOBFUSCATION
);
433 ADD_DECODER_FLAG(decoder
, SRV_UDPFLG_TCPOBFUSCATION
);
434 out
<< " (" << decoder
.DecodeFlags(flags
) << ')';
436 } else if (tag
.GetNameID() == ST_PREFERENCE
) {
437 out
<< tag
.GetInt() << ' ';
438 switch (tag
.GetInt()) {
439 case 0: out
<< "SRV_PR_NORMAL"; break;
440 case 1: out
<< "SRV_PR_HIGH"; break;
441 case 2: out
<< "SRV_PR_LOW"; break;
442 default: out
<< "??";
447 } else if (tag
.IsStr()) {
448 out
<< MakePrintableString(tag
.GetStr());
449 } else if (tag
.IsFloat()) {
450 out
<< tag
.GetFloat();
451 } else if (tag
.IsHash()) {
452 out
<< tag
.GetHash();
453 } else if (tag
.IsBlob()) {
454 out
<< wxString::Format(wxT("(size = %u)"), tag
.GetBlobSize());
455 } else if (tag
.IsBsob()) {
456 out
<< wxString::Format(wxT("(size = %u)"), tag
.GetBsobSize());
464 std::ostream
& operator<<(std::ostream
& out
, const CFriendTag
& tag
)
467 if (tag
.GetName().empty()) {
468 out
<< hex(tag
.GetNameID()) << ' ' << DecodeFriendTagNameID(tag
.GetNameID());
470 out
<< TagNameString(tag
.GetName());
472 out
<< ", " << (unsigned)tag
.GetType() << ' ' << DecodeTagType(tag
.GetType()) << ", ";
475 } else if (tag
.IsStr()) {
476 out
<< MakePrintableString(tag
.GetStr());
477 } else if (tag
.IsFloat()) {
478 out
<< tag
.GetFloat();
479 } else if (tag
.IsHash()) {
480 out
<< tag
.GetHash();
481 } else if (tag
.IsBlob()) {
482 out
<< wxString::Format(wxT("(size = %u)"), tag
.GetBlobSize());
483 } else if (tag
.IsBsob()) {
484 out
<< wxString::Format(wxT("(size = %u)"), tag
.GetBsobSize());