Exemple #1
0
  private static OptionSet parseOptions(String[] argv) throws IOException {
    OptionSet args = null;
    OptionParser parser = new OptionParser();
    parser.acceptsAll(Arrays.asList("l", CMD_LIST), "list readers");
    parser.acceptsAll(Arrays.asList("p", OPT_PROVIDER), "specify provider").withRequiredArg();
    parser.acceptsAll(Arrays.asList("v", OPT_VERBOSE), "be verbose");
    parser.acceptsAll(Arrays.asList("e", OPT_ERROR), "fail if not 0x9000");
    parser.acceptsAll(Arrays.asList("h", OPT_HELP), "show help");
    parser.acceptsAll(Arrays.asList("r", OPT_READER), "use reader").withRequiredArg();
    parser.acceptsAll(Arrays.asList("a", CMD_APDU), "send APDU").withRequiredArg();
    parser.acceptsAll(Arrays.asList("w", OPT_WEB), "open ATR in web");
    parser.acceptsAll(Arrays.asList("V", OPT_VERSION), "show version information");
    parser.accepts(OPT_DUMP, "save dump to file").withRequiredArg().ofType(File.class);
    parser.accepts(OPT_REPLAY, "replay command from dump").withRequiredArg().ofType(File.class);

    parser.accepts(OPT_SUN, "load SunPCSC");
    parser.accepts(OPT_JNA, "load jnasmartcardio");
    parser.accepts(OPT_CONNECT, "connect to host:port or URL").withRequiredArg();
    parser.accepts(OPT_PINNED, "require certificate").withRequiredArg().ofType(File.class);

    parser.accepts(OPT_PROVIDERS, "list providers");
    parser.accepts(OPT_ALL, "process all readers");
    parser.accepts(OPT_WAIT, "wait for card insertion");
    parser.accepts(OPT_T0, "use T=0");
    parser.accepts(OPT_T1, "use T=1");
    parser.accepts(OPT_TEST_SERVER, "run a test server on port 10000").withRequiredArg();
    parser.accepts(OPT_NO_GET_RESPONSE, "don't use GET RESPONSE with SunPCSC");
    parser.accepts(OPT_LIB, "use specific PC/SC lib with SunPCSC").withRequiredArg();
    parser.accepts(OPT_PROVIDER_TYPE, "provider type if not PC/SC").withRequiredArg();

    // Parse arguments
    try {
      args = parser.parse(argv);
      // Try to fetch all values so that format is checked before usage
      for (String s : parser.recognizedOptions().keySet()) {
        args.valuesOf(s);
      }
    } catch (OptionException e) {
      if (e.getCause() != null) {
        System.err.println(e.getMessage() + ": " + e.getCause().getMessage());
      } else {
        System.err.println(e.getMessage());
      }
      System.err.println();
      help_and_exit(parser, System.err);
    }
    if (args.has(OPT_HELP)) {
      help_and_exit(parser, System.out);
    }
    return args;
  }
Exemple #2
0
  public static void parseArgs(String args[]) throws java.io.IOException {

    parser.acceptsAll(asList("h", "?"), "show help then exit");
    OptionSpec<String> CMD = parser.accepts("c", "command").withRequiredArg().ofType(String.class);
    OptionSpec<String> LOGIN =
        parser.accepts("u", "LoginId").withRequiredArg().ofType(String.class);
    OptionSpec<String> PASSWORD =
        parser.accepts("p", "password").withRequiredArg().ofType(String.class);
    OptionSpec<String> ISSUER =
        parser.accepts("i", "IssuerDN").withRequiredArg().ofType(String.class);
    OptionSpec<String> SUBJECT =
        parser.accepts("s", "SubjectDN").withRequiredArg().ofType(String.class);
    OptionSpec<String> CONTEXT =
        parser
            .accepts("C", "context:UNITTEST,DEVELOPMENT,SDK,PRODUCTION")
            .withRequiredArg()
            .ofType(String.class);

    OptionSet options = parser.parse(args);

    // check for help
    if (options.has("?")) {
      parser.printHelpOn(System.out);
      System.exit(0);
    }
    if (options.has(CMD)) {
      cmd = options.valueOf(CMD);
    } else {
      System.out.println("a -c cmd argument is required");
      parser.printHelpOn(System.out);
      System.exit(0);
    }
    if (options.has(LOGIN)) {
      loginName = options.valueOf(LOGIN);
    }
    if (options.has(PASSWORD)) {
      password = options.valueOf(PASSWORD);
    }
    if (options.has(ISSUER)) {
      issuer = options.valueOf(ISSUER);
    }
    if (options.has(SUBJECT)) {
      subject = options.valueOf(SUBJECT);
    }
    if (options.has(CONTEXT)) {
      context = options.valueOf(CONTEXT);
      if (!context.equals("UNITTEST")
          && !context.equals("SDK")
          && !context.equals("DEVELOPMENT")
          && !context.equals("PRODUCTION")) {
        System.out.println("unrecognized CONTEXT value: " + context);
        System.exit(-1);
      }
    }
  }
 /** Initializes the command line parser with all supported options. */
 private static OptionParser setupParser() {
   OptionParser parser = new OptionParser();
   parser
       .acceptsAll(Arrays.asList("N", "num-nodes"), "Number of nodes (roads) in the simulation")
       .withRequiredArg()
       .describedAs("nodes");
   parser
       .acceptsAll(Arrays.asList("D", "node-degree"), "The desired average node degree")
       .withRequiredArg()
       .describedAs("deg");
   parser
       .acceptsAll(Arrays.asList("node-capacity"), "The default node capacity")
       .withRequiredArg()
       .describedAs("capacity");
   parser
       .acceptsAll(Arrays.asList("d", "node-delay"), "Range of possible node delays")
       .withRequiredArg()
       .describedAs("min:max");
   parser
       .acceptsAll(Arrays.asList("C", "num-vehicles"), "Number of vehicles in the simulation")
       .withRequiredArg()
       .describedAs("vehicles");
   parser
       .acceptsAll(
           Arrays.asList("S", "vehicle-strategies"),
           "Comma separated list of possible routing strategies")
       .withRequiredArg()
       .describedAs("strategies");
   parser.acceptsAll(Arrays.asList("o", "output-file")).withRequiredArg().describedAs("file");
   parser
       .acceptsAll(Arrays.asList("one-way-prob"), "Probability for a road to be a one-way street")
       .withRequiredArg()
       .describedAs("prob");
   parser
       .acceptsAll(
           Arrays.asList("graph"),
           "A file containing a user-define graph to be used in the simulation")
       .withRequiredArg()
       .describedAs("graph-file");
   parser.accepts(
       "congested",
       "Build a simulation that likely contains a bottleneck."); // TODO: This is a hack for SEAMS
                                                                 // 2012
   return parser;
 }
  @Test
  public void supportsOptionSynonyms() {
    OptionParser parser = new OptionParser();
    List<String> synonyms = asList("message", "blurb", "greeting");
    parser.acceptsAll(synonyms).withRequiredArg();
    String expectedMessage = "Hello";

    OptionSet options = parser.parse("--message", expectedMessage);

    for (String each : synonyms) {
      assertTrue(each, options.has(each));
      assertTrue(each, options.hasArgument(each));
      assertEquals(each, expectedMessage, options.valueOf(each));
      assertEquals(each, asList(expectedMessage), options.valuesOf(each));
    }
  }
  @Override
  protected void customizeOptionParsing(OptionParser parser) {
    parser
        .accepts(USER_DATA_DIR_KEY, description("User data directory", DEFAULT_USER_DATA_DIR))
        .withRequiredArg();
    parser
        .accepts(APP_NAME_KEY, description("Application name", DEFAULT_APP_NAME))
        .withRequiredArg();
    parser
        .accepts(APP_DATA_DIR_KEY, description("Application data directory", DEFAULT_APP_DATA_DIR))
        .withRequiredArg();
    parser
        .acceptsAll(
            asList(APP_DATA_DIR_CLEAN_KEY, "clean"),
            description("Clean application data directory", DEFAULT_APP_DATA_DIR_CLEAN))
        .withRequiredArg()
        .ofType(boolean.class);
    parser
        .accepts(ProgramArguments.NAME_KEY, description("Name of this node", null))
        .withRequiredArg();
    // use a fixed port as arbitrator use that for his ID
    parser
        .accepts(ProgramArguments.PORT_KEY, description("Port to listen on", 9999))
        .withRequiredArg()
        .ofType(int.class);
    parser
        .accepts(
            ProgramArguments.USE_LOCALHOST,
            description("Use localhost network for development", false))
        .withRequiredArg()
        .ofType(boolean.class);
    parser
        .accepts(ProgramArguments.DEV_TEST, description("Enable arbitrator dev priv key", false))
        .withRequiredArg()
        .ofType(boolean.class);
    parser
        .accepts(BitcoinNetwork.KEY, description("Bitcoin network", BitcoinNetwork.DEFAULT))
        .withRequiredArg()
        .ofType(BitcoinNetwork.class)
        .withValuesConvertedBy(new EnumValueConverter(BitcoinNetwork.class));

    parser
        .accepts(RegTestHost.KEY, description("", RegTestHost.DEFAULT))
        .withRequiredArg()
        .ofType(RegTestHost.class)
        .withValuesConvertedBy(new EnumValueConverter(RegTestHost.class));
  }
  public static void main(String[] args) {
    // TODO main
    OptionParser parser = new OptionParser();
    parser.acceptsAll(Arrays.asList("h", "help"), "Show this help dialog.");
    OptionSpec<String> serverOption =
        parser
            .acceptsAll(Arrays.asList("s", "server"), "Server to join.")
            .withRequiredArg()
            .describedAs("server-address[:port]");
    OptionSpec<String> proxyOption =
        parser
            .acceptsAll(
                Arrays.asList("P", "proxy"),
                "SOCKS proxy to use. Ignored in presence of 'socks-proxy-list'.")
            .withRequiredArg()
            .describedAs("proxy-address");
    OptionSpec<String> ownerOption =
        parser
            .acceptsAll(
                Arrays.asList("o", "owner"), "Owner of the bot (username of in-game control).")
            .withRequiredArg()
            .describedAs("username");
    OptionSpec<?> offlineOption =
        parser.acceptsAll(
            Arrays.asList("O", "offline"),
            "Offline-mode. Ignores 'password' and 'account-list' (will "
                + "generate random usernames if 'username' is not supplied).");
    OptionSpec<?> autoRejoinOption =
        parser.acceptsAll(Arrays.asList("a", "auto-rejoin"), "Auto-rejoin a server on disconnect.");
    OptionSpec<Integer> loginDelayOption =
        parser
            .acceptsAll(
                Arrays.asList("d", "login-delay"),
                "Delay between bot joins, in milliseconds. 5000 is "
                    + "recommended if not using socks proxies.")
            .withRequiredArg()
            .describedAs("delay")
            .ofType(Integer.class);
    OptionSpec<Integer> botAmountOption =
        parser
            .acceptsAll(
                Arrays.asList("b", "bot-amount"),
                "Amount of bots to join. Must be <= amount of accounts.")
            .withRequiredArg()
            .describedAs("amount")
            .ofType(Integer.class);

    OptionSpec<String> accountListOption =
        parser
            .accepts(
                "account-list",
                "File containing a list of accounts, in username/email:password format.")
            .withRequiredArg()
            .describedAs("file");
    OptionSpec<String> socksProxyListOption =
        parser
            .accepts(
                "socks-proxy-list",
                "File containing a list of SOCKS proxies, in address:port format.")
            .withRequiredArg()
            .describedAs("file");
    OptionSpec<String> httpProxyListOption =
        parser
            .accepts(
                "http-proxy-list",
                "File containing a list of HTTP proxies, in address:port format.")
            .withRequiredArg()
            .describedAs("file");

    OptionSet options;
    try {
      options = parser.parse(args);
    } catch (OptionException exception) {
      try {
        parser.printHelpOn(System.out);
      } catch (Exception exception1) {
        exception1.printStackTrace();
      }
      return;
    }

    if (options.has("help")) {
      printHelp(parser);
      return;
    }

    final boolean offline = options.has(offlineOption);
    final boolean autoRejoin = options.has(autoRejoinOption);

    final List<String> accounts;
    if (options.has(accountListOption)) {
      accounts = loadAccounts(options.valueOf(accountListOption));
    } else if (!offline) {
      System.out.println("Option 'accounts' must be supplied in " + "absence of option 'offline'.");
      printHelp(parser);
      return;
    } else accounts = null;

    final String server;
    if (!options.has(serverOption)) {
      System.out.println("Option 'server' required.");
      printHelp(parser);
      return;
    } else server = options.valueOf(serverOption);

    final String owner;
    if (!options.has(ownerOption)) {
      System.out.println("Option 'owner' required.");
      printHelp(parser);
      return;
    } else owner = options.valueOf(ownerOption);

    final List<String> socksProxies;
    if (options.has(socksProxyListOption))
      socksProxies = loadProxies(options.valueOf(socksProxyListOption));
    else socksProxies = null;
    final boolean useProxy = socksProxies != null;

    final List<String> httpProxies;
    if (options.has(httpProxyListOption))
      httpProxies = loadLoginProxies(options.valueOf(httpProxyListOption));
    else if (!offline && accounts != null) {
      System.out.println(
          "Option 'http-proxy-list' required if " + "option 'account-list' is supplied.");
      printHelp(parser);
      return;
    } else httpProxies = null;

    final int loginDelay;
    if (options.has(loginDelayOption)) loginDelay = options.valueOf(loginDelayOption);
    else loginDelay = 0;

    final int botAmount;
    if (!options.has(botAmountOption)) {
      System.out.println("Option 'bot-amount' required.");
      printHelp(parser);
      return;
    } else botAmount = options.valueOf(botAmountOption);

    initGui();
    while (!sessions.get()) {
      synchronized (sessions) {
        try {
          sessions.wait(5000);
        } catch (InterruptedException exception) {
        }
      }
    }

    final Queue<Runnable> lockQueue = new ArrayDeque<Runnable>();

    ExecutorService service = Executors.newFixedThreadPool(botAmount + (loginDelay > 0 ? 1 : 0));
    final Object firstWait = new Object();
    if (loginDelay > 0) {
      service.execute(
          new Runnable() {
            @Override
            public void run() {
              synchronized (firstWait) {
                try {
                  firstWait.wait();
                } catch (InterruptedException exception) {
                }
              }
              while (true) {
                if (die) return;
                while (slotsTaken.get() >= 2) {
                  synchronized (slotsTaken) {
                    try {
                      slotsTaken.wait(500);
                    } catch (InterruptedException exception) {
                    }
                  }
                }
                synchronized (lockQueue) {
                  if (lockQueue.size() > 0) {
                    Runnable thread = lockQueue.poll();
                    synchronized (thread) {
                      thread.notifyAll();
                    }
                    lockQueue.offer(thread);
                  } else continue;
                }
                try {
                  Thread.sleep(loginDelay);
                } catch (InterruptedException exception) {
                }
                while (!sessions.get()) {
                  synchronized (sessions) {
                    try {
                      sessions.wait(5000);
                    } catch (InterruptedException exception) {
                    }
                  }
                }
              }
            }
          });
    }
    final List<String> accountsInUse = new ArrayList<String>();
    for (int i = 0; i < botAmount; i++) {
      final int botNumber = i;
      Runnable runnable =
          new Runnable() {
            @Override
            public void run() {
              if (loginDelay > 0)
                synchronized (lockQueue) {
                  lockQueue.add(this);
                }
              Random random = new Random();

              if (!offline) {
                boolean authenticated = false;
                user:
                while (true) {
                  if (authenticated) {
                    authenticated = false;
                    sessionCount.decrementAndGet();
                  }
                  Session session = null;
                  String loginProxy;
                  String account = accounts.get(random.nextInt(accounts.size()));
                  synchronized (accountsInUse) {
                    if (accountsInUse.size() == accounts.size()) System.exit(0);
                    while (accountsInUse.contains(account))
                      account = accounts.get(random.nextInt(accounts.size()));
                    accountsInUse.add(account);
                  }
                  String[] accountParts = account.split(":");
                  while (true) {
                    while (!sessions.get()) {
                      synchronized (sessions) {
                        try {
                          sessions.wait(5000);
                        } catch (InterruptedException exception) {
                        }
                      }
                    }
                    loginProxy = httpProxies.get(random.nextInt(httpProxies.size()));
                    try {
                      session = Util.retrieveSession(accountParts[0], accountParts[1], loginProxy);
                      // addAccount(session);
                      sessionCount.incrementAndGet();
                      authenticated = true;
                      break;
                    } catch (AuthenticationException exception) {
                      System.err.println("[Bot" + botNumber + "] " + exception);
                      if (!exception.getMessage().startsWith("Exception"))
                        // && !exception.getMessage().equals(
                        // "Too many failed logins"))
                        continue user;
                    }
                  }
                  System.out.println(
                      "["
                          + session.getUsername()
                          + "] Password: "******", Session ID: "
                          + session.getSessionId());
                  while (!joins.get()) {
                    synchronized (joins) {
                      try {
                        joins.wait(5000);
                      } catch (InterruptedException exception) {
                      }
                    }
                  }
                  if (loginDelay > 0) {
                    synchronized (this) {
                      try {
                        synchronized (firstWait) {
                          firstWait.notifyAll();
                        }
                        wait();
                      } catch (InterruptedException exception) {
                      }
                    }
                  }

                  while (true) {
                    String proxy =
                        useProxy ? socksProxies.get(random.nextInt(socksProxies.size())) : null;
                    try {
                      new DarkBotMCSpambot(
                          DARK_BOT,
                          server,
                          session.getUsername(),
                          session.getPassword(),
                          session.getSessionId(),
                          null,
                          proxy,
                          owner);
                      if (die) break user;
                      else if (!autoRejoin) break;
                    } catch (Exception exception) {
                      exception.printStackTrace();
                      System.out.println(
                          "["
                              + session.getUsername()
                              + "] Error connecting: "
                              + exception.getCause().toString());
                    }
                  }
                  System.out.println("[" + session.getUsername() + "] Account failed");
                }
              } else {
                while (true) {
                  String proxy =
                      useProxy ? socksProxies.get(random.nextInt(socksProxies.size())) : null;
                  try {
                    String username = "";
                    if (accounts != null) {
                      username = accounts.get(random.nextInt(accounts.size())).split(":")[0];
                      synchronized (accountsInUse) {
                        while (accountsInUse.contains(username))
                          username = accounts.get(random.nextInt(accounts.size()));
                        accountsInUse.add(username);
                      }
                    } else
                      for (int i = 0; i < 10 + random.nextInt(6); i++)
                        username += alphas[random.nextInt(alphas.length)];
                    if (loginDelay > 0) {
                      synchronized (this) {
                        try {
                          synchronized (firstWait) {
                            firstWait.notifyAll();
                          }
                          wait();
                        } catch (InterruptedException exception) {
                        }
                      }
                    }
                    new DarkBotMCSpambot(DARK_BOT, server, username, "", "", null, proxy, owner);
                    if (die || !autoRejoin) break;
                    else continue;
                  } catch (Exception exception) {
                    System.out.println(
                        "[Bot" + botNumber + "] Error connecting: " + exception.toString());
                  }
                }
              }
            }
          };
      service.execute(runnable);
    }
    service.shutdown();
    while (!service.isTerminated()) {
      try {
        service.awaitTermination(9000, TimeUnit.DAYS);
      } catch (InterruptedException exception) {
        exception.printStackTrace();
      }
    }
    System.exit(0);
  }
  @Override
  public int run(String[] args) throws IOException {
    OptionParser p = new OptionParser();
    OptionSpec<String> maxwiOpt =
        p.accepts(maxwiOptName, "location of maxWi map file (HDFS) REQUIRED")
            .withRequiredArg()
            .ofType(String.class);
    OptionSpec<Float> thresholdOpt =
        p.accepts(thresholdOptName, "similarity threshold")
            .withRequiredArg()
            .ofType(Float.class)
            .defaultsTo(DEFAULT_THRESHOLD);
    OptionSpec<Integer> stripesOpt =
        p.accepts(stripesOptName, "number of stripes to divide the similarity matrix")
            .withRequiredArg()
            .ofType(Integer.class)
            .defaultsTo(1);
    OptionSpec<Integer> spreadOpt =
        p.accepts(spreadOptName, "number of reducers per stripe")
            .withRequiredArg()
            .ofType(Integer.class)
            .defaultsTo(DEFAULT_SPREAD);
    OptionSpec<Integer> factorOpt =
        p.accepts(factorOptName, "number of mappers per reducer")
            .withRequiredArg()
            .ofType(Integer.class)
            .defaultsTo(DEFAULT_FACTOR);
    OptionSpec<Integer> maxVectorIDOpt =
        p.accepts(maxVectorIDOptName, "maximum vector ID").withRequiredArg().ofType(Integer.class);
    p.acceptsAll(Arrays.asList("h", "?"), "show help");

    OptionSet options = parseOptions(p, args);

    // to distinguish indexes built in successive runs
    DateFormat df = new SimpleDateFormat("yyyyMMdd-HHmmss");
    Date date = new Date();

    float threshold = options.valueOf(thresholdOpt); // threshold
    if (threshold < 0 || threshold >= 1) {
      System.err.println(thresholdOptName + " should be between 0 and 1");
      System.exit(1);
    }

    int numStripes = options.valueOf(stripesOpt); // number of stripes
    if (numStripes < 1) {
      System.err.println(stripesOptName + " should be > 0");
      System.exit(1);
    }

    // MapReduce parameters
    int spread = options.valueOf(spreadOpt); // how many reducers per stripe
    if (spread < 1) {
      System.err.println(spreadOptName + " should be > 0");
      System.exit(1);
    }

    int factor = options.valueOf(factorOpt); // how many mappers per reducer
    if (factor < 1) {
      System.err.println(factorOptName + " should be > 0");
      System.exit(1);
    }

    int maxKey = 0;
    if (options.has(maxVectorIDOpt)) {
      maxKey = options.valueOf(maxVectorIDOpt); // maximum value of the vector ID
      if (maxKey < 1) {
        System.err.println(maxVectorIDOptName + " should be > 0");
        System.exit(1);
      }
    }

    int numReducers = GenericKey.StripePartitioner.numReducers(numStripes, spread);
    int numMappers = numReducers * factor;
    int numBuckets = numMappers;

    // pick the file with max weights from command line
    String maxWiDir = options.valueOf(maxwiOpt);
    List<String> nonOptArgs = options.nonOptionArguments();

    LOG.info("Threshold set to " + threshold);
    LOG.info(
        String.format(
            "Buckets: %1$-10s Factor: %2$-10s Stripes: %3$-10s Spread: %4$-10s Reducers: %5$-10s",
            numBuckets, factor, numStripes, spread, numReducers));

    // start building the jobs
    JobConf conf1 = new JobConf(getConf(), Similarity.class);
    conf1.setFloat(PARAM_APS_THRESHOLD, threshold);
    conf1.setInt(PARAM_APS_STRIPES, numStripes);
    DistributedCache.addCacheFile(URI.create(maxWiDir), conf1);

    Path inputPath = new Path(nonOptArgs.get(0));
    Path indexPath =
        new Path(
            nonOptArgs.get(0) + "-index-" + threshold + "-s" + numStripes + "_" + df.format(date));
    // index filtering pruned nested directory
    Path indexOnlyPath = new Path(indexPath, "part*");
    Path outputPath = new Path(nonOptArgs.get(1) + "-" + threshold + "-s" + numStripes);
    FileInputFormat.setInputPaths(conf1, inputPath);
    FileOutputFormat.setOutputPath(conf1, indexPath);

    conf1.setInputFormat(SequenceFileInputFormat.class);
    conf1.setOutputFormat(SequenceFileOutputFormat.class);
    conf1.setMapOutputKeyClass(LongWritable.class);
    conf1.setMapOutputValueClass(IndexItem.class);
    conf1.setOutputKeyClass(LongWritable.class);
    conf1.setOutputValueClass(IndexItemArrayWritable.class);
    conf1.setMapperClass(IndexerMapper.class);
    conf1.setReducerClass(IndexerReducer.class);

    // assuming input is sorted according to the key (vectorID) so that the
    // part files are locally sorted
    MultipleOutputs.addNamedOutput(
        conf1,
        PRUNED,
        SequenceFileOutputFormat.class,
        IntWritable.class,
        VectorComponentArrayWritable.class);

    // remove the stuff we added from the job name
    conf1.set(
        "mapred.job.name",
        "APS-" + indexPath.getName().substring(0, indexPath.getName().length() - 16));
    conf1.setNumTasksToExecutePerJvm(-1); // JVM reuse
    conf1.setSpeculativeExecution(false);
    conf1.setCompressMapOutput(true);
    // hash the posting lists in different buckets to distribute the load
    conf1.setNumReduceTasks(numBuckets);

    RunningJob job1 = JobClient.runJob(conf1);

    // part 2
    JobConf conf2 = new JobConf(getConf(), Similarity.class);

    if (numStripes > 0) FileUtils.mergeRestFile(conf2, indexPath, PRUNED, INDEX_INTERVAL);

    MultipleInputs.addInputPath(
        conf2, indexOnlyPath, SequenceFileInputFormat.class, SimilarityMapperIndex.class);
    MultipleInputs.addInputPath(
        conf2, inputPath, SequenceFileInputFormat.class, SimilarityMapperInput.class);
    FileOutputFormat.setOutputPath(conf2, outputPath);
    conf2.setCombinerClass(SimilarityCombiner.class);
    conf2.setReducerClass(SimilarityReducer.class);
    conf2.setPartitionerClass(GenericKey.StripePartitioner.class);
    conf2.setOutputKeyComparatorClass(GenericKey.Comparator.class);
    conf2.setOutputValueGroupingComparator(GenericKey.PrimaryComparator.class);
    conf2.setMapOutputKeyClass(GenericKey.class);
    conf2.setMapOutputValueClass(GenericValue.class);
    conf2.setOutputKeyClass(VectorPair.class);
    conf2.setOutputValueClass(NullWritable.class);

    Counter numDocs =
        job1.getCounters()
            .findCounter("org.apache.hadoop.mapred.Task$Counter", "MAP_INPUT_RECORDS");
    maxKey = maxKey > 0 ? maxKey : (int) numDocs.getValue();
    LOG.info("Setting max key value in input to " + maxKey);
    conf2.setInt(PARAM_APS_MAXKEY, maxKey);

    conf2.setInt(PARAM_APS_STRIPES, numStripes);
    conf2.setFloat(PARAM_APS_THRESHOLD, threshold);
    conf2.setInt(PARAM_APS_REDUCER_PER_STRIPE, spread);
    conf2.set("mapred.job.name", "APS-" + outputPath.getName());

    conf2.setNumTasksToExecutePerJvm(-1); // JVM reuse
    conf2.setSpeculativeExecution(false);
    conf2.setCompressMapOutput(true);
    conf2.setNumReduceTasks(numReducers);

    JobClient.runJob(conf2);

    return 0;
  }
  @Override
  public void configure(Binder binder) {
    OptionParser parser = new OptionParser();

    ArgumentAcceptingOptionSpec<Integer> portSpec =
        parser
            .accepts("port", "The port to listen on")
            .withOptionalArg()
            .ofType(Integer.class)
            .defaultsTo(8080);

    ArgumentAcceptingOptionSpec<String> addressSpec =
        parser
            .accepts("address", "The address to bind to")
            .withOptionalArg()
            .ofType(String.class)
            .defaultsTo("0.0.0.0");

    ArgumentAcceptingOptionSpec<Integer> proxyPortRange =
        parser
            .accepts("proxyPortRange", "The range of ports to use for proxies")
            .withOptionalArg()
            .ofType(Integer.class)
            .defaultsTo(8081, 8581)
            .withValuesSeparatedBy('-');

    ArgumentAcceptingOptionSpec<Integer> ttlSpec =
        parser
            .accepts("ttl", "Time in seconds until an unused proxy is deleted")
            .withOptionalArg()
            .ofType(Integer.class)
            .defaultsTo(0);

    parser.acceptsAll(asList("help", "?"), "This help text");

    OptionSet options = parser.parse(args);

    if (options.has("?")) {
      try {
        parser.printHelpOn(System.out);
        System.exit(0);
      } catch (IOException e) {
        // should never happen, but...
        e.printStackTrace();
      }
      return;
    }

    List<Integer> ports = options.valuesOf(proxyPortRange);
    if (ports.size() < 2) {
      throw new IllegalArgumentException();
    }
    Integer minPort;
    Integer maxPort;
    if (ports.get(1) > ports.get(0)) {
      minPort = ports.get(0);
      maxPort = ports.get(1);
    } else {
      minPort = ports.get(1);
      maxPort = ports.get(0);
    }
    Integer port = portSpec.value(options);
    if (port >= minPort && port <= maxPort) {
      int num = maxPort - minPort;
      minPort = port + 1;
      maxPort = minPort + num;
    }

    binder.bind(Key.get(Integer.class, new NamedImpl("port"))).toInstance(port);
    binder
        .bind(Key.get(String.class, new NamedImpl("address")))
        .toInstance(addressSpec.value(options));
    binder.bind(Key.get(Integer.class, new NamedImpl("minPort"))).toInstance(minPort);
    binder.bind(Key.get(Integer.class, new NamedImpl("maxPort"))).toInstance(maxPort);
    binder.bind(Key.get(Integer.class, new NamedImpl("ttl"))).toInstance(ttlSpec.value(options));

    /*
     * Init User Agent String Parser, update of the UAS datastore will run in background.
     */
    // temporarily disabled because user-agent-string.info no longer exists
    // BrowserMobHttpClient.getUserAgentStringParser();
  }
  public static void main(String[] args) {
    // TODO main
    OptionParser parser = new OptionParser();
    parser.acceptsAll(Arrays.asList("h", "help"), "Show this help dialog.");
    OptionSpec<String> serverOption =
        parser
            .acceptsAll(Arrays.asList("s", "server"), "Server to join.")
            .withRequiredArg()
            .describedAs("server-address[:port]");
    OptionSpec<String> proxyOption =
        parser
            .acceptsAll(
                Arrays.asList("P", "proxy"),
                "SOCKS proxy to use. Ignored in presence of 'socks-proxy-list'.")
            .withRequiredArg()
            .describedAs("proxy-address");
    OptionSpec<String> ownerOption =
        parser
            .acceptsAll(
                Arrays.asList("o", "owner"), "Owner of the bot (username of in-game control).")
            .withRequiredArg()
            .describedAs("username");
    OptionSpec<?> offlineOption =
        parser.acceptsAll(
            Arrays.asList("O", "offline"),
            "Offline-mode. Ignores 'password' and 'account-list' (will "
                + "generate random usernames if 'username' is not supplied).");
    OptionSpec<?> autoRejoinOption =
        parser.acceptsAll(Arrays.asList("a", "auto-rejoin"), "Auto-rejoin a server on disconnect.");
    OptionSpec<Integer> loginDelayOption =
        parser
            .acceptsAll(
                Arrays.asList("d", "login-delay"),
                "Delay between bot joins, in milliseconds. 5000 is "
                    + "recommended if not using socks proxies.")
            .withRequiredArg()
            .describedAs("delay")
            .ofType(Integer.class);
    OptionSpec<Integer> botAmountOption =
        parser
            .acceptsAll(
                Arrays.asList("b", "bot-amount"),
                "Amount of bots to join. Must be <= amount of accounts.")
            .withRequiredArg()
            .describedAs("amount")
            .ofType(Integer.class);
    OptionSpec<String> protocolOption =
        parser
            .accepts(
                "protocol",
                "Protocol version to use. Can be either protocol number or Minecraft version.")
            .withRequiredArg();
    OptionSpec<?> protocolsOption =
        parser.accepts("protocols", "List available protocols and exit.");

    OptionSpec<String> accountListOption =
        parser
            .accepts(
                "account-list",
                "File containing a list of accounts, in username/email:password format.")
            .withRequiredArg()
            .describedAs("file");
    OptionSpec<String> socksProxyListOption =
        parser
            .accepts(
                "socks-proxy-list",
                "File containing a list of SOCKS proxies, in address:port format.")
            .withRequiredArg()
            .describedAs("file");
    OptionSpec<String> httpProxyListOption =
        parser
            .accepts(
                "http-proxy-list",
                "File containing a list of HTTP proxies, in address:port format.")
            .withRequiredArg()
            .describedAs("file");
    OptionSpec<String> captchaListOption =
        parser
            .accepts("captcha-list", "File containing a list of chat baised captcha to bypass.")
            .withRequiredArg()
            .describedAs("file");

    OptionSet options;
    try {
      options = parser.parse(args);
    } catch (OptionException exception) {
      try {
        parser.printHelpOn(System.out);
      } catch (Exception exception1) {
        exception1.printStackTrace();
      }
      return;
    }

    if (options.has("help")) {
      printHelp(parser);
      return;
    }
    if (options.has(protocolsOption)) {
      System.out.println("Available protocols:");
      for (ProtocolProvider provider : ProtocolProvider.getProviders())
        System.out.println(
            "\t"
                + provider.getMinecraftVersion()
                + " ("
                + provider.getSupportedVersion()
                + "): "
                + provider.getClass().getName());
      System.out.println(
          "If no protocols are listed above, you may attempt to specify a protocol version in case the provider is actually in the class-path.");
      return;
    }

    final boolean offline = options.has(offlineOption);
    final boolean autoRejoin = options.has(autoRejoinOption);

    final List<String> accounts;
    if (options.has(accountListOption)) {
      accounts = loadAccounts(options.valueOf(accountListOption));
    } else if (!offline) {
      System.out.println("Option 'accounts' must be supplied in " + "absence of option 'offline'.");
      printHelp(parser);
      return;
    } else accounts = null;

    final List<String> captcha;
    if (options.has(captchaListOption)) readCaptchaFile(options.valueOf(captchaListOption));

    final String server;
    if (!options.has(serverOption)) {
      System.out.println("Option 'server' required.");
      printHelp(parser);
      return;
    } else server = options.valueOf(serverOption);

    final String owner;
    if (!options.has(ownerOption)) {
      System.out.println("Option 'owner' required.");
      printHelp(parser);
      return;
    } else owner = options.valueOf(ownerOption);

    final int protocol;
    if (options.has(protocolOption)) {
      String protocolString = options.valueOf(protocolOption);
      int parsedProtocol;
      try {
        parsedProtocol = Integer.parseInt(protocolString);
      } catch (NumberFormatException exception) {
        ProtocolProvider foundProvider = null;
        for (ProtocolProvider provider : ProtocolProvider.getProviders())
          if (protocolString.equals(provider.getMinecraftVersion())) foundProvider = provider;
        if (foundProvider == null) {
          System.out.println("No provider found for Minecraft version '" + protocolString + "'.");
          return;
        } else parsedProtocol = foundProvider.getSupportedVersion();
      }
      protocol = parsedProtocol;
    } else protocol = MinecraftBot.LATEST_PROTOCOL;

    final List<String> socksProxies;
    if (options.has(socksProxyListOption))
      socksProxies = loadProxies(options.valueOf(socksProxyListOption));
    else socksProxies = null;
    final boolean useProxy = socksProxies != null;

    final List<String> httpProxies;
    if (options.has(httpProxyListOption))
      httpProxies = loadLoginProxies(options.valueOf(httpProxyListOption));
    else if (!offline && accounts != null) {
      System.out.println(
          "Option 'http-proxy-list' required if " + "option 'account-list' is supplied.");
      printHelp(parser);
      return;
    } else httpProxies = null;

    final int loginDelay;
    if (options.has(loginDelayOption)) loginDelay = options.valueOf(loginDelayOption);
    else loginDelay = 0;

    final int botAmount;
    if (!options.has(botAmountOption)) {
      System.out.println("Option 'bot-amount' required.");
      printHelp(parser);
      return;
    } else botAmount = options.valueOf(botAmountOption);

    initGui();
    while (!sessions.get()) {
      synchronized (sessions) {
        try {
          sessions.wait(5000);
        } catch (InterruptedException exception) {
        }
      }
    }

    final Queue<Runnable> lockQueue = new ArrayDeque<Runnable>();

    ExecutorService service = Executors.newFixedThreadPool(botAmount + (loginDelay > 0 ? 1 : 0));
    final Object firstWait = new Object();
    if (loginDelay > 0) {
      service.execute(
          new Runnable() {
            @Override
            public void run() {
              synchronized (firstWait) {
                try {
                  firstWait.wait();
                } catch (InterruptedException exception) {
                }
              }
              while (true) {
                try {
                  Thread.sleep(loginDelay);
                } catch (InterruptedException exception) {
                }
                synchronized (lockQueue) {
                  if (lockQueue.size() > 0) {
                    Runnable thread = lockQueue.poll();
                    synchronized (thread) {
                      thread.notifyAll();
                    }
                    lockQueue.offer(thread);
                  } else continue;
                }
                while (!sessions.get()) {
                  synchronized (sessions) {
                    try {
                      sessions.wait(5000);
                    } catch (InterruptedException exception) {
                    }
                  }
                }
              }
            }
          });
    }
    final List<String> accountsInUse = new ArrayList<String>();
    final Map<String, AtomicInteger> workingProxies = new HashMap<String, AtomicInteger>();
    for (int i = 0; i < botAmount; i++) {
      final int botNumber = i;
      Runnable runnable =
          new Runnable() {
            @Override
            public void run() {
              if (loginDelay > 0)
                synchronized (lockQueue) {
                  lockQueue.add(this);
                }
              Random random = new Random();

              if (!offline) {
                AuthService authService = new LegacyAuthService();
                boolean authenticated = false;
                user:
                while (true) {
                  if (authenticated) {
                    authenticated = false;
                    sessionCount.decrementAndGet();
                  }
                  Session session = null;
                  String loginProxy;
                  String account = accounts.get(random.nextInt(accounts.size()));
                  synchronized (accountsInUse) {
                    if (accountsInUse.size() == accounts.size()) System.exit(0);
                    while (accountsInUse.contains(account))
                      account = accounts.get(random.nextInt(accounts.size()));
                    accountsInUse.add(account);
                  }
                  String[] accountParts = account.split(":");
                  while (true) {
                    while (!sessions.get()) {
                      synchronized (sessions) {
                        try {
                          sessions.wait(5000);
                        } catch (InterruptedException exception) {
                        }
                      }
                    }
                    synchronized (workingProxies) {
                      Iterator<String> iterator = workingProxies.keySet().iterator();
                      if (iterator.hasNext()) loginProxy = iterator.next();
                      else loginProxy = httpProxies.get(random.nextInt(httpProxies.size()));
                      ;
                    }
                    try {
                      session =
                          authService.login(
                              accountParts[0],
                              accountParts[1],
                              toProxy(loginProxy, Proxy.Type.HTTP));
                      // addAccount(session);
                      synchronized (workingProxies) {
                        AtomicInteger count = workingProxies.get(loginProxy);
                        if (count != null) count.set(0);
                        else workingProxies.put(loginProxy, new AtomicInteger());
                      }
                      sessionCount.incrementAndGet();
                      authenticated = true;
                      break;
                    } catch (IOException exception) {
                      synchronized (workingProxies) {
                        workingProxies.remove(loginProxy);
                      }
                      System.err.println("[Bot" + botNumber + "] " + loginProxy + ": " + exception);
                    } catch (AuthenticationException exception) {
                      if (exception.getMessage().contains("Too many failed logins")) {
                        synchronized (workingProxies) {
                          AtomicInteger count = workingProxies.get(loginProxy);
                          if (count != null && count.incrementAndGet() >= 5)
                            workingProxies.remove(loginProxy);
                        }
                      }
                      System.err.println("[Bot" + botNumber + "] " + loginProxy + ": " + exception);
                      continue user;
                    }
                  }
                  System.out.println("[" + session.getUsername() + "] " + session);
                  while (!joins.get()) {
                    synchronized (joins) {
                      try {
                        joins.wait(5000);
                      } catch (InterruptedException exception) {
                      }
                    }
                  }
                  if (loginDelay > 0) {
                    synchronized (this) {
                      try {
                        synchronized (firstWait) {
                          firstWait.notifyAll();
                        }
                        wait();
                      } catch (InterruptedException exception) {
                      }
                    }
                  }

                  while (true) {
                    String proxy =
                        useProxy ? socksProxies.get(random.nextInt(socksProxies.size())) : null;
                    try {
                      DarkBotMCSpambot bot =
                          new DarkBotMCSpambot(
                              generateData(
                                  server,
                                  session.getUsername(),
                                  session.getPassword(),
                                  authService,
                                  session,
                                  protocol,
                                  null,
                                  proxy),
                              owner);
                      while (bot.getBot().isConnected()) {
                        try {
                          Thread.sleep(500);
                        } catch (InterruptedException exception) {
                          exception.printStackTrace();
                        }
                      }
                      if (!autoRejoin) break;
                    } catch (Exception exception) {
                      exception.printStackTrace();
                      System.out.println(
                          "["
                              + session.getUsername()
                              + "] Error connecting: "
                              + exception.getCause().toString());
                    }
                  }
                  System.out.println("[" + session.getUsername() + "] Account failed");
                }
              } else {
                while (true) {
                  String proxy =
                      useProxy ? socksProxies.get(random.nextInt(socksProxies.size())) : null;
                  try {
                    String username;
                    if (accounts != null) {
                      username = accounts.get(random.nextInt(accounts.size())).split(":")[0];
                      synchronized (accountsInUse) {
                        while (accountsInUse.contains(username))
                          username = accounts.get(random.nextInt(accounts.size()));
                        accountsInUse.add(username);
                      }
                    } else username = Util.generateRandomString(10 + random.nextInt(6));
                    if (loginDelay > 0) {
                      synchronized (this) {
                        try {
                          synchronized (firstWait) {
                            firstWait.notifyAll();
                          }
                          wait();
                        } catch (InterruptedException exception) {
                        }
                      }
                    }
                    DarkBotMCSpambot bot =
                        new DarkBotMCSpambot(
                            generateData(server, username, null, null, null, protocol, null, proxy),
                            owner);
                    while (bot.getBot().isConnected()) {
                      try {
                        Thread.sleep(500);
                      } catch (InterruptedException exception) {
                        exception.printStackTrace();
                      }
                    }
                    if (!autoRejoin) break;
                    else continue;
                  } catch (Exception exception) {
                    System.out.println(
                        "[Bot" + botNumber + "] Error connecting: " + exception.toString());
                  }
                }
              }
            }
          };
      service.execute(runnable);
    }
    service.shutdown();
    while (!service.isTerminated()) {
      try {
        service.awaitTermination(9000, TimeUnit.DAYS);
      } catch (InterruptedException exception) {
        exception.printStackTrace();
      }
    }
    System.exit(0);
  }