Package net.bnubot.core.bnls

Source Code of net.bnubot.core.bnls.BNLSConnection

/**
* This file is distributed under the GPL
* $Id: BNLSConnection.java 1896 2014-02-11 10:57:38Z scotta $
*/

package net.bnubot.core.bnls;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;

import net.bnubot.core.bncs.ProductIDs;
import net.bnubot.logging.Out;
import net.bnubot.settings.GlobalSettings;
import net.bnubot.util.BNetInputStream;
import net.bnubot.util.MirrorSelector;
import net.bnubot.util.crypto.HexDump;
import net.bnubot.util.task.Task;

/**
* @author scotta
*/
public class BNLSConnection {

  private Socket bnlsSocket = null;
  private InputStream bnlsInputStream = null;
  private OutputStream bnlsOutputStream = null;

  private void setBNLSConnected(boolean c) throws IOException {
    if(bnlsSocket != null) {
      bnlsSocket.close();
      bnlsSocket = null;
      bnlsInputStream = null;
      bnlsOutputStream = null;
    }

    if(c) {
      InetAddress address = MirrorSelector.getClosestMirror(GlobalSettings.bnlsServer, GlobalSettings.bnlsPort);
      Out.info(getClass(), "Connecting to " + address + ":" + GlobalSettings.bnlsPort + ".");
      bnlsSocket = new Socket(address, GlobalSettings.bnlsPort);
      bnlsSocket.setKeepAlive(true);
      bnlsInputStream = bnlsSocket.getInputStream();
      bnlsOutputStream = bnlsSocket.getOutputStream();
    }
  }


  /**
   * Connect to BNLS and get verbyte
   * @param connect
   * @throws IOException
   * @throws SocketException
   */
  public void initialize() throws IOException {
    // Connect to BNLS
    setBNLSConnected(true);

    // Send BNLS_AUTHORIZE
    try (BNLSPacket loginPacket = new BNLSPacket(BNLSPacketId.BNLS_AUTHORIZE)) {
      loginPacket.writeNTString("bnu2");
      loginPacket.sendPacket(bnlsOutputStream);
    }

    // Recieve BNLS_AUTHORIZE
    BNetInputStream is = readPacket(BNLSPacketId.BNLS_AUTHORIZE);
    int serverCode = is.readDWord();

    // Calculate checksum
    int checksum = (int) (org.jbls.BNLSProtocol.BNLSlist.BNLSChecksum(
        "bot", serverCode) & 0xFFFFFFFF);

    // Send BNLS_AUTHORIZEPROOF
    try (BNLSPacket loginPacket = new BNLSPacket(BNLSPacketId.BNLS_AUTHORIZEPROOF)) {
      loginPacket.writeDWord(checksum);
      loginPacket.sendPacket(bnlsOutputStream);
    }

    // Recieve BNLS_AUTHORIZEPROOF
    is = readPacket(BNLSPacketId.BNLS_AUTHORIZEPROOF);
    int statusCode = is.readDWord();
    if (statusCode != 0)
      Out.error(getClass(), "Login to BNLS failed; logged in anonymously");
  }

  public int getVerByte(ProductIDs product) throws IOException {
    // Ask BNLS for the verbyte
    try (BNLSPacket vbPacket = new BNLSPacket(BNLSPacketId.BNLS_REQUESTVERSIONBYTE)) {
      vbPacket.writeDWord(product.getBnls());
      vbPacket.sendPacket(bnlsOutputStream);
      vbPacket.close();
    }

    BNetInputStream vbInputStream = readPacket(BNLSPacketId.BNLS_REQUESTVERSIONBYTE);
    int vbProduct = vbInputStream.readDWord();
    if (vbProduct == 0)
      throw new IOException("BNLS_REQUESTVERSIONBYTE failed.");
    if(vbProduct != product.getBnls())
      throw new IOException("BNLS_REQUESTVERSIONBYTE returned the wrong product [0x" + Integer.toHexString(vbProduct) + "]");
    return vbInputStream.readWord();
  }

  public VersionCheckResult sendVersionCheckEx2(Task task, ProductIDs productID, long MPQFileTime, String MPQFileName, byte[] ValueStr) throws IOException, InterruptedException {
    try (BNLSPacket bnlsOut = new BNLSPacket(BNLSPacketId.BNLS_VERSIONCHECKEX2)) {
      bnlsOut.writeDWord(productID.getBnls());
      bnlsOut.writeDWord(0); // Flags
      bnlsOut.writeDWord(0); // Cookie
      bnlsOut.writeQWord(MPQFileTime);
      bnlsOut.writeNTString(MPQFileName);
      bnlsOut.writeNTString(ValueStr);
      bnlsOut.sendPacket(bnlsOutputStream);

      long startTime = System.currentTimeMillis();
      task.setDeterminate(15000, "ms");
      while (bnlsInputStream.available() < 3) {
        Thread.sleep(50);

        long timeElapsed = System.currentTimeMillis() - startTime;
        if (timeElapsed > 15000) {
          Out.error(getClass(), "BNLS_VERSIONCHECKEX2 timed out");
          setBNLSConnected(false);
          return null;
        }

        task.setProgress((int) timeElapsed);
      }
      task.complete();

      BNLSPacketReader bpr = new BNLSPacketReader(bnlsInputStream);
      if(bpr.packetId != BNLSPacketId.BNLS_VERSIONCHECKEX2)
        throw new IOException("Recieved the wrong packet (" + bpr.packetId.name() + ", but expected BNLS_VERSIONCHECKEX2)");
      BNetInputStream bnlsIn = bpr.getInputStream();
      int success = bnlsIn.readDWord();
      if (success != 1) {
        Out.error(getClass(), "BNLS_VERSIONCHECKEX2 Failed\n"
            + HexDump.hexDump(bpr.getData()));
        setBNLSConnected(false);
        return null;
      }

      VersionCheckResult vcr = new VersionCheckResult();
      vcr.exeVersion = bnlsIn.readDWord();
      vcr.exeHash = bnlsIn.readDWord();
      vcr.exeInfo = bnlsIn.readNTBytes();
      bnlsIn.readDWord(); // cookie
      bnlsIn.readDWord(); // verbyte
      assert (bnlsIn.available() == 0);

      Out.info(getClass(), "Recieved version check from BNLS.");

      if((vcr.exeVersion == 0)
      || (vcr.exeHash == 0)
      || (vcr.exeInfo == null)
      || (vcr.exeInfo.length == 0)) {
        Out.error(getClass(), "Recieved invalid CheckRevision data.");
        return null;
      }

      // Everything went well!
      return vcr;
    } catch (UnknownHostException e) {
      setBNLSConnected(false);
      Out.error(getClass(), "BNLS connection failed: " + e.getMessage());
      return null;
    }
  }

  public void keepAlive() throws IOException {
    try (BNLSPacket p = new BNLSPacket(BNLSPacketId.BNLS_NULL)) {
      p.sendPacket(bnlsOutputStream);
    }
  }

  private BNetInputStream readPacket(BNLSPacketId expected) throws IOException {
    BNLSPacketReader pr = new BNLSPacketReader(bnlsInputStream);
    if(pr.packetId != expected)
      throw new IOException("Recieved the wrong packet (" + pr.packetId.name() + ", but expected " + expected.name() + ")");
    return pr.getInputStream();
  }

  public BNetInputStream sendWarden0(int cookie, int client, byte[] seed) throws IOException {
    try (BNLSPacket p = new BNLSPacket(BNLSPacketId.BNLS_WARDEN)) {
      p.writeByte(0);
      p.writeDWord(cookie);
      p.writeDWord(client);
      p.writeWord(seed.length);
      p.write(seed);
      p.writeNTString("");
      p.writeWord(0);
      p.sendPacket(bnlsOutputStream);
    }

    return readPacket(BNLSPacketId.BNLS_WARDEN);
  }

  public BNetInputStream sendWarden1(int cookie, byte[] payload) throws IOException {
    try (BNLSPacket p = new BNLSPacket(BNLSPacketId.BNLS_WARDEN)) {
      p.writeByte(1);
      p.writeDWord(cookie);
      p.writeWord(payload.length);
      p.write(payload);
      p.sendPacket(bnlsOutputStream);
    }

    return readPacket(BNLSPacketId.BNLS_WARDEN);
  }
}
TOP

Related Classes of net.bnubot.core.bnls.BNLSConnection

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.