Refactored The Version Checker

Now the version checker supports downloading for every single BCV release
This commit is contained in:
Konloch 2021-07-21 12:55:03 -07:00
parent 7b227bb10e
commit d8c88b18d1
4 changed files with 317 additions and 5 deletions

View file

@ -31,6 +31,7 @@ public class HTTPRequest {
private DataOutputStream writer;
private HttpURLConnection connection;
private Set<Entry<String, List<String>>> lastConnectionHeaders;
private int statusCode;
/**
* Creates a new HTTPRequest object
@ -89,7 +90,12 @@ public class HTTPRequest {
public Set<Entry<String, List<String>>> getLastConnectionHeaders() {
return lastConnectionHeaders;
}
public int getStatusCode()
{
return statusCode;
}
/**
* By default follow redirects are enabled
*/
@ -147,6 +153,7 @@ public class HTTPRequest {
st.add(s);
lastConnectionHeaders = connection.getHeaderFields().entrySet();
statusCode = connection.getResponseCode();
} catch (Exception e) {
cleanup();
throw e;
@ -178,6 +185,7 @@ public class HTTPRequest {
}
lastConnectionHeaders = connection.getHeaderFields().entrySet();
statusCode = connection.getResponseCode();
} catch (Exception e) {
cleanup();
throw e;
@ -203,6 +211,7 @@ public class HTTPRequest {
s = reader.readLine();
lastConnectionHeaders = connection.getHeaderFields().entrySet();
statusCode = connection.getResponseCode();
} catch (Exception e) {
cleanup();
throw e;
@ -232,6 +241,7 @@ public class HTTPRequest {
s = reader.readLine();
lastConnectionHeaders = connection.getHeaderFields().entrySet();
statusCode = connection.getResponseCode();
} catch (Exception e) {
cleanup();
throw e;

View file

@ -16,6 +16,7 @@ import me.konloch.kontainer.io.DiskReader;
import the.bytecode.club.bytecodeviewer.bootloader.Boot;
import the.bytecode.club.bytecodeviewer.api.BCV;
import the.bytecode.club.bytecodeviewer.api.ExceptionUI;
import the.bytecode.club.bytecodeviewer.bootloader.UpdateCheck;
import the.bytecode.club.bytecodeviewer.gui.MainViewerGUI;
import the.bytecode.club.bytecodeviewer.gui.components.*;
import the.bytecode.club.bytecodeviewer.gui.resourceviewer.TabbedPane;
@ -146,7 +147,7 @@ public class BytecodeViewer
public static final Gson gson = new GsonBuilder().setPrettyPrinting().create();
//Threads
private static final Thread versionChecker = new Thread(new VersionChecker(), "Version Checker");
private static final Thread versionChecker = new Thread(new UpdateCheck(), "Version Checker");
private static final Thread pingBack = new Thread(new PingBack(), "Pingback");
private static final Thread installFatJar = new Thread(new InstallFatJar(), "Install Fat-Jar");
private static final Thread bootCheck = new Thread(new BootCheck(), "Boot Check");

View file

@ -46,7 +46,7 @@ public class Constants
public static boolean DEV_MODE;
//if true the version checker will prompt and ask how you would like to proceed
public static final boolean TEST_VERSION_CHECKER = false;
public static final boolean FORCE_VERSION_CHECKER_PROMPT = false;
public static final String fs = System.getProperty("file.separator");
public static final String nl = System.getProperty("line.separator");
@ -114,8 +114,8 @@ public class Constants
*/
public static String getVersion(String mavenVersion)
{
if(TEST_VERSION_CHECKER)
return "2.10.1";
if(FORCE_VERSION_CHECKER_PROMPT)
return "9.9.9";
if(mavenVersion == null)
{

View file

@ -0,0 +1,301 @@
package the.bytecode.club.bytecodeviewer.bootloader;
import de.skuzzle.semantic.Version;
import me.konloch.kontainer.io.HTTPRequest;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.Configuration;
import the.bytecode.club.bytecodeviewer.api.BCV;
import the.bytecode.club.bytecodeviewer.gui.components.FileChooser;
import the.bytecode.club.bytecodeviewer.gui.components.MultipleChoiceDialog;
import the.bytecode.club.bytecodeviewer.translation.TranslatedStrings;
import javax.swing.*;
import java.awt.*;
import java.io.*;
import java.net.URI;
import java.net.URL;
import static the.bytecode.club.bytecodeviewer.Constants.*;
/***************************************************************************
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
* Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
/**
* @author Konloch
*/
public class UpdateCheck implements Runnable
{
//just brute force download the url path
//one of these works for every single version of BCV
public static final String[] remoteGithubReleases = new String[]
{
//current url scheme since v2.9.12
"https://github.com/Konloch/bytecode-viewer/releases/download/v{VERSION}/Bytecode-Viewer-{VERSION}.jar",
//for v2.9.10 and v2.9.11
"https://github.com/Konloch/bytecode-viewer/releases/download/{VERSION}/Bytecode-Viewer-{VERSION}.jar",
//for v2.7.0 to v2.9.8
"https://github.com/Konloch/bytecode-viewer/releases/download/v{VERSION}/BytecodeViewer.{VERSION}.zip",
//for v2.0 to v2.6.0
"https://github.com/Konloch/bytecode-viewer/releases/download/v{VERSION}/BytecodeViewer.{VERSION}.jar",
//for v1.1 to v1.5.3
"https://github.com/Konloch/bytecode-viewer/releases/download/b{VERSION}/BytecodeViewer.Beta.{VERSION}.jar",
//for v1.4
"https://github.com/Konloch/bytecode-viewer/releases/download/b.{VERSION}/BytecodeViewer.Beta.{VERSION}.jar",
//for v1.0
"https://github.com/Konloch/bytecode-viewer/releases/download/B{VERSION}/BytecodeViewer.jar",
};
//a list of all of the released versions of BCV
public static final String[] versions = new String[]
{
"2.10.14",
"2.10.13",
"2.10.12",
"2.10.11",
"2.9.22",
"2.9.21",
"2.9.20",
"2.9.19",
"2.9.18",
"2.9.17",
"2.9.16",
"2.9.15",
"2.9.14",
"2.9.13",
"2.9.12",
"2.9.11",
"2.9.10", //broken due to repo change
"2.9.8", //broken due to repo change & zip
"2.9.7", //broken due to repo change & zip
"2.9.6", //zip
"2.9.5", //zip
"2.9.4", //zip
"2.9.3", //zip
"2.9.2", //zip
"2.9.1", //zip
"2.9.0", //zip
"2.8.1", //zip
"2.8.0", //zip
"2.7.1", //zip
"2.7.0", //zip
"2.6.0",
"2.5.2",
"2.5.1",
"2.5.0",
"2.4.0",
"2.3.0",
"2.2.1",
"2.2.0",
"2.1.1",
"2.1.0",
"2.0.1",
"2.0",
"1.5.3",
"1.5.2",
"1.5.1",
"1.5",
"1.4",
"1.3.1",
"1.3",
"1.2",
"1.1",
"1.0",
};
@Override
public void run()
{
try {
HTTPRequest r = new HTTPRequest(new URL("https://raw.githubusercontent.com/Konloch/bytecode-viewer/master/VERSION"));
final Version version = Version.parseVersion(r.readSingle());
final Version localVersion = Version.parseVersion(VERSION);
try {
//developer version
if (!localVersion.isGreaterThan(version))
return;
} catch (Exception ignored) { }
MultipleChoiceDialog outdatedDialog = new MultipleChoiceDialog("Bytecode Viewer - Outdated Version",
"Your version: " + localVersion + ", latest version: " + version + nl +
"What would you like to do?",
new String[]{"Open The Download Page", "Download The Updated Jar", "Do Nothing (And Don't Ask Again)"});
int result = outdatedDialog.promptChoice();
if (result == 0)
{
if (Desktop.isDesktopSupported())
Desktop.getDesktop().browse(new URI("https://github.com/Konloch/bytecode-viewer/releases"));
else
BytecodeViewer.showMessage("Cannot open the page, please manually type it."
+ nl + "https://github.com/Konloch/bytecode-viewer/releases");
}
else if (result == 1)
{
//TODO move this to after the file extension has been found
final File file = promptFileSave("Jar Archives", "jar");
if(file != null)
{
Thread downloadThread = new Thread(() ->
downloadBCV(version.toString(), file, ()->{}, ()->{}), "Downloader");
downloadThread.start();
}
}
else if(result == 2)
{
//TODO save version into a hashset called doNotPrompt
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static File promptFileSave(String description, String extension) throws IOException
{
JFileChooser fc = new FileChooser(new File("./").getCanonicalFile(),
"Select Save File", description, extension);
int returnVal = fc.showSaveDialog(BytecodeViewer.viewer);
File file = null;
if (returnVal == JFileChooser.APPROVE_OPTION)
{
Configuration.setLastOpenDirectory(fc.getSelectedFile());
file = fc.getSelectedFile();
String nameLowercase = file.getAbsolutePath().toLowerCase();
if (!nameLowercase.endsWith(".jar"))
file = new File(file.getAbsolutePath() + ".jar");
if (file.exists())
{
MultipleChoiceDialog overwriteDialog = new MultipleChoiceDialog("Bytecode Viewer - Overwrite File",
"The file " + file + " exists, would you like to overwrite it?",
new String[]{TranslatedStrings.YES.toString(), TranslatedStrings.NO.toString()});
if (overwriteDialog.promptChoice() != 0)
return null;
file.delete();
}
}
return file;
}
//used to download all released versions of BCV
/*public static void main(String[] args)
{
BytecodeViewer.viewer = new MainViewerGUI();
for(String version : versions)
{
//TODO most are jars, check which are zip and append zip as needed
File file = new File("./" + version + ".zip");
if(!file.exists())
downloadBCV(version, file, () -> {}, () -> {});
}
}*/
private static void downloadBCV(String version, File saveTo, Runnable onFinish, Runnable onFail)
{
boolean found = false;
for(String urlAttempt : remoteGithubReleases)
{
try
{
String url = urlAttempt.replace("{VERSION}", version);
if(validURl(url))
{
download(url, saveTo, onFinish);
found = true;
break;
}
} catch (FileNotFoundException ex) {
//ignore 404s
} catch (Exception e) {
//print network errors but don't alert user
e.printStackTrace();
}
}
if(!found)
{
BCV.logE("Failed to download BCV v" + version);
BytecodeViewer.showMessage("Unable to download BCV v" + version + ", please let Konloch know.");
onFail.run();
}
}
private static boolean validURl(String url) throws Exception
{
HTTPRequest request = new HTTPRequest(new URL(url));
request.readSingle();
return request.getStatusCode() == 200;
}
private static void download(String url, File saveTo, Runnable onFinish) throws Exception
{
BCV.log("Downloading from: " + url);
BytecodeViewer.showMessage("Downloading the jar in the background, when it's finished you will be alerted with another message box."
+ nl + nl + "Expect this to take several minutes.");
InputStream is = new URL(url).openConnection().getInputStream();
FileOutputStream fos = new FileOutputStream(saveTo);
try
{
byte[] buffer = new byte[8192];
int len;
int downloaded = 0;
boolean flag = false;
while ((len = is.read(buffer)) > 0)
{
fos.write(buffer, 0, len);
fos.flush();
downloaded += 8192;
int mbs = downloaded / 1048576;
if (mbs % 5 == 0 && mbs != 0)
{
if (!flag)
System.out.println("Downloaded " + mbs + "MBs so far");
flag = true;
} else
flag = false;
}
} finally {
try {
if (is != null)
is.close();
} finally {
fos.flush();
fos.close();
}
}
BCV.log("Download finished!");
BytecodeViewer.showMessage("Download successful! You can find the updated program at " + saveTo.getAbsolutePath());
onFinish.run();
}
}