more clients
| 1 | /* |
| 2 | * Created on 7 Jun 2007 |
| 3 | * Created by Allan Crooks |
| 4 | * Copyright (C) 2007 Aelitis, All Rights Reserved. |
| 5 | * |
| 6 | * This program is free software; you can redistribute it and/or |
| 7 | * modify it under the terms of the GNU General Public License |
| 8 | * as published by the Free Software Foundation; either version 2 |
| 9 | * of the License, or (at your option) any later version. |
| 10 | * This program is distributed in the hope that it will be useful, |
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 13 | * GNU General Public License for more details. |
| 14 | * You should have received a copy of the GNU General Public License |
| 15 | * along with this program; if not, write to the Free Software |
| 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
| 17 | * |
| 18 | * AELITIS, SAS au capital de 46,603.30 euros |
| 19 | * 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France. |
| 20 | */ |
| 21 | package com.aelitis.azureus.core.peermanager.utils; |
| 22 | |
| 23 | import java.util.ArrayList; |
| 24 | import java.util.HashMap; |
| 25 | import org.gudy.azureus2.core3.internat.MessageText; |
| 26 | |
| 27 | public class BTPeerIDByteDecoderDefinitions { |
| 28 | |
| 29 | // Az style two byte code identifiers to real client name. |
| 30 | private static HashMap az_style_code_map = new HashMap(); |
| 31 | private static HashMap az_client_version_map = new HashMap(); |
| 32 | |
| 33 | // Shadow's style one byte code identifiers to real client name. |
| 34 | private static HashMap shadow_style_code_map = new HashMap(); |
| 35 | private static HashMap shadow_client_version_map = new HashMap(); |
| 36 | |
| 37 | // Mainline's new style uses one byte code identifiers too. |
| 38 | private static HashMap mainline_style_code_map = new HashMap(); |
| 39 | |
| 40 | /** |
| 41 | * List of objects which describes clients with their own custom |
| 42 | * naming scheme. |
| 43 | */ |
| 44 | private static ArrayList custom_style_client_list = new ArrayList(); |
| 45 | |
| 46 | // Version number formats. |
| 47 | static String VER_AZ_THREE_DIGITS = "1.2.3"; |
| 48 | static String VER_AZ_THREE_DIGITS_PLUS_MNEMONIC = "1.2.3 [4]"; |
| 49 | static String VER_AZ_ONE_MAJ_TWO_MIN_PLUS_MNEMONIC = "1.23 [4]"; |
| 50 | static String VER_AZ_FOUR_DIGITS = "1.2.3.4"; |
| 51 | static String VER_AZ_TWO_MAJ_TWO_MIN = "12.34"; |
| 52 | static String VER_AZ_SKIP_FIRST_ONE_MAJ_TWO_MIN = "2.34"; |
| 53 | static String VER_AZ_KTORRENT_STYLE = "1.2.3=[RD].4"; |
| 54 | static String VER_AZ_TRANSMISSION_STYLE = "transmission"; |
| 55 | static String VER_AZ_LAST_THREE_DIGITS = "2.3.4"; |
| 56 | static String VER_AZ_THREE_ALPHANUMERIC_DIGITS = "2.33.4"; // So 'B' = 11, for example, like Shadow's style of numbering. |
| 57 | |
| 58 | // These are used to describe how the version number is extracted from the |
| 59 | // peer ID as well as how that version number is formatted. |
| 60 | static String VER_BLOCK = "abcde"; // Is given as a block in the peer ID, we show the same block |
| 61 | static String VER_DOTTED_BLOCK = "a.b.c.d.e"; // Is given as a dotted block in the peer ID, we show the block in the same dotted format. |
| 62 | static String VER_BYTE_BLOCK_DOTTED_CHAR = "abcde -> a.b.c.d.e"; // Is given a block in the peer ID, but should be displayed in a dotted format. |
| 63 | static String VER_BITS_ON_WHEELS = "BOW-STYLE"; |
| 64 | static String VER_TWO_BYTE_THREE_PART = "ab -> a . b/10 . b%10"; |
| 65 | static String NO_VERSION = "NO_VERSION"; |
| 66 | |
| 67 | // Used to register client information. |
| 68 | private static void addAzStyle(String id, String client) { |
| 69 | addAzStyle(id, client, VER_AZ_FOUR_DIGITS); |
| 70 | } |
| 71 | |
| 72 | private static void addAzStyle(String id, String client, String version_style) { |
| 73 | if (id.length() != 2) {throw new RuntimeException("not two chars long - " + id);} |
| 74 | az_style_code_map.put(id, client); |
| 75 | az_client_version_map.put(client, version_style); |
| 76 | } |
| 77 | |
| 78 | private static void addShadowStyle(char id, String client) { |
| 79 | addShadowStyle(id, client, VER_AZ_THREE_DIGITS); |
| 80 | } |
| 81 | |
| 82 | private static void addShadowStyle(char id, String client, String version_style) { |
| 83 | shadow_style_code_map.put("" + id, client); |
| 84 | shadow_client_version_map.put(client, version_style); |
| 85 | } |
| 86 | |
| 87 | private static void addMainlineStyle(char id, String client) { |
| 88 | mainline_style_code_map.put("" + id, client); |
| 89 | } |
| 90 | |
| 91 | private static ClientData addSimpleClient(String client_name, String identifier) { |
| 92 | return addSimpleClient(client_name, identifier, 0); |
| 93 | } |
| 94 | |
| 95 | private static ClientData addSimpleClient(String client_name, String identifier, int position) { |
| 96 | ClientData result = new ClientData(client_name, identifier, position); |
| 97 | custom_style_client_list.add(result); |
| 98 | return result; |
| 99 | } |
| 100 | |
| 101 | private static void addVersionedClient(ClientData client, String version_type, int length) { |
| 102 | addVersionedClient(client, version_type, length, null); |
| 103 | } |
| 104 | |
| 105 | private static void addVersionedClient(ClientData client, String version_type, int length, String format) { |
| 106 | addVersionedClient(client, version_type, length, format, client.simple_string.length() + client.simple_string_pos); |
| 107 | } |
| 108 | |
| 109 | private static void addVersionedClient(ClientData client, String version_type, int length, int version_pos) { |
| 110 | addVersionedClient(client, version_type, length, null, version_pos); |
| 111 | } |
| 112 | |
| 113 | private static void addVersionedClient(ClientData client, String version_type, int length, String format, int version_pos) { |
| 114 | client.version_data = new VersionNumberData(version_type, length, format, version_pos); |
| 115 | } |
| 116 | |
| 117 | public static String getAzStyleClientName(String peer_id) { |
| 118 | return (String)az_style_code_map.get(peer_id.substring(1, 3)); |
| 119 | } |
| 120 | |
| 121 | public static String getShadowStyleClientName(String peer_id) { |
| 122 | return (String)shadow_style_code_map.get(peer_id.substring(0, 1)); |
| 123 | } |
| 124 | |
| 125 | public static String getMainlineStyleClientName(String peer_id) { |
| 126 | return (String)mainline_style_code_map.get(peer_id.substring(0, 1)); |
| 127 | } |
| 128 | |
| 129 | public static String getAzStyleClientVersion(String client_name, String peer_id) { |
| 130 | String version_scheme = (String)az_client_version_map.get(client_name); |
| 131 | if (version_scheme == NO_VERSION) {return null;} |
| 132 | try { |
| 133 | return client_name + " " + BTPeerIDByteDecoderUtils.decodeAzStyleVersionNumber( |
| 134 | peer_id.substring(3, 7), version_scheme |
| 135 | ); |
| 136 | } |
| 137 | catch (Exception e) { |
| 138 | BTPeerIDByteDecoder.logUnknownClient(peer_id); |
| 139 | return null; |
| 140 | } |
| 141 | } |
| 142 | |
| 143 | public static ClientData getSubstringStyleClient(String peer_id) { |
| 144 | ClientData cd = null; |
| 145 | for (int i=0; i<custom_style_client_list.size(); i++) { |
| 146 | cd = (ClientData)custom_style_client_list.get(i); |
| 147 | if (peer_id.startsWith(cd.simple_string, cd.simple_string_pos)) { |
| 148 | return cd; |
| 149 | } |
| 150 | } |
| 151 | return null; |
| 152 | } |
| 153 | |
| 154 | public static String getSubstringStyleClientVersion(ClientData client_data, String peer_id, byte[] peer_id_bytes) { |
| 155 | VersionNumberData verdata = client_data.version_data; |
| 156 | if (verdata == null) {return null;} |
| 157 | |
| 158 | String version_scheme = verdata.type; |
| 159 | String version_string = null; |
| 160 | try { |
| 161 | if (version_scheme == VER_TWO_BYTE_THREE_PART) { |
| 162 | int start_byte_index = verdata.pos; |
| 163 | version_string = BTPeerIDByteDecoderUtils.getTwoByteThreePartVersion(peer_id_bytes[start_byte_index], peer_id_bytes[start_byte_index+1]); |
| 164 | } |
| 165 | else if (version_scheme == VER_BLOCK && verdata.length == -1) { |
| 166 | version_string = BTPeerIDByteDecoderUtils.extractReadableVersionSubstringFromPeerID(peer_id.substring(verdata.pos, peer_id.length())); |
| 167 | } |
| 168 | else { |
| 169 | version_string = BTPeerIDByteDecoderUtils.decodeCustomVersionNumber( |
| 170 | peer_id.substring(verdata.pos, verdata.pos + verdata.length), version_scheme |
| 171 | ); |
| 172 | } |
| 173 | |
| 174 | if (verdata.fmt == null) {return client_data.client_name + " " + version_string;} |
| 175 | else {return client_data.client_name + verdata.fmt.replaceFirst("%s", version_string);} |
| 176 | } |
| 177 | catch (Exception e) { |
| 178 | BTPeerIDByteDecoder.logUnknownClient(peer_id); |
| 179 | return null; |
| 180 | } |
| 181 | } |
| 182 | |
| 183 | public static String formatUnknownAzStyleClient(String peer_id) { |
| 184 | String version_string = peer_id.substring(3, 7); |
| 185 | try { |
| 186 | version_string = BTPeerIDByteDecoderUtils.decodeAzStyleVersionNumber( |
| 187 | version_string, VER_AZ_FOUR_DIGITS); |
| 188 | } |
| 189 | catch (Exception e) {/* Just use the unformatted string */} |
| 190 | |
| 191 | return MessageText.getString("PeerSocket.unknown_az_style", new String[] { |
| 192 | peer_id.substring(1, 3), version_string |
| 193 | }); |
| 194 | } |
| 195 | |
| 196 | public static String formatUnknownShadowStyleClient(String peer_id) { |
| 197 | String version_string = BTPeerIDByteDecoderUtils.getShadowStyleVersionNumber(peer_id); |
| 198 | return MessageText.getString("PeerSocket.unknown_shadow_style", new String[] { |
| 199 | peer_id.substring(0, 1), version_string |
| 200 | }); |
| 201 | } |
| 202 | |
| 203 | |
| 204 | /** |
| 205 | * OK - here's where we store the definitions. |
| 206 | * |
| 207 | * Good place for information about BT peer ID conventions: |
| 208 | * http://wiki.theory.org/BitTorrentSpecification |
| 209 | * http://transmission.m0k.org/trac/browser/trunk/libtransmission/clients.c (hello Transmission authors!) :) |
| 210 | * http://rufus.cvs.sourceforge.net/rufus/Rufus/g3peerid.py?view=log (for older clients) |
| 211 | * http://shareaza.svn.sourceforge.net/viewvc/shareaza/trunk/shareaza/BTClient.cpp?view=markup |
| 212 | * http://libtorrent.rakshasa.no/browser/trunk/libtorrent/src/torrent/peer/client_list.cc |
| 213 | * |
| 214 | * By default - if you are unsure about a client's versioning scheme, you should |
| 215 | * register it without passing an explicit value. |
| 216 | * |
| 217 | * There are some clients which generate peer ID's in Azureus style, but some don't |
| 218 | * provide accurate or maybe even any information about what version they are. |
| 219 | * |
| 220 | * I've decided that we should follow this criteria - if a client generates a peer |
| 221 | * ID which strictly matches the Az-style specification (0'th char is '-', 7'th char |
| 222 | * is '-'), then we should include it in this list - if there's no derivable version |
| 223 | * information, then we flag it as NO_VERSION. |
| 224 | * |
| 225 | * Oh, and hello any closed source BitTorrent client authors who may be reading! ;) |
| 226 | */ |
| 227 | static { |
| 228 | // We define ourselves first... :) |
| 229 | addAzStyle("AZ", "Azureus", VER_AZ_FOUR_DIGITS); |
| 230 | |
| 231 | // ... and then do everything else alphabetically. |
| 232 | addAzStyle("A~", "Ares", VER_AZ_THREE_DIGITS); |
| 233 | addAzStyle("AG", "Ares", VER_AZ_THREE_DIGITS); |
| 234 | //addAzStyle("AR", "ArcticTorrent", NO_VERSION); //based on libtorrent but same peerid for different versions |
| 235 | addAzStyle("AR", "Ares"); // Ares is more likely than ArcticTorrent |
| 236 | addAzStyle("AV", "Avicora"); |
| 237 | addAzStyle("AX", "BitPump", VER_AZ_TWO_MAJ_TWO_MIN); |
| 238 | addAzStyle("AT", "Artemis"); |
| 239 | addAzStyle("BB", "BitBuddy", "1.234"); |
| 240 | addAzStyle("BC", "BitComet", VER_AZ_SKIP_FIRST_ONE_MAJ_TWO_MIN); |
| 241 | addAzStyle("BE", "BitTorrent SDK"); |
| 242 | addAzStyle("BF", "BitFlu", NO_VERSION); |
| 243 | addAzStyle("BG", "BTG", VER_AZ_FOUR_DIGITS); |
| 244 | addAzStyle("bk", "BitKitten (libtorrent)"); |
| 245 | addAzStyle("BR", "BitRocket", "1.2(34)"); |
| 246 | addAzStyle("BS", "BTSlave"); |
| 247 | addAzStyle("BW", "BitWombat"); |
| 248 | addAzStyle("BX", "BittorrentX"); |
| 249 | addAzStyle("CB", "Shareaza Plus"); |
| 250 | addAzStyle("CD", "Enhanced CTorrent", VER_AZ_TWO_MAJ_TWO_MIN); |
| 251 | addAzStyle("CT", "CTorrent", "1.2.34"); |
| 252 | addAzStyle("DP", "Propogate Data Client"); |
| 253 | addAzStyle("DE", "Deluge", VER_AZ_FOUR_DIGITS); |
| 254 | addAzStyle("EB", "EBit"); |
| 255 | addAzStyle("ES", "Electric Sheep", VER_AZ_THREE_DIGITS); |
| 256 | addAzStyle("FC", "FileCroc"); |
| 257 | addAzStyle("FG", "FlashGet", VER_AZ_SKIP_FIRST_ONE_MAJ_TWO_MIN); |
| 258 | addAzStyle("FT", "FoxTorrent/RedSwoosh"); |
| 259 | addAzStyle("GR", "GetRight", "1.2"); |
| 260 | addAzStyle("GS", "GSTorrent"); // TODO: Format is v"abcd" |
| 261 | addAzStyle("HL", "Halite", VER_AZ_THREE_DIGITS); |
| 262 | addAzStyle("HN", "Hydranode"); |
| 263 | addAzStyle("KT", "KTorrent", VER_AZ_KTORRENT_STYLE); |
| 264 | addAzStyle("LC", "LeechCraft"); |
| 265 | addAzStyle("LH", "LH-ABC"); |
| 266 | addAzStyle("LK", "linkage", VER_AZ_THREE_DIGITS); |
| 267 | addAzStyle("LP", "Lphant", VER_AZ_TWO_MAJ_TWO_MIN); |
| 268 | addAzStyle("LT", "libtorrent (Rasterbar)", VER_AZ_THREE_ALPHANUMERIC_DIGITS); |
| 269 | addAzStyle("lt", "libTorrent (Rakshasa)", VER_AZ_THREE_ALPHANUMERIC_DIGITS); |
| 270 | addAzStyle("LW", "LimeWire", NO_VERSION); // The "0001" bytes found after the LW commonly refers to the version of the BT protocol implemented. Documented here: http://www.limewire.org/wiki/index.php?title=BitTorrentRevision |
| 271 | addAzStyle("MO", "MonoTorrent"); |
| 272 | addAzStyle("MP", "MooPolice", VER_AZ_THREE_DIGITS); |
| 273 | addAzStyle("MR", "Miro"); |
| 274 | addAzStyle("MT", "MoonlightTorrent"); |
| 275 | addAzStyle("NE", "BT Next Evolution", VER_AZ_THREE_DIGITS); |
| 276 | addAzStyle("NX", "Net Transport"); |
| 277 | addAzStyle("OS", "OneSwarm", VER_AZ_FOUR_DIGITS); |
| 278 | addAzStyle("OT", "OmegaTorrent"); |
| 279 | addAzStyle("PC", PeerClassifier.CACHE_LOGIC, "12.3-4" ); |
| 280 | addAzStyle("PD", "Pando"); |
| 281 | addAzStyle("PE", "PeerProject"); |
| 282 | addAzStyle("pX", "pHoeniX"); |
| 283 | addAzStyle("qB", "qBittorrent", VER_AZ_THREE_DIGITS); |
| 284 | addAzStyle("QD", "qqdownload"); |
| 285 | addAzStyle("RT", "Retriever"); |
| 286 | addAzStyle("RZ", "RezTorrent"); |
| 287 | addAzStyle("S~", "Shareaza alpha/beta"); |
| 288 | addAzStyle("SB", "SwiftBit"); |
| 289 | addAzStyle("SD", "\u8FC5\u96F7\u5728\u7EBF (Xunlei)"); // Apparently, the English name of the client is "Thunderbolt". |
| 290 | addAzStyle("SG", "GS Torrent", VER_AZ_FOUR_DIGITS); |
| 291 | addAzStyle("SN", "ShareNET"); |
| 292 | addAzStyle("SP", "BitSpirit"); // >= 3.6 |
| 293 | addAzStyle("SS", "SwarmScope"); |
| 294 | addAzStyle("ST", "SymTorrent", "2.34"); |
| 295 | addAzStyle("st", "SharkTorrent"); |
| 296 | addAzStyle("SZ", "Shareaza"); |
| 297 | addAzStyle("TN", "Torrent.NET"); |
| 298 | addAzStyle("TR", "Transmission", VER_AZ_TRANSMISSION_STYLE); |
| 299 | addAzStyle("TS", "TorrentStorm"); |
| 300 | addAzStyle("TT", "TuoTu", VER_AZ_THREE_DIGITS); |
| 301 | addAzStyle("UL", "uLeecher!"); |
| 302 | addAzStyle("UT", "\u00B5Torrent", VER_AZ_THREE_DIGITS_PLUS_MNEMONIC); |
| 303 | addAzStyle("UM", "\u00B5Torrent Mac", VER_AZ_THREE_DIGITS_PLUS_MNEMONIC); |
| 304 | addAzStyle("WT", "Bitlet"); |
| 305 | addAzStyle("WY", "FireTorrent"); // formerly Wyzo. |
| 306 | addAzStyle("VG", "\u54c7\u560E (Vagaa)", VER_AZ_FOUR_DIGITS); |
| 307 | addAzStyle("XL", "\u8FC5\u96F7\u5728\u7EBF (Xunlei)"); // Apparently, the English name of the client is "Thunderbolt". |
| 308 | addAzStyle("XT", "XanTorrent"); |
| 309 | addAzStyle("XX", "XTorrent", "1.2.34"); |
| 310 | addAzStyle("XC", "XTorrent", "1.2.34"); |
| 311 | addAzStyle("ZT", "ZipTorrent"); |
| 312 | |
| 313 | addShadowStyle('A', "ABC"); |
| 314 | addShadowStyle('O', "Osprey Permaseed"); |
| 315 | addShadowStyle('Q', "BTQueue"); |
| 316 | addShadowStyle('R', "Tribler"); |
| 317 | addShadowStyle('S', "Shad0w"); |
| 318 | addShadowStyle('T', "BitTornado"); |
| 319 | addShadowStyle('U', "UPnP NAT"); |
| 320 | |
| 321 | addMainlineStyle('M', "Mainline"); |
| 322 | addMainlineStyle('Q', "Queen Bee"); |
| 323 | |
| 324 | // Simple clients with no version number. |
| 325 | addSimpleClient("\u00B5Torrent 1.7.0 RC", "-UT170-"); // http://forum.utorrent.com/viewtopic.php?pid=260927#p260927 |
| 326 | addSimpleClient("Azureus 1", "Azureus"); |
| 327 | addSimpleClient("Azureus 2.0.3.2", "Azureus", 5); |
| 328 | addSimpleClient("Aria 2", "-aria2-"); |
| 329 | addSimpleClient("BitTorrent Plus! II", "PRC.P---"); |
| 330 | addSimpleClient("BitTorrent Plus!", "P87.P---"); |
| 331 | addSimpleClient("BitTorrent Plus!", "S587Plus"); |
| 332 | addSimpleClient("BitTyrant (Azureus Mod)", "AZ2500BT"); |
| 333 | addSimpleClient("Blizzard Downloader", "BLZ"); |
| 334 | addSimpleClient("BTGetit", "BG", 10); |
| 335 | addSimpleClient("BTugaXP", "btuga"); |
| 336 | addSimpleClient("BTugaXP", "BTuga", 5); |
| 337 | addSimpleClient("BTugaXP", "oernu"); |
| 338 | addSimpleClient("Deadman Walking", "BTDWV-"); |
| 339 | addSimpleClient("Deadman", "Deadman Walking-"); |
| 340 | addSimpleClient("External Webseed", "Ext"); |
| 341 | addSimpleClient("G3 Torrent", "-G3"); |
| 342 | addSimpleClient("GreedBT 2.7.1", "271-"); |
| 343 | addSimpleClient("Hurricane Electric", "arclight"); |
| 344 | addSimpleClient("HTTP Seed", "-WS" ); // used internally to denote incoming webseed connections |
| 345 | addSimpleClient("JVtorrent", "10-------"); |
| 346 | addSimpleClient("Limewire", "LIME"); |
| 347 | addSimpleClient("Martini Man", "martini"); |
| 348 | addSimpleClient("Pando", "Pando"); |
| 349 | addSimpleClient("PeerApp", "PEERAPP"); |
| 350 | addSimpleClient("SimpleBT", "btfans", 4); |
| 351 | addSimpleClient("Swarmy", "a00---0"); |
| 352 | addSimpleClient("Swarmy", "a02---0"); |
| 353 | addSimpleClient("Teeweety", "T00---0"); |
| 354 | addSimpleClient("TorrentTopia", "346-"); |
| 355 | addSimpleClient("XanTorrent", "DansClient"); |
| 356 | |
| 357 | /** |
| 358 | * This is interesting - it uses Mainline style, except uses two characters instead of one. |
| 359 | * And then - the particular numbering style it uses would actually break the way we decode |
| 360 | * version numbers (our code is too hardcoded to "-x-y-z--" style version numbers). |
| 361 | * |
| 362 | * This should really be declared as a Mainline style peer ID, but I would have to |
| 363 | * make my code more generic. Not a bad thing - just something I'm not doing right |
| 364 | * now. |
| 365 | */ |
| 366 | addSimpleClient("Amazon AWS S3", "S3-"); |
| 367 | |
| 368 | // Clients with their own custom format and version number style. |
| 369 | ClientData client = null; |
| 370 | |
| 371 | // DNA01000 becomes version 1.0 - we'll ignore the other digits for now. |
| 372 | client = addSimpleClient("BitTorrent DNA", "DNA"); |
| 373 | addVersionedClient(client, VER_BYTE_BLOCK_DOTTED_CHAR, 2, 4); |
| 374 | |
| 375 | // Pre build 10000 versions. |
| 376 | client = addSimpleClient("Opera", "OP"); |
| 377 | addVersionedClient(client, VER_BLOCK, 4, " (Build %s)"); |
| 378 | |
| 379 | // Post build 10000 versions. |
| 380 | client = addSimpleClient("Opera", "O"); |
| 381 | addVersionedClient(client, VER_BLOCK, 5, " (Build %s)"); |
| 382 | |
| 383 | client = addSimpleClient("Burst!", "Mbrst"); |
| 384 | addVersionedClient(client, VER_DOTTED_BLOCK, 5); // 3 version components, 5 chars which describe it |
| 385 | |
| 386 | client = addSimpleClient("TurboBT", "turbobt"); |
| 387 | addVersionedClient(client, VER_BLOCK, 5); |
| 388 | |
| 389 | client = addSimpleClient("BT Protocol Daemon", "btpd"); |
| 390 | addVersionedClient(client, VER_BLOCK, 3, 5); |
| 391 | |
| 392 | client = addSimpleClient("Plus!", "Plus"); |
| 393 | addVersionedClient(client, VER_BYTE_BLOCK_DOTTED_CHAR, 3); |
| 394 | |
| 395 | client = addSimpleClient("XBT", "XBT"); |
| 396 | addVersionedClient(client, VER_BYTE_BLOCK_DOTTED_CHAR, 3); |
| 397 | |
| 398 | client = addSimpleClient("BitsOnWheels", "-BOW"); |
| 399 | addVersionedClient(client, VER_BITS_ON_WHEELS, 3); |
| 400 | |
| 401 | client = addSimpleClient("eXeem", "eX"); |
| 402 | addVersionedClient(client, VER_BLOCK, 18, " [%s]"); // Refers to user ID. |
| 403 | |
| 404 | client = addSimpleClient("MLdonkey", "-ML"); |
| 405 | addVersionedClient(client, VER_DOTTED_BLOCK, 5); |
| 406 | |
| 407 | client = addSimpleClient("Bitlet", "BitLet"); |
| 408 | addVersionedClient(client, VER_BYTE_BLOCK_DOTTED_CHAR, 2); |
| 409 | |
| 410 | client = addSimpleClient("AllPeers", "AP"); |
| 411 | addVersionedClient(client, VER_BLOCK, -1); |
| 412 | |
| 413 | client = addSimpleClient("BTuga Revolution", "BTM"); |
| 414 | addVersionedClient(client, VER_BYTE_BLOCK_DOTTED_CHAR, 2); |
| 415 | |
| 416 | client = addSimpleClient("Rufus", "RS", 2); |
| 417 | addVersionedClient(client, VER_TWO_BYTE_THREE_PART, 2, 0); |
| 418 | |
| 419 | // BitMagnet - predecessor to Rufus. |
| 420 | client = addSimpleClient("BitMagnet", "BM", 2); |
| 421 | addVersionedClient(client, VER_TWO_BYTE_THREE_PART, 2, 0); |
| 422 | |
| 423 | client = addSimpleClient("QVOD", "QVOD"); |
| 424 | addVersionedClient(client, VER_BLOCK, 4, " (Build %s)"); |
| 425 | |
| 426 | // Top-BT - based on BitTornado, but doesn't quite stick |
| 427 | // to Shadow's naming conventions - so we'll use substring |
| 428 | // matching instead. |
| 429 | client = addSimpleClient("Top-BT", "TB"); |
| 430 | addVersionedClient(client, VER_BYTE_BLOCK_DOTTED_CHAR, 3); |
| 431 | |
| 432 | } |
| 433 | |
| 434 | static class ClientData { |
| 435 | |
| 436 | String client_name; |
| 437 | private int simple_string_pos; |
| 438 | private String simple_string; |
| 439 | private VersionNumberData version_data; |
| 440 | |
| 441 | ClientData(String client_name, String simple_string, int simple_string_pos) { |
| 442 | this.simple_string_pos = simple_string_pos; |
| 443 | this.simple_string = simple_string; |
| 444 | this.client_name = client_name; |
| 445 | this.version_data = null; |
| 446 | } |
| 447 | |
| 448 | } |
| 449 | |
| 450 | static class VersionNumberData { |
| 451 | |
| 452 | private String type; // How to extract and put digit components together |
| 453 | private int pos; // Where does this appear in a client ID string? |
| 454 | private String fmt; // How do we display that version number? |
| 455 | private int length; // How long is the version number? |
| 456 | |
| 457 | VersionNumberData(String type, int length, String formatter, int position) { |
| 458 | this.type = type; |
| 459 | this.pos = position; |
| 460 | this.fmt = formatter; |
| 461 | this.length = length; |
| 462 | } |
| 463 | |
| 464 | } |
| 465 | |
| 466 | |
| 467 | } |
Copyright © 2010 Geeknet, Inc. All rights reserved. Terms of Use