/**
  * Writes the <code>shape</code>, <code>coords</code>, <code>href</code>,
  * <code>nohref</code> Attribute for the specified figure and ellipse.
  *
  * @return Returns true, if the circle is inside of the image bounds.
  */
 private boolean writeCircleAttributes(IXMLElement elem, SVGFigure f, Ellipse2D.Double ellipse) {
     AffineTransform t = TRANSFORM.getClone(f);
     if (t == null) {
         t = drawingTransform;
     } else {
         t.preConcatenate(drawingTransform);
     }
     
     if ((t.getType() &
             (AffineTransform.TYPE_UNIFORM_SCALE | AffineTransform.TYPE_TRANSLATION)) ==
             t.getType() &&
             ellipse.width == ellipse.height
             ) {
         
         Point2D.Double start = new Point2D.Double(ellipse.x, ellipse.y);
         Point2D.Double end = new Point2D.Double(ellipse.x + ellipse.width, ellipse.y + ellipse.height);
         t.transform(start, start);
         t.transform(end, end);
         ellipse.x = Math.min(start.x, end.x);
         ellipse.y = Math.min(start.y, end.y);
         ellipse.width = Math.abs(start.x - end.x);
         ellipse.height = Math.abs(start.y - end.y);
         
         elem.setAttribute("shape", "circle");
         elem.setAttribute("coords",
                 (int) (ellipse.x + ellipse.width / 2d)+","+
                 (int) (ellipse.y + ellipse.height / 2d)+","+
                 (int) (ellipse.width / 2d)
                 );
         writeHrefAttribute(elem, f);
         return bounds.intersects(ellipse.getBounds());
     } else {
         return writePolyAttributes(elem, f, (Shape) ellipse);
     }
 }
 protected void drawImageMosaic(Graphics2D g2) {
   // Break the image up into tiles. Draw each
   //   tile with its own transparency, allowing
   //   the background to show through to varying
   //   degrees.
   int side = 36;
   int width = mImage.getWidth();
   int height = mImage.getHeight();
   for (int y = 0; y < height; y += side) {
     for (int x = 0; x < width; x += side) {
       // Calculate an appropriate transparency value.
       float xBias = (float) x / (float) width;
       float yBias = (float) y / (float) height;
       float alpha = 1.0f - Math.abs(xBias - yBias);
       g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha));
       // Draw the subimage.
       int w = Math.min(side, width - x);
       int h = Math.min(side, height - y);
       BufferedImage tile = mImage.getSubimage(x, y, w, h);
       g2.drawImage(tile, x, y, null);
     }
   }
   // Reset the composite.
   g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
 }
Exemple #3
0
 public int rate() {
   int score = 0;
   int cur = 1;
   for (int i = 0; i < properties.values.size(); i++) {
     score += 10000 - Math.min(10000, Math.abs((1 << i) - properties.values.get(i)));
   }
   return score;
 }
  private void updateLoader() {
    if (NavigineApp.Navigation == null) return;

    // Log.d(TAG, String.format(Locale.ENGLISH, "Update loader: %d", mLoader));

    long timeNow = DateTimeUtils.currentTimeMillis();
    if (mLoader < 0) return;

    int status = LocationLoader.checkLocationLoader(mLoader);
    if (status < 100) {
      if ((Math.abs(timeNow - mLoaderTime) > LOADER_TIMEOUT / 3 && status == 0)
          || (Math.abs(timeNow - mLoaderTime) > LOADER_TIMEOUT)) {
        mListView.setVisibility(View.GONE);
        mStatusLabel.setVisibility(View.VISIBLE);
        mStatusLabel.setText("Loading timeout!\nPlease, check your internet connection!");
        Log.d(TAG, String.format(Locale.ENGLISH, "Load stopped on timeout!"));
        LocationLoader.stopLocationLoader(mLoader);
        mLoader = -1;
      } else {
        mListView.setVisibility(View.GONE);
        mStatusLabel.setVisibility(View.VISIBLE);
        mStatusLabel.setText(String.format(Locale.ENGLISH, "Loading content (%d%%)", status));
      }
    } else {
      Log.d(TAG, String.format(Locale.ENGLISH, "Load finished with result: %d", status));
      LocationLoader.stopLocationLoader(mLoader);
      mLoader = -1;

      if (status == 100) {
        parseMapsXml();
        if (mInfoList.isEmpty()) {
          mListView.setVisibility(View.GONE);
          mStatusLabel.setVisibility(View.VISIBLE);
          mStatusLabel.setText("No locations available");
        } else {
          mListView.setVisibility(View.VISIBLE);
          mStatusLabel.setVisibility(View.GONE);
        }
      } else {
        mListView.setVisibility(View.GONE);
        mStatusLabel.setVisibility(View.VISIBLE);
        mStatusLabel.setText("Error loading!\nPlease, check your ID!");
      }
    }
  }
 public void nudge(int i) {
   x[i] += (double) rand.nextInt(1000) / 8756;
   y[i] += (double) rand.nextInt(1000) / 5432;
   int tmpScale = (int) (Math.abs(Math.sin(x[i])) * 10);
   scale[i] = (double) tmpScale / 10;
   int nudgeX = (int) (((double) getWidth() / 2) * .8);
   int nudgeY = (int) (((double) getHeight() / 2) * .60);
   xh[i] = (int) (Math.sin(x[i]) * nudgeX) + nudgeX;
   yh[i] = (int) (Math.sin(y[i]) * nudgeY) + nudgeY;
 }
  public void paint(Graphics g) {
    Graphics2D g2d = (Graphics2D) g;
    if (is) {
      if (true) {
        g.clearRect(0, 0, getSize().width, getSize().height);
      }
    }
    if (flagtool == 2) { // 清除

      g.clearRect(0, 0, getSize().width, getSize().height);
    }
    for (int i = 0; i < points.size() - 1; i++) {
      p1 = (onePoint) points.elementAt(i);
      p2 = (onePoint) points.elementAt(i + 1);

      g2d.setColor(p1.c); // ////////////需要使用Graphics2D从Graphics类中继承下来的方法 setColor()设置当前的颜色
      size = new BasicStroke(p1.border, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND);
      g2d.setStroke(size);
      if (p1.tool == p2.tool) {
        switch (p1.tool) {
          case 0:
            Line2D.Double line1 = new Line2D.Double(p1.x, p1.y, p2.x, p2.y);
            g2d.draw(line1);
            break;
          case 1:
            Line2D.Double line2 = new Line2D.Double(p1.x, p1.y, p2.x, p2.y);
            g2d.draw(line2);
            break;
          case 3:
            Ellipse2D.Double ellipse =
                new Ellipse2D.Double(p1.x, p1.y, Math.abs(p2.x - p1.x), Math.abs(p2.y - p1.y));
            g2d.draw(ellipse);
            break;
          case 4:
            Rectangle2D.Double rect =
                new Rectangle2D.Double(p1.x, p1.y, Math.abs(p2.x - p1.x), Math.abs(p2.y - p1.y));
            g2d.draw(rect);
            break;
          default:
        }
      }
    }
  }
        public void run() {
          if (NavigineApp.Navigation == null) return;

          long timeNow = DateTimeUtils.currentTimeMillis();

          String userHash = NavigineApp.Settings.getString("user_hash", "");
          if (userHash.length() == 0) return;

          if (mLoader >= 0) updateLoader();

          if (Math.abs(timeNow - mUpdateLocationLoadersTime) > 1000) updateLocationLoaders();
        }
Exemple #8
0
 /**
  * returns in the form " X hours and Y minutes from now/ago" or " RIGHT NOW!" it returns nothing
  * if the difference is > 1 day
  */
 private String getTimeDifference(int mins) {
   if (Math.abs(mins) > 60 * 24) {
     return "";
   }
   boolean neg = mins < 0;
   mins = Math.abs(mins);
   if (mins < 5) {
     return " ****THAT'S RIGHT NOW!****";
   }
   String ret = " (";
   int hrs = mins / 60;
   mins = mins % 60;
   if (hrs > 0) {
     ret = ret + hrs + " hours and ";
   }
   ret = ret + mins + " minutes ";
   if (neg) {
     ret = ret + "ago)";
   } else ret = ret + "from now)";
   return ret;
 }
Exemple #9
0
 public void shuffle() {
   for (int i = 0; i < 3; i++) {
     for (int j = 0; j < num_cards; j++) {
       int k = Math.abs(rand.nextInt() % num_cards);
       /* swap */
       int temp = deck[j];
       deck[j] = deck[k];
       deck[k] = temp;
     }
   }
   current = 0;
 }
Exemple #10
0
  // override me
  public void doZoomIn(Rectangle rbRect) {
    int x = rbRect.x - mLeft - 5;
    int y = rbRect.y - mTop - 5;

    // zoom in
    double xInc = getXZoomIncrement();
    double yInc = getYZoomIncrement();

    // get coordinates of new view center
    // correct the x value if necessary
    double xx = correctX((double) x);

    // correct the Y coordinate if necessary
    double yy = correctY((double) y);

    double newXCtr = (xx / winXScale) + winXOrigin;
    double newYCtr = (yy / winYScale) + winYOrigin;

    // compute the deltas for current range
    double xDelta = Math.abs(getMaxXVal() - getMinXVal()) / 2.0;
    double yDelta = Math.abs(getMaxYVal() - getMinYVal()) / 2.0;

    // compute the aspect ratio of the few
    double aspect = xDelta / yDelta;
    // if (aspect > 1.0)
    // xInc *= aspect;
    // else
    // yInc *= aspect;

    double newXMin = newXCtr < 0 ? newXCtr - xDelta + xInc : newXCtr - xDelta + xInc;
    double newXMax = newXCtr < 0 ? newXCtr + xDelta - xInc : newXCtr + xDelta - xInc;
    double newYMin = newYCtr < 0 ? newYCtr - yDelta + yInc : newYCtr - yDelta + yInc;
    double newYMax = newYCtr < 0 ? newYCtr + yDelta - yInc : newYCtr + yDelta - yInc;

    double[] oldYs = {getMinYVal(), getMaxYVal()};
    double[] newYs = {newYMin, newYMax};
    double[] oldXs = {getMinXVal(), getMaxXVal()};
    double[] newXs = {newXMin, newXMax};
    this.zoomDomain(oldYs, newYs, oldXs, newXs);
  }
 /**
  * All other write methods delegate their work to here.
  */
 public void write(OutputStream out, java.util.List<Figure> figures) throws IOException {
     Rectangle2D.Double drawingRect = null;
     
     for (Figure f : figures) {
         if (drawingRect == null) {
             drawingRect = f.getBounds();
         } else {
             drawingRect.add(f.getBounds());
         }
     }
     
     AffineTransform drawingTransform = new AffineTransform();
     drawingTransform.translate(
             -Math.min(0, drawingRect.x),
             -Math.min(0, drawingRect.y)
             );
     
     write(out, figures, drawingTransform,
             new Dimension(
             (int) (Math.abs(drawingRect.x) + drawingRect.width),
             (int) (Math.abs(drawingRect.y) + drawingRect.height))
             );
 }
 /**
  * Writes the <code>shape</code>, <code>coords</code>, <code>href</code>,
  * <code>nohref</code> Attribute for the specified figure and rectangle.
  *
  * @return Returns true, if the rect is inside of the image bounds.
  */
 private boolean writeRectAttributes(IXMLElement elem, SVGFigure f, Rectangle2D.Double rect) {
     AffineTransform t = TRANSFORM.getClone(f);
     if (t == null) {
         t = drawingTransform;
     } else {
         t.preConcatenate(drawingTransform);
     }
     
     if ((t.getType() &
             (AffineTransform.TYPE_UNIFORM_SCALE | AffineTransform.TYPE_TRANSLATION)) ==
             t.getType()
             ) {
         
         Point2D.Double start = new Point2D.Double(rect.x, rect.y);
         Point2D.Double end = new Point2D.Double(rect.x + rect.width, rect.y + rect.height);
         t.transform(start, start);
         t.transform(end, end);
         Rectangle r = new Rectangle(
                 (int) Math.min(start.x, end.x),
                 (int) Math.min(start.y, end.y),
                 (int) Math.abs(start.x - end.x),
                 (int) Math.abs(start.y - end.y)
                 );
         
         elem.setAttribute("shape", "rect");
         elem.setAttribute("coords",
                 r.x + ","+
                 r.y + ","+
                 (r.x + r.width) + ","+
                 (r.y + r.height)
                 );
         writeHrefAttribute(elem, f);
         return bounds.intersects(r);
     } else {
         return writePolyAttributes(elem, f, (Shape) rect);
     }
 }
  private void updateLocationLoaders() {
    if (NavigineApp.Navigation == null) return;

    long timeNow = DateTimeUtils.currentTimeMillis();
    mUpdateLocationLoadersTime = timeNow;

    synchronized (mLoaderMap) {
      Iterator<Map.Entry<String, LoaderState>> iter = mLoaderMap.entrySet().iterator();
      while (iter.hasNext()) {
        Map.Entry<String, LoaderState> entry = iter.next();

        LoaderState loader = entry.getValue();
        if (loader.state < 100) {
          loader.timeLabel = timeNow;
          if (loader.type == DOWNLOAD) loader.state = LocationLoader.checkLocationLoader(loader.id);
          if (loader.type == UPLOAD) loader.state = LocationLoader.checkLocationUploader(loader.id);
        } else if (loader.state == 100) {
          String archivePath = NavigineApp.Navigation.getArchivePath();
          String locationFile =
              LocationLoader.getLocationFile(NavigineApp.AppContext, loader.location);
          if (archivePath != null && archivePath.equals(locationFile)) {
            Log.d(TAG, "Reloading archive " + archivePath);
            if (NavigineApp.Navigation.loadArchive(archivePath)) {
              SharedPreferences.Editor editor = NavigineApp.Settings.edit();
              editor.putString("map_file", archivePath);
              editor.commit();
            }
          }
          if (loader.type == DOWNLOAD) LocationLoader.stopLocationLoader(loader.id);
          if (loader.type == UPLOAD) LocationLoader.stopLocationUploader(loader.id);
          iter.remove();
        } else {
          // Load failed
          if (Math.abs(timeNow - loader.timeLabel) > 5000) {
            if (loader.type == DOWNLOAD) LocationLoader.stopLocationLoader(loader.id);
            if (loader.type == UPLOAD) LocationLoader.stopLocationUploader(loader.id);
            iter.remove();
          }
        }
      }
    }
    updateLocalVersions();
    mAdapter.updateList();
  }
  public Track chooseTrack(Random random) {
    Track[] tracks = getTracks();
    float[] probs = new float[tracks.length];

    float totalProb = 0;
    for (int i = 0; i < tracks.length; i++) {
      totalProb += getProbability(tracks[i]);
      probs[i] = totalProb;
      //      System.out.println(Float.toString(totalProb) + " " + getProbability(tracks[i]) + " " +
      // tracks[i]);
    }

    if (totalProb == 0) return null;

    while (true) {
      float rand = Math.abs(random.nextFloat()) * totalProb;
      //      System.out.println("r=" + Float.toString(rand));
      for (int i = 0; i < tracks.length; i++) if (rand <= probs[i]) return tracks[i];
    }
  }
 public static double factorY(double h) {
   return h * height / Math.abs(ymax - ymin);
 }
 public static double factorX(double w) {
   return w * width / Math.abs(xmax - xmin);
 }
Exemple #17
0
  // ------------------------------------------------------------------
  // initialize the canvas contents or judge the user's mouse events and respond
  public void paint(Graphics g) {

    // if forceNumber < 0 and !mUp: do nothing until mUp

    // if forceNumber < 0 and mUp (click): start the forces
    if (forceNumber < 0 && mUp) {
      fInit = true;
      mDown = false;
      // next line added 4/17/08 (correction for case of zero force true answer)
      mUp = false;
      forceNumber = 0;
      forceName = forceNames[forceNumber];
      userPosX = tailPosX;
      userPosY = tailPosY;
      numTries = 0;
      messageCanvas.notifyMouseClick(blinkerStrings[forceNumber]);
      // create the force equation and vector objects
      canvasEquation = new CanvasEquation(g);
      canvasVector = new CanvasVector(g);
    }

    // if mouseDown and all forces finished: do end game
    if (mDown && (forceNumber == maxForceNumber + 1)) {
      endGame("OK", cgiScript, problemNo, mouseUpsString);
    }

    // if mouseDown or mouseDrag and really a force:
    //     erase user's old vector & eqn, update position
    if ((mDown || mDrag) && (forceNumber >= 0) && (forceNumber <= maxForceNumber)) {
      messageCanvas.notifyMouseDown(blinkerStrings[forceNumber]);
      eraseUserStuff(g, forceX[0], forceY[0], 0);
      if (numEquations == 2) {
        eraseUserStuff(g, forceX[1], forceY[1], 1);
      }
      userPosX = newUserPosX;
      userPosY = newUserPosY;
    }

    // if browserPaint or forceInit or mouseDown or mouseDrag and really a force:
    //     plot fixed & user's new stuff
    if ((ifBrowserPaint || fInit || mDown || mDrag)
        && (forceNumber >= 0)
        && (forceNumber <= maxForceNumber)) {

      // redraw the userCanvas bounding box and the apparatus
      g.setColor(Color.black);
      g.drawRect(0, 0, userFrameX, userFrameY);
      problemSelector.drawUserApparatus(g);

      // draw the user's previously-done correct vectors
      if (forceNumber > 0) {
        drawDoneVectors(forceNumber - 1, g);
      }

      // draw the user's new vector and equation
      canvasVector.plotVector(tailPosX, tailPosY, userPosX, userPosY, g);
      forceX[0] = p2fX(userPosX, userPosY);
      forceY[0] = p2fY(userPosX, userPosY);
      canvasEquation.plotEquation(g, forceName, units, forceX[0], forceY[0], 0);
      if (numEquations == 2) {
        forceX[1] = (int) Math.round(cost * forceX[0] - sint * forceY[0]);
        forceY[1] = (int) Math.round(sint * forceX[0] + cost * forceY[0]);
        canvasEquation.plotEquation(g, forceName, units, forceX[1], forceY[1], 1);
      }

      // get ready up for new input
      fInit = mDown = mDrag = false;
      if (ifBrowserPaint) {
        ifBrowserPaint = false;
      }
    }

    // if mouseUp, evaluate the user's answer
    if (mUp && (forceNumber >= 0) && (forceNumber < numForces)) {

      // keep track of the mouse ups
      String leftStr = "";
      String rightStr = "";
      String midStr = mouseUpsString.substring(forceNumber, forceNumber + 1);
      if (forceNumber > 0) {
        leftStr = mouseUpsString.substring(0, forceNumber);
      }
      if (forceNumber < numForces - 1) {
        rightStr = mouseUpsString.substring(forceNumber + 1, numForces);
      }
      int numTries = Integer.parseInt(midStr);
      numTries++;
      if (numTries <= 9) {
        midStr = Integer.toString(numTries);
      } else {
        midStr = "9";
      }
      mouseUpsString = leftStr + midStr + rightStr;

      // if correct, cycle to the next force or to the trailer message
      int matchIndex = matchForceComps[forceNumber] - 1;

      int depX = Math.abs(forceX[matchIndex] - truAnsX[forceNumber][matchIndex]);
      int depY = Math.abs(forceY[matchIndex] - truAnsY[forceNumber][matchIndex]);
      if ((depX <= forceTolerance) && (depY <= forceTolerance)) {

        // erase the user's stuff
        for (int n = 0; n <= numEquations - 1; n++) {
          eraseUserStuff(g, forceX[n], forceY[n], n);
        }

        // draw the apparatus
        problemSelector.drawUserApparatus(g);

        // draw the set of correctly done vectors
        drawDoneVectors(forceNumber, g);

        // notify the resultsCanvas of the user's correctly drawn force
        boolean ifResultsDone = false;
        if (forceNumber == maxForceNumber) {
          ifResultsDone = true;
        }
        resultsCanvas.notifyMouseUpOk(
            ifResultsDone,
            forceNumber,
            forceNames,
            units,
            truAnsX,
            truAnsY,
            resultsSpacingStrings,
            numEquations,
            numForces);

        // cycle the force or do the end game
        if (forceNumber < maxForceNumber) {
          forceNumber++;
          numTries = 0;
          forceName = forceNames[forceNumber];
          userPosX = tailPosX;
          userPosY = tailPosY;
          forceX[0] = forceY[0] = forceX[1] = forceY[1] = 0;
          // draw the equation and message for the *next* force
          for (int n = 0; n <= numEquations - 1; n++) {
            canvasEquation.plotEquation(g, forceName, units, forceX[n], forceY[n], n);
          }
          // notify the messageCanvas that there is a new force
          messageCanvas.notifyMouseUpOk(blinkerStrings[forceNumber]);
        } else {
          g.setColor(userTrailerColor);
          g.drawString(userTrailer, userTrailerPosX, userTrailerPosY);
          // notify the messageCanvas that we are all done
          messageCanvas.notifyMouseUpOk("done");
          forceNumber++;
        }
      }
      // if not correct and mode > 1, check # of tries
      else {
        if (problemMode > 1 && numTries >= maxTriesEachForce) {
          endGame("notOK", cgiScript, problemNo, mouseUpsString);
        }
      }
      fInit = mUp = mDown = false;
    }
  }
package qat.common;
Exemple #19
0
 /** Grab random num for task id */
 String createUniqueId() {
   return "" + Integer.toString(Math.abs(r.nextInt()), 36);
 }
 /**
  * Parses the given text into a Java class capable of being run
  *
  * @param text the text of the script/class to parse
  * @return the main class defined in the given script
  */
 public Class parseClass(String text) throws CompilationFailedException {
   return parseClass(
       text, "script" + System.currentTimeMillis() + Math.abs(text.hashCode()) + ".groovy");
 }
public class BNetProtocol {

  protected Socket socket = null;
  private BNetInputStream BNInputStream = null;
  private DataOutputStream BNetOutputStream = null;

  private int serverToken = 0;
  private final int clientToken = Math.abs(new Random().nextInt());

  private Integer nlsRevision = null;

  private SRP srp = null;

  protected Socket makeSocket(String address, int port) throws UnknownHostException, IOException {
    Socket s;
    InetAddress addr = InetAddress.getByName(address);
    s = new Socket(addr, port);
    s.setKeepAlive(true);
    return s;
  }

  public BNetProtocol() {}

  public void BNetConnect() throws Exception {
    socket = makeSocket("119.194.195.251", 5004);
    BNInputStream = new BNetInputStream(socket.getInputStream());
    BNetOutputStream = new DataOutputStream(socket.getOutputStream());

    socket.setSoTimeout(1000);

    BNetOutputStream.writeByte(0x01);

    System.out.println("Connect to Server");

    BNetAuthInfo();
  }

  public void BNetAuthInfo() throws IOException {
    BNetProtocolPacket p;
    int tzBias = TimeZone.getDefault().getOffset(System.currentTimeMillis()) / -60000;

    p = new BNetProtocolPacket(BNetProtocolPacketId.SID_AUTH_INFO);
    p.writeDWord(0);
    p.writeDWord(0x49583836); // Platform IX86
    p.writeDWord(0x57335850); // Warcraft III
    p.writeDWord(0x00000000); // Version byte
    p.writeDWord("koKR");
    p.writeDWord(0); // Local IP
    p.writeDWord(tzBias); // TZ bias
    p.writeDWord(0x412); // Locale ID
    p.writeDWord(0x412); // Language ID
    p.writeNTString("KOR"); // Country abreviation
    p.writeNTString("Korea"); // Country
    p.sendPacket(BNetOutputStream);
  }

  private BNetPacketReader obtainPacket() throws IOException {
    byte magic;
    do {
      magic = BNInputStream.readByte();
    } while (magic != (byte) 0xFF);
    try {
      return new BNetPacketReader(BNInputStream);
    } catch (SocketTimeoutException e) {
      throw new IOException("Unexpected socket timeout while reading packet", e);
    }
  }

  public void BNetLogin() throws Exception {
    while (!socket.isClosed()) {
      BNetPacketReader pr;
      try {
        pr = obtainPacket();
      } catch (SocketTimeoutException e) {
        continue;
      } catch (SocketException e) {
        if (socket == null) break;
        if (socket.isClosed()) break;
        throw e;
      }

      BNetInputStream is = pr.getData();
      switch (pr.packetId) {
        case SID_OPTIONALWORK:
        case SID_EXTRAWORK:
        case SID_REQUIREDWORK:
          break;
        case SID_NULL:
          {
            BNetProtocolPacket p = new BNetProtocolPacket(BNetProtocolPacketId.SID_NULL);
            p.sendPacket(BNetOutputStream);
            break;
          }

        case SID_PING:
          {
            System.out.println("PONG!");
            BNetProtocolPacket p = new BNetProtocolPacket(BNetProtocolPacketId.SID_PING);
            p.writeDWord(is.readDWord());
            p.sendPacket(BNetOutputStream);
            break;
          }

        case SID_AUTH_INFO:
          {
            if (pr.packetId == BNetProtocolPacketId.SID_AUTH_INFO) {
              nlsRevision = is.readDWord();
              serverToken = is.readDWord();
              is.skip(4); // int udpValue = is.readDWord();
            }
            assert (is.available() == 0);

            BNetProtocolPacket p = new BNetProtocolPacket(BNetProtocolPacketId.SID_AUTH_CHECK);
            p.writeDWord(clientToken); // Client Token
            p.writeDWord(0x1015019c); // EXE Version
            p.writeDWord(0x1b375294); // EXE Hash
            p.writeDWord(1); // Number of CD-Keys
            p.writeDWord(0); // Spawn CD-Key
            p.writeDWord(0x00000000);
            p.writeDWord(0x00000000);
            p.writeDWord(0x00000000);
            p.writeDWord(0x00000000);
            p.writeDWord(0x00000000);
            p.writeDWord(0x00000000);
            p.writeDWord(0x00000000);
            p.writeDWord(0x00000000);
            p.writeDWord(0x00000000);
            p.writeNTString("war3.exe 03/18/11 20:03:55 471040");
            p.writeNTString("Chat");
            p.sendPacket(BNetOutputStream);
            break;
          }

        case SID_AUTH_CHECK:
          {
            int result = is.readDWord();
            String extraInfo = is.readNTString();
            assert (is.available() == 0);

            if (pr.packetId == BNetProtocolPacketId.SID_AUTH_CHECK) {
              if (result != 0) {
                switch (result) {
                  case 0x211:
                    System.out.println("BANNED!" + extraInfo);
                    break;
                  default:
                    System.out.println("Unknown Error" + Integer.toHexString(result));
                    break;
                    // todo: disconnect socket
                }
                System.out.println("Disconnect!" + extraInfo);
                break;
              }
              System.out.println("Passed Check Revision");
            } else {
              if (result != 2) {
                // todo: disconnect socket
                System.out.println("Failed Version Check!");
                break;
              }
              System.out.println("Passed Check Revision");
            }
            sendAuth();
            break;
          }

        case SID_LOGONRESPONSE2:
          {
            int result = is.readDWord();
            switch (result) {
              case 0x00: // Success
                System.out.println("Login successful; entering chat.");
                sendEnterChat();
                sendJoinChannelFirst();
                break;
              case 0x01:
                // todo: disconnect socket
                System.out.println("Account does not Exist");
                break;
              case 0x02:
                // todo: disconnect socket
                System.out.println("Incorrect password.");
                break;
              case 0x06: // Account is closed
                // todo: disconnect socket
                System.out.println("Your account is locked.");
                break;
              default:
                // todo: disconnect socket
                System.out.println("Unknown ERROR.");
                break;
            }
            break;
          }

        case SID_ENTERCHAT:
          {
            String uniqueUserName = is.readNTString();

            BNetChat();
          }
      }
    }
  }

  public void sendAuth() throws Exception {
    String username = "******";
    String password = "******";
    int passwordHash[] = DoubleHash.doubleHash(password.toLowerCase(), clientToken, serverToken);

    BNetProtocolPacket p = new BNetProtocolPacket(BNetProtocolPacketId.SID_LOGONRESPONSE2);
    p.writeDWord(clientToken);
    p.writeDWord(serverToken);
    p.writeDWord(passwordHash[0]);
    p.writeDWord(passwordHash[1]);
    p.writeDWord(passwordHash[2]);
    p.writeDWord(passwordHash[3]);
    p.writeDWord(passwordHash[4]);
    p.writeNTString(username);
    p.sendPacket(BNetOutputStream);
  }

  private void sendEnterChat() throws Exception {
    BNetProtocolPacket p = new BNetProtocolPacket(BNetProtocolPacketId.SID_ENTERCHAT);
    p.writeNTString("");
    p.writeNTString("");
    p.sendPacket(BNetOutputStream);
  }

  public void sendJoinChannelFirst() throws Exception {
    BNetProtocolPacket p = new BNetProtocolPacket(BNetProtocolPacketId.SID_JOINCHANNEL);
    p.writeDWord(1);
    p.writeNTString("W3");
    p.sendPacket(BNetOutputStream);
  }

  private void BNetChat() throws Exception {
    while (!socket.isClosed()) {
      BNetPacketReader pr;
      try {
        pr = obtainPacket();
      } catch (SocketTimeoutException e) {
        continue;
      } catch (SocketException e) {
        if (socket == null) break;
        if (socket.isClosed()) break;
        throw e;
      }

      BNetInputStream is = pr.getData();
      switch (pr.packetId) {
        case SID_CHATEVENT:
          {
            BNetChatEventId eid = BNetChatEventId.values()[is.readDWord()];
            int flags = is.readDWord();
            int ping = is.readDWord();
            is.skip(12);
            String username = is.readNTString();
            ByteArray data = null;
            StatString statstr = null;

            System.out.println(username + ":");

            switch (eid) {
              case EID_SHOWUSER:
              case EID_USERFLAGS:
              case EID_JOIN:
              case EID_LEAVE:
              case EID_TALK:
              case EID_EMOTE:
              case EID_WHISPERSENT:
              case EID_WHISPER:
                {
                  System.out.println(is.readNTString());
                  break;
                }
            }
          }
      }
    }
  }

  public void sendChatCommand(ByteArray data) {
    try {
      BNetProtocolPacket p = new BNetProtocolPacket(BNetProtocolPacketId.SID_CHATCOMMAND);
      p.writeNTString(data);
      p.sendPacket(BNetOutputStream);
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
}