Package net.bnubot.vercheck

Source Code of net.bnubot.vercheck.VersionCheck

/**
* This file is distributed under the GPL
* $Id: VersionCheck.java 1810 2009-06-22 17:33:07Z scotta $
*/

package net.bnubot.vercheck;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;

import javax.swing.JOptionPane;

import net.bnubot.core.ChatQueue;
import net.bnubot.core.PluginManager;
import net.bnubot.logging.Out;
import net.bnubot.settings.GlobalSettings;
import net.bnubot.settings.Settings;
import net.bnubot.util.BNetUser;
import net.bnubot.util.OperatingSystem;
import net.bnubot.util.SHA1Sum;
import net.bnubot.util.URLDownloader;

import org.jbls.util.Constants;

/**
* @author scotta
*/
public class VersionCheck {
  private static final String VERSION_CHECK_TIME = "versionCheckTime";

  protected static XMLElementDecorator elem = null;
  protected static VersionNumber vnLatest = null;

  /**
   * Helper method to the version check
   * @param force If enabled, do the version check no matter what. Otherwise, only do it once every six hours
   * @return True if there was an update; false if none available or no version check was performed
   * @throws Exception If an error occurred
   */
  public static boolean checkVersion(boolean force) throws Exception {
    return checkVersion(force, null, false);
  }

  public static boolean checkVersion(boolean force, BNetUser bnSubject, boolean whisperBack) throws Exception {
    if(!force) {
      final long lastVersionCheck = Settings.getSection(null).read(VERSION_CHECK_TIME, 0l);
      long now = System.currentTimeMillis();
      // Wait 6 hours
      if(now - lastVersionCheck < 6 * 60 * 60 * 1000)
        return false;
    }

    return checkVersion(false, GlobalSettings.releaseType, bnSubject, whisperBack);
  }

  /**
   * Helper method to the version check
   * @see #doCheckVersion(boolean, ReleaseType, String, String)
   */
  private static boolean checkVersion(boolean forceDownload, ReleaseType rt, BNetUser bnSubject, boolean whisperBack) throws Exception {
    if(CurrentVersion.fromJar()) {
      String path = System.getProperty("net.bnubot.jarpath", "BNUBot.jar");
      if(!new File(path).exists())
        throw new FileNotFoundException(path);
      return checkVersion(forceDownload, rt, path, null, bnSubject, whisperBack);
    }

    return checkVersion(false, rt, null, null, bnSubject, whisperBack);
  }

  /**
   * Helper method to the version check
   * This method is protected because it is used by InstallMain
   * @see #doCheckVersion(boolean, ReleaseType, String, String)
   */
  protected static boolean checkVersion(boolean forceDownload, ReleaseType rt, String jarFileName, String downloadFolder) throws Exception {
    return checkVersion(forceDownload, rt, jarFileName, downloadFolder, null, false);
  }

  private static boolean checkVersion(boolean forceDownload, ReleaseType rt, String jarFileName, String downloadFolder, BNetUser bnSubject, boolean whisperBack) throws Exception {
    boolean cv = doCheckVersion(forceDownload, rt, jarFileName, downloadFolder, bnSubject, whisperBack);
    URLDownloader.flush();
    if(!cv)
      if(bnSubject == null)
        Out.debug(VersionCheck.class, "No update available.");
      else
        bnSubject.sendChat("No update available.", whisperBack);
    return cv;
  }

  /**
   * Go ahead and do the version check for real now
   * @param forceDownload Install mode: don't ask any questions, just download everything
   * @param rt The ReleaseType to check for
   * @param jarFileName Location of BNUBot.jar
   * @param downloadFolder Location of the install path
   * @param bnSubject The user to send information to
   * @param whisperBack Was the initial command a whisper?
   * @return whether an update is available
   * @throws Exception if an error occurred
   */
  private static boolean doCheckVersion(boolean forceDownload, ReleaseType rt, String jarFileName, String downloadFolder, BNetUser bnSubject, boolean whisperBack) throws Exception {
    if(!forceDownload) {
      Settings.getSection(null).write(VERSION_CHECK_TIME, System.currentTimeMillis());
      Settings.store();
    }

    try {
      String url = "http://www.clanbnu.net/bnubot/version.php?";
      if(!forceDownload && (CurrentVersion.version().getSvnRevision() != null))
        url += "svn=" + CurrentVersion.version().getSvnRevision() + "&";
      url += "release=" + rt.toString();
      url += "&os=" + OperatingSystem.userOS.name();
      if(Out.isDebug(VersionCheck.class))
        Out.debugAlways(VersionCheck.class, "Requesting latest version from " + url);
      elem = XMLElementDecorator.parse(url);
    } catch(Exception e) {
      if(bnSubject == null)
        Out.error(VersionCheck.class, "Failed to get latest version: " + e.getClass().getSimpleName() + ".");
      else
        bnSubject.sendChat("Failed to get latest version: " + e.getClass().getSimpleName() + ".", whisperBack);
      return false;
    }

    if(downloadFolder != null)
      jarFileName = downloadFolder + File.separatorChar + jarFileName;

    XMLElementDecorator error = elem.getChild("error");
    if(error != null) {
      if(bnSubject == null)
        Out.error(VersionCheck.class, error.getString());
      else
        bnSubject.sendChat(error.getString(), whisperBack);
      return false;
    }

    XMLElementDecorator motd = elem.getPath("bnubot/motd");
    if((motd != null) && (motd.getString() != null))
      Out.info(VersionCheck.class, motd.getString());

    if(forceDownload || CurrentVersion.fromJar()) {
      XMLElementDecorator downloads = elem.getPath("bnubot/downloads");
      if(downloads != null) {
        for(XMLElementDecorator file : downloads.getChildren("file")) {
          XMLElementDecorator sha1Element = file.getChild("sha1");
          SHA1Sum sha1 = null;
          if(sha1Element != null)
            sha1 = new SHA1Sum(sha1Element.getString());
          String from = file.getChild("from").getString();
          String to = file.getChild("to").getString();
          if(downloadFolder != null)
            to = downloadFolder + File.separatorChar + to;
          URLDownloader.downloadURL(
            new URL(from),
            new File(to),
            sha1,
            false);
        }
      }
    }

    XMLElementDecorator gamesElem = elem.getPath("bnubot/games");
    if(gamesElem != null)
      for(int i = 0; i < Constants.prods.length; i++) {
        String game = Constants.prods[i];
        int verByte = Constants.IX86verbytes[i];

        XMLElementDecorator gameElem = gamesElem.getPath(game);
        if(gameElem == null)
          continue;

        int vb = gameElem.getPath("verbyte").getInt();

        if(verByte != vb) {
          Out.error(VersionCheck.class, "Verbyte for game " + game + " is updating from 0x" + Integer.toHexString(verByte) + " to 0x" + Integer.toHexString(vb));
          Constants.IX86verbytes[i] = vb;
        }
      }

    XMLElementDecorator verLatest = elem.getPath("bnubot/latestVersion");
    if(verLatest == null)
      return false;

    String releaseType = verLatest.getChild("type").getString();
    // FIXME: this is for logging, to collect data
    if(releaseType == null)
      throw new NullPointerException("type is null\n" + verLatest.toString());
    vnLatest = new VersionNumber(
        Enum.valueOf(ReleaseType.class, releaseType),
        verLatest.getChild("major").getInt(),
        verLatest.getChild("minor").getInt(),
        verLatest.getChild("revision").getInt(),
        verLatest.getChild("release").getInt(),
        verLatest.getChild("svn").getInt(),
        verLatest.getChild("built").getDate());

    String url = verLatest.getChild("url").getString();

    XMLElementDecorator sha1Element = verLatest.getChild("sha1");
    SHA1Sum sha1 = null;
    if((sha1Element != null) && (sha1Element.getString() != null))
      sha1 = new SHA1Sum(sha1Element.getString());

    if(forceDownload) {
      if(url == null)
        return false;

      URLDownloader.downloadURL(new URL(url), new File(jarFileName), sha1, true);
      return true;
    }

    if(!vnLatest.isNewerThan(CurrentVersion.version()))
      return false;

    Out.error(VersionCheck.class, "Latest version: " + vnLatest.toString());

    if(url == null)
      return true;

    if(jarFileName != null) {
      File thisJar = new File(jarFileName);
      if(thisJar.exists()) {
        boolean doUpdate = true;
        try {
          if((bnSubject == null) && PluginManager.getEnableGui()) {
            String msg = "BNU-Bot version " + vnLatest.toString() + " is available.\nWould you like to update?";
            doUpdate = JOptionPane.showConfirmDialog(null, msg, "BNU-Bot update available", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION;
          }
        } catch(Exception e) {
          // GUI is probably broken
          Out.exception(e);
        }
        if(doUpdate) {
          // Find the parent folder
          String parentFolder = thisJar.getAbsolutePath();
          parentFolder = parentFolder.substring(0, parentFolder.lastIndexOf(File.separatorChar) + 1);

          // Download to download.jar
          File to = new File(parentFolder + "download.jar");
          URLDownloader.downloadURL(new URL(url), to, sha1, true);
          URLDownloader.flush();

          String command;
          switch(OperatingSystem.userOS) {
          case WINDOWS:
            command = "BNUBot.exe";
            break;
          case OSX:
            command = "Contents/MacOS/JavaApplicationStub";
            break;
          default:
            command = "./run.sh";
            break;
          }

          // Swap the files
          renameFile(thisJar, new File(parentFolder + CurrentVersion.version().toFileName()));
          renameFile(to, thisJar);
          to.delete();

          // Show complete notification
          try {
            if((bnSubject == null) && PluginManager.getEnableGui())
              JOptionPane.showMessageDialog(null, "Update complete. BNU-Bot will now attempt to restart.");
          } catch(Exception e) {
            // GUI is probably broken
            Out.exception(e);
          }

          if(bnSubject != null) {
            bnSubject.sendChat("Updated to " + vnLatest.toString() + "; restarting", whisperBack);

            // Wait a maximum of 10 seconds for the queue to empty
            long target = System.currentTimeMillis() + 10000;
            ChatQueue cq = bnSubject.getConnection().getProfile().getChatQueue();
            while((cq.size() > 0) && (target > System.currentTimeMillis())) {
              Thread.sleep(100);
              Thread.yield();
            }
          }

          try {
            Runtime.getRuntime().exec(command);
          } catch (Throwable e) {
            // Restart failed; oh well, nothing we can do about it now!
            Out.exception(e);
          }
          System.exit(0);
        }
        return true;
      }
    }

    Out.error(VersionCheck.class, "Update: " + url);
    return true;
  }

  private static void renameFile(File from, File to) throws IOException {
    if(from.renameTo(to))
      return;

    // Windows doesn't allow renaming open files; copy the contents instead
    FileInputStream is = new FileInputStream(from);
    FileOutputStream os = new FileOutputStream(to);
    byte[] b = new byte[1024];

    do {
      int c = is.read(b);
      if(c == -1)
        break;
      os.write(b, 0, c);
    } while(true);

    os.close();
    is.close();

    to.setLastModified(from.lastModified());
  }
}
TOP

Related Classes of net.bnubot.vercheck.VersionCheck

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.